diff --git a/fifteen_min/src/viewer.rs b/fifteen_min/src/viewer.rs index 779ae799bf..e8b0906026 100644 --- a/fifteen_min/src/viewer.rs +++ b/fifteen_min/src/viewer.rs @@ -12,7 +12,7 @@ use map_model::connectivity::WalkingOptions; use map_model::{AmenityType, Building, BuildingID, LaneType}; use widgetry::table::{Col, Filter, Table}; use widgetry::{ - lctrl, Btn, Cached, Checkbox, Choice, Color, Drawable, EventCtx, GeomBatch, GfxCtx, + lctrl, Cached, Checkbox, Choice, Color, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line, Outcome, Panel, RewriteColor, State, StyledButtons, Text, TextExt, Transition, VerticalAlignment, Widget, }; @@ -314,11 +314,9 @@ fn build_panel(ctx: &mut EventCtx, app: &App, start: &Building, isochrone: &Isoc for (amenity, buildings) in isochrone.amenities_reachable.borrow() { rows.push( - Btn::text_fg(format!("{}: {}", amenity, buildings.len())).build( - ctx, - format!("businesses: {}", amenity), - None, - ), + ctx.style() + .btn_secondary_light_text(&format!("{}: {}", amenity, buildings.len())) + .build_widget(ctx, &format!("businesses: {}", amenity)), ); } diff --git a/game/src/edit/mod.rs b/game/src/edit/mod.rs index a24996d3c7..b3c4e803a5 100644 --- a/game/src/edit/mod.rs +++ b/game/src/edit/mod.rs @@ -10,8 +10,8 @@ use map_gui::tools::{grey_out_map, ChooseSomething, ColorLegend, PopupMsg}; use map_gui::ID; use map_model::{EditCmd, IntersectionID, LaneID, LaneType, MapEdits}; use widgetry::{ - lctrl, Btn, Choice, Color, ControlState, Drawable, EventCtx, GfxCtx, HorizontalAlignment, Key, - Line, Menu, Outcome, Panel, State, StyledButtons, Text, TextExt, VerticalAlignment, Widget, + lctrl, Choice, Color, ControlState, Drawable, EventCtx, GfxCtx, HorizontalAlignment, Key, Line, + Menu, Outcome, Panel, State, StyledButtons, Text, TextExt, VerticalAlignment, Widget, }; pub use self::cluster_traffic_signals::ClusterTrafficSignalEditor; @@ -547,7 +547,11 @@ impl LoadEdits { for name in abstio::list_all_objects(abstio::path("system/proposals")) { let path = abstio::path(format!("system/proposals/{}.json", name)); if MapEdits::load(&app.primary.map, path.clone(), &mut Timer::throwaway()).is_ok() { - proposals.push(Btn::text_fg(&name).build(ctx, path, None)); + proposals.push( + ctx.style() + .btn_secondary_light_text(&name) + .build_widget(ctx, &path), + ); } } diff --git a/game/src/edit/traffic_signals/mod.rs b/game/src/edit/traffic_signals/mod.rs index 9c21e0ea1e..86f878d37c 100644 --- a/game/src/edit/traffic_signals/mod.rs +++ b/game/src/edit/traffic_signals/mod.rs @@ -10,7 +10,7 @@ use map_model::{ TurnPriority, }; use widgetry::{ - lctrl, Btn, Color, ControlState, DrawBaselayer, Drawable, EventCtx, GeomBatch, GfxCtx, + lctrl, Color, ControlState, DrawBaselayer, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line, MultiButton, Outcome, Panel, RewriteColor, State, StyledButtons, Text, TextExt, VerticalAlignment, Widget, }; @@ -546,7 +546,8 @@ fn make_top_panel(ctx: &mut EventCtx, app: &App, can_undo: bool, can_redo: bool) ]), Widget::row(row), if app.opts.dev { - Btn::text_fg("Export") + ctx.style() + .btn_secondary_light_text("Export") .tooltip(Text::from_multiline(vec![ Line("This will create a JSON file in traffic_signal_data/.").small(), Line( @@ -555,7 +556,7 @@ fn make_top_panel(ctx: &mut EventCtx, app: &App, can_undo: bool, can_redo: bool) ) .small(), ])) - .build_def(ctx, None) + .build_def(ctx) } else { Widget::nothing() }, diff --git a/game/src/info/bus.rs b/game/src/info/bus.rs index d97321df5f..c06086eafb 100644 --- a/game/src/info/bus.rs +++ b/game/src/info/bus.rs @@ -4,7 +4,7 @@ use map_gui::tools::ColorNetwork; use map_gui::ID; use map_model::{BusRoute, BusRouteID, BusStopID, PathStep}; use sim::{AgentID, CarID}; -use widgetry::{Btn, Color, EventCtx, Key, Line, StyledButtons, Text, TextExt, Widget}; +use widgetry::{Color, EventCtx, Key, Line, StyledButtons, Text, TextExt, Widget}; use crate::app::App; use crate::info::{header_btns, make_tabs, Details, Tab}; @@ -25,7 +25,11 @@ pub fn stop(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BusStopID) for r in app.primary.map.get_routes_serving_stop(id) { // Full names can overlap, so include the ID let label = format!("{} ({})", r.full_name, r.id); - rows.push(Btn::text_fg(format!("Route {}", r.short_name)).build(ctx, &label, None)); + rows.push( + ctx.style() + .btn_secondary_light_text(&format!("Route {}", r.short_name)) + .build_widget(ctx, &label), + ); details.hyperlinks.insert(label, Tab::BusRoute(r.id)); let arrivals: Vec<(Time, CarID)> = all_arrivals @@ -290,7 +294,12 @@ pub fn route(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BusRouteI // TODO Soon it'll be time to split into tabs { - rows.push(Btn::text_fg("Edit schedule").build(ctx, format!("edit {}", route.id), Key::E)); + rows.push( + ctx.style() + .btn_secondary_light_text("Edit schedule") + .hotkey(Key::E) + .build_widget(ctx, &format!("edit {}", route.id)), + ); rows.push(describe_schedule(route).draw(ctx)); } diff --git a/game/src/info/intersection.rs b/game/src/info/intersection.rs index cac5088241..c3e573c359 100644 --- a/game/src/info/intersection.rs +++ b/game/src/info/intersection.rs @@ -7,7 +7,7 @@ use map_gui::render::traffic_signal::draw_signal_stage; use map_model::{IntersectionID, IntersectionType, StageType}; use sim::AgentType; use widgetry::{ - Btn, Checkbox, Color, DrawWithTooltips, EventCtx, FanChart, GeomBatch, Line, PlotOptions, + Checkbox, Color, DrawWithTooltips, EventCtx, FanChart, GeomBatch, Line, PlotOptions, ScatterPlot, Series, StyledButtons, Text, Widget, }; @@ -220,11 +220,11 @@ pub fn current_demand( .build_def(ctx), ); if app.opts.dev { - rows.push(Btn::text_fg("Where are these agents headed?").build( - ctx, - format!("routes across {}", id), - None, - )); + rows.push( + ctx.style() + .btn_secondary_light_text("Where are these agents headed?") + .build_widget(ctx, &format!("routes across {}", id)), + ); } rows diff --git a/game/src/sandbox/dashboards/misc.rs b/game/src/sandbox/dashboards/misc.rs index 17d1fe11a0..b9b972c38a 100644 --- a/game/src/sandbox/dashboards/misc.rs +++ b/game/src/sandbox/dashboards/misc.rs @@ -2,8 +2,8 @@ use abstutil::{prettyprint_usize, Counter}; use geom::Time; use map_model::BusRouteID; use widgetry::{ - Autocomplete, Btn, DrawBaselayer, EventCtx, GfxCtx, Line, LinePlot, Outcome, Panel, - PlotOptions, Series, State, TextExt, Widget, + Autocomplete, DrawBaselayer, EventCtx, GfxCtx, Line, LinePlot, Outcome, Panel, PlotOptions, + Series, State, StyledButtons, TextExt, Widget, }; use crate::app::{App, Transition}; @@ -172,7 +172,9 @@ impl TransitRoutes { .into_iter() .map(|(boardings, alightings, waiting, name, id)| { Widget::row(vec![ - Btn::text_fg(name).build(ctx, id.to_string(), None), + ctx.style() + .btn_secondary_light_text(&name) + .build_widget(ctx, &id.to_string()), format!( "{} boardings, {} alightings, {} currently waiting", prettyprint_usize(-boardings as usize), diff --git a/map_gui/src/tools/city_picker.rs b/map_gui/src/tools/city_picker.rs index b2c6520a09..194ef05daa 100644 --- a/map_gui/src/tools/city_picker.rs +++ b/map_gui/src/tools/city_picker.rs @@ -2,7 +2,7 @@ use abstio::MapName; use geom::{Distance, Percent, Polygon, Pt2D}; use map_model::City; use widgetry::{ - Autocomplete, Btn, Color, ControlState, DrawBaselayer, EventCtx, GeomBatch, GfxCtx, Key, Line, + Autocomplete, Color, ControlState, DrawBaselayer, EventCtx, GeomBatch, GfxCtx, Key, Line, Outcome, Panel, ScreenPt, State, StyledButtons, Text, TextExt, Transition, Widget, }; @@ -271,8 +271,9 @@ impl AllCityPicker { for name in MapName::list_all_maps() { buttons.push( - Btn::text_fg(name.describe()) - .build(ctx, name.path(), None) + ctx.style() + .btn_secondary_light_text(&name.describe()) + .build_widget(ctx, &name.path()) .margin_right(10) .margin_below(10), ); diff --git a/santa/src/before_level.rs b/santa/src/before_level.rs index 16f73c1de8..82bf561695 100644 --- a/santa/src/before_level.rs +++ b/santa/src/before_level.rs @@ -11,9 +11,9 @@ use map_gui::tools::PopupMsg; use map_gui::ID; use map_model::BuildingID; use widgetry::{ - Btn, ButtonBuilder, Color, ControlState, Drawable, EventCtx, GeomBatch, GfxCtx, - HorizontalAlignment, Key, Line, Outcome, Panel, RewriteColor, State, StyledButtons, Text, - TextExt, VerticalAlignment, Widget, + ButtonBuilder, Color, ControlState, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, + Key, Line, Outcome, Panel, RewriteColor, State, StyledButtons, Text, TextExt, + VerticalAlignment, Widget, }; use crate::buildings::{BldgState, Buildings}; diff --git a/widgetry/src/lib.rs b/widgetry/src/lib.rs index a6b82b58a8..5306dcadb3 100644 --- a/widgetry/src/lib.rs +++ b/widgetry/src/lib.rs @@ -47,7 +47,7 @@ pub use crate::tools::warper::Warper; pub use crate::tools::Cached; pub use crate::widgets::autocomplete::Autocomplete; pub(crate) use crate::widgets::button::Button; -pub use crate::widgets::button::{Btn, ButtonBuilder, MultiButton}; +pub use crate::widgets::button::{ButtonBuilder, MultiButton}; pub use crate::widgets::checkbox::Checkbox; pub use crate::widgets::compare_times::CompareTimes; pub(crate) use crate::widgets::dropdown::Dropdown; diff --git a/widgetry/src/widgets/button.rs b/widgetry/src/widgets/button.rs index ace3a33a7e..fd73501591 100644 --- a/widgetry/src/widgets/button.rs +++ b/widgetry/src/widgets/button.rs @@ -29,31 +29,6 @@ pub struct Button { } impl Button { - fn widget( - ctx: &EventCtx, - normal: GeomBatch, - hovered: GeomBatch, - disabled: GeomBatch, - hotkey: Option, - action: &str, - maybe_tooltip: Option, - hitbox: Polygon, - is_disabled: bool, - ) -> Widget { - Widget::new(Box::new(Self::new( - ctx, - normal, - hovered, - disabled, - hotkey, - action, - maybe_tooltip, - hitbox, - is_disabled, - ))) - .named(action) - } - fn new( ctx: &EventCtx, normal: GeomBatch, @@ -147,16 +122,6 @@ impl WidgetImpl for Button { } } -/// A questionably named place to start creating buttons. -pub struct Btn {} - -impl Btn { - pub fn text_fg>(action: I) -> BtnBuilder { - let action = action.into(); - BtnBuilder::TextFG(action.clone(), Text::from(Line(action)), None) - } -} - #[derive(Clone, Debug, Default)] pub struct ButtonBuilder<'a> { padding: EdgeInsets, @@ -675,91 +640,6 @@ struct Label<'a> { font: Option, } -pub enum BtnBuilder { - TextFG(String, Text, Option), -} - -impl BtnBuilder { - pub fn tooltip(mut self, tooltip: Text) -> BtnBuilder { - match self { - BtnBuilder::TextFG(_, _, ref mut maybe_tooltip) => { - assert!(maybe_tooltip.is_none()); - *maybe_tooltip = Some(tooltip); - } - } - self - } - - pub fn no_tooltip(self) -> BtnBuilder { - self.tooltip(Text::new()) - } - - pub fn build, MK: Into>>( - self, - ctx: &EventCtx, - action: I, - key: MK, - ) -> Widget { - match self { - BtnBuilder::TextFG(_, normal_txt, maybe_t) => { - let (normal, hitbox) = normal_txt - .clone() - .batch(ctx) - .container() - .padding(8) - .to_geom(ctx, None); - let (hovered, _) = normal_txt - .change_fg(Color::ORANGE) - .batch(ctx) - .container() - .padding(8) - .to_geom(ctx, None); - - Button::widget( - ctx, - normal.clone(), - hovered, - normal, - key.into(), - &action.into(), - maybe_t, - hitbox, - false, - ) - .outline(2.0, Color::WHITE) - } - } - } - - // Use the text as the action - pub fn build_def>>(self, ctx: &EventCtx, key: MK) -> Widget { - match self { - BtnBuilder::TextFG(ref action, _, _) => { - assert!(!action.is_empty()); - let copy = action.clone(); - self.build(ctx, copy, key) - } - } - } - - pub fn inactive(self, ctx: &EventCtx) -> Widget { - match self { - BtnBuilder::TextFG(action, txt, _) => Widget::draw_batch( - ctx, - txt.change_fg(Color::grey(0.5)) - .render(ctx) - .batch() - .container() - .padding(8) - .outline(2.0, Color::WHITE) - .to_geom(ctx, None) - .0, - ) - .named(action), - } - } -} - // Like an image map from the old HTML days pub struct MultiButton { draw: Drawable, diff --git a/widgetry_demo/src/lib.rs b/widgetry_demo/src/lib.rs index f35392226d..5f1a8f2d3a 100644 --- a/widgetry_demo/src/lib.rs +++ b/widgetry_demo/src/lib.rs @@ -5,7 +5,7 @@ use rand_xorshift::XorShiftRng; use geom::{Angle, Duration, Percent, Polygon, Pt2D, Time}; use widgetry::{ - lctrl, Btn, Checkbox, Choice, Color, Drawable, EventCtx, Fill, GeomBatch, GfxCtx, + lctrl, Checkbox, Choice, Color, Drawable, EventCtx, Fill, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line, LinePlot, Outcome, Panel, PersistentSplit, PlotOptions, Series, SharedAppState, State, StyledButtons, Text, TextExt, Texture, Transition, UpdateType, VerticalAlignment, Widget, @@ -380,7 +380,10 @@ fn make_controls(ctx: &mut EventCtx) -> Panel { Text::from(Line("Spinner").big_heading_styled().size(18)).draw(ctx), widgetry::Spinner::new(ctx, (0, 11), 1), Widget::row(vec![ - Btn::text_fg("New faces").build(ctx, "generate new faces", Key::F), + ctx.style() + .btn_secondary_light_text("New faces") + .hotkey(Key::F) + .build_widget(ctx, "generate new faces"), Checkbox::switch(ctx, "Draw scrollable canvas", None, true), Checkbox::switch(ctx, "Show timeseries", lctrl(Key::T), false), ]), @@ -411,7 +414,9 @@ fn make_controls(ctx: &mut EventCtx) -> Panel { Choice::new("-10s", Duration::seconds(-10.0)), ], ), - Btn::text_fg("Reset Timer").build(ctx, "reset the stopwatch", None), + ctx.style() + .btn_secondary_light_text("Reset Timer") + .build_widget(ctx, "reset the stopwatch"), ]) .evenly_spaced(), Widget::row(vec![ @@ -448,7 +453,9 @@ fn make_controls(ctx: &mut EventCtx) -> Panel { Choice::new("Hot", (Texture::SAND, Texture::CACTUS)), ], ), - Btn::text_fg("Apply").build(ctx, "apply", None), + ctx.style() + .btn_secondary_light_text("Apply") + .build_widget(ctx, "apply"), ]) .margin_above(30), ]))