[gtk+/overlay] overlay: derive from GtkBin



commit c42999eccf6f006b14ed0d8cafa31f15ebb6a4aa
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Jun 10 23:23:33 2011 -0400

    overlay: derive from GtkBin

 gtk/gtkoverlay.c |  173 +++++++++++++++++++++++-------------------------------
 gtk/gtkoverlay.h |   37 ++++++------
 2 files changed, 92 insertions(+), 118 deletions(-)
---
diff --git a/gtk/gtkoverlay.c b/gtk/gtkoverlay.c
index bf13560..996f4bd 100644
--- a/gtk/gtkoverlay.c
+++ b/gtk/gtkoverlay.c
@@ -30,7 +30,6 @@
 
 struct _GtkOverlayPrivate
 {
-  GtkWidget *main_widget;
   GtkWidget *relative_widget;
   GSList    *children;
 };
@@ -60,7 +59,7 @@ enum
 
 static void gtk_overlay_buildable_init (GtkBuildableIface *iface);
 
-G_DEFINE_TYPE_WITH_CODE (GtkOverlay, gtk_overlay, GTK_TYPE_CONTAINER,
+G_DEFINE_TYPE_WITH_CODE (GtkOverlay, gtk_overlay, GTK_TYPE_BIN,
                          G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
                                                 gtk_overlay_buildable_init))
 
@@ -133,12 +132,6 @@ gtk_overlay_create_child_window (GtkOverlay *overlay,
 }
 
 static void
-gtk_overlay_dispose (GObject *object)
-{
-  G_OBJECT_CLASS (gtk_overlay_parent_class)->dispose (object);
-}
-
-static void
 gtk_overlay_get_property (GObject    *object,
                           guint       prop_id,
                           GValue     *value,
@@ -172,12 +165,14 @@ gtk_overlay_set_property (GObject      *object,
     case PROP_RELATIVE_WIDGET:
       {
         GtkWidget *relative_widget;
+        GtkWidget *main_widget;
 
         relative_widget = g_value_get_object (value);
 
-        if (priv->main_widget != NULL &&
+        main_widget = gtk_bin_get_child (GTK_BIN (object));
+        if (main_widget != NULL &&
             relative_widget != NULL &&
-            !gtk_widget_is_ancestor (relative_widget, priv->main_widget))
+            !gtk_widget_is_ancestor (relative_widget, main_widget))
           {
             g_warning ("relative_widget must be a child of the main widget");
             break;
@@ -193,34 +188,6 @@ gtk_overlay_set_property (GObject      *object,
 }
 
 static void
-gtk_overlay_get_preferred_width (GtkWidget *widget,
-                                 gint      *minimum,
-                                 gint      *natural)
-{
-  GtkOverlayPrivate *priv = GTK_OVERLAY (widget)->priv;
-
-  *minimum = 0;
-  *natural = 0;
-
-  if (priv->main_widget)
-    gtk_widget_get_preferred_width (priv->main_widget, minimum, natural);
-}
-
-static void
-gtk_overlay_get_preferred_height (GtkWidget *widget,
-                                  gint      *minimum,
-                                  gint      *natural)
-{
-  GtkOverlayPrivate *priv = GTK_OVERLAY (widget)->priv;
-
-  *minimum = 0;
-  *natural = 0;
-
-  if (priv->main_widget)
-    gtk_widget_get_preferred_height (priv->main_widget, minimum, natural);
-}
-
-static void
 gtk_overlay_child_allocate (GtkWidget           *child,
                             GdkWindow           *child_window, /* can be NULL */
                             const GtkAllocation *window_allocation,
@@ -250,6 +217,44 @@ effective_align (GtkAlign         align,
 }
 
 static void
+gtk_overlay_get_preferred_width (GtkWidget *widget,
+                                 gint      *minimum,
+                                 gint      *natural)
+{
+  GtkBin *bin = GTK_BIN (widget);
+  GtkWidget *child;
+
+  if (minimum)
+    *minimum = 0;
+
+  if (natural)
+    *natural = 0;
+
+  child = gtk_bin_get_child (bin);
+  if (child && gtk_widget_get_visible (child))
+    gtk_widget_get_preferred_width (child, minimum, natural);
+}
+
+static void
+gtk_overlay_get_preferred_height (GtkWidget *widget,
+                                  gint      *minimum,
+                                  gint      *natural)
+{
+  GtkBin *bin = GTK_BIN (widget);
+  GtkWidget *child;
+
+  if (minimum)
+    *minimum = 0;
+
+  if (natural)
+    *natural = 0;
+
+  child = gtk_bin_get_child (bin);
+  if (child && gtk_widget_get_visible (child))
+    gtk_widget_get_preferred_height (child, minimum, natural);
+}
+
+static void
 gtk_overlay_size_allocate (GtkWidget     *widget,
                            GtkAllocation *allocation)
 {
@@ -258,20 +263,22 @@ gtk_overlay_size_allocate (GtkWidget     *widget,
   GtkOverlayChild *child;
   GtkAllocation main_alloc;
   GSList *children;
+  GtkWidget *main_widget;
 
   GTK_WIDGET_CLASS (gtk_overlay_parent_class)->size_allocate (widget, allocation);
 
-  if (priv->main_widget == NULL)
+  main_widget = gtk_bin_get_child (GTK_BIN (widget));
+  if (main_widget == NULL)
     return;
 
-  gtk_widget_size_allocate (priv->main_widget, allocation);
+  gtk_widget_size_allocate (main_widget, allocation);
 
   /* if a relative widget exists place the floating widgets in relation to it */
   if (priv->relative_widget)
     {
       gint x, y;
 
-      gtk_widget_translate_coordinates (priv->relative_widget, priv->main_widget, 0, 0, &x, &y);
+      gtk_widget_translate_coordinates (priv->relative_widget, main_widget, 0, 0, &x, &y);
       main_alloc.x = allocation->x + x;
       main_alloc.y = allocation->y + y;
       main_alloc.width = gtk_widget_get_allocated_width (priv->relative_widget);
@@ -294,8 +301,7 @@ gtk_overlay_size_allocate (GtkWidget     *widget,
 
       child = children->data;
 
-      if (child->widget == priv->main_widget ||
-          !gtk_widget_get_visible (child->widget))
+      if (!gtk_widget_get_visible (child->widget))
         continue;
 
       gtk_widget_get_preferred_size (child->widget, NULL, &req);
@@ -371,9 +377,7 @@ gtk_overlay_realize (GtkWidget *widget)
     {
       child = children->data;
 
-      if (child->widget == priv->main_widget)
-        child->window = gtk_widget_get_window (priv->main_widget);
-      else if (child->window == NULL)
+      if (child->window == NULL)
         child->window = gtk_overlay_create_child_window (overlay, child->widget);
     }
 }
@@ -390,17 +394,10 @@ gtk_overlay_unrealize (GtkWidget *widget)
     {
       child = children->data;
 
-      if (child->widget == priv->main_widget)
-        {
-          child->window = NULL;
-        }
-      else
-        {
-          gtk_widget_set_parent_window (child->widget, NULL);
-          gdk_window_set_user_data (child->window, NULL);
-          gdk_window_destroy (child->window);
-          child->window = NULL;
-        }
+      gtk_widget_set_parent_window (child->widget, NULL);
+      gdk_window_set_user_data (child->window, NULL);
+      gdk_window_destroy (child->window);
+      child->window = NULL;
     }
 
   GTK_WIDGET_CLASS (gtk_overlay_parent_class)->unrealize (widget);
@@ -460,9 +457,6 @@ gtk_overlay_draw (GtkWidget *widget,
     {
       child = children->data;
 
-      if (child->widget == priv->main_widget)
-        continue;
-
       if (gtk_cairo_should_draw_window (cr, child->window))
         {
           cairo_save (cr);
@@ -487,26 +481,17 @@ overlay_add (GtkContainer *container,
 {
   GtkOverlay *overlay = GTK_OVERLAY (container);
   GtkOverlayPrivate *priv = overlay->priv;
+  GtkWidget *main_widget;
 
-  if (priv->main_widget != NULL)
-    {
-      g_warning ("Attempting to add a widget with type %s to a %s, "
-                 "but as a GtkOverlay subclass a %s can only contain one main widget at a time; "
-                 "it already contains a widget of type %s",
-                 g_type_name (G_OBJECT_TYPE (widget)),
-                 g_type_name (G_OBJECT_TYPE (container)),
-                 g_type_name (G_OBJECT_TYPE (container)),
-                 g_type_name (G_OBJECT_TYPE (priv->main_widget)));
-      return;
-    }
-
-  priv->main_widget = widget;
-  add_child (overlay, widget);
+  GTK_CONTAINER_CLASS (gtk_overlay_parent_class)->add (container, widget);
 
-  /* if we have a previously added relative widget we must check that it is
-     still valid */
-  if (priv->relative_widget != NULL &&
-      !gtk_widget_is_ancestor (priv->relative_widget, priv->main_widget))
+  /* if we have a previously added relative widget, we must
+   * check that it is still valid
+   */
+  main_widget = gtk_bin_get_child (GTK_BIN (container));
+  if (main_widget != NULL &&
+      priv->relative_widget != NULL &&
+      !gtk_widget_is_ancestor (priv->relative_widget, main_widget))
     {
       g_warning ("The previously relative widget with type %s is not compatible "
                  "with the new main widget added %s, the relative widget will "
@@ -518,10 +503,10 @@ overlay_add (GtkContainer *container,
 }
 
 static void
-gtk_overlay_remove (GtkContainer *overlay,
+gtk_overlay_remove (GtkContainer *container,
                     GtkWidget    *widget)
 {
-  GtkOverlayPrivate *priv = GTK_OVERLAY (overlay)->priv;
+  GtkOverlayPrivate *priv = GTK_OVERLAY (container)->priv;
   GtkOverlayChild *child;
   GSList *children;
 
@@ -531,23 +516,22 @@ gtk_overlay_remove (GtkContainer *overlay,
 
       if (child->widget == widget)
         {
-          if (child->window != NULL && child->widget != priv->main_widget)
+          if (child->window != NULL)
             {
               gdk_window_set_user_data (child->window, NULL);
               gdk_window_destroy (child->window);
             }
 
-          if (widget == priv->main_widget)
-            priv->main_widget = NULL;
-
           gtk_widget_unparent (widget);
 
           priv->children = g_slist_delete_link (priv->children, children);
           g_slice_free (GtkOverlayChild, child);
 
-          break;
+          return;
         }
     }
+
+  GTK_CONTAINER_CLASS (gtk_overlay_parent_class)->remove (container, widget);
 }
 
 static void
@@ -559,9 +543,13 @@ gtk_overlay_forall (GtkContainer *overlay,
   GtkOverlayPrivate *priv = GTK_OVERLAY (overlay)->priv;
   GtkOverlayChild *child;
   GSList *children;
+  GtkWidget *main_widget;
 
-  children = priv->children;
+  main_widget = gtk_bin_get_child (GTK_BIN (overlay));
+  if (main_widget)
+    (* callback) (main_widget, callback_data);
 
+  children = priv->children;
   while (children)
     {
       child = children->data;
@@ -571,17 +559,6 @@ gtk_overlay_forall (GtkContainer *overlay,
     }
 }
 
-static GType
-gtk_overlay_child_type (GtkContainer *overlay)
-{
-  GtkOverlayPrivate *priv = GTK_OVERLAY (overlay)->priv;
-
-  if (priv->main_widget != NULL)
-    return G_TYPE_NONE;
-  else
-    return GTK_TYPE_WIDGET;
-}
-
 static void
 gtk_overlay_set_offset_internal (GtkOverlay      *overlay,
                                  GtkOverlayChild *child,
@@ -675,7 +652,6 @@ gtk_overlay_class_init (GtkOverlayClass *klass)
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
   GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
 
-  object_class->dispose = gtk_overlay_dispose;
   object_class->get_property = gtk_overlay_get_property;
   object_class->set_property = gtk_overlay_set_property;
 
@@ -691,7 +667,6 @@ gtk_overlay_class_init (GtkOverlayClass *klass)
   container_class->add = overlay_add;
   container_class->remove = gtk_overlay_remove;
   container_class->forall = gtk_overlay_forall;
-  container_class->child_type = gtk_overlay_child_type;
   container_class->set_child_property = gtk_overlay_set_child_property;
   container_class->get_child_property = gtk_overlay_get_child_property;
 
diff --git a/gtk/gtkoverlay.h b/gtk/gtkoverlay.h
index b3a48c6..33c9681 100644
--- a/gtk/gtkoverlay.h
+++ b/gtk/gtkoverlay.h
@@ -27,7 +27,7 @@
 #ifndef __GTK_OVERLAY_H__
 #define __GTK_OVERLAY_H__
 
-#include <gtk/gtkcontainer.h>
+#include <gtk/gtkbin.h>
 
 G_BEGIN_DECLS
 
@@ -45,14 +45,14 @@ typedef struct _GtkOverlayPrivate  GtkOverlayPrivate;
 
 struct _GtkOverlay
 {
-  GtkContainer parent;
+  GtkBin parent;
 
   GtkOverlayPrivate *priv;
 };
 
 struct _GtkOverlayClass
 {
-  GtkContainerClass parent_class;
+  GtkBinClass parent_class;
 
   /* Padding for future expansion */
   void (*_gtk_reserved1) (void);
@@ -63,30 +63,29 @@ struct _GtkOverlayClass
   void (*_gtk_reserved6) (void);
   void (*_gtk_reserved7) (void);
   void (*_gtk_reserved8) (void);
-  void (*_gtk_reserved9) (void);
 };
 
-GType       gtk_overlay_get_type                 (void) G_GNUC_CONST;
+GType      gtk_overlay_get_type            (void) G_GNUC_CONST;
 
-GtkWidget  *gtk_overlay_new                      (void);
+GtkWidget *gtk_overlay_new                 (void);
 
-void        gtk_overlay_set_relative_widget      (GtkOverlay *overlay,
-                                                  GtkWidget  *relative_widget);
+void       gtk_overlay_set_relative_widget (GtkOverlay *overlay,
+                                            GtkWidget  *relative_widget);
 
-GtkWidget  *gtk_overlay_get_relative_widget      (GtkOverlay *overlay);
+GtkWidget *gtk_overlay_get_relative_widget (GtkOverlay *overlay);
 
-void        gtk_overlay_add                      (GtkOverlay *overlay,
-                                                  GtkWidget  *widget);
+void       gtk_overlay_add                 (GtkOverlay *overlay,
+                                            GtkWidget  *widget);
 
-void        gtk_overlay_set_offset               (GtkOverlay *overlay,
-                                                  GtkWidget  *widget,
-                                                  gint        x_offset,
-                                                  gint        y_offset);
+void       gtk_overlay_set_offset          (GtkOverlay *overlay,
+                                            GtkWidget  *widget,
+                                            gint        x_offset,
+                                            gint        y_offset);
 
-void        gtk_overlay_get_offset               (GtkOverlay *overlay,
-                                                  GtkWidget  *widget,
-                                                  gint       *x_offset,
-                                                  gint       *y_offset);
+void       gtk_overlay_get_offset          (GtkOverlay *overlay,
+                                            GtkWidget  *widget,
+                                            gint       *x_offset,
+                                            gint       *y_offset);
 
 G_END_DECLS
 



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