diff --git a/editor/src/abtest/mod.rs b/editor/src/abtest/mod.rs index f279de1620..c88cf5565c 100644 --- a/editor/src/abtest/mod.rs +++ b/editor/src/abtest/mod.rs @@ -56,7 +56,7 @@ impl ABTestMode { } impl State for ABTestMode { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { let mut txt = Text::prompt("A/B Test Mode"); txt.add_line(ui.primary.map.get_edits().edits_name.clone()); if let Some(ref diff) = self.diff_trip { @@ -80,12 +80,12 @@ impl State for ABTestMode { false, ); } - if let Some(pair) = self.common.event(ctx, ui, &mut self.menu) { - return pair; + if let Some(t) = self.common.event(ctx, ui, &mut self.menu) { + return t; } if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } if self.menu.action("swap") { @@ -96,14 +96,11 @@ impl State for ABTestMode { } if self.menu.action("scoreboard") { - return ( - Transition::Push(Box::new(score::Scoreboard::new( - ctx, - &ui.primary, - ui.secondary.as_ref().unwrap(), - ))), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(score::Scoreboard::new( + ctx, + &ui.primary, + ui.secondary.as_ref().unwrap(), + ))); } if self.menu.action("save state") { @@ -148,9 +145,9 @@ impl State for ABTestMode { if self.menu.action("step forwards 0.1s") { self.step(Duration::seconds(0.1), ui, ctx); } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } else { - (Transition::Keep, EventLoopMode::Animation) + Transition::KeepWithMode(EventLoopMode::Animation) } } diff --git a/editor/src/abtest/score.rs b/editor/src/abtest/score.rs index 5fbc0b2d1a..973fc839dd 100644 --- a/editor/src/abtest/score.rs +++ b/editor/src/abtest/score.rs @@ -2,8 +2,8 @@ use crate::game::{State, Transition}; use crate::ui::PerMapUI; use crate::ui::UI; use ezgui::{ - hotkey, EventCtx, EventLoopMode, GfxCtx, HorizontalAlignment, Key, ModalMenu, Text, - VerticalAlignment, Wizard, WrappedWizard, + hotkey, EventCtx, GfxCtx, HorizontalAlignment, Key, ModalMenu, Text, VerticalAlignment, Wizard, + WrappedWizard, }; use geom::Duration; use itertools::Itertools; @@ -83,24 +83,21 @@ impl Scoreboard { } impl State for Scoreboard { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { self.menu.handle_event(ctx, None); if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } if self.menu.action("browse trips") { - return ( - Transition::Push(Box::new(BrowseTrips { - trips: CompareTrips::new( - ui.primary.sim.get_finished_trips(), - ui.secondary.as_ref().unwrap().sim.get_finished_trips(), - ), - wizard: Wizard::new(), - })), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(BrowseTrips { + trips: CompareTrips::new( + ui.primary.sim.get_finished_trips(), + ui.secondary.as_ref().unwrap().sim.get_finished_trips(), + ), + wizard: Wizard::new(), + })); } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { @@ -118,14 +115,14 @@ struct BrowseTrips { } impl State for BrowseTrips { - fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> Transition { if pick_trip(&self.trips, &mut self.wizard.wrap(ctx)).is_some() { // TODO show more details... - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } else if self.wizard.aborted() { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { diff --git a/editor/src/abtest/setup.rs b/editor/src/abtest/setup.rs index c536ab0681..e28ff7470f 100644 --- a/editor/src/abtest/setup.rs +++ b/editor/src/abtest/setup.rs @@ -3,9 +3,7 @@ use crate::edit::apply_map_edits; use crate::game::{State, Transition}; use crate::render::DrawMap; use crate::ui::{Flags, PerMapUI, UI}; -use ezgui::{ - hotkey, EventCtx, EventLoopMode, GfxCtx, Key, LogScroller, ModalMenu, Wizard, WrappedWizard, -}; +use ezgui::{hotkey, EventCtx, GfxCtx, Key, LogScroller, ModalMenu, Wizard, WrappedWizard}; use geom::Duration; use map_model::{Map, MapEdits}; use sim::{ABTest, Scenario, SimFlags}; @@ -24,29 +22,26 @@ impl PickABTest { } impl State for PickABTest { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { if let Some(ab_test) = pick_ab_test(&ui.primary.map, self.wizard.wrap(ctx)) { let scroller = LogScroller::new(ab_test.test_name.clone(), ab_test.describe()); - return ( - Transition::Replace(Box::new(ABTestSetup { - menu: ModalMenu::new( - &format!("A/B Test Editor for {}", ab_test.test_name), - vec![ - (hotkey(Key::Escape), "quit"), - (hotkey(Key::R), "run A/B test"), - (hotkey(Key::L), "load savestate"), - ], - ctx, - ), - ab_test, - scroller, - })), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(ABTestSetup { + menu: ModalMenu::new( + &format!("A/B Test Editor for {}", ab_test.test_name), + vec![ + (hotkey(Key::Escape), "quit"), + (hotkey(Key::R), "run A/B test"), + (hotkey(Key::L), "load savestate"), + ], + ctx, + ), + ab_test, + scroller, + })); } else if self.wizard.aborted() { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { @@ -61,26 +56,20 @@ struct ABTestSetup { } impl State for ABTestSetup { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { ctx.canvas.handle_event(ctx.input); self.menu.handle_event(ctx, None); if self.scroller.event(ctx.input) { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } else if self.menu.action("run A/B test") { - return ( - Transition::Replace(Box::new(launch_test(&self.ab_test, ui, ctx))), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(launch_test(&self.ab_test, ui, ctx))); } else if self.menu.action("load savestate") { - return ( - Transition::Push(Box::new(LoadSavestate { - ab_test: self.ab_test.clone(), - wizard: Wizard::new(), - })), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(LoadSavestate { + ab_test: self.ab_test.clone(), + wizard: Wizard::new(), + })); } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { @@ -95,16 +84,13 @@ struct LoadSavestate { } impl State for LoadSavestate { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { if let Some(ss) = pick_savestate(&self.ab_test, &mut self.wizard.wrap(ctx)) { - return ( - Transition::Replace(Box::new(launch_savestate(&self.ab_test, ss, ui, ctx))), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(launch_savestate(&self.ab_test, ss, ui, ctx))); } else if self.wizard.aborted() { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { diff --git a/editor/src/common/mod.rs b/editor/src/common/mod.rs index cf8b89acf8..12e5fb4a49 100644 --- a/editor/src/common/mod.rs +++ b/editor/src/common/mod.rs @@ -43,24 +43,20 @@ impl CommonState { ctx: &mut EventCtx, ui: &mut UI, menu: &mut ModalMenu, - ) -> Option<(Transition, EventLoopMode)> { + ) -> Option { if menu.action("warp") { - return Some(( - Transition::Push(Box::new(warp::EnteringWarp::new())), - EventLoopMode::InputOnly, - )); + return Some(Transition::Push(Box::new(warp::EnteringWarp::new()))); } if menu.action("navigate") { - return Some(( - Transition::Push(Box::new(navigate::Navigator::new(ui))), - EventLoopMode::InputOnly, - )); + return Some(Transition::Push(Box::new(navigate::Navigator::new(ui)))); } self.associated.event(ui); self.turn_cycler.event(ctx, ui); if menu.action("take a screenshot") { - return Some((Transition::Keep, EventLoopMode::ScreenCaptureCurrentShot)); + return Some(Transition::KeepWithMode( + EventLoopMode::ScreenCaptureCurrentShot, + )); } None diff --git a/editor/src/common/navigate.rs b/editor/src/common/navigate.rs index caf8e8f251..98140f4748 100644 --- a/editor/src/common/navigate.rs +++ b/editor/src/common/navigate.rs @@ -28,10 +28,10 @@ impl Navigator { } impl State for Navigator { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { let map = &ui.primary.map; match self.autocomplete.event(ctx.input) { - InputResult::Canceled => (Transition::Pop, EventLoopMode::InputOnly), + InputResult::Canceled => Transition::Pop, InputResult::Done(name, ids) => { // Roads share intersections, so of course there'll be overlap here. let mut cross_streets = HashSet::new(); @@ -45,21 +45,18 @@ impl State for Navigator { } } } - ( - Transition::Replace(Box::new(CrossStreet { - first: *ids.iter().next().unwrap(), - autocomplete: Autocomplete::new( - &format!("{} and what?", name), - cross_streets - .into_iter() - .map(|r| (map.get_r(r).get_name(), r)) - .collect(), - ), - })), - EventLoopMode::InputOnly, - ) + Transition::Replace(Box::new(CrossStreet { + first: *ids.iter().next().unwrap(), + autocomplete: Autocomplete::new( + &format!("{} and what?", name), + cross_streets + .into_iter() + .map(|r| (map.get_r(r).get_name(), r)) + .collect(), + ), + })) } - InputResult::StillActive => (Transition::Keep, EventLoopMode::InputOnly), + InputResult::StillActive => Transition::Keep, } } @@ -75,21 +72,21 @@ struct CrossStreet { impl State for CrossStreet { // When None, this is done. - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { let map = &ui.primary.map; match self.autocomplete.event(ctx.input) { InputResult::Canceled => { // Just warp to somewhere on the first road let road = map.get_r(self.first); println!("Warping to {}", road.get_name()); - ( - Transition::Replace(Box::new(Warping { + Transition::ReplaceWithMode( + Box::new(Warping { warper: Warper::new( ctx, road.center_pts.dist_along(road.center_pts.length() / 2.0).0, ), id: ID::Lane(road.all_lanes()[0]), - })), + }), EventLoopMode::Animation, ) } @@ -105,15 +102,15 @@ impl State for CrossStreet { } else { map.get_i(road.dst_i).polygon.center() }; - ( - Transition::Replace(Box::new(Warping { + Transition::ReplaceWithMode( + Box::new(Warping { warper: Warper::new(ctx, pt), id: ID::Lane(road.all_lanes()[0]), - })), + }), EventLoopMode::Animation, ) } - InputResult::StillActive => (Transition::Keep, EventLoopMode::InputOnly), + InputResult::StillActive => Transition::Keep, } } diff --git a/editor/src/common/warp.rs b/editor/src/common/warp.rs index 8a2bd9f45e..30fa858aa9 100644 --- a/editor/src/common/warp.rs +++ b/editor/src/common/warp.rs @@ -20,23 +20,23 @@ impl EnteringWarp { } impl State for EnteringWarp { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { match self.tb.event(ctx.input) { - InputResult::Canceled => (Transition::Pop, EventLoopMode::InputOnly), + InputResult::Canceled => Transition::Pop, InputResult::Done(to, _) => { if let Some((id, pt)) = warp_point(to, &ui.primary) { - ( - Transition::Replace(Box::new(Warping { + Transition::ReplaceWithMode( + Box::new(Warping { warper: Warper::new(ctx, pt), id, - })), + }), EventLoopMode::Animation, ) } else { - (Transition::Pop, EventLoopMode::InputOnly) + Transition::Pop } } - InputResult::StillActive => (Transition::Keep, EventLoopMode::InputOnly), + InputResult::StillActive => Transition::Keep, } } @@ -51,12 +51,12 @@ pub struct Warping { } impl State for Warping { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { if let Some(evmode) = self.warper.event(ctx) { - (Transition::Keep, evmode) + Transition::KeepWithMode(evmode) } else { ui.primary.current_selection = Some(self.id); - (Transition::Pop, EventLoopMode::InputOnly) + Transition::Pop } } diff --git a/editor/src/debug/bus_explorer.rs b/editor/src/debug/bus_explorer.rs index 2efd2dfbb6..d5d14025dd 100644 --- a/editor/src/debug/bus_explorer.rs +++ b/editor/src/debug/bus_explorer.rs @@ -2,7 +2,7 @@ use crate::common::CommonState; use crate::game::{State, Transition}; use crate::helpers::ID; use crate::ui::{ShowEverything, UI}; -use ezgui::{EventCtx, EventLoopMode, GfxCtx, Key, Text, WarpingItemSlider}; +use ezgui::{EventCtx, GfxCtx, Key, Text, WarpingItemSlider}; use geom::Pt2D; use map_model::BusStopID; @@ -45,7 +45,7 @@ impl BusRouteExplorer { } impl State for BusRouteExplorer { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { if ctx.redo_mouseover() { ui.primary.current_selection = ui.recalculate_current_selection( ctx, @@ -61,9 +61,9 @@ impl State for BusRouteExplorer { if done_warping { ui.primary.current_selection = Some(ID::BusStop(*self.slider.get().1)); } - (Transition::Keep, evmode) + Transition::KeepWithMode(evmode) } else { - (Transition::Pop, EventLoopMode::InputOnly) + Transition::Pop } } diff --git a/editor/src/debug/color_picker.rs b/editor/src/debug/color_picker.rs index 1d1d81e8f6..06b7ba58bf 100644 --- a/editor/src/debug/color_picker.rs +++ b/editor/src/debug/color_picker.rs @@ -1,8 +1,7 @@ use crate::game::{State, Transition}; use crate::ui::UI; use ezgui::{ - hotkey, Canvas, Color, EventCtx, EventLoopMode, GfxCtx, InputResult, Key, ModalMenu, ScreenPt, - ScrollingMenu, + hotkey, Canvas, Color, EventCtx, GfxCtx, InputResult, Key, ModalMenu, ScreenPt, ScrollingMenu, }; use geom::{Distance, Polygon}; @@ -24,25 +23,22 @@ impl ColorChooser { } impl State for ColorChooser { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { match self.menu.event(&mut ctx.input) { - InputResult::Canceled => (Transition::Pop, EventLoopMode::InputOnly), - InputResult::StillActive => (Transition::Keep, EventLoopMode::InputOnly), - InputResult::Done(name, _) => ( - Transition::Replace(Box::new(ColorChanger { - name: name.clone(), - original: ui.cs.get_modified(&name), - menu: ModalMenu::new( - &format!("Color Picker for {}", name), - vec![ - (hotkey(Key::Backspace), "revert"), - (hotkey(Key::Escape), "finalize"), - ], - ctx, - ), - })), - EventLoopMode::InputOnly, - ), + InputResult::Canceled => Transition::Pop, + InputResult::StillActive => Transition::Keep, + InputResult::Done(name, _) => Transition::Replace(Box::new(ColorChanger { + name: name.clone(), + original: ui.cs.get_modified(&name), + menu: ModalMenu::new( + &format!("Color Picker for {}", name), + vec![ + (hotkey(Key::Backspace), "revert"), + (hotkey(Key::Escape), "finalize"), + ], + ctx, + ), + })), } } @@ -58,14 +54,14 @@ struct ColorChanger { } impl State for ColorChanger { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { self.menu.handle_event(ctx, None); if self.menu.action("revert") { ui.cs.reset_modified(&self.name, self.original); - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } else if self.menu.action("finalize") { println!("Setting color for {}", self.name); - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } if let Some(pt) = ctx.input.get_moved_mouse() { @@ -78,7 +74,7 @@ impl State for ColorChanger { .override_color(&self.name, get_color(x as f32, y as f32)); } } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { diff --git a/editor/src/debug/mod.rs b/editor/src/debug/mod.rs index cb67a02c31..537c3ac507 100644 --- a/editor/src/debug/mod.rs +++ b/editor/src/debug/mod.rs @@ -88,7 +88,7 @@ impl DebugMode { } impl State for DebugMode { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { if ctx.redo_mouseover() { ui.primary.current_selection = ui.recalculate_current_selection(ctx, &ui.primary.sim, self, true); @@ -126,24 +126,18 @@ impl State for DebugMode { self.menu.handle_event(ctx, Some(txt)); ctx.canvas.handle_event(ctx.input); - if let Some(pair) = self.common.event(ctx, ui, &mut self.menu) { - return pair; + if let Some(t) = self.common.event(ctx, ui, &mut self.menu) { + return t; } if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } if self.menu.action("sandbox mode") { - return ( - Transition::Replace(Box::new(SandboxMode::new(ctx))), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(SandboxMode::new(ctx))); } if self.menu.action("edit mode") { - return ( - Transition::Replace(Box::new(EditMode::new(ctx, ui))), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(EditMode::new(ctx, ui))); } if self.menu.action("show/hide chokepoints") { @@ -211,10 +205,7 @@ impl State for DebugMode { self.neighborhood_summary.event(ui, &mut self.menu); if let Some(debugger) = polygons::PolygonDebugger::new(ctx, ui) { - return ( - Transition::Push(Box::new(debugger)), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(debugger)); } { @@ -244,15 +235,12 @@ impl State for DebugMode { if self.menu.action("screenshot everything") { let bounds = ui.primary.map.get_bounds(); assert!(bounds.min_x == 0.0 && bounds.min_y == 0.0); - return ( - Transition::Keep, - EventLoopMode::ScreenCaptureEverything { - dir: format!("../data/screenshots/pending_{}", ui.primary.map.get_name()), - zoom: 3.0, - max_x: bounds.max_x, - max_y: bounds.max_y, - }, - ); + return Transition::KeepWithMode(EventLoopMode::ScreenCaptureEverything { + dir: format!("../data/screenshots/pending_{}", ui.primary.map.get_name()), + zoom: 3.0, + max_x: bounds.max_x, + max_y: bounds.max_y, + }); } if self.search_results.is_some() { @@ -260,27 +248,18 @@ impl State for DebugMode { self.search_results = None; } } else if self.menu.action("search OSM metadata") { - return ( - Transition::Push(Box::new(SearchOSM { - entry: TextBox::new("Search for what?", None), - })), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(SearchOSM { + entry: TextBox::new("Search for what?", None), + })); } else if self.menu.action("configure colors") { - return ( - Transition::Push(Box::new(color_picker::ColorChooser::new(ui))), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(color_picker::ColorChooser::new(ui))); } if let Some(explorer) = bus_explorer::BusRouteExplorer::new(ctx, ui) { - return ( - Transition::Push(Box::new(explorer)), - EventLoopMode::Animation, - ); + return Transition::PushWithMode(Box::new(explorer), EventLoopMode::Animation); } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw_default_ui(&self) -> bool { @@ -526,9 +505,9 @@ struct SearchOSM { } impl State for SearchOSM { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { match self.entry.event(&mut ctx.input) { - InputResult::Canceled => (Transition::Pop, EventLoopMode::InputOnly), + InputResult::Canceled => Transition::Pop, InputResult::Done(filter, _) => { let mut ids = HashSet::new(); let map = &ui.primary.map; @@ -551,15 +530,11 @@ impl State for SearchOSM { } } - ( - Transition::PopWithData(Box::new(|state| { - state.downcast_mut::().unwrap().search_results = - Some((filter, ids)); - })), - EventLoopMode::InputOnly, - ) + Transition::PopWithData(Box::new(|state| { + state.downcast_mut::().unwrap().search_results = Some((filter, ids)); + })) } - InputResult::StillActive => (Transition::Keep, EventLoopMode::InputOnly), + InputResult::StillActive => Transition::Keep, } } diff --git a/editor/src/debug/polygons.rs b/editor/src/debug/polygons.rs index 4ba7d43872..cf80bbf607 100644 --- a/editor/src/debug/polygons.rs +++ b/editor/src/debug/polygons.rs @@ -3,7 +3,7 @@ use crate::helpers::ID; use crate::render::calculate_corners; use crate::ui::UI; use abstutil::Timer; -use ezgui::{hotkey, EventCtx, EventLoopMode, GfxCtx, ItemSlider, Key, Text}; +use ezgui::{hotkey, EventCtx, GfxCtx, ItemSlider, Key, Text}; use geom::{Polygon, Pt2D, Triangle}; pub struct PolygonDebugger { @@ -152,14 +152,14 @@ impl PolygonDebugger { } impl State for PolygonDebugger { - fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> Transition { self.slider.event(ctx); ctx.canvas.handle_event(ctx.input); if self.slider.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, ui: &UI) { diff --git a/editor/src/edit/mod.rs b/editor/src/edit/mod.rs index 7c8b3b0ed7..9391022102 100644 --- a/editor/src/edit/mod.rs +++ b/editor/src/edit/mod.rs @@ -12,10 +12,7 @@ use crate::render::{ use crate::sandbox::SandboxMode; use crate::ui::{PerMapUI, ShowEverything, UI}; use abstutil::Timer; -use ezgui::{ - hotkey, lctrl, Color, EventCtx, EventLoopMode, GfxCtx, Key, ModalMenu, Text, Wizard, - WrappedWizard, -}; +use ezgui::{hotkey, lctrl, Color, EventCtx, GfxCtx, Key, ModalMenu, Text, Wizard, WrappedWizard}; use map_model::{ IntersectionID, Lane, LaneID, LaneType, Map, MapEdits, Road, RoadID, TurnID, TurnType, }; @@ -53,7 +50,7 @@ impl EditMode { } impl State for EditMode { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { // The .clone() is probably not that expensive, and it makes later code a bit // easier to read. :) let orig_edits = ui.primary.map.get_edits().clone(); @@ -87,41 +84,29 @@ impl State for EditMode { false, ); } - if let Some(pair) = self.common.event(ctx, ui, &mut self.menu) { - return pair; + if let Some(t) = self.common.event(ctx, ui, &mut self.menu) { + return t; } if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } if self.menu.action("sandbox mode") { - return ( - Transition::Replace(Box::new(SandboxMode::new(ctx))), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(SandboxMode::new(ctx))); } if self.menu.action("debug mode") { - return ( - Transition::Replace(Box::new(DebugMode::new(ctx, ui))), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(DebugMode::new(ctx, ui))); } // TODO Only if current edits are unsaved if self.menu.action("save edits") { - return ( - Transition::Push(Box::new(Saving { - wizard: Wizard::new(), - })), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(Saving { + wizard: Wizard::new(), + })); } else if self.menu.action("load different edits") { - return ( - Transition::Push(Box::new(Loading { - wizard: Wizard::new(), - })), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(Loading { + wizard: Wizard::new(), + })); } if let Some(ID::Lane(id)) = ui.primary.current_selection { @@ -170,13 +155,10 @@ impl State for EditMode { .input .contextual_action(Key::U, "bulk edit lanes on this road") { - return ( - Transition::Push(Box::new(BulkEditLanes { - road: ui.primary.map.get_l(id).parent, - wizard: Wizard::new(), - })), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(BulkEditLanes { + road: ui.primary.map.get_l(id).parent, + wizard: Wizard::new(), + })); } else if orig_edits.lane_overrides.contains_key(&id) && ctx.input.contextual_action(Key::R, "revert") { @@ -191,10 +173,9 @@ impl State for EditMode { .input .contextual_action(Key::E, &format!("edit stop signs for {}", id)) { - return ( - Transition::Push(Box::new(stop_signs::StopSignEditor::new(id, ctx, ui))), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(stop_signs::StopSignEditor::new( + id, ctx, ui, + ))); } else if orig_edits.stop_sign_overrides.contains_key(&id) && ctx.input.contextual_action(Key::R, "revert") { @@ -208,12 +189,9 @@ impl State for EditMode { .input .contextual_action(Key::E, &format!("edit traffic signal for {}", id)) { - return ( - Transition::Push(Box::new(traffic_signals::TrafficSignalEditor::new( - id, ctx, ui, - ))), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(traffic_signals::TrafficSignalEditor::new( + id, ctx, ui, + ))); } else if orig_edits.traffic_signal_overrides.contains_key(&id) && ctx.input.contextual_action(Key::R, "revert") { @@ -224,7 +202,7 @@ impl State for EditMode { } } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw_default_ui(&self) -> bool { @@ -320,13 +298,13 @@ struct Saving { } impl State for Saving { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { ctx.canvas.handle_event(ctx.input); if save_edits(self.wizard.wrap(ctx), &mut ui.primary.map).is_some() || self.wizard.aborted() { - (Transition::Pop, EventLoopMode::InputOnly) + Transition::Pop } else { - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } } @@ -341,7 +319,7 @@ struct Loading { } impl State for Loading { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { ctx.canvas.handle_event(ctx.input); if let Some(new_edits) = load_edits( &ui.primary.map, @@ -349,11 +327,11 @@ impl State for Loading { "Load which map edits?", ) { apply_map_edits(&mut ui.primary, &ui.cs, ctx, new_edits); - (Transition::Pop, EventLoopMode::InputOnly) + Transition::Pop } else if self.wizard.aborted() { - (Transition::Pop, EventLoopMode::InputOnly) + Transition::Pop } else { - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } } @@ -369,15 +347,15 @@ struct BulkEditLanes { } impl State for BulkEditLanes { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { ctx.canvas.handle_event(ctx.input); if let Some(edits) = bulk_edit(self.road, &mut self.wizard.wrap(ctx), &ui.primary.map) { apply_map_edits(&mut ui.primary, &ui.cs, ctx, edits); - (Transition::Pop, EventLoopMode::InputOnly) + Transition::Pop } else if self.wizard.aborted() { - (Transition::Pop, EventLoopMode::InputOnly) + Transition::Pop } else { - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } } diff --git a/editor/src/edit/stop_signs.rs b/editor/src/edit/stop_signs.rs index 620b4ab573..5097b01c68 100644 --- a/editor/src/edit/stop_signs.rs +++ b/editor/src/edit/stop_signs.rs @@ -4,7 +4,7 @@ use crate::game::{State, Transition}; use crate::helpers::ID; use crate::render::{DrawIntersection, DrawOptions, DrawTurn}; use crate::ui::{ShowEverything, UI}; -use ezgui::{hotkey, Color, EventCtx, EventLoopMode, GeomBatch, GfxCtx, Key, ModalMenu, Text}; +use ezgui::{hotkey, Color, EventCtx, GeomBatch, GfxCtx, Key, ModalMenu, Text}; use geom::Polygon; use map_model::{IntersectionID, RoadID, TurnID, TurnPriority}; use std::collections::HashMap; @@ -51,7 +51,7 @@ impl StopSignEditor { } impl State for StopSignEditor { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { self.menu.handle_event(ctx, None); ctx.canvas.handle_event(ctx.input); @@ -108,13 +108,13 @@ impl State for StopSignEditor { apply_map_edits(&mut ui.primary, &ui.cs, ctx, new_edits); } } else if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } else if self.menu.action("reset to default") { let mut new_edits = ui.primary.map.get_edits().clone(); new_edits.stop_sign_overrides.remove(&self.id); apply_map_edits(&mut ui.primary, &ui.cs, ctx, new_edits); } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, ui: &UI) { diff --git a/editor/src/edit/traffic_signals.rs b/editor/src/edit/traffic_signals.rs index 9e9feba5ae..96e01004ef 100644 --- a/editor/src/edit/traffic_signals.rs +++ b/editor/src/edit/traffic_signals.rs @@ -6,8 +6,7 @@ use crate::render::{draw_signal_cycle, draw_signal_diagram, DrawCtx, DrawOptions use crate::ui::{ShowEverything, UI}; use abstutil::Timer; use ezgui::{ - hotkey, Color, EventCtx, EventLoopMode, GeomBatch, GfxCtx, Key, ModalMenu, MultiKey, Wizard, - WrappedWizard, + hotkey, Color, EventCtx, GeomBatch, GfxCtx, Key, ModalMenu, MultiKey, Wizard, WrappedWizard, }; use geom::Duration; use map_model::{ControlTrafficSignal, Cycle, IntersectionID, Map, TurnID, TurnPriority, TurnType}; @@ -59,7 +58,7 @@ impl TrafficSignalEditor { } impl State for TrafficSignalEditor { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { self.menu.handle_event(ctx, None); ctx.canvas.handle_event(ctx.input); @@ -149,7 +148,7 @@ impl State for TrafficSignalEditor { } } else { if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } if self.current_cycle != 0 && self.menu.action("select previous cycle") { @@ -235,7 +234,7 @@ impl State for TrafficSignalEditor { apply_map_edits(&mut ui.primary, &ui.cs, ctx, new_edits); } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, ui: &UI) { diff --git a/editor/src/game.rs b/editor/src/game.rs index 829d0499e2..c85cd8a228 100644 --- a/editor/src/game.rs +++ b/editor/src/game.rs @@ -44,30 +44,54 @@ impl Game { impl GUI for Game { fn event(&mut self, ctx: &mut EventCtx) -> EventLoopMode { - let (transition, evloop) = self.states.last_mut().unwrap().event(ctx, &mut self.ui); + let transition = self.states.last_mut().unwrap().event(ctx, &mut self.ui); match transition { - Transition::Keep => {} + Transition::Keep => EventLoopMode::InputOnly, Transition::Pop => { self.states.pop().unwrap().on_destroy(&mut self.ui); if self.states.is_empty() { self.before_quit(ctx.canvas); std::process::exit(0); } + EventLoopMode::InputOnly } Transition::PopWithData(cb) => { self.states.pop().unwrap().on_destroy(&mut self.ui); cb(self.states.last_mut().unwrap()); + EventLoopMode::InputOnly } Transition::Push(state) => { self.states.last_mut().unwrap().on_suspend(&mut self.ui); self.states.push(state); + EventLoopMode::InputOnly } Transition::Replace(state) => { self.states.pop().unwrap().on_destroy(&mut self.ui); self.states.push(state); + EventLoopMode::InputOnly + } + + // A little repetitive... + Transition::KeepWithMode(evmode) => evmode, + Transition::PopWithMode(evmode) => { + self.states.pop().unwrap().on_destroy(&mut self.ui); + if self.states.is_empty() { + self.before_quit(ctx.canvas); + std::process::exit(0); + } + evmode + } + Transition::PushWithMode(state, evmode) => { + self.states.last_mut().unwrap().on_suspend(&mut self.ui); + self.states.push(state); + evmode + } + Transition::ReplaceWithMode(state, evmode) => { + self.states.pop().unwrap().on_destroy(&mut self.ui); + self.states.push(state); + evmode } } - evloop } fn draw(&self, g: &mut GfxCtx) { @@ -114,7 +138,9 @@ impl GUI for Game { } pub trait State: downcast_rs::Downcast { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode); + // Logically this returns Transition, but since EventLoopMode is almost always + // InputOnly, the variations are encoded by Transition. + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition; fn draw(&self, g: &mut GfxCtx, ui: &UI); fn draw_default_ui(&self) -> bool { true @@ -129,11 +155,19 @@ pub trait State: downcast_rs::Downcast { downcast_rs::impl_downcast!(State); +// pub enum Transition { + // These variants imply EventLoopMode::InputOnly. Keep, Pop, // If a state needs to pass data back to the parent, use this. Sadly, runtime type casting. PopWithData(Box)>), Push(Box), Replace(Box), + + // These don't. + KeepWithMode(EventLoopMode), + PopWithMode(EventLoopMode), + PushWithMode(Box, EventLoopMode), + ReplaceWithMode(Box, EventLoopMode), } diff --git a/editor/src/mission/all_trips.rs b/editor/src/mission/all_trips.rs index beabc2ebc4..cdf8f48239 100644 --- a/editor/src/mission/all_trips.rs +++ b/editor/src/mission/all_trips.rs @@ -87,7 +87,7 @@ impl TripsVisualizer { } impl State for TripsVisualizer { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { let time = self.current_time(); let mut txt = Text::prompt("Trips Visualizer"); @@ -112,7 +112,7 @@ impl State for TripsVisualizer { let thirty_mins = Duration::minutes(30); if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } else if time != last_time && self.menu.action("forwards 10 seconds") { self.time_slider .set_percent(ctx, (time + ten_secs) / last_time); @@ -137,7 +137,7 @@ impl State for TripsVisualizer { self.time_slider .set_percent(ctx, ((time + dt) / last_time).min(1.0)); } else { - return (Transition::Keep, EventLoopMode::InputOnly); + return Transition::Keep; } // TODO Do this more efficiently. ;) @@ -151,9 +151,9 @@ impl State for TripsVisualizer { .collect(); if self.speed.is_paused() { - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } else { - (Transition::Keep, EventLoopMode::Animation) + Transition::KeepWithMode(EventLoopMode::Animation) } } diff --git a/editor/src/mission/dataviz.rs b/editor/src/mission/dataviz.rs index 8b21e3b0c3..fc4be18308 100644 --- a/editor/src/mission/dataviz.rs +++ b/editor/src/mission/dataviz.rs @@ -4,8 +4,7 @@ use crate::helpers::{rotating_color_total, ID}; use crate::ui::UI; use abstutil::{prettyprint_usize, Timer}; use ezgui::{ - hotkey, Color, EventCtx, EventLoopMode, GfxCtx, HorizontalAlignment, Key, ModalMenu, Text, - VerticalAlignment, + hotkey, Color, EventCtx, GfxCtx, HorizontalAlignment, Key, ModalMenu, Text, VerticalAlignment, }; use geom::{Distance, Polygon, Pt2D}; use popdat::{Estimate, PopDat}; @@ -59,7 +58,7 @@ impl DataVisualizer { } } impl State for DataVisualizer { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { let mut txt = Text::prompt("Data Visualizer"); if let Some(ref name) = self.current_tract { txt.add_line("Census ".to_string()); @@ -80,7 +79,7 @@ impl State for DataVisualizer { // TODO Remember which dataset we're showing and don't allow reseting to the same. if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } else if self.current_dataset != 0 && self.menu.action("household vehicles") { self.current_dataset = 0; } else if self.current_dataset != 1 && self.menu.action("commute times") { @@ -103,7 +102,7 @@ impl State for DataVisualizer { } } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, ui: &UI) { diff --git a/editor/src/mission/individ_trips.rs b/editor/src/mission/individ_trips.rs index 6e1940ceef..22e8d71036 100644 --- a/editor/src/mission/individ_trips.rs +++ b/editor/src/mission/individ_trips.rs @@ -3,7 +3,7 @@ use crate::game::{State, Transition}; use crate::helpers::ID; use crate::mission::trips::{clip_trips, Trip, TripEndpt}; use crate::ui::{ShowEverything, UI}; -use ezgui::{hotkey, Color, EventCtx, EventLoopMode, GfxCtx, ItemSlider, Key, Text}; +use ezgui::{hotkey, Color, EventCtx, GfxCtx, ItemSlider, Key, Text}; use geom::{Circle, Distance, Line, Speed}; use map_model::BuildingID; use popdat::psrc; @@ -56,7 +56,7 @@ impl TripsVisualizer { } impl State for TripsVisualizer { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { self.slider.event(ctx); ctx.canvas.handle_event(ctx.input); @@ -70,9 +70,9 @@ impl State for TripsVisualizer { } if self.slider.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, ui: &UI) { diff --git a/editor/src/mission/mod.rs b/editor/src/mission/mod.rs index 0bb95ab798..2a93345cb9 100644 --- a/editor/src/mission/mod.rs +++ b/editor/src/mission/mod.rs @@ -10,7 +10,7 @@ use crate::game::{State, Transition}; use crate::sandbox::SandboxMode; use crate::ui::UI; use abstutil::Timer; -use ezgui::{hotkey, EventCtx, EventLoopMode, GfxCtx, Key, ModalMenu, Wizard, WrappedWizard}; +use ezgui::{hotkey, EventCtx, GfxCtx, Key, ModalMenu, Wizard, WrappedWizard}; use geom::Duration; use map_model::Map; use sim::Scenario; @@ -45,27 +45,18 @@ impl MissionEditMode { } impl State for MissionEditMode { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { self.menu.handle_event(ctx, None); ctx.canvas.handle_event(ctx.input); if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } else if self.menu.action("visualize population data") { - return ( - Transition::Push(Box::new(dataviz::DataVisualizer::new(ctx, ui))), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(dataviz::DataVisualizer::new(ctx, ui))); } else if self.menu.action("visualize individual PSRC trips") { - return ( - Transition::Push(Box::new(individ_trips::TripsVisualizer::new(ctx, ui))), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(individ_trips::TripsVisualizer::new(ctx, ui))); } else if self.menu.action("visualize all PSRC trips") { - return ( - Transition::Push(Box::new(all_trips::TripsVisualizer::new(ctx, ui))), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(all_trips::TripsVisualizer::new(ctx, ui))); } else if self.menu.action("set up simulation with PSRC trips") { let scenario = trips_to_scenario( ctx, @@ -84,38 +75,23 @@ impl State for MissionEditMode { .sim .step(&ui.primary.map, Duration::const_seconds(0.1)); }); - return ( - Transition::Replace(Box::new(SandboxMode::new(ctx))), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(SandboxMode::new(ctx))); } else if self.menu.action("create scenario from PSRC trips") { - return ( - Transition::Push(Box::new(TripsToScenario { - wizard: Wizard::new(), - })), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(TripsToScenario { + wizard: Wizard::new(), + })); } else if self.menu.action("manage neighborhoods") { - return ( - Transition::Push(Box::new(neighborhood::NeighborhoodPicker::new())), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(neighborhood::NeighborhoodPicker::new())); } else if self.menu.action("load scenario") { - return ( - Transition::Push(Box::new(LoadScenario { - wizard: Wizard::new(), - })), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(LoadScenario { + wizard: Wizard::new(), + })); } else if self.menu.action("create new scenario") { - return ( - Transition::Push(Box::new(CreateNewScenario { - wizard: Wizard::new(), - })), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(CreateNewScenario { + wizard: Wizard::new(), + })); } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { @@ -128,14 +104,14 @@ struct TripsToScenario { } impl State for TripsToScenario { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { if let Some((t1, t2)) = pick_time_range(self.wizard.wrap(ctx)) { trips_to_scenario(ctx, ui, t1, t2).save(); - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } else if self.wizard.aborted() { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { @@ -148,16 +124,13 @@ struct LoadScenario { } impl State for LoadScenario { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { if let Some(scenario) = load_scenario(&ui.primary.map, &mut self.wizard.wrap(ctx)) { - return ( - Transition::Replace(Box::new(scenario::ScenarioManager::new(scenario, ctx))), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(scenario::ScenarioManager::new(scenario, ctx))); } else if self.wizard.aborted() { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { @@ -170,27 +143,24 @@ struct CreateNewScenario { } impl State for CreateNewScenario { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { let mut wrapped = self.wizard.wrap(ctx); if let Some(name) = wrapped.input_string("Name the scenario") { - return ( - Transition::Replace(Box::new(scenario::ScenarioManager::new( - Scenario { - scenario_name: name, - map_name: ui.primary.map.get_name().to_string(), - seed_parked_cars: Vec::new(), - spawn_over_time: Vec::new(), - border_spawn_over_time: Vec::new(), - individ_trips: Vec::new(), - }, - ctx, - ))), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(scenario::ScenarioManager::new( + Scenario { + scenario_name: name, + map_name: ui.primary.map.get_name().to_string(), + seed_parked_cars: Vec::new(), + spawn_over_time: Vec::new(), + border_spawn_over_time: Vec::new(), + individ_trips: Vec::new(), + }, + ctx, + ))); } else if self.wizard.aborted() { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { diff --git a/editor/src/mission/neighborhood.rs b/editor/src/mission/neighborhood.rs index 9f6afbfc31..9bbde6ff48 100644 --- a/editor/src/mission/neighborhood.rs +++ b/editor/src/mission/neighborhood.rs @@ -1,8 +1,6 @@ use crate::game::{State, Transition}; use crate::ui::UI; -use ezgui::{ - hotkey, Color, EventCtx, EventLoopMode, GfxCtx, Key, ModalMenu, Wizard, WrappedWizard, -}; +use ezgui::{hotkey, Color, EventCtx, GfxCtx, Key, ModalMenu, Wizard, WrappedWizard}; use geom::{Circle, Distance, Line, Polygon, Pt2D}; use map_model::{Map, NeighborhoodBuilder}; @@ -21,32 +19,29 @@ impl NeighborhoodPicker { } impl State for NeighborhoodPicker { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { ctx.canvas.handle_event(ctx.input); if let Some(n) = pick_neighborhood(&ui.primary.map, self.wizard.wrap(ctx)) { - return ( - Transition::Push(Box::new(NeighborhoodEditor { - menu: ModalMenu::new( - &format!("Neighborhood Editor for {}", n.name), - vec![ - (hotkey(Key::Escape), "quit"), - (hotkey(Key::S), "save"), - (hotkey(Key::X), "export as an Osmosis polygon filter"), - (hotkey(Key::P), "add a new point"), - ], - ctx, - ), - neighborhood: n, - mouseover_pt: None, - moving_pt: false, - })), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(NeighborhoodEditor { + menu: ModalMenu::new( + &format!("Neighborhood Editor for {}", n.name), + vec![ + (hotkey(Key::Escape), "quit"), + (hotkey(Key::S), "save"), + (hotkey(Key::X), "export as an Osmosis polygon filter"), + (hotkey(Key::P), "add a new point"), + ], + ctx, + ), + neighborhood: n, + mouseover_pt: None, + moving_pt: false, + })); } else if self.wizard.aborted() { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, ui: &UI) { @@ -74,7 +69,7 @@ struct NeighborhoodEditor { } impl State for NeighborhoodEditor { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { let gps_bounds = ui.primary.map.get_gps_bounds(); self.menu.handle_event(ctx, None); @@ -93,7 +88,7 @@ impl State for NeighborhoodEditor { } } else { if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } else if self.neighborhood.points.len() >= 3 && self.menu.action("save") { self.neighborhood.save(); } else if self.neighborhood.points.len() >= 3 @@ -131,7 +126,7 @@ impl State for NeighborhoodEditor { self.moving_pt = true; } } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, ui: &UI) { diff --git a/editor/src/mission/scenario.rs b/editor/src/mission/scenario.rs index 61adebb01a..629595428c 100644 --- a/editor/src/mission/scenario.rs +++ b/editor/src/mission/scenario.rs @@ -3,9 +3,7 @@ use crate::mission::input_time; use crate::sandbox::SandboxMode; use crate::ui::UI; use abstutil::WeightedUsizeChoice; -use ezgui::{ - hotkey, EventCtx, EventLoopMode, GfxCtx, Key, LogScroller, ModalMenu, Wizard, WrappedWizard, -}; +use ezgui::{hotkey, EventCtx, GfxCtx, Key, LogScroller, ModalMenu, Wizard, WrappedWizard}; use geom::Duration; use map_model::{IntersectionID, Map, Neighborhood}; use sim::{BorderSpawnOverTime, OriginDestination, Scenario, SeedParkedCars, SpawnOverTime}; @@ -37,19 +35,16 @@ impl ScenarioManager { } impl State for ScenarioManager { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { self.menu.handle_event(ctx, None); ctx.canvas.handle_event(ctx.input); if self.menu.action("save") { self.scenario.save(); } else if self.menu.action("edit") { - return ( - Transition::Push(Box::new(ScenarioEditor { - scenario: self.scenario.clone(), - wizard: Wizard::new(), - })), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(ScenarioEditor { + scenario: self.scenario.clone(), + wizard: Wizard::new(), + })); } else if self.menu.action("instantiate") { ctx.loading_screen("instantiate scenario", |_, timer| { self.scenario.instantiate( @@ -60,14 +55,11 @@ impl State for ScenarioManager { ); ui.primary.sim.step(&ui.primary.map, Duration::seconds(0.1)); }); - return ( - Transition::Replace(Box::new(SandboxMode::new(ctx))), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(SandboxMode::new(ctx))); } else if self.scroller.event(&mut ctx.input) { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { @@ -82,24 +74,21 @@ struct ScenarioEditor { } impl State for ScenarioEditor { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { if let Some(()) = edit_scenario(&ui.primary.map, &mut self.scenario, self.wizard.wrap(ctx)) { // TODO autosave, or at least make it clear there are unsaved edits let scenario = self.scenario.clone(); - return ( - Transition::PopWithData(Box::new(|state| { - let mut manager = state.downcast_mut::().unwrap(); - manager.scroller = - LogScroller::new(scenario.scenario_name.clone(), scenario.describe()); - manager.scenario = scenario; - })), - EventLoopMode::InputOnly, - ); + return Transition::PopWithData(Box::new(|state| { + let mut manager = state.downcast_mut::().unwrap(); + manager.scroller = + LogScroller::new(scenario.scenario_name.clone(), scenario.describe()); + manager.scenario = scenario; + })); } else if self.wizard.aborted() { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, ui: &UI) { diff --git a/editor/src/sandbox/mod.rs b/editor/src/sandbox/mod.rs index 5135e2c3c0..be6797f5f5 100644 --- a/editor/src/sandbox/mod.rs +++ b/editor/src/sandbox/mod.rs @@ -72,7 +72,7 @@ impl SandboxMode { } impl State for SandboxMode { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { self.time_travel.record(ui); let mut txt = Text::prompt("Sandbox Mode"); @@ -106,21 +106,15 @@ impl State for SandboxMode { false, ); } - if let Some(pair) = self.common.event(ctx, ui, &mut self.menu) { - return pair; + if let Some(t) = self.common.event(ctx, ui, &mut self.menu) { + return t; } if let Some(spawner) = spawner::AgentSpawner::new(ctx, ui, &mut self.menu) { - return ( - Transition::Push(Box::new(spawner)), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(spawner)); } if let Some(explorer) = route_explorer::RouteExplorer::new(ctx, ui) { - return ( - Transition::Push(Box::new(explorer)), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(explorer)); } if self.following.is_none() { @@ -159,27 +153,18 @@ impl State for SandboxMode { //return EventLoopMode::InputOnly; } if self.menu.action("scoreboard") { - return ( - Transition::Push(Box::new(score::Scoreboard::new(ctx, ui))), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(score::Scoreboard::new(ctx, ui))); } if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } if self.menu.action("debug mode") { // TODO Replace or Push? - return ( - Transition::Replace(Box::new(DebugMode::new(ctx, ui))), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(DebugMode::new(ctx, ui))); } if self.menu.action("edit mode") { - return ( - Transition::Replace(Box::new(EditMode::new(ctx, ui))), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(EditMode::new(ctx, ui))); } if let Some(dt) = self.speed.event(ctx, &mut self.menu, ui.primary.sim.time()) { @@ -199,10 +184,7 @@ impl State for SandboxMode { if self.speed.is_paused() { if !ui.primary.sim.is_empty() && self.menu.action("reset sim") { ui.primary.reset_sim(); - return ( - Transition::Replace(Box::new(SandboxMode::new(ctx))), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(SandboxMode::new(ctx))); } if self.menu.action("save sim state") { ui.primary.sim.save(); @@ -268,16 +250,13 @@ impl State for SandboxMode { false, ); } else if self.menu.action("jump to specific time") { - return ( - Transition::Push(Box::new(JumpingToTime { - wizard: Wizard::new(), - })), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(JumpingToTime { + wizard: Wizard::new(), + })); } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } else { - (Transition::Keep, EventLoopMode::Animation) + Transition::KeepWithMode(EventLoopMode::Animation) } } @@ -324,7 +303,7 @@ struct JumpingToTime { } impl State for JumpingToTime { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { let mut wiz = self.wizard.wrap(ctx); if let Some(t) = input_time(&mut wiz, "Jump to what time?") { @@ -334,7 +313,7 @@ impl State for JumpingToTime { "Bad time", vec![&format!("{} isn't after {}", t, ui.primary.sim.time())], ) { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } } else { if dt > Duration::ZERO { @@ -343,12 +322,12 @@ impl State for JumpingToTime { }); } - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } } else if self.wizard.aborted() { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { diff --git a/editor/src/sandbox/route_explorer.rs b/editor/src/sandbox/route_explorer.rs index 6fd7c8878f..c6352a63fe 100644 --- a/editor/src/sandbox/route_explorer.rs +++ b/editor/src/sandbox/route_explorer.rs @@ -2,7 +2,7 @@ use crate::common::CommonState; use crate::game::{State, Transition}; use crate::render::DrawTurn; use crate::ui::{ShowEverything, UI}; -use ezgui::{Color, EventCtx, EventLoopMode, GfxCtx, Key, Text, WarpingItemSlider}; +use ezgui::{Color, EventCtx, GfxCtx, Key, Text, WarpingItemSlider}; use geom::{Distance, Polygon, Pt2D}; use map_model::{Traversable, LANE_THICKNESS}; use sim::AgentID; @@ -66,7 +66,7 @@ impl RouteExplorer { } impl State for RouteExplorer { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { if ctx.redo_mouseover() { ui.primary.current_selection = ui.recalculate_current_selection( ctx, @@ -81,9 +81,9 @@ impl State for RouteExplorer { // We don't really care about setting current_selection to the current step; drawing covers // it up anyway. if let Some((evmode, _)) = self.slider.event(ctx) { - (Transition::Keep, evmode) + Transition::KeepWithMode(evmode) } else { - (Transition::Pop, EventLoopMode::InputOnly) + Transition::Pop } } diff --git a/editor/src/sandbox/score.rs b/editor/src/sandbox/score.rs index ee706c35c2..1a733f7058 100644 --- a/editor/src/sandbox/score.rs +++ b/editor/src/sandbox/score.rs @@ -1,8 +1,8 @@ use crate::game::{State, Transition}; use crate::ui::UI; use ezgui::{ - hotkey, EventCtx, EventLoopMode, GfxCtx, HorizontalAlignment, Key, ModalMenu, Text, - VerticalAlignment, Wizard, WrappedWizard, + hotkey, EventCtx, GfxCtx, HorizontalAlignment, Key, ModalMenu, Text, VerticalAlignment, Wizard, + WrappedWizard, }; use geom::{Duration, DurationHistogram}; use itertools::Itertools; @@ -47,21 +47,18 @@ impl Scoreboard { } impl State for Scoreboard { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { self.menu.handle_event(ctx, None); if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } if self.menu.action("browse trips") { - return ( - Transition::Push(Box::new(BrowseTrips { - trips: ui.primary.sim.get_finished_trips(), - wizard: Wizard::new(), - })), - EventLoopMode::InputOnly, - ); + return Transition::Push(Box::new(BrowseTrips { + trips: ui.primary.sim.get_finished_trips(), + wizard: Wizard::new(), + })); } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { @@ -79,14 +76,14 @@ struct BrowseTrips { } impl State for BrowseTrips { - fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> Transition { if pick_trip(&self.trips, &mut self.wizard.wrap(ctx)).is_some() { // TODO show trip departure, where it started and ended - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } else if self.wizard.aborted() { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { diff --git a/editor/src/sandbox/spawner.rs b/editor/src/sandbox/spawner.rs index 2b845b657b..6efc2271b5 100644 --- a/editor/src/sandbox/spawner.rs +++ b/editor/src/sandbox/spawner.rs @@ -4,7 +4,7 @@ use crate::helpers::ID; use crate::render::DrawOptions; use crate::ui::{ShowEverything, UI}; use abstutil::Timer; -use ezgui::{hotkey, EventCtx, EventLoopMode, GfxCtx, Key, ModalMenu}; +use ezgui::{hotkey, EventCtx, GfxCtx, Key, ModalMenu}; use geom::{Duration, PolyLine}; use map_model::{ BuildingID, IntersectionID, IntersectionType, LaneType, PathRequest, Position, LANE_THICKNESS, @@ -116,11 +116,11 @@ impl AgentSpawner { } impl State for AgentSpawner { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { // TODO Instructions to select target building/lane self.menu.handle_event(ctx, None); if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } ctx.canvas.handle_event(ctx.input); @@ -144,7 +144,7 @@ impl State for AgentSpawner { } _ => { self.maybe_goal = None; - return (Transition::Keep, EventLoopMode::InputOnly); + return Transition::Keep; } }; @@ -176,7 +176,7 @@ impl State for AgentSpawner { ); if lanes.is_empty() { self.maybe_goal = None; - return (Transition::Keep, EventLoopMode::InputOnly); + return Transition::Keep; } Position::new(lanes[0], map.get_l(lanes[0]).length()) } @@ -290,10 +290,10 @@ impl State for AgentSpawner { &ShowEverything::new(), false, ); - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw_default_ui(&self) -> bool { diff --git a/editor/src/splash_screen.rs b/editor/src/splash_screen.rs index 34995b74f8..032ebffe38 100644 --- a/editor/src/splash_screen.rs +++ b/editor/src/splash_screen.rs @@ -41,27 +41,24 @@ impl SplashScreen { } impl State for SplashScreen { - fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition { if let Some((ref mut screensaver, ref mut rng)) = self.maybe_screensaver { screensaver.update(rng, ctx.input, ctx.canvas, &ui.primary.map); } - let transition = if let Some(t) = - splash_screen(&mut self.wizard, ctx, ui, &mut self.maybe_screensaver) - { - t - } else if self.wizard.aborted() { - Transition::Pop - } else { - Transition::Keep - }; - let evloop = if self.maybe_screensaver.is_some() { + let evmode = if self.maybe_screensaver.is_some() { EventLoopMode::Animation } else { EventLoopMode::InputOnly }; - (transition, evloop) + if let Some(t) = splash_screen(&mut self.wizard, ctx, ui, &mut self.maybe_screensaver) { + t + } else if self.wizard.aborted() { + Transition::PopWithMode(evmode) + } else { + Transition::KeepWithMode(evmode) + } } fn draw(&self, g: &mut GfxCtx, _: &UI) { @@ -135,6 +132,12 @@ fn splash_screen( let about = "About"; let quit = "Quit"; + let evmode = if maybe_screensaver.is_some() { + EventLoopMode::Animation + } else { + EventLoopMode::InputOnly + }; + // TODO No hotkey for quit because it's just the normal menu escape? match wizard .choose_string_hotkeys( @@ -172,10 +175,13 @@ fn splash_screen( // TODO want to clear wizard and screensaver as we leave this state. Some(Transition::Push(Box::new(SandboxMode::new(ctx)))) } else if wizard.aborted() { - Some(Transition::Replace(Box::new(SplashScreen { - wizard: Wizard::new(), - maybe_screensaver: maybe_screensaver.take(), - }))) + Some(Transition::ReplaceWithMode( + Box::new(SplashScreen { + wizard: Wizard::new(), + maybe_screensaver: maybe_screensaver.take(), + }), + evmode, + )) } else { None } diff --git a/editor/src/tutorial.rs b/editor/src/tutorial.rs index c46704a6ce..17f35848f0 100644 --- a/editor/src/tutorial.rs +++ b/editor/src/tutorial.rs @@ -1,6 +1,6 @@ use crate::game::{State, Transition}; use crate::ui::UI; -use ezgui::{hotkey, EventCtx, EventLoopMode, GfxCtx, Key, ModalMenu, Text}; +use ezgui::{hotkey, EventCtx, GfxCtx, Key, ModalMenu, Text}; use geom::Pt2D; pub struct TutorialMode { @@ -21,7 +21,7 @@ impl TutorialMode { } impl State for TutorialMode { - fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> Transition { let mut txt = Text::prompt("Tutorial"); txt.add_line("Click and drag to pan around".to_string()); @@ -30,23 +30,20 @@ impl State for TutorialMode { txt.add_line("".to_string()); txt.add_line("Great! Press ENTER to continue.".to_string()); if ctx.input.key_pressed(Key::Enter, "next step of tutorial") { - return ( - Transition::Replace(Box::new(Part2 { - orig_cam_zoom: ctx.canvas.cam_zoom, - menu: ModalMenu::new("Tutorial", vec![(hotkey(Key::Escape), "quit")], ctx), - })), - EventLoopMode::InputOnly, - ); + return Transition::Replace(Box::new(Part2 { + orig_cam_zoom: ctx.canvas.cam_zoom, + menu: ModalMenu::new("Tutorial", vec![(hotkey(Key::Escape), "quit")], ctx), + })); } } self.menu.handle_event(ctx, Some(txt)); ctx.canvas.handle_event(ctx.input); if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) { @@ -64,7 +61,7 @@ struct Part2 { } impl State for Part2 { - fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> (Transition, EventLoopMode) { + fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> Transition { let mut txt = Text::prompt("Tutorial"); txt.add_line("Use your mouse wheel or touchpad to zoom in and out".to_string()); @@ -72,17 +69,17 @@ impl State for Part2 { txt.add_line("".to_string()); txt.add_line("Great! Press ENTER to continue.".to_string()); if ctx.input.key_pressed(Key::Enter, "next step of tutorial") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } } self.menu.handle_event(ctx, Some(txt)); ctx.canvas.handle_event(ctx.input); if self.menu.action("quit") { - return (Transition::Pop, EventLoopMode::InputOnly); + return Transition::Pop; } - (Transition::Keep, EventLoopMode::InputOnly) + Transition::Keep } fn draw(&self, g: &mut GfxCtx, _: &UI) {