Index: ps/trunk/source/gui/CButton.h =================================================================== --- ps/trunk/source/gui/CButton.h +++ ps/trunk/source/gui/CButton.h @@ -24,7 +24,7 @@ #include "gui/CGUISprite.h" #include "gui/CGUIString.h" -class CButton : public IGUIButtonBehavior, public IGUITextOwner +class CButton : public IGUIObject, public IGUITextOwner, public IGUIButtonBehavior { GUI_OBJECT(CButton) @@ -35,7 +35,12 @@ /** * @see IGUIObject#ResetStates() */ - virtual void ResetStates() { IGUIButtonBehavior::ResetStates(); } + virtual void ResetStates(); + + /** + * @see IGUIObject#UpdateCachedSize() + */ + virtual void UpdateCachedSize(); /** * @see IGUIObject#HandleMessage() Index: ps/trunk/source/gui/CButton.cpp =================================================================== --- ps/trunk/source/gui/CButton.cpp +++ ps/trunk/source/gui/CButton.cpp @@ -25,8 +25,8 @@ CButton::CButton(CGUI& pGUI) : IGUIObject(pGUI), - IGUIButtonBehavior(pGUI), - IGUITextOwner(pGUI), + IGUIButtonBehavior(*static_cast(this)), + IGUITextOwner(*static_cast(this)), m_BufferZone(), m_CellID(), m_Caption(), @@ -72,9 +72,21 @@ CalculateTextPosition(m_CachedActualSize, m_TextPos, m_GeneratedTexts[0]); } +void CButton::ResetStates() +{ + IGUIObject::ResetStates(); + IGUIButtonBehavior::ResetStates(); +} + +void CButton::UpdateCachedSize() +{ + IGUIObject::UpdateCachedSize(); + IGUITextOwner::UpdateCachedSize(); +} + void CButton::HandleMessage(SGUIMessage& Message) { - // Important + IGUIObject::HandleMessage(Message); IGUIButtonBehavior::HandleMessage(Message); IGUITextOwner::HandleMessage(Message); } Index: ps/trunk/source/gui/CChart.h =================================================================== --- ps/trunk/source/gui/CChart.h +++ ps/trunk/source/gui/CChart.h @@ -41,7 +41,7 @@ /** * Chart for a data visualization as lines or points */ -class CChart : public IGUITextOwner +class CChart : public IGUIObject, public IGUITextOwner { GUI_OBJECT(CChart) @@ -51,6 +51,11 @@ protected: /** + * @see IGUIObject#UpdateCachedSize() + */ + void UpdateCachedSize(); + + /** * @see IGUIObject#HandleMessage() */ virtual void HandleMessage(SGUIMessage& Message); Index: ps/trunk/source/gui/CChart.cpp =================================================================== --- ps/trunk/source/gui/CChart.cpp +++ ps/trunk/source/gui/CChart.cpp @@ -32,7 +32,7 @@ CChart::CChart(CGUI& pGUI) : IGUIObject(pGUI), - IGUITextOwner(pGUI), + IGUITextOwner(*static_cast(this)), m_AxisColor(), m_AxisWidth(), m_BufferZone(), @@ -58,8 +58,17 @@ { } +void CChart::UpdateCachedSize() +{ + IGUIObject::UpdateCachedSize(); + IGUITextOwner::UpdateCachedSize(); +} + void CChart::HandleMessage(SGUIMessage& Message) { + IGUIObject::HandleMessage(Message); + // IGUITextOwner::HandleMessage(Message); performed in UpdateSeries + // TODO: implement zoom switch (Message.type) { Index: ps/trunk/source/gui/CCheckBox.h =================================================================== --- ps/trunk/source/gui/CCheckBox.h +++ ps/trunk/source/gui/CCheckBox.h @@ -21,7 +21,7 @@ #include "gui/CGUISprite.h" #include "gui/IGUIButtonBehavior.h" -class CCheckBox : public IGUIButtonBehavior +class CCheckBox : public IGUIObject, public IGUIButtonBehavior { GUI_OBJECT(CCheckBox) @@ -32,7 +32,7 @@ /** * @see IGUIObject#ResetStates() */ - virtual void ResetStates() { IGUIButtonBehavior::ResetStates(); } + virtual void ResetStates(); /** * @see IGUIObject#HandleMessage() Index: ps/trunk/source/gui/CCheckBox.cpp =================================================================== --- ps/trunk/source/gui/CCheckBox.cpp +++ ps/trunk/source/gui/CCheckBox.cpp @@ -23,7 +23,7 @@ CCheckBox::CCheckBox(CGUI& pGUI) : IGUIObject(pGUI), - IGUIButtonBehavior(pGUI), + IGUIButtonBehavior(*static_cast(this)), m_CellID(), m_Checked(), m_SpriteUnchecked(), @@ -51,16 +51,21 @@ { } +void CCheckBox::ResetStates() +{ + IGUIObject::ResetStates(); + IGUIButtonBehavior::ResetStates(); +} + void CCheckBox::HandleMessage(SGUIMessage& Message) { - // Important + IGUIObject::HandleMessage(Message); IGUIButtonBehavior::HandleMessage(Message); switch (Message.type) { case GUIM_PRESSED: { - // Switch to opposite. SetSetting("checked", !m_Checked, true); break; } Index: ps/trunk/source/gui/CDropDown.cpp =================================================================== --- ps/trunk/source/gui/CDropDown.cpp +++ ps/trunk/source/gui/CDropDown.cpp @@ -29,7 +29,6 @@ CDropDown::CDropDown(CGUI& pGUI) : CList(pGUI), - IGUIObject(pGUI), m_Open(), m_HideScrollBar(), m_ElementHighlight(-1), @@ -93,7 +92,7 @@ void CDropDown::HandleMessage(SGUIMessage& Message) { - // Important + // CList::HandleMessage(Message); placed after the switch! switch (Message.type) { Index: ps/trunk/source/gui/CInput.h =================================================================== --- ps/trunk/source/gui/CInput.h +++ ps/trunk/source/gui/CInput.h @@ -31,7 +31,7 @@ * any other features than word-wrapping, and we need to be * able to rapidly change the string. */ -class CInput : public IGUIScrollBarOwner +class CInput : public IGUIObject, public IGUIScrollBarOwner { GUI_OBJECT(CInput) @@ -45,7 +45,7 @@ /** * @see IGUIObject#ResetStates() */ - virtual void ResetStates() { IGUIScrollBarOwner::ResetStates(); } + virtual void ResetStates(); // Check where the mouse is hovering, and get the appropriate text position. // return is the text-position index. Index: ps/trunk/source/gui/CInput.cpp =================================================================== --- ps/trunk/source/gui/CInput.cpp +++ ps/trunk/source/gui/CInput.cpp @@ -40,7 +40,7 @@ CInput::CInput(CGUI& pGUI) : IGUIObject(pGUI), - IGUIScrollBarOwner(pGUI), + IGUIScrollBarOwner(*static_cast(this)), m_iBufferPos(-1), m_iBufferPos_Tail(-1), m_SelectingText(), @@ -842,9 +842,15 @@ return IN_PASS; } +void CInput::ResetStates() +{ + IGUIObject::ResetStates(); + IGUIScrollBarOwner::ResetStates(); +} void CInput::HandleMessage(SGUIMessage& Message) { + IGUIObject::HandleMessage(Message); IGUIScrollBarOwner::HandleMessage(Message); switch (Message.type) Index: ps/trunk/source/gui/CList.h =================================================================== --- ps/trunk/source/gui/CList.h +++ ps/trunk/source/gui/CList.h @@ -34,7 +34,7 @@ * A scroll-bar will appear when needed. This will be * achieved with the IGUIScrollBarOwner structure. */ -class CList : public IGUIScrollBarOwner, public IGUITextOwner +class CList : public IGUIObject, public IGUIScrollBarOwner, public IGUITextOwner { GUI_OBJECT(CList) @@ -45,7 +45,12 @@ /** * @see IGUIObject#ResetStates() */ - virtual void ResetStates() { IGUIScrollBarOwner::ResetStates(); } + virtual void ResetStates(); + + /** + * @see IGUIObject#UpdateCachedSize() + */ + virtual void UpdateCachedSize(); /** * Adds an item last to the list. @@ -53,6 +58,7 @@ virtual void AddItem(const CStrW& str, const CStrW& data); protected: + /** * Sets up text, should be called every time changes has been * made that can change the visual. Index: ps/trunk/source/gui/CList.cpp =================================================================== --- ps/trunk/source/gui/CList.cpp +++ ps/trunk/source/gui/CList.cpp @@ -28,8 +28,8 @@ CList::CList(CGUI& pGUI) : IGUIObject(pGUI), - IGUITextOwner(pGUI), - IGUIScrollBarOwner(pGUI), + IGUITextOwner(*static_cast(this)), + IGUIScrollBarOwner(*static_cast(this)), m_Modified(false), m_PrevSelectedItem(-1), m_LastItemClickTime(0), @@ -139,8 +139,21 @@ } } +void CList::ResetStates() +{ + IGUIObject::ResetStates(); + IGUIScrollBarOwner::ResetStates(); +} + +void CList::UpdateCachedSize() +{ + IGUIObject::UpdateCachedSize(); + IGUITextOwner::UpdateCachedSize(); +} + void CList::HandleMessage(SGUIMessage& Message) { + IGUIObject::HandleMessage(Message); IGUIScrollBarOwner::HandleMessage(Message); //IGUITextOwner::HandleMessage(Message); <== placed it after the switch instead! Index: ps/trunk/source/gui/COList.cpp =================================================================== --- ps/trunk/source/gui/COList.cpp +++ ps/trunk/source/gui/COList.cpp @@ -31,7 +31,6 @@ COList::COList(CGUI& pGUI) : CList(pGUI), - IGUIObject(pGUI), m_SpriteHeading(), m_Sortable(), m_SelectedColumn(), Index: ps/trunk/source/gui/CProgressBar.cpp =================================================================== --- ps/trunk/source/gui/CProgressBar.cpp +++ ps/trunk/source/gui/CProgressBar.cpp @@ -38,7 +38,6 @@ void CProgressBar::HandleMessage(SGUIMessage& Message) { - // Important IGUIObject::HandleMessage(Message); switch (Message.type) Index: ps/trunk/source/gui/CRadioButton.cpp =================================================================== --- ps/trunk/source/gui/CRadioButton.cpp +++ ps/trunk/source/gui/CRadioButton.cpp @@ -20,13 +20,12 @@ #include "CRadioButton.h" CRadioButton::CRadioButton(CGUI& pGUI) - : CCheckBox(pGUI), IGUIObject(pGUI) + : CCheckBox(pGUI) { } void CRadioButton::HandleMessage(SGUIMessage& Message) { - // Important IGUIButtonBehavior::HandleMessage(Message); switch (Message.type) Index: ps/trunk/source/gui/CSlider.cpp =================================================================== --- ps/trunk/source/gui/CSlider.cpp +++ ps/trunk/source/gui/CSlider.cpp @@ -61,6 +61,8 @@ void CSlider::HandleMessage(SGUIMessage& Message) { + IGUIObject::HandleMessage(Message); + switch (Message.type) { case GUIM_SETTINGS_UPDATED: Index: ps/trunk/source/gui/CText.h =================================================================== --- ps/trunk/source/gui/CText.h +++ ps/trunk/source/gui/CText.h @@ -26,7 +26,7 @@ /** * Text field that just displays static text. */ -class CText : public IGUIScrollBarOwner, public IGUITextOwner +class CText : public IGUIObject, public IGUIScrollBarOwner, public IGUITextOwner { GUI_OBJECT(CText) @@ -37,7 +37,12 @@ /** * @see IGUIObject#ResetStates() */ - virtual void ResetStates() { IGUIScrollBarOwner::ResetStates(); } + virtual void ResetStates(); + + /** + * @see IGUIObject#UpdateCachedSize() + */ + virtual void UpdateCachedSize(); /** * Test if mouse position is over an icon @@ -51,6 +56,8 @@ */ void SetupText(); + virtual void RegisterScriptFunctions(); + /** * @see IGUIObject#HandleMessage() */ @@ -62,6 +69,13 @@ virtual void Draw(); /** + * Script accessors to this GUI object. + */ + static JSFunctionSpec JSI_methods[]; + + static bool GetTextSize(JSContext* cx, uint argc, JS::Value* vp); + + /** * Placement of text. Ignored when scrollbars are active. */ CPos m_TextPos; Index: ps/trunk/source/gui/CText.cpp =================================================================== --- ps/trunk/source/gui/CText.cpp +++ ps/trunk/source/gui/CText.cpp @@ -22,11 +22,12 @@ #include "gui/CGUI.h" #include "gui/CGUIScrollBarVertical.h" #include "gui/CGUIText.h" +#include "scriptinterface/ScriptInterface.h" CText::CText(CGUI& pGUI) : IGUIObject(pGUI), - IGUIScrollBarOwner(pGUI), - IGUITextOwner(pGUI), + IGUIScrollBarOwner(*static_cast(this)), + IGUITextOwner(*static_cast(this)), m_BufferZone(), m_Caption(), m_CellID(), @@ -121,8 +122,21 @@ } } +void CText::ResetStates() +{ + IGUIObject::ResetStates(); + IGUIScrollBarOwner::ResetStates(); +} + +void CText::UpdateCachedSize() +{ + IGUIObject::UpdateCachedSize(); + IGUITextOwner::UpdateCachedSize(); +} + void CText::HandleMessage(SGUIMessage& Message) { + IGUIObject::HandleMessage(Message); IGUIScrollBarOwner::HandleMessage(Message); //IGUITextOwner::HandleMessage(Message); <== placed it after the switch instead! @@ -237,3 +251,34 @@ return false; } + +void CText::RegisterScriptFunctions() +{ + JSContext* cx = m_pGUI.GetScriptInterface()->GetContext(); + JSAutoRequest rq(cx); + JS_DefineFunctions(cx, m_JSObject, CText::JSI_methods); +} + +JSFunctionSpec CText::JSI_methods[] = +{ + JS_FN("getTextSize", CText::GetTextSize, 0, 0), + JS_FS_END +}; + +bool CText::GetTextSize(JSContext* cx, uint argc, JS::Value* vp) +{ + // No JSAutoRequest needed for these calls + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + CText* thisObj = ScriptInterface::GetPrivate(cx, args, &JSI_IGUIObject::JSI_class); + if (!thisObj) + { + JSAutoRequest rq(cx); + JS_ReportError(cx, "This is not a CText object!"); + return false; + } + + thisObj->UpdateText(); + + ScriptInterface::ToJSVal(cx, args.rval(), thisObj->m_GeneratedTexts[0].GetSize()); + return true; +} Index: ps/trunk/source/gui/CTooltip.h =================================================================== --- ps/trunk/source/gui/CTooltip.h +++ ps/trunk/source/gui/CTooltip.h @@ -25,7 +25,7 @@ /** * Dynamic tooltips. Similar to CText. */ -class CTooltip : public IGUITextOwner +class CTooltip : public IGUIObject, public IGUITextOwner { GUI_OBJECT(CTooltip) @@ -37,6 +37,11 @@ void SetupText(); /** + * @see IGUIObject#UpdateCachedSize() + */ + void UpdateCachedSize(); + + /** * @see IGUIObject#HandleMessage() */ virtual void HandleMessage(SGUIMessage& Message); Index: ps/trunk/source/gui/CTooltip.cpp =================================================================== --- ps/trunk/source/gui/CTooltip.cpp +++ ps/trunk/source/gui/CTooltip.cpp @@ -27,7 +27,7 @@ CTooltip::CTooltip(CGUI& pGUI) : IGUIObject(pGUI), - IGUITextOwner(pGUI), + IGUITextOwner(*static_cast(this)), m_BufferZone(), m_Caption(), m_Font(), @@ -133,8 +133,15 @@ SetSetting("size", size, true); } +void CTooltip::UpdateCachedSize() +{ + IGUIObject::UpdateCachedSize(); + IGUITextOwner::UpdateCachedSize(); +} + void CTooltip::HandleMessage(SGUIMessage& Message) { + IGUIObject::HandleMessage(Message); IGUITextOwner::HandleMessage(Message); } Index: ps/trunk/source/gui/GUITooltip.cpp =================================================================== --- ps/trunk/source/gui/GUITooltip.cpp +++ ps/trunk/source/gui/GUITooltip.cpp @@ -117,7 +117,7 @@ if (style.empty()) return; - // Must be a CTooltip*, but we avoid dynamic_cast + // Must be a CTooltip* IGUIObject* tooltipobj = pGUI.FindObjectByName("__tooltip_" + style); if (!tooltipobj || !tooltipobj->SettingExists("use_object")) { @@ -172,7 +172,7 @@ if (style.empty()) return; - // Must be a CTooltip*, but we avoid dynamic_cast + // Must be a CTooltip* IGUIObject* tooltipobj = pGUI.FindObjectByName("__tooltip_" + style); if (!tooltipobj || !tooltipobj->SettingExists("use_object") || !tooltipobj->SettingExists("hide_object")) { @@ -204,7 +204,7 @@ static i32 GetTooltipDelay(const CStr& style, CGUI& pGUI) { - // Must be a CTooltip*, but we avoid dynamic_cast + // Must be a CTooltip* IGUIObject* tooltipobj = pGUI.FindObjectByName("__tooltip_" + style); if (!tooltipobj) Index: ps/trunk/source/gui/IGUIButtonBehavior.h =================================================================== --- ps/trunk/source/gui/IGUIButtonBehavior.h +++ ps/trunk/source/gui/IGUIButtonBehavior.h @@ -35,10 +35,12 @@ * Can be used with multiple inheritance alongside * IGUISettingsObject and such. */ -class IGUIButtonBehavior : virtual public IGUIObject +class IGUIButtonBehavior { + NONCOPYABLE(IGUIButtonBehavior); + public: - IGUIButtonBehavior(CGUI& pGUI); + IGUIButtonBehavior(IGUIObject& pObject); virtual ~IGUIButtonBehavior(); /** @@ -61,13 +63,7 @@ /** * @see IGUIObject#ResetStates() */ - virtual void ResetStates() - { - // Notify the gui that we aren't hovered anymore - UpdateMouseOver(nullptr); - m_Pressed = false; - m_PressedRight = false; - } + virtual void ResetStates(); /** * Everybody knows how a button works, you don't simply press it, @@ -85,6 +81,13 @@ CStrW m_SoundLeave; CStrW m_SoundPressed; CStrW m_SoundReleased; + +private: + /** + * Reference to the IGUIObject. + * Private, because we don't want to inherit it in multiple classes. + */ + IGUIObject& m_pObject; }; #endif // INCLUDED_IGUIBUTTONBEHAVIOR Index: ps/trunk/source/gui/IGUIButtonBehavior.cpp =================================================================== --- ps/trunk/source/gui/IGUIButtonBehavior.cpp +++ ps/trunk/source/gui/IGUIButtonBehavior.cpp @@ -19,11 +19,10 @@ #include "IGUIButtonBehavior.h" -#include "gui/CGUI.h" #include "gui/CGUISprite.h" -IGUIButtonBehavior::IGUIButtonBehavior(CGUI& pGUI) - : IGUIObject(pGUI), +IGUIButtonBehavior::IGUIButtonBehavior(IGUIObject& pObject) + : m_pObject(pObject), m_Pressed(), m_PressedRight(), m_SoundDisabled(), @@ -32,94 +31,100 @@ m_SoundPressed(), m_SoundReleased() { - RegisterSetting("sound_disabled", m_SoundDisabled); - RegisterSetting("sound_enter", m_SoundEnter); - RegisterSetting("sound_leave", m_SoundLeave); - RegisterSetting("sound_pressed", m_SoundPressed); - RegisterSetting("sound_released", m_SoundReleased); + 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() { } +void IGUIButtonBehavior::ResetStates() +{ + m_Pressed = false; + m_PressedRight = false; +} + void IGUIButtonBehavior::HandleMessage(SGUIMessage& Message) { // TODO Gee: easier access functions switch (Message.type) { case GUIM_MOUSE_ENTER: - if (m_Enabled) - PlaySound(m_SoundEnter); + if (m_pObject.IsEnabled()) + m_pObject.PlaySound(m_SoundEnter); break; case GUIM_MOUSE_LEAVE: - if (m_Enabled) - PlaySound(m_SoundLeave); + if (m_pObject.IsEnabled()) + m_pObject.PlaySound(m_SoundLeave); break; case GUIM_MOUSE_DBLCLICK_LEFT: - if (!m_Enabled) + if (!m_pObject.IsEnabled()) break; // Since GUIM_MOUSE_PRESS_LEFT also gets called twice in a // doubleclick event, we let it handle playing sounds. - SendEvent(GUIM_DOUBLE_PRESSED, "doublepress"); + m_pObject.SendEvent(GUIM_DOUBLE_PRESSED, "doublepress"); break; case GUIM_MOUSE_PRESS_LEFT: - if (!m_Enabled) + if (!m_pObject.IsEnabled()) { - PlaySound(m_SoundDisabled); + m_pObject.PlaySound(m_SoundDisabled); break; } - PlaySound(m_SoundPressed); - SendEvent(GUIM_PRESSED, "press"); + m_pObject.PlaySound(m_SoundPressed); + m_pObject.SendEvent(GUIM_PRESSED, "press"); m_Pressed = true; break; case GUIM_MOUSE_DBLCLICK_RIGHT: - if (!m_Enabled) + if (!m_pObject.IsEnabled()) break; // Since GUIM_MOUSE_PRESS_RIGHT also gets called twice in a // doubleclick event, we let it handle playing sounds. - SendEvent(GUIM_DOUBLE_PRESSED_MOUSE_RIGHT, "doublepressright"); + m_pObject.SendEvent(GUIM_DOUBLE_PRESSED_MOUSE_RIGHT, "doublepressright"); break; case GUIM_MOUSE_PRESS_RIGHT: - if (!m_Enabled) + if (!m_pObject.IsEnabled()) { - PlaySound(m_SoundDisabled); + m_pObject.PlaySound(m_SoundDisabled); break; } // Button was right-clicked - PlaySound(m_SoundPressed); - SendEvent(GUIM_PRESSED_MOUSE_RIGHT, "pressright"); + m_pObject.PlaySound(m_SoundPressed); + m_pObject.SendEvent(GUIM_PRESSED_MOUSE_RIGHT, "pressright"); m_PressedRight = true; break; case GUIM_MOUSE_RELEASE_RIGHT: - if (!m_Enabled) + if (!m_pObject.IsEnabled()) break; if (m_PressedRight) { m_PressedRight = false; - PlaySound(m_SoundReleased); + m_pObject.PlaySound(m_SoundReleased); } break; case GUIM_MOUSE_RELEASE_LEFT: - if (!m_Enabled) + if (!m_pObject.IsEnabled()) break; if (m_Pressed) { m_Pressed = false; - PlaySound(m_SoundReleased); + m_pObject.PlaySound(m_SoundReleased); } break; @@ -130,10 +135,10 @@ const CGUISpriteInstance& IGUIButtonBehavior::GetButtonSprite(const CGUISpriteInstance& sprite, const CGUISpriteInstance& sprite_over, const CGUISpriteInstance& sprite_pressed, const CGUISpriteInstance& sprite_disabled) const { - if (!m_Enabled) + if (!m_pObject.IsEnabled()) return sprite_disabled || sprite; - if (!m_MouseHovering) + if (!m_pObject.IsMouseOver()) return sprite; if (m_Pressed) Index: ps/trunk/source/gui/IGUIObject.h =================================================================== --- ps/trunk/source/gui/IGUIObject.h +++ ps/trunk/source/gui/IGUIObject.h @@ -130,6 +130,16 @@ //@{ /** + * Registers the given setting variables 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); + + /** * Returns whether there is a setting with the given name registered. * * @param Setting setting name @@ -172,6 +182,11 @@ void SetSetting(const CStr& Setting, const T& Value, const bool SendMessage); /** + * Returns whether this object is set to be hidden or ghost. + */ + bool IsEnabled() const; + + /** * Returns whether this is object is set to be hidden. */ bool IsHidden() const; @@ -182,6 +197,20 @@ bool IsHiddenOrGhost() const; /** + * Retrieves the configured sound filename from the given setting name and plays that once. + */ + void PlaySound(const CStrW& soundPath) const; + + /** + * Send event to this GUI object (HandleMessage and ScriptEvent) + * + * @param type Type of GUI message to be handled + * @param EventName String representation of event name + * @return IN_HANDLED if event was handled, or IN_PASS if skipped + */ + InReaction SendEvent(EGUIMessageType type, const CStr& EventName); + + /** * All sizes are relative to resolution, and the calculation * is not wanted in real time, therefore it is cached, update * the cached size with this function. @@ -203,10 +232,9 @@ void RegisterScriptHandler(const CStr& Action, const CStr& Code, CGUI& pGUI); /** - * Creates the JS Object representing this page upon first use. - * Can be overridden by derived classes to extend it. + * Inheriting classes may append JS functions to the JS object representing this class. */ - virtual void CreateJSObject(); + virtual void RegisterScriptFunctions() {} /** * Retrieves the JSObject representing this GUI object. @@ -227,16 +255,6 @@ //-------------------------------------------------------- //@{ - /** - * Registers the given setting variables 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); - public: /** * This function is called with different messages @@ -318,11 +336,6 @@ */ void SetFocus(); - /** - * Workaround to avoid a dynamic_cast which can be 80 times slower than this. - */ - virtual void* GetTextOwner() { return nullptr; } - protected: /** * Check if object is focused. @@ -367,15 +380,6 @@ CRect m_CachedActualSize; /** - * Send event to this GUI object (HandleMessage and ScriptEvent) - * - * @param type Type of GUI message to be handled - * @param EventName String representation of event name - * @return IN_HANDLED if event was handled, or IN_PASS if skipped - */ - InReaction SendEvent(EGUIMessageType type, const CStr& EventName); - - /** * Execute the script for a particular action. * Does nothing if no script has been registered for that action. * The mouse coordinates will be passed as the first argument. @@ -404,11 +408,6 @@ */ void UpdateMouseOver(IGUIObject* const& pMouseOver); - /** - * Retrieves the configured sound filename from the given setting name and plays that once. - */ - void PlaySound(const CStrW& soundPath) const; - //@} private: //-------------------------------------------------------- @@ -417,6 +416,11 @@ //@{ /** + * Creates the JS object representing this page upon first use. + */ + void CreateJSObject(); + + /** * Updates some internal data depending on the setting changed. */ void PreSettingChange(const CStr& Setting); Index: ps/trunk/source/gui/IGUIObject.cpp =================================================================== --- ps/trunk/source/gui/IGUIObject.cpp +++ ps/trunk/source/gui/IGUIObject.cpp @@ -453,6 +453,8 @@ m_JSObject.init(cx, m_pGUI.GetScriptInterface()->CreateCustomObject("GUIObject")); JS_SetPrivate(m_JSObject.get(), this); + + RegisterScriptFunctions(); } JSObject* IGUIObject::GetJSObject() @@ -465,6 +467,11 @@ return m_JSObject.get(); } +bool IGUIObject::IsEnabled() const +{ + return m_Enabled; +} + bool IGUIObject::IsHidden() const { return m_Hidden; Index: ps/trunk/source/gui/IGUIScrollBarOwner.h =================================================================== --- ps/trunk/source/gui/IGUIScrollBarOwner.h +++ ps/trunk/source/gui/IGUIScrollBarOwner.h @@ -29,12 +29,14 @@ * Base-class this if you want an object to contain * one, or several, scroll-bars. */ -class IGUIScrollBarOwner : virtual public IGUIObject +class IGUIScrollBarOwner { + NONCOPYABLE(IGUIScrollBarOwner); + friend class IGUIScrollBar; public: - IGUIScrollBarOwner(CGUI& pGUI); + IGUIScrollBarOwner(IGUIObject& m_pObject); virtual ~IGUIScrollBarOwner(); virtual void Draw(); @@ -75,12 +77,18 @@ virtual float GetScrollBarPos(const int index) const; protected: - /** * Predominately you will only have one, but you can have * as many as you like. */ std::vector m_ScrollBars; + +private: + /** + * Reference to the IGUIObject. + * Private, because we don't want to inherit it in multiple classes. + */ + IGUIObject& m_pObject; }; #endif // INCLUDED_IGUISCROLLBAROWNER Index: ps/trunk/source/gui/IGUIScrollBarOwner.cpp =================================================================== --- ps/trunk/source/gui/IGUIScrollBarOwner.cpp +++ ps/trunk/source/gui/IGUIScrollBarOwner.cpp @@ -22,8 +22,8 @@ #include "gui/CGUI.h" #include "gui/IGUIScrollBar.h" -IGUIScrollBarOwner::IGUIScrollBarOwner(CGUI& pGUI) - : IGUIObject(pGUI) +IGUIScrollBarOwner::IGUIScrollBarOwner(IGUIObject& pObject) + : m_pObject(pObject) { } @@ -35,8 +35,6 @@ void IGUIScrollBarOwner::ResetStates() { - IGUIObject::ResetStates(); - for (IGUIScrollBar* const& sb : m_ScrollBars) sb->SetBarPressed(false); } @@ -49,7 +47,7 @@ const SGUIScrollBarStyle* IGUIScrollBarOwner::GetScrollBarStyle(const CStr& style) const { - return m_pGUI.GetScrollBarStyle(style); + return m_pObject.GetGUI().GetScrollBarStyle(style); } void IGUIScrollBarOwner::HandleMessage(SGUIMessage& msg) Index: ps/trunk/source/gui/IGUITextOwner.h =================================================================== --- ps/trunk/source/gui/IGUITextOwner.h +++ ps/trunk/source/gui/IGUITextOwner.h @@ -31,7 +31,6 @@ #define INCLUDED_IGUITEXTOWNER #include "gui/IGUIObject.h" -#include "gui/scripting/JSInterface_IGUITextOwner.h" #include @@ -42,12 +41,12 @@ /** * Framework for handling Output text. */ -class IGUITextOwner : virtual public IGUIObject +class IGUITextOwner { - friend bool JSI_IGUITextOwner::GetTextSize(JSContext* cx, uint argc, JS::Value* vp); + NONCOPYABLE(IGUITextOwner); public: - IGUITextOwner(CGUI& pGUI); + IGUITextOwner(IGUIObject& pObject); virtual ~IGUITextOwner(); /** @@ -61,11 +60,6 @@ CGUIText& AddText(const CGUIString& Text, const CStrW& Font, const float& Width, const float& BufferZone); /** - * Subscribe the custom JS methods. - */ - void CreateJSObject(); - - /** * @see IGUIObject#HandleMessage() */ virtual void HandleMessage(SGUIMessage& Message); @@ -92,19 +86,18 @@ */ virtual bool MouseOverIcon(); - /** - * Workaround to avoid a dynamic_cast which can be 80 times slower than this. - */ - virtual void* GetTextOwner() { return this; } - protected: - /** * Setup texts. Functions that sets up all texts when changes have been made. */ virtual void SetupText() = 0; /** + * Regenerate the text in case it is invalid. Should only be called when inevitable. + */ + virtual void UpdateText(); + + /** * Whether the cached text is currently valid (if not then SetupText will be called by Draw) */ bool m_GeneratedTextsValid; @@ -119,10 +112,12 @@ */ void CalculateTextPosition(CRect& ObjSize, CPos& TextPos, CGUIText& Text); +private: /** - * Calculate the size of the first generated text. + * Reference to the IGUIObject. + * Private, because we don't want to inherit it in multiple classes. */ - CSize CalculateTextSize(); + IGUIObject& m_pObject; }; #endif // INCLUDED_IGUITEXTOWNER Index: ps/trunk/source/gui/IGUITextOwner.cpp =================================================================== --- ps/trunk/source/gui/IGUITextOwner.cpp +++ ps/trunk/source/gui/IGUITextOwner.cpp @@ -21,12 +21,12 @@ #include "gui/CGUI.h" #include "gui/CGUIString.h" -#include "gui/scripting/JSInterface_IGUITextOwner.h" #include -IGUITextOwner::IGUITextOwner(CGUI& pGUI) - : IGUIObject(pGUI), m_GeneratedTextsValid(false) +IGUITextOwner::IGUITextOwner(IGUIObject& pObject) + : m_pObject(pObject), + m_GeneratedTextsValid() { } @@ -34,14 +34,6 @@ { } -void IGUITextOwner::CreateJSObject() -{ - IGUIObject::CreateJSObject(); - - JSI_IGUITextOwner::RegisterScriptFunctions( - m_pGUI.GetScriptInterface()->GetContext(), m_JSObject); -} - CGUIText& IGUITextOwner::AddText() { m_GeneratedTexts.emplace_back(); @@ -51,7 +43,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_pGUI, Text, Font, Width, BufferZone, this); + m_GeneratedTexts.emplace_back(m_pObject.GetGUI(), Text, Font, Width, BufferZone, &m_pObject); return m_GeneratedTexts.back(); } @@ -82,24 +74,26 @@ void IGUITextOwner::UpdateCachedSize() { - // If an ancestor's size changed, this will let us intercept the change and // update our text positions - - IGUIObject::UpdateCachedSize(); m_GeneratedTextsValid = false; } -void IGUITextOwner::DrawText(size_t index, const CGUIColor& color, const CPos& pos, float z, const CRect& clipping) +void IGUITextOwner::UpdateText() { if (!m_GeneratedTextsValid) { SetupText(); m_GeneratedTextsValid = true; } +} + +void IGUITextOwner::DrawText(size_t index, const CGUIColor& color, const CPos& pos, float z, const CRect& clipping) +{ + UpdateText(); ENSURE(index < m_GeneratedTexts.size() && "Trying to draw a Text Index within a IGUITextOwner that doesn't exist"); - m_GeneratedTexts.at(index).Draw(m_pGUI, color, pos, z, clipping); + m_GeneratedTexts.at(index).Draw(m_pObject.GetGUI(), color, pos, z, clipping); } void IGUITextOwner::CalculateTextPosition(CRect& ObjSize, CPos& TextPos, CGUIText& Text) @@ -108,7 +102,7 @@ // loop through all of the TextCall objects again. TextPos.x = ObjSize.left; - switch (GetSetting("text_valign")) + switch (m_pObject.GetSetting("text_valign")) { case EVAlign_Top: TextPos.y = ObjSize.top; @@ -126,21 +120,6 @@ } } -CSize IGUITextOwner::CalculateTextSize() -{ - if (!m_GeneratedTextsValid) - { - SetupText(); - m_GeneratedTextsValid = true; - } - - if (m_GeneratedTexts.empty()) - return CSize(); - - // GUI Object types that use multiple texts may override this function. - return m_GeneratedTexts[0].GetSize(); -} - bool IGUITextOwner::MouseOverIcon() { return false; Index: ps/trunk/source/gui/MiniMap.cpp =================================================================== --- ps/trunk/source/gui/MiniMap.cpp +++ ps/trunk/source/gui/MiniMap.cpp @@ -141,6 +141,7 @@ void CMiniMap::HandleMessage(SGUIMessage& Message) { + IGUIObject::HandleMessage(Message); switch (Message.type) { case GUIM_MOUSE_PRESS_LEFT: Index: ps/trunk/source/gui/scripting/JSInterface_IGUITextOwner.h =================================================================== --- ps/trunk/source/gui/scripting/JSInterface_IGUITextOwner.h +++ ps/trunk/source/gui/scripting/JSInterface_IGUITextOwner.h @@ -1,32 +0,0 @@ -/* Copyright (C) 2019 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#ifndef INCLUDED_JSI_IGUITEXTOWNER -#define INCLUDED_JSI_IGUITEXTOWNER - -#include "scriptinterface/ScriptInterface.h" - -namespace JSI_IGUITextOwner -{ - extern JSFunctionSpec JSI_methods[]; - - void RegisterScriptFunctions(JSContext* cx, JS::HandleObject obj); - - bool GetTextSize(JSContext* cx, uint argc, JS::Value* vp); -} - -#endif // INCLUDED_JSI_IGUITEXTOWNER Index: ps/trunk/source/gui/scripting/JSInterface_IGUITextOwner.cpp =================================================================== --- ps/trunk/source/gui/scripting/JSInterface_IGUITextOwner.cpp +++ ps/trunk/source/gui/scripting/JSInterface_IGUITextOwner.cpp @@ -1,55 +0,0 @@ -/* Copyright (C) 2019 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#include "precompiled.h" - -#include "JSInterface_IGUITextOwner.h" - -#include "gui/IGUITextOwner.h" -#include "scriptinterface/ScriptInterface.h" - -JSFunctionSpec JSI_IGUITextOwner::JSI_methods[] = -{ - JS_FN("getTextSize", JSI_IGUITextOwner::GetTextSize, 0, 0), - JS_FS_END -}; - -void JSI_IGUITextOwner::RegisterScriptFunctions(JSContext* cx, JS::HandleObject obj) -{ - JS_DefineFunctions(cx, obj, JSI_methods); -} - -bool JSI_IGUITextOwner::GetTextSize(JSContext* cx, uint argc, JS::Value* vp) -{ - // No JSAutoRequest needed for these calls - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - IGUIObject* obj = ScriptInterface::GetPrivate(cx, args, &JSI_IGUIObject::JSI_class); - if (!obj) - return false; - - // Avoid dynamic_cast for performance reasons - IGUITextOwner* objText = static_cast(obj->GetTextOwner()); - if (!objText) - { - JSAutoRequest rq(cx); - JS_ReportError(cx, "This IGUIObject is not an IGUITextOwner!"); - return false; - } - - ScriptInterface::ToJSVal(cx, args.rval(), objText->CalculateTextSize()); - return true; -}