1 /***********************************************************************
2 	created:	21/2/2004
3 	author:		Paul D Turner
4 
5 	purpose:	Defines the interface for the WindowManager object
6 *************************************************************************/
7 /***************************************************************************
8  *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
9  *
10  *   Permission is hereby granted, free of charge, to any person obtaining
11  *   a copy of this software and associated documentation files (the
12  *   "Software"), to deal in the Software without restriction, including
13  *   without limitation the rights to use, copy, modify, merge, publish,
14  *   distribute, sublicense, and/or sell copies of the Software, and to
15  *   permit persons to whom the Software is furnished to do so, subject to
16  *   the following conditions:
17  *
18  *   The above copyright notice and this permission notice shall be
19  *   included in all copies or substantial portions of the Software.
20  *
21  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24  *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25  *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  *   OTHER DEALINGS IN THE SOFTWARE.
28  ***************************************************************************/
29 #ifndef _CEGUIWindowManager_h_
30 #define _CEGUIWindowManager_h_
31 
32 #include "CEGUI/Base.h"
33 #include "CEGUI/String.h"
34 #include "CEGUI/Singleton.h"
35 #include "CEGUI/Logger.h"
36 #include "CEGUI/IteratorBase.h"
37 #include "CEGUI/EventSet.h"
38 #include <map>
39 #include <vector>
40 
41 #if defined(_MSC_VER)
42 #	pragma warning(push)
43 #	pragma warning(disable : 4275)
44 #	pragma warning(disable : 4251)
45 #endif
46 
47 
48 // Start of CEGUI namespace section
49 namespace CEGUI
50 {
51 /*!
52 \brief
53 	The WindowManager class describes an object that manages creation and lifetime of Window objects.
54 
55 	The WindowManager is the means by which Window objects are created and destroyed.  For each sub-class
56 	of Window that is to be created, there must exist a WindowFactory object which is registered with the
57 	WindowFactoryManager.  Additionally, the WindowManager tracks every Window object created, and can be
58 	used to access those Window objects by name.
59 */
60 class CEGUIEXPORT WindowManager : public Singleton<WindowManager>,
61                                   public EventSet,
62                                   public AllocatedObject<WindowManager>
63 {
64 public:
65     /*************************************************************************
66         Public static data
67     *************************************************************************/
68     static const String GeneratedWindowNameBase; //!< Base name to use for generated window names.
69     //! Namespace for global events.
70     static const String EventNamespace;
71     /** Event fired when a new Window object is created.
72      * Handlers are passed a const WindowEventArgs reference with
73      * WindowEventArgs::window set to the Window that has just been created.
74      */
75     static const String EventWindowCreated;
76     /** Event fired when a Window object is destroyed.
77      * Handlers are passed a const WindowEventArgs reference with
78      * WindowEventArgs::window set to the Window that has been destroyed.
79      */
80     static const String EventWindowDestroyed;
81 
82     static const String GUILayoutSchemaName; //!< Filename of the XML schema used for validating GUILayout files.
83 
84 	/*!
85 	\brief
86 		Function type that is used as a callback when loading layouts from XML; the function is called
87 		for each Property element encountered.
88 
89 	\param window
90 		Window object that the property is to be applied to.
91 
92 	\param propname
93 		String holding the name of the property that is being set.
94 
95 	\param propvalue
96 		String holding the new value that will be applied to the property specified by /a propname.
97 
98 	\param userdata
99 		Some client code supplied data.
100 
101 	\return
102 		- true if the property should be set.
103 		- false if the property should not be set,
104 	*/
105 	typedef bool PropertyCallback(Window* window, String& propname, String& propvalue, void* userdata);
106 
107 	/*************************************************************************
108 		Construction and Destruction
109 	*************************************************************************/
110 	/*!
111 	\brief
112 		Constructs a new WindowManager object.
113 
114 		NB: Client code should not create WindowManager objects - they are of limited use to you!  The
115 		intended pattern of access is to get a pointer to the GUI system's WindowManager via the System
116 		object, and use that.
117 	*/
118 	WindowManager(void);
119 
120 
121 	/*!
122 	\brief
123 		Destructor for WindowManager objects
124 
125 		This will properly destry all remaining Window objects.  Note that WindowFactory objects will not
126 		be destroyed (since they are owned by whoever created them).
127 	*/
128 	~WindowManager(void);
129 
130 
131 	/*************************************************************************
132 		Window Related Methods
133 	*************************************************************************/
134 	/*!
135 	\brief
136 		Creates a new Window object of the specified type, and gives it the specified unique name.
137 
138 	\param type
139 		String that describes the type of Window to be created.  A valid WindowFactory for the specified type must be registered.
140 
141 	\param name
142 		String that holds the name that is to be given to the new window.  If
143         \a name is empty, a name will be generated for the window.
144 
145 	\return
146 		Pointer to the newly created Window object.
147 
148     \exception  InvalidRequestException WindowManager is locked and no Windows
149                                         may be created.
150 	\exception	UnknownObjectException		No WindowFactory is registered for \a type Window objects.
151 	\exception	GenericException			Some other error occurred (Exception message has details).
152 	*/
153 	Window* createWindow(const String& type, const String& name = "");
154 
155 
156 	/*!
157 	\brief
158 		Destroy the specified Window object.
159 
160 	\param window
161 		Pointer to the Window object to be destroyed.
162 
163 	\return
164 		Nothing
165 
166 	\exception	InvalidRequestException		Can be thrown if the WindowFactory for \a window's object type was removed.
167 	*/
168 	void	destroyWindow(Window* window);
169 
170 
171 	/*!
172 	\brief
173 		Destroys all Window objects within the system
174 
175 	\return
176 		Nothing.
177 
178 	\exception	InvalidRequestException		Thrown if the WindowFactory for any Window object type has been removed.
179 	*/
180 	void	destroyAllWindows(void);
181 
182     //! return whether Window is alive.
183     bool isAlive(const Window* window) const;
184 
185     /*!
186     \brief
187         Creates a set of windows (a GUI layout) from the information in the specified XML.
188 
189     \param source
190         RawDataContainer holding the XML source
191 
192     \param callback
193         PropertyCallback function to be called for each Property element loaded from the layout.  This is
194         called prior to the property value being applied to the window enabling client code manipulation of
195         properties.
196 
197     \param userdata
198         Client code data pointer passed to the PropertyCallback function.
199 
200     \return
201         Pointer to the root Window object defined in the layout.
202     */
203     Window* loadLayoutFromContainer(const RawDataContainer& source, PropertyCallback* callback = 0, void* userdata = 0);
204 
205 	/*!
206 	\brief
207 		Creates a set of windows (a GUI layout) from the information in the specified XML file.
208 
209 	\param filename
210 		String object holding the filename of the XML file to be processed.
211 
212     \param resourceGroup
213         Resource group identifier to be passed to the resource provider when loading the layout file.
214 
215 	\param callback
216 		PropertyCallback function to be called for each Property element loaded from the layout.  This is
217 		called prior to the property value being applied to the window enabling client code manipulation of
218 		properties.
219 
220 	\param userdata
221 		Client code data pointer passed to the PropertyCallback function.
222 
223 	\return
224 		Pointer to the root Window object defined in the layout.
225 
226 	\exception FileIOException			thrown if something goes wrong while processing the file \a filename.
227 	\exception InvalidRequestException	thrown if \a filename appears to be invalid.
228 	*/
229 	Window*	loadLayoutFromFile(const String& filename, const String& resourceGroup = "", PropertyCallback* callback = 0, void* userdata = 0);
230 
231     /*!
232     \brief
233         Creates a set of windows (a GUI layout) from the information in the specified XML.
234 
235     \param source
236         String holding the XML source
237 
238     \param callback
239         PropertyCallback function to be called for each Property element loaded from the layout.  This is
240         called prior to the property value being applied to the window enabling client code manipulation of
241         properties.
242 
243     \param userdata
244         Client code data pointer passed to the PropertyCallback function.
245 
246     \return
247         Pointer to the root Window object defined in the layout.
248     */
249     Window* loadLayoutFromString(const String& source, PropertyCallback* callback = 0, void* userdata = 0);
250 
251     /*!
252     \brief
253         Return whether the window dead pool is empty.
254 
255     \return
256         - true if there are no windows in the dead pool.
257         - false if the dead pool contains >=1 window awaiting destruction.
258     */
259     bool isDeadPoolEmpty(void) const;
260 
261     /*!
262     \brief
263         Permanently destroys any windows placed in the dead pool.
264 
265     \note
266         It is probably not a good idea to call this from a Window based event handler
267         if the specific window has been or is being destroyed.
268 
269     \return
270         Nothing.
271     */
272     void cleanDeadPool(void);
273 
274     /*!
275     \brief
276         Writes a full XML window layout, starting at the given Window to the given OutStream.
277 
278     \param window
279         Window object to become the root of the layout.
280 
281     \param out_stream
282         OutStream (std::ostream based) object where data is to be sent.
283 
284     \return
285         Nothing.
286     */
287     void writeLayoutToStream(const Window& window, OutStream& out_stream) const;
288 
289     /*!
290     \brief
291         Writes a full XML window layout, starting at the given Window and returns the result as string
292 
293     \param window
294         Window object to become the root of the layout.
295 
296     \warning
297         This is a convenience function and isn't designed to be fast at all! Use the other alternatives
298         if you want performance.
299 
300     \return
301         String containing XML of the resulting layout
302     */
303     String getLayoutAsString(const Window& window) const;
304 
305     /*!
306     \brief
307         Save a full XML window layout, starting at the given Window, to a file
308         with the given file name.
309 
310     \param window
311         Window object to become the root of the layout.
312 
313     \param filename
314         The name of the file to which the XML will be written.  Note that this
315         does not use any part of the ResourceProvider system, but rather will
316         write directly to disk.  If this is not desirable, you should prefer the
317         OutStream based writeWindowLayoutToStream functions.
318     */
319     void saveLayoutToFile(const Window& window, const String& filename) const;
320 
321     /*!
322     \brief
323         Returns the default resource group currently set for layouts.
324 
325     \return
326         String describing the default resource group identifier that will be
327         used when loading layouts.
328     */
getDefaultResourceGroup()329     static const String& getDefaultResourceGroup()
330         { return d_defaultResourceGroup; }
331 
332     /*!
333     \brief
334         Sets the default resource group to be used when loading layouts
335 
336     \param resourceGroup
337         String describing the default resource group identifier to be used.
338 
339     \return
340         Nothing.
341     */
setDefaultResourceGroup(const String & resourceGroup)342     static void setDefaultResourceGroup(const String& resourceGroup)
343         { d_defaultResourceGroup = resourceGroup; }
344 
345     /*!
346     \brief
347         Put WindowManager into the locked state.
348 
349         While WindowManager is in the locked state all attempts to create a
350         Window of any type will fail with an InvalidRequestException being
351         thrown.  Calls to lock/unlock are recursive; if multiple calls to lock
352         are made, WindowManager is only unlocked after a matching number of
353         calls to unlock.
354 
355     \note
356         This is primarily intended for internal use within the system.
357     */
358     void lock();
359 
360     /*!
361     \brief
362         Put WindowManager into the unlocked state.
363 
364         While WindowManager is in the locked state all attempts to create a
365         Window of any type will fail with an InvalidRequestException being
366         thrown.  Calls to lock/unlock are recursive; if multiple calls to lock
367         are made, WindowManager is only unlocked after a matching number of
368         calls to unlock.
369 
370     \note
371         This is primarily intended for internal use within the system.
372     */
373     void unlock();
374 
375     /*!
376     \brief
377         Returns whether WindowManager is currently in the locked state.
378 
379         While WindowManager is in the locked state all attempts to create a
380         Window of any type will fail with an InvalidRequestException being
381         thrown.  Calls to lock/unlock are recursive; if multiple calls to lock
382         are made, WindowManager is only unlocked after a matching number of
383         calls to unlock.
384 
385     \return
386         - true to indicate WindowManager is locked and that any attempt to
387         create Window objects will fail.
388         - false to indicate WindowManager is unlocked and that Window objects
389         may be created as normal.
390     */
391     bool isLocked() const;
392 
393 private:
394     /*************************************************************************
395         Implementation Methods
396     *************************************************************************/
397     /*!
398     \brief
399         Implementation method to generate a unique name to use for a window.
400     */
401     String generateUniqueWindowName();
402 
403     //! function to set up RenderEffect on a window
404     void initialiseRenderEffect(Window* wnd, const String& effect) const;
405 
406     /*************************************************************************
407 		Implementation Data
408 	*************************************************************************/
409     typedef std::vector<Window*
410         CEGUI_VECTOR_ALLOC(Window*)> WindowVector; //!< Type to use for a collection of Window pointers.
411 
412     //! collection of created windows.
413 	WindowVector d_windowRegistry;
414     WindowVector d_deathrow; //!< Collection of 'destroyed' windows.
415 
416     unsigned long   d_uid_counter;  //!< Counter used to generate unique window names.
417     static String d_defaultResourceGroup;   //!< holds default resource group
418     //! count of times WM is locked against new window creation.
419     uint    d_lockCount;
420 
421 public:
422 	/*************************************************************************
423 		Iterator stuff
424 	*************************************************************************/
425 	typedef	ConstVectorIterator<WindowVector>	WindowIterator;
426 
427 	/*!
428 	\brief
429 		Return a WindowManager::WindowIterator object to iterate over the currently defined Windows.
430 	*/
431 	WindowIterator	getIterator(void) const;
432 
433     /*!
434     \brief
435     Outputs the names of ALL existing windows to log (DEBUG function).
436 
437     \param zone
438     Helper string that can specify where the name dump was made (e.g. "BEFORE FRAME DELETION").
439 
440     \return
441     Nothing.
442     */
443     void DEBUG_dumpWindowNames(String zone) const;
444 };
445 
446 } // End of  CEGUI namespace section
447 
448 #if defined(_MSC_VER)
449 #	pragma warning(pop)
450 #endif
451 
452 #endif	// end of guard _CEGUIWindowManager_h_
453