[gtk+/wip/events: 6/16] events: Add the basics of the event recognizer implementation



commit 7fa20e5395cae31e54ac5635c00429f92dfbc3e1
Author: Benjamin Otte <otte redhat com>
Date:   Sat Mar 3 22:49:43 2012 +0100

    events: Add the basics of the event recognizer implementation

 gtk/Makefile.am                 |    4 +
 gtk/gtk.h                       |    2 +
 gtk/gtkeventrecognizer.c        |  262 ++++++++++++++++++++++++
 gtk/gtkeventrecognizer.h        |  104 ++++++++++
 gtk/gtkeventrecognizerprivate.h |   35 ++++
 gtk/gtkeventtracker.c           |  420 +++++++++++++++++++++++++++++++++++++++
 gtk/gtkeventtracker.h           |   81 ++++++++
 gtk/gtkeventtrackerprivate.h    |   33 +++
 gtk/gtktypes.h                  |    4 +
 9 files changed, 945 insertions(+), 0 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 41e42d5..8ee0a5f 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -237,6 +237,8 @@ gtk_public_h_sources = 		\
 	gtkentrycompletion.h	\
 	gtkenums.h		\
 	gtkeventbox.h		\
+	gtkeventrecognizer.h	\
+	gtkeventtracker.h	\
 	gtkexpander.h		\
 	gtkfilechooser.h	\
 	gtkfilechooserbutton.h	\
@@ -644,6 +646,8 @@ gtk_base_c_sources = 		\
 	gtkentrybuffer.c	\
 	gtkentrycompletion.c	\
 	gtkeventbox.c		\
+	gtkeventrecognizer.c	\
+	gtkeventtracker.c	\
 	gtkexpander.c		\
 	gtkfilechooser.c	\
 	gtkfilechooserbutton.c	\
diff --git a/gtk/gtk.h b/gtk/gtk.h
index de0181b..04be83b 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -95,6 +95,8 @@
 #include <gtk/gtkentrycompletion.h>
 #include <gtk/gtkenums.h>
 #include <gtk/gtkeventbox.h>
+#include <gtk/gtkeventrecognizer.h>
+#include <gtk/gtkeventtracker.h>
 #include <gtk/gtkexpander.h>
 #include <gtk/gtkfixed.h>
 #include <gtk/gtkfilechooser.h>
diff --git a/gtk/gtkeventrecognizer.c b/gtk/gtkeventrecognizer.c
new file mode 100644
index 0000000..11e93d2
--- /dev/null
+++ b/gtk/gtkeventrecognizer.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright  2012 Red Hat Inc.
+ *
+ * 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
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include "gtkeventrecognizer.h"
+#include "gtkeventrecognizerprivate.h"
+
+#include "gtkeventtracker.h"
+#include "gtkeventtrackerprivate.h"
+#include "gtkintl.h"
+#include "gtkmarshalers.h"
+#include "gtkwidget.h"
+
+/**
+ * SECTION:gtkeventrecognizer
+ * @Short_description: Recognizes gestures from events
+ * @Title: GtkEventRecognizer
+ * @See_also: #GtkEventTracker
+ *
+ * #GtkEventRecoginzer and its subclasses are used for defining the event
+ * handling behavior of #GtkWidgets. 
+ *
+ * #GtkEventRecognizer was added in GTK 3.6.
+ */
+
+enum {
+  STARTED,
+  UPDATED,
+  FINISHED,
+  CANCELLED,
+  /* add more */
+  LAST_SIGNAL
+};
+
+guint signals[LAST_SIGNAL];
+
+G_DEFINE_ABSTRACT_TYPE (GtkEventRecognizer, gtk_event_recognizer, G_TYPE_OBJECT)
+
+static void
+gtk_event_recognizer_default_recognize (GtkEventRecognizer *recognizer,
+                                        GtkWidget          *widget,
+                                        GdkEvent           *event)
+{
+}
+
+static gboolean
+gtk_event_recognizer_default_track (GtkEventRecognizer *recognizer,
+                                    GtkEventTracker    *tracker,
+                                    GdkEvent           *event)
+{
+  return FALSE;
+}
+
+static void
+gtk_event_recognizer_class_init (GtkEventRecognizerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  klass->tracker_type = GTK_TYPE_EVENT_TRACKER;
+
+  klass->recognize = gtk_event_recognizer_default_recognize;
+  klass->track = gtk_event_recognizer_default_track;
+
+  /**
+   * GtkEventRecognizer::started:
+   * @recognizer: the recognizer
+   * @tracker: the tracker that was started
+   *
+   * Signals that @tracker has started recognizing an event sequence. Widgets
+   * using @recognizer may now wish to update transient state based on
+   * @tracker.
+   *
+   * From now on, @recognizer will emit GtkEventRecognizer::updated signals
+   * for @tracker until either the sequence got cancelled via a
+   * GtkEventRecognizer::cancelled signal emission or successfully recognized
+   * with a GtkEventRecognizer::finished signal.
+   */
+  signals[STARTED] =
+    g_signal_new (I_("started"),
+                  G_TYPE_FROM_CLASS (object_class),
+		  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GtkEventRecognizerClass, started),
+                  NULL, NULL,
+                  _gtk_marshal_VOID__OBJECT,
+                  G_TYPE_NONE, 1, GTK_TYPE_EVENT_TRACKER);
+  /**
+   * GtkEventRecognizer::updated:
+   * @recognizer: the recognizer
+   * @tracker: the tracker that was updated
+   *
+   * Signals that @tracker has updated its internal state while recognizing 
+   * an event sequence. Widgets using @recognizer may now wish to update 
+   * transient state based on @tracker.
+   */
+  signals[UPDATED] =
+    g_signal_new (I_("updated"),
+                  G_TYPE_FROM_CLASS (object_class),
+		  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GtkEventRecognizerClass, updated),
+                  NULL, NULL,
+                  _gtk_marshal_VOID__OBJECT,
+                  G_TYPE_NONE, 1, GTK_TYPE_EVENT_TRACKER);
+  /**
+   * GtkEventRecognizer::finished:
+   * @recognizer: the recognizer
+   * @tracker: the tracker that was finished
+   *
+   * Signals that @tracker has successfully recognized an event sequence and
+   * will now stop processing events or change state. Widgets using @recognizer
+   * should now update their state based on this event based on the information
+   * provided by @tracker.
+   *
+   * This signal will only be emitted after GtkEventRecognizer::started has
+   * been emitted for @tracker. It might not ever be emitted if @tracker was
+   * cancelled and GtkEventRecognizer::cancelled has been emitted instead. After
+   * this signal has been emitted, no new signals will be emitted for @tracker.
+   */
+  signals[FINISHED] =
+    g_signal_new (I_("finished"),
+                  G_TYPE_FROM_CLASS (object_class),
+		  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GtkEventRecognizerClass, finished),
+                  NULL, NULL,
+                  _gtk_marshal_VOID__OBJECT,
+                  G_TYPE_NONE, 1, GTK_TYPE_EVENT_TRACKER);
+  /**
+   * GtkEventRecognizer::cancelled:
+   * @recognizer: the recognizer
+   * @tracker: the tracker that was cancelled
+   *
+   * Signals that @tracker has been cancelled. It will now stop tracking
+   * events. A widget should now undo all modifications it did due prior signal
+   * emissions.
+   *
+   * This signal will only be emitted after GtkEventRecognizer::started has
+   * been emitted for @tracker. If it gets emitted, no other events will be emitted
+   * for @tracker.
+   */
+  signals[CANCELLED] =
+    g_signal_new (I_("cancelled"),
+                  G_TYPE_FROM_CLASS (object_class),
+		  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GtkEventRecognizerClass, cancelled),
+                  NULL, NULL,
+                  _gtk_marshal_VOID__OBJECT,
+                  G_TYPE_NONE, 1, GTK_TYPE_EVENT_TRACKER);
+}
+
+static void
+gtk_event_recognizer_init (GtkEventRecognizer *recognizer)
+{
+}
+
+gint
+gtk_event_recognizer_class_get_event_mask (GtkEventRecognizerClass *klass)
+{
+  g_return_val_if_fail (GTK_IS_EVENT_RECOGNIZER_CLASS (klass), 0);
+
+  return klass->event_mask;
+}
+
+void
+gtk_event_recognizer_class_set_event_mask (GtkEventRecognizerClass *klass,
+                                           gint                     event_mask)
+{
+  g_return_if_fail (GTK_IS_EVENT_RECOGNIZER_CLASS (klass));
+
+  klass->event_mask = event_mask;
+}
+
+GType
+gtk_event_recognizer_class_get_tracker_type (GtkEventRecognizerClass *klass)
+{
+  g_return_val_if_fail (GTK_IS_EVENT_RECOGNIZER_CLASS (klass), 0);
+
+  return klass->tracker_type;
+}
+
+void
+gtk_event_recognizer_class_set_tracker_type (GtkEventRecognizerClass *klass,
+                                             GType                    tracker_type)
+{
+  g_return_if_fail (GTK_IS_EVENT_RECOGNIZER_CLASS (klass));
+  g_return_if_fail (g_type_is_a (tracker_type, klass->tracker_type));
+
+  klass->tracker_type = tracker_type;
+}
+
+void
+gtk_event_recognizer_create_tracker (GtkEventRecognizer *recognizer,
+                                     GtkWidget          *widget,
+                                     GdkEvent           *event)
+{
+  GtkEventTracker *tracker;
+
+  g_return_if_fail (GTK_IS_EVENT_RECOGNIZER (recognizer));
+  g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
+  g_return_if_fail (event != NULL);
+
+  tracker = g_object_new (GTK_EVENT_RECOGNIZER_GET_CLASS (recognizer)->tracker_type,
+                          "recognizer", recognizer,
+                          "widget", widget,
+                          NULL);
+  
+  _gtk_event_tracker_add (tracker);
+  _gtk_event_recognizer_track (recognizer,
+                               tracker,
+                               event);
+}
+
+void
+_gtk_event_recognizer_recognize (GtkEventRecognizer *recognizer,
+                                 GtkWidget          *widget,
+                                 GdkEvent           *event)
+{
+  GtkEventRecognizerClass *klass;
+
+  g_return_if_fail (GTK_IS_EVENT_RECOGNIZER (recognizer));
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (event != NULL);
+
+  klass = GTK_EVENT_RECOGNIZER_GET_CLASS (recognizer);
+
+  klass->recognize (recognizer, widget, event);
+}
+
+gboolean
+_gtk_event_recognizer_track (GtkEventRecognizer *recognizer,
+                             GtkEventTracker    *tracker,
+                             GdkEvent           *event)
+{
+  GtkEventRecognizerClass *klass;
+
+  g_return_val_if_fail (GTK_IS_EVENT_RECOGNIZER (recognizer), FALSE);
+  g_return_val_if_fail (GTK_IS_EVENT_TRACKER (tracker), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (gtk_event_tracker_is_finished (tracker))
+    return FALSE;
+
+  klass = GTK_EVENT_RECOGNIZER_GET_CLASS (recognizer);
+  return klass->track (recognizer, tracker, event);
+}
+
diff --git a/gtk/gtkeventrecognizer.h b/gtk/gtkeventrecognizer.h
new file mode 100644
index 0000000..74c9b0c
--- /dev/null
+++ b/gtk/gtkeventrecognizer.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright  2012 Red Hat Inc.
+ *
+ * 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
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_EVENT_RECOGNIZER_H__
+#define __GTK_EVENT_RECOGNIZER_H__
+
+#include <gdk/gdk.h>
+
+#include <gtk/gtktypes.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_EVENT_RECOGNIZER           (gtk_event_recognizer_get_type ())
+#define GTK_EVENT_RECOGNIZER(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_EVENT_RECOGNIZER, GtkEventRecognizer))
+#define GTK_EVENT_RECOGNIZER_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_EVENT_RECOGNIZER, GtkEventRecognizerClass))
+#define GTK_IS_EVENT_RECOGNIZER(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_EVENT_RECOGNIZER))
+#define GTK_IS_EVENT_RECOGNIZER_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_EVENT_RECOGNIZER))
+#define GTK_EVENT_RECOGNIZER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_EVENT_RECOGNIZER, GtkEventRecognizerClass))
+
+typedef struct _GtkEventRecognizerClass        GtkEventRecognizerClass;
+typedef struct _GtkEventRecognizerPrivate      GtkEventRecognizerPrivate;
+typedef struct _GtkEventRecognizerClassPrivate GtkEventRecognizerClassPrivate;
+
+struct _GtkEventRecognizer
+{
+  GObject parent;
+
+  GtkEventRecognizerPrivate *priv;
+};
+
+struct _GtkEventRecognizerClass
+{
+  GObjectClass parent_class;
+
+  /* XXX: Put into private struct */
+  gint                event_mask;
+  GType               tracker_type;
+
+  void                (* recognize)                       (GtkEventRecognizer *recognizer,
+                                                           GtkWidget          *widget,
+                                                           GdkEvent           *event);
+  gboolean            (* track)                           (GtkEventRecognizer *recognizer,
+                                                           GtkEventTracker    *tracker,
+                                                           GdkEvent           *event);
+
+  /* signals */
+  void                (* started)                         (GtkEventRecognizer *recognizer,
+                                                           GtkEventTracker    *tracker);
+  void                (* updated)                         (GtkEventRecognizer *recognizer,
+                                                           GtkEventTracker    *tracker);
+  void                (* cancelled)                       (GtkEventRecognizer *recognizer,
+                                                           GtkEventTracker    *tracker);
+  void                (* finished)                        (GtkEventRecognizer *recognizer,
+                                                           GtkEventTracker    *tracker);
+
+  /* Padding for future expansion */
+  void (*_gtk_reserved0) (void);
+  void (*_gtk_reserved1) (void);
+  void (*_gtk_reserved2) (void);
+  void (*_gtk_reserved3) (void);
+  void (*_gtk_reserved4) (void);
+  void (*_gtk_reserved5) (void);
+  void (*_gtk_reserved6) (void);
+  void (*_gtk_reserved7) (void);
+};
+
+GType                 gtk_event_recognizer_get_type               (void) G_GNUC_CONST;
+
+gint                  gtk_event_recognizer_class_get_event_mask   (GtkEventRecognizerClass *klass);
+void                  gtk_event_recognizer_class_set_event_mask   (GtkEventRecognizerClass *klass,
+                                                                   gint                     event_mask);
+GType                 gtk_event_recognizer_class_get_tracker_type (GtkEventRecognizerClass *klass);
+void                  gtk_event_recognizer_class_set_tracker_type (GtkEventRecognizerClass *klass,
+                                                                   GType                    tracker_type);
+
+void                  gtk_event_recognizer_create_tracker         (GtkEventRecognizer      *recognizer,
+                                                                   GtkWidget               *widget,
+                                                                   GdkEvent                *event);
+
+
+G_END_DECLS
+
+#endif /* __GTK_EVENT_RECOGNIZER_H__ */
diff --git a/gtk/gtkeventrecognizerprivate.h b/gtk/gtkeventrecognizerprivate.h
new file mode 100644
index 0000000..3724fad
--- /dev/null
+++ b/gtk/gtkeventrecognizerprivate.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright  2012 Red Hat Inc.
+ *
+ * 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
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GTK_EVENT_RECOGNIZER_PRIVATE_H__
+#define __GTK_EVENT_RECOGNIZER_PRIVATE_H__
+
+#include <gdk/gdk.h>
+
+#include <gtk/gtktypes.h>
+
+void                _gtk_event_recognizer_recognize       (GtkEventRecognizer *recognizer,
+                                                           GtkWidget          *widget,
+                                                           GdkEvent           *event);
+gboolean            _gtk_event_recognizer_track           (GtkEventRecognizer *recognizer,
+                                                           GtkEventTracker    *tracker,
+                                                           GdkEvent           *event);
+
+#endif /* __GTK_EVENT_RECOGNIZER_PRIVATE_H__ */
diff --git a/gtk/gtkeventtracker.c b/gtk/gtkeventtracker.c
new file mode 100644
index 0000000..6be59fb
--- /dev/null
+++ b/gtk/gtkeventtracker.c
@@ -0,0 +1,420 @@
+/*
+ * Copyright  2012 Red Hat Inc.
+ *
+ * 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
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include "gtkeventtracker.h"
+
+#include "gtkeventrecognizer.h"
+#include "gtkeventrecognizerprivate.h"
+#include "gtkintl.h"
+#include "gtkwidget.h"
+
+/**
+ * SECTION:gtkeventtracker
+ * @Short_description: Tracks the events from a #GtkEventRecognizer
+ * @Title: GtkEventTracker
+ * @See_also: #GtkEventRecognizer
+ *
+ * The #GtkEventTracker object - or a subclass of it - is used to track
+ * sequences of events as recognized by a #GtkEventRecognizer. Once the
+ * recognizer finds it can potentially identify a sequence of events, it
+ * creates a #GtkEventTracker and uses it to store information about the
+ * event. See the event handling howto for a highlevel overview.
+ *
+ * #GtkEventTracker was added in GTK 3.6.
+ */
+
+
+enum {
+  PROP_0,
+  PROP_RECOGNIZER,
+  PROP_WIDGET
+};
+
+struct _GtkEventTrackerPrivate {
+  GtkEventRecognizer *recognizer;
+  GtkWidget *widget;
+
+  guint started :1;
+  guint finished :1;
+  guint cancelled :1;
+};
+
+G_DEFINE_ABSTRACT_TYPE (GtkEventTracker, gtk_event_tracker, G_TYPE_OBJECT)
+
+static GQueue trackers = G_QUEUE_INIT;
+
+static void
+gtk_event_tracker_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  GtkEventTracker *tracker = GTK_EVENT_TRACKER (object);
+  GtkEventTrackerPrivate *priv = tracker->priv;
+
+  switch (prop_id)
+    {
+    case PROP_RECOGNIZER:
+      priv->recognizer = g_value_dup_object (value);
+      if (priv->recognizer == NULL)
+        g_critical ("Attempting to construct a `%s' without a recognizer", G_OBJECT_TYPE_NAME (object));
+      break;
+    case PROP_WIDGET:
+      priv->widget = g_value_dup_object (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_event_tracker_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  GtkEventTracker *tracker = GTK_EVENT_TRACKER (object);
+  GtkEventTrackerPrivate *priv = tracker->priv;
+
+  switch (prop_id)
+    {
+    case PROP_RECOGNIZER:
+      g_value_set_object (value, priv->recognizer);
+      break;
+    case PROP_WIDGET:
+      g_value_set_object (value, priv->widget);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_event_tracker_dispose (GObject *object)
+{
+  GtkEventTracker *tracker = GTK_EVENT_TRACKER (object);
+  GtkEventTrackerPrivate *priv = tracker->priv;
+
+  g_queue_remove (&trackers, tracker);
+
+  g_clear_object (&priv->recognizer);
+  g_clear_object (&priv->widget);
+
+  G_OBJECT_CLASS (gtk_event_tracker_parent_class)->dispose (object);
+}
+
+static void
+gtk_event_tracker_class_init (GtkEventTrackerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = gtk_event_tracker_dispose;
+  object_class->set_property = gtk_event_tracker_set_property;
+  object_class->get_property = gtk_event_tracker_get_property;
+
+  g_object_class_install_property (object_class,
+                                   PROP_RECOGNIZER,
+                                   g_param_spec_object ("recognizer",
+                                                        P_("recognizer"),
+                                                        P_("Recognizer running this tracker"),
+                                                        GTK_TYPE_EVENT_RECOGNIZER,
+                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (object_class,
+                                   PROP_WIDGET,
+                                   g_param_spec_object ("widget",
+                                                        P_("widget"),
+                                                        P_("Widget that spawned this tracker"),
+                                                        GTK_TYPE_WIDGET,
+                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  g_type_class_add_private (object_class, sizeof (GtkEventTrackerPrivate));
+}
+
+static void
+gtk_event_tracker_init (GtkEventTracker *tracker)
+{
+  tracker->priv = G_TYPE_INSTANCE_GET_PRIVATE (tracker,
+                                               GTK_TYPE_EVENT_TRACKER,
+                                               GtkEventTrackerPrivate);
+}
+
+/**
+ * gtk_event_tracker_get_recognizer:
+ * @tracker: The event tracker
+ *
+ * Gets the recognizer that spawned this @tracker.
+ *
+ * Returns: The recognizer that spawned this tracker
+ *
+ * @Since: 3.6
+ **/
+GtkEventRecognizer *
+gtk_event_tracker_get_recognizer (GtkEventTracker *tracker)
+{
+  g_return_val_if_fail (GTK_IS_EVENT_TRACKER (tracker), NULL);
+
+  return tracker->priv->recognizer;
+}
+
+/**
+ * gtk_event_tracker_get_widget:
+ * @tracker: The event tracker
+ *
+ * Gets the widget that is affected by this tracker.
+ *
+ * Returns: The widget this tracker runs on or %NULL if none.
+ *
+ * @Since: 3.6
+ **/
+GtkWidget *
+gtk_event_tracker_get_widget (GtkEventTracker *tracker)
+{
+  g_return_val_if_fail (GTK_IS_EVENT_TRACKER (tracker), NULL);
+
+  return tracker->priv->widget;
+}
+
+/**
+ * gtk_event_tracker_is_cancelled:
+ * @tracker: The event tracker
+ *
+ * Queries if the tracker has been cancelled. A #GtkEventTracker
+ * can be cancelled for various reasons. See gtk_event_tracker_cancel()
+ * for details.
+ *
+ * Returns: %TRUE if the @tracker has been cancelled
+ **/
+gboolean
+gtk_event_tracker_is_cancelled (GtkEventTracker *tracker)
+{
+  g_return_val_if_fail (GTK_IS_EVENT_TRACKER (tracker), TRUE);
+
+  return tracker->priv->cancelled;
+}
+
+/**
+ * gtk_event_tracker_is_started:
+ * @tracker: The event tracker
+ *
+ * Checks if the event tracker is started. An event tracker is
+ * considered started after the GtkEventRecognizer::started signal
+ * has been emitted for it.
+ *
+ * Returns: %TRUE if the event tracker is started
+ **/
+gboolean
+gtk_event_tracker_is_started (GtkEventTracker *tracker)
+{
+  g_return_val_if_fail (GTK_IS_EVENT_TRACKER (tracker), TRUE);
+
+  return tracker->priv->started;
+}
+
+/**
+ * gtk_event_tracker_is_finished:
+ * @tracker: The event tracker
+ *
+ * Checks if the event tracker is finished. An event tracker is
+ * considered finished when it will not process events or emit
+ * signals anymore. At that point, the GtkEventRecognizer::finished
+ * or GtkEventRecognizer::cancelled signal will have been emitted
+ * for @recognizer.
+ *
+ * Returns: %TRUE if the event tracker is finished
+ **/
+gboolean
+gtk_event_tracker_is_finished (GtkEventTracker *tracker)
+{
+  g_return_val_if_fail (GTK_IS_EVENT_TRACKER (tracker), TRUE);
+
+  return tracker->priv->finished;
+}
+
+/**
+ * gtk_event_tracker_cancel:
+ * @tracker: The event tracker
+ *
+ * Cancels the event tracker if the event tracker is not finished yet.
+ * If the event tracker was already finished, this function returns
+ * immediately.
+ *
+ * Cancelling an event tracker will cause the 
+ * GtkEventRecognizer::cancelled signal to be emitted and the @tracker
+ * will not process any new events.
+ **/
+void
+gtk_event_tracker_cancel (GtkEventTracker *tracker)
+{
+  GtkEventTrackerPrivate *priv;
+
+  g_return_if_fail (GTK_IS_EVENT_TRACKER (tracker));
+
+  priv = tracker->priv;
+
+  if (priv->finished)
+    return;
+
+  priv->finished = TRUE;
+  priv->cancelled = TRUE;
+
+  if (priv->started)
+    g_signal_emit_by_name (priv->recognizer,
+                           "cancelled",
+                           tracker);
+  else
+    priv->started = TRUE;
+
+  /* release the reference from adding the tracker upon construction */
+  g_object_unref (tracker);
+}
+
+/**
+ * gtk_event_tracker_start:
+ * @tracker: The tracker to start
+ *
+ * Emits the GtkEventRecognizer::started signal for the @tracker. This
+ * signal should be emitted when @tracker should be made public and
+ * widgets using it might want to provide feedback for an impending event
+ * recognition.
+ *
+ * This function should only be called by #GtkEventRecognizer
+ * implementations.
+ **/
+void
+gtk_event_tracker_start (GtkEventTracker *tracker)
+{
+  GtkEventTrackerPrivate *priv;
+
+  g_return_if_fail (GTK_IS_EVENT_TRACKER (tracker));
+
+  priv = tracker->priv;
+  if (priv->started)
+    return;
+
+  priv->started = TRUE;
+
+  g_signal_emit_by_name (priv->recognizer,
+                         "started",
+                         tracker);
+}
+
+/**
+ * gtk_event_tracker_update:
+ * @tracker: The tracker to update
+ *
+ * Emits the GtkEventRecognizer::updated signal for the @tracker. This
+ * signal should be emitted when @tracker has updated its state and
+ * widgets might want to update their state based on it.
+ *
+ * This function should only be called by #GtkEventRecognizer
+ * implementations.
+ **/
+void
+gtk_event_tracker_update (GtkEventTracker *tracker)
+{
+  GtkEventTrackerPrivate *priv;
+
+  g_return_if_fail (GTK_IS_EVENT_TRACKER (tracker));
+
+  priv = tracker->priv;
+
+  g_object_ref (tracker);
+
+  gtk_event_tracker_start (tracker);
+
+  if (priv->finished)
+    return;
+
+  g_signal_emit_by_name (priv->recognizer,
+                         "updated",
+                         tracker);
+
+  g_object_unref (tracker);
+}
+
+/**
+ * gtk_event_tracker_finish:
+ * @tracker: The event tracker
+ *
+ * Marks the event tracker as finished and emits the 
+ * GtkEventRecognizer::finished signal. If the @tracker has
+ * already been finished, nothing happens.
+ *
+ * This function should only be called by #GtkEventRecognizer
+ * implementations.
+ **/
+void
+gtk_event_tracker_finish (GtkEventTracker *tracker)
+{
+  GtkEventTrackerPrivate *priv;
+
+  g_return_if_fail (GTK_IS_EVENT_TRACKER (tracker));
+
+  priv = tracker->priv;
+
+  if (priv->finished)
+    return;
+
+  priv->finished = TRUE;
+
+  if (priv->started)
+    g_signal_emit_by_name (priv->recognizer,
+                           "finished",
+                           tracker);
+
+  /* release the reference from adding the tracker upon construction */
+  g_object_unref (tracker);
+}
+
+void
+_gtk_event_tracker_add (GtkEventTracker *tracker)
+{
+  g_queue_push_tail (&trackers, tracker);
+}
+
+gboolean
+_gtk_event_trackers_invoke (GdkEvent *event)
+{
+  GList *list;
+  gboolean eat_event = FALSE;
+
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  list = g_queue_peek_head_link (&trackers); 
+  while (list)
+    {
+      GtkEventTracker *tracker = list->data;
+
+      g_object_ref (tracker);
+
+      eat_event |= _gtk_event_recognizer_track (tracker->priv->recognizer,
+                                                tracker,
+                                                event);
+
+      list = list->next;
+      g_object_unref (tracker);
+    }
+
+  return eat_event;
+}
diff --git a/gtk/gtkeventtracker.h b/gtk/gtkeventtracker.h
new file mode 100644
index 0000000..f7fe593
--- /dev/null
+++ b/gtk/gtkeventtracker.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright  2012 Red Hat Inc.
+ *
+ * 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
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_EVENT_TRACKER_H__
+#define __GTK_EVENT_TRACKER_H__
+
+#include <gtk/gtktypes.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_EVENT_TRACKER           (gtk_event_tracker_get_type ())
+#define GTK_EVENT_TRACKER(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_EVENT_TRACKER, GtkEventTracker))
+#define GTK_EVENT_TRACKER_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_EVENT_TRACKER, GtkEventTrackerClass))
+#define GTK_IS_EVENT_TRACKER(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_EVENT_TRACKER))
+#define GTK_IS_EVENT_TRACKER_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_EVENT_TRACKER))
+#define GTK_EVENT_TRACKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_EVENT_TRACKER, GtkEventTrackerClass))
+
+typedef struct _GtkEventTrackerClass      GtkEventTrackerClass;
+typedef struct _GtkEventTrackerPrivate    GtkEventTrackerPrivate;
+
+struct _GtkEventTracker
+{
+  GObject parent;
+
+  GtkEventTrackerPrivate *priv;
+};
+
+struct _GtkEventTrackerClass
+{
+  GObjectClass parent_class;
+
+  /* Padding for future expansion */
+  void (*_gtk_reserved0) (void);
+  void (*_gtk_reserved1) (void);
+  void (*_gtk_reserved2) (void);
+  void (*_gtk_reserved3) (void);
+  void (*_gtk_reserved4) (void);
+  void (*_gtk_reserved5) (void);
+  void (*_gtk_reserved6) (void);
+  void (*_gtk_reserved7) (void);
+};
+
+GType                 gtk_event_tracker_get_type          (void) G_GNUC_CONST;
+
+GtkEventRecognizer *  gtk_event_tracker_get_recognizer    (GtkEventTracker      *tracker);
+GtkWidget *           gtk_event_tracker_get_widget        (GtkEventTracker      *tracker);
+
+gboolean              gtk_event_tracker_is_started        (GtkEventTracker      *tracker);
+gboolean              gtk_event_tracker_is_finished       (GtkEventTracker      *tracker);
+gboolean              gtk_event_tracker_is_cancelled      (GtkEventTracker      *tracker);
+
+void                  gtk_event_tracker_cancel            (GtkEventTracker      *tracker);
+
+void                  gtk_event_tracker_start             (GtkEventTracker      *tracker);
+void                  gtk_event_tracker_update            (GtkEventTracker      *tracker);
+void                  gtk_event_tracker_finish            (GtkEventTracker      *tracker);
+
+G_END_DECLS
+
+#endif /* __GTK_EVENT_TRACKER_H__ */
diff --git a/gtk/gtkeventtrackerprivate.h b/gtk/gtkeventtrackerprivate.h
new file mode 100644
index 0000000..dbc8999
--- /dev/null
+++ b/gtk/gtkeventtrackerprivate.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright  2012 Red Hat Inc.
+ *
+ * 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
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GTK_EVENT_TRACKER_PRIVATE_H__
+#define __GTK_EVENT_TRACKER_PRIVATE_H__
+
+#include <gdk/gdk.h>
+
+#include <gtk/gtktypes.h>
+
+void                _gtk_event_tracker_add                (GtkEventTracker *tracker);
+
+gboolean            _gtk_event_trackers_invoke            (GdkEvent        *event);
+
+
+#endif /* __GTK_EVENT_TRACKER_PRIVATE_H__ */
diff --git a/gtk/gtktypes.h b/gtk/gtktypes.h
index b3eade3..7e2b0b1 100644
--- a/gtk/gtktypes.h
+++ b/gtk/gtktypes.h
@@ -29,10 +29,14 @@
 #ifndef __GTK_TYPES_H__
 #define __GTK_TYPES_H__
 
+#include <glib-object.h>
+
 G_BEGIN_DECLS
 
 typedef struct _GtkAdjustment          GtkAdjustment;
 typedef struct _GtkClipboard	       GtkClipboard;
+typedef struct _GtkEventRecognizer     GtkEventRecognizer;
+typedef struct _GtkEventTracker        GtkEventTracker;
 typedef struct _GtkIconSet             GtkIconSet;
 typedef struct _GtkIconSource          GtkIconSource;
 typedef struct _GtkRcStyle             GtkRcStyle;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]