colorplane: Fully port to GtkGesture
A GtkGestureDrag is used for color selection, removing also the need to track the pointer state in widget data. The GDK grab performed just to set the crosshair cursor has been replaced by a call to gdk_window_set_device_cursor(), which will be unset if the drag operation is finished, or cancelled due to the implicit grab being broken.
This commit is contained in:
		@ -19,6 +19,7 @@
 | 
			
		||||
 | 
			
		||||
#include "gtkcolorplaneprivate.h"
 | 
			
		||||
 | 
			
		||||
#include "gtkgesturedrag.h"
 | 
			
		||||
#include "gtkgesturelongpress.h"
 | 
			
		||||
#include "gtkaccessible.h"
 | 
			
		||||
#include "gtkadjustment.h"
 | 
			
		||||
@ -32,8 +33,8 @@ struct _GtkColorPlanePrivate
 | 
			
		||||
  GtkAdjustment *v_adj;
 | 
			
		||||
 | 
			
		||||
  cairo_surface_t *surface;
 | 
			
		||||
  gboolean in_drag;
 | 
			
		||||
 | 
			
		||||
  GtkGesture *drag_gesture;
 | 
			
		||||
  GtkGesture *long_press_gesture;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -180,32 +181,27 @@ plane_configure (GtkWidget         *widget,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_cross_grab (GtkWidget *widget,
 | 
			
		||||
                GdkDevice *device,
 | 
			
		||||
                guint32    time)
 | 
			
		||||
set_cross_cursor (GtkWidget *widget,
 | 
			
		||||
                  gboolean   enabled)
 | 
			
		||||
{
 | 
			
		||||
  GdkCursor *cursor;
 | 
			
		||||
  GdkCursor *cursor = NULL;
 | 
			
		||||
  GdkWindow *window;
 | 
			
		||||
  GdkDevice *device;
 | 
			
		||||
 | 
			
		||||
  cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (widget)),
 | 
			
		||||
                                       GDK_CROSSHAIR);
 | 
			
		||||
  gdk_device_grab (device,
 | 
			
		||||
                   gtk_widget_get_window (widget),
 | 
			
		||||
                   GDK_OWNERSHIP_NONE,
 | 
			
		||||
                   FALSE,
 | 
			
		||||
                   GDK_POINTER_MOTION_MASK
 | 
			
		||||
                    | GDK_POINTER_MOTION_HINT_MASK
 | 
			
		||||
                    | GDK_BUTTON_RELEASE_MASK,
 | 
			
		||||
                   cursor,
 | 
			
		||||
                   time);
 | 
			
		||||
  g_object_unref (cursor);
 | 
			
		||||
}
 | 
			
		||||
  window = gtk_widget_get_window (widget);
 | 
			
		||||
  device = gtk_gesture_get_device (GTK_COLOR_PLANE (widget)->priv->drag_gesture);
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
plane_grab_broken (GtkWidget          *widget,
 | 
			
		||||
                   GdkEventGrabBroken *event)
 | 
			
		||||
{
 | 
			
		||||
  GTK_COLOR_PLANE (widget)->priv->in_drag = FALSE;
 | 
			
		||||
  return TRUE;
 | 
			
		||||
  if (!window || !device)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (enabled)
 | 
			
		||||
    cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (widget)),
 | 
			
		||||
                                         GDK_CROSSHAIR);
 | 
			
		||||
 | 
			
		||||
  gdk_window_set_device_cursor (window, device, cursor);
 | 
			
		||||
 | 
			
		||||
  if (cursor)
 | 
			
		||||
    g_object_unref (cursor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -237,64 +233,6 @@ update_color (GtkColorPlane *plane,
 | 
			
		||||
  gtk_widget_queue_draw (widget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
plane_button_press (GtkWidget      *widget,
 | 
			
		||||
                    GdkEventButton *event)
 | 
			
		||||
{
 | 
			
		||||
  GtkColorPlane *plane = GTK_COLOR_PLANE (widget);
 | 
			
		||||
 | 
			
		||||
  if (event->button == GDK_BUTTON_SECONDARY)
 | 
			
		||||
    {
 | 
			
		||||
      gboolean handled;
 | 
			
		||||
 | 
			
		||||
      g_signal_emit_by_name (widget, "popup-menu", &handled);
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (plane->priv->in_drag || event->button != GDK_BUTTON_PRIMARY)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  plane->priv->in_drag = TRUE;
 | 
			
		||||
  set_cross_grab (widget, gdk_event_get_device ((GdkEvent*)event), event->time);
 | 
			
		||||
  update_color (plane, event->x, event->y);
 | 
			
		||||
  gtk_widget_grab_focus (widget);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
plane_button_release (GtkWidget      *widget,
 | 
			
		||||
                      GdkEventButton *event)
 | 
			
		||||
{
 | 
			
		||||
  GtkColorPlane *plane = GTK_COLOR_PLANE (widget);
 | 
			
		||||
 | 
			
		||||
  if (!plane->priv->in_drag || event->button != GDK_BUTTON_PRIMARY)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  plane->priv->in_drag = FALSE;
 | 
			
		||||
 | 
			
		||||
  update_color (plane, event->x, event->y);
 | 
			
		||||
  gdk_device_ungrab (gdk_event_get_device ((GdkEvent *) event), event->time);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
plane_motion_notify (GtkWidget      *widget,
 | 
			
		||||
                     GdkEventMotion *event)
 | 
			
		||||
{
 | 
			
		||||
  GtkColorPlane *plane = GTK_COLOR_PLANE (widget);
 | 
			
		||||
 | 
			
		||||
  if (!plane->priv->in_drag)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  gdk_event_request_motions (event);
 | 
			
		||||
  update_color (plane, event->x, event->y);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
hold_action (GtkGestureLongPress *gesture,
 | 
			
		||||
             gdouble              x,
 | 
			
		||||
@ -306,17 +244,6 @@ hold_action (GtkGestureLongPress *gesture,
 | 
			
		||||
  g_signal_emit_by_name (plane, "popup-menu", &handled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
plane_touch (GtkWidget     *widget,
 | 
			
		||||
             GdkEventTouch *event)
 | 
			
		||||
{
 | 
			
		||||
  GtkColorPlane *plane = GTK_COLOR_PLANE (widget);
 | 
			
		||||
 | 
			
		||||
  update_color (plane, event->x, event->y);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
sv_move (GtkColorPlane *plane,
 | 
			
		||||
         gdouble        ds,
 | 
			
		||||
@ -403,6 +330,57 @@ plane_key_press (GtkWidget   *widget,
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
plane_drag_gesture_begin (GtkGestureDrag *gesture,
 | 
			
		||||
                          gdouble         start_x,
 | 
			
		||||
                          gdouble         start_y,
 | 
			
		||||
                          GtkColorPlane  *plane)
 | 
			
		||||
{
 | 
			
		||||
  guint button;
 | 
			
		||||
 | 
			
		||||
  button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
 | 
			
		||||
 | 
			
		||||
  if (button == GDK_BUTTON_SECONDARY)
 | 
			
		||||
    {
 | 
			
		||||
      gboolean handled;
 | 
			
		||||
 | 
			
		||||
      g_signal_emit_by_name (plane, "popup-menu", &handled);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (button != GDK_BUTTON_PRIMARY)
 | 
			
		||||
    {
 | 
			
		||||
      gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  set_cross_cursor (GTK_WIDGET (plane), TRUE);
 | 
			
		||||
  update_color (plane, start_x, start_y);
 | 
			
		||||
  gtk_widget_grab_focus (GTK_WIDGET (plane));
 | 
			
		||||
  gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
plane_drag_gesture_update (GtkGestureDrag *gesture,
 | 
			
		||||
                           gdouble         offset_x,
 | 
			
		||||
                           gdouble         offset_y,
 | 
			
		||||
                           GtkColorPlane  *plane)
 | 
			
		||||
{
 | 
			
		||||
  gdouble start_x, start_y;
 | 
			
		||||
 | 
			
		||||
  gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (gesture),
 | 
			
		||||
                                    &start_x, &start_y);
 | 
			
		||||
  update_color (plane, start_x + offset_x, start_y + offset_y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
plane_drag_gesture_end (GtkGestureDrag *gesture,
 | 
			
		||||
                        gdouble         offset_x,
 | 
			
		||||
                        gdouble         offset_y,
 | 
			
		||||
                        GtkColorPlane  *plane)
 | 
			
		||||
{
 | 
			
		||||
  set_cross_cursor (GTK_WIDGET (plane), FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
gtk_color_plane_init (GtkColorPlane *plane)
 | 
			
		||||
{
 | 
			
		||||
@ -424,10 +402,21 @@ gtk_color_plane_init (GtkColorPlane *plane)
 | 
			
		||||
      atk_object_set_role (atk_obj, ATK_ROLE_COLOR_CHOOSER);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  plane->priv->drag_gesture = gtk_gesture_drag_new (GTK_WIDGET (plane));
 | 
			
		||||
  g_signal_connect (plane->priv->drag_gesture, "drag-begin",
 | 
			
		||||
		    G_CALLBACK (plane_drag_gesture_begin), plane);
 | 
			
		||||
  g_signal_connect (plane->priv->drag_gesture, "drag-update",
 | 
			
		||||
		    G_CALLBACK (plane_drag_gesture_update), plane);
 | 
			
		||||
  g_signal_connect (plane->priv->drag_gesture, "drag-end",
 | 
			
		||||
		    G_CALLBACK (plane_drag_gesture_end), plane);
 | 
			
		||||
  gtk_gesture_attach (plane->priv->drag_gesture, GTK_PHASE_TARGET);
 | 
			
		||||
  gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (plane->priv->drag_gesture),
 | 
			
		||||
                                     FALSE);
 | 
			
		||||
 | 
			
		||||
  plane->priv->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (plane));
 | 
			
		||||
  g_signal_connect (plane->priv->long_press_gesture, "pressed",
 | 
			
		||||
                    G_CALLBACK (hold_action), plane);
 | 
			
		||||
  gtk_gesture_attach (plane->priv->long_press_gesture, GTK_PHASE_BUBBLE);
 | 
			
		||||
  gtk_gesture_attach (plane->priv->long_press_gesture, GTK_PHASE_TARGET);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -442,6 +431,9 @@ plane_finalize (GObject *object)
 | 
			
		||||
  g_clear_object (&plane->priv->s_adj);
 | 
			
		||||
  g_clear_object (&plane->priv->v_adj);
 | 
			
		||||
 | 
			
		||||
  gtk_gesture_detach (plane->priv->drag_gesture);
 | 
			
		||||
  g_clear_object (&plane->priv->drag_gesture);
 | 
			
		||||
 | 
			
		||||
  gtk_gesture_detach (plane->priv->long_press_gesture);
 | 
			
		||||
  g_clear_object (&plane->priv->long_press_gesture);
 | 
			
		||||
 | 
			
		||||
@ -503,12 +495,7 @@ gtk_color_plane_class_init (GtkColorPlaneClass *class)
 | 
			
		||||
 | 
			
		||||
  widget_class->draw = plane_draw;
 | 
			
		||||
  widget_class->configure_event = plane_configure;
 | 
			
		||||
  widget_class->button_press_event = plane_button_press;
 | 
			
		||||
  widget_class->button_release_event = plane_button_release;
 | 
			
		||||
  widget_class->motion_notify_event = plane_motion_notify;
 | 
			
		||||
  widget_class->grab_broken_event = plane_grab_broken;
 | 
			
		||||
  widget_class->key_press_event = plane_key_press;
 | 
			
		||||
  widget_class->touch_event = plane_touch;
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_H_ADJUSTMENT,
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user