aboutsummaryrefslogtreecommitdiffstats
path: root/lib/widgets
diff options
context:
space:
mode:
authorAlexandre Mazari <amazari@igalia.com>2011-04-19 00:30:58 +0800
committerAlexandre Mazari <amazari@igalia.com>2011-04-19 17:04:39 +0800
commit05d631cb9b95e3be827cbfbcdeb569834a967959 (patch)
tree2f82caed7b1e18aa01464bebe895469d1da561ba /lib/widgets
parent03d920eebb49fb9ecfda4ec00b669d1032caf587 (diff)
downloadgsoc2013-epiphany-05d631cb9b95e3be827cbfbcdeb569834a967959.tar
gsoc2013-epiphany-05d631cb9b95e3be827cbfbcdeb569834a967959.tar.gz
gsoc2013-epiphany-05d631cb9b95e3be827cbfbcdeb569834a967959.tar.bz2
gsoc2013-epiphany-05d631cb9b95e3be827cbfbcdeb569834a967959.tar.lz
gsoc2013-epiphany-05d631cb9b95e3be827cbfbcdeb569834a967959.tar.xz
gsoc2013-epiphany-05d631cb9b95e3be827cbfbcdeb569834a967959.tar.zst
gsoc2013-epiphany-05d631cb9b95e3be827cbfbcdeb569834a967959.zip
Import latest version of Gedit's overlay code.
Diffstat (limited to 'lib/widgets')
-rw-r--r--lib/widgets/gedit-overlay-child.c71
-rw-r--r--lib/widgets/gedit-overlay.c190
-rw-r--r--lib/widgets/gedit-overlay.h3
3 files changed, 169 insertions, 95 deletions
diff --git a/lib/widgets/gedit-overlay-child.c b/lib/widgets/gedit-overlay-child.c
index e30d6edfb..7593fe18c 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 bad7825a3..28e1010f0 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 9e1c76991..224c3ee83 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__ */