mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-26 16:02:23 +03:00
using color scheme in most places
This commit is contained in:
parent
623f0528cd
commit
e7e334a460
@ -1,135 +1,135 @@
|
|||||||
{
|
{
|
||||||
"map": {
|
"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": [
|
"Debug": [
|
||||||
0.52514017,
|
1.0,
|
||||||
0.4302144,
|
0.0,
|
||||||
0.9794487,
|
0.0,
|
||||||
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
|
1.0
|
||||||
],
|
],
|
||||||
"BrightDebug": [
|
"BrightDebug": [
|
||||||
0.51087564,
|
0.8,
|
||||||
0.66038465,
|
0.1,
|
||||||
0.94535834,
|
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
|
1.0
|
||||||
],
|
],
|
||||||
"Visited": [
|
"Visited": [
|
||||||
0.6067979,
|
0.0,
|
||||||
0.99225366,
|
0.0,
|
||||||
0.9826904,
|
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
|
1.0
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,13 @@ extern crate serde_json;
|
|||||||
|
|
||||||
use graphics::types::Color;
|
use graphics::types::Color;
|
||||||
use rand;
|
use rand;
|
||||||
use std::collections::HashMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Error, ErrorKind, Read, Write};
|
use std::io::{Error, ErrorKind, Read, Write};
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, EnumIter, Hash)]
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, EnumIter, PartialOrd, Ord)]
|
||||||
pub enum ColorSetting {
|
pub enum Colors {
|
||||||
Debug,
|
Debug,
|
||||||
BrightDebug,
|
BrightDebug,
|
||||||
Road,
|
Road,
|
||||||
@ -37,7 +37,7 @@ pub enum ColorSetting {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct ColorScheme {
|
pub struct ColorScheme {
|
||||||
map: HashMap<ColorSetting, Color>,
|
map: BTreeMap<Colors, Color>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorScheme {
|
impl ColorScheme {
|
||||||
@ -53,11 +53,11 @@ impl ColorScheme {
|
|||||||
file.read_to_string(&mut contents)?;
|
file.read_to_string(&mut contents)?;
|
||||||
let scheme: ColorScheme = serde_json::from_str(&contents).unwrap();
|
let scheme: ColorScheme = serde_json::from_str(&contents).unwrap();
|
||||||
|
|
||||||
for setting in ColorSetting::iter() {
|
for color in Colors::iter() {
|
||||||
if !scheme.map.contains_key(&setting) {
|
if !scheme.map.contains_key(&color) {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!("no color for {:?} defined", setting),
|
format!("no color for {:?} defined", color),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,16 +65,20 @@ impl ColorScheme {
|
|||||||
Ok(scheme)
|
Ok(scheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn random_settings() -> ColorScheme {
|
pub fn random_colors() -> ColorScheme {
|
||||||
let mut scheme = ColorScheme {
|
let mut scheme = ColorScheme {
|
||||||
map: HashMap::new(),
|
map: BTreeMap::new(),
|
||||||
};
|
};
|
||||||
for setting in ColorSetting::iter() {
|
for color in Colors::iter() {
|
||||||
scheme.map.insert(
|
scheme
|
||||||
setting,
|
.map
|
||||||
[rand::random(), rand::random(), rand::random(), 1.0],
|
.insert(color, [rand::random(), rand::random(), rand::random(), 1.0]);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
scheme
|
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;
|
extern crate map_model;
|
||||||
|
|
||||||
|
use colors::{ColorScheme, Colors};
|
||||||
use ezgui::input::UserInput;
|
use ezgui::input::UserInput;
|
||||||
use graphics::types::Color;
|
use graphics::types::Color;
|
||||||
use map_model::{Map, Road, RoadID};
|
use map_model::{Map, Road, RoadID};
|
||||||
use piston::input::Key;
|
use piston::input::Key;
|
||||||
use render;
|
|
||||||
use std::collections::{HashSet, VecDeque};
|
use std::collections::{HashSet, VecDeque};
|
||||||
|
|
||||||
// Keeps track of state so this can be interactively visualized
|
// Keeps track of state so this can be interactively visualized
|
||||||
@ -76,16 +76,16 @@ impl Floodfiller {
|
|||||||
false
|
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) {
|
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 {
|
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
|
// TODO linear search shouldnt suck too much for interactive mode
|
||||||
if self.queue.contains(&r.id) {
|
if self.queue.contains(&r.id) {
|
||||||
return Some(render::QUEUED_COLOR);
|
return Some(cs.get(Colors::Queued));
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
|
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
use colors::{ColorScheme, Colors};
|
||||||
use ezgui::input::UserInput;
|
use ezgui::input::UserInput;
|
||||||
use ezgui::text_box::TextBox;
|
use ezgui::text_box::TextBox;
|
||||||
use graphics::types::Color;
|
use graphics::types::Color;
|
||||||
use map_model;
|
use map_model;
|
||||||
use piston::input::Key;
|
use piston::input::Key;
|
||||||
use render;
|
|
||||||
|
|
||||||
pub enum SearchState {
|
pub enum SearchState {
|
||||||
Empty,
|
Empty,
|
||||||
@ -14,18 +14,18 @@ pub enum SearchState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SearchState {
|
impl SearchState {
|
||||||
pub fn color_r(&self, r: &map_model::Road) -> Option<Color> {
|
pub fn color_r(&self, r: &map_model::Road, cs: &ColorScheme) -> Option<Color> {
|
||||||
self.choose_color(&r.osm_tags)
|
self.choose_color(&r.osm_tags, cs)
|
||||||
}
|
}
|
||||||
pub fn color_b(&self, b: &map_model::Building) -> Option<Color> {
|
pub fn color_b(&self, b: &map_model::Building, cs: &ColorScheme) -> Option<Color> {
|
||||||
self.choose_color(&b.osm_tags)
|
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 {
|
if let SearchState::FilterOSM(filter) = self {
|
||||||
for tag in osm_tags {
|
for tag in osm_tags {
|
||||||
if tag.contains(filter) {
|
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
|
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
use animation;
|
use animation;
|
||||||
|
use colors::{ColorScheme, Colors};
|
||||||
use control::ControlMap;
|
use control::ControlMap;
|
||||||
use ezgui::canvas::{Canvas, GfxCtx};
|
use ezgui::canvas::{Canvas, GfxCtx};
|
||||||
use ezgui::input::UserInput;
|
use ezgui::input::UserInput;
|
||||||
@ -139,6 +140,7 @@ impl SelectionState {
|
|||||||
draw_map: &render::DrawMap,
|
draw_map: &render::DrawMap,
|
||||||
control_map: &ControlMap,
|
control_map: &ControlMap,
|
||||||
sim: &Sim,
|
sim: &Sim,
|
||||||
|
cs: &ColorScheme,
|
||||||
g: &mut GfxCtx,
|
g: &mut GfxCtx,
|
||||||
) {
|
) {
|
||||||
match *self {
|
match *self {
|
||||||
@ -147,7 +149,7 @@ impl SelectionState {
|
|||||||
if let Some(signal) = control_map.traffic_signals.get(&id) {
|
if let Some(signal) = control_map.traffic_signals.get(&id) {
|
||||||
let (cycle, _) = signal.current_cycle_and_remaining_time(sim.time.as_time());
|
let (cycle, _) = signal.current_cycle_and_remaining_time(sim.time.as_time());
|
||||||
for t in &cycle.turns {
|
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 turn = draw_map.get_t(relevant_turns[idx % relevant_turns.len()].id);
|
||||||
let geom_turn =
|
let geom_turn =
|
||||||
geom_map.get_t(relevant_turns[idx % relevant_turns.len()].id);
|
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 {
|
for map_t in all_turns {
|
||||||
let draw_t = draw_map.get_t(map_t.id);
|
let draw_t = draw_map.get_t(map_t.id);
|
||||||
let geom_t = geom_map.get_t(map_t.id);
|
let geom_t = geom_map.get_t(map_t.id);
|
||||||
if geom_t.conflicts_with(geom_turn) {
|
if geom_t.conflicts_with(geom_turn) {
|
||||||
// TODO should we instead change color_t?
|
// 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 {
|
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
|
// 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) => {
|
SelectionState::TooltipRoad(id) => {
|
||||||
canvas.draw_mouse_tooltip(g, &draw_map.get_r(id).tooltip_lines(map, geom_map));
|
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
|
// TODO instead, since color logic is complicated anyway, just have a way to ask "are we
|
||||||
// selecting this generic ID?"
|
// 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 {
|
match *self {
|
||||||
SelectionState::SelectedRoad(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(render::SELECTED_COLOR),
|
SelectionState::TooltipRoad(id) if r.id == id => Some(cs.get(Colors::Selected)),
|
||||||
_ => None,
|
_ => 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 {
|
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,
|
_ => 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 {
|
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,
|
_ => 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 {
|
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,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn color_c(&self, c: CarID) -> Option<Color> {
|
pub fn color_c(&self, c: CarID, cs: &ColorScheme) -> Option<Color> {
|
||||||
match *self {
|
match *self {
|
||||||
SelectionState::SelectedCar(id) if c == id => Some(render::SELECTED_COLOR),
|
SelectionState::SelectedCar(id) if c == id => Some(cs.get(Colors::Selected)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,7 @@ mod parcel;
|
|||||||
mod road;
|
mod road;
|
||||||
mod turn;
|
mod turn;
|
||||||
|
|
||||||
use ezgui::canvas;
|
|
||||||
use geom;
|
use geom;
|
||||||
use graphics::types::Color;
|
|
||||||
pub use render::map::DrawMap;
|
pub use render::map::DrawMap;
|
||||||
pub use render::road::DrawRoad;
|
pub use render::road::DrawRoad;
|
||||||
pub use render::turn::DrawTurn;
|
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 BIG_ARROW_TIP_LENGTH: f64 = 1.0;
|
||||||
const TURN_ICON_ARROW_TIP_LENGTH: f64 = BIG_ARROW_TIP_LENGTH * 0.8;
|
const TURN_ICON_ARROW_TIP_LENGTH: f64 = BIG_ARROW_TIP_LENGTH * 0.8;
|
||||||
const TURN_ICON_ARROW_LENGTH: f64 = 2.0;
|
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;
|
extern crate map_model;
|
||||||
|
|
||||||
use aabb_quadtree::geom::Rect;
|
use aabb_quadtree::geom::Rect;
|
||||||
|
use colors::{ColorScheme, Colors};
|
||||||
use ezgui::canvas::GfxCtx;
|
use ezgui::canvas::GfxCtx;
|
||||||
use geom;
|
use geom;
|
||||||
use geom::geometry;
|
use geom::geometry;
|
||||||
@ -11,7 +12,7 @@ use graphics;
|
|||||||
use graphics::math::Vec2d;
|
use graphics::math::Vec2d;
|
||||||
use graphics::types::Color;
|
use graphics::types::Color;
|
||||||
use map_model::{Pt2D, RoadID};
|
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;
|
use std::f64;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[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 =
|
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) {
|
for pair in self.yellow_center_lines.windows(2) {
|
||||||
road_marking.draw(
|
road_marking.draw(
|
||||||
@ -61,9 +62,10 @@ impl DrawRoad {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_debug(&self, g: &mut GfxCtx, geom_r: &geom::GeomRoad) {
|
pub fn draw_debug(&self, g: &mut GfxCtx, cs: &ColorScheme, geom_r: &geom::GeomRoad) {
|
||||||
let line = graphics::Line::new_round(DEBUG_COLOR, PARCEL_BOUNDARY_THICKNESS / 2.0);
|
let line =
|
||||||
let circle = graphics::Ellipse::new(BRIGHT_DEBUG_COLOR);
|
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 {
|
for &(pt1, pt2) in &geom_r.lane_center_lines {
|
||||||
line.draw(
|
line.draw(
|
||||||
|
@ -4,6 +4,7 @@ extern crate aabb_quadtree;
|
|||||||
extern crate map_model;
|
extern crate map_model;
|
||||||
|
|
||||||
use aabb_quadtree::geom::Rect;
|
use aabb_quadtree::geom::Rect;
|
||||||
|
use colors::{ColorScheme, Colors};
|
||||||
use ezgui::canvas::GfxCtx;
|
use ezgui::canvas::GfxCtx;
|
||||||
use geom;
|
use geom;
|
||||||
use geom::GeomMap;
|
use geom::GeomMap;
|
||||||
@ -13,7 +14,7 @@ use graphics::math::Vec2d;
|
|||||||
use graphics::types::Color;
|
use graphics::types::Color;
|
||||||
use map_model::TurnID;
|
use map_model::TurnID;
|
||||||
use render::{BIG_ARROW_TIP_LENGTH, TURN_ICON_ARROW_LENGTH, TURN_ICON_ARROW_THICKNESS,
|
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 std::f64;
|
||||||
use vecmath;
|
use vecmath;
|
||||||
|
|
||||||
@ -78,8 +79,8 @@ impl DrawTurn {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_icon(&self, g: &mut GfxCtx, color: Color) {
|
pub fn draw_icon(&self, g: &mut GfxCtx, color: Color, cs: &ColorScheme) {
|
||||||
let circle = graphics::Ellipse::new(TURN_ICON_CIRCLE_COLOR);
|
let circle = graphics::Ellipse::new(cs.get(Colors::TurnIconCircle));
|
||||||
circle.draw(self.icon_circle, &g.ctx.draw_state, g.ctx.transform, g.gfx);
|
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);
|
let turn_line = graphics::Line::new_round(color, TURN_ICON_ARROW_THICKNESS);
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
extern crate map_model;
|
extern crate map_model;
|
||||||
|
|
||||||
use animation;
|
use animation;
|
||||||
use colors::ColorScheme;
|
use colors::{ColorScheme, Colors};
|
||||||
use control::ControlMap;
|
use control::ControlMap;
|
||||||
use ezgui::ToggleableLayer;
|
use ezgui::ToggleableLayer;
|
||||||
use ezgui::canvas;
|
use ezgui::canvas;
|
||||||
@ -64,7 +64,8 @@ pub struct UI {
|
|||||||
color_picker: ColorPicker,
|
color_picker: ColorPicker,
|
||||||
|
|
||||||
canvas: Canvas,
|
canvas: Canvas,
|
||||||
color_scheme: ColorScheme,
|
// TODO maybe never pass this to other places? Always resolve colors here?
|
||||||
|
cs: ColorScheme,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UI {
|
impl UI {
|
||||||
@ -117,7 +118,7 @@ impl UI {
|
|||||||
color_picker: ColorPicker::new(),
|
color_picker: ColorPicker::new(),
|
||||||
|
|
||||||
canvas: Canvas::new(),
|
canvas: Canvas::new(),
|
||||||
color_scheme: ColorScheme::random_settings(),
|
cs: ColorScheme::random_colors(),
|
||||||
};
|
};
|
||||||
|
|
||||||
match savestate::load("editor_state") {
|
match savestate::load("editor_state") {
|
||||||
@ -139,7 +140,7 @@ impl UI {
|
|||||||
match ColorScheme::load("color_scheme") {
|
match ColorScheme::load("color_scheme") {
|
||||||
Ok(scheme) => {
|
Ok(scheme) => {
|
||||||
println!("Loaded previous color_scheme");
|
println!("Loaded previous color_scheme");
|
||||||
ui.color_scheme = scheme;
|
ui.cs = scheme;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
println!("Couldn't load color_scheme: {}", 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
|
// 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");
|
savestate::write("editor_state", state).expect("Saving editor_state failed");
|
||||||
self.color_scheme
|
self.cs
|
||||||
.write("color_scheme")
|
.write("color_scheme")
|
||||||
.expect("Saving color_scheme failed");
|
.expect("Saving color_scheme failed");
|
||||||
println!("Saved editor_state and color_scheme");
|
println!("Saved editor_state and color_scheme");
|
||||||
@ -341,10 +342,10 @@ impl UI {
|
|||||||
for r in &roads_onscreen {
|
for r in &roads_onscreen {
|
||||||
r.draw(g, self.color_road(r.id));
|
r.draw(g, self.color_road(r.id));
|
||||||
if self.canvas.cam_zoom >= MIN_ZOOM_FOR_ROAD_MARKERS {
|
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() {
|
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() {
|
if self.show_icons.is_enabled() {
|
||||||
for t in &self.draw_map.get_turn_icons_onscreen(screen_bbox) {
|
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
|
for c in &self.sim_ctrl
|
||||||
.sim
|
.sim
|
||||||
.get_draw_cars_on_turn(t.id, &self.geom_map)
|
.get_draw_cars_on_turn(t.id, &self.geom_map)
|
||||||
@ -394,6 +395,7 @@ impl UI {
|
|||||||
&self.draw_map,
|
&self.draw_map,
|
||||||
&self.control_map,
|
&self.control_map,
|
||||||
&self.sim_ctrl.sim,
|
&self.sim_ctrl.sim,
|
||||||
|
&self.cs,
|
||||||
g,
|
g,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -489,17 +491,19 @@ impl UI {
|
|||||||
fn color_road(&self, id: map_model::RoadID) -> Color {
|
fn color_road(&self, id: map_model::RoadID) -> Color {
|
||||||
let r = self.map.get_r(id);
|
let r = self.map.get_r(id);
|
||||||
let default = match r.lane_type {
|
let default = match r.lane_type {
|
||||||
map_model::LaneType::Driving => render::ROAD_COLOR,
|
map_model::LaneType::Driving => self.cs.get(Colors::Road),
|
||||||
map_model::LaneType::Parking => render::PARKING_COLOR,
|
map_model::LaneType::Parking => self.cs.get(Colors::Parking),
|
||||||
map_model::LaneType::Sidewalk => render::SIDEWALK_COLOR,
|
map_model::LaneType::Sidewalk => self.cs.get(Colors::Sidewalk),
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO This evaluates all the color methods, which may be expensive. But the option
|
// TODO This evaluates all the color methods, which may be expensive. But the option
|
||||||
// chaining is harder to read. :(
|
// chaining is harder to read. :(
|
||||||
vec![
|
vec![
|
||||||
self.current_selection_state.color_r(r),
|
self.current_selection_state.color_r(r, &self.cs),
|
||||||
self.current_search_state.color_r(r),
|
self.current_search_state.color_r(r, &self.cs),
|
||||||
self.floodfiller.as_ref().and_then(|f| f.color_r(r)),
|
self.floodfiller
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|f| f.color_r(r, &self.cs)),
|
||||||
if self.steepness_active.is_enabled() {
|
if self.steepness_active.is_enabled() {
|
||||||
self.steepness_viz.color_r(&self.map, r)
|
self.steepness_viz.color_r(&self.map, r)
|
||||||
} else {
|
} else {
|
||||||
@ -521,29 +525,31 @@ impl UI {
|
|||||||
// TODO weird to squeeze in some quick logic here?
|
// TODO weird to squeeze in some quick logic here?
|
||||||
let default_color = if let Some(s) = self.control_map.traffic_signals.get(&i.id) {
|
let default_color = if let Some(s) = self.control_map.traffic_signals.get(&i.id) {
|
||||||
if s.changed() {
|
if s.changed() {
|
||||||
render::CHANGED_TRAFFIC_SIGNAL_INTERSECTION_COLOR
|
self.cs.get(Colors::ChangedTrafficSignalIntersection)
|
||||||
} else {
|
} else {
|
||||||
render::TRAFFIC_SIGNAL_INTERSECTION_COLOR
|
self.cs.get(Colors::TrafficSignalIntersection)
|
||||||
}
|
}
|
||||||
} else if let Some(s) = self.control_map.stop_signs.get(&i.id) {
|
} else if let Some(s) = self.control_map.stop_signs.get(&i.id) {
|
||||||
if s.changed() {
|
if s.changed() {
|
||||||
render::CHANGED_STOP_SIGN_INTERSECTION_COLOR
|
self.cs.get(Colors::ChangedStopSignIntersection)
|
||||||
} else {
|
} else {
|
||||||
render::NORMAL_INTERSECTION_COLOR
|
self.cs.get(Colors::NormalIntersection)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
render::NORMAL_INTERSECTION_COLOR
|
self.cs.get(Colors::NormalIntersection)
|
||||||
};
|
};
|
||||||
|
|
||||||
self.current_selection_state
|
self.current_selection_state
|
||||||
.color_i(i)
|
.color_i(i, &self.cs)
|
||||||
.unwrap_or(default_color)
|
.unwrap_or(default_color)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn color_turn_icon(&self, id: map_model::TurnID) -> Color {
|
fn color_turn_icon(&self, id: map_model::TurnID) -> Color {
|
||||||
let t = self.map.get_t(id);
|
let t = self.map.get_t(id);
|
||||||
// TODO traffic signal selection logic maybe moves here
|
// TODO traffic signal selection logic maybe moves here
|
||||||
self.current_selection_state.color_t(t).unwrap_or_else(|| {
|
self.current_selection_state
|
||||||
|
.color_t(t, &self.cs)
|
||||||
|
.unwrap_or_else(|| {
|
||||||
self.stop_sign_editor
|
self.stop_sign_editor
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|e| e.color_t(t, &self.control_map))
|
.and_then(|e| e.color_t(t, &self.control_map))
|
||||||
@ -554,7 +560,7 @@ impl UI {
|
|||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
self.turn_colors
|
self.turn_colors
|
||||||
.color_t(t)
|
.color_t(t)
|
||||||
.unwrap_or(render::TURN_ICON_INACTIVE_COLOR)
|
.unwrap_or(self.cs.get(Colors::TurnIconInactive))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -563,8 +569,8 @@ impl UI {
|
|||||||
fn color_building(&self, id: map_model::BuildingID) -> Color {
|
fn color_building(&self, id: map_model::BuildingID) -> Color {
|
||||||
let b = self.map.get_b(id);
|
let b = self.map.get_b(id);
|
||||||
vec![
|
vec![
|
||||||
self.current_selection_state.color_b(b),
|
self.current_selection_state.color_b(b, &self.cs),
|
||||||
self.current_search_state.color_b(b),
|
self.current_search_state.color_b(b, &self.cs),
|
||||||
if self.osm_classifier_active.is_enabled() {
|
if self.osm_classifier_active.is_enabled() {
|
||||||
self.osm_classifier.color_b(b)
|
self.osm_classifier.color_b(b)
|
||||||
} else {
|
} else {
|
||||||
@ -573,17 +579,20 @@ impl UI {
|
|||||||
].iter()
|
].iter()
|
||||||
.filter_map(|c| *c)
|
.filter_map(|c| *c)
|
||||||
.next()
|
.next()
|
||||||
.unwrap_or(render::BUILDING_COLOR)
|
.unwrap_or(self.cs.get(Colors::Building))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns (boundary, fill) color
|
// Returns (boundary, fill) color
|
||||||
fn color_parcel(&self, id: map_model::ParcelID) -> (Color, Color) {
|
fn color_parcel(&self, id: map_model::ParcelID) -> (Color, Color) {
|
||||||
let _p = self.map.get_p(id);
|
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 {
|
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;
|
return c;
|
||||||
}
|
}
|
||||||
if self.sim_ctrl.sim.is_moving(id) {
|
if self.sim_ctrl.sim.is_moving(id) {
|
||||||
|
@ -10,7 +10,6 @@ use piston::input::{Button, Event, Key, MouseButton, MouseCursorEvent, MouseScro
|
|||||||
PressEvent, ReleaseEvent};
|
PressEvent, ReleaseEvent};
|
||||||
use piston::window::Size;
|
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 BLACK: Color = [0.0, 0.0, 0.0, 1.0];
|
||||||
pub const BLUE: Color = [0.0, 0.0, 1.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];
|
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 PURPLE: Color = [0.5, 0.0, 0.5, 1.0];
|
||||||
pub const CYAN: Color = [0.0, 1.0, 1.0, 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];
|
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 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_FG_COLOR: Color = BLACK;
|
||||||
const TEXT_BG_COLOR: Color = [0.0, 1.0, 0.0, 0.5];
|
const TEXT_BG_COLOR: Color = [0.0, 1.0, 0.0, 0.5];
|
||||||
|
Loading…
Reference in New Issue
Block a user