Handling Events from Lua

From CEGUI Wiki - Crazy Eddie's GUI System (Open Source)
Jump to: navigation, search

Written for CEGUI 0.3


Works with versions 0.3.x (obsolete)

Written for CEGUI 0.4


Works with versions 0.4.x (obsolete)

Moving the handling of GUI events outside of your project code, and into Lua scripts can add a great deal of flexibilty to your interface. Simple GUI related stuff can be easily prototyped, and modified during testing.

Event handlers in Lua are just regular Lua functions that take one parameter. An CEGUI::EventArgs struct. The functions you register as event handlers must already be registered with the system, so unless you load them all from your init-script, you will need to load some script files before doing any Lua handled events.

Here we go...


Loading the script files

There are two ways of loading your script files. You can use the C++ interface or you can do it from Lua in your init-script. The two approaches are very alike, as the Lua version uses a direct binding to the same C++ function.

 CEGUI::System::executeScriptFile(const CEGUI::String& filename, const CEGUI::String& resourceGroup = "");

Obviously this function takes two parameters, a filename and the resource group. I think most people ignore the last parameter pretty much.

Calling this function with the Lua scripting module correctly attached to CEGUI, will execute the specified Lua script file. This means that functions etc. declared within these files will be accessible to your program, except of course if they are declared local.

So. From C++ you would do something like this:

 CEGUI::System::getSingleton().executeScriptFile("../datafiles/scripts/guiscript.lua");

If anything goes wrong an exception is thrown.

From Lua you could use this code:

 CEGUI.System:getSingleton():executeScriptFile("../datafiles/scripts/guiscript.lua")

any global code in these script files will also be executed so be sure to manage each execution if necessary (with a counter fx).

Registering Events to Lua Functions

Now that we have our scripts loaded and all, we are ready to bind some events to our scripted handlers.

The function to use when binding scripted events is a little different from the regular C++ one.

Event::Connection subscribeScriptedEvent(const String& name, const String& subscriber_name);

name is the name of the event you want to subscribe. As usual. subscriber_name is a string holding the name of the Lua function to bind to the event.

After this call the Lua function specified will be registered as the event handler. And works exactly like the C++ version (except being Lua of course)

Here's a little snippet to bind a PushButton Clicked event to a Lua function:

 CEGUI::PushButton* pb = (CEGUI::PushButton*)CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/Button","lua_powered_button");
 pb->setSize(CEGUI::Size(0.1f,0.1f));
 pb->setPosition(CEGUI::Point(0.1f,0.1f));
 pb->subscribeScriptedEvent("Clicked","luabtn_clicked");
 CEGUI::System::getSingleton().getGUISheet()->addChildWindow(pb);

This code would create a simple TaharezLook button, subscribe the Lua function luabtn_clicked to its Clicked event, and finally add it to the current GUI sheet.

Now let's take a look at that Lua event handler:

 function luabtn_clicked(e)
   local we = CEGUI.toWindowEventArgs(e)
   we.window:setText("handled from Lua");
 end

Here we make sure the button text is handled from Lua when the button is clicked. We use a utility function:

 CEGUI.toWindowEventArgs(e)

it's obvious what it does, and converters for the other EventArgs class are also available.

Registering Lua Event Handlers from XML Layouts

It's very easy to bind scripted event handlers to the windows in your XML layouts.

Take a look a this example:

 <?xml version="1.0"?>
 <GUILayout>
 <Window Type="TaharezLook/Button" Name="lua_powered_button">
 <Property Name="Width" Value="0.1" />
 <Property Name="Height" Value="0.1" />
 <Property Name="XPosition" Value="0.1" />
 <Property Name="YPosition" Value="0.1" />
 <Event Name="Clicked" Function="luabtn_clicked" />
 </Window>
 </GUILayout>

This simple layout create the same button as described above and even bind the scripted event handler to it.


now you know how to do stuff with your GUI without writing C++ code.

--User:Lindquist 17:10, 6 May 2005 (BST)