mirror of
https://github.com/a-b-street/abstreet.git
synced 2025-01-03 20:14:53 +03:00
ripping out lane paintbrush editor, changing to a popup per lane
This commit is contained in:
parent
bcf4550be2
commit
462a812348
@ -3,6 +3,7 @@ use crate::common::Colorer;
|
|||||||
use crate::edit::apply_map_edits;
|
use crate::edit::apply_map_edits;
|
||||||
use crate::game::{msg, State, Transition, WizardState};
|
use crate::game::{msg, State, Transition, WizardState};
|
||||||
use crate::helpers::ID;
|
use crate::helpers::ID;
|
||||||
|
use crate::managed::WrappedComposite;
|
||||||
use crate::ui::UI;
|
use crate::ui::UI;
|
||||||
use ezgui::{
|
use ezgui::{
|
||||||
hotkey, Button, Choice, Color, Composite, EventCtx, GfxCtx, HorizontalAlignment, Key, Line,
|
hotkey, Button, Choice, Color, Composite, EventCtx, GfxCtx, HorizontalAlignment, Key, Line,
|
||||||
@ -14,135 +15,149 @@ use map_model::{
|
|||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
pub struct LaneEditor {
|
pub struct LaneEditor {
|
||||||
pub brush: Brush,
|
l: LaneID,
|
||||||
composite: Composite,
|
composite: Composite,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
impl LaneEditor {
|
||||||
pub enum Brush {
|
pub fn new(l: LaneID, ctx: &mut EventCtx, ui: &UI) -> LaneEditor {
|
||||||
Inactive,
|
let mut row = Vec::new();
|
||||||
Driving,
|
let lt = ui.primary.map.get_l(l).lane_type;
|
||||||
Bike,
|
for (icon, label, key, active) in vec![
|
||||||
Bus,
|
(
|
||||||
Parking,
|
"driving",
|
||||||
Construction,
|
"convert to a driving lane",
|
||||||
Reverse,
|
Key::D,
|
||||||
|
lt != LaneType::Driving,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"bike",
|
||||||
|
"convert to a protected bike lane",
|
||||||
|
Key::B,
|
||||||
|
lt != LaneType::Biking,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"bus",
|
||||||
|
"convert to a bus-only lane",
|
||||||
|
Key::T,
|
||||||
|
lt != LaneType::Bus,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"parking",
|
||||||
|
"convert to an on-street parking lane",
|
||||||
|
Key::P,
|
||||||
|
lt != LaneType::Parking,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"construction",
|
||||||
|
"close for construction",
|
||||||
|
Key::C,
|
||||||
|
lt != LaneType::Construction,
|
||||||
|
),
|
||||||
|
("contraflow", "reverse lane direction", Key::F, true),
|
||||||
|
] {
|
||||||
|
row.push(
|
||||||
|
if active {
|
||||||
|
ManagedWidget::btn(Button::rectangle_svg(
|
||||||
|
&format!("assets/edit/{}.svg", icon),
|
||||||
|
label,
|
||||||
|
hotkey(key),
|
||||||
|
RewriteColor::ChangeAll(colors::HOVERING),
|
||||||
|
ctx,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
ManagedWidget::draw_svg_transform(
|
||||||
|
ctx,
|
||||||
|
&format!("assets/edit/{}.svg", icon),
|
||||||
|
RewriteColor::ChangeAll(Color::WHITE.alpha(0.5)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.padding(5),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let revert = if ui.primary.map.get_edits().original_lts.contains_key(&l)
|
||||||
|
|| ui.primary.map.get_edits().reversed_lanes.contains(&l)
|
||||||
|
{
|
||||||
|
WrappedComposite::text_button(ctx, "Revert", hotkey(Key::R))
|
||||||
|
} else {
|
||||||
|
Button::inactive_button("Revert", ctx)
|
||||||
|
};
|
||||||
|
|
||||||
|
let composite = Composite::new(
|
||||||
|
ManagedWidget::col(vec![
|
||||||
|
ManagedWidget::draw_text(ctx, Text::from(Line("Modify lane"))).centered_horiz(),
|
||||||
|
ManagedWidget::row(row).centered(),
|
||||||
|
WrappedComposite::text_button(ctx, "Finish", hotkey(Key::Escape)),
|
||||||
|
WrappedComposite::text_button(ctx, "Edit entire road", hotkey(Key::U)),
|
||||||
|
revert,
|
||||||
|
])
|
||||||
|
.bg(colors::PANEL_BG)
|
||||||
|
.padding(10),
|
||||||
|
)
|
||||||
|
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
||||||
|
.build(ctx);
|
||||||
|
|
||||||
|
LaneEditor { l, composite }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LaneEditor {
|
impl State for LaneEditor {
|
||||||
pub fn new(ctx: &mut EventCtx) -> LaneEditor {
|
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition {
|
||||||
LaneEditor {
|
ctx.canvas_movement();
|
||||||
brush: Brush::Inactive,
|
|
||||||
composite: make_brush_panel(ctx, Brush::Inactive),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Option<Transition> {
|
|
||||||
// Change brush
|
|
||||||
match self.composite.event(ctx) {
|
match self.composite.event(ctx) {
|
||||||
Some(Outcome::Clicked(x)) => {
|
Some(Outcome::Clicked(x)) => {
|
||||||
let b = match x.as_ref() {
|
let map = &ui.primary.map;
|
||||||
"convert to a driving lane" => Brush::Driving,
|
let result = match x.as_ref() {
|
||||||
"convert to a protected bike lane" => Brush::Bike,
|
"convert to a driving lane" => {
|
||||||
"convert to a bus-only lane" => Brush::Bus,
|
try_change_lane_type(self.l, LaneType::Driving, map)
|
||||||
"convert to a on-street parking lane" => Brush::Parking,
|
}
|
||||||
"convert to a closed for construction" => Brush::Construction,
|
"convert to a protected bike lane" => {
|
||||||
"convert to a reverse lane direction" => Brush::Reverse,
|
try_change_lane_type(self.l, LaneType::Biking, map)
|
||||||
|
}
|
||||||
|
"convert to a bus-only lane" => {
|
||||||
|
try_change_lane_type(self.l, LaneType::Bus, map)
|
||||||
|
}
|
||||||
|
"convert to an on-street parking lane" => {
|
||||||
|
try_change_lane_type(self.l, LaneType::Parking, map)
|
||||||
|
}
|
||||||
|
"close for construction" => {
|
||||||
|
try_change_lane_type(self.l, LaneType::Construction, map)
|
||||||
|
}
|
||||||
|
"reverse lane direction" => try_reverse(self.l, map),
|
||||||
|
"Finish" => {
|
||||||
|
return Transition::Pop;
|
||||||
|
}
|
||||||
|
"Edit entire road" => {
|
||||||
|
return Transition::Replace(make_bulk_edit_lanes(map.get_l(self.l).parent));
|
||||||
|
}
|
||||||
|
"Revert" => {
|
||||||
|
// TODO It's hard to revert both changes at once.
|
||||||
|
if let Some(lt) = map.get_edits().original_lts.get(&self.l) {
|
||||||
|
try_change_lane_type(self.l, *lt, map)
|
||||||
|
} else {
|
||||||
|
try_reverse(self.l, map)
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
if self.brush == b {
|
match result {
|
||||||
self.brush = Brush::Inactive;
|
Ok(cmd) => {
|
||||||
} else {
|
let mut edits = ui.primary.map.get_edits().clone();
|
||||||
self.brush = b;
|
edits.commands.push(cmd);
|
||||||
|
apply_map_edits(ctx, ui, edits);
|
||||||
|
return Transition::Replace(Box::new(LaneEditor::new(self.l, ctx, ui)));
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
return Transition::Push(msg("Error", vec![err]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.composite = make_brush_panel(ctx, self.brush);
|
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ID::Lane(l)) = ui.primary.current_selection {
|
/*// Woo, a special case! The construction tool also applies to intersections.
|
||||||
// TODO Refactor all of these mappings!
|
|
||||||
if self.brush != Brush::Inactive {
|
|
||||||
let label = match self.brush {
|
|
||||||
Brush::Inactive => unreachable!(),
|
|
||||||
Brush::Driving => "driving lane",
|
|
||||||
Brush::Bike => "protected bike lane",
|
|
||||||
Brush::Bus => "bus-only lane",
|
|
||||||
Brush::Parking => "on-street parking lane",
|
|
||||||
Brush::Construction => "closed for construction",
|
|
||||||
Brush::Reverse => "reverse lane direction",
|
|
||||||
};
|
|
||||||
if ui
|
|
||||||
.per_obj
|
|
||||||
.action(ctx, Key::Space, &format!("convert to a {}", label))
|
|
||||||
{
|
|
||||||
// These errors are universal.
|
|
||||||
if ui.primary.map.get_l(l).is_sidewalk() {
|
|
||||||
return Some(Transition::Push(msg(
|
|
||||||
"Error",
|
|
||||||
vec!["Can't modify sidewalks"],
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
if ui.primary.map.get_l(l).lane_type == LaneType::SharedLeftTurn {
|
|
||||||
return Some(Transition::Push(msg(
|
|
||||||
"Error",
|
|
||||||
vec!["Can't modify shared-left turn lanes yet"],
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
match apply_brush(self.brush, &ui.primary.map, l) {
|
|
||||||
Ok(Some(cmd)) => {
|
|
||||||
let mut edits = ui.primary.map.get_edits().clone();
|
|
||||||
edits.commands.push(cmd);
|
|
||||||
apply_map_edits(ctx, ui, edits);
|
|
||||||
}
|
|
||||||
Ok(None) => {}
|
|
||||||
Err(err) => {
|
|
||||||
return Some(Transition::Push(msg("Error", vec![err])));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ui
|
|
||||||
.per_obj
|
|
||||||
.action(ctx, Key::U, "bulk edit lanes on this road")
|
|
||||||
{
|
|
||||||
return Some(Transition::Push(make_bulk_edit_lanes(
|
|
||||||
ui.primary.map.get_l(l).parent,
|
|
||||||
)));
|
|
||||||
} else if let Some(lt) = ui.primary.map.get_edits().original_lts.get(&l) {
|
|
||||||
if ui.per_obj.action(ctx, Key::R, "revert") {
|
|
||||||
if let Some(err) = can_change_lane_type(l, *lt, &ui.primary.map) {
|
|
||||||
return Some(Transition::Push(msg("Error", vec![err])));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut edits = ui.primary.map.get_edits().clone();
|
|
||||||
edits.commands.push(EditCmd::ChangeLaneType {
|
|
||||||
id: l,
|
|
||||||
lt: *lt,
|
|
||||||
orig_lt: ui.primary.map.get_l(l).lane_type,
|
|
||||||
});
|
|
||||||
apply_map_edits(ctx, ui, edits);
|
|
||||||
}
|
|
||||||
} else if ui.primary.map.get_edits().reversed_lanes.contains(&l) {
|
|
||||||
if ui.per_obj.action(ctx, Key::R, "revert") {
|
|
||||||
match apply_brush(Brush::Reverse, &ui.primary.map, l) {
|
|
||||||
Ok(Some(cmd)) => {
|
|
||||||
let mut edits = ui.primary.map.get_edits().clone();
|
|
||||||
edits.commands.push(cmd);
|
|
||||||
apply_map_edits(ctx, ui, edits);
|
|
||||||
}
|
|
||||||
Ok(None) => {}
|
|
||||||
Err(err) => {
|
|
||||||
return Some(Transition::Push(msg("Error", vec![err])));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Woo, a special case! The construction tool also applies to intersections.
|
|
||||||
if let Some(ID::Intersection(i)) = ui.primary.current_selection {
|
if let Some(ID::Intersection(i)) = ui.primary.current_selection {
|
||||||
if self.brush == Brush::Construction
|
if self.brush == Brush::Construction
|
||||||
&& ui
|
&& ui
|
||||||
@ -181,64 +196,16 @@ impl LaneEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
None
|
Transition::Keep
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(&self, g: &mut GfxCtx) {
|
fn draw(&self, g: &mut GfxCtx, _: &UI) {
|
||||||
self.composite.draw(g);
|
self.composite.draw(g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_brush_panel(ctx: &mut EventCtx, brush: Brush) -> Composite {
|
|
||||||
let mut row = Vec::new();
|
|
||||||
for (b, icon, label, key) in vec![
|
|
||||||
(Brush::Driving, "driving", "driving lane", Key::D),
|
|
||||||
(Brush::Bike, "bike", "protected bike lane", Key::B),
|
|
||||||
(Brush::Bus, "bus", "bus-only lane", Key::T),
|
|
||||||
(Brush::Parking, "parking", "on-street parking lane", Key::P),
|
|
||||||
(
|
|
||||||
Brush::Construction,
|
|
||||||
"construction",
|
|
||||||
"closed for construction",
|
|
||||||
Key::C,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Brush::Reverse,
|
|
||||||
"contraflow",
|
|
||||||
"reverse lane direction",
|
|
||||||
Key::F,
|
|
||||||
),
|
|
||||||
] {
|
|
||||||
row.push(
|
|
||||||
ManagedWidget::col(vec![ManagedWidget::btn(Button::rectangle_svg_rewrite(
|
|
||||||
&format!("assets/edit/{}.svg", icon),
|
|
||||||
&format!("convert to a {}", label),
|
|
||||||
hotkey(key),
|
|
||||||
if brush == b {
|
|
||||||
RewriteColor::ChangeAll(Color::RED)
|
|
||||||
} else {
|
|
||||||
RewriteColor::NoOp
|
|
||||||
},
|
|
||||||
RewriteColor::ChangeAll(colors::HOVERING),
|
|
||||||
ctx,
|
|
||||||
))])
|
|
||||||
.padding(5),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Composite::new(
|
|
||||||
ManagedWidget::col(vec![
|
|
||||||
ManagedWidget::draw_text(ctx, Text::from(Line("Modify lanes"))).centered_horiz(),
|
|
||||||
ManagedWidget::row(row).centered(),
|
|
||||||
])
|
|
||||||
.bg(colors::PANEL_BG)
|
|
||||||
.padding(10),
|
|
||||||
)
|
|
||||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
|
||||||
.build(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn can_change_lane_type(l: LaneID, new_lt: LaneType, map: &Map) -> Option<String> {
|
fn can_change_lane_type(l: LaneID, new_lt: LaneType, map: &Map) -> Option<String> {
|
||||||
let r = map.get_parent(l);
|
let r = map.get_parent(l);
|
||||||
let (fwds, idx) = r.dir_and_offset(l);
|
let (fwds, idx) = r.dir_and_offset(l);
|
||||||
@ -292,18 +259,30 @@ fn can_change_lane_type(l: LaneID, new_lt: LaneType, map: &Map) -> Option<String
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_change_lane_type(l: LaneID, new_lt: LaneType, map: &Map) -> Result<Option<EditCmd>, String> {
|
fn try_change_lane_type(l: LaneID, new_lt: LaneType, map: &Map) -> Result<EditCmd, String> {
|
||||||
if let Some(err) = can_change_lane_type(l, new_lt, map) {
|
if let Some(err) = can_change_lane_type(l, new_lt, map) {
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
if map.get_l(l).lane_type == new_lt {
|
Ok(EditCmd::ChangeLaneType {
|
||||||
Ok(None)
|
id: l,
|
||||||
|
lt: new_lt,
|
||||||
|
orig_lt: map.get_l(l).lane_type,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_reverse(l: LaneID, map: &Map) -> Result<EditCmd, String> {
|
||||||
|
let lane = map.get_l(l);
|
||||||
|
if !lane.lane_type.is_for_moving_vehicles() {
|
||||||
|
Err(format!("You can't reverse a {:?} lane", lane.lane_type))
|
||||||
|
} else if map.get_r(lane.parent).dir_and_offset(l).1 != 0 {
|
||||||
|
Err(format!(
|
||||||
|
"You can only reverse the lanes next to the road's yellow center line"
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(Some(EditCmd::ChangeLaneType {
|
Ok(EditCmd::ReverseLane {
|
||||||
id: l,
|
l,
|
||||||
lt: new_lt,
|
dst_i: lane.src_i,
|
||||||
orig_lt: map.get_l(l).lane_type,
|
})
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,31 +351,3 @@ fn make_bulk_edit_lanes(road: RoadID) -> Box<dyn State> {
|
|||||||
)))
|
)))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this returns a string error message, the edit didn't work. If it returns Ok(None), then
|
|
||||||
// it's a no-op.
|
|
||||||
fn apply_brush(brush: Brush, map: &Map, l: LaneID) -> Result<Option<EditCmd>, String> {
|
|
||||||
match brush {
|
|
||||||
Brush::Inactive => unreachable!(),
|
|
||||||
Brush::Driving => try_change_lane_type(l, LaneType::Driving, map),
|
|
||||||
Brush::Bike => try_change_lane_type(l, LaneType::Biking, map),
|
|
||||||
Brush::Bus => try_change_lane_type(l, LaneType::Bus, map),
|
|
||||||
Brush::Parking => try_change_lane_type(l, LaneType::Parking, map),
|
|
||||||
Brush::Construction => try_change_lane_type(l, LaneType::Construction, map),
|
|
||||||
Brush::Reverse => {
|
|
||||||
let lane = map.get_l(l);
|
|
||||||
if !lane.lane_type.is_for_moving_vehicles() {
|
|
||||||
return Err(format!("You can't reverse a {:?} lane", lane.lane_type));
|
|
||||||
}
|
|
||||||
if map.get_r(lane.parent).dir_and_offset(l).1 != 0 {
|
|
||||||
return Err(format!(
|
|
||||||
"You can only reverse the lanes next to the road's yellow center line"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Ok(Some(EditCmd::ReverseLane {
|
|
||||||
l,
|
|
||||||
dst_i: lane.src_i,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -2,7 +2,6 @@ mod lanes;
|
|||||||
mod stop_signs;
|
mod stop_signs;
|
||||||
mod traffic_signals;
|
mod traffic_signals;
|
||||||
|
|
||||||
use self::lanes::{Brush, LaneEditor};
|
|
||||||
pub use self::stop_signs::StopSignEditor;
|
pub use self::stop_signs::StopSignEditor;
|
||||||
pub use self::traffic_signals::TrafficSignalEditor;
|
pub use self::traffic_signals::TrafficSignalEditor;
|
||||||
use crate::common::{tool_panel, CommonState, Overlays, Warping};
|
use crate::common::{tool_panel, CommonState, Overlays, Warping};
|
||||||
@ -15,7 +14,7 @@ use crate::sandbox::{GameplayMode, SandboxMode};
|
|||||||
use crate::ui::UI;
|
use crate::ui::UI;
|
||||||
use abstutil::Timer;
|
use abstutil::Timer;
|
||||||
use ezgui::{hotkey, lctrl, Choice, EventCtx, GfxCtx, Key, Line, ModalMenu, Text, WrappedWizard};
|
use ezgui::{hotkey, lctrl, Choice, EventCtx, GfxCtx, Key, Line, ModalMenu, Text, WrappedWizard};
|
||||||
use map_model::{EditCmd, LaneID, MapEdits};
|
use map_model::{EditCmd, LaneID, LaneType, MapEdits};
|
||||||
use sim::Sim;
|
use sim::Sim;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
@ -27,8 +26,6 @@ pub struct EditMode {
|
|||||||
mode: GameplayMode,
|
mode: GameplayMode,
|
||||||
pub suspended_sim: Sim,
|
pub suspended_sim: Sim,
|
||||||
|
|
||||||
lane_editor: LaneEditor,
|
|
||||||
|
|
||||||
once: bool,
|
once: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +48,6 @@ impl EditMode {
|
|||||||
),
|
),
|
||||||
mode,
|
mode,
|
||||||
suspended_sim,
|
suspended_sim,
|
||||||
lane_editor: LaneEditor::new(ctx),
|
|
||||||
once: true,
|
once: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,22 +84,18 @@ impl State for EditMode {
|
|||||||
|
|
||||||
self.menu.event(ctx);
|
self.menu.event(ctx);
|
||||||
|
|
||||||
if self.mode.can_edit_lanes() {
|
|
||||||
if let Some(t) = self.lane_editor.event(ctx, ui) {
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.canvas_movement();
|
ctx.canvas_movement();
|
||||||
// Restrict what can be selected.
|
// Restrict what can be selected.
|
||||||
if ctx.redo_mouseover() {
|
if ctx.redo_mouseover() {
|
||||||
ui.recalculate_current_selection(ctx);
|
ui.recalculate_current_selection(ctx);
|
||||||
if let Some(ID::Lane(_)) = ui.primary.current_selection {
|
if let Some(ID::Lane(l)) = ui.primary.current_selection {
|
||||||
} else if let Some(ID::Intersection(_)) = ui.primary.current_selection {
|
if !self.mode.can_edit_lanes()
|
||||||
if self.lane_editor.brush != Brush::Construction
|
|| ui.primary.map.get_l(l).is_sidewalk()
|
||||||
&& self.lane_editor.brush != Brush::Inactive
|
|| ui.primary.map.get_l(l).lane_type == LaneType::SharedLeftTurn
|
||||||
{
|
{
|
||||||
ui.primary.current_selection = None;
|
ui.primary.current_selection = None;
|
||||||
}
|
}
|
||||||
|
} else if let Some(ID::Intersection(_)) = ui.primary.current_selection {
|
||||||
} else {
|
} else {
|
||||||
ui.primary.current_selection = None;
|
ui.primary.current_selection = None;
|
||||||
}
|
}
|
||||||
@ -149,6 +141,11 @@ impl State for EditMode {
|
|||||||
apply_map_edits(ctx, ui, edits);
|
apply_map_edits(ctx, ui, edits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(ID::Lane(l)) = ui.primary.current_selection {
|
||||||
|
if ui.per_obj.left_click(ctx, "edit lane") {
|
||||||
|
return Transition::Push(Box::new(lanes::LaneEditor::new(l, ctx, ui)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !ui.primary.map.get_edits().commands.is_empty() && self.menu.action("undo") {
|
if !ui.primary.map.get_edits().commands.is_empty() && self.menu.action("undo") {
|
||||||
let mut edits = ui.primary.map.get_edits().clone();
|
let mut edits = ui.primary.map.get_edits().clone();
|
||||||
@ -188,9 +185,6 @@ impl State for EditMode {
|
|||||||
|
|
||||||
self.tool_panel.draw(g);
|
self.tool_panel.draw(g);
|
||||||
self.menu.draw(g);
|
self.menu.draw(g);
|
||||||
if self.mode.can_edit_lanes() {
|
|
||||||
self.lane_editor.draw(g);
|
|
||||||
}
|
|
||||||
CommonState::draw_osd(g, ui, &ui.primary.current_selection);
|
CommonState::draw_osd(g, ui, &ui.primary.current_selection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,20 @@ impl GUI for Game {
|
|||||||
}
|
}
|
||||||
DrawBaselayer::Custom => {}
|
DrawBaselayer::Custom => {}
|
||||||
DrawBaselayer::PreviousState => {
|
DrawBaselayer::PreviousState => {
|
||||||
|
match self.states[self.states.len() - 2].draw_baselayer() {
|
||||||
|
DrawBaselayer::DefaultMap => {
|
||||||
|
self.ui.draw(
|
||||||
|
g,
|
||||||
|
DrawOptions::new(),
|
||||||
|
&self.ui.primary.sim,
|
||||||
|
&ShowEverything::new(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
DrawBaselayer::Custom => {}
|
||||||
|
// Nope, don't recurse
|
||||||
|
DrawBaselayer::PreviousState => {}
|
||||||
|
}
|
||||||
|
|
||||||
self.states[self.states.len() - 2].draw(g, &self.ui);
|
self.states[self.states.len() - 2].draw(g, &self.ui);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user