libglademm and signal autoconnect



Hi.

Recently I've started to try out
libglademm, and it seems that the signal
autoconnect feature is not implemented.
I think the reason is the impossibility
of properly implementing a symbolic lookup.
If this is the case, I think there are
a few workarounds to try.
For example, the attached hack allows
to get the handlers by names. I understand
that its nothing more than a hack right
now, but it can be improved. My question
is whether or not such a things are acceptable
for libglademm at all. Were such a workarounds
considered ever before, and if so, what
were the results? What people do think
about an approach of the attached hack?
The patch also changes an example code
to use that trick, so that people can see
right away what it does (well, it does
nearly nothing right now though :)
Index: libglade/src/xml.hg
===================================================================
--- libglade/src/xml.hg	(revision 2071)
+++ libglade/src/xml.hg	(working copy)
@@ -44,6 +44,50 @@
 };
 
 
+#define _STR(x) #x
+#define STR(x) _STR(x)
+#define GLADEMM_SLOT(n, s) \
+    slot_map[STR(s)] = sigc::mem_fun(this, &n::s)
+
+#define GLADEMM_DECLARE_SLOTS(...) \
+virtual void __init_slots(void) \
+{ \
+    __VA_ARGS__; \
+}
+
+class NoSlotException : public std::exception
+{
+public:
+  NoSlotException(const Glib::ustring& name) { str = name; }
+  virtual ~NoSlotException(void) throw() {}
+  virtual const char* what() const throw()
+  {
+    return str.c_str();
+  }
+
+protected:
+  Glib::ustring str;
+};
+
+class Slots : public Glib::Object
+{
+public:
+  const sigc::slot<void> get_slot(const Glib::ustring name)
+  {
+    if (slot_map.empty())
+	__init_slots();
+    std::map<Glib::ustring, sigc::slot<void> >::iterator it =
+	    slot_map.find(name);
+    if (it == slot_map.end())
+	throw NoSlotException(name);
+    return it->second;
+  }
+
+protected:
+  virtual void __init_slots(void) = 0;
+  std::map<Glib::ustring, sigc::slot<void> > slot_map;
+};
+
 class Xml : public Glib::Object
 {
   _CLASS_GOBJECT(Xml, GladeXML, GLADE_XML, Glib::Object, GObject)
@@ -276,7 +320,10 @@
    */
   void connect_clicked(const Glib::ustring& name, const sigc::slot<void>& slot_);
 
+  void autoconnect_clicked(const Glib::ustring& name,
+	const Slots& slots_);
 
+
 ///* interface for changing the custom widget handling */
 //typedef GtkWidget *(* GladeXMLCustomWidgetHandler) (GladeXML *xml,
 //						    gchar *func_name,
Index: examples/basic/basic.cc
===================================================================
--- examples/basic/basic.cc	(revision 2071)
+++ examples/basic/basic.cc	(working copy)
@@ -4,15 +4,25 @@
 
 Gtk::Dialog* pDialog = 0;
 
+class MySlots : public Gnome::Glade::Slots
+{
+private:
+GLADEMM_DECLARE_SLOTS(
+  GLADEMM_SLOT(MySlots, on_button_clicked)
+);
+
 void on_button_clicked()
 {
   if(pDialog)
     pDialog->hide(); //hide() will cause main::run() to end.
 }
 
+};
+
 int main (int argc, char **argv)
 {
   Gtk::Main kit(argc, argv);
+  MySlots slots;
 
   //Load the Glade file and instiate its widgets:
   Glib::RefPtr<Gnome::Glade::Xml> refXml;
@@ -41,14 +51,7 @@
   refXml->get_widget("DialogBasic", pDialog);
   if(pDialog)
   {
-    //Get the Glade-instantiated Button, and connect a signal handler:
-    Gtk::Button* pButton = 0;
-    refXml->get_widget("quit_button", pButton);
-    if(pButton)
-    {
-      pButton->signal_clicked().connect( sigc::ptr_fun(on_button_clicked) );
-    }
-
+    refXml->connect_clicked("quit_button", slots.get_slot("on_button_clicked"));
     kit.run(*pDialog);
   }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]