undo/redo for outdoor details
This commit is contained in:
@@ -87,4 +87,56 @@ public:
|
||||
void reattach(cScenario& to);
|
||||
};
|
||||
|
||||
// Store a version of the outdoor details for undo history.
|
||||
// This could be made a struct that cTown contains, and that would eliminate the next 2 functions, but it would
|
||||
// require changing every reference to these detail values in the game and fileio code, making them more verbose. I don't know
|
||||
// if that's worth it.
|
||||
struct out_details_t {
|
||||
std::string name;
|
||||
eAmbientSound ambient_sound;
|
||||
snd_num_t out_sound;
|
||||
int bg_out;
|
||||
int bg_fight;
|
||||
int bg_town;
|
||||
int bg_dungeon;
|
||||
std::string comment;
|
||||
|
||||
bool operator==(const out_details_t& other) const {
|
||||
CHECK_EQ(other,name);
|
||||
CHECK_EQ(other,ambient_sound);
|
||||
CHECK_EQ(other,out_sound);
|
||||
CHECK_EQ(other,bg_out);
|
||||
CHECK_EQ(other,bg_fight);
|
||||
CHECK_EQ(other,bg_town);
|
||||
CHECK_EQ(other,bg_dungeon);
|
||||
CHECK_EQ(other,comment);
|
||||
return true;
|
||||
}
|
||||
bool operator!=(const out_details_t& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
inline out_details_t details_from_out(cOutdoors& out) {
|
||||
return {
|
||||
out.name,
|
||||
out.ambient_sound,
|
||||
out.out_sound,
|
||||
out.bg_out,
|
||||
out.bg_fight,
|
||||
out.bg_town,
|
||||
out.bg_dungeon,
|
||||
out.comment
|
||||
};
|
||||
}
|
||||
|
||||
inline void out_set_details(cOutdoors& out, const out_details_t& details) {
|
||||
out.name = details.name;
|
||||
out.ambient_sound = details.ambient_sound;
|
||||
out.out_sound = details.out_sound;
|
||||
out.bg_out = details.bg_out;
|
||||
out.bg_fight = details.bg_fight;
|
||||
out.bg_town = details.bg_town;
|
||||
out.bg_dungeon = details.bg_dungeon;
|
||||
out.comment = details.comment;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -552,20 +552,30 @@ bool change_ter(short& change_from,short& change_to,short& chance) {
|
||||
return chg_dlg.getResult<bool>();
|
||||
}
|
||||
|
||||
static bool outdoor_details_event_filter(cDialog& me, std::string, eKeyMod) {
|
||||
static bool save_outdoor_details(cDialog& me, std::string, eKeyMod, const out_details_t old_details, out_details_t& details) {
|
||||
if(!me.toast(true)) return true;
|
||||
current_terrain->name = me["name"].getText();
|
||||
current_terrain->comment = me["comment"].getText();
|
||||
current_terrain->bg_out = me["bg-out"].getTextAsNum();
|
||||
current_terrain->bg_fight = me["bg-fight"].getTextAsNum();
|
||||
current_terrain->bg_town = me["bg-town"].getTextAsNum();
|
||||
current_terrain->bg_dungeon = me["bg-dungeon"].getTextAsNum();
|
||||
details.name = me["name"].getText();
|
||||
details.comment = me["comment"].getText();
|
||||
details.bg_out = me["bg-out"].getTextAsNum();
|
||||
details.bg_fight = me["bg-fight"].getTextAsNum();
|
||||
details.bg_town = me["bg-town"].getTextAsNum();
|
||||
details.bg_dungeon = me["bg-dungeon"].getTextAsNum();
|
||||
|
||||
if(details != old_details){
|
||||
out_set_details(*current_terrain, details);
|
||||
undo_list.add(action_ptr(new aEditOutDetails(cur_out, old_details, details)));
|
||||
update_edit_menu();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void outdoor_details() {
|
||||
using namespace std::placeholders;
|
||||
out_details_t old_details = details_from_out(*current_terrain);
|
||||
out_details_t new_details = old_details;
|
||||
cDialog out_dlg(*ResMgr::dialogs.get("edit-outdoor-details"));
|
||||
out_dlg["okay"].attachClickHandler(outdoor_details_event_filter);
|
||||
out_dlg["okay"].attachClickHandler(std::bind(save_outdoor_details, _1, _2, _3, old_details, std::ref(new_details)));
|
||||
out_dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, &out_dlg, false));
|
||||
std::ostringstream str_out;
|
||||
str_out << "X = " << cur_out.x << ", Y = " << cur_out.y;
|
||||
@@ -577,7 +587,7 @@ void outdoor_details() {
|
||||
out_dlg["bg-town"].setTextToNum(current_terrain->bg_town);
|
||||
out_dlg["bg-dungeon"].setTextToNum(current_terrain->bg_dungeon);
|
||||
dynamic_cast<cLedGroup&>(out_dlg["ambient"]).setSelected("snd" + std::to_string(int(current_terrain->ambient_sound) + 1));
|
||||
out_dlg["ambient"].attachFocusHandler([](cDialog& me, std::string, bool) -> bool {
|
||||
out_dlg["ambient"].attachFocusHandler([&new_details](cDialog& me, std::string, bool) -> bool {
|
||||
cLedGroup& lg = dynamic_cast<cLedGroup&>(me["ambient"]);
|
||||
std::string hit = lg.getSelected();
|
||||
std::string prev = lg.getPrevSelection();
|
||||
@@ -589,9 +599,9 @@ void outdoor_details() {
|
||||
lg.setSelected(prev);
|
||||
return false;
|
||||
}
|
||||
current_terrain->out_sound = i;
|
||||
new_details.out_sound = i;
|
||||
}
|
||||
current_terrain->ambient_sound = choice;
|
||||
new_details.ambient_sound = choice;
|
||||
return true;
|
||||
});
|
||||
out_dlg.attachClickHandlers([](cDialog& me, std::string which, eKeyMod) -> bool {
|
||||
|
@@ -970,4 +970,14 @@ bool aEditTownTimers::undo_me() {
|
||||
bool aEditTownTimers::redo_me() {
|
||||
scenario.towns[which]->timers = new_timers;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool aEditOutDetails::undo_me() {
|
||||
out_set_details(*scenario.outdoors[out_sec.x][out_sec.y], old_details);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aEditOutDetails::redo_me() {
|
||||
out_set_details(*scenario.outdoors[out_sec.x][out_sec.y], new_details);
|
||||
return true;
|
||||
}
|
||||
|
@@ -631,4 +631,15 @@ public:
|
||||
cAction("Edit Town Event Timers"), which(which), old_timers(old_timers), new_timers(new_timers) {}
|
||||
};
|
||||
|
||||
class aEditOutDetails : public cAction {
|
||||
location out_sec;
|
||||
out_details_t old_details;
|
||||
out_details_t new_details;
|
||||
bool undo_me() override;
|
||||
bool redo_me() override;
|
||||
public:
|
||||
aEditOutDetails(location out_sec, out_details_t old_details, out_details_t new_details) :
|
||||
cAction("Edit Outdoor Details"), out_sec(out_sec), old_details(old_details), new_details(new_details) {}
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user