Introduction

In this tutorial we will create a Button Widget and assign an event handler to it. Tutorial 1 is a prerequisite for this tutorial, unless you know how to setup QuickGUI and inject input correctly.

Step 1 : Creating the Button

The GUIManager creates a default Sheet for use, which can be retrieved by calling

QuickGUI::Sheet* defaultSheet = mGUIManager->getActiveSheet();

Using the Sheet we can create the majority of Widgets supported in QuickGUI. Widgets are created using Desc objects, similar to the way the GUIManager was created. To create a Button, we will need a ButtonDesc object. Desc objects can be created via the DescManager.

QuickGUI::DescManager::getSingleton();

By default, the DescManager has a Desc for each Widget, used for general purposes, and also internally. Additionally, the DescManager supports creation and destruction of Descs, and gives Access to these descs.

QuickGUI::ButtonDesc* bd = QuickGUI::DescManager::getSingleton().getDefaultButtonDesc();

Using the desc object has many benefits. You can set button properties before creating the button, and also re-use the desc to create other buttons. All properties of the desc object have corresponding API calls, meaning the Button's properties can be changed after creation. Also note that all desc objects have a "resetToDefaults" function. At any time you can enforce all desc properties to be reverted to their default values. Lets give a few properties and create the button:

bd->widget_name = "MyButton";
  bd->widget_dimensions.size = QuickGUI::Size(100,25);
  bd->widget_dimensions.position = QuickGUI::Point(50,50);
  QuickGUI::Button* myButton = defaultSheet->createButton(bd);

Compile and run, and a button should be 50 pixels from the right and 50 pixels from the top! By default the skinType is set to "default", which is provided with QuickGUI. Feel free to change this if you have another skin you would like to use. Its also important to note the "resetToDefault" function, as it will reset a Descs properties to a default state.

Step 2 : Adding Text to a Button

There are two ways to add Text to a button: before creation, and after creation.

Adding Text to a button before its created must be done through the desc object. The ButtonDesc object comes with a TextDesc object, which is used to describe the text of the button. Text is made up of TextSegments, which are strings of text that are the same color and font. You can append several segments together to create a variety of effects. Here is a basic sample:

bd->textDesc.segments.push_back(QuickGUI::TextSegment("micross.12",QuickGUI::ColourValue::Red,"Click Me!"));

What the above line of code does is add a segment of text with string "Click Me!", using the font "micross.12", in red color. The micross.12 font must exist in an *.fontdef file, recognized by Ogre.

If you are re-using the desc object to create multiple objects, you may want to clear the text segments before adding text:

bd->textDesc.segments.clear();

Changing the Text of a Button after it is created is done through the Button's API. (setText(...))

Step 3 : Skinning the button

The skin is another property that can be set before or after creation of a Widget.

The desc property 'widget_skinTypeName' stores the name of the Skin of the widget, which references a Skin Type, which are defined in .skinTypes files.

By default a widget's skin is set to 'default', which is provided in qgui.core.zip. For example if we wanted to change our button's skin to look like a Vertical ScrollBar's down arrow, we could set the property prior to creation:

bd->widget_skinTypeName = "default.vscrolldown";

or if we wanted to change the skin after creation:

myButton->setSkinType("default.vscrolldown");

Step 4 : Register an Event Handler



In QuickGUI, Widgets of the GUI will fire events when certain actions are performed. In order to get notified when an event happens, an Event Handler needs to be registered. All event handlers follow this signature:

void myClass::myFunction(const EventArgs& args) { ... }

The following is an example of registering an Event Handler when the mouse buttons goes up while over a button:

myButton->addWidgetEventHandler(QuickGUI::WIDGET_EVENT_MOUSE_BUTTON_UP,&myClass::myFunction,this);

"this" refers to the object instance that will call the function. In the case above, the myClass instance is registering the event handler inside one of its functions. Whenever the Mouse button goes up over myButton, myFunction will be called.

Note that myClass must be polymorphic, or you may receive a compiler error like:

QuickGUIEventHandlerPointer.h:55: error: cannot dynamic_cast
 '((QuickGUI::EventHandlerPointer<myClass>*)this)->QuickGUI::EventHandlerPointer<myClass>::d_object' 
  (of type 'class myClass*') to type 'void*' (source type is not polymorphic)

The class can be made polymorphic by making the constructor virtual:

virtual ~myClass();

Step 5 : EventArgs



EventArgs are the most general form of Args in QuickGUI. Many Args are derived from this base class, such as WidgetEventArgs and MouseEventArgs. There is a type member that stores what type the Event really is, but in most cases you will know. For example, clicking on a button generally involves a mouse, so you can be comfortable in casting the EventArgs to MouseEventArgs and using data from it.

In the following example, we convert the EventArgs into MouseEventArgs, and check to see if the Left Mouse Button went up:

void MainForm::test1(const QuickGUI::EventArgs& args)
  {
      const QuickGUI::MouseEventArgs& mea = dynamic_cast<const QuickGUI::MouseEventArgs&>(args);
  
      if(mea.button == QuickGUI::MB_Left)
      {
          ; // do something
      }
  }

Using this approach, we can also get the Widget involved in the event. In this case MouseEventArgs is derived from WidgetEventArgs, so we can access the widget like this:

mea.widget

An alternative would be to cast the EventArgs into WidgetEventArgs and get access to the widget that way.

There are a lot of Events for the Widget class, and many widget have unique Events. For widgets with unique Events, for example a List, you will use the following function to register handlers:

List::addListEventHandler(...)

Step 6 : Convenient creation of Widgets



In previous versions of QuickGUI, all Widgets required the user to supply a Desc in order for them to be created. Since v9.03, I have created several overloaded functions, allowing Widgets to be created without needing a Desc. In the example above, a ButtonDesc was needed to create the Button. In the latest code base, its also possible to create a button using the following code:

defaultSheet->createButton();
  defaultSheet->createButton(QuickGUI::Point(50,50));
  defaultSheet->createButton("Click Me!",QuickGUI::Rect(50,50,100,25));
  ...

This also applies to the majority of other widgets in QuickGUI.


Alias: QuickGUI_Beginner_Tutorial_2