Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

CEGUIGUILayout_xmlHandler.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002         filename:       CEGUIGUILayout_xmlHandler.cpp
00003         created:        5/7/2004
00004         author:         Paul D Turner
00005         
00006         purpose:        Implements XML parser for GUILayout files
00007 *************************************************************************/
00008 /*************************************************************************
00009     Crazy Eddie's GUI System (http://www.cegui.org.uk)
00010     Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
00011 
00012     This library is free software; you can redistribute it and/or
00013     modify it under the terms of the GNU Lesser General Public
00014     License as published by the Free Software Foundation; either
00015     version 2.1 of the License, or (at your option) any later version.
00016 
00017     This library is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020     Lesser General Public License for more details.
00021 
00022     You should have received a copy of the GNU Lesser General Public
00023     License along with this library; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 *************************************************************************/
00026 #include "CEGUIGUILayout_xmlHandler.h"
00027 #include "CEGUIExceptions.h"
00028 #include "CEGUISystem.h"
00029 #include "CEGUIScriptModule.h"
00030 #include "CEGUIXMLAttributes.h"
00031 
00032 
00033 // Start of CEGUI namespace section
00034 namespace CEGUI
00035 {
00036 /*************************************************************************
00037         Implementation Constants
00038 *************************************************************************/
00039 const String GUILayout_xmlHandler::GUILayoutElement( (utf8*)"GUILayout" );
00040 const String GUILayout_xmlHandler::WindowElement( (utf8*)"Window" );
00041 const String GUILayout_xmlHandler::PropertyElement( (utf8*)"Property" );
00042 const String GUILayout_xmlHandler::LayoutImportElement( (utf8*)"LayoutImport" );
00043 const String GUILayout_xmlHandler::EventElement( (utf8*)"Event" );
00044 const char      GUILayout_xmlHandler::WindowTypeAttribute[]             = "Type";
00045 const char      GUILayout_xmlHandler::WindowNameAttribute[]             = "Name";
00046 const char      GUILayout_xmlHandler::PropertyNameAttribute[]   = "Name";
00047 const char      GUILayout_xmlHandler::PropertyValueAttribute[]  = "Value";
00048 const char      GUILayout_xmlHandler::LayoutParentAttribute[]   = "Parent";
00049 const char      GUILayout_xmlHandler::LayoutImportFilenameAttribute[]   = "Filename";
00050 const char      GUILayout_xmlHandler::LayoutImportPrefixAttribute[]             = "Prefix";
00051 const char      GUILayout_xmlHandler::LayoutImportResourceGroupAttribute[] = "ResourceGroup";
00052 const char      GUILayout_xmlHandler::EventNameAttribute[]              = "Name";
00053 const char      GUILayout_xmlHandler::EventFunctionAttribute[]  = "Function";
00054 
00055 void GUILayout_xmlHandler::elementStart(const String& element, const XMLAttributes& attributes)
00056 {
00057         // handle root GUILayoutElement element
00058         if (element == GUILayoutElement)
00059         {
00060                 d_layoutParent = attributes.getValueAsString(LayoutParentAttribute);
00061 
00062                 // before we go to the trouble of creating the layout, see if this parent exists
00063                 if (!d_layoutParent.empty())
00064                 {
00065                         if (!WindowManager::getSingleton().isWindowPresent(d_layoutParent))
00066                         {
00067                                 // signal error - with more info about what we have done.
00068                                 throw InvalidRequestException((utf8*)"GUILayout_xmlHandler::startElement - layout loading has been aborted since the specified parent Window ('" + d_layoutParent + "') does not exist.");
00069                         }
00070 
00071                 }
00072 
00073         }
00074         // handle Window element (create window and make an entry on our "window stack")
00075         else if (element == WindowElement)
00076         {
00077                 // get type of window to create
00078         String windowType(attributes.getValueAsString(WindowTypeAttribute));
00079 
00080                 // get name for new window
00081         String windowName(attributes.getValueAsString(WindowNameAttribute));
00082 
00083                 // attempt to create window
00084                 try
00085                 {
00086                         Window* wnd = WindowManager::getSingleton().createWindow(windowType, d_namingPrefix + windowName);
00087 
00088                         // add this window to the current parent (if any)
00089                         if (!d_stack.empty())
00090                         {
00091                                 d_stack.back()->addChildWindow(wnd);
00092                         }
00093                         else
00094                         {
00095                                 d_root = wnd;
00096                         }
00097 
00098                         // make this window the top of the stack
00099                         d_stack.push_back(wnd);
00100                 }
00101                 catch (AlreadyExistsException exc)
00102                 {
00103                         // delete all windows created
00104                         cleanupLoadedWindows();
00105 
00106                         // signal error - with more info about what we have done.
00107                         throw InvalidRequestException((utf8*)"GUILayout_xmlHandler::startElement - layout loading has been aborted since Window named '" + windowName + "' already exists.");
00108                 }
00109                 catch (UnknownObjectException exc)
00110                 {
00111                         // delete all windows created
00112                         cleanupLoadedWindows();
00113 
00114                         // signal error - with more info about what we have done.
00115                         throw InvalidRequestException((utf8*)"GUILayout_xmlHandler::startElement - layout loading has been aborted since no WindowFactory is available for '" + windowType + "' objects.");
00116                 }
00117 
00118         }
00119         // handle Property element (set property for window at top of stack)
00120         else if (element == PropertyElement)
00121         {
00122                 // get property name
00123         String propertyName(attributes.getValueAsString(PropertyNameAttribute));
00124 
00125                 // get property value string
00126         String propertyValue(attributes.getValueAsString(PropertyValueAttribute));
00127 
00128                 // attempt to set property on window
00129                 try
00130                 {
00131                         if (!d_stack.empty())
00132                         {
00133                                 Window* curwindow = d_stack.back();
00134                                 bool useit = true;
00135                                 if (NULL != d_propertyCallback)
00136                                 {
00137                                         useit = (*d_propertyCallback)(curwindow, propertyName, propertyValue, d_userData);
00138                                 }
00139                                 if (useit)
00140                                 {
00141                                         curwindow->setProperty(propertyName, propertyValue);
00142                                 }
00143                         }
00144                 }
00145                 catch (Exception exc)
00146                 {
00147                         // Don't do anything here, but the error will have been logged.
00148                 }
00149 
00150         }
00151         // handle layout import element (attach a layout to the window at the top of the stack)
00152         else if (element == LayoutImportElement)
00153         {
00154                 String prefixName(d_namingPrefix);
00155         prefixName += attributes.getValueAsString(LayoutImportPrefixAttribute);
00156 
00157                 Window* subLayout = WindowManager::getSingleton().loadWindowLayout(
00158                 attributes.getValueAsString( LayoutImportFilenameAttribute),
00159                                 prefixName,
00160                 attributes.getValueAsString(LayoutImportResourceGroupAttribute),
00161                                 d_propertyCallback,
00162                                 d_userData);
00163 
00164                 if ((subLayout != NULL) && (!d_stack.empty()))
00165                 {
00166                         d_stack.back()->addChildWindow(subLayout);
00167                 }
00168 
00169         }
00170         // handle event subscription element
00171         else if (element == EventElement)
00172         {
00173         String eventName(attributes.getValueAsString(EventNameAttribute));
00174         String functionName(attributes.getValueAsString(EventFunctionAttribute));
00175 
00176                 // attempt to subscribe property on window
00177                 try
00178                 {
00179                         if (!d_stack.empty())
00180                         {
00181                 d_stack.back()->subscribeEvent(eventName, ScriptFunctor(functionName));
00182                         }
00183                 }
00184                 catch (Exception exc)
00185                 {
00186                         // Don't do anything here, but the error will have been logged.
00187                 }
00188 
00189         }
00190         // anything else is an error which *should* have already been caught by XML validation
00191         else
00192         {
00193                 throw FileIOException("GUILayout_xmlHandler::startElement - Unexpected data was found while parsing the gui-layout file: '" + element + "' is unknown.");
00194         }
00195 
00196 }
00197 
00198 void GUILayout_xmlHandler::elementEnd(const String& element)
00199 {
00200         // handle root GUILayoutElement element
00201         if (element == GUILayoutElement)
00202         {
00203                 // attach to named parent if needed
00204                 if (!d_layoutParent.empty() && (d_root != NULL))
00205                 {
00206                         WindowManager::getSingleton().getWindow(d_layoutParent)->addChildWindow(d_root);
00207                 }
00208 
00209         }
00210         // handle Window element
00211         else if (element == WindowElement)
00212         {
00213                 // pop a window from the window stack
00214                 if (!d_stack.empty())
00215                 {
00216                         d_stack.pop_back();
00217                 }
00218 
00219         }
00220 
00221 }
00222 
00223 
00224 /*************************************************************************
00225         Destroy all windows created so far.     
00226 *************************************************************************/
00227 void GUILayout_xmlHandler::cleanupLoadedWindows(void)
00228 {
00229         // Notes: We could just destroy the root window of the layout, which normally would also destroy
00230         // all attached windows.  Since the client may have specified that certain windows are not auto-destroyed
00231         // we can't rely on this, so we work backwards detaching and deleting windows instead.
00232         while (!d_stack.empty())
00233         {
00234                 Window* wnd = d_stack.back();
00235 
00236                 // detach from parent
00237                 if (wnd->getParent() != NULL)
00238                 {
00239                         wnd->getParent()->removeChildWindow(wnd);
00240                 }
00241 
00242                 // destroy the window
00243                 WindowManager::getSingleton().destroyWindow(wnd);
00244 
00245                 // pop window from stack
00246                 d_stack.pop_back();
00247         }
00248 
00249         d_root = NULL;
00250 }
00251 
00252 
00253 /*************************************************************************
00254         Return a pointer to the 'root' window created.
00255 *************************************************************************/
00256 Window* GUILayout_xmlHandler::getLayoutRootWindow(void) const
00257 {
00258         return d_root;
00259 }
00260 
00261 } // End of  CEGUI namespace section

Generated on Wed Sep 7 09:56:31 2005 for Crazy Eddies GUI System by  doxygen 1.4.3