mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-25 11:44:25 +03:00
less work for the default InputOnly
This commit is contained in:
parent
fe38f2ff97
commit
6905595a05
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -43,24 +43,20 @@ impl CommonState {
|
||||
ctx: &mut EventCtx,
|
||||
ui: &mut UI,
|
||||
menu: &mut ModalMenu,
|
||||
) -> Option<(Transition, EventLoopMode)> {
|
||||
) -> Option<Transition> {
|
||||
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
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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::<DebugMode>().unwrap().search_results =
|
||||
Some((filter, ids));
|
||||
})),
|
||||
EventLoopMode::InputOnly,
|
||||
)
|
||||
Transition::PopWithData(Box::new(|state| {
|
||||
state.downcast_mut::<DebugMode>().unwrap().search_results = Some((filter, ids));
|
||||
}))
|
||||
}
|
||||
InputResult::StillActive => (Transition::Keep, EventLoopMode::InputOnly),
|
||||
InputResult::StillActive => Transition::Keep,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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<FnOnce(&mut Box<State>)>),
|
||||
Push(Box<State>),
|
||||
Replace(Box<State>),
|
||||
|
||||
// These don't.
|
||||
KeepWithMode(EventLoopMode),
|
||||
PopWithMode(EventLoopMode),
|
||||
PushWithMode(Box<State>, EventLoopMode),
|
||||
ReplaceWithMode(Box<State>, EventLoopMode),
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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::<ScenarioManager>().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::<ScenarioManager>().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) {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user