undo/redo for creating strings
This commit is contained in:
@@ -370,7 +370,28 @@ static void delete_last_string(eStrMode mode) {
|
||||
str_list.pop_back();
|
||||
}
|
||||
|
||||
static void create_string(eStrMode mode, bool option_hit) {
|
||||
static void create_many_strings(eStrMode mode) {
|
||||
auto& str_list = fetch_str_list(mode);
|
||||
std::vector<std::string> new_strings;
|
||||
for(int i = 0; i < 8; ++i){
|
||||
str_list.push_back("*");
|
||||
new_strings.push_back("*");
|
||||
}
|
||||
undo_list.add(action_ptr(new aCreateStrings(mode, new_strings)));
|
||||
update_edit_menu();
|
||||
}
|
||||
|
||||
static void try_edit_string(eStrMode mode, size_t which, bool is_new) {
|
||||
auto& str_list = fetch_str_list(mode);
|
||||
if(is_new)
|
||||
str_list.emplace_back("*");
|
||||
if(!edit_text_str(which,mode,is_new) && is_new)
|
||||
str_list.pop_back();
|
||||
}
|
||||
|
||||
static void edit_loc_string(eStrMode mode, size_t which) {
|
||||
bool is_new = false;
|
||||
edit_text_str(which,mode,is_new);
|
||||
}
|
||||
|
||||
static bool handle_rb_action(location the_point, bool option_hit) {
|
||||
@@ -454,13 +475,10 @@ static bool handle_rb_action(location the_point, bool option_hit) {
|
||||
if(j == size_before - 1)
|
||||
delete_last_string(STRS_SCEN);
|
||||
else if(j == size_before)
|
||||
scenario.spec_strs.resize(size_before + 8, "*");
|
||||
create_many_strings(STRS_SCEN);
|
||||
else clear_string(STRS_SCEN, j);
|
||||
} else {
|
||||
if(j == size_before)
|
||||
scenario.spec_strs.emplace_back("*");
|
||||
if(!edit_text_str(j,STRS_SCEN) && j == size_before && scenario.spec_strs[j] == "*")
|
||||
scenario.spec_strs.pop_back();
|
||||
try_edit_string(STRS_SCEN, j, j == size_before);
|
||||
}
|
||||
start_string_editing(STRS_SCEN);
|
||||
if(size_before > scenario.spec_strs.size())
|
||||
@@ -473,13 +491,10 @@ static bool handle_rb_action(location the_point, bool option_hit) {
|
||||
if(j == size_before - 1)
|
||||
delete_last_string(STRS_OUT);
|
||||
else if(j == size_before)
|
||||
current_terrain->spec_strs.resize(size_before + 8, "*");
|
||||
create_many_strings(STRS_OUT);
|
||||
else clear_string(STRS_OUT, j);
|
||||
} else {
|
||||
if(j == size_before)
|
||||
current_terrain->spec_strs.emplace_back("*");
|
||||
if(!edit_text_str(j,STRS_OUT) && j == size_before && current_terrain->spec_strs[j] == "*")
|
||||
current_terrain->spec_strs.pop_back();
|
||||
try_edit_string(STRS_OUT, j, j == size_before);
|
||||
}
|
||||
start_string_editing(STRS_OUT);
|
||||
if(size_before > current_terrain->spec_strs.size())
|
||||
@@ -492,13 +507,10 @@ static bool handle_rb_action(location the_point, bool option_hit) {
|
||||
if(j == size_before - 1)
|
||||
delete_last_string(STRS_TOWN);
|
||||
else if(j == size_before)
|
||||
town->spec_strs.resize(size_before + 8, "*");
|
||||
create_many_strings(STRS_TOWN);
|
||||
else clear_string(STRS_TOWN, j);
|
||||
} else {
|
||||
if(j == size_before)
|
||||
town->spec_strs.emplace_back("*");
|
||||
if(!edit_text_str(j,STRS_TOWN) && j == size_before && town->spec_strs[j] == "*")
|
||||
town->spec_strs.pop_back();
|
||||
try_edit_string(STRS_TOWN, j, j == size_before);
|
||||
}
|
||||
start_string_editing(STRS_TOWN);
|
||||
if(size_before > town->spec_strs.size())
|
||||
@@ -545,13 +557,10 @@ static bool handle_rb_action(location the_point, bool option_hit) {
|
||||
if(j == size_before - 1)
|
||||
delete_last_string(STRS_JOURNAL);
|
||||
else if(j == size_before)
|
||||
scenario.journal_strs.resize(size_before + 8, "*");
|
||||
create_many_strings(STRS_JOURNAL);
|
||||
else clear_string(STRS_JOURNAL, j);
|
||||
} else {
|
||||
if(j == size_before)
|
||||
scenario.journal_strs.emplace_back("*");
|
||||
if(!edit_text_str(j,STRS_JOURNAL) && j == size_before && scenario.journal_strs[j] == "*")
|
||||
scenario.journal_strs.pop_back();
|
||||
try_edit_string(STRS_JOURNAL, j, j == size_before);
|
||||
}
|
||||
start_string_editing(STRS_JOURNAL);
|
||||
if(size_before > scenario.journal_strs.size())
|
||||
@@ -604,7 +613,7 @@ static bool handle_rb_action(location the_point, bool option_hit) {
|
||||
current_terrain->sign_locs[j] = {-1, -1, "*"};
|
||||
}
|
||||
} else {
|
||||
edit_text_str(j,STRS_OUT_SIGN);
|
||||
edit_loc_string(STRS_OUT_SIGN,j);
|
||||
}
|
||||
start_string_editing(STRS_OUT_SIGN);
|
||||
if(size_before > current_terrain->sign_locs.size())
|
||||
@@ -625,7 +634,7 @@ static bool handle_rb_action(location the_point, bool option_hit) {
|
||||
town->sign_locs[j] = {-1, -1, "*"};
|
||||
}
|
||||
} else {
|
||||
edit_text_str(j,STRS_TOWN_SIGN);
|
||||
edit_loc_string(STRS_TOWN_SIGN,j);
|
||||
}
|
||||
start_string_editing(STRS_TOWN_SIGN);
|
||||
if(size_before > town->sign_locs.size())
|
||||
@@ -646,7 +655,7 @@ static bool handle_rb_action(location the_point, bool option_hit) {
|
||||
current_terrain->area_desc[j] = {0, 0, 0, 0, "*"};
|
||||
}
|
||||
} else {
|
||||
edit_text_str(j,STRS_OUT_RECT);
|
||||
edit_loc_string(STRS_OUT_RECT,j);
|
||||
}
|
||||
start_string_editing(STRS_OUT_RECT);
|
||||
if(size_before > current_terrain->area_desc.size())
|
||||
@@ -667,7 +676,7 @@ static bool handle_rb_action(location the_point, bool option_hit) {
|
||||
town->area_desc[j] = {0, 0, 0, 0, "*"};
|
||||
}
|
||||
} else {
|
||||
edit_text_str(j,STRS_TOWN_RECT);
|
||||
edit_loc_string(STRS_TOWN_RECT,j);
|
||||
}
|
||||
start_string_editing(STRS_TOWN_RECT);
|
||||
if(size_before > town->area_desc.size())
|
||||
|
@@ -668,16 +668,20 @@ std::string edit_string_action_name(std::string what, eStrMode str_mode){
|
||||
return name;
|
||||
}
|
||||
|
||||
static bool edit_text_event_filter(cDialog& me, std::string item_hit, short& which_str, eStrMode str_mode,bool loop,short min_str,short max_str) {
|
||||
static bool edit_text_event_filter(cDialog& me, std::string item_hit, short& which_str, eStrMode str_mode,bool& is_new,bool loop,short min_str,short max_str) {
|
||||
std::string newVal = me["text"].getText();
|
||||
|
||||
std::string& realVal = fetch_str(str_mode, which_str);
|
||||
if(realVal != newVal){
|
||||
if(is_new){
|
||||
undo_list.add(action_ptr(new aCreateStrings(str_mode, {newVal})));
|
||||
}
|
||||
else if(realVal != newVal){
|
||||
// edit menu will update when string editor closes
|
||||
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;
|
||||
realVal = newVal;
|
||||
is_new = false;
|
||||
if(item_hit == "okay") me.toast(true);
|
||||
else if(item_hit == "left" || item_hit == "right") {
|
||||
if(item_hit[0] == 'l')
|
||||
@@ -700,12 +704,12 @@ static bool edit_text_event_filter(cDialog& me, std::string item_hit, short& whi
|
||||
return true;
|
||||
}
|
||||
|
||||
bool edit_text_str(short which_str,eStrMode mode,bool loop,short min_str,short max_str) {
|
||||
bool edit_text_str(short which_str,eStrMode mode,bool& is_new,bool loop,short min_str,short max_str) {
|
||||
using namespace std::placeholders;
|
||||
short first = which_str;
|
||||
|
||||
cDialog dlog(*ResMgr::dialogs.get("edit-text"));
|
||||
dlog.attachClickHandlers(std::bind(edit_text_event_filter, _1, _2, std::ref(which_str), mode, loop, min_str, max_str), {"okay", "left", "right"});
|
||||
dlog.attachClickHandlers(std::bind(edit_text_event_filter, _1, _2, std::ref(which_str), mode, std::ref(is_new), loop, min_str, max_str), {"okay", "left", "right"});
|
||||
dlog["cancel"].attachClickHandler(std::bind(&cDialog::toast, _1, false));
|
||||
|
||||
dlog["num"].setText(str_info(mode, which_str));
|
||||
@@ -1162,15 +1166,17 @@ static bool edit_spec_enc_value(cDialog& me, std::string item_hit, node_stack_t&
|
||||
auto mode = eStrMode(edit_stack.top().mode);
|
||||
store = num_strs(mode);
|
||||
ensure_str(mode, store);
|
||||
if(edit_text_str(store, mode, false, store)) {
|
||||
bool is_new = true;
|
||||
if(edit_text_str(store, mode, is_new, false, store)) {
|
||||
auto otherField = get_control_for_field(fcn.continuation);
|
||||
me[otherField].setTextToNum(num_strs(mode) - 1);
|
||||
} else store = val;
|
||||
} else {
|
||||
// Otherwise, edit only the sequence of strings specified. The values of the fields won't change.
|
||||
store = val;
|
||||
bool is_new = false;
|
||||
auto otherField = get_control_for_field(fcn.continuation);
|
||||
edit_text_str(val, eStrMode(edit_stack.top().mode), false, val, me[otherField].getTextAsNum());
|
||||
edit_text_str(val, eStrMode(edit_stack.top().mode), is_new, false, val, me[otherField].getTextAsNum());
|
||||
}
|
||||
break;
|
||||
case eSpecPicker::TOGGLE: {
|
||||
|
@@ -14,7 +14,7 @@ short choose_text_res(std::string res_list,short first_t,short last_t,unsigned s
|
||||
short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent,std::string title);
|
||||
short choose_text_editable(std::vector<std::string>& list, short cur_choice, cDialog* parent, std::string title);
|
||||
short choose_pattern(short cur_choice, cDialog* parent, bool expandRotatable);
|
||||
bool edit_text_str(short which_str,eStrMode mode,bool loop = true,short min_str = 0,short max_str = -1);
|
||||
bool edit_text_str(short which_str,eStrMode mode,bool& is_new,bool loop = true,short min_str = 0,short max_str = -1);
|
||||
bool edit_spec_enc(short which_node,short mode,cDialog* parent);
|
||||
short get_fresh_spec(short which_mode);
|
||||
void edit_spec_text(eStrMode mode,short *str1,short *str2,cDialog* parent);
|
||||
|
@@ -1100,6 +1100,7 @@ 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);
|
||||
start_string_editing(str_mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1107,5 +1108,28 @@ 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();
|
||||
start_string_editing(str_mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aCreateStrings::undo_me() {
|
||||
if(str_mode == STRS_TOWN) set_current_town(which_town);
|
||||
else if(str_mode == STRS_OUT) set_current_out(which_out);
|
||||
auto& str_list = fetch_str_list(str_mode);
|
||||
for(int i = 0; i < strs.size(); ++i){
|
||||
str_list.pop_back();
|
||||
}
|
||||
start_string_editing(str_mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aCreateStrings::redo_me() {
|
||||
if(str_mode == STRS_TOWN) set_current_town(which_town);
|
||||
else if(str_mode == STRS_OUT) set_current_out(which_out);
|
||||
auto& str_list = fetch_str_list(str_mode);
|
||||
for(auto str : strs){
|
||||
str_list.push_back(str);
|
||||
}
|
||||
start_string_editing(str_mode);
|
||||
return true;
|
||||
}
|
@@ -770,4 +770,17 @@ public:
|
||||
cAction(name), str_mode(mode), which_town(cur_town), which_out(cur_out), str(str) {}
|
||||
};
|
||||
|
||||
class aCreateStrings : public cAction {
|
||||
eStrMode str_mode;
|
||||
std::vector<std::string> strs;
|
||||
// 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:
|
||||
aCreateStrings(eStrMode mode, std::vector<std::string> strs) :
|
||||
cAction(edit_string_action_name("Create", mode) + (strs.size() > 1 ? "s" : "")), str_mode(mode), strs(strs), which_town(cur_town), which_out(cur_out) {}
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user