mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 15:33:44 +03:00
simplify TurnCyclerState, only use it in sandbox mode. prep for cleaning up context-sensitive actions
This commit is contained in:
parent
8288a4b6af
commit
dd9b43c990
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user