move OSM search into debug mode. most players wont care about OSM metadata.

This commit is contained in:
Dustin Carlino 2019-04-26 10:21:05 -07:00
parent 4d73469ec2
commit 5450739231
5 changed files with 67 additions and 152 deletions

View File

@ -6,7 +6,7 @@ mod polygons;
use crate::game::{GameState, Mode};
use crate::objects::ID;
use crate::ui::{ShowLayers, ShowObject};
use ezgui::{Color, EventCtx, EventLoopMode, GfxCtx, Key, Text, Wizard};
use ezgui::{Color, EventCtx, EventLoopMode, GfxCtx, InputResult, Key, Text, TextBox, Wizard};
use map_model::RoadID;
use std::collections::{HashMap, HashSet};
@ -18,11 +18,13 @@ pub struct DebugMode {
objects: objects::ObjectDebugger,
hidden: HashSet<ID>,
layers: ShowLayers,
search_results: Option<(String, HashSet<ID>)>,
}
enum State {
Exploring,
Polygons(polygons::PolygonDebugger),
SearchOSM(TextBox),
}
impl DebugMode {
@ -35,6 +37,7 @@ impl DebugMode {
objects: objects::ObjectDebugger::new(),
hidden: HashSet::new(),
layers: ShowLayers::new(),
search_results: None,
}
}
@ -68,6 +71,13 @@ impl DebugMode {
if !mode.hidden.is_empty() {
txt.add_line(format!("Hiding {} things", mode.hidden.len()));
}
if let Some((ref search, ref results)) = mode.search_results {
txt.add_line(format!(
"Search for {} has {} results",
search,
results.len()
));
}
ctx.input
.set_mode_with_new_prompt("Debug Mode", txt, ctx.canvas);
if ctx.input.modal_action("quit") {
@ -159,6 +169,14 @@ impl DebugMode {
};
}
if mode.search_results.is_some() {
if ctx.input.modal_action("clear OSM search results") {
mode.search_results = None;
}
} else if ctx.input.modal_action("search OSM metadata") {
mode.state = State::SearchOSM(TextBox::new("Search for what?", None));
}
EventLoopMode::InputOnly
}
State::Polygons(ref mut debugger) => {
@ -167,6 +185,40 @@ impl DebugMode {
}
EventLoopMode::InputOnly
}
State::SearchOSM(ref mut tb) => {
match tb.event(&mut ctx.input) {
InputResult::Canceled => {
mode.state = State::Exploring;
}
InputResult::Done(filter, _) => {
mode.state = State::Exploring;
let mut ids = HashSet::new();
let map = &state.ui.state.primary.map;
for r in map.all_roads() {
if r.osm_tags
.iter()
.any(|(k, v)| format!("{} = {}", k, v).contains(&filter))
{
for l in r.all_lanes() {
ids.insert(ID::Lane(l));
}
}
}
for b in map.all_buildings() {
if b.osm_tags
.iter()
.any(|(k, v)| format!("{} = {}", k, v).contains(&filter))
{
ids.insert(ID::Building(b.id));
}
}
mode.search_results = Some((filter, ids));
}
InputResult::StillActive => {}
}
EventLoopMode::InputOnly
}
}
}
_ => unreachable!(),
@ -197,6 +249,14 @@ impl DebugMode {
.get("something associated with something else"),
);
}
if let Some((_, ref results)) = mode.search_results {
for id in results {
color_overrides.insert(
*id,
state.ui.state.cs.get_def("search result", Color::RED),
);
}
}
state
.ui
.new_draw(g, None, color_overrides, &state.ui.state.primary.sim, mode);
@ -235,6 +295,9 @@ impl DebugMode {
.new_draw(g, None, HashMap::new(), &state.ui.state.primary.sim, mode);
debugger.draw(g, &state.ui);
}
State::SearchOSM(ref tb) => {
tb.draw(g);
}
},
_ => unreachable!(),
}

View File

@ -1,5 +1,4 @@
pub mod neighborhood_summary;
pub mod search;
pub mod show_associated;
pub mod turn_cycler;
pub mod warp;

View File

@ -1,80 +0,0 @@
use crate::objects::{DrawCtx, ID};
use crate::plugins::{BlockingPlugin, PluginCtx};
use ezgui::{Color, GfxCtx, InputResult, TextBox};
pub enum SearchState {
EnteringSearch(TextBox),
FilterOSM(String),
}
impl SearchState {
pub fn new(ctx: &mut PluginCtx) -> Option<SearchState> {
if ctx.input.action_chosen("search for something") {
return Some(SearchState::EnteringSearch(TextBox::new(
"Search for what?",
None,
)));
}
None
}
// If not, act like stackable modal.
pub fn is_blocking(&self) -> bool {
match self {
SearchState::EnteringSearch(_) => true,
SearchState::FilterOSM(_) => false,
}
}
}
impl BlockingPlugin for SearchState {
fn blocking_event(&mut self, ctx: &mut PluginCtx) -> bool {
match self {
SearchState::EnteringSearch(tb) => match tb.event(&mut ctx.input) {
InputResult::Canceled => {
return false;
}
InputResult::Done(filter, _) => {
*self = SearchState::FilterOSM(filter);
}
InputResult::StillActive => {}
},
SearchState::FilterOSM(filter) => {
ctx.input.set_mode_with_prompt(
"Search",
format!("Search for {}", filter),
&ctx.canvas,
);
if ctx.input.modal_action("quit") {
return false;
}
}
};
true
}
fn draw(&self, g: &mut GfxCtx, _ctx: &DrawCtx) {
if let SearchState::EnteringSearch(tb) = self {
tb.draw(g);
}
}
// TODO This became useless for unzoomed roads!
fn color_for(&self, obj: ID, ctx: &DrawCtx) -> Option<Color> {
if let SearchState::FilterOSM(filter) = self {
let osm_tags = match obj {
ID::Lane(l) => &ctx.map.get_parent(l).osm_tags,
ID::Building(b) => &ctx.map.get_b(b).osm_tags,
_ => {
return None;
}
};
for (k, v) in osm_tags {
if format!("{} = {}", k, v).contains(filter) {
return Some(ctx.cs.get_def("search result", Color::RED));
}
}
}
None
}
}

View File

@ -76,11 +76,6 @@ impl UIState {
}
pub fn color_obj(&self, id: ID, ctx: &DrawCtx) -> Option<Color> {
if let Some(ref plugin) = self.primary_plugins.search {
if let Some(c) = plugin.color_for(id, ctx) {
return Some(c);
}
}
if let Some(ref plugin) = self.exclusive_blocking_plugin {
return plugin.color_for(id, ctx);
}
@ -115,26 +110,6 @@ impl UIState {
// Exclusive blocking plugins first
{
// Special cases of weird blocking exclusive plugins!
if self
.primary_plugins
.search
.as_ref()
.map(|p| p.is_blocking())
.unwrap_or(false)
{
if !self
.primary_plugins
.search
.as_mut()
.unwrap()
.blocking_event(&mut ctx)
{
self.primary_plugins.search = None;
}
return;
}
if self.exclusive_blocking_plugin.is_some() {
if !self
.exclusive_blocking_plugin
@ -147,10 +122,7 @@ impl UIState {
return;
}
// TODO Don't reinstantiate if search is present but nonblocking!
if let Some(p) = view::search::SearchState::new(&mut ctx) {
self.primary_plugins.search = Some(p);
} else if let Some(p) = view::warp::WarpState::new(&mut ctx) {
if let Some(p) = view::warp::WarpState::new(&mut ctx) {
self.exclusive_blocking_plugin = Some(Box::new(p));
} else if ctx.secondary.is_none() {
if let Some(p) = edit::a_b_tests::ABTestManager::new(&mut ctx) {
@ -165,16 +137,6 @@ impl UIState {
self.exclusive_blocking_plugin = Some(Box::new(p));
}
}
if self
.primary_plugins
.search
.as_ref()
.map(|p| p.is_blocking())
.unwrap_or(false)
|| self.exclusive_blocking_plugin.is_some()
{
return;
}
}
// Exclusive nonblocking plugins
@ -199,25 +161,6 @@ impl UIState {
}
}
// Stackable modal plugins
if self
.primary_plugins
.search
.as_ref()
.map(|p| !p.is_blocking())
.unwrap_or(false)
{
if !self
.primary_plugins
.search
.as_mut()
.unwrap()
.blocking_event(&mut ctx)
{
self.primary_plugins.search = None;
}
}
// Ambient plugins
for p in self.primary_plugins.ambient_plugins.iter_mut() {
p.ambient_event(&mut ctx);
@ -225,12 +168,6 @@ impl UIState {
}
pub fn draw(&self, g: &mut GfxCtx, ctx: &DrawCtx) {
if let Some(ref plugin) = self.primary_plugins.search {
plugin.draw(g, ctx);
if plugin.is_blocking() {
return;
}
}
if let Some(ref plugin) = self.exclusive_blocking_plugin {
plugin.draw(g, ctx);
return;
@ -285,16 +222,12 @@ impl PerMapUI {
// Anything that holds onto any kind of ID has to live here!
pub struct PluginsPerMap {
// When present, this either acts like exclusive blocking or like stackable modal. :\
search: Option<view::search::SearchState>,
ambient_plugins: Vec<Box<AmbientPlugin>>,
}
impl PluginsPerMap {
pub fn new(state: &PerMapUI, prerender: &Prerender, timer: &mut Timer) -> PluginsPerMap {
PluginsPerMap {
search: None,
ambient_plugins: vec![
Box::new(view::neighborhood_summary::NeighborhoodSummary::new(
&state.map,

View File

@ -45,7 +45,6 @@ impl GUI for UI {
"View",
vec![
(None, "show neighborhood summaries"),
(Some(Key::Slash), "search for something"),
(Some(Key::J), "warp to an object"),
],
),
@ -81,7 +80,6 @@ impl GUI for UI {
),
ModalMenu::new("A/B Trip Explorer", vec![(Key::Enter, "quit")]),
ModalMenu::new("A/B All Trips Explorer", vec![(Key::Enter, "quit")]),
ModalMenu::new("Search", vec![(Key::Enter, "quit")]),
ModalMenu::new("Neighborhood Summaries", vec![(Key::Enter, "quit")]),
// The new exciting things!
ModalMenu::new(
@ -156,6 +154,8 @@ impl GUI for UI {
(Key::Num5, "show/hide extra shapes"),
(Key::Num6, "show/hide geometry debug mode"),
(Key::F1, "screenshot everything"),
(Key::Slash, "search OSM metadata"),
(Key::M, "clear OSM search results"),
],
),
ModalMenu::new(