mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 15:33:44 +03:00
using color scheme in most places
This commit is contained in:
parent
623f0528cd
commit
e7e334a460
@ -1,135 +1,135 @@
|
||||
{
|
||||
"map": {
|
||||
"Sidewalk": [
|
||||
0.7231658,
|
||||
0.68797094,
|
||||
0.75104135,
|
||||
1.0
|
||||
],
|
||||
"TurnIconCircle": [
|
||||
0.063196,
|
||||
0.79656935,
|
||||
0.62435865,
|
||||
1.0
|
||||
],
|
||||
"Turn": [
|
||||
0.7646927,
|
||||
0.08863717,
|
||||
0.598167,
|
||||
1.0
|
||||
],
|
||||
"NextQueued": [
|
||||
0.13027889,
|
||||
0.48449433,
|
||||
0.9080713,
|
||||
1.0
|
||||
],
|
||||
"TurnIconInactive": [
|
||||
0.14615297,
|
||||
0.9214722,
|
||||
0.4148339,
|
||||
1.0
|
||||
],
|
||||
"RoadOrientation": [
|
||||
0.7582534,
|
||||
0.99075705,
|
||||
0.70908225,
|
||||
1.0
|
||||
],
|
||||
"Queued": [
|
||||
0.3389185,
|
||||
0.0877803,
|
||||
0.9954711,
|
||||
1.0
|
||||
],
|
||||
"ConflictingTurn": [
|
||||
0.2613939,
|
||||
0.05315745,
|
||||
0.13176817,
|
||||
1.0
|
||||
],
|
||||
"ChangedStopSignIntersection": [
|
||||
0.68394506,
|
||||
0.3545285,
|
||||
0.798195,
|
||||
1.0
|
||||
],
|
||||
"ParcelInterior": [
|
||||
0.61576617,
|
||||
0.3485126,
|
||||
0.079839945,
|
||||
1.0
|
||||
],
|
||||
"Building": [
|
||||
0.6194557,
|
||||
0.04746574,
|
||||
0.048986018,
|
||||
1.0
|
||||
],
|
||||
"ParcelBoundary": [
|
||||
0.10262495,
|
||||
0.27895468,
|
||||
0.24475342,
|
||||
1.0
|
||||
],
|
||||
"Parking": [
|
||||
0.18110627,
|
||||
0.7668609,
|
||||
0.78273845,
|
||||
1.0
|
||||
],
|
||||
"Selected": [
|
||||
0.5561179,
|
||||
0.67208916,
|
||||
0.888709,
|
||||
1.0
|
||||
],
|
||||
"Road": [
|
||||
0.42062867,
|
||||
0.18196481,
|
||||
0.002040863,
|
||||
1.0
|
||||
],
|
||||
"SearchResult": [
|
||||
0.29739696,
|
||||
0.1459617,
|
||||
0.38928866,
|
||||
1.0
|
||||
],
|
||||
"Debug": [
|
||||
0.52514017,
|
||||
0.4302144,
|
||||
0.9794487,
|
||||
1.0
|
||||
],
|
||||
"ChangedTrafficSignalIntersection": [
|
||||
0.92895883,
|
||||
0.54622823,
|
||||
0.5924938,
|
||||
1.0
|
||||
],
|
||||
"NormalIntersection": [
|
||||
0.6803359,
|
||||
0.82401633,
|
||||
0.27655125,
|
||||
1.0
|
||||
],
|
||||
"TrafficSignalIntersection": [
|
||||
0.53518486,
|
||||
0.6754812,
|
||||
0.6970498,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"BrightDebug": [
|
||||
0.51087564,
|
||||
0.66038465,
|
||||
0.94535834,
|
||||
0.8,
|
||||
0.1,
|
||||
0.1,
|
||||
1.0
|
||||
],
|
||||
"Road": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"Parking": [
|
||||
0.5,
|
||||
0.0,
|
||||
0.5,
|
||||
1.0
|
||||
],
|
||||
"Sidewalk": [
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"ChangedStopSignIntersection": [
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"ChangedTrafficSignalIntersection": [
|
||||
1.0,
|
||||
0.65,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"TrafficSignalIntersection": [
|
||||
1.0,
|
||||
1.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"NormalIntersection": [
|
||||
0.3,
|
||||
0.3,
|
||||
0.3,
|
||||
1.0
|
||||
],
|
||||
"Selected": [
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"Turn": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"ConflictingTurn": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.5
|
||||
],
|
||||
"Building": [
|
||||
0.7,
|
||||
0.7,
|
||||
0.7,
|
||||
1.0
|
||||
],
|
||||
"ParcelBoundary": [
|
||||
0.3,
|
||||
0.3,
|
||||
0.3,
|
||||
1.0
|
||||
],
|
||||
"ParcelInterior": [
|
||||
0.5,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"RoadOrientation": [
|
||||
1.0,
|
||||
1.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"SearchResult": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"Visited": [
|
||||
0.6067979,
|
||||
0.99225366,
|
||||
0.9826904,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"Queued": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"NextQueued": [
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"TurnIconCircle": [
|
||||
0.3,
|
||||
0.3,
|
||||
0.3,
|
||||
1.0
|
||||
],
|
||||
"TurnIconInactive": [
|
||||
0.7,
|
||||
0.7,
|
||||
0.7,
|
||||
1.0
|
||||
]
|
||||
}
|
||||
|
@ -4,13 +4,13 @@ extern crate serde_json;
|
||||
|
||||
use graphics::types::Color;
|
||||
use rand;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs::File;
|
||||
use std::io::{Error, ErrorKind, Read, Write};
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, EnumIter, Hash)]
|
||||
pub enum ColorSetting {
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, EnumIter, PartialOrd, Ord)]
|
||||
pub enum Colors {
|
||||
Debug,
|
||||
BrightDebug,
|
||||
Road,
|
||||
@ -37,7 +37,7 @@ pub enum ColorSetting {
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct ColorScheme {
|
||||
map: HashMap<ColorSetting, Color>,
|
||||
map: BTreeMap<Colors, Color>,
|
||||
}
|
||||
|
||||
impl ColorScheme {
|
||||
@ -53,11 +53,11 @@ impl ColorScheme {
|
||||
file.read_to_string(&mut contents)?;
|
||||
let scheme: ColorScheme = serde_json::from_str(&contents).unwrap();
|
||||
|
||||
for setting in ColorSetting::iter() {
|
||||
if !scheme.map.contains_key(&setting) {
|
||||
for color in Colors::iter() {
|
||||
if !scheme.map.contains_key(&color) {
|
||||
return Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("no color for {:?} defined", setting),
|
||||
format!("no color for {:?} defined", color),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -65,16 +65,20 @@ impl ColorScheme {
|
||||
Ok(scheme)
|
||||
}
|
||||
|
||||
pub fn random_settings() -> ColorScheme {
|
||||
pub fn random_colors() -> ColorScheme {
|
||||
let mut scheme = ColorScheme {
|
||||
map: HashMap::new(),
|
||||
map: BTreeMap::new(),
|
||||
};
|
||||
for setting in ColorSetting::iter() {
|
||||
scheme.map.insert(
|
||||
setting,
|
||||
[rand::random(), rand::random(), rand::random(), 1.0],
|
||||
);
|
||||
for color in Colors::iter() {
|
||||
scheme
|
||||
.map
|
||||
.insert(color, [rand::random(), rand::random(), rand::random(), 1.0]);
|
||||
}
|
||||
scheme
|
||||
}
|
||||
|
||||
pub fn get(&self, c: Colors) -> Color {
|
||||
// TODO make sure this isn't slow; maybe back this with an array
|
||||
*self.map.get(&c).unwrap()
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
extern crate map_model;
|
||||
|
||||
use colors::{ColorScheme, Colors};
|
||||
use ezgui::input::UserInput;
|
||||
use graphics::types::Color;
|
||||
use map_model::{Map, Road, RoadID};
|
||||
use piston::input::Key;
|
||||
use render;
|
||||
use std::collections::{HashSet, VecDeque};
|
||||
|
||||
// Keeps track of state so this can be interactively visualized
|
||||
@ -76,16 +76,16 @@ impl Floodfiller {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn color_r(&self, r: &Road) -> Option<Color> {
|
||||
pub fn color_r(&self, r: &Road, cs: &ColorScheme) -> Option<Color> {
|
||||
if self.visited.contains(&r.id) {
|
||||
return Some(render::VISITED_COLOR);
|
||||
return Some(cs.get(Colors::Visited));
|
||||
}
|
||||
if !self.queue.is_empty() && *self.queue.front().unwrap() == r.id {
|
||||
return Some(render::NEXT_QUEUED_COLOR);
|
||||
return Some(cs.get(Colors::NextQueued));
|
||||
}
|
||||
// TODO linear search shouldnt suck too much for interactive mode
|
||||
if self.queue.contains(&r.id) {
|
||||
return Some(render::QUEUED_COLOR);
|
||||
return Some(cs.get(Colors::Queued));
|
||||
}
|
||||
None
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
use colors::{ColorScheme, Colors};
|
||||
use ezgui::input::UserInput;
|
||||
use ezgui::text_box::TextBox;
|
||||
use graphics::types::Color;
|
||||
use map_model;
|
||||
use piston::input::Key;
|
||||
use render;
|
||||
|
||||
pub enum SearchState {
|
||||
Empty,
|
||||
@ -14,18 +14,18 @@ pub enum SearchState {
|
||||
}
|
||||
|
||||
impl SearchState {
|
||||
pub fn color_r(&self, r: &map_model::Road) -> Option<Color> {
|
||||
self.choose_color(&r.osm_tags)
|
||||
pub fn color_r(&self, r: &map_model::Road, cs: &ColorScheme) -> Option<Color> {
|
||||
self.choose_color(&r.osm_tags, cs)
|
||||
}
|
||||
pub fn color_b(&self, b: &map_model::Building) -> Option<Color> {
|
||||
self.choose_color(&b.osm_tags)
|
||||
pub fn color_b(&self, b: &map_model::Building, cs: &ColorScheme) -> Option<Color> {
|
||||
self.choose_color(&b.osm_tags, cs)
|
||||
}
|
||||
|
||||
fn choose_color(&self, osm_tags: &[String]) -> Option<Color> {
|
||||
fn choose_color(&self, osm_tags: &[String], cs: &ColorScheme) -> Option<Color> {
|
||||
if let SearchState::FilterOSM(filter) = self {
|
||||
for tag in osm_tags {
|
||||
if tag.contains(filter) {
|
||||
return Some(render::SEARCH_RESULT_COLOR);
|
||||
return Some(cs.get(Colors::SearchResult));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
use animation;
|
||||
use colors::{ColorScheme, Colors};
|
||||
use control::ControlMap;
|
||||
use ezgui::canvas::{Canvas, GfxCtx};
|
||||
use ezgui::input::UserInput;
|
||||
@ -139,6 +140,7 @@ impl SelectionState {
|
||||
draw_map: &render::DrawMap,
|
||||
control_map: &ControlMap,
|
||||
sim: &Sim,
|
||||
cs: &ColorScheme,
|
||||
g: &mut GfxCtx,
|
||||
) {
|
||||
match *self {
|
||||
@ -147,7 +149,7 @@ impl SelectionState {
|
||||
if let Some(signal) = control_map.traffic_signals.get(&id) {
|
||||
let (cycle, _) = signal.current_cycle_and_remaining_time(sim.time.as_time());
|
||||
for t in &cycle.turns {
|
||||
draw_map.get_t(*t).draw_full(g, render::TURN_COLOR);
|
||||
draw_map.get_t(*t).draw_full(g, cs.get(Colors::Turn));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -160,22 +162,22 @@ impl SelectionState {
|
||||
let turn = draw_map.get_t(relevant_turns[idx % relevant_turns.len()].id);
|
||||
let geom_turn =
|
||||
geom_map.get_t(relevant_turns[idx % relevant_turns.len()].id);
|
||||
turn.draw_full(g, render::TURN_COLOR);
|
||||
turn.draw_full(g, cs.get(Colors::Turn));
|
||||
for map_t in all_turns {
|
||||
let draw_t = draw_map.get_t(map_t.id);
|
||||
let geom_t = geom_map.get_t(map_t.id);
|
||||
if geom_t.conflicts_with(geom_turn) {
|
||||
// TODO should we instead change color_t?
|
||||
draw_t.draw_icon(g, render::CONFLICTING_TURN_COLOR);
|
||||
draw_t.draw_icon(g, cs.get(Colors::ConflictingTurn), cs);
|
||||
}
|
||||
}
|
||||
}
|
||||
None => for turn in &relevant_turns {
|
||||
draw_map.get_t(turn.id).draw_full(g, render::TURN_COLOR);
|
||||
draw_map.get_t(turn.id).draw_full(g, cs.get(Colors::Turn));
|
||||
},
|
||||
}
|
||||
// TODO tmp
|
||||
draw_map.get_r(id).draw_debug(g, geom_map.get_r(id));
|
||||
draw_map.get_r(id).draw_debug(g, cs, geom_map.get_r(id));
|
||||
}
|
||||
SelectionState::TooltipRoad(id) => {
|
||||
canvas.draw_mouse_tooltip(g, &draw_map.get_r(id).tooltip_lines(map, geom_map));
|
||||
@ -192,34 +194,36 @@ impl SelectionState {
|
||||
// TODO instead, since color logic is complicated anyway, just have a way to ask "are we
|
||||
// selecting this generic ID?"
|
||||
|
||||
pub fn color_r(&self, r: &map_model::Road) -> Option<Color> {
|
||||
pub fn color_r(&self, r: &map_model::Road, cs: &ColorScheme) -> Option<Color> {
|
||||
match *self {
|
||||
SelectionState::SelectedRoad(id, _) if r.id == id => Some(render::SELECTED_COLOR),
|
||||
SelectionState::TooltipRoad(id) if r.id == id => Some(render::SELECTED_COLOR),
|
||||
SelectionState::SelectedRoad(id, _) if r.id == id => Some(cs.get(Colors::Selected)),
|
||||
SelectionState::TooltipRoad(id) if r.id == id => Some(cs.get(Colors::Selected)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
pub fn color_i(&self, i: &map_model::Intersection) -> Option<Color> {
|
||||
pub fn color_i(&self, i: &map_model::Intersection, cs: &ColorScheme) -> Option<Color> {
|
||||
match *self {
|
||||
SelectionState::SelectedIntersection(id) if i.id == id => Some(render::SELECTED_COLOR),
|
||||
SelectionState::SelectedIntersection(id) if i.id == id => {
|
||||
Some(cs.get(Colors::Selected))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
pub fn color_t(&self, t: &map_model::Turn) -> Option<Color> {
|
||||
pub fn color_t(&self, t: &map_model::Turn, cs: &ColorScheme) -> Option<Color> {
|
||||
match *self {
|
||||
SelectionState::SelectedTurn(id) if t.id == id => Some(render::SELECTED_COLOR),
|
||||
SelectionState::SelectedTurn(id) if t.id == id => Some(cs.get(Colors::Selected)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
pub fn color_b(&self, b: &map_model::Building) -> Option<Color> {
|
||||
pub fn color_b(&self, b: &map_model::Building, cs: &ColorScheme) -> Option<Color> {
|
||||
match *self {
|
||||
SelectionState::SelectedBuilding(id) if b.id == id => Some(render::SELECTED_COLOR),
|
||||
SelectionState::SelectedBuilding(id) if b.id == id => Some(cs.get(Colors::Selected)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
pub fn color_c(&self, c: CarID) -> Option<Color> {
|
||||
pub fn color_c(&self, c: CarID, cs: &ColorScheme) -> Option<Color> {
|
||||
match *self {
|
||||
SelectionState::SelectedCar(id) if c == id => Some(render::SELECTED_COLOR),
|
||||
SelectionState::SelectedCar(id) if c == id => Some(cs.get(Colors::Selected)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,7 @@ mod parcel;
|
||||
mod road;
|
||||
mod turn;
|
||||
|
||||
use ezgui::canvas;
|
||||
use geom;
|
||||
use graphics::types::Color;
|
||||
pub use render::map::DrawMap;
|
||||
pub use render::road::DrawRoad;
|
||||
pub use render::turn::DrawTurn;
|
||||
@ -24,27 +22,3 @@ const TURN_ICON_ARROW_THICKNESS: f64 = geom::BIG_ARROW_THICKNESS / 3.0;
|
||||
const BIG_ARROW_TIP_LENGTH: f64 = 1.0;
|
||||
const TURN_ICON_ARROW_TIP_LENGTH: f64 = BIG_ARROW_TIP_LENGTH * 0.8;
|
||||
const TURN_ICON_ARROW_LENGTH: f64 = 2.0;
|
||||
|
||||
pub const DEBUG_COLOR: Color = canvas::RED;
|
||||
pub const BRIGHT_DEBUG_COLOR: Color = [0.8, 0.1, 0.1, 1.0];
|
||||
pub const ROAD_COLOR: Color = canvas::BLACK;
|
||||
pub const PARKING_COLOR: Color = canvas::PURPLE;
|
||||
pub const SIDEWALK_COLOR: Color = canvas::GREEN;
|
||||
pub const CHANGED_STOP_SIGN_INTERSECTION_COLOR: Color = canvas::GREEN;
|
||||
pub const CHANGED_TRAFFIC_SIGNAL_INTERSECTION_COLOR: Color = canvas::ORANGE;
|
||||
pub const TRAFFIC_SIGNAL_INTERSECTION_COLOR: Color = canvas::YELLOW;
|
||||
pub const NORMAL_INTERSECTION_COLOR: Color = canvas::DARK_GREY;
|
||||
pub const SELECTED_COLOR: Color = canvas::BLUE;
|
||||
pub const TURN_COLOR: Color = canvas::GREEN;
|
||||
pub const CONFLICTING_TURN_COLOR: Color = [1.0, 0.0, 0.0, 0.5];
|
||||
pub const BUILDING_COLOR: Color = canvas::LIGHT_GREY;
|
||||
pub const PARCEL_BOUNDARY_COLOR: Color = canvas::DARK_GREY;
|
||||
pub const PARCEL_INTERIOR_COLOR: Color = canvas::LIGHT_BROWN;
|
||||
const ROAD_ORIENTATION_COLOR: Color = canvas::YELLOW;
|
||||
pub const SEARCH_RESULT_COLOR: Color = canvas::RED;
|
||||
// For interactive algorithms
|
||||
pub const VISITED_COLOR: Color = canvas::BLUE;
|
||||
pub const QUEUED_COLOR: Color = canvas::RED;
|
||||
pub const NEXT_QUEUED_COLOR: Color = canvas::GREEN;
|
||||
const TURN_ICON_CIRCLE_COLOR: Color = canvas::DARK_GREY;
|
||||
pub const TURN_ICON_INACTIVE_COLOR: Color = canvas::LIGHT_GREY;
|
||||
|
@ -4,6 +4,7 @@ extern crate aabb_quadtree;
|
||||
extern crate map_model;
|
||||
|
||||
use aabb_quadtree::geom::Rect;
|
||||
use colors::{ColorScheme, Colors};
|
||||
use ezgui::canvas::GfxCtx;
|
||||
use geom;
|
||||
use geom::geometry;
|
||||
@ -11,7 +12,7 @@ use graphics;
|
||||
use graphics::math::Vec2d;
|
||||
use graphics::types::Color;
|
||||
use map_model::{Pt2D, RoadID};
|
||||
use render::{BRIGHT_DEBUG_COLOR, DEBUG_COLOR, PARCEL_BOUNDARY_THICKNESS, ROAD_ORIENTATION_COLOR};
|
||||
use render::PARCEL_BOUNDARY_THICKNESS;
|
||||
use std::f64;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -47,9 +48,9 @@ impl DrawRoad {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_detail(&self, g: &mut GfxCtx) {
|
||||
pub fn draw_detail(&self, g: &mut GfxCtx, cs: &ColorScheme) {
|
||||
let road_marking =
|
||||
graphics::Line::new_round(ROAD_ORIENTATION_COLOR, geom::BIG_ARROW_THICKNESS);
|
||||
graphics::Line::new_round(cs.get(Colors::RoadOrientation), geom::BIG_ARROW_THICKNESS);
|
||||
|
||||
for pair in self.yellow_center_lines.windows(2) {
|
||||
road_marking.draw(
|
||||
@ -61,9 +62,10 @@ impl DrawRoad {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_debug(&self, g: &mut GfxCtx, geom_r: &geom::GeomRoad) {
|
||||
let line = graphics::Line::new_round(DEBUG_COLOR, PARCEL_BOUNDARY_THICKNESS / 2.0);
|
||||
let circle = graphics::Ellipse::new(BRIGHT_DEBUG_COLOR);
|
||||
pub fn draw_debug(&self, g: &mut GfxCtx, cs: &ColorScheme, geom_r: &geom::GeomRoad) {
|
||||
let line =
|
||||
graphics::Line::new_round(cs.get(Colors::Debug), PARCEL_BOUNDARY_THICKNESS / 2.0);
|
||||
let circle = graphics::Ellipse::new(cs.get(Colors::BrightDebug));
|
||||
|
||||
for &(pt1, pt2) in &geom_r.lane_center_lines {
|
||||
line.draw(
|
||||
|
@ -4,6 +4,7 @@ extern crate aabb_quadtree;
|
||||
extern crate map_model;
|
||||
|
||||
use aabb_quadtree::geom::Rect;
|
||||
use colors::{ColorScheme, Colors};
|
||||
use ezgui::canvas::GfxCtx;
|
||||
use geom;
|
||||
use geom::GeomMap;
|
||||
@ -13,7 +14,7 @@ use graphics::math::Vec2d;
|
||||
use graphics::types::Color;
|
||||
use map_model::TurnID;
|
||||
use render::{BIG_ARROW_TIP_LENGTH, TURN_ICON_ARROW_LENGTH, TURN_ICON_ARROW_THICKNESS,
|
||||
TURN_ICON_ARROW_TIP_LENGTH, TURN_ICON_CIRCLE_COLOR};
|
||||
TURN_ICON_ARROW_TIP_LENGTH};
|
||||
use std::f64;
|
||||
use vecmath;
|
||||
|
||||
@ -78,8 +79,8 @@ impl DrawTurn {
|
||||
);
|
||||
}
|
||||
|
||||
pub fn draw_icon(&self, g: &mut GfxCtx, color: Color) {
|
||||
let circle = graphics::Ellipse::new(TURN_ICON_CIRCLE_COLOR);
|
||||
pub fn draw_icon(&self, g: &mut GfxCtx, color: Color, cs: &ColorScheme) {
|
||||
let circle = graphics::Ellipse::new(cs.get(Colors::TurnIconCircle));
|
||||
circle.draw(self.icon_circle, &g.ctx.draw_state, g.ctx.transform, g.gfx);
|
||||
|
||||
let turn_line = graphics::Line::new_round(color, TURN_ICON_ARROW_THICKNESS);
|
||||
|
@ -5,7 +5,7 @@
|
||||
extern crate map_model;
|
||||
|
||||
use animation;
|
||||
use colors::ColorScheme;
|
||||
use colors::{ColorScheme, Colors};
|
||||
use control::ControlMap;
|
||||
use ezgui::ToggleableLayer;
|
||||
use ezgui::canvas;
|
||||
@ -64,7 +64,8 @@ pub struct UI {
|
||||
color_picker: ColorPicker,
|
||||
|
||||
canvas: Canvas,
|
||||
color_scheme: ColorScheme,
|
||||
// TODO maybe never pass this to other places? Always resolve colors here?
|
||||
cs: ColorScheme,
|
||||
}
|
||||
|
||||
impl UI {
|
||||
@ -117,7 +118,7 @@ impl UI {
|
||||
color_picker: ColorPicker::new(),
|
||||
|
||||
canvas: Canvas::new(),
|
||||
color_scheme: ColorScheme::random_settings(),
|
||||
cs: ColorScheme::random_colors(),
|
||||
};
|
||||
|
||||
match savestate::load("editor_state") {
|
||||
@ -139,7 +140,7 @@ impl UI {
|
||||
match ColorScheme::load("color_scheme") {
|
||||
Ok(scheme) => {
|
||||
println!("Loaded previous color_scheme");
|
||||
ui.color_scheme = scheme;
|
||||
ui.cs = scheme;
|
||||
}
|
||||
Err(err) => {
|
||||
println!("Couldn't load color_scheme: {}", err);
|
||||
@ -318,7 +319,7 @@ impl UI {
|
||||
};
|
||||
// TODO maybe make state line up with the map, so loading from a new map doesn't break
|
||||
savestate::write("editor_state", state).expect("Saving editor_state failed");
|
||||
self.color_scheme
|
||||
self.cs
|
||||
.write("color_scheme")
|
||||
.expect("Saving color_scheme failed");
|
||||
println!("Saved editor_state and color_scheme");
|
||||
@ -341,10 +342,10 @@ impl UI {
|
||||
for r in &roads_onscreen {
|
||||
r.draw(g, self.color_road(r.id));
|
||||
if self.canvas.cam_zoom >= MIN_ZOOM_FOR_ROAD_MARKERS {
|
||||
r.draw_detail(g);
|
||||
r.draw_detail(g, &self.cs);
|
||||
}
|
||||
if self.debug_mode.is_enabled() {
|
||||
r.draw_debug(g, self.geom_map.get_r(r.id));
|
||||
r.draw_debug(g, &self.cs, self.geom_map.get_r(r.id));
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,7 +357,7 @@ impl UI {
|
||||
|
||||
if self.show_icons.is_enabled() {
|
||||
for t in &self.draw_map.get_turn_icons_onscreen(screen_bbox) {
|
||||
t.draw_icon(g, self.color_turn_icon(t.id));
|
||||
t.draw_icon(g, self.color_turn_icon(t.id), &self.cs);
|
||||
for c in &self.sim_ctrl
|
||||
.sim
|
||||
.get_draw_cars_on_turn(t.id, &self.geom_map)
|
||||
@ -394,6 +395,7 @@ impl UI {
|
||||
&self.draw_map,
|
||||
&self.control_map,
|
||||
&self.sim_ctrl.sim,
|
||||
&self.cs,
|
||||
g,
|
||||
);
|
||||
|
||||
@ -489,17 +491,19 @@ impl UI {
|
||||
fn color_road(&self, id: map_model::RoadID) -> Color {
|
||||
let r = self.map.get_r(id);
|
||||
let default = match r.lane_type {
|
||||
map_model::LaneType::Driving => render::ROAD_COLOR,
|
||||
map_model::LaneType::Parking => render::PARKING_COLOR,
|
||||
map_model::LaneType::Sidewalk => render::SIDEWALK_COLOR,
|
||||
map_model::LaneType::Driving => self.cs.get(Colors::Road),
|
||||
map_model::LaneType::Parking => self.cs.get(Colors::Parking),
|
||||
map_model::LaneType::Sidewalk => self.cs.get(Colors::Sidewalk),
|
||||
};
|
||||
|
||||
// TODO This evaluates all the color methods, which may be expensive. But the option
|
||||
// chaining is harder to read. :(
|
||||
vec![
|
||||
self.current_selection_state.color_r(r),
|
||||
self.current_search_state.color_r(r),
|
||||
self.floodfiller.as_ref().and_then(|f| f.color_r(r)),
|
||||
self.current_selection_state.color_r(r, &self.cs),
|
||||
self.current_search_state.color_r(r, &self.cs),
|
||||
self.floodfiller
|
||||
.as_ref()
|
||||
.and_then(|f| f.color_r(r, &self.cs)),
|
||||
if self.steepness_active.is_enabled() {
|
||||
self.steepness_viz.color_r(&self.map, r)
|
||||
} else {
|
||||
@ -521,50 +525,52 @@ impl UI {
|
||||
// TODO weird to squeeze in some quick logic here?
|
||||
let default_color = if let Some(s) = self.control_map.traffic_signals.get(&i.id) {
|
||||
if s.changed() {
|
||||
render::CHANGED_TRAFFIC_SIGNAL_INTERSECTION_COLOR
|
||||
self.cs.get(Colors::ChangedTrafficSignalIntersection)
|
||||
} else {
|
||||
render::TRAFFIC_SIGNAL_INTERSECTION_COLOR
|
||||
self.cs.get(Colors::TrafficSignalIntersection)
|
||||
}
|
||||
} else if let Some(s) = self.control_map.stop_signs.get(&i.id) {
|
||||
if s.changed() {
|
||||
render::CHANGED_STOP_SIGN_INTERSECTION_COLOR
|
||||
self.cs.get(Colors::ChangedStopSignIntersection)
|
||||
} else {
|
||||
render::NORMAL_INTERSECTION_COLOR
|
||||
self.cs.get(Colors::NormalIntersection)
|
||||
}
|
||||
} else {
|
||||
render::NORMAL_INTERSECTION_COLOR
|
||||
self.cs.get(Colors::NormalIntersection)
|
||||
};
|
||||
|
||||
self.current_selection_state
|
||||
.color_i(i)
|
||||
.color_i(i, &self.cs)
|
||||
.unwrap_or(default_color)
|
||||
}
|
||||
|
||||
fn color_turn_icon(&self, id: map_model::TurnID) -> Color {
|
||||
let t = self.map.get_t(id);
|
||||
// TODO traffic signal selection logic maybe moves here
|
||||
self.current_selection_state.color_t(t).unwrap_or_else(|| {
|
||||
self.stop_sign_editor
|
||||
.as_ref()
|
||||
.and_then(|e| e.color_t(t, &self.control_map))
|
||||
.unwrap_or_else(|| {
|
||||
self.traffic_signal_editor
|
||||
.as_ref()
|
||||
.and_then(|e| e.color_t(t, &self.geom_map, &self.control_map))
|
||||
.unwrap_or_else(|| {
|
||||
self.turn_colors
|
||||
.color_t(t)
|
||||
.unwrap_or(render::TURN_ICON_INACTIVE_COLOR)
|
||||
})
|
||||
})
|
||||
})
|
||||
self.current_selection_state
|
||||
.color_t(t, &self.cs)
|
||||
.unwrap_or_else(|| {
|
||||
self.stop_sign_editor
|
||||
.as_ref()
|
||||
.and_then(|e| e.color_t(t, &self.control_map))
|
||||
.unwrap_or_else(|| {
|
||||
self.traffic_signal_editor
|
||||
.as_ref()
|
||||
.and_then(|e| e.color_t(t, &self.geom_map, &self.control_map))
|
||||
.unwrap_or_else(|| {
|
||||
self.turn_colors
|
||||
.color_t(t)
|
||||
.unwrap_or(self.cs.get(Colors::TurnIconInactive))
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn color_building(&self, id: map_model::BuildingID) -> Color {
|
||||
let b = self.map.get_b(id);
|
||||
vec![
|
||||
self.current_selection_state.color_b(b),
|
||||
self.current_search_state.color_b(b),
|
||||
self.current_selection_state.color_b(b, &self.cs),
|
||||
self.current_search_state.color_b(b, &self.cs),
|
||||
if self.osm_classifier_active.is_enabled() {
|
||||
self.osm_classifier.color_b(b)
|
||||
} else {
|
||||
@ -573,17 +579,20 @@ impl UI {
|
||||
].iter()
|
||||
.filter_map(|c| *c)
|
||||
.next()
|
||||
.unwrap_or(render::BUILDING_COLOR)
|
||||
.unwrap_or(self.cs.get(Colors::Building))
|
||||
}
|
||||
|
||||
// Returns (boundary, fill) color
|
||||
fn color_parcel(&self, id: map_model::ParcelID) -> (Color, Color) {
|
||||
let _p = self.map.get_p(id);
|
||||
(render::PARCEL_BOUNDARY_COLOR, render::PARCEL_INTERIOR_COLOR)
|
||||
(
|
||||
self.cs.get(Colors::ParcelBoundary),
|
||||
self.cs.get(Colors::ParcelInterior),
|
||||
)
|
||||
}
|
||||
|
||||
fn color_car(&self, id: CarID) -> Color {
|
||||
if let Some(c) = self.current_selection_state.color_c(id) {
|
||||
if let Some(c) = self.current_selection_state.color_c(id, &self.cs) {
|
||||
return c;
|
||||
}
|
||||
if self.sim_ctrl.sim.is_moving(id) {
|
||||
|
@ -10,7 +10,6 @@ use piston::input::{Button, Event, Key, MouseButton, MouseCursorEvent, MouseScro
|
||||
PressEvent, ReleaseEvent};
|
||||
use piston::window::Size;
|
||||
|
||||
//pub const WHITE: Color = [1.0, 1.0, 1.0, 1.0];
|
||||
pub const BLACK: Color = [0.0, 0.0, 0.0, 1.0];
|
||||
pub const BLUE: Color = [0.0, 0.0, 1.0, 1.0];
|
||||
pub const YELLOW: Color = [1.0, 1.0, 0.0, 1.0];
|
||||
@ -22,9 +21,7 @@ pub const DARK_GREY: Color = [0.3, 0.3, 0.3, 1.0];
|
||||
pub const PURPLE: Color = [0.5, 0.0, 0.5, 1.0];
|
||||
pub const CYAN: Color = [0.0, 1.0, 1.0, 1.0];
|
||||
pub const LIGHT_BROWN: Color = [210.0 / 255.0, 105.0 / 255.0, 30.0 / 255.0, 1.0];
|
||||
// TODO it'd be a bit more efficient to not render it at all...
|
||||
pub const ALMOST_INVISIBLE: Color = [0.0, 0.0, 0.0, 0.1];
|
||||
//pub const INVISIBLE: Color = [0.0, 0.0, 0.0, 0.0];
|
||||
|
||||
const TEXT_FG_COLOR: Color = BLACK;
|
||||
const TEXT_BG_COLOR: Color = [0.0, 1.0, 0.0, 0.5];
|
||||
|
Loading…
Reference in New Issue
Block a user