mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-23 22:42:32 +03:00
Lift ChooseSomething to widgetry for bus_spotting
This commit is contained in:
parent
7af2c028fc
commit
6d2e5ee603
@ -1,6 +1,7 @@
|
||||
use map_gui::tools::{draw_isochrone, ChooseSomething, ColorLegend};
|
||||
use map_gui::tools::{draw_isochrone, ColorLegend};
|
||||
use map_gui::ID;
|
||||
use map_model::AmenityType;
|
||||
use widgetry::tools::ChooseSomething;
|
||||
use widgetry::{
|
||||
Cached, Choice, Color, Drawable, EventCtx, GfxCtx, HorizontalAlignment, Line, Panel,
|
||||
SimpleState, State, TextExt, Transition, VerticalAlignment, Widget,
|
||||
|
@ -7,7 +7,7 @@ use map_gui::colors::ColorSchemeChoice;
|
||||
use map_gui::load::MapLoader;
|
||||
use map_gui::options::OptionsPanel;
|
||||
use map_gui::render::{calculate_corners, DrawMap, DrawOptions};
|
||||
use map_gui::tools::{ChooseSomething, PromptInput};
|
||||
use map_gui::tools::PromptInput;
|
||||
use map_gui::{AppLike, ID};
|
||||
use map_model::{
|
||||
osm, ControlTrafficSignal, IntersectionID, PathConstraints, Perimeter, Position, RoadID,
|
||||
@ -15,7 +15,7 @@ use map_model::{
|
||||
};
|
||||
use sim::Sim;
|
||||
use synthpop::TripEndpoint;
|
||||
use widgetry::tools::PopupMsg;
|
||||
use widgetry::tools::{ChooseSomething, PopupMsg};
|
||||
use widgetry::{
|
||||
lctrl, Cached, Choice, Color, DrawBaselayer, Drawable, EventCtx, GeomBatch, GfxCtx,
|
||||
HorizontalAlignment, Key, Line, Outcome, Panel, State, Text, Toggle, UpdateType,
|
||||
|
@ -4,8 +4,9 @@
|
||||
use abstutil::Timer;
|
||||
use geom::{LonLat, Percent};
|
||||
use map_gui::colors::ColorSchemeChoice;
|
||||
use map_gui::tools::{ChooseSomething, CityPicker};
|
||||
use map_gui::tools::CityPicker;
|
||||
use map_gui::AppLike;
|
||||
use widgetry::tools::ChooseSomething;
|
||||
use widgetry::{Choice, EventCtx, Key, Line, Panel, SimpleState, State, Widget};
|
||||
|
||||
use crate::app::{App, Transition};
|
||||
|
@ -2,9 +2,9 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use geom::{Distance, LonLat, Pt2D, Ring};
|
||||
use map_gui::render::DrawOptions;
|
||||
use map_gui::tools::{ChooseSomething, PromptInput};
|
||||
use map_gui::tools::PromptInput;
|
||||
use widgetry::mapspace::{ObjectID, World, WorldOutcome};
|
||||
use widgetry::tools::Lasso;
|
||||
use widgetry::tools::{ChooseSomething, Lasso};
|
||||
use widgetry::{
|
||||
lctrl, Choice, Color, DrawBaselayer, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key,
|
||||
Line, Outcome, Panel, SimpleState, State, Text, TextBox, VerticalAlignment, Widget,
|
||||
|
@ -4,11 +4,11 @@ use abstutil::{prettyprint_usize, Timer};
|
||||
use geom::Speed;
|
||||
use map_gui::options::OptionsPanel;
|
||||
use map_gui::render::DrawMap;
|
||||
use map_gui::tools::{grey_out_map, ChooseSomething, ColorLegend};
|
||||
use map_gui::tools::{grey_out_map, ColorLegend};
|
||||
use map_gui::ID;
|
||||
use map_model::{EditCmd, IntersectionID, LaneID, MapEdits};
|
||||
use widgetry::mapspace::ToggleZoomed;
|
||||
use widgetry::tools::PopupMsg;
|
||||
use widgetry::tools::{ChooseSomething, PopupMsg};
|
||||
use widgetry::{
|
||||
lctrl, Choice, Color, ControlState, EventCtx, GfxCtx, HorizontalAlignment, Image, Key, Line,
|
||||
Menu, Outcome, Panel, State, Text, TextBox, TextExt, VerticalAlignment, Widget,
|
||||
|
@ -1,9 +1,9 @@
|
||||
use geom::Duration;
|
||||
use map_gui::tools::{ChooseSomething, FilePicker};
|
||||
use map_gui::tools::FilePicker;
|
||||
use map_model::{
|
||||
ControlStopSign, ControlTrafficSignal, EditCmd, EditIntersection, IntersectionID, StageType,
|
||||
};
|
||||
use widgetry::tools::PopupMsg;
|
||||
use widgetry::tools::{ChooseSomething, PopupMsg};
|
||||
use widgetry::{
|
||||
Choice, DrawBaselayer, EventCtx, Key, Line, Panel, SimpleState, Spinner, State, Text, TextExt,
|
||||
Widget,
|
||||
|
@ -2,8 +2,8 @@ use std::collections::BTreeSet;
|
||||
|
||||
use abstutil::Timer;
|
||||
use geom::Duration;
|
||||
use map_gui::tools::ChooseSomething;
|
||||
use map_model::IntersectionID;
|
||||
use widgetry::tools::ChooseSomething;
|
||||
use widgetry::{
|
||||
Choice, EventCtx, GfxCtx, HorizontalAlignment, Key, Outcome, Panel, State, TextExt, UpdateType,
|
||||
VerticalAlignment, Widget,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use geom::{Polygon, Pt2D};
|
||||
use map_gui::tools::ChooseSomething;
|
||||
use map_model::{BuildingID, IntersectionID};
|
||||
use widgetry::mapspace::{ObjectID, World, WorldOutcome};
|
||||
use widgetry::tools::ChooseSomething;
|
||||
use widgetry::{
|
||||
Choice, Color, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line, Outcome,
|
||||
Panel, State, TextExt, VerticalAlignment, Widget,
|
||||
|
@ -4,10 +4,10 @@ use maplit::btreeset;
|
||||
|
||||
use abstutil::prettyprint_usize;
|
||||
use geom::{Duration, Time};
|
||||
use map_gui::tools::{checkbox_per_mode, grey_out_map, ChooseSomething, CityPicker};
|
||||
use map_gui::tools::{checkbox_per_mode, grey_out_map, CityPicker};
|
||||
use sim::SlidingWindow;
|
||||
use synthpop::{ScenarioModifier, TripMode};
|
||||
use widgetry::tools::{PopupMsg, URLManager};
|
||||
use widgetry::tools::{ChooseSomething, PopupMsg, URLManager};
|
||||
use widgetry::{
|
||||
lctrl, Choice, Color, EventCtx, GfxCtx, HorizontalAlignment, Key, Line, LinePlot, Outcome,
|
||||
Panel, PlotOptions, Series, SimpleState, Slider, Spinner, State, Text, TextExt,
|
||||
|
@ -6,11 +6,11 @@ use map_gui::colors::ColorSchemeChoice;
|
||||
use map_gui::load::MapLoader;
|
||||
use map_gui::options::OptionsPanel;
|
||||
use map_gui::render::{unzoomed_agent_radius, UnzoomedAgents};
|
||||
use map_gui::tools::{ChooseSomething, Minimap, TurnExplorer};
|
||||
use map_gui::tools::{Minimap, TurnExplorer};
|
||||
use map_gui::{AppLike, ID};
|
||||
use sim::Analytics;
|
||||
use synthpop::Scenario;
|
||||
use widgetry::tools::{FileLoader, FutureLoader, URLManager};
|
||||
use widgetry::tools::{ChooseSomething, FileLoader, FutureLoader, URLManager};
|
||||
use widgetry::{lctrl, Choice, EventCtx, GfxCtx, Key, Outcome, Panel, State, UpdateType};
|
||||
|
||||
pub use self::gameplay::{spawn_agents_around, GameplayMode, TutorialPointer, TutorialState};
|
||||
|
@ -5,9 +5,9 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use abstio::MapName;
|
||||
use abstutil::Counter;
|
||||
use map_gui::tools::{ChooseSomething, PromptInput};
|
||||
use map_gui::tools::PromptInput;
|
||||
use map_model::PathRequest;
|
||||
use widgetry::tools::PopupMsg;
|
||||
use widgetry::tools::{ChooseSomething, PopupMsg};
|
||||
use widgetry::{Choice, EventCtx, Key, Line, State, Widget};
|
||||
|
||||
use crate::partition::BlockID;
|
||||
|
@ -2,8 +2,9 @@ use std::collections::HashSet;
|
||||
|
||||
use abstutil::prettyprint_usize;
|
||||
use geom::{ArrowCap, Circle, Distance, Duration, PolyLine, Pt2D, Time};
|
||||
use map_gui::tools::{ChooseSomething, ColorLegend, Minimap, MinimapControls};
|
||||
use map_gui::tools::{ColorLegend, Minimap, MinimapControls};
|
||||
use map_model::BuildingID;
|
||||
use widgetry::tools::ChooseSomething;
|
||||
use widgetry::{
|
||||
Choice, Color, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Image, Key, Line,
|
||||
Outcome, Panel, State, Text, TextExt, UpdateType, VerticalAlignment, Widget,
|
||||
|
@ -22,7 +22,7 @@ pub use self::trip_files::{TripManagement, TripManagementState};
|
||||
pub use self::turn_explorer::TurnExplorer;
|
||||
pub use self::ui::{
|
||||
checkbox_per_mode, cmp_count, cmp_dist, cmp_duration, color_for_mode, percentage_bar,
|
||||
ChooseSomething, FilePicker, PromptInput,
|
||||
FilePicker, PromptInput,
|
||||
};
|
||||
pub use self::waypoints::{InputWaypoints, WaypointID};
|
||||
use crate::AppLike;
|
||||
|
@ -5,12 +5,13 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use abstutil::Timer;
|
||||
use synthpop::TripEndpoint;
|
||||
use widgetry::tools::ChooseSomething;
|
||||
use widgetry::{
|
||||
Choice, Color, EventCtx, GfxCtx, Key, Line, Panel, SimpleState, State, Text, TextBox, TextExt,
|
||||
Transition, Widget,
|
||||
};
|
||||
|
||||
use crate::tools::{grey_out_map, ChooseSomething};
|
||||
use crate::tools::grey_out_map;
|
||||
use crate::AppLike;
|
||||
|
||||
/// Save sequences of waypoints as named trips. Basic file management -- save, load, browse. This
|
||||
|
@ -10,72 +10,13 @@ use geom::{Distance, Duration, Polygon};
|
||||
use synthpop::TripMode;
|
||||
use widgetry::tools::FutureLoader;
|
||||
use widgetry::{
|
||||
Choice, Color, DrawBaselayer, EventCtx, GeomBatch, GfxCtx, Key, Line, Menu, Outcome, Panel,
|
||||
State, Text, TextBox, Toggle, Transition, Widget,
|
||||
Color, DrawBaselayer, EventCtx, GeomBatch, GfxCtx, Key, Line, Outcome, Panel, State, Text,
|
||||
TextBox, Toggle, Transition, Widget,
|
||||
};
|
||||
|
||||
use crate::tools::grey_out_map;
|
||||
use crate::AppLike;
|
||||
|
||||
/// Choose something from a menu, then feed the answer to a callback.
|
||||
pub struct ChooseSomething<A: AppLike, T> {
|
||||
panel: Panel,
|
||||
// Wrapped in an Option so that we can consume it once
|
||||
cb: Option<Box<dyn FnOnce(T, &mut EventCtx, &mut A) -> Transition<A>>>,
|
||||
}
|
||||
|
||||
impl<A: AppLike + 'static, T: 'static> ChooseSomething<A, T> {
|
||||
pub fn new_state<I: Into<String>>(
|
||||
ctx: &mut EventCtx,
|
||||
query: I,
|
||||
choices: Vec<Choice<T>>,
|
||||
cb: Box<dyn FnOnce(T, &mut EventCtx, &mut A) -> Transition<A>>,
|
||||
) -> Box<dyn State<A>> {
|
||||
Box::new(ChooseSomething {
|
||||
panel: Panel::new_builder(Widget::col(vec![
|
||||
Widget::row(vec![
|
||||
Line(query).small_heading().into_widget(ctx),
|
||||
ctx.style().btn_close_widget(ctx),
|
||||
]),
|
||||
Menu::widget(ctx, choices).named("menu"),
|
||||
]))
|
||||
.build(ctx),
|
||||
cb: Some(cb),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: AppLike + 'static, T: 'static> State<A> for ChooseSomething<A, T> {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut A) -> Transition<A> {
|
||||
match self.panel.event(ctx) {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => Transition::Pop,
|
||||
_ => {
|
||||
let data = self.panel.take_menu_choice::<T>("menu");
|
||||
// If the callback doesn't replace or pop this ChooseSomething state, then
|
||||
// it'll break when the user tries to interact with the menu again.
|
||||
(self.cb.take().unwrap())(data, ctx, app)
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
if ctx.normal_left_click() && ctx.canvas.get_cursor_in_screen_space().is_none() {
|
||||
return Transition::Pop;
|
||||
}
|
||||
Transition::Keep
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_baselayer(&self) -> DrawBaselayer {
|
||||
DrawBaselayer::PreviousState
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, app: &A) {
|
||||
grey_out_map(g, app);
|
||||
self.panel.draw(g);
|
||||
}
|
||||
}
|
||||
|
||||
/// Prompt for arbitrary text input, then feed the answer to a callback.
|
||||
pub struct PromptInput<A: AppLike> {
|
||||
panel: Panel,
|
||||
|
@ -6,10 +6,9 @@ use futures_channel::mpsc;
|
||||
|
||||
use abstio::{DataPacks, Manifest, MapName};
|
||||
use abstutil::prettyprint_bytes;
|
||||
use widgetry::tools::{FutureLoader, PopupMsg};
|
||||
use widgetry::tools::{ChooseSomething, FutureLoader, PopupMsg};
|
||||
use widgetry::{EventCtx, Key, Transition};
|
||||
|
||||
use crate::tools::ChooseSomething;
|
||||
use crate::AppLike;
|
||||
|
||||
// For each city, how many total bytes do the runtime files cost to download?
|
||||
|
62
widgetry/src/tools/choose_something.rs
Normal file
62
widgetry/src/tools/choose_something.rs
Normal file
@ -0,0 +1,62 @@
|
||||
use crate::{
|
||||
Choice, DrawBaselayer, EventCtx, GfxCtx, Line, Menu, Outcome, Panel, State, Transition, Widget,
|
||||
};
|
||||
|
||||
/// Choose something from a menu, then feed the answer to a callback.
|
||||
pub struct ChooseSomething<A, T> {
|
||||
panel: Panel,
|
||||
// Wrapped in an Option so that we can consume it once
|
||||
cb: Option<Box<dyn FnOnce(T, &mut EventCtx, &mut A) -> Transition<A>>>,
|
||||
}
|
||||
|
||||
impl<A: 'static, T: 'static> ChooseSomething<A, T> {
|
||||
pub fn new_state<I: Into<String>>(
|
||||
ctx: &mut EventCtx,
|
||||
query: I,
|
||||
choices: Vec<Choice<T>>,
|
||||
cb: Box<dyn FnOnce(T, &mut EventCtx, &mut A) -> Transition<A>>,
|
||||
) -> Box<dyn State<A>> {
|
||||
Box::new(ChooseSomething {
|
||||
panel: Panel::new_builder(Widget::col(vec![
|
||||
Widget::row(vec![
|
||||
Line(query).small_heading().into_widget(ctx),
|
||||
ctx.style().btn_close_widget(ctx),
|
||||
]),
|
||||
Menu::widget(ctx, choices).named("menu"),
|
||||
]))
|
||||
.build(ctx),
|
||||
cb: Some(cb),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: 'static, T: 'static> State<A> for ChooseSomething<A, T> {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut A) -> Transition<A> {
|
||||
match self.panel.event(ctx) {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"close" => Transition::Pop,
|
||||
_ => {
|
||||
let data = self.panel.take_menu_choice::<T>("menu");
|
||||
// If the callback doesn't replace or pop this ChooseSomething state, then
|
||||
// it'll break when the user tries to interact with the menu again.
|
||||
(self.cb.take().unwrap())(data, ctx, app)
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
if ctx.normal_left_click() && ctx.canvas.get_cursor_in_screen_space().is_none() {
|
||||
return Transition::Pop;
|
||||
}
|
||||
Transition::Keep
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_baselayer(&self) -> DrawBaselayer {
|
||||
DrawBaselayer::PreviousState
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, _: &A) {
|
||||
super::grey_out_map(g);
|
||||
self.panel.draw(g);
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
mod choose_something;
|
||||
mod lasso;
|
||||
mod load;
|
||||
mod popup;
|
||||
@ -5,11 +6,15 @@ pub(crate) mod screenshot;
|
||||
mod url;
|
||||
pub(crate) mod warper;
|
||||
|
||||
pub use choose_something::ChooseSomething;
|
||||
pub use lasso::{Lasso, PolyLineLasso};
|
||||
pub use load::{FileLoader, FutureLoader, RawBytes};
|
||||
pub use popup::PopupMsg;
|
||||
pub use url::URLManager;
|
||||
|
||||
use crate::{Color, GfxCtx};
|
||||
use geom::Polygon;
|
||||
|
||||
/// Store a cached key/value pair, only recalculating when the key changes.
|
||||
pub struct Cached<K: PartialEq + Clone, V> {
|
||||
contents: Option<(K, V)>,
|
||||
@ -71,3 +76,13 @@ impl<K: PartialEq + Clone, V> Default for Cached<K, V> {
|
||||
pub fn open_browser<I: AsRef<str>>(url: I) {
|
||||
let _ = webbrowser::open(url.as_ref());
|
||||
}
|
||||
|
||||
fn grey_out_map(g: &mut GfxCtx) {
|
||||
// This is a copy of grey_out_map from map_gui, with no dependencies on App
|
||||
g.fork_screenspace();
|
||||
g.draw_polygon(
|
||||
Color::BLACK.alpha(0.6),
|
||||
Polygon::rectangle(g.canvas.window_width, g.canvas.window_height),
|
||||
);
|
||||
g.unfork();
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
use crate::{
|
||||
hotkeys, Color, DrawBaselayer, EventCtx, GfxCtx, Key, Line, Outcome, Panel, State, Text,
|
||||
Transition, Widget,
|
||||
hotkeys, DrawBaselayer, EventCtx, GfxCtx, Key, Line, Outcome, Panel, State, Text, Transition,
|
||||
Widget,
|
||||
};
|
||||
use geom::Polygon;
|
||||
|
||||
/// Display a message dialog.
|
||||
pub struct PopupMsg {
|
||||
@ -59,14 +58,7 @@ impl<A> State<A> for PopupMsg {
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, _: &A) {
|
||||
// This is a copy of grey_out_map from map_gui, with no dependencies on App
|
||||
g.fork_screenspace();
|
||||
g.draw_polygon(
|
||||
Color::BLACK.alpha(0.6),
|
||||
Polygon::rectangle(g.canvas.window_width, g.canvas.window_height),
|
||||
);
|
||||
g.unfork();
|
||||
|
||||
super::grey_out_map(g);
|
||||
self.panel.draw(g);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user