simplify TurnCyclerState, only use it in sandbox mode. prep for cleaning up context-sensitive actions

This commit is contained in:
Dustin Carlino 2020-03-28 11:41:24 -07:00
parent 8288a4b6af
commit dd9b43c990
4 changed files with 83 additions and 82 deletions

View File

@ -12,87 +12,83 @@ use geom::{Distance, Polygon, Time};
use map_model::{IntersectionID, LaneID, TurnType};
use sim::{AgentID, DontDrawAgents};
// TODO Misnomer. Kind of just handles temporary hovering things now.
pub enum TurnCyclerState {
Inactive,
ShowRoute(AgentID, Time, Drawable),
pub struct RoutePreview {
preview: Option<(AgentID, Time, Drawable)>,
}
impl TurnCyclerState {
impl RoutePreview {
pub fn new() -> RoutePreview {
RoutePreview { preview: None }
}
}
impl RoutePreview {
pub fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Option<Transition> {
match app.primary.current_selection {
Some(ID::Lane(id)) if !app.primary.map.get_turns_from_lane(id).is_empty() => {
if app
if let Some(ID::Lane(id)) = app.primary.current_selection {
if !app.primary.map.get_turns_from_lane(id).is_empty()
&& app
.per_obj
.action(ctx, Key::Z, "explore turns from this lane")
{
return Some(Transition::Push(Box::new(TurnExplorer {
l: id,
idx: 0,
composite: TurnExplorer::make_panel(ctx, app, id, 0),
})));
}
} else if let Some(ID::Intersection(i)) = app.primary.current_selection {
if let Some(ref signal) = app.primary.map.maybe_get_traffic_signal(i) {
if app
.per_obj
.action(ctx, Key::F, "explore traffic signal details")
{
return Some(Transition::Push(Box::new(TurnExplorer {
l: id,
idx: 0,
composite: TurnExplorer::make_panel(ctx, app, id, 0),
app.primary.current_selection = None;
let (idx, _, _) =
signal.current_phase_and_remaining_time(app.primary.sim.time());
return Some(Transition::Push(Box::new(ShowTrafficSignal {
i,
composite: make_signal_diagram(ctx, app, i, idx, false),
current_phase: idx,
})));
}
}
Some(ID::Intersection(i)) => {
if let Some(ref signal) = app.primary.map.maybe_get_traffic_signal(i) {
if app
.per_obj
.action(ctx, Key::F, "explore traffic signal details")
{
app.primary.current_selection = None;
let (idx, _, _) =
signal.current_phase_and_remaining_time(app.primary.sim.time());
return Some(Transition::Push(Box::new(ShowTrafficSignal {
i,
composite: make_signal_diagram(ctx, app, i, idx, false),
current_phase: idx,
})));
}
}
*self = TurnCyclerState::Inactive;
}
Some(ref id) => {
if let Some(agent) = id.agent_id() {
let now = app.primary.sim.time();
let recalc = match self {
TurnCyclerState::ShowRoute(a, t, _) => agent != *a || now != *t,
_ => true,
};
if recalc {
if let Some(trace) =
app.primary.sim.trace_route(agent, &app.primary.map, None)
{
let mut batch = GeomBatch::new();
batch.extend(
app.cs.get_def("route", Color::ORANGE.alpha(0.5)),
dashed_lines(
&trace,
Distance::meters(0.75),
Distance::meters(1.0),
Distance::meters(0.4),
),
);
*self = TurnCyclerState::ShowRoute(agent, now, batch.upload(ctx));
}
}
} else {
*self = TurnCyclerState::Inactive;
} else if let Some(agent) = app
.primary
.current_selection
.as_ref()
.and_then(|id| id.agent_id())
{
let now = app.primary.sim.time();
if self
.preview
.as_ref()
.map(|(a, t, _)| agent != *a || now != *t)
.unwrap_or(true)
{
if let Some(trace) = app.primary.sim.trace_route(agent, &app.primary.map, None) {
let mut batch = GeomBatch::new();
batch.extend(
app.cs.get_def("route", Color::ORANGE.alpha(0.5)),
dashed_lines(
&trace,
Distance::meters(0.75),
Distance::meters(1.0),
Distance::meters(0.4),
),
);
self.preview = Some((agent, now, batch.upload(ctx)));
}
}
_ => {
*self = TurnCyclerState::Inactive;
}
return None;
}
self.preview = None;
None
}
pub fn draw(&self, g: &mut GfxCtx, _: &App) {
match self {
TurnCyclerState::Inactive => {}
TurnCyclerState::ShowRoute(_, _, ref d) => {
g.redraw(d);
}
pub fn draw(&self, g: &mut GfxCtx) {
if let Some((_, _, ref d)) = self.preview {
g.redraw(d);
}
}
}

View File

@ -2,17 +2,18 @@ mod bus_explorer;
mod colors;
mod heatmap;
mod minimap;
mod misc_tools;
mod navigate;
mod overlays;
mod panels;
mod shortcuts;
mod turn_cycler;
mod warp;
pub use self::bus_explorer::ShowBusRoute;
pub use self::colors::{ColorLegend, Colorer};
pub use self::heatmap::{make_heatmap, HeatmapColors, HeatmapOptions};
pub use self::minimap::Minimap;
pub use self::misc_tools::RoutePreview;
pub use self::overlays::Overlays;
pub use self::panels::tool_panel;
pub use self::warp::Warping;
@ -29,16 +30,12 @@ use geom::Polygon;
use std::collections::BTreeSet;
pub struct CommonState {
turn_cycler: turn_cycler::TurnCyclerState,
info_panel: Option<InfoPanel>,
}
impl CommonState {
pub fn new() -> CommonState {
CommonState {
turn_cycler: turn_cycler::TurnCyclerState::Inactive,
info_panel: None,
}
CommonState { info_panel: None }
}
// This has to be called after anything that calls app.per_obj.action(). Oof.
@ -56,12 +53,6 @@ impl CommonState {
return Some(Transition::Push(warp::EnteringWarp::new()));
}
// TODO Disable unless gameplay.can_examine_objects. Not going to worry about this right
// now, since these controls should change anyway.
if let Some(t) = self.turn_cycler.event(ctx, app) {
return Some(t);
}
if let Some(ref id) = app.primary.current_selection {
if app.per_obj.action(ctx, Key::I, "show info")
|| app.per_obj.left_click(ctx, "show info")
@ -94,15 +85,14 @@ impl CommonState {
None
}
pub fn draw_no_osd(&self, g: &mut GfxCtx, app: &App) {
self.turn_cycler.draw(g, app);
pub fn draw_no_osd(&self, g: &mut GfxCtx) {
if let Some(ref info) = self.info_panel {
info.draw(g);
}
}
pub fn draw(&self, g: &mut GfxCtx, app: &App) {
self.draw_no_osd(g, app);
self.draw_no_osd(g);
CommonState::draw_osd(g, app, &app.primary.current_selection);
}

View File

@ -244,7 +244,7 @@ impl State for ScenarioManager {
}
self.composite.draw(g);
self.common.draw_no_osd(g, app);
self.common.draw_no_osd(g);
self.tool_panel.draw(g);
if let Some(ID::Building(b)) = app.primary.current_selection {

View File

@ -4,7 +4,7 @@ mod speed;
use crate::app::App;
use crate::colors;
use crate::common::{tool_panel, CommonState, Minimap, Overlays, ShowBusRoute};
use crate::common::{tool_panel, CommonState, Minimap, Overlays, RoutePreview, ShowBusRoute};
use crate::debug::DebugMode;
use crate::edit::{
apply_map_edits, can_edit_lane, save_edits_as, EditMode, LaneEditor, StopSignEditor,
@ -36,6 +36,7 @@ pub struct SandboxMode {
pub struct SandboxControls {
pub common: Option<CommonState>,
route_preview: Option<RoutePreview>,
tool_panel: Option<WrappedComposite>,
time_panel: Option<TimePanel>,
pub speed: Option<SpeedControls>,
@ -54,6 +55,11 @@ impl SandboxMode {
} else {
None
},
route_preview: if gameplay.can_examine_objects() {
Some(RoutePreview::new())
} else {
None
},
tool_panel: if gameplay.has_tool_panel() {
Some(tool_panel(ctx))
} else {
@ -220,6 +226,12 @@ impl State for SandboxMode {
}
}
if let Some(ref mut r) = self.controls.route_preview {
if let Some(t) = r.event(ctx, app) {
return t;
}
}
// Fragile ordering. Don't call this before all the per_obj actions have been called. But
// also let this work before tool_panel, so Key::Escape from the info panel beats the one
// to quit. And let speed update the sim before we update the info panel.
@ -289,6 +301,9 @@ impl State for SandboxMode {
if let Some(ref m) = self.controls.minimap {
m.draw(g, app);
}
if let Some(ref r) = self.controls.route_preview {
r.draw(g);
}
self.gameplay.draw(g, app);
}