From 512bfd40673bf43a7bda311915840f1f50ac87c9 Mon Sep 17 00:00:00 2001 From: Gee Date: Mon, 1 Dec 2003 07:06:55 +0000 Subject: [PATCH] no message This was SVN commit r128. --- source/gui/CButton.cpp | 87 ++-------- source/gui/CGUI.cpp | 229 ++++++++++++++++++++++---- source/gui/CGUI.h | 57 ++++++- source/gui/CGUISprite.cpp | 23 +-- source/gui/CGUISprite.h | 30 ++-- source/gui/GUI.h | 13 +- source/gui/GUIbase.h | 27 +++- source/gui/GUIutil.cpp | 10 +- source/gui/GUIutil.h | 258 ++++++++++++++++++++---------- source/gui/IGUIObject.cpp | 92 +++++------ source/gui/IGUIObject.h | 28 +++- source/gui/IGUISettingsObject.cpp | 1 + source/gui/IGUISettingsObject.h | 22 +++ 13 files changed, 575 insertions(+), 302 deletions(-) diff --git a/source/gui/CButton.cpp b/source/gui/CButton.cpp index 37f135d9c5..9cca472018 100755 --- a/source/gui/CButton.cpp +++ b/source/gui/CButton.cpp @@ -16,11 +16,6 @@ using namespace std; // Offsets DECLARE_SETTINGS_INFO(SButtonSettings) -//------------------------------------------------------------------- -// Implementation Macros -//------------------------------------------------------------------- -#define _GUI_ADD_OFFSET(type, str, var) GUI_ADD_OFFSET(CButton, SButtonSettings, m_Settings, type, str, var) - //------------------------------------------------------------------- // Constructor / Destructor //------------------------------------------------------------------- @@ -49,21 +44,9 @@ CButton::CButton() // Setup the base ones too SetupBaseSettingsInfo(m_SettingsInfo); - // Setup the new ones - _GUI_ADD_OFFSET("bool", "disabled", m_Disabled) - _GUI_ADD_OFFSET("string", "font", m_Font) - _GUI_ADD_OFFSET("string", "sprite", m_Sprite) - _GUI_ADD_OFFSET("string", "sprite-disabled", m_SpriteDisabled) - _GUI_ADD_OFFSET("string", "sprite-over", m_SpriteOver) - _GUI_ADD_OFFSET("string", "sprite-pressed", m_SpritePressed) - _GUI_ADD_OFFSET("align", "textalign", m_TextAlign) - _GUI_ADD_OFFSET("color", "textcolor", m_TextColor) - _GUI_ADD_OFFSET("color", "textcolor-disabled", m_TextColorDisabled) - _GUI_ADD_OFFSET("color", "textcolor-over", m_TextColorOver) - _GUI_ADD_OFFSET("color", "textcolor-pressed", m_TextColorPressed) - _GUI_ADD_OFFSET("valign", "textvalign", m_TextValign) - _GUI_ADD_OFFSET("string", "tooltip", m_ToolTip) - _GUI_ADD_OFFSET("string", "tooltip-style", m_ToolTipStyle) + GUI_ADD_OFFSET_EXT(SButtonSettings, m_Sprite, "string", "sprite") + GUI_ADD_OFFSET_EXT(SButtonSettings, m_SpriteOver, "string", "sprite-over") + GUI_ADD_OFFSET_EXT(SButtonSettings, m_SpritePressed,"string", "sprite-pressed") } } @@ -88,24 +71,19 @@ void CButton::HandleMessage(const EGUIMessage &Message) break; case GUIM_MOUSE_ENTER: -/// OUTPUT(GUIM_MOUSE_ENTER) break; case GUIM_MOUSE_LEAVE: -/// OUTPUT(GUIM_MOUSE_LEAVE) break; case GUIM_MOUSE_PRESS_LEFT: -/// OUTPUT(GUIM_MOUSE_PRESS_LEFT) break; case GUIM_MOUSE_RELEASE_LEFT: -/// OUTPUT(GUIM_MOUSE_RELEASE_LEFT) break; case GUIM_PRESSED: GetGUI()->TEMPmessage = "Button " + string((const TCHAR*)m_Name) + " was pressed!"; -/// OUTPUT(GUIM_PRESSED); break; default: @@ -115,57 +93,18 @@ void CButton::HandleMessage(const EGUIMessage &Message) void CButton::Draw() { - if (m_MouseHovering) - { - if (m_Pressed) - glColor3f(0.7f, 0.f, 0.f); - else - glColor3f(0,1,(float)m_BaseSettings.m_Size.pixel.right/300.f); - } - else - 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); ////////// - glPushMatrix(); - glTranslatef(0.0f, 0.0f, GetBaseSettings().m_Z); - - // Do this - glBegin(GL_QUADS); - //glBegin(GL_TRIANGLES); - glVertex2i(m_CachedActualSize.right, m_CachedActualSize.bottom); - glVertex2i(m_CachedActualSize.left, m_CachedActualSize.bottom); - glVertex2i(m_CachedActualSize.left, m_CachedActualSize.top); - glVertex2i(m_CachedActualSize.right, m_CachedActualSize.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); - //glVertex2i(GetBaseSettings().m_Size.right, GetBaseSettings().m_Size.top); -*/ glEnd(); - - //glDisable(GL_DEPTH_TEST); - -/* glEnable(GL_TEXTURE_2D); - glColor3f(1,1,1); - - //glLoadIdentity(); - //glTranslatef(ca.left + 10, g_yres - (ca.top + 10), GetBaseSettings().m_Z + 0.1f); - glTranslatef(ca.left + 10, ca.top + 10, 0.0f); - //glScalef(0,-1,0); - font_bind(GetGUI()->TEMPfont); - glprintf("%s", (const TCHAR*)m_Name); -*/ //glColor3f(0,0,0); - //font.print(GetBaseSettings().m_Size.left + 3, GetBaseSettings().m_Size.top - 15, LEFT, "Object: %s", GetName().c_str()); - - //glEnable(GL_DEPTH_TEST); - - glPopMatrix(); + if (GetGUI()) + { + if (m_Pressed && m_Settings.m_SpritePressed != CStr("null")) + GetGUI()->DrawSprite(m_Settings.m_SpritePressed, GetBaseSettings().m_Z, m_CachedActualSize); + else + if (m_MouseHovering && !m_Pressed && m_Settings.m_SpriteOver != CStr("null")) + GetGUI()->DrawSprite(m_Settings.m_SpriteOver, GetBaseSettings().m_Z, m_CachedActualSize); + else + GetGUI()->DrawSprite(m_Settings.m_Sprite, GetBaseSettings().m_Z, m_CachedActualSize); + } } diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index 38f9b68156..94d236b91b 100755 --- a/source/gui/CGUI.cpp +++ b/source/gui/CGUI.cpp @@ -17,7 +17,7 @@ gee@pyro.nu #include #include "XercesErrorHandler.h" -#include "../ps/Prometheus.h" +#include "Prometheus.h" #include "input.h" // namespaces used @@ -70,18 +70,19 @@ bool CGUI::HandleEvent(const SDL_Event& ev) pNearest->HandleMessage(GUIM_MOUSE_PRESS_LEFT); // some temp - /* CClientArea ca; + CClientArea ca; bool hidden; - GUI::GetSetting(*this, CStr(_T("a2")), CStr(_T("size")), ca); - GUI::GetSetting(*this, CStr(_T("a2")), CStr(_T("hidden")), hidden); + GUI::GetSetting(*this, CStr("Child1"), CStr("size"), ca); + GUI::GetSetting(*this, CStr("Child1"), CStr("hidden"), hidden); - hidden = !hidden; - ca.pixel.right += 30; + //hidden = !hidden; + ca.pixel.left -= 30; + ca.pixel.bottom += 15; - GUI::SetSetting(*this, CStr(_T("a2")), CStr(_T("size")), ca); - GUI::SetSetting(*this, CStr(_T("a2")), CStr(_T("hidden")), hidden); - */ } + GUI::SetSetting(*this, CStr("Child1"), CStr("size"), ca); + GUI::SetSetting(*this, CStr("Child1"), CStr("hidden"), hidden); + } } else if (ev.type == SDL_MOUSEBUTTONUP) @@ -247,6 +248,50 @@ void CGUI::Draw() glPopMatrix(); } +void CGUI::DrawSprite(const CStr &SpriteName, + const float &Z, + const CRect &Rect, + const CRect &Clipping) +{ + // This is no error, so we won't report it. + if (SpriteName == CStr("null")) + return; + + bool DoClipping = (Clipping != CRect(0,0,0,0)); + CGUISprite Sprite; + + // Fetch real sprite from name + if (m_Sprites.count(SpriteName) == 0) + { + // GeeTODO report error + return; + } + else Sprite = m_Sprites[SpriteName]; + + glPushMatrix(); + glTranslatef(0.0f, 0.0f, Z); + + // Iterate all images and request them being drawn be the + // CRenderer + std::vector::const_iterator cit; + for (cit=Sprite.m_Images.begin(); cit!=Sprite.m_Images.end(); ++cit) + { + CRect real = cit->m_Size.GetClientArea(Rect); + + glColor3f(cit->m_BackColor.r , cit->m_BackColor.g, cit->m_BackColor.b); + //glColor3f((float)real.right/1000.f, 0.5f, 0.5f); + + // Do this + glBegin(GL_QUADS); + glVertex2i(real.right, real.bottom); + glVertex2i(real.left, real.bottom); + glVertex2i(real.left, real.top); + glVertex2i(real.right, real.top); + glEnd(); + } + glPopMatrix(); +} + void CGUI::Destroy() { // We can use the map to delete all @@ -280,8 +325,8 @@ void CGUI::UpdateResolution() void CGUI::AddObject(IGUIObject* pObject) { -/* try - {*/ + try + { // Add CGUI pointer GUI::RecurseObject(0, pObject, &IGUIObject::SetGUI, this); @@ -291,11 +336,11 @@ void CGUI::AddObject(IGUIObject* pObject) // Cache tree GUI<>::RecurseObject(0, pObject, &IGUIObject::UpdateCachedSize); - /* } + } catch (PS_RESULT e) { throw e; - }*/ + } } void CGUI::UpdateObjects() @@ -372,13 +417,12 @@ void CGUI::LoadXMLFile(const string &Filename) parser->setValidationScheme(XercesDOMParser::Val_Auto); parser->setDoNamespaces(false); parser->setDoSchema(false); + parser->setCreateEntityReferenceNodes(false); // Set cosutomized error handler CXercesErrorHandler *errorHandler = new CXercesErrorHandler(); parser->setErrorHandler(errorHandler); - parser->setCreateEntityReferenceNodes(false); - try { /// g_nemLog("*** Xerces XML Parsing Errors"); @@ -439,6 +483,15 @@ void CGUI::LoadXMLFile(const string &Filename) { Xerces_ReadRootSprites(node); } + else + if (root_name == "styles") + { + Xerces_ReadRootStyles(node); + } + else + { + // GeeTODO output in log + } } } @@ -494,6 +547,25 @@ void CGUI::Xerces_ReadRootSprites(XERCES_CPP_NAMESPACE::DOMElement *pElement) } } +void CGUI::Xerces_ReadRootStyles(XERCES_CPP_NAMESPACE::DOMElement *pElement) +{ + // Iterate main children + // they should all be elements + DOMNodeList *children = pElement->getChildNodes(); + + for (int i=0; igetLength(); ++i) + { + DOMNode *child = children->item(i); + + if (child->getNodeType() == DOMNode::ELEMENT_NODE) + { + // Read in this whole object into the GUI + DOMElement *element = (DOMElement*)child; + Xerces_ReadStyle(element); + } + } +} + void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent) { assert(pParent && pElement); @@ -503,7 +575,7 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent) IGUIObject *object = NULL; // Well first of all we need to determine the type - string type = XMLString::transcode( pElement->getAttribute( XMLString::transcode("type") ) ); + CStr type = XMLString::transcode( pElement->getAttribute( XMLString::transcode("type") ) ); // Construct object from specified type // henceforth, we need to do a rollback before aborting. @@ -513,12 +585,46 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent) if (!object) { // Report error that object was unsuccessfully loaded - ReportParseError("Unrecognized type: " + type); + ReportParseError(CStr("Unrecognized type: ") + type); delete object; return; } + // + // Read Style and set defaults + // + CStr argStyle = XMLString::transcode( pElement->getAttribute( XMLString::transcode("style") ) ); + + if (argStyle != CStr()) + { + // Get style + if (m_Styles.count(argStyle) == 0) + { + // GeeTODO Error + + } + else + { + // Get setting + SGUIStyle Style = m_Styles[argStyle]; + + // Iterate settings, it won't be able to set them all probably, but that doesn't matter + std::map::const_iterator cit; + for (cit = Style.m_SettingsDefaults.begin(); cit != Style.m_SettingsDefaults.end(); ++cit) + { + // Try set setting in object + try + { + object->SetSetting(cit->first, cit->second); + } + // It doesn't matter if it fail, it's not suppose to be able to set every setting. + // since it's generic. + catch (...) {} + } + } + } + // // Read Attributes // @@ -530,15 +636,15 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent) for (i=0; igetLength(); ++i) { DOMAttr *attr = (DOMAttr*)attributes->item(i); - string attr_name = XMLString::transcode( attr->getName() ); - string attr_value = XMLString::transcode( attr->getValue() ); + CStr attr_name = XMLString::transcode( attr->getName() ); + CStr attr_value = XMLString::transcode( attr->getValue() ); - // Ignore "type", we've already checked it - if (attr_name == "type") + // Ignore "type" and "style", we've already checked it + if (attr_name == CStr("type") || attr_name == CStr("style") ) continue; // Also the name needs some special attention - if (attr_name == "name") + if (attr_name == CStr("name")) { object->SetName(attr_value); NameSet = true; @@ -552,7 +658,7 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent) } catch (PS_RESULT e) { - ReportParseError("Can't set \"" + attr_name + "\" to \"" + attr_value + "\""); + ReportParseError(CStr("Can't set \"") + attr_name + CStr("\" to \"") + attr_value + CStr("\"")); // This is not a fatal error } @@ -611,7 +717,7 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent) } // GeeTODO check invalid strings? } - } + } // // Input Child @@ -625,7 +731,7 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent) pParent->AddChild(object); } catch (PS_RESULT e) - { + { ReportParseError(e); } } @@ -695,29 +801,88 @@ void CGUI::Xerces_ReadImage(XERCES_CPP_NAMESPACE::DOMElement *pElement, CGUISpri // // Now we can iterate all attributes and store -/* DOMNamedNodeMap *attributes = pElement->getAttributes(); + DOMNamedNodeMap *attributes = pElement->getAttributes(); for (int i=0; igetLength(); ++i) { DOMAttr *attr = (DOMAttr*)attributes->item(i); - string attr_name = XMLString::transcode( attr->getName() ); - string attr_value = XMLString::transcode( attr->getValue() ); + CStr attr_name = XMLString::transcode( attr->getName() ); + CStr attr_value(XMLString::transcode( attr->getValue() )); // This is the only attribute we want - if (attr_name == "texture") + if (attr_name == CStr("texture")) { image.m_Texture = attr_value; } else + if (attr_name == CStr("size")) { - // Log - g_console.submit("echo Error attribute " + attr_name + " is not expected in "); + CClientArea ca; + if (!GUI::ParseString(attr_value, ca)) + { + // GeeTODO : Error + } + else image.m_Size = ca; + } + else + if (attr_name == CStr("backcolor")) + { + CColor color; + if (!GUI::ParseString(attr_value, color)) + { + // GeeTODO : Error + } + else image.m_BackColor = color; + } + else + { + // GeeTODO Log + //g_console.submit("echo Error attribute " + attr_name + " is not expected in "); return; } } -*/ + // // Input // parent.AddImage(image); } + +void CGUI::Xerces_ReadStyle(XERCES_CPP_NAMESPACE::DOMElement *pElement) +{ + assert(pElement); + + // style object we're adding + SGUIStyle style; + CStr name; + + // + // Read Attributes + // + + // Now we can iterate all attributes and store + DOMNamedNodeMap *attributes = pElement->getAttributes(); + for (int i=0; igetLength(); ++i) + { + DOMAttr *attr = (DOMAttr*)attributes->item(i); + CStr attr_name = XMLString::transcode( attr->getName() ); + CStr attr_value = XMLString::transcode( attr->getValue() ); + + // The "name" setting is actually the name of the style + // and not a new default + if (attr_name == CStr("name")) + name = attr_value; + else + // Type cannot be styled + if (attr_name == CStr("type")) + ; // GeeTODO output warning + else + style.m_SettingsDefaults[attr_name] = attr_value; + } + + // + // Add to CGUI + // + + m_Styles[name] = style; +} diff --git a/source/gui/CGUI.h b/source/gui/CGUI.h index bf17c7ae7f..727fdf2c52 100755 --- a/source/gui/CGUI.h +++ b/source/gui/CGUI.h @@ -25,8 +25,7 @@ gee@pyro.nu #include #include -///// janwas: yeah I don't know how the including etiquette is really -#include "../ps/Singleton.h" +#include "Singleton.h" #include "input.h" // JW: grr, classes suck in this case :P class XERCES_CPP_NAMESPACE::DOMElement; @@ -49,6 +48,17 @@ extern bool gui_handler(const SDL_Event& ev); // Declarations //-------------------------------------------------------- +/** + * @author Gustav Larsson + * + * Contains a list of values for new defaults to objects. + */ +struct SGUIStyle +{ + // A list of defualts for + std::map m_SettingsDefaults; +}; + /** * @author Gustav Larsson * @@ -87,7 +97,18 @@ public: * Displays the whole GUI */ void Draw(); - + + /** + * Draw GUI Sprite, cooperates with CRenderer. + * + * @param SpriteName By name! The GUI will fetch the real object itself. + * @param Z Drawing order, depth value + * @param Rect Position and Size + * @param Clipping The sprite shouldn't be drawn outside this rectangle + */ + void DrawSprite(const CStr &SpriteName, const float &Z, + const CRect &Rect, const CRect &Clipping=CRect(0,0,0,0)); + /** * Clean up, call this to clean up all memory allocated * within the GUI. @@ -104,6 +125,9 @@ public: /** * Load a GUI XML file into the GUI. * + * VERY IMPORTANT! All \-files must be read before + * everything else! + * * @param Filename Name of file */ void LoadXMLFile(const std::string &Filename); @@ -254,6 +278,16 @@ private: */ void Xerces_ReadRootSprites(XERCES_CPP_NAMESPACE::DOMElement *pElement); + /** + * Reads in the root element \ (the DOMElement). + * + * @param pElement The Xerces C++ Parser object that represents + * the sprites-tag. + * + * @see LoadXMLFile() + */ + void Xerces_ReadRootStyles(XERCES_CPP_NAMESPACE::DOMElement *pElement); + // Read Subs /** @@ -300,6 +334,17 @@ private: */ void Xerces_ReadImage(XERCES_CPP_NAMESPACE::DOMElement *pElement, CGUISprite &parent); + /** + * Reads in the element \ (the DOMElement) and stores the + * result in m_Styles. + * + * @param pElement The Xerces C++ Parser object that represents + * the sprite-tag. + * + * @see LoadXMLFile() + */ + void Xerces_ReadStyle(XERCES_CPP_NAMESPACE::DOMElement *pElement); + //@} private: @@ -351,12 +396,16 @@ private: //@} //-------------------------------------------------------- - /** @name Sprites */ + /** @name Databases */ //-------------------------------------------------------- //@{ + /// Sprites std::map m_Sprites; + /// Styles + std::map m_Styles; + //@} }; diff --git a/source/gui/CGUISprite.cpp b/source/gui/CGUISprite.cpp index 0baad8bcbf..b7af60b49f 100755 --- a/source/gui/CGUISprite.cpp +++ b/source/gui/CGUISprite.cpp @@ -8,27 +8,8 @@ gee@pyro.nu #include "GUI.h" using namespace std; - +/* void CGUISprite::Draw(const float &z, const CRect &rect, const CRect &clipping=CRect(0,0,0,0)) { - bool DoClipping = (clipping != CRect(0,0,0,0)); - - // Iterate all images and request them being drawn be the - // CRenderer - std::vector::iterator it; - for (it=m_Images.begin(); it!=m_Images.end(); ++it) - { - glPushMatrix(); - glTranslatef(0.0f, 0.0f, z); - - // Do this - glBegin(GL_QUADS); - glVertex2i(rect.right, rect.bottom); - glVertex2i(rect.left, rect.bottom); - glVertex2i(rect.left, rect.top); - glVertex2i(rect.right, rect.top); - glEnd(); - - glPopMatrix(); - } } +*/ \ No newline at end of file diff --git a/source/gui/CGUISprite.h b/source/gui/CGUISprite.h index d2da115883..a787e19f7e 100755 --- a/source/gui/CGUISprite.h +++ b/source/gui/CGUISprite.h @@ -53,19 +53,18 @@ struct SGUIImage { CStr m_Texture; - // Placement modifiers - int m_Pixel[4]; - float m_Percent[4]; + // Image placement + CClientArea m_Size; - // Texture modifiers - int m_TexturePixel[4]; - float m_TexturePercent[4]; + // Texture placement + CClientArea m_TextureSize; - //CColor m_BackColor; - //CColor m_BorderColor; + // Color + CColor m_BackColor; + CColor m_BorderColor; -// int16 m_BorderSize; - bool m_Border; // I've decided to have only the 1 pixel available + // 0 or 1 pixel border is the only option + bool m_Border; }; /** @@ -74,9 +73,16 @@ struct SGUIImage * The GUI sprite, is actually several real sprites (images) * like a collage. View the section in the GUI * TDD for more information. + * + * Drawing routine is located in CGUI + * + * @see CGUI#DrawSprite */ class CGUISprite { + // For CGUI::DrawSprite() + friend class CGUI; + public: CGUISprite() {} virtual ~CGUISprite() {} @@ -89,7 +95,7 @@ public: * @param clipping The clipping rectangle, things should only * be drawn within these perimeters. */ - void Draw(const float &z, const CRect &rect, const CRect &clipping); + //void Draw(const float &z, const CRect &rect, const CRect &clipping); /** * Adds an image to the sprite collage. @@ -100,7 +106,7 @@ public: private: /// List of images - std::vector m_Images; + std::vector m_Images; }; #endif diff --git a/source/gui/GUI.h b/source/gui/GUI.h index 08de651eeb..38704a249b 100755 --- a/source/gui/GUI.h +++ b/source/gui/GUI.h @@ -59,19 +59,10 @@ gee@pyro.nu #include #include -//// janwas: these are very sloppy added, I don't know the etiquette -#include "../ps/Prometheus.h" -#include "../ps/CStr.h" +#include "Prometheus.h" +#include "CStr.h" #include "types.h" #include "ogl.h" -//// This is what I need from these includes -/* - - OGL - - #define DEFINE_ERROR(x, y) PS_RESULT x=y; - - #define DECLARE_ERROR(x) extern PS_RESULT x; - - PS_RESULT - - u16 -*/ #include "GUIbase.h" #include "GUIutil.h" diff --git a/source/gui/GUIbase.h b/source/gui/GUIbase.h index 85fcbdd74e..4fce545cfc 100755 --- a/source/gui/GUIbase.h +++ b/source/gui/GUIbase.h @@ -37,14 +37,17 @@ class IGUIObject; // Temp #define CInput nemInput -//#define CStr std::string -// Example -// GUI_ADD_OFFSET(CButton, SButtonSettings, m_Settings, "frozen", m_Frozen); -// -#define GUI_ADD_OFFSET(_class, _struct, name, type, str, var) \ - m_SettingsInfo[str].m_Offset = offsetof(_class, name) + offsetof(_struct, var); \ - m_SettingsInfo[str].m_Type = type; +#define GUI_ADD_OFFSET_GENERIC(si, guiss, _struct, var, type, str) \ + si[CStr(str)].m_Offset = offsetof(_struct, var); \ + si[CStr(str)].m_SettingsStruct = guiss; \ + si[CStr(str)].m_Type = CStr(type); + +#define GUI_ADD_OFFSET_BASE(_struct, var, type, str) \ + GUI_ADD_OFFSET_GENERIC(m_SettingsInfo, GUISS_BASE, _struct, var, type, str) + +#define GUI_ADD_OFFSET_EXT(_struct, var, type, str) \ + GUI_ADD_OFFSET_GENERIC(m_SettingsInfo, GUISS_EXTENDED, _struct, var, type, str) // Declares the static variable in IGUISettingsObject<> #define DECLARE_SETTINGS_INFO(_struct) \ @@ -95,6 +98,16 @@ enum GUIRR_DISABLED=2 }; +/** + * @enum EGUISettingsStruct + * TODO comment + */ +enum EGUISettingsStruct +{ + GUISS_BASE, + GUISS_EXTENDED +}; + // Typedefs typedef std::map map_pObjects; typedef std::vector vector_pObjects; diff --git a/source/gui/GUIutil.cpp b/source/gui/GUIutil.cpp index 184838f7d6..b2e3dfdc96 100755 --- a/source/gui/GUIutil.cpp +++ b/source/gui/GUIutil.cpp @@ -6,7 +6,7 @@ gee@pyro.nu //#include "stdafx.h" #include "GUI.h" -#include "../ps/Parser.h" +#include "Parser.h" using namespace std; @@ -23,8 +23,12 @@ CClientArea::CClientArea(const CStr &Value) SetClientArea(Value); } -CRect CClientArea::GetClientArea(const CRect &parent) +CRect CClientArea::GetClientArea(const CRect &parent) const { + // If it's a 0 0 100% 100% we need no calculations + if (percent == CRect(0,0,100,100) && pixel == CRect(0,0,0,0)) + return parent; + CRect client; // This should probably be cached and not calculated all the time for every object. @@ -170,5 +174,5 @@ const IGUIObject * CInternalCGUIAccessorBase::GetObjectPointer(const CGUI &GUIin void CInternalCGUIAccessorBase::QueryResetting(IGUIObject *pObject) { - GUI<>::RecurseObject(0, pObject, IGUIObject::ResetStates); + GUI<>::RecurseObject(0, pObject, &IGUIObject::ResetStates); } diff --git a/source/gui/GUIutil.h b/source/gui/GUIutil.h index 31024ea270..250002dfb1 100755 --- a/source/gui/GUIutil.h +++ b/source/gui/GUIutil.h @@ -22,6 +22,7 @@ gee@pyro.nu // Includes / Compiler directives //-------------------------------------------------------- #include "GUI.h" +#include "Parser.h" //-------------------------------------------------------- // Help Classes/Structs for the GUI @@ -51,6 +52,12 @@ struct CRect } }; +// TEMP +struct CColor +{ + float r, g, b, a; +}; + /** * @author Gustav Larsson * @@ -74,7 +81,7 @@ public: /** * Get client area rectangle when the parent is given */ - CRect GetClientArea(const CRect &parent); + CRect GetClientArea(const CRect &parent) const; /** * The ClientArea can be set from a string looking like: @@ -94,13 +101,6 @@ public: bool SetClientArea(const CStr &Value); }; - -// TEMP -struct CColor -{ - float r, g, b, a; -}; - //-------------------------------------------------------- // Forward declarations //-------------------------------------------------------- @@ -163,7 +163,9 @@ public: return PS_SETTING_FAIL; // Set value - Value = *(T*)((size_t)pObject+pObject->GetSettingsInfo()[Setting].m_Offset); + Value = + *(T*)((size_t)pObject->GetStructPointer(pObject->GetSettingsInfo()[Setting].m_SettingsStruct) + + pObject->GetSettingsInfo()[Setting].m_Offset); return PS_OK; } @@ -187,8 +189,8 @@ public: return PS_SETTING_FAIL; // Set value - // This better be the correct adress - *(T*)((size_t)pObject+pObject->GetSettingsInfo()[Setting].m_Offset) = Value; + *(T*)((size_t)pObject->GetStructPointer(pObject->GetSettingsInfo()[Setting].m_SettingsStruct) + + pObject->GetSettingsInfo()[Setting].m_Offset) = Value; // @@ -198,7 +200,7 @@ public: // If setting was "size", we need to re-cache itself and all children if (Setting == CStr(_T("size"))) { - RecurseObject(0, pObject, IGUIObject::UpdateCachedSize); + RecurseObject(0, pObject, &IGUIObject::UpdateCachedSize); } else if (Setting == CStr(_T("hidden"))) @@ -261,85 +263,173 @@ public: return SetSetting(pObject, Setting, Value); } - //-------------------------------------------------------- - // This function returns the C++ structure of the - // inputted string. For instance if you input - // "0 0 10 10" and request a CRect, it will give you - // a CRect(0,0,10,10). - // This function is widely used within the GUI. - // Input: - // String The Value in string format - // Return: - // Returns the value in the structure T. - //-------------------------------------------------------- -/* static T GetStringValue(const CStr &String) + + /** + * Sets a value by setting and object name using a real + * datatype as input. + * + * This is just a wrapper for _mem_ParseString() which really + * works the magic. + * + * @param Type type in string, like "float" or "client area" + * @param Value The value in string form, like "0 0 100% 100%" + * @param tOutput Parsed value of type T + * @return True at success. + * + * @see _mem_ParseString() + */ + static bool ParseString(const CStr &Value, T &tOutput) { - if (typeid(T) == typeid(int)) - { - return atoi(String.c_str()); - } + void *mem = NULL; - if (typeid(T) == typeid(float) || - typeid(T) == typeid(double)) - { - return atof(String.c_str()); - } + if (!_mem_ParseString(Value, mem)) + return false; + + // Copy from memory + tOutput = *(T*)mem; - if (typeid(T) == typeid(CRect)) - { - (CRect)return CRect(); - } + delete [] mem; - if (typeid(T) == typeid(CColor)) - { - return CColor(); - } - - switch(typeid(T)) - { - case typeid(int): - return atoi(String); - - case typeid(float): - case typeid(double): - return atof(String); - - case typeid(CRect): - return CRect(0,0,0,0); - - case typeid(CColor): - return CColor(0,0,0,0); - - default: - // Repport error unrecognized - return T(); - } - - // If this function is called T is unrecognized - - // TODO repport error - - return T(); + // Undefined type - GeeTODO, maybe report in log + return true; } -*/ -/* - static T GetStringValue(const CStr &String) - { - return atoi(String.c_str()); - } -*/ - // int -/* static int GetStringValue(const CStr &String) - { - // If this function is called T is unrecognized - - // TODO repport error - - return 10; - } -*/ private: + /** + * Input a value in string form, and it will output the result in + * Memory with type T. + * + * @param Type type in string, like "float" or "client area" + * @param Value The value in string form, like "0 0 100% 100%" + * @param Memory Should be NULL, will be constructed within the function. + * @return True at success. + */ + static bool _mem_ParseString(const CStr &Value, void *&Memory) + { +/* if (typeid(T) == typeid(CStr)) + { + tOutput = Value; + return true; + } + else +*/ if (typeid(T) == typeid(bool)) + { + bool _Value; + + if (Value == CStr(_T("true"))) + _Value = true; + else + if (Value == CStr(_T("false"))) + _Value = false; + else + return false; + + Memory = malloc(sizeof(bool)); + memcpy(Memory, (const void*)&_Value, sizeof(bool)); + return true; + } + else + if (typeid(T) == typeid(float)) + { + float _Value = Value.ToFloat(); + // GeeTODO Okay float value!? + Memory = malloc(sizeof(float)); + memcpy(Memory, (const void*)&_Value, sizeof(float)); + return true; + } + else + if (typeid(T) == typeid(CRect)) + { + // Use the parser to parse the values + CParser parser; + parser.InputTaskType("", "_$value_$value_$value_$value_"); + + string str = (const TCHAR*)Value; + + CParserLine line; + line.ParseString(parser, str); + if (!line.m_ParseOK) + { + // Parsing failed + return false; + } + int values[4]; + for (int i=0; i<4; ++i) + { + if (!line.GetArgInt(i, values[i])) + { + // Parsing failed + return false; + } + } + + // Finally the rectangle values + CRect _Value(values[0], values[1], values[2], values[3]); + + Memory = malloc(sizeof(CRect)); + memcpy(Memory, (const void*)&_Value, sizeof(CRect)); + return true; + } + else + if (typeid(T) == typeid(CClientArea)) + { + // Get Client Area + CClientArea _Value; + + // Check if valid! + if (!_Value.SetClientArea(Value)) + { + return false; + } + + Memory = malloc(sizeof(CClientArea)); + memcpy(Memory, (const void*)&_Value, sizeof(CClientArea)); + return true; + } + else + if (typeid(T) == typeid(CColor)) + { + // Use the parser to parse the values + CParser parser; + parser.InputTaskType("", "_$value_$value_$value_[$value_]"); + + string str = (const TCHAR*)Value; + + CParserLine line; + line.ParseString(parser, str); + if (!line.m_ParseOK) + { + // Parsing failed GeeTODO + return false; + } + float values[4]; + values[3] = 255.f; // default + for (int i=0; i ///// @@ -20,10 +20,10 @@ map_Settings IGUIObject::m_SettingsInfo; //------------------------------------------------------------------- // Implementation Macros //------------------------------------------------------------------- -#define _GUI_ADD_OFFSET(type, str, var) \ +/*#define _GUI_ADD_OFFSET(type, str, var) \ SettingsInfo[str].m_Offset = offsetof(IGUIObject, m_BaseSettings) + offsetof(SGUIBaseSettings,var); \ SettingsInfo[str].m_Type = type; - +*/ //------------------------------------------------------------------- // Constructor / Destructor //------------------------------------------------------------------- @@ -119,13 +119,21 @@ void IGUIObject::Destroy() void IGUIObject::SetupBaseSettingsInfo(map_Settings &SettingsInfo) { - _GUI_ADD_OFFSET("bool", "enabled", m_Enabled) +/* _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) _GUI_ADD_OFFSET("bool", "absolute", m_Absolute) +*/ + GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Enabled, "bool", "enabled") + GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Hidden, "bool", "hidden") + GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Size, "client area", "size") + GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Style, "string", "style") + GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Z, "float", "z") + GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Caption, "string", "caption") + GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Absolute, "bool", "absolute") } bool IGUIObject::MouseOver() @@ -200,74 +208,43 @@ void IGUIObject::SetSetting(const CStr &Setting, const CStr &Value) if (set.m_Type == CStr(_T("string"))) { - GUI::SetSetting(this, Setting, Value); + GUI::SetSetting(this, Setting, Value); } else if (set.m_Type == CStr(_T("bool"))) { - bool bValue; - - if (Value == CStr(_T("true"))) - bValue = true; - else - if (Value == CStr(_T("false"))) - bValue = false; - else + bool _Value; + if (!GUI::ParseString(Value, _Value)) throw PS_FAIL; - GUI::SetSetting(this, Setting, bValue); + GUI::SetSetting(this, Setting, _Value); } else if (set.m_Type == CStr(_T("float"))) { - // GeeTODO Okay float value!? - GUI::SetSetting(this, Setting, Value.ToFloat() ); + float _Value; + if (!GUI::ParseString(Value, _Value)) + throw PS_FAIL; + + GUI::SetSetting(this, Setting, _Value); } else if (set.m_Type == CStr(_T("rect"))) { - // Use the parser to parse the values - CParser parser; - parser.InputTaskType("", "_$value_$value_$value_$value_"); - - // GeeTODO string really? - string str = (const TCHAR*)Value; - - CParserLine line; - line.ParseString(parser, str); - if (!line.m_ParseOK) - { - // ERROR! + CRect _Value; + if (!GUI::ParseString(Value, _Value)) throw PS_FAIL; - } - int values[4]; - for (int i=0; i<4; ++i) - { - if (!line.GetArgInt(i, values[i])) - { - // ERROR! - throw PS_FAIL; - } - } - // Finally the rectangle values - CRect rect(values[0], values[1], values[2], values[3]); - GUI::SetSetting(this, Setting, rect); + GUI::SetSetting(this, Setting, _Value); } else if (set.m_Type == CStr(_T("client area"))) { - // Get Client Area - CClientArea ca; + CClientArea _Value; + if (!GUI::ParseString(Value, _Value)) + throw PS_FAIL; - if (!ca.SetClientArea(Value)) - { - // GeeTODO REPORT - } - - // Check if valid! - - GUI::SetSetting(this, Setting, ca); + GUI::SetSetting(this, Setting, _Value); } else { @@ -308,6 +285,19 @@ IGUIObject *IGUIObject::GetParent() return m_pParent; } +void * IGUIObject::GetStructPointer(const EGUISettingsStruct &SettingsStruct) const +{ + switch (SettingsStruct) + { + case GUISS_BASE: + return (void*)&m_BaseSettings; + + default: + // GeeTODO report error + return NULL; + } +} + void IGUIObject::UpdateCachedSize() { // If absolute="false" and the object has got a parent, diff --git a/source/gui/IGUIObject.h b/source/gui/IGUIObject.h index f3a853db49..ec26626456 100755 --- a/source/gui/IGUIObject.h +++ b/source/gui/IGUIObject.h @@ -70,8 +70,9 @@ enum EValign { EValign_Top, EValign_Bottom, EValign_Center }; */ struct SGUISetting { - size_t m_Offset; // The offset from IGUIObject to the variable (not from SGUIBaseSettings or similar) - CStr m_Type; // "string" or maybe "int" + size_t m_Offset; // The offset from IGUIObject to the variable (not from SGUIBaseSettings or similar) + EGUISettingsStruct m_SettingsStruct; + CStr m_Type; // "string" or maybe "int" }; /** @@ -103,7 +104,6 @@ struct SGUIBaseSettings class IGUIObject { friend class CGUI; - friend class CInternalCGUIAccessorBase; #ifndef _MSC_VER template @@ -237,6 +237,8 @@ public: * * @param Setting Setting by name * @param Value Value to set to + * + * @throws PS_RESULT */ void SetSetting(const CStr &Setting, const CStr &Value); @@ -302,6 +304,14 @@ protected: */ IGUIObject *GetParent(); + /** + * You input the setting struct you want, and it will return a pointer to + * the struct. + * + * @param SettingsStruct tells us which pointer ot return + */ + virtual void *GetStructPointer(const EGUISettingsStruct &SettingsStruct) const; + // Get cached mouse x/y from CGUI u16 GetMouseX() const; u16 GetMouseY() const; @@ -361,6 +371,18 @@ protected: /// Base settings SGUIBaseSettings m_BaseSettings; + /** + * This is an array of true or false, each element is associated with + * a string representing a setting. Number of elements is equal to + * number of settings. + * + * A true means the setting has been manually set in the file when + * read. This is important to know because I don't want to force + * the user to include its -XML-files first, so somehow + * the GUI needs to know which settings were set, and which is meant + * to + */ + // More variables /// Is mouse hovering the object? used with the function MouseOver() diff --git a/source/gui/IGUISettingsObject.cpp b/source/gui/IGUISettingsObject.cpp index a0ad91570a..bdec22f724 100755 --- a/source/gui/IGUISettingsObject.cpp +++ b/source/gui/IGUISettingsObject.cpp @@ -8,3 +8,4 @@ gee@pyro.nu #include "GUI.h" using namespace std; + diff --git a/source/gui/IGUISettingsObject.h b/source/gui/IGUISettingsObject.h index 222113f7cf..2ec7054133 100755 --- a/source/gui/IGUISettingsObject.h +++ b/source/gui/IGUISettingsObject.h @@ -101,6 +101,28 @@ public: } protected: + /** + * You input the setting struct you want, and it will return a pointer to + * the struct. + * + * @param SettingsStruct tells us which pointer to return + */ + virtual void *GetStructPointer(const EGUISettingsStruct &SettingsStruct) const + { + switch (SettingsStruct) + { + case GUISS_BASE: + return (void*)&m_BaseSettings; + + case GUISS_EXTENDED: + return (void*)&m_Settings; + + default: + // GeeTODO report error + return NULL; + } + } + /// Settings struct SETTINGS m_Settings;