diff options
Diffstat (limited to 'lib/widgets/ephy-overlay-escaping-child.c')
-rw-r--r-- | lib/widgets/ephy-overlay-escaping-child.c | 314 |
1 files changed, 0 insertions, 314 deletions
diff --git a/lib/widgets/ephy-overlay-escaping-child.c b/lib/widgets/ephy-overlay-escaping-child.c deleted file mode 100644 index b1fd796a8..000000000 --- a/lib/widgets/ephy-overlay-escaping-child.c +++ /dev/null @@ -1,314 +0,0 @@ -/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * Copyright © 2011 Igalia S.L. - * - * This library 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. - * - * This library 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 - * 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 "ephy-overlay-escaping-child.h" - -#define EPHY_OVERLAY_ESCAPING_CHILD_DEFAULT_DISTANCE 20 - -G_DEFINE_TYPE (EphyOverlayEscapingChild, ephy_overlay_escaping_child, GEDIT_TYPE_OVERLAY_CHILD); - -/* properties */ -enum -{ - PROP_0, - PROP_ESCAPING_DISTANCE -}; - -struct _EphyOverlayEscapingChildPrivate -{ - guint escaping_distance; - GtkAllocation initial_allocation; - GdkRectangle escaping_area; -}; - -/* If the pointer leaves the window, restore the widget position */ -static gboolean -parent_leave_notify_event (GtkWidget *widget, - GdkEventMotion *event, - GtkWidget *parent) -{ - EphyOverlayEscapingChildPrivate *priv = EPHY_OVERLAY_ESCAPING_CHILD (widget)->priv; - GtkAllocation alloc; - - gtk_widget_get_allocation (widget, &alloc); - alloc.y = priv->initial_allocation.y; - gtk_widget_size_allocate (widget, &alloc); - - return FALSE; -} - -/* this should be in Gdk...really */ -static gboolean -is_point_in_rectangle (int point_x, - int point_y, - GdkRectangle rectangle) -{ - int rectangle_x_higher_bound = rectangle.x + rectangle.width; - int rectangle_y_higher_bound = rectangle.y + rectangle.height; - - return point_x >= rectangle.x && point_x < rectangle_x_higher_bound - && point_y >= rectangle.y && point_y < rectangle_y_higher_bound; -} - -/* Keep the widget-pointer distance at at least - * EphyOverlayEscapingChildPrivate::escaping_distance by sliding the widget - * away if needed. - */ -static gboolean -parent_motion_notify_event (GtkWidget *widget, - GdkEventMotion *event, - GtkWidget *parent) -{ - EphyOverlayEscapingChildPrivate *priv = EPHY_OVERLAY_ESCAPING_CHILD (widget)->priv; - int distance_x, distance_y; - GtkAllocation alloc; - - gtk_widget_get_allocation (widget, &alloc); - - if (is_point_in_rectangle (event->x, event->y, priv->escaping_area)) { - gdk_window_get_device_position (gtk_widget_get_window (widget), - gdk_event_get_device ((GdkEvent *) event), - &distance_x, &distance_y, NULL); - alloc.y += priv->escaping_distance + distance_y; - } - else { - /* Put the widget at its original position if we are out of the escaping - * zone. Do nothing if it is already there. - */ - if (alloc.y == priv->initial_allocation.y) - return FALSE; - alloc.y = priv->initial_allocation.y; - } - - gtk_widget_size_allocate (widget, &alloc); - - return FALSE; -} - -/* When the parent overlay is resized, the child relative position is modified. - * So we update our initial_allocation to this new value and redefine our - * escaping area. - */ -static void -parent_size_allocate (GtkWidget *widget, - GdkRectangle *allocation, - GtkWidget *parent) -{ - EphyOverlayEscapingChildPrivate *priv = EPHY_OVERLAY_ESCAPING_CHILD (widget)->priv; - GtkAllocation initial_allocation; - - gtk_widget_get_allocation (widget, &initial_allocation); - priv->escaping_area = priv->initial_allocation = initial_allocation; - - /* Define an escaping area around the widget. - * Current implementation only handle horizontal lowerside widgets - */ - priv->escaping_area.height += priv->escaping_distance; - /* escape on both right and left */ - priv->escaping_area.width += 2 * priv->escaping_distance; - priv->escaping_area.x -= priv->escaping_distance; - priv->escaping_area.y -= priv->escaping_distance; -} - -/* Install listeners on our overlay parents to locate the pointer - * and our relative position. - */ -static void -ephy_overlay_escaping_child_parent_set (GtkWidget *widget, - GtkWidget *previous_parent) -{ - GtkWidget *parent; - - if (previous_parent != NULL) { - g_signal_handlers_disconnect_by_func (previous_parent, - G_CALLBACK (parent_motion_notify_event), - widget); - g_signal_handlers_disconnect_by_func (previous_parent, - G_CALLBACK (parent_leave_notify_event), - widget); - g_signal_handlers_disconnect_by_func (previous_parent, - G_CALLBACK (parent_size_allocate), - widget); - } - - parent = gtk_widget_get_parent (widget); - if (parent == NULL) - return; - - g_signal_connect_swapped (parent, - "motion-notify-event", - G_CALLBACK (parent_motion_notify_event), - widget); - g_signal_connect_swapped (parent, - "leave-notify-event", - G_CALLBACK (parent_leave_notify_event), - widget); - g_signal_connect_swapped (parent, - "size-allocate", - G_CALLBACK (parent_size_allocate), - widget); - -} - -/* When the mouse is over us, translate the event coords and slide the widget - * accordingly - */ -static gboolean -ephy_overlay_escaping_child_motion_notify_event (GtkWidget *widget, - GdkEventMotion *event) -{ - EphyOverlayEscapingChildPrivate *priv = EPHY_OVERLAY_ESCAPING_CHILD (widget)->priv; - - event->x += priv->initial_allocation.x; - event->y += priv->initial_allocation.y; - return parent_motion_notify_event (widget, event, gtk_widget_get_parent (widget)); -} - -/* Make our event window propagate mouse motion events, so we can slide the widget, - * when hovered. - */ -static void -ephy_overlay_escaping_child_realize (GtkWidget *widget) -{ - GdkWindow *window; - GdkEventMask events; - - GTK_WIDGET_CLASS (ephy_overlay_escaping_child_parent_class)->realize (widget); - - window = gtk_widget_get_window (widget); - events = gdk_window_get_events (window); - events |= GDK_POINTER_MOTION_MASK; - - gdk_window_set_events (window, events); -} - -static void -ephy_overlay_escaping_child_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - EphyOverlayEscapingChild *self = EPHY_OVERLAY_ESCAPING_CHILD (object); - EphyOverlayEscapingChildPrivate *priv = self->priv; - - switch (property_id) { - case PROP_ESCAPING_DISTANCE: - g_value_set_uint (value, priv->escaping_distance); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -ephy_overlay_escaping_child_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - EphyOverlayEscapingChild *self = EPHY_OVERLAY_ESCAPING_CHILD (object); - EphyOverlayEscapingChildPrivate *priv = self->priv; - - switch (property_id) - { - case PROP_ESCAPING_DISTANCE: - priv->escaping_distance = g_value_get_uint (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -ephy_overlay_escaping_child_class_init (EphyOverlayEscapingChildClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - - g_type_class_add_private (klass, sizeof(EphyOverlayEscapingChildPrivate)); - - gobject_class->get_property = ephy_overlay_escaping_child_get_property; - gobject_class->set_property = ephy_overlay_escaping_child_set_property; - - widget_class->parent_set = ephy_overlay_escaping_child_parent_set; - widget_class->motion_notify_event = ephy_overlay_escaping_child_motion_notify_event; - widget_class->realize = ephy_overlay_escaping_child_realize; - - g_object_class_install_property (gobject_class, - PROP_ESCAPING_DISTANCE, - g_param_spec_uint ("escaping-distance", - "Escaping distance", - "Maximum distance between the mouse pointer and the widget", - 0, - G_MAXUINT, - EPHY_OVERLAY_ESCAPING_CHILD_DEFAULT_DISTANCE, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); -} - -static void -ephy_overlay_escaping_child_init (EphyOverlayEscapingChild *self) -{ - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - EPHY_TYPE_OVERLAY_ESCAPING_CHILD, - EphyOverlayEscapingChildPrivate); -} - -/** - * ephy_overlay_escaping_child_new: - * @widget: the wrapped #GtkWidget - * @escaping_distance: the distance from which the widget escapes the mouse - * pointer - * - * Creates a new #EphyOverlayEscapingChild object wrapping the provided - * widget. The widget will stay at a minimal distance of @escaping_distance pixel - * from the mouse pointer. - * - * Returns: a new #EphyOverlayEscapingChild object - */ -EphyOverlayEscapingChild * -ephy_overlay_escaping_child_new_with_distance (GtkWidget *widget, - guint escaping_distance) -{ - return g_object_new (EPHY_TYPE_OVERLAY_ESCAPING_CHILD, - "widget", widget, - "escaping-distance", escaping_distance, - NULL); -} - -/** - * ephy_overlay_escaping_child_new: - * @widget: the wrapped #GtkWidget - * - * Creates a new #EphyOverlayEscapingChild object wrapping the provided - * widget. The widget will stay at a minimal distance of 20 pixels from - * the mouse pointer. - * - * Returns: a new #EphyOverlayEscapingChild object - */ -EphyOverlayEscapingChild * -ephy_overlay_escaping_child_new (GtkWidget *widget) -{ - return g_object_new (EPHY_TYPE_OVERLAY_ESCAPING_CHILD, - "widget", widget, - NULL); -} |