[gtk+] colorswatch: Support touch events
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] colorswatch: Support touch events
- Date: Sat, 3 Mar 2012 06:51:18 +0000 (UTC)
commit b43d00fa2acfb41387e3382b95037d55d4d472ab
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Mar 3 01:48:55 2012 -0500
colorswatch: Support touch events
Support long press for customizing, and short press for
selecting/activating. This is simpler than the generic
press-and-hold support in the multitouch branch; we don't
display any feedback, and the timeout is currently hardcoded
to 1 second.
gtk/gtkcolorswatch.c | 137 +++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 119 insertions(+), 18 deletions(-)
---
diff --git a/gtk/gtkcolorswatch.c b/gtk/gtkcolorswatch.c
index 3c8edd5..c75ef2d 100644
--- a/gtk/gtkcolorswatch.c
+++ b/gtk/gtkcolorswatch.c
@@ -33,6 +33,15 @@
#include "a11y/gtkcolorswatchaccessible.h"
+typedef struct {
+ GtkWidget *widget;
+
+ GdkEventSequence *sequence;
+ guint press_and_hold_id;
+ gint start_x;
+ gint start_y;
+} GtkPressAndHoldData;
+
struct _GtkColorSwatchPrivate
{
GdkRGBA color;
@@ -44,6 +53,8 @@ struct _GtkColorSwatchPrivate
guint selectable : 1;
GdkWindow *event_window;
+
+ GtkPressAndHoldData *press_and_hold;
};
enum
@@ -485,30 +496,116 @@ swatch_button_press (GtkWidget *widget,
}
static gboolean
+swatch_primary_action (GtkColorSwatch *swatch)
+{
+ GtkWidget *widget = (GtkWidget *)swatch;
+ GtkStateFlags flags;
+
+ flags = gtk_widget_get_state_flags (widget);
+ if (!swatch->priv->has_color)
+ {
+ g_signal_emit (swatch, signals[ACTIVATE], 0);
+ return TRUE;
+ }
+ else if (swatch->priv->selectable &&
+ (flags & GTK_STATE_FLAG_SELECTED) == 0)
+ {
+ gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_SELECTED, FALSE);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
swatch_button_release (GtkWidget *widget,
GdkEventButton *event)
{
GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget);
- GtkStateFlags flags;
if (event->button == GDK_BUTTON_PRIMARY &&
swatch->priv->contains_pointer)
+ return swatch_primary_action (swatch);
+
+ return FALSE;
+}
+
+static void
+swatch_press_and_hold_cancel (GtkWidget *widget,
+ GtkPressAndHoldData *data)
+{
+ if (data->press_and_hold_id)
{
- flags = gtk_widget_get_state_flags (widget);
- if (!swatch->priv->has_color)
- {
- g_signal_emit (swatch, signals[ACTIVATE], 0);
- return TRUE;
- }
- else if (swatch->priv->selectable &&
- (flags & GTK_STATE_FLAG_SELECTED) == 0)
- {
- gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_SELECTED, FALSE);
- return TRUE;
- }
+ g_source_remove (data->press_and_hold_id);
+ data->press_and_hold_id = 0;
}
+
+ data->sequence = NULL;
+}
- return FALSE;
+static void
+swatch_press_and_hold_free (GtkPressAndHoldData *data)
+{
+ swatch_press_and_hold_cancel (data->widget, data);
+ g_slice_free (GtkPressAndHoldData, data);
+}
+
+static gboolean
+swatch_press_and_hold_action (gpointer data)
+{
+ GtkPressAndHoldData *pah = data;
+
+ emit_customize (GTK_COLOR_SWATCH (pah->widget));
+ swatch_press_and_hold_cancel (pah->widget, pah);
+
+ return G_SOURCE_REMOVE;
+}
+
+
+static gboolean
+swatch_touch (GtkWidget *widget,
+ GdkEventTouch *event)
+{
+ GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget);
+ GtkPressAndHoldData *data;
+
+ if (!swatch->priv->press_and_hold)
+ swatch->priv->press_and_hold = g_slice_new0 (GtkPressAndHoldData);
+
+ data = swatch->priv->press_and_hold;
+
+ /* We're already tracking a different touch, ignore */
+ if (data->sequence != NULL && data->sequence != event->sequence)
+ return TRUE;
+
+ if (event->type == GDK_TOUCH_BEGIN)
+ {
+ data->widget = widget;
+ data->sequence = event->sequence;
+ data->start_x = event->x;
+ data->start_y = event->y;
+
+ data->press_and_hold_id =
+ gdk_threads_add_timeout (1000, swatch_press_and_hold_action, data);
+ }
+ else if (event->type == GDK_TOUCH_UPDATE)
+ {
+ if (gtk_drag_check_threshold (widget,
+ data->start_x, data->start_y,
+ event->x, event->y))
+ swatch_press_and_hold_cancel (widget, data);
+ }
+ else if (event->type == GDK_TOUCH_END)
+ {
+ swatch_press_and_hold_cancel (widget, data);
+ swatch_primary_action (swatch);
+ }
+ else if (event->type == GDK_TOUCH_CANCEL)
+ {
+ swatch_press_and_hold_cancel (widget, data);
+ }
+
+ return TRUE;
}
static void
@@ -552,10 +649,11 @@ swatch_realize (GtkWidget *widget)
attributes.height = allocation.height;
attributes.wclass = GDK_INPUT_ONLY;
attributes.event_mask = gtk_widget_get_events (widget);
- attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_ENTER_NOTIFY_MASK |
- GDK_LEAVE_NOTIFY_MASK);
+ attributes.event_mask |= GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_LEAVE_NOTIFY_MASK
+ | GDK_TOUCH_MASK;
attributes_mask = GDK_WA_X | GDK_WA_Y;
@@ -661,6 +759,8 @@ swatch_finalize (GObject *object)
GtkColorSwatch *swatch = GTK_COLOR_SWATCH (object);
g_free (swatch->priv->icon);
+ if (swatch->priv->press_and_hold)
+ swatch_press_and_hold_free (swatch->priv->press_and_hold);
G_OBJECT_CLASS (gtk_color_swatch_parent_class)->finalize (object);
}
@@ -692,6 +792,7 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
widget_class->map = swatch_map;
widget_class->unmap = swatch_unmap;
widget_class->size_allocate = swatch_size_allocate;
+ widget_class->touch_event = swatch_touch;
signals[ACTIVATE] =
g_signal_new ("activate",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]