start an interactive legend for the minimap. pretty disjoint from real

AgentColorScheme right now
This commit is contained in:
Dustin Carlino 2019-12-16 15:40:32 -08:00
parent a7071a1bc4
commit eda40ecdec
8 changed files with 156 additions and 38 deletions

View File

@ -45,6 +45,8 @@ impl fmt::Display for Color {
}
impl Color {
// TODO Won't this confuse the shader? :P
pub const INVISIBLE: Color = Color::rgba_f(1.0, 0.0, 0.0, 0.0);
pub const BLACK: Color = Color::rgb_f(0.0, 0.0, 0.0);
pub const WHITE: Color = Color::rgb_f(1.0, 1.0, 1.0);
pub const RED: Color = Color::rgb_f(1.0, 0.0, 0.0);

View File

@ -0,0 +1,3 @@
<svg width="21" height="15" viewBox="0 0 21 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.8" d="M10.5 0.5C5.72727 0.5 1.65136 3.40267 0 7.5C1.65136 11.5973 5.72727 14.5 10.5 14.5C15.2727 14.5 19.3486 11.5973 21 7.5C19.3486 3.40267 15.2727 0.5 10.5 0.5ZM10.5 12.1667C7.86545 12.1667 5.72727 10.076 5.72727 7.5C5.72727 4.924 7.86545 2.83333 10.5 2.83333C13.1345 2.83333 15.2727 4.924 15.2727 7.5C15.2727 10.076 13.1345 12.1667 10.5 12.1667ZM10.5 4.7C8.91545 4.7 7.63636 5.95067 7.63636 7.5C7.63636 9.04933 8.91545 10.3 10.5 10.3C12.0845 10.3 13.3636 9.04933 13.3636 7.5C13.3636 5.95067 12.0845 4.7 10.5 4.7Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 652 B

View File

@ -38,7 +38,6 @@ impl ABTestMode {
(hotkey(Key::D), "diff all trips"),
(hotkey(Key::A), "stop diffing trips"),
(hotkey(Key::O), "save state"),
(hotkey(Key::Semicolon), "change agent colorscheme"),
// TODO load arbitrary savestate
],
ctx,

View File

@ -1,9 +1,9 @@
use crate::common::route_viewer::RouteViewer;
use crate::common::{RouteExplorer, TripExplorer};
use crate::game::{msg, Transition, WizardState};
use crate::render::{AgentColorScheme, MIN_ZOOM_FOR_DETAIL};
use crate::game::{msg, Transition};
use crate::render::MIN_ZOOM_FOR_DETAIL;
use crate::ui::UI;
use ezgui::{hotkey, Choice, EventCtx, GfxCtx, Key, ModalMenu};
use ezgui::{hotkey, EventCtx, GfxCtx, Key, ModalMenu};
use geom::{Pt2D, Time};
use sim::{TripID, TripResult};
@ -83,29 +83,6 @@ impl AgentTools {
}
self.route_viewer.event(ctx, ui, menu);
if menu.action("change agent colorscheme") {
return Some(Transition::Push(WizardState::new(Box::new(
|wiz, ctx, ui| {
let (_, acs) = wiz.wrap(ctx).choose("Which colorscheme for agents?", || {
let mut choices = Vec::new();
for (acs, name) in AgentColorScheme::all() {
if ui.agent_cs != acs {
choices.push(Choice::new(name, acs));
}
}
choices
})?;
ui.agent_cs = acs;
ui.agent_cs_legend = acs.make_color_legend(ctx, &ui.cs);
ui.primary.draw_map.agents.borrow_mut().invalidate_cache();
if let Some(ref mut s) = ui.secondary {
s.draw_map.agents.borrow_mut().invalidate_cache();
}
Some(Transition::Pop)
},
))));
}
if let Some(explorer) = RouteExplorer::new(ctx, ui) {
return Some(Transition::Push(Box::new(explorer)));
}

View File

@ -160,7 +160,6 @@ pub struct ColorLegend {
impl ColorLegend {
pub fn new(ctx: &EventCtx, header: Text, rows: Vec<(&str, Color)>) -> ColorLegend {
// TODO add a bg here and stop using prompt?
let mut col = vec![ManagedWidget::draw_text(ctx, header)];
let radius = 15.0;

View File

@ -1,18 +1,33 @@
use crate::render::MIN_ZOOM_FOR_DETAIL;
use crate::game::{Transition, WizardState};
use crate::managed::{Composite, ManagedWidget, Outcome};
use crate::render::{AgentColorScheme, MIN_ZOOM_FOR_DETAIL};
use crate::ui::UI;
use ezgui::{Color, EventCtx, GfxCtx, ScreenPt, ScreenRectangle};
use geom::{Distance, Polygon, Pt2D, Ring};
use ezgui::{
hotkey, Button, Choice, Color, EventCtx, GeomBatch, GfxCtx, Key, Line, RewriteColor, ScreenPt,
ScreenRectangle, Text,
};
use geom::{Circle, Distance, Polygon, Pt2D, Ring};
use std::collections::HashMap;
pub struct Minimap {
dragging: bool,
controls: VisibilityPanel,
}
impl Minimap {
pub fn new() -> Minimap {
Minimap { dragging: false }
pub fn new(ctx: &EventCtx, ui: &UI) -> Minimap {
Minimap {
dragging: false,
controls: VisibilityPanel::new(ctx, ui),
}
}
pub fn event(&mut self, ui: &mut UI, ctx: &mut EventCtx) {
pub fn event(&mut self, ui: &mut UI, ctx: &mut EventCtx) -> Option<Transition> {
if let Some(t) = self.controls.event(ctx, ui) {
return Some(t);
}
// TODO duplicate some stuff for now, until we figure out what to cache
let square_len = 0.15 * ctx.canvas.window_width;
let top_left = ScreenPt::new(
@ -38,7 +53,7 @@ impl Minimap {
} else if inner_rect.contains(pt) && ctx.input.left_mouse_button_pressed() {
self.dragging = true;
} else {
return;
return None;
}
let percent_x = (pt.x - inner_rect.x1) / (inner_rect.x2 - inner_rect.x1);
@ -53,9 +68,13 @@ impl Minimap {
let map_y2 = bounds.min_y + (inner_rect.y2 - inner_rect.y1) / zoom;
let map_pt = Pt2D::new(map_x, percent_y * (map_y2 - bounds.min_y));
ctx.canvas.center_on_map_pt(map_pt);
None
}
pub fn draw(&self, g: &mut GfxCtx, ui: &UI) {
self.controls.draw(g);
if g.canvas.cam_zoom < MIN_ZOOM_FOR_DETAIL {
return;
}
@ -154,3 +173,116 @@ fn clamp(x: f64, min: f64, max: f64) -> f64 {
x
}
}
pub struct VisibilityPanel {
composite: Composite,
enabled: HashMap<String, bool>,
}
impl VisibilityPanel {
fn make_panel(ctx: &EventCtx, entries: Vec<(String, Color, bool)>) -> Composite {
let radius = 15.0;
let mut col = vec![ManagedWidget::btn_no_cb(Button::text(
Text::from(Line("change")),
Color::INVISIBLE,
Color::ORANGE,
hotkey(Key::Semicolon),
"change agent colorscheme",
ctx,
))];
for (label, color, enabled) in entries {
// TODO Blur out when disabled
col.push(
ManagedWidget::row(vec![
ManagedWidget::btn_no_cb(Button::rectangle_svg(
"assets/tools/visibility.svg",
&format!("show/hide {}", label),
None,
RewriteColor::Change(Color::WHITE, Color::ORANGE),
ctx,
)),
ManagedWidget::draw_batch(
ctx,
GeomBatch::from(vec![(
color,
Circle::new(Pt2D::new(radius, radius), Distance::meters(radius))
.to_polygon(),
)]),
),
ManagedWidget::draw_text(ctx, Text::from(Line(label))),
])
.centered_cross(),
);
}
Composite::minimal_size(
ManagedWidget::col(col).bg(Color::grey(0.4)),
ScreenPt::new(
ctx.canvas.window_width - 550.0,
ctx.canvas.window_height - 300.0,
),
)
}
fn new(ctx: &EventCtx, ui: &UI) -> VisibilityPanel {
// TODO take over make_color_legend
let mut rows = Vec::new();
let mut enabled = HashMap::new();
for (label, color) in vec![
("car", ui.cs.get("unzoomed car")),
("bike", ui.cs.get("unzoomed bike")),
("bus", ui.cs.get("unzoomed bus")),
("pedestrian", ui.cs.get("unzoomed pedestrian")),
] {
enabled.insert(label.to_string(), true);
rows.push((label.to_string(), color, true));
}
VisibilityPanel {
composite: VisibilityPanel::make_panel(ctx, rows),
enabled,
}
}
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Option<Transition> {
match self.composite.event(ctx, ui) {
Some(Outcome::Transition(_)) => unreachable!(),
Some(Outcome::Clicked(x)) => match x.as_ref() {
"change agent colorscheme" => {
return Some(Transition::Push(WizardState::new(Box::new(
|wiz, ctx, ui| {
let (_, acs) =
wiz.wrap(ctx).choose("Which colorscheme for agents?", || {
let mut choices = Vec::new();
for (acs, name) in AgentColorScheme::all() {
if ui.agent_cs != acs {
choices.push(Choice::new(name, acs));
}
}
choices
})?;
ui.agent_cs = acs;
ui.agent_cs_legend = acs.make_color_legend(ctx, &ui.cs);
ui.primary.draw_map.agents.borrow_mut().invalidate_cache();
if let Some(ref mut s) = ui.secondary {
s.draw_map.agents.borrow_mut().invalidate_cache();
}
Some(Transition::Pop)
},
))));
}
x => {
let key = x["show/hide ".len()..].to_string();
*self.enabled.get_mut(&key).unwrap() = !self.enabled[&key];
println!("{} is now {}", key, self.enabled[&key]);
}
},
None => {}
}
None
}
fn draw(&self, g: &mut GfxCtx) {
self.composite.draw(g);
}
}

View File

@ -80,6 +80,11 @@ impl ManagedWidget {
self
}
pub fn centered_cross(mut self) -> ManagedWidget {
self.style.align_items = Some(AlignItems::Center);
self
}
pub fn evenly_spaced(mut self) -> ManagedWidget {
self.style.justify_content = Some(JustifyContent::SpaceBetween);
self

View File

@ -47,7 +47,7 @@ impl SandboxMode {
common: CommonState::new(),
tool_panel: tool_panel(ctx, Some(Box::new(Overlays::change_overlays))),
minimap: if mode.has_minimap() {
Some(Minimap::new())
Some(Minimap::new(ctx, ui))
} else {
None
},
@ -57,7 +57,6 @@ impl SandboxMode {
vec![
(lctrl(Key::E), "edit mode"),
(hotkey(Key::Q), "scoreboard"),
(hotkey(Key::Semicolon), "change agent colorscheme"),
(None, "explore a bus route"),
],
ctx,
@ -96,7 +95,9 @@ impl State for SandboxMode {
ui.recalculate_current_selection(ctx);
}
if let Some(ref mut m) = self.minimap {
m.event(ui, ctx);
if let Some(t) = m.event(ui, ctx) {
return t;
}
}
if let Some(t) = self.agent_tools.event(ctx, ui, &mut self.menu) {