From 9f60f7e3784e26b36acbd310caabcb83e0b12a09 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Fri, 21 Feb 2020 22:25:48 -0500 Subject: [PATCH] Implement tag in DialogXML which substitutes a buttons key shortcut into its label --- rsrc/dialogs/cast-spell.xml | 24 ++++++------- rsrc/dialogs/get-items.xml | 12 +++---- rsrc/dialogs/select-pc.xml | 12 +++---- rsrc/dialogs/soul-crystal.xml | 8 ++--- src/dialogxml/widgets/button.cpp | 10 +++--- src/dialogxml/widgets/button.hpp | 1 - src/dialogxml/widgets/control.cpp | 60 ++++++++++++++++++++++++++----- src/dialogxml/widgets/control.hpp | 5 +-- 8 files changed, 88 insertions(+), 44 deletions(-) diff --git a/rsrc/dialogs/cast-spell.xml b/rsrc/dialogs/cast-spell.xml index 79f32507..2217deeb 100644 --- a/rsrc/dialogs/cast-spell.xml +++ b/rsrc/dialogs/cast-spell.xml @@ -4,21 +4,21 @@ Select a Spell: - - - - - - + + + + + + - - - - - - + + + + + + diff --git a/rsrc/dialogs/get-items.xml b/rsrc/dialogs/get-items.xml index 954f9338..93ee78e3 100644 --- a/rsrc/dialogs/get-items.xml +++ b/rsrc/dialogs/get-items.xml @@ -3,12 +3,12 @@ - - - - - + + + + + + - - - - - + + + + + + diff --git a/rsrc/dialogs/soul-crystal.xml b/rsrc/dialogs/soul-crystal.xml index c5a13a84..12daf696 100644 --- a/rsrc/dialogs/soul-crystal.xml +++ b/rsrc/dialogs/soul-crystal.xml @@ -5,16 +5,16 @@ - + (spot empty) - + (spot empty) - + (spot empty) - + (spot empty) Select monster to summon: diff --git a/src/dialogxml/widgets/button.cpp b/src/dialogxml/widgets/button.cpp index 677e4365..0a2ec6d3 100644 --- a/src/dialogxml/widgets/button.cpp +++ b/src/dialogxml/widgets/button.cpp @@ -84,7 +84,11 @@ void cButton::draw(){ int w = string_length(lbl, style); to_rect.inset((w - 30) / -2,0); } - win_draw_string(*inWindow,to_rect,lbl,textMode,style); + std::string label = lbl, keyDesc = getAttachedKeyDescription(); + for(size_t key_pos = label.find_first_of('\a'); key_pos < label.size(); key_pos = label.find_first_of('\a')) { + label.replace(key_pos, 1, keyDesc); + } + win_draw_string(*inWindow,to_rect,label,textMode,style); // frame default button, to provide a visual cue that it's the default if(key.spec && key.k == key_enter) drawFrame(2,frameStyle); } @@ -151,9 +155,7 @@ bool cButton::parseContent(ticpp::Node& content, int n, std::string tagName, std text += dlogStringFilter(content.Value()); return true; } else if(content.Value() == "key") { - // TODO: There's surely a better way to do this - if(text.length() > 0) throw xBadVal("button", xBadVal::CONTENT, text + "", content.Row(), content.Column(), fname); - labelWithKey = true; + text += '\a'; return true; } return cControl::parseContent(content, n, tagName, fname, text); diff --git a/src/dialogxml/widgets/button.hpp b/src/dialogxml/widgets/button.hpp index 10fc9fa0..7f6cddae 100644 --- a/src/dialogxml/widgets/button.hpp +++ b/src/dialogxml/widgets/button.hpp @@ -88,7 +88,6 @@ protected: cButton(cDialog& parent,eControlType t); private: bool manageFormat(eFormat prop, bool set, boost::any* val) override; - bool labelWithKey; std::string fromList; static rectangle btnRects[13][2]; protected: diff --git a/src/dialogxml/widgets/control.cpp b/src/dialogxml/widgets/control.cpp index 9fd8c759..68b32e52 100644 --- a/src/dialogxml/widgets/control.cpp +++ b/src/dialogxml/widgets/control.cpp @@ -311,18 +311,60 @@ static unsigned char removeShift(unsigned char c){ return afterUnShift[c - ' ']; } -void cControl::setTextToKey() { - if(key.spec); // TODO: Handle this case - else { +std::string cControl::getAttachedKeyDescription() { + std::string s; + if(key.spec) { + auto mod = key.mod; + std::string keyName; + switch(key.k) { + case key_left: keyName = "left"; break; + case key_right: keyName = "right"; break; + case key_up: keyName = "up"; break; + case key_down: keyName = "down"; break; + case key_esc: keyName = "esc"; break; + case key_enter: keyName = "enter"; break; + case key_tab: keyName = "tab"; break; + case key_help: keyName = "help"; break; + case key_bsp: keyName = "backspace"; break; + case key_del: keyName = "delete"; break; + case key_home: keyName = "home"; break; + case key_end: keyName = "end"; break; + case key_pgup: keyName = "pgup"; break; + case key_pgdn: keyName = "pgdn"; break; + case key_insert: keyName = "insert"; break; + case key_copy: keyName = "c"; mod += mod_ctrl; break; + case key_cut: keyName = "x"; mod += mod_ctrl; break; + case key_paste: keyName = "v"; mod += mod_ctrl; break; + case key_selectall: keyName = "a"; mod += mod_ctrl; break; + case key_undo: keyName = "z"; mod += mod_ctrl; break; + case key_redo: keyName = "y"; mod += mod_ctrl; break; + case key_top: keyName = "home"; mod += mod_ctrl; break; + case key_bottom: keyName = "end"; mod += mod_ctrl; break; +#ifdef __APPLE__ + case key_word_left: keyName = "left"; mod += mod_alt; break; + case key_word_right: keyName = "right"; mod += mod_alt; break; + case key_word_bsp: keyName = "backspace"; mod += mod_alt; break; + case key_word_del: keyName = "delete"; mod += mod_alt; break; +#else + case key_word_left: keyName = "left"; mod += mod_ctrl; break; + case key_word_right: keyName = "right"; mod += mod_ctrl; break; + case key_word_bsp: keyName = "backspace"; mod += mod_ctrl; break; + case key_word_del: keyName = "delete"; mod += mod_ctrl; break; +#endif + } + if(mod_contains(mod, mod_ctrl)) s += '^'; + if(mod_contains(mod, mod_alt)) s = '#'; + if(mod_contains(mod, mod_shift)) s += '$'; + } else { unsigned char c = key.c; - if(key.mod - mod_shift != key.mod) c = applyShift(c); + if(mod_contains(key.mod, mod_shift)) c = applyShift(c); else c = removeShift(c); - lbl.clear(); - if(key.mod - mod_ctrl != key.mod) lbl += '^'; - else if(key.mod - mod_alt != key.mod) lbl = '*'; - lbl += c; + if(mod_contains(key.mod, mod_ctrl)) s += '^'; + if(mod_contains(key.mod, mod_alt)) s = '#'; + if(c == ' ') s += "space"; + else s += c; } - if(isVisible()) draw(); + return s; } void cControl::attachKey(cKey key){ diff --git a/src/dialogxml/widgets/control.hpp b/src/dialogxml/widgets/control.hpp index 72acca81..bf9a3e9b 100644 --- a/src/dialogxml/widgets/control.hpp +++ b/src/dialogxml/widgets/control.hpp @@ -137,8 +137,6 @@ public: void attachKey(cKey key); /// Detach any currently assigned keyboard shortcut from the control. void detachKey(); - /// Set the control's text to a representation of its assigned keyboard shortcut. - void setTextToKey(); /// Check if the control has an assigned keyboard shortcut. /// @return true if a keyboard shortcut is assigned. bool hasKey(); @@ -146,6 +144,9 @@ public: /// @return the currently-assigned keyboard shortcut. /// @note You should first check that a shortcut is assigned using hasKey(). cKey getAttachedKey(); + /// Retrieve the control's current keyboard shortcut as a human-readable string. + /// @return the currently-assigned keyboard shortcut, or an empty string if none is assigned. + std::string getAttachedKeyDescription(); /// Attach an event handler to this control. /// @tparam t The type of event to attach. /// @param handler The event handler function or functor. Its signature depends on the event type.