Difference between revisions of "CEGUI In Practice - Creating widgets"

From CEGUI Wiki - Crazy Eddie's GUI System (Open Source)
Jump to: navigation, search
(The Widget in Practice)
 
(15 intermediate revisions by 7 users not shown)
Line 1: Line 1:
{{VersionBadge|0.7}}
+
{{VersionBadge|0.8}}
 
{{Series|CEGUI In Practice|2}}
 
{{Series|CEGUI In Practice|2}}
  
 
== CEGUI In-Practice 2 ==
 
== CEGUI In-Practice 2 ==
  
Welcome back.  This is the second installment of CEGUI In-Practice tutorial series.  In this we will build upon the previous tutorial, [[CEGUI InPractice 1]].  We will show how to create Widgets and manage them.
+
Welcome back.  This is the second installment of CEGUI In-Practice tutorial series.  In this we will build upon the previous tutorial, [[CEGUI In Practice - Introduction]].  We will show how to create Widgets and manage them.
  
 
=== The Widget ===
 
=== The Widget ===
Line 10: Line 10:
 
In the last example we showed how to bootstrap the system with Ogre, and gave a brief introduction to CEGUI's script files.  Now we will work on understanding what a widget is and how to use them.  Lets jump in and create a window which will display a box with an image in the middle of the screen:
 
In the last example we showed how to bootstrap the system with Ogre, and gave a brief introduction to CEGUI's script files.  Now we will work on understanding what a widget is and how to use them.  Lets jump in and create a window which will display a box with an image in the middle of the screen:
  
 +
<tabber>
 +
C++=
 
<source lang="cpp">
 
<source lang="cpp">
CEGUI::Window *myImageWindow = CEGUI::WindowManager::getSingletonPtr()->createWindow("TaharezLook/StaticImage","PrettyWindow" );  
+
CEGUI::Window *myImageWindow = CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/StaticImage","PrettyWindow" );  
 
</source>
 
</source>
 +
|-|
 +
Python=
 +
<source lang="python">
 +
myImageWindow = PyCEGUI.WindowManager.getSingleton().createWindow("TaharezLook/StaticImage","PrettyWindow" )
 +
</source>
 +
</tabber>
  
 
CEGUI uses numerous derived classes code-side to create windows.  The base class CEGUI::Window is the generic window. the CEGUI::WindowManager calls a factory class when creating a window which returns the windows pointer. The first argument, "TaharezLook/StaticImage" tells the factory what kind of window to make.  These windows are defined in .scheme, which are subsequently defined more depth in other .xml files. The second argument is the name which the window will have.   
 
CEGUI uses numerous derived classes code-side to create windows.  The base class CEGUI::Window is the generic window. the CEGUI::WindowManager calls a factory class when creating a window which returns the windows pointer. The first argument, "TaharezLook/StaticImage" tells the factory what kind of window to make.  These windows are defined in .scheme, which are subsequently defined more depth in other .xml files. The second argument is the name which the window will have.   
Line 18: Line 26:
 
[Note: As a point to note, there is no strict requirement on naming of windows, except to avoid repeat names.  Some users tend to prefer a naming convention using ParentName/ChildName.  ie.  "ConsoleWindow/SendButton" or "_MasterRoot/HealthBar"]
 
[Note: As a point to note, there is no strict requirement on naming of windows, except to avoid repeat names.  Some users tend to prefer a naming convention using ParentName/ChildName.  ie.  "ConsoleWindow/SendButton" or "_MasterRoot/HealthBar"]
  
Once we have created the window, myImageWindow will be a pointer to a CEGUI::{{DoxygenClass|DefaultWindow|0.7}} which is derived from CEGUI::{{DoxygenClass|Window|0.7}}. If you look in the .scheme file you can see can see what a Widget is derived from via the TargetType= tag.
+
Once we have created the window, myImageWindow will be a pointer to a CEGUI::{{DoxygenClass|DefaultWindow|0.8}} which is derived from CEGUI::{{DoxygenClass|Window|0.8}}. If you look in the .scheme file you can see can see what a Widget is derived from via the TargetType= tag.
  
 
Next we need to set some properties for this window. There are two ways of doing this. The first is via the propertyset, or the second way by calling the function. The latter way can be more annoying at times, as you may have to cast the window to the correct type to get access to the member functions, but may be more intuitive depending on how you think.
 
Next we need to set some properties for this window. There are two ways of doing this. The first is via the propertyset, or the second way by calling the function. The latter way can be more annoying at times, as you may have to cast the window to the correct type to get access to the member functions, but may be more intuitive depending on how you think.
Line 27: Line 35:
  
 
Before we jump in too far, we need to understand how CEGUI Handles positions. CEGUI Uses a Unified Dimension system.  
 
Before we jump in too far, we need to understand how CEGUI Handles positions. CEGUI Uses a Unified Dimension system.  
<source lang="cpp">CEGUI::UDim(scale,offset)</source>
+
 
 +
<tabber>
 +
C++=
 +
<source lang="cpp">
 +
CEGUI::UDim(scale,offset);
 +
</source>
 +
|-|
 +
Python=
 +
<source lang="python">
 +
PyCEGUI.UDim(scale,offset)
 +
</source>
 +
</tabber>
 +
 
 
The first number is the relative point on the screen between (0,1). So if we were looking at the X axis (left to right on the screen) a UDim(0.5,0) would be Halfway across the screen with zero pixels offset. Udim(0.0,50) would be starting at the left side of the screen +50 pixels. You can combine them too Udim(0.75,10) would be 3/4 of the way across the screen, with an additional 10 pixels.
 
The first number is the relative point on the screen between (0,1). So if we were looking at the X axis (left to right on the screen) a UDim(0.5,0) would be Halfway across the screen with zero pixels offset. Udim(0.0,50) would be starting at the left side of the screen +50 pixels. You can combine them too Udim(0.75,10) would be 3/4 of the way across the screen, with an additional 10 pixels.
  
 
A point on the screen (or a UVector2) is made up of two UDims:
 
A point on the screen (or a UVector2) is made up of two UDims:
<source lang="cpp">CEGUI::UVector2(UDim x,UDim y)</source>
+
 
 +
<tabber>
 +
C++=
 +
<source lang="cpp">
 +
CEGUI::UVector2(CEGUI::UDim x, CEGUI::UDim y);
 +
</source>
 +
|-|
 +
Python=
 +
<source lang="python">
 +
PyCEGUI.UVector2(PyCEGUI.UDim x, PyCEGUI.UDim y)
 +
</source>
 +
</tabber>
  
 
As such, a CEGUI::Rect is as you would imagine, 4 UDims
 
As such, a CEGUI::Rect is as you would imagine, 4 UDims
  
<source lang="cpp">CEGUI::URect(CEGUI::Udim left,CEGUI::Udim top,CEGUI::Udim right,CEGUI::Udim bottom)</source>
+
<tabber>
 
+
C++=
 +
<source lang="cpp">
 +
CEGUI::URect(CEGUI::Udim left,CEGUI::Udim top,CEGUI::Udim right,CEGUI::Udim bottom);
 +
</source>
 +
|-|
 +
Python=
 +
<source lang="python">
 +
PyCEGUI.URect(PyCEGUI.Udim left, PyCEGUI.Udim top, PyCEGUI.Udim right, PyCEGUI.Udim bottom)
 +
</source>
 +
</tabber>
  
 
So now that we know how positions are done, lets move our created window to the middle of the screen:
 
So now that we know how positions are done, lets move our created window to the middle of the screen:
 
==== The Widget in Practice ====
 
==== The Widget in Practice ====
  
<source lang="cpp">myImageWindow->setPosition(CEGUI::UVector2(CEGUI::UDim(0.5,0),CEGUI::UDim(0.5,0)));</source>
+
<tabber>
 +
C++=
 +
<source lang="cpp">
 +
myImageWindow->setPosition(CEGUI::UVector2(CEGUI::UDim(0.5,0),CEGUI::UDim(0.5,0)));
 +
</source>
 +
|-|
 +
Python=
 +
<source lang="python">
 +
myImageWindow.setPosition(PyCEGUI.UVector2(PyCEGUI.UDim(0.5,0), PyCEGUI.UDim(0.5,0)))
 +
</source>
 +
</tabber>
  
 
That may look a little ugly but break it down. setPosition takes a UVector2, and each UVector2 is made up of an X and Y Udim, which is made up of a Scale and Absolute float.  
 
That may look a little ugly but break it down. setPosition takes a UVector2, and each UVector2 is made up of an X and Y Udim, which is made up of a Scale and Absolute float.  
Line 47: Line 97:
 
So, we have moved our window to the middle of the screen.. but CEGUI doesn't know how big to make it? So set its size to 150 pixels by 100 pixels [Note: I dropped the namespace for this to increase readability].  
 
So, we have moved our window to the middle of the screen.. but CEGUI doesn't know how big to make it? So set its size to 150 pixels by 100 pixels [Note: I dropped the namespace for this to increase readability].  
  
<source lang="cpp">myImageWindow->setSize(UVector2(UDim(0,150),UDim(0,100)));</source>
 
  
In this case we specified the Udim using 0 for scales, and the actual pixel size in the absolute argument. The Absolute argument is additive to the scale, and in this case we didn't want to have the size be affected by the scale argument. If we were creating a splash screen that took up the entire window, we would likely want the size to be UVector2(UDim(1,0),UDim(1,0) with the position being at UVector2(Udim(0,0), UDim(0,0).
+
<tabber>
 +
C++=
 +
<source lang="cpp">
 +
myImageWindow->setSize(USize(UDim(0,150),UDim(0,100)));
 +
</source>
 +
|-|
 +
Python=
 +
<source lang="python">
 +
myImageWindow.setSize(USize(UDim(0,150),UDim(0,100)));
 +
</source>
 +
</tabber>
 +
 
 +
In this case we specified the Udim using 0 for scales, and the actual pixel size in the absolute argument. The Absolute argument is additive to the scale, and in this case we didn't want to have the size be affected by the scale argument. If we were creating a splash screen that took up the entire window, we would likely want the size to be USize(UDim(1,0),UDim(1,0) with the position being at USize(Udim(0,0), UDim(0,0).
  
 +
[TODO: Add a proper description of USize which replaced UVector2 for setting size in CEGUI 0.8.3]
  
 
Now that we have created the window to the size we want. We need to tell it what image to display! That we will do by using the PropertySet as follows.
 
Now that we have created the window to the size we want. We need to tell it what image to display! That we will do by using the PropertySet as follows.
  
 +
<tabber>
 +
C++=
 
<source lang="cpp">
 
<source lang="cpp">
myImageWindow->setProperty("Image","set:TaharezLook image:full_image");
+
myImageWindow->setProperty("Image","TaharezLook/full_image");
 
</source>
 
</source>
 +
|-|
 +
Python=
 +
<source lang="python">
 +
myImageWindow.setProperty("Image","TaharezLook/full_image")
 +
</source>
 +
</tabber>
  
The first agument is what Property we want to set, and the second argument is what value to set. The second argument is a string broken into two pieces in this example. We need to know what ImageSet we are looking in, which is referenced following the 'set:' portion. And then the image via the 'image:' portion. In this case we want it to show the full_image.
+
The first agument is what Property we want to set, and the second argument is what value to set. The second argument is a string with first the Imageset name, a dash, and then the Image name: "YourImagesetName/ImageName".
  
A Listing of properties for TaharezLook is available here [http://cegui.org.uk/static/TaharezLookProperties.html]
+
A Listing of properties for TaharezLook is available here [http://cegui.org.uk/wiki/Property_reference_for_TaharezLook]
  
 
Now that we have created the window. We need to attach it to the current root window.
 
Now that we have created the window. We need to attach it to the current root window.
  
<source lang="cpp">CEGUI::System::getGUISheet()->addChildWindow(myImageWindow);</source>
+
<tabber>
 +
C++=
 +
<source lang="cpp">
 +
CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow()->addChild(myImageWindow);
 +
</source>
 +
|-|
 +
Python=
 +
<source lang="python">
 +
PyCEGUI.System.getSingleton().getDefaultGUIContext().getRootWindow().addChild(myImageWindow)
 +
</source>
 +
</tabber>
  
 
This will allow the Window to be displayed.
 
This will allow the Window to be displayed.
 
  
 
==== Conclusion ====
 
==== Conclusion ====

Latest revision as of 23:13, 10 April 2014

Written for CEGUI 0.8


Works with versions 0.8.x (stable)

Works with latest CEGUI stable!

CEGUI In Practice series

This page is part of a series, use links above to easily navigate through all chapters of the series.

CEGUI In-Practice 2

Welcome back. This is the second installment of CEGUI In-Practice tutorial series. In this we will build upon the previous tutorial, CEGUI In Practice - Introduction. We will show how to create Widgets and manage them.

The Widget

In the last example we showed how to bootstrap the system with Ogre, and gave a brief introduction to CEGUI's script files. Now we will work on understanding what a widget is and how to use them. Lets jump in and create a window which will display a box with an image in the middle of the screen:

CEGUI::Window *myImageWindow = CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/StaticImage","PrettyWindow" );

myImageWindow = PyCEGUI.WindowManager.getSingleton().createWindow("TaharezLook/StaticImage","PrettyWindow" )

CEGUI uses numerous derived classes code-side to create windows. The base class CEGUI::Window is the generic window. the CEGUI::WindowManager calls a factory class when creating a window which returns the windows pointer. The first argument, "TaharezLook/StaticImage" tells the factory what kind of window to make. These windows are defined in .scheme, which are subsequently defined more depth in other .xml files. The second argument is the name which the window will have.

[Note: As a point to note, there is no strict requirement on naming of windows, except to avoid repeat names. Some users tend to prefer a naming convention using ParentName/ChildName. ie. "ConsoleWindow/SendButton" or "_MasterRoot/HealthBar"]

Once we have created the window, myImageWindow will be a pointer to a CEGUI::DefaultWindow which is derived from CEGUI::Window. If you look in the .scheme file you can see can see what a Widget is derived from via the TargetType= tag.

Next we need to set some properties for this window. There are two ways of doing this. The first is via the propertyset, or the second way by calling the function. The latter way can be more annoying at times, as you may have to cast the window to the correct type to get access to the member functions, but may be more intuitive depending on how you think.

The Unified Dimension System

We created our widget, now we need to position it and define its size. Lets do that via code shall we?

Before we jump in too far, we need to understand how CEGUI Handles positions. CEGUI Uses a Unified Dimension system.

CEGUI::UDim(scale,offset);

PyCEGUI.UDim(scale,offset)

The first number is the relative point on the screen between (0,1). So if we were looking at the X axis (left to right on the screen) a UDim(0.5,0) would be Halfway across the screen with zero pixels offset. Udim(0.0,50) would be starting at the left side of the screen +50 pixels. You can combine them too Udim(0.75,10) would be 3/4 of the way across the screen, with an additional 10 pixels.

A point on the screen (or a UVector2) is made up of two UDims:

CEGUI::UVector2(CEGUI::UDim x, CEGUI::UDim y);

PyCEGUI.UVector2(PyCEGUI.UDim x, PyCEGUI.UDim y)

As such, a CEGUI::Rect is as you would imagine, 4 UDims

CEGUI::URect(CEGUI::Udim left,CEGUI::Udim top,CEGUI::Udim right,CEGUI::Udim bottom);

PyCEGUI.URect(PyCEGUI.Udim left, PyCEGUI.Udim top, PyCEGUI.Udim right, PyCEGUI.Udim bottom)

So now that we know how positions are done, lets move our created window to the middle of the screen:

The Widget in Practice

myImageWindow->setPosition(CEGUI::UVector2(CEGUI::UDim(0.5,0),CEGUI::UDim(0.5,0)));

myImageWindow.setPosition(PyCEGUI.UVector2(PyCEGUI.UDim(0.5,0), PyCEGUI.UDim(0.5,0)))

That may look a little ugly but break it down. setPosition takes a UVector2, and each UVector2 is made up of an X and Y Udim, which is made up of a Scale and Absolute float.

So, we have moved our window to the middle of the screen.. but CEGUI doesn't know how big to make it? So set its size to 150 pixels by 100 pixels [Note: I dropped the namespace for this to increase readability].


myImageWindow->setSize(USize(UDim(0,150),UDim(0,100)));

myImageWindow.setSize(USize(UDim(0,150),UDim(0,100)));

In this case we specified the Udim using 0 for scales, and the actual pixel size in the absolute argument. The Absolute argument is additive to the scale, and in this case we didn't want to have the size be affected by the scale argument. If we were creating a splash screen that took up the entire window, we would likely want the size to be USize(UDim(1,0),UDim(1,0) with the position being at USize(Udim(0,0), UDim(0,0).

[TODO: Add a proper description of USize which replaced UVector2 for setting size in CEGUI 0.8.3]

Now that we have created the window to the size we want. We need to tell it what image to display! That we will do by using the PropertySet as follows.

myImageWindow->setProperty("Image","TaharezLook/full_image");

myImageWindow.setProperty("Image","TaharezLook/full_image")

The first agument is what Property we want to set, and the second argument is what value to set. The second argument is a string with first the Imageset name, a dash, and then the Image name: "YourImagesetName/ImageName".

A Listing of properties for TaharezLook is available here [1]

Now that we have created the window. We need to attach it to the current root window.

CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow()->addChild(myImageWindow);

PyCEGUI.System.getSingleton().getDefaultGUIContext().getRootWindow().addChild(myImageWindow)

This will allow the Window to be displayed.

Conclusion

So with this quick tutorial we got a very short introduction to PropertySet usage (Important!) and a little bit about how the Unified Dimension System in CEGUI Works. While still not terribly useful, we're beginning to understand how to use some of CEGUI's faculties. Next up, we'll learn how to get some interactivity from this thing.