remove piston stuff, cut over to glutin in some basic way. nothing

displays now. :D
This commit is contained in:
Dustin Carlino 2019-01-22 16:13:18 -08:00
parent 974b04e74d
commit af7596f9a5
8 changed files with 75 additions and 440 deletions

View File

@ -65,7 +65,10 @@
## Switch to OpenGL (for speed)
- switch ezgui (could make it generic and have piston or glium support, but maybe not worth it)
- render text
- get playground_gui running
- cant see anything
- render text
- calling draw way too frequently
- change ezgui API to allow uploading geometry once
- undo the y inversion hacks at last!

View File

@ -13,10 +13,6 @@ glutin = "0.19.0"
log = "0.4.5"
ordered-float = "1.0.1"
palette = "0.4"
piston = "0.39.0"
piston2d-graphics = "0.28.0"
piston2d-opengl_graphics = "0.57.0"
pistoncore-glutin_window = "0.51.1"
serde = "1.0"
serde_derive = "1.0"
textwrap = "0.11"

View File

@ -1,8 +1,6 @@
use crate::screen_geom::ScreenRectangle;
use crate::{text, GfxCtx, ScreenPt, Text, UserInput};
use geom::{Bounds, Pt2D};
use graphics::Transformed;
use opengl_graphics::{Filter, GlyphCache, TextureSettings};
use std::cell::RefCell;
const ZOOM_SPEED: f64 = 0.1;
@ -24,7 +22,7 @@ pub struct Canvas {
pub window_width: f64,
pub window_height: f64,
glyphs: RefCell<GlyphCache<'static>>,
//glyphs: RefCell<GlyphCache<'static>>,
// TODO Bit weird and hacky to mutate inside of draw() calls.
covered_areas: RefCell<Vec<ScreenRectangle>>,
@ -32,12 +30,11 @@ pub struct Canvas {
impl Canvas {
pub fn new(initial_width: u32, initial_height: u32) -> Canvas {
let texture_settings = TextureSettings::new().filter(Filter::Nearest);
// TODO We could also preload everything and not need the RefCell.
let glyphs = RefCell::new(
/*let glyphs = RefCell::new(
GlyphCache::new("../data/assets/DejaVuSans.ttf", (), texture_settings)
.expect("Could not load font"),
);
);*/
Canvas {
cam_x: 0.0,
@ -52,8 +49,6 @@ impl Canvas {
window_width: f64::from(initial_width),
window_height: f64::from(initial_height),
glyphs,
covered_areas: RefCell::new(Vec::new()),
}
}
@ -93,11 +88,7 @@ impl Canvas {
}
}
pub(crate) fn start_drawing(&self, g: &mut GfxCtx) {
g.ctx = g
.orig_ctx
.trans(-self.cam_x, -self.cam_y)
.zoom(self.cam_zoom);
pub(crate) fn start_drawing(&self) {
self.covered_areas.borrow_mut().clear();
}
@ -106,17 +97,17 @@ impl Canvas {
}
pub fn draw_mouse_tooltip(&self, g: &mut GfxCtx, txt: Text) {
let glyphs = &mut self.glyphs.borrow_mut();
/*let glyphs = &mut self.glyphs.borrow_mut();
let (width, height) = txt.dims(glyphs);
let x1 = self.cursor_x - (width / 2.0);
let y1 = self.cursor_y - (height / 2.0);
// No need to cover the tooltip; this tooltip follows the mouse anyway.
text::draw_text_bubble(g, glyphs, ScreenPt::new(x1, y1), txt);
text::draw_text_bubble(g, glyphs, ScreenPt::new(x1, y1), txt);*/
}
// TODO Rename these draw_nonblocking_text_*
pub fn draw_text_at(&self, g: &mut GfxCtx, txt: Text, map_pt: Pt2D) {
let glyphs = &mut self.glyphs.borrow_mut();
/*let glyphs = &mut self.glyphs.borrow_mut();
let (width, height) = txt.dims(glyphs);
let pt = self.map_to_screen(map_pt);
text::draw_text_bubble(
@ -124,20 +115,20 @@ impl Canvas {
glyphs,
ScreenPt::new(pt.x - (width / 2.0), pt.y - (height / 2.0)),
txt,
);
);*/
}
pub fn draw_text_at_topleft(&self, g: &mut GfxCtx, txt: Text, pt: Pt2D) {
text::draw_text_bubble(
/*text::draw_text_bubble(
g,
&mut self.glyphs.borrow_mut(),
self.map_to_screen(pt),
txt,
);
);*/
}
pub fn draw_text_at_screenspace_topleft(&self, g: &mut GfxCtx, txt: Text, pt: ScreenPt) {
text::draw_text_bubble(g, &mut self.glyphs.borrow_mut(), pt, txt);
//text::draw_text_bubble(g, &mut self.glyphs.borrow_mut(), pt, txt);
}
// The text box covers up what's beneath and eats the cursor (for get_cursor_in_map_space).
@ -147,7 +138,7 @@ impl Canvas {
txt: Text,
(horiz, vert): (HorizontalAlignment, VerticalAlignment),
) {
if txt.is_empty() {
/*if txt.is_empty() {
return;
}
let glyphs = &mut self.glyphs.borrow_mut();
@ -168,11 +159,12 @@ impl Canvas {
glyphs,
ScreenPt::new(x1, y1),
txt,
));
));*/
}
pub fn text_dims(&self, txt: &Text) -> (f64, f64) {
txt.dims(&mut self.glyphs.borrow_mut())
//txt.dims(&mut self.glyphs.borrow_mut())
(10.0, 10.0)
}
fn zoom_towards_mouse(&mut self, delta_zoom: f64) {

View File

@ -1,6 +1,5 @@
use crate::ScreenPt;
use glium::glutin;
use piston::input as pi;
#[derive(Clone, Copy, PartialEq)]
pub enum Event {
@ -68,70 +67,6 @@ impl Event {
_ => None,
}
}
pub fn from_piston_event(ev: pi::Event) -> Event {
use piston::input::{
ButtonEvent, CursorEvent, MouseCursorEvent, MouseScrollEvent, PressEvent, ReleaseEvent,
ResizeEvent, TouchEvent, UpdateEvent,
};
if let Some(pi::Button::Mouse(button)) = ev.press_args() {
if button == pi::MouseButton::Left {
return Event::LeftMouseButtonDown;
}
if button == pi::MouseButton::Right {
return Event::RightMouseButtonDown;
}
}
if let Some(pi::Button::Mouse(button)) = ev.release_args() {
if button == pi::MouseButton::Left {
return Event::LeftMouseButtonUp;
}
if button == pi::MouseButton::Right {
return Event::RightMouseButtonUp;
}
}
if let Some(pi::Button::Keyboard(key)) = ev.press_args() {
if let Some(key) = Key::from_piston_key(key, ev.button_args()) {
return Event::KeyPress(key);
}
return Event::Unknown;
}
if let Some(pi::Button::Keyboard(key)) = ev.release_args() {
if let Some(key) = Key::from_piston_key(key, ev.button_args()) {
return Event::KeyRelease(key);
}
return Event::Unknown;
}
if ev.update_args().is_some() {
return Event::Update;
}
if let Some(pair) = ev.mouse_cursor_args() {
return Event::MouseMovedTo(ScreenPt::new(pair[0], pair[1]));
}
if let Some(args) = ev.touch_args() {
// The docs say these are normalized [0, 1] coordinates, but... they're not. :D
return Event::MouseMovedTo(ScreenPt::new(args.x, args.y));
}
if let Some(pair) = ev.mouse_scroll_args() {
return Event::MouseWheelScroll(pair[1]);
}
if let Some(pair) = ev.resize_args() {
return Event::WindowResized(pair[0], pair[1]);
}
if let Some(has) = ev.cursor_args() {
if has {
return Event::WindowGainedCursor;
} else {
// TODO Sometimes this doesn't happen! :(
return Event::WindowLostCursor;
}
}
panic!("Unknown piston event {:?}", ev);
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
@ -314,86 +249,6 @@ impl Key {
}
}
fn from_piston_key(key: pi::Key, args: Option<pi::ButtonArgs>) -> Option<Key> {
if let Some(a) = args {
if a.scancode == Some(39) {
return Some(Key::Semicolon);
}
}
Some(match key {
pi::Key::A => Key::A,
pi::Key::B => Key::B,
pi::Key::C => Key::C,
pi::Key::D => Key::D,
pi::Key::E => Key::E,
pi::Key::F => Key::F,
pi::Key::G => Key::G,
pi::Key::H => Key::H,
pi::Key::I => Key::I,
pi::Key::J => Key::J,
pi::Key::K => Key::K,
pi::Key::L => Key::L,
pi::Key::M => Key::M,
pi::Key::N => Key::N,
pi::Key::O => Key::O,
pi::Key::P => Key::P,
pi::Key::Q => Key::Q,
pi::Key::R => Key::R,
pi::Key::S => Key::S,
pi::Key::T => Key::T,
pi::Key::U => Key::U,
pi::Key::V => Key::V,
pi::Key::W => Key::W,
pi::Key::X => Key::X,
pi::Key::Y => Key::Y,
pi::Key::Z => Key::Z,
pi::Key::D1 => Key::Num1,
pi::Key::D2 => Key::Num2,
pi::Key::D3 => Key::Num3,
pi::Key::D4 => Key::Num4,
pi::Key::D5 => Key::Num5,
pi::Key::D6 => Key::Num6,
pi::Key::D7 => Key::Num7,
pi::Key::D8 => Key::Num8,
pi::Key::D9 => Key::Num9,
pi::Key::D0 => Key::Num0,
pi::Key::LeftBracket => Key::LeftBracket,
pi::Key::RightBracket => Key::RightBracket,
pi::Key::Space => Key::Space,
pi::Key::Slash => Key::Slash,
pi::Key::Period => Key::Dot,
pi::Key::Comma => Key::Comma,
pi::Key::Escape => Key::Escape,
pi::Key::Return => Key::Enter,
pi::Key::Tab => Key::Tab,
pi::Key::Backspace => Key::Backspace,
pi::Key::LShift => Key::LeftShift,
pi::Key::LCtrl => Key::LeftControl,
pi::Key::LAlt => Key::LeftAlt,
pi::Key::Left => Key::LeftArrow,
pi::Key::Right => Key::RightArrow,
pi::Key::Up => Key::UpArrow,
pi::Key::Down => Key::DownArrow,
pi::Key::F1 => Key::F1,
pi::Key::F2 => Key::F2,
pi::Key::F3 => Key::F3,
pi::Key::F4 => Key::F4,
pi::Key::F5 => Key::F5,
pi::Key::F6 => Key::F6,
pi::Key::F7 => Key::F7,
pi::Key::F8 => Key::F8,
pi::Key::F9 => Key::F9,
pi::Key::F10 => Key::F10,
pi::Key::F11 => Key::F11,
pi::Key::F12 => Key::F12,
_ => {
println!("Unknown piston key {:?}", key);
return None;
}
})
}
fn from_glutin_key(input: glutin::KeyboardInput) -> Option<Key> {
let key = input.virtual_keycode?;
Some(match key {

View File

@ -28,143 +28,11 @@ pub use crate::top_menu::{Folder, TopMenu};
pub use crate::wizard::{Wizard, WrappedWizard};
use geom::Pt2D;
use glium::{implement_vertex, uniform, Surface};
use graphics::Transformed;
use opengl_graphics::GlGraphics;
use std::mem;
// TODO Not super happy about exposing this; fork_screenspace for external callers should be
// smarter.
pub const TOP_MENU_HEIGHT: f64 = text::LINE_HEIGHT;
pub struct GfxCtx<'a> {
orig_ctx: graphics::Context,
ctx: graphics::Context,
gfx: &'a mut GlGraphics,
}
impl<'a> GfxCtx<'a> {
pub fn new(g: &'a mut GlGraphics, c: graphics::Context) -> GfxCtx<'a> {
GfxCtx {
gfx: g,
orig_ctx: c,
ctx: c,
}
}
// Up to the caller to call unfork()!
// TODO Canvas doesn't understand this change, so things like text drawing that use
// map_to_screen will just be confusing.
pub fn fork(&mut self, top_left: Pt2D, zoom: f64) -> graphics::Context {
mem::replace(
&mut self.ctx,
self.orig_ctx
.trans(-zoom * top_left.x(), -zoom * top_left.y())
.zoom(zoom),
)
}
pub fn fork_screenspace(&mut self) -> graphics::Context {
self.fork(Pt2D::new(0.0, 0.0), 1.0)
}
pub fn unfork(&mut self, old_ctx: graphics::Context) {
self.ctx = old_ctx;
}
pub fn clear(&mut self, color: Color) {
graphics::clear(color.0, self.gfx);
}
// Use graphics::Line internally for now, but make it easy to switch to something else by
// picking this API now.
pub fn draw_line(&mut self, color: Color, thickness: f64, line: &geom::Line) {
self.draw_polygon(color, &line.to_polyline().make_polygons(thickness));
}
pub fn draw_rounded_line(&mut self, color: Color, thickness: f64, line: &geom::Line) {
self.draw_line(color, thickness, line);
self.draw_circle(color, &geom::Circle::new(line.pt1(), thickness / 2.0));
self.draw_circle(color, &geom::Circle::new(line.pt2(), thickness / 2.0));
}
pub fn draw_arrow(&mut self, color: Color, thickness: f64, line: &geom::Line) {
// TODO Raw method doesn't work yet in all cases...
graphics::Line::new_round(color.0, thickness).draw_arrow(
[
line.pt1().x(),
line.pt1().y(),
line.pt2().x(),
line.pt2().y(),
],
2.0 * thickness,
&self.ctx.draw_state,
self.ctx.transform,
self.gfx,
);
/*use dimensioned::si;
let head_size = 2.0 * thickness;
let angle = line.angle();
let triangle_height = (head_size / 2.0).sqrt() * si::M;
self.draw_polygon(
color,
&geom::Polygon::new(&vec![
//line.pt2(),
//line.pt2().project_away(head_size, angle.rotate_degs(-135.0)),
line.reverse()
.dist_along(triangle_height)
.project_away(thickness / 2.0, angle.rotate_degs(90.0)),
line.pt1()
.project_away(thickness / 2.0, angle.rotate_degs(90.0)),
line.pt1()
.project_away(thickness / 2.0, angle.rotate_degs(-90.0)),
line.reverse()
.dist_along(triangle_height)
.project_away(thickness / 2.0, angle.rotate_degs(-90.0)),
//line.pt2().project_away(head_size, angle.rotate_degs(135.0)),
]),
);
self.draw_polygon(
color,
&geom::Polygon::new(&vec![
line.pt2(),
line.pt2()
.project_away(head_size, angle.rotate_degs(-135.0)),
line.pt2().project_away(head_size, angle.rotate_degs(135.0)),
]),
);*/
}
pub fn draw_polygon(&mut self, color: Color, poly: &geom::Polygon) {
for tri in &poly.triangles {
graphics::Polygon::new(color.0).draw(
&[
[tri.pt1.x(), tri.pt1.y()],
[tri.pt2.x(), tri.pt2.y()],
[tri.pt3.x(), tri.pt3.y()],
],
&self.ctx.draw_state,
self.ctx.transform,
self.gfx,
);
}
}
pub fn draw_circle(&mut self, color: Color, circle: &geom::Circle) {
graphics::Ellipse::new(color.0).draw(
[
circle.center.x() - circle.radius,
circle.center.y() - circle.radius,
2.0 * circle.radius,
2.0 * circle.radius,
],
&self.ctx.draw_state,
self.ctx.transform,
self.gfx,
);
}
}
pub struct ToggleableLayer {
layer_name: String,
// If None, never automatically enable at a certain zoom level.
@ -231,7 +99,7 @@ type Uniforms<'a> = glium::uniforms::UniformsStorage<
glium::uniforms::UniformsStorage<'a, [[f32; 4]; 4], glium::uniforms::EmptyUniforms>,
>;
pub struct NewGfxCtx<'a> {
pub struct GfxCtx<'a> {
display: &'a glium::Display,
target: &'a mut glium::Frame,
program: &'a glium::Program,
@ -239,12 +107,13 @@ pub struct NewGfxCtx<'a> {
params: glium::DrawParameters<'a>,
}
impl<'a> NewGfxCtx<'a> {
impl<'a> GfxCtx<'a> {
pub fn new(
canvas: &Canvas,
display: &'a glium::Display,
target: &'a mut glium::Frame,
program: &'a glium::Program,
) -> NewGfxCtx<'a> {
) -> GfxCtx<'a> {
let params = glium::DrawParameters {
depth: glium::Depth {
test: glium::DepthTest::IfLess,
@ -261,7 +130,7 @@ impl<'a> NewGfxCtx<'a> {
view_matrix: camera.get_view(),
};
NewGfxCtx {
GfxCtx {
display,
target,
program,
@ -273,25 +142,21 @@ impl<'a> NewGfxCtx<'a> {
// Up to the caller to call unfork()!
// TODO Canvas doesn't understand this change, so things like text drawing that use
// map_to_screen will just be confusing.
pub fn fork(&mut self, top_left: Pt2D, zoom: f64) -> Uniforms {
pub fn fork(&mut self, top_left: Pt2D, zoom: f64) {
let mut camera = CameraState::new();
// TODO setup camera based on values above
let mut uniforms = uniform! {
self.uniforms = uniform! {
persp_matrix: camera.get_perspective(),
view_matrix: camera.get_view(),
};
mem::swap(&mut self.uniforms, &mut uniforms);
uniforms
}
pub fn fork_screenspace(&mut self) -> Uniforms {
pub fn fork_screenspace(&mut self) {
self.fork(Pt2D::new(0.0, 0.0), 1.0)
}
pub fn unfork(&mut self, old_uniforms: Uniforms<'a>) {
// TODO What do we need to do to re-upload?
self.uniforms = old_uniforms;
pub fn unfork(&mut self) {
// TODO Reset to canvas?
}
pub fn clear(&mut self, color: Color) {

View File

@ -1,11 +1,7 @@
use crate::input::{ContextMenu, ModalMenuState};
use crate::{Canvas, Event, GfxCtx, ModalMenu, NewGfxCtx, TopMenu, UserInput};
use crate::{Canvas, Event, GfxCtx, ModalMenu, TopMenu, UserInput};
use abstutil::Timer;
use glium::glutin;
use glutin_window::GlutinWindow;
use opengl_graphics::{GlGraphics, OpenGL};
use piston::event_loop::{EventLoop, EventSettings, Events};
use piston::window::WindowSettings;
use std::io::Write;
use std::time::{Duration, Instant};
use std::{env, fs, panic, process, thread};
@ -40,75 +36,8 @@ pub enum EventLoopMode {
ScreenCaptureEverything { zoom: f64, max_x: f64, max_y: f64 },
}
pub fn run<T, G: GUI<T>>(mut gui: G, window_title: &str) {
// DPI is broken on my system; force the old behavior.
env::set_var("WINIT_HIDPI_FACTOR", "1.0");
let opengl = OpenGL::V3_2;
let settings = WindowSettings::new(
window_title,
[
gui.get_mut_canvas().window_width as u32,
gui.get_mut_canvas().window_height as u32,
],
)
.opengl(opengl)
.exit_on_esc(false)
// TODO it'd be cool to dynamically tweak antialiasing settings as we zoom in
.samples(2)
.srgb(false);
let mut window: GlutinWindow = settings.build().expect("Could not create window");
let mut events = Events::new(EventSettings::new().lazy(true));
let mut gl = GlGraphics::new(opengl);
let mut state = State {
last_event_mode: EventLoopMode::InputOnly,
context_menu: ContextMenu::Inactive,
top_menu: gui.top_menu(),
modal_state: ModalMenuState::new(G::modal_menus()),
last_data: None,
screen_cap: None,
gui,
};
while let Some(ev) = events.next(&mut window) {
use piston::input::{CloseEvent, RenderEvent};
if let Some(args) = ev.render_args() {
gl.draw(args.viewport(), |c, g| {
state.draw(&mut GfxCtx::new(g, c));
});
} else if ev.close_args().is_some() {
state.gui.before_quit();
process::exit(0);
} else {
// Skip some events.
use piston::input::{
AfterRenderEvent, FocusEvent, IdleEvent, MouseRelativeEvent, TextEvent,
};
if ev.after_render_args().is_some() {
state.after_render();
continue;
}
if state.screen_cap.is_some() {
continue;
}
if ev.after_render_args().is_some()
|| ev.focus_args().is_some()
|| ev.idle_args().is_some()
|| ev.mouse_relative_args().is_some()
|| ev.text_args().is_some()
{
continue;
}
state = state.event(ev, &mut events);
}
}
}
struct State<T, G: GUI<T>> {
gui: G,
last_event_mode: EventLoopMode,
context_menu: ContextMenu,
top_menu: Option<TopMenu>,
modal_state: ModalMenuState,
@ -117,18 +46,18 @@ struct State<T, G: GUI<T>> {
}
impl<T, G: GUI<T>> State<T, G> {
fn event(mut self, ev: piston::input::Event, events: &mut Events) -> State<T, G> {
fn event(mut self, ev: Event) -> (State<T, G>, EventLoopMode) {
// It's impossible / very unlikey we'll grab the cursor in map space before the very first
// start_drawing call.
let mut input = UserInput::new(
Event::from_piston_event(ev),
ev,
self.context_menu,
self.top_menu,
self.modal_state,
self.gui.get_mut_canvas(),
);
let mut gui = self.gui;
let (new_event_mode, data) =
let (event_mode, data) =
match panic::catch_unwind(panic::AssertUnwindSafe(|| gui.event(&mut input))) {
Ok(pair) => pair,
Err(err) => {
@ -156,38 +85,28 @@ impl<T, G: GUI<T>> State<T, G> {
self.modal_state.active = still_active;
// Don't constantly reset the events struct -- only when laziness changes.
if new_event_mode != self.last_event_mode {
events.set_lazy(new_event_mode == EventLoopMode::InputOnly);
self.last_event_mode = new_event_mode;
if let EventLoopMode::ScreenCaptureEverything { zoom, max_x, max_y } = new_event_mode {
self.screen_cap = Some(ScreenCaptureState::new(
self.gui.get_mut_canvas(),
zoom,
max_x,
max_y,
));
events.set_lazy(false);
}
if let EventLoopMode::ScreenCaptureEverything { zoom, max_x, max_y } = event_mode {
self.screen_cap = Some(ScreenCaptureState::new(
self.gui.get_mut_canvas(),
zoom,
max_x,
max_y,
));
}
self
(self, event_mode)
}
fn new_draw(&mut self, display: &glium::Display, program: &glium::Program) {
fn draw(&mut self, display: &glium::Display, program: &glium::Program) {
let mut target = display.draw();
// TODO call draw
NewGfxCtx::new(&display, &mut target, program);
target.finish().unwrap();
}
let mut g = GfxCtx::new(self.gui.get_mut_canvas(), &display, &mut target, program);
fn draw(&mut self, g: &mut GfxCtx) {
// If the very first event is render, then just wait.
if let Some(ref data) = self.last_data {
self.gui.get_mut_canvas().start_drawing(g);
self.gui.get_mut_canvas().start_drawing();
match panic::catch_unwind(panic::AssertUnwindSafe(|| {
self.gui.new_draw(g, data, self.screen_cap.is_some())
self.gui.new_draw(&mut g, data, self.screen_cap.is_some())
})) {
Ok(naming_hint) => {
if let Some(ref mut cap) = self.screen_cap {
@ -203,16 +122,18 @@ impl<T, G: GUI<T>> State<T, G> {
if self.screen_cap.is_none() {
// Always draw the menus last.
if let Some(ref menu) = self.top_menu {
menu.draw(g, self.gui.get_mut_canvas());
menu.draw(&mut g, self.gui.get_mut_canvas());
}
for (_, ref menu) in &self.modal_state.active {
menu.draw(g, self.gui.get_mut_canvas());
menu.draw(&mut g, self.gui.get_mut_canvas());
}
if let ContextMenu::Displaying(ref menu) = self.context_menu {
menu.draw(g, self.gui.get_mut_canvas());
menu.draw(&mut g, self.gui.get_mut_canvas());
}
}
}
target.finish().unwrap();
}
fn after_render(&mut self) {
@ -319,7 +240,7 @@ impl ScreenCaptureState {
}
}
pub fn new_run<T, G: GUI<T>>(mut gui: G, window_title: &str) {
pub fn run<T, G: GUI<T>>(mut gui: G, window_title: &str) {
// DPI is broken on my system; force the old behavior.
env::set_var("WINIT_HIDPI_FACTOR", "1.0");
@ -341,7 +262,6 @@ pub fn new_run<T, G: GUI<T>>(mut gui: G, window_title: &str) {
.unwrap();
let mut state = State {
last_event_mode: EventLoopMode::InputOnly,
context_menu: ContextMenu::Inactive,
top_menu: gui.top_menu(),
modal_state: ModalMenuState::new(G::modal_menus()),
@ -352,22 +272,30 @@ pub fn new_run<T, G: GUI<T>>(mut gui: G, window_title: &str) {
let mut accumulator = Duration::new(0, 0);
let mut previous_clock = Instant::now();
let mut send_update_events = false;
loop {
state.new_draw(&display, &program);
state.draw(&display, &program);
state.after_render();
let mut new_events: Vec<glutin::WindowEvent> = Vec::new();
events_loop.poll_events(|event| {
if let glutin::Event::WindowEvent { event, .. } = event {
if event == glutin::WindowEvent::CloseRequested {
state.gui.before_quit();
process::exit(0);
}
if state.screen_cap.is_none() {
// TODO manage laziness differently
//state = state.event(event, &mut events);
}
new_events.push(event);
}
});
for event in new_events {
if event == glutin::WindowEvent::CloseRequested {
state.gui.before_quit();
process::exit(0);
}
if state.screen_cap.is_none() {
if let Some(ev) = Event::from_glutin_event(event) {
let (new_state, mode) = state.event(ev);
state = new_state;
send_update_events = mode == EventLoopMode::Animation;
}
}
}
let now = Instant::now();
accumulator += now - previous_clock;

View File

@ -1,9 +1,5 @@
use crate::screen_geom::ScreenRectangle;
use crate::{Canvas, Color, GfxCtx, ScreenPt};
use graphics;
use graphics::character::CharacterCache;
use graphics::{Rectangle, Transformed};
use opengl_graphics::GlyphCache;
use ordered_float::NotNan;
use textwrap;
@ -124,7 +120,7 @@ impl Text {
self.lines.is_empty()
}
pub(crate) fn dims(&self, glyphs: &mut GlyphCache) -> (f64, f64) {
/*pub(crate) fn dims(&self, glyphs: &mut GlyphCache) -> (f64, f64) {
let width = self
.lines
.iter()
@ -143,10 +139,10 @@ impl Text {
.unwrap();
let height = (self.lines.len() as f64) * LINE_HEIGHT;
(width, height)
}
}*/
}
pub fn draw_text_bubble(
/*pub fn draw_text_bubble(
g: &mut GfxCtx,
glyphs: &mut GlyphCache,
top_left: ScreenPt,
@ -210,4 +206,4 @@ pub fn draw_text_bubble(
x2: top_left.x + total_width,
y2: top_left.y + total_height,
}
}
}*/

View File

@ -135,7 +135,7 @@ impl TopMenu {
y2: TOP_MENU_HEIGHT,
});
let old_ctx = g.fork_screenspace();
g.fork_screenspace();
g.draw_polygon(
text::BG_COLOR,
&Polygon::rectangle_topleft(Pt2D::new(0.0, 0.0), canvas.window_width, TOP_MENU_HEIGHT),
@ -148,7 +148,7 @@ impl TopMenu {
&Polygon::rectangle_topleft(Pt2D::new(r.x1, r.y1), r.x2 - r.x1, r.y2 - r.y1),
);
}
g.unfork(old_ctx);
g.unfork();
canvas.draw_text_at_screenspace_topleft(g, self.txt.clone(), ScreenPt::new(0.0, 0.0));