diff --git a/source/gui/CButton.cpp b/source/gui/CButton.cpp new file mode 100755 index 0000000000..34b902ff4a --- /dev/null +++ b/source/gui/CButton.cpp @@ -0,0 +1,157 @@ +/* +CButton +by Gustav Larsson +gee@pyro.nu +*/ + +//#include "stdafx." +#include "GUI.h" + +using namespace std; + +// TEMP TODO Gee +///extern nemFontNTF font; + +// 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 +//------------------------------------------------------------------- +CButton::CButton() +{ + // Settings defaults ! + m_Settings.m_Disabled = false; + m_Settings.m_Font = "null"; + m_Settings.m_Sprite = "null"; + m_Settings.m_SpriteDisabled = "null"; + m_Settings.m_SpriteOver = "null"; + m_Settings.m_SpritePressed = "null"; + m_Settings.m_TextAlign = EAlign_Center; +// m_Settings.m_TextColor = CColor(); +// m_Settings.m_TextColorDisabled; +// m_Settings.m_TextColorOver; +// m_Settings.m_TextColorPressed; + m_Settings.m_TextValign = EValign_Center; + m_Settings.m_ToolTip = "null"; + m_Settings.m_ToolTipStyle = "null"; + + + // Static! Only done once + if (m_SettingsInfo.empty()) + { + // 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) + } +} + +CButton::~CButton() +{ +} + +//------------------------------------------------------------------- +// Handles messages send from the CGUI +// Input: +// Message Message ID, GUIM_* +//------------------------------------------------------------------- +void CButton::HandleMessage(const EGUIMessage &Message) +{ +// TODO REMOVE +#define OUTPUT(x) g_console.submit("echo Object(%s) %s", m_Name.c_str(), #x); + + CGUIButtonBehavior::HandleMessage(Message); + + switch (Message) + { + case GUIM_PREPROCESS: + break; + + case GUIM_POSTPROCESS: + break; + + case GUIM_MOUSE_OVER: + 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: +/// OUTPUT(GUIM_PRESSED); + break; + + default: + break; + } +} + +//------------------------------------------------------------------- +// Draws the object +// Input: +// pInput Handler of keyboard and mouse +//------------------------------------------------------------------- +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.right/300.f); + } + else + glColor3f((float)m_BaseSettings.m_Size.right/300.f,0,1); + + glPushMatrix(); + glTranslatef(0.0f, 0.0f, GetBaseSettings().m_Z); + + // Do this + glBegin(GL_QUADS); + 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); + + 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(); +} \ No newline at end of file diff --git a/source/gui/CButton.h b/source/gui/CButton.h new file mode 100755 index 0000000000..bfdc5f8db9 --- /dev/null +++ b/source/gui/CButton.h @@ -0,0 +1,77 @@ +/* +GUI Object - Button +by Gustav Larsson +gee@pyro.nu + +--Overview-- + + GUI Object representing a simple button + +--More info-- + + Check GUI.h + +*/ + +#ifndef CButton_H +#define CButton_H + +//-------------------------------------------------------- +// Includes / Compiler directives +//-------------------------------------------------------- +#include "GUI.h" + +//-------------------------------------------------------- +// Macros +//-------------------------------------------------------- + +//-------------------------------------------------------- +// Types +//-------------------------------------------------------- + +//-------------------------------------------------------- +// Declarations +//-------------------------------------------------------- + +// Settings +struct SButtonSettings +{ + bool m_Disabled; + CStr m_Font; + CStr m_Sprite; + CStr m_SpriteDisabled; + CStr m_SpriteOver; + CStr m_SpritePressed; + EAlign m_TextAlign; + CColor m_TextColor; + CColor m_TextColorDisabled; + CColor m_TextColorOver; + CColor m_TextColorPressed; + EValign m_TextValign; + CStr m_ToolTip; + CStr m_ToolTipStyle; +}; + +/////////////////////////////////////////////////////////////////////////////// + +class CButton : public CGUISettingsObject, public CGUIButtonBehavior +{ + GUI_OBJECT(CButton) + +public: + CButton(); + virtual ~CButton(); + + + + // Since we're doing multiple inheritance, this is to avoid error message + virtual map_Settings GetSettingsInfo() const { return CGUISettingsObject::m_SettingsInfo; } + + // Handle Messages + virtual void HandleMessage(const EGUIMessage &Message); + + // Draw + virtual void Draw(); +}; + +#endif \ No newline at end of file diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp new file mode 100755 index 0000000000..53bd746b46 --- /dev/null +++ b/source/gui/CGUI.cpp @@ -0,0 +1,737 @@ +/* +CGUI +by Gustav Larsson +gee@pyro.nu +*/ + +//#include "stdafx." +#include "GUI.h" +#include +#include +#include + +///#include "nemesis.h" +//#include incCONSOLE + +#include +#include +#include +#include +#include +#include "XercesErrorHandler.h" + +// namespaces used +XERCES_CPP_NAMESPACE_USE +using namespace std; + +#ifdef _MSC_VER +#pragma comment(lib, "xerces-c_2.lib") +#endif + + +#include "input.h" + +// JW: how about having each object export hit_test(x,y), +// instead of accessing the global mouse pos? +int gui_mouse_x, gui_mouse_y; + +// called from main loop when (input) events are received. +// event is passed to other handlers if false is returned. + +// JW: problem! this needs to be static, or not a member function +// (it's a callback from the input distributor) +bool InputHandler(const SDL_Event& ev) +{ + if(ev.type == SDL_MOUSEMOTION) + gui_mouse_x = ev.motion.x, gui_mouse_y = ev.motion.y; + +// JW: (pre|post)process omitted; what're they for? why would we need any special button_released handling? + + // Only one object can be hovered + // check which one it is, if any ! + CGUIObject *pNearest = NULL; + +// GUI::RecurseObject(GUIRR_HIDDEN, m_BaseObject, &CGUIObject::ChooseMouseOverAndClosest, pNearest); + + // Now we'll call UpdateMouseOver on *all* objects, + // we'll input the one hovered, and they will each + // update their own data and send messages accordingly +// GUI::RecurseObject(GUIRR_HIDDEN, m_BaseObject, &CGUIObject::UpdateMouseOver, pNearest); + + if(pNearest) + { +/* if(ev.type == SDL_MOUSEBUTTONDOWN) + pNearest->HandleMessage(GUIM_MOUSE_PRESS_LEFT); // JW: want to pass SDL button value, or translate? + else if(ev.type == SDL_MOUSEBUTTONUP) + pNearest->HandleMessage(GUIM_MOUSE_RELEASE_LEFT); // JW: want to pass SDL button value, or translate? +*/ + } + +// JW: what's the difference between mPress and mDown? what's the code below responsible for? +/*/* // Generally if just mouse is clicked + if (m_pInput->mDown(NEMM_BUTTON1) && pNearest) + { + pNearest->HandleMessage(GUIM_MOUSE_DOWN_LEFT); + } +*/ + + return false; +} + +//------------------------------------------------------------------- +// Constructor / Destructor +//------------------------------------------------------------------- +CGUI::CGUI() +{ + m_BaseObject = new CButton; // Big todo! + m_BaseObject->SetGUI(this); + + // This will make this invisible, not add + //m_BaseObject->SetName(BASE_OBJECT_NAME); +} + +CGUI::~CGUI() +{ + if (m_BaseObject) + delete m_BaseObject; +} + +// Construct an object +CGUIObject *CGUI::ConstructObject(const CStr &str) +{ + if (m_ObjectTypes.count(str) > 0) + return (*m_ObjectTypes[str])(); + else + return NULL; +} + +//------------------------------------------------------------------- +// Initializes the GUI +// Inputs: +// +//------------------------------------------------------------------- +void CGUI::Initialize(/*/*CInput *pInput*/) +{ +/// m_pInput = pInput; + + // Add base types! + AddObjectType("button", &CButton::ConstructObject); +} + +//------------------------------------------------------------------- +// Process the GUI, this should be run every loop after CInput +// has been processed +//------------------------------------------------------------------- +void CGUI::Process() +{ +/*/* + + // GeeTODO / check if m_pInput is valid, otherwise return +/// assert(m_pInput); + + // Pre-process all objects + try + { + GUI::RecurseObject(0, m_BaseObject, &CGUIObject::HandleMessage, GUIM_PREPROCESS); + } + catch (PS_RESULT e) + { + return; + } + + // Check mouse over + try + { + // Only one object can be hovered + // check which one it is, if any ! + CGUIObject *pNearest = NULL; + + GUI::RecurseObject(GUIRR_HIDDEN, m_BaseObject, &CGUIObject::ChooseMouseOverAndClosest, pNearest); + + // Now we'll call UpdateMouseOver on *all* objects, + // we'll input the one hovered, and they will each + // update their own data and send messages accordingly + GUI::RecurseObject(GUIRR_HIDDEN, m_BaseObject, &CGUIObject::UpdateMouseOver, pNearest); + + // If pressed + if (m_pInput->mPress(NEMM_BUTTON1) && pNearest) + { + pNearest->HandleMessage(GUIM_MOUSE_PRESS_LEFT); + } + else + // If released + if (m_pInput->mRelease(NEMM_BUTTON1) && pNearest) + { + pNearest->HandleMessage(GUIM_MOUSE_RELEASE_LEFT); + } + + // Generally if just mouse is clicked + if (m_pInput->mDown(NEMM_BUTTON1) && pNearest) + { + pNearest->HandleMessage(GUIM_MOUSE_DOWN_LEFT); + } + + } + catch (PS_RESULT e) + { + return; + } + + // Post-process all objects + try + { + GUI::RecurseObject(0, m_BaseObject, &CGUIObject::HandleMessage, GUIM_POSTPROCESS); + } + catch (PS_RESULT e) + { + return; + } +*/ +} + +//------------------------------------------------------------------- +// Make all drawing calls of the GUI +//------------------------------------------------------------------- +void CGUI::Draw() +{ + try + { + // Recurse CGUIObject::Draw() + GUI<>::RecurseObject(GUIRR_HIDDEN, m_BaseObject, &CGUIObject::Draw); + } + catch (PS_RESULT e) + { + return; + } +} + +//------------------------------------------------------------------- +// Shutdown all memory +//------------------------------------------------------------------- +void CGUI::Destroy() +{ + // We can use the map to delete all + // now we don't want to cancel all if one Destory fails + map_pObjects::iterator it; + for (it = m_pAllObjects.begin(); it != m_pAllObjects.end(); ++it) + { + try + { + it->second->Destroy(); + } + catch (PS_RESULT e) + { + + } + + delete it->second; + it->second = NULL; + } + + // Clear all + m_pAllObjects.clear(); + m_Sprites.clear(); +} + +//------------------------------------------------------------------- +// Adds an object to the GUI's object database +// Input: +// Name Name of object +// pObject Object's pointer +// +// Return: +// Throws PS_RESULT +//------------------------------------------------------------------- +void CGUI::AddObject(CGUIObject* pObject) +{ + try + { + // Add CGUI pointer + GUI::RecurseObject(0, pObject, &CGUIObject::SetGUI, this); + + // Add child to base object + m_BaseObject->AddChild(pObject); + } + catch (PS_RESULT e) + { + throw e; + } +} + +//------------------------------------------------------------------- +// Should be called when an object has been +// This function is atomic, meaning if it throws anything, it will +// have seen it through that nothing was ultimately changed. +// Throws: +// Whatever AddToPointersMap throws +//------------------------------------------------------------------- +void CGUI::UpdateObjects() +{ + // We'll fill a temporary map until we know everything + // succeeded + map_pObjects AllObjects; + + try + { + // Fill freshly + GUI< map_pObjects >::RecurseObject(0, m_BaseObject, &CGUIObject::AddToPointersMap, AllObjects ); + } + catch (PS_RESULT e) + { + // Throw the same error + throw e; + } + + // Else actually update the real one + m_pAllObjects = AllObjects; +} + +//------------------------------------------------------------------- +// Check if an object exists by name +// Input: +// Name Object reference name +//------------------------------------------------------------------- +bool CGUI::ObjectExists(const CStr &Name) const +{ + if (m_pAllObjects.count(Name)) + return true; + else + return false; +} + +//------------------------------------------------------------------- +// Report XML Reading Error, should be called from within the +// Xerces_* functions. These will not +// Input: +// str String explaining error +//------------------------------------------------------------------- +void CGUI::ReportParseError(const CStr &str, ...) +{ + // Print header + if (m_Errors==0) + { +/// g_nemLog("*** GUI Tree Creation Errors"); + } + + // Important, set ParseError to true + ++m_Errors; + + char buffer[512]; + va_list args; + + // get arguments + va_start(args, str); + vsprintf(buffer, str.c_str(), args); + va_end(args); + +/// g_nemLog(" %s", buffer); +} + +//------------------------------------------------------------------- +// Adds an object to the GUI's object database +// Input: +// Filename XML filename +//------------------------------------------------------------------- +void CGUI::LoadXMLFile(const CStr &Filename) +{ + // Reset parse error + // we can later check if this has increased + m_Errors = 0; + + // Initialize XML library + XMLPlatformUtils::Initialize(); + + // Create parser instance + XercesDOMParser *parser = new XercesDOMParser(); + + bool ParseFailed = false; + + if (parser) + { + // Setup parser + parser->setValidationScheme(XercesDOMParser::Val_Auto); + parser->setDoNamespaces(false); + parser->setDoSchema(false); + + // Set cosutomized error handler + XercesErrorHandler *errorHandler = new XercesErrorHandler(); + parser->setErrorHandler(errorHandler); + + parser->setCreateEntityReferenceNodes(false); + + try + { +/// g_nemLog("*** Xerces XML Parsing Errors"); + + // Get main node + LocalFileInputSource source( XMLString::transcode(Filename.c_str()) ); + + // parse + parser->parse(source); + + // Check how many errors + ParseFailed = parser->getErrorCount() != 0; + if (ParseFailed) + { + // TODO report for real! +/// g_console.submit("echo Xerces XML Parsing Reports %d errors", parser->getErrorCount()); + } + } + catch (const XMLException& toCatch) + { + char* message = XMLString::transcode(toCatch.getMessage()); +/// g_console.submit("echo Exception message is: %s", message); + XMLString::release(&message); + } + catch (const DOMException& toCatch) + { + char* message = XMLString::transcode(toCatch.msg); +/// g_console.submit("echo Exception message is: %s", message); + XMLString::release(&message); + } + catch (...) + { +/// g_console.submit("echo Unexpected Exception"); + } + + // Parse Failed? + if (!ParseFailed) + { + DOMDocument *doc = parser->getDocument(); + DOMElement *node = doc->getDocumentElement(); + + // Check root element's (node) name so we know what kind of + // data we'll be expecting + string root_name = XMLString::transcode( node->getNodeName() ); + + if (root_name == "objects") + { + Xerces_ReadRootObjects(node); + } + else + if (root_name == "sprites") + { + Xerces_ReadRootSprites(node); + } + } + } + + // Now report if any other errors occured + if (m_Errors > 0) + { +/// g_console.submit("echo GUI Tree Creation Reports %d errors", m_Errors); + } + + XMLPlatformUtils::Terminate(); +} + + +//=================================================================== +// XML Reading Xerces Specific Sub-Routines +//=================================================================== + +//------------------------------------------------------------------- +// Reads in the root element (the DOMElement). +// Input: +// pElement The Xerces C++ Parser object that represents +// the . +//------------------------------------------------------------------- +void CGUI::Xerces_ReadRootObjects(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_ReadObject(element, m_BaseObject); + } + } +} + +//------------------------------------------------------------------- +// Reads in the root element (the DOMElement). +// Input: +// pElement The Xerces C++ Parser object that represents +// the . +//------------------------------------------------------------------- +void CGUI::Xerces_ReadRootSprites(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_ReadSprite(element); + } + } +} + + +//------------------------------------------------------------------- +// Notice! Recursive function! +// +// Reads in an (the DOMElement) and stores it +// as a child in the pParent. +// It will also check the object's children and call this function +// on them too. Also it will call all other functions that reads +// in other stuff that can be found within an object. Such as +// will call Xerces_ReadAction (TODO, real funcion?) +// Input: +// pParent Parent to add this object as child in +// pElement The Xerces C++ Parser object that represents +// the . +//------------------------------------------------------------------- +void CGUI::Xerces_ReadObject(DOMElement *pElement, CGUIObject *pParent) +{ + assert(pParent && pElement); + + // Our object we are going to create + CGUIObject *object = NULL; + + // Well first of all we need to determine the type + string type = XMLString::transcode( pElement->getAttribute( XMLString::transcode("type") ) ); + + // Construct object from specified type + // henceforth, we need to do a rollback before aborting. + // i.e. releasing this object + object = ConstructObject(type); + + if (!object) + { + // Report error that object was unsuccessfully loaded + ReportParseError("Unrecognized type: " + type); + + delete object; + return; + } + + // + // Read Attributes + // + + bool NameSet = false; + + // Now we can iterate all attributes and store + 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() ); + + // Ignore "type", we've already checked it + if (attr_name == "type") + continue; + + // Also the name needs some special attention + if (attr_name == "name") + { + object->SetName(attr_value); + NameSet = true; + continue; + } + + // Try setting the value + try + { + object->SetSetting(attr_name, attr_value); + } + catch (PS_RESULT e) + { + ReportParseError("Can't set \"" + attr_name + "\" to \"" + attr_value + "\""); + + // This is not a fatal error + } + } + + // Check if name isn't set, report error in that case + if (!NameSet) + { + // Set Random name! TODO + } + + // + // Read Children + // + + // Iterate children + DOMNodeList *children = pElement->getChildNodes(); + + for (int i=0; igetLength(); ++i) + { + // Get node + DOMNode *child = children->item(i); + + // Check type (it's probably text or element) + + // A child element + if (child->getNodeType() == DOMNode::ELEMENT_NODE) + { + // Check what name the elements got + string element_name = XMLString::transcode( child->getNodeName() ); + + if (element_name == "object") + { + // First get element and not node + DOMElement *element = (DOMElement*)child; + + // TODO REPORT ERROR + + // Call this function on the child + Xerces_ReadObject(element, object); + } + } + else + if (child->getNodeType() == DOMNode::TEXT_NODE) + { + CStr caption = XMLString::transcode( child->getNodeValue() ); + + // Text is only okay if it's the first element i.e. caption ... + if (i==0) + { + // TODO !!!!! CROP STRING! + + // Set the setting caption to this + GUI::SetSetting(object, "caption", caption); + } + // TODO check invalid strings? + } + } + + // + // Input Child + // + + try + { + if (pParent == m_BaseObject) + AddObject(object); + else + pParent->AddChild(object); + } + catch (PS_RESULT e) + { + ReportParseError(e); + } +} + + +//------------------------------------------------------------------- +// Reads in a (the DOMElement). +// Input: +// pElement The Xerces C++ Parser object that represents +// the . +//------------------------------------------------------------------- +void CGUI::Xerces_ReadSprite(XERCES_CPP_NAMESPACE::DOMElement *pElement) +{ + assert(pElement); + + // Sprite object we're adding + CGUISprite sprite; + + // and what will be its reference name + CStr name; + + // + // Read Attributes + // + + // Get name, we know it exists because of DTD requirements + name = XMLString::transcode( pElement->getAttribute( XMLString::transcode("name") ) ); + + // + // Read Children (the images) + // + + // Iterate children + DOMNodeList *children = pElement->getChildNodes(); + + for (int i=0; igetLength(); ++i) + { + // Get node + DOMNode *child = children->item(i); + + // Check type (it's probably text or element) + + // A child element + if (child->getNodeType() == DOMNode::ELEMENT_NODE) + { + // All Elements will be of type "image" by DTD law + + // First get element and not node + DOMElement *element = (DOMElement*)child; + + // Call this function on the child + Xerces_ReadImage(element, sprite); + } + } + + // + // Add Sprite + // + + m_Sprites[name] = sprite; +} + + +//------------------------------------------------------------------- +// Reads in a (the DOMElement) to parent +// Input: +// parent Sprite to add this image too +// pElement The Xerces C++ Parser object that represents +// the . +//------------------------------------------------------------------- +void CGUI::Xerces_ReadImage(XERCES_CPP_NAMESPACE::DOMElement *pElement, CGUISprite &parent) +{ + assert(pElement); + + // Image object we're adding + SGUIImage image; + + // TODO - Setup defaults here (or maybe they are in the SGUIImage ctor) + + // + // 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); + string attr_name = XMLString::transcode( attr->getName() ); + string attr_value = XMLString::transcode( attr->getValue() ); + + // This is the only attribute we want + if (attr_name == "texture") + { + image.m_Texture = attr_value; + } + else + { + // Log + g_console.submit("echo Error attribute " + attr_name + " is not expected in "); + return; + } + } +*/ + // + // Input + // + + parent.AddImage(image); +} diff --git a/source/gui/CGUI.h b/source/gui/CGUI.h new file mode 100755 index 0000000000..e6fde0e49d --- /dev/null +++ b/source/gui/CGUI.h @@ -0,0 +1,197 @@ +/* +CGUI +by Gustav Larsson +gee@pyro.nu + +--Overview-- + + This is the top class of the whole GUI, all objects + and settings are stored within this class. + +--More info-- + + Check GUI.h + +*/ + +#ifndef CGUI_H +#define CGUI_H + +//-------------------------------------------------------- +// Includes / Compiler directives +//-------------------------------------------------------- +#include "GUI.h" +#include +#include +#include + +#include "input.h" // JW: grr, classes suck in this case :P + +class XERCES_CPP_NAMESPACE::DOMElement; + +//-------------------------------------------------------- +// Macros +//-------------------------------------------------------- + +//-------------------------------------------------------- +// Types +//-------------------------------------------------------- + +//-------------------------------------------------------- +// Error declarations +//-------------------------------------------------------- + +//-------------------------------------------------------- +// Declarations +//-------------------------------------------------------- + +class CGUI +{ + + // Only CGUIObject's leaf functions uses CGUI + // freely. + friend class CGUIObject; + +private: + // Private typedefs + typedef CGUIObject *(*ConstructObjectFunction)(); + +public: + CGUI(); + ~CGUI(); + + // Initialize + void Initialize(/*/*nemInput *pInput*/); + + // Process + void Process(); + + // Draw + void Draw(); + + // Shutdown + void Destroy(); + + // Load a GUI XML file + void LoadXMLFile(const CStr &Filename); + + // Checks if object exists and return true or false accordingly + bool ObjectExists(const CStr &Name) const; + + // Get pInput +/// CInput *GetInput() { return m_pInput; } + + // to add a type: + // AddObjecType("button", &CButton::ConstructObject); + void AddObjectType(const CStr &str, ConstructObjectFunction pFunc) { m_ObjectTypes[str] = pFunc; } + +private: + void UpdateObjects(); + + // Adds an object to the GUI's object database + // Private, you can only add objects through XML files. + void AddObject(CGUIObject* pObject); + + // Report a XML parsing error + void ReportParseError(const CStr &str, ...); + + // Construct an object + CGUIObject *ConstructObject(const CStr &str); + + // + // XML Reading Xerces C++ specific subroutines + // + + /** + Xerces_* functions tree + + ========================== + + (ReadRootObjects) + | + +- (ReadObject) + | + +- + | + +-Optional Type Extensions (CGUIObject::ReadExtendedElement) TODO + | + +-«object» *recursive* + + + (ReadRootStyles) + | + +-