Start rearranging the left panel, per Mara's design. #743

This commit is contained in:
Dustin Carlino 2021-09-21 10:14:16 -07:00
parent 632a527dbc
commit 0d01906b08
5 changed files with 96 additions and 84 deletions

View File

@ -2,10 +2,7 @@ use geom::Distance;
use map_gui::tools::URLManager; use map_gui::tools::URLManager;
use map_gui::ID; use map_gui::ID;
use map_model::{EditCmd, LaneType}; use map_model::{EditCmd, LaneType};
use widgetry::{ use widgetry::{lctrl, EventCtx, GfxCtx, Key, Line, Outcome, Panel, State, TextExt, Widget};
lctrl, EventCtx, GfxCtx, HorizontalAlignment, Key, Line, Outcome, Panel, State, TextExt,
VerticalAlignment, Widget,
};
use crate::app::{App, Transition}; use crate::app::{App, Transition};
use crate::edit::{LoadEdits, RoadEditor, SaveEdits}; use crate::edit::{LoadEdits, RoadEditor, SaveEdits};
@ -207,10 +204,5 @@ fn make_top_panel(ctx: &mut EventCtx, app: &App) -> Panel {
} }
// TODO Should undo/redo, save, share functionality also live here? // TODO Should undo/redo, save, share functionality also live here?
Panel::new_builder(Widget::col(vec![ Tab::Explore.make_left_panel(ctx, app, Widget::col(file_management))
Tab::Explore.make_header(ctx, app),
Widget::col(file_management).section(ctx),
]))
.aligned(HorizontalAlignment::Left, VerticalAlignment::Top)
.build(ctx)
} }

View File

@ -10,7 +10,8 @@ mod share;
use map_gui::tools::{grey_out_map, nice_map_name, open_browser, CityPicker}; use map_gui::tools::{grey_out_map, nice_map_name, open_browser, CityPicker};
use widgetry::{ use widgetry::{
lctrl, EventCtx, GfxCtx, Key, Line, Panel, SimpleState, State, Text, TextExt, Widget, lctrl, EventCtx, GfxCtx, HorizontalAlignment, Key, Line, Panel, SimpleState, State, Text,
TextExt, VerticalAlignment, Widget,
}; };
pub use self::explore::ExploreMap; pub use self::explore::ExploreMap;
@ -33,52 +34,86 @@ pub trait TakeLayers {
} }
impl Tab { impl Tab {
pub fn make_header(self, ctx: &mut EventCtx, app: &App) -> Widget { pub fn make_left_panel(self, ctx: &mut EventCtx, app: &App, contents: Widget) -> Panel {
Widget::col(vec![ // Ideally TabController could manage this, but the contents of each section are
Widget::row(vec![ // substantial, controlled by entirely different States.
ctx.style()
.btn_plain let mut contents = Some(contents.section(ctx));
.btn()
.image_path("system/assets/pregame/logo.svg") let mut col = vec![Widget::row(vec![
.image_dims(50.0) ctx.style()
.build_widget(ctx, "about A/B Street"), .btn_plain
ctx.style() .btn()
.btn_popup_icon_text( .image_path("system/assets/pregame/logo.svg")
"system/assets/tools/map.svg", .image_dims(50.0)
nice_map_name(app.primary.map.get_name()), .build_widget(ctx, "about A/B Street"),
) ctx.style()
.hotkey(lctrl(Key::L)) .btn_popup_icon_text(
.build_widget(ctx, "change map") "system/assets/tools/map.svg",
.centered_vert() nice_map_name(app.primary.map.get_name()),
.align_right(), )
]), .hotkey(lctrl(Key::L))
Widget::row(vec![ .build_widget(ctx, "change map")
ctx.style() .centered_vert()
.btn_tab .align_right(),
.icon_text("system/assets/tools/pan.svg", "Explore") ])];
.hotkey(Key::Num1)
.disabled(self == Tab::Explore) col.push(
.build_def(ctx), ctx.style()
ctx.style() .btn_tab
.btn_tab .icon_text("system/assets/tools/pan.svg", "Explore")
.icon_text("system/assets/tools/pencil.svg", "Create new bike lanes") .hotkey(Key::Num1)
.hotkey(Key::Num2) .disabled(self == Tab::Explore)
.disabled(self == Tab::Create) .build_def(ctx),
.build_def(ctx), );
ctx.style() if self == Tab::Explore {
.btn_tab col.push(contents.take().unwrap());
.icon_text("system/assets/tools/pin.svg", "Plan a route") }
.hotkey(Key::Num3)
.disabled(self == Tab::Route) col.push(
.build_def(ctx), ctx.style()
ctx.style() .btn_tab
.btn_tab .icon_text("system/assets/tools/pencil.svg", "Create new bike lanes")
.icon_text("system/assets/meters/trip_histogram.svg", "Predict impact") .hotkey(Key::Num2)
.hotkey(Key::Num4) .disabled(self == Tab::Create)
.disabled(self == Tab::PredictImpact) .build_def(ctx),
.build_def(ctx), );
]), if self == Tab::Create {
]) col.push(contents.take().unwrap());
}
col.push(
ctx.style()
.btn_tab
.icon_text("system/assets/tools/pin.svg", "Plan a route")
.hotkey(Key::Num3)
.disabled(self == Tab::Route)
.build_def(ctx),
);
if self == Tab::Route {
col.push(contents.take().unwrap());
}
col.push(
ctx.style()
.btn_tab
.icon_text("system/assets/meters/trip_histogram.svg", "Predict impact")
.hotkey(Key::Num4)
.disabled(self == Tab::PredictImpact)
.build_def(ctx),
);
if self == Tab::PredictImpact {
col.push(contents.take().unwrap());
}
let mut panel = Panel::new_builder(Widget::col(col))
.exact_height(ctx.canvas.window_height)
.aligned(HorizontalAlignment::Left, VerticalAlignment::Top);
if self == Tab::Route {
// Hovering on a card
panel = panel.ignore_initial_events();
}
panel.build(ctx)
} }
pub fn handle_action<T: TakeLayers + State<App>>( pub fn handle_action<T: TakeLayers + State<App>>(

View File

@ -8,8 +8,7 @@ use map_gui::ID;
use map_model::{PathRequest, PathStepV2, RoadID}; use map_model::{PathRequest, PathStepV2, RoadID};
use sim::{Scenario, TripEndpoint, TripMode}; use sim::{Scenario, TripEndpoint, TripMode};
use widgetry::{ use widgetry::{
Drawable, EventCtx, GfxCtx, HorizontalAlignment, Line, Outcome, Panel, Spinner, State, Text, Drawable, EventCtx, GfxCtx, Line, Outcome, Panel, Spinner, State, Text, TextExt, Widget,
TextExt, VerticalAlignment, Widget,
}; };
use crate::app::{App, Transition}; use crate::app::{App, Transition};
@ -133,7 +132,6 @@ impl State<App> for ShowGaps {
fn make_top_panel(ctx: &mut EventCtx, app: &App) -> Panel { fn make_top_panel(ctx: &mut EventCtx, app: &App) -> Panel {
let data = app.session.mode_shift.value().unwrap(); let data = app.session.mode_shift.value().unwrap();
let col = vec![ let col = vec![
Tab::PredictImpact.make_header(ctx, app),
// TODO Info button with popup explaining all the assumptions... (where scenario data comes // TODO Info button with popup explaining all the assumptions... (where scenario data comes
// from, only driving -> cycling, no off-map starts or ends, etc) // from, only driving -> cycling, no off-map starts or ends, etc)
format!( format!(
@ -155,9 +153,7 @@ fn make_top_panel(ctx: &mut EventCtx, app: &App) -> Panel {
data.results.describe().into_widget(ctx), data.results.describe().into_widget(ctx),
]; ];
Panel::new_builder(Widget::col(col)) Tab::PredictImpact.make_left_panel(ctx, app, Widget::col(col))
.aligned(HorizontalAlignment::Left, VerticalAlignment::Top)
.build(ctx)
} }
// TODO For now, it's easier to just copy pieces from sandbox/dashboards/mode_shift.rs. I'm not // TODO For now, it's easier to just copy pieces from sandbox/dashboards/mode_shift.rs. I'm not

View File

@ -3,10 +3,7 @@ use map_gui::tools::PopupMsg;
use map_model::{ use map_model::{
BufferType, Direction, DrivingSide, EditCmd, EditRoad, LaneSpec, LaneType, RoadID, BufferType, Direction, DrivingSide, EditCmd, EditRoad, LaneSpec, LaneType, RoadID,
}; };
use widgetry::{ use widgetry::{Choice, EventCtx, GfxCtx, Key, Outcome, Panel, State, TextExt, Widget};
Choice, EventCtx, GfxCtx, HorizontalAlignment, Key, Outcome, Panel, State, TextExt,
VerticalAlignment, Widget,
};
use crate::app::{App, Transition}; use crate::app::{App, Transition};
use crate::common::RouteSketcher; use crate::common::RouteSketcher;
@ -37,10 +34,7 @@ impl QuickSketch {
} }
fn update_top_panel(&mut self, ctx: &mut EventCtx, app: &App) { fn update_top_panel(&mut self, ctx: &mut EventCtx, app: &App) {
let mut col = vec![ let mut col = vec![self.route_sketcher.get_widget_to_describe(ctx)];
Tab::Create.make_header(ctx, app),
self.route_sketcher.get_widget_to_describe(ctx),
];
if self.route_sketcher.is_route_started() { if self.route_sketcher.is_route_started() {
// We're usually replacing an existing panel, except the very first time. // We're usually replacing an existing panel, except the very first time.
@ -78,9 +72,8 @@ impl QuickSketch {
.evenly_spaced(), .evenly_spaced(),
); );
} }
self.top_panel = Panel::new_builder(Widget::col(col))
.aligned(HorizontalAlignment::Left, VerticalAlignment::Top) self.top_panel = Tab::Create.make_left_panel(ctx, app, Widget::col(col));
.build(ctx);
} }
} }

View File

@ -8,9 +8,8 @@ use map_gui::tools::{grey_out_map, ChooseSomething, PopupMsg};
use map_model::{Path, PathStep, NORMAL_LANE_THICKNESS}; use map_model::{Path, PathStep, NORMAL_LANE_THICKNESS};
use sim::{TripEndpoint, TripMode}; use sim::{TripEndpoint, TripMode};
use widgetry::{ use widgetry::{
Choice, Color, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line, LinePlot, Choice, Color, Drawable, EventCtx, GeomBatch, GfxCtx, Key, Line, LinePlot, Outcome, Panel,
Outcome, Panel, PlotOptions, Series, SimpleState, Slider, State, Text, TextBox, TextExt, PlotOptions, Series, SimpleState, Slider, State, Text, TextBox, TextExt, Widget,
VerticalAlignment, Widget,
}; };
use crate::app::{App, Transition}; use crate::app::{App, Transition};
@ -55,8 +54,7 @@ impl RoutePlanner {
self.results = results; self.results = results;
let params = &app.session.routing_params; let params = &app.session.routing_params;
let mut new_panel = Panel::new_builder(Widget::col(vec![ let col = Widget::col(vec![
Tab::Route.make_header(ctx, app),
self.files.get_panel_widget(ctx), self.files.get_panel_widget(ctx),
self.waypoints.get_panel_widget(ctx), self.waypoints.get_panel_widget(ctx),
Widget::col(vec![ Widget::col(vec![
@ -81,11 +79,9 @@ impl RoutePlanner {
]) ])
.section(ctx), .section(ctx),
results_widget, results_widget,
])) ]);
.aligned(HorizontalAlignment::Left, VerticalAlignment::Top)
// Hovering on a card let mut new_panel = Tab::Route.make_left_panel(ctx, app, col);
.ignore_initial_events()
.build(ctx);
// TODO After scrolling down and dragging a slider, sometimes releasing the slider // TODO After scrolling down and dragging a slider, sometimes releasing the slider
// registers as clicking "X" on the waypoints! Maybe just replace() in that case? // registers as clicking "X" on the waypoints! Maybe just replace() in that case?