Make the start/end rectangular filter actually apply to the trip tables. #574

This commit is contained in:
Dustin Carlino 2021-03-31 11:06:40 -07:00
parent c89e918fec
commit 0e86b94408
4 changed files with 85 additions and 46 deletions

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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)

View File

@ -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),
} }
} }
} }