mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-29 17:34:58 +03:00
start an interactive legend for the minimap. pretty disjoint from real
AgentColorScheme right now
This commit is contained in:
parent
a7071a1bc4
commit
eda40ecdec
@ -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);
|
||||
|
3
game/assets/tools/visibility.svg
Normal file
3
game/assets/tools/visibility.svg
Normal 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 |
@ -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,
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user