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"),
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 {
return false;
}

View File

@ -22,6 +22,7 @@ pub struct TripTable {
finished_trips_table: Table<App, FinishedTrip, Filters>,
cancelled_trips_table: Table<App, CancelledTrip, Filters>,
unfinished_trips_table: Table<App, UnfinishedTrip, Filters>,
dirty: bool,
}
impl TripTable {
@ -111,6 +112,7 @@ impl TripTable {
finished_trips_table,
cancelled_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) {
// if true, tabs handled the action
} 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(
ctx,
self.panel.stash("starts_in"),
));
} else if x == "filter ends" {
self.dirty = true;
return Transition::Push(RectangularSelector::new(
ctx,
self.panel.stash("ends_in"),
@ -157,28 +163,33 @@ impl State<App> for TripTable {
return t;
}
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);
}
other => unimplemented!("unknown tab: {}", other),
}
self.dirty = true;
}
_ => {}
}
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
}
@ -193,8 +204,8 @@ struct FinishedTrip {
mode: TripMode,
modified: bool,
capped: bool,
starts_off_map: bool,
ends_off_map: bool,
start: TripEndpoint,
end: TripEndpoint,
departure: Time,
duration_after: Duration,
duration_before: Duration,
@ -206,8 +217,8 @@ struct CancelledTrip {
id: TripID,
mode: TripMode,
departure: Time,
starts_off_map: bool,
ends_off_map: bool,
start: TripEndpoint,
end: TripEndpoint,
duration_before: Duration,
reason: String,
}
@ -252,14 +263,6 @@ fn produce_raw_data(app: &App) -> (Vec<FinishedTrip>, Vec<CancelledTrip>) {
let sim = &app.primary.sim;
for (_, id, mode, maybe_duration_after) in &sim.get_analytics().finished_trips {
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 {
times.get(id).cloned()
} else {
@ -274,8 +277,8 @@ fn produce_raw_data(app: &App) -> (Vec<FinishedTrip>, Vec<CancelledTrip>) {
id: *id,
mode: *mode,
departure: trip.departure,
starts_off_map,
ends_off_map,
start: trip.start,
end: trip.end,
duration_before: duration_before.unwrap_or(Duration::ZERO),
reason,
});
@ -291,8 +294,8 @@ fn produce_raw_data(app: &App) -> (Vec<FinishedTrip>, Vec<CancelledTrip>) {
departure: trip.departure,
modified: trip.modified,
capped: trip.capped,
starts_off_map,
ends_off_map,
start: trip.start,
end: trip.end,
duration_after,
duration_before: duration_before.unwrap(),
waiting,
@ -403,16 +406,34 @@ fn make_table_finished_trips(app: &App) -> Table<App, FinishedTrip, Filters> {
.unwrap_or(true),
}
}),
apply: Box::new(|state, x| {
apply: Box::new(|state, x, app| {
if !state.modes.contains(&x.mode) {
return false;
}
if !state.off_map_starts && x.starts_off_map {
if !state.off_map_starts && matches!(x.start, TripEndpoint::Border(_)) {
return false;
}
if !state.off_map_ends && x.ends_off_map {
if !state.off_map_ends && matches!(x.end, TripEndpoint::Border(_)) {
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 {
return false;
}
@ -575,16 +596,34 @@ fn make_table_cancelled_trips(app: &App) -> Table<App, CancelledTrip, Filters> {
capped_trips: true,
}
}),
apply: Box::new(|state, x| {
apply: Box::new(|state, x, app| {
if !state.modes.contains(&x.mode) {
return false;
}
if !state.off_map_starts && x.starts_off_map {
if !state.off_map_starts && matches!(x.start, TripEndpoint::Border(_)) {
return false;
}
if !state.off_map_ends && x.ends_off_map {
if !state.off_map_ends && matches!(x.end, TripEndpoint::Border(_)) {
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
}),
};
@ -686,7 +725,7 @@ fn make_table_unfinished_trips(app: &App) -> Table<App, UnfinishedTrip, Filters>
capped_trips: true,
}
}),
apply: Box::new(|state, x| {
apply: Box::new(|state, x, _| {
if !state.modes.contains(&x.mode) {
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 {
TripMode::Walk | TripMode::Transit => (if from {
self.start_sidewalk_spot(map)

View File

@ -35,7 +35,7 @@ pub struct Filter<A, T, F> {
pub state: F,
pub to_controls: Box<dyn Fn(&mut EventCtx, &A, &F) -> Widget>,
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> {
@ -82,7 +82,7 @@ impl<A, T, F> Table<A, T, F> {
// Filter
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);
}
}
@ -186,7 +186,7 @@ impl<A, T> Filter<A, T, ()> {
state: (),
to_controls: Box::new(|_, _, _| Widget::nothing()),
from_controls: Box::new(|_| ()),
apply: Box::new(|_, _| true),
apply: Box::new(|_, _, _| true),
}
}
}