CEGUI In Practice - A push button
Written for CEGUI 0.7
Works with versions 0.7.x (obsolete)
CEGUI In Practice series
CEGUI In-Practice 4
Hello hello, you're making good headway through these tutorials! Alright, last lesson we got a glimpse of how to send input to CEGUI. This is useful, because today we're going to make a button. And not just any button, but a button which makes something happen! I know, exciting.
Some groundwork
First we need to look into how CEGUI handles event control.
CEGUI is based around the Event/Subscriber method. Meaning, something (A button, an edit box, a list box) fires off an event (MouseClick,Text Accepted, or Selection), and something else (The Application Class, another CEGUI Widget, anything!) is informed about it. It does this via the
CEGUI::Window::subscribeEvent(const String& name,Event::Subscriber subscriber)
The first argument is the Event that you wish to keep track of. Events are static const strings. You will find these in the respective header files for CEGUI Widget types. (Example CEGUIPushButton contains CEGUI::PushButton::EventClicked)
The second argument is the subscriber which will be called whenever this event occurs.
Let's give an example of how to register our character to jump whenever a button is pressed. First, let's create our Button, which will make our character jump. Although this is bad coding style, we will create the button in global scope for ease of this example.
CEGUI::Window *gJumpBtnWindow = NULL; void CreateJumpButton() { gJumpBtnWindow = CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/Button","JumpPushButton"); // Create Window gJumpBtnWindow->setPosition(CEGUI::UVector2(CEGUI::UDim(0.75,0),CEGUI::UDim(0.50,0)); gJumpBtnWindow->setSize(CEGUI::UVector2(CEGUI::UDim(0,50),CEGUI::UDim(0,50)); gJumpBtnWindow->setText("Jump!"); CEGUI::System::getSingleton().getGUISheet()->addChildWindow(gJumpBtnWindow); }
The above code Creates the button of type "TaharezLook/Button", as exists in the .scheme file. Then it gives it the name of "JumpPushButton" and sets its size and position, followed by attaching it to the root GUI Window. This is review from two tutorials ago. However, the setText one is new. It's pretty Self explanatory I would assume, but it Sets the text for windows. PushButtons, EditBoxes, FrameWindows, etc. all have a spot to display text and this function will do it.
Now that we have created our button, let's create a class that will receive this JumpPushButton's events. Please remember this is an example. In your application, it likely won't be this simple!
class OurPlayer { public: OurPlayer() { RegisterForEvents(); // Call our Register function }; bool Jump(const CEGUI::EventArgs& /*e*/){}; // Jump for joy private: RegisterForEvents() { gJumpBtnWindow->subscribeEvent(CEGUI::PushButton::EventClicked,CEGUI::Event::Subscriber(&OurPlayer::Jump,this)); }; }
Alright, that's a neat little class right? I don't know how you're going to make your character jump, so you get to fill in that information. I'm just gonna show you how to interact with the GUI!
Alright, the really interesting line here is the RegisterForEvents() function. You may or may not have dealt with EventSubscribers before in other applications, so I will give a very brief intro to them.
Basically, they work by creating a structure which is supplied to CEGUI stating what function to call, and where to get an instance of a member that has that function. the first argument, &OurPlayer::Jump states that we want to use the function Jump which is a member of OurPlayer. The problem is it doesn't know WHICH OurPlayer we want to use. What if we are playing split screen and we have two OurPlayer classes? One for the Left player and one for the Right player? Now we need to specify which player. There is the second argument. In C++, this returns a pointer to the class execution is currently in. So since we're registering this event within a class, we tell it to use this, which will reference the class that called RegisterForEvents();
If we had created as follows:
OurPlayer *leftPlayer; OurPlayer *rightPlayer;
then we would call the function like this
gJumpBtnWindow->subscribeEvent(CEGUI::PushButton::EventClicked,CEGUI::Event::Subscriber(&OurPlayer::Jump,leftPlayer));
So as you can see this allows for a lot of possibilities. There are also events for:
- MouseClicked,
- MouseEnters,
- MouseLeaves,
- EventActivated,
- EventTextChanged,
- EventAlphaChanged,
- EventSized
Just to name a few. There is a Huge listing of events which all windows inherit in CEGUIWindow.h
Conclusion
Hopefully this tutorial showed you how to implement events in cegui. They really are the mechanism which all things happen. Once you master how to use events, the rest of the GUI becomes so easy to use, as most user interactions are event driven. While you may not use them all, there are even events for Rotating windows and dropping windows on other windows! Just think of the possibilities. Until next time Happy Clicking!