mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-25 11:44:25 +03:00
yet more layout refactor
This commit is contained in:
parent
f9cfe136e0
commit
834f060462
@ -60,31 +60,21 @@ impl App {
|
||||
}
|
||||
|
||||
let mut c = Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::row(vec![{
|
||||
let mut txt = Text::from(
|
||||
Line("Here's a bunch of text to force some scrolling.").small_heading(),
|
||||
);
|
||||
txt.add(
|
||||
Line(
|
||||
"Bug: scrolling by clicking and dragging doesn't work while the \
|
||||
stopwatch is running.",
|
||||
)
|
||||
.fg(Color::RED),
|
||||
);
|
||||
txt.draw(ctx)
|
||||
}]),
|
||||
Widget::row(vec![
|
||||
Widget::col2(vec![
|
||||
Text::from_multiline(vec![
|
||||
Line("Here's a bunch of text to force some scrolling.").small_heading(),
|
||||
Line(
|
||||
"Bug: scrolling by clicking and dragging doesn't work while the stopwatch \
|
||||
is running.",
|
||||
)
|
||||
.fg(Color::RED),
|
||||
])
|
||||
.draw(ctx),
|
||||
Widget::row2(vec![
|
||||
// Examples of styling widgets
|
||||
Widget::col(col1)
|
||||
.outline(3.0, Color::BLACK)
|
||||
.padding(5)
|
||||
.margin_right(5),
|
||||
Widget::col(col2)
|
||||
.outline(3.0, Color::BLACK)
|
||||
.padding(5)
|
||||
.margin_right(5),
|
||||
Widget::col(col3).outline(3.0, Color::BLACK).padding(5),
|
||||
Widget::col2(col1).outline(3.0, Color::BLACK).padding(5),
|
||||
Widget::col2(col2).outline(3.0, Color::BLACK).padding(5),
|
||||
Widget::col2(col3).outline(3.0, Color::BLACK).padding(5),
|
||||
]),
|
||||
LinePlot::new(
|
||||
ctx,
|
||||
@ -117,6 +107,7 @@ impl App {
|
||||
},
|
||||
),
|
||||
])
|
||||
.padding(16)
|
||||
.bg(Color::grey(0.4)),
|
||||
)
|
||||
// Don't let the panel exceed this percentage of the window. Scrollbars appear
|
||||
@ -267,36 +258,30 @@ fn setup_scrollable_canvas(ctx: &mut EventCtx) -> Drawable {
|
||||
|
||||
fn make_controls(ctx: &mut EventCtx) -> Composite {
|
||||
Composite::new(
|
||||
Widget::col(vec![
|
||||
{
|
||||
let mut txt = Text::from(Line("ezgui demo").small_heading());
|
||||
txt.add(Line(
|
||||
"Click and drag to pan, use touchpad or scroll wheel to zoom",
|
||||
));
|
||||
txt.draw(ctx)
|
||||
},
|
||||
Widget::row(vec![
|
||||
Widget::col2(vec![
|
||||
Text::from_multiline(vec![
|
||||
Line("ezgui demo").small_heading(),
|
||||
Line("Click and drag to pan, use touchpad or scroll wheel to zoom"),
|
||||
])
|
||||
.draw(ctx),
|
||||
Widget::row2(vec![
|
||||
// This just cycles between two arbitrary buttons
|
||||
Checkbox::new(
|
||||
false,
|
||||
Btn::text_bg1("Pause").build(ctx, "pause the stopwatch", hotkey(Key::Space)),
|
||||
Btn::text_bg1("Resume").build(ctx, "resume the stopwatch", hotkey(Key::Space)),
|
||||
)
|
||||
.named("paused")
|
||||
.margin(5),
|
||||
Btn::text_fg("Reset timer")
|
||||
.build(ctx, "reset the stopwatch", None)
|
||||
.margin(5),
|
||||
Btn::text_fg("New faces")
|
||||
.build(ctx, "generate new faces", hotkey(Key::F))
|
||||
.margin(5),
|
||||
Checkbox::text(ctx, "Draw scrollable canvas", None, true).margin(5),
|
||||
Checkbox::text(ctx, "Show timeseries", lctrl(Key::T), false).margin(5),
|
||||
.named("paused"),
|
||||
Btn::text_fg("Reset timer").build(ctx, "reset the stopwatch", None),
|
||||
Btn::text_fg("New faces").build(ctx, "generate new faces", hotkey(Key::F)),
|
||||
Checkbox::text(ctx, "Draw scrollable canvas", None, true),
|
||||
Checkbox::text(ctx, "Show timeseries", lctrl(Key::T), false),
|
||||
])
|
||||
.evenly_spaced(),
|
||||
"Stopwatch: ...".draw_text(ctx).named("stopwatch"),
|
||||
])
|
||||
.bg(Color::grey(0.4)),
|
||||
.bg(Color::grey(0.4))
|
||||
.padding(16),
|
||||
)
|
||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
||||
.build(ctx)
|
||||
|
@ -78,12 +78,11 @@ impl Wizard {
|
||||
if self.tb_comp.is_none() {
|
||||
self.tb_comp = Some(
|
||||
Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::row(vec![
|
||||
Widget::col2(vec![
|
||||
Widget::row2(vec![
|
||||
Line(query).small_heading().draw(ctx),
|
||||
Btn::text_fg("X")
|
||||
.build(ctx, "quit", hotkey(Key::Escape))
|
||||
.margin(5)
|
||||
.align_right(),
|
||||
]),
|
||||
Text::new().draw(ctx).named("error"),
|
||||
@ -93,7 +92,7 @@ impl Wizard {
|
||||
])
|
||||
.bg(ctx.style().panel_bg)
|
||||
.outline(5.0, Color::WHITE)
|
||||
.padding(5),
|
||||
.padding(16),
|
||||
)
|
||||
.build(ctx),
|
||||
);
|
||||
@ -264,8 +263,8 @@ impl<'a, 'b> WrappedWizard<'a, 'b> {
|
||||
);
|
||||
self.wizard.menu_comp = Some(
|
||||
Composite::new(
|
||||
Widget::row(vec![
|
||||
Widget::col(col).margin_right(15),
|
||||
Widget::row2(vec![
|
||||
Widget::col2(col),
|
||||
Btn::plaintext("X").build(self.ctx, "quit", hotkey(Key::Escape)),
|
||||
])
|
||||
.bg(self.ctx.style().panel_bg)
|
||||
@ -388,15 +387,13 @@ impl<'a, 'b> WrappedWizard<'a, 'b> {
|
||||
assert!(self.wizard.ack.is_none());
|
||||
self.wizard.ack = Some(
|
||||
Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
txt.draw(self.ctx),
|
||||
Btn::text_bg2("OK")
|
||||
.build(self.ctx, "OK", hotkey(Key::Enter))
|
||||
.margin(5),
|
||||
Btn::text_bg2("OK").build(self.ctx, "OK", hotkey(Key::Enter)),
|
||||
])
|
||||
.bg(self.ctx.style().panel_bg)
|
||||
.outline(10.0, Color::WHITE)
|
||||
.padding(10),
|
||||
.padding(16),
|
||||
)
|
||||
.build(self.ctx),
|
||||
);
|
||||
|
@ -85,7 +85,7 @@ impl CompareTimes {
|
||||
top_left: ScreenPt::new(0.0, 0.0),
|
||||
}));
|
||||
|
||||
let y_axis = Widget::col(
|
||||
let y_axis = Widget::custom_col(
|
||||
labels
|
||||
.iter()
|
||||
.rev()
|
||||
@ -102,7 +102,7 @@ impl CompareTimes {
|
||||
JustDraw::wrap(ctx, label).centered_vert().margin_right(5)
|
||||
};
|
||||
|
||||
let x_axis = Widget::row(
|
||||
let x_axis = Widget::custom_row(
|
||||
labels
|
||||
.iter()
|
||||
.map(|x| Line(x.to_string()).small().draw(ctx))
|
||||
@ -115,12 +115,13 @@ impl CompareTimes {
|
||||
|
||||
// It's a bit of work to make both the x and y axis line up with the plot. :)
|
||||
let plot_width = plot.get_width_for_forcing();
|
||||
Widget::row(vec![Widget::col(vec![
|
||||
Widget::row(vec![y_label, y_axis, plot]),
|
||||
Widget::col(vec![x_axis, x_label])
|
||||
Widget::custom_col(vec![
|
||||
Widget::custom_row(vec![y_label, y_axis, plot]),
|
||||
Widget::custom_col(vec![x_axis, x_label])
|
||||
.force_width(plot_width)
|
||||
.align_right(),
|
||||
])])
|
||||
])
|
||||
.container()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ impl<T: Yvalue<T>> LinePlot<T> {
|
||||
// The text is already scaled; don't use Widget::draw_batch and scale it again.
|
||||
row.push(JustDraw::wrap(ctx, batch));
|
||||
}
|
||||
let x_axis = Widget::row(row).padding(10);
|
||||
let x_axis = Widget::custom_row(row).padding(10).evenly_spaced();
|
||||
|
||||
let num_y_labels = 4;
|
||||
let mut col = Vec::new();
|
||||
@ -185,14 +185,15 @@ impl<T: Yvalue<T>> LinePlot<T> {
|
||||
col.push(max_y.from_percent(percent_y).prettyprint().draw_text(ctx));
|
||||
}
|
||||
col.reverse();
|
||||
let y_axis = Widget::col(col).padding(10);
|
||||
let y_axis = Widget::custom_col(col).padding(10).evenly_spaced();
|
||||
|
||||
// Don't let the x-axis fill the parent container
|
||||
Widget::row(vec![Widget::col(vec![
|
||||
Widget::custom_col(vec![
|
||||
legend.margin_below(10),
|
||||
Widget::row(vec![y_axis.evenly_spaced(), Widget::new(Box::new(plot))]),
|
||||
x_axis.evenly_spaced(),
|
||||
])])
|
||||
Widget::custom_row(vec![y_axis, Widget::new(Box::new(plot))]),
|
||||
x_axis,
|
||||
])
|
||||
.container()
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,14 +322,13 @@ pub fn make_legend<T: Yvalue<T>>(
|
||||
}
|
||||
seen.insert(s.label.clone());
|
||||
if opts.filterable {
|
||||
row.push(Widget::row(vec![
|
||||
Checkbox::colored(ctx, &s.label, s.color, !opts.disabled.contains(&s.label))
|
||||
.margin_right(8),
|
||||
row.push(Widget::row2(vec![
|
||||
Checkbox::colored(ctx, &s.label, s.color, !opts.disabled.contains(&s.label)),
|
||||
Line(&s.label).draw(ctx),
|
||||
]));
|
||||
} else {
|
||||
let radius = 15.0;
|
||||
row.push(Widget::row(vec![
|
||||
row.push(Widget::row2(vec![
|
||||
Widget::draw_batch(
|
||||
ctx,
|
||||
GeomBatch::from(vec![(
|
||||
@ -336,13 +336,12 @@ pub fn make_legend<T: Yvalue<T>>(
|
||||
Circle::new(Pt2D::new(radius, radius), Distance::meters(radius))
|
||||
.to_polygon(),
|
||||
)]),
|
||||
)
|
||||
.margin(5),
|
||||
),
|
||||
s.label.clone().draw_text(ctx),
|
||||
]));
|
||||
}
|
||||
}
|
||||
Widget::row(row).flex_wrap(ctx, 24)
|
||||
Widget::custom_row(row).flex_wrap(ctx, 24)
|
||||
}
|
||||
|
||||
// TODO If this proves useful, lift to geom
|
||||
|
@ -156,7 +156,7 @@ impl ScatterPlot {
|
||||
// The text is already scaled; don't use Widget::draw_batch and scale it again.
|
||||
row.push(JustDraw::wrap(ctx, batch));
|
||||
}
|
||||
let x_axis = Widget::row(row).padding(10);
|
||||
let x_axis = Widget::custom_row(row).padding(10).evenly_spaced();
|
||||
|
||||
let num_y_labels = 4;
|
||||
let mut col = Vec::new();
|
||||
@ -165,14 +165,15 @@ impl ScatterPlot {
|
||||
col.push(max_y.from_percent(percent_y).prettyprint().draw_text(ctx));
|
||||
}
|
||||
col.reverse();
|
||||
let y_axis = Widget::col(col).padding(10);
|
||||
let y_axis = Widget::custom_col(col).padding(10).evenly_spaced();
|
||||
|
||||
// Don't let the x-axis fill the parent container
|
||||
Widget::row(vec![Widget::col(vec![
|
||||
Widget::custom_col(vec![
|
||||
legend.margin_below(10),
|
||||
Widget::row(vec![y_axis.evenly_spaced(), Widget::new(Box::new(plot))]),
|
||||
x_axis.evenly_spaced(),
|
||||
])])
|
||||
Widget::custom_row(vec![y_axis, Widget::new(Box::new(plot))]),
|
||||
x_axis,
|
||||
])
|
||||
.container()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,16 +131,15 @@ impl Tab {
|
||||
master_col.push({
|
||||
let mut txt = Text::from(Line("A/B STREET").display_title());
|
||||
txt.add(Line("CHALLENGES").big_heading_styled());
|
||||
txt.draw(ctx).centered_horiz().margin_below(20)
|
||||
txt.draw(ctx).centered_horiz()
|
||||
});
|
||||
master_col.push(
|
||||
Btn::text_bg2("Introduction and tutorial")
|
||||
.build_def(ctx, None)
|
||||
.centered_horiz()
|
||||
.bg(app.cs.panel_bg)
|
||||
.padding(10)
|
||||
.outline(10.0, Color::BLACK)
|
||||
.margin_below(10),
|
||||
.padding(16)
|
||||
.outline(2.0, Color::BLACK),
|
||||
);
|
||||
// Slightly inconsistent: pushes twice and leaves this challenge picker open
|
||||
cbs.push((
|
||||
@ -156,13 +155,9 @@ impl Tab {
|
||||
Tab::ChallengeStage(ref n, _) => &name == n,
|
||||
};
|
||||
if current {
|
||||
flex_row.push(Btn::text_bg2(&name).inactive(ctx).margin(10));
|
||||
flex_row.push(Btn::text_bg2(&name).inactive(ctx));
|
||||
} else {
|
||||
flex_row.push(
|
||||
Btn::text_bg2(&name)
|
||||
.build_def(ctx, hotkey(Key::NUM_KEYS[idx]))
|
||||
.margin(10),
|
||||
);
|
||||
flex_row.push(Btn::text_bg2(&name).build_def(ctx, hotkey(Key::NUM_KEYS[idx])));
|
||||
cbs.push((
|
||||
name.clone(),
|
||||
Box::new(move |ctx, app| {
|
||||
@ -174,12 +169,11 @@ impl Tab {
|
||||
}
|
||||
}
|
||||
master_col.push(
|
||||
Widget::row(flex_row)
|
||||
Widget::custom_row(flex_row)
|
||||
.flex_wrap(ctx, 80)
|
||||
.bg(app.cs.panel_bg)
|
||||
.padding(10)
|
||||
.margin(10)
|
||||
.outline(10.0, Color::BLACK),
|
||||
.padding(16)
|
||||
.outline(2.0, Color::BLACK),
|
||||
);
|
||||
|
||||
let mut main_row = Vec::new();
|
||||
@ -194,9 +188,9 @@ impl Tab {
|
||||
.enumerate()
|
||||
{
|
||||
if current == idx {
|
||||
col.push(Btn::text_fg(&stage.title).inactive(ctx).margin(10));
|
||||
col.push(Btn::text_fg(&stage.title).inactive(ctx));
|
||||
} else {
|
||||
col.push(Btn::text_fg(&stage.title).build_def(ctx, None).margin(10));
|
||||
col.push(Btn::text_fg(&stage.title).build_def(ctx, None));
|
||||
let name = name.to_string();
|
||||
cbs.push((
|
||||
stage.title,
|
||||
@ -209,11 +203,10 @@ impl Tab {
|
||||
}
|
||||
}
|
||||
main_row.push(
|
||||
Widget::col(col)
|
||||
Widget::col2(col)
|
||||
.bg(app.cs.panel_bg)
|
||||
.padding(10)
|
||||
.margin(10)
|
||||
.outline(10.0, Color::BLACK),
|
||||
.padding(16)
|
||||
.outline(2.0, Color::BLACK),
|
||||
);
|
||||
}
|
||||
|
||||
@ -227,9 +220,7 @@ impl Tab {
|
||||
|
||||
let mut inner_col = vec![
|
||||
txt.draw(ctx),
|
||||
Btn::text_fg("Start!")
|
||||
.build_def(ctx, hotkey(Key::Enter))
|
||||
.margin(10),
|
||||
Btn::text_fg("Start!").build_def(ctx, hotkey(Key::Enter)),
|
||||
];
|
||||
|
||||
if let Some(scores) = app.session.high_scores.get(&challenge.gameplay) {
|
||||
@ -249,11 +240,10 @@ impl Tab {
|
||||
}
|
||||
|
||||
main_row.push(
|
||||
Widget::col(inner_col)
|
||||
Widget::col2(inner_col)
|
||||
.bg(app.cs.panel_bg)
|
||||
.padding(10)
|
||||
.margin(10)
|
||||
.outline(10.0, Color::BLACK),
|
||||
.padding(16)
|
||||
.outline(2.0, Color::BLACK),
|
||||
);
|
||||
cbs.push((
|
||||
"Start!".to_string(),
|
||||
@ -271,10 +261,10 @@ impl Tab {
|
||||
));
|
||||
}
|
||||
|
||||
master_col.push(Widget::row(main_row));
|
||||
master_col.push(Widget::row2(main_row));
|
||||
|
||||
let mut c = WrappedComposite::new(
|
||||
Composite::new(Widget::col(master_col))
|
||||
Composite::new(Widget::col2(master_col))
|
||||
.exact_size_percent(90, 85)
|
||||
.build(ctx),
|
||||
)
|
||||
|
@ -142,16 +142,17 @@ impl ColorLegend {
|
||||
);
|
||||
// Extra wrapping to make the labels stretch against just the scale, not everything else
|
||||
// TODO Long labels aren't nicely lined up with the boundaries between buckets
|
||||
Widget::custom_row(vec![Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
Widget::draw_batch(ctx, batch),
|
||||
Widget::row(
|
||||
Widget::custom_row(
|
||||
labels
|
||||
.into_iter()
|
||||
.map(|lbl| Line(lbl).small().draw(ctx))
|
||||
.collect(),
|
||||
)
|
||||
.evenly_spaced(),
|
||||
])])
|
||||
])
|
||||
.container()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,9 +312,11 @@ impl Minimap {
|
||||
|
||||
fn make_minimap_panel(ctx: &mut EventCtx, app: &App, zoom_lvl: usize) -> Composite {
|
||||
if ctx.canvas.cam_zoom < app.opts.min_zoom_for_detail {
|
||||
return Composite::new(Widget::row(vec![
|
||||
make_tool_panel(ctx, app).align_right().margin_right(16),
|
||||
make_vert_viz_panel(ctx, app).bg(app.cs.panel_bg).padding(7),
|
||||
return Composite::new(Widget::row2(vec![
|
||||
make_tool_panel(ctx, app).align_right(),
|
||||
make_vert_viz_panel(ctx, app)
|
||||
.bg(app.cs.panel_bg)
|
||||
.padding(16),
|
||||
]))
|
||||
.aligned(
|
||||
HorizontalAlignment::Right,
|
||||
@ -326,7 +328,7 @@ fn make_minimap_panel(ctx: &mut EventCtx, app: &App, zoom_lvl: usize) -> Composi
|
||||
let zoom_col = {
|
||||
let mut col = vec![Btn::svg_def("../data/system/assets/speed/speed_up.svg")
|
||||
.build(ctx, "zoom in", None)
|
||||
.margin(12)];
|
||||
.margin_below(20)];
|
||||
for i in (0..=3).rev() {
|
||||
let color = if zoom_lvl < i {
|
||||
Color::WHITE.alpha(0.2)
|
||||
@ -341,50 +343,47 @@ fn make_minimap_panel(ctx: &mut EventCtx, app: &App, zoom_lvl: usize) -> Composi
|
||||
rect,
|
||||
)
|
||||
.build(ctx, format!("zoom to level {}", i + 1), None)
|
||||
.margin(12),
|
||||
.margin_below(20),
|
||||
);
|
||||
}
|
||||
col.push(
|
||||
Btn::svg_def("../data/system/assets/speed/slow_down.svg")
|
||||
.build(ctx, "zoom out", None)
|
||||
.margin(12),
|
||||
Btn::svg_def("../data/system/assets/speed/slow_down.svg").build(ctx, "zoom out", None),
|
||||
);
|
||||
// The zoom column should start below the "pan up" arrow. But if we put it on the row with
|
||||
// <, minimap, and > then it messes up the horizontal alignment of the pan up arrow.
|
||||
// Also, double column to avoid the background color stretching to the bottom of the row.
|
||||
Widget::col(vec![Widget::col(col).bg(app.cs.inner_panel)]).margin_above(26)
|
||||
Widget::custom_col(vec![Widget::custom_col(col)
|
||||
.padding(10)
|
||||
.bg(app.cs.inner_panel)])
|
||||
.margin_above(26)
|
||||
};
|
||||
|
||||
let square_len = 0.15 * ctx.canvas.window_width;
|
||||
let minimap_controls = Widget::col(vec![
|
||||
let minimap_controls = Widget::col2(vec![
|
||||
Btn::svg_def("../data/system/assets/minimap/up.svg")
|
||||
.build(ctx, "pan up", None)
|
||||
.margin(5)
|
||||
.centered_horiz(),
|
||||
Widget::row(vec![
|
||||
Widget::row2(vec![
|
||||
Btn::svg_def("../data/system/assets/minimap/left.svg")
|
||||
.build(ctx, "pan left", None)
|
||||
.margin(5)
|
||||
.centered_vert(),
|
||||
Filler::new(ScreenDims::new(square_len, square_len)).named("minimap"),
|
||||
Btn::svg_def("../data/system/assets/minimap/right.svg")
|
||||
.build(ctx, "pan right", None)
|
||||
.margin(5)
|
||||
.centered_vert(),
|
||||
]),
|
||||
Btn::svg_def("../data/system/assets/minimap/down.svg")
|
||||
.build(ctx, "pan down", None)
|
||||
.margin(5)
|
||||
.centered_horiz(),
|
||||
]);
|
||||
|
||||
Composite::new(Widget::row(vec![
|
||||
make_tool_panel(ctx, app).margin_right(16),
|
||||
Widget::col(vec![
|
||||
Widget::row(vec![minimap_controls, zoom_col]),
|
||||
Composite::new(Widget::row2(vec![
|
||||
make_tool_panel(ctx, app),
|
||||
Widget::col2(vec![
|
||||
Widget::row2(vec![minimap_controls, zoom_col]),
|
||||
make_horiz_viz_panel(ctx, app),
|
||||
])
|
||||
.padding(7)
|
||||
.padding(16)
|
||||
.bg(app.cs.panel_bg),
|
||||
]))
|
||||
.aligned(
|
||||
@ -395,8 +394,7 @@ fn make_minimap_panel(ctx: &mut EventCtx, app: &App, zoom_lvl: usize) -> Composi
|
||||
}
|
||||
|
||||
fn make_tool_panel(ctx: &mut EventCtx, app: &App) -> Widget {
|
||||
// TODO Apply something to everything in the column
|
||||
Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
(if ctx.canvas.cam_zoom >= app.opts.min_zoom_for_detail {
|
||||
Btn::svg_def("../data/system/assets/minimap/zoom_out_fully.svg").build(
|
||||
ctx,
|
||||
@ -410,16 +408,13 @@ fn make_tool_panel(ctx: &mut EventCtx, app: &App) -> Widget {
|
||||
None,
|
||||
)
|
||||
})
|
||||
.bg(app.cs.inner_panel)
|
||||
.margin_below(16),
|
||||
.bg(app.cs.inner_panel),
|
||||
Btn::svg_def("../data/system/assets/tools/layers.svg")
|
||||
.build(ctx, "change layers", hotkey(Key::L))
|
||||
.bg(app.cs.inner_panel)
|
||||
.margin_below(16),
|
||||
.bg(app.cs.inner_panel),
|
||||
Btn::svg_def("../data/system/assets/tools/search.svg")
|
||||
.build(ctx, "search", hotkey(Key::K))
|
||||
.bg(app.cs.inner_panel)
|
||||
.margin_below(16),
|
||||
.bg(app.cs.inner_panel),
|
||||
])
|
||||
}
|
||||
|
||||
@ -431,7 +426,7 @@ fn make_horiz_viz_panel(ctx: &mut EventCtx, app: &App) -> Widget {
|
||||
}
|
||||
let last = row.pop().unwrap();
|
||||
row.push(last.margin_right(0));
|
||||
Widget::row(row)
|
||||
Widget::custom_row(row)
|
||||
}
|
||||
|
||||
fn make_vert_viz_panel(ctx: &mut EventCtx, app: &App) -> Widget {
|
||||
@ -441,10 +436,8 @@ fn make_vert_viz_panel(ctx: &mut EventCtx, app: &App) -> Widget {
|
||||
let mut row = Vec::new();
|
||||
row.push(Checkbox::colored(ctx, label, *color, *enabled).margin_right(8));
|
||||
row.push(Line(label).draw(ctx));
|
||||
col.push(Widget::row(row).margin_below(7));
|
||||
col.push(Widget::custom_row(row));
|
||||
}
|
||||
let last = col.pop().unwrap();
|
||||
col.push(last.margin_below(0));
|
||||
|
||||
Widget::col(col)
|
||||
Widget::col2(col)
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ impl Navigator {
|
||||
pub fn new(ctx: &mut EventCtx, app: &App) -> Box<dyn State> {
|
||||
Box::new(Navigator {
|
||||
composite: Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::row(vec![
|
||||
Widget::col2(vec![
|
||||
Widget::row2(vec![
|
||||
Line("Enter a street name").small_heading().draw(ctx),
|
||||
Btn::text_fg("X")
|
||||
.build(ctx, "close", hotkey(Key::Escape))
|
||||
@ -36,6 +36,7 @@ impl Navigator {
|
||||
)
|
||||
.named("street"),
|
||||
])
|
||||
.padding(16)
|
||||
.bg(app.cs.panel_bg),
|
||||
)
|
||||
.build(ctx),
|
||||
@ -104,8 +105,8 @@ impl CrossStreet {
|
||||
|
||||
Box::new(CrossStreet {
|
||||
composite: Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::row(vec![
|
||||
Widget::col2(vec![
|
||||
Widget::row2(vec![
|
||||
{
|
||||
let mut txt = Text::from(Line("What cross street?").small_heading());
|
||||
// TODO This isn't so clear...
|
||||
@ -128,7 +129,8 @@ impl CrossStreet {
|
||||
)
|
||||
.named("street"),
|
||||
])
|
||||
.bg(app.cs.panel_bg),
|
||||
.bg(app.cs.panel_bg)
|
||||
.padding(16),
|
||||
)
|
||||
.build(ctx),
|
||||
first,
|
||||
|
@ -10,15 +10,15 @@ pub fn tool_panel(ctx: &mut EventCtx, app: &App) -> WrappedComposite {
|
||||
let row = vec![
|
||||
// TODO Maybe this is confusing -- it doesn't jump to the title screen necessarily.
|
||||
// Caller has to handle this one
|
||||
Btn::svg_def("../data/system/assets/tools/home.svg")
|
||||
.build(ctx, "back", hotkey(Key::Escape))
|
||||
.margin(10),
|
||||
Btn::svg_def("../data/system/assets/tools/settings.svg")
|
||||
.build(ctx, "settings", None)
|
||||
.margin(10),
|
||||
Btn::svg_def("../data/system/assets/tools/home.svg").build(
|
||||
ctx,
|
||||
"back",
|
||||
hotkey(Key::Escape),
|
||||
),
|
||||
Btn::svg_def("../data/system/assets/tools/settings.svg").build(ctx, "settings", None),
|
||||
];
|
||||
WrappedComposite::new(
|
||||
Composite::new(Widget::row(row).bg(app.cs.panel_bg))
|
||||
Composite::new(Widget::row2(row).bg(app.cs.panel_bg).padding(16))
|
||||
.aligned(HorizontalAlignment::Left, VerticalAlignment::BottomAboveOSD)
|
||||
.build(ctx),
|
||||
)
|
||||
|
@ -54,8 +54,8 @@ impl Floodfiller {
|
||||
let (unzoomed, zoomed, legend) = colorer.build(ctx);
|
||||
Box::new(Floodfiller {
|
||||
composite: Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::row(vec![
|
||||
Widget::col2(vec![
|
||||
Widget::row2(vec![
|
||||
Line(title).small_heading().draw(ctx),
|
||||
Btn::text_fg("X")
|
||||
.build(ctx, "close", hotkey(Key::Escape))
|
||||
|
@ -35,23 +35,21 @@ impl DebugMode {
|
||||
pub fn new(ctx: &mut EventCtx, app: &App) -> DebugMode {
|
||||
DebugMode {
|
||||
composite: Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::row(vec![
|
||||
Widget::col2(vec![
|
||||
Widget::row2(vec![
|
||||
Line("Debug Mode").small_heading().draw(ctx),
|
||||
Btn::text_fg("X")
|
||||
.build(ctx, "close", hotkey(Key::Escape))
|
||||
.align_right(),
|
||||
]),
|
||||
Text::new().draw(ctx).named("current info"),
|
||||
Checkbox::text(ctx, "show buildings", hotkey(Key::Num1), true).margin_below(5),
|
||||
Checkbox::text(ctx, "show intersections", hotkey(Key::Num2), true)
|
||||
.margin_below(5),
|
||||
Checkbox::text(ctx, "show lanes", hotkey(Key::Num3), true).margin_below(5),
|
||||
Checkbox::text(ctx, "show areas", hotkey(Key::Num4), true).margin_below(5),
|
||||
Checkbox::text(ctx, "show labels", hotkey(Key::Num5), false).margin_below(5),
|
||||
Checkbox::text(ctx, "show route for all agents", hotkey(Key::R), false)
|
||||
.margin_below(5),
|
||||
Widget::col(
|
||||
Checkbox::text(ctx, "show buildings", hotkey(Key::Num1), true),
|
||||
Checkbox::text(ctx, "show intersections", hotkey(Key::Num2), true),
|
||||
Checkbox::text(ctx, "show lanes", hotkey(Key::Num3), true),
|
||||
Checkbox::text(ctx, "show areas", hotkey(Key::Num4), true),
|
||||
Checkbox::text(ctx, "show labels", hotkey(Key::Num5), false),
|
||||
Checkbox::text(ctx, "show route for all agents", hotkey(Key::R), false),
|
||||
Widget::col2(
|
||||
vec![
|
||||
(lctrl(Key::H), "unhide everything"),
|
||||
(None, "screenshot everything"),
|
||||
@ -64,13 +62,11 @@ impl DebugMode {
|
||||
(None, "find bad traffic signals"),
|
||||
]
|
||||
.into_iter()
|
||||
.map(|(key, action)| {
|
||||
Btn::text_fg(action).build_def(ctx, key).margin_below(5)
|
||||
})
|
||||
.map(|(key, action)| Btn::text_fg(action).build_def(ctx, key))
|
||||
.collect(),
|
||||
),
|
||||
])
|
||||
.padding(10)
|
||||
.padding(16)
|
||||
.bg(app.cs.panel_bg),
|
||||
)
|
||||
.aligned(HorizontalAlignment::Right, VerticalAlignment::Top)
|
||||
|
@ -137,17 +137,14 @@ impl State for PolygonDebugger {
|
||||
|
||||
fn make_panel(ctx: &mut EventCtx, app: &App) -> Composite {
|
||||
Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::row(vec![
|
||||
Line("Geometry debugger")
|
||||
.small_heading()
|
||||
.draw(ctx)
|
||||
.margin(5),
|
||||
Widget::col2(vec![
|
||||
Widget::row2(vec![
|
||||
Line("Geometry debugger").small_heading().draw(ctx),
|
||||
Btn::text_fg("X")
|
||||
.build(ctx, "close", hotkey(Key::Escape))
|
||||
.align_right(),
|
||||
]),
|
||||
Widget::row(vec![
|
||||
Widget::row2(vec![
|
||||
// TODO inactive
|
||||
Btn::text_fg("<").build(ctx, "previous", hotkey(Key::LeftArrow)),
|
||||
"noun X/Y".draw_text(ctx).named("pointer"),
|
||||
@ -159,7 +156,7 @@ fn make_panel(ctx: &mut EventCtx, app: &App) -> Composite {
|
||||
.centered_horiz(),
|
||||
])
|
||||
.bg(app.cs.panel_bg)
|
||||
.padding(5),
|
||||
.padding(16),
|
||||
)
|
||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
||||
.build(ctx)
|
||||
|
@ -22,7 +22,7 @@ impl ClusterTrafficSignalEditor {
|
||||
app.primary.current_selection = None;
|
||||
Box::new(ClusterTrafficSignalEditor {
|
||||
composite: Composite::new(
|
||||
Widget::row(vec![
|
||||
Widget::row2(vec![
|
||||
Btn::text_fg("Finish").build_def(ctx, hotkey(Key::Escape))
|
||||
])
|
||||
.bg(app.cs.panel_bg),
|
||||
|
@ -48,7 +48,7 @@ impl StopSignEditor {
|
||||
.collect();
|
||||
|
||||
let composite = Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
"Stop sign editor".draw_text(ctx),
|
||||
if ControlStopSign::new(&app.primary.map, id)
|
||||
!= app.primary.map.get_stop_sign(id).clone()
|
||||
@ -62,7 +62,7 @@ impl StopSignEditor {
|
||||
Btn::text_fg("Finish").build_def(ctx, hotkey(Key::Escape)),
|
||||
])
|
||||
.bg(app.cs.panel_bg)
|
||||
.padding(10),
|
||||
.padding(16),
|
||||
)
|
||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
||||
.build(ctx);
|
||||
|
@ -234,5 +234,5 @@ pub fn checkbox_per_mode(
|
||||
);
|
||||
filters.push(m.ongoing_verb().draw_text(ctx).margin_right(10));
|
||||
}
|
||||
Widget::row(filters)
|
||||
Widget::custom_row(filters)
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ pub fn people(ctx: &mut EventCtx, app: &App, details: &mut Details, id: Building
|
||||
details
|
||||
.hyperlinks
|
||||
.insert(p.to_string(), Tab::PersonTrips(p, BTreeMap::new()));
|
||||
let widget = Widget::col(vec![
|
||||
let widget = Widget::col2(vec![
|
||||
Btn::text_bg1(p.to_string()).build_def(ctx, None),
|
||||
if let Some((t, mode)) = next_trip {
|
||||
format!(
|
||||
@ -161,7 +161,7 @@ fn header(
|
||||
) -> Vec<Widget> {
|
||||
let mut rows = vec![];
|
||||
|
||||
rows.push(Widget::row(vec![
|
||||
rows.push(Widget::row2(vec![
|
||||
Line(id.to_string()).small_heading().draw(ctx),
|
||||
header_btns(ctx),
|
||||
]));
|
||||
|
@ -15,7 +15,7 @@ pub fn stop(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BusStopID)
|
||||
|
||||
let sim = &app.primary.sim;
|
||||
|
||||
rows.push(Widget::row(vec![
|
||||
rows.push(Widget::row2(vec![
|
||||
Line("Bus stop").small_heading().draw(ctx),
|
||||
header_btns(ctx),
|
||||
]));
|
||||
@ -99,7 +99,7 @@ fn bus_header(
|
||||
}
|
||||
|
||||
let mut rows = vec![];
|
||||
rows.push(Widget::row(vec![
|
||||
rows.push(Widget::row2(vec![
|
||||
Line(format!(
|
||||
"{} (route {})",
|
||||
id,
|
||||
@ -145,9 +145,9 @@ fn delays_over_time(ctx: &mut EventCtx, app: &App, id: BusRouteID) -> Widget {
|
||||
.unwrap_or_else(Vec::new),
|
||||
});
|
||||
}
|
||||
Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
Line("Delays between stops").small_heading().draw(ctx),
|
||||
LinePlot::new(ctx, series, PlotOptions::fixed()).margin(10),
|
||||
LinePlot::new(ctx, series, PlotOptions::fixed()),
|
||||
])
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ fn passenger_delay(ctx: &mut EventCtx, app: &App, details: &mut Details, id: Bus
|
||||
.bus_passenger_delays(app.primary.sim.time(), id)
|
||||
.collect::<BTreeMap<_, _>>();
|
||||
for idx in 0..route.stops.len() {
|
||||
col.push(Widget::row(vec![
|
||||
col.push(Widget::row2(vec![
|
||||
format!("Stop {}", idx + 1).draw_text(ctx),
|
||||
Btn::svg(
|
||||
"../data/system/assets/tools/pin.svg",
|
||||
@ -214,10 +214,7 @@ fn passenger_delay(ctx: &mut EventCtx, app: &App, details: &mut Details, id: Bus
|
||||
}
|
||||
let timeline = Widget::draw_batch(ctx, batch);
|
||||
|
||||
master_col.push(Widget::row(vec![
|
||||
timeline.margin(5),
|
||||
Widget::col(col).margin(5),
|
||||
]));
|
||||
master_col.push(Widget::row2(vec![timeline, Widget::col2(col)]));
|
||||
|
||||
Widget::col(master_col)
|
||||
Widget::col2(master_col)
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use map_model::AreaID;
|
||||
pub fn area(ctx: &EventCtx, app: &App, _: &mut Details, id: AreaID) -> Vec<Widget> {
|
||||
let mut rows = vec![];
|
||||
|
||||
rows.push(Widget::row(vec![
|
||||
rows.push(Widget::row2(vec![
|
||||
Line(id.to_string()).small_heading().draw(ctx),
|
||||
header_btns(ctx),
|
||||
]));
|
||||
|
@ -58,7 +58,7 @@ pub fn traffic(
|
||||
)));
|
||||
rows.push(txt.draw(ctx));
|
||||
|
||||
rows.push(opts.to_controls(ctx, app).margin_below(15));
|
||||
rows.push(opts.to_controls(ctx, app));
|
||||
|
||||
let time = if opts.show_end_of_day {
|
||||
app.primary.sim.get_end_of_day()
|
||||
@ -98,7 +98,7 @@ pub fn delay(
|
||||
let i = app.primary.map.get_i(id);
|
||||
|
||||
assert!(i.is_traffic_signal());
|
||||
rows.push(opts.to_controls(ctx, app).margin_below(10));
|
||||
rows.push(opts.to_controls(ctx, app));
|
||||
|
||||
rows.push(delay_plot(ctx, app, id, opts));
|
||||
|
||||
@ -168,13 +168,10 @@ pub fn current_demand(
|
||||
);
|
||||
|
||||
rows.push(
|
||||
Widget::col(vec![
|
||||
txt.draw(ctx).margin_below(10),
|
||||
Widget::draw_batch(ctx, batch),
|
||||
])
|
||||
.padding(10)
|
||||
.bg(app.cs.inner_panel)
|
||||
.outline(2.0, Color::WHITE),
|
||||
Widget::col2(vec![txt.draw(ctx), Widget::draw_batch(ctx, batch)])
|
||||
.padding(10)
|
||||
.bg(app.cs.inner_panel)
|
||||
.outline(2.0, Color::WHITE),
|
||||
);
|
||||
|
||||
rows
|
||||
@ -212,11 +209,8 @@ fn delay_plot(ctx: &EventCtx, app: &App, i: IntersectionID, opts: &DataOptions)
|
||||
pts,
|
||||
})
|
||||
.collect();
|
||||
Widget::col(vec![
|
||||
Line("Delay through intersection")
|
||||
.small_heading()
|
||||
.draw(ctx)
|
||||
.margin_below(10),
|
||||
Widget::col2(vec![
|
||||
Line("Delay through intersection").small_heading().draw(ctx),
|
||||
ScatterPlot::new(
|
||||
ctx,
|
||||
series,
|
||||
@ -250,7 +244,7 @@ fn header(
|
||||
IntersectionType::Border => format!("Border #{}", id.0),
|
||||
IntersectionType::Construction => format!("{} (under construction)", id),
|
||||
};
|
||||
rows.push(Widget::row(vec![
|
||||
rows.push(Widget::row2(vec![
|
||||
Line(label).small_heading().draw(ctx),
|
||||
header_btns(ctx),
|
||||
]));
|
||||
|
@ -60,7 +60,7 @@ pub fn info(ctx: &EventCtx, app: &App, details: &mut Details, id: LaneID) -> Vec
|
||||
),
|
||||
});
|
||||
}
|
||||
rows.push("Parking spots available".draw_text(ctx).margin_above(10));
|
||||
rows.push("Parking spots available".draw_text(ctx));
|
||||
rows.push(LinePlot::new(
|
||||
ctx,
|
||||
series,
|
||||
@ -130,10 +130,8 @@ pub fn debug(ctx: &EventCtx, app: &App, details: &mut Details, id: LaneID) -> Ve
|
||||
|
||||
rows.extend(make_table(ctx, kv.into_iter()));
|
||||
|
||||
rows.push(Widget::row(vec![
|
||||
"Copy OriginalLane to clipboard: "
|
||||
.draw_text(ctx)
|
||||
.margin_right(15),
|
||||
rows.push(Widget::row2(vec![
|
||||
"Copy OriginalLane to clipboard: ".draw_text(ctx),
|
||||
Btn::svg_def("../data/system/assets/tools/clipboard.svg").build(
|
||||
ctx,
|
||||
"copy OriginalLane",
|
||||
@ -184,7 +182,7 @@ pub fn traffic(
|
||||
)));
|
||||
rows.push(txt.draw(ctx));
|
||||
|
||||
rows.push(opts.to_controls(ctx, app).margin_below(15));
|
||||
rows.push(opts.to_controls(ctx, app));
|
||||
|
||||
let r = map.get_l(id).parent;
|
||||
let time = if opts.show_end_of_day {
|
||||
@ -216,7 +214,7 @@ fn header(ctx: &EventCtx, app: &App, details: &mut Details, id: LaneID, tab: Tab
|
||||
let r = map.get_r(l.parent);
|
||||
|
||||
let label = if l.is_sidewalk() { "Sidewalk" } else { "Lane" };
|
||||
rows.push(Widget::row(vec![
|
||||
rows.push(Widget::row2(vec![
|
||||
Line(format!("{} #{}", label, id.0))
|
||||
.small_heading()
|
||||
.draw(ctx),
|
||||
|
@ -253,7 +253,7 @@ impl InfoPanel {
|
||||
if let Some(id) = maybe_id.clone() {
|
||||
for (key, label) in ctx_actions.actions(app, id) {
|
||||
cached_actions.push(key);
|
||||
col.push(hotkey_btn(ctx, app, label, key).margin(5));
|
||||
col.push(hotkey_btn(ctx, app, label, key));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -318,7 +318,7 @@ impl InfoPanel {
|
||||
tab,
|
||||
time: app.primary.sim.time(),
|
||||
is_paused: ctx_actions.is_paused(),
|
||||
composite: Composite::new(Widget::col(col).bg(Color::hex("#5B5B5B")).padding(16))
|
||||
composite: Composite::new(Widget::col2(col).bg(Color::hex("#5B5B5B")).padding(16))
|
||||
.aligned(
|
||||
HorizontalAlignment::Percent(0.02),
|
||||
VerticalAlignment::Percent(0.2),
|
||||
@ -489,25 +489,13 @@ fn make_table<I: Into<String>>(
|
||||
rows: impl Iterator<Item = (I, String)>,
|
||||
) -> Vec<Widget> {
|
||||
rows.map(|(k, v)| {
|
||||
Widget::row(vec![
|
||||
Widget::row2(vec![
|
||||
Line(k).secondary().draw(ctx),
|
||||
// TODO not quite...
|
||||
v.draw_text(ctx).centered_vert().align_right(),
|
||||
])
|
||||
})
|
||||
.collect()
|
||||
|
||||
// Attempt two
|
||||
/*let mut keys = Text::new();
|
||||
let mut values = Text::new();
|
||||
for (k, v) in rows {
|
||||
keys.add(Line(k));
|
||||
values.add(Line(v));
|
||||
}
|
||||
vec![Widget::row(vec![
|
||||
keys.draw(ctx),
|
||||
values.draw(ctx).centered_vert().bg(Color::GREEN),
|
||||
])]*/
|
||||
}
|
||||
|
||||
fn throughput<F: Fn(&Analytics) -> Vec<(TripMode, Vec<(Time, usize)>)>>(
|
||||
@ -537,11 +525,10 @@ fn throughput<F: Fn(&Analytics) -> Vec<(TripMode, Vec<(Time, usize)>)>>(
|
||||
|
||||
let mut plot_opts = PlotOptions::filterable();
|
||||
plot_opts.disabled = opts.disabled_series();
|
||||
Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
Line("Number of crossing agents per hour")
|
||||
.small_heading()
|
||||
.draw(ctx)
|
||||
.margin_below(10),
|
||||
.draw(ctx),
|
||||
LinePlot::new(ctx, series, plot_opts),
|
||||
])
|
||||
.padding(10)
|
||||
@ -558,22 +545,24 @@ fn make_tabs(
|
||||
let mut row = Vec::new();
|
||||
for (name, link) in tabs {
|
||||
if current_tab == link {
|
||||
row.push(Btn::text_bg2(name).inactive(ctx));
|
||||
row.push(Btn::text_bg2(name).inactive(ctx).centered_vert());
|
||||
} else {
|
||||
hyperlinks.insert(name.to_string(), link);
|
||||
row.push(Btn::text_bg2(name).build_def(ctx, None));
|
||||
row.push(Btn::text_bg2(name).build_def(ctx, None).centered_vert());
|
||||
}
|
||||
}
|
||||
// TODO Centered, but actually, we need to set the padding of each button to divide the
|
||||
// available space evenly. Fancy fill rules... hmmm.
|
||||
Widget::row(row).bg(Color::WHITE).margin_vert(16)
|
||||
Widget::custom_row(row).bg(Color::WHITE).margin_vert(16)
|
||||
}
|
||||
|
||||
fn header_btns(ctx: &EventCtx) -> Widget {
|
||||
Widget::row(vec![
|
||||
Btn::svg_def("../data/system/assets/tools/location.svg")
|
||||
.build(ctx, "jump to object", hotkey(Key::J))
|
||||
.margin(5),
|
||||
Widget::row2(vec![
|
||||
Btn::svg_def("../data/system/assets/tools/location.svg").build(
|
||||
ctx,
|
||||
"jump to object",
|
||||
hotkey(Key::J),
|
||||
),
|
||||
Btn::plaintext("X").build(ctx, "close info", hotkey(Key::Escape)),
|
||||
])
|
||||
.align_right()
|
||||
@ -615,7 +604,7 @@ impl DataOptions {
|
||||
if app.has_prebaked().is_none() {
|
||||
return Widget::nothing();
|
||||
}
|
||||
Widget::row(vec![
|
||||
Widget::row2(vec![
|
||||
Checkbox::custom_text(
|
||||
ctx,
|
||||
"Show before changes",
|
||||
|
@ -39,7 +39,7 @@ pub fn info(ctx: &mut EventCtx, app: &App, details: &mut Details, id: ParkingLot
|
||||
),
|
||||
});
|
||||
}
|
||||
rows.push("Parking spots available".draw_text(ctx).margin_above(10));
|
||||
rows.push("Parking spots available".draw_text(ctx));
|
||||
rows.push(LinePlot::new(
|
||||
ctx,
|
||||
series,
|
||||
@ -56,7 +56,7 @@ pub fn info(ctx: &mut EventCtx, app: &App, details: &mut Details, id: ParkingLot
|
||||
|
||||
fn header(ctx: &EventCtx, details: &mut Details, id: ParkingLotID, tab: Tab) -> Vec<Widget> {
|
||||
vec![
|
||||
Widget::row(vec![
|
||||
Widget::row2(vec![
|
||||
Line(id.to_string()).small_heading().draw(ctx),
|
||||
header_btns(ctx),
|
||||
]),
|
||||
|
@ -121,9 +121,9 @@ pub fn trips(
|
||||
|
||||
// TODO Style wrong. Button should be the entire row.
|
||||
rows.push(
|
||||
Widget::row(vec![
|
||||
Widget::custom_row(vec![
|
||||
format!("Trip {} ", idx + 1).draw_text(ctx).margin_right(21),
|
||||
Widget::row(vec![
|
||||
Widget::row2(vec![
|
||||
Widget::draw_svg_transform(
|
||||
ctx,
|
||||
match trip_mode {
|
||||
@ -133,8 +133,7 @@ pub fn trips(
|
||||
TripMode::Transit => "../data/system/assets/meters/bus.svg",
|
||||
},
|
||||
RewriteColor::ChangeAll(color),
|
||||
)
|
||||
.margin_right(10),
|
||||
),
|
||||
Line(trip_status).small().fg(color).draw(ctx),
|
||||
])
|
||||
.fully_rounded()
|
||||
@ -224,11 +223,7 @@ pub fn bio(
|
||||
let batch = GeomBatch::from_svg_contents(svg_data).autocrop();
|
||||
let dims = batch.get_dims();
|
||||
let batch = batch.scale((200.0 / dims.width).min(200.0 / dims.height));
|
||||
rows.push(
|
||||
Widget::draw_batch(ctx, batch)
|
||||
.centered_horiz()
|
||||
.margin_below(10),
|
||||
);
|
||||
rows.push(Widget::draw_batch(ctx, batch).centered_horiz());
|
||||
|
||||
let nickname = petname::Petnames::default().generate(&mut rng, 2, " ");
|
||||
let age = rng.gen_range(5, 100);
|
||||
@ -267,8 +262,7 @@ pub fn bio(
|
||||
Line("Pandemic model state: ").secondary(),
|
||||
Line(status),
|
||||
])
|
||||
.draw(ctx)
|
||||
.margin_below(5),
|
||||
.draw(ctx),
|
||||
);
|
||||
}
|
||||
|
||||
@ -372,7 +366,7 @@ pub fn crowd(
|
||||
) -> Vec<Widget> {
|
||||
let mut rows = vec![];
|
||||
|
||||
rows.push(Widget::row(vec![
|
||||
rows.push(Widget::row2(vec![
|
||||
Line("Pedestrian crowd").small_heading().draw(ctx),
|
||||
header_btns(ctx),
|
||||
]));
|
||||
@ -384,16 +378,10 @@ pub fn crowd(
|
||||
.agent_to_person(AgentID::Pedestrian(*id))
|
||||
.unwrap();
|
||||
// TODO What other info is useful to summarize?
|
||||
rows.push(
|
||||
Widget::row(vec![
|
||||
format!("{})", idx + 1)
|
||||
.draw_text(ctx)
|
||||
.centered_vert()
|
||||
.margin_right(10),
|
||||
Btn::text_fg(person.to_string()).build_def(ctx, None),
|
||||
])
|
||||
.margin_below(10),
|
||||
);
|
||||
rows.push(Widget::row2(vec![
|
||||
format!("{})", idx + 1).draw_text(ctx).centered_vert(),
|
||||
Btn::text_fg(person.to_string()).build_def(ctx, None),
|
||||
]));
|
||||
details.hyperlinks.insert(
|
||||
person.to_string(),
|
||||
Tab::PersonTrips(
|
||||
@ -420,23 +408,24 @@ pub fn parked_car(
|
||||
) -> Vec<Widget> {
|
||||
let mut rows = vec![];
|
||||
|
||||
rows.push(Widget::row(vec![
|
||||
rows.push(Widget::row2(vec![
|
||||
Line(format!("Parked car #{}", id.0))
|
||||
.small_heading()
|
||||
.draw(ctx),
|
||||
Widget::row(vec![
|
||||
Widget::row2(vec![
|
||||
// Little indirect, but the handler of this action is actually the ContextualActions
|
||||
// for SandboxMode.
|
||||
if is_paused {
|
||||
Btn::svg_def("../data/system/assets/tools/location.svg")
|
||||
.build(ctx, "follow (run the simulation)", hotkey(Key::F))
|
||||
.margin(5)
|
||||
Btn::svg_def("../data/system/assets/tools/location.svg").build(
|
||||
ctx,
|
||||
"follow (run the simulation)",
|
||||
hotkey(Key::F),
|
||||
)
|
||||
} else {
|
||||
// TODO Blink
|
||||
Btn::svg_def("../data/system/assets/tools/location.svg")
|
||||
.normal_color(RewriteColor::ChangeAll(Color::hex("#7FFA4D")))
|
||||
.build(ctx, "unfollow (pause the simulation)", hotkey(Key::F))
|
||||
.margin(5)
|
||||
},
|
||||
Btn::plaintext("X").build(ctx, "close info", hotkey(Key::Escape)),
|
||||
])
|
||||
@ -529,7 +518,7 @@ fn header(
|
||||
PersonState::OffMap => (None, ("off map", None)),
|
||||
};
|
||||
|
||||
rows.push(Widget::row(vec![
|
||||
rows.push(Widget::custom_row(vec![
|
||||
Line(format!("{}", id)).small_heading().draw(ctx),
|
||||
if let Some(icon) = maybe_icon {
|
||||
Widget::draw_svg_transform(ctx, icon, RewriteColor::ChangeAll(Color::hex("#A3A3A3")))
|
||||
@ -542,19 +531,20 @@ fn header(
|
||||
.fg(Color::hex("#A3A3A3"))
|
||||
.draw(ctx)
|
||||
.margin_horiz(10),
|
||||
Widget::row(vec![
|
||||
Widget::row2(vec![
|
||||
// Little indirect, but the handler of this action is actually the ContextualActions
|
||||
// for SandboxMode.
|
||||
if is_paused {
|
||||
Btn::svg_def("../data/system/assets/tools/location.svg")
|
||||
.build(ctx, "follow (run the simulation)", hotkey(Key::F))
|
||||
.margin(5)
|
||||
Btn::svg_def("../data/system/assets/tools/location.svg").build(
|
||||
ctx,
|
||||
"follow (run the simulation)",
|
||||
hotkey(Key::F),
|
||||
)
|
||||
} else {
|
||||
// TODO Blink
|
||||
Btn::svg_def("../data/system/assets/tools/location.svg")
|
||||
.normal_color(RewriteColor::ChangeAll(Color::hex("#7FFA4D")))
|
||||
.build(ctx, "unfollow (pause the simulation)", hotkey(Key::F))
|
||||
.margin(5)
|
||||
},
|
||||
Btn::plaintext("X").build(ctx, "close info", hotkey(Key::Escape)),
|
||||
])
|
||||
|
@ -70,8 +70,8 @@ pub fn ongoing(
|
||||
let mut col = Vec::new();
|
||||
|
||||
{
|
||||
col.push(Widget::row(vec![
|
||||
Widget::row(vec![Line("Trip time").secondary().draw(ctx)])
|
||||
col.push(Widget::custom_row(vec![
|
||||
Widget::custom_row(vec![Line("Trip time").secondary().draw(ctx)])
|
||||
.force_width_pct(ctx, col_width),
|
||||
Text::from_all(vec![
|
||||
Line(props.total_time.to_string()),
|
||||
@ -81,10 +81,10 @@ pub fn ongoing(
|
||||
]));
|
||||
}
|
||||
{
|
||||
col.push(Widget::row(vec![
|
||||
Widget::row(vec![Line("Distance").secondary().draw(ctx)])
|
||||
col.push(Widget::custom_row(vec![
|
||||
Widget::custom_row(vec![Line("Distance").secondary().draw(ctx)])
|
||||
.force_width_pct(ctx, col_width),
|
||||
Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
Text::from_all(vec![
|
||||
Line(props.dist_crossed.describe_rounded()),
|
||||
Line(format!("/{}", props.total_dist.describe_rounded())).secondary(),
|
||||
@ -99,10 +99,13 @@ pub fn ongoing(
|
||||
]));
|
||||
}
|
||||
{
|
||||
col.push(Widget::row(vec![
|
||||
Widget::row(vec![Line("Waiting").secondary().draw(ctx)])
|
||||
col.push(Widget::custom_row(vec![
|
||||
Line("Waiting")
|
||||
.secondary()
|
||||
.draw(ctx)
|
||||
.container()
|
||||
.force_width_pct(ctx, col_width),
|
||||
Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
format!("{} here", props.waiting_here).draw_text(ctx),
|
||||
Text::from_all(vec![
|
||||
if props.total_waiting != Duration::ZERO {
|
||||
@ -130,7 +133,7 @@ pub fn ongoing(
|
||||
Some(props.dist_crossed / props.total_dist),
|
||||
));
|
||||
|
||||
Widget::col(col)
|
||||
Widget::col2(col)
|
||||
}
|
||||
|
||||
pub fn future(
|
||||
@ -185,15 +188,14 @@ pub fn future(
|
||||
"This will advance the simulation to {}",
|
||||
start_time.ampm_tostring()
|
||||
))))
|
||||
.build(ctx, format!("wait for {}", trip), None)
|
||||
.margin_above(10),
|
||||
.build(ctx, format!("wait for {}", trip), None),
|
||||
);
|
||||
details
|
||||
.time_warpers
|
||||
.insert(format!("wait for {}", trip), (trip, start_time));
|
||||
}
|
||||
|
||||
Widget::col(col)
|
||||
Widget::col2(col)
|
||||
}
|
||||
|
||||
pub fn finished(
|
||||
@ -270,15 +272,15 @@ pub fn finished(
|
||||
let col_width = 15;
|
||||
|
||||
let total_trip_time = phases.last().as_ref().and_then(|p| p.end_time).unwrap() - start_time;
|
||||
col.push(Widget::row(vec![
|
||||
Widget::row(vec![Line("Trip time").secondary().draw(ctx)])
|
||||
col.push(Widget::custom_row(vec![
|
||||
Widget::custom_row(vec![Line("Trip time").secondary().draw(ctx)])
|
||||
.force_width_pct(ctx, col_width),
|
||||
total_trip_time.to_string().draw_text(ctx),
|
||||
]));
|
||||
|
||||
let (_, waiting) = app.primary.sim.finished_trip_time(trip).unwrap();
|
||||
col.push(Widget::row(vec![
|
||||
Widget::row(vec![Line("Total waiting time").secondary().draw(ctx)])
|
||||
col.push(Widget::custom_row(vec![
|
||||
Widget::custom_row(vec![Line("Total waiting time").secondary().draw(ctx)])
|
||||
.force_width_pct(ctx, col_width),
|
||||
waiting.to_string().draw_text(ctx),
|
||||
]));
|
||||
@ -294,7 +296,7 @@ pub fn finished(
|
||||
None,
|
||||
));
|
||||
|
||||
Widget::col(col)
|
||||
Widget::col2(col)
|
||||
}
|
||||
|
||||
pub fn aborted(ctx: &mut EventCtx, app: &App, trip: TripID) -> Widget {
|
||||
@ -319,7 +321,7 @@ pub fn aborted(ctx: &mut EventCtx, app: &App, trip: TripID) -> Widget {
|
||||
.into_iter(),
|
||||
));
|
||||
|
||||
Widget::col(col)
|
||||
Widget::col2(col)
|
||||
}
|
||||
|
||||
fn make_timeline(
|
||||
@ -574,10 +576,10 @@ fn make_timeline(
|
||||
}
|
||||
|
||||
let mut col = vec![
|
||||
Widget::row(vec![start_btn, Widget::row(timeline), goal_btn])
|
||||
Widget::custom_row(vec![start_btn, Widget::custom_row(timeline), goal_btn])
|
||||
.evenly_spaced()
|
||||
.margin_above(25),
|
||||
Widget::row(vec![
|
||||
Widget::row2(vec![
|
||||
start_time.ampm_tostring().draw_text(ctx),
|
||||
if let Some(t) = end_time {
|
||||
t.ampm_tostring().draw_text(ctx).align_right()
|
||||
@ -585,7 +587,7 @@ fn make_timeline(
|
||||
Widget::nothing()
|
||||
},
|
||||
]),
|
||||
Widget::row(vec![
|
||||
Widget::row2(vec![
|
||||
{
|
||||
details
|
||||
.time_warpers
|
||||
@ -623,8 +625,7 @@ fn make_timeline(
|
||||
} else {
|
||||
Widget::nothing()
|
||||
},
|
||||
])
|
||||
.margin_above(5),
|
||||
]),
|
||||
];
|
||||
if path_impossible {
|
||||
col.push("Map edits have disconnected the path taken before".draw_text(ctx));
|
||||
@ -633,7 +634,7 @@ fn make_timeline(
|
||||
if false {
|
||||
col.extend(elevation);
|
||||
}
|
||||
Widget::col(col)
|
||||
Widget::col2(col)
|
||||
}
|
||||
|
||||
fn make_elevation(ctx: &EventCtx, color: Color, walking: bool, path: &Path, map: &Map) -> Widget {
|
||||
|
@ -331,11 +331,11 @@ pub fn make_signal_diagram(
|
||||
};
|
||||
let mut col = if edit_mode {
|
||||
vec![
|
||||
txt_widget.margin_below(10),
|
||||
txt_widget,
|
||||
Btn::text_bg2("Edit entire signal").build_def(ctx, hotkey(Key::E)),
|
||||
]
|
||||
} else {
|
||||
vec![Widget::row(vec![
|
||||
vec![Widget::row2(vec![
|
||||
txt_widget,
|
||||
Btn::text_fg("X")
|
||||
.build(ctx, "close", hotkey(Key::Escape))
|
||||
@ -353,7 +353,6 @@ pub fn make_signal_diagram(
|
||||
Polygon::rectangle(0.2 * ctx.canvas.window_width / ctx.get_scale_factor(), 2.0),
|
||||
)]),
|
||||
)
|
||||
.margin(15)
|
||||
.centered_horiz(),
|
||||
);
|
||||
|
||||
@ -381,14 +380,16 @@ pub fn make_signal_diagram(
|
||||
hovered.append(normal.clone());
|
||||
hovered.push(Color::RED, bbox.to_outline(Distance::meters(5.0)));
|
||||
|
||||
Btn::custom(normal, hovered, bbox.clone())
|
||||
.build(ctx, format!("phase {}", idx + 1), None)
|
||||
.margin(5)
|
||||
Btn::custom(normal, hovered, bbox.clone()).build(
|
||||
ctx,
|
||||
format!("phase {}", idx + 1),
|
||||
None,
|
||||
)
|
||||
};
|
||||
|
||||
let phase_col = if edit_mode {
|
||||
Widget::col(vec![
|
||||
Widget::row(vec![
|
||||
Widget::col2(vec![
|
||||
Widget::row2(vec![
|
||||
match phase.phase_type {
|
||||
PhaseType::Fixed(d) => Line(format!("Phase {}: {}", idx + 1, d)),
|
||||
PhaseType::Adaptive(d) => {
|
||||
@ -396,8 +397,7 @@ pub fn make_signal_diagram(
|
||||
}
|
||||
}
|
||||
.small_heading()
|
||||
.draw(ctx)
|
||||
.margin_right(10),
|
||||
.draw(ctx),
|
||||
Btn::svg_def("../data/system/assets/tools/edit.svg").build(
|
||||
ctx,
|
||||
format!("change duration of phase {}", idx + 1),
|
||||
@ -414,17 +414,15 @@ pub fn make_signal_diagram(
|
||||
} else {
|
||||
Widget::nothing()
|
||||
},
|
||||
])
|
||||
.margin_below(10),
|
||||
Widget::row(vec![
|
||||
]),
|
||||
Widget::row2(vec![
|
||||
phase_btn,
|
||||
Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
if idx == 0 {
|
||||
Btn::text_fg("↑").inactive(ctx)
|
||||
} else {
|
||||
Btn::text_fg("↑").build(ctx, format!("move up phase {}", idx + 1), None)
|
||||
}
|
||||
.margin_below(5),
|
||||
},
|
||||
if idx == signal.phases.len() - 1 {
|
||||
Btn::text_fg("↓").inactive(ctx)
|
||||
} else {
|
||||
@ -440,7 +438,7 @@ pub fn make_signal_diagram(
|
||||
]),
|
||||
])
|
||||
} else {
|
||||
Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
match phase.phase_type {
|
||||
PhaseType::Fixed(d) => format!("Phase {}: {}", idx + 1, d).draw_text(ctx),
|
||||
PhaseType::Adaptive(d) => {
|
||||
@ -469,14 +467,13 @@ pub fn make_signal_diagram(
|
||||
Polygon::rectangle(0.2 * ctx.canvas.window_width / ctx.get_scale_factor(), 2.0),
|
||||
)]),
|
||||
)
|
||||
.margin(15)
|
||||
.centered_horiz(),
|
||||
);
|
||||
|
||||
col.push(Btn::text_fg("Add new phase").build_def(ctx, None));
|
||||
}
|
||||
|
||||
Composite::new(Widget::col(col).bg(app.cs.panel_bg).padding(10))
|
||||
Composite::new(Widget::col2(col).bg(app.cs.panel_bg).padding(16))
|
||||
.aligned(HorizontalAlignment::Left, VerticalAlignment::Top)
|
||||
.exact_size_percent(30, 85)
|
||||
.build(ctx)
|
||||
|
@ -34,12 +34,12 @@ impl ActiveTraffic {
|
||||
|
||||
Box::new(ActiveTraffic {
|
||||
composite: Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
DashTab::ActiveTraffic.picker(ctx, app),
|
||||
LinePlot::new(ctx, active_agents, PlotOptions::fixed()),
|
||||
])
|
||||
.bg(app.cs.panel_bg)
|
||||
.padding(10),
|
||||
.padding(16),
|
||||
)
|
||||
.exact_size_percent(90, 90)
|
||||
.build(ctx),
|
||||
@ -86,11 +86,11 @@ impl BusRoutes {
|
||||
Line("Bus routes").small_heading().draw(ctx),
|
||||
];
|
||||
for r in routes {
|
||||
col.push(Btn::text_fg(r).build_def(ctx, None).margin(5));
|
||||
col.push(Btn::text_fg(r).build_def(ctx, None));
|
||||
}
|
||||
|
||||
Box::new(BusRoutes {
|
||||
composite: Composite::new(Widget::col(col).bg(app.cs.panel_bg).padding(10))
|
||||
composite: Composite::new(Widget::col2(col).bg(app.cs.panel_bg).padding(16))
|
||||
.exact_size_percent(90, 90)
|
||||
.build(ctx),
|
||||
})
|
||||
|
@ -40,7 +40,7 @@ impl DashTab {
|
||||
Widget::custom_row(vec![
|
||||
// TODO Centered, but actually, we need to set the padding of each button to divide the
|
||||
// available space evenly. Fancy fill rules... hmmm.
|
||||
Widget::row(row).bg(Color::WHITE).margin_vert(16),
|
||||
Widget::custom_row(row).bg(Color::WHITE).margin_vert(16),
|
||||
Btn::plaintext("X")
|
||||
.build(ctx, "close", hotkey(Key::Escape))
|
||||
.align_right(),
|
||||
|
@ -273,7 +273,7 @@ fn make_meter(
|
||||
]),
|
||||
])
|
||||
.bg(app.cs.panel_bg)
|
||||
.padding(20),
|
||||
.padding(16),
|
||||
)
|
||||
.aligned(HorizontalAlignment::Right, VerticalAlignment::Top)
|
||||
.build(ctx)
|
||||
@ -370,7 +370,7 @@ fn cutscene_task(mode: &GameplayMode) -> Box<dyn Fn(&mut EventCtx) -> Widget> {
|
||||
])
|
||||
.draw(ctx)
|
||||
.margin_below(30),
|
||||
Widget::row(vec![
|
||||
Widget::row2(vec![
|
||||
Widget::col2(vec![
|
||||
Line("Time").fg(Color::BLACK).draw(ctx),
|
||||
Widget::draw_svg_transform(
|
||||
|
@ -338,7 +338,7 @@ fn make_meter(
|
||||
},
|
||||
])
|
||||
.bg(app.cs.panel_bg)
|
||||
.padding(35),
|
||||
.padding(16),
|
||||
)
|
||||
.aligned(HorizontalAlignment::Right, VerticalAlignment::Top)
|
||||
.build(ctx)
|
||||
|
@ -284,21 +284,21 @@ impl AgentMeter {
|
||||
|
||||
let rows = vec![
|
||||
"Active trips".draw_text(ctx),
|
||||
Widget::row(vec![
|
||||
Widget::row(vec![
|
||||
Widget::custom_row(vec![
|
||||
Widget::custom_row(vec![
|
||||
Widget::draw_svg(ctx, "../data/system/assets/meters/pedestrian.svg")
|
||||
.margin_right(5),
|
||||
prettyprint_usize(by_mode[&TripMode::Walk]).draw_text(ctx),
|
||||
]),
|
||||
Widget::row(vec![
|
||||
Widget::custom_row(vec![
|
||||
Widget::draw_svg(ctx, "../data/system/assets/meters/bike.svg").margin_right(5),
|
||||
prettyprint_usize(by_mode[&TripMode::Bike]).draw_text(ctx),
|
||||
]),
|
||||
Widget::row(vec![
|
||||
Widget::custom_row(vec![
|
||||
Widget::draw_svg(ctx, "../data/system/assets/meters/car.svg").margin_right(5),
|
||||
prettyprint_usize(by_mode[&TripMode::Drive]).draw_text(ctx),
|
||||
]),
|
||||
Widget::row(vec![
|
||||
Widget::custom_row(vec![
|
||||
Widget::draw_svg(ctx, "../data/system/assets/meters/bus.svg").margin_right(5),
|
||||
prettyprint_usize(by_mode[&TripMode::Transit]).draw_text(ctx),
|
||||
]),
|
||||
@ -312,9 +312,8 @@ impl AgentMeter {
|
||||
Polygon::rectangle(0.2 * ctx.canvas.window_width / ctx.get_scale_factor(), 2.0),
|
||||
)]),
|
||||
)
|
||||
.margin(15)
|
||||
.centered_horiz(),
|
||||
Widget::row(vec![
|
||||
Widget::row2(vec![
|
||||
{
|
||||
let mut txt = Text::new();
|
||||
let pct = if unfinished == 0 {
|
||||
@ -335,7 +334,7 @@ impl AgentMeter {
|
||||
]),
|
||||
];
|
||||
|
||||
let composite = Composite::new(Widget::col(rows).bg(app.cs.panel_bg).padding(20))
|
||||
let composite = Composite::new(Widget::col2(rows).bg(app.cs.panel_bg).padding(16))
|
||||
.aligned(HorizontalAlignment::Right, VerticalAlignment::Top)
|
||||
.build(ctx);
|
||||
|
||||
|
@ -33,7 +33,6 @@ enum SpeedSetting {
|
||||
}
|
||||
|
||||
impl SpeedControls {
|
||||
// TODO Could use checkbox here, but not sure it'll make things that much simpler.
|
||||
fn make_panel(ctx: &mut EventCtx, app: &App, paused: bool, setting: SpeedSetting) -> Composite {
|
||||
let mut row = Vec::new();
|
||||
row.push(
|
||||
@ -51,7 +50,7 @@ impl SpeedControls {
|
||||
);
|
||||
|
||||
row.push(
|
||||
Widget::row(
|
||||
Widget::custom_row(
|
||||
vec![
|
||||
(SpeedSetting::Realtime, "real-time speed"),
|
||||
(SpeedSetting::Fast, "5x speed"),
|
||||
@ -100,7 +99,7 @@ impl SpeedControls {
|
||||
);
|
||||
|
||||
row.push(
|
||||
Widget::row(vec![
|
||||
Widget::custom_row(vec![
|
||||
Btn::svg_def("../data/system/assets/speed/jump_to_time.svg")
|
||||
.pad(9)
|
||||
.build(ctx, "jump to specific time", hotkey(Key::B)),
|
||||
@ -111,7 +110,7 @@ impl SpeedControls {
|
||||
.bg(app.cs.section_bg),
|
||||
);
|
||||
|
||||
Composite::new(Widget::row(row).bg(app.cs.panel_bg).padding(16))
|
||||
Composite::new(Widget::custom_row(row).bg(app.cs.panel_bg).padding(16))
|
||||
.aligned(
|
||||
HorizontalAlignment::Center,
|
||||
VerticalAlignment::BottomAboveOSD,
|
||||
@ -350,14 +349,13 @@ impl JumpToTime {
|
||||
target,
|
||||
maybe_mode,
|
||||
composite: Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::row(vec![
|
||||
Widget::col2(vec![
|
||||
Widget::row2(vec![
|
||||
Line("Jump to what time?").small_heading().draw(ctx),
|
||||
Btn::plaintext("X")
|
||||
.build(ctx, "close", hotkey(Key::Escape))
|
||||
.align_right(),
|
||||
])
|
||||
.margin_below(15),
|
||||
]),
|
||||
if app.has_prebaked().is_some() {
|
||||
Widget::draw_batch(
|
||||
ctx,
|
||||
@ -380,8 +378,7 @@ impl JumpToTime {
|
||||
0.25 * ctx.canvas.window_width,
|
||||
target.to_percent(end_of_day).min(1.0),
|
||||
)
|
||||
.named("time slider")
|
||||
.margin_below(15),
|
||||
.named("time slider"),
|
||||
Btn::text_bg2(format!("Jump to {}", target.ampm_tostring()))
|
||||
.build(ctx, "jump to time", hotkey(Key::Enter))
|
||||
.centered_horiz()
|
||||
@ -393,8 +390,7 @@ impl JumpToTime {
|
||||
Polygon::rectangle(0.25 * ctx.canvas.window_width, 2.0),
|
||||
)]),
|
||||
)
|
||||
.margin_above(20)
|
||||
.margin_below(20),
|
||||
.margin_above(10),
|
||||
Btn::text_bg2("Jump to the next delay over 5 minutes")
|
||||
.build_def(ctx, None)
|
||||
.centered_horiz(),
|
||||
@ -506,7 +502,7 @@ impl TimeWarpScreen {
|
||||
started: Instant::now(),
|
||||
traffic_jams,
|
||||
composite: Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
Text::new().draw(ctx).named("text"),
|
||||
Btn::text_bg2("stop now")
|
||||
.build_def(ctx, hotkey(Key::Escape))
|
||||
@ -644,12 +640,11 @@ impl TimePanel {
|
||||
TimePanel {
|
||||
time: app.primary.sim.time(),
|
||||
composite: Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
Text::from(
|
||||
Line(app.primary.sim.time().ampm_tostring_spacers()).big_heading_styled(),
|
||||
)
|
||||
.draw(ctx)
|
||||
.margin(10)
|
||||
.centered_horiz(),
|
||||
{
|
||||
let mut batch = GeomBatch::new();
|
||||
@ -684,17 +679,16 @@ impl TimePanel {
|
||||
|
||||
Widget::draw_batch(ctx, batch)
|
||||
},
|
||||
Widget::row(vec![
|
||||
Widget::custom_row(vec![
|
||||
Line("00:00").small().draw(ctx),
|
||||
Widget::draw_svg(ctx, "../data/system/assets/speed/sunrise.svg"),
|
||||
Line("12:00").small().draw(ctx),
|
||||
Widget::draw_svg(ctx, "../data/system/assets/speed/sunset.svg"),
|
||||
Line("24:00").small().draw(ctx),
|
||||
])
|
||||
.padding(10)
|
||||
.evenly_spaced(),
|
||||
])
|
||||
.padding(10)
|
||||
.padding(16)
|
||||
.bg(app.cs.panel_bg),
|
||||
)
|
||||
.aligned(HorizontalAlignment::Left, VerticalAlignment::Top)
|
||||
|
@ -72,10 +72,10 @@ impl UI {
|
||||
model,
|
||||
state: State::viewing(),
|
||||
composite: Composite::new(
|
||||
Widget::col(vec![
|
||||
Widget::col2(vec![
|
||||
Line("Map Editor").small_heading().draw(ctx),
|
||||
Text::new().draw(ctx).named("current info"),
|
||||
Widget::col(
|
||||
Widget::col2(
|
||||
vec![
|
||||
(hotkey(Key::Escape), "quit"),
|
||||
(None, "save raw map"),
|
||||
@ -89,7 +89,7 @@ impl UI {
|
||||
.collect(),
|
||||
),
|
||||
])
|
||||
.padding(10)
|
||||
.padding(16)
|
||||
.bg(Color::grey(0.4)),
|
||||
)
|
||||
.aligned(HorizontalAlignment::Right, VerticalAlignment::Top)
|
||||
|
Loading…
Reference in New Issue
Block a user