From a3a10ca6e4d1da630f4633b735d29fc8cd1df5e2 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Sat, 14 Jun 2025 19:56:50 -0500 Subject: [PATCH] undo/redo for placing and pasting specials --- src/scenedit/scen.actions.cpp | 11 ++++++++++- src/scenedit/scen.keydlgs.cpp | 3 ++- src/scenedit/scen.undo.cpp | 15 ++++++++------- src/scenedit/scen.undo.hpp | 8 +++++--- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/scenedit/scen.actions.cpp b/src/scenedit/scen.actions.cpp index 6767d1f6..28d91796 100644 --- a/src/scenedit/scen.actions.cpp +++ b/src/scenedit/scen.actions.cpp @@ -945,6 +945,8 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) { if(specials[x].spec < 0) { specials[x] = spot_hit; specials[x].spec = spec->first; + undo_list.add(action_ptr(new aPlaceEraseSpecial("Paste Special Encounter", true, specials[x]))); + update_edit_menu(); break; } } @@ -1141,7 +1143,7 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) { specials.pop_back(); } while(!specials.empty() && specials.back().spec < 0); } - undo_action.reset(new aEraseSpecial(for_redo)); + undo_action.reset(new aPlaceEraseSpecial("Erase Special", false, for_redo)); break; } overall_mode = MODE_DRAWING; @@ -2774,6 +2776,7 @@ void place_edit_special(location loc) { for(short i = 0; i < specials.size(); i++) if(specials[i] == loc && specials[i].spec >= 0) { edit_spec_enc(specials[i].spec, editing_town ? 2 : 1, nullptr); + // TODO add the edit specials actions return; } // new special @@ -2785,6 +2788,9 @@ void place_edit_special(location loc) { if(edit_spec_enc(spec, editing_town ? 2: 1, nullptr)) { specials[i] = loc; specials[i].spec = spec; + undo_list.add(action_ptr(new aPlaceEraseSpecial("Place Special Encounter", true, specials[i]))); + // TODO add the edit specials actions + update_edit_menu(); } break; } @@ -2813,6 +2819,9 @@ void set_special(location spot_hit) { if(spec >= 0) { specials[x] = spot_hit; specials[x].spec = spec; + undo_list.add(action_ptr(new aPlaceEraseSpecial("Place Special Encounter", true, specials[x]))); + // TODO if create/edit was used, add those actions + update_edit_menu(); } break; } diff --git a/src/scenedit/scen.keydlgs.cpp b/src/scenedit/scen.keydlgs.cpp index 180ce150..79762f40 100644 --- a/src/scenedit/scen.keydlgs.cpp +++ b/src/scenedit/scen.keydlgs.cpp @@ -1380,6 +1380,7 @@ static bool edit_spec_enc_value(cDialog& me, std::string item_hit, node_stack_t& } // mode - 0 scen 1 - out 2 - town +// TODO collect a list of undo actions that can be committed to undo_list by the calling code bool edit_spec_enc(short which_node,short mode,cDialog* parent) { using namespace std::placeholders; cSpecial the_node; @@ -1653,7 +1654,7 @@ static bool edit_special_num_event_filter(cDialog& me, std::string item_hit, sho short edit_special_num(short mode,short what_start) { using namespace std::placeholders; - size_t num_specs = 0; + short num_specs = 0; switch(mode) { case 0: num_specs = scenario.scen_specials.size(); break; case 1: num_specs = current_terrain->specials.size(); break; diff --git a/src/scenedit/scen.undo.cpp b/src/scenedit/scen.undo.cpp index e42a1c73..87c9f07a 100644 --- a/src/scenedit/scen.undo.cpp +++ b/src/scenedit/scen.undo.cpp @@ -76,18 +76,19 @@ void cTerrainAction::redo() { // Undo/Redo implementations for actions: -bool aEraseSpecial::undo_me() { +bool aPlaceEraseSpecial::undo_me() { + cArea* cur_area = get_current_area(); + auto& specials = cur_area->special_locs; + specials.erase(std::remove(specials.begin(), specials.end(), for_redo)); + return true; +} + +bool aPlaceEraseSpecial::redo_me() { cArea* cur_area = get_current_area(); auto& specials = cur_area->special_locs; specials.push_back(for_redo); return true; } -bool aEraseSpecial::redo_me() { - cArea* cur_area = get_current_area(); - auto& specials = cur_area->special_locs; - specials.pop_back(); - return true; -} aCreateDeleteTown::aCreateDeleteTown(bool create, cTown* t) : cAction(create ? "Create Town" : "Delete Last Town", !create) diff --git a/src/scenedit/scen.undo.hpp b/src/scenedit/scen.undo.hpp index 0e1c46af..10fe77dd 100644 --- a/src/scenedit/scen.undo.hpp +++ b/src/scenedit/scen.undo.hpp @@ -63,10 +63,12 @@ public: old_property(old_property) {} }; -/// Action that erased a special encounter from a spot -class aEraseSpecial : public cTerrainAction { +/// Action that places or erases a special encounter from a spot +class aPlaceEraseSpecial : public cTerrainAction { public: - aEraseSpecial(spec_loc_t special) : cTerrainAction("Erase Special Encounter", special), for_redo(special) {} + aPlaceEraseSpecial(std::string name, bool place, spec_loc_t special) : + cTerrainAction(name, special, !place), + for_redo(special) {} bool undo_me() override; bool redo_me() override; private: