scenedit undo/redo infrastructure
This commit is contained in:
@@ -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
|
Reference in New Issue
Block a user