mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 09:24:26 +03:00
Move per-gameplay panels from top-center to top-right. Left align time. #551
This commit is contained in:
parent
b6536122e0
commit
0d8cc27961
@ -20,7 +20,7 @@ use crate::sandbox::{Actions, SandboxControls};
|
|||||||
// TODO A nice level to unlock: specifying your own commute, getting to work on it
|
// TODO A nice level to unlock: specifying your own commute, getting to work on it
|
||||||
|
|
||||||
pub struct OptimizeCommute {
|
pub struct OptimizeCommute {
|
||||||
top_center: Panel,
|
top_right: Panel,
|
||||||
person: PersonID,
|
person: PersonID,
|
||||||
mode: GameplayMode,
|
mode: GameplayMode,
|
||||||
goal: Duration,
|
goal: Duration,
|
||||||
@ -43,7 +43,7 @@ impl OptimizeCommute {
|
|||||||
let person = app.primary.sim.find_person_by_orig_id(orig_person).unwrap();
|
let person = app.primary.sim.find_person_by_orig_id(orig_person).unwrap();
|
||||||
let trips = app.primary.sim.get_person(person).trips.clone();
|
let trips = app.primary.sim.get_person(person).trips.clone();
|
||||||
Box::new(OptimizeCommute {
|
Box::new(OptimizeCommute {
|
||||||
top_center: Panel::empty(ctx),
|
top_right: Panel::empty(ctx),
|
||||||
person,
|
person,
|
||||||
mode: GameplayMode::OptimizeCommute(orig_person, goal),
|
mode: GameplayMode::OptimizeCommute(orig_person, goal),
|
||||||
goal,
|
goal,
|
||||||
@ -134,7 +134,7 @@ impl GameplayState for OptimizeCommute {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.top_center.event(ctx) {
|
match self.top_right.event(ctx) {
|
||||||
Outcome::Clicked(x) => match x.as_ref() {
|
Outcome::Clicked(x) => match x.as_ref() {
|
||||||
"edit map" => {
|
"edit map" => {
|
||||||
return Some(Transition::Push(EditMode::new(ctx, app, self.mode.clone())));
|
return Some(Transition::Push(EditMode::new(ctx, app, self.mode.clone())));
|
||||||
@ -170,7 +170,7 @@ impl GameplayState for OptimizeCommute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, g: &mut GfxCtx, _: &App) {
|
fn draw(&self, g: &mut GfxCtx, _: &App) {
|
||||||
self.top_center.draw(g);
|
self.top_right.draw(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recreate_panels(&mut self, ctx: &mut EventCtx, app: &App) {
|
fn recreate_panels(&mut self, ctx: &mut EventCtx, app: &App) {
|
||||||
@ -179,7 +179,7 @@ impl GameplayState for OptimizeCommute {
|
|||||||
txt.append_all(cmp_duration_shorter(app, after, before));
|
txt.append_all(cmp_duration_shorter(app, after, before));
|
||||||
txt.append(Line(")"));
|
txt.append(Line(")"));
|
||||||
|
|
||||||
self.top_center = Panel::new(Widget::col(vec![
|
self.top_right = Panel::new(Widget::col(vec![
|
||||||
challenge_header(ctx, "Optimize the VIP's commute"),
|
challenge_header(ctx, "Optimize the VIP's commute"),
|
||||||
Widget::row(vec![
|
Widget::row(vec![
|
||||||
format!("Speed up the VIP's trips by {}", self.goal)
|
format!("Speed up the VIP's trips by {}", self.goal)
|
||||||
@ -201,7 +201,7 @@ impl GameplayState for OptimizeCommute {
|
|||||||
])
|
])
|
||||||
.centered(),
|
.centered(),
|
||||||
]))
|
]))
|
||||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
.aligned(HorizontalAlignment::Right, VerticalAlignment::Top)
|
||||||
.build(ctx);
|
.build(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ use crate::sandbox::{Actions, SandboxControls, SandboxMode};
|
|||||||
const THRESHOLD: Duration = Duration::const_seconds(20.0 * 60.0);
|
const THRESHOLD: Duration = Duration::const_seconds(20.0 * 60.0);
|
||||||
|
|
||||||
pub struct FixTrafficSignals {
|
pub struct FixTrafficSignals {
|
||||||
top_center: Panel,
|
top_right: Panel,
|
||||||
time: Time,
|
time: Time,
|
||||||
worst: Option<(IntersectionID, Duration)>,
|
worst: Option<(IntersectionID, Duration)>,
|
||||||
done_at: Option<Time>,
|
done_at: Option<Time>,
|
||||||
@ -28,7 +28,7 @@ pub struct FixTrafficSignals {
|
|||||||
impl FixTrafficSignals {
|
impl FixTrafficSignals {
|
||||||
pub fn new(ctx: &mut EventCtx) -> Box<dyn GameplayState> {
|
pub fn new(ctx: &mut EventCtx) -> Box<dyn GameplayState> {
|
||||||
Box::new(FixTrafficSignals {
|
Box::new(FixTrafficSignals {
|
||||||
top_center: Panel::empty(ctx),
|
top_right: Panel::empty(ctx),
|
||||||
time: Time::START_OF_DAY,
|
time: Time::START_OF_DAY,
|
||||||
worst: None,
|
worst: None,
|
||||||
done_at: None,
|
done_at: None,
|
||||||
@ -154,7 +154,7 @@ impl GameplayState for FixTrafficSignals {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.top_center.event(ctx) {
|
match self.top_right.event(ctx) {
|
||||||
Outcome::Clicked(x) => match x.as_ref() {
|
Outcome::Clicked(x) => match x.as_ref() {
|
||||||
"edit map" => {
|
"edit map" => {
|
||||||
return Some(Transition::Push(EditMode::new(ctx, app, self.mode.clone())));
|
return Some(Transition::Push(EditMode::new(ctx, app, self.mode.clone())));
|
||||||
@ -228,12 +228,12 @@ impl GameplayState for FixTrafficSignals {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, g: &mut GfxCtx, _: &App) {
|
fn draw(&self, g: &mut GfxCtx, _: &App) {
|
||||||
self.top_center.draw(g);
|
self.top_right.draw(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recreate_panels(&mut self, ctx: &mut EventCtx, app: &App) {
|
fn recreate_panels(&mut self, ctx: &mut EventCtx, app: &App) {
|
||||||
if let Some(time) = self.done_at {
|
if let Some(time) = self.done_at {
|
||||||
self.top_center = Panel::new(Widget::col(vec![
|
self.top_right = Panel::new(Widget::col(vec![
|
||||||
challenge_header(ctx, "Traffic signal survivor"),
|
challenge_header(ctx, "Traffic signal survivor"),
|
||||||
Widget::row(vec![
|
Widget::row(vec![
|
||||||
Line(format!("Delay exceeded {} at {}", THRESHOLD, time))
|
Line(format!("Delay exceeded {} at {}", THRESHOLD, time))
|
||||||
@ -243,7 +243,7 @@ impl GameplayState for FixTrafficSignals {
|
|||||||
ctx.style().btn_outline.text("try again").build_def(ctx),
|
ctx.style().btn_outline.text("try again").build_def(ctx),
|
||||||
]),
|
]),
|
||||||
]))
|
]))
|
||||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
.aligned(HorizontalAlignment::Right, VerticalAlignment::Top)
|
||||||
.build(ctx);
|
.build(ctx);
|
||||||
} else {
|
} else {
|
||||||
let meter = if let Some((_, delay)) = self.worst {
|
let meter = if let Some((_, delay)) = self.worst {
|
||||||
@ -286,7 +286,7 @@ impl GameplayState for FixTrafficSignals {
|
|||||||
])
|
])
|
||||||
};
|
};
|
||||||
|
|
||||||
self.top_center = Panel::new(Widget::col(vec![
|
self.top_right = Panel::new(Widget::col(vec![
|
||||||
challenge_header(ctx, "Traffic signal survivor"),
|
challenge_header(ctx, "Traffic signal survivor"),
|
||||||
Widget::row(vec![
|
Widget::row(vec![
|
||||||
Line(format!(
|
Line(format!(
|
||||||
@ -302,7 +302,7 @@ impl GameplayState for FixTrafficSignals {
|
|||||||
]),
|
]),
|
||||||
meter,
|
meter,
|
||||||
]))
|
]))
|
||||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
.aligned(HorizontalAlignment::Right, VerticalAlignment::Top)
|
||||||
.build(ctx);
|
.build(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ use crate::sandbox::{Actions, SandboxControls, SandboxMode};
|
|||||||
|
|
||||||
// TODO Maybe remember what things were spawned, offer to replay this later
|
// TODO Maybe remember what things were spawned, offer to replay this later
|
||||||
pub struct Freeform {
|
pub struct Freeform {
|
||||||
top_center: Panel,
|
top_right: Panel,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Freeform {
|
impl Freeform {
|
||||||
@ -40,7 +40,7 @@ impl Freeform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Box::new(Freeform {
|
Box::new(Freeform {
|
||||||
top_center: Panel::empty(ctx),
|
top_right: Panel::empty(ctx),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ impl GameplayState for Freeform {
|
|||||||
_: &mut SandboxControls,
|
_: &mut SandboxControls,
|
||||||
_: &mut Actions,
|
_: &mut Actions,
|
||||||
) -> Option<Transition> {
|
) -> Option<Transition> {
|
||||||
match self.top_center.event(ctx) {
|
match self.top_right.event(ctx) {
|
||||||
Outcome::Clicked(x) => match x.as_ref() {
|
Outcome::Clicked(x) => match x.as_ref() {
|
||||||
"change map" => Some(Transition::Push(CityPicker::new(
|
"change map" => Some(Transition::Push(CityPicker::new(
|
||||||
ctx,
|
ctx,
|
||||||
@ -114,7 +114,7 @@ impl GameplayState for Freeform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, g: &mut GfxCtx, _: &App) {
|
fn draw(&self, g: &mut GfxCtx, _: &App) {
|
||||||
self.top_center.draw(g);
|
self.top_right.draw(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recreate_panels(&mut self, ctx: &mut EventCtx, app: &App) {
|
fn recreate_panels(&mut self, ctx: &mut EventCtx, app: &App) {
|
||||||
@ -164,8 +164,8 @@ impl GameplayState for Freeform {
|
|||||||
.into_widget(ctx),
|
.into_widget(ctx),
|
||||||
];
|
];
|
||||||
|
|
||||||
self.top_center = Panel::new(Widget::col(rows))
|
self.top_right = Panel::new(Widget::col(rows))
|
||||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
.aligned(HorizontalAlignment::Right, VerticalAlignment::Top)
|
||||||
.build(ctx);
|
.build(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ use crate::sandbox::gameplay::{GameplayMode, GameplayState};
|
|||||||
use crate::sandbox::{Actions, SandboxControls, SandboxMode};
|
use crate::sandbox::{Actions, SandboxControls, SandboxMode};
|
||||||
|
|
||||||
pub struct PlayScenario {
|
pub struct PlayScenario {
|
||||||
top_center: Panel,
|
top_right: Panel,
|
||||||
scenario_name: String,
|
scenario_name: String,
|
||||||
modifiers: Vec<ScenarioModifier>,
|
modifiers: Vec<ScenarioModifier>,
|
||||||
}
|
}
|
||||||
@ -44,7 +44,7 @@ impl PlayScenario {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Box::new(PlayScenario {
|
Box::new(PlayScenario {
|
||||||
top_center: Panel::empty(ctx),
|
top_right: Panel::empty(ctx),
|
||||||
scenario_name: name.to_string(),
|
scenario_name: name.to_string(),
|
||||||
modifiers,
|
modifiers,
|
||||||
})
|
})
|
||||||
@ -63,7 +63,7 @@ impl GameplayState for PlayScenario {
|
|||||||
// on_destroy can wipe this out.
|
// on_destroy can wipe this out.
|
||||||
app.primary.has_modified_trips = !self.modifiers.is_empty();
|
app.primary.has_modified_trips = !self.modifiers.is_empty();
|
||||||
|
|
||||||
match self.top_center.event(ctx) {
|
match self.top_right.event(ctx) {
|
||||||
Outcome::Clicked(x) => match x.as_ref() {
|
Outcome::Clicked(x) => match x.as_ref() {
|
||||||
"change map" => {
|
"change map" => {
|
||||||
let scenario = self.scenario_name.clone();
|
let scenario = self.scenario_name.clone();
|
||||||
@ -117,7 +117,7 @@ impl GameplayState for PlayScenario {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, g: &mut GfxCtx, _: &App) {
|
fn draw(&self, g: &mut GfxCtx, _: &App) {
|
||||||
self.top_center.draw(g);
|
self.top_right.draw(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_destroy(&self, app: &mut App) {
|
fn on_destroy(&self, app: &mut App) {
|
||||||
@ -169,8 +169,8 @@ impl GameplayState for PlayScenario {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
self.top_center = Panel::new(Widget::col(rows))
|
self.top_right = Panel::new(Widget::col(rows))
|
||||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
.aligned(HorizontalAlignment::Right, VerticalAlignment::Top)
|
||||||
.build(ctx);
|
.build(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ const ESCORT: CarID = CarID(0, VehicleType::Car);
|
|||||||
const CAR_BIKE_CONTENTION_GOAL: Duration = Duration::const_seconds(15.0);
|
const CAR_BIKE_CONTENTION_GOAL: Duration = Duration::const_seconds(15.0);
|
||||||
|
|
||||||
pub struct Tutorial {
|
pub struct Tutorial {
|
||||||
top_center: Panel,
|
top_right: Panel,
|
||||||
last_finished_task: Task,
|
last_finished_task: Task,
|
||||||
|
|
||||||
msg_panel: Option<Panel>,
|
msg_panel: Option<Panel>,
|
||||||
@ -126,7 +126,7 @@ impl Tutorial {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.top_center.event(ctx) {
|
match self.top_right.event(ctx) {
|
||||||
Outcome::Clicked(x) => match x.as_ref() {
|
Outcome::Clicked(x) => match x.as_ref() {
|
||||||
"Quit" => {
|
"Quit" => {
|
||||||
return Some(maybe_exit_sandbox(ctx));
|
return Some(maybe_exit_sandbox(ctx));
|
||||||
@ -190,24 +190,24 @@ impl Tutorial {
|
|||||||
Some(ID::Lane(l)) => {
|
Some(ID::Lane(l)) => {
|
||||||
if app.primary.map.get_l(l).is_biking() && !tut.inspected_bike_lane {
|
if app.primary.map.get_l(l).is_biking() && !tut.inspected_bike_lane {
|
||||||
tut.inspected_bike_lane = true;
|
tut.inspected_bike_lane = true;
|
||||||
self.top_center = tut.make_top_center(ctx, false);
|
self.top_right = tut.make_top_right(ctx, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(ID::Building(_)) => {
|
Some(ID::Building(_)) => {
|
||||||
if !tut.inspected_building {
|
if !tut.inspected_building {
|
||||||
tut.inspected_building = true;
|
tut.inspected_building = true;
|
||||||
self.top_center = tut.make_top_center(ctx, false);
|
self.top_right = tut.make_top_right(ctx, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(ID::Intersection(i)) => {
|
Some(ID::Intersection(i)) => {
|
||||||
let i = app.primary.map.get_i(i);
|
let i = app.primary.map.get_i(i);
|
||||||
if i.is_stop_sign() && !tut.inspected_stop_sign {
|
if i.is_stop_sign() && !tut.inspected_stop_sign {
|
||||||
tut.inspected_stop_sign = true;
|
tut.inspected_stop_sign = true;
|
||||||
self.top_center = tut.make_top_center(ctx, false);
|
self.top_right = tut.make_top_right(ctx, false);
|
||||||
}
|
}
|
||||||
if i.is_border() && !tut.inspected_border {
|
if i.is_border() && !tut.inspected_border {
|
||||||
tut.inspected_border = true;
|
tut.inspected_border = true;
|
||||||
self.top_center = tut.make_top_center(ctx, false);
|
self.top_right = tut.make_top_right(ctx, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -233,7 +233,7 @@ impl Tutorial {
|
|||||||
if !tut.was_paused && is_paused {
|
if !tut.was_paused && is_paused {
|
||||||
tut.num_pauses += 1;
|
tut.num_pauses += 1;
|
||||||
tut.was_paused = true;
|
tut.was_paused = true;
|
||||||
self.top_center = tut.make_top_center(ctx, false);
|
self.top_right = tut.make_top_right(ctx, false);
|
||||||
}
|
}
|
||||||
if tut.num_pauses == 3 {
|
if tut.num_pauses == 3 {
|
||||||
tut.next();
|
tut.next();
|
||||||
@ -249,14 +249,14 @@ impl Tutorial {
|
|||||||
.is_none();
|
.is_none();
|
||||||
if !tut.car_parked && is_parked && tut.following_car {
|
if !tut.car_parked && is_parked && tut.following_car {
|
||||||
tut.car_parked = true;
|
tut.car_parked = true;
|
||||||
self.top_center = tut.make_top_center(ctx, false);
|
self.top_right = tut.make_top_right(ctx, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if following_car && !tut.following_car {
|
if following_car && !tut.following_car {
|
||||||
// TODO There's a delay of one event before the checklist updates, because the
|
// TODO There's a delay of one event before the checklist updates, because the
|
||||||
// info panel opening happens at the end of the event. Not a big deal.
|
// info panel opening happens at the end of the event. Not a big deal.
|
||||||
tut.following_car = true;
|
tut.following_car = true;
|
||||||
self.top_center = tut.make_top_center(ctx, false);
|
self.top_right = tut.make_top_right(ctx, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if tut.prank_done {
|
if tut.prank_done {
|
||||||
@ -382,7 +382,7 @@ impl GameplayState for Tutorial {
|
|||||||
grey_out_map(g, app);
|
grey_out_map(g, app);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.top_center.draw(g);
|
self.top_right.draw(g);
|
||||||
|
|
||||||
if let Some(ref msg) = self.msg_panel {
|
if let Some(ref msg) = self.msg_panel {
|
||||||
// Arrows underneath the message panel, but on top of other panels
|
// Arrows underneath the message panel, but on top of other panels
|
||||||
@ -419,7 +419,7 @@ impl GameplayState for Tutorial {
|
|||||||
|
|
||||||
fn recreate_panels(&mut self, ctx: &mut EventCtx, app: &App) {
|
fn recreate_panels(&mut self, ctx: &mut EventCtx, app: &App) {
|
||||||
let tut = app.session.tutorial.as_ref().unwrap();
|
let tut = app.session.tutorial.as_ref().unwrap();
|
||||||
self.top_center = tut.make_top_center(ctx, self.last_finished_task >= Task::WatchBikes);
|
self.top_right = tut.make_top_right(ctx, self.last_finished_task >= Task::WatchBikes);
|
||||||
|
|
||||||
// Time can't pass while self.msg_panel is active
|
// Time can't pass while self.msg_panel is active
|
||||||
}
|
}
|
||||||
@ -727,7 +727,7 @@ impl TutorialState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_top_center(&self, ctx: &mut EventCtx, edit_map: bool) -> Panel {
|
fn make_top_right(&self, ctx: &mut EventCtx, edit_map: bool) -> Panel {
|
||||||
let mut col = vec![Widget::row(vec![
|
let mut col = vec![Widget::row(vec![
|
||||||
Line("Tutorial").small_heading().into_widget(ctx),
|
Line("Tutorial").small_heading().into_widget(ctx),
|
||||||
Widget::vert_separator(ctx, 50.0),
|
Widget::vert_separator(ctx, 50.0),
|
||||||
@ -784,7 +784,7 @@ impl TutorialState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Panel::new(Widget::col(col))
|
Panel::new(Widget::col(col))
|
||||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
.aligned(HorizontalAlignment::Right, VerticalAlignment::Top)
|
||||||
.build(ctx)
|
.build(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,7 +808,7 @@ impl TutorialState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Box::new(Tutorial {
|
Box::new(Tutorial {
|
||||||
top_center: self.make_top_center(ctx, last_finished_task >= Task::WatchBikes),
|
top_right: self.make_top_right(ctx, last_finished_task >= Task::WatchBikes),
|
||||||
last_finished_task,
|
last_finished_task,
|
||||||
|
|
||||||
msg_panel: if let Some((ref lines, horiz_align, _)) = self.lines() {
|
msg_panel: if let Some((ref lines, horiz_align, _)) = self.lines() {
|
||||||
@ -1191,7 +1191,7 @@ impl TutorialState {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
let top_center = state.make_top_center(ctx, true);
|
let top_right = state.make_top_right(ctx, true);
|
||||||
state.stages.push(
|
state.stages.push(
|
||||||
Stage::new(Task::FixBikes)
|
Stage::new(Task::FixBikes)
|
||||||
.scenario(bike_lane_scenario)
|
.scenario(bike_lane_scenario)
|
||||||
@ -1216,7 +1216,7 @@ impl TutorialState {
|
|||||||
)
|
)
|
||||||
.msg(
|
.msg(
|
||||||
vec!["To edit lanes, click 'edit map' and then select a lane."],
|
vec!["To edit lanes, click 'edit map' and then select a lane."],
|
||||||
arrow(top_center.center_of("edit map")),
|
arrow(top_right.center_of("edit map")),
|
||||||
)
|
)
|
||||||
.msg(
|
.msg(
|
||||||
vec![
|
vec![
|
||||||
|
@ -238,9 +238,7 @@ impl TimePanel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Widget::col(vec![
|
Widget::col(vec![
|
||||||
Text::from(Line(self.time.ampm_tostring()).big_monospaced())
|
Text::from(Line(self.time.ampm_tostring()).big_monospaced()).into_widget(ctx),
|
||||||
.into_widget(ctx)
|
|
||||||
.centered_horiz(),
|
|
||||||
time_bar,
|
time_bar,
|
||||||
trip_results,
|
trip_results,
|
||||||
record_trips,
|
record_trips,
|
||||||
|
Loading…
Reference in New Issue
Block a user