diff --git a/src/dialogxml/dialogs/dialog.cpp b/src/dialogxml/dialogs/dialog.cpp index 0e8976cb..70381c64 100644 --- a/src/dialogxml/dialogs/dialog.cpp +++ b/src/dialogxml/dialogs/dialog.cpp @@ -543,6 +543,10 @@ void cDialog::handle_events() { if(info["id"].empty()) continue; eKeyMod mods = static_cast(std::stoi(info["mods"])); controls[info["id"]]->triggerClickHandler(*this, info["id"], mods); + }else if(replaying && has_next_action() && next_action_type() == "field_input"){ + Element& next_action = pop_next_action(); + cKey key = key_from_action(next_action); + dynamic_cast(getControl(currentFocus)).handleInput(key); }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 479ccc22..e253b6a0 100644 --- a/src/dialogxml/widgets/field.cpp +++ b/src/dialogxml/widgets/field.cpp @@ -17,6 +17,7 @@ #include "tools/keymods.hpp" #include "tools/winutil.hpp" #include "tools/cursors.hpp" +#include "replay.hpp" bool cTextField::callHandler(event_fcn::type onFocus, cDialog& me, std::string id) { if(field_type != FLD_TEXT) { @@ -396,6 +397,9 @@ static cKey divineFunction(cKey key) { } void cTextField::handleInput(cKey key) { + if(recording){ + record_field_input(key); + } changeMade = true; bool select = mod_contains(key.mod, mod_shift); bool haveSelection = insertionPoint != selectionPoint; diff --git a/src/tools/replay.cpp b/src/tools/replay.cpp index 9ad9a089..89303a42 100644 --- a/src/tools/replay.cpp +++ b/src/tools/replay.cpp @@ -11,6 +11,10 @@ #include #include #include "tools/framerate_limiter.hpp" +#include +#include +#include + using base64 = cppcodec::base64_rfc4648; bool recording = false; @@ -89,6 +93,32 @@ void record_action(std::string action_type, std::map in log_document.SaveFile(log_file); } +void record_field_input(cKey key) { + std::map info; + std::ostringstream sstr; + + sstr << key.spec; + info["spec"] = sstr.str(); + + sstr.str(""); + if(key.spec){ + sstr << key.k; + info["k"] = sstr.str(); + }else{ + std::wostringstream wstr; + wstr << key.c; + std::wstring_convert> converter; + std::string c = converter.to_bytes(wstr.str()); + info["c"] = c; + } + + sstr.str(""); + sstr << key.mod; + info["mod"] = sstr.str(); + + record_action("field_input", info); +} + bool has_next_action() { return next_action != nullptr; } @@ -162,3 +192,29 @@ short short_from_action(Element& action) { sstr >> s; return s; } + +cKey key_from_action(Element& action) { + auto info = info_from_action(action); + cKey key; + int enum_v; + + std::istringstream sstr(info["spec"]); + sstr >> key.spec; + + if(key.spec){ + sstr.str(info["k"]); + sstr >> enum_v; + key.k = static_cast(enum_v); + }else{ + std::wstring_convert> converter; + std::wstring wstr = converter.from_bytes(info["c"]); + std::wistringstream wsstr(wstr); + wsstr >> key.c; + } + + sstr.str(info["mod"]); + sstr >> enum_v; + key.mod = static_cast(enum_v); + + return key; +} \ No newline at end of file diff --git a/src/tools/replay.hpp b/src/tools/replay.hpp index bdeb3c35..1cc9146e 100644 --- a/src/tools/replay.hpp +++ b/src/tools/replay.hpp @@ -6,6 +6,7 @@ #include #include #include "location.hpp" +#include "keycodes.hpp" // Input recording system namespace ticpp { class Element; } @@ -17,6 +18,7 @@ extern bool replaying; extern bool init_action_log(std::string command, std::string file); extern void record_action(std::string action_type, std::string inner_text, bool cdata = false); extern void record_action(std::string action_type, std::map info); +extern void record_field_input(cKey key); extern bool has_next_action(); extern std::string next_action_type(); extern Element& pop_next_action(std::string expected_action_type=""); @@ -25,5 +27,6 @@ extern std::string encode_file(fs::path file); extern void decode_file(std::string data, fs::path file); extern location location_from_action(Element& action); extern short short_from_action(Element& action); +extern cKey key_from_action(Element& action); #endif