Make a tool to select a rectangular region. No way to pass back the

results yet. #574
This commit is contained in:
Dustin Carlino 2021-03-31 10:04:23 -07:00
parent 7f4f83d4e0
commit dff923b3e6
3 changed files with 92 additions and 1 deletions

View File

@ -11,6 +11,7 @@ mod commuter;
mod generic_trip_table;
mod misc;
mod parking_overhead;
mod selector;
mod summaries;
mod traffic_signals;
mod trip_table;

View File

@ -0,0 +1,83 @@
use geom::{Polygon, Pt2D};
use widgetry::{
Color, EventCtx, GfxCtx, HorizontalAlignment, Key, Line, Outcome, Panel, State, TextExt,
VerticalAlignment, Widget,
};
use crate::app::{App, Transition};
// TODO Lift to widgetry
pub struct RectangularSelector {
panel: Panel,
region: Option<Polygon>,
corners: Option<(Pt2D, Pt2D, bool)>,
}
impl RectangularSelector {
pub fn new(ctx: &mut EventCtx, region: Option<Polygon>) -> Box<dyn State<App>> {
Box::new(RectangularSelector {
panel: Panel::new(Widget::col(vec![
Widget::row(vec![
Line("Select a rectangular region")
.small_heading()
.into_widget(ctx),
ctx.style().btn_close_widget(ctx),
]),
// TODO Key style
"Hold control, then click and drag to draw".text_widget(ctx),
]))
.aligned(HorizontalAlignment::Right, VerticalAlignment::Top)
.build(ctx),
region,
corners: None,
})
}
}
impl State<App> for RectangularSelector {
fn event(&mut self, ctx: &mut EventCtx, _: &mut App) -> Transition {
if ctx.is_key_down(Key::LeftControl) {
if ctx.input.left_mouse_button_released() {
if let Some((_, _, ref mut dragging)) = self.corners {
*dragging = false;
}
}
if let Some(pt) = ctx.canvas.get_cursor_in_map_space() {
if ctx.input.left_mouse_button_pressed() {
self.corners = Some((pt, pt, true));
}
if let Some((_, ref mut pt2, dragging)) = self.corners {
if dragging {
*pt2 = pt;
}
}
}
} else {
ctx.canvas_movement();
}
match self.panel.event(ctx) {
Outcome::Clicked(x) => match x.as_ref() {
"close" => {
return Transition::Pop;
}
_ => unreachable!(),
},
_ => {}
}
Transition::Keep
}
fn draw(&self, g: &mut GfxCtx, _: &App) {
self.panel.draw(g);
if let Some(p) = self.region.clone() {
g.draw_polygon(Color::BLUE.alpha(0.5), p);
}
if let Some((pt1, pt2, _)) = self.corners {
if let Some(p) = Polygon::rectangle_two_corners(pt1, pt2) {
g.draw_polygon(Color::RED.alpha(0.5), p);
}
}
}
}

View File

@ -9,9 +9,10 @@ use widgetry::{
};
use super::generic_trip_table::{open_trip_transition, preview_trip};
use super::selector::RectangularSelector;
use super::DashTab;
use crate::app::{App, Transition};
use crate::common::{checkbox_per_mode, cmp_duration_shorter, color_for_mode};
use crate::sandbox::dashboards::DashTab;
pub struct TripTable {
tab: DashTab,
@ -136,6 +137,10 @@ impl State<App> for TripTable {
return Transition::Pop;
} else if self.table_tabs.handle_action(ctx, &x, &mut self.panel) {
// if true, tabs handled the action
} else if x == "filter starts" {
return Transition::Push(RectangularSelector::new(ctx, None));
} else if x == "filter ends" {
return Transition::Push(RectangularSelector::new(ctx, None));
} else {
unreachable!("unhandled action: {}", x)
}
@ -313,6 +318,8 @@ fn make_table_finished_trips(app: &App) -> Table<App, FinishedTrip, Filters> {
Widget::row(vec![
Toggle::switch(ctx, "starting off-map", None, state.off_map_starts),
Toggle::switch(ctx, "ending off-map", None, state.off_map_ends),
ctx.style().btn_plain.text("filter starts").build_def(ctx),
ctx.style().btn_plain.text("filter ends").build_def(ctx),
if app.primary.has_modified_trips {
Toggle::switch(
ctx,