mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-26 07:52:05 +03:00
basic accordians for trips
This commit is contained in:
parent
7be5b3f34a
commit
8ed2d596ff
@ -6,6 +6,7 @@ use ezgui::{Btn, Color, EventCtx, Line, Text, TextExt, Widget};
|
||||
use geom::{Angle, Circle, Time};
|
||||
use map_model::{BuildingID, LaneID, Traversable, SIDEWALK_THICKNESS};
|
||||
use sim::{DrawPedestrianInput, PedestrianID, PersonID, TripMode, TripResult};
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
pub fn info(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BuildingID) -> Vec<Widget> {
|
||||
let mut rows = header(ctx, app, details, id, Tab::BldgInfo(id));
|
||||
@ -104,7 +105,7 @@ pub fn people(ctx: &mut EventCtx, app: &App, details: &mut Details, id: Building
|
||||
let label = format!("Person #{}", p.0);
|
||||
details
|
||||
.hyperlinks
|
||||
.insert(label.clone(), Tab::PersonTrips(p));
|
||||
.insert(label.clone(), Tab::PersonTrips(p, BTreeSet::new()));
|
||||
rows.push(Widget::col(vec![
|
||||
Btn::text_bg1(label).build_def(ctx, None),
|
||||
if let Some((t, mode)) = next_trip {
|
||||
|
@ -19,8 +19,10 @@ use ezgui::{
|
||||
};
|
||||
use geom::{Circle, Distance, Duration, Time};
|
||||
use map_model::{AreaID, BuildingID, BusStopID, IntersectionID, LaneID};
|
||||
use sim::{AgentID, Analytics, CarID, PedestrianID, PersonID, PersonState, TripMode, VehicleType};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use sim::{
|
||||
AgentID, Analytics, CarID, PedestrianID, PersonID, PersonState, TripID, TripMode, VehicleType,
|
||||
};
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap};
|
||||
|
||||
pub struct InfoPanel {
|
||||
tab: Tab,
|
||||
@ -40,7 +42,7 @@ pub struct InfoPanel {
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub enum Tab {
|
||||
PersonStatus(PersonID),
|
||||
PersonTrips(PersonID),
|
||||
PersonTrips(PersonID, BTreeSet<TripID>),
|
||||
PersonBio(PersonID),
|
||||
|
||||
BusStatus(CarID),
|
||||
@ -100,7 +102,7 @@ impl Tab {
|
||||
// TODO Temporary hack until object actions go away.
|
||||
fn to_id(self, app: &App) -> Option<ID> {
|
||||
match self {
|
||||
Tab::PersonStatus(p) | Tab::PersonTrips(p) | Tab::PersonBio(p) => {
|
||||
Tab::PersonStatus(p) | Tab::PersonTrips(p, _) | Tab::PersonBio(p) => {
|
||||
match app.primary.sim.get_person(p).state {
|
||||
PersonState::Inside(b) => Some(ID::Building(b)),
|
||||
PersonState::Trip(t) => app
|
||||
@ -177,7 +179,9 @@ impl InfoPanel {
|
||||
|
||||
let (mut col, main_tab) = match tab {
|
||||
Tab::PersonStatus(p) => (person::status(ctx, app, &mut details, p), true),
|
||||
Tab::PersonTrips(p) => (person::trips(ctx, app, &mut details, p), false),
|
||||
Tab::PersonTrips(p, ref open) => {
|
||||
(person::trips(ctx, app, &mut details, p, open), false)
|
||||
}
|
||||
Tab::PersonBio(p) => (person::bio(ctx, app, &mut details, p), false),
|
||||
Tab::BusStatus(c) => (bus::bus_status(ctx, app, &mut details, c), true),
|
||||
Tab::BusDelays(c) => (bus::bus_delays(ctx, app, &mut details, c), true),
|
||||
|
@ -3,7 +3,10 @@ use crate::info::{building, header_btns, make_table, make_tabs, trip, Details, T
|
||||
use crate::render::Renderable;
|
||||
use ezgui::{Btn, Color, EventCtx, Line, TextExt, Widget};
|
||||
use map_model::Map;
|
||||
use sim::{AgentID, CarID, PedestrianID, Person, PersonID, PersonState, TripResult, VehicleType};
|
||||
use sim::{
|
||||
AgentID, CarID, PedestrianID, Person, PersonID, PersonState, TripID, TripResult, VehicleType,
|
||||
};
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
pub fn status(ctx: &mut EventCtx, app: &App, details: &mut Details, id: PersonID) -> Vec<Widget> {
|
||||
let mut rows = header(ctx, app, details, id, Tab::PersonStatus(id));
|
||||
@ -43,15 +46,29 @@ pub fn status(ctx: &mut EventCtx, app: &App, details: &mut Details, id: PersonID
|
||||
}
|
||||
}
|
||||
|
||||
rows.push(trip::details(ctx, app, t, details));
|
||||
let mut open_trips = BTreeSet::new();
|
||||
open_trips.insert(t);
|
||||
rows.push(trip::details(ctx, app, t, details, id, open_trips));
|
||||
}
|
||||
}
|
||||
|
||||
rows
|
||||
}
|
||||
|
||||
pub fn trips(ctx: &mut EventCtx, app: &App, details: &mut Details, id: PersonID) -> Vec<Widget> {
|
||||
let mut rows = header(ctx, app, details, id, Tab::PersonTrips(id));
|
||||
pub fn trips(
|
||||
ctx: &mut EventCtx,
|
||||
app: &App,
|
||||
details: &mut Details,
|
||||
id: PersonID,
|
||||
open_trips: &BTreeSet<TripID>,
|
||||
) -> Vec<Widget> {
|
||||
let mut rows = header(
|
||||
ctx,
|
||||
app,
|
||||
details,
|
||||
id,
|
||||
Tab::PersonTrips(id, open_trips.clone()),
|
||||
);
|
||||
|
||||
let map = &app.primary.map;
|
||||
let sim = &app.primary.sim;
|
||||
@ -79,7 +96,26 @@ pub fn trips(ctx: &mut EventCtx, app: &App, details: &mut Details, id: PersonID)
|
||||
}
|
||||
TripResult::TripDoesntExist => unreachable!(),
|
||||
}
|
||||
rows.push(trip::details(ctx, app, *t, details));
|
||||
if open_trips.contains(t) {
|
||||
rows.push(trip::details(ctx, app, *t, details, id, open_trips.clone()));
|
||||
} else {
|
||||
// TODO Style wrong. Button should be the entire row.
|
||||
rows.push(
|
||||
Widget::row(vec![
|
||||
format!("Trip #{}", t.0).draw_text(ctx),
|
||||
Btn::text_fg("▼")
|
||||
.build(ctx, format!("show Trip #{}", t.0), None)
|
||||
.align_right(),
|
||||
])
|
||||
.outline(2.0, Color::WHITE),
|
||||
);
|
||||
let mut new_trips = open_trips.clone();
|
||||
new_trips.insert(*t);
|
||||
details.hyperlinks.insert(
|
||||
format!("show Trip #{}", t.0),
|
||||
Tab::PersonTrips(id, new_trips),
|
||||
);
|
||||
}
|
||||
}
|
||||
if wheres_waldo {
|
||||
rows.push(current_status(ctx, person, map));
|
||||
@ -182,23 +218,26 @@ pub fn parked_car(ctx: &EventCtx, app: &App, details: &mut Details, id: CarID) -
|
||||
fn header(ctx: &EventCtx, app: &App, details: &mut Details, id: PersonID, tab: Tab) -> Vec<Widget> {
|
||||
let mut rows = vec![];
|
||||
|
||||
let descr = match app.primary.sim.get_person(id).state {
|
||||
let (current_trip, descr) = match app.primary.sim.get_person(id).state {
|
||||
PersonState::Inside(b) => {
|
||||
building::draw_occupants(details, app, b, Some(id));
|
||||
"inside"
|
||||
(None, "inside")
|
||||
}
|
||||
PersonState::Trip(t) => match app.primary.sim.trip_to_agent(t).ok() {
|
||||
Some(AgentID::Pedestrian(_)) => "on foot",
|
||||
Some(AgentID::Car(c)) => match c.1 {
|
||||
VehicleType::Car => "in a car",
|
||||
VehicleType::Bike => "on a bike",
|
||||
VehicleType::Bus => unreachable!(),
|
||||
PersonState::Trip(t) => (
|
||||
Some(t),
|
||||
match app.primary.sim.trip_to_agent(t).ok() {
|
||||
Some(AgentID::Pedestrian(_)) => "on foot",
|
||||
Some(AgentID::Car(c)) => match c.1 {
|
||||
VehicleType::Car => "in a car",
|
||||
VehicleType::Bike => "on a bike",
|
||||
VehicleType::Bus => unreachable!(),
|
||||
},
|
||||
// TODO Really should clean up the TripModeChange issue
|
||||
None => "...",
|
||||
},
|
||||
// TODO Really should clean up the TripModeChange issue
|
||||
None => "...",
|
||||
},
|
||||
PersonState::OffMap => "off map",
|
||||
PersonState::Limbo => "in limbo",
|
||||
),
|
||||
PersonState::OffMap => (None, "off map"),
|
||||
PersonState::Limbo => (None, "in limbo"),
|
||||
};
|
||||
|
||||
rows.push(Widget::row(vec![
|
||||
@ -208,13 +247,17 @@ fn header(ctx: &EventCtx, app: &App, details: &mut Details, id: PersonID, tab: T
|
||||
header_btns(ctx),
|
||||
]));
|
||||
|
||||
let mut open_trips = BTreeSet::new();
|
||||
if let Some(t) = current_trip {
|
||||
open_trips.insert(t);
|
||||
}
|
||||
rows.push(make_tabs(
|
||||
ctx,
|
||||
&mut details.hyperlinks,
|
||||
tab,
|
||||
vec![
|
||||
("Status", Tab::PersonStatus(id)),
|
||||
("Trips", Tab::PersonTrips(id)),
|
||||
("Trips", Tab::PersonTrips(id, open_trips)),
|
||||
("Bio", Tab::PersonBio(id)),
|
||||
],
|
||||
));
|
||||
|
@ -1,16 +1,24 @@
|
||||
use crate::app::App;
|
||||
use crate::colors;
|
||||
use crate::helpers::ID;
|
||||
use crate::info::{make_table, Details};
|
||||
use crate::info::{make_table, Details, Tab};
|
||||
use crate::render::dashed_lines;
|
||||
use ezgui::{
|
||||
Btn, Color, EventCtx, GeomBatch, Line, Plot, PlotOptions, RewriteColor, Series, Text, Widget,
|
||||
};
|
||||
use geom::{Angle, Distance, Duration, Polygon, Pt2D, Time};
|
||||
use map_model::{Map, Path, PathStep};
|
||||
use sim::{TripEndpoint, TripID, TripPhaseType, TripResult};
|
||||
use sim::{PersonID, TripEndpoint, TripID, TripPhaseType, TripResult};
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
pub fn details(ctx: &mut EventCtx, app: &App, trip: TripID, details: &mut Details) -> Widget {
|
||||
pub fn details(
|
||||
ctx: &mut EventCtx,
|
||||
app: &App,
|
||||
trip: TripID,
|
||||
details: &mut Details,
|
||||
person: PersonID,
|
||||
mut open_trips: BTreeSet<TripID>,
|
||||
) -> Widget {
|
||||
let map = &app.primary.map;
|
||||
let sim = &app.primary.sim;
|
||||
let phases = sim.get_analytics().get_trip_phases(trip, map);
|
||||
@ -24,7 +32,19 @@ pub fn details(ctx: &mut EventCtx, app: &App, trip: TripID, details: &mut Detail
|
||||
TripResult::TripDone => ("finished", None),
|
||||
TripResult::TripDoesntExist => unreachable!(),
|
||||
};
|
||||
let mut col = vec![Line(format!("Trip #{} ({})", trip.0, trip_status)).draw(ctx)];
|
||||
let mut col = vec![Widget::row(vec![
|
||||
Line(format!("Trip #{} ({})", trip.0, trip_status)).draw(ctx),
|
||||
Btn::text_fg("▲")
|
||||
.build(ctx, format!("hide Trip #{}", trip.0), None)
|
||||
.align_right(),
|
||||
])
|
||||
.outline(2.0, Color::WHITE)];
|
||||
|
||||
open_trips.remove(&trip);
|
||||
details.hyperlinks.insert(
|
||||
format!("hide Trip #{}", trip.0),
|
||||
Tab::PersonTrips(person, open_trips),
|
||||
);
|
||||
|
||||
let mut kv = vec![
|
||||
("Departure", start_time.ampm_tostring()),
|
||||
|
Loading…
Reference in New Issue
Block a user