mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 12:12:00 +03:00
refactor BulkSelect. use it for access-restricted zones too!
This commit is contained in:
parent
2c27c89796
commit
5b7cf6d532
@ -1,4 +1,5 @@
|
||||
use crate::app::App;
|
||||
use crate::edit::select::RoadSelector;
|
||||
use crate::edit::{apply_map_edits, change_speed_limit, try_change_lt};
|
||||
use crate::game::{msg, State, Transition};
|
||||
use ezgui::{
|
||||
@ -7,15 +8,105 @@ use ezgui::{
|
||||
};
|
||||
use geom::Speed;
|
||||
use map_model::{EditCmd, LaneType, RoadID};
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
pub struct BulkEdit {
|
||||
pub struct BulkSelect {
|
||||
composite: Composite,
|
||||
selector: RoadSelector,
|
||||
}
|
||||
|
||||
impl BulkSelect {
|
||||
pub fn new(ctx: &mut EventCtx, app: &mut App) -> Box<dyn State> {
|
||||
let selector = RoadSelector::new(app, BTreeSet::new());
|
||||
let composite = make_select_composite(ctx, app, &selector);
|
||||
Box::new(BulkSelect {
|
||||
composite,
|
||||
selector,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn make_select_composite(ctx: &mut EventCtx, app: &App, selector: &RoadSelector) -> Composite {
|
||||
Composite::new(Widget::col(vec![
|
||||
Line("Edit many roads").small_heading().draw(ctx),
|
||||
selector.make_controls(ctx),
|
||||
Widget::row(vec![
|
||||
if selector.roads.is_empty() {
|
||||
Btn::text_fg("Edit 0 roads").inactive(ctx)
|
||||
} else {
|
||||
Btn::text_fg(format!("Edit {} roads", selector.roads.len())).build(
|
||||
ctx,
|
||||
"edit roads",
|
||||
hotkey(Key::E),
|
||||
)
|
||||
},
|
||||
if app.opts.dev {
|
||||
Btn::text_fg(format!(
|
||||
"Export {} roads to shared-row",
|
||||
selector.roads.len()
|
||||
))
|
||||
.build(ctx, "export roads to shared-row", None)
|
||||
} else {
|
||||
Widget::nothing()
|
||||
},
|
||||
Btn::text_fg("Cancel").build_def(ctx, hotkey(Key::Escape)),
|
||||
])
|
||||
.evenly_spaced(),
|
||||
]))
|
||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
||||
.build(ctx)
|
||||
}
|
||||
|
||||
impl State for BulkSelect {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
"Cancel" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
"edit roads" => {
|
||||
return Transition::Replace(crate::edit::bulk::BulkEdit::new(
|
||||
ctx,
|
||||
self.selector.roads.iter().cloned().collect(),
|
||||
self.selector.preview.take().unwrap(),
|
||||
));
|
||||
}
|
||||
"export roads to shared-row" => {
|
||||
crate::debug::shared_row::export(
|
||||
self.selector.roads.iter().cloned().collect(),
|
||||
&app.primary.map,
|
||||
);
|
||||
}
|
||||
x => {
|
||||
if self.selector.event(ctx, app, Some(x)) {
|
||||
self.composite = make_select_composite(ctx, app, &self.selector);
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
if self.selector.event(ctx, app, None) {
|
||||
self.composite = make_select_composite(ctx, app, &self.selector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, app: &App) {
|
||||
self.composite.draw(g);
|
||||
self.selector.draw(g, app, true);
|
||||
}
|
||||
}
|
||||
|
||||
struct BulkEdit {
|
||||
composite: Composite,
|
||||
roads: Vec<RoadID>,
|
||||
preview: Drawable,
|
||||
}
|
||||
|
||||
impl BulkEdit {
|
||||
pub fn new(ctx: &mut EventCtx, roads: Vec<RoadID>, preview: Drawable) -> Box<dyn State> {
|
||||
fn new(ctx: &mut EventCtx, roads: Vec<RoadID>, preview: Drawable) -> Box<dyn State> {
|
||||
Box::new(BulkEdit {
|
||||
composite: Composite::new(Widget::col(vec![
|
||||
Line(format!("Editing {} roads", roads.len()))
|
||||
|
@ -160,7 +160,7 @@ impl State for EditMode {
|
||||
match self.top_center.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
"bulk edit" => {
|
||||
return Transition::Push(select::BulkSelect::new(ctx, app));
|
||||
return Transition::Push(bulk::BulkSelect::new(ctx, app));
|
||||
}
|
||||
"finish editing" => {
|
||||
return self.quit(ctx, app);
|
||||
|
@ -1,21 +1,16 @@
|
||||
use crate::app::{App, ShowEverything};
|
||||
use crate::common::CommonState;
|
||||
use crate::game::{State, Transition};
|
||||
use crate::helpers::{intersections_from_roads, ID};
|
||||
use ezgui::{
|
||||
hotkey, Btn, Color, Composite, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key,
|
||||
Line, Outcome, RewriteColor, VerticalAlignment, Widget,
|
||||
};
|
||||
use ezgui::{hotkey, Btn, Color, Drawable, EventCtx, GeomBatch, GfxCtx, Key, RewriteColor, Widget};
|
||||
use geom::Distance;
|
||||
use map_model::{IntersectionID, Map, RoadID};
|
||||
use petgraph::graphmap::UnGraphMap;
|
||||
use sim::DontDrawAgents;
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
pub struct BulkSelect {
|
||||
composite: Composite,
|
||||
roads: BTreeSet<RoadID>,
|
||||
preview: Option<Drawable>,
|
||||
pub struct RoadSelector {
|
||||
pub roads: BTreeSet<RoadID>,
|
||||
pub preview: Option<Drawable>,
|
||||
mode: Mode,
|
||||
dragging: bool,
|
||||
}
|
||||
@ -30,16 +25,65 @@ pub enum Mode {
|
||||
Erase,
|
||||
}
|
||||
|
||||
impl BulkSelect {
|
||||
pub fn new(ctx: &mut EventCtx, app: &mut App) -> Box<dyn State> {
|
||||
impl RoadSelector {
|
||||
pub fn new(app: &mut App, roads: BTreeSet<RoadID>) -> RoadSelector {
|
||||
app.primary.current_selection = None;
|
||||
Box::new(BulkSelect {
|
||||
composite: make_composite(ctx, app, &Mode::Paint, &BTreeSet::new()),
|
||||
roads: BTreeSet::new(),
|
||||
RoadSelector {
|
||||
roads,
|
||||
preview: None,
|
||||
mode: Mode::Paint,
|
||||
dragging: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_controls(&self, ctx: &mut EventCtx) -> Widget {
|
||||
Widget::custom_row(vec![
|
||||
if let Mode::Paint = self.mode {
|
||||
Widget::draw_svg_transform(
|
||||
ctx,
|
||||
"system/assets/tools/pencil.svg",
|
||||
RewriteColor::ChangeAll(Color::hex("#4CA7E9")),
|
||||
)
|
||||
} else {
|
||||
Btn::svg_def("system/assets/tools/pencil.svg").build(ctx, "paint", hotkey(Key::P))
|
||||
},
|
||||
if let Mode::Erase = self.mode {
|
||||
Widget::draw_svg_transform(
|
||||
ctx,
|
||||
"system/assets/tools/eraser.svg",
|
||||
RewriteColor::ChangeAll(Color::hex("#4CA7E9")),
|
||||
)
|
||||
} else {
|
||||
Btn::svg_def("system/assets/tools/eraser.svg").build(
|
||||
ctx,
|
||||
"erase",
|
||||
hotkey(Key::Backspace),
|
||||
)
|
||||
},
|
||||
if let Mode::Route { .. } = self.mode {
|
||||
Widget::draw_svg_transform(
|
||||
ctx,
|
||||
"system/assets/timeline/start_pos.svg",
|
||||
RewriteColor::ChangeAll(Color::hex("#4CA7E9")),
|
||||
)
|
||||
} else {
|
||||
Btn::svg_def("system/assets/timeline/start_pos.svg").build(
|
||||
ctx,
|
||||
"select along route",
|
||||
hotkey(Key::R),
|
||||
)
|
||||
},
|
||||
if let Mode::Pan = self.mode {
|
||||
Widget::draw_svg_transform(
|
||||
ctx,
|
||||
"system/assets/tools/pan.svg",
|
||||
RewriteColor::ChangeAll(Color::hex("#4CA7E9")),
|
||||
)
|
||||
} else {
|
||||
Btn::svg_def("system/assets/tools/pan.svg").build(ctx, "pan", hotkey(Key::Escape))
|
||||
},
|
||||
])
|
||||
.evenly_spaced()
|
||||
}
|
||||
|
||||
fn roads_changed(&mut self, ctx: &mut EventCtx, app: &App) {
|
||||
@ -60,12 +104,10 @@ impl BulkSelect {
|
||||
);
|
||||
}
|
||||
self.preview = Some(ctx.upload(batch));
|
||||
self.composite = make_composite(ctx, app, &self.mode, &self.roads);
|
||||
}
|
||||
}
|
||||
|
||||
impl State for BulkSelect {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
// Pass it Outcome::Clicked. Returns true if anything changed.
|
||||
pub fn event(&mut self, ctx: &mut EventCtx, app: &mut App, clicked: Option<&str>) -> bool {
|
||||
if ctx.redo_mouseover() {
|
||||
app.primary.current_selection = app.calculate_current_selection(
|
||||
ctx,
|
||||
@ -138,27 +180,28 @@ impl State for BulkSelect {
|
||||
};
|
||||
if change {
|
||||
self.roads_changed(ctx, app);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
match clicked {
|
||||
Some(x) => match x {
|
||||
"paint" => {
|
||||
self.dragging = false;
|
||||
self.mode = Mode::Paint;
|
||||
self.composite = make_composite(ctx, app, &self.mode, &self.roads);
|
||||
return true;
|
||||
}
|
||||
"erase" => {
|
||||
self.dragging = false;
|
||||
self.mode = Mode::Erase;
|
||||
self.composite = make_composite(ctx, app, &self.mode, &self.roads);
|
||||
return true;
|
||||
}
|
||||
"pan" => {
|
||||
app.primary.current_selection = None;
|
||||
self.dragging = false;
|
||||
self.mode = Mode::Pan;
|
||||
self.composite = make_composite(ctx, app, &self.mode, &self.roads);
|
||||
return true;
|
||||
}
|
||||
"select along route" => {
|
||||
app.primary.current_selection = None;
|
||||
@ -167,23 +210,7 @@ impl State for BulkSelect {
|
||||
i1: None,
|
||||
preview_path: None,
|
||||
};
|
||||
self.composite = make_composite(ctx, app, &self.mode, &self.roads);
|
||||
}
|
||||
"Cancel" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
"edit roads" => {
|
||||
return Transition::Replace(crate::edit::bulk::BulkEdit::new(
|
||||
ctx,
|
||||
self.roads.iter().cloned().collect(),
|
||||
self.preview.take().unwrap(),
|
||||
));
|
||||
}
|
||||
"export roads to shared-row" => {
|
||||
crate::debug::shared_row::export(
|
||||
self.roads.iter().cloned().collect(),
|
||||
&app.primary.map,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
@ -243,6 +270,7 @@ impl State for BulkSelect {
|
||||
self.roads.extend(roads);
|
||||
self.mode = Mode::Pan;
|
||||
self.roads_changed(ctx, app);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
*preview_path = None;
|
||||
@ -250,13 +278,14 @@ impl State for BulkSelect {
|
||||
}
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
false
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, app: &App) {
|
||||
self.composite.draw(g);
|
||||
if let Some(ref p) = self.preview {
|
||||
g.redraw(p);
|
||||
pub fn draw(&self, g: &mut GfxCtx, app: &App, show_preview: bool) {
|
||||
if show_preview {
|
||||
if let Some(ref p) = self.preview {
|
||||
g.redraw(p);
|
||||
}
|
||||
}
|
||||
if g.canvas.get_cursor_in_map_space().is_some() {
|
||||
if let Some(cursor) = match self.mode {
|
||||
@ -294,88 +323,6 @@ impl State for BulkSelect {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_composite(
|
||||
ctx: &mut EventCtx,
|
||||
app: &App,
|
||||
mode: &Mode,
|
||||
roads: &BTreeSet<RoadID>,
|
||||
) -> Composite {
|
||||
Composite::new(Widget::col(vec![
|
||||
Line("Edit many roads").small_heading().draw(ctx),
|
||||
Widget::custom_row(vec![
|
||||
if let Mode::Paint = mode {
|
||||
Widget::draw_svg_transform(
|
||||
ctx,
|
||||
"system/assets/tools/pencil.svg",
|
||||
RewriteColor::ChangeAll(Color::hex("#4CA7E9")),
|
||||
)
|
||||
} else {
|
||||
Btn::svg_def("system/assets/tools/pencil.svg").build(ctx, "paint", hotkey(Key::P))
|
||||
},
|
||||
if let Mode::Erase = mode {
|
||||
Widget::draw_svg_transform(
|
||||
ctx,
|
||||
"system/assets/tools/eraser.svg",
|
||||
RewriteColor::ChangeAll(Color::hex("#4CA7E9")),
|
||||
)
|
||||
} else {
|
||||
Btn::svg_def("system/assets/tools/eraser.svg").build(
|
||||
ctx,
|
||||
"erase",
|
||||
hotkey(Key::Backspace),
|
||||
)
|
||||
},
|
||||
if let Mode::Route { .. } = mode {
|
||||
Widget::draw_svg_transform(
|
||||
ctx,
|
||||
"system/assets/timeline/start_pos.svg",
|
||||
RewriteColor::ChangeAll(Color::hex("#4CA7E9")),
|
||||
)
|
||||
} else {
|
||||
Btn::svg_def("system/assets/timeline/start_pos.svg").build(
|
||||
ctx,
|
||||
"select along route",
|
||||
hotkey(Key::R),
|
||||
)
|
||||
},
|
||||
if let Mode::Pan = mode {
|
||||
Widget::draw_svg_transform(
|
||||
ctx,
|
||||
"system/assets/tools/pan.svg",
|
||||
RewriteColor::ChangeAll(Color::hex("#4CA7E9")),
|
||||
)
|
||||
} else {
|
||||
Btn::svg_def("system/assets/tools/pan.svg").build(ctx, "pan", hotkey(Key::Escape))
|
||||
},
|
||||
])
|
||||
.evenly_spaced(),
|
||||
Widget::row(vec![
|
||||
if roads.is_empty() {
|
||||
Btn::text_fg("Edit 0 roads").inactive(ctx)
|
||||
} else {
|
||||
Btn::text_fg(format!("Edit {} roads", roads.len())).build(
|
||||
ctx,
|
||||
"edit roads",
|
||||
hotkey(Key::E),
|
||||
)
|
||||
},
|
||||
if app.opts.dev {
|
||||
Btn::text_fg(format!("Export {} roads to shared-row", roads.len())).build(
|
||||
ctx,
|
||||
"export roads to shared-row",
|
||||
None,
|
||||
)
|
||||
} else {
|
||||
Widget::nothing()
|
||||
},
|
||||
Btn::text_fg("Cancel").build_def(ctx, hotkey(Key::Escape)),
|
||||
])
|
||||
.evenly_spaced(),
|
||||
]))
|
||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
||||
.build(ctx)
|
||||
}
|
||||
|
||||
// Simple search along undirected roads
|
||||
fn pathfind(map: &Map, i1: IntersectionID, i2: IntersectionID) -> Option<Vec<RoadID>> {
|
||||
let mut graph: UnGraphMap<IntersectionID, RoadID> = UnGraphMap::new();
|
||||
|
@ -1,9 +1,10 @@
|
||||
use crate::app::{App, ShowEverything};
|
||||
use crate::app::App;
|
||||
use crate::common::ColorDiscrete;
|
||||
use crate::common::CommonState;
|
||||
use crate::edit::apply_map_edits;
|
||||
use crate::edit::select::RoadSelector;
|
||||
use crate::game::{State, Transition};
|
||||
use crate::helpers::{checkbox_per_mode, intersections_from_roads, ID};
|
||||
use crate::helpers::{checkbox_per_mode, intersections_from_roads};
|
||||
use enumset::EnumSet;
|
||||
use ezgui::{
|
||||
hotkey, Btn, Color, Composite, Drawable, EventCtx, GfxCtx, HorizontalAlignment, Key, Line,
|
||||
@ -11,12 +12,12 @@ use ezgui::{
|
||||
};
|
||||
use map_model::{EditCmd, RoadID};
|
||||
use maplit::btreeset;
|
||||
use sim::{DontDrawAgents, TripMode};
|
||||
use sim::TripMode;
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
pub struct ZoneEditor {
|
||||
composite: Composite,
|
||||
members: BTreeSet<RoadID>,
|
||||
selector: RoadSelector,
|
||||
allow_through_traffic: BTreeSet<TripMode>,
|
||||
unzoomed: Drawable,
|
||||
zoomed: Drawable,
|
||||
@ -25,7 +26,7 @@ pub struct ZoneEditor {
|
||||
}
|
||||
|
||||
impl ZoneEditor {
|
||||
pub fn new(ctx: &mut EventCtx, app: &App, start: RoadID) -> Box<dyn State> {
|
||||
pub fn new(ctx: &mut EventCtx, app: &mut App, start: RoadID) -> Box<dyn State> {
|
||||
let start = app.primary.map.get_r(start);
|
||||
let members = if let Some(z) = start.get_zone(&app.primary.map) {
|
||||
z.members.clone()
|
||||
@ -40,12 +41,15 @@ impl ZoneEditor {
|
||||
.collect();
|
||||
|
||||
let (unzoomed, zoomed, legend) = draw_zone(ctx, app, &members);
|
||||
let orig_members = members.clone();
|
||||
let selector = RoadSelector::new(app, members);
|
||||
|
||||
Box::new(ZoneEditor {
|
||||
composite: Composite::new(Widget::col(vec![
|
||||
Line("Editing restricted access zone")
|
||||
.small_heading()
|
||||
.draw(ctx),
|
||||
selector.make_controls(ctx).named("selector"),
|
||||
legend,
|
||||
make_instructions(ctx, &allow_through_traffic),
|
||||
checkbox_per_mode(ctx, app, &allow_through_traffic),
|
||||
@ -57,8 +61,8 @@ impl ZoneEditor {
|
||||
]))
|
||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
||||
.build(ctx),
|
||||
orig_members: members.clone(),
|
||||
members,
|
||||
orig_members,
|
||||
selector,
|
||||
allow_through_traffic,
|
||||
unzoomed,
|
||||
zoomed,
|
||||
@ -66,57 +70,14 @@ impl ZoneEditor {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Handle splitting/merging zones.
|
||||
impl State for ZoneEditor {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
ctx.canvas_movement();
|
||||
|
||||
// TODO Share with PaintSelect.
|
||||
if ctx.redo_mouseover() {
|
||||
app.primary.current_selection = app.calculate_current_selection(
|
||||
ctx,
|
||||
&DontDrawAgents {},
|
||||
&ShowEverything::new(),
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
if let Some(ID::Road(_)) = app.primary.current_selection {
|
||||
} else if let Some(ID::Lane(l)) = app.primary.current_selection {
|
||||
app.primary.current_selection = Some(ID::Road(app.primary.map.get_l(l).parent));
|
||||
} else {
|
||||
app.primary.current_selection = None;
|
||||
}
|
||||
if let Some(ID::Road(r)) = app.primary.current_selection {
|
||||
if app.primary.map.get_r(r).is_light_rail() {
|
||||
app.primary.current_selection = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Need to figure out merging/splitting zones.
|
||||
if let Some(ID::Road(r)) = app.primary.current_selection {
|
||||
if self.members.contains(&r) {
|
||||
if app.per_obj.left_click(ctx, "remove road from zone") {
|
||||
self.members.remove(&r);
|
||||
let (unzoomed, zoomed, _) = draw_zone(ctx, app, &self.members);
|
||||
self.unzoomed = unzoomed;
|
||||
self.zoomed = zoomed;
|
||||
}
|
||||
} else {
|
||||
if app.per_obj.left_click(ctx, "add road to zone") {
|
||||
self.members.insert(r);
|
||||
let (unzoomed, zoomed, _) = draw_zone(ctx, app, &self.members);
|
||||
self.unzoomed = unzoomed;
|
||||
self.zoomed = zoomed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match self.composite.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||
"Apply" => {
|
||||
let mut edits = app.primary.map.get_edits().clone();
|
||||
for r in self.orig_members.difference(&self.members) {
|
||||
for r in self.orig_members.difference(&self.selector.roads) {
|
||||
edits.commands.push(EditCmd::ChangeAccessRestrictions {
|
||||
id: *r,
|
||||
old_allow_through_traffic: app
|
||||
@ -134,7 +95,7 @@ impl State for ZoneEditor {
|
||||
.iter()
|
||||
.map(|m| m.to_constraints())
|
||||
.collect::<EnumSet<_>>();
|
||||
for r in &self.members {
|
||||
for r in &self.selector.roads {
|
||||
let old_allow_through_traffic =
|
||||
app.primary.map.get_r(*r).allow_through_traffic.clone();
|
||||
if old_allow_through_traffic != new_allow_through_traffic {
|
||||
@ -152,9 +113,33 @@ impl State for ZoneEditor {
|
||||
"Cancel" => {
|
||||
return Transition::Pop;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
x => {
|
||||
if self.selector.event(ctx, app, Some(x)) {
|
||||
let new_controls = self
|
||||
.selector
|
||||
.make_controls(ctx)
|
||||
.named("selector")
|
||||
.margin_below(10);
|
||||
self.composite.replace(ctx, "selector", new_controls);
|
||||
let (unzoomed, zoomed, _) = draw_zone(ctx, app, &self.selector.roads);
|
||||
self.unzoomed = unzoomed;
|
||||
self.zoomed = zoomed;
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
None => {
|
||||
if self.selector.event(ctx, app, None) {
|
||||
let new_controls = self
|
||||
.selector
|
||||
.make_controls(ctx)
|
||||
.named("selector")
|
||||
.margin_below(10);
|
||||
self.composite.replace(ctx, "selector", new_controls);
|
||||
let (unzoomed, zoomed, _) = draw_zone(ctx, app, &self.selector.roads);
|
||||
self.unzoomed = unzoomed;
|
||||
self.zoomed = zoomed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut new_allow_through_traffic = BTreeSet::new();
|
||||
@ -180,6 +165,7 @@ impl State for ZoneEditor {
|
||||
g.redraw(&self.zoomed);
|
||||
}
|
||||
self.composite.draw(g);
|
||||
self.selector.draw(g, app, false);
|
||||
CommonState::draw_osd(g, app);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user