00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00034 namespace CEGUI
00035 {
00036
00037
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
00058 if (element == GUILayoutElement)
00059 {
00060 d_layoutParent = attributes.getValueAsString(LayoutParentAttribute);
00061
00062
00063 if (!d_layoutParent.empty())
00064 {
00065 if (!WindowManager::getSingleton().isWindowPresent(d_layoutParent))
00066 {
00067
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
00075 else if (element == WindowElement)
00076 {
00077
00078 String windowType(attributes.getValueAsString(WindowTypeAttribute));
00079
00080
00081 String windowName(attributes.getValueAsString(WindowNameAttribute));
00082
00083
00084 try
00085 {
00086 Window* wnd = WindowManager::getSingleton().createWindow(windowType, d_namingPrefix + windowName);
00087
00088
00089 if (!d_stack.empty())
00090 {
00091 d_stack.back()->addChildWindow(wnd);
00092 }
00093 else
00094 {
00095 d_root = wnd;
00096 }
00097
00098
00099 d_stack.push_back(wnd);
00100 }
00101 catch (AlreadyExistsException exc)
00102 {
00103
00104 cleanupLoadedWindows();
00105
00106
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
00112 cleanupLoadedWindows();
00113
00114
00115 throw InvalidRequestException((utf8*)"GUILayout_xmlHandler::startElement - layout loading has been aborted since no WindowFactory is available for '" + windowType + "' objects.");
00116 }
00117
00118 }
00119
00120 else if (element == PropertyElement)
00121 {
00122
00123 String propertyName(attributes.getValueAsString(PropertyNameAttribute));
00124
00125
00126 String propertyValue(attributes.getValueAsString(PropertyValueAttribute));
00127
00128
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
00148 }
00149
00150 }
00151
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
00171 else if (element == EventElement)
00172 {
00173 String eventName(attributes.getValueAsString(EventNameAttribute));
00174 String functionName(attributes.getValueAsString(EventFunctionAttribute));
00175
00176
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
00187 }
00188
00189 }
00190
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
00201 if (element == GUILayoutElement)
00202 {
00203
00204 if (!d_layoutParent.empty() && (d_root != NULL))
00205 {
00206 WindowManager::getSingleton().getWindow(d_layoutParent)->addChildWindow(d_root);
00207 }
00208
00209 }
00210
00211 else if (element == WindowElement)
00212 {
00213
00214 if (!d_stack.empty())
00215 {
00216 d_stack.pop_back();
00217 }
00218
00219 }
00220
00221 }
00222
00223
00224
00225
00226
00227 void GUILayout_xmlHandler::cleanupLoadedWindows(void)
00228 {
00229
00230
00231
00232 while (!d_stack.empty())
00233 {
00234 Window* wnd = d_stack.back();
00235
00236
00237 if (wnd->getParent() != NULL)
00238 {
00239 wnd->getParent()->removeChildWindow(wnd);
00240 }
00241
00242
00243 WindowManager::getSingleton().destroyWindow(wnd);
00244
00245
00246 d_stack.pop_back();
00247 }
00248
00249 d_root = NULL;
00250 }
00251
00252
00253
00254
00255
00256 Window* GUILayout_xmlHandler::getLayoutRootWindow(void) const
00257 {
00258 return d_root;
00259 }
00260
00261 }