mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 09:24:26 +03:00
Make the start/end rectangular filter actually apply to the trip tables. #574
This commit is contained in:
parent
c89e918fec
commit
0e86b94408
@ -190,7 +190,7 @@ fn make_table(app: &App) -> Table<App, Entry, Filters> {
|
|||||||
starts_off_map: panel.is_checked("starting off-map"),
|
starts_off_map: panel.is_checked("starting off-map"),
|
||||||
ends_off_map: panel.is_checked("ending off-map"),
|
ends_off_map: panel.is_checked("ending off-map"),
|
||||||
}),
|
}),
|
||||||
apply: Box::new(|state, x| {
|
apply: Box::new(|state, x, _| {
|
||||||
if !state.starts_off_map && x.starts_off_map {
|
if !state.starts_off_map && x.starts_off_map {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ pub struct TripTable {
|
|||||||
finished_trips_table: Table<App, FinishedTrip, Filters>,
|
finished_trips_table: Table<App, FinishedTrip, Filters>,
|
||||||
cancelled_trips_table: Table<App, CancelledTrip, Filters>,
|
cancelled_trips_table: Table<App, CancelledTrip, Filters>,
|
||||||
unfinished_trips_table: Table<App, UnfinishedTrip, Filters>,
|
unfinished_trips_table: Table<App, UnfinishedTrip, Filters>,
|
||||||
|
dirty: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TripTable {
|
impl TripTable {
|
||||||
@ -111,6 +112,7 @@ impl TripTable {
|
|||||||
finished_trips_table,
|
finished_trips_table,
|
||||||
cancelled_trips_table,
|
cancelled_trips_table,
|
||||||
unfinished_trips_table,
|
unfinished_trips_table,
|
||||||
|
dirty: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,11 +141,15 @@ impl State<App> for TripTable {
|
|||||||
} else if self.table_tabs.handle_action(ctx, &x, &mut self.panel) {
|
} else if self.table_tabs.handle_action(ctx, &x, &mut self.panel) {
|
||||||
// if true, tabs handled the action
|
// if true, tabs handled the action
|
||||||
} else if x == "filter starts" {
|
} else if x == "filter starts" {
|
||||||
|
// Set the dirty bit, so we re-apply the filters when the selector state is
|
||||||
|
// done.
|
||||||
|
self.dirty = true;
|
||||||
return Transition::Push(RectangularSelector::new(
|
return Transition::Push(RectangularSelector::new(
|
||||||
ctx,
|
ctx,
|
||||||
self.panel.stash("starts_in"),
|
self.panel.stash("starts_in"),
|
||||||
));
|
));
|
||||||
} else if x == "filter ends" {
|
} else if x == "filter ends" {
|
||||||
|
self.dirty = true;
|
||||||
return Transition::Push(RectangularSelector::new(
|
return Transition::Push(RectangularSelector::new(
|
||||||
ctx,
|
ctx,
|
||||||
self.panel.stash("ends_in"),
|
self.panel.stash("ends_in"),
|
||||||
@ -157,28 +163,33 @@ impl State<App> for TripTable {
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.table_tabs.active_tab_idx() {
|
self.dirty = true;
|
||||||
0 => {
|
|
||||||
self.finished_trips_table.panel_changed(&self.panel);
|
|
||||||
self.finished_trips_table
|
|
||||||
.replace_render(ctx, app, &mut self.panel);
|
|
||||||
}
|
|
||||||
1 => {
|
|
||||||
self.cancelled_trips_table.panel_changed(&self.panel);
|
|
||||||
self.cancelled_trips_table
|
|
||||||
.replace_render(ctx, app, &mut self.panel);
|
|
||||||
}
|
|
||||||
2 => {
|
|
||||||
self.unfinished_trips_table.panel_changed(&self.panel);
|
|
||||||
self.unfinished_trips_table
|
|
||||||
.replace_render(ctx, app, &mut self.panel);
|
|
||||||
}
|
|
||||||
other => unimplemented!("unknown tab: {}", other),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.dirty {
|
||||||
|
self.dirty = false;
|
||||||
|
match self.table_tabs.active_tab_idx() {
|
||||||
|
0 => {
|
||||||
|
self.finished_trips_table.panel_changed(&self.panel);
|
||||||
|
self.finished_trips_table
|
||||||
|
.replace_render(ctx, app, &mut self.panel);
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
self.cancelled_trips_table.panel_changed(&self.panel);
|
||||||
|
self.cancelled_trips_table
|
||||||
|
.replace_render(ctx, app, &mut self.panel);
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
self.unfinished_trips_table.panel_changed(&self.panel);
|
||||||
|
self.unfinished_trips_table
|
||||||
|
.replace_render(ctx, app, &mut self.panel);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Transition::Keep
|
Transition::Keep
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,8 +204,8 @@ struct FinishedTrip {
|
|||||||
mode: TripMode,
|
mode: TripMode,
|
||||||
modified: bool,
|
modified: bool,
|
||||||
capped: bool,
|
capped: bool,
|
||||||
starts_off_map: bool,
|
start: TripEndpoint,
|
||||||
ends_off_map: bool,
|
end: TripEndpoint,
|
||||||
departure: Time,
|
departure: Time,
|
||||||
duration_after: Duration,
|
duration_after: Duration,
|
||||||
duration_before: Duration,
|
duration_before: Duration,
|
||||||
@ -206,8 +217,8 @@ struct CancelledTrip {
|
|||||||
id: TripID,
|
id: TripID,
|
||||||
mode: TripMode,
|
mode: TripMode,
|
||||||
departure: Time,
|
departure: Time,
|
||||||
starts_off_map: bool,
|
start: TripEndpoint,
|
||||||
ends_off_map: bool,
|
end: TripEndpoint,
|
||||||
duration_before: Duration,
|
duration_before: Duration,
|
||||||
reason: String,
|
reason: String,
|
||||||
}
|
}
|
||||||
@ -252,14 +263,6 @@ fn produce_raw_data(app: &App) -> (Vec<FinishedTrip>, Vec<CancelledTrip>) {
|
|||||||
let sim = &app.primary.sim;
|
let sim = &app.primary.sim;
|
||||||
for (_, id, mode, maybe_duration_after) in &sim.get_analytics().finished_trips {
|
for (_, id, mode, maybe_duration_after) in &sim.get_analytics().finished_trips {
|
||||||
let trip = sim.trip_info(*id);
|
let trip = sim.trip_info(*id);
|
||||||
let starts_off_map = match trip.start {
|
|
||||||
TripEndpoint::Border(_) => true,
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
let ends_off_map = match trip.end {
|
|
||||||
TripEndpoint::Border(_) => true,
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
let duration_before = if let Some(ref times) = trip_times_before {
|
let duration_before = if let Some(ref times) = trip_times_before {
|
||||||
times.get(id).cloned()
|
times.get(id).cloned()
|
||||||
} else {
|
} else {
|
||||||
@ -274,8 +277,8 @@ fn produce_raw_data(app: &App) -> (Vec<FinishedTrip>, Vec<CancelledTrip>) {
|
|||||||
id: *id,
|
id: *id,
|
||||||
mode: *mode,
|
mode: *mode,
|
||||||
departure: trip.departure,
|
departure: trip.departure,
|
||||||
starts_off_map,
|
start: trip.start,
|
||||||
ends_off_map,
|
end: trip.end,
|
||||||
duration_before: duration_before.unwrap_or(Duration::ZERO),
|
duration_before: duration_before.unwrap_or(Duration::ZERO),
|
||||||
reason,
|
reason,
|
||||||
});
|
});
|
||||||
@ -291,8 +294,8 @@ fn produce_raw_data(app: &App) -> (Vec<FinishedTrip>, Vec<CancelledTrip>) {
|
|||||||
departure: trip.departure,
|
departure: trip.departure,
|
||||||
modified: trip.modified,
|
modified: trip.modified,
|
||||||
capped: trip.capped,
|
capped: trip.capped,
|
||||||
starts_off_map,
|
start: trip.start,
|
||||||
ends_off_map,
|
end: trip.end,
|
||||||
duration_after,
|
duration_after,
|
||||||
duration_before: duration_before.unwrap(),
|
duration_before: duration_before.unwrap(),
|
||||||
waiting,
|
waiting,
|
||||||
@ -403,16 +406,34 @@ fn make_table_finished_trips(app: &App) -> Table<App, FinishedTrip, Filters> {
|
|||||||
.unwrap_or(true),
|
.unwrap_or(true),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
apply: Box::new(|state, x| {
|
apply: Box::new(|state, x, app| {
|
||||||
if !state.modes.contains(&x.mode) {
|
if !state.modes.contains(&x.mode) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if !state.off_map_starts && x.starts_off_map {
|
if !state.off_map_starts && matches!(x.start, TripEndpoint::Border(_)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if !state.off_map_ends && x.ends_off_map {
|
if !state.off_map_ends && matches!(x.end, TripEndpoint::Border(_)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if let Some(ref polygon) = state.starts_in {
|
||||||
|
if x.start
|
||||||
|
.pos(x.mode, true, &app.primary.map)
|
||||||
|
.map(|pos| !polygon.contains_pt(pos.pt(&app.primary.map)))
|
||||||
|
.unwrap_or(true)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(ref polygon) = state.ends_in {
|
||||||
|
if x.end
|
||||||
|
.pos(x.mode, false, &app.primary.map)
|
||||||
|
.map(|pos| !polygon.contains_pt(pos.pt(&app.primary.map)))
|
||||||
|
.unwrap_or(true)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
if !state.unmodified_trips && !x.modified {
|
if !state.unmodified_trips && !x.modified {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -575,16 +596,34 @@ fn make_table_cancelled_trips(app: &App) -> Table<App, CancelledTrip, Filters> {
|
|||||||
capped_trips: true,
|
capped_trips: true,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
apply: Box::new(|state, x| {
|
apply: Box::new(|state, x, app| {
|
||||||
if !state.modes.contains(&x.mode) {
|
if !state.modes.contains(&x.mode) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if !state.off_map_starts && x.starts_off_map {
|
if !state.off_map_starts && matches!(x.start, TripEndpoint::Border(_)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if !state.off_map_ends && x.ends_off_map {
|
if !state.off_map_ends && matches!(x.end, TripEndpoint::Border(_)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if let Some(ref polygon) = state.starts_in {
|
||||||
|
if x.start
|
||||||
|
.pos(x.mode, true, &app.primary.map)
|
||||||
|
.map(|pos| !polygon.contains_pt(pos.pt(&app.primary.map)))
|
||||||
|
.unwrap_or(true)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(ref polygon) = state.ends_in {
|
||||||
|
if x.end
|
||||||
|
.pos(x.mode, false, &app.primary.map)
|
||||||
|
.map(|pos| !polygon.contains_pt(pos.pt(&app.primary.map)))
|
||||||
|
.unwrap_or(true)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
@ -686,7 +725,7 @@ fn make_table_unfinished_trips(app: &App) -> Table<App, UnfinishedTrip, Filters>
|
|||||||
capped_trips: true,
|
capped_trips: true,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
apply: Box::new(|state, x| {
|
apply: Box::new(|state, x, _| {
|
||||||
if !state.modes.contains(&x.mode) {
|
if !state.modes.contains(&x.mode) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -366,7 +366,7 @@ impl TripEndpoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pos(self, mode: TripMode, from: bool, map: &Map) -> Option<Position> {
|
pub fn pos(self, mode: TripMode, from: bool, map: &Map) -> Option<Position> {
|
||||||
match mode {
|
match mode {
|
||||||
TripMode::Walk | TripMode::Transit => (if from {
|
TripMode::Walk | TripMode::Transit => (if from {
|
||||||
self.start_sidewalk_spot(map)
|
self.start_sidewalk_spot(map)
|
||||||
|
@ -35,7 +35,7 @@ pub struct Filter<A, T, F> {
|
|||||||
pub state: F,
|
pub state: F,
|
||||||
pub to_controls: Box<dyn Fn(&mut EventCtx, &A, &F) -> Widget>,
|
pub to_controls: Box<dyn Fn(&mut EventCtx, &A, &F) -> Widget>,
|
||||||
pub from_controls: Box<dyn Fn(&Panel) -> F>,
|
pub from_controls: Box<dyn Fn(&Panel) -> F>,
|
||||||
pub apply: Box<dyn Fn(&F, &T) -> bool>,
|
pub apply: Box<dyn Fn(&F, &T, &A) -> bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, T, F> Table<A, T, F> {
|
impl<A, T, F> Table<A, T, F> {
|
||||||
@ -82,7 +82,7 @@ impl<A, T, F> Table<A, T, F> {
|
|||||||
|
|
||||||
// Filter
|
// Filter
|
||||||
for row in &self.data {
|
for row in &self.data {
|
||||||
if (self.filter.apply)(&self.filter.state, row) {
|
if (self.filter.apply)(&self.filter.state, row, app) {
|
||||||
data.push(row);
|
data.push(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,7 +186,7 @@ impl<A, T> Filter<A, T, ()> {
|
|||||||
state: (),
|
state: (),
|
||||||
to_controls: Box::new(|_, _, _| Widget::nothing()),
|
to_controls: Box::new(|_, _, _| Widget::nothing()),
|
||||||
from_controls: Box::new(|_| ()),
|
from_controls: Box::new(|_| ()),
|
||||||
apply: Box::new(|_, _| true),
|
apply: Box::new(|_, _, _| true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user