undo/redo for editing/clearing a special item
This commit is contained in:
@@ -1444,4 +1444,12 @@ bool cItem::operator==(const cItem& other) {
|
||||
CHECK_EQ(other, rechargeable);
|
||||
CHECK_EQ(other, desc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cSpecItem::operator==(const cSpecItem& other) {
|
||||
CHECK_EQ(other, flags);
|
||||
CHECK_EQ(other, special);
|
||||
CHECK_EQ(other, name);
|
||||
CHECK_EQ(other, descr);
|
||||
return true;
|
||||
}
|
@@ -99,6 +99,10 @@ public:
|
||||
short special = -1;
|
||||
std::string name;
|
||||
std::string descr;
|
||||
|
||||
// For detecting actual changes to special items in the scenario editor
|
||||
bool operator==(const cSpecItem& other);
|
||||
bool operator!=(const cSpecItem& other) { return !(*this == other); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -487,29 +487,17 @@ static bool handle_rb_action(location the_point, bool option_hit) {
|
||||
break;
|
||||
// Clear special item (it can't be deleted fully)
|
||||
else {
|
||||
// TODO undo action
|
||||
scenario.special_items[j] = cSpecItem();
|
||||
scenario.special_items[j].name = "Unused Special Item";
|
||||
cSpecItem cleared;
|
||||
cleared.name = "Unused Special Item";
|
||||
undo_list.add(action_ptr(new aEditClearSpecialItem("Clear Special Item", j, scenario.special_items[j], cleared)));
|
||||
update_edit_menu();
|
||||
scenario.special_items[j] = cleared;
|
||||
}
|
||||
} else {
|
||||
bool is_new = false;
|
||||
// Create new special item
|
||||
if(j == size_before) {
|
||||
is_new = true;
|
||||
scenario.special_items.emplace_back();
|
||||
scenario.special_items.back().name = "New Special Item";
|
||||
}
|
||||
|
||||
bool is_new = (j == size_before);
|
||||
if(edit_spec_item(j)){
|
||||
// Create new confirmed
|
||||
if(is_new){
|
||||
undo_list.add(action_ptr(new aCreateDeleteSpecialItem(true, scenario.special_items.back())));
|
||||
update_edit_menu();
|
||||
}
|
||||
// Special item edited
|
||||
else{
|
||||
// TODO undo action
|
||||
}
|
||||
// Special item create/edit undo action is added in save_spec_item() because special item editor
|
||||
// has left/right buttons and may someday be launched with create/edit buttons elsewhere.
|
||||
}
|
||||
// Create new canceled
|
||||
else if(is_new){
|
||||
|
@@ -2168,7 +2168,10 @@ static void put_spec_item_in_dlog(cDialog& me, cSpecItem& item, short which) {
|
||||
dynamic_cast<cLed&>(me["usable"]).setState(item.flags % 10 > 0 ? led_red : led_off);
|
||||
}
|
||||
|
||||
static bool save_spec_item(cDialog& me, cSpecItem& item, short which) {
|
||||
static bool save_spec_item(cDialog& me, cSpecItem& item, short which, bool& is_new, bool need_confirm = false) {
|
||||
if(!me.toast(true)) return false;
|
||||
me.untoast();
|
||||
|
||||
item.name = me["name"].getText();
|
||||
item.descr = me["descr"].getText();
|
||||
item.special = me["spec"].getTextAsNum();
|
||||
@@ -2177,35 +2180,61 @@ static bool save_spec_item(cDialog& me, cSpecItem& item, short which) {
|
||||
item.flags += 10;
|
||||
if(dynamic_cast<cLed&>(me["usable"]).getState() != led_off)
|
||||
item.flags += 1;
|
||||
scenario.special_items[which] = item;
|
||||
|
||||
if(item != scenario.special_items[which] || is_new){
|
||||
if(need_confirm){
|
||||
// Confirm keeping changes
|
||||
cChoiceDlog dlog("confirm-edit-spec-item", {"keep","revert","cancel"}, &me);
|
||||
dlog->getControl("keep-msg").replaceText("{{spec-item}}", item.name);
|
||||
std::string choice = dlog.show();
|
||||
if(choice == "revert"){
|
||||
put_spec_item_in_dlog(me, scenario.special_items[which], which);
|
||||
return false;
|
||||
}else if(choice == "cancel"){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Create new confirmed
|
||||
if(is_new){
|
||||
undo_list.add(action_ptr(new aCreateDeleteSpecialItem(true, scenario.special_items.back())));
|
||||
update_edit_menu();
|
||||
}
|
||||
// Special item edited
|
||||
else{
|
||||
undo_list.add(action_ptr(new aEditClearSpecialItem("Edit Special Item", which, scenario.special_items[which], item)));
|
||||
update_edit_menu();
|
||||
}
|
||||
scenario.special_items[which] = item;
|
||||
}
|
||||
is_new = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool edit_spec_item_event_filter(cDialog& me, std::string hit, cSpecItem& item, short& which) {
|
||||
static bool edit_spec_item_event_filter(cDialog& me, std::string hit, cSpecItem& item, short& which, bool& is_new) {
|
||||
if(hit == "cancel") {
|
||||
me.toast(false);
|
||||
} else if(hit == "okay") {
|
||||
if(save_spec_item(me, item, which)) me.toast(true);
|
||||
if(save_spec_item(me, item, which, is_new)) me.toast(true);
|
||||
} else if(hit == "left") {
|
||||
if(!save_spec_item(me, item, which)) return true;
|
||||
if(!save_spec_item(me, item, which, is_new, true)) return true;
|
||||
which--;
|
||||
if(which < 0) which = scenario.special_items.size() - 1;
|
||||
item = scenario.special_items[which];
|
||||
put_spec_item_in_dlog(me, item, which);
|
||||
} else if(hit == "right") {
|
||||
if(!save_spec_item(me, item, which)) return true;
|
||||
if(!save_spec_item(me, item, which, is_new, true)) return true;
|
||||
which++;
|
||||
if(which >= scenario.special_items.size()) which = 0;
|
||||
item = scenario.special_items[which];
|
||||
put_spec_item_in_dlog(me, item, which);
|
||||
} else if(hit == "edit-spec") {
|
||||
if(!save_spec_item(me, item, which)) return true;
|
||||
if(!save_spec_item(me, item, which, is_new)) return true;
|
||||
short spec = me["spec"].getTextAsNum();
|
||||
if(spec < 0)
|
||||
spec = get_fresh_spec(0);
|
||||
if(edit_spec_enc(spec,0,&me))
|
||||
me["spec"].setTextToNum(spec);
|
||||
save_spec_item(me, item, which);
|
||||
save_spec_item(me, item, which, is_new);
|
||||
|
||||
}
|
||||
return true;
|
||||
@@ -2214,17 +2243,22 @@ static bool edit_spec_item_event_filter(cDialog& me, std::string hit, cSpecItem&
|
||||
bool edit_spec_item(short which_item) {
|
||||
short first = which_item;
|
||||
using namespace std::placeholders;
|
||||
bool is_new = false;
|
||||
// Create new special item
|
||||
if(which_item == scenario.special_items.size()) {
|
||||
is_new = true;
|
||||
scenario.special_items.emplace_back();
|
||||
scenario.special_items.back().name = "New Special Item";
|
||||
}
|
||||
cSpecItem item = scenario.special_items[which_item];
|
||||
|
||||
cDialog item_dlg(*ResMgr::dialogs.get("edit-special-item"));
|
||||
item_dlg["spec"].attachFocusHandler(std::bind(check_range_msg, _1, _2, _3, -1, scenario.scen_specials.size(), "Scenario special node called", "-1 for no special"));
|
||||
item_dlg.attachClickHandlers(std::bind(edit_spec_item_event_filter, _1, _2, std::ref(item), std::ref(which_item)), {"okay", "cancel", "clear", "edit-spec"});
|
||||
item_dlg.attachClickHandlers(std::bind(edit_spec_item_event_filter, _1, _2, std::ref(item), std::ref(which_item), std::ref(is_new)), {"okay", "cancel", "clear", "edit-spec", "left", "right"});
|
||||
|
||||
if(scenario.special_items.size() == 1) {
|
||||
item_dlg["left"].hide();
|
||||
item_dlg["right"].hide();
|
||||
} else {
|
||||
item_dlg.attachClickHandlers(std::bind(edit_spec_item_event_filter, _1, _2, std::ref(item), std::ref(which_item)), {"left", "right"});
|
||||
}
|
||||
|
||||
put_spec_item_in_dlog(item_dlg, item, which_item);
|
||||
|
@@ -439,4 +439,24 @@ bool aCreateDeleteShop::redo_me() {
|
||||
}
|
||||
scenario.shops.push_back(shop);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aEditClearSpecialItem::undo_me() {
|
||||
// If not editing special items, show it
|
||||
if(overall_mode != MODE_EDIT_SPECIAL_ITEMS){
|
||||
start_special_item_editing();
|
||||
// TODO scroll to show the item
|
||||
}
|
||||
scenario.special_items[which] = before;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aEditClearSpecialItem::redo_me() {
|
||||
// If not editing special items, show it
|
||||
if(overall_mode != MODE_EDIT_SPECIAL_ITEMS){
|
||||
start_special_item_editing();
|
||||
// TODO scroll to show the item
|
||||
}
|
||||
scenario.special_items[which] = after;
|
||||
return true;
|
||||
}
|
@@ -304,4 +304,16 @@ public:
|
||||
cAction(name), which(which), before(before), after(after) {}
|
||||
};
|
||||
|
||||
/// Action which edits or clears a special item
|
||||
class aEditClearSpecialItem : public cAction {
|
||||
size_t which;
|
||||
cSpecItem before;
|
||||
cSpecItem after;
|
||||
bool undo_me() override;
|
||||
bool redo_me() override;
|
||||
public:
|
||||
aEditClearSpecialItem(std::string name, size_t which, cSpecItem before, cSpecItem after) :
|
||||
cAction(name), which(which), before(before), after(after) {}
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user