diff --git a/game/src/edit/traffic_signals/edits.rs b/game/src/edit/traffic_signals/edits.rs index c62ae0bade..842447bc92 100644 --- a/game/src/edit/traffic_signals/edits.rs +++ b/game/src/edit/traffic_signals/edits.rs @@ -1,5 +1,5 @@ use crate::app::App; -use crate::edit::traffic_signals::{make_top_panel, BundleEdits, TrafficSignalEditor}; +use crate::edit::traffic_signals::{BundleEdits, TrafficSignalEditor}; use crate::edit::{apply_map_edits, check_sidewalk_connectivity, StopSignEditor}; use crate::game::{ChooseSomething, DrawBaselayer, State, Transition}; use crate::sandbox::GameplayMode; @@ -76,17 +76,9 @@ impl State for ChangeDuration { let idx = self.idx; return Transition::PopWithData(Box::new(move |state, ctx, app| { let editor = state.downcast_mut::().unwrap(); - - let mut bundle = BundleEdits::get_current(app, &editor.members); - editor.command_stack.push(bundle.clone()); - editor.redo_stack.clear(); - for ts in &mut bundle.signals { + editor.add_new_edit(ctx, app, idx, |ts| { ts.phases[idx].phase_type = new_type.clone(); - } - bundle.apply(app); - - editor.top_panel = make_top_panel(ctx, app, true, false); - editor.change_phase(ctx, app, idx); + }); })); } _ => unreachable!(), @@ -155,15 +147,9 @@ pub fn edit_entire_signal( Box::new(move |new_signal, _, _| { Transition::PopWithData(Box::new(move |state, ctx, app| { let editor = state.downcast_mut::().unwrap(); - - let mut bundle = BundleEdits::get_current(app, &editor.members); - editor.command_stack.push(bundle.clone()); - editor.redo_stack.clear(); - bundle.signals = vec![new_signal]; - bundle.apply(app); - - editor.top_panel = make_top_panel(ctx, app, true, false); - editor.change_phase(ctx, app, 0); + editor.add_new_edit(ctx, app, 0, |ts| { + *ts = new_signal.clone(); + }); })) }), )), @@ -171,15 +157,9 @@ pub fn edit_entire_signal( let mut new_signal = app.primary.map.get_traffic_signal(i).clone(); if new_signal.convert_to_ped_scramble() { let editor = state.downcast_mut::().unwrap(); - - let mut bundle = BundleEdits::get_current(app, &editor.members); - editor.command_stack.push(bundle.clone()); - editor.redo_stack.clear(); - bundle.signals = vec![new_signal]; - bundle.apply(app); - - editor.top_panel = make_top_panel(ctx, app, true, false); - editor.change_phase(ctx, app, 0); + editor.add_new_edit(ctx, app, 0, |ts| { + *ts = new_signal.clone(); + }); } })), x if x == stop_sign => { @@ -214,10 +194,6 @@ pub fn edit_entire_signal( } x if x == reset => Transition::PopWithData(Box::new(move |state, ctx, app| { let editor = state.downcast_mut::().unwrap(); - - let mut bundle = BundleEdits::get_current(app, &editor.members); - editor.command_stack.push(bundle.clone()); - editor.redo_stack.clear(); let new_signal = ControlTrafficSignal::get_possible_policies( &app.primary.map, i, @@ -225,11 +201,9 @@ pub fn edit_entire_signal( ) .remove(0) .1; - bundle.signals = vec![new_signal]; - bundle.apply(app); - - editor.top_panel = make_top_panel(ctx, app, true, false); - editor.change_phase(ctx, app, 0); + editor.add_new_edit(ctx, app, 0, |ts| { + *ts = new_signal.clone(); + }); })), _ => unreachable!(), }), diff --git a/game/src/edit/traffic_signals/mod.rs b/game/src/edit/traffic_signals/mod.rs index 775483d925..f3e3ac71ea 100644 --- a/game/src/edit/traffic_signals/mod.rs +++ b/game/src/edit/traffic_signals/mod.rs @@ -122,6 +122,25 @@ impl TrafficSignalEditor { self.draw_current = self.recalc_draw_current(ctx, app); } + fn add_new_edit( + &mut self, + ctx: &mut EventCtx, + app: &mut App, + idx: usize, + fxn: F, + ) { + let mut bundle = BundleEdits::get_current(app, &self.members); + self.command_stack.push(bundle.clone()); + self.redo_stack.clear(); + for ts in &mut bundle.signals { + fxn(ts); + } + bundle.apply(app); + + self.top_panel = make_top_panel(ctx, app, true, false); + self.change_phase(ctx, app, idx); + } + fn recalc_draw_current(&self, ctx: &mut EventCtx, app: &App) -> Drawable { let mut batch = GeomBatch::new(); @@ -218,16 +237,9 @@ impl State for TrafficSignalEditor { )); } if x == "Add new phase" { - let mut bundle = BundleEdits::get_current(app, &self.members); - self.command_stack.push(bundle.clone()); - self.redo_stack.clear(); - for ts in &mut bundle.signals { + self.add_new_edit(ctx, app, num_phases, |ts| { ts.phases.push(Phase::new()); - } - bundle.apply(app); - - self.top_panel = make_top_panel(ctx, app, true, false); - self.change_phase(ctx, app, num_phases); + }); return Transition::Keep; } if let Some(x) = x.strip_prefix("change duration of phase ") { @@ -240,49 +252,23 @@ impl State for TrafficSignalEditor { } if let Some(x) = x.strip_prefix("delete phase ") { let idx = x.parse::().unwrap() - 1; - - let mut bundle = BundleEdits::get_current(app, &self.members); - self.command_stack.push(bundle.clone()); - self.redo_stack.clear(); - for ts in &mut bundle.signals { + self.add_new_edit(ctx, app, 0, |ts| { ts.phases.remove(idx); - } - bundle.apply(app); - - self.top_panel = make_top_panel(ctx, app, true, false); - // Don't use change_phase; it tries to preserve scroll - self.current_phase = if idx == num_phases - 1 { idx - 1 } else { idx }; - self.side_panel = make_side_panel(ctx, app, &self.members, self.current_phase); + }); return Transition::Keep; } if let Some(x) = x.strip_prefix("move up phase ") { let idx = x.parse::().unwrap() - 1; - - let mut bundle = BundleEdits::get_current(app, &self.members); - self.command_stack.push(bundle.clone()); - self.redo_stack.clear(); - for ts in &mut bundle.signals { + self.add_new_edit(ctx, app, idx - 1, |ts| { ts.phases.swap(idx, idx - 1); - } - bundle.apply(app); - - self.top_panel = make_top_panel(ctx, app, true, false); - self.change_phase(ctx, app, idx - 1); + }); return Transition::Keep; } if let Some(x) = x.strip_prefix("move down phase ") { let idx = x.parse::().unwrap() - 1; - - let mut bundle = BundleEdits::get_current(app, &self.members); - self.command_stack.push(bundle.clone()); - self.redo_stack.clear(); - for ts in &mut bundle.signals { + self.add_new_edit(ctx, app, idx + 1, |ts| { ts.phases.swap(idx, idx + 1); - } - bundle.apply(app); - - self.top_panel = make_top_panel(ctx, app, true, false); - self.change_phase(ctx, app, idx + 1); + }); return Transition::Keep; } if let Some(x) = x.strip_prefix("phase ") { @@ -303,9 +289,8 @@ impl State for TrafficSignalEditor { self.command_stack.push(bundle.clone()); self.redo_stack.clear(); - self.current_phase = 0; self.top_panel = make_top_panel(ctx, app, true, false); - self.change_phase(ctx, app, self.current_phase); + self.change_phase(ctx, app, 0); return Transition::Push(PopupMsg::new( ctx, @@ -426,19 +411,13 @@ impl State for TrafficSignalEditor { pri ), ) { - let mut bundle = BundleEdits::get_current(app, &self.members); - self.command_stack.push(bundle.clone()); - self.redo_stack.clear(); - for ts in &mut bundle.signals { + let idx = self.current_phase; + let signal = signal.clone(); + self.add_new_edit(ctx, app, idx, |ts| { if ts.id == id.parent { - ts.phases[self.current_phase].edit_group(&signal.turn_groups[&id], pri); - break; + ts.phases[idx].edit_group(&signal.turn_groups[&id], pri); } - } - bundle.apply(app); - - self.top_panel = make_top_panel(ctx, app, true, false); - self.change_phase(ctx, app, self.current_phase); + }); return Transition::KeepWithMouseover; } }