just refactoring some places that mutably build up rows/cols

This commit is contained in:
Dustin Carlino 2020-03-04 16:13:17 -08:00
parent 250b59bfee
commit 54f4597166
7 changed files with 149 additions and 124 deletions

View File

@ -41,6 +41,7 @@ enum WidgetType {
Histogram(Histogram),
Row(Vec<ManagedWidget>),
Column(Vec<ManagedWidget>),
Nothing,
}
struct LayoutStyle {
@ -338,11 +339,31 @@ impl ManagedWidget {
}
pub fn row(widgets: Vec<ManagedWidget>) -> ManagedWidget {
ManagedWidget::new(WidgetType::Row(widgets))
ManagedWidget::new(WidgetType::Row(
widgets
.into_iter()
.filter(|w| match w.widget {
WidgetType::Nothing => false,
_ => true,
})
.collect(),
))
}
pub fn col(widgets: Vec<ManagedWidget>) -> ManagedWidget {
ManagedWidget::new(WidgetType::Column(widgets))
ManagedWidget::new(WidgetType::Column(
widgets
.into_iter()
.filter(|w| match w.widget {
WidgetType::Nothing => false,
_ => true,
})
.collect(),
))
}
pub fn nothing() -> ManagedWidget {
ManagedWidget::new(WidgetType::Nothing)
}
}
@ -385,6 +406,7 @@ impl ManagedWidget {
}
}
}
WidgetType::Nothing => unreachable!(),
}
None
}
@ -419,6 +441,7 @@ impl ManagedWidget {
w.draw(g, sliders, menus);
}
}
WidgetType::Nothing => unreachable!(),
}
}
@ -472,6 +495,7 @@ impl ManagedWidget {
stretch.add_child(parent, col).unwrap();
return;
}
WidgetType::Nothing => unreachable!(),
};
let dims = widget.get_dims();
let mut style = Style {
@ -600,6 +624,7 @@ impl ManagedWidget {
);
}
}
WidgetType::Nothing => unreachable!(),
}
}
@ -628,6 +653,7 @@ impl ManagedWidget {
w.get_all_click_actions(actions);
}
}
WidgetType::Nothing => unreachable!(),
}
}
@ -660,6 +686,7 @@ impl ManagedWidget {
}
return None;
}
WidgetType::Nothing => unreachable!(),
};
if found {
Some(self)
@ -688,6 +715,7 @@ impl ManagedWidget {
}
return None;
}
WidgetType::Nothing => unreachable!(),
};
if found {
Some(self)

View File

@ -670,18 +670,20 @@ impl Overlays {
);
}
let mut col = vec![ManagedWidget::row(vec![
ManagedWidget::draw_text(ctx, Text::from(Line("intersection demand"))),
ManagedWidget::btn(Button::rectangle_svg(
"../data/system/assets/tools/locate.svg",
"intersection demand",
None,
RewriteColor::Change(Color::hex("#CC4121"), colors::HOVERING),
ctx,
)),
WrappedComposite::text_button(ctx, "X", None).align_right(),
])];
col.push(ColorLegend::row(ctx, Color::RED, "current demand"));
let col = vec![
ManagedWidget::row(vec![
ManagedWidget::draw_text(ctx, Text::from(Line("intersection demand"))),
ManagedWidget::btn(Button::rectangle_svg(
"../data/system/assets/tools/locate.svg",
"intersection demand",
None,
RewriteColor::Change(Color::hex("#CC4121"), colors::HOVERING),
ctx,
)),
WrappedComposite::text_button(ctx, "X", None).align_right(),
]),
ColorLegend::row(ctx, Color::RED, "current demand"),
];
Overlays::IntersectionDemand(
app.primary.sim.time(),
@ -714,7 +716,7 @@ impl Overlays {
.get_analytics()
.bus_passenger_delays(app.primary.sim.time(), id);
for idx in 0..route.stops.len() {
let mut row = vec![
col.push(ManagedWidget::row(vec![
ManagedWidget::draw_text(ctx, Text::from(Line(format!("Stop {}", idx + 1)))),
ManagedWidget::btn(Button::rectangle_svg(
"../data/system/assets/tools/locate.svg",
@ -723,20 +725,19 @@ impl Overlays {
RewriteColor::Change(Color::hex("#CC4121"), colors::HOVERING),
ctx,
)),
];
if let Some(hgram) = delay_per_stop.remove(&route.stops[idx]) {
row.push(ManagedWidget::draw_text(
ctx,
Text::from(Line(format!(
": {} (avg {})",
hgram.count(),
hgram.select(Statistic::Mean)
))),
));
} else {
row.push(ManagedWidget::draw_text(ctx, Text::from(Line(": nobody"))));
}
col.push(ManagedWidget::row(row));
if let Some(hgram) = delay_per_stop.remove(&route.stops[idx]) {
ManagedWidget::draw_text(
ctx,
Text::from(Line(format!(
": {} (avg {})",
hgram.count(),
hgram.select(Statistic::Mean)
))),
)
} else {
ManagedWidget::draw_text(ctx, Text::from(Line(": nobody")))
},
]));
}
let y_len = ctx.default_line_height() * (route.stops.len() as f64);

View File

@ -75,7 +75,7 @@ impl LaneEditor {
);
}
let mut col = vec![
let col = vec![
ManagedWidget::draw_text(
ctx,
Text::from(Line(format!(
@ -86,22 +86,20 @@ impl LaneEditor {
.centered_horiz(),
ManagedWidget::row(row).centered(),
WrappedComposite::text_button(ctx, "Finish", hotkey(Key::Escape)),
// TODO Not ready for general use
if app.opts.dev {
WrappedComposite::text_button(ctx, "Edit entire road", hotkey(Key::U))
} else {
ManagedWidget::nothing()
},
if app.primary.map.get_edits().original_lts.contains_key(&l)
|| app.primary.map.get_edits().reversed_lanes.contains(&l)
{
WrappedComposite::text_button(ctx, "Revert", hotkey(Key::R))
} else {
Button::inactive_button(ctx, "Revert")
},
];
// TODO Not ready for general use
if app.opts.dev {
col.push(WrappedComposite::text_button(
ctx,
"Edit entire road",
hotkey(Key::U),
));
}
if app.primary.map.get_edits().original_lts.contains_key(&l)
|| app.primary.map.get_edits().reversed_lanes.contains(&l)
{
col.push(WrappedComposite::text_button(ctx, "Revert", hotkey(Key::R)));
} else {
col.push(Button::inactive_button(ctx, "Revert"));
};
let composite = Composite::new(ManagedWidget::col(col).bg(colors::PANEL_BG).padding(10))
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)

View File

@ -304,7 +304,7 @@ impl State for TrafficSignalEditor {
}
fn make_top_panel(ctx: &mut EventCtx, app: &App, can_undo: bool, can_redo: bool) -> Composite {
let mut row = vec![
let row = vec![
WrappedComposite::text_button(ctx, "Finish", hotkey(Key::Escape)),
WrappedComposite::text_button(ctx, "Finish", hotkey(Key::Escape)),
WrappedComposite::text_button(ctx, "Preview", lctrl(Key::P)),
@ -339,11 +339,17 @@ fn make_top_panel(ctx: &mut EventCtx, app: &App, can_undo: bool, can_redo: bool)
)
})
.margin(15),
if app.opts.dev {
WrappedComposite::text_button(ctx, "Edit metadata", None)
} else {
ManagedWidget::nothing()
},
if app.opts.dev {
WrappedComposite::text_button(ctx, "Export", None)
} else {
ManagedWidget::nothing()
},
];
if app.opts.dev {
row.push(WrappedComposite::text_button(ctx, "Edit metadata", None));
row.push(WrappedComposite::text_button(ctx, "Export", None));
}
Composite::new(ManagedWidget::row(row).bg(colors::PANEL_BG))
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
.build(ctx)

View File

@ -75,7 +75,7 @@ impl State for TitleScreen {
}
pub fn main_menu(ctx: &mut EventCtx, app: &App) -> Box<dyn State> {
let mut col = vec![
let col = vec![
WrappedComposite::svg_button(
ctx,
"../data/system/assets/pregame/quit.svg",
@ -110,23 +110,21 @@ pub fn main_menu(ctx: &mut EventCtx, app: &App) -> Box<dyn State> {
WrappedComposite::text_bg_button(ctx, "COMMUNITY PROPOSALS", hotkey(Key::P)),
])
.centered(),
];
if app.opts.dev {
col.push(
if app.opts.dev {
ManagedWidget::row(vec![
WrappedComposite::text_bg_button(ctx, "INTERNAL DEV TOOLS", hotkey(Key::M)),
WrappedComposite::text_bg_button(ctx, "INTERNAL A/B TEST MODE", hotkey(Key::A)),
])
.centered(),
);
}
col.push(
.centered()
} else {
ManagedWidget::nothing()
},
ManagedWidget::col(vec![
WrappedComposite::text_bg_button(ctx, "About A/B Street", None),
ManagedWidget::draw_text(ctx, built_info::time()),
])
.centered(),
);
];
let mut c = WrappedComposite::new(
Composite::new(ManagedWidget::col(col).evenly_spaced())
@ -209,9 +207,7 @@ pub fn main_menu(ctx: &mut EventCtx, app: &App) -> Box<dyn State> {
}
fn about(ctx: &mut EventCtx) -> Box<dyn State> {
let mut col = Vec::new();
col.push(
let col = vec![
WrappedComposite::svg_button(
ctx,
"../data/system/assets/pregame/back.svg",
@ -219,50 +215,49 @@ fn about(ctx: &mut EventCtx) -> Box<dyn State> {
hotkey(Key::Escape),
)
.align_left(),
);
let mut txt = Text::new();
txt.add(Line("A/B STREET").size(50));
txt.add(Line("Created by Dustin Carlino, UX by Yuwen Li"));
txt.add(Line(""));
txt.add(Line("Contact: dabreegster@gmail.com"));
txt.add(Line(
"Project: http://github.com/dabreegster/abstreet (aliased by abstreet.org)",
));
txt.add(Line("Map data from OpenStreetMap and King County GIS"));
// TODO Add more here
txt.add(Line(
"See full credits at https://github.com/dabreegster/abstreet#credits",
));
txt.add(Line(""));
// TODO Word wrapping please?
txt.add(Line(
"Disclaimer: This game is based on imperfect data, heuristics ",
));
txt.add(Line(
"concocted under the influence of cold brew, a simplified traffic ",
));
txt.add(Line(
"simulation model, and a deeply flawed understanding of how much ",
));
txt.add(Line(
"articulated buses can bend around tight corners. Use this as a ",
));
txt.add(Line(
"conversation starter with your city government, not a final ",
));
txt.add(Line(
"decision maker. Any resemblance of in-game characters to real ",
));
txt.add(Line(
"people is probably coincidental, except for PedestrianID(42). ",
));
txt.add(Line("Have the appropriate amount of fun."));
col.push(
ManagedWidget::draw_text(ctx, txt)
.centered_horiz()
.align_vert_center(),
);
{
let mut txt = Text::new();
txt.add(Line("A/B STREET").size(50));
txt.add(Line("Created by Dustin Carlino, UX by Yuwen Li"));
txt.add(Line(""));
txt.add(Line("Contact: dabreegster@gmail.com"));
txt.add(Line(
"Project: http://github.com/dabreegster/abstreet (aliased by abstreet.org)",
));
txt.add(Line("Map data from OpenStreetMap and King County GIS"));
// TODO Add more here
txt.add(Line(
"See full credits at https://github.com/dabreegster/abstreet#credits",
));
txt.add(Line(""));
// TODO Word wrapping please?
txt.add(Line(
"Disclaimer: This game is based on imperfect data, heuristics ",
));
txt.add(Line(
"concocted under the influence of cold brew, a simplified traffic ",
));
txt.add(Line(
"simulation model, and a deeply flawed understanding of how much ",
));
txt.add(Line(
"articulated buses can bend around tight corners. Use this as a ",
));
txt.add(Line(
"conversation starter with your city government, not a final ",
));
txt.add(Line(
"decision maker. Any resemblance of in-game characters to real ",
));
txt.add(Line(
"people is probably coincidental, except for PedestrianID(42). ",
));
txt.add(Line("Have the appropriate amount of fun."));
ManagedWidget::draw_text(ctx, txt)
.centered_horiz()
.align_vert_center()
},
];
ManagedGUIState::fullscreen(
WrappedComposite::new(

View File

@ -325,16 +325,15 @@ impl FinalScore {
let mut txt = Text::from(Line("Final score").roboto_bold());
txt.add(Line(verdict));
let mut row = vec![
let row = vec![
if next.is_some() {
WrappedComposite::text_button(ctx, "next challenge", None)
} else {
ManagedWidget::nothing()
},
WrappedComposite::text_button(ctx, "try again", None),
WrappedComposite::text_button(ctx, "back to challenges", None),
];
if next.is_some() {
row.insert(
0,
WrappedComposite::text_button(ctx, "next challenge", None),
);
}
Box::new(FinalScore {
composite: Composite::new(

View File

@ -422,23 +422,21 @@ impl AgentMeter {
ManagedWidget::draw_text(ctx, txt)
},
{
let mut row = vec![WrappedComposite::text_bg_button(
ctx,
"more data",
hotkey(Key::Q),
)];
if app.has_prebaked().is_some() {
row.push(
ManagedWidget::row(vec![
WrappedComposite::text_bg_button(ctx, "more data", hotkey(Key::Q)),
if app.has_prebaked().is_some() {
WrappedComposite::svg_button(
ctx,
"../data/system/assets/meters/trip_histogram.svg",
"compare trips to baseline",
None,
)
.align_right(),
);
}
ManagedWidget::row(row).centered()
.align_right()
} else {
ManagedWidget::nothing()
},
])
.centered()
},
];
// TODO Slight hack. If we're jumping right into a tutorial and don't have the prebaked