starting an options panel, with a way to toggle traffic signal rendering style

This commit is contained in:
Dustin Carlino 2019-12-03 10:39:16 -08:00
parent 7ddd9cb277
commit 3fc4684fec
11 changed files with 140 additions and 50 deletions

View File

@ -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();

View File

@ -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 {

View File

@ -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| {

View File

@ -7,6 +7,7 @@ mod game;
mod helpers;
mod managed;
mod mission;
mod options;
mod pregame;
mod render;
mod sandbox;

View File

@ -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
View 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)
}))
}

View File

@ -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)>,
}

View File

@ -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

View File

@ -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 => {}
}
}
}
}

View File

@ -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

View File

@ -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,
}
}