diff -r c4b946c1a7b8 lib/irrlicht/include/IGUIElementFactory.h --- a/lib/irrlicht/include/IGUIElementFactory.h Mon Sep 01 16:36:53 2008 +0200 +++ b/lib/irrlicht/include/IGUIElementFactory.h Mon Sep 01 17:23:12 2008 +0200 @@ -56,6 +56,9 @@ /** \param type: Type of GUI element. \return: Returns name of the type if this factory can create the type, otherwise 0. */ virtual const c8* getCreateableGUIElementTypeName(EGUI_ELEMENT_TYPE type) const = 0; + + //! get the typenumber for the elementname + virtual EGUI_ELEMENT_TYPE getTypeFromName(const c8* name) const = 0; }; diff -r c4b946c1a7b8 lib/irrlicht/include/IGUIEnvironment.h --- a/lib/irrlicht/include/IGUIEnvironment.h Mon Sep 01 16:36:53 2008 +0200 +++ b/lib/irrlicht/include/IGUIEnvironment.h Mon Sep 01 17:23:12 2008 +0200 @@ -11,6 +11,7 @@ #include "EMessageBoxFlags.h" #include "IEventReceiver.h" #include "IXMLReader.h" +#include "EAttributes.h" namespace irr { @@ -536,6 +537,21 @@ //! reads an element virtual void readGUIElement(io::IXMLReader* reader, IGUIElement* parent) =0; + + //! remove default attribute settings for all element types + virtual void clearDefaultElementAttributes() = 0; + + //! load a set of default attribute settings from a xml file + virtual bool loadDefaultElementAttributes(const c8* filename) = 0; + + //! save current default attribute settings to a xml file + virtual bool saveDefaultElementAttributes(const c8* filename) = 0; + + //! Use the settings of the given IGUIElement as default attribute settings for this element type + virtual void setDefaultElementAttribute(IGUIElement* defaultElement) = 0; + + //! Set how the default attributes for elements should be used + virtual void setDefaultElementAttributeUsage(io::E_DEFAULT_ATTRIBUTE_USAGE usage) = 0; }; diff -r c4b946c1a7b8 lib/irrlicht/source/Irrlicht/CDefaultGUIElementFactory.h --- a/lib/irrlicht/source/Irrlicht/CDefaultGUIElementFactory.h Mon Sep 01 16:36:53 2008 +0200 +++ b/lib/irrlicht/source/Irrlicht/CDefaultGUIElementFactory.h Mon Sep 01 17:23:12 2008 +0200 @@ -54,9 +54,10 @@ \return: Returns the name of the type if this factory can create it, otherwise it returns 0. */ virtual const c8* getCreateableGUIElementTypeName(EGUI_ELEMENT_TYPE type) const; + //! get the typenumber for the elementname + virtual EGUI_ELEMENT_TYPE getTypeFromName(const c8* name) const; + private: - - EGUI_ELEMENT_TYPE getTypeFromName(const c8* name) const; IGUIEnvironment* Environment; }; diff -r c4b946c1a7b8 lib/irrlicht/source/Irrlicht/CGUIEnvironment.cpp --- a/lib/irrlicht/source/Irrlicht/CGUIEnvironment.cpp Mon Sep 01 16:36:53 2008 +0200 +++ b/lib/irrlicht/source/Irrlicht/CGUIEnvironment.cpp Mon Sep 01 17:23:12 2008 +0200 @@ -34,6 +34,7 @@ #include "CGUIToolBar.h" #include "CGUITable.h" +#include "CAttributes.h" #include "CDefaultGUIElementFactory.h" #include "IWriteFile.h" #include "IXMLWriter.h" @@ -55,6 +56,7 @@ //! constructor CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* driver, IOSOperator* op) : IGUIElement(EGUIET_ELEMENT, 0, 0, 0, core::rect(core::position2d(0,0), driver ? driver->getScreenSize() : core::dimension2d(0,0))), + DefaultElementAttributeUsage(io::EDAU_IGNORE), Driver(driver), Hovered(0), Focus(0), LastHoveredMousePos(0,0), CurrentSkin(0), FileSystem(fs), UserReceiver(0), Operator(op) { @@ -139,6 +141,8 @@ CurrentSkin = 0; } + clearDefaultElementAttributes(); + u32 i; // delete all sprite banks @@ -665,6 +669,17 @@ } +//! get the typenumber for the elementname +EGUI_ELEMENT_TYPE CGUIEnvironment::getTypeFromName(const c8* name) const +{ + EGUI_ELEMENT_TYPE type = EGUIET_ELEMENT; + for (s32 i=0; i<(int)GUIElementFactoryList.size() && type == EGUIET_ELEMENT; ++i) + type = GUIElementFactoryList[i]->getTypeFromName(name); + + return type; +} + + //! adds a GUI Element using its name IGUIElement* CGUIEnvironment::addGUIElement(const c8* elementName, IGUIElement* parent) { @@ -770,6 +785,216 @@ reader->drop(); return true; +} + +void CGUIEnvironment::clearDefaultElementAttributes() +{ + for ( u32 i=0; i < DefaultElementAttributes.size(); ++i ) + { + DefaultElementAttributes[i].Attribute->drop(); + } + DefaultElementAttributes.clear(); +} + +bool CGUIEnvironment::loadDefaultElementAttributes(const c8* filename) +{ + io::IReadFile* file = FileSystem->createAndOpenFile(filename); + if (!file) + { + os::Printer::log("Unable to open gui file", filename, ELL_ERROR); + return false; + } + + io::IXMLReader* reader = FileSystem->createXMLReader(file); + if (!reader) + { + file->drop(); + os::Printer::log("not a valid XML file", file->getFileName(), ELL_ERROR); + return false; + } + + // read file + while(reader->read()) + { + readDefaultElementAttribute(reader); + } + + // finish up + reader->drop(); + file->drop(); + + return true; + +} + +//! Set how the default attributes for elements should be used +void CGUIEnvironment::setDefaultElementAttributeUsage(io::E_DEFAULT_ATTRIBUTE_USAGE usage) +{ + DefaultElementAttributeUsage = usage; +} + +// Set a default element attribute, overriding former attributes of the same type +// The used Attribute will be grab'ed within this function. +void CGUIEnvironment::setDefaultElementAttribute(const SDefaultElementAttribute& attribute) +{ + if ( attribute.Attribute ) + attribute.Attribute->grab(); + for ( u32 i=0; idrop(); + DefaultElementAttributes[i] = attribute; + return; + } + } + DefaultElementAttributes.push_back( attribute ); +} + +void CGUIEnvironment::readDefaultElementAttribute(io::IXMLReader* reader) +{ + if (!reader) + return; + + SDefaultElementAttribute defaultAttrib; + + if ( reader->getNodeType() == io::EXN_NONE + || reader->getNodeType() == io::EXN_UNKNOWN + || reader->getNodeType() == io::EXN_ELEMENT_END) + return; + + if (!wcscmp(IRR_XML_FORMAT_GUI_ENV, reader->getNodeName())) + { + // defaultAttrib.Type = ; CGUIEnvironment seems to have no own EGUI_ELEMENT_TYPE + } + else if (!wcscmp(IRR_XML_FORMAT_GUI_ELEMENT, reader->getNodeName())) + { + // find node type and create it + core::stringc attrName = reader->getAttributeValue(IRR_XML_FORMAT_GUI_ELEMENT_ATTR_TYPE); + defaultAttrib.Type = getTypeFromName(attrName.c_str()); + defaultAttrib.TypeName = attrName; + } + + // read attributes + + while(reader->read()) + { + bool endreached = false; + + switch (reader->getNodeType()) + { + case io::EXN_ELEMENT_END: + if (!wcscmp(IRR_XML_FORMAT_GUI_ELEMENT, reader->getNodeName()) || + !wcscmp(IRR_XML_FORMAT_GUI_ENV, reader->getNodeName())) + { + endreached = true; + } + break; + case io::EXN_ELEMENT: + if (!wcscmp(L"attributes", reader->getNodeName())) + { + // read attributes + io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver); + attr->read(reader, true); + if ( defaultAttrib.Type != EGUIET_ELEMENT ) + { + defaultAttrib.Attribute = attr; + setDefaultElementAttribute(defaultAttrib); + } + attr->drop(); + } + else + if (!wcscmp(IRR_XML_FORMAT_GUI_ELEMENT, reader->getNodeName()) || + !wcscmp(IRR_XML_FORMAT_GUI_ENV, reader->getNodeName())) + { + readDefaultElementAttribute(reader); + } + else + { + os::Printer::log("Found unknown element in irrlicht GUI file", + core::stringc(reader->getNodeName()).c_str()); + } + + break; + } + + if (endreached) + break; + } +} + +bool CGUIEnvironment::saveDefaultElementAttributes(const c8* filename) +{ + io::IWriteFile* file = FileSystem->createAndWriteFile(filename); + if (!file) + return false; + + io::IXMLWriter* writer = FileSystem->createXMLWriter(file); + if (!writer) + { + file->drop(); + return false; + } + + writer->writeXMLHeader(); + + // root element start (to get a valid xml-file) + core::stringw nameRoot("unknown"); + writer->writeElement( IRR_XML_FORMAT_GUI_ELEMENT, + false, IRR_XML_FORMAT_GUI_ELEMENT_ATTR_TYPE, + nameRoot.c_str() ); + writer->writeLineBreak(); + writer->writeLineBreak(); + + for ( u32 i=0; igetAttributeCount() > 0 ) + { + core::stringw name(DefaultElementAttributes[i].TypeName.c_str()); + writer->writeElement( IRR_XML_FORMAT_GUI_ELEMENT, + false, IRR_XML_FORMAT_GUI_ELEMENT_ATTR_TYPE, + name.c_str() ); + + writer->writeLineBreak(); + writer->writeLineBreak(); + + DefaultElementAttributes[i].Attribute->write(writer); + writer->writeLineBreak(); + + // write closing brace + writer->writeClosingTag(IRR_XML_FORMAT_GUI_ELEMENT); + writer->writeLineBreak(); + writer->writeLineBreak(); + } + } + + // close root element + writer->writeClosingTag(IRR_XML_FORMAT_GUI_ELEMENT); + writer->writeLineBreak(); + writer->writeLineBreak(); + + writer->drop(); + file->drop(); + + return true; +} + +void CGUIEnvironment::setDefaultElementAttribute(IGUIElement* defaultElement) +{ + if ( !defaultElement ) + return; + + SDefaultElementAttribute attrib; + attrib.Type = defaultElement->getType(); + attrib.TypeName = defaultElement->getTypeName(); + + io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver); + defaultElement->serializeAttributes(attr); + attrib.Attribute = attr; + setDefaultElementAttribute(attrib); + attr->drop(); } @@ -824,7 +1049,21 @@ attr->read(reader, true); if (node) - node->deserializeAttributes(attr); + { + // set the default attribute if available + u32 i; + for ( i=0; i < DefaultElementAttributes.size(); ++i ) + { + if ( DefaultElementAttributes[i].Type == node->getType() ) + { + attr->setDefaultAttributeUsage( DefaultElementAttributeUsage ); + attr->setDefaultAttributes( DefaultElementAttributes[i].Attribute ); + break; + } + } + + node->deserializeAttributes(attr); + } attr->drop(); } @@ -832,7 +1071,7 @@ if (!wcscmp(IRR_XML_FORMAT_GUI_ELEMENT, reader->getNodeName()) || !wcscmp(IRR_XML_FORMAT_GUI_ENV, reader->getNodeName())) { - readGUIElement(reader, node); + readGUIElement(reader, node ? node : parent); } else { @@ -859,9 +1098,21 @@ const wchar_t* name = 0; - // write properties + io::IAttributes* attr = FileSystem->createEmptyAttributes(); + + // set the default attribute if available + u32 i; + for ( i=0; i < DefaultElementAttributes.size(); ++i ) + { + if ( DefaultElementAttributes[i].Type == node->getType() ) + { + attr->setDefaultAttributeUsage( DefaultElementAttributeUsage ); + attr->setDefaultAttributes( DefaultElementAttributes[i].Attribute ); + break; + } + } - io::IAttributes* attr = FileSystem->createEmptyAttributes(); + // write properties node->serializeAttributes(attr); // all gui elements must have at least one attribute diff -r c4b946c1a7b8 lib/irrlicht/source/Irrlicht/CGUIEnvironment.h --- a/lib/irrlicht/source/Irrlicht/CGUIEnvironment.h Mon Sep 01 16:36:53 2008 +0200 +++ b/lib/irrlicht/source/Irrlicht/CGUIEnvironment.h Mon Sep 01 17:23:12 2008 +0200 @@ -246,6 +246,22 @@ //! reads an element virtual void readGUIElement(io::IXMLReader* reader, IGUIElement* parent); + //! remove default attribute settings for all element types + virtual void clearDefaultElementAttributes(); + + //! load a set of default attribute settings from a xml file + virtual bool loadDefaultElementAttributes(const c8* filename); + + //! save current default attribute settings to a xml file + virtual bool saveDefaultElementAttributes(const c8* filename); + + //! Use the settings of the given IGUIElement as default attribute settings for this element type + virtual void setDefaultElementAttribute(IGUIElement* defaultElement); + + //! Set how the default attributes for elements should be used + virtual void setDefaultElementAttributeUsage(io::E_DEFAULT_ATTRIBUTE_USAGE usage); + + virtual void readDefaultElementAttribute(io::IXMLReader* reader); private: @@ -254,6 +270,9 @@ void updateHoveredElement(core::position2d mousePos); void loadBuiltInFont(); + + //! get the typenumber for the elementname + EGUI_ELEMENT_TYPE getTypeFromName(const c8* name) const; struct SFont { @@ -287,6 +306,21 @@ SToolTip ToolTip; + struct SDefaultElementAttribute + { + SDefaultElementAttribute() : Type(EGUIET_ELEMENT), Attribute(0) {} + + EGUI_ELEMENT_TYPE Type; + core::stringc TypeName; + io::IAttributes * Attribute; + }; + core::array DefaultElementAttributes; + io::E_DEFAULT_ATTRIBUTE_USAGE DefaultElementAttributeUsage; + + // Set a default element attribute, overriding former attributes of the same type + // The used Attribute will be grab'ed within this function. + void setDefaultElementAttribute(const SDefaultElementAttribute& attribute); + core::array GUIElementFactoryList; core::array Fonts;