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 "CEGUIWindowManager.h"
00027 #include "CEGUIWindowFactoryManager.h"
00028 #include "CEGUIWindowFactory.h"
00029 #include "CEGUIWindow.h"
00030 #include "CEGUIExceptions.h"
00031 #include "CEGUIGUILayout_xmlHandler.h"
00032 #include "CEGUIXMLParser.h"
00033 #include <iostream>
00034 #include <sstream>
00035
00036
00037 namespace CEGUI
00038 {
00039
00040
00041
00042
00043 template<> WindowManager* Singleton<WindowManager>::ms_Singleton = NULL;
00044
00045
00046
00047
00048
00049
00050 const char WindowManager::GUILayoutSchemaName[] = "GUILayout.xsd";
00051 const String WindowManager::GeneratedWindowNameBase("__cewin_uid_");
00052
00053
00054
00055
00056
00057 WindowManager::WindowManager(void) :
00058 d_uid_counter(0)
00059 {
00060 Logger::getSingleton().logEvent((utf8*)"CEGUI::WindowManager singleton created");
00061 }
00062
00063
00064
00065
00066
00067 WindowManager::~WindowManager(void)
00068 {
00069 destroyAllWindows();
00070 cleanDeadPool();
00071
00072 Logger::getSingleton().logEvent((utf8*)"CEGUI::WindowManager singleton destroyed");
00073 }
00074
00075
00076
00077
00078
00079 Window* WindowManager::createWindow(const String& type, const String& name)
00080 {
00081 String finalName(name.empty() ? generateUniqueWindowName() : name);
00082
00083 if (isWindowPresent(finalName))
00084 {
00085 throw AlreadyExistsException("WindowManager::createWindow - A Window object with the name '" + finalName +"' already exists within the system.");
00086 }
00087
00088 WindowFactoryManager& wfMgr = WindowFactoryManager::getSingleton();
00089 WindowFactory* factory = wfMgr.getFactory(type);
00090
00091 Window* newWindow = factory->createWindow(finalName);
00092 Logger::getSingleton().logEvent("Window '" + finalName +"' of type '" + type + "' has been created.", Informative);
00093
00094
00095 if (wfMgr.isFalagardMappedType(type))
00096 {
00097
00098
00099 newWindow->setLookNFeel(type, wfMgr.getMappedLookForType(type));
00100 }
00101
00102
00103 newWindow->initialise();
00104
00105 d_windowRegistry[finalName] = newWindow;
00106
00107 return newWindow;
00108 }
00109
00110
00111
00112
00113
00114 void WindowManager::destroyWindow(Window* window)
00115 {
00116 if (window != NULL)
00117 {
00118
00119
00120
00121
00122 String name = window->getName();
00123
00124 destroyWindow(name);
00125 }
00126
00127 }
00128
00129
00130
00131
00132
00133 void WindowManager::destroyWindow(const String& window)
00134 {
00135 WindowRegistry::iterator wndpos = d_windowRegistry.find(window);
00136
00137 if (wndpos != d_windowRegistry.end())
00138 {
00139 Window* wnd = wndpos->second;
00140
00141
00142 d_windowRegistry.erase(wndpos);
00143
00144
00145 wnd->destroy();
00146
00147
00148 d_deathrow.push_back(wnd);
00149
00150
00151 System::getSingleton().notifyWindowDestroyed(wnd);
00152
00153 Logger::getSingleton().logEvent((utf8*)"Window '" + window + "' has been added to dead pool.", Informative);
00154 }
00155
00156 }
00157
00158
00159
00160
00161
00162 Window* WindowManager::getWindow(const String& name) const
00163 {
00164 WindowRegistry::const_iterator pos = d_windowRegistry.find(name);
00165
00166 if (pos == d_windowRegistry.end())
00167 {
00168 throw UnknownObjectException("WindowManager::getWindow - A Window object with the name '" + name +"' does not exist within the system");
00169 }
00170
00171 return pos->second;
00172 }
00173
00174
00175
00176
00177
00178 bool WindowManager::isWindowPresent(const String& name) const
00179 {
00180 return (d_windowRegistry.find(name) != d_windowRegistry.end());
00181 }
00182
00183
00184
00185
00186
00187 void WindowManager::destroyAllWindows(void)
00188 {
00189 String window_name;
00190 while (!d_windowRegistry.empty())
00191 {
00192 window_name = d_windowRegistry.begin()->first;
00193 destroyWindow(window_name);
00194 }
00195
00196 }
00197
00198
00199
00200
00201
00202
00203 Window* WindowManager::loadWindowLayout(const String& filename, const String& name_prefix, const String& resourceGroup, PropertyCallback* callback, void* userdata)
00204 {
00205 if (filename.empty() || (filename == (utf8*)""))
00206 {
00207 throw InvalidRequestException((utf8*)"WindowManager::loadWindowLayout - Filename supplied for gui-layout loading must be valid.");
00208 }
00209
00210
00211 Logger::getSingleton().logEvent((utf8*)"---- Beginning loading of GUI layout from '" + filename + "' ----", Informative);
00212
00213
00214 GUILayout_xmlHandler handler(name_prefix, callback, userdata);
00215
00216
00217 try
00218 {
00219 System::getSingleton().getXMLParser()->parseXMLFile(handler, filename, GUILayoutSchemaName, resourceGroup);
00220 }
00221 catch(...)
00222 {
00223 Logger::getSingleton().logEvent("WindowManager::loadWindowLayout - loading of layout from file '" + filename +"' failed.", Errors);
00224 throw;
00225 }
00226
00227
00228 Logger::getSingleton().logEvent((utf8*)"---- Successfully completed loading of GUI layout from '" + filename + "' ----", Standard);
00229
00230 return handler.getLayoutRootWindow();
00231 }
00232
00233
00234 WindowManager& WindowManager::getSingleton(void)
00235 {
00236 return Singleton<WindowManager>::getSingleton();
00237 }
00238
00239
00240 WindowManager* WindowManager::getSingletonPtr(void)
00241 {
00242 return Singleton<WindowManager>::getSingletonPtr();
00243 }
00244
00245 bool WindowManager::isDeadPoolEmpty(void) const
00246 {
00247 return d_deathrow.empty();
00248 }
00249
00250 void WindowManager::cleanDeadPool(void)
00251 {
00252 WindowVector::reverse_iterator curr = d_deathrow.rbegin();
00253 for (; curr != d_deathrow.rend(); ++curr)
00254 {
00255
00256 #if defined(DEBUG) || defined (_DEBUG)
00257 CEGUI_LOGINSANE("Window '" + (*curr)->getName() + "' about to be finally destroyed from dead pool.");
00258 #endif
00259
00260 WindowFactory* factory = WindowFactoryManager::getSingleton().getFactory((*curr)->getType());
00261 factory->destroyWindow(*curr);
00262 }
00263
00264
00265 d_deathrow.clear();
00266 }
00267
00268 void WindowManager::writeWindowLayoutToStream(const Window& window, OutStream& out_stream, bool writeParent) const
00269 {
00270
00271 out_stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00272
00273 out_stream << "<GUILayout";
00274
00275 if ((window.getParent() != 0) && writeParent)
00276 {
00277 out_stream << " Parent=\"" << window.getParent()->getName() << "\" ";
00278 }
00279
00280 out_stream << ">" << std::endl;
00281
00282 window.writeXMLToStream(out_stream);
00283
00284 out_stream << "</GUILayout>" << std::endl;
00285 }
00286
00287 void WindowManager::writeWindowLayoutToStream(const String& window, OutStream& out_stream, bool writeParent) const
00288 {
00289 writeWindowLayoutToStream(*getWindow(window), out_stream, writeParent);
00290 }
00291
00292 String WindowManager::generateUniqueWindowName()
00293 {
00294
00295 std::ostringstream uidname;
00296 uidname << GeneratedWindowNameBase.c_str() << d_uid_counter;
00297
00298
00299 unsigned long old_uid = d_uid_counter;
00300 ++d_uid_counter;
00301
00302
00303 if (d_uid_counter < old_uid)
00304 Logger::getSingleton().logEvent("UID counter for generated window names has wrapped around - the fun shall now commence!");
00305
00306
00307 return String(uidname.str());
00308 }
00309
00310
00311
00312
00313
00314
00315 WindowManager::WindowIterator WindowManager::getIterator(void) const
00316 {
00317 return WindowIterator(d_windowRegistry.begin(), d_windowRegistry.end());
00318 }
00319 }