diff --git a/src/dialogxml/dialogs/dialog.cpp b/src/dialogxml/dialogs/dialog.cpp index 1aab81726..21f09d69d 100644 --- a/src/dialogxml/dialogs/dialog.cpp +++ b/src/dialogxml/dialogs/dialog.cpp @@ -551,6 +551,12 @@ void cDialog::handle_events() { }else if(replaying && has_next_action("handleTab")){ Element& next_action = pop_next_action(); handleTab(boost::lexical_cast(next_action.GetText())); + }else if(replaying && has_next_action("field_focus")) { + Element& next_action = pop_next_action(); + setFocus(&(dynamic_cast(getControl(next_action.GetText())))); + }else if(replaying && has_next_action("field_selection")) { + cTextField& text_field = dynamic_cast(getControl(currentFocus)); + text_field.replay_selection(pop_next_action()); }else{ while(win.pollEvent(currentEvent)) handle_one_event(currentEvent, fps_limiter); } diff --git a/src/dialogxml/widgets/field.cpp b/src/dialogxml/widgets/field.cpp index 72307c695..45819f380 100644 --- a/src/dialogxml/widgets/field.cpp +++ b/src/dialogxml/widgets/field.cpp @@ -54,6 +54,11 @@ bool cTextField::callHandler(event_fcn::type onFocus, cDialog& me, } void cTextField::callHandler(event_fcn::type onFocus, cDialog& me, std::string id) { + // Focus events for text fields need to be recorded: + if(recording){ + record_action("field_focus", id); + } + if(onFocus) onFocus(me,id); haveFocus = true; if(insertionPoint < 0) @@ -118,6 +123,22 @@ void cTextField::set_ip(location clickLoc, int cTextField::* insertionPoint) { } } +void cTextField::record_selection() { + if(recording){ + std::map info; + info["insertionPoint"] = boost::lexical_cast(insertionPoint); + info["selectionPoint"] = boost::lexical_cast(selectionPoint); + record_action("field_selection", info); + } +} + +void cTextField::replay_selection(ticpp::Element& next_action) { + auto info = info_from_action(next_action); + insertionPoint = boost::lexical_cast(info["insertionPoint"]); + selectionPoint = boost::lexical_cast(info["selectionPoint"]); + redraw(); +} + bool cTextField::handleClick(location clickLoc, cFramerateLimiter& fps_limiter) { if(!haveFocus && parent && !parent->setFocus(this)) return true; haveFocus = true; @@ -165,6 +186,7 @@ bool cTextField::handleClick(location clickLoc, cFramerateLimiter& fps_limiter) } fps_limiter.frame_finished(); } + record_selection(); redraw(); return true; } @@ -640,6 +662,7 @@ void cTextField::handleInput(cKey key, bool record) { setText(contents); insertionPoint = ip; selectionPoint = sp; + record_selection(); } bool cTextField::parseAttribute(ticpp::Attribute& attr, std::string tagName, std::string fname) { diff --git a/src/dialogxml/widgets/field.hpp b/src/dialogxml/widgets/field.hpp index 5d8f2d902..3b10afb07 100644 --- a/src/dialogxml/widgets/field.hpp +++ b/src/dialogxml/widgets/field.hpp @@ -70,11 +70,13 @@ public: cTextField(cTextField& other) = delete; /// This field is only used by cDialog during the loading process. Changing it will have no effect. long tabOrder = 0; + void replay_selection(ticpp::Element& next_action); private: void callHandler(event_fcn::type onFocus, cDialog& me, std::string id) override; bool callHandler(event_fcn::type onFocus, cDialog& me, std::string id) override; bool manageFormat(eFormat prop, bool set, boost::any* val) override; void set_ip(location clickLoc, int cTextField::* insertionPoint); + void record_selection(); cUndoList history; action_ptr current_action; eFldType field_type;