Automatically toggle between day/night colorschemes at 6am and 6pm, if

you pass --day_night. Fails to update all panels immediately.
This commit is contained in:
Dustin Carlino 2020-11-10 08:33:44 -08:00
parent f30e1e2fff
commit a4dfa2f40a
4 changed files with 98 additions and 52 deletions

View File

@ -11,7 +11,7 @@ use sim::{Analytics, Scenario, Sim, SimCallback, SimFlags};
use widgetry::{Canvas, EventCtx, GfxCtx, Prerender, SharedAppState};
use crate::challenges::HighScore;
use crate::colors::ColorScheme;
use crate::colors::{ColorScheme, ColorSchemeChoice};
use crate::helpers::ID;
use crate::layer::Layer;
use crate::options::Options;
@ -427,6 +427,25 @@ impl App {
borrows
}
/// Change the color scheme. Idempotent. Return true if there was a change.
pub fn change_color_scheme(&mut self, ctx: &mut EventCtx, cs: ColorSchemeChoice) -> bool {
if self.opts.color_scheme == cs {
return false;
}
self.opts.color_scheme = cs;
self.cs = ColorScheme::new(self.opts.color_scheme);
ctx.set_style(self.cs.gui_style.clone());
ctx.loading_screen("rerendering map colors", |ctx, timer| {
let (draw_map, zorder_range) =
DrawMap::new(&self.primary.map, &self.opts, &self.cs, ctx, timer);
self.primary.draw_map = draw_map;
self.primary.zorder_range = zorder_range;
});
true
}
}
pub struct ShowLayers {

View File

@ -43,6 +43,10 @@ pub fn main(mut args: CmdArgs) {
if args.enabled("--lowzoom") {
opts.min_zoom_for_detail = 1.0;
}
if args.enabled("--day_night") {
opts.toggle_day_night_colors = true;
opts.color_scheme = colors::ColorSchemeChoice::NightMode;
}
if let Some(x) = args.optional("--color_scheme") {
let mut ok = false;

View File

@ -5,10 +5,10 @@ use widgetry::{
};
use crate::app::App;
use crate::colors::{ColorScheme, ColorSchemeChoice};
use crate::colors::ColorSchemeChoice;
use crate::game::Transition;
use crate::helpers::grey_out_map;
use crate::render::{DrawBuilding, DrawMap};
use crate::render::DrawBuilding;
/// Options controlling the UI.
// TODO SimOptions stuff too
@ -25,6 +25,8 @@ pub struct Options {
pub traffic_signal_style: TrafficSignalStyle,
/// The color scheme for map elements, agents, and the UI.
pub color_scheme: ColorSchemeChoice,
/// Automatically change color_scheme based on simulation time to reflect day/night
pub toggle_day_night_colors: bool,
/// Map elements are drawn differently when unzoomed and zoomed. This specifies the canvas zoom
/// level where they switch.
pub min_zoom_for_detail: f64,
@ -53,6 +55,7 @@ impl Options {
traffic_signal_style: TrafficSignalStyle::BAP,
color_scheme: ColorSchemeChoice::Standard,
toggle_day_night_colors: false,
min_zoom_for_detail: 4.0,
camera_angle: CameraAngle::TopDown,
@ -305,18 +308,9 @@ impl State<App> for OptionsPanel {
});
}
let scheme = self.panel.dropdown_value("Color scheme");
if app.opts.color_scheme != scheme {
app.opts.color_scheme = scheme;
app.cs = ColorScheme::new(app.opts.color_scheme);
ctx.set_style(app.cs.gui_style.clone());
ctx.loading_screen("rerendering map colors", |ctx, timer| {
let (draw_map, zorder_range) =
DrawMap::new(&app.primary.map, &app.opts, &app.cs, ctx, timer);
app.primary.draw_map = draw_map;
app.primary.zorder_range = zorder_range;
});
if app.change_color_scheme(ctx, self.panel.dropdown_value("Color scheme")) {
// If the player picks a different scheme, don't undo it later.
app.opts.toggle_day_night_colors = false;
}
app.opts.min_zoom_for_detail = self.panel.dropdown_value("min zoom");

View File

@ -14,6 +14,7 @@ use widgetry::{
use self::misc_tools::RoutePreview;
pub use self::misc_tools::TurnExplorer;
use crate::app::App;
use crate::colors::ColorSchemeChoice;
use crate::common::{tool_panel, CommonState, ContextualActions, IsochroneViewer, Minimap};
use crate::debug::DebugMode;
use crate::edit::{
@ -101,6 +102,19 @@ impl SandboxMode {
impl State<App> for SandboxMode {
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
if app.opts.toggle_day_night_colors {
let cs_changed = if is_daytime(app) {
app.change_color_scheme(ctx, ColorSchemeChoice::Standard)
} else {
app.change_color_scheme(ctx, ColorSchemeChoice::NightMode)
};
if cs_changed {
// TODO Recreate panels. This handles some of them, but it also loses minimap zoom
// state, and misses the top_panel managed by individual GameplayStates.
self.controls = SandboxControls::new(ctx, app, &self.gameplay);
}
}
// Do this before gameplay
if self.gameplay.can_move_canvas() {
ctx.canvas_movement();
@ -764,43 +778,7 @@ impl State<App> for SandboxLoader {
LoadStage::Finalizing => {
let gameplay = self.mode.initialize(ctx, app);
let sandbox = Box::new(SandboxMode {
controls: SandboxControls {
common: if gameplay.has_common() {
Some(CommonState::new())
} 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 {
None
},
time_panel: if gameplay.has_time_panel() {
Some(TimePanel::new(ctx, app))
} else {
None
},
speed: if gameplay.has_speed() {
Some(SpeedControls::new(ctx, app))
} else {
None
},
agent_meter: if gameplay.has_agent_meter() {
Some(AgentMeter::new(ctx, app))
} else {
None
},
minimap: if gameplay.has_minimap() {
Some(Minimap::new(ctx, app, true))
} else {
None
},
},
controls: SandboxControls::new(ctx, app, &gameplay),
gameplay,
gameplay_mode: self.mode.clone(),
recalc_unzoomed_agent: None,
@ -847,3 +825,54 @@ fn mouseover_unzoomed_agent_circle(ctx: &mut EventCtx, app: &mut App) {
}
}
}
fn is_daytime(app: &App) -> bool {
let hours = app.primary.sim.time().get_parts().0 % 24;
hours >= 6 && hours < 18
}
impl SandboxControls {
pub fn new(
ctx: &mut EventCtx,
app: &App,
gameplay: &Box<dyn gameplay::GameplayState>,
) -> SandboxControls {
SandboxControls {
common: if gameplay.has_common() {
Some(CommonState::new())
} 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 {
None
},
time_panel: if gameplay.has_time_panel() {
Some(TimePanel::new(ctx, app))
} else {
None
},
speed: if gameplay.has_speed() {
Some(SpeedControls::new(ctx, app))
} else {
None
},
agent_meter: if gameplay.has_agent_meter() {
Some(AgentMeter::new(ctx, app))
} else {
None
},
minimap: if gameplay.has_minimap() {
Some(Minimap::new(ctx, app, true))
} else {
None
},
}
}
}