1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>Crazy Eddies GUI System: The Beginners Guide to Creating a CEGUI Window</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Generated by Doxygen 1.7.4 -->
<script type="text/javascript">
function hasClass(ele,cls) {
return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}
function addClass(ele,cls) {
if (!this.hasClass(ele,cls)) ele.className += " "+cls;
}
function removeClass(ele,cls) {
if (hasClass(ele,cls)) {
var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
ele.className=ele.className.replace(reg,' ');
}
}
function toggleVisibility(linkObj) {
var base = linkObj.getAttribute('id');
var summary = document.getElementById(base + '-summary');
var content = document.getElementById(base + '-content');
var trigger = document.getElementById(base + '-trigger');
if ( hasClass(linkObj,'closed') ) {
summary.style.display = 'none';
content.style.display = 'block';
trigger.src = 'open.png';
removeClass(linkObj,'closed');
addClass(linkObj,'opened');
} else if ( hasClass(linkObj,'opened') ) {
summary.style.display = 'block';
content.style.display = 'none';
trigger.src = 'closed.png';
removeClass(linkObj,'opened');
addClass(linkObj,'closed');
}
return false;
}
</script>
<div id="top">
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
<div id="projectname">Crazy Eddies GUI System <span id="projectnumber">0.7.6</span></div>
</td>
</tr>
</tbody>
</table>
</div>
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main Page</span></a></li>
<li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="namespaces.html"><span>Namespaces</span></a></li>
<li><a href="annotated.html"><span>Classes</span></a></li>
<li><a href="files.html"><span>Files</span></a></li>
</ul>
</div>
</div>
<div class="header">
<div class="headertitle">
<div class="title">The Beginners Guide to Creating a <a class="el" href="namespaceCEGUI.html" title="Main namespace for Crazy Eddie's GUI Library.">CEGUI</a> <a class="el" href="classCEGUI_1_1Window.html" title="An abstract base class providing common functionality and specifying the required interface for deriv...">Window</a> </div> </div>
</div>
<div class="contents">
<div class="textblock"><dl class="author"><dt><b>Author:</b></dt><dd>Paul D Turner</dd></dl>
<p>The purpose of this tutorial is to show you how to create a simple window and get it on screen. Before continuing here, it is very important that you have already read and fully understood the articles <a class="el" href="rendering_tutorial.html">The Beginners Guide to Getting CEGUI Rendering</a>, <a class="el" href="resprov_tutorial.html">The Beginners Guide to resource loading with ResourceProviders</a> and <a class="el" href="datafile_tutorial.html">The Beginners Guide to Data Files and Defaults Initialisation</a> because this tutorial builds upon the basic ideas introduced in those previous tutorials.</p>
<p><br/>
</p>
<h2><a class="anchor" id="window_tutorial_intro"></a>
Introduction to window and widget concepts</h2>
<p>Before we get to the the meat of this tutorial there are some essential ideas that you must first consider.</p>
<h3><a class="anchor" id="window_tutorial_window_base"></a>
Every widget is a window</h3>
<p>This is the most central concept that must be grasped when working with <a class="el" href="namespaceCEGUI.html" title="Main namespace for Crazy Eddie's GUI Library.">CEGUI</a>. Every widget within the system is derived from the same <a class="el" href="classCEGUI_1_1Window.html" title="An abstract base class providing common functionality and specifying the required interface for deriv...">Window</a> base class; so for the purposes of this tutorial, whenever I mention a window, the same ideas could just as easily be applied to a push button or scrollbar widget.</p>
<h3><a class="anchor" id="window_tutorial_window_inheritance"></a>
Many settings are inherited</h3>
<p>Many of the settings and properties available for windows in <a class="el" href="namespaceCEGUI.html" title="Main namespace for Crazy Eddie's GUI Library.">CEGUI</a> are passed down the window hierarchy. For example, if you set the alpha transparency on a particular window to 0.5, then by default, all window and widgets attached to that window will also be affected by the change applied at the higher level; although note also that the actual setting on the child window remains unchanged - the final values and/or settings used are usually some combination of the setting values from all windows in the hierarchy down to the current window. This also applies to things such as window destruction; by default, a window will destroy attached child windows and widgets when it is destroyed. The main advantages of this arrangement are that you can easily affect a the whole GUI by making changes to the root window settings for things like alpha, visibility, enabled / disabled state, and can easily 'clean up' an entire GUI layout by simply destroying the root window. The default 'inherited' behaviours can be overridden on a per window basis where more fine grained control is needed, or where certain advanced management techniques are to be used.</p>
<p><br/>
</p>
<h2><a class="anchor" id="window_tutorial_creating_intro"></a>
Creating the windows</h2>
<p>Enough of the waffle! Let's create a window.</p>
<p>There are two ways of doing this, via C++ code and XML layout files. Each approach is discussed below.</p>
<h3><a class="anchor" id="window_tutorial_creating_cpp"></a>
GUI Creation via C++ code</h3>
<p>All windows in <a class="el" href="namespaceCEGUI.html" title="Main namespace for Crazy Eddie's GUI Library.">CEGUI</a> are created by the <a class="el" href="classCEGUI_1_1WindowManager.html" title="The WindowManager class describes an object that manages creation and lifetime of Window objects...">WindowManager</a> singleton object. You can get access to this object via the WindowManager::getSingleton function: </p>
<div class="fragment"><pre class="fragment"><span class="keyword">using namespace </span>CEGUI;
<a class="code" href="classCEGUI_1_1WindowManager.html" title="The WindowManager class describes an object that manages creation and lifetime of Window objects...">WindowManager</a>& wmgr = WindowManager::getSingleton();
</pre></div><p>In general, you will be using what is known as a DefaultWindow (or to use its old name, DefaultGUISheet) as the 'root' window in your GUI. This is not required, but is the accepted pattern of usage for <a class="el" href="namespaceCEGUI.html" title="Main namespace for Crazy Eddie's GUI Library.">CEGUI</a> and, once you start adding more top-level windows, helps simplify laying things out.</p>
<p>So, to get the ball rolling, we'll create a DefaultWindow as set it as the root 'GUI Sheet' for the GUI: </p>
<div class="fragment"><pre class="fragment">Window* myRoot = wmgr.createWindow( <span class="stringliteral">"DefaultWindow"</span>, <span class="stringliteral">"root"</span> );
<a class="code" href="classCEGUI_1_1System.html#a8d059b018d621be0e4b98d069421426f" title="Return singleton System object.">System::getSingleton</a>().<a class="code" href="classCEGUI_1_1System.html#a8317dec1b0358be9b0c660a0eba6d209" title="Set the active GUI sheet (root) window.">setGUISheet</a>( myRoot );
</pre></div><p>The <a class="el" href="classCEGUI_1_1WindowManager.html#a4cbf9d34edb1829f7a1b7cce9b42eab1" title="Creates a new Window object of the specified type, and gives it the specified unique name...">WindowManager::createWindow</a> function takes two strings as its parameters. The first one, <code>"DefaultWindow"</code> in this example, tells the system the type or class of the window you wish to create. Generally, the windows you have available are those which were registered when you loaded your scheme file, although some, like DefaultWindow, are global types and are always available. The second parameter, <code>"root"</code> in this example, is a unique name which will be assigned to the window; this name can be used to retrieve a pointer to the window from the <a class="el" href="classCEGUI_1_1WindowManager.html" title="The WindowManager class describes an object that manages creation and lifetime of Window objects...">WindowManager</a> at a later time. Note that naming your root window "root" is not required, but is a common convention.</p>
<p>The <a class="el" href="classCEGUI_1_1System.html#a8317dec1b0358be9b0c660a0eba6d209" title="Set the active GUI sheet (root) window.">System::setGUISheet</a> function is used to specify a given window as the root of the GUI. This will replace any current sheet / root window, although do note that the previous window hierarchy is not actually destroyed - it is just detached from the display - you can easily switch between GUI 'pages' by simply flipping between them using the <a class="el" href="classCEGUI_1_1System.html#a8317dec1b0358be9b0c660a0eba6d209" title="Set the active GUI sheet (root) window.">System::setGUISheet</a> function.</p>
<p>Now you have created your first window and attached it to the GUI system, and the system will use this window as the root of the GUI when it draws the GUI. But if you were to compile a simple program using this code, you still can't see anything; what gives? There's nothing wrong with your application, the DefaultWindow which we created above is just totally invisible! This is what makes the DefaultWindow ideally suited as a root window; it serves as a blank canvas onto which other window and widgets can be attached. Lets do that now...</p>
<p>Here we will create a frame window; this is a window that functions in a similar manner to the windows on your desktop UI, it has a title bar and can be moved and re-sized. </p>
<div class="fragment"><pre class="fragment">FrameWindow* fWnd = <span class="keyword">static_cast<</span>FrameWindow*<span class="keyword">></span>(
wmgr.createWindow( <span class="stringliteral">"TaharezLook/FrameWindow"</span>, <span class="stringliteral">"testWindow"</span> ));
</pre></div><p>here we are creating a <code>"TaharezLook/FrameWindow"</code> window. This name uses another convention seen throughout the system, whereby a window type is prefixed by the name of the widget set (if you were to load the WindowsLook scheme, you could create a <code>"WindowsLook/FrameWindow"</code> object instead). We have given our new window the simple test name of <code>"testWindow"</code>. One final thing to note is the use of the cast, this is required since the <a class="el" href="classCEGUI_1_1WindowManager.html#a4cbf9d34edb1829f7a1b7cce9b42eab1" title="Creates a new Window object of the specified type, and gives it the specified unique name...">WindowManager::createWindow</a> function always returns a the <a class="el" href="classCEGUI_1_1Window.html" title="An abstract base class providing common functionality and specifying the required interface for deriv...">Window</a> type. In this - and many other - cases a basic <a class="el" href="classCEGUI_1_1Window.html" title="An abstract base class providing common functionality and specifying the required interface for deriv...">Window</a> pointer will suffice, but there are times when you'll want to access functions introduced in the sub-classes, so the use of the cast as shown is common when using <a class="el" href="namespaceCEGUI.html" title="Main namespace for Crazy Eddie's GUI Library.">CEGUI</a>.</p>
<p>In order for the system to be able to do something useful with our new window, we must perform a few additional steps.</p>
<p>First, we must attach the window to the root window we established above: </p>
<div class="fragment"><pre class="fragment">myRoot->addChildWindow( fWnd );
</pre></div><p>Now we can set an initial position and size for our window. <a class="el" href="namespaceCEGUI.html" title="Main namespace for Crazy Eddie's GUI Library.">CEGUI</a> uses a 'unified' co-ordinate system enabling the use of relative (scale) and absolute (offset) components at the same time - this is why each co-ordinate you will see has two parts. For a slightly extended introduction of this concept see <a class="el" href="fal_intro.html#fal_unifiedsystem">The Unified Co-ordinate System</a> which is part of the <a class="el" href="fal_man.html">Falagard skinning system for CEGUI</a>. Back to the example: </p>
<div class="fragment"><pre class="fragment"><span class="comment">// position a quarter of the way in from the top-left of parent.</span>
fWnd->setPosition( UVector2( UDim( 0.25f, 0 ), UDim( 0.25f, 0 ) ) );
<span class="comment">// set size to be half the size of the parent</span>
fWnd->setSize( UVector2( UDim( 0.5f, 0 ), UDim( 0.5f, 0 ) ) );
</pre></div><p>Finally, we set a caption for the frame window's title bar: </p>
<div class="fragment"><pre class="fragment">fWnd->setText( <span class="stringliteral">"Hello World!"</span> );
</pre></div><p> And that's it! When compiled into an application, you will now see a simple frame window in the middle of the display.</p>
<p><br/>
</p>
<h3><a class="anchor" id="window_tutorial_creating_xml"></a>
XML layouts</h3>
<p>All of the above is very nice, but there is one major drawback; any time you wish to adjust the GUI layout, you need to edit your code and recompile. This will get old pretty quick, so what you really want is to be able to specify your GUI layout externally, and have your code load the layout via a file. This is the purpose of the <a class="el" href="namespaceCEGUI.html" title="Main namespace for Crazy Eddie's GUI Library.">CEGUI</a> layout XML files.</p>
<p>The system supports XML layout files, which can be loaded via the <a class="el" href="classCEGUI_1_1WindowManager.html#ac2b32e08e317fdd5455944dbe75cf253" title="Creates a set of windows (a Gui layout) from the information in the specified XML file...">WindowManager::loadWindowLayout</a> function. This function creates all the windows for you and returns a pointer to the root window of the loaded hierarchy - which is ideal for assigning as the root of the GUI!</p>
<p>So, first of all we need a layout file. The following XML saved as a text file, is a layout file equivalent to the code we discussed above: </p>
<div class="fragment"><pre class="fragment"><?xml version=<span class="stringliteral">"1.0"</span> ?>
<GUILayout>
<Window Type=<span class="stringliteral">"DefaultWindow"</span> Name=<span class="stringliteral">"root"</span>>
<Window Type=<span class="stringliteral">"TaharezLook/FrameWindow"</span> Name=<span class="stringliteral">"testWindow"</span>>
<Property Name=<span class="stringliteral">"UnifiedPosition"</span> Value=<span class="stringliteral">"{ {0.25, 0}, {0.25, 0} }"</span> />
<Property Name=<span class="stringliteral">"UnifiedSize"</span> Value=<span class="stringliteral">"{ {0.5, 0}, {0.5, 0} }"</span> />
<Property Name=<span class="stringliteral">"Text"</span> Value=<span class="stringliteral">"Hello World!"</span> />
</Window>
</Window>
</GUILayout>
</pre></div><p>The <a class="el" href="classCEGUI_1_1Window.html" title="An abstract base class providing common functionality and specifying the required interface for deriv...">Window</a> elements show an obvious mapping to the <a class="el" href="classCEGUI_1_1WindowManager.html#a4cbf9d34edb1829f7a1b7cce9b42eab1" title="Creates a new Window object of the specified type, and gives it the specified unique name...">WindowManager::createWindow</a> function - they take a type and a name which directly correspond to the parameters discussed previously.</p>
<p>Nesting of the <a class="el" href="classCEGUI_1_1Window.html" title="An abstract base class providing common functionality and specifying the required interface for deriv...">Window</a> elements is used to attach certain windows to others. Note that you may only have one 'root' level window in a layout file, which is another reason you'll usually see the DefaultWindow used as a canvas on which other windows and widgets are placed.</p>
<p>The <a class="el" href="classCEGUI_1_1Property.html" title="An abstract class that defines the interface to access object properties by name.">Property</a> elements are used to set properties on the <a class="el" href="classCEGUI_1_1Window.html" title="An abstract base class providing common functionality and specifying the required interface for deriv...">Window</a> being defined. There are many properties available for each window/widget class, and each class also inherits all properties from it's parent class. See the <a href="namespaces.html">Properties namespaces in the API reference</a> for documentation on the available hard-coded properties and their value string formats. Since 'Falagard' skins can create their own properties, it is likely that the windows you are using contain many more properties than listed in the previous link - for these 'soft' properties, you need to consult whichever documentation is provided with the skin you are using (for example, see the <a class="el" href="namespaceCEGUI.html" title="Main namespace for Crazy Eddie's GUI Library.">CEGUI</a> Wiki: <a href="http://www.cegui.org.uk/wiki/index.php/SetProperty">TaharezLook Properties</a> and <a href="http://www.cegui.org.uk/wiki/index.php/SetProperty_(WindowsLook)">WindowsLook Properties</a>.</p>
<p>If saved as a file called "test.layout", you could load this layout and set it as the GUI root as follows: </p>
<div class="fragment"><pre class="fragment"><span class="keyword">using namespace </span>CEGUI;
<a class="code" href="classCEGUI_1_1Window.html" title="An abstract base class providing common functionality and specifying the required interface for deriv...">Window</a>* myRoot = WindowManager::getSingleton().loadWindowLayout( <span class="stringliteral">"test.layout"</span> );
<a class="code" href="classCEGUI_1_1System.html#a8d059b018d621be0e4b98d069421426f" title="Return singleton System object.">System::getSingleton</a>().<a class="code" href="classCEGUI_1_1System.html#a8317dec1b0358be9b0c660a0eba6d209" title="Set the active GUI sheet (root) window.">setGUISheet</a>( myRoot );
</pre></div><p>The end result is exactly the same as what was done in C++ code earlier, except that now you can modify and enhance the GUI layout without the need for constant editing and recompilation of the application code.</p>
<p><br/>
</p>
<h2><a class="anchor" id="window_tutorial_conclusion"></a>
Conclusion</h2>
<p>Here you have seen how to perform basic window creation, how to create a simple window hierarchy, and how modify some window settings. You have seen how this can be accomplished using both C++ code and external XML layout files. There are many advanced possibilities available using both methods, although such possibilities are beyond the scope of this indroductory tutorial. </p>
</div></div>
<hr class="footer"/><address class="footer"><small>Generated on Sun Jan 22 2012 16:07:40 for Crazy Eddies GUI System by 
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.4 </small></address>
</body>
</html>
|