Line up the LTN left and top panels exactly, and make the background

solid
This commit is contained in:
Dustin Carlino 2022-03-08 09:18:34 +00:00
parent 477783e430
commit 5b2d5c82ff
9 changed files with 154 additions and 125 deletions

View File

@ -39,67 +39,72 @@ impl BrowseNeighborhoods {
) )
}); });
let left_panel = crate::common::left_panel_builder(Widget::col(vec![ let top_panel = crate::common::app_top_panel(ctx, app);
app.session.alt_proposals.to_widget(ctx, app), let left_panel = crate::common::left_panel_builder(
"Click a neighborhood to edit filters".text_widget(ctx), ctx,
Widget::row(vec![ &top_panel,
ctx.style()
.btn_outline
.text("Plan a route")
.hotkey(Key::R)
.build_def(ctx),
ctx.style()
.btn_outline
.text("Export to GeoJSON")
.build_def(ctx),
])
.section(ctx),
Line("Advanced").small_heading().into_widget(ctx),
Widget::col(vec![ Widget::col(vec![
app.session.alt_proposals.to_widget(ctx, app),
"Click a neighborhood to edit filters".text_widget(ctx),
Widget::row(vec![ Widget::row(vec![
"Draw neighborhoods:".text_widget(ctx).centered_vert(), ctx.style()
.btn_outline
.text("Plan a route")
.hotkey(Key::R)
.build_def(ctx),
ctx.style()
.btn_outline
.text("Export to GeoJSON")
.build_def(ctx),
])
.section(ctx),
Line("Advanced").small_heading().into_widget(ctx),
Widget::col(vec![
Widget::row(vec![
"Draw neighborhoods:".text_widget(ctx).centered_vert(),
Widget::dropdown(
ctx,
"style",
app.session.draw_neighborhood_style,
vec![
Choice::new("simple", Style::SimpleColoring),
Choice::new("cells", Style::Cells),
Choice::new("quietness", Style::Quietness),
Choice::new("all rat-runs", Style::RatRuns),
],
),
]),
Toggle::checkbox(
ctx,
"highlight boundary roads",
Key::H,
app.session.highlight_boundary_roads,
),
])
.section(ctx),
Widget::col(vec![
"Predict proposal impact".text_widget(ctx),
impact_widget(ctx, app),
])
.section(ctx),
Widget::col(vec![Widget::row(vec![
Widget::dropdown( Widget::dropdown(
ctx, ctx,
"style", "heuristic",
app.session.draw_neighborhood_style, app.session.heuristic,
vec![ Heuristic::choices(),
Choice::new("simple", Style::SimpleColoring),
Choice::new("cells", Style::Cells),
Choice::new("quietness", Style::Quietness),
Choice::new("all rat-runs", Style::RatRuns),
],
), ),
]), ctx.style()
Toggle::checkbox( .btn_outline
ctx, .text("Automatically place filters")
"highlight boundary roads", .build_def(ctx),
Key::H, ])])
app.session.highlight_boundary_roads, .section(ctx),
), ]),
]) )
.section(ctx),
Widget::col(vec![
"Predict proposal impact".text_widget(ctx),
impact_widget(ctx, app),
])
.section(ctx),
Widget::col(vec![Widget::row(vec![
Widget::dropdown(
ctx,
"heuristic",
app.session.heuristic,
Heuristic::choices(),
),
ctx.style()
.btn_outline
.text("Automatically place filters")
.build_def(ctx),
])])
.section(ctx),
]))
.build(ctx); .build(ctx);
Box::new(BrowseNeighborhoods { Box::new(BrowseNeighborhoods {
top_panel: crate::common::app_top_panel(ctx, app), top_panel,
left_panel, left_panel,
world, world,
draw_over_roads, draw_over_roads,

View File

@ -12,13 +12,13 @@ pub fn app_top_panel(ctx: &mut EventCtx, app: &App) -> Panel {
.small_heading() .small_heading()
.into_widget(ctx) .into_widget(ctx)
.centered_vert(), .centered_vert(),
map_gui::tools::change_map_btn(ctx, app), map_gui::tools::change_map_btn(ctx, app).centered_vert(),
ctx.style() ctx.style()
.btn_plain .btn_plain
.icon("system/assets/tools/search.svg") .icon("system/assets/tools/search.svg")
.hotkey(lctrl(Key::F)) .hotkey(lctrl(Key::F))
.build_widget(ctx, "search") .build_widget(ctx, "search")
.align_right(), .centered_vert(),
])) ]))
.aligned(HorizontalAlignment::Left, VerticalAlignment::Top) .aligned(HorizontalAlignment::Left, VerticalAlignment::Top)
.dims_width(PanelDims::ExactPercent(1.0)) .dims_width(PanelDims::ExactPercent(1.0))
@ -51,12 +51,14 @@ pub fn handle_top_panel(ctx: &mut EventCtx, app: &App, panel: &mut Panel) -> Opt
} }
} }
pub fn left_panel_builder(contents: Widget) -> PanelBuilder { pub fn left_panel_builder(ctx: &EventCtx, top_panel: &Panel, contents: Widget) -> PanelBuilder {
let top_height = top_panel.panel_dims().height;
Panel::new_builder(contents) Panel::new_builder(contents)
// TODO Vertical alignment below top panel is brittle
.aligned( .aligned(
HorizontalAlignment::Percent(0.0), HorizontalAlignment::Percent(0.0),
VerticalAlignment::Percent(0.1), VerticalAlignment::Below(top_height),
) )
.dims_height(PanelDims::ExactPercent(0.9)) .dims_height(PanelDims::ExactPixels(
ctx.canvas.window_height - top_height,
))
} }

View File

@ -51,6 +51,7 @@ impl Viewer {
.panel_builder( .panel_builder(
ctx, ctx,
app, app,
&self.top_panel,
Widget::col(vec![ Widget::col(vec![
ctx.style() ctx.style()
.btn_outline .btn_outline

View File

@ -46,7 +46,7 @@ impl ShowResults {
}); });
} }
let left_panel = crate::common::left_panel_builder(Widget::col(vec![ let contents = Widget::col(vec![
Widget::row(vec![ Widget::row(vec![
Line("Impact prediction").small_heading().into_widget(ctx), Line("Impact prediction").small_heading().into_widget(ctx),
ctx.style() ctx.style()
@ -60,8 +60,9 @@ impl ShowResults {
app.session.impact.filters.to_panel(ctx, app), app.session.impact.filters.to_panel(ctx, app),
app.session.impact.compare_counts.get_panel_widget(ctx).named("compare counts"), app.session.impact.compare_counts.get_panel_widget(ctx).named("compare counts"),
ctx.style().btn_outline.text("Save before/after counts to files").build_def(ctx), ctx.style().btn_outline.text("Save before/after counts to files").build_def(ctx),
])) ]);
.build(ctx); let top_panel = crate::common::app_top_panel(ctx, app);
let left_panel = crate::common::left_panel_builder(ctx, &top_panel, contents).build(ctx);
let mut batch = GeomBatch::new(); let mut batch = GeomBatch::new();
for (_, (block, color)) in app.session.partitioning.all_neighborhoods() { for (_, (block, color)) in app.session.partitioning.all_neighborhoods() {
@ -69,7 +70,7 @@ impl ShowResults {
} }
let draw_all_neighborhoods = batch.upload(ctx); let draw_all_neighborhoods = batch.upload(ctx);
Box::new(Self { Box::new(Self {
top_panel: crate::common::app_top_panel(ctx, app), top_panel,
left_panel, left_panel,
draw_all_neighborhoods, draw_all_neighborhoods,
}) })

View File

@ -3,7 +3,8 @@ use map_model::{IntersectionID, PathConstraints, RoadID};
use widgetry::mapspace::{ObjectID, World, WorldOutcome}; use widgetry::mapspace::{ObjectID, World, WorldOutcome};
use widgetry::tools::open_browser; use widgetry::tools::open_browser;
use widgetry::{ use widgetry::{
lctrl, Color, EventCtx, Image, Key, Line, PanelBuilder, TextExt, Widget, DEFAULT_CORNER_RADIUS, lctrl, Color, EventCtx, Image, Key, Line, Panel, PanelBuilder, TextExt, Widget,
DEFAULT_CORNER_RADIUS,
}; };
use crate::{ use crate::{
@ -21,9 +22,10 @@ impl Tab {
self, self,
ctx: &mut EventCtx, ctx: &mut EventCtx,
app: &App, app: &App,
top_panel: &Panel,
per_tab_contents: Widget, per_tab_contents: Widget,
) -> PanelBuilder { ) -> PanelBuilder {
crate::common::left_panel_builder(Widget::col(vec![ let contents = Widget::col(vec![
app.session.alt_proposals.to_widget(ctx, app), app.session.alt_proposals.to_widget(ctx, app),
Widget::row(vec![ Widget::row(vec![
Line("Editing neighborhood") Line("Editing neighborhood")
@ -61,7 +63,8 @@ impl Tab {
.section(ctx), .section(ctx),
self.make_buttons(ctx), self.make_buttons(ctx),
per_tab_contents.section(ctx), per_tab_contents.section(ctx),
])) ]);
crate::common::left_panel_builder(ctx, top_panel, contents)
} }
pub fn handle_action( pub fn handle_action(

View File

@ -79,6 +79,7 @@ impl BrowseRatRuns {
.panel_builder( .panel_builder(
ctx, ctx,
app, app,
&self.top_panel,
percentage_bar( percentage_bar(
ctx, ctx,
Text::from(Line(format!( Text::from(Line(format!(
@ -101,6 +102,7 @@ impl BrowseRatRuns {
.panel_builder( .panel_builder(
ctx, ctx,
app, app,
&self.top_panel,
Widget::col(vec![ Widget::col(vec![
percentage_bar( percentage_bar(
ctx, ctx,

View File

@ -64,7 +64,7 @@ impl RoutePlanner {
self.files.autosave(app); self.files.autosave(app);
let results_widget = self.recalculate_paths(ctx, app); let results_widget = self.recalculate_paths(ctx, app);
let mut panel = crate::common::left_panel_builder(Widget::col(vec![ let contents = Widget::col(vec![
app.session.alt_proposals.to_widget(ctx, app), app.session.alt_proposals.to_widget(ctx, app),
Widget::row(vec![ Widget::row(vec![
Line("Plan a route").small_heading().into_widget(ctx), Line("Plan a route").small_heading().into_widget(ctx),
@ -98,10 +98,11 @@ impl RoutePlanner {
]) ])
.into_widget(ctx), .into_widget(ctx),
results_widget, results_widget,
])) ]);
// Hovering on waypoint cards let mut panel = crate::common::left_panel_builder(ctx, &self.top_panel, contents)
.ignore_initial_events() // Hovering on waypoint cards
.build(ctx); .ignore_initial_events()
.build(ctx);
panel.restore(ctx, &self.left_panel); panel.restore(ctx, &self.left_panel);
self.left_panel = panel; self.left_panel = panel;

View File

@ -36,9 +36,11 @@ pub struct SelectBoundary {
impl SelectBoundary { impl SelectBoundary {
pub fn new_state(ctx: &mut EventCtx, app: &App, id: NeighborhoodID) -> Box<dyn State<App>> { pub fn new_state(ctx: &mut EventCtx, app: &App, id: NeighborhoodID) -> Box<dyn State<App>> {
let top_panel = crate::common::app_top_panel(ctx, app);
let left_panel = make_panel(ctx, &top_panel);
let mut state = SelectBoundary { let mut state = SelectBoundary {
top_panel: crate::common::app_top_panel(ctx, app), top_panel,
left_panel: make_panel(ctx), left_panel,
id, id,
world: World::bounded(app.map.get_bounds()), world: World::bounded(app.map.get_bounds()),
draw_boundary_roads: draw_boundary_roads(ctx, app), draw_boundary_roads: draw_boundary_roads(ctx, app),
@ -145,7 +147,7 @@ impl SelectBoundary {
} }
self.draw_boundary_roads = draw_boundary_roads(ctx, app); self.draw_boundary_roads = draw_boundary_roads(ctx, app);
self.left_panel = make_panel(ctx); self.left_panel = make_panel(ctx, &self.top_panel);
} }
Err(err) => { Err(err) => {
self.last_failed_change = Some((id, self.currently_have_block(app, id))); self.last_failed_change = Some((id, self.currently_have_block(app, id)));
@ -249,7 +251,7 @@ impl State<App> for SelectBoundary {
if let Some(polygon) = lasso.event(ctx) { if let Some(polygon) = lasso.event(ctx) {
self.lasso = None; self.lasso = None;
self.add_blocks_freehand(ctx, app, polygon); self.add_blocks_freehand(ctx, app, polygon);
self.left_panel = make_panel(ctx); self.left_panel = make_panel(ctx, &self.top_panel);
} }
return Transition::Keep; return Transition::Keep;
} }
@ -275,7 +277,7 @@ impl State<App> for SelectBoundary {
} }
"Select freehand" => { "Select freehand" => {
self.lasso = Some(Lasso::new()); self.lasso = Some(Lasso::new());
self.left_panel = make_panel_for_lasso(ctx); self.left_panel = make_panel_for_lasso(ctx, &self.top_panel);
} }
_ => unreachable!(), _ => unreachable!(),
} }
@ -319,60 +321,68 @@ impl State<App> for SelectBoundary {
} }
} }
fn make_panel(ctx: &mut EventCtx) -> Panel { fn make_panel(ctx: &mut EventCtx, top_panel: &Panel) -> Panel {
crate::common::left_panel_builder(Widget::col(vec![ crate::common::left_panel_builder(
Line("Adjusting neighborhood boundary") ctx,
.small_heading() top_panel,
Widget::col(vec![
Line("Adjusting neighborhood boundary")
.small_heading()
.into_widget(ctx),
Text::from_all(vec![
Line("Click").fg(ctx.style().text_hotkey_color),
Line(" to add/remove a block"),
])
.into_widget(ctx),
Text::from_all(vec![
Line("Hold "),
Line(Key::LeftControl.describe()).fg(ctx.style().text_hotkey_color),
Line(" and paint over blocks to add"),
])
.into_widget(ctx),
Text::from_all(vec![
Line("Hold "),
Line(Key::LeftShift.describe()).fg(ctx.style().text_hotkey_color),
Line(" and paint over blocks to remove"),
])
.into_widget(ctx), .into_widget(ctx),
Text::from_all(vec![
Line("Click").fg(ctx.style().text_hotkey_color),
Line(" to add/remove a block"),
])
.into_widget(ctx),
Text::from_all(vec![
Line("Hold "),
Line(Key::LeftControl.describe()).fg(ctx.style().text_hotkey_color),
Line(" and paint over blocks to add"),
])
.into_widget(ctx),
Text::from_all(vec![
Line("Hold "),
Line(Key::LeftShift.describe()).fg(ctx.style().text_hotkey_color),
Line(" and paint over blocks to remove"),
])
.into_widget(ctx),
ctx.style()
.btn_outline
.icon_text("system/assets/tools/select.svg", "Select freehand")
.hotkey(Key::F)
.build_def(ctx),
Widget::row(vec![
ctx.style() ctx.style()
.btn_solid_primary .btn_outline
.text("Confirm") .icon_text("system/assets/tools/select.svg", "Select freehand")
.hotkey(Key::Enter) .hotkey(Key::F)
.build_def(ctx),
ctx.style()
.btn_solid_destructive
.text("Cancel")
.hotkey(Key::Escape)
.build_def(ctx), .build_def(ctx),
Widget::row(vec![
ctx.style()
.btn_solid_primary
.text("Confirm")
.hotkey(Key::Enter)
.build_def(ctx),
ctx.style()
.btn_solid_destructive
.text("Cancel")
.hotkey(Key::Escape)
.build_def(ctx),
]),
Text::new().into_widget(ctx).named("warning"),
]), ]),
Text::new().into_widget(ctx).named("warning"), )
]))
.build(ctx) .build(ctx)
} }
fn make_panel_for_lasso(ctx: &mut EventCtx) -> Panel { fn make_panel_for_lasso(ctx: &mut EventCtx, top_panel: &Panel) -> Panel {
crate::common::left_panel_builder(Widget::col(vec![ crate::common::left_panel_builder(
"Draw a custom boundary for a neighborhood" ctx,
.text_widget(ctx) top_panel,
.centered_vert(), Widget::col(vec![
Text::from_all(vec![ "Draw a custom boundary for a neighborhood"
Line("Click and drag").fg(ctx.style().text_hotkey_color), .text_widget(ctx)
Line(" to select the blocks to add to this neighborhood"), .centered_vert(),
]) Text::from_all(vec![
.into_widget(ctx), Line("Click and drag").fg(ctx.style().text_hotkey_color),
])) Line(" to select the blocks to add to this neighborhood"),
])
.into_widget(ctx),
]),
)
.build(ctx) .build(ctx)
} }

View File

@ -361,6 +361,10 @@ impl ColorScheme {
let mut cs = ColorScheme::day_mode(); let mut cs = ColorScheme::day_mode();
cs.scheme = ColorSchemeChoice::LTN; cs.scheme = ColorSchemeChoice::LTN;
cs.private_road = None; cs.private_road = None;
cs.gui_style.panel_bg = Color::WHITE;
cs.panel_bg = cs.gui_style.panel_bg;
cs cs
} }
} }