[gtkmm] Gtk::Container: Improve some vfuncs



commit 40f1e8f9ee914b0c2a6fcf433e85a96d7280f94e
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Fri Dec 30 14:35:53 2016 +0100

    Gtk::Container: Improve some vfuncs
    
    Let forall_vfunc() take a sigc::slot instead of a function pointer.
    Let get_child_property_vfunc() and set_child_property_vfunc() take
    Gtk::Widget* and Glib::ValueBase& instead of GtkWidget* and GValue*.
    Add get_path_for_child_vfunc(). Bug 670204

 gtk/src/container.ccg   |   56 +++++++++++++++++++++++++++++++++++++++++++++++
 gtk/src/container.hg    |   45 ++++++++++++++++++++++---------------
 gtk/src/gtk_vfuncs.defs |   17 ++++++-------
 3 files changed, 91 insertions(+), 27 deletions(-)
---
diff --git a/gtk/src/container.ccg b/gtk/src/container.ccg
index 2546c16..c705d35 100644
--- a/gtk/src/container.ccg
+++ b/gtk/src/container.ccg
@@ -167,6 +167,62 @@ void Container_Class::remove_callback(GtkContainer* self, GtkWidget* p0)
   }
 }
 
+// Custom hand-coded callback:
+void Container_Class::forall_vfunc_callback(GtkContainer* self,
+  gboolean include_internals, GtkCallback callback, gpointer callback_data)
+{
+  const auto obj_base = static_cast<Glib::ObjectBase*>(
+      Glib::ObjectBase::_get_current_wrapper((GObject*)self));
+
+  // Non-gtkmmproc-generated custom classes implicitly call the default
+  // Glib::ObjectBase constructor, which sets is_derived_. But gtkmmproc-
+  // generated classes can use this optimisation, which avoids the unnecessary
+  // parameter conversions if there is no possibility of the virtual function
+  // being overridden:
+  if(obj_base && obj_base->is_derived_())
+  {
+    const auto obj = dynamic_cast<CppObjectType* const>(obj_base);
+    if(obj) // This can be NULL during destruction.
+    {
+      try // Trap C++ exceptions which would normally be lost because this is a C callback.
+      {
+        if (callback == &container_foreach_callback)
+        {
+          // This call comes from Container::forall() or Container::foreach(),
+          // or is a recursive call. Don't create another slot layer.
+          // callback_data is a pointer to a Container::ForeachSlot.
+          const auto slot = static_cast<Container::ForeachSlot*>(callback_data);
+
+          // Call the virtual member method, which derived classes might override.
+          obj->forall_vfunc(include_internals, *slot);
+        }
+        else
+        {
+          // A slot that, when called, will call the callback function with the callback_data.
+          Container::ForeachSlot slot = [callback, callback_data](Widget& widget)
+                                        { callback(widget.gobj(), callback_data); };
+
+          // Call the virtual member method, which derived classes might override.
+          obj->forall_vfunc(include_internals, slot);
+        }
+        return;
+      }
+      catch(...)
+      {
+        Glib::exception_handlers_invoke();
+      }
+    }
+  }
+
+  BaseClassType *const base = static_cast<BaseClassType*>(
+      g_type_class_peek_parent(G_OBJECT_GET_CLASS(self)) // Get the parent class of the object class (The 
original underlying C class).
+  );
+
+  // Call the original underlying C function:
+  if(base && base->forall)
+    (*base->forall)(self, include_internals, callback, callback_data);
+}
+
 void Container::foreach(const Container::ForeachSlot& slot)
 {
   ForeachSlot slot_copy (slot);
diff --git a/gtk/src/container.hg b/gtk/src/container.hg
index 633b03a..47436ee 100644
--- a/gtk/src/container.hg
+++ b/gtk/src/container.hg
@@ -27,11 +27,6 @@ _PINCLUDE(gtkmm/private/widget_p.h)
  * These widgets can be used to group other widgets together.
  */
 
-/* we'll include gtkfeatures because we dont want to include the whole
-   gtk/gtk.h - this file is used by almost ALL our widgets, so dependencies
-   in minimum - adding things here will increase compile times ALOT */
-
-
 namespace Gtk
 {
 
@@ -81,10 +76,10 @@ public:
   /// Request that contained widgets check their size
   _WRAP_METHOD(void check_resize(), gtk_container_check_resize)
 
-  /** For instance,
-   * void on_foreach(Gtk::Widget* widget);
+  /** For instance,<br>
+   * void on_foreach(Gtk::Widget& widget);
    */
-  typedef sigc::slot<void(Widget&)> ForeachSlot;
+  using ForeachSlot = sigc::slot<void(Widget&)>;
 
   /** Operate on contained items.
    *
@@ -156,6 +151,8 @@ public:
 
   _WRAP_METHOD(GType child_type() const, gtk_container_child_type)
 
+  // gtk_container_get_path_for_child() returns a newly created GtkWidgetPath.
+#m4 _CONVERSION(`GtkWidgetPath*',`WidgetPath',`Glib::wrap($3, false)')
   _WRAP_METHOD(WidgetPath get_path_for_child(const Widget& child) const, gtk_container_get_path_for_child)
 
   // Ignore functions such as gtk_container_class_install_child_property(),  which I think are for themes, 
like the GtkWidget style properties.
@@ -193,10 +190,10 @@ protected:
    * Most applications should use foreach(), rather than forall().
    *
    * @param include_internals
-   * @param callback A callback.
-   * @param callback_data Callback user data
+   * @param slot A slot to call for each child.
    */
-  _WRAP_VFUNC(void forall(gboolean include_internals, GtkCallback callback, gpointer callback_data), forall)
+  _WRAP_VFUNC(void forall(bool include_internals, const ForeachSlot& slot{callback}), forall,
+    custom_vfunc_callback, slot_name slot, slot_callback container_foreach_callback, no_slot_copy)
 
   /** Sets a child property for this container and its child.
    *
@@ -205,13 +202,15 @@ protected:
    * examples of child properties are the position or pack-type of a widget
    * which is contained in a Gtk::Box.
    *
-   * @param child The child property.
+   * @param child The child widget.
    * @param property_id The ID of the child property to set.
    * @param value The new value for the child property.
-   * @param pspec
+   * @param pspec The GParamSpec of the child property to set.
    */
-  _WRAP_VFUNC(void set_child_property(GtkWidget* child, guint property_id, const GValue* value, GParamSpec* 
pspec), set_child_property)
+  _WRAP_VFUNC(void set_child_property(Widget* child, guint property_id,
+    const Glib::ValueBase& value, GParamSpec* pspec), set_child_property)
 
+#m4 _CONVERSION(`const Widget*', `GtkWidget*', `const_cast<$2>(Glib::unwrap($3))')
   /** Returns a child property for this container and its child.
    *
    * Child  properties are object properties that are not specific to either the
@@ -219,12 +218,22 @@ protected:
    * examples of child properties are the position or pack-type of a widget
    * which is contained in a Gtk::Box.
    *
-   * @param child The child property.
+   * @param child The child widget.
    * @param property_id The ID of the child property to get.
-   * @param value A GValue to fill with the child property's value.
-   * @param pspec
+   * @param value A Glib::Value to fill with the child property's value.
+   * @param pspec The GParamSpec of the child property to get.
+   */
+  _WRAP_VFUNC(void get_child_property(const Widget* child, guint property_id,
+    Glib::ValueBase& value, GParamSpec* pspec) const, get_child_property)
+
+#m4 _CONVERSION(`WidgetPath', `GtkWidgetPath*', __FR2P)
+  /** Returns a widget path representing all the widget hierarchy
+   * from the toplevel down to and including @a child.
+   *
+   * @param child The child widget.
+   * @return The WidgetPath of @a child.
    */
-  _WRAP_VFUNC(void get_child_property(GtkWidget* child, guint property_id, GValue* value, GParamSpec* pspec) 
const, get_child_property)
+  _WRAP_VFUNC(WidgetPath get_path_for_child(const Widget* child) const, get_path_for_child, refreturn_ctype)
 
 #m4begin
 dnl// Hook in special code to catch explicit uses of gtk_object_destroy() by
diff --git a/gtk/src/gtk_vfuncs.defs b/gtk/src/gtk_vfuncs.defs
index 3c6e396..48860b9 100644
--- a/gtk/src/gtk_vfuncs.defs
+++ b/gtk/src/gtk_vfuncs.defs
@@ -279,7 +279,6 @@
   (return-type "GType")
 )
 
-
 (define-vfunc forall
   (of-object "GtkContainer")
   (return-type "none")
@@ -290,14 +289,6 @@
    )
 )
 
-(define-vfunc composite_name
-  (of-object "GtkContainer")
-  (return-type "gchar*")
-  (parameters
-    '("GtkWidget*" "child")
-  )
-)
-
 (define-vfunc set_child_property
   (of-object "GtkContainer")
   (return-type "none")
@@ -320,6 +311,14 @@
   )
 )
 
+(define-vfunc get_path_for_child
+  (of-object "GtkContainer")
+  (return-type "GtkWidgetPath*")
+  (parameters
+    '("GtkWidget*" "child")
+  )
+)
+
 ; GtkEditable
 
 (define-vfunc do_insert_text


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