From 2b36b9f03adddfa2dd78195b272e578d1b31af39 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 18 Sep 2020 07:43:05 -0700 Subject: [PATCH] add textured theme (#335) --- game/src/challenges.rs | 2 +- game/src/colors.rs | 53 ++++++++++++------- game/src/common/city_picker.rs | 4 +- game/src/cutscene.rs | 2 +- game/src/devtools/mod.rs | 2 +- game/src/pregame.rs | 8 +-- game/src/render/area.rs | 15 +++--- game/src/render/map.rs | 2 +- game/src/sandbox/dashboards/misc.rs | 4 +- .../sandbox/dashboards/parking_overhead.rs | 2 +- game/src/sandbox/dashboards/summaries.rs | 2 +- game/src/sandbox/dashboards/trip_table.rs | 2 +- game/src/sandbox/gameplay/mod.rs | 2 +- widgetry/src/geom.rs | 18 ++++--- 14 files changed, 69 insertions(+), 49 deletions(-) diff --git a/game/src/challenges.rs b/game/src/challenges.rs index 90ffb26a3b..9215be7098 100644 --- a/game/src/challenges.rs +++ b/game/src/challenges.rs @@ -284,7 +284,7 @@ impl State for ChallengesPicker { } fn draw(&self, g: &mut GfxCtx, app: &App) { - g.clear(app.cs.grass); + g.clear(app.cs.dialog_bg); self.panel.draw(g); } } diff --git a/game/src/colors.rs b/game/src/colors.rs index 863fa971ca..9cc2cfd12f 100644 --- a/game/src/colors.rs +++ b/game/src/colors.rs @@ -1,5 +1,5 @@ use crate::common::ColorScale; -use widgetry::{Choice, Color, Style}; +use widgetry::{Choice, Color, Fill, Style, Texture}; // I've gone back and forth how to organize color scheme code. I was previously against having one // centralized place with all definitions, because careful naming or comments are needed to explain @@ -21,6 +21,7 @@ pub enum ColorSchemeChoice { BAP, OSM, Starcat, + Textured, } impl ColorSchemeChoice { @@ -33,6 +34,7 @@ impl ColorSchemeChoice { Choice::new("bap", ColorSchemeChoice::BAP), Choice::new("osm", ColorSchemeChoice::OSM), Choice::new("starcat", ColorSchemeChoice::Starcat), + Choice::new("textured", ColorSchemeChoice::Textured), ] } } @@ -52,6 +54,7 @@ pub struct ColorScheme { pub bottom_bar_name: Color, pub fade_map_dark: Color, pub gui_style: Style, + pub dialog_bg: Color, // Roads pub driving_lane: Color, @@ -81,14 +84,14 @@ pub struct ColorScheme { // Other static elements pub void_background: Color, - pub map_background: Color, + pub map_background: Fill, pub unzoomed_interesting_intersection: Color, pub residential_building: Color, pub commerical_building: Color, pub building_outline: Color, pub parking_lot: Color, - pub grass: Color, - pub water: Color, + pub grass: Fill, + pub water: Fill, // Unzoomed dynamic elements pub unzoomed_car: Color, @@ -133,6 +136,7 @@ impl ColorScheme { ColorSchemeChoice::BAP => ColorScheme::bap(), ColorSchemeChoice::OSM => ColorScheme::osm(), ColorSchemeChoice::Starcat => ColorScheme::starcat(), + ColorSchemeChoice::Textured => ColorScheme::textured(), } } @@ -152,6 +156,7 @@ impl ColorScheme { bottom_bar_id: Color::RED, bottom_bar_name: Color::CYAN, fade_map_dark: Color::BLACK.alpha(0.6), + dialog_bg: hex("#94C84A"), gui_style, // Roads @@ -182,14 +187,14 @@ impl ColorScheme { // Other static elements void_background: Color::BLACK, - map_background: Color::grey(0.87), + map_background: Color::grey(0.87).into(), unzoomed_interesting_intersection: Color::BLACK, residential_building: Color::hex("#C4C1BC"), commerical_building: Color::hex("#9FABA7"), building_outline: Color::hex("#938E85"), parking_lot: Color::grey(0.7), - grass: hex("#94C84A"), - water: Color::rgb(164, 200, 234), + grass: hex("#94C84A").into(), + water: Color::rgb(164, 200, 234).into(), // Unzoomed dynamic elements unzoomed_car: hex("#A32015"), @@ -264,12 +269,13 @@ impl ColorScheme { let mut cs = ColorScheme::standard(); cs.residential_building = hex("#42208B"); cs.sidewalk = hex("#7C55C8"); - cs.grass = hex("#063D88"); - cs.map_background = hex("#070747"); + cs.grass = hex("#063D88").into(); + cs.dialog_bg = hex("#063D88"); + cs.map_background = hex("#070747").into(); cs.unzoomed_arterial = hex("#54247A"); cs.unzoomed_highway = hex("#DD1F7F"); cs.unzoomed_residential = hex("#4D51AC"); - cs.water = hex("#2A43AA"); + cs.water = hex("#2A43AA").into(); // Horrible choice, but demonstrate it can be done. cs.panel_bg = Color::PURPLE; cs.gui_style.panel_bg = Color::PURPLE; @@ -278,8 +284,8 @@ impl ColorScheme { fn sam_green_day() -> ColorScheme { let mut cs = ColorScheme::standard(); - cs.map_background = hex("#CFE2C4"); - cs.water = hex("#B4D3E5"); + cs.map_background = hex("#CFE2C4").into(); + cs.water = hex("#B4D3E5").into(); cs.driving_lane = hex("#C6CDD5"); cs.residential_building = hex("#CCD4BD"); cs.sidewalk = hex("#98A1AA"); @@ -288,8 +294,9 @@ impl ColorScheme { fn sam_desert_day() -> ColorScheme { let mut cs = ColorScheme::standard(); - cs.map_background = hex("#FEE4D7"); - cs.grass = hex("#F6C6AF"); + cs.map_background = hex("#FEE4D7").into(); + cs.grass = hex("#F6C6AF").into(); + cs.dialog_bg = hex("#F6C6AF"); cs.driving_lane = hex("#BECBD3"); cs.residential_building = hex("#DEAA95"); cs.sidewalk = hex("#8B9EA8"); @@ -308,7 +315,8 @@ impl ColorScheme { hex("#FF616E"), hex("#FA8D37"), ]; - cs.grass = hex("#84BA3B"); // #2F8C2C + cs.grass = hex("#84BA3B").into(); // #2F8C2C + cs.dialog_bg = hex("#84BA3B"); cs.residential_building = hex("#367335"); // #194C18 cs.normal_intersection = hex("#4B5485"); cs.driving_lane = hex("#384173"); @@ -316,7 +324,7 @@ impl ColorScheme { cs.sidewalk = hex("#89ABD9"); cs.sidewalk_lines = hex("#4B5485"); cs.general_road_marking = hex("#89ABD9"); - cs.map_background = hex("#589D54"); // #153F14 + cs.map_background = hex("#589D54").into(); // #153F14 cs.ped_crowd = hex("#DD5444"); cs.road_center_line = hex("#BCFF00"); cs @@ -332,9 +340,10 @@ impl ColorScheme { fn starcat() -> ColorScheme { let mut cs = ColorScheme::standard(); - cs.grass = hex("#3F8C0C"); + cs.grass = hex("#3F8C0C").into(); + cs.dialog_bg = hex("#3F8C0C"); cs.residential_building = hex("#8099A8"); // #5E7486 - cs.map_background = hex("#737373"); + cs.map_background = hex("#737373").into(); cs.driving_lane = hex("#2A2A2A"); // TODO for arterial cs.road_center_line = hex("#DB952E"); cs.general_road_marking = hex("#D6D6D6"); @@ -344,4 +353,12 @@ impl ColorScheme { cs.bus_lane = hex("#AD302D"); cs } + + fn textured() -> ColorScheme { + let mut cs = ColorScheme::standard(); + cs.grass = Texture::GRASS.into(); + cs.water = Texture::STILL_WATER.into(); + cs.map_background = Texture::CONCRETE.into(); + cs + } } diff --git a/game/src/common/city_picker.rs b/game/src/common/city_picker.rs index 6d7b13292c..137b96cc83 100644 --- a/game/src/common/city_picker.rs +++ b/game/src/common/city_picker.rs @@ -40,9 +40,9 @@ impl CityPicker { let zoom = (0.8 * ctx.canvas.window_width / bounds.width()) .min(0.8 * ctx.canvas.window_height / bounds.height()); - batch.push(app.cs.map_background, city.boundary); + batch.push(app.cs.map_background.clone(), city.boundary); for (area_type, polygon) in city.areas { - batch.push(DrawArea::color(area_type, &app.cs), polygon); + batch.push(DrawArea::fill(area_type, &app.cs), polygon); } for (name, polygon) in city.regions { diff --git a/game/src/cutscene.rs b/game/src/cutscene.rs index 452ea6e6be..0f43df3c67 100644 --- a/game/src/cutscene.rs +++ b/game/src/cutscene.rs @@ -153,7 +153,7 @@ impl State for CutscenePlayer { fn draw(&self, g: &mut GfxCtx, app: &App) { // Happens to be a nice background color too ;) - g.clear(app.cs.grass); + g.clear(app.cs.dialog_bg); self.panel.draw(g); } } diff --git a/game/src/devtools/mod.rs b/game/src/devtools/mod.rs index f1e5acc46a..36b1d319f4 100644 --- a/game/src/devtools/mod.rs +++ b/game/src/devtools/mod.rs @@ -138,7 +138,7 @@ impl State for DevToolsMode { } fn draw(&self, g: &mut GfxCtx, app: &App) { - g.clear(app.cs.grass); + g.clear(app.cs.dialog_bg); self.panel.draw(g); } } diff --git a/game/src/pregame.rs b/game/src/pregame.rs index 98b80b8738..afb39e5ce0 100644 --- a/game/src/pregame.rs +++ b/game/src/pregame.rs @@ -45,7 +45,7 @@ impl TitleScreen { hotkeys(vec![Key::Space, Key::Enter]), ), ]) - .bg(app.cs.grass) + .bg(app.cs.dialog_bg) .padding(16) .outline(3.0, Color::BLACK) .centered(), @@ -235,7 +235,7 @@ impl State for MainMenu { } fn draw(&self, g: &mut GfxCtx, app: &App) { - g.clear(app.cs.grass); + g.clear(app.cs.dialog_bg); self.panel.draw(g); } } @@ -315,7 +315,7 @@ impl State for About { } fn draw(&self, g: &mut GfxCtx, app: &App) { - g.clear(app.cs.grass); + g.clear(app.cs.dialog_bg); self.panel.draw(g); } } @@ -472,7 +472,7 @@ impl State for Proposals { } fn draw(&self, g: &mut GfxCtx, app: &App) { - g.clear(app.cs.grass); + g.clear(app.cs.dialog_bg); self.panel.draw(g); } } diff --git a/game/src/render/area.rs b/game/src/render/area.rs index 5039f1e554..ef4e2c19b2 100644 --- a/game/src/render/area.rs +++ b/game/src/render/area.rs @@ -4,7 +4,7 @@ use crate::helpers::ID; use crate::render::{DrawOptions, Renderable}; use geom::Polygon; use map_model::{Area, AreaID, AreaType, Map}; -use widgetry::{Color, EventCtx, GeomBatch, GfxCtx, Line, Text}; +use widgetry::{Color, EventCtx, Fill, GeomBatch, GfxCtx, Line, Text}; pub struct DrawArea { pub id: AreaID, @@ -17,7 +17,7 @@ impl DrawArea { cs: &ColorScheme, all_areas: &mut GeomBatch, ) -> DrawArea { - all_areas.push(DrawArea::color(area.area_type, cs), area.polygon.clone()); + all_areas.push(DrawArea::fill(area.area_type, cs), area.polygon.clone()); if false { // TODO Z-order needs to be on top of everything // TODO Need to auto-size better -- ensure it's completely contained in the polygon, @@ -35,12 +35,13 @@ impl DrawArea { DrawArea { id: area.id } } - pub fn color(area_type: AreaType, cs: &ColorScheme) -> Color { + pub fn fill(area_type: AreaType, cs: &ColorScheme) -> Fill { match area_type { - AreaType::Park => cs.grass, - AreaType::Water => cs.water, - AreaType::PedestrianIsland => Color::grey(0.3), - AreaType::Island => cs.map_background, + // MJK TODO: convert some of these to be a Fill on the theme rather than `into` + AreaType::Park => cs.grass.clone(), + AreaType::Water => cs.water.clone(), + AreaType::PedestrianIsland => Color::grey(0.3).into(), + AreaType::Island => cs.map_background.clone(), } } } diff --git a/game/src/render/map.rs b/game/src/render/map.rs index b2bb36e7f9..ae7beb90f7 100644 --- a/game/src/render/map.rs +++ b/game/src/render/map.rs @@ -134,7 +134,7 @@ impl DrawMap { timer.stop("upload all areas"); let boundary_polygon = ctx.upload(GeomBatch::from(vec![( - cs.map_background, + cs.map_background.clone(), map.get_boundary_polygon().clone(), )])); diff --git a/game/src/sandbox/dashboards/misc.rs b/game/src/sandbox/dashboards/misc.rs index f84ca780a2..f678096cee 100644 --- a/game/src/sandbox/dashboards/misc.rs +++ b/game/src/sandbox/dashboards/misc.rs @@ -66,7 +66,7 @@ impl State for ActiveTraffic { } fn draw(&self, g: &mut GfxCtx, app: &App) { - g.clear(app.cs.grass); + g.clear(app.cs.dialog_bg); self.panel.draw(g); } } @@ -231,7 +231,7 @@ impl State for TransitRoutes { } fn draw(&self, g: &mut GfxCtx, app: &App) { - g.clear(app.cs.grass); + g.clear(app.cs.dialog_bg); self.panel.draw(g); } } diff --git a/game/src/sandbox/dashboards/parking_overhead.rs b/game/src/sandbox/dashboards/parking_overhead.rs index 57d5db6366..f492f3a5d9 100644 --- a/game/src/sandbox/dashboards/parking_overhead.rs +++ b/game/src/sandbox/dashboards/parking_overhead.rs @@ -143,7 +143,7 @@ impl State for ParkingOverhead { } fn draw(&self, g: &mut GfxCtx, app: &App) { - g.clear(app.cs.grass); + g.clear(app.cs.dialog_bg); self.panel.draw(g); preview_trip(g, app, &self.panel); } diff --git a/game/src/sandbox/dashboards/summaries.rs b/game/src/sandbox/dashboards/summaries.rs index bdf17a2cb7..acb2c9cb0f 100644 --- a/game/src/sandbox/dashboards/summaries.rs +++ b/game/src/sandbox/dashboards/summaries.rs @@ -74,7 +74,7 @@ impl State for TripSummaries { } fn draw(&self, g: &mut GfxCtx, app: &App) { - g.clear(app.cs.grass); + g.clear(app.cs.dialog_bg); self.panel.draw(g); } } diff --git a/game/src/sandbox/dashboards/trip_table.rs b/game/src/sandbox/dashboards/trip_table.rs index 47cae92d83..6421a8c74e 100644 --- a/game/src/sandbox/dashboards/trip_table.rs +++ b/game/src/sandbox/dashboards/trip_table.rs @@ -182,7 +182,7 @@ impl State for TripTable { } fn draw(&self, g: &mut GfxCtx, app: &App) { - g.clear(app.cs.grass); + g.clear(app.cs.dialog_bg); self.panel.draw(g); preview_trip(g, app, &self.panel); } diff --git a/game/src/sandbox/gameplay/mod.rs b/game/src/sandbox/gameplay/mod.rs index 5605c78915..3842ccc2b1 100644 --- a/game/src/sandbox/gameplay/mod.rs +++ b/game/src/sandbox/gameplay/mod.rs @@ -393,7 +393,7 @@ impl State for FinalScore { fn draw(&self, g: &mut GfxCtx, app: &App) { // Happens to be a nice background color too ;) - g.clear(app.cs.grass); + g.clear(app.cs.dialog_bg); self.panel.draw(g); } } diff --git a/widgetry/src/geom.rs b/widgetry/src/geom.rs index 2c13616f26..da8e314b8a 100644 --- a/widgetry/src/geom.rs +++ b/widgetry/src/geom.rs @@ -20,14 +20,6 @@ impl GeomBatch { } } - /// Creates a batch of colored polygons. - pub fn from(list: Vec<(Color, Polygon)>) -> GeomBatch { - GeomBatch { - list: list.into_iter().map(|(c, p)| (Fill::Color(c), p)).collect(), - autocrop_dims: true, - } - } - // Adds a single polygon, painted according to `Fill` pub fn push>(&mut self, fill: F, p: Polygon) { self.list.push((fill.into(), p)); @@ -196,6 +188,16 @@ impl GeomBatch { } } +impl> From> for GeomBatch { + /// Creates a batch of filled polygons. + fn from(list: Vec<(F, Polygon)>) -> GeomBatch { + GeomBatch { + list: list.into_iter().map(|(c, p)| (c.into(), p)).collect(), + autocrop_dims: true, + } + } +} + pub enum RewriteColor { NoOp, Change(Color, Color),