diff --git a/binaries/data/gui/hello.xml b/binaries/data/gui/hello.xml index d3ec16b8d9..0489e19077 100755 --- a/binaries/data/gui/hello.xml +++ b/binaries/data/gui/hello.xml @@ -1,13 +1,10 @@ - + - - - - - + - \ No newline at end of file + + diff --git a/binaries/data/gui/objects.dtd b/binaries/data/gui/objects.dtd index 1167920dd1..2225ff42f7 100755 --- a/binaries/data/gui/objects.dtd +++ b/binaries/data/gui/objects.dtd @@ -18,7 +18,7 @@ - + diff --git a/source/gui/CButton.cpp b/source/gui/CButton.cpp index a582424286..ef51d34fd6 100755 --- a/source/gui/CButton.cpp +++ b/source/gui/CButton.cpp @@ -117,10 +117,10 @@ void CButton::Draw() if (m_Pressed) glColor3f(0.7f, 0.f, 0.f); else - glColor3f(0,1,(float)m_BaseSettings.m_Size.right/300.f); + glColor3f(0,1,(float)m_BaseSettings.m_Size.pixel.right/300.f); } else - glColor3f((float)m_BaseSettings.m_Size.right/300.f,0,1); + glColor3f((float)m_BaseSettings.m_Size.pixel.right/300.f,0,1); ////////// Gee: janwas, this is just temp to see it glDisable(GL_TEXTURE_2D); @@ -133,11 +133,19 @@ void CButton::Draw() // Do this glBegin(GL_QUADS); //glBegin(GL_TRIANGLES); - glVertex2i(GetBaseSettings().m_Size.right, GetBaseSettings().m_Size.bottom); + //CRect ca = GetBaseSettings().m_Size.GetClientArea(CRect(0, 0, g_xres, g_yres)); + CRect ca = m_CachedActualSize; + + glVertex2i(ca.right, ca.bottom); + glVertex2i(ca.left, ca.bottom); + glVertex2i(ca.left, ca.top); + glVertex2i(ca.right, ca.top); + +/* glVertex2i(GetBaseSettings().m_Size.right, GetBaseSettings().m_Size.bottom); glVertex2i(GetBaseSettings().m_Size.left, GetBaseSettings().m_Size.bottom); glVertex2i(GetBaseSettings().m_Size.left, GetBaseSettings().m_Size.top); glVertex2i(GetBaseSettings().m_Size.right, GetBaseSettings().m_Size.top); -/* +*//* glVertex2i(GetBaseSettings().m_Size.right, GetBaseSettings().m_Size.bottom); glVertex2i(GetBaseSettings().m_Size.left, GetBaseSettings().m_Size.bottom); glVertex2i(GetBaseSettings().m_Size.left, GetBaseSettings().m_Size.top); @@ -152,4 +160,4 @@ void CButton::Draw() //glEnable(GL_DEPTH_TEST); glPopMatrix(); -} \ No newline at end of file +} diff --git a/source/gui/CButton.h b/source/gui/CButton.h index 36eca0a416..17c5c6059a 100755 --- a/source/gui/CButton.h +++ b/source/gui/CButton.h @@ -94,4 +94,4 @@ public: virtual void Draw(); }; -#endif \ No newline at end of file +#endif diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index 08a592f204..64a51758b0 100755 --- a/source/gui/CGUI.cpp +++ b/source/gui/CGUI.cpp @@ -239,6 +239,11 @@ void CGUI::Destroy() m_Sprites.clear(); } +void CGUI::UpdateResolution() +{ + GUI<>::RecurseObject(0, m_BaseObject, &IGUIObject::UpdateCachedSize ); +} + void CGUI::AddObject(IGUIObject* pObject) { /* try diff --git a/source/gui/CGUI.h b/source/gui/CGUI.h index 1a2938415a..5180c8b267 100755 --- a/source/gui/CGUI.h +++ b/source/gui/CGUI.h @@ -128,6 +128,17 @@ public: */ void AddObjectType(const CStr &str, ConstructObjectFunction pFunc) { m_ObjectTypes[str] = pFunc; } + /** + * Update Resolution, should be called every time the resolution + * of the opengl screen has been changed, this is becuase it needs + * to re-cache all its actual sizes + * + * Needs no input since screen resolution is global. + * + * @see IGUIObject#UpdateCachedSize() + */ + void UpdateResolution(); + private: /** * Updates the object pointers, needs to be called each @@ -346,4 +357,4 @@ private: //@} }; -#endif \ No newline at end of file +#endif diff --git a/source/gui/CGUISprite.cpp b/source/gui/CGUISprite.cpp index 5357e0fff0..0baad8bcbf 100755 --- a/source/gui/CGUISprite.cpp +++ b/source/gui/CGUISprite.cpp @@ -31,4 +31,4 @@ void CGUISprite::Draw(const float &z, const CRect &rect, const CRect &clipping=C glPopMatrix(); } -} \ No newline at end of file +} diff --git a/source/gui/CGUISprite.h b/source/gui/CGUISprite.h index f35dd93c15..d2da115883 100755 --- a/source/gui/CGUISprite.h +++ b/source/gui/CGUISprite.h @@ -103,4 +103,4 @@ private: std::vector m_Images; }; -#endif \ No newline at end of file +#endif diff --git a/source/gui/GUI.h b/source/gui/GUI.h index 4bab6fa4c1..08de651eeb 100755 --- a/source/gui/GUI.h +++ b/source/gui/GUI.h @@ -56,6 +56,7 @@ gee@pyro.nu //-------------------------------------------------------- #include #include +#include #include //// janwas: these are very sloppy added, I don't know the etiquette @@ -82,4 +83,4 @@ gee@pyro.nu #include "CGUI.h" -#endif \ No newline at end of file +#endif diff --git a/source/gui/GUIbase.h b/source/gui/GUIbase.h index d226716901..cfc69942df 100755 --- a/source/gui/GUIbase.h +++ b/source/gui/GUIbase.h @@ -97,7 +97,7 @@ enum // Typedefs typedef std::map map_pObjects; - +typedef std::vector vector_pObjects; //-------------------------------------------------------- // Error declarations @@ -113,4 +113,4 @@ DECLARE_ERROR(PS_NEEDS_NAME) DECLARE_ERROR(PS_LEXICAL_FAIL) DECLARE_ERROR(PS_SYNTACTICAL_FAIL) -#endif \ No newline at end of file +#endif diff --git a/source/gui/GUIutil.cpp b/source/gui/GUIutil.cpp index d30c8eab9d..9a3d8dacce 100755 --- a/source/gui/GUIutil.cpp +++ b/source/gui/GUIutil.cpp @@ -6,9 +6,149 @@ gee@pyro.nu //#include "stdafx.h" #include "GUI.h" +#include "../ps/Parser.h" using namespace std; +//-------------------------------------------------------- +// Help Classes/Structs for the GUI implementation +//-------------------------------------------------------- + +CClientArea::CClientArea() : pixel(0,0,0,0), percent(0,0,0,0) +{ +} + +CClientArea::CClientArea(const CStr &Value) +{ + SetClientArea(Value); +} + +CRect CClientArea::GetClientArea(const CRect &parent) +{ + CRect client; + + // This should probably be cached and not calculated all the time for every object. + client.left = int(float(parent.left) + float(parent.right-parent.left)*float(percent.left))/100.f + pixel.left; + client.top = int(float(parent.top) + float(parent.bottom-parent.top)*float(percent.top))/100.f + pixel.top; + client.right = int(float(parent.left) + float(parent.right-parent.left)*float(percent.right))/100.f + pixel.right; + client.bottom = int(float(parent.top) + float(parent.bottom-parent.top)*float(percent.bottom))/100.f + pixel.bottom; + + return client; +} + +bool CClientArea::SetClientArea(const CStr &Value) +{ + // Get value in STL string format + string _Value = (const TCHAR*)Value; + + // This might lack incredible speed, but since all XML files + // are read at startup, reading 100 client areas will be + // negligible in the loading time. + + // Setup parser to parse the value + CParser parser; + + // One of the for values: + // will give outputs like (in argument): + // (200) <== no percent, just the first $value + // (200) (percent) <== just the percent + // (200) (percent) (100) <== percent PLUS pixel + // (200) (percent) (-100) <== percent MINUS pixel + // (200) (percent) (100) (-100) <== Both PLUS and MINUS are used, INVALID + string one_value = "_$value[$arg(percent)%_[+_$value]_[-_$arg(_minus)$value]_]"; + string four_values = one_value + "$arg(delim)" + + one_value + "$arg(delim)" + + one_value + "$arg(delim)" + + one_value + "$arg(delim)_"; // it's easier to just end with another delimiter + + parser.InputTaskType("ClientArea", four_values); + + CParserLine line; + line.ParseString(parser, _Value); + + if (!line.m_ParseOK) + return false; + + int arg_count[4]; // argument counts for the four values + int arg_start[4] = {0,0,0,0}; // location of first argument, [0] is alwasy 0 + + // Divide into the four piles (delimiter is an argument named "delim") + for (int i=0, valuenr=0; isecond; -} \ No newline at end of file +} diff --git a/source/gui/GUIutil.h b/source/gui/GUIutil.h index e5d95b0de5..a9b72520ea 100755 --- a/source/gui/GUIutil.h +++ b/source/gui/GUIutil.h @@ -23,6 +23,84 @@ gee@pyro.nu //-------------------------------------------------------- #include "GUI.h" +//-------------------------------------------------------- +// Help Classes/Structs for the GUI +//-------------------------------------------------------- +// TEMP +struct CRect +{ + CRect() {} + CRect(int _l, int _t, int _r, int _b) : + left(_l), + top(_t), + right(_r), + bottom(_b) {} + int bottom, top, left, right; + + bool operator ==(const CRect &rect) const + { + return (bottom==rect.bottom) && + (top==rect.top) && + (left==rect.left) && + (right==rect.right); + } + + bool operator !=(const CRect &rect) const + { + return !(*this==rect); + } +}; + +/** + * @author Gustav Larsson + * + * Client Area is a rectangle relative to a parent rectangle + * + * You can input the whole value of the Client Area by + * string. Like used in the GUI. + */ +struct CClientArea +{ +public: + CClientArea(); + CClientArea(const CStr &Value); + + /// Pixel modifiers + CRect pixel; + + /// Percent modifiers (I'll let this be integers, I don't think a greater precision is needed) + CRect percent; + + /** + * Get client area rectangle when the parent is given + */ + CRect GetClientArea(const CRect &parent); + + /** + * The ClientArea can be set from a string looking like: + * + * @code + * "0 0 100% 100%" + * "50%-10 50%-10 50%+10 50%+10" @endcode + * + * i.e. First percent modifier, then + or - and the pixel modifier. + * Although you can use just the percent or the pixel modifier. Notice + * though that the percent modifier must always be the first when + * both modifiers are inputted. + * + * @return true if success, false if failure. If false then the client area + * will be unchanged. + */ + bool SetClientArea(const CStr &Value); +}; + + +// TEMP +struct CColor +{ + float r, g, b, a; +}; + //-------------------------------------------------------- // Forward declarations //-------------------------------------------------------- @@ -154,6 +232,8 @@ public: // one with the friend relationship IGUIObject *pObject = GetObjectPointer(GUIinstance, Object); + pObject->CheckSettingsValidity(); + return SetSetting(pObject, Setting, Value); } @@ -351,4 +431,4 @@ private: } }; -#endif \ No newline at end of file +#endif diff --git a/source/gui/IGUIButtonBehavior.h b/source/gui/IGUIButtonBehavior.h index 1f2c100aa3..2b51e83b87 100755 --- a/source/gui/IGUIButtonBehavior.h +++ b/source/gui/IGUIButtonBehavior.h @@ -68,4 +68,4 @@ protected: bool m_Pressed; }; -#endif \ No newline at end of file +#endif diff --git a/source/gui/IGUIObject.cpp b/source/gui/IGUIObject.cpp index 695109ffd7..7519e8ba0d 100755 --- a/source/gui/IGUIObject.cpp +++ b/source/gui/IGUIObject.cpp @@ -124,15 +124,12 @@ void IGUIObject::Destroy() void IGUIObject::SetupBaseSettingsInfo(map_Settings &SettingsInfo) { - SettingsInfo["hejsan"].m_Offset = 0; - - - _GUI_ADD_OFFSET("bool", "enabled", m_Enabled) - _GUI_ADD_OFFSET("bool", "hidden", m_Hidden) - _GUI_ADD_OFFSET("rect", "size1024", m_Size) - _GUI_ADD_OFFSET("string", "style", m_Style) - _GUI_ADD_OFFSET("float", "z", m_Z) - _GUI_ADD_OFFSET("string", "caption", m_Caption) + _GUI_ADD_OFFSET("bool", "enabled", m_Enabled) + _GUI_ADD_OFFSET("bool", "hidden", m_Hidden) + _GUI_ADD_OFFSET("client area", "size", m_Size) + _GUI_ADD_OFFSET("string", "style", m_Style) + _GUI_ADD_OFFSET("float", "z", m_Z) + _GUI_ADD_OFFSET("string", "caption", m_Caption) } bool IGUIObject::MouseOver() @@ -143,10 +140,14 @@ bool IGUIObject::MouseOver() u16 mouse_x = GetMouseX(), mouse_y = GetMouseY(); - return (mouse_x >= m_BaseSettings.m_Size.left && - mouse_x <= m_BaseSettings.m_Size.right && - mouse_y >= m_BaseSettings.m_Size.bottom && - mouse_y <= m_BaseSettings.m_Size.top); + //CRect ca = m_BaseSettings.m_Size.GetClientArea(CRect(0,0,g_xres,g_yres)); + CRect ca = m_CachedActualSize; + + + return (mouse_x >= ca.left && + mouse_x <= ca.right && + mouse_y >= ca.top && + mouse_y <= ca.bottom); } u16 IGUIObject::GetMouseX() const @@ -217,9 +218,6 @@ void IGUIObject::SetSetting(const CStr &Setting, const CStr &Value) else if (set.m_Type == CStr(_T("rect"))) { - // TEMP - //GUI::SetSetting(this, Setting, CRect(100,100,200,200)); - // Use the parser to parse the values CParser parser; parser.InputTaskType("", "_$value_$value_$value_$value_"); @@ -249,6 +247,21 @@ void IGUIObject::SetSetting(const CStr &Setting, const CStr &Value) GUI::SetSetting(this, Setting, rect); } else + if (set.m_Type == CStr(_T("client area"))) + { + // Get Client Area + CClientArea ca; + + if (!ca.SetClientArea(Value)) + { + // GeeTODO REPORT + } + + // Check if valid! + + GUI::SetSetting(this, Setting, ca); + } + else { throw PS_FAIL; } @@ -287,9 +300,17 @@ IGUIObject *IGUIObject::GetParent() return m_pParent; } +void IGUIObject::UpdateCachedSize() +{ + m_CachedActualSize = m_BaseSettings.m_Size.GetClientArea( CRect(0, 0, g_xres, g_yres) ); +} + // GeeTODO keep this function and all??? void IGUIObject::CheckSettingsValidity() { + // Size might have been change, update cached size + UpdateCachedSize(); + // If we hide an object, reset many of its parts if (GetBaseSettings().m_Hidden) { @@ -310,4 +331,4 @@ void IGUIObject::CheckSettingsValidity() catch (...) { } -} \ No newline at end of file +} diff --git a/source/gui/IGUIObject.h b/source/gui/IGUIObject.h index 020fe6091a..4a0ff37bda 100755 --- a/source/gui/IGUIObject.h +++ b/source/gui/IGUIObject.h @@ -48,7 +48,6 @@ class CGUI; // Map with pointers typedef std::map map_Settings; -typedef std::vector vector_pObjects; //-------------------------------------------------------- // Error declarations @@ -58,36 +57,6 @@ typedef std::vector vector_pObjects; // Declarations //-------------------------------------------------------- -// TEMP -struct CRect -{ - CRect() {} - CRect(int _l, int _b, int _r, int _t) : - top(_t), - bottom(_b), - right(_r), - left(_l) {} - int bottom, top, left, right; - - bool operator ==(const CRect &rect) const - { - return (bottom==rect.bottom) && - (top==rect.top) && - (left==rect.left) && - (right==rect.right); - } - - bool operator !=(const CRect &rect) const - { - return !(*this==rect); - } -}; - -// TEMP -struct CColor -{ - float r, g, b, a; -}; // Text alignments enum EAlign { EAlign_Left, EAlign_Right, EAlign_Center }; @@ -117,7 +86,8 @@ struct SGUIBaseSettings bool m_Hidden; bool m_Enabled; bool m_Absolute; - CRect m_Size; +// CRect m_Size2; + CClientArea m_Size; CStr m_Style; float m_Z; CStr m_Caption; // Is usually set within an XML element and not in the attributes @@ -134,7 +104,7 @@ struct SGUIBaseSettings class IGUIObject { friend class CGUI; - friend class GUI; + template friend class GUI; public: IGUIObject(); @@ -229,6 +199,13 @@ public: */ bool SettingExists(const CStr &Setting) const; + /** + * 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. + */ + void UpdateCachedSize(); + /** * Should be called every time the settings has been updated * will also send a message GUIM_SETTINGS_UPDATED, so that @@ -321,6 +298,14 @@ protected: u16 GetMouseX() const; u16 GetMouseY() const; + /** + * Cached size, real size m_Size is actually dependent on resolution + * and can have different *real* outcomes, this is the real outcome + * cached to avoid slow calculations in real time. + */ + CRect m_CachedActualSize; + + //@} private: //-------------------------------------------------------- @@ -379,7 +364,7 @@ protected: * located hardcoded, in order to acquire a pointer * for that variable... Say "frozen" gives * the offset from IGUIObject to m_Frozen. - * note! NOT from SGUIBaseSettings to + * note! @uNOT from SGUIBaseSettings to * m_Frozen! */ static map_Settings m_SettingsInfo; @@ -402,4 +387,4 @@ class CGUIDummyObject : public IGUIObject virtual void Draw() {} }; -#endif \ No newline at end of file +#endif diff --git a/source/gui/IGUISettingsObject.cpp b/source/gui/IGUISettingsObject.cpp index 1b66d1123b..a0ad91570a 100755 --- a/source/gui/IGUISettingsObject.cpp +++ b/source/gui/IGUISettingsObject.cpp @@ -7,4 +7,4 @@ gee@pyro.nu //#include "stdafx.h" #include "GUI.h" -using namespace std; \ No newline at end of file +using namespace std; diff --git a/source/gui/IGUISettingsObject.h b/source/gui/IGUISettingsObject.h index 163f700f44..222113f7cf 100755 --- a/source/gui/IGUISettingsObject.h +++ b/source/gui/IGUISettingsObject.h @@ -121,4 +121,4 @@ protected: static map_Settings m_SettingsInfo; }; -#endif \ No newline at end of file +#endif diff --git a/source/gui/XercesErrorHandler.h b/source/gui/XercesErrorHandler.h index 7057dea63a..04c931e1df 100755 --- a/source/gui/XercesErrorHandler.h +++ b/source/gui/XercesErrorHandler.h @@ -97,4 +97,4 @@ private: //@} }; -#endif \ No newline at end of file +#endif