mirror of
https://github.com/a-b-street/abstreet.git
synced 2025-01-02 03:18:55 +03:00
starting an options panel, with a way to toggle traffic signal rendering style
This commit is contained in:
parent
7ddd9cb277
commit
3fc4684fec
@ -3,6 +3,7 @@ pub mod setup;
|
||||
use crate::common::{AgentTools, CommonState};
|
||||
use crate::debug::DebugMode;
|
||||
use crate::game::{State, Transition};
|
||||
use crate::options;
|
||||
use crate::render::MIN_ZOOM_FOR_DETAIL;
|
||||
use crate::ui::{PerMapUI, UI};
|
||||
use abstutil::Timer;
|
||||
@ -52,6 +53,7 @@ impl ABTestMode {
|
||||
(hotkey(Key::Escape), "quit"),
|
||||
(lctrl(Key::D), "debug mode"),
|
||||
(hotkey(Key::F1), "take a screenshot"),
|
||||
(None, "options"),
|
||||
],
|
||||
0.2,
|
||||
ctx,
|
||||
@ -130,6 +132,9 @@ impl State for ABTestMode {
|
||||
if self.general_tools.action("take a screenshot") {
|
||||
return Transition::KeepWithMode(EventLoopMode::ScreenCaptureCurrentShot);
|
||||
}
|
||||
if self.general_tools.action("options") {
|
||||
return Transition::Push(options::open_panel());
|
||||
}
|
||||
|
||||
if self.menu.action("swap") {
|
||||
let secondary = ui.secondary.take().unwrap();
|
||||
|
@ -10,6 +10,7 @@ mod routes;
|
||||
use crate::common::CommonState;
|
||||
use crate::game::{msg, State, Transition, WizardState};
|
||||
use crate::helpers::ID;
|
||||
use crate::options;
|
||||
use crate::render::MIN_ZOOM_FOR_DETAIL;
|
||||
use crate::ui::{ShowLayers, ShowObject, UI};
|
||||
use abstutil::Timer;
|
||||
@ -60,6 +61,7 @@ impl DebugMode {
|
||||
vec![
|
||||
(hotkey(Key::Escape), "return to previous mode"),
|
||||
(hotkey(Key::F1), "take a screenshot"),
|
||||
(None, "options"),
|
||||
],
|
||||
0.2,
|
||||
ctx,
|
||||
@ -121,6 +123,9 @@ impl State for DebugMode {
|
||||
if self.general_tools.action("take a screenshot") {
|
||||
return Transition::KeepWithMode(EventLoopMode::ScreenCaptureCurrentShot);
|
||||
}
|
||||
if self.general_tools.action("options") {
|
||||
return Transition::Push(options::open_panel());
|
||||
}
|
||||
|
||||
self.all_routes.event(ui, &mut self.menu, ctx);
|
||||
match ui.primary.current_selection {
|
||||
|
@ -6,6 +6,7 @@ use crate::common::{CommonState, Warping};
|
||||
use crate::debug::DebugMode;
|
||||
use crate::game::{State, Transition, WizardState};
|
||||
use crate::helpers::{ColorScheme, ID};
|
||||
use crate::options;
|
||||
use crate::render::{
|
||||
DrawIntersection, DrawLane, DrawOptions, DrawRoad, Renderable, MIN_ZOOM_FOR_DETAIL,
|
||||
};
|
||||
@ -53,6 +54,7 @@ impl EditMode {
|
||||
vec![
|
||||
(lctrl(Key::D), "debug mode"),
|
||||
(hotkey(Key::F1), "take a screenshot"),
|
||||
(None, "options"),
|
||||
],
|
||||
0.2,
|
||||
ctx,
|
||||
@ -169,6 +171,9 @@ impl State for EditMode {
|
||||
if self.general_tools.action("take a screenshot") {
|
||||
return Transition::KeepWithMode(EventLoopMode::ScreenCaptureCurrentShot);
|
||||
}
|
||||
if self.general_tools.action("options") {
|
||||
return Transition::Push(options::open_panel());
|
||||
}
|
||||
|
||||
if ui.primary.map.get_edits().dirty && self.menu.action("save edits") {
|
||||
return Transition::Push(WizardState::new(Box::new(|wiz, ctx, ui| {
|
||||
|
@ -7,6 +7,7 @@ mod game;
|
||||
mod helpers;
|
||||
mod managed;
|
||||
mod mission;
|
||||
mod options;
|
||||
mod pregame;
|
||||
mod render;
|
||||
mod sandbox;
|
||||
|
@ -2,6 +2,7 @@ use crate::common::{CommonState, ObjectColorer, ObjectColorerBuilder, Warping};
|
||||
use crate::game::{State, Transition, WizardState};
|
||||
use crate::helpers::ID;
|
||||
use crate::mission::pick_time_range;
|
||||
use crate::options;
|
||||
use crate::sandbox::{GameplayMode, SandboxMode};
|
||||
use crate::ui::{ShowEverything, UI};
|
||||
use abstutil::{prettyprint_usize, Counter, MultiMap, WeightedUsizeChoice};
|
||||
@ -129,6 +130,7 @@ impl ScenarioManager {
|
||||
vec![
|
||||
(hotkey(Key::Escape), "quit"),
|
||||
(hotkey(Key::F1), "take a screenshot"),
|
||||
(None, "options"),
|
||||
],
|
||||
0.2,
|
||||
ctx,
|
||||
@ -182,6 +184,8 @@ impl State for ScenarioManager {
|
||||
return Transition::Pop;
|
||||
} else if self.general_tools.action("take a screenshot") {
|
||||
return Transition::KeepWithMode(EventLoopMode::ScreenCaptureCurrentShot);
|
||||
} else if self.general_tools.action("options") {
|
||||
return Transition::Push(options::open_panel());
|
||||
} else if self.menu.action("save") {
|
||||
self.scenario.save();
|
||||
} else if self.menu.action("edit") {
|
||||
|
53
game/src/options.rs
Normal file
53
game/src/options.rs
Normal file
@ -0,0 +1,53 @@
|
||||
use crate::game::{State, Transition, WizardState};
|
||||
use ezgui::Choice;
|
||||
|
||||
pub struct Options {
|
||||
pub traffic_signal_style: TrafficSignalStyle,
|
||||
}
|
||||
|
||||
impl Options {
|
||||
pub fn default() -> Options {
|
||||
Options {
|
||||
traffic_signal_style: TrafficSignalStyle::GroupArrows,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub enum TrafficSignalStyle {
|
||||
GroupArrows,
|
||||
Icons,
|
||||
IndividualTurnArrows,
|
||||
}
|
||||
impl abstutil::Cloneable for TrafficSignalStyle {}
|
||||
|
||||
pub fn open_panel() -> Box<dyn State> {
|
||||
WizardState::new(Box::new(move |wiz, ctx, ui| {
|
||||
let mut wizard = wiz.wrap(ctx);
|
||||
let (_, traffic_signal_style) =
|
||||
wizard.choose("How should traffic signals be drawn?", || {
|
||||
vec![
|
||||
Choice::new(
|
||||
"arrows showing the protected and permitted movements",
|
||||
TrafficSignalStyle::GroupArrows,
|
||||
),
|
||||
Choice::new(
|
||||
"icons for movements (like the editor UI)",
|
||||
TrafficSignalStyle::Icons,
|
||||
),
|
||||
Choice::new(
|
||||
"arrows showing individual turns (to debug)",
|
||||
TrafficSignalStyle::IndividualTurnArrows,
|
||||
),
|
||||
]
|
||||
})?;
|
||||
if ui.opts.traffic_signal_style != traffic_signal_style {
|
||||
ui.opts.traffic_signal_style = traffic_signal_style;
|
||||
println!("Rerendering traffic signals...");
|
||||
for i in ui.primary.draw_map.intersections.iter_mut() {
|
||||
*i.draw_traffic_signal.borrow_mut() = None;
|
||||
}
|
||||
}
|
||||
Some(Transition::Pop)
|
||||
}))
|
||||
}
|
@ -18,7 +18,7 @@ pub struct DrawIntersection {
|
||||
zorder: isize,
|
||||
|
||||
draw_default: Drawable,
|
||||
draw_traffic_signal: RefCell<Option<(Drawable, Time)>>,
|
||||
pub draw_traffic_signal: RefCell<Option<(Drawable, Time)>>,
|
||||
// Only for traffic signals
|
||||
pub crosswalks: Vec<(TurnID, GeomBatch)>,
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ mod traffic_signal;
|
||||
mod turn;
|
||||
|
||||
use crate::helpers::{ColorScheme, ID};
|
||||
use crate::options::Options;
|
||||
pub use crate::render::area::DrawArea;
|
||||
use crate::render::bike::DrawBike;
|
||||
use crate::render::car::DrawCar;
|
||||
@ -103,6 +104,7 @@ pub struct DrawCtx<'a> {
|
||||
pub map: &'a Map,
|
||||
pub draw_map: &'a DrawMap,
|
||||
pub sim: &'a Sim,
|
||||
pub opts: &'a Options,
|
||||
}
|
||||
|
||||
// TODO Borrow, don't clone, and fix up lots of places storing indirect things to populate
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::options::TrafficSignalStyle;
|
||||
use crate::render::{DrawCtx, DrawTurnGroup, BIG_ARROW_THICKNESS};
|
||||
use crate::ui::UI;
|
||||
use ezgui::{
|
||||
@ -30,60 +31,25 @@ pub fn draw_signal_phase(
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Live settings panel to toggle between these 3 styles
|
||||
if true {
|
||||
for g in DrawTurnGroup::for_i(i, ctx.map) {
|
||||
batch.push(ctx.cs.get("turn block background"), g.block.clone());
|
||||
let arrow_color = match phase.get_priority_of_group(g.id) {
|
||||
TurnPriority::Protected => ctx.cs.get("turn protected by traffic signal"),
|
||||
TurnPriority::Yield => ctx
|
||||
.cs
|
||||
.get("turn that can yield by traffic signal")
|
||||
.alpha(1.0),
|
||||
TurnPriority::Banned => ctx.cs.get("turn not in current phase"),
|
||||
};
|
||||
batch.push(arrow_color, g.arrow.clone());
|
||||
}
|
||||
} else if true {
|
||||
for g in &phase.protected_groups {
|
||||
if g.crosswalk.is_none() {
|
||||
batch.push(
|
||||
protected_color,
|
||||
signal.turn_groups[g]
|
||||
.geom
|
||||
.make_arrow(BIG_ARROW_THICKNESS * 2.0)
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
}
|
||||
for g in &phase.yield_groups {
|
||||
if g.crosswalk.is_none() {
|
||||
batch.extend(
|
||||
yield_color,
|
||||
signal.turn_groups[g]
|
||||
.geom
|
||||
.make_arrow_outline(BIG_ARROW_THICKNESS * 2.0, BIG_ARROW_THICKNESS / 2.0)
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// For debugging, can still show individual turns
|
||||
for turn in ctx.map.get_turns_in_intersection(i) {
|
||||
if turn.between_sidewalks() {
|
||||
continue;
|
||||
}
|
||||
match phase.get_priority_of_turn(turn.id, signal) {
|
||||
TurnPriority::Protected => {
|
||||
match ctx.opts.traffic_signal_style {
|
||||
TrafficSignalStyle::GroupArrows => {
|
||||
for g in &phase.protected_groups {
|
||||
if g.crosswalk.is_none() {
|
||||
batch.push(
|
||||
protected_color,
|
||||
turn.geom.make_arrow(BIG_ARROW_THICKNESS * 2.0).unwrap(),
|
||||
signal.turn_groups[g]
|
||||
.geom
|
||||
.make_arrow(BIG_ARROW_THICKNESS * 2.0)
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
TurnPriority::Yield => {
|
||||
}
|
||||
for g in &phase.yield_groups {
|
||||
if g.crosswalk.is_none() {
|
||||
batch.extend(
|
||||
yield_color,
|
||||
turn.geom
|
||||
signal.turn_groups[g]
|
||||
.geom
|
||||
.make_arrow_outline(
|
||||
BIG_ARROW_THICKNESS * 2.0,
|
||||
BIG_ARROW_THICKNESS / 2.0,
|
||||
@ -91,7 +57,47 @@ pub fn draw_signal_phase(
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
TurnPriority::Banned => {}
|
||||
}
|
||||
}
|
||||
TrafficSignalStyle::Icons => {
|
||||
for g in DrawTurnGroup::for_i(i, ctx.map) {
|
||||
batch.push(ctx.cs.get("turn block background"), g.block.clone());
|
||||
let arrow_color = match phase.get_priority_of_group(g.id) {
|
||||
TurnPriority::Protected => ctx.cs.get("turn protected by traffic signal"),
|
||||
TurnPriority::Yield => ctx
|
||||
.cs
|
||||
.get("turn that can yield by traffic signal")
|
||||
.alpha(1.0),
|
||||
TurnPriority::Banned => ctx.cs.get("turn not in current phase"),
|
||||
};
|
||||
batch.push(arrow_color, g.arrow.clone());
|
||||
}
|
||||
}
|
||||
TrafficSignalStyle::IndividualTurnArrows => {
|
||||
for turn in ctx.map.get_turns_in_intersection(i) {
|
||||
if turn.between_sidewalks() {
|
||||
continue;
|
||||
}
|
||||
match phase.get_priority_of_turn(turn.id, signal) {
|
||||
TurnPriority::Protected => {
|
||||
batch.push(
|
||||
protected_color,
|
||||
turn.geom.make_arrow(BIG_ARROW_THICKNESS * 2.0).unwrap(),
|
||||
);
|
||||
}
|
||||
TurnPriority::Yield => {
|
||||
batch.extend(
|
||||
yield_color,
|
||||
turn.geom
|
||||
.make_arrow_outline(
|
||||
BIG_ARROW_THICKNESS * 2.0,
|
||||
BIG_ARROW_THICKNESS / 2.0,
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
TurnPriority::Banned => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ use crate::edit::EditMode;
|
||||
use crate::edit::{apply_map_edits, save_edits};
|
||||
use crate::game::{msg, State, Transition, WizardState};
|
||||
use crate::helpers::ID;
|
||||
use crate::options;
|
||||
use crate::pregame::main_menu;
|
||||
use crate::ui::{ShowEverything, UI};
|
||||
use abstutil::Timer;
|
||||
@ -48,6 +49,7 @@ impl SandboxMode {
|
||||
(hotkey(Key::Escape), "back to title screen"),
|
||||
(lctrl(Key::D), "debug mode"),
|
||||
(hotkey(Key::F1), "take a screenshot"),
|
||||
(None, "options"),
|
||||
],
|
||||
0.3,
|
||||
ctx,
|
||||
@ -211,6 +213,9 @@ impl State for SandboxMode {
|
||||
if self.general_tools.action("take a screenshot") {
|
||||
return Transition::KeepWithMode(EventLoopMode::ScreenCaptureCurrentShot);
|
||||
}
|
||||
if self.general_tools.action("options") {
|
||||
return Transition::Push(options::open_panel());
|
||||
}
|
||||
|
||||
if let Some(ID::Building(b)) = ui.primary.current_selection {
|
||||
let cars = ui
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::helpers::{ColorScheme, ID};
|
||||
use crate::options::Options;
|
||||
use crate::render::{
|
||||
draw_vehicle, AgentCache, AgentColorScheme, DrawCtx, DrawMap, DrawOptions, DrawPedCrowd,
|
||||
DrawPedestrian, Renderable, MIN_ZOOM_FOR_DETAIL,
|
||||
@ -17,6 +18,7 @@ pub struct UI {
|
||||
pub cs: ColorScheme,
|
||||
pub agent_cs: AgentColorScheme,
|
||||
pub prebaked: Analytics,
|
||||
pub opts: Options,
|
||||
}
|
||||
|
||||
impl UI {
|
||||
@ -120,6 +122,7 @@ impl UI {
|
||||
cs,
|
||||
agent_cs: AgentColorScheme::VehicleTypes,
|
||||
prebaked,
|
||||
opts: Options::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,6 +139,7 @@ impl UI {
|
||||
map: &self.primary.map,
|
||||
draw_map: &self.primary.draw_map,
|
||||
sim: &self.primary.sim,
|
||||
opts: &self.opts,
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user