From 33af6da5e1370bbdc9fa90bbb85073d2fd2a8f40 Mon Sep 17 00:00:00 2001 From: elexis Date: Wed, 4 Sep 2019 15:29:36 +0000 Subject: [PATCH] Implement JS support for GUI object "hotkey" setting missing from 6d8b9e33ef, refs #567, #2604, 9e499cdec5. Allows JS GUI to assign hotkeys to GUI objects from JS instead of XML. Differential Revision: https://code.wildfiregames.com/D2257 Comments By: nani Tested By: nani, Jenkins Tested on: clang, VS2015 This was SVN commit r22845. --- source/gui/CGUI.cpp | 30 ++++++++++++++++++++++-------- source/gui/CGUI.h | 8 ++++++-- source/gui/IGUIObject.cpp | 10 ++++++++++ source/gui/IGUIObject.h | 1 + 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index 28145cf9f5..2f8acddc33 100644 --- a/source/gui/CGUI.cpp +++ b/source/gui/CGUI.cpp @@ -466,6 +466,28 @@ void CGUI::SetFocusedObject(IGUIObject* pObject) } } +void CGUI::SetObjectHotkey(IGUIObject* pObject, const CStr& hotkeyTag) +{ + if (!hotkeyTag.empty()) + m_HotkeyObjects[hotkeyTag].push_back(pObject); +} + +void CGUI::UnsetObjectHotkey(IGUIObject* pObject, const CStr& hotkeyTag) +{ + if (hotkeyTag.empty()) + return; + + std::vector& assignment = m_HotkeyObjects[hotkeyTag]; + + assignment.erase( + std::remove_if( + assignment.begin(), + assignment.end(), + [&pObject](const IGUIObject* hotkeyObject) + { return pObject == hotkeyObject; }), + assignment.end()); +} + const SGUIScrollBarStyle* CGUI::GetScrollBarStyle(const CStr& style) const { std::map::const_iterator it = m_ScrollBarStyles.find(style); @@ -603,7 +625,6 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec ATTR(style); ATTR(type); ATTR(name); - ATTR(hotkey); ATTR(z); ATTR(on); ATTR(file); @@ -635,7 +656,6 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec bool ManuallySetZ = false; CStrW inclusionPath; - CStr hotkeyTag; for (XMBAttribute attr : attributes) { @@ -659,9 +679,6 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec continue; } - if (attr.Name == attr_hotkey) - hotkeyTag = attr.Value; - if (attr.Name == attr_z) ManuallySetZ = true; @@ -679,9 +696,6 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec ++m_InternalNameNumber; } - if (!hotkeyTag.empty()) - m_HotkeyObjects[hotkeyTag].push_back(object); - CStrW caption(Element.GetText().FromUTF8()); if (!caption.empty()) object->SetSettingFromString("caption", caption, false); diff --git a/source/gui/CGUI.h b/source/gui/CGUI.h index 334848b73a..bf40e8f330 100644 --- a/source/gui/CGUI.h +++ b/source/gui/CGUI.h @@ -147,6 +147,12 @@ public: */ void LoadXmlFile(const VfsPath& Filename, boost::unordered_set& Paths); + /** + * Allows the JS side to modify the hotkey setting assigned to a GUI object. + */ + void SetObjectHotkey(IGUIObject* pObject, const CStr& hotkeyTag); + void UnsetObjectHotkey(IGUIObject* pObject, const CStr& hotkeyTag); + /** * Return the object which is an ancestor of every other GUI object. */ @@ -625,8 +631,6 @@ private: * Map from hotkey names to objects that listen to the hotkey. * (This is an optimisation to avoid recursing over the whole GUI * tree every time a hotkey is pressed). - * Currently this is only set at load time - dynamic changes to an - * object's hotkey property will be ignored. */ std::map > m_HotkeyObjects; diff --git a/source/gui/IGUIObject.cpp b/source/gui/IGUIObject.cpp index 2ecf0d9f01..316db69aea 100644 --- a/source/gui/IGUIObject.cpp +++ b/source/gui/IGUIObject.cpp @@ -154,6 +154,7 @@ bool IGUIObject::SetSettingFromString(const CStr& Setting, const CStrW& Value, c template void IGUIObject::SetSetting(const CStr& Setting, T& Value, const bool SendMessage) { + PreSettingChange(Setting); static_cast* >(m_Settings[Setting])->m_pSetting = std::move(Value); SettingChanged(Setting, SendMessage); } @@ -161,10 +162,17 @@ void IGUIObject::SetSetting(const CStr& Setting, T& Value, const bool SendMessag template void IGUIObject::SetSetting(const CStr& Setting, const T& Value, const bool SendMessage) { + PreSettingChange(Setting); static_cast* >(m_Settings[Setting])->m_pSetting = Value; SettingChanged(Setting, SendMessage); } +void IGUIObject::PreSettingChange(const CStr& Setting) +{ + if (Setting == "hotkey") + m_pGUI.UnsetObjectHotkey(this, GetSetting(Setting)); +} + void IGUIObject::SettingChanged(const CStr& Setting, const bool SendMessage) { if (Setting == "size") @@ -178,6 +186,8 @@ void IGUIObject::SettingChanged(const CStr& Setting, const bool SendMessage) if (GetSetting(Setting)) RecurseObject(nullptr, &IGUIObject::ResetStates); } + else if (Setting == "hotkey") + m_pGUI.SetObjectHotkey(this, GetSetting(Setting)); if (SendMessage) { diff --git a/source/gui/IGUIObject.h b/source/gui/IGUIObject.h index 6c5d883eec..f829530c4c 100644 --- a/source/gui/IGUIObject.h +++ b/source/gui/IGUIObject.h @@ -428,6 +428,7 @@ private: /** * Updates some internal data depending on the setting changed. */ + void PreSettingChange(const CStr& Setting); void SettingChanged(const CStr& Setting, const bool SendMessage); /**