Index: source/gui/CButton.h =================================================================== --- source/gui/CButton.h +++ source/gui/CButton.h @@ -31,7 +31,7 @@ GUI_OBJECT(CButton) public: - CButton(); + CButton(CGUI* guiPage); virtual ~CButton(); /** Index: source/gui/CButton.cpp =================================================================== --- source/gui/CButton.cpp +++ source/gui/CButton.cpp @@ -22,7 +22,8 @@ #include "gui/CGUIColor.h" #include "lib/ogl.h" -CButton::CButton() +CButton::CButton(CGUI* guiPage) + : IGUIObject(guiPage) { AddSetting(GUIST_float, "buffer_zone"); AddSetting(GUIST_CGUIString, "caption"); Index: source/gui/CChart.h =================================================================== --- source/gui/CChart.h +++ source/gui/CChart.h @@ -27,6 +27,8 @@ struct CChartData { + CChartData(const CGUIColor& color) : m_Color(color) {}; + CGUIColor m_Color; std::vector m_Points; }; @@ -41,7 +43,7 @@ GUI_OBJECT(CChart) public: - CChart(); + CChart(CGUI* guiPage); virtual ~CChart(); protected: Index: source/gui/CChart.cpp =================================================================== --- source/gui/CChart.cpp +++ source/gui/CChart.cpp @@ -29,7 +29,8 @@ #include -CChart::CChart() +CChart::CChart(CGUI* guiPage) + : IGUIObject(guiPage) { AddSetting(GUIST_CGUIColor, "axis_color"); AddSetting(GUIST_float, "axis_width"); @@ -105,9 +106,9 @@ ADD(m_CachedActualSize.left, m_CachedActualSize.top); ADD(rect.left, rect.top - m_AxisWidth); #undef ADD - CGUIColor axis_color(0.5f, 0.5f, 0.5f, 1.f); - GUI::GetSetting(this, "axis_color", axis_color); - DrawTriangleStrip(shader, axis_color, vertices); + CGUIColor* axis_color = nullptr; + GUI::GetSettingPointer(this, "axis_color", axis_color); + DrawTriangleStrip(shader, *axis_color, vertices); } void CChart::Draw() @@ -170,8 +171,10 @@ // Reset depth mask glDepthMask(1); + CGUIColor color(GetGUI(), CColor(1.f, 1.f, 1.f, 1.f)); + for (size_t i = 0; i < m_TextPositions.size(); ++i) - DrawText(i, CGUIColor(1.f, 1.f, 1.f, 1.f), m_TextPositions[i], bz + 0.5f); + DrawText(i, color, m_TextPositions[i], bz + 0.5f); } CRect CChart::GetChartRect() const @@ -184,6 +187,9 @@ void CChart::UpdateSeries() { + if (!GetGUI()) + return; + CGUISeries* pSeries; GUI::GetSettingPointer(this, "series", pSeries); @@ -191,12 +197,12 @@ GUI::GetSettingPointer(this, "series_color", pSeriesColor); m_Series.clear(); - m_Series.resize(pSeries->m_Series.size()); + m_Series.resize(pSeries->m_Series.size(), CGUIColor(GetGUI())); for (size_t i = 0; i < pSeries->m_Series.size(); ++i) { CChartData& data = m_Series[i]; - if (i < pSeriesColor->m_Items.size() && !GUI::ParseColor(pSeriesColor->m_Items[i].GetOriginalString(), data.m_Color, 0)) + if (i < pSeriesColor->m_Items.size() && !GUI::ParseColor( pSeriesColor->m_Items[i].GetOriginalString(), data.m_Color, 0)) LOGWARNING("GUI: Error parsing 'series_color' (\"%s\")", utf8_from_wstring(pSeriesColor->m_Items[i].GetOriginalString())); data.m_Points = pSeries->m_Series[i]; Index: source/gui/CCheckBox.h =================================================================== --- source/gui/CCheckBox.h +++ source/gui/CCheckBox.h @@ -32,7 +32,7 @@ GUI_OBJECT(CCheckBox) public: - CCheckBox(); + CCheckBox(CGUI* guiPage); virtual ~CCheckBox(); /** Index: source/gui/CCheckBox.cpp =================================================================== --- source/gui/CCheckBox.cpp +++ source/gui/CCheckBox.cpp @@ -28,7 +28,8 @@ * TODO: Since there is no call to DrawText, the checkbox won't render any text. * Thus the font, caption, textcolor and other settings have no effect. */ -CCheckBox::CCheckBox() +CCheckBox::CCheckBox(CGUI* guiPage) + : IGUIObject(guiPage) { AddSetting(GUIST_float, "buffer_zone"); AddSetting(GUIST_CGUIString, "caption"); Index: source/gui/CDropDown.h =================================================================== --- source/gui/CDropDown.h +++ source/gui/CDropDown.h @@ -50,7 +50,7 @@ GUI_OBJECT(CDropDown) public: - CDropDown(); + CDropDown(CGUI* guiPage); virtual ~CDropDown(); // virtual void ResetStates() { IGUIButtonBehavior::ResetStates(); } Index: source/gui/CDropDown.cpp =================================================================== --- source/gui/CDropDown.cpp +++ source/gui/CDropDown.cpp @@ -26,8 +26,8 @@ #include "ps/CLogger.h" #include "soundmanager/ISoundManager.h" -CDropDown::CDropDown() - : m_Open(false), m_HideScrollBar(false), m_ElementHighlight(-1) +CDropDown::CDropDown(CGUI* guiPage) + : CList(guiPage), IGUIObject(guiPage), m_Open(false), m_HideScrollBar(false), m_ElementHighlight(-1) { AddSetting(GUIST_float, "button_width"); AddSetting(GUIST_float, "dropdown_size"); @@ -487,7 +487,6 @@ CGUISpriteInstance* sprite2; CGUISpriteInstance* sprite2_second; int cell_id, selected = 0; - CGUIColor color; bool enabled; GUI::GetSetting(this, "enabled", enabled); @@ -495,7 +494,9 @@ GUI::GetSettingPointer(this, "sprite2", sprite2); GUI::GetSetting(this, "cell_id", cell_id); GUI::GetSetting(this, "selected", selected); - GUI::GetSetting(this, enabled ? "textcolor_selected" : "textcolor_disabled", color); + + CGUIColor* color = nullptr; + GUI::GetSettingPointer(this, enabled ? "textcolor_selected" : "textcolor_disabled", color); GUI::GetSettingPointer(this, enabled ? "sprite" : "sprite_disabled", sprite); GetGUI()->DrawSprite(*sprite, cell_id, bz, m_CachedActualSize); @@ -530,7 +531,7 @@ m_CachedActualSize.right-button_width, m_CachedActualSize.bottom); CPos pos(m_CachedActualSize.left, m_CachedActualSize.top); - DrawText(selected, color, pos, bz+0.1f, cliparea); + DrawText(selected, *color, pos, bz+0.1f, cliparea); } bool* scrollbar = NULL; Index: source/gui/CGUI.h =================================================================== --- source/gui/CGUI.h +++ source/gui/CGUI.h @@ -49,7 +49,7 @@ class IGUIObject; class CGUISpriteInstance; struct SGUIText; -struct CGUIColor; +class CGUIColor; struct SGUIText; struct SGUIIcon; class CGUIString; @@ -71,7 +71,7 @@ private: // Private typedefs - typedef IGUIObject *(*ConstructObjectFunction)(); + typedef IGUIObject *(*ConstructObjectFunction)(CGUI*); public: CGUI(const shared_ptr& runtime); @@ -226,7 +226,7 @@ * @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. */ - SGUIText GenerateText(const CGUIString& Text, const CStrW& Font, const float& Width, const float& BufferZone, const IGUIObject* pObject = NULL); + SGUIText GenerateText(const CGUIString& Text, const CStrW& Font, const float& Width, const float& BufferZone, const IGUIObject* pObject = NULL) const; /** Index: source/gui/CGUI.cpp =================================================================== --- source/gui/CGUI.cpp +++ source/gui/CGUI.cpp @@ -288,10 +288,10 @@ m_ScriptInterface.reset(new ScriptInterface("Engine", "GUIPage", runtime)); m_ScriptInterface->SetCallbackData(this); + m_BaseObject = new CGUIDummyObject(this); + GuiScriptingInit(*m_ScriptInterface); m_ScriptInterface->LoadGlobalScripts(); - m_BaseObject = new CGUIDummyObject; - m_BaseObject->SetGUI(this); } CGUI::~CGUI() @@ -305,12 +305,10 @@ IGUIObject* CGUI::ConstructObject(const CStr& str) { if (m_ObjectTypes.count(str) > 0) - return (*m_ObjectTypes[str])(); - else - { - // Error reporting will be handled with the NULL return. - return NULL; - } + return (*m_ObjectTypes[str])(this); + + // Error reporting will be handled with the NULL return. + return NULL; } void CGUI::Initialize() @@ -355,13 +353,12 @@ void CGUI::DrawSprite(const CGUISpriteInstance& Sprite, int CellID, const float& Z, const CRect& Rect, const CRect& UNUSED(Clipping)) { - // If the sprite doesn't exist (name == ""), don't bother drawing anything if (Sprite.IsEmpty()) return; // TODO: Clipping? - Sprite.Draw(Rect, CellID, m_Sprites, Z); + Sprite.Draw(this, Rect, CellID, m_Sprites, Z); } void CGUI::Destroy() @@ -401,9 +398,6 @@ { try { - // Add CGUI pointer - GUI::RecurseObject(0, pObject, &IGUIObject::SetGUI, this); - m_BaseObject->AddChild(pObject); // Cache tree @@ -528,7 +522,7 @@ } }; -SGUIText CGUI::GenerateText(const CGUIString& string, const CStrW& FontW, const float& Width, const float& BufferZone, const IGUIObject* pObject) +SGUIText CGUI::GenerateText(const CGUIString& string, const CStrW& FontW, const float& Width, const float& BufferZone, const IGUIObject* pObject) const { SGUIText Text; @@ -1148,8 +1142,6 @@ CStr action = CStr(child.GetAttributes().GetNamedItem(attr_on)); - // We need to set the GUI this object belongs to because RegisterScriptHandler requires an associated GUI. - object->SetGUI(this); object->RegisterScriptHandler(action.LowerCase(), code, this); } else if (element_name == elmt_repeat) @@ -1413,7 +1405,7 @@ LOGERROR("GUI must not have more than one "); else { - effects = new SGUIImageEffects; + effects = new SGUIImageEffects(this); Xeromyces_ReadEffects(child, pFile, *effects); } } @@ -1435,7 +1427,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite& parent) { - SGUIImage* Image = new SGUIImage; + SGUIImage* Image = new SGUIImage(this); Image->m_TextureSize = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); Image->m_Size = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); @@ -1520,7 +1512,7 @@ } else if (attr_name == "backcolor") { - CGUIColor color; + CGUIColor color(this); if (!GUI::ParseString(attr_value, color)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); else @@ -1528,7 +1520,7 @@ } else if (attr_name == "bordercolor") { - CGUIColor color; + CGUIColor color(this); if (!GUI::ParseString(attr_value, color)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); else @@ -1556,7 +1548,7 @@ LOGERROR("GUI must not have more than one "); else { - Image->m_Effects = new SGUIImageEffects; + Image->m_Effects = new SGUIImageEffects(this); Xeromyces_ReadEffects(child, pFile, *Image->m_Effects); } } @@ -1576,7 +1568,7 @@ if (attr_name == "add_color") { - CGUIColor color; + CGUIColor color(this); if (!GUI::ParseColor(attr_value, color, 0)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); else effects.m_AddColor = color; @@ -1732,7 +1724,7 @@ void CGUI::Xeromyces_ReadTooltip(XMBElement Element, CXeromyces* pFile) { - IGUIObject* object = new CTooltip; + IGUIObject* object = new CTooltip(this); for (XMBAttribute attr : Element.GetAttributes()) { @@ -1752,7 +1744,7 @@ { XMBAttributeList attributes = Element.GetAttributes(); - CGUIColor color; + CGUIColor color(this); CStr name = attributes.GetNamedItem(pFile->GetAttributeID("name")); // Try parsing value @@ -1767,5 +1759,5 @@ return; } - m_PreDefinedColors[name] = color; + m_PreDefinedColors.emplace(name, color); } Index: source/gui/CGUIColor.h =================================================================== --- source/gui/CGUIColor.h +++ source/gui/CGUIColor.h @@ -19,18 +19,23 @@ #define INCLUDED_GUICOLOR #include "graphics/Color.h" -#include "gui/GUIManager.h" + +class CGUI; +class CStr8; /** * Same as the CColor class, but this one can also parse colors predefined in the GUI page (such as "yellow"). */ -struct CGUIColor : public CColor +class CGUIColor : public CColor { - using CColor::CColor; +public: + CGUIColor(const CGUI* mGUI); + CGUIColor(const CGUI* mGUI, const CColor& color); + + bool ParseString(const CStr8& value, int defaultAlpha = 255); - bool ParseString(const CStr& value, int defaultAlpha = 255) - { - return g_GUI->GetPreDefinedColor(value, *this) || CColor::ParseString(value, defaultAlpha); - } +private: + const CGUI* m_GUI; }; + #endif // INCLUDED_GUICOLOR Index: source/gui/CGUIColor.cpp =================================================================== --- /dev/null +++ source/gui/CGUIColor.cpp @@ -0,0 +1,36 @@ +/* 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 "CGUI.h" +#include "CGUIColor.h" + +CGUIColor::CGUIColor(const CGUI* mGUI) +: m_GUI(mGUI), CColor() +{ +} + +CGUIColor::CGUIColor(const CGUI* mGUI, const CColor& color) +: m_GUI(mGUI), CColor(color) +{ +} + +bool CGUIColor::ParseString(const CStr8& value, int defaultAlpha) +{ + return m_GUI->GetPreDefinedColor(value, *this) || CColor::ParseString(value, defaultAlpha); +}; Index: source/gui/CGUISprite.h =================================================================== --- source/gui/CGUISprite.h +++ source/gui/CGUISprite.h @@ -43,7 +43,10 @@ struct SGUIImageEffects { - SGUIImageEffects() : m_Greyscale(false) {} + SGUIImageEffects(const CGUI* guiPage) + : m_Greyscale(false), m_AddColor(CGUIColor(guiPage)), m_SolidColor(CGUIColor(guiPage)) + {} + CGUIColor m_AddColor; CGUIColor m_SolidColor; bool m_Greyscale; @@ -57,9 +60,10 @@ { NONCOPYABLE(SGUIImage); public: - SGUIImage() : + SGUIImage(const CGUI* mGUI) : m_FixedHAspectRatio(0.f), m_RoundCoordinates(true), m_WrapMode(GL_REPEAT), - m_Effects(NULL), m_Border(false), m_DeltaZ(0.f) + m_Effects(NULL), m_Border(false), m_DeltaZ(0.f), + m_BackColor(CGUIColor(mGUI)), m_BorderColor(CGUIColor(mGUI)) { } @@ -166,7 +170,7 @@ CGUISpriteInstance(CGUISpriteInstance&&) = default; CGUISpriteInstance& operator=(CGUISpriteInstance&&) = default; - void Draw(const CRect& Size, int CellID, std::map& Sprites, float Z) const; + void Draw(CGUI* guiPage, const CRect& Size, int CellID, std::map& Sprites, float Z) const; bool IsEmpty() const; const CStr& GetName() const { return m_SpriteName; } void SetName(const CStr& SpriteName); Index: source/gui/CGUISprite.cpp =================================================================== --- source/gui/CGUISprite.cpp +++ source/gui/CGUISprite.cpp @@ -30,11 +30,11 @@ m_Images.push_back(image); } -void CGUISpriteInstance::Draw(const CRect& Size, int CellID, std::map& Sprites, float Z) const +void CGUISpriteInstance::Draw(CGUI* guiPage, const CRect& Size, int CellID, std::map& Sprites, float Z) const { if (m_CachedSize != Size || m_CachedCellID != CellID) { - GUIRenderer::UpdateDrawCallCache(m_DrawCallCache, m_SpriteName, Size, CellID, Sprites); + GUIRenderer::UpdateDrawCallCache(guiPage, m_DrawCallCache, m_SpriteName, Size, CellID, Sprites); m_CachedSize = Size; m_CachedCellID = CellID; } Index: source/gui/CImage.h =================================================================== --- source/gui/CImage.h +++ source/gui/CImage.h @@ -37,7 +37,7 @@ GUI_OBJECT(CImage) public: - CImage(); + CImage(CGUI* guiPage); virtual ~CImage(); protected: Index: source/gui/CImage.cpp =================================================================== --- source/gui/CImage.cpp +++ source/gui/CImage.cpp @@ -23,7 +23,8 @@ #include "lib/ogl.h" -CImage::CImage() +CImage::CImage(CGUI* guiPage) + : IGUIObject(guiPage) { AddSetting(GUIST_CGUISpriteInstance, "sprite"); AddSetting(GUIST_int, "cell_id"); Index: source/gui/CInput.h =================================================================== --- source/gui/CInput.h +++ source/gui/CInput.h @@ -38,7 +38,7 @@ struct SRow; public: - CInput(); + CInput(CGUI* guiPage); virtual ~CInput(); /** Index: source/gui/CInput.cpp =================================================================== --- source/gui/CInput.cpp +++ source/gui/CInput.cpp @@ -39,8 +39,9 @@ extern int g_yres; -CInput::CInput() - : m_iBufferPos(-1), m_iBufferPos_Tail(-1), m_SelectingText(false), m_HorizontalScroll(0.f), +CInput::CInput(CGUI* guiPage) + : IGUIObject(guiPage), IGUIScrollBarOwner(guiPage), + m_iBufferPos(-1), m_iBufferPos_Tail(-1), m_SelectingText(false), m_HorizontalScroll(0.f), m_PrevTime(0.0), m_CursorVisState(true), m_CursorBlinkRate(0.5), m_ComposingText(false), m_iComposedLength(0), m_iComposedPos(0), m_iInsertPos(0), m_Readonly(false) { @@ -1173,12 +1174,15 @@ if (!GetGUI()) return; - CStrW font_name_w; - CGUIColor color, color_selected; - GUI::GetSetting(this, "font", font_name_w); - GUI::GetSetting(this, "textcolor", color); - GUI::GetSetting(this, "textcolor_selected", color_selected); - CStrIntern font_name(font_name_w.ToUTF8()); + CStrW* font_name_w; + GUI::GetSettingPointer(this, "font", font_name_w); + CStrIntern font_name(font_name_w->ToUTF8()); + + CGUIColor* color = nullptr; + GUI::GetSettingPointer(this, "textcolor", color); + + CGUIColor* color_selected = nullptr; + GUI::GetSettingPointer(this, "textcolor_selected", color_selected); // Get pointer of caption, it might be very large, and we don't // want to copy it continuously. @@ -1420,7 +1424,7 @@ buffered_y = -scroll; // Setup initial color (then it might change and change back, when drawing selected area) - textRenderer.Color(color); + textRenderer.Color(*color); tech->BeginPass(); @@ -1465,7 +1469,7 @@ if (SelectingText() && it->m_ListStart + i == VirtualTo) { using_selected_color = false; - textRenderer.Color(color); + textRenderer.Color(*color); } // selecting only one, then we need only to draw a cursor. @@ -1479,7 +1483,7 @@ !using_selected_color) { using_selected_color = true; - textRenderer.Color(color_selected); + textRenderer.Color(*color_selected); } if (i != (int)it->m_ListOfX.size()) @@ -1498,12 +1502,12 @@ if (it->m_ListStart + (int)it->m_ListOfX.size() == m_iBufferPos) { - textRenderer.Color(color); + textRenderer.Color(*color); if (m_CursorVisState) textRenderer.PutAdvance(L"_"); if (using_selected_color) - textRenderer.Color(color_selected); + textRenderer.Color(*color_selected); } textRenderer.SetTransform(savedTransform); Index: source/gui/CList.h =================================================================== --- source/gui/CList.h +++ source/gui/CList.h @@ -34,7 +34,7 @@ GUI_OBJECT(CList) public: - CList(); + CList(CGUI* guiPage); virtual ~CList(); /** Index: source/gui/CList.cpp =================================================================== --- source/gui/CList.cpp +++ source/gui/CList.cpp @@ -27,8 +27,9 @@ #include "soundmanager/ISoundManager.h" -CList::CList() - : m_Modified(false), m_PrevSelectedItem(-1), m_LastItemClickTime(0) +CList::CList(CGUI* guiPage) + : IGUIObject(guiPage), IGUIScrollBarOwner(guiPage), + m_Modified(false), m_PrevSelectedItem(-1), m_LastItemClickTime(0) { // Add sprite_disabled! TODO @@ -384,8 +385,8 @@ } } - CGUIColor color; - GUI::GetSetting(this, _textcolor, color); + CGUIColor* color; + GUI::GetSettingPointer(this, _textcolor, color); for (size_t i = 0; i < pList->m_Items.size(); ++i) { @@ -407,7 +408,7 @@ cliparea.left = GetScrollBar(0).GetOuterRect().right; } - DrawText(i, color, rect.TopLeft() - CPos(0.f, scroll - m_ItemsYPositions[i]), bz+0.1f, cliparea); + DrawText(i, *color, rect.TopLeft() - CPos(0.f, scroll - m_ItemsYPositions[i]), bz+0.1f, cliparea); } } } Index: source/gui/COList.h =================================================================== --- source/gui/COList.h +++ source/gui/COList.h @@ -25,11 +25,12 @@ */ struct COListColumn { + COListColumn(const CGUI* mGUI) : m_TextColor(CGUIColor(mGUI)) {}; + CGUIColor m_TextColor; CStr m_Id; float m_Width; CStrW m_Heading; - }; /** @@ -45,7 +46,7 @@ GUI_OBJECT(COList) public: - COList(); + COList(CGUI* guiPage); protected: void SetupText(); Index: source/gui/COList.cpp =================================================================== --- source/gui/COList.cpp +++ source/gui/COList.cpp @@ -27,7 +27,8 @@ const float SORT_SPRITE_DIM = 16.0f; const CPos COLUMN_SHIFT = CPos(0, 4); -COList::COList() : CList() +COList::COList(CGUI* guiPage) + : CList(guiPage), IGUIObject(guiPage) { AddSetting(GUIST_CGUISpriteInstance, "sprite_heading"); AddSetting(GUIST_bool, "sortable"); // The actual sorting is done in JS for more versatility @@ -222,7 +223,7 @@ } else if (child.GetNodeName() == elmt_column) { - COListColumn column; + COListColumn column(GetGUI()); bool hidden = false; for (XMBAttribute attr : child.GetAttributes()) @@ -232,7 +233,7 @@ if (attr_name == "color") { - CGUIColor color; + CGUIColor color(GetGUI()); if (!GUI::ParseString(attr_value.FromUTF8(), color)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); else @@ -394,8 +395,8 @@ int selectedColumnOrder; GUI::GetSetting(this, "selected_column_order", selectedColumnOrder); - CGUIColor color; - GUI::GetSetting(this, _textcolor, color); + CGUIColor* color; + GUI::GetSettingPointer(this, _textcolor, color); float xpos = 0; for (size_t col = 0; col < m_Columns.size(); ++col) @@ -433,7 +434,7 @@ } // Draw column header text - DrawText(col, color, leftTopCorner + COLUMN_SHIFT, bz + 0.1f, rect_head); + DrawText(col, *color, leftTopCorner + COLUMN_SHIFT, bz + 0.1f, rect_head); xpos += width; } Index: source/gui/CProgressBar.h =================================================================== --- source/gui/CProgressBar.h +++ source/gui/CProgressBar.h @@ -30,7 +30,7 @@ GUI_OBJECT(CProgressBar) public: - CProgressBar(); + CProgressBar(CGUI* guiPage); virtual ~CProgressBar(); protected: Index: source/gui/CProgressBar.cpp =================================================================== --- source/gui/CProgressBar.cpp +++ source/gui/CProgressBar.cpp @@ -22,7 +22,8 @@ #include "lib/ogl.h" -CProgressBar::CProgressBar() +CProgressBar::CProgressBar(CGUI* guiPage) + : IGUIObject(guiPage) { AddSetting(GUIST_CGUISpriteInstance, "sprite_background"); AddSetting(GUIST_CGUISpriteInstance, "sprite_bar"); Index: source/gui/CRadioButton.h =================================================================== --- source/gui/CRadioButton.h +++ source/gui/CRadioButton.h @@ -32,6 +32,8 @@ GUI_OBJECT(CRadioButton) public: + CRadioButton(CGUI* guiPage); + /** * @see IGUIObject#HandleMessage() */ Index: source/gui/CRadioButton.cpp =================================================================== --- source/gui/CRadioButton.cpp +++ source/gui/CRadioButton.cpp @@ -21,6 +21,11 @@ #include "GUI.h" +CRadioButton::CRadioButton(CGUI* guiPage) + : CCheckBox(guiPage), IGUIObject(guiPage) +{ +} + void CRadioButton::HandleMessage(SGUIMessage& Message) { // Important Index: source/gui/CSlider.h =================================================================== --- source/gui/CSlider.h +++ source/gui/CSlider.h @@ -26,7 +26,7 @@ GUI_OBJECT(CSlider) public: - CSlider(); + CSlider(CGUI* guiPage); virtual ~CSlider(); protected: Index: source/gui/CSlider.cpp =================================================================== --- source/gui/CSlider.cpp +++ source/gui/CSlider.cpp @@ -22,8 +22,8 @@ #include "ps/CLogger.h" -CSlider::CSlider() - : m_IsPressed(false), m_ButtonSide(0) +CSlider::CSlider(CGUI* guiPage) + : IGUIObject(guiPage), m_IsPressed(false), m_ButtonSide(0) { AddSetting(GUIST_float, "value"); AddSetting(GUIST_float, "min_value"); Index: source/gui/CText.h =================================================================== --- source/gui/CText.h +++ source/gui/CText.h @@ -30,7 +30,7 @@ GUI_OBJECT(CText) public: - CText(); + CText(CGUI* guiPage); virtual ~CText(); /** Index: source/gui/CText.cpp =================================================================== --- source/gui/CText.cpp +++ source/gui/CText.cpp @@ -23,7 +23,8 @@ #include "gui/GUI.h" #include "lib/ogl.h" -CText::CText() +CText::CText(CGUI* guiPage) + : IGUIObject(guiPage), IGUIScrollBarOwner(guiPage) { AddSetting(GUIST_float, "buffer_zone"); AddSetting(GUIST_CGUIString, "caption"); @@ -65,11 +66,9 @@ void CText::SetupText() { - if (!GetGUI()) + if (!GetGUI() || m_GeneratedTexts.empty()) return; - ENSURE(m_GeneratedTexts.size()>=1); - CStrW font; if (GUI::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) // Use the default if none is specified @@ -236,13 +235,13 @@ bool enabled; GUI::GetSetting(this, "enabled", enabled); - CGUIColor color; - GUI::GetSetting(this, enabled ? "textcolor" : "textcolor_disabled", color); + CGUIColor* color; + GUI::GetSettingPointer(this, enabled ? "textcolor" : "textcolor_disabled", color); if (scrollbar) - DrawText(0, color, m_CachedActualSize.TopLeft() - CPos(0.f, scroll), bz+0.1f, cliparea); + DrawText(0, *color, m_CachedActualSize.TopLeft() - CPos(0.f, scroll), bz+0.1f, cliparea); else - DrawText(0, color, m_TextPos, bz+0.1f, cliparea); + DrawText(0, *color, m_TextPos, bz+0.1f, cliparea); } bool CText::MouseOverIcon() Index: source/gui/CTooltip.h =================================================================== --- source/gui/CTooltip.h +++ source/gui/CTooltip.h @@ -28,7 +28,7 @@ GUI_OBJECT(CTooltip) public: - CTooltip(); + CTooltip(CGUI* guiPage); virtual ~CTooltip(); protected: Index: source/gui/CTooltip.cpp =================================================================== --- source/gui/CTooltip.cpp +++ source/gui/CTooltip.cpp @@ -22,7 +22,8 @@ #include -CTooltip::CTooltip() +CTooltip::CTooltip(CGUI* guiPage) + : IGUIObject(guiPage) { // If the tooltip is an object by itself: AddSetting(GUIST_float, "buffer_zone"); @@ -168,8 +169,8 @@ GetGUI()->DrawSprite(*sprite, 0, z, m_CachedActualSize); - CGUIColor color; - GUI::GetSetting(this, "textcolor", color); + CGUIColor* color = nullptr; + GUI::GetSettingPointer(this, "textcolor", color); - DrawText(0, color, m_CachedActualSize.TopLeft(), z+0.1f); + DrawText(0, *color, m_CachedActualSize.TopLeft(), z+0.1f); } Index: source/gui/GUIManager.h =================================================================== --- source/gui/GUIManager.h +++ source/gui/GUIManager.h @@ -32,7 +32,7 @@ class CGUI; class JSObject; class IGUIObject; -struct CGUIColor; +class CGUIColor; struct SGUIIcon; /** @@ -72,6 +72,7 @@ * Load a new GUI page and make it active. All current pages will be retained, * and will still be drawn and receive tick events, but will not receive * user inputs. + * If given, the callbackHandler function will be executed once this page is closed. */ void PushPage(const CStrW& pageName, shared_ptr initData); @@ -103,11 +104,6 @@ InReaction HandleEvent(const SDL_Event_* ev); /** - * See CGUI::GetPreDefinedColor; applies to the currently active page. - */ - bool GetPreDefinedColor(const CStr& name, CGUIColor& output) const; - - /** * See CGUI::SendEventToAll; applies to the currently active page. */ void SendEventToAll(const CStr& eventName) const; @@ -145,16 +141,19 @@ */ const CParamNode& GetTemplate(const std::string& templateName); -private: - struct SGUIPage + class SGUIPage { + public: + SGUIPage(const CStrW& pageName, const shared_ptr initData); + void LoadPage(shared_ptr scriptRuntime); + CStrW name; boost::unordered_set inputs; // for hotloading shared_ptr initData; // data to be passed to the init() function shared_ptr gui; // the actual GUI page }; - void LoadPage(SGUIPage& page); +private: shared_ptr top() const; Index: source/gui/GUIManager.cpp =================================================================== --- source/gui/GUIManager.cpp +++ source/gui/GUIManager.cpp @@ -82,22 +82,21 @@ { // The page stack is cleared (including the script context where initData came from), // therefore we have to clone initData. + shared_ptr initDataClone; if (!initData.isUndefined()) - { initDataClone = srcScriptInterface->WriteStructuredClone(initData); - } + m_PageStack.clear(); + PushPage(pageName, initDataClone); } void CGUIManager::PushPage(const CStrW& pageName, shared_ptr initData) { - m_PageStack.push_back(SGUIPage()); - m_PageStack.back().name = pageName; - m_PageStack.back().initData = initData; - LoadPage(m_PageStack.back()); - + // Push the page prior to loading its contents, because that may Push another GUI page and that should be pushed on top of this new page. + m_PageStack.emplace_back(SGUIPage(pageName, initData)); + m_PageStack.back().LoadPage(m_ScriptRuntime); ResetCursor(); } @@ -160,13 +159,18 @@ } } -void CGUIManager::LoadPage(SGUIPage& page) +CGUIManager::SGUIPage::SGUIPage(const CStrW& pageName, const shared_ptr initData) + : name(pageName), initData(initData), inputs(), gui() +{ +} + +void CGUIManager::SGUIPage::LoadPage(shared_ptr scriptRuntime) { // If we're hotloading then try to grab some data from the previous page shared_ptr hotloadData; - if (page.gui) + if (gui) { - shared_ptr scriptInterface = page.gui->GetScriptInterface(); + shared_ptr scriptInterface = gui->GetScriptInterface(); JSContext* cx = scriptInterface->GetContext(); JSAutoRequest rq(cx); @@ -176,13 +180,13 @@ hotloadData = scriptInterface->WriteStructuredClone(hotloadDataVal); } - page.inputs.clear(); - page.gui.reset(new CGUI(m_ScriptRuntime)); + inputs.clear(); + gui.reset(new CGUI(scriptRuntime)); - page.gui->Initialize(); + gui->Initialize(); - VfsPath path = VfsPath("gui") / page.name; - page.inputs.insert(path); + VfsPath path = VfsPath("gui") / name; + inputs.insert(path); CXeromyces xero; if (xero.Load(g_VFS, path, "gui_page") != PSRETURN_OK) @@ -196,7 +200,7 @@ if (root.GetNodeName() != elmt_page) { - LOGERROR("GUI page '%s' must have root element ", utf8_from_wstring(page.name)); + LOGERROR("GUI page '%s' must have root element ", utf8_from_wstring(name)); return; } @@ -204,7 +208,7 @@ { if (node.GetNodeName() != elmt_include) { - LOGERROR("GUI page '%s' must only have elements inside ", utf8_from_wstring(page.name)); + LOGERROR("GUI page '%s' must only have elements inside ", utf8_from_wstring(name)); continue; } @@ -221,18 +225,18 @@ VfsPaths pathnames; vfs::GetPathnames(g_VFS, directory, L"*.xml", pathnames); for (const VfsPath& path : pathnames) - page.gui->LoadXmlFile(path, page.inputs); + gui->LoadXmlFile(path, inputs); } else { VfsPath path = VfsPath("gui") / nameW; - page.gui->LoadXmlFile(path, page.inputs); + gui->LoadXmlFile(path, inputs); } } - page.gui->SendEventToAll("load"); + gui->SendEventToAll("load"); - shared_ptr scriptInterface = page.gui->GetScriptInterface(); + shared_ptr scriptInterface = gui->GetScriptInterface(); JSContext* cx = scriptInterface->GetContext(); JSAutoRequest rq(cx); @@ -240,15 +244,15 @@ JS::RootedValue hotloadDataVal(cx); JS::RootedValue global(cx, scriptInterface->GetGlobalObject()); - if (page.initData) - scriptInterface->ReadStructuredClone(page.initData, &initDataVal); + if (initData) + scriptInterface->ReadStructuredClone(initData, &initDataVal); if (hotloadData) scriptInterface->ReadStructuredClone(hotloadData, &hotloadDataVal); if (scriptInterface->HasProperty(global, "init") && !scriptInterface->CallFunctionVoid(global, "init", initDataVal, hotloadDataVal)) - LOGERROR("GUI page '%s': Failed to call init() function", utf8_from_wstring(page.name)); + LOGERROR("GUI page '%s': Failed to call init() function", utf8_from_wstring(name)); } Status CGUIManager::ReloadChangedFile(const VfsPath& path) @@ -257,7 +261,7 @@ if (p.inputs.count(path)) { LOGMESSAGE("GUI file '%s' changed - reloading page '%s'", path.string8(), utf8_from_wstring(p.name)); - LoadPage(p); + p.LoadPage(m_ScriptRuntime); // TODO: this can crash if LoadPage runs an init script which modifies the page stack and breaks our iterators } @@ -268,7 +272,7 @@ { // TODO: this can crash if LoadPage runs an init script which modifies the page stack and breaks our iterators for (SGUIPage& p : m_PageStack) - LoadPage(p); + p.LoadPage(m_ScriptRuntime); return INFO::OK; } @@ -345,12 +349,6 @@ return IN_PASS; } - -bool CGUIManager::GetPreDefinedColor(const CStr& name, CGUIColor& output) const -{ - return top()->GetPreDefinedColor(name, output); -} - void CGUIManager::SendEventToAll(const CStr& eventName) const { top()->SendEventToAll(eventName); Index: source/gui/GUIRenderer.h =================================================================== --- source/gui/GUIRenderer.h +++ source/gui/GUIRenderer.h @@ -27,6 +27,7 @@ #include +class CGUI; struct SGUIImageEffects; struct SGUIImage; @@ -42,7 +43,7 @@ struct SDrawCall { - SDrawCall(const SGUIImage* image) : m_Image(image) {} + SDrawCall(const CGUI* mGUI, const SGUIImage* image) : m_Image(image), m_BorderColor(mGUI), m_BackColor(mGUI) {} CRect ComputeTexCoords() const; const SGUIImage* m_Image; @@ -79,7 +80,7 @@ namespace GUIRenderer { - void UpdateDrawCallCache(DrawCalls& Calls, const CStr& SpriteName, const CRect& Size, int CellID, std::map& Sprites); + void UpdateDrawCallCache(const CGUI* guiPage, DrawCalls& Calls, const CStr& SpriteName, const CRect& Size, int CellID, std::map& Sprites); void Draw(DrawCalls& Calls, float Z); } Index: source/gui/GUIRenderer.cpp =================================================================== --- source/gui/GUIRenderer.cpp +++ source/gui/GUIRenderer.cpp @@ -58,7 +58,7 @@ } -void GUIRenderer::UpdateDrawCallCache(DrawCalls& Calls, const CStr& SpriteName, const CRect& Size, int CellID, std::map& Sprites) +void GUIRenderer::UpdateDrawCallCache(const CGUI* mGUI, DrawCalls& Calls, const CStr& SpriteName, const CRect& Size, int CellID, std::map& Sprites) { // This is called only when something has changed (like the size of the // sprite), so it doesn't need to be particularly efficient. @@ -94,18 +94,18 @@ LOGERROR("Trying to use a sprite that doesn't exist (\"%s\").", SpriteName.c_str()); return; } - CGUISprite* Sprite = new CGUISprite; + CGUISprite* Sprite = new CGUISprite(); VfsPath TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.AfterLast(":")); if (SpriteName.Find("stretched:") != -1) { // TODO: Should check (nicely) that this is a valid file? - SGUIImage* Image = new SGUIImage; + SGUIImage* Image = new SGUIImage(mGUI); Image->m_TextureName = TextureName; // Allow grayscale images for disabled portraits if (SpriteName.Find("grayscale:") != -1) { - Image->m_Effects = new SGUIImageEffects; + Image->m_Effects = new SGUIImageEffects(mGUI); Image->m_Effects->m_Greyscale = true; } @@ -120,7 +120,7 @@ else if (SpriteName.Find("cropped:") != -1) { // TODO: Should check (nicely) that this is a valid file? - SGUIImage* Image = new SGUIImage; + SGUIImage* Image = new SGUIImage(mGUI); CStr info = SpriteName.AfterLast("cropped:").BeforeFirst(":"); double xRatio = info.BeforeFirst(",").ToDouble(); @@ -140,7 +140,7 @@ if (SpriteName.Find("color:") != -1) { CStrW value = wstring_from_utf8(SpriteName.AfterLast("color:").BeforeFirst(":")); - CGUIColor color; + CGUIColor color(mGUI); // Check color is valid if (!GUI::ParseString(value, color)) @@ -149,7 +149,7 @@ return; } - SGUIImage* Image = new SGUIImage; + SGUIImage* Image = new SGUIImage(mGUI); // If we are using a mask, this is an effect. // Otherwise we can fallback to the "back color" attribute @@ -157,7 +157,7 @@ if (SpriteName.Find("textureAsMask:") != -1) { Image->m_TextureName = TextureName; - Image->m_Effects = new SGUIImageEffects; + Image->m_Effects = new SGUIImageEffects(mGUI); Image->m_Effects->m_SolidColor = color; } else @@ -189,7 +189,7 @@ std::vector::const_iterator cit; for (cit = it->second->m_Images.begin(); cit != it->second->m_Images.end(); ++cit) { - SDrawCall Call(*cit); // pointers are safe since we never modify sprites/images after startup + SDrawCall Call(mGUI, *cit); // pointers are safe since we never modify sprites/images after startup CRect ObjectSize = (*cit)->m_Size.GetClientArea(Size); @@ -231,7 +231,7 @@ } Call.m_BackColor = (*cit)->m_BackColor; - Call.m_BorderColor = (*cit)->m_Border ? (*cit)->m_BorderColor : CGUIColor(); + Call.m_BorderColor = (*cit)->m_Border ? (*cit)->m_BorderColor : CGUIColor(mGUI); Call.m_DeltaZ = (*cit)->m_DeltaZ; if (!Call.m_HasTexture) @@ -240,7 +240,7 @@ } else if ((*cit)->m_Effects) { - if ((*cit)->m_Effects->m_AddColor != CGUIColor()) + if (static_cast((*cit)->m_Effects->m_AddColor) != CColor()) { Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_add); Call.m_ShaderColorParameter = (*cit)->m_Effects->m_AddColor; @@ -253,7 +253,7 @@ { Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_grayscale); } - else if ((*cit)->m_Effects->m_SolidColor != CGUIColor()) + else if (static_cast((*cit)->m_Effects->m_SolidColor) != CColor()) { Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid_mask); Call.m_ShaderColorParameter = (*cit)->m_Effects->m_SolidColor; @@ -438,7 +438,7 @@ shader->VertexPointer(3, GL_FLOAT, 3*sizeof(float), &data[0]); glDrawArrays(GL_TRIANGLES, 0, 6); - if (cit->m_BorderColor != CGUIColor()) + if (static_cast(cit->m_BorderColor) != CColor()) { shader->Uniform(str_color, cit->m_BorderColor); Index: source/gui/GUIbase.h =================================================================== --- source/gui/GUIbase.h +++ source/gui/GUIbase.h @@ -49,7 +49,8 @@ // Setup an object's ConstructObject function #define GUI_OBJECT(obj) \ public: \ - static IGUIObject* ConstructObject() { return new obj(); } + static IGUIObject* ConstructObject(CGUI* guiPage) \ + { return new obj(guiPage); } /** Index: source/gui/GUItext.h =================================================================== --- source/gui/GUItext.h +++ source/gui/GUItext.h @@ -90,10 +90,10 @@ */ struct STextCall { - STextCall() : + STextCall(const CGUI* mGUI) : m_UseCustomColor(false), m_Bold(false), m_Italic(false), m_Underlined(false), - m_pSpriteCall(NULL) {} + m_pSpriteCall(NULL), m_Color(CGUIColor(mGUI)) {} /** * Position Index: source/gui/GUItext.cpp =================================================================== --- source/gui/GUItext.cpp +++ source/gui/GUItext.cpp @@ -118,7 +118,7 @@ // to the icon, this is to be able to iterate // through the text-calls without having to // complex the structure virtually for nothing more. - SGUIText::STextCall TextCall; + SGUIText::STextCall TextCall(pGUI); // Also add it to the sprites being rendered. SGUIText::SSpriteCall SpriteCall; @@ -174,7 +174,7 @@ } else if (_to > _from && !Feedback.m_NewLine) { - SGUIText::STextCall TextCall; + SGUIText::STextCall TextCall(pGUI); // Set defaults TextCall.m_Font = DefaultFont; Index: source/gui/GUIutil.h =================================================================== --- source/gui/GUIutil.h +++ source/gui/GUIutil.h @@ -44,8 +44,16 @@ class CMatrix3D; template +class SettingTypeConstructor +{ +public: + static T* ConstructSettingType(const CGUI* pGUI); +}; + +template bool __ParseString(const CStrW& Value, T& tOutput); + // Model-view-projection matrix with (0,0) in top-left of screen CMatrix3D GetDefaultGuiMatrix(); @@ -117,7 +125,7 @@ */ static const CGUISpriteInstance& FallBackSprite(const CGUISpriteInstance& prim, const CGUISpriteInstance& sec) { - return (prim.IsEmpty() ? sec : prim); + return prim.IsEmpty() ? sec : prim; } /** @@ -130,8 +138,15 @@ */ static CGUIColor FallBackColor(const CGUIColor& prim, const CGUIColor& sec) { - // CGUIColor() == null. - return ((prim!=CGUIColor())?(prim):(sec)); + return static_cast(prim) == CColor() ? sec : prim; + } + + /** + * Creates an instance of the given GUI setting type. + */ + static T* ConstructSettingType(const CGUI* pGUI) + { + return SettingTypeConstructor::ConstructSettingType(pGUI); } /** Index: source/gui/GUIutil.cpp =================================================================== --- source/gui/GUIutil.cpp +++ source/gui/GUIutil.cpp @@ -27,6 +27,18 @@ extern int g_xres, g_yres; +template +T* SettingTypeConstructor::ConstructSettingType(const CGUI* UNUSED(pGUI)) +{ + return new T(); +} + +template <> +CGUIColor* SettingTypeConstructor::ConstructSettingType(const CGUI* pGUI) +{ + return new CGUIColor(pGUI); +} + template <> bool __ParseString(const CStrW& Value, bool& Output) { @@ -399,6 +411,7 @@ // Instantiate templated functions: #define TYPE(T) \ + template T* SettingTypeConstructor::ConstructSettingType(const CGUI* pGUI); \ template PSRETURN GUI::GetSettingPointer(const IGUIObject* pObject, const CStr& Setting, T*& Value); \ template PSRETURN GUI::GetSetting(const IGUIObject* pObject, const CStr& Setting, T& Value); \ template PSRETURN GUI::SetSetting(IGUIObject* pObject, const CStr& Setting, T& Value, const bool& SkipMessage); \ @@ -412,5 +425,6 @@ // you attempt to retrieve a sprite using GetSetting, since that copies the sprite // and will mess up the caching performed by DrawSprite. You have to use GetSettingPointer // instead. (This is mainly useful to stop me accidentally using the wrong function.) +template CGUISpriteInstance* SettingTypeConstructor::ConstructSettingType(const CGUI* pGUI); \ template PSRETURN GUI::GetSettingPointer(const IGUIObject* pObject, const CStr& Setting, CGUISpriteInstance*& Value); template PSRETURN GUI::SetSetting(IGUIObject* pObject, const CStr& Setting, CGUISpriteInstance& Value, const bool& SkipMessage); Index: source/gui/IGUIButtonBehavior.cpp =================================================================== --- source/gui/IGUIButtonBehavior.cpp +++ source/gui/IGUIButtonBehavior.cpp @@ -133,34 +133,35 @@ CGUIColor IGUIButtonBehavior::ChooseColor() { - CGUIColor color, color2; + CGUIColor* color; + CGUIColor* color2; // Yes, the object must possess these settings. They are standard - GUI::GetSetting(this, "textcolor", color); + GUI::GetSettingPointer(this, "textcolor", color); bool enabled; GUI::GetSetting(this, "enabled", enabled); if (!enabled) { - GUI::GetSetting(this, "textcolor_disabled", color2); - return GUI<>::FallBackColor(color2, color); + GUI::GetSettingPointer(this, "textcolor_disabled", color2); + return GUI<>::FallBackColor(*color2, *color); } else if (m_MouseHovering) { if (m_Pressed) { - GUI::GetSetting(this, "textcolor_pressed", color2); - return GUI<>::FallBackColor(color2, color); + GUI::GetSettingPointer(this, "textcolor_pressed", color2); + return GUI<>::FallBackColor(*color2, *color); } else { - GUI::GetSetting(this, "textcolor_over", color2); - return GUI<>::FallBackColor(color2, color); + GUI::GetSettingPointer(this, "textcolor_over", color2); + return GUI<>::FallBackColor(*color2, *color); } } else - return color; + return *color; } void IGUIButtonBehavior::DrawButton(const CRect& rect, const float& z, CGUISpriteInstance& sprite, CGUISpriteInstance& sprite_over, CGUISpriteInstance& sprite_pressed, CGUISpriteInstance& sprite_disabled, int cell_id) Index: source/gui/IGUIObject.h =================================================================== --- source/gui/IGUIObject.h +++ source/gui/IGUIObject.h @@ -107,7 +107,7 @@ friend bool JSI_IGUIObject::getTextSize(JSContext* cx, uint argc, JS::Value* vp); public: - IGUIObject(); + IGUIObject(CGUI* guiPage); virtual ~IGUIObject(); /** @@ -332,8 +332,6 @@ */ virtual float GetBufferedZ() const; - void SetGUI(CGUI* const& pGUI); - /** * Set parent of this object */ @@ -516,7 +514,7 @@ private: // An object can't function stand alone - CGUI *m_pGUI; + CGUI* m_pGUI; // Internal storage for registered script handlers. std::map > m_ScriptHandlers; @@ -535,6 +533,7 @@ GUI_OBJECT(CGUIDummyObject) public: + CGUIDummyObject(CGUI* guiPage) : IGUIObject(guiPage) {} virtual void Draw() {} // Empty can never be hovered. It is only a category. Index: source/gui/IGUIObject.cpp =================================================================== --- source/gui/IGUIObject.cpp +++ source/gui/IGUIObject.cpp @@ -30,14 +30,15 @@ template void SGUISetting::Init(IGUIObject& pObject, const CStr& Name) { - m_pSetting = new T(); + m_pSetting = GUI::ConstructSettingType(pObject.GetGUI()); m_FromJSVal = [Name, &pObject](JSContext* cx, JS::HandleValue v) { - T value; - if (!ScriptInterface::FromJSVal(cx, v, value)) + T* value = GUI::ConstructSettingType(pObject.GetGUI()); + + if (!ScriptInterface::FromJSVal(cx, v, *value)) return false; - GUI::SetSetting(&pObject, Name, value); + GUI::SetSetting(&pObject, Name, *value); return true; }; @@ -46,9 +47,11 @@ }; } -IGUIObject::IGUIObject() - : m_pGUI(NULL), m_pParent(NULL), m_MouseHovering(false), m_LastClickTime() +IGUIObject::IGUIObject(CGUI* guiPage) + : m_pGUI(guiPage), m_pParent(NULL), m_MouseHovering(false), m_LastClickTime() { + JS_AddExtraGCRootsTracer(m_pGUI->GetScriptInterface()->GetJSRuntime(), Trace, this); + AddSetting(GUIST_bool, "enabled"); AddSetting(GUIST_bool, "hidden"); AddSetting(GUIST_CClientArea, "size"); @@ -88,12 +91,6 @@ //------------------------------------------------------------------- // Functions //------------------------------------------------------------------- -void IGUIObject::SetGUI(CGUI* const& pGUI) -{ - if (!m_pGUI) - JS_AddExtraGCRootsTracer(pGUI->GetScriptInterface()->GetJSRuntime(), Trace, this); - m_pGUI = pGUI; -} void IGUIObject::AddChild(IGUIObject* pChild) { @@ -246,10 +243,10 @@ #define TYPE(type) \ else if (set.m_Type == GUIST_##type) \ { \ - type _Value; \ - if (!GUI::ParseString(Value, _Value)) \ + type* _Value = GUI::ConstructSettingType(GetGUI()); \ + if (!GUI::ParseString(Value, *_Value)) \ return PSRETURN_GUI_UnableToParse; \ - GUI::SetSetting(this, Setting, _Value, SkipMessage); \ + GUI::SetSetting(this, Setting, *_Value, SkipMessage); \ } if (0) @@ -452,8 +449,6 @@ void IGUIObject::SetScriptHandler(const CStr& Action, JS::HandleObject Function) { - // m_ScriptHandlers is only rooted after SetGUI() has been called (which sets up the GC trace callbacks), - // so we can't safely store objects in it if the GUI hasn't been set yet. ENSURE(m_pGUI && "A GUI must be associated with the GUIObject before adding ScriptHandlers!"); m_ScriptHandlers[Action] = JS::Heap(Function); } Index: source/gui/IGUIScrollBar.h =================================================================== --- source/gui/IGUIScrollBar.h +++ source/gui/IGUIScrollBar.h @@ -247,12 +247,6 @@ CGUI* GetGUI() const; /** - * Set GUI pointer - * @param pGUI pointer to CGUI object. - */ - void SetGUI(CGUI* pGUI) { m_pGUI = pGUI; } - - /** * Set Width * @param width Width */ Index: source/gui/IGUIScrollBarOwner.h =================================================================== --- source/gui/IGUIScrollBarOwner.h +++ source/gui/IGUIScrollBarOwner.h @@ -35,7 +35,7 @@ friend class IGUIScrollBar; public: - IGUIScrollBarOwner(); + IGUIScrollBarOwner(CGUI* guiPage); virtual ~IGUIScrollBarOwner(); virtual void Draw(); Index: source/gui/IGUIScrollBarOwner.cpp =================================================================== --- source/gui/IGUIScrollBarOwner.cpp +++ source/gui/IGUIScrollBarOwner.cpp @@ -19,7 +19,8 @@ #include "GUI.h" -IGUIScrollBarOwner::IGUIScrollBarOwner() +IGUIScrollBarOwner::IGUIScrollBarOwner(CGUI* guiPage) + : IGUIObject(guiPage) { } @@ -40,7 +41,6 @@ void IGUIScrollBarOwner::AddScrollBar(IGUIScrollBar* scrollbar) { scrollbar->SetHostObject(this); - scrollbar->SetGUI(GetGUI()); m_ScrollBars.push_back(scrollbar); } Index: source/gui/MiniMap.h =================================================================== --- source/gui/MiniMap.h +++ source/gui/MiniMap.h @@ -29,7 +29,7 @@ { GUI_OBJECT(CMiniMap) public: - CMiniMap(); + CMiniMap(CGUI* guiPage); virtual ~CMiniMap(); protected: virtual void Draw(); Index: source/gui/MiniMap.cpp =================================================================== --- source/gui/MiniMap.cpp +++ source/gui/MiniMap.cpp @@ -62,7 +62,8 @@ return (0xff000000 | b | g<<8 | r<<16); } -CMiniMap::CMiniMap() : +CMiniMap::CMiniMap(CGUI* guiPage) : + IGUIObject(guiPage), 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_NextBlinkTime(0.0), m_PingDuration(25.0), m_BlinkState(false), m_WaterHeight(0.0)