mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 23:43:25 +03:00
tool-assisted refactor of ezgui Outcome
This commit is contained in:
parent
f73516d183
commit
41f4cfff6d
@ -121,7 +121,7 @@ impl GUI for App {
|
||||
|
||||
// This dispatches event handling to all of the widgets inside.
|
||||
match self.controls.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
// These outcomes should probably be a custom enum per Composite, to be more
|
||||
// typesafe.
|
||||
"reset the stopwatch" => {
|
||||
@ -140,7 +140,7 @@ impl GUI for App {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// An update event means that no keyboard/mouse input happened, but time has passed.
|
||||
@ -176,8 +176,8 @@ impl GUI for App {
|
||||
if let Some((_, ref mut p)) = self.timeseries_panel {
|
||||
match p.event(ctx) {
|
||||
// No buttons in there
|
||||
Some(Outcome::Clicked(_)) => unreachable!(),
|
||||
None => {}
|
||||
Outcome::Clicked(_) => unreachable!(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -742,7 +742,7 @@ impl Composite {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn event(&mut self, ctx: &mut EventCtx) -> Option<Outcome> {
|
||||
pub fn event(&mut self, ctx: &mut EventCtx) -> Outcome {
|
||||
if (self.scrollable_x || self.scrollable_y)
|
||||
&& ctx
|
||||
.canvas
|
||||
@ -834,7 +834,7 @@ impl Composite {
|
||||
self.top_level.restore(ctx, &prev);
|
||||
|
||||
// Since we just moved things around, let all widgets respond to the mouse being somewhere
|
||||
ctx.no_op_event(true, |ctx| assert!(self.event(ctx).is_none()));
|
||||
ctx.no_op_event(true, |ctx| assert_eq!(self.event(ctx), Outcome::Nothing));
|
||||
}
|
||||
|
||||
pub fn scroll_to_member(&mut self, ctx: &EventCtx, name: String) {
|
||||
@ -934,14 +934,14 @@ impl Composite {
|
||||
self.recompute_layout(ctx, false);
|
||||
|
||||
// Since we just moved things around, let all widgets respond to the mouse being somewhere
|
||||
ctx.no_op_event(true, |ctx| assert!(self.event(ctx).is_none()));
|
||||
ctx.no_op_event(true, |ctx| assert_eq!(self.event(ctx), Outcome::Nothing));
|
||||
}
|
||||
pub fn align_below(&mut self, ctx: &mut EventCtx, other: &Composite, pad: f64) {
|
||||
self.vert = VerticalAlignment::Below(other.top_level.rect.y2 + pad);
|
||||
self.recompute_layout(ctx, false);
|
||||
|
||||
// Since we just moved things around, let all widgets respond to the mouse being somewhere
|
||||
ctx.no_op_event(true, |ctx| assert!(self.event(ctx).is_none()));
|
||||
ctx.no_op_event(true, |ctx| assert_eq!(self.event(ctx), Outcome::Nothing));
|
||||
}
|
||||
|
||||
// All margins/padding/etc from the previous widget are retained.
|
||||
@ -1045,7 +1045,7 @@ impl CompositeBuilder {
|
||||
// Just trigger error if a button is double-defined
|
||||
c.get_all_click_actions();
|
||||
// Let all widgets initially respond to the mouse being somewhere
|
||||
ctx.no_op_event(true, |ctx| assert!(c.event(ctx).is_none()));
|
||||
ctx.no_op_event(true, |ctx| assert_eq!(c.event(ctx), Outcome::Nothing));
|
||||
c
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ impl Wizard {
|
||||
}
|
||||
|
||||
match self.tb_comp.as_mut().unwrap().event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"quit" => {
|
||||
self.alive = false;
|
||||
self.tb_comp = None;
|
||||
@ -129,7 +129,7 @@ impl Wizard {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => None,
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -220,14 +220,14 @@ impl<'a, 'b> WrappedWizard<'a, 'b> {
|
||||
// wizard
|
||||
if self.wizard.ack.is_some() {
|
||||
match self.wizard.ack.as_mut().unwrap().event(self.ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"OK" => {
|
||||
self.wizard.ack = None;
|
||||
self.wizard.alive = false;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
@ -280,7 +280,7 @@ impl<'a, 'b> WrappedWizard<'a, 'b> {
|
||||
}
|
||||
|
||||
match self.wizard.menu_comp.as_mut().unwrap().event(self.ctx) {
|
||||
Some(Outcome::Clicked(x)) if x == "quit" => {
|
||||
Outcome::Clicked(x) if x == "quit" => {
|
||||
self.wizard.alive = false;
|
||||
self.wizard.menu_comp = None;
|
||||
return None;
|
||||
@ -367,7 +367,7 @@ impl<'a, 'b> WrappedWizard<'a, 'b> {
|
||||
self.setup_ack(txt);
|
||||
}
|
||||
match self.wizard.ack.as_mut().unwrap().event(self.ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"OK" => {
|
||||
self.wizard.confirmed_state.push(Box::new(()));
|
||||
self.wizard.ack = None;
|
||||
@ -375,7 +375,7 @@ impl<'a, 'b> WrappedWizard<'a, 'b> {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => None,
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,14 +81,14 @@ impl WidgetImpl for Button {
|
||||
}
|
||||
if self.hovering && ctx.normal_left_click() {
|
||||
self.hovering = false;
|
||||
output.outcome = Some(Outcome::Clicked(self.action.clone()));
|
||||
output.outcome = Outcome::Clicked(self.action.clone());
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(ref hotkey) = self.hotkey {
|
||||
if ctx.input.new_was_pressed(hotkey) {
|
||||
self.hovering = false;
|
||||
output.outcome = Some(Outcome::Clicked(self.action.clone()));
|
||||
output.outcome = Outcome::Clicked(self.action.clone());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
Btn, Button, Color, EventCtx, GeomBatch, GfxCtx, Line, MultiKey, RewriteColor, ScreenDims,
|
||||
ScreenPt, Text, TextExt, TextSpan, Widget, WidgetImpl, WidgetOutput,
|
||||
Btn, Button, Color, EventCtx, GeomBatch, GfxCtx, Line, MultiKey, Outcome, RewriteColor,
|
||||
ScreenDims, ScreenPt, Text, TextExt, TextSpan, Widget, WidgetImpl, WidgetOutput,
|
||||
};
|
||||
|
||||
pub struct Checkbox {
|
||||
@ -196,7 +196,8 @@ impl WidgetImpl for Checkbox {
|
||||
|
||||
fn event(&mut self, ctx: &mut EventCtx, output: &mut WidgetOutput) {
|
||||
self.btn.event(ctx, output);
|
||||
if output.outcome.take().is_some() {
|
||||
if let Outcome::Clicked(_) = output.outcome {
|
||||
output.outcome = Outcome::Nothing;
|
||||
std::mem::swap(&mut self.btn, &mut self.other_btn);
|
||||
self.btn.set_pos(self.other_btn.top_left);
|
||||
self.enabled = !self.enabled;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{EventCtx, GfxCtx, ScreenDims, ScreenPt, Widget, WidgetImpl, WidgetOutput};
|
||||
use crate::{EventCtx, GfxCtx, Outcome, ScreenDims, ScreenPt, Widget, WidgetImpl, WidgetOutput};
|
||||
|
||||
pub struct Nothing {}
|
||||
|
||||
@ -49,7 +49,7 @@ impl WidgetImpl for Container {
|
||||
fn event(&mut self, ctx: &mut EventCtx, output: &mut WidgetOutput) {
|
||||
for w in &mut self.members {
|
||||
w.widget.event(ctx, output);
|
||||
if output.outcome.is_some() {
|
||||
if output.outcome != Outcome::Nothing {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
Btn, Button, Choice, Color, EventCtx, GeomBatch, GfxCtx, InputResult, Menu, ScreenDims,
|
||||
ScreenPt, ScreenRectangle, WidgetImpl, WidgetOutput,
|
||||
Btn, Button, Choice, Color, EventCtx, GeomBatch, GfxCtx, InputResult, Menu, Outcome,
|
||||
ScreenDims, ScreenPt, ScreenRectangle, WidgetImpl, WidgetOutput,
|
||||
};
|
||||
use geom::{Distance, Polygon, Pt2D};
|
||||
|
||||
@ -113,7 +113,8 @@ impl<T: 'static + Clone> WidgetImpl for Dropdown<T> {
|
||||
}
|
||||
} else {
|
||||
self.btn.event(ctx, output);
|
||||
if output.outcome.take().is_some() {
|
||||
if let Outcome::Clicked(_) = output.outcome {
|
||||
output.outcome = Outcome::Nothing;
|
||||
self.open_menu(ctx);
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ impl<T: 'static + Clone> WidgetImpl for Menu<T> {
|
||||
if rect.contains(pt) && choice.active {
|
||||
// TODO Two ways of communicating results, based on use in wizards or a
|
||||
// larger composite.
|
||||
output.outcome = Some(Outcome::Clicked(choice.label.clone()));
|
||||
output.outcome = Outcome::Clicked(choice.label.clone());
|
||||
self.state = InputResult::Done(choice.label.clone(), choice.data.clone());
|
||||
return;
|
||||
}
|
||||
@ -146,7 +146,7 @@ impl<T: 'static + Clone> WidgetImpl for Menu<T> {
|
||||
if let Some(ref hotkey) = choice.hotkey {
|
||||
if ctx.input.new_was_pressed(hotkey) {
|
||||
self.state = InputResult::Done(choice.label.clone(), choice.data.clone());
|
||||
output.outcome = Some(Outcome::Clicked(choice.label.clone()));
|
||||
output.outcome = Outcome::Clicked(choice.label.clone());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -157,7 +157,7 @@ impl<T: 'static + Clone> WidgetImpl for Menu<T> {
|
||||
let choice = &self.choices[self.current_idx];
|
||||
if choice.active {
|
||||
self.state = InputResult::Done(choice.label.clone(), choice.data.clone());
|
||||
output.outcome = Some(Outcome::Clicked(choice.label.clone()));
|
||||
output.outcome = Outcome::Clicked(choice.label.clone());
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
|
@ -42,8 +42,14 @@ pub trait WidgetImpl: downcast_rs::Downcast {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Outcome {
|
||||
/// An action was done
|
||||
Clicked(String),
|
||||
/// A dropdown or checkbox changed values
|
||||
Changed(String),
|
||||
/// Nothing happened
|
||||
Nothing,
|
||||
}
|
||||
|
||||
pub struct WidgetOutput {
|
||||
@ -51,14 +57,14 @@ pub struct WidgetOutput {
|
||||
pub redo_layout: bool,
|
||||
/// This widget produced an Outcome, and event handling should immediately stop. Most widgets
|
||||
/// shouldn't set this.
|
||||
pub outcome: Option<Outcome>,
|
||||
pub outcome: Outcome,
|
||||
}
|
||||
|
||||
impl WidgetOutput {
|
||||
pub fn new() -> WidgetOutput {
|
||||
WidgetOutput {
|
||||
redo_layout: false,
|
||||
outcome: None,
|
||||
outcome: Outcome::Nothing,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
Btn, Button, Choice, Color, Dropdown, EventCtx, GeomBatch, GfxCtx, JustDraw, MultiKey,
|
||||
Btn, Button, Choice, Color, Dropdown, EventCtx, GeomBatch, GfxCtx, JustDraw, MultiKey, Outcome,
|
||||
ScreenDims, ScreenPt, Widget, WidgetImpl, WidgetOutput,
|
||||
};
|
||||
use geom::Polygon;
|
||||
@ -71,7 +71,7 @@ impl<T: 'static + Clone + PartialEq> WidgetImpl for PersistentSplit<T> {
|
||||
|
||||
fn event(&mut self, ctx: &mut EventCtx, output: &mut WidgetOutput) {
|
||||
self.btn.event(ctx, output);
|
||||
if output.outcome.is_some() {
|
||||
if let Outcome::Clicked(_) = output.outcome {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
text, Btn, Button, EventCtx, GeomBatch, GfxCtx, Line, ScreenDims, ScreenPt, ScreenRectangle,
|
||||
Text, Widget, WidgetImpl, WidgetOutput,
|
||||
text, Btn, Button, EventCtx, GeomBatch, GfxCtx, Line, Outcome, ScreenDims, ScreenPt,
|
||||
ScreenRectangle, Text, Widget, WidgetImpl, WidgetOutput,
|
||||
};
|
||||
use geom::{Polygon, Pt2D};
|
||||
|
||||
@ -69,7 +69,8 @@ impl WidgetImpl for Spinner {
|
||||
|
||||
fn event(&mut self, ctx: &mut EventCtx, output: &mut WidgetOutput) {
|
||||
self.up.event(ctx, output);
|
||||
if output.outcome.take().is_some() {
|
||||
if let Outcome::Clicked(_) = output.outcome {
|
||||
output.outcome = Outcome::Nothing;
|
||||
if self.current != self.high {
|
||||
self.current += 1;
|
||||
}
|
||||
@ -78,7 +79,8 @@ impl WidgetImpl for Spinner {
|
||||
}
|
||||
|
||||
self.down.event(ctx, output);
|
||||
if output.outcome.take().is_some() {
|
||||
if let Outcome::Clicked(_) = output.outcome {
|
||||
output.outcome = Outcome::Nothing;
|
||||
if self.current != self.low {
|
||||
self.current -= 1;
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ impl CityPicker {
|
||||
impl State for CityPicker {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -120,7 +120,7 @@ impl State for CityPicker {
|
||||
});
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if ctx.redo_mouseover() {
|
||||
|
@ -39,13 +39,13 @@ impl State for IsochroneViewer {
|
||||
ctx.canvas_movement();
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
|
@ -121,7 +121,7 @@ impl Minimap {
|
||||
|
||||
let pan_speed = 100.0;
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x {
|
||||
Outcome::Clicked(x) => match x {
|
||||
x if x == "pan up" => {
|
||||
self.offset_y -= pan_speed * self.zoom;
|
||||
return Some(Transition::KeepWithMouseover);
|
||||
@ -188,7 +188,7 @@ impl Minimap {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
if self.composite.has_widget("zorder") {
|
||||
app.primary.show_zorder = self.composite.spinner("zorder");
|
||||
|
@ -44,7 +44,7 @@ impl Navigator {
|
||||
impl State for Navigator {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -53,7 +53,7 @@ impl State for Navigator {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
if let Some(roads) = self.composite.autocomplete_done("street") {
|
||||
if roads.is_empty() {
|
||||
@ -137,7 +137,7 @@ impl State for CrossStreet {
|
||||
let map = &app.primary.map;
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
// Just warp to somewhere on the first road
|
||||
let road = map.get_r(self.first[0]);
|
||||
@ -151,7 +151,7 @@ impl State for CrossStreet {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
if let Some(roads) = self.composite.autocomplete_done("street") {
|
||||
// Find the best match
|
||||
@ -240,7 +240,7 @@ impl SearchBuildings {
|
||||
impl State for SearchBuildings {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -249,7 +249,7 @@ impl State for SearchBuildings {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
if let Some(bldgs) = self.composite.autocomplete_done("bldg") {
|
||||
if bldgs.is_empty() {
|
||||
|
@ -124,7 +124,7 @@ impl DebugWarp {
|
||||
impl State for DebugWarp {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -141,7 +141,7 @@ impl State for DebugWarp {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => Transition::Keep,
|
||||
_ => Transition::Keep,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ struct CutscenePlayer {
|
||||
impl State for CutscenePlayer {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"quit" => {
|
||||
// TODO Should SandboxMode use on_destroy for this?
|
||||
app.primary.clear_sim();
|
||||
@ -130,7 +130,7 @@ impl State for CutscenePlayer {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
// TODO Should the Composite for text widgets with wrapping do this instead?
|
||||
if ctx.input.is_window_resized() {
|
||||
@ -317,11 +317,11 @@ impl FYI {
|
||||
impl State for FYI {
|
||||
fn event(&mut self, ctx: &mut EventCtx, _: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Okay" => Transition::Pop,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => Transition::Keep,
|
||||
_ => Transition::Keep,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,13 +88,13 @@ impl State for Floodfiller {
|
||||
ctx.canvas_movement();
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let constraints = self.composite.dropdown_value("constraints");
|
||||
|
@ -112,7 +112,7 @@ impl State for DebugMode {
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -213,7 +213,7 @@ impl State for DebugMode {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
// TODO We should really recalculate current_selection when these change. Meh.
|
||||
self.layers.show_buildings = self.composite.is_checked("show buildings");
|
||||
|
@ -59,7 +59,7 @@ impl State for PolygonDebugger {
|
||||
ctx.canvas_movement();
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -83,7 +83,7 @@ impl State for PolygonDebugger {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
// TODO Could be more efficient here
|
||||
let idx = (self.composite.slider("slider").get_percent() * (self.items.len() - 1) as f64)
|
||||
|
@ -128,13 +128,13 @@ impl State for PopularDestinations {
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let opts = if self.composite.is_checked("Show heatmap") {
|
||||
|
@ -151,13 +151,13 @@ impl State for ViewKML {
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let query: String = self.composite.dropdown_value("query");
|
||||
|
@ -384,7 +384,7 @@ impl State for ParkingMapper {
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
app.opts.min_zoom_for_detail =
|
||||
crate::options::Options::default().min_zoom_for_detail;
|
||||
@ -428,7 +428,7 @@ impl State for ParkingMapper {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
let show = self.composite.dropdown_value("Show");
|
||||
if show != self.show {
|
||||
|
@ -56,7 +56,7 @@ impl DevToolsMode {
|
||||
impl State for DevToolsMode {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -90,7 +90,7 @@ impl State for DevToolsMode {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
|
@ -65,7 +65,7 @@ impl State for PolygonEditor {
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -76,7 +76,7 @@ impl State for PolygonEditor {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some(cursor) = ctx.canvas.get_cursor_in_map_space() {
|
||||
|
@ -87,7 +87,7 @@ impl ScenarioManager {
|
||||
impl State for ScenarioManager {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -96,7 +96,7 @@ impl State for ScenarioManager {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
ctx.canvas_movement();
|
||||
|
@ -128,7 +128,7 @@ impl State for StoryMapEditor {
|
||||
Mode::Editing(idx, ref mut composite) => {
|
||||
ctx.canvas_movement();
|
||||
match composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
self.mode = Mode::View;
|
||||
self.redo_panel(ctx);
|
||||
@ -152,7 +152,7 @@ impl State for StoryMapEditor {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Mode::Freehand(None) => {
|
||||
@ -176,7 +176,7 @@ impl State for StoryMapEditor {
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
// TODO autosave
|
||||
return Transition::Pop;
|
||||
@ -264,7 +264,7 @@ impl State for StoryMapEditor {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
|
@ -60,7 +60,7 @@ fn make_select_composite(ctx: &mut EventCtx, app: &App, selector: &RoadSelector)
|
||||
impl State for BulkSelect {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Cancel" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -83,7 +83,7 @@ impl State for BulkSelect {
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
if self.selector.event(ctx, app, None) {
|
||||
self.composite = make_select_composite(ctx, app, &self.selector);
|
||||
}
|
||||
@ -164,7 +164,7 @@ impl State for BulkEdit {
|
||||
ctx.canvas_movement();
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Quit" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -192,7 +192,7 @@ impl State for BulkEdit {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
|
@ -36,13 +36,13 @@ impl ClusterTrafficSignalEditor {
|
||||
impl State for ClusterTrafficSignalEditor {
|
||||
fn event(&mut self, ctx: &mut EventCtx, _: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Finish" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
ctx.canvas_movement();
|
||||
|
@ -140,7 +140,7 @@ impl State for LaneEditor {
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Change access restrictions" => {
|
||||
return Transition::Push(ZoneEditor::new(
|
||||
ctx,
|
||||
@ -197,7 +197,7 @@ impl State for LaneEditor {
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
let parent = app.primary.map.get_parent(self.l);
|
||||
let new = self.composite.dropdown_value("speed limit");
|
||||
let old = parent.speed_limit;
|
||||
|
@ -159,7 +159,7 @@ impl State for EditMode {
|
||||
}
|
||||
|
||||
match self.top_center.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"bulk edit" => {
|
||||
return Transition::Push(bulk::BulkSelect::new(ctx, app));
|
||||
}
|
||||
@ -168,10 +168,10 @@ impl State for EditMode {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
match self.changelist.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"load edits" => {
|
||||
if app.primary.map.unsaved_edits() {
|
||||
return Transition::PushTwice(
|
||||
@ -224,7 +224,7 @@ impl State for EditMode {
|
||||
));
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
// Just kind of constantly scrape this
|
||||
app.opts.resume_after_edit = self.top_center.persistent_split_value("finish editing");
|
||||
@ -347,7 +347,7 @@ impl SaveEdits {
|
||||
impl State for SaveEdits {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Save" | "Overwrite existing edits" => {
|
||||
let mut edits = app.primary.map.get_edits().clone();
|
||||
edits.edits_name = self.current_name.clone();
|
||||
@ -369,7 +369,7 @@ impl State for SaveEdits {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
let name = self.composite.text_box("filename");
|
||||
if name != self.current_name {
|
||||
@ -442,7 +442,7 @@ impl LoadEdits {
|
||||
impl State for LoadEdits {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => Transition::Pop,
|
||||
"Start over with blank edits" => {
|
||||
apply_map_edits(ctx, app, MapEdits::new());
|
||||
@ -489,7 +489,7 @@ impl State for LoadEdits {
|
||||
}
|
||||
}
|
||||
},
|
||||
None => Transition::Keep,
|
||||
_ => Transition::Keep,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ impl RoadSelector {
|
||||
self.preview = Some(ctx.upload(batch));
|
||||
}
|
||||
|
||||
// Pass it Outcome::Clicked. Returns true if anything changed.
|
||||
// Pass None. Returns true if anything changed.
|
||||
pub fn event(&mut self, ctx: &mut EventCtx, app: &mut App, clicked: Option<&str>) -> bool {
|
||||
if ctx.redo_mouseover() {
|
||||
app.primary.current_selection = app.calculate_current_selection(
|
||||
|
@ -116,7 +116,7 @@ impl State for StopSignEditor {
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Finish" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -178,7 +178,7 @@ impl State for StopSignEditor {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
Transition::Keep
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ impl State for TrafficSignalEditor {
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Edit entire signal" => {
|
||||
return Transition::Push(edit_entire_signal(
|
||||
app,
|
||||
@ -178,7 +178,7 @@ impl State for TrafficSignalEditor {
|
||||
unreachable!()
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if ctx.redo_mouseover() {
|
||||
@ -237,7 +237,7 @@ impl State for TrafficSignalEditor {
|
||||
}
|
||||
|
||||
match self.top_panel.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Finish" => {
|
||||
if let Some(orig) = self.command_stack.get(0) {
|
||||
return check_for_missing_groups(ctx, app, &mut self.composite, orig);
|
||||
@ -281,7 +281,7 @@ impl State for TrafficSignalEditor {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
@ -814,14 +814,14 @@ impl State for PreviewTrafficSignal {
|
||||
ctx.canvas_movement();
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"back to editing" => {
|
||||
app.primary.clear_sim();
|
||||
return Transition::Pop;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
self.time_panel.event(ctx, app);
|
||||
|
@ -74,7 +74,7 @@ impl ZoneEditor {
|
||||
impl State for ZoneEditor {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Apply" => {
|
||||
let mut edits = app.primary.map.get_edits().clone();
|
||||
for r in self.orig_members.difference(&self.selector.roads) {
|
||||
@ -123,7 +123,7 @@ impl State for ZoneEditor {
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
if self.selector.event(ctx, app, None) {
|
||||
let new_controls = self.selector.make_controls(ctx).named("selector");
|
||||
self.composite.replace(ctx, "selector", new_controls);
|
||||
|
@ -461,7 +461,7 @@ impl InfoPanel {
|
||||
|
||||
let maybe_id = self.tab.to_id(app);
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(action)) => {
|
||||
Outcome::Clicked(action) => {
|
||||
if let Some(new_tab) = self.hyperlinks.get(&action).cloned() {
|
||||
let mut new = InfoPanel::new(ctx, app, new_tab, ctx_actions);
|
||||
// TODO Most cases use changed_settings, but one doesn't. Detect that
|
||||
@ -560,7 +560,7 @@ impl InfoPanel {
|
||||
(close_panel, Some(t))
|
||||
}
|
||||
}
|
||||
None => {
|
||||
_ => {
|
||||
// Maybe a non-click action should change the tab. Aka, checkboxes/dropdowns/etc on
|
||||
// a tab.
|
||||
if let Some(new_tab) = self.tab.changed_settings(&self.composite) {
|
||||
|
@ -37,11 +37,11 @@ impl dyn Layer {
|
||||
) -> Option<LayerOutcome> {
|
||||
composite.align_above(ctx, minimap);
|
||||
match composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => Some(LayerOutcome::Close),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => None,
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -145,7 +145,7 @@ impl PickLayer {
|
||||
impl State for PickLayer {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {}
|
||||
"None" => {
|
||||
app.layer = None;
|
||||
@ -211,7 +211,7 @@ impl State for PickLayer {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
if self.composite.clicked_outside(ctx) {
|
||||
return Transition::Pop;
|
||||
}
|
||||
|
@ -37,13 +37,13 @@ impl Layer for Pandemic {
|
||||
|
||||
self.composite.align_above(ctx, minimap);
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Some(LayerOutcome::Close);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
let new_opts = self.options();
|
||||
if self.opts != new_opts {
|
||||
*self = Pandemic::new(ctx, app, new_opts);
|
||||
|
@ -45,13 +45,13 @@ impl Layer for Occupancy {
|
||||
|
||||
self.composite.align_above(ctx, minimap);
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Some(LayerOutcome::Close);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
let new_onstreet = self.composite.is_checked("On-street spots");
|
||||
let new_garages = self.composite.is_checked("Public garages");
|
||||
let new_lots = self.composite.is_checked("Parking lots");
|
||||
|
@ -37,13 +37,13 @@ impl Layer for PopulationMap {
|
||||
|
||||
self.composite.align_above(ctx, minimap);
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Some(LayerOutcome::Close);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
let new_opts = self.options();
|
||||
if self.opts != new_opts {
|
||||
*self = PopulationMap::new(ctx, app, new_opts);
|
||||
|
@ -126,13 +126,13 @@ impl Layer for Throughput {
|
||||
|
||||
self.composite.align_above(ctx, minimap);
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Some(LayerOutcome::Close);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
let new_compare = self
|
||||
.composite
|
||||
.maybe_is_checked("Compare before edits")
|
||||
@ -307,13 +307,13 @@ impl Layer for Delay {
|
||||
|
||||
self.composite.align_above(ctx, minimap);
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Some(LayerOutcome::Close);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
let new_compare = self
|
||||
.composite
|
||||
.maybe_is_checked("Compare before edits")
|
||||
|
@ -28,13 +28,13 @@ impl Layer for TransitNetwork {
|
||||
) -> Option<LayerOutcome> {
|
||||
self.composite.align_above(ctx, minimap);
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Some(LayerOutcome::Close);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
let new_show_all_routes = self.composite.is_checked("show all routes");
|
||||
let new_show_buses = self.composite.is_checked("show buses");
|
||||
let new_show_trains = self.composite.is_checked("show trains");
|
||||
|
@ -36,7 +36,7 @@ impl WrappedComposite {
|
||||
}
|
||||
|
||||
pub fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Option<WrappedOutcome> {
|
||||
match self.inner.event(ctx)? {
|
||||
match self.inner.event(ctx) {
|
||||
Outcome::Clicked(x) => {
|
||||
if let Some(ref cb) = self.callbacks.get(&x) {
|
||||
let t = (cb)(ctx, app)?;
|
||||
@ -45,6 +45,7 @@ impl WrappedComposite {
|
||||
Some(WrappedOutcome::Clicked(x))
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,7 +214,7 @@ impl OptionsPanel {
|
||||
impl State for OptionsPanel {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -266,7 +266,7 @@ impl State for OptionsPanel {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
|
@ -59,13 +59,13 @@ impl TitleScreen {
|
||||
impl State for TitleScreen {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"start game" => {
|
||||
return Transition::Replace(MainMenu::new(ctx, app));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
self.screensaver.update(&mut self.rng, ctx, app);
|
||||
@ -169,7 +169,7 @@ impl MainMenu {
|
||||
impl State for MainMenu {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"quit" => {
|
||||
// TODO before_quit?
|
||||
std::process::exit(0);
|
||||
@ -226,7 +226,7 @@ impl State for MainMenu {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
@ -297,7 +297,7 @@ impl About {
|
||||
impl State for About {
|
||||
fn event(&mut self, ctx: &mut EventCtx, _: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"back" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -310,7 +310,7 @@ impl State for About {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
@ -409,7 +409,7 @@ impl Proposals {
|
||||
impl State for Proposals {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"back" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -462,7 +462,7 @@ impl State for Proposals {
|
||||
return Transition::Replace(Proposals::new(ctx, app, Some(x.to_string())));
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
|
@ -341,13 +341,13 @@ impl State for CommuterPatterns {
|
||||
ctx.canvas_movement();
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let block_selection = if let Some(Some(b)) = ctx
|
||||
|
@ -49,8 +49,8 @@ impl ActiveTraffic {
|
||||
impl State for ActiveTraffic {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => DashTab::TripSummaries.transition(ctx, app, &x),
|
||||
None => Transition::Keep,
|
||||
Outcome::Clicked(x) => DashTab::TripSummaries.transition(ctx, app, &x),
|
||||
_ => Transition::Keep,
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,14 +155,14 @@ impl TransitRoutes {
|
||||
impl State for TransitRoutes {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
let route = match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => {
|
||||
Outcome::Clicked(x) => {
|
||||
if let Some(x) = x.strip_prefix("BusRoute #") {
|
||||
BusRouteID(x.parse::<usize>().unwrap())
|
||||
} else {
|
||||
return DashTab::TransitRoutes.transition(ctx, app, &x);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
_ => {
|
||||
if let Some(routes) = self.composite.autocomplete_done("search") {
|
||||
if !routes.is_empty() {
|
||||
routes[0]
|
||||
|
@ -77,7 +77,7 @@ impl ParkingOverhead {
|
||||
impl State for ParkingOverhead {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Total duration" => {
|
||||
self.opts.change(SortBy::TotalDuration);
|
||||
self.recalc(ctx, app);
|
||||
@ -124,7 +124,7 @@ impl State for ParkingOverhead {
|
||||
return DashTab::ParkingOverhead.transition(ctx, app, x);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
let off_map_starts = self.composite.is_checked("starting off-map");
|
||||
let off_map_ends = self.composite.is_checked("ending off-map");
|
||||
if self.opts.off_map_starts != off_map_starts
|
||||
|
@ -54,8 +54,8 @@ impl TripSummaries {
|
||||
impl State for TripSummaries {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => DashTab::TripSummaries.transition(ctx, app, &x),
|
||||
None => {
|
||||
Outcome::Clicked(x) => DashTab::TripSummaries.transition(ctx, app, &x),
|
||||
_ => {
|
||||
let mut filter = Filter {
|
||||
changes_pct: self.composite.dropdown_value("filter"),
|
||||
modes: BTreeSet::new(),
|
||||
|
@ -84,7 +84,7 @@ impl TripTable {
|
||||
impl State for TripTable {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Departure" => {
|
||||
self.opts.change(SortBy::Departure);
|
||||
self.recalc(ctx, app);
|
||||
@ -135,7 +135,7 @@ impl State for TripTable {
|
||||
return DashTab::TripTable.transition(ctx, app, x);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
let mut modes = BTreeSet::new();
|
||||
for m in TripMode::all() {
|
||||
if self.composite.is_checked(m.ongoing_verb()) {
|
||||
|
@ -167,7 +167,7 @@ impl GameplayState for OptimizeCommute {
|
||||
}
|
||||
|
||||
match self.top_center.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"edit map" => {
|
||||
return Some(Transition::Push(Box::new(EditMode::new(
|
||||
ctx,
|
||||
@ -191,10 +191,10 @@ impl GameplayState for OptimizeCommute {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
match self.meter.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"locate VIP" => {
|
||||
controls.common.as_mut().unwrap().launch_info_panel(
|
||||
ctx,
|
||||
@ -207,7 +207,7 @@ impl GameplayState for OptimizeCommute {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
None
|
||||
|
@ -191,7 +191,7 @@ impl GameplayState for FixTrafficSignals {
|
||||
}
|
||||
|
||||
match self.top_center.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"edit map" => {
|
||||
return Some(Transition::Push(Box::new(EditMode::new(
|
||||
ctx,
|
||||
@ -228,10 +228,10 @@ impl GameplayState for FixTrafficSignals {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
match self.meter.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"go to slowest intersection" => {
|
||||
let i = app
|
||||
.primary
|
||||
@ -268,7 +268,7 @@ impl GameplayState for FixTrafficSignals {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
None
|
||||
|
@ -43,7 +43,7 @@ impl GameplayState for Freeform {
|
||||
_: &mut SandboxControls,
|
||||
) -> Option<Transition> {
|
||||
match self.top_center.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"change map" => {
|
||||
Some(Transition::Push(CityPicker::new(
|
||||
ctx,
|
||||
@ -71,7 +71,7 @@ impl GameplayState for Freeform {
|
||||
"Start a new trip" => Some(Transition::Push(AgentSpawner::new(ctx, None))),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => None,
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,7 +242,7 @@ impl State for AgentSpawner {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
let old_mode: TripMode = self.composite.dropdown_value("mode");
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -278,7 +278,7 @@ impl State for AgentSpawner {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
// We need to recalculate the path to see if this is sane. Otherwise we could trick a
|
||||
// pedestrian into wandering on/off a highway border.
|
||||
|
@ -355,7 +355,7 @@ impl FinalScore {
|
||||
impl State for FinalScore {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Keep simulating" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -392,7 +392,7 @@ impl State for FinalScore {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if self.chose_next || self.chose_back_to_challenges {
|
||||
|
@ -48,7 +48,7 @@ impl GameplayState for PlayScenario {
|
||||
app.primary.has_modified_trips = !self.modifiers.is_empty();
|
||||
|
||||
match self.top_center.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"change map" => {
|
||||
let scenario = self.scenario_name.clone();
|
||||
Some(Transition::Push(CityPicker::new(
|
||||
@ -90,7 +90,7 @@ impl GameplayState for PlayScenario {
|
||||
))),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => None,
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,7 +214,7 @@ impl EditScenarioModifiers {
|
||||
impl State for EditScenarioModifiers {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Discard changes" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -256,7 +256,7 @@ impl State for EditScenarioModifiers {
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
@ -357,7 +357,7 @@ impl ChangeMode {
|
||||
impl State for ChangeMode {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Discard changes" => Transition::Pop,
|
||||
"Apply" => {
|
||||
let to_mode = self.composite.dropdown_value::<TripMode>("to_mode");
|
||||
@ -404,7 +404,7 @@ impl State for ChangeMode {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => Transition::Keep,
|
||||
_ => Transition::Keep,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ impl Tutorial {
|
||||
}
|
||||
|
||||
match self.top_center.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"Quit" => {
|
||||
return Some(maybe_exit_sandbox());
|
||||
}
|
||||
@ -128,12 +128,12 @@ impl Tutorial {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some(ref mut msg) = self.msg_panel {
|
||||
match msg.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"previous message" => {
|
||||
tut.prev();
|
||||
return Some(transition(ctx, app, tut));
|
||||
@ -144,7 +144,7 @@ impl Tutorial {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
// Don't allow other interactions
|
||||
return Some(Transition::Keep);
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ impl State for ShowTrafficSignal {
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -112,7 +112,7 @@ impl State for ShowTrafficSignal {
|
||||
self.change_phase(x["phase ".len()..].parse::<usize>().unwrap() - 1, ctx, app);
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
@ -164,7 +164,7 @@ impl State for TurnExplorer {
|
||||
ctx.canvas_movement();
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -178,7 +178,7 @@ impl State for TurnExplorer {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
|
@ -373,13 +373,13 @@ impl AgentMeter {
|
||||
return self.event(ctx, app);
|
||||
}
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"more data" => {
|
||||
return Some(Transition::Push(dashboards::TripTable::new(ctx, app)));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
None
|
||||
|
@ -144,7 +144,7 @@ impl SpeedControls {
|
||||
maybe_mode: Option<&GameplayMode>,
|
||||
) -> Option<Transition> {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"real-time speed" => {
|
||||
self.setting = SpeedSetting::Realtime;
|
||||
self.composite = SpeedControls::make_panel(ctx, app, self.paused, self.setting);
|
||||
@ -212,7 +212,7 @@ impl SpeedControls {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
// Just kind of constantly scrape this
|
||||
app.opts.time_increment = self.composite.persistent_split_value("step forwards");
|
||||
@ -420,7 +420,7 @@ impl JumpToTime {
|
||||
impl State for JumpToTime {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -450,7 +450,7 @@ impl State for JumpToTime {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
app.opts.dont_draw_time_warp = self.composite.is_checked("don't draw");
|
||||
let target = app
|
||||
@ -612,13 +612,13 @@ impl State for TimeWarpScreen {
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"stop now" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
if self.composite.clicked_outside(ctx) {
|
||||
return Transition::Pop;
|
||||
|
@ -65,7 +65,7 @@ impl State for UberTurnPicker {
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -105,7 +105,7 @@ impl State for UberTurnPicker {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
@ -214,7 +214,7 @@ impl State for UberTurnViewer {
|
||||
ctx.canvas_movement();
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
@ -238,7 +238,7 @@ impl State for UberTurnViewer {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
if self.composite.is_checked("legal / illegal movements") != self.legal_turns {
|
||||
return Transition::Replace(UberTurnViewer::new(
|
||||
ctx,
|
||||
|
@ -250,7 +250,7 @@ impl GUI for UI {
|
||||
}
|
||||
None => {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"quit" => {
|
||||
self.before_quit(ctx.canvas);
|
||||
std::process::exit(0);
|
||||
@ -285,7 +285,7 @@ impl GUI for UI {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {
|
||||
_ => {
|
||||
if ctx.input.key_pressed(Key::I, "create intersection") {
|
||||
if let Some(pt) = cursor {
|
||||
self.model.create_i(pt, ctx.prerender);
|
||||
|
Loading…
Reference in New Issue
Block a user