undo/redo for deleting non-location strings

This commit is contained in:
2025-06-21 12:52:31 -05:00
parent b2c69554f3
commit 5b0806467a
5 changed files with 61 additions and 10 deletions

View File

@@ -346,11 +346,33 @@ static bool handle_lb_click(location the_point) {
static void clear_string(eStrMode mode, size_t which) {
std::string& value = fetch_str(mode, which);
undo_list.add(action_ptr(new aEditClearString(edit_string_action_name(true, mode), mode, which, value, "*")));
undo_list.add(action_ptr(new aEditClearString(edit_string_action_name("Clear", mode), mode, which, value, "*")));
update_edit_menu();
value = "*";
}
// Only for strings not tied to a location -- for creation and deletion
std::vector<std::string>& fetch_str_list(eStrMode str_mode){
switch(str_mode){
case 0: return scenario.spec_strs;
case 1: return current_terrain->spec_strs;
case 2: return town->spec_strs;
case 3: return scenario.journal_strs;
default: throw "Invalid string mode " + std::to_string(str_mode) + " (valid are 0-3)";
}
}
static void delete_last_string(eStrMode mode) {
auto& str_list = fetch_str_list(mode);
std::string str = str_list.back();
undo_list.add(action_ptr(new aDeleteString(edit_string_action_name("Delete", mode), mode, str)));
update_edit_menu();
str_list.pop_back();
}
static void create_string(eStrMode mode, bool option_hit) {
}
static bool handle_rb_action(location the_point, bool option_hit) {
long right_top = right_sbar->getPosition();
for(int i = 0; i < NRSONPAGE && i + right_top < NRS; i++)
@@ -430,7 +452,7 @@ static bool handle_rb_action(location the_point, bool option_hit) {
size_before = scenario.spec_strs.size();
if(option_hit) {
if(j == size_before - 1)
scenario.spec_strs.pop_back();
delete_last_string(STRS_SCEN);
else if(j == size_before)
scenario.spec_strs.resize(size_before + 8, "*");
else clear_string(STRS_SCEN, j);
@@ -449,7 +471,7 @@ static bool handle_rb_action(location the_point, bool option_hit) {
size_before = current_terrain->spec_strs.size();
if(option_hit) {
if(j == size_before - 1)
current_terrain->spec_strs.pop_back();
delete_last_string(STRS_OUT);
else if(j == size_before)
current_terrain->spec_strs.resize(size_before + 8, "*");
else clear_string(STRS_OUT, j);
@@ -468,7 +490,7 @@ static bool handle_rb_action(location the_point, bool option_hit) {
size_before = town->spec_strs.size();
if(option_hit) {
if(j == size_before - 1)
town->spec_strs.pop_back();
delete_last_string(STRS_TOWN);
else if(j == size_before)
town->spec_strs.resize(size_before + 8, "*");
else clear_string(STRS_TOWN, j);
@@ -521,7 +543,7 @@ static bool handle_rb_action(location the_point, bool option_hit) {
size_before = scenario.journal_strs.size();
if(option_hit) {
if(j == size_before - 1)
scenario.journal_strs.pop_back();
delete_last_string(STRS_JOURNAL);
else if(j == size_before)
scenario.journal_strs.resize(size_before + 8, "*");
else clear_string(STRS_JOURNAL, j);

View File

@@ -2,6 +2,8 @@
#ifndef BOE_SCEN_GLOBAL_HPP
#define BOE_SCEN_GLOBAL_HPP
#include <vector>
const int BITMAP_WIDTH = 28;
const int BITMAP_HEIGHT = 36;
@@ -115,7 +117,7 @@ enum ePalBtn {
};
extern std::string& fetch_str(eStrMode str_mode, size_t which);
extern std::string edit_string_action_name(bool clear, eStrMode str_mode);
extern std::string edit_string_action_name(std::string what, eStrMode str_mode);
extern std::vector<std::string>& fetch_str_list(eStrMode str_mode);
#endif

View File

@@ -654,8 +654,8 @@ short choose_text_editable(std::vector<std::string>& list, short cur_choice, cDi
return cur_choice;
}
std::string edit_string_action_name(bool clear, eStrMode str_mode){
std::string name = clear ? "Clear " : "Edit ";
std::string edit_string_action_name(std::string what, eStrMode str_mode){
std::string name = what + " ";
switch(str_mode){
case 0: name += "Scenario Text"; break;
case 1: name += "Outdoor Text"; break;
@@ -674,7 +674,7 @@ static bool edit_text_event_filter(cDialog& me, std::string item_hit, short& whi
std::string& realVal = fetch_str(str_mode, which_str);
if(realVal != newVal){
// edit menu will update when string editor closes
undo_list.add(action_ptr(new aEditClearString(edit_string_action_name(false, str_mode), str_mode, which_str, realVal, newVal)));
undo_list.add(action_ptr(new aEditClearString(edit_string_action_name("Edit", str_mode), str_mode, which_str, realVal, newVal)));
}
fetch_str(str_mode, which_str) = newVal;

View File

@@ -1094,4 +1094,18 @@ bool aEditClearString::redo_me() {
fetch_str(str_mode, which) = new_value;
start_string_editing(str_mode);
return true;
}
bool aDeleteString::undo_me() {
if(str_mode == STRS_TOWN) set_current_town(which_town);
else if(str_mode == STRS_OUT) set_current_out(which_out);
fetch_str_list(str_mode).push_back(str);
return true;
}
bool aDeleteString::redo_me() {
if(str_mode == STRS_TOWN) set_current_town(which_town);
else if(str_mode == STRS_OUT) set_current_out(which_out);
fetch_str_list(str_mode).pop_back();
return true;
}

View File

@@ -757,4 +757,17 @@ public:
cAction(name), str_mode(str_mode), which(which), old_value(old_value), new_value(new_value), which_town(cur_town), which_out(cur_out) {}
};
class aDeleteString : public cAction {
eStrMode str_mode;
std::string str;
// undo/redo for town text and outdoor text depends on global state of which town/outdoor section are active
size_t which_town;
location which_out;
bool undo_me() override;
bool redo_me() override;
public:
aDeleteString(std::string name, eStrMode mode, std::string str) :
cAction(name), str_mode(mode), which_town(cur_town), which_out(cur_out), str(str) {}
};
#endif