Re: Implementing event handler for objects
Daniel Wallin <[email protected]>
| Newsgroups | gmane.comp.lang.lua.bind.user |
|---|---|
| Message-ID | <[email protected]> |
On Wed, Apr 6, 2011 at 6:05 PM, Jonatan Magnusson <[email protected]> wrote: > Hi > > I'm wrapping a GUI toolkit using Luabind, and i've struck upon a problem > with handling events. > > The GUI-toolkit I'm wrapping is wxWidgets. Every widget inherits > wxEvtHandler and that > class has a method called Bind() that is used to connect events to an > event handler. A stupid example: > > class MyClass { > void init () > { > b = wxButton (frm, -1, "Some button"); > b->Bind (wxEVT_COMMAND_BUTTON_CLICKED, > &MyClass::HandleButtonClick, this); > } > > void HandleButtonClick (wxCommandEvent& ev) > { > printf ("Button clicked.\n"); > } > } > > My dream API for this in Lua would be: > > b = wx.Button (frm, -1, "Some button") > b.on_click = function () > print ("Button clicked.\n") > end This should be possible by doing something like: template <unsigned Event> void bind_wx_event( luabind::object const& self, luabind::object const& handler) { luabind::object_cast<wxEvtHandler*>(self)->Bind(handler, self); } void no_read(wxEvtHandler&) { throw std::runtime_error("can't read"); } ... class_<wxEvtHandler>("wxEvtHandler"); class_<wxButton, wxEvtHandler>(wxButton) .property("on_click", no_read, bind_wx_event<wxEVT_COMMAND_BUTTON_CLICKED>); The easiest way to make that less repetitive would be to just use a macro for it: #define EVT_PROPERTY(name, id) property(#name, no_read, bind_wx_event<id>) > Or, even better: > > b.on_click:add (function () > print ("Button clicked, with multiple event handlers.\n") > end That would be possible in the same way, but you'd need to return a proxy object from the property accessor. > I guess I could live with something like this, which is more like the > C++ API: > > b.bind (wx.EVT_COMMAND_BUTTON_CLICKED, function (ev) > print ("Button clicked again...\n") > end) I'm not sure if it helps any in this case, but it is also possible to extend the exported classes from Lua. So for instance, if you have the above API and want to make it better, you should be able to do something like: function no_read() error("can't read") end wxButton.on_read = property(no_read, function(self, handler) self:Bind(wx.EVT_COMMAND_BUTTON_CLICKED, handler) end) this can be helpful since it's easier to automate these kinds of things in Lua. Does any of this help? -- Daniel Wallin BoostPro Computing http://www.boostpro.com ------------------------------------------------------------------------------ Xperia(TM) PLAY It's a major breakthrough. An authentic gaming smartphone on the nation's most reliable network. And it wants your games. http://p.sf.net/sfu/verizon-sfdev