Index: binaries/data/mods/public/gui/reference/civinfo/CivInfoPage.js =================================================================== --- binaries/data/mods/public/gui/reference/civinfo/CivInfoPage.js +++ binaries/data/mods/public/gui/reference/civinfo/CivInfoPage.js @@ -87,7 +87,7 @@ { let tooltip_icon = ""; if (tooltip) - tooltip_icon = '[icon="iconInfo" tooltip="' + escapeQuotation(tooltip) + '" tooltip_style="civInfoTooltip"]'; + tooltip_icon = '[icon="iconInfo"]'; let description_text = ""; if (description) Index: source/gui/CGUI.cpp =================================================================== --- source/gui/CGUI.cpp +++ source/gui/CGUI.cpp @@ -441,8 +441,7 @@ { // If the style is not recognised (or an empty string) then ApplyStyle will // emit an error message. Thus we don't need to handle it here. - if (pObject->ApplyStyle(styleName)) - pObject->m_Style = styleName; + pObject->ApplyStyle(styleName); } void CGUI::UnsetObjectStyle(IGUIObject* pObject) @@ -895,10 +894,10 @@ if (object->m_Absolute) // If the object is absolute, we'll have to get the parent's Z buffered, // and add to that! - object->SetSetting("z", pParent->GetBufferedZ() + 10.f, false); + object->m_Z.Set(pParent->GetBufferedZ() + 10.f, false); else // If the object is relative, then we'll just store Z as "10" - object->SetSetting("z", 10.f, false); + object->m_Z.Set(10.f, false); } if (!AddObject(*pParent, *object)) Index: source/gui/CGUISetting.h =================================================================== --- source/gui/CGUISetting.h +++ source/gui/CGUISetting.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -20,6 +20,9 @@ #include "gui/ObjectBases/IGUIObject.h" +class IGUIObject; +class ScriptRequest; + /** * This setting interface allows GUI objects to call setting function functions without having to know the setting type. * This is fact is used for setting the value from a JS value or XML value (string) and when deleting the setting, @@ -29,69 +32,96 @@ { public: NONCOPYABLE(IGUISetting); + IGUISetting(const CStr& name, IGUIObject* owner); - IGUISetting() = default; + /** + * Parses the given string and assigns to the setting value. Used for parsing XML attributes. + */ + bool FromString(const CStrW& value, const bool sendMessage); + + /** + * Parses the given JS::Value using ScriptInterface::FromJSVal and assigns it to the setting data. + */ + bool FromJSVal(const ScriptRequest& rq, JS::HandleValue value, const bool sendMessage); + + /** + * Converts the setting data to a JS::Value using ScriptInterface::ToJSVal. + */ + virtual void ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue value) = 0; + +protected: + IGUISetting(IGUISetting&& o); virtual ~IGUISetting() = default; - /** - * Parses the given string and assigns to the setting value. Used for parsing XML attributes. - */ - virtual bool FromString(const CStrW& Value, const bool SendMessage) = 0; - - /** - * Parses the given JS::Value using ScriptInterface::FromJSVal and assigns it to the setting data. - */ - virtual bool FromJSVal(const ScriptRequest& rq, JS::HandleValue Value, const bool SendMessage) = 0; - - /** - * Converts the setting data to a JS::Value using ScriptInterface::ToJSVal. - */ - virtual void ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue Value) = 0; -}; - -template -class CGUISetting : public IGUISetting -{ -public: - NONCOPYABLE(CGUISetting); - - CGUISetting(IGUIObject& pObject, const CStr& Name, T& Value); - - /** - * Parses the given string and assigns to the setting value. Used for parsing XML attributes. - */ - bool FromString(const CStrW& Value, const bool SendMessage) override; - - /** - * Parses the given JS::Value using ScriptInterface::FromJSVal and assigns it to the setting data. - */ - bool FromJSVal(const ScriptRequest& rq, JS::HandleValue Value, const bool SendMessage) override; + virtual bool DoFromString(const CStrW& value) = 0; + virtual bool DoFromJSVal(const ScriptRequest& rq, JS::HandleValue value) = 0; /** - * Converts the setting data to a JS::Value using ScriptInterface::ToJSVal. + * Triggers the IGUIObject logic when a setting changes. + * This must be called by derived classes when something externally visible changes. */ - void ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue Value) override; + void OnSettingChange(const CStr& setting, bool sendMessage); /** - * These members are public because they are either unmodifiable or free to be modified. - * In particular it avoids the need for setter templates specialized depending on copiability. + * Return the name of the setting, from JS. */ + virtual CStr GetName() const = 0; /** * The object that stores this setting. */ IGUIObject& m_pObject; +}; + +/** + * Wraps a T. Makes sure the appropriate setting functions are called when modifying T, + * and likewise makes sure that JS/xml settings affect T appropriately, + * while being as transparent as possible to use from C++ code. + */ +template +class CGUISimpleSetting : public IGUISetting +{ +public: + template + CGUISimpleSetting(IGUIObject* pObject, const CStr& Name, Args&&... args) + : IGUISetting(Name, pObject), m_Name(Name), m_Setting(args...) + {} + NONCOPYABLE(CGUISimpleSetting); + MOVABLE(CGUISimpleSetting); + + operator T&() { return m_Setting; } + operator const T&() const { return m_Setting; } + + T* operator->() { return &m_Setting; } + const T* operator->() const { return &m_Setting; } /** - * Property name identifying the setting. + * Explicit getter for when that's more convenient than a cast. */ + T& Get() { return m_Setting; } + const T& Get() const { return m_Setting; } + + /** + * 'Uglified' operator=, so that SendMessage is explicit. + */ + void Set(T value, bool sendMessage) + { + m_Setting = std::move(value); + OnSettingChange(m_Name, sendMessage); + } + +protected: + virtual CStr GetName() const override + { + return m_Name; + } + + virtual bool DoFromString(const CStrW& value) override; + virtual bool DoFromJSVal(const ScriptRequest& rq, JS::HandleValue value) override; + virtual void ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue value) override; + const CStr m_Name; - - /** - * Holds a reference to the value of the setting. - * The setting value is stored in the member class to optimize for draw calls of that class. - */ - T& m_pSetting; + T m_Setting; }; #endif // INCLUDED_CGUISETTINGS Index: source/gui/CGUISetting.cpp =================================================================== --- source/gui/CGUISetting.cpp +++ source/gui/CGUISetting.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -22,67 +22,85 @@ #include "gui/CGUI.h" #include "ps/CLogger.h" -template +IGUISetting::IGUISetting(const CStr& name, IGUIObject* owner) : m_pObject(*owner) +{ + m_pObject.RegisterSetting(name, this); +} -CGUISetting::CGUISetting(IGUIObject& pObject, const CStr& Name, T& Value) - : m_pSetting(Value), m_Name(Name), m_pObject(pObject) +IGUISetting::IGUISetting(IGUISetting&& o) : m_pObject(o.m_pObject) { + m_pObject.ReregisterSetting(o.GetName(), this); } -template -bool CGUISetting::FromString(const CStrW& Value, const bool SendMessage) +bool IGUISetting::FromString(const CStrW& value, const bool sendMessage) +{ + m_pObject.PreSettingChange(GetName()); + + if (!DoFromString(value)) + return false; + + OnSettingChange(GetName(), sendMessage); + return true; +} + +/** + * Parses the given JS::Value using ScriptInterface::FromJSVal and assigns it to the setting data. + */ +bool IGUISetting::FromJSVal(const ScriptRequest& rq, JS::HandleValue value, const bool sendMessage) { - T settingValue; + m_pObject.PreSettingChange(GetName()); - if (!CGUI::ParseString(&m_pObject.GetGUI(), Value, settingValue)) + if (!DoFromJSVal(rq, value)) return false; - m_pObject.SetSetting(m_Name, settingValue, SendMessage); + OnSettingChange(GetName(), sendMessage); return true; +} + +void IGUISetting::OnSettingChange(const CStr& setting, bool sendMessage) +{ + m_pObject.SettingChanged(setting, sendMessage); +} + +template +bool CGUISimpleSetting::DoFromString(const CStrW& value) +{ + return CGUI::ParseString(&m_pObject.GetGUI(), value, m_Setting); }; template<> -bool CGUISetting::FromJSVal(const ScriptRequest& rq, JS::HandleValue Value, const bool SendMessage) +bool CGUISimpleSetting::DoFromJSVal(const ScriptRequest& rq, JS::HandleValue value) { - CGUIColor settingValue; - if (Value.isString()) + if (value.isString()) { CStr name; - if (!ScriptInterface::FromJSVal(rq, Value, name)) + if (!ScriptInterface::FromJSVal(rq, value, name)) return false; - if (!settingValue.ParseString(m_pObject.GetGUI(), name)) + if (!m_Setting.ParseString(m_pObject.GetGUI(), name)) { LOGERROR("Invalid color '%s'", name.c_str()); return false; } } - else if (!ScriptInterface::FromJSVal(rq, Value, settingValue)) - return false; - m_pObject.SetSetting(m_Name, settingValue, SendMessage); - return true; + return ScriptInterface::FromJSVal(rq, value, m_Setting); }; template -bool CGUISetting::FromJSVal(const ScriptRequest& rq, JS::HandleValue Value, const bool SendMessage) +bool CGUISimpleSetting::DoFromJSVal(const ScriptRequest& rq, JS::HandleValue value) { - T settingValue; - if (!ScriptInterface::FromJSVal(rq, Value, settingValue)) - return false; - - m_pObject.SetSetting(m_Name, settingValue, SendMessage); - return true; + return ScriptInterface::FromJSVal(rq, value, m_Setting); }; template -void CGUISetting::ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue Value) +void CGUISimpleSetting::ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue value) { - ScriptInterface::ToJSVal(rq, Value, m_pSetting); + ScriptInterface::ToJSVal(rq, value, m_Setting); }; #define TYPE(T) \ - template class CGUISetting; \ + template class CGUISimpleSetting; \ #include "gui/GUISettingTypes.h" #undef TYPE Index: source/gui/CGUIText.h =================================================================== --- source/gui/CGUIText.h +++ source/gui/CGUIText.h @@ -164,10 +164,11 @@ * can be changed by tags. * @param Width Width, 0 if no word-wrapping. * @param BufferZone space between text and edge, and space between text and images. + * @param Align Horizontal alignment (left / center / right). * @param pObject Optional parameter for error output. Used *only* if error parsing fails, * and we need to be able to output which object the error occurred in to aid the user. */ - CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& FontW, const float Width, const float BufferZone, const IGUIObject* pObject); + CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& FontW, const float Width, const float BufferZone, const EAlign align, const IGUIObject* pObject); /** * Draw this CGUIText object Index: source/gui/CGUIText.cpp =================================================================== --- source/gui/CGUIText.cpp +++ source/gui/CGUIText.cpp @@ -59,7 +59,7 @@ m_Indentation = Size.Width + BufferZone * 2; } -CGUIText::CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& FontW, const float Width, const float BufferZone, const IGUIObject* pObject) +CGUIText::CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& FontW, const float Width, const float BufferZone, const EAlign align, const IGUIObject* pObject) { if (string.m_Words.empty()) return; @@ -76,13 +76,6 @@ int pos_last_img = -1; // Position in the string where last img (either left or right) were encountered. // in order to avoid duplicate processing. - // get the alignment type for the control we are computing the text for since - // we are computing the horizontal alignment in this method in order to not have - // to run through the TextCalls a second time in the CalculateTextPosition method again - EAlign align = EAlign::LEFT; - if (pObject->SettingExists("text_align")) - align = pObject->GetSetting("text_align"); - // Go through string word by word for (int i = 0; i < static_cast(string.m_Words.size()) - 1; ++i) { Index: source/gui/GUITooltip.h =================================================================== --- source/gui/GUITooltip.h +++ source/gui/GUITooltip.h @@ -44,7 +44,6 @@ CStr m_PreviousTooltipName; CVector2D m_PreviousMousePos; double m_Time; - bool m_IsIconTooltip; }; #endif // INCLUDED_GUITOOLTIP Index: source/gui/GUITooltip.cpp =================================================================== --- source/gui/GUITooltip.cpp +++ source/gui/GUITooltip.cpp @@ -20,7 +20,7 @@ #include "GUITooltip.h" #include "gui/CGUI.h" -#include "gui/ObjectBases/IGUIObject.h" +#include "gui/ObjectTypes/CTooltip.h" #include "lib/timer.h" #include "ps/CLogger.h" @@ -83,30 +83,11 @@ bool GUITooltip::GetTooltip(IGUIObject* obj, CStr& style) { - if (obj && obj->SettingExists("_icon_tooltip_style") && obj->MouseOverIcon()) + if (obj && !obj->GetTooltip().empty()) { - style = obj->GetSetting("_icon_tooltip_style"); - if (!obj->GetSetting("_icon_tooltip").empty()) - { - if (style.empty()) - style = "default"; - m_IsIconTooltip = true; - return true; - } + style = obj->GetTooltipStyle().empty() ? "default" : obj->GetTooltipStyle(); + return true; } - - if (obj && obj->SettingExists("tooltip_style")) - { - style = obj->GetSetting("tooltip_style"); - if (!obj->GetSetting("tooltip").empty()) - { - if (style.empty()) - style = "default"; - m_IsIconTooltip = false; - return true; - } - } - return false; } @@ -118,29 +99,20 @@ return; // Must be a CTooltip* - IGUIObject* tooltipobj = pGUI.FindObjectByName("__tooltip_" + style); + CTooltip* tooltipobj = static_cast(pGUI.FindObjectByName("__tooltip_" + style)); if (!tooltipobj || !tooltipobj->SettingExists("use_object")) { LOGERROR("Cannot find tooltip named '%s'", style.c_str()); return; } - IGUIObject* usedobj; // object actually used to display the tooltip in + IGUIObject* usedobj; // object actually used to display the tooltip in. - const CStr& usedObjectName = tooltipobj->GetSetting("use_object"); + const CStr& usedObjectName = tooltipobj->GetUsedObject(); if (usedObjectName.empty()) { usedobj = tooltipobj; - - if (usedobj->SettingExists("_mousepos")) - { - usedobj->SetSetting("_mousepos", pos, true); - } - else - { - LOGERROR("Object '%s' used by tooltip '%s' isn't a tooltip object!", usedObjectName.c_str(), style.c_str()); - return; - } + tooltipobj->SetMousePos(pos); } else { @@ -154,7 +126,7 @@ if (usedobj->SettingExists("caption")) { - const CStrW& text = obj->GetSetting(m_IsIconTooltip ? "_icon_tooltip" : "tooltip"); + const CStrW& text = obj->GetTooltip(); usedobj->SetSettingFromString("caption", text, true); } else @@ -163,8 +135,7 @@ return; } - // Every IGUIObject has a "hidden" setting - usedobj->SetSetting("hidden", false, true); + usedobj->SetHidden(false); } void GUITooltip::HideTooltip(const CStr& style, CGUI& pGUI) @@ -173,14 +144,13 @@ return; // Must be a CTooltip* - IGUIObject* tooltipobj = pGUI.FindObjectByName("__tooltip_" + style); + CTooltip* tooltipobj = static_cast(pGUI.FindObjectByName("__tooltip_" + style)); if (!tooltipobj || !tooltipobj->SettingExists("use_object") || !tooltipobj->SettingExists("hide_object")) { LOGERROR("Cannot find tooltip named '%s' or it is not a tooltip", style.c_str()); return; } - - const CStr& usedObjectName = tooltipobj->GetSetting("use_object"); + const CStr& usedObjectName = tooltipobj->GetUsedObject(); if (!usedObjectName.empty()) { IGUIObject* usedobj = pGUI.FindObjectByName(usedObjectName); @@ -194,18 +164,17 @@ return; } - if (tooltipobj->GetSetting("hide_object")) - // Every IGUIObject has a "hidden" setting - usedobj->SetSetting("hidden", true, true); + if (tooltipobj->ShouldHideObject()) + usedobj->SetHidden(true); } else - tooltipobj->SetSetting("hidden", true, true); + tooltipobj->SetHidden(true); } static i32 GetTooltipDelay(const CStr& style, CGUI& pGUI) { // Must be a CTooltip* - IGUIObject* tooltipobj = pGUI.FindObjectByName("__tooltip_" + style); + CTooltip* tooltipobj = static_cast(pGUI.FindObjectByName("__tooltip_" + style)); if (!tooltipobj) { @@ -213,7 +182,7 @@ return 500; } - return tooltipobj->GetSetting("delay"); + return tooltipobj->GetTooltipDelay(); } void GUITooltip::Update(IGUIObject* Nearest, const CVector2D& MousePos, CGUI& GUI) @@ -271,41 +240,31 @@ break; case ST_SHOWING: - // Handle special case of icon tooltips - if (Nearest == m_PreviousObject && (!m_IsIconTooltip || Nearest->MouseOverIcon())) + // Mouse moved onto a new object + if (GetTooltip(Nearest, style)) { - // Still showing the same object's tooltip, but the text might have changed - if (GetTooltip(Nearest, style)) - ShowTooltip(Nearest, MousePos, style, GUI); - } - else - { - // Mouse moved onto a new object - if (GetTooltip(Nearest, style)) - { - CStr style_old; + CStr style_old; - // If we're displaying a tooltip with no delay, then we want to - // reset so that other object that should have delay can't - // "ride this tail", it have to wait. - // Notice that this doesn't apply to when you go from one delay=0 - // to another delay=0 - if (GetTooltip(m_PreviousObject, style_old) && GetTooltipDelay(style_old, GUI) == 0 && - GetTooltipDelay(style, GUI) != 0) - { - HideTooltip(m_PreviousTooltipName, GUI); - nextstate = ST_IN_MOTION; - } - else - { - // Hide old scrollbar - HideTooltip(m_PreviousTooltipName, GUI); - nextstate = ST_SHOWING; - } + // If we're displaying a tooltip with no delay, then we want to + // reset so that other object that should have delay can't + // "ride this tail", it have to wait. + // Notice that this doesn't apply to when you go from one delay=0 + // to another delay=0 + if (GetTooltip(m_PreviousObject, style_old) && GetTooltipDelay(style_old, GUI) == 0 && + GetTooltipDelay(style, GUI) != 0) + { + HideTooltip(m_PreviousTooltipName, GUI); + nextstate = ST_IN_MOTION; } else - nextstate = ST_COOLING; + { + // Hide old scrollbar + HideTooltip(m_PreviousTooltipName, GUI); + nextstate = ST_SHOWING; + } } + else + nextstate = ST_COOLING; break; case ST_COOLING: Index: source/gui/ObjectBases/IGUIButtonBehavior.h =================================================================== --- source/gui/ObjectBases/IGUIButtonBehavior.h +++ source/gui/ObjectBases/IGUIButtonBehavior.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -84,12 +84,11 @@ bool m_Pressed; bool m_PressedRight; - // Settings - CStrW m_SoundDisabled; - CStrW m_SoundEnter; - CStrW m_SoundLeave; - CStrW m_SoundPressed; - CStrW m_SoundReleased; + CGUISimpleSetting m_SoundDisabled; + CGUISimpleSetting m_SoundEnter; + CGUISimpleSetting m_SoundLeave; + CGUISimpleSetting m_SoundPressed; + CGUISimpleSetting m_SoundReleased; private: /** Index: source/gui/ObjectBases/IGUIButtonBehavior.cpp =================================================================== --- source/gui/ObjectBases/IGUIButtonBehavior.cpp +++ source/gui/ObjectBases/IGUIButtonBehavior.cpp @@ -33,17 +33,12 @@ : m_pObject(pObject), m_Pressed(), m_PressedRight(), - m_SoundDisabled(), - m_SoundEnter(), - m_SoundLeave(), - m_SoundPressed(), - m_SoundReleased() + m_SoundDisabled(&pObject, "sound_disabled"), + m_SoundEnter(&pObject, "sound_enter"), + m_SoundLeave(&pObject, "sound_leave"), + m_SoundPressed(&pObject, "sound_pressed"), + m_SoundReleased(&pObject, "sound_released") { - m_pObject.RegisterSetting("sound_disabled", m_SoundDisabled); - m_pObject.RegisterSetting("sound_enter", m_SoundEnter); - m_pObject.RegisterSetting("sound_leave", m_SoundLeave); - m_pObject.RegisterSetting("sound_pressed", m_SoundPressed); - m_pObject.RegisterSetting("sound_released", m_SoundReleased); } IGUIButtonBehavior::~IGUIButtonBehavior() Index: source/gui/ObjectBases/IGUIObject.h =================================================================== --- source/gui/ObjectBases/IGUIObject.h +++ source/gui/ObjectBases/IGUIObject.h @@ -25,6 +25,7 @@ #ifndef INCLUDED_IGUIOBJECT #define INCLUDED_IGUIOBJECT +#include "gui/CGUISetting.h" #include "gui/SettingTypes/CGUISize.h" #include "gui/SGUIMessage.h" #include "lib/input.h" // just for IN_PASS @@ -55,6 +56,9 @@ { friend class CGUI; + // For triggering message update handlers. + friend class IGUISetting; + // Allow getProperty to access things like GetParent() template friend class JSI_GUIProxy; @@ -123,14 +127,11 @@ //@{ /** - * Registers the given setting variables with the GUI object. + * Registers the given setting with the GUI object. * Enable XML and JS to modify the given variable. - * - * @param Type Setting type - * @param Name Setting reference name */ - template - void RegisterSetting(const CStr& Name, T& Value); + void RegisterSetting(const CStr& Name, IGUISetting* setting); + void ReregisterSetting(const CStr& Name, IGUISetting* setting); /** * Returns whether there is a setting with the given name registered. @@ -140,40 +141,14 @@ */ bool SettingExists(const CStr& Setting) const; - /** - * Get a mutable reference to the setting. - * If no such setting exists, an exception of type std::out_of_range is thrown. - * If the value is modified, there is no GUIM_SETTINGS_UPDATED message sent. - */ - template - T& GetSetting(const CStr& Setting); - - template - const T& GetSetting(const CStr& Setting) const; - /** * Set a setting by string, regardless of what type it is. * Used to parse setting values from XML files. * For example a CRect(10,10,20,20) is created from "10 10 20 20". - * Returns false if the conversion fails, otherwise true. + * @return false if the setting does not exist or the conversion fails, otherwise true. */ bool SetSettingFromString(const CStr& Setting, const CStrW& Value, const bool SendMessage); - /** - * Assigns the given value to the setting identified by the given name. - * Uses move semantics, so do not read from Value after this call. - * - * @param SendMessage If true, a GUIM_SETTINGS_UPDATED message will be broadcasted to all GUI objects. - */ - template - void SetSetting(const CStr& Setting, T& Value, const bool SendMessage); - - /** - * This variant will copy the value. - */ - template - void SetSetting(const CStr& Setting, const T& Value, const bool SendMessage); - /** * Returns whether this object is set to be hidden or ghost. */ @@ -184,11 +159,17 @@ */ bool IsHidden() const; + void SetHidden(bool hidden) { m_Hidden.Set(hidden, true); } + /** * Returns whether this object is set to be hidden or ghost. */ bool IsHiddenOrGhost() const; + const CStrW& GetTooltip() const { return m_Tooltip; } + + const CStr& GetTooltipStyle() const { return m_TooltipStyle; } + /** * Retrieves the configured sound filename from the given setting name and plays that once. */ @@ -543,18 +524,17 @@ // Cached JSObject representing this GUI object. std::unique_ptr m_JSObject; - // Cache references to settings for performance - bool m_Enabled; - bool m_Hidden; - CGUISize m_Size; - CStr m_Style; - CStr m_Hotkey; - float m_Z; - bool m_Absolute; - bool m_Ghost; - float m_AspectRatio; - CStrW m_Tooltip; - CStr m_TooltipStyle; + CGUISimpleSetting m_Enabled; + CGUISimpleSetting m_Hidden; + CGUISimpleSetting m_Size; + CGUISimpleSetting m_Style; + CGUISimpleSetting m_Hotkey; + CGUISimpleSetting m_Z; + CGUISimpleSetting m_Absolute; + CGUISimpleSetting m_Ghost; + CGUISimpleSetting m_AspectRatio; + CGUISimpleSetting m_Tooltip; + CGUISimpleSetting m_TooltipStyle; }; #endif // INCLUDED_IGUIOBJECT Index: source/gui/ObjectBases/IGUIObject.cpp =================================================================== --- source/gui/ObjectBases/IGUIObject.cpp +++ source/gui/ObjectBases/IGUIObject.cpp @@ -43,43 +43,22 @@ m_pParent(), m_MouseHovering(), m_LastClickTime(), - m_Enabled(), - m_Hidden(), - m_Size(), - m_Style(), - m_Hotkey(), - m_Z(), - m_Absolute(), - m_Ghost(), - m_AspectRatio(), - m_Tooltip(), - m_TooltipStyle() + m_Enabled(this, "enabled", true), + m_Hidden(this, "hidden", false), + m_Size(this, "size"), + m_Style(this, "style"), + m_Hotkey(this, "hotkey"), + m_Z(this, "z"), + m_Absolute(this, "absolute", true), + m_Ghost(this, "ghost", false), + m_AspectRatio(this, "aspectratio"), + m_Tooltip(this, "tooltip"), + m_TooltipStyle(this, "tooltip_style") { - RegisterSetting("enabled", m_Enabled); - RegisterSetting("hidden", m_Hidden); - RegisterSetting("size", m_Size); - RegisterSetting("style", m_Style); - RegisterSetting("hotkey", m_Hotkey); - RegisterSetting("z", m_Z); - RegisterSetting("absolute", m_Absolute); - RegisterSetting("ghost", m_Ghost); - RegisterSetting("aspectratio", m_AspectRatio); - RegisterSetting("tooltip", m_Tooltip); - RegisterSetting("tooltip_style", m_TooltipStyle); - - // Setup important defaults - // TODO: Should be in the default style? - SetSetting("hidden", false, true); - SetSetting("ghost", false, true); - SetSetting("enabled", true, true); - SetSetting("absolute", true, true); } IGUIObject::~IGUIObject() { - for (const std::pair& p : m_Settings) - delete p.second; - if (!m_ScriptHandlers.empty()) JS_RemoveExtraGCRootsTracer(m_pGUI.GetScriptInterface()->GetGeneralJSContext(), Trace, this); @@ -92,13 +71,20 @@ m_Children.push_back(&pChild); } -template -void IGUIObject::RegisterSetting(const CStr& Name, T& Value) +void IGUIObject::RegisterSetting(const CStr& Name, IGUISetting* setting) { if (SettingExists(Name)) LOGERROR("The setting '%s' already exists on the object '%s'!", Name.c_str(), GetPresentableName().c_str()); else - m_Settings.emplace(Name, new CGUISetting(*this, Name, Value)); + m_Settings.emplace(Name, setting); +} + +void IGUIObject::ReregisterSetting(const CStr& Name, IGUISetting* setting) +{ + if (!SettingExists(Name)) + LOGERROR("The setting '%s' must already exist on the object '%s'!", Name.c_str(), GetPresentableName().c_str()); + else + m_Settings.at(Name) = setting; } bool IGUIObject::SettingExists(const CStr& Setting) const @@ -106,18 +92,6 @@ return m_Settings.find(Setting) != m_Settings.end(); } -template -T& IGUIObject::GetSetting(const CStr& Setting) -{ - return static_cast* >(m_Settings.at(Setting))->m_pSetting; -} - -template -const T& IGUIObject::GetSetting(const CStr& Setting) const -{ - return static_cast* >(m_Settings.at(Setting))->m_pSetting; -} - bool IGUIObject::SetSettingFromString(const CStr& Setting, const CStrW& Value, const bool SendMessage) { const std::map::iterator it = m_Settings.find(Setting); @@ -129,26 +103,10 @@ return it->second->FromString(Value, SendMessage); } -template -void IGUIObject::SetSetting(const CStr& Setting, T& Value, const bool SendMessage) -{ - PreSettingChange(Setting); - static_cast* >(m_Settings.at(Setting))->m_pSetting = std::move(Value); - SettingChanged(Setting, SendMessage); -} - -template -void IGUIObject::SetSetting(const CStr& Setting, const T& Value, const bool SendMessage) -{ - PreSettingChange(Setting); - static_cast* >(m_Settings.at(Setting))->m_pSetting = Value; - SettingChanged(Setting, SendMessage); -} - void IGUIObject::PreSettingChange(const CStr& Setting) { if (Setting == "hotkey") - m_pGUI.UnsetObjectHotkey(this, GetSetting(Setting)); + m_pGUI.UnsetObjectHotkey(this, m_Hotkey); } void IGUIObject::SettingChanged(const CStr& Setting, const bool SendMessage) @@ -165,9 +123,9 @@ RecurseObject(nullptr, &IGUIObject::ResetStates); } else if (Setting == "hotkey") - m_pGUI.SetObjectHotkey(this, GetSetting(Setting)); + m_pGUI.SetObjectHotkey(this, m_Hotkey); else if (Setting == "style") - m_pGUI.SetObjectStyle(this, GetSetting(Setting)); + m_pGUI.SetObjectStyle(this, m_Style); if (SendMessage) { @@ -249,9 +207,9 @@ // use its cached size instead of the screen. Notice // it must have just been cached for it to work. if (!m_Absolute && m_pParent && !IsRootObject()) - m_CachedActualSize = m_Size.GetSize(m_pParent->m_CachedActualSize); + m_CachedActualSize = m_Size->GetSize(m_pParent->m_CachedActualSize); else - m_CachedActualSize = m_Size.GetSize(CRect(0.f, 0.f, g_xres / g_GuiScale, g_yres / g_GuiScale)); + m_CachedActualSize = m_Size->GetSize(CRect(0.f, 0.f, g_xres / g_GuiScale, g_yres / g_GuiScale)); // In a few cases, GUI objects have to resize to fill the screen // but maintain a constant aspect ratio. @@ -295,7 +253,7 @@ for (const std::pair& p : m_pGUI.GetStyle(StyleName).m_SettingsDefaults) { if (SettingExists(p.first)) - SetSettingFromString(p.first, p.second, true); + m_Settings.at(p.first)->FromString(p.second, true); else if (StyleName != "default") LOGWARNING("GUI object has no setting \"%s\", but the style \"%s\" defines it", p.first, StyleName.c_str()); } @@ -543,23 +501,3 @@ for (std::pair>& handler : m_ScriptHandlers) JS::TraceEdge(trc, &handler.second, "IGUIObject::m_ScriptHandlers"); } - -// Instantiate templated functions: -// These functions avoid copies by working with a reference and move semantics. -#define TYPE(T) \ - template void IGUIObject::RegisterSetting(const CStr& Name, T& Value); \ - template T& IGUIObject::GetSetting(const CStr& Setting); \ - template const T& IGUIObject::GetSetting(const CStr& Setting) const; \ - template void IGUIObject::SetSetting(const CStr& Setting, T& Value, const bool SendMessage); \ - -#include "gui/GUISettingTypes.h" -#undef TYPE - -// Copying functions - discouraged except for primitives. -#define TYPE(T) \ - template void IGUIObject::SetSetting(const CStr& Setting, const T& Value, const bool SendMessage); \ - -#define GUITYPE_IGNORE_NONCOPYABLE -#include "gui/GUISettingTypes.h" -#undef GUITYPE_IGNORE_NONCOPYABLE -#undef TYPE Index: source/gui/ObjectBases/IGUITextOwner.h =================================================================== --- source/gui/ObjectBases/IGUITextOwner.h +++ source/gui/ObjectBases/IGUITextOwner.h @@ -30,6 +30,8 @@ #ifndef INCLUDED_IGUITEXTOWNER #define INCLUDED_IGUITEXTOWNER +#include "gui/CGUISetting.h" +#include "gui/SettingTypes/EAlign.h" #include "maths/Rect.h" #include @@ -117,6 +119,9 @@ */ void CalculateTextPosition(CRect& ObjSize, CVector2D& TextPos, CGUIText& Text); + CGUISimpleSetting m_TextAlign; + CGUISimpleSetting m_TextVAlign; + private: /** * Reference to the IGUIObject. Index: source/gui/ObjectBases/IGUITextOwner.cpp =================================================================== --- source/gui/ObjectBases/IGUITextOwner.cpp +++ source/gui/ObjectBases/IGUITextOwner.cpp @@ -28,8 +28,10 @@ #include IGUITextOwner::IGUITextOwner(IGUIObject& pObject) - : m_pObject(pObject), - m_GeneratedTextsValid() +: m_pObject(pObject), + m_GeneratedTextsValid(), + m_TextAlign(&pObject, "text_align", EAlign::LEFT), + m_TextVAlign(&pObject, "text_valign", EVAlign::TOP) { } @@ -46,7 +48,7 @@ CGUIText& IGUITextOwner::AddText(const CGUIString& Text, const CStrW& Font, const float& Width, const float& BufferZone) { // Avoids a move constructor - m_GeneratedTexts.emplace_back(m_pObject.GetGUI(), Text, Font, Width, BufferZone, &m_pObject); + m_GeneratedTexts.emplace_back(m_pObject.GetGUI(), Text, Font, Width, BufferZone, m_TextAlign, &m_pObject); return m_GeneratedTexts.back(); } @@ -105,7 +107,7 @@ // loop through all of the TextCall objects again. TextPos.X = ObjSize.left; - switch (m_pObject.GetSetting("text_valign")) + switch (m_TextVAlign) { case EVAlign::TOP: TextPos.Y = ObjSize.top; Index: source/gui/ObjectTypes/CButton.h =================================================================== --- source/gui/ObjectTypes/CButton.h +++ source/gui/ObjectTypes/CButton.h @@ -77,19 +77,17 @@ virtual void CreateJSObject(); // Settings - float m_BufferZone; - CGUIString m_Caption; - CStrW m_Font; - CGUISpriteInstance m_Sprite; - CGUISpriteInstance m_SpriteOver; - CGUISpriteInstance m_SpritePressed; - CGUISpriteInstance m_SpriteDisabled; - EAlign m_TextAlign; - EVAlign m_TextVAlign; - CGUIColor m_TextColor; - CGUIColor m_TextColorOver; - CGUIColor m_TextColorPressed; - CGUIColor m_TextColorDisabled; + CGUISimpleSetting m_BufferZone; + CGUISimpleSetting m_Caption; + CGUISimpleSetting m_Font; + CGUISimpleSetting m_Sprite; + CGUISimpleSetting m_SpriteOver; + CGUISimpleSetting m_SpritePressed; + CGUISimpleSetting m_SpriteDisabled; + CGUISimpleSetting m_TextColor; + CGUISimpleSetting m_TextColorOver; + CGUISimpleSetting m_TextColorPressed; + CGUISimpleSetting m_TextColorDisabled; }; #endif // INCLUDED_CBUTTON Index: source/gui/ObjectTypes/CButton.cpp =================================================================== --- source/gui/ObjectTypes/CButton.cpp +++ source/gui/ObjectTypes/CButton.cpp @@ -27,34 +27,18 @@ : IGUIObject(pGUI), IGUIButtonBehavior(*static_cast(this)), IGUITextOwner(*static_cast(this)), - m_BufferZone(), - m_Caption(), - m_Font(), - m_Sprite(), - m_SpriteOver(), - m_SpritePressed(), - m_SpriteDisabled(), - m_TextAlign(), - m_TextVAlign(), - m_TextColor(), - m_TextColorOver(), - m_TextColorPressed(), - m_TextColorDisabled() + m_BufferZone(this, "buffer_zone"), + m_Caption(this, "caption"), + m_Font(this, "font"), + m_Sprite(this, "sprite"), + m_SpriteOver(this, "sprite_over"), + m_SpritePressed(this, "sprite_pressed"), + m_SpriteDisabled(this, "sprite_disabled"), + m_TextColor(this, "textcolor"), + m_TextColorOver(this, "textcolor_over"), + m_TextColorPressed(this, "textcolor_pressed"), + m_TextColorDisabled(this, "textcolor_disabled") { - RegisterSetting("buffer_zone", m_BufferZone); - RegisterSetting("caption", m_Caption); - RegisterSetting("font", m_Font); - RegisterSetting("sprite", m_Sprite); - RegisterSetting("sprite_over", m_SpriteOver); - RegisterSetting("sprite_pressed", m_SpritePressed); - RegisterSetting("sprite_disabled", m_SpriteDisabled); - RegisterSetting("text_align", m_TextAlign); - RegisterSetting("text_valign", m_TextVAlign); - RegisterSetting("textcolor", m_TextColor); - RegisterSetting("textcolor_over", m_TextColorOver); - RegisterSetting("textcolor_pressed", m_TextColorPressed); - RegisterSetting("textcolor_disabled", m_TextColorDisabled); - AddText(); } @@ -66,7 +50,7 @@ { ENSURE(m_GeneratedTexts.size() == 1); - m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, m_CachedActualSize.GetWidth(), m_BufferZone, this); + m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, m_CachedActualSize.GetWidth(), m_BufferZone, m_TextAlign, this); CalculateTextPosition(m_CachedActualSize, m_TextPos, m_GeneratedTexts[0]); } @@ -110,13 +94,13 @@ const CGUIColor& CButton::ChooseColor() { if (!m_Enabled) - return m_TextColorDisabled ? m_TextColorDisabled : m_TextColor; + return m_TextColorDisabled.Get() ? m_TextColorDisabled : m_TextColor; if (!m_MouseHovering) return m_TextColor; if (m_Pressed) - return m_TextColorPressed ? m_TextColorPressed : m_TextColor; + return m_TextColorPressed.Get() ? m_TextColorPressed : m_TextColor; - return m_TextColorOver ? m_TextColorOver : m_TextColor; + return m_TextColorOver.Get() ? m_TextColorOver : m_TextColor; } Index: source/gui/ObjectTypes/CChart.h =================================================================== --- source/gui/ObjectTypes/CChart.h +++ source/gui/ObjectTypes/CChart.h @@ -82,15 +82,14 @@ bool m_EqualX, m_EqualY; // Settings - CGUIColor m_AxisColor; - float m_AxisWidth; - float m_BufferZone; - CStrW m_Font; - CStrW m_FormatX; - CStrW m_FormatY; - CGUIList m_SeriesColor; - CGUISeries m_SeriesSetting; - EAlign m_TextAlign; + CGUISimpleSetting m_AxisColor; + CGUISimpleSetting m_AxisWidth; + CGUISimpleSetting m_BufferZone; + CGUISimpleSetting m_Font; + CGUISimpleSetting m_FormatX; + CGUISimpleSetting m_FormatY; + CGUISimpleSetting m_SeriesColor; + CGUISimpleSetting m_SeriesSetting; private: /** Index: source/gui/ObjectTypes/CChart.cpp =================================================================== --- source/gui/ObjectTypes/CChart.cpp +++ source/gui/ObjectTypes/CChart.cpp @@ -33,25 +33,15 @@ CChart::CChart(CGUI& pGUI) : IGUIObject(pGUI), IGUITextOwner(*static_cast(this)), - m_AxisColor(), - m_AxisWidth(), - m_BufferZone(), - m_Font(), - m_FormatX(), - m_FormatY(), - m_SeriesColor(), - m_SeriesSetting(), - m_TextAlign() + m_AxisColor(this, "axis_color"), + m_AxisWidth(this, "axis_width"), + m_BufferZone(this, "buffer_zone"), + m_Font(this, "font"), + m_FormatX(this, "format_x"), + m_FormatY(this, "format_y"), + m_SeriesColor(this, "series_color"), + m_SeriesSetting(this, "series") { - RegisterSetting("axis_color", m_AxisColor); - RegisterSetting("axis_width", m_AxisWidth); - RegisterSetting("buffer_zone", m_BufferZone); - RegisterSetting("font", m_Font); - RegisterSetting("format_x", m_FormatX); - RegisterSetting("format_y", m_FormatY); - RegisterSetting("series_color", m_SeriesColor); - RegisterSetting("series", m_SeriesSetting); - RegisterSetting("text_align", m_TextAlign); } CChart::~CChart() @@ -184,16 +174,16 @@ void CChart::UpdateSeries() { m_Series.clear(); - m_Series.resize(m_SeriesSetting.m_Series.size()); + m_Series.resize(m_SeriesSetting->m_Series.size()); - for (size_t i = 0; i < m_SeriesSetting.m_Series.size(); ++i) + for (size_t i = 0; i < m_SeriesSetting->m_Series.size(); ++i) { CChartData& data = m_Series[i]; - if (i < m_SeriesColor.m_Items.size() && !data.m_Color.ParseString(m_pGUI, m_SeriesColor.m_Items[i].GetOriginalString().ToUTF8(), 0)) - LOGWARNING("GUI: Error parsing 'series_color' (\"%s\")", utf8_from_wstring(m_SeriesColor.m_Items[i].GetOriginalString())); + if (i < m_SeriesColor->m_Items.size() && !data.m_Color.ParseString(m_pGUI, m_SeriesColor->m_Items[i].GetOriginalString().ToUTF8(), 0)) + LOGWARNING("GUI: Error parsing 'series_color' (\"%s\")", utf8_from_wstring(m_SeriesColor->m_Items[i].GetOriginalString())); - data.m_Points = m_SeriesSetting.m_Series[i]; + data.m_Points = m_SeriesSetting->m_Series[i]; } UpdateBounds(); Index: source/gui/ObjectTypes/CCheckBox.h =================================================================== --- source/gui/ObjectTypes/CCheckBox.h +++ source/gui/ObjectTypes/CCheckBox.h @@ -47,15 +47,15 @@ protected: // Settings - bool m_Checked; - CGUISpriteInstance m_SpriteUnchecked; - CGUISpriteInstance m_SpriteUncheckedOver; - CGUISpriteInstance m_SpriteUncheckedPressed; - CGUISpriteInstance m_SpriteUncheckedDisabled; - CGUISpriteInstance m_SpriteChecked; - CGUISpriteInstance m_SpriteCheckedOver; - CGUISpriteInstance m_SpriteCheckedPressed; - CGUISpriteInstance m_SpriteCheckedDisabled; + CGUISimpleSetting m_Checked; + CGUISimpleSetting m_SpriteUnchecked; + CGUISimpleSetting m_SpriteUncheckedOver; + CGUISimpleSetting m_SpriteUncheckedPressed; + CGUISimpleSetting m_SpriteUncheckedDisabled; + CGUISimpleSetting m_SpriteChecked; + CGUISimpleSetting m_SpriteCheckedOver; + CGUISimpleSetting m_SpriteCheckedPressed; + CGUISimpleSetting m_SpriteCheckedDisabled; }; #endif // INCLUDED_CCHECKBOX Index: source/gui/ObjectTypes/CCheckBox.cpp =================================================================== --- source/gui/ObjectTypes/CCheckBox.cpp +++ source/gui/ObjectTypes/CCheckBox.cpp @@ -24,25 +24,16 @@ CCheckBox::CCheckBox(CGUI& pGUI) : IGUIObject(pGUI), IGUIButtonBehavior(*static_cast(this)), - m_Checked(), - m_SpriteUnchecked(), - m_SpriteUncheckedOver(), - m_SpriteUncheckedPressed(), - m_SpriteUncheckedDisabled(), - m_SpriteChecked(), - m_SpriteCheckedOver(), - m_SpriteCheckedPressed(), - m_SpriteCheckedDisabled() + m_Checked(this, "checked"), + m_SpriteUnchecked(this, "sprite"), + m_SpriteUncheckedOver(this, "sprite_over"), + m_SpriteUncheckedPressed(this, "sprite_pressed"), + m_SpriteUncheckedDisabled(this, "sprite_disabled"), + m_SpriteChecked(this, "sprite2"), + m_SpriteCheckedOver(this, "sprite2_over"), + m_SpriteCheckedPressed(this, "sprite2_pressed"), + m_SpriteCheckedDisabled(this, "sprite2_disabled") { - RegisterSetting("checked", m_Checked), - RegisterSetting("sprite", m_SpriteUnchecked); - RegisterSetting("sprite_over", m_SpriteUncheckedOver); - RegisterSetting("sprite_pressed", m_SpriteUncheckedPressed); - RegisterSetting("sprite_disabled", m_SpriteUncheckedDisabled); - RegisterSetting("sprite2", m_SpriteChecked); - RegisterSetting("sprite2_over", m_SpriteCheckedOver); - RegisterSetting("sprite2_pressed", m_SpriteCheckedPressed); - RegisterSetting("sprite2_disabled", m_SpriteCheckedDisabled); } CCheckBox::~CCheckBox() @@ -64,7 +55,7 @@ { case GUIM_PRESSED: { - SetSetting("checked", !m_Checked, true); + m_Checked.Set(!m_Checked, true); break; } Index: source/gui/ObjectTypes/CDropDown.h =================================================================== --- source/gui/ObjectTypes/CDropDown.h +++ source/gui/ObjectTypes/CDropDown.h @@ -123,22 +123,21 @@ double m_TimeOfLastInput; // Settings - float m_ButtonWidth; - float m_DropDownSize; - float m_DropDownBuffer; - u32 m_MinimumVisibleItems; - CStrW m_SoundClosed; - CStrW m_SoundEnter; - CStrW m_SoundLeave; - CStrW m_SoundOpened; - CGUISpriteInstance m_SpriteDisabled; - CGUISpriteInstance m_SpriteList; - CGUISpriteInstance m_Sprite2; - CGUISpriteInstance m_Sprite2Over; - CGUISpriteInstance m_Sprite2Pressed; - CGUISpriteInstance m_Sprite2Disabled; - CGUIColor m_TextColorDisabled; - EVAlign m_TextVAlign; + CGUISimpleSetting m_ButtonWidth; + CGUISimpleSetting m_DropDownSize; + CGUISimpleSetting m_DropDownBuffer; + CGUISimpleSetting m_MinimumVisibleItems; + CGUISimpleSetting m_SoundClosed; + CGUISimpleSetting m_SoundEnter; + CGUISimpleSetting m_SoundLeave; + CGUISimpleSetting m_SoundOpened; + CGUISimpleSetting m_SpriteDisabled; + CGUISimpleSetting m_SpriteList; + CGUISimpleSetting m_Sprite2; + CGUISimpleSetting m_Sprite2Over; + CGUISimpleSetting m_Sprite2Pressed; + CGUISimpleSetting m_Sprite2Disabled; + CGUISimpleSetting m_TextColorDisabled; }; #endif // INCLUDED_CDROPDOWN Index: source/gui/ObjectTypes/CDropDown.cpp =================================================================== --- source/gui/ObjectTypes/CDropDown.cpp +++ source/gui/ObjectTypes/CDropDown.cpp @@ -32,46 +32,27 @@ m_Open(), m_HideScrollBar(), m_ElementHighlight(-1), - m_ButtonWidth(), - m_DropDownSize(), - m_DropDownBuffer(), - m_MinimumVisibleItems(), - m_SoundClosed(), - m_SoundEnter(), - m_SoundLeave(), - m_SoundOpened(), - m_SpriteDisabled(), - m_SpriteList(), - m_Sprite2(), - m_Sprite2Over(), - m_Sprite2Pressed(), - m_Sprite2Disabled(), - m_TextColorDisabled(), - m_TextVAlign() + m_ButtonWidth(this, "button_width"), + m_DropDownSize(this, "dropdown_size"), + m_DropDownBuffer(this, "dropdown_buffer"), + m_MinimumVisibleItems(this, "minimum_visible_items"), + m_SoundClosed(this, "sound_closed"), + m_SoundEnter(this, "sound_enter"), + m_SoundLeave(this, "sound_leave"), + m_SoundOpened(this, "sound_opened"), + // Setting "sprite" is registered by CList and used as the background + m_SpriteDisabled(this, "sprite_disabled"), + m_SpriteList(this, "sprite_list"), // Background of the drop down list + m_Sprite2(this, "sprite2"), // Button that sits to the right + m_Sprite2Over(this, "sprite2_over"), + m_Sprite2Pressed(this, "sprite2_pressed"), + m_Sprite2Disabled(this, "sprite2_disabled"), + m_TextColorDisabled(this, "textcolor_disabled") + // Add these in CList! And implement TODO + //RegisterSetting("textcolor_over"); + //RegisterSetting("textcolor_pressed"); { - RegisterSetting("button_width", m_ButtonWidth); - RegisterSetting("dropdown_size", m_DropDownSize); - RegisterSetting("dropdown_buffer", m_DropDownBuffer); - RegisterSetting("minimum_visible_items", m_MinimumVisibleItems); - RegisterSetting("sound_closed", m_SoundClosed); - RegisterSetting("sound_enter", m_SoundEnter); - RegisterSetting("sound_leave", m_SoundLeave); - RegisterSetting("sound_opened", m_SoundOpened); - // Setting "sprite" is registered by CList and used as the background - RegisterSetting("sprite_disabled", m_SpriteDisabled); - RegisterSetting("sprite_list", m_SpriteList); // Background of the drop down list - RegisterSetting("sprite2", m_Sprite2); // Button that sits to the right - RegisterSetting("sprite2_over", m_Sprite2Over); - RegisterSetting("sprite2_pressed", m_Sprite2Pressed); - RegisterSetting("sprite2_disabled", m_Sprite2Disabled); - RegisterSetting("textcolor_disabled", m_TextColorDisabled); - RegisterSetting("text_valign", m_TextVAlign); - // Add these in CList! And implement TODO - //RegisterSetting("textcolor_over"); - //RegisterSetting("textcolor_pressed"); - - // Scrollbar is forced to be true. - SetSetting("scrollbar", true, true); + m_ScrollBar.Set(true, true); } CDropDown::~CDropDown() @@ -128,7 +109,7 @@ CRect rect = GetListRect(); mouse.Y += scroll; int set = -1; - for (int i = 0; i < static_cast(m_List.m_Items.size()); ++i) + for (int i = 0; i < static_cast(m_List->m_Items.size()); ++i) { if (mouse.Y >= rect.top + m_ItemsYPositions[i] && mouse.Y < rect.top + m_ItemsYPositions[i+1] && @@ -178,7 +159,7 @@ if (!m_Open) { - if (m_List.m_Items.empty()) + if (m_List->m_Items.empty()) return; m_Open = true; @@ -228,7 +209,7 @@ break; ++m_ElementHighlight; - SetSetting("selected", m_ElementHighlight, true); + m_Selected.Set(m_ElementHighlight, true); break; } @@ -243,7 +224,7 @@ break; --m_ElementHighlight; - SetSetting("selected", m_ElementHighlight, true); + m_Selected.Set(m_ElementHighlight, true); break; } @@ -299,7 +280,7 @@ return IN_PASS; // Set current selected item to highlighted, before // then really processing these in CList::ManuallyHandleKeys() - SetSetting("selected", m_ElementHighlight, true); + m_Selected.Set(m_ElementHighlight, true); update_highlight = true; break; @@ -324,13 +305,13 @@ int closest = -1; int bestIndex = -1; int difference = 1250; - for (int i = 0; i < static_cast(m_List.m_Items.size()); ++i) + for (int i = 0; i < static_cast(m_List->m_Items.size()); ++i) { int indexOfDifference = 0; int diff = 0; for (size_t j = 0; j < m_InputBuffer.length(); ++j) { - diff = std::abs(static_cast(m_List.m_Items[i].GetRawString().LowerCase()[j]) - static_cast(m_InputBuffer[j])); + diff = std::abs(static_cast(m_List->m_Items[i].GetRawString().LowerCase()[j]) - static_cast(m_InputBuffer[j])); if (diff == 0) indexOfDifference = j+1; else @@ -346,7 +327,7 @@ // let's select the closest element. There should basically always be one. if (closest != -1) { - SetSetting("selected", closest, true); + m_Selected.Set(closest, true); update_highlight = true; GetScrollBar(0).SetPos(m_ItemsYPositions[closest] - 60); } @@ -453,15 +434,15 @@ if (!m_Enabled) { - m_pGUI.DrawSprite(m_Sprite2Disabled ? m_Sprite2Disabled : m_Sprite2, bz + 0.05f, rect); + m_pGUI.DrawSprite(m_Sprite2Disabled.Get() ? m_Sprite2Disabled : m_Sprite2, bz + 0.05f, rect); } else if (m_Open) { - m_pGUI.DrawSprite(m_Sprite2Pressed ? m_Sprite2Pressed : m_Sprite2, bz + 0.05f, rect); + m_pGUI.DrawSprite(m_Sprite2Pressed.Get() ? m_Sprite2Pressed : m_Sprite2, bz + 0.05f, rect); } else if (m_MouseHovering) { - m_pGUI.DrawSprite(m_Sprite2Over ? m_Sprite2Over : m_Sprite2, bz + 0.05f, rect); + m_pGUI.DrawSprite(m_Sprite2Over.Get() ? m_Sprite2Over : m_Sprite2, bz + 0.05f, rect); } else m_pGUI.DrawSprite(m_Sprite2, bz + 0.05f, rect); @@ -483,12 +464,12 @@ // TODO: drawScrollbar as an argument of DrawList? if (m_HideScrollBar) - m_ScrollBar = false; + m_ScrollBar.Set(false, false); DrawList(m_ElementHighlight, m_SpriteList, m_SpriteSelectArea, m_TextColor); if (m_HideScrollBar) - m_ScrollBar = old; + m_ScrollBar.Set(old, false); } } Index: source/gui/ObjectTypes/CHotkeyPicker.h =================================================================== --- source/gui/ObjectTypes/CHotkeyPicker.h +++ source/gui/ObjectTypes/CHotkeyPicker.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -59,7 +59,7 @@ void FireEvent(const CStr& event); // Time without changes until a "combination" event is sent. - float m_TimeToCombination; + CGUISimpleSetting m_TimeToCombination; // Time of the last registered key change. double m_LastKeyChange; Index: source/gui/ObjectTypes/CHotkeyPicker.cpp =================================================================== --- source/gui/ObjectTypes/CHotkeyPicker.cpp +++ source/gui/ObjectTypes/CHotkeyPicker.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -45,9 +45,8 @@ JSVAL_VECTOR(CHotkeyPicker::Key); -CHotkeyPicker::CHotkeyPicker(CGUI& pGUI) : IGUIObject(pGUI), m_TimeToCombination(1.f) +CHotkeyPicker::CHotkeyPicker(CGUI& pGUI) : IGUIObject(pGUI), m_TimeToCombination(this, "time_to_combination", 1.f) { - RegisterSetting("time_to_combination", m_TimeToCombination); // 8 keys at the same time is probably more than we'll ever need. m_KeysPressed.reserve(8); } Index: source/gui/ObjectTypes/CImage.h =================================================================== --- source/gui/ObjectTypes/CImage.h +++ source/gui/ObjectTypes/CImage.h @@ -45,8 +45,7 @@ */ virtual void Draw(); - // Settings - CGUISpriteInstance m_Sprite; + CGUISimpleSetting m_Sprite; }; #endif // INCLUDED_CIMAGE Index: source/gui/ObjectTypes/CImage.cpp =================================================================== --- source/gui/ObjectTypes/CImage.cpp +++ source/gui/ObjectTypes/CImage.cpp @@ -23,9 +23,8 @@ CImage::CImage(CGUI& pGUI) : IGUIObject(pGUI), - m_Sprite() + m_Sprite(this, "sprite") { - RegisterSetting("sprite", m_Sprite); } CImage::~CImage() Index: source/gui/ObjectTypes/CInput.h =================================================================== --- source/gui/ObjectTypes/CInput.h +++ source/gui/ObjectTypes/CInput.h @@ -216,24 +216,23 @@ static const CStr EventNamePress; static const CStr EventNameTab; - // Settings - i32 m_BufferPosition; - float m_BufferZone; - CStrW m_Caption; - CGUIString m_PlaceholderText; - CStrW m_Font; - CStrW m_MaskChar; - bool m_Mask; - i32 m_MaxLength; - bool m_MultiLine; - bool m_Readonly; - bool m_ScrollBar; - CStr m_ScrollBarStyle; - CGUISpriteInstance m_Sprite; - CGUISpriteInstance m_SpriteSelectArea; - CGUIColor m_TextColor; - CGUIColor m_TextColorSelected; - CGUIColor m_PlaceholderColor; + CGUISimpleSetting m_BufferPosition; + CGUISimpleSetting m_BufferZone; + CGUISimpleSetting m_Caption; + CGUISimpleSetting m_PlaceholderText; + CGUISimpleSetting m_Font; + CGUISimpleSetting m_MaskChar; + CGUISimpleSetting m_Mask; + CGUISimpleSetting m_MaxLength; + CGUISimpleSetting m_MultiLine; + CGUISimpleSetting m_Readonly; + CGUISimpleSetting m_ScrollBar; + CGUISimpleSetting m_ScrollBarStyle; + CGUISimpleSetting m_Sprite; + CGUISimpleSetting m_SpriteSelectArea; + CGUISimpleSetting m_TextColor; + CGUISimpleSetting m_TextColorSelected; + CGUISimpleSetting m_PlaceholderColor; }; #endif // INCLUDED_CINPUT Index: source/gui/ObjectTypes/CInput.cpp =================================================================== --- source/gui/ObjectTypes/CInput.cpp +++ source/gui/ObjectTypes/CInput.cpp @@ -56,40 +56,24 @@ m_iComposedLength(), m_iComposedPos(), m_iInsertPos(), - m_BufferPosition(), - m_BufferZone(), - m_Caption(), - m_Font(), - m_MaskChar(), - m_Mask(), - m_MaxLength(), - m_MultiLine(), - m_Readonly(), - m_ScrollBar(), - m_ScrollBarStyle(), - m_Sprite(), - m_SpriteSelectArea(), - m_TextColor(), - m_TextColorSelected() + m_BufferPosition(this, "buffer_position"), + m_BufferZone(this, "buffer_zone"), + m_Caption(this, "caption"), + m_Font(this, "font"), + m_MaskChar(this, "mask_char"), + m_Mask(this, "mask"), + m_MaxLength(this, "max_length"), + m_MultiLine(this, "multiline"), + m_Readonly(this, "readonly"), + m_ScrollBar(this, "scrollbar"), + m_ScrollBarStyle(this, "scrollbar_style"), + m_Sprite(this, "sprite"), + m_SpriteSelectArea(this, "sprite_selectarea"), + m_TextColor(this, "textcolor"), + m_TextColorSelected(this, "textcolor_selected"), + m_PlaceholderText(this, "placeholder_text"), + m_PlaceholderColor(this, "placeholder_color") { - RegisterSetting("buffer_position", m_BufferPosition); - RegisterSetting("buffer_zone", m_BufferZone); - RegisterSetting("caption", m_Caption); - RegisterSetting("font", m_Font); - RegisterSetting("mask_char", m_MaskChar); - RegisterSetting("mask", m_Mask); - RegisterSetting("max_length", m_MaxLength); - RegisterSetting("multiline", m_MultiLine); - RegisterSetting("readonly", m_Readonly); - RegisterSetting("scrollbar", m_ScrollBar); - RegisterSetting("scrollbar_style", m_ScrollBarStyle); - RegisterSetting("sprite", m_Sprite); - RegisterSetting("sprite_selectarea", m_SpriteSelectArea); - RegisterSetting("textcolor", m_TextColor); - RegisterSetting("textcolor_selected", m_TextColorSelected); - RegisterSetting("placeholder_text", m_PlaceholderText); - RegisterSetting("placeholder_color", m_PlaceholderColor); - CFG_GET_VAL("gui.cursorblinkrate", m_CursorBlinkRate); CGUIScrollBarVertical* bar = new CGUIScrollBarVertical(pGUI); @@ -103,12 +87,12 @@ void CInput::UpdateBufferPositionSetting() { - SetSetting("buffer_position", m_iBufferPos, false); + m_BufferPosition.Set(m_iBufferPos, false); } void CInput::ClearComposedText() { - m_Caption.erase(m_iInsertPos, m_iComposedLength); + m_Caption->erase(m_iInsertPos, m_iComposedLength); m_iBufferPos = m_iInsertPos; UpdateBufferPositionSetting(); m_iComposedLength = 0; @@ -139,7 +123,7 @@ std::wstring text = wstring_from_utf8(ev->ev.text.text); // Check max length - if (m_MaxLength != 0 && m_Caption.length() + text.length() > static_cast(m_MaxLength)) + if (m_MaxLength != 0 && m_Caption->length() + text.length() > static_cast(m_MaxLength)) return IN_HANDLED; m_WantedX = 0.0f; @@ -153,10 +137,10 @@ m_ComposingText = false; } - if (m_iBufferPos == static_cast(m_Caption.length())) - m_Caption.append(text); + if (m_iBufferPos == static_cast(m_Caption->length())) + m_Caption->append(text); else - m_Caption.insert(m_iBufferPos, text); + m_Caption->insert(m_iBufferPos, text); UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1); @@ -197,7 +181,7 @@ m_ComposingText = ev->ev.edit.start != 0 || rawLength != 0; if (m_ComposingText) { - m_Caption.insert(m_iInsertPos, wtext); + m_Caption->insert(m_iInsertPos, wtext); // The text buffer is limited to SDL_TEXTEDITINGEVENT_TEXT_SIZE bytes, yet start // increases without limit, so don't let it advance beyond the composed text length @@ -282,15 +266,15 @@ { m_iBufferPos_Tail = -1; - if (m_Caption.empty() || m_iBufferPos == 0) + if (m_Caption->empty() || m_iBufferPos == 0) break; - if (m_iBufferPos == static_cast(m_Caption.length())) - m_Caption = m_Caption.Left(static_cast(m_Caption.length()) - 1); + if (m_iBufferPos == static_cast(m_Caption->length())) + m_Caption.Get() = m_Caption->Left(static_cast(m_Caption->length()) - 1); else - m_Caption = - m_Caption.Left(m_iBufferPos - 1) + - m_Caption.Right(static_cast(m_Caption.length()) - m_iBufferPos); + m_Caption.Get() = + m_Caption->Left(m_iBufferPos - 1) + + m_Caption->Right(static_cast(m_Caption->length()) - m_iBufferPos); --m_iBufferPos; @@ -309,12 +293,12 @@ DeleteCurSelection(); else { - if (m_Caption.empty() || m_iBufferPos == static_cast(m_Caption.length())) + if (m_Caption->empty() || m_iBufferPos == static_cast(m_Caption->length())) break; - m_Caption = - m_Caption.Left(m_iBufferPos) + - m_Caption.Right(static_cast(m_Caption.length()) - (m_iBufferPos + 1)); + m_Caption.Get() = + m_Caption->Left(m_iBufferPos) + + m_Caption->Right(static_cast(m_Caption->length()) - (m_iBufferPos + 1)); UpdateText(m_iBufferPos, m_iBufferPos + 1, m_iBufferPos); } @@ -344,7 +328,7 @@ return; // Check max length - if (m_MaxLength != 0 && m_Caption.length() >= static_cast(m_MaxLength)) + if (m_MaxLength != 0 && m_Caption->length() >= static_cast(m_MaxLength)) break; m_WantedX = 0.0f; @@ -353,12 +337,12 @@ DeleteCurSelection(); m_iBufferPos_Tail = -1; - if (m_iBufferPos == static_cast(m_Caption.length())) - m_Caption += cooked; + if (m_iBufferPos == static_cast(m_Caption->length())) + m_Caption.Get() += cooked; else - m_Caption = - m_Caption.Left(m_iBufferPos) + cooked + - m_Caption.Right(static_cast(m_Caption.length()) - m_iBufferPos); + m_Caption.Get() = + m_Caption->Left(m_iBufferPos) + cooked + + m_Caption->Right(static_cast(m_Caption->length()) - m_iBufferPos); UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos + 1); @@ -411,7 +395,7 @@ m_iBufferPos_Tail = m_iBufferPos; } - m_iBufferPos = static_cast(m_Caption.length()); + m_iBufferPos = static_cast(m_Caption->length()); m_WantedX = 0.0f; UpdateAutoScroll(); @@ -474,7 +458,7 @@ else if (!SelectingText()) m_iBufferPos_Tail = m_iBufferPos; - if (m_iBufferPos < static_cast(m_Caption.length())) + if (m_iBufferPos < static_cast(m_Caption->length())) ++m_iBufferPos; } else @@ -607,7 +591,7 @@ void CInput::SetupGeneratedPlaceholderText() { - m_GeneratedPlaceholderText = CGUIText(m_pGUI, m_PlaceholderText, m_Font, 0, m_BufferZone, this); + m_GeneratedPlaceholderText = CGUIText(m_pGUI, m_PlaceholderText, m_Font, 0, m_BufferZone, EAlign::LEFT, this); m_GeneratedPlaceholderTextValid = true; } @@ -632,18 +616,18 @@ SDL_free(utf8_text); // Check max length - if (m_MaxLength != 0 && m_Caption.length() + text.length() > static_cast(m_MaxLength)) - text = text.substr(0, static_cast(m_MaxLength) - m_Caption.length()); + if (m_MaxLength != 0 && m_Caption->length() + text.length() > static_cast(m_MaxLength)) + text = text.substr(0, static_cast(m_MaxLength) - m_Caption->length()); if (SelectingText()) DeleteCurSelection(); - if (m_iBufferPos == static_cast(m_Caption.length())) - m_Caption += text; + if (m_iBufferPos == static_cast(m_Caption->length())) + m_Caption.Get() += text; else - m_Caption = - m_Caption.Left(m_iBufferPos) + text + - m_Caption.Right(static_cast(m_Caption.length()) - m_iBufferPos); + m_Caption.Get() = + m_Caption->Left(m_iBufferPos) + text + + m_Caption->Right(static_cast(m_Caption->length()) - m_iBufferPos); UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1); @@ -678,7 +662,7 @@ virtualTo = m_iBufferPos; } - CStrW text = m_Caption.Left(virtualTo).Right(virtualTo - virtualFrom); + CStrW text = m_Caption->Left(virtualTo).Right(virtualTo - virtualFrom); SDL_SetClipboardText(text.ToUTF8().c_str()); @@ -702,10 +686,10 @@ if (SelectingText()) DeleteCurSelection(); - if (!m_Caption.empty() && m_iBufferPos != 0) + if (!m_Caption->empty() && m_iBufferPos != 0) { m_iBufferPos_Tail = m_iBufferPos; - CStrW searchString = m_Caption.Left(m_iBufferPos); + CStrW searchString = m_Caption->Left(m_iBufferPos); // If we are starting in whitespace, adjust position until we get a non whitespace while (m_iBufferPos > 0) @@ -748,22 +732,22 @@ if (SelectingText()) DeleteCurSelection(); - if (!m_Caption.empty() && m_iBufferPos < static_cast(m_Caption.length())) + if (!m_Caption->empty() && m_iBufferPos < static_cast(m_Caption->length())) { // Delete the word to the right of the cursor m_iBufferPos_Tail = m_iBufferPos; // Delete chars to the right unit we hit whitespace - while (++m_iBufferPos < static_cast(m_Caption.length())) + while (++m_iBufferPos < static_cast(m_Caption->length())) { - if (iswspace(m_Caption[m_iBufferPos]) || iswpunct(m_Caption[m_iBufferPos])) + if (iswspace(m_Caption.Get()[m_iBufferPos]) || iswpunct(m_Caption.Get()[m_iBufferPos])) break; } // Eliminate any whitespace behind the word we just deleted - while (m_iBufferPos < static_cast(m_Caption.length())) + while (m_iBufferPos < static_cast(m_Caption->length())) { - if (!iswspace(m_Caption[m_iBufferPos])) + if (!iswspace(m_Caption.Get()[m_iBufferPos])) break; ++m_iBufferPos; @@ -786,9 +770,9 @@ else if (!SelectingText()) m_iBufferPos_Tail = m_iBufferPos; - if (!m_Caption.empty() && m_iBufferPos != 0) + if (!m_Caption->empty() && m_iBufferPos != 0) { - CStrW searchString = m_Caption.Left(m_iBufferPos); + CStrW searchString = m_Caption->Left(m_iBufferPos); // If we are starting in whitespace, adjust position until we get a non whitespace while (m_iBufferPos > 0) @@ -839,19 +823,19 @@ else if (!SelectingText()) m_iBufferPos_Tail = m_iBufferPos; - if (!m_Caption.empty() && m_iBufferPos < static_cast(m_Caption.length())) + if (!m_Caption->empty() && m_iBufferPos < static_cast(m_Caption->length())) { // Select chars to the right until we hit whitespace - while (++m_iBufferPos < static_cast(m_Caption.length())) + while (++m_iBufferPos < static_cast(m_Caption->length())) { - if (iswspace(m_Caption[m_iBufferPos]) || iswpunct(m_Caption[m_iBufferPos])) + if (iswspace(m_Caption.Get()[m_iBufferPos]) || iswpunct(m_Caption.Get()[m_iBufferPos])) break; } // Also select any whitespace following the word we just selected - while (m_iBufferPos < static_cast(m_Caption.length())) + while (m_iBufferPos < static_cast(m_Caption->length())) { - if (!iswspace(m_Caption[m_iBufferPos])) + if (!iswspace(m_Caption.Get()[m_iBufferPos])) break; ++m_iBufferPos; @@ -984,20 +968,20 @@ if (m_ComposingText) break; - if (m_Caption.empty()) + if (m_Caption->empty()) break; m_iBufferPos = m_iBufferPos_Tail = GetMouseHoveringTextPosition(); - if (m_iBufferPos >= (int)m_Caption.length()) - m_iBufferPos = m_iBufferPos_Tail = m_Caption.length() - 1; + if (m_iBufferPos >= (int)m_Caption->length()) + m_iBufferPos = m_iBufferPos_Tail = m_Caption->length() - 1; // See if we are clicking over whitespace - if (iswspace(m_Caption[m_iBufferPos])) + if (iswspace(m_Caption.Get()[m_iBufferPos])) { // see if we are in a section of whitespace greater than one character - if ((m_iBufferPos + 1 < (int) m_Caption.length() && iswspace(m_Caption[m_iBufferPos + 1])) || - (m_iBufferPos - 1 > 0 && iswspace(m_Caption[m_iBufferPos - 1]))) + if ((m_iBufferPos + 1 < (int) m_Caption->length() && iswspace(m_Caption.Get()[m_iBufferPos + 1])) || + (m_iBufferPos - 1 > 0 && iswspace(m_Caption.Get()[m_iBufferPos - 1]))) { // // We are clicking in an area with more than one whitespace character @@ -1007,7 +991,7 @@ // skip the whitespace while (m_iBufferPos > 0) { - if (!iswspace(m_Caption[m_iBufferPos - 1])) + if (!iswspace(m_Caption.Get()[m_iBufferPos - 1])) break; m_iBufferPos--; @@ -1015,52 +999,52 @@ // now go until we hit white space or punctuation while (m_iBufferPos > 0) { - if (iswspace(m_Caption[m_iBufferPos - 1])) + if (iswspace(m_Caption.Get()[m_iBufferPos - 1])) break; m_iBufferPos--; - if (iswpunct(m_Caption[m_iBufferPos])) + if (iswpunct(m_Caption.Get()[m_iBufferPos])) break; } // [2] Then the right // go right until we are not in whitespace - while (++m_iBufferPos_Tail < static_cast(m_Caption.length())) + while (++m_iBufferPos_Tail < static_cast(m_Caption->length())) { - if (!iswspace(m_Caption[m_iBufferPos_Tail])) + if (!iswspace(m_Caption.Get()[m_iBufferPos_Tail])) break; } - if (m_iBufferPos_Tail == static_cast(m_Caption.length())) + if (m_iBufferPos_Tail == static_cast(m_Caption->length())) break; // now go to the right until we hit whitespace or punctuation - while (++m_iBufferPos_Tail < static_cast(m_Caption.length())) + while (++m_iBufferPos_Tail < static_cast(m_Caption->length())) { - if (iswspace(m_Caption[m_iBufferPos_Tail]) || iswpunct(m_Caption[m_iBufferPos_Tail])) + if (iswspace(m_Caption.Get()[m_iBufferPos_Tail]) || iswpunct(m_Caption.Get()[m_iBufferPos_Tail])) break; } } else { // single whitespace so select word to the right - while (++m_iBufferPos_Tail < static_cast(m_Caption.length())) + while (++m_iBufferPos_Tail < static_cast(m_Caption->length())) { - if (!iswspace(m_Caption[m_iBufferPos_Tail])) + if (!iswspace(m_Caption.Get()[m_iBufferPos_Tail])) break; } - if (m_iBufferPos_Tail == static_cast(m_Caption.length())) + if (m_iBufferPos_Tail == static_cast(m_Caption->length())) break; // Don't include the leading whitespace m_iBufferPos = m_iBufferPos_Tail; // now go to the right until we hit whitespace or punctuation - while (++m_iBufferPos_Tail < static_cast(m_Caption.length())) + while (++m_iBufferPos_Tail < static_cast(m_Caption->length())) { - if (iswspace(m_Caption[m_iBufferPos_Tail]) || iswpunct(m_Caption[m_iBufferPos_Tail])) + if (iswspace(m_Caption.Get()[m_iBufferPos_Tail]) || iswpunct(m_Caption.Get()[m_iBufferPos_Tail])) break; } } @@ -1071,17 +1055,17 @@ // go until we hit white space or punctuation while (m_iBufferPos > 0) { - if (iswspace(m_Caption[m_iBufferPos - 1])) + if (iswspace(m_Caption.Get()[m_iBufferPos - 1])) break; m_iBufferPos--; - if (iswpunct(m_Caption[m_iBufferPos])) + if (iswpunct(m_Caption.Get()[m_iBufferPos])) break; } // go to the right until we hit whitespace or punctuation - while (++m_iBufferPos_Tail < static_cast(m_Caption.length())) - if (iswspace(m_Caption[m_iBufferPos_Tail]) || iswpunct(m_Caption[m_iBufferPos_Tail])) + while (++m_iBufferPos_Tail < static_cast(m_Caption->length())) + if (iswspace(m_Caption.Get()[m_iBufferPos_Tail]) || iswpunct(m_Caption.Get()[m_iBufferPos_Tail])) break; } UpdateAutoScroll(); @@ -1206,11 +1190,11 @@ if (m_ScrollBar && m_MultiLine) IGUIScrollBarOwner::Draw(); - CStrIntern font_name(m_Font.ToUTF8()); + CStrIntern font_name(m_Font->ToUTF8()); wchar_t mask_char = L'*'; - if (m_Mask && m_MaskChar.length() > 0) - mask_char = m_MaskChar[0]; + if (m_Mask && m_MaskChar->length() > 0) + mask_char = m_MaskChar.Get()[0]; m_pGUI.DrawSprite(m_Sprite, bz, m_CachedActualSize); @@ -1407,7 +1391,7 @@ if (i < (int)it->m_ListOfX.size()) { if (!m_Mask) - x_pointer += font.GetCharacterWidth(m_Caption[it->m_ListStart + i]); + x_pointer += font.GetCharacterWidth(m_Caption.Get()[it->m_ListStart + i]); else x_pointer += font.GetCharacterWidth(mask_char); } @@ -1493,7 +1477,7 @@ if (i != (int)it->m_ListOfX.size()) { if (!m_Mask) - textRenderer.PrintfAdvance(L"%lc", m_Caption[it->m_ListStart + i]); + textRenderer.PrintfAdvance(L"%lc", m_Caption.Get()[it->m_ListStart + i]); else textRenderer.PrintfAdvance(L"%lc", mask_char); } @@ -1527,7 +1511,7 @@ tech->EndPass(); - if (m_Caption.empty() && !m_PlaceholderText.GetRawString().empty()) + if (m_Caption->empty() && !m_PlaceholderText->GetRawString().empty()) DrawPlaceholderText(bz, cliparea); } @@ -1541,18 +1525,18 @@ void CInput::UpdateText(int from, int to_before, int to_after) { - if (m_MaxLength != 0 && m_Caption.length() > static_cast(m_MaxLength)) - m_Caption = m_Caption.substr(0, m_MaxLength); + if (m_MaxLength != 0 && m_Caption->length() > static_cast(m_MaxLength)) + m_Caption.Get() = m_Caption->substr(0, m_MaxLength); - CStrIntern font_name(m_Font.ToUTF8()); + CStrIntern font_name(m_Font->ToUTF8()); wchar_t mask_char = L'*'; - if (m_Mask && m_MaskChar.length() > 0) - mask_char = m_MaskChar[0]; + if (m_Mask && m_MaskChar->length() > 0) + mask_char = m_MaskChar.Get()[0]; // Ensure positions are valid after caption changes - m_iBufferPos = std::min(m_iBufferPos, static_cast(m_Caption.size())); - m_iBufferPos_Tail = std::min(m_iBufferPos_Tail, static_cast(m_Caption.size())); + m_iBufferPos = std::min(m_iBufferPos, static_cast(m_Caption->size())); + m_iBufferPos_Tail = std::min(m_iBufferPos_Tail, static_cast(m_Caption->size())); UpdateBufferPositionSetting(); if (font_name.empty()) @@ -1568,7 +1552,7 @@ int to = 0; // make sure it's initialized if (to_before == -1) - to = static_cast(m_Caption.length()); + to = static_cast(m_Caption->length()); CFontMetrics font(font_name); @@ -1671,7 +1655,7 @@ if (destroy_row_to != m_CharacterPositions.end()) to = destroy_row_to->m_ListStart; // notice it will iterate [from, to), so it will never reach to. else - to = static_cast(m_Caption.length()); + to = static_cast(m_Caption->length()); // Setup the first row @@ -1698,7 +1682,7 @@ check_point_row_start += delta; check_point_row_end += delta; - if (to != static_cast(m_Caption.length())) + if (to != static_cast(m_Caption->length())) to += delta; } } @@ -1711,9 +1695,9 @@ for (int i = from; i < to; ++i) { - if (m_Caption[i] == L'\n' && m_MultiLine) + if (m_Caption.Get()[i] == L'\n' && m_MultiLine) { - if (i == to-1 && to != static_cast(m_Caption.length())) + if (i == to-1 && to != static_cast(m_Caption->length())) break; // it will be added outside current_line = m_CharacterPositions.insert(current_line, row); @@ -1726,12 +1710,12 @@ } else { - if (m_Caption[i] == L' '/* || TODO Gee (2004-10-13): the '-' disappears, fix. - m_Caption[i] == L'-'*/) + if (m_Caption.Get()[i] == L' '/* || TODO Gee (2004-10-13): the '-' disappears, fix. + m_Caption.Get()[i] == L'-'*/) last_word_started = i+1; if (!m_Mask) - x_pos += font.GetCharacterWidth(m_Caption[i]); + x_pos += font.GetCharacterWidth(m_Caption.Get()[i]); else x_pos += font.GetCharacterWidth(mask_char); @@ -1856,7 +1840,7 @@ if (destroy_row_to != m_CharacterPositions.end()) to = destroy_row_to->m_ListStart; // notice it will iterate [from, to[, so it will never reach to. else - to = static_cast(m_Caption.length()); + to = static_cast(m_Caption->length()); // Set current line, new rows will be added before current_line, so @@ -1909,7 +1893,7 @@ // Now get the height of the font. // TODO: Get the real font - CFontMetrics font(CStrIntern(m_Font.ToUTF8())); + CFontMetrics font(CStrIntern(m_Font->ToUTF8())); float spacing = (float)font.GetLineSpacing(); // Change mouse position relative to text. @@ -2000,9 +1984,9 @@ virtualTo = m_iBufferPos; } - m_Caption = - m_Caption.Left(virtualFrom) + - m_Caption.Right(static_cast(m_Caption.length()) - virtualTo); + m_Caption.Get() = + m_Caption->Left(virtualFrom) + + m_Caption->Right(static_cast(m_Caption->length()) - virtualTo); UpdateText(virtualFrom, virtualTo, virtualFrom); @@ -2038,7 +2022,7 @@ // Now get the height of the font. // TODO: Get the real font - CFontMetrics font(CStrIntern(m_Font.ToUTF8())); + CFontMetrics font(CStrIntern(m_Font->ToUTF8())); float spacing = (float)font.GetLineSpacing(); //float height = font.GetHeight(); Index: source/gui/ObjectTypes/CList.h =================================================================== --- source/gui/ObjectTypes/CList.h +++ source/gui/ObjectTypes/CList.h @@ -126,24 +126,22 @@ virtual int GetHoveredItem(); - // Settings - float m_BufferZone; - CStrW m_Font; - bool m_ScrollBar; - CStr m_ScrollBarStyle; - bool m_ScrollBottom; - CStrW m_SoundDisabled; - CStrW m_SoundSelected; - CGUISpriteInstance m_Sprite; - CGUISpriteInstance m_SpriteSelectArea; - EAlign m_TextAlign; - CGUIColor m_TextColor; - CGUIColor m_TextColorSelected; - i32 m_Selected; - bool m_AutoScroll; - i32 m_Hovered; - CGUIList m_List; - CGUIList m_ListData; + CGUISimpleSetting m_BufferZone; + CGUISimpleSetting m_Font; + CGUISimpleSetting m_ScrollBar; + CGUISimpleSetting m_ScrollBarStyle; + CGUISimpleSetting m_ScrollBottom; + CGUISimpleSetting m_SoundDisabled; + CGUISimpleSetting m_SoundSelected; + CGUISimpleSetting m_Sprite; + CGUISimpleSetting m_SpriteSelectArea; + CGUISimpleSetting m_TextColor; + CGUISimpleSetting m_TextColorSelected; + CGUISimpleSetting m_Selected; + CGUISimpleSetting m_AutoScroll; + CGUISimpleSetting m_Hovered; + CGUISimpleSetting m_List; + CGUISimpleSetting m_ListData; private: static const CStr EventNameSelectionChange; Index: source/gui/ObjectTypes/CList.cpp =================================================================== --- source/gui/ObjectTypes/CList.cpp +++ source/gui/ObjectTypes/CList.cpp @@ -38,49 +38,25 @@ m_Modified(false), m_PrevSelectedItem(-1), m_LastItemClickTime(0), - m_BufferZone(), - m_Font(), - m_ScrollBar(), - m_ScrollBarStyle(), - m_ScrollBottom(false), - m_SoundDisabled(), - m_SoundSelected(), - m_Sprite(), - m_SpriteSelectArea(), - m_TextAlign(), - m_TextColor(), - m_TextColorSelected(), - m_Selected(), - m_AutoScroll(), - m_Hovered(), - m_List(), - m_ListData() + m_BufferZone(this, "buffer_zone"), + m_Font(this, "font"), + m_ScrollBar(this, "scrollbar", false), + m_ScrollBarStyle(this, "scrollbar_style"), + m_ScrollBottom(this, "scroll_bottom", false), + m_SoundDisabled(this, "sound_disabled"), + m_SoundSelected(this, "sound_selected"), + m_Sprite(this, "sprite"), + // Add sprite_disabled! TODO + m_SpriteSelectArea(this, "sprite_selectarea"), + m_TextColor(this, "textcolor"), + m_TextColorSelected(this, "textcolor_selected"), + m_Selected(this, "selected", -1), // Index selected. -1 is none. + m_AutoScroll(this, "auto_scroll", false), + m_Hovered(this, "hovered", -1), + // Each list item has both a name (in 'list') and an associated data string (in 'list_data') + m_List(this, "list"), + m_ListData(this, "list_data") { - RegisterSetting("buffer_zone", m_BufferZone); - RegisterSetting("font", m_Font); - RegisterSetting("scrollbar", m_ScrollBar); - RegisterSetting("scrollbar_style", m_ScrollBarStyle); - RegisterSetting("scroll_bottom", m_ScrollBottom); - RegisterSetting("sound_disabled", m_SoundDisabled); - RegisterSetting("sound_selected", m_SoundSelected); - RegisterSetting("sprite", m_Sprite); - // Add sprite_disabled! TODO - RegisterSetting("sprite_selectarea", m_SpriteSelectArea); - RegisterSetting("text_align", m_TextAlign); - RegisterSetting("textcolor", m_TextColor); - RegisterSetting("textcolor_selected", m_TextColorSelected); - RegisterSetting("selected", m_Selected); // Index selected. -1 is none. - RegisterSetting("auto_scroll", m_AutoScroll); - RegisterSetting("hovered", m_Hovered); - // Each list item has both a name (in 'list') and an associated data string (in 'list_data') - RegisterSetting("list", m_List); - RegisterSetting("list_data", m_ListData); - - SetSetting("scrollbar", false, true); - SetSetting("selected", -1, true); - SetSetting("hovered", -1, true); - SetSetting("auto_scroll", false, true); - // Add scroll-bar CGUIScrollBarVertical* bar = new CGUIScrollBarVertical(pGUI); bar->SetRightAligned(true); @@ -123,14 +99,14 @@ if (append && !m_ItemsYPositions.empty()) buffered_y = m_ItemsYPositions.back(); - m_ItemsYPositions.resize(m_List.m_Items.size() + 1); + m_ItemsYPositions.resize(m_List->m_Items.size() + 1); - for (size_t i = append ? m_List.m_Items.size() - 1 : 0; i < m_List.m_Items.size(); ++i) + for (size_t i = append ? m_List->m_Items.size() - 1 : 0; i < m_List->m_Items.size(); ++i) { CGUIText* text; - if (!m_List.m_Items[i].GetOriginalString().empty()) - text = &AddText(m_List.m_Items[i], m_Font, width, m_BufferZone); + if (!m_List->m_Items[i].GetOriginalString().empty()) + text = &AddText(m_List->m_Items[i], m_Font, width, m_BufferZone); else { // Minimum height of a space character of the current font size @@ -143,7 +119,7 @@ buffered_y += text->GetSize().Height; } - m_ItemsYPositions[m_List.m_Items.size()] = buffered_y; + m_ItemsYPositions[m_List->m_Items.size()] = buffered_y; // Setup scrollbar if (m_ScrollBar) @@ -221,7 +197,7 @@ int hovered = GetHoveredItem(); if (hovered == -1) break; - SetSetting("selected", hovered, true); + m_Selected.Set(hovered, true); UpdateAutoScroll(); PlaySound(m_SoundSelected); @@ -240,7 +216,7 @@ if (m_Hovered == -1) break; - SetSetting("hovered", -1, true); + m_Hovered.Set(-1, true); ScriptEvent(EventNameHoverChange); break; } @@ -251,7 +227,7 @@ if (hovered == m_Hovered) break; - SetSetting("hovered", hovered, true); + m_Hovered.Set(hovered, true); ScriptEvent(EventNameHoverChange); break; } @@ -369,7 +345,7 @@ } } - for (size_t i = 0; i < m_List.m_Items.size(); ++i) + for (size_t i = 0; i < m_List->m_Items.size(); ++i) { if (m_ItemsYPositions[i+1] - scroll < 0 || m_ItemsYPositions[i] - scroll > rect.GetHeight()) @@ -400,8 +376,8 @@ void CList::AddItem(const CGUIString& str, const CGUIString& data) { // Do not send a settings-changed message - m_List.m_Items.push_back(str); - m_ListData.m_Items.push_back(data); + m_List->m_Items.push_back(str); + m_ListData->m_Items.push_back(data); SetupText(true); } @@ -428,9 +404,9 @@ void CList::SelectNextElement() { - if (m_Selected != static_cast(m_List.m_Items.size()) - 1) + if (m_Selected != static_cast(m_List->m_Items.size()) - 1) { - SetSetting("selected", m_Selected + 1, true); + m_Selected.Set(m_Selected + 1, true); PlaySound(m_SoundSelected); } } @@ -439,7 +415,7 @@ { if (m_Selected > 0) { - SetSetting("selected", m_Selected - 1, true); + m_Selected.Set(m_Selected - 1, true); PlaySound(m_SoundSelected); } } @@ -447,15 +423,15 @@ void CList::SelectFirstElement() { if (m_Selected >= 0) - SetSetting("selected", 0, true); + m_Selected.Set(0, true); } void CList::SelectLastElement() { - const int index = static_cast(m_List.m_Items.size()) - 1; + const int index = static_cast(m_List->m_Items.size()) - 1; if (m_Selected != index) - SetSetting("selected", index, true); + m_Selected.Set(index, true); } void CList::UpdateAutoScroll() @@ -494,7 +470,7 @@ mouse.X <= GetScrollBar(0).GetOuterRect().right) return -1; - for (size_t i = 0; i < m_List.m_Items.size(); ++i) + for (size_t i = 0; i < m_List->m_Items.size(); ++i) if (mouse.Y >= rect.top + m_ItemsYPositions[i] && mouse.Y < rect.top + m_ItemsYPositions[i + 1]) return i; Index: source/gui/ObjectTypes/CMiniMap.h =================================================================== --- source/gui/ObjectTypes/CMiniMap.h +++ source/gui/ObjectTypes/CMiniMap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -84,7 +84,7 @@ bool m_TerrainDirty; // Whether to draw a black square around and under the minimap. - bool m_Mask; + CGUISimpleSetting m_Mask; ssize_t m_Width, m_Height; Index: source/gui/ObjectTypes/CMiniMap.cpp =================================================================== --- source/gui/ObjectTypes/CMiniMap.cpp +++ source/gui/ObjectTypes/CMiniMap.cpp @@ -109,11 +109,9 @@ CMiniMap::CMiniMap(CGUI& pGUI) : IGUIObject(pGUI), m_TerrainTexture(0), m_TerrainData(0), m_MapSize(0), m_Terrain(0), m_TerrainDirty(true), m_MapScale(1.f), - m_EntitiesDrawn(0), m_IndexArray(GL_STATIC_DRAW), m_VertexArray(GL_DYNAMIC_DRAW), m_Mask(false), + m_EntitiesDrawn(0), m_IndexArray(GL_STATIC_DRAW), m_VertexArray(GL_DYNAMIC_DRAW), m_Mask(this, "mask", false), m_NextBlinkTime(0.0), m_PingDuration(25.0), m_BlinkState(false), m_WaterHeight(0.0) { - RegisterSetting("mask", m_Mask); - m_Clicking = false; m_MouseHovering = false; Index: source/gui/ObjectTypes/COList.h =================================================================== --- source/gui/ObjectTypes/COList.h +++ source/gui/ObjectTypes/COList.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -25,18 +25,21 @@ /** * Represents a column. */ -struct COListColumn +class COListColumn { +public: + COListColumn(IGUIObject* owner, const CStr& cid) + : m_Width(0), m_Id(cid), m_List(owner, "list_" + cid), m_Hidden(owner, "hidden_" + cid, false) + {} // Avoid copying the strings. NONCOPYABLE(COListColumn); MOVABLE(COListColumn); - COListColumn() : m_Width(0), m_Hidden(false) {} CGUIColor m_TextColor; CStr m_Id; float m_Width; CStrW m_Heading; // CGUIString?? - CGUIList m_List; - bool m_Hidden; + CGUISimpleSetting m_List; + CGUISimpleSetting m_Hidden; }; /** @@ -73,14 +76,13 @@ */ std::vector m_Columns; - // Settings - CGUISpriteInstance m_SpriteHeading; - bool m_Sortable; - CStr m_SelectedColumn; - i32 m_SelectedColumnOrder; - CGUISpriteInstance m_SpriteAsc; - CGUISpriteInstance m_SpriteDesc; - CGUISpriteInstance m_SpriteNotSorted; + CGUISimpleSetting m_SpriteHeading; + CGUISimpleSetting m_Sortable; + CGUISimpleSetting m_SelectedColumn; + CGUISimpleSetting m_SelectedColumnOrder; + CGUISimpleSetting m_SpriteAsc; + CGUISimpleSetting m_SpriteDesc; + CGUISimpleSetting m_SpriteNotSorted; private: static const CStr EventNameSelectionColumnChange; Index: source/gui/ObjectTypes/COList.cpp =================================================================== --- source/gui/ObjectTypes/COList.cpp +++ source/gui/ObjectTypes/COList.cpp @@ -33,26 +33,19 @@ COList::COList(CGUI& pGUI) : CList(pGUI), - m_SpriteHeading(), - m_Sortable(), - m_SelectedColumn(), - m_SelectedColumnOrder(), - m_SpriteAsc(), - m_SpriteDesc(), - m_SpriteNotSorted() + m_SpriteHeading(this, "sprite_heading"), + m_Sortable(this, "sortable"), // The actual sorting is done in JS for more versatility + m_SelectedColumn(this, "selected_column"), + m_SelectedColumnOrder(this, "selected_column_order"), + m_SpriteAsc(this, "sprite_asc"), // Show the order of sorting + m_SpriteDesc(this, "sprite_desc"), + m_SpriteNotSorted(this, "sprite_not_sorted") { - RegisterSetting("sprite_heading", m_SpriteHeading); - RegisterSetting("sortable", m_Sortable); // The actual sorting is done in JS for more versatility - RegisterSetting("selected_column", m_SelectedColumn); - RegisterSetting("selected_column_order", m_SelectedColumnOrder); - RegisterSetting("sprite_asc", m_SpriteAsc); // Show the order of sorting - RegisterSetting("sprite_desc", m_SpriteDesc); - RegisterSetting("sprite_not_sorted", m_SpriteNotSorted); } void COList::SetupText() { - m_ItemsYPositions.resize(m_List.m_Items.size() + 1); + m_ItemsYPositions.resize(m_List->m_Items.size() + 1); // Delete all generated texts. Some could probably be saved, // but this is easier, and this function will never be called @@ -82,7 +75,7 @@ // Generate texts float buffered_y = 0.f; - for (size_t i = 0; i < m_List.m_Items.size(); ++i) + for (size_t i = 0; i < m_List->m_Items.size(); ++i) { m_ItemsYPositions[i] = buffered_y; float shift = 0.0f; @@ -93,8 +86,8 @@ width *= m_TotalAvailableColumnWidth; CGUIText* text; - if (!column.m_List.m_Items[i].GetOriginalString().empty()) - text = &AddText(column.m_List.m_Items[i], m_Font, width, m_BufferZone); + if (!column.m_List->m_Items[i].GetOriginalString().empty()) + text = &AddText(column.m_List->m_Items[i], m_Font, width, m_BufferZone); else { // Minimum height of a space character of the current font size @@ -107,7 +100,7 @@ buffered_y += shift; } - m_ItemsYPositions[m_List.m_Items.size()] = buffered_y; + m_ItemsYPositions[m_List->m_Items.size()] = buffered_y; if (m_ScrollBar) { @@ -158,14 +151,14 @@ mouse.X < leftTopCorner.X + width && mouse.Y < leftTopCorner.Y + m_HeadingHeight) { - if (column.m_Id != m_SelectedColumn) + if (column.m_Id != static_cast(m_SelectedColumn)) { - SetSetting("selected_column_order", -1, true); + m_SelectedColumnOrder.Set(-1, true); CStr selected_column = column.m_Id; - SetSetting("selected_column", selected_column, true); + m_SelectedColumn.Set(selected_column, true); } else - SetSetting("selected_column_order", -m_SelectedColumnOrder, true); + m_SelectedColumnOrder.Set(-m_SelectedColumnOrder, true); ScriptEvent(EventNameSelectionColumnChange); PlaySound(m_SoundSelected); @@ -199,7 +192,14 @@ } else if (child.GetNodeName() == elmt_column) { - COListColumn column; + CStr id; + XERO_ITER_ATTR(child, attr) + { + if (attr.Name == attr_id) + id = attr.Value; + } + + COListColumn column(this, id); for (XMBAttribute attr : child.GetAttributes()) { @@ -211,17 +211,13 @@ if (!CGUI::ParseString(&m_pGUI, attr_value.FromUTF8(), column.m_TextColor)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); } - else if (attr_name == "id") - { - column.m_Id = attr_value; - } else if (attr_name == "hidden") { bool hidden = false; if (!CGUI::ParseString(&m_pGUI, attr_value.FromUTF8(), hidden)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); else - column.m_Hidden = hidden; + column.m_Hidden.Set(hidden, false); } else if (attr_name == "width") { @@ -282,13 +278,6 @@ void COList::AdditionalChildrenHandled() { SetupText(); - - // Do this after the last push_back call to avoid iterator invalidation - for (COListColumn& column : m_Columns) - { - RegisterSetting("list_" + column.m_Id, column.m_List); - RegisterSetting("hidden_" + column.m_Id, column.m_Hidden); - } } void COList::DrawList(const int& selected, const CGUISpriteInstance& sprite, const CGUISpriteInstance& sprite_selected, const CGUIColor& textcolor) @@ -367,18 +356,18 @@ if (m_Sortable) { const CGUISpriteInstance* pSprite; - if (m_SelectedColumn == column.m_Id) + if (m_SelectedColumn.Get() == column.m_Id) { if (m_SelectedColumnOrder == 0) LOGERROR("selected_column_order must not be 0"); if (m_SelectedColumnOrder != -1) - pSprite = &m_SpriteAsc; + pSprite = &m_SpriteAsc.Get(); else - pSprite = &m_SpriteDesc; + pSprite = &m_SpriteDesc.Get(); } else - pSprite = &m_SpriteNotSorted; + pSprite = &m_SpriteNotSorted.Get(); m_pGUI.DrawSprite(*pSprite, bz + 0.1f, CRect(leftTopCorner + CVector2D(width - SORT_SPRITE_DIM, 0), leftTopCorner + CVector2D(width, SORT_SPRITE_DIM))); } @@ -391,7 +380,7 @@ // Draw list items for each column const size_t objectsCount = m_Columns.size(); - for (size_t i = 0; i < m_List.m_Items.size(); ++i) + for (size_t i = 0; i < m_List->m_Items.size(); ++i) { if (m_ItemsYPositions[i+1] - scroll < 0 || m_ItemsYPositions[i] - scroll > rect.GetHeight()) Index: source/gui/ObjectTypes/CProgressBar.h =================================================================== --- source/gui/ObjectTypes/CProgressBar.h +++ source/gui/ObjectTypes/CProgressBar.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -45,9 +45,9 @@ void HandleMessage(SGUIMessage& Message); // Settings - CGUISpriteInstance m_SpriteBackground; - CGUISpriteInstance m_SpriteBar; - float m_Progress; + CGUISimpleSetting m_SpriteBackground; + CGUISimpleSetting m_SpriteBar; + CGUISimpleSetting m_Progress; }; #endif // INCLUDED_CPROGRESSBAR Index: source/gui/ObjectTypes/CProgressBar.cpp =================================================================== --- source/gui/ObjectTypes/CProgressBar.cpp +++ source/gui/ObjectTypes/CProgressBar.cpp @@ -23,13 +23,10 @@ CProgressBar::CProgressBar(CGUI& pGUI) : IGUIObject(pGUI), - m_SpriteBackground(), - m_SpriteBar(), - m_Progress() + m_SpriteBackground(this, "sprite_background"), + m_SpriteBar(this, "sprite_bar"), + m_Progress(this, "progress") // Between 0 and 100. { - RegisterSetting("sprite_background", m_SpriteBackground); - RegisterSetting("sprite_bar", m_SpriteBar); - RegisterSetting("progress", m_Progress); // between 0 and 100 } CProgressBar::~CProgressBar() @@ -46,9 +43,9 @@ if (Message.value == "progress") { if (m_Progress > 100.f) - SetSetting("progress", 100.f, true); + m_Progress.Set(100.f, true); else if (m_Progress < 0.f) - SetSetting("progress", 0.f, true); + m_Progress.Set(0.f, true); } break; default: Index: source/gui/ObjectTypes/CRadioButton.cpp =================================================================== --- source/gui/ObjectTypes/CRadioButton.cpp +++ source/gui/ObjectTypes/CRadioButton.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -27,7 +27,7 @@ void CRadioButton::HandleMessage(SGUIMessage& Message) { IGUIButtonBehavior::HandleMessage(Message); - + /* switch (Message.type) { case GUIM_PRESSED: @@ -44,5 +44,5 @@ default: break; - } + }*/ } Index: source/gui/ObjectTypes/CSlider.h =================================================================== --- source/gui/ObjectTypes/CSlider.h +++ source/gui/ObjectTypes/CSlider.h @@ -61,12 +61,12 @@ void IncrementallyChangeValue(const float value); // Settings - float m_ButtonSide; - float m_MinValue; - float m_MaxValue; - CGUISpriteInstance m_Sprite; - CGUISpriteInstance m_SpriteBar; - float m_Value; + CGUISimpleSetting m_ButtonSide; + CGUISimpleSetting m_MinValue; + CGUISimpleSetting m_MaxValue; + CGUISimpleSetting m_Sprite; + CGUISimpleSetting m_SpriteBar; + CGUISimpleSetting m_Value; private: CVector2D m_Mouse; Index: source/gui/ObjectTypes/CSlider.cpp =================================================================== --- source/gui/ObjectTypes/CSlider.cpp +++ source/gui/ObjectTypes/CSlider.cpp @@ -27,21 +27,14 @@ CSlider::CSlider(CGUI& pGUI) : IGUIObject(pGUI), IGUIButtonBehavior(*static_cast(this)), - m_ButtonSide(), - m_MaxValue(), - m_MinValue(), - m_Sprite(), - m_SpriteBar(), - m_Value() + m_ButtonSide(this, "button_width"), + m_MaxValue(this, "max_value"), + m_MinValue(this, "min_value"), + m_Sprite(this, "sprite"), + m_SpriteBar(this, "sprite_bar"), + m_Value(this, "value") { - RegisterSetting("button_width", m_ButtonSide); - RegisterSetting("max_value", m_MaxValue); - RegisterSetting("min_value", m_MinValue); - RegisterSetting("sprite", m_Sprite); - RegisterSetting("sprite_bar", m_SpriteBar); - RegisterSetting("value", m_Value); - - m_Value = Clamp(m_Value, m_MinValue, m_MaxValue); + m_Value.Set(Clamp(m_Value, m_MinValue, m_MaxValue), false); } CSlider::~CSlider() @@ -61,7 +54,7 @@ void CSlider::IncrementallyChangeValue(const float difference) { - m_Value = Clamp(m_Value + difference, m_MinValue, m_MaxValue); + m_Value.Set(Clamp(m_Value + difference, m_MinValue, m_MaxValue), true); UpdateValue(); } @@ -72,11 +65,13 @@ switch (Message.type) { + /* case GUIM_SETTINGS_UPDATED: { - m_Value = Clamp(m_Value, m_MinValue, m_MaxValue); + m_Value.Set(Clamp(m_Value, m_MinValue, m_MaxValue), true); break; } + */ case GUIM_MOUSE_WHEEL_DOWN: { if (m_Pressed) @@ -119,7 +114,6 @@ void CSlider::UpdateValue() { - SetSetting("value", m_Value, true); ScriptEvent(EventNameValueChange); } Index: source/gui/ObjectTypes/CText.h =================================================================== --- source/gui/ObjectTypes/CText.h +++ source/gui/ObjectTypes/CText.h @@ -77,22 +77,19 @@ */ CVector2D m_TextPos; - // Settings - float m_BufferZone; - CGUIString m_Caption; - bool m_Clip; - CStrW m_Font; - bool m_ScrollBar; - CStr m_ScrollBarStyle; - bool m_ScrollBottom; - bool m_ScrollTop; - CGUISpriteInstance m_Sprite; - EAlign m_TextAlign; - EVAlign m_TextVAlign; - CGUIColor m_TextColor; - CGUIColor m_TextColorDisabled; - CStrW m_IconTooltip; - CStr m_IconTooltipStyle; + CGUISimpleSetting m_BufferZone; + CGUISimpleSetting m_Caption; + CGUISimpleSetting m_Clip; + CGUISimpleSetting m_Font; + CGUISimpleSetting m_ScrollBar; + CGUISimpleSetting m_ScrollBarStyle; + CGUISimpleSetting m_ScrollBottom; + CGUISimpleSetting m_ScrollTop; + CGUISimpleSetting m_Sprite; + CGUISimpleSetting m_TextColor; + CGUISimpleSetting m_TextColorDisabled; + CGUISimpleSetting m_IconTooltip; + CGUISimpleSetting m_IconTooltipStyle; }; #endif // INCLUDED_CTEXT Index: source/gui/ObjectTypes/CText.cpp =================================================================== --- source/gui/ObjectTypes/CText.cpp +++ source/gui/ObjectTypes/CText.cpp @@ -28,43 +28,20 @@ : IGUIObject(pGUI), IGUIScrollBarOwner(*static_cast(this)), IGUITextOwner(*static_cast(this)), - m_BufferZone(), - m_Caption(), - m_Clip(), - m_Font(), - m_ScrollBar(), - m_ScrollBarStyle(), - m_ScrollBottom(), - m_ScrollTop(), - m_Sprite(), - m_TextAlign(), - m_TextVAlign(), - m_TextColor(), - m_TextColorDisabled(), - m_IconTooltip(), - m_IconTooltipStyle() + m_BufferZone(this, "buffer_zone"), + m_Caption(this, "caption"), + m_Clip(this, "clip", true), + m_Font(this, "font"), + m_ScrollBar(this, "scrollbar", false), + m_ScrollBarStyle(this, "scrollbar_style"), + m_ScrollBottom(this, "scroll_bottom"), + m_ScrollTop(this, "scroll_top"), + m_Sprite(this, "sprite"), + m_TextColor(this, "textcolor"), + m_TextColorDisabled(this, "textcolor_disabled"), + m_IconTooltip(this, "_icon_tooltip"), + m_IconTooltipStyle(this, "_icon_tooltip_style") { - RegisterSetting("buffer_zone", m_BufferZone); - RegisterSetting("caption", m_Caption); - RegisterSetting("clip", m_Clip); - RegisterSetting("font", m_Font); - RegisterSetting("scrollbar", m_ScrollBar); - RegisterSetting("scrollbar_style", m_ScrollBarStyle); - RegisterSetting("scroll_bottom", m_ScrollBottom); - RegisterSetting("scroll_top", m_ScrollTop); - RegisterSetting("sprite", m_Sprite); - RegisterSetting("text_align", m_TextAlign); - RegisterSetting("text_valign", m_TextVAlign); - RegisterSetting("textcolor", m_TextColor); - RegisterSetting("textcolor_disabled", m_TextColorDisabled); - // Private settings - RegisterSetting("_icon_tooltip", m_IconTooltip); - RegisterSetting("_icon_tooltip_style", m_IconTooltipStyle); - - //SetSetting("ghost", true, true); - SetSetting("scrollbar", false, true); - SetSetting("clip", true, true); - // Add scroll-bar CGUIScrollBarVertical* bar = new CGUIScrollBarVertical(pGUI); bar->SetRightAligned(true); @@ -88,7 +65,7 @@ if (m_ScrollBar && GetScrollBar(0).GetStyle()) width -= GetScrollBar(0).GetStyle()->m_Width; - m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, width, m_BufferZone, this); + m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, width, m_BufferZone, m_TextAlign, this); if (!m_ScrollBar) CalculateTextPosition(m_CachedActualSize, m_TextPos, m_GeneratedTexts[0]); @@ -246,8 +223,8 @@ // If tooltip exists, set the property if (!spritecall.m_Tooltip.empty()) { - SetSettingFromString("_icon_tooltip_style", spritecall.m_TooltipStyle, true); - SetSettingFromString("_icon_tooltip", spritecall.m_Tooltip, true); + m_IconTooltipStyle.FromString(spritecall.m_TooltipStyle, true); + m_IconTooltip.FromString(spritecall.m_Tooltip, true); } return true; Index: source/gui/ObjectTypes/CTooltip.h =================================================================== --- source/gui/ObjectTypes/CTooltip.h +++ source/gui/ObjectTypes/CTooltip.h @@ -35,6 +35,11 @@ CTooltip(CGUI& pGUI); virtual ~CTooltip(); + const CStr& GetUsedObject() const { return m_UseObject; } + i32 GetTooltipDelay() const { return m_Delay; } + bool ShouldHideObject() const { return m_HideObject; } + void SetMousePos(const CVector2D& vec) { m_MousePos.Set(vec, true); } + protected: void SetupText(); @@ -52,21 +57,19 @@ virtual float GetBufferedZ() const; - // Settings - float m_BufferZone; - CGUIString m_Caption; - CStrW m_Font; - CGUISpriteInstance m_Sprite; - i32 m_Delay; - CGUIColor m_TextColor; - float m_MaxWidth; - CVector2D m_Offset; - EVAlign m_Anchor; - EAlign m_TextAlign; - bool m_Independent; - CVector2D m_MousePos; - CStr m_UseObject; - bool m_HideObject; + CGUISimpleSetting m_BufferZone; + CGUISimpleSetting m_Caption; + CGUISimpleSetting m_Font; + CGUISimpleSetting m_Sprite; + CGUISimpleSetting m_Delay; + CGUISimpleSetting m_TextColor; + CGUISimpleSetting m_MaxWidth; + CGUISimpleSetting m_Offset; + CGUISimpleSetting m_Anchor; + CGUISimpleSetting m_Independent; + CGUISimpleSetting m_MousePos; + CGUISimpleSetting m_UseObject; + CGUISimpleSetting m_HideObject; }; #endif // INCLUDED_CTOOLTIP Index: source/gui/ObjectTypes/CTooltip.cpp =================================================================== --- source/gui/ObjectTypes/CTooltip.cpp +++ source/gui/ObjectTypes/CTooltip.cpp @@ -28,46 +28,24 @@ CTooltip::CTooltip(CGUI& pGUI) : IGUIObject(pGUI), IGUITextOwner(*static_cast(this)), - m_BufferZone(), - m_Caption(), - m_Font(), - m_Sprite(), - m_Delay(), - m_TextColor(), - m_MaxWidth(), - m_Offset(), - m_Anchor(), - m_TextAlign(), - m_Independent(), - m_MousePos(), - m_UseObject(), - m_HideObject() + m_BufferZone(this, "buffer_zone"), + m_Caption(this, "caption"), + m_Font(this, "font"), + m_Sprite(this, "sprite"), + m_Delay(this, "delay", 500), // in milliseconds + m_TextColor(this, "textcolor"), + m_MaxWidth(this, "maxwidth"), + m_Offset(this, "offset"), + m_Anchor(this, "anchor", EVAlign::BOTTOM), + // This is used for tooltips that are hidden/revealed manually by scripts, rather than through the standard tooltip display mechanism + m_Independent(this, "independent"), + // Private settings: + // This is set by GUITooltip + m_MousePos(this, "_mousepos"), + // If the tooltip is just a reference to another object: + m_UseObject(this, "use_object"), + m_HideObject(this, "hide_object") { - // If the tooltip is an object by itself: - RegisterSetting("buffer_zone", m_BufferZone); - RegisterSetting("caption", m_Caption); - RegisterSetting("font", m_Font); - RegisterSetting("sprite", m_Sprite); - RegisterSetting("delay", m_Delay); // in milliseconds - RegisterSetting("textcolor", m_TextColor); - RegisterSetting("maxwidth", m_MaxWidth); - RegisterSetting("offset", m_Offset); - RegisterSetting("anchor", m_Anchor); - RegisterSetting("text_align", m_TextAlign); - // This is used for tooltips that are hidden/revealed manually by scripts, rather than through the standard tooltip display mechanism - RegisterSetting("independent", m_Independent); - // Private settings: - // This is set by GUITooltip - RegisterSetting("_mousepos", m_MousePos); - // If the tooltip is just a reference to another object: - RegisterSetting("use_object", m_UseObject); - RegisterSetting("hide_object", m_HideObject); - - // Defaults - SetSetting("delay", 500, true); - SetSetting("anchor", EVAlign::BOTTOM, true); - SetSetting("text_align", EAlign::LEFT, true); - // Set up a blank piece of text, to be replaced with a more // interesting message later AddText(); @@ -81,7 +59,7 @@ { ENSURE(m_GeneratedTexts.size() == 1); - m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, m_MaxWidth, m_BufferZone, this); + m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, m_MaxWidth, m_BufferZone, m_TextAlign, this); // Position the tooltip relative to the mouse: @@ -91,21 +69,21 @@ float textheight = m_GeneratedTexts[0].GetSize().Height; CGUISize size; - size.pixel.left = mousepos.X + m_Offset.X; + size.pixel.left = mousepos.X + m_Offset->X; size.pixel.right = size.pixel.left + textwidth; switch (m_Anchor) { case EVAlign::TOP: - size.pixel.top = mousepos.Y + m_Offset.Y; + size.pixel.top = mousepos.Y + m_Offset->Y; size.pixel.bottom = size.pixel.top + textheight; break; case EVAlign::BOTTOM: - size.pixel.bottom = mousepos.Y + m_Offset.Y; + size.pixel.bottom = mousepos.Y + m_Offset->Y; size.pixel.top = size.pixel.bottom - textheight; break; case EVAlign::CENTER: - size.pixel.top = mousepos.Y + m_Offset.Y - textheight/2.f; + size.pixel.top = mousepos.Y + m_Offset->Y - textheight/2.f; size.pixel.bottom = size.pixel.top + textwidth; break; default: @@ -130,7 +108,7 @@ else if (size.pixel.right > screenw) size.pixel.left -= (size.pixel.right-screenw), size.pixel.right = screenw; - SetSetting("size", size, true); + m_Size.Set(size, true); } void CTooltip::UpdateCachedSize()