Re: libglademm signal_connect?
- From: leyland needham <leyland gmail com>
- To: gtkmm <gtkmm-list gnome org>
- Subject: Re: libglademm signal_connect?
- Date: Sat, 1 Jan 2005 17:15:45 -0800
On Sat, 1 Jan 2005 13:33:04 -0800, leyland needham <leyland gmail com> wrote:
> I checked out the latest cvs of it and this seems like a (shorter)
> replacement for this :
>
> Gtk::MenuItem* pMenuItem = 0;
> refXml->get_widget("menuitem5", pMenuItem);
> if(pMenuItem)
> pMenuItem->signal_activate().connect(sigc::ptr_fun(&on_button_clicked));
>
> Which is what I kind of didn't want to do. I was hoping for something
> that would use the handler name, and not the widget name. There by any
> place in the gladexml you use the handler name it would attach my
> callback. Or even something that would do autoconnects, although glade
> doesn't support objects in every place you can have a handler (like
> for menus), so you couldn't just attach handlers from an object I
> create.
>
> My personal preference is to only derive from widgets when needed, so
> I prefer to use connect methods, but I would also like to abstract
> more from the contents of the glade file so users can make custom
> interfaces, and all they have to know is what handlers my program
> provides/attachs to the glade interface.
>
> On Sat, 01 Jan 2005 10:25:59 +0100, Alberto Paro
> <alberto paro homeunix org> wrote:
> > Il giorno sab, 01-01-2005 alle 00:16 -0800, leyland needham ha scritto:
> > > Like instead of having to get the widget and signal connect it
> > > yourself, do something like this :
> > > GladeXml->signal_connect( "HandlerName", ptr_fun(&my_signal_handler));
> > > GladeXml->signal_connect( "Handler2Name", mem_fun(foo,&CFoo::bar));
> > >
> > > Would this be out of scope for the libglade wrapper?
> > In libglademm cvs there is connect_clicked()
> >
> > Usage from VariablesMap example:
> >
> > //Connect button's signal handler:
> > //Glade::Xml::connect_clicked() is a convenience method, which has
> > nothing to do with the VariablesMap.
> > m_refGlade->connect_clicked("button", sigc::mem_fun(*this,
> > &ExampleWindow::on_button_clicked));
> > m_refGlade->connect_clicked("file_new", sigc::mem_fun(*this,
> > &ExampleWindow::on_file_new));
> > m_refGlade->connect_clicked("file_exit", sigc::mem_fun(*this,
> > &ExampleWindow::on_file_exit));
> > m_refGlade->connect_clicked("help_info", sigc::mem_fun(*this,
> > &ExampleWindow::on_info));
> >
> > Hi,
> > Alberto
> >
> >
>
I've created my own version of a signal_connect function, that works
more the way I wanted it to, in case any one is interested in using
it, or if any one wants to look into integrating this into libglademm.
This is probably a big hack and I am not sure how safe it is (hasn't
crashed on me in my tests), most of it is hacked from the glibmm and
gtkmm in they handle signals. I tried using glibmm directly but it
wasn't working because it is designed to work with associated
wrappers, and I think glade widgets only get wrapped when you call
get_widget on them.
The main function to call is
void signal_connect(Glib::RefPtr<Gnome::Glade::Xml> refXml,
const Glib::ustring& handlername,
const sigc::slot<void> &slot);
An example is :
signal_connect(refXml, "OnQuitHandler", sigc::ptr_fun(&on_quit_handler));
The code for it is here :
#include <gtkmm.h>
#include <libglademm.h>
#include <glade/glade.h>
typedef struct {
const sigc::slot_base *slot;
} connect_data_data;
static void
slot0_void_callback(GObject* self, void* data)
{
// Do not try to call a signal on a disassociated wrapper.
//if(Glib::ObjectBase::_get_current_wrapper(self))
{
try
{
if(sigc::slot_base *const slot = static_cast<sigc::slot_base*>(data))
(*static_cast<sigc::slot<void>*>(slot))();
}
catch(...)
{
Glib::exception_handlers_invoke();
}
}
}
static void
destroy_notify_handler(gpointer data, GClosure*)
{
//glib calls this when it has finished with a glib signal connection,
//either when the emitting object dies, or when the connection has
been disconnected.
// notification from gtk+.
sigc::slot_base *slot = static_cast<sigc::slot_base*>(data);
if(slot)
delete slot; // if there are connection objects referring to slot_
they are notified during destruction of slot_
}
static void
connect_data_connect_func(const gchar *handler_name, GObject *object,
const gchar *signal_name, const gchar *signal_data,
GObject *connect_object, gboolean after,
gpointer user_data)
{
const sigc::slot_base *slot = ((connect_data_data *)user_data)->slot;
if (connect_object) {
// don't know what to do about this
// g_signal_connect_object(object, signal_name, data->func,
// connect_object, (after ? G_CONNECT_AFTER : 0) | G_CONNECT_SWAPPED);
} else {
// Glib::SignalProxyConnectionNode *const pConnectionNode =
// new Glib::SignalProxyConnectionNode(*slot, object);
// connect it to glib
// pConnectionNode will be passed in the data argument to the callback.
// pConnectionNode->connection_id_ = g_signal_connect_data(
// object, signal_name,
// (GCallback)&Glib::SignalProxyNormal::slot0_void_callback,
// pConnectionNode,
// &Glib::SignalProxyConnectionNode::destroy_notify_handler,
// static_cast<GConnectFlags>((after) ? G_CONNECT_AFTER : 0));
sigc::slot_base *slot_ = new sigc::slot_base(*slot);
g_signal_connect_data( object, signal_name,
(GCallback)&slot0_void_callback,
slot_,
destroy_notify_handler,
static_cast<GConnectFlags>((after) ? G_CONNECT_AFTER : 0));
g_print("%s %s\n", handler_name, signal_name);
}
}
void signal_connect(Glib::RefPtr<Gnome::Glade::Xml> refXml,
const Glib::ustring& handlername,
const sigc::slot<void> &slot)
{
connect_data_data data;
data.slot = &slot;
glade_xml_signal_connect_full(refXml->gobj(), handlername.c_str(),
connect_data_connect_func, &data);
}
This all can be improved by maybe having a list of handlers, and then
passing it to each gladexml when you load an glade interface.
Lee
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]