diff options
Diffstat (limited to 'lib/widgets/gedit-overlay.c')
-rw-r--r-- | lib/widgets/gedit-overlay.c | 259 |
1 files changed, 139 insertions, 120 deletions
diff --git a/lib/widgets/gedit-overlay.c b/lib/widgets/gedit-overlay.c index 1972adaa1..7cff41729 100644 --- a/lib/widgets/gedit-overlay.c +++ b/lib/widgets/gedit-overlay.c @@ -2,41 +2,30 @@ * gedit-overlay.c * This file is part of gedit * - * Copyright (C) 2010 - Ignacio Casal Quinteiro + * Copyright (C) 2011 - Ignacio Casal Quinteiro * * Based on Mike Krüger <mkrueger@novell.com> work. * - * gedit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * + * gedit is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * * gedit is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with gedit; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "gedit-overlay.h" -#include "gedit-theatrics-animated-widget.h" +#include "gedit-overlay-child.h" #define GEDIT_OVERLAY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_OVERLAY, GeditOverlayPrivate)) -typedef struct _OverlayChild -{ - GtkWidget *child; - GdkGravity gravity; - guint offset; - - guint fixed_position : 1; - guint is_animated : 1; -} OverlayChild; - struct _GeditOverlayPrivate { GtkWidget *main_widget; @@ -70,31 +59,13 @@ static void gedit_overlay_set_vadjustment (GeditOverlay *overlay, GtkAdjustment *adjustment); G_DEFINE_TYPE_WITH_CODE (GeditOverlay, gedit_overlay, GTK_TYPE_CONTAINER, - G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)) - -static void -free_container_child (OverlayChild *child) -{ - g_slice_free (OverlayChild, child); -} + G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)) static void add_toplevel_widget (GeditOverlay *overlay, - GtkWidget *widget, - gboolean fixed_position, - gboolean is_animated, - GdkGravity gravity, - guint offset) + GtkWidget *child) { - OverlayChild *child = g_slice_new (OverlayChild); - - child->child = widget; - child->gravity = gravity; - child->fixed_position = fixed_position; - child->is_animated = is_animated; - child->offset = offset; - - gtk_widget_set_parent (widget, GTK_WIDGET (overlay)); + gtk_widget_set_parent (child, GTK_WIDGET (overlay)); overlay->priv->children = g_slist_append (overlay->priv->children, child); @@ -199,9 +170,7 @@ gedit_overlay_set_property (GObject *object, case PROP_MAIN_WIDGET: overlay->priv->main_widget = g_value_get_object (value); add_toplevel_widget (overlay, - overlay->priv->main_widget, - TRUE, FALSE, GDK_GRAVITY_STATIC, - 0); + overlay->priv->main_widget); break; case PROP_HADJUSTMENT: @@ -287,7 +256,7 @@ gedit_overlay_get_preferred_width (GtkWidget *widget, gint *natural) { GeditOverlayPrivate *priv = GEDIT_OVERLAY (widget)->priv; - OverlayChild *child; + GtkWidget *child; GSList *children; gint child_min, child_nat; @@ -298,10 +267,10 @@ gedit_overlay_get_preferred_width (GtkWidget *widget, { child = children->data; - if (!gtk_widget_get_visible (child->child)) + if (!gtk_widget_get_visible (child)) continue; - gtk_widget_get_preferred_width (child->child, &child_min, &child_nat); + gtk_widget_get_preferred_width (child, &child_min, &child_nat); *minimum = MAX (*minimum, child_min); *natural = MAX (*natural, child_nat); @@ -314,7 +283,7 @@ gedit_overlay_get_preferred_height (GtkWidget *widget, gint *natural) { GeditOverlayPrivate *priv = GEDIT_OVERLAY (widget)->priv; - OverlayChild *child; + GtkWidget *child; GSList *children; gint child_min, child_nat; @@ -325,10 +294,10 @@ gedit_overlay_get_preferred_height (GtkWidget *widget, { child = children->data; - if (!gtk_widget_get_visible (child->child)) + if (!gtk_widget_get_visible (child)) continue; - gtk_widget_get_preferred_height (child->child, &child_min, &child_nat); + gtk_widget_get_preferred_height (child, &child_min, &child_nat); *minimum = MAX (*minimum, child_min); *natural = MAX (*natural, child_nat); @@ -343,29 +312,31 @@ set_children_positions (GeditOverlay *overlay) for (l = overlay->priv->children; l != NULL; l = g_slist_next (l)) { GeditOverlayPrivate *priv = overlay->priv; - OverlayChild *child = (OverlayChild *)l->data; + GtkWidget *child = GTK_WIDGET (l->data); GtkRequisition req; GtkAllocation alloc; + guint offset; - if (child->child == priv->main_widget) + if (child == priv->main_widget) continue; - gtk_widget_get_preferred_size (child->child, &req, NULL); + gtk_widget_get_preferred_size (child, &req, NULL); + offset = gedit_overlay_child_get_offset (GEDIT_OVERLAY_CHILD (child)); - /* FIXME: Add all the gravities here */ - switch (child->gravity) + /* FIXME: Add all the positions here */ + switch (gedit_overlay_child_get_position (GEDIT_OVERLAY_CHILD (child))) { /* The gravity is treated as position and not as a gravity */ - case GDK_GRAVITY_NORTH_EAST: - alloc.x = priv->main_alloc.width - req.width - child->offset; + case GEDIT_OVERLAY_CHILD_POSITION_NORTH_EAST: + alloc.x = priv->main_alloc.width - req.width - offset; alloc.y = 0; break; - case GDK_GRAVITY_NORTH_WEST: - alloc.x = child->offset; + case GEDIT_OVERLAY_CHILD_POSITION_NORTH_WEST: + alloc.x = offset; alloc.y = 0; break; - case GDK_GRAVITY_SOUTH_WEST: - alloc.x = child->offset; + case GEDIT_OVERLAY_CHILD_POSITION_SOUTH_WEST: + alloc.x = offset; alloc.y = priv->main_alloc.height - req.height; break; default: @@ -373,7 +344,7 @@ set_children_positions (GeditOverlay *overlay) alloc.y = 0; } - if (!child->fixed_position) + if (!gedit_overlay_child_get_fixed (GEDIT_OVERLAY_CHILD (child))) { alloc.x *= gtk_adjustment_get_value (priv->hadjustment); alloc.y *= gtk_adjustment_get_value (priv->vadjustment); @@ -382,7 +353,7 @@ set_children_positions (GeditOverlay *overlay) alloc.width = req.width; alloc.height = req.height; - gtk_widget_size_allocate (child->child, &alloc); + gtk_widget_size_allocate (child, &alloc); } } @@ -404,31 +375,88 @@ gedit_overlay_size_allocate (GtkWidget *widget, set_children_positions (overlay); } +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; + + if (child == widget) + { + 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); + break; + } + } + } + + return overlay_child; +} + static void overlay_add (GtkContainer *overlay, GtkWidget *widget) { - add_toplevel_widget (GEDIT_OVERLAY (overlay), widget, - FALSE, FALSE, GDK_GRAVITY_STATIC, 0); + GeditOverlayChild *child; + + /* check that the widget is not added yet */ + child = get_overlay_child (GEDIT_OVERLAY (overlay), widget); + + 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)); + } + + add_toplevel_widget (GEDIT_OVERLAY (overlay), GTK_WIDGET (child)); + } } static void gedit_overlay_remove (GtkContainer *overlay, GtkWidget *widget) { - GeditOverlay *goverlay = GEDIT_OVERLAY (overlay); + GeditOverlayPrivate *priv = GEDIT_OVERLAY (overlay)->priv; GSList *l; - for (l = goverlay->priv->children; l != NULL; l = g_slist_next (l)) + for (l = priv->children; l != NULL; l = g_slist_next (l)) { - OverlayChild *child = (OverlayChild *)l->data; + GtkWidget *child = l->data; - if (child->child == widget) + if (child == widget) { gtk_widget_unparent (widget); - goverlay->priv->children = g_slist_remove_link (goverlay->priv->children, - l); - free_container_child (child); + priv->children = g_slist_remove_link (priv->children, + l); + + g_slist_free (l); break; } } @@ -445,9 +473,9 @@ gedit_overlay_forall (GtkContainer *overlay, for (l = goverlay->priv->children; l != NULL; l = g_slist_next (l)) { - OverlayChild *child = (OverlayChild *)l->data; + GtkWidget *child = GTK_WIDGET (l->data); - (* callback) (child->child, callback_data); + (* callback) (child, callback_data); } } @@ -598,59 +626,50 @@ gedit_overlay_init (GeditOverlay *overlay) overlay->priv = GEDIT_OVERLAY_GET_PRIVATE (overlay); } +/** + * gedit_overlay_new: + * @main_widget: a #GtkWidget + * + * Creates a new #GeditOverlay + * + * Returns: a new #GeditOverlay object. + */ GtkWidget * gedit_overlay_new (GtkWidget *main_widget) { + g_return_val_if_fail (GTK_IS_WIDGET (main_widget), NULL); + return GTK_WIDGET (g_object_new (GEDIT_TYPE_OVERLAY, "main-widget", main_widget, NULL)); } -static GeditTheatricsAnimatedWidget * -get_animated_widget (GeditOverlay *overlay, - GtkWidget *widget) +/** + * gedit_overlay_add: + * @overlay: a #GeditOverlay + * @widget: a #GtkWidget to be added to the container + * @position: a #GeditOverlayChildPosition + * @offset: offset for @widget + * + * Adds @widget to @overlay in a specific position. + */ +void +gedit_overlay_add (GeditOverlay *overlay, + GtkWidget *widget, + GeditOverlayChildPosition position, + guint offset) { - GSList *l; - - for (l = overlay->priv->children; l != NULL; l = g_slist_next (l)) - { - OverlayChild *child = (OverlayChild *)l->data; - GtkWidget *in_widget; + GeditOverlayChild *child; - if (!child->is_animated) - continue; - - g_object_get (child->child, "widget", &in_widget, NULL); - g_assert (in_widget != NULL); + g_return_if_fail (GEDIT_IS_OVERLAY (overlay)); + g_return_if_fail (GTK_IS_WIDGET (widget)); - if (in_widget == widget) - { - return GEDIT_THEATRICS_ANIMATED_WIDGET (child->child); - } - } + gtk_container_add (GTK_CONTAINER (overlay), widget); - return NULL; -} + /* NOTE: can we improve this without exposing overlay child? */ + child = get_overlay_child (overlay, widget); + g_assert (child != NULL); -/* Note: see that we use the gravity as a position */ -void -gedit_overlay_add (GeditOverlay *overlay, - GtkWidget *widget, - GtkOrientation orientation, - GdkGravity gravity, - guint offset, - gboolean in) -{ - GeditTheatricsAnimatedWidget *anim_widget; - - anim_widget = get_animated_widget (overlay, widget); - - if (anim_widget == NULL) - { - anim_widget = gedit_theatrics_animated_widget_new (widget, orientation); - gtk_widget_show (GTK_WIDGET (anim_widget)); - - add_toplevel_widget (overlay, GTK_WIDGET (anim_widget), TRUE, - TRUE, gravity, offset); - } + gedit_overlay_child_set_position (child, position); + gedit_overlay_child_set_offset (child, offset); } |