scenedit undo/redo infrastructure
This commit is contained in:
@@ -65,6 +65,7 @@
|
||||
413AAF672D38A4A5002E9BF1 /* living.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 914698FB1A7362D900F20F5E /* living.cpp */; };
|
||||
413FE08F2CECFAFF000D97DC /* winutil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 413FE08E2CECFAFF000D97DC /* winutil.cpp */; };
|
||||
415EEEB02D5534A500B47408 /* prefs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 415EEEAF2D5534A500B47408 /* prefs.cpp */; };
|
||||
41E550542DEB8C2A00A7DF52 /* scen.undo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41E550532DEB8C2A00A7DF52 /* scen.undo.cpp */; };
|
||||
91034D211B225E4A008F01C1 /* scen.appleevents.mm in Sources */ = {isa = PBXBuildFile; fileRef = 91034D201B225E49008F01C1 /* scen.appleevents.mm */; };
|
||||
911A14031B8FAFC600900FD9 /* town_read.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91C2A6EC1B8FA91400346948 /* town_read.cpp */; };
|
||||
911A14041B8FB00300900FD9 /* talk_read.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91C2A6EE1B8FAA8E00346948 /* talk_read.cpp */; };
|
||||
@@ -635,6 +636,8 @@
|
||||
410CEEE72D84618C00FFF8CD /* profile.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = profile.hpp; sourceTree = "<group>"; };
|
||||
413FE08E2CECFAFF000D97DC /* winutil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = winutil.cpp; sourceTree = "<group>"; };
|
||||
415EEEAF2D5534A500B47408 /* prefs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = prefs.cpp; sourceTree = "<group>"; };
|
||||
41E550522DEB8C1400A7DF52 /* scen.undo.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = scen.undo.hpp; sourceTree = "<group>"; };
|
||||
41E550532DEB8C2A00A7DF52 /* scen.undo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scen.undo.cpp; sourceTree = "<group>"; };
|
||||
91034D201B225E49008F01C1 /* scen.appleevents.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = scen.appleevents.mm; sourceTree = "<group>"; };
|
||||
9103DC652C6A406600849E60 /* cli.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = cli.hpp; sourceTree = "<group>"; };
|
||||
910BBA170FB8BECA001E34EA /* dialog.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = dialog.hpp; sourceTree = "<group>"; };
|
||||
@@ -1468,6 +1471,7 @@
|
||||
91B3EEE70F969BA700BF5B67 /* scen.btnmg.hpp */,
|
||||
91B3EEE10F969BA700BF5B67 /* scen.core.hpp */,
|
||||
91B3EEE40F969BA700BF5B67 /* scen.fileio.hpp */,
|
||||
41E550522DEB8C1400A7DF52 /* scen.undo.hpp */,
|
||||
91B3EEDE0F969BA700BF5B67 /* scen.global.hpp */,
|
||||
91B3EEE50F969BA700BF5B67 /* scen.graphics.hpp */,
|
||||
91B3EEE00F969BA700BF5B67 /* scen.keydlgs.hpp */,
|
||||
@@ -1482,6 +1486,7 @@
|
||||
91B3EEEA0F969BA700BF5B67 /* src */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
41E550532DEB8C2A00A7DF52 /* scen.undo.cpp */,
|
||||
91B3EEF10F969BA700BF5B67 /* scen.actions.cpp */,
|
||||
91034D201B225E49008F01C1 /* scen.appleevents.mm */,
|
||||
91B3EEF50F969BA700BF5B67 /* scen.btnmg.cpp */,
|
||||
@@ -2250,6 +2255,7 @@
|
||||
914CA45819074E0100B6ADD1 /* scen.menus.mac.mm in Sources */,
|
||||
91034D211B225E4A008F01C1 /* scen.appleevents.mm in Sources */,
|
||||
91B0D5D21E344300002BE4DA /* view_dialogs.cpp in Sources */,
|
||||
41E550542DEB8C2A00A7DF52 /* scen.undo.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@@ -12,6 +12,7 @@ scened_sources = Split("""
|
||||
scen.main.cpp
|
||||
scen.sdfpicker.cpp
|
||||
scen.townout.cpp
|
||||
scen.undo.cpp
|
||||
../view_dialogs.cpp
|
||||
../fileio/fileio_party.cpp
|
||||
../damage.cpp
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include "scen.keydlgs.hpp"
|
||||
#include "scen.townout.hpp"
|
||||
#include "scen.menus.hpp"
|
||||
#include "scen.undo.hpp"
|
||||
#include "mathutil.hpp"
|
||||
#include "fileio/fileio.hpp"
|
||||
#include "tools/keymods.hpp"
|
||||
@@ -710,6 +711,7 @@ static bool handle_rb_action(location the_point, bool option_hit) {
|
||||
|
||||
static bool handle_terrain_action(location the_point, bool ctrl_hit) {
|
||||
cArea* cur_area = get_current_area();
|
||||
std::shared_ptr<cAction> undo_action = nullptr;
|
||||
if(mouse_spot.x >= 0 && mouse_spot.y >= 0) {
|
||||
if(cur_viewing_mode == 0) {
|
||||
spot_hit.x = cen_x + mouse_spot.x - 4;
|
||||
@@ -1090,6 +1092,7 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) {
|
||||
auto& specials = cur_area->special_locs;
|
||||
for(short x = 0; x < specials.size(); x++)
|
||||
if(specials[x] == spot_hit && specials[x].spec >= 0) {
|
||||
spec_loc_t for_redo = specials[x];
|
||||
specials[x] = {-1,-1};
|
||||
specials[x].spec = -1;
|
||||
if(x == specials.size() - 1) {
|
||||
@@ -1098,6 +1101,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));
|
||||
break;
|
||||
}
|
||||
overall_mode = MODE_DRAWING;
|
||||
@@ -1204,6 +1208,11 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) {
|
||||
if((overall_mode == MODE_DRAWING) && (old_mode != MODE_DRAWING))
|
||||
set_string("Drawing mode",scenario.ter_types[current_terrain_type].name);
|
||||
draw_terrain();
|
||||
|
||||
if(undo_action != nullptr){
|
||||
undo_list.add(undo_action);
|
||||
update_edit_menu();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool need_redraw = false;
|
||||
|
@@ -48,13 +48,3 @@ bool monst_on_space(location loc,short m_num);
|
||||
void place_edit_special(location loc);
|
||||
void set_special(location spot_hit);
|
||||
bool save_check(std::string which_dlog, bool allow_no = true);
|
||||
|
||||
/// Represents the action of adding a new town to the end of the list
|
||||
class aNewTown : public cAction {
|
||||
class cTown* theTown;
|
||||
bool undo_me() override;
|
||||
bool redo_me() override;
|
||||
public:
|
||||
aNewTown(class cTown* t);
|
||||
~aNewTown();
|
||||
};
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include "scen.sdfpicker.hpp"
|
||||
#include "scen.fileio.hpp"
|
||||
#include "scen.core.hpp"
|
||||
#include "scen.undo.hpp"
|
||||
#include "mathutil.hpp"
|
||||
#include "dialogxml/widgets/button.hpp"
|
||||
#include "dialogxml/widgets/field.hpp"
|
||||
@@ -1642,27 +1643,6 @@ void set_current_out(location out_sec, bool continuous_shift, bool first_restore
|
||||
set_up_main_screen();
|
||||
}
|
||||
|
||||
aNewTown::aNewTown(cTown* t)
|
||||
: cAction("add town")
|
||||
, theTown(t)
|
||||
{}
|
||||
|
||||
bool aNewTown::undo_me() {
|
||||
scenario.towns.resize(scenario.towns.size() - 1);
|
||||
set_current_town(scenario.towns.size() - 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aNewTown::redo_me() {
|
||||
scenario.towns.push_back(theTown);
|
||||
set_current_town(scenario.towns.size() - 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
aNewTown::~aNewTown() {
|
||||
if(!isDone()) delete theTown;
|
||||
}
|
||||
|
||||
bool new_town() {
|
||||
ter_num_t preset = 0;
|
||||
cChoiceDlog new_dlg("new-town", {"okay", "cancel"});
|
||||
|
93
src/scenedit/scen.undo.cpp
Normal file
93
src/scenedit/scen.undo.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
#include "scen.undo.hpp"
|
||||
|
||||
#include "scenario/scenario.hpp"
|
||||
#include "scenario/area.hpp"
|
||||
|
||||
extern bool editing_town;
|
||||
extern short cur_town;
|
||||
extern short cur_town;
|
||||
extern location cur_out;
|
||||
extern short cen_x;
|
||||
extern short cen_y;
|
||||
extern cScenario scenario;
|
||||
extern cArea* get_current_area();
|
||||
extern void start_town_edit();
|
||||
extern void start_out_edit();
|
||||
extern void redraw_screen();
|
||||
|
||||
cTerrainAction::cTerrainAction(std::string name, short town_num, location where) : cAction(name) {
|
||||
area.is_town = true;
|
||||
area.town_num = town_num;
|
||||
area.where = where;
|
||||
}
|
||||
cTerrainAction::cTerrainAction(std::string name, location out_sec, location where) : cAction(name) {
|
||||
area.is_town = false;
|
||||
area.out_sec = out_sec;
|
||||
area.where = where;
|
||||
}
|
||||
cTerrainAction::cTerrainAction(std::string name, location where) : cAction(name) {
|
||||
area.is_town = editing_town;
|
||||
// One of these two will be ignored
|
||||
area.town_num = cur_town;
|
||||
area.out_sec = cur_out;
|
||||
|
||||
area.where = where;
|
||||
}
|
||||
|
||||
void cTerrainAction::showChangeSite() {
|
||||
if(area.is_town){
|
||||
cur_town = area.town_num;
|
||||
}else{
|
||||
cur_out = area.out_sec;
|
||||
}
|
||||
editing_town = area.is_town;
|
||||
|
||||
// TODO this isn't working and I don't know why:
|
||||
cen_x = area.where.x;
|
||||
cen_y = area.where.y;
|
||||
redraw_screen();
|
||||
}
|
||||
|
||||
void cTerrainAction::undo() {
|
||||
showChangeSite();
|
||||
cAction::undo();
|
||||
}
|
||||
void cTerrainAction::redo() {
|
||||
showChangeSite();
|
||||
cAction::redo();
|
||||
}
|
||||
|
||||
// Undo/Redo implementations for actions:
|
||||
|
||||
bool aEraseSpecial::undo_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;
|
||||
}
|
||||
|
||||
aNewTown::aNewTown(cTown* t)
|
||||
: cAction("Add Town")
|
||||
, theTown(t)
|
||||
{}
|
||||
|
||||
bool aNewTown::undo_me() {
|
||||
scenario.towns.resize(scenario.towns.size() - 1);
|
||||
cur_town = min(cur_town, scenario.towns.size() - 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aNewTown::redo_me() {
|
||||
scenario.towns.push_back(theTown);
|
||||
return true;
|
||||
}
|
||||
|
||||
aNewTown::~aNewTown() {
|
||||
if(!isDone()) delete theTown;
|
||||
}
|
51
src/scenedit/scen.undo.hpp
Normal file
51
src/scenedit/scen.undo.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef BoE_scen_undo_h
|
||||
#define BoE_scen_undo_h
|
||||
|
||||
#include "location.hpp"
|
||||
#include "tools/undo.hpp"
|
||||
|
||||
struct area_ref_t {
|
||||
bool is_town;
|
||||
// Can't just make the next two a union for compiler reasons.
|
||||
short town_num;
|
||||
location out_sec;
|
||||
location where;
|
||||
};
|
||||
|
||||
// Action that modified town or outdoor terrain, so we should show the modified area when undoing or redoing
|
||||
class cTerrainAction : public cAction {
|
||||
public:
|
||||
cTerrainAction(std::string name, short town_num, location where);
|
||||
cTerrainAction(std::string name, location out_sec, location where);
|
||||
cTerrainAction(std::string name, location where);
|
||||
void undo();
|
||||
void redo();
|
||||
bool undo_me() = 0;
|
||||
bool redo_me() = 0;
|
||||
private:
|
||||
/// Show where the change happened
|
||||
void showChangeSite();
|
||||
area_ref_t area;
|
||||
};
|
||||
|
||||
/// Represents the action of adding a new town to the end of the list
|
||||
class aNewTown : public cAction {
|
||||
class cTown* theTown;
|
||||
bool undo_me() override;
|
||||
bool redo_me() override;
|
||||
public:
|
||||
aNewTown(class cTown* t);
|
||||
~aNewTown();
|
||||
};
|
||||
|
||||
class aEraseSpecial : public cTerrainAction {
|
||||
public:
|
||||
aEraseSpecial(spec_loc_t special) : cTerrainAction("Erase Special Encounter", special), for_redo(special) {}
|
||||
bool undo_me() override;
|
||||
bool redo_me() override;
|
||||
private:
|
||||
spec_loc_t for_redo;
|
||||
bool editing_town;
|
||||
};
|
||||
|
||||
#endif
|
@@ -15,6 +15,7 @@
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "location.hpp"
|
||||
|
||||
class cAction {
|
||||
std::string actname;
|
||||
@@ -93,6 +94,6 @@ public:
|
||||
static size_t maxUndoSize;
|
||||
};
|
||||
|
||||
// As a special convention, I will prefix action classes with 'a' instead of 'c'
|
||||
// As a special convention, I will prefix non-abstract action classes with 'a' instead of 'c'
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user