[epiphany] Import latest version of Gedit's overlay code.



commit 05d631cb9b95e3be827cbfbcdeb569834a967959
Author: Alexandre Mazari <amazari igalia com>
Date:   Mon Apr 18 18:30:58 2011 +0200

    Import latest version of Gedit's overlay code.

 lib/widgets/gedit-overlay-child.c |   71 ++++++++------
 lib/widgets/gedit-overlay.c       |  190 +++++++++++++++++++++++++------------
 lib/widgets/gedit-overlay.h       |    3 +
 3 files changed, 169 insertions(+), 95 deletions(-)
---
diff --git a/lib/widgets/gedit-overlay-child.c b/lib/widgets/gedit-overlay-child.c
index e30d6ed..7593fe1 100644
--- a/lib/widgets/gedit-overlay-child.c
+++ b/lib/widgets/gedit-overlay-child.c
@@ -23,7 +23,6 @@
 
 struct _GeditOverlayChildPrivate
 {
-	GtkWidget                *widget;
 	GBinding                 *binding;
 	GeditOverlayChildPosition position;
 	guint                     offset;
@@ -50,7 +49,7 @@ gedit_overlay_child_get_property (GObject    *object,
 	switch (prop_id)
 	{
 		case PROP_WIDGET:
-			g_value_set_object (value, child->priv->widget);
+			g_value_set_object (value, gtk_bin_get_child (GTK_BIN (child)));
 			break;
 		case PROP_POSITION:
 			g_value_set_uint (value, child->priv->position);
@@ -117,17 +116,29 @@ gedit_overlay_child_realize (GtkWidget *widget)
 }
 
 static void
-gedit_overlay_child_get_preferred_width (GtkWidget *widget,
-                                         gint      *minimum,
-                                         gint      *natural)
+gedit_overlay_child_get_size (GtkWidget     *widget,
+                              GtkOrientation orientation,
+                              gint          *minimum,
+                              gint          *natural)
 {
-	GeditOverlayChild *child = GEDIT_OVERLAY_CHILD (widget);
+	GeditOverlayChild *overlay_child = GEDIT_OVERLAY_CHILD (widget);
+	GtkWidget *child;
 	gint child_min = 0, child_nat = 0;
 
-	if (child->priv->widget != NULL)
+	child = gtk_bin_get_child (GTK_BIN (overlay_child));
+
+	if (child != NULL)
 	{
-		gtk_widget_get_preferred_width (child->priv->widget,
-		                                &child_min, &child_nat);
+		if (orientation == GTK_ORIENTATION_HORIZONTAL)
+		{
+			gtk_widget_get_preferred_width (child,
+			                                &child_min, &child_nat);
+		}
+		else
+		{
+			gtk_widget_get_preferred_height (child,
+			                                 &child_min, &child_nat);
+		}
 	}
 
 	*minimum = child_min;
@@ -135,28 +146,27 @@ gedit_overlay_child_get_preferred_width (GtkWidget *widget,
 }
 
 static void
+gedit_overlay_child_get_preferred_width (GtkWidget *widget,
+                                         gint      *minimum,
+                                         gint      *natural)
+{
+	gedit_overlay_child_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum, natural);
+}
+
+static void
 gedit_overlay_child_get_preferred_height (GtkWidget *widget,
                                           gint      *minimum,
                                           gint      *natural)
 {
-	GeditOverlayChild *child = GEDIT_OVERLAY_CHILD (widget);
-	gint child_min = 0, child_nat = 0;
-
-	if (child->priv->widget != NULL)
-	{
-		gtk_widget_get_preferred_height (child->priv->widget,
-		                                 &child_min, &child_nat);
-	}
-
-	*minimum = child_min;
-	*natural = child_nat;
+	gedit_overlay_child_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum, natural);
 }
 
 static void
 gedit_overlay_child_size_allocate (GtkWidget     *widget,
                                    GtkAllocation *allocation)
 {
-	GeditOverlayChild *child = GEDIT_OVERLAY_CHILD (widget);
+	GeditOverlayChild *overlay_child = GEDIT_OVERLAY_CHILD (widget);
+	GtkWidget *child;
 	GtkAllocation tmp;
 
 	tmp.width = allocation->width;
@@ -165,10 +175,11 @@ gedit_overlay_child_size_allocate (GtkWidget     *widget,
 
 	GTK_WIDGET_CLASS (gedit_overlay_child_parent_class)->size_allocate (widget, allocation);
 
-	if (child->priv->widget != NULL)
+	child = gtk_bin_get_child (GTK_BIN (overlay_child));
+
+	if (child != NULL)
 	{
-		gtk_widget_size_allocate (child->priv->widget,
-		                          &tmp);
+		gtk_widget_size_allocate (child, &tmp);
 	}
 }
 
@@ -176,13 +187,11 @@ static void
 gedit_overlay_child_add (GtkContainer *container,
                          GtkWidget    *widget)
 {
-	GeditOverlayChild *child = GEDIT_OVERLAY_CHILD (container);
+	GeditOverlayChild *overlay_child = GEDIT_OVERLAY_CHILD (container);
 
-	child->priv->widget = widget;
-
-	child->priv->binding = g_object_bind_property (G_OBJECT (widget), "visible",
-						       G_OBJECT (container), "visible",
-						       G_BINDING_BIDIRECTIONAL);
+	overlay_child->priv->binding = g_object_bind_property (G_OBJECT (widget), "visible",
+							       G_OBJECT (container), "visible",
+							       G_BINDING_BIDIRECTIONAL);
 
 	GTK_CONTAINER_CLASS (gedit_overlay_child_parent_class)->add (container, widget);
 }
@@ -193,8 +202,6 @@ gedit_overlay_child_remove (GtkContainer *container,
 {
 	GeditOverlayChild *child = GEDIT_OVERLAY_CHILD (container);
 
-	child->priv->widget = NULL;
-
 	g_object_unref (child->priv->binding);
 
 	GTK_CONTAINER_CLASS (gedit_overlay_child_parent_class)->remove (container, widget);
diff --git a/lib/widgets/gedit-overlay.c b/lib/widgets/gedit-overlay.c
index bad7825..28e1010 100644
--- a/lib/widgets/gedit-overlay.c
+++ b/lib/widgets/gedit-overlay.c
@@ -26,6 +26,12 @@
 
 #define GEDIT_OVERLAY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_OVERLAY, GeditOverlayPrivate))
 
+typedef struct
+{
+	GtkWidget *child;
+	GtkWidget *original;
+} ChildContainer;
+
 struct _GeditOverlayPrivate
 {
 	GtkWidget *main_widget;
@@ -42,14 +48,62 @@ enum
 
 G_DEFINE_TYPE (GeditOverlay, gedit_overlay, GTK_TYPE_CONTAINER)
 
+static ChildContainer *
+child_container_new (GtkWidget *child,
+                     GtkWidget *original)
+{
+	ChildContainer *ret;
+
+	ret = g_slice_new (ChildContainer);
+	ret->child = child;
+	ret->original = original;
+
+	return ret;
+}
+
+static void
+child_container_free (ChildContainer *container)
+{
+	g_slice_free (ChildContainer, container);
+}
+
+static GtkWidget *
+child_container_get_child (ChildContainer *container)
+{
+	GtkWidget *child;
+
+	if (container->child != NULL)
+	{
+		child = container->child;
+	}
+	else
+	{
+		child = container->original;
+	}
+
+	return child;
+}
+
 static void
 add_toplevel_widget (GeditOverlay *overlay,
-                     GtkWidget    *child)
+                     GtkWidget    *child,
+                     GtkWidget    *original)
 {
-	gtk_widget_set_parent (child, GTK_WIDGET (overlay));
+	ChildContainer *container;
+
+	if (child != NULL)
+	{
+		gtk_widget_set_parent (child, GTK_WIDGET (overlay));
+	}
+	else
+	{
+		gtk_widget_set_parent (original, GTK_WIDGET (overlay));
+	}
+
+	container = child_container_new (child, original);
 
 	overlay->priv->children = g_slist_append (overlay->priv->children,
-	                                          child);
+	                                          container);
 }
 
 static void
@@ -83,6 +137,27 @@ gedit_overlay_get_property (GObject    *object,
 	}
 }
 
+static GtkWidget *
+wrap_child_if_needed (GtkWidget *widget)
+{
+	GtkWidget *child;
+
+	if (GEDIT_IS_OVERLAY_CHILD (widget))
+	{
+		return widget;
+	}
+
+	child = GTK_WIDGET (gedit_overlay_child_new (widget));
+	gtk_widget_show (child);
+
+	g_signal_connect_swapped (widget,
+	                          "destroy",
+	                          G_CALLBACK (gtk_widget_destroy),
+	                          child);
+
+	return child;
+}
+
 static void
 gedit_overlay_set_property (GObject      *object,
                             guint         prop_id,
@@ -95,10 +170,14 @@ gedit_overlay_set_property (GObject      *object,
 	switch (prop_id)
 	{
 		case PROP_MAIN_WIDGET:
+		{
 			priv->main_widget = g_value_get_object (value);
-			add_toplevel_widget (overlay, priv->main_widget);
-			break;
 
+			add_toplevel_widget (overlay,
+			                     NULL,
+			                     priv->main_widget);
+			break;
+		}
 		case PROP_RELATIVE_WIDGET:
 			priv->relative_widget = g_value_get_object (value);
 			break;
@@ -132,7 +211,7 @@ gedit_overlay_realize (GtkWidget *widget)
 	attributes.event_mask = gtk_widget_get_events (widget);
 	attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
 
-	attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
+	attributes_mask = GDK_WA_X | GDK_WA_Y;
 
 	window = gdk_window_new (gtk_widget_get_parent_window (widget),
 	                         &attributes, attributes_mask);
@@ -203,15 +282,18 @@ gedit_overlay_size_allocate (GtkWidget     *widget,
 
 	for (l = priv->children; l != NULL; l = g_slist_next (l))
 	{
-		GtkWidget *child = GTK_WIDGET (l->data);
+		ChildContainer *container = l->data;
+		GtkWidget *child;
 		GtkRequisition req;
 		GtkAllocation alloc;
 		guint offset;
 
+		child = child_container_get_child (container);
+
 		if (child == priv->main_widget)
 			continue;
 
-		gtk_widget_get_preferred_size (child, &req, NULL);
+		gtk_widget_get_preferred_size (child, NULL, &req);
 		offset = gedit_overlay_child_get_offset (GEDIT_OVERLAY_CHILD (child));
 
 		/* FIXME: Add all the positions here */
@@ -219,7 +301,7 @@ gedit_overlay_size_allocate (GtkWidget     *widget,
 		{
 			/* The gravity is treated as position and not as a gravity */
 			case GEDIT_OVERLAY_CHILD_POSITION_NORTH_EAST:
-				alloc.x = main_alloc.width - req.width - offset;
+				alloc.x = MAX (main_alloc.x, main_alloc.width - req.width - (gint) offset);
 				alloc.y = 0;
 				break;
 			case GEDIT_OVERLAY_CHILD_POSITION_NORTH_WEST:
@@ -228,19 +310,19 @@ gedit_overlay_size_allocate (GtkWidget     *widget,
 				break;
 			case GEDIT_OVERLAY_CHILD_POSITION_SOUTH_WEST:
 				alloc.x = offset;
-				alloc.y = main_alloc.height - req.height;
+				alloc.y = MAX (main_alloc.y, main_alloc.height - req.height);
 				break;
 			case GEDIT_OVERLAY_CHILD_POSITION_SOUTH_EAST:
-				alloc.x = main_alloc.width - req.width - offset;
-				alloc.y = main_alloc.height - req.height;
+				alloc.x = MAX (main_alloc.x, main_alloc.width - req.width - (gint) offset);
+				alloc.y = MAX (main_alloc.y, main_alloc.height - req.height);
 				break;
 			default:
 				alloc.x = 0;
 				alloc.y = 0;
 		}
 
-		alloc.width = req.width;
-		alloc.height = req.height;
+		alloc.width = MIN (main_alloc.width, req.width);
+		alloc.height = MIN (main_alloc.height, req.height);
 
 		gtk_widget_size_allocate (child, &alloc);
 	}
@@ -250,43 +332,20 @@ static GeditOverlayChild *
 get_overlay_child (GeditOverlay *overlay,
                    GtkWidget    *widget)
 {
-	GeditOverlayChild *overlay_child = NULL;
 	GSList *l;
 
 	for (l = overlay->priv->children; l != NULL; l = g_slist_next (l))
 	{
-		GtkWidget *child = GTK_WIDGET (l->data);
-
-		/* skip the main widget as it is not a OverlayChild */
-		if (child == overlay->priv->main_widget)
-			continue;
+		ChildContainer *container = l->data;
 
-		if (child == widget)
+		if (container->original == widget &&
+		    GEDIT_IS_OVERLAY_CHILD (container->child))
 		{
-			overlay_child = GEDIT_OVERLAY_CHILD (child);
-			break;
-		}
-		else
-		{
-			GtkWidget *in_widget;
-
-			/* let's try also with the internal widget */
-			g_object_get (child, "widget", &in_widget, NULL);
-			g_assert (in_widget != NULL);
-
-			if (in_widget == widget)
-			{
-				overlay_child = GEDIT_OVERLAY_CHILD (child);
-				g_object_unref (in_widget);
-
-				break;
-			}
-
-			g_object_unref (in_widget);
+			return GEDIT_OVERLAY_CHILD (container->child);
 		}
 	}
 
-	return overlay_child;
+	return NULL;
 }
 
 static void
@@ -300,20 +359,9 @@ overlay_add (GtkContainer *overlay,
 
 	if (child == NULL)
 	{
-		if (GEDIT_IS_OVERLAY_CHILD (widget))
-		{
-			child = GEDIT_OVERLAY_CHILD (widget);
-		}
-		else
-		{
-			child = gedit_overlay_child_new (widget);
-			gtk_widget_show (GTK_WIDGET (child));
-
-			g_signal_connect_swapped (widget, "destroy",
-			                          G_CALLBACK (gtk_widget_destroy), child);
-		}
-
-		add_toplevel_widget (GEDIT_OVERLAY (overlay), GTK_WIDGET (child));
+		add_toplevel_widget (GEDIT_OVERLAY (overlay),
+		                     wrap_child_if_needed (widget),
+		                     widget);
 	}
 }
 
@@ -326,15 +374,27 @@ gedit_overlay_remove (GtkContainer *overlay,
 
 	for (l = priv->children; l != NULL; l = g_slist_next (l))
 	{
-		GtkWidget *child = l->data;
+		ChildContainer *container = l->data;
+		GtkWidget *original = container->original;
 
-		if (child == widget)
+		if (original == widget)
 		{
 			gtk_widget_unparent (widget);
-			priv->children = g_slist_remove_link (priv->children,
+
+			if (container->child != NULL &&
+			    original != container->child)
+			{
+				g_signal_handlers_disconnect_by_func (original,
+				                                      gtk_widget_destroy,
+				                                      container->child);
+
+				gtk_widget_destroy (container->child);
+			}
+
+			child_container_free (container);
+			priv->children = g_slist_delete_link (priv->children,
 			                                      l);
 
-			g_slist_free (l);
 			break;
 		}
 	}
@@ -350,10 +410,14 @@ gedit_overlay_forall (GtkContainer *overlay,
 	GSList *children;
 
 	children = priv->children;
+
 	while (children)
 	{
-		GtkWidget *child = GTK_WIDGET (children->data);
+		ChildContainer *container = children->data;
 		children = children->next;
+		GtkWidget *child;
+
+		child = child_container_get_child (container);
 
 		(* callback) (child, callback_data);
 	}
@@ -365,7 +429,6 @@ gedit_overlay_child_type (GtkContainer *overlay)
 	return GTK_TYPE_WIDGET;
 }
 
-
 static void
 gedit_overlay_class_init (GeditOverlayClass *klass)
 {
@@ -402,7 +465,6 @@ gedit_overlay_class_init (GeditOverlayClass *klass)
 	                                                      "Widget on which the floating widgets are placed",
 	                                                      GTK_TYPE_WIDGET,
 	                                                      G_PARAM_READWRITE |
-	                                                      G_PARAM_CONSTRUCT_ONLY |
 	                                                      G_PARAM_STATIC_STRINGS));
 
 	g_type_class_add_private (object_class, sizeof (GeditOverlayPrivate));
@@ -412,6 +474,8 @@ static void
 gedit_overlay_init (GeditOverlay *overlay)
 {
 	overlay->priv = GEDIT_OVERLAY_GET_PRIVATE (overlay);
+
+	gtk_widget_set_app_paintable (GTK_WIDGET (overlay), TRUE);
 }
 
 /**
diff --git a/lib/widgets/gedit-overlay.h b/lib/widgets/gedit-overlay.h
index 9e1c769..224c3ee 100644
--- a/lib/widgets/gedit-overlay.h
+++ b/lib/widgets/gedit-overlay.h
@@ -62,6 +62,9 @@ void		 gedit_overlay_add			(GeditOverlay             *overlay,
 							 GeditOverlayChildPosition position,
 							 guint                     offset);
 
+void             gedit_overlay_set_composited           (GeditOverlay             *overlay,
+                                                         gboolean                  enabled);
+
 G_END_DECLS
 
 #endif /* __GEDIT_OVERLAY_H__ */



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