1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
use maplit::btreeset;

use map_model::RoadID;
use widgetry::tools::PopupMsg;
use widgetry::{
    EventCtx, GfxCtx, HorizontalAlignment, Line, Outcome, Panel, State, VerticalAlignment, Widget,
};

use crate::app::{App, Transition};
use crate::common::RoadSelector;

pub struct BulkSelect {
    panel: Panel,
    selector: RoadSelector,
}

impl BulkSelect {
    pub fn new_state(ctx: &mut EventCtx, app: &mut App, start: RoadID) -> Box<dyn State<App>> {
        let selector = RoadSelector::new(ctx, app, btreeset! {start});
        let panel = make_select_panel(ctx, &selector);
        Box::new(BulkSelect { panel, selector })
    }
}

fn make_select_panel(ctx: &mut EventCtx, selector: &RoadSelector) -> Panel {
    Panel::new_builder(Widget::col(vec![
        Line("Select many roads").small_heading().into_widget(ctx),
        selector.make_controls(ctx),
        Widget::row(vec![
            ctx.style()
                .btn_outline
                .text(format!(
                    "Export {} roads to shared-row",
                    selector.roads.len()
                ))
                .build_widget(ctx, "export roads to shared-row"),
            ctx.style()
                .btn_outline
                .text("export one road to Streetmix")
                .build_def(ctx),
            ctx.style().btn_close_widget(ctx),
        ])
        .evenly_spaced(),
    ]))
    .aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
    .build(ctx)
}

impl State<App> for BulkSelect {
    fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
        match self.panel.event(ctx) {
            Outcome::Clicked(x) => match x.as_ref() {
                "close" => {
                    return Transition::Pop;
                }
                "export roads to shared-row" => {
                    let path = crate::debug::shared_row::export(
                        self.selector.roads.iter().cloned().collect(),
                        self.selector.intersections.iter().cloned().collect(),
                        &app.primary.map,
                    );
                    return Transition::Push(PopupMsg::new_state(
                        ctx,
                        "Roads exported",
                        vec![format!("Roads exported to shared-row format at {}", path)],
                    ));
                }
                "export one road to Streetmix" => {
                    let path = crate::debug::streetmix::export(
                        *self.selector.roads.iter().next().unwrap(),
                        &app.primary.map,
                    );
                    return Transition::Push(PopupMsg::new_state(
                        ctx,
                        "One road exported",
                        vec![format!(
                            "One arbitrary road from your selection exported to Streetmix format \
                             at {}",
                            path
                        )],
                    ));
                }
                x => {
                    if self.selector.event(ctx, app, Some(x)) {
                        self.panel = make_select_panel(ctx, &self.selector);
                    }
                }
            },
            _ => {
                if self.selector.event(ctx, app, None) {
                    self.panel = make_select_panel(ctx, &self.selector);
                }
            }
        }

        Transition::Keep
    }

    fn draw(&self, g: &mut GfxCtx, app: &App) {
        self.panel.draw(g);
        self.selector.draw(g, app, true);
    }
}