Compare commits
25 Commits
wip/css-op
...
wip/events
Author | SHA1 | Date | |
---|---|---|---|
|
31363bea06 | ||
|
2bf2b5df5f | ||
|
55421f7fed | ||
|
ca5b9aa001 | ||
|
b469025153 | ||
|
c7f55213ee | ||
|
7749195e0b | ||
|
a28f99bf40 | ||
|
699a315ff8 | ||
|
7914ce8231 | ||
|
39b9acf56d | ||
|
4f2a7bb96d | ||
|
e89f76a944 | ||
|
20dd5c5b43 | ||
|
61c1737cde | ||
|
2640918761 | ||
|
1b48a544e5 | ||
|
6a14c755c8 | ||
|
dd499e9829 | ||
|
f08fb83b21 | ||
|
d1975edb6a | ||
|
a0ab7cc207 | ||
|
4da18923c5 | ||
|
d3cdf494d9 | ||
|
82838a2056 |
@@ -691,6 +691,7 @@ gdk_device_set_key
|
||||
gdk_device_get_key
|
||||
gdk_device_set_axis_use
|
||||
gdk_device_get_axis_use
|
||||
gdk_device_get_axis_label
|
||||
gdk_device_get_associated_device
|
||||
gdk_device_list_slave_devices
|
||||
gdk_device_get_device_type
|
||||
|
103
docs/reference/gtk/event-handling.xml
Normal file
103
docs/reference/gtk/event-handling.xml
Normal file
@@ -0,0 +1,103 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
|
||||
]>
|
||||
<chapter id="event-handling">
|
||||
<title>Event handling in GTK+ 3</title>
|
||||
|
||||
<para>
|
||||
In version 3.6, GTK+ has overhauled the way widgets handle input events
|
||||
considerably. The main motivation for this has been the more complex
|
||||
interaction models used by modern toolkitts. In particular, enabling
|
||||
all the behaviors people expect from multitouch support was guiding the
|
||||
design.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The principles outlined in this chapter are only relevant for people
|
||||
that want to implement their own #GtkWidgets. It is not necessary that
|
||||
you understand the concepts here when all you want to do is use existing
|
||||
widgets to create your own application.
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>The high-level view</title>
|
||||
|
||||
<para>
|
||||
FIXME
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The GTK event system is a cooperative event handling system. This means
|
||||
that event recognizers need not know on their own if they should
|
||||
recognize an event, but they communicate with other recognizers about
|
||||
the process.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<title>Setting up your widget</title>
|
||||
|
||||
<section>
|
||||
<title>Using GtkBuilder</title>
|
||||
<para>
|
||||
FIXME (with examples!)
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Manual addition of event recognizers</title>
|
||||
<para>
|
||||
FIXME (with examples!)
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<title>Event flow</title>
|
||||
|
||||
<section>
|
||||
<title>Lifetime of a #GtkEventTracker</title>
|
||||
<para>
|
||||
FIXME
|
||||
</para>
|
||||
<section>
|
||||
|
||||
<section>
|
||||
<title>Flow of a #GdkEvent through the event machinery</title>
|
||||
<para>
|
||||
FIXME (make sure to not be too specific, so we can still change stuff later)
|
||||
</para>
|
||||
<section>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<title>Writing your own event recognizers</title>
|
||||
|
||||
<para>
|
||||
The GTK developers generally discourage the writing of new event recognizers.
|
||||
We are trying to provide a consistent feel to GTK applications and with all
|
||||
the included event recognizers we think almost all the functionality needed
|
||||
for event handling should be there for you to use.
|
||||
|
||||
Of course, every rule has its exceptions or you might just feel adventurous.
|
||||
so should you see yourself in a situation where you need to write your own
|
||||
event recognizers, here are some hints on how to do it.
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>FIXME</title>
|
||||
<para>
|
||||
FIXME
|
||||
</para>
|
||||
<section>
|
||||
|
||||
</section>
|
||||
|
||||
</chapter>
|
@@ -271,6 +271,13 @@
|
||||
<xi:include href="xml/gtkscrollable.xml" />
|
||||
</chapter>
|
||||
|
||||
<chapter id="Events">
|
||||
<title>Event handling</title>
|
||||
<xi:include href="xml/event-handling.xml" />
|
||||
<xi:include href="xml/gtkeventrecognizer.xml" />
|
||||
<xi:include href="xml/gtkeventtracker.xml" />
|
||||
</chapter>
|
||||
|
||||
<chapter id="Printing">
|
||||
<title>Printing</title>
|
||||
<xi:include href="xml/gtkprintoperation.xml" />
|
||||
|
@@ -101,6 +101,7 @@ gdk_private_headers = \
|
||||
gdkdisplaymanagerprivate.h \
|
||||
gdkdisplayprivate.h \
|
||||
gdkdndprivate.h \
|
||||
gdkeventsequenceprivate.h \
|
||||
gdkscreenprivate.h \
|
||||
gdkinternals.h \
|
||||
gdkintl.h \
|
||||
@@ -121,6 +122,7 @@ gdk_c_sources = \
|
||||
gdkdisplaymanager.c \
|
||||
gdkdnd.c \
|
||||
gdkevents.c \
|
||||
gdkeventsequence.c \
|
||||
gdkglobals.c \
|
||||
gdkkeys.c \
|
||||
gdkkeyuni.c \
|
||||
|
@@ -93,8 +93,8 @@ gdk_broadway_device_init (GdkBroadwayDevice *device_core)
|
||||
|
||||
device = GDK_DEVICE (device_core);
|
||||
|
||||
_gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, NULL, GDK_AXIS_X, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, NULL, GDK_AXIS_Y, 0, 0, 1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@@ -47,6 +47,7 @@ gdk_cursor_unref
|
||||
gdk_device_free_history
|
||||
gdk_device_get_associated_device
|
||||
gdk_device_get_axis
|
||||
gdk_device_get_axis_label
|
||||
gdk_device_get_axis_use
|
||||
gdk_device_get_axis_value
|
||||
gdk_device_get_device_type
|
||||
|
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkeventsequenceprivate.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkintl.h"
|
||||
|
||||
@@ -43,6 +44,7 @@ typedef struct _GdkAxisInfo GdkAxisInfo;
|
||||
struct _GdkAxisInfo
|
||||
{
|
||||
GdkAtom label;
|
||||
gchar *label_string;
|
||||
GdkAxisUse use;
|
||||
|
||||
gdouble min_axis;
|
||||
@@ -255,16 +257,26 @@ gdk_device_class_init (GdkDeviceClass *klass)
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_axis_info_clear (gpointer data)
|
||||
{
|
||||
GdkAxisInfo *info = data;
|
||||
|
||||
g_free (info->label_string);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_init (GdkDevice *device)
|
||||
{
|
||||
device->axes = g_array_new (FALSE, TRUE, sizeof (GdkAxisInfo));
|
||||
g_array_set_clear_func (device->axes, gdk_axis_info_clear);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_dispose (GObject *object)
|
||||
{
|
||||
GdkDevice *device = GDK_DEVICE (object);
|
||||
GSList *list;
|
||||
|
||||
if (device->type == GDK_DEVICE_TYPE_SLAVE)
|
||||
_gdk_device_remove_slave (device->associated, device);
|
||||
@@ -278,6 +290,18 @@ gdk_device_dispose (GObject *object)
|
||||
device->associated = NULL;
|
||||
}
|
||||
|
||||
for (list = device->sequences; list; list = list->next)
|
||||
{
|
||||
GdkEventSequence *sequence = list->data;
|
||||
|
||||
/* Set device to NULL in advance so that the unreffing doesn't
|
||||
* modify the list we iterate over */
|
||||
sequence->device = NULL;
|
||||
gdk_event_sequence_unref (sequence);
|
||||
}
|
||||
g_slist_free (device->sequences);
|
||||
device->sequences = NULL;
|
||||
|
||||
if (device->axes)
|
||||
{
|
||||
g_array_free (device->axes, TRUE);
|
||||
@@ -770,6 +794,39 @@ gdk_device_set_key (GdkDevice *device,
|
||||
device->keys[index_].modifiers = modifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_device_get_axis_label:
|
||||
* @device: a pointer #GdkDevice.
|
||||
* @index_: the index of the axis.
|
||||
*
|
||||
* Returns the label for the axis. If it exists, the label of
|
||||
* an axis is a string identifying the axis. Labels for the same
|
||||
* types of axes may differ between devices and platforms. Try to use
|
||||
* gdk_device_get_axis_use() if possible.
|
||||
*
|
||||
* This function is useful as a debugging help. It should never
|
||||
* be presented to users.
|
||||
*
|
||||
* Returns: a string describing the label of the axis or %NULL
|
||||
* if the axis has no label.
|
||||
*
|
||||
* Since: 3.6
|
||||
**/
|
||||
const char *
|
||||
gdk_device_get_axis_label (GdkDevice *device,
|
||||
guint index_)
|
||||
{
|
||||
GdkAxisInfo *info;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
|
||||
g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
|
||||
g_return_val_if_fail (index_ < device->axes->len, NULL);
|
||||
|
||||
info = &g_array_index (device->axes, GdkAxisInfo, index_);
|
||||
|
||||
return info->label_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_device_get_axis_use:
|
||||
* @device: a pointer #GdkDevice.
|
||||
@@ -1329,6 +1386,7 @@ _gdk_device_reset_axes (GdkDevice *device)
|
||||
guint
|
||||
_gdk_device_add_axis (GdkDevice *device,
|
||||
GdkAtom label_atom,
|
||||
const char *label_string,
|
||||
GdkAxisUse use,
|
||||
gdouble min_value,
|
||||
gdouble max_value,
|
||||
@@ -1337,8 +1395,12 @@ _gdk_device_add_axis (GdkDevice *device,
|
||||
GdkAxisInfo axis_info;
|
||||
guint pos;
|
||||
|
||||
GDK_NOTE (INPUT, g_print ("Adding axis '%s' with use %d for range [%g, %g] with %gunits/m\n",
|
||||
label_string, use, min_value, max_value, resolution));
|
||||
|
||||
axis_info.use = use;
|
||||
axis_info.label = label_atom;
|
||||
axis_info.label_string = g_strdup (label_string);
|
||||
axis_info.min_value = min_value;
|
||||
axis_info.max_value = max_value;
|
||||
axis_info.resolution = resolution;
|
||||
|
@@ -88,6 +88,10 @@ typedef enum
|
||||
* @GDK_AXIS_XTILT: the axis is used for x tilt information.
|
||||
* @GDK_AXIS_YTILT: the axis is used for y tilt information.
|
||||
* @GDK_AXIS_WHEEL: the axis is used for wheel information.
|
||||
* @GDK_AXIS_X_RELATIVE: the axis used to describe relative movement along
|
||||
* the x axis. Useful for tracking movement on %GDK_SOURCE_TOUCHPAD devices.
|
||||
* @GDK_AXIS_Y_RELATIVE: the axis used to describe relative movement along
|
||||
* the y axis. Useful for tracking movement on %GDK_SOURCE_TOUCHPAD devices.
|
||||
* @GDK_AXIS_LAST: a constant equal to the numerically highest axis value.
|
||||
*
|
||||
* An enumeration describing the way in which a device
|
||||
@@ -103,6 +107,8 @@ typedef enum
|
||||
GDK_AXIS_XTILT,
|
||||
GDK_AXIS_YTILT,
|
||||
GDK_AXIS_WHEEL,
|
||||
GDK_AXIS_X_RELATIVE,
|
||||
GDK_AXIS_Y_RELATIVE,
|
||||
GDK_AXIS_LAST
|
||||
} GdkAxisUse;
|
||||
|
||||
@@ -163,6 +169,8 @@ void gdk_device_set_key (GdkDevice *device,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers);
|
||||
|
||||
const char * gdk_device_get_axis_label(GdkDevice *device,
|
||||
guint index_);
|
||||
GdkAxisUse gdk_device_get_axis_use (GdkDevice *device,
|
||||
guint index_);
|
||||
void gdk_device_set_axis_use (GdkDevice *device,
|
||||
|
@@ -56,6 +56,7 @@ struct _GdkDevice
|
||||
GList *slaves;
|
||||
GdkDeviceType type;
|
||||
GArray *axes;
|
||||
GSList *sequences;
|
||||
};
|
||||
|
||||
struct _GdkDeviceClass
|
||||
@@ -117,6 +118,7 @@ void _gdk_device_set_associated_device (GdkDevice *device,
|
||||
void _gdk_device_reset_axes (GdkDevice *device);
|
||||
guint _gdk_device_add_axis (GdkDevice *device,
|
||||
GdkAtom label_atom,
|
||||
const char *label_string,
|
||||
GdkAxisUse use,
|
||||
gdouble min_value,
|
||||
gdouble max_value,
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkeventsequenceprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
@@ -600,6 +601,7 @@ gdk_event_copy (const GdkEvent *event)
|
||||
case GDK_TOUCH_UPDATE:
|
||||
case GDK_TOUCH_END:
|
||||
case GDK_TOUCH_CANCEL:
|
||||
new_event->touch.sequence = gdk_event_sequence_ref (event->touch.sequence);
|
||||
if (event->touch.axes)
|
||||
new_event->touch.axes = g_memdup (event->touch.axes,
|
||||
sizeof (gdouble) * gdk_device_get_n_axes (event->touch.device));
|
||||
@@ -689,6 +691,7 @@ gdk_event_free (GdkEvent *event)
|
||||
case GDK_TOUCH_END:
|
||||
case GDK_TOUCH_CANCEL:
|
||||
g_free (event->touch.axes);
|
||||
gdk_event_sequence_unref (event->touch.sequence);
|
||||
break;
|
||||
|
||||
case GDK_EXPOSE:
|
||||
|
@@ -144,8 +144,6 @@ typedef struct _GdkEventWindowState GdkEventWindowState;
|
||||
typedef struct _GdkEventSetting GdkEventSetting;
|
||||
typedef struct _GdkEventGrabBroken GdkEventGrabBroken;
|
||||
|
||||
typedef struct _GdkEventSequence GdkEventSequence;
|
||||
|
||||
typedef union _GdkEvent GdkEvent;
|
||||
|
||||
/**
|
||||
|
85
gdk/gdkeventsequence.c
Normal file
85
gdk/gdkeventsequence.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/* gdkeventsequence.h - tracking sequences of events
|
||||
* Copyright (C) 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 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkeventsequenceprivate.h"
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
|
||||
/* XXX: Does not return a reference - should we change that? */
|
||||
GdkEventSequence *
|
||||
gdk_event_sequence_new (GdkDevice *device,
|
||||
guint sequence_id)
|
||||
{
|
||||
GdkEventSequence *sequence = g_slice_new0 (GdkEventSequence);
|
||||
|
||||
/* device owns sequence, so cannot ref device here */
|
||||
sequence->ref_count = 1;
|
||||
sequence->device = device;
|
||||
sequence->sequence_id = sequence_id;
|
||||
sequence->axes = g_new0 (gdouble, gdk_device_get_n_axes (device));
|
||||
|
||||
device->sequences = g_slist_prepend (device->sequences, sequence);
|
||||
|
||||
return sequence;
|
||||
}
|
||||
|
||||
GdkEventSequence *
|
||||
gdk_event_sequence_lookup (GdkDevice *device,
|
||||
guint sequence_id)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
for (list = device->sequences; list; list = list->next)
|
||||
{
|
||||
GdkEventSequence *sequence = list->data;
|
||||
|
||||
if (sequence->sequence_id == sequence_id)
|
||||
return sequence;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GdkEventSequence *
|
||||
gdk_event_sequence_ref (GdkEventSequence *sequence)
|
||||
{
|
||||
sequence->ref_count++;
|
||||
|
||||
return sequence;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_event_sequence_unref (GdkEventSequence *sequence)
|
||||
{
|
||||
sequence->ref_count--;
|
||||
if (sequence->ref_count > 0)
|
||||
return;
|
||||
|
||||
if (sequence->device)
|
||||
{
|
||||
GdkDevice *device = sequence->device;
|
||||
|
||||
device->sequences = g_slist_remove (device->sequences, sequence);
|
||||
}
|
||||
|
||||
g_free (sequence->axes);
|
||||
g_slice_free (GdkEventSequence, sequence);
|
||||
}
|
44
gdk/gdkeventsequenceprivate.h
Normal file
44
gdk/gdkeventsequenceprivate.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* gdkeventsequence.h - tracking sequences of events
|
||||
* Copyright (C) 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 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GDK_EVENT_SEQUENCE_H__
|
||||
#define __GDK_EVENT_SEQUENCE_H__
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
|
||||
struct _GdkEventSequence {
|
||||
GdkDevice *device;
|
||||
guint sequence_id;
|
||||
guint ref_count;
|
||||
double *axes;
|
||||
};
|
||||
|
||||
GdkEventSequence * gdk_event_sequence_new (GdkDevice *device,
|
||||
guint sequence_id);
|
||||
GdkEventSequence * gdk_event_sequence_lookup (GdkDevice *device,
|
||||
guint sequence_id);
|
||||
|
||||
GdkEventSequence * gdk_event_sequence_ref (GdkEventSequence *sequence);
|
||||
void gdk_event_sequence_unref (GdkEventSequence *sequence);
|
||||
|
||||
#endif /* __GDK_EVENT_SEQUENCE_H__ */
|
@@ -123,6 +123,7 @@ typedef struct _GdkDragContext GdkDragContext;
|
||||
typedef struct _GdkDisplayManager GdkDisplayManager;
|
||||
typedef struct _GdkDeviceManager GdkDeviceManager;
|
||||
typedef struct _GdkDisplay GdkDisplay;
|
||||
typedef struct _GdkEventSequence GdkEventSequence;
|
||||
typedef struct _GdkScreen GdkScreen;
|
||||
typedef struct _GdkWindow GdkWindow;
|
||||
typedef struct _GdkKeymap GdkKeymap;
|
||||
|
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "gdkwindow.h"
|
||||
|
||||
#include "gdkeventsequenceprivate.h"
|
||||
#include "gdkrectangle.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkintl.h"
|
||||
@@ -9483,7 +9484,7 @@ proxy_pointer_event (GdkDisplay *display,
|
||||
{
|
||||
event->touch.time = time_;
|
||||
event->touch.state = state | GDK_BUTTON1_MASK;
|
||||
event->touch.sequence = source_event->touch.sequence;
|
||||
event->touch.sequence = gdk_event_sequence_ref (source_event->touch.sequence);
|
||||
event->touch.emulating_pointer = source_event->touch.emulating_pointer;
|
||||
convert_toplevel_coords_to_window (event_win,
|
||||
toplevel_x, toplevel_y,
|
||||
@@ -9772,7 +9773,7 @@ proxy_button_event (GdkEvent *source_event,
|
||||
event->touch.device = source_event->touch.device;
|
||||
event->touch.axes = g_memdup (source_event->touch.axes,
|
||||
sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
|
||||
event->touch.sequence = source_event->touch.sequence;
|
||||
event->touch.sequence = gdk_event_sequence_ref (source_event->touch.sequence);
|
||||
event->touch.emulating_pointer = source_event->touch.emulating_pointer;
|
||||
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
|
@@ -107,8 +107,8 @@ gdk_quartz_device_core_init (GdkQuartzDeviceCore *quartz_device_core)
|
||||
|
||||
device = GDK_DEVICE (quartz_device_core);
|
||||
|
||||
_gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, NULL, GDK_AXIS_X, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, NULL, GDK_AXIS_Y, 0, 0, 1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@@ -334,8 +334,8 @@ gdk_device_core_init (GdkDeviceCore *device_core)
|
||||
|
||||
device = GDK_DEVICE (device_core);
|
||||
|
||||
_gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, NULL, GDK_AXIS_X, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, NULL, GDK_AXIS_Y, 0, 0, 1);
|
||||
}
|
||||
|
||||
struct wl_input_device *
|
||||
|
@@ -96,8 +96,8 @@ gdk_device_win32_init (GdkDeviceWin32 *device_win32)
|
||||
|
||||
device = GDK_DEVICE (device_win32);
|
||||
|
||||
_gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, NULL, GDK_AXIS_X, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, NULL, GDK_AXIS_Y, 0, 0, 1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@@ -593,6 +593,7 @@ _gdk_input_wintab_init_check (GdkDeviceManager *_device_manager)
|
||||
{
|
||||
_gdk_device_add_axis (GDK_DEVICE (device),
|
||||
GDK_NONE,
|
||||
NULL,
|
||||
GDK_AXIS_X,
|
||||
axis_x.axMin,
|
||||
axis_x.axMax,
|
||||
@@ -604,6 +605,7 @@ _gdk_input_wintab_init_check (GdkDeviceManager *_device_manager)
|
||||
{
|
||||
_gdk_device_add_axis (GDK_DEVICE (device),
|
||||
GDK_NONE,
|
||||
NULL,
|
||||
GDK_AXIS_Y,
|
||||
axis_y.axMin,
|
||||
axis_y.axMax,
|
||||
@@ -616,6 +618,7 @@ _gdk_input_wintab_init_check (GdkDeviceManager *_device_manager)
|
||||
{
|
||||
_gdk_device_add_axis (GDK_DEVICE (device),
|
||||
GDK_NONE,
|
||||
NULL,
|
||||
GDK_AXIS_PRESSURE,
|
||||
axis_npressure.axMin,
|
||||
axis_npressure.axMax,
|
||||
@@ -638,6 +641,7 @@ _gdk_input_wintab_init_check (GdkDeviceManager *_device_manager)
|
||||
*/
|
||||
_gdk_device_add_axis (GDK_DEVICE (device),
|
||||
GDK_NONE,
|
||||
NULL,
|
||||
GDK_AXIS_XTILT,
|
||||
-1000,
|
||||
1000,
|
||||
@@ -645,6 +649,7 @@ _gdk_input_wintab_init_check (GdkDeviceManager *_device_manager)
|
||||
|
||||
_gdk_device_add_axis (GDK_DEVICE (device),
|
||||
GDK_NONE,
|
||||
NULL,
|
||||
GDK_AXIS_YTILT,
|
||||
-1000,
|
||||
1000,
|
||||
|
@@ -104,8 +104,8 @@ gdk_x11_device_core_init (GdkX11DeviceCore *device_core)
|
||||
|
||||
device = GDK_DEVICE (device_core);
|
||||
|
||||
_gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, NULL, GDK_AXIS_X, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, GDK_NONE, NULL, GDK_AXIS_Y, 0, 0, 1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include "gdkdevicemanagerprivate-core.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkeventsequenceprivate.h"
|
||||
#include "gdkeventtranslator.h"
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdkintl.h"
|
||||
@@ -167,7 +168,8 @@ translate_valuator_class (GdkDisplay *display,
|
||||
static gboolean initialized = FALSE;
|
||||
static Atom label_atoms [GDK_AXIS_LAST] = { 0 };
|
||||
GdkAxisUse use = GDK_AXIS_IGNORE;
|
||||
GdkAtom label;
|
||||
GdkAtom atom;
|
||||
const char *label;
|
||||
gint i;
|
||||
|
||||
if (!initialized)
|
||||
@@ -178,6 +180,8 @@ translate_valuator_class (GdkDisplay *display,
|
||||
label_atoms [GDK_AXIS_XTILT] = gdk_x11_get_xatom_by_name_for_display (display, "Abs Tilt X");
|
||||
label_atoms [GDK_AXIS_YTILT] = gdk_x11_get_xatom_by_name_for_display (display, "Abs Tilt Y");
|
||||
label_atoms [GDK_AXIS_WHEEL] = gdk_x11_get_xatom_by_name_for_display (display, "Abs Wheel");
|
||||
label_atoms [GDK_AXIS_X_RELATIVE] = gdk_x11_get_xatom_by_name_for_display (display, "Rel X");
|
||||
label_atoms [GDK_AXIS_Y_RELATIVE] = gdk_x11_get_xatom_by_name_for_display (display, "Rel Y");
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
@@ -191,11 +195,17 @@ translate_valuator_class (GdkDisplay *display,
|
||||
}
|
||||
|
||||
if (valuator_label != None)
|
||||
label = gdk_x11_xatom_to_atom_for_display (display, valuator_label);
|
||||
{
|
||||
atom = gdk_x11_xatom_to_atom_for_display (display, valuator_label);
|
||||
label = gdk_x11_get_xatom_name_for_display (display, valuator_label);
|
||||
}
|
||||
else
|
||||
label = GDK_NONE;
|
||||
{
|
||||
atom = GDK_NONE;
|
||||
label = NULL;
|
||||
}
|
||||
|
||||
_gdk_device_add_axis (device, label, use, min, max, resolution);
|
||||
_gdk_device_add_axis (device, atom, label, use, min, max, resolution);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -855,6 +865,7 @@ set_user_time (GdkEvent *event)
|
||||
|
||||
static gdouble *
|
||||
translate_axes (GdkDevice *device,
|
||||
gdouble *saved_values,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GdkWindow *window,
|
||||
@@ -866,16 +877,22 @@ translate_axes (GdkDevice *device,
|
||||
|
||||
g_object_get (device, "n-axes", &n_axes, NULL);
|
||||
|
||||
axes = g_new0 (gdouble, n_axes);
|
||||
axes = g_new (gdouble, n_axes);
|
||||
vals = valuators->values;
|
||||
|
||||
for (i = 0; i < valuators->mask_len * 8; i++)
|
||||
for (i = 0; i < MIN (valuators->mask_len * 8, n_axes); i++)
|
||||
{
|
||||
GdkAxisUse use;
|
||||
gdouble val;
|
||||
|
||||
if (!XIMaskIsSet (valuators->mask, i))
|
||||
continue;
|
||||
{
|
||||
if (saved_values)
|
||||
axes[i] = saved_values[i];
|
||||
else
|
||||
axes[i] = 0.0;
|
||||
continue;
|
||||
}
|
||||
|
||||
use = gdk_device_get_axis_use (device, i);
|
||||
val = *vals++;
|
||||
@@ -898,6 +915,9 @@ translate_axes (GdkDevice *device,
|
||||
_gdk_device_translate_axis (device, i, val, &axes[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (saved_values)
|
||||
saved_values[i] = axes[i];
|
||||
}
|
||||
|
||||
return axes;
|
||||
@@ -1267,6 +1287,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
|
||||
event->button.axes = translate_axes (event->button.device,
|
||||
NULL,
|
||||
event->button.x,
|
||||
event->button.y,
|
||||
event->button.window,
|
||||
@@ -1368,6 +1389,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
event->motion.is_hint = FALSE;
|
||||
|
||||
event->motion.axes = translate_axes (event->motion.device,
|
||||
NULL,
|
||||
event->motion.x,
|
||||
event->motion.y,
|
||||
event->motion.window,
|
||||
@@ -1417,7 +1439,22 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
|
||||
event->touch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
|
||||
if (ev->evtype == XI_TouchBegin)
|
||||
{
|
||||
event->touch.state |= GDK_BUTTON1_MASK;
|
||||
event->touch.sequence = gdk_event_sequence_new (event->touch.device, xev->detail);
|
||||
gdk_event_sequence_ref (event->touch.sequence);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no ref here, we want the sequence to go away with the event */
|
||||
event->touch.sequence = gdk_event_sequence_lookup (event->touch.device, xev->detail);
|
||||
}
|
||||
|
||||
event->touch.axes = translate_axes (event->touch.device,
|
||||
event->touch.sequence->axes,
|
||||
event->touch.x,
|
||||
event->touch.y,
|
||||
event->touch.window,
|
||||
@@ -1432,13 +1469,6 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_Y, &event->touch.y);
|
||||
}
|
||||
|
||||
event->touch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
|
||||
if (ev->evtype == XI_TouchBegin)
|
||||
event->touch.state |= GDK_BUTTON1_MASK;
|
||||
|
||||
event->touch.sequence = GUINT_TO_POINTER (xev->detail);
|
||||
|
||||
if (xev->flags & XITouchEmulatingPointer)
|
||||
{
|
||||
event->touch.emulating_pointer = TRUE;
|
||||
@@ -1471,7 +1501,6 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
xev->flags & XITouchEmulatingPointer));
|
||||
|
||||
event->touch.window = window;
|
||||
event->touch.sequence = GUINT_TO_POINTER (xev->detail);
|
||||
event->touch.type = GDK_TOUCH_UPDATE;
|
||||
event->touch.time = xev->time;
|
||||
event->touch.x = (gdouble) xev->event_x;
|
||||
@@ -1486,6 +1515,9 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
|
||||
event->touch.sequence = gdk_event_sequence_lookup (event->touch.device, xev->detail);
|
||||
gdk_event_sequence_ref (event->touch.sequence);
|
||||
|
||||
event->touch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
|
||||
event->touch.state |= GDK_BUTTON1_MASK;
|
||||
@@ -1497,6 +1529,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
}
|
||||
|
||||
event->touch.axes = translate_axes (event->touch.device,
|
||||
event->touch.sequence->axes,
|
||||
event->touch.x,
|
||||
event->touch.y,
|
||||
event->touch.window,
|
||||
|
@@ -237,6 +237,8 @@ gtk_public_h_sources = \
|
||||
gtkentrycompletion.h \
|
||||
gtkenums.h \
|
||||
gtkeventbox.h \
|
||||
gtkeventrecognizer.h \
|
||||
gtkeventtracker.h \
|
||||
gtkexpander.h \
|
||||
gtkfilechooser.h \
|
||||
gtkfilechooserbutton.h \
|
||||
@@ -249,6 +251,8 @@ gtk_public_h_sources = \
|
||||
gtkfontchooserdialog.h \
|
||||
gtkfontchooserwidget.h \
|
||||
gtkframe.h \
|
||||
gtkgesture.h \
|
||||
gtkgesturerecognizer.h \
|
||||
gtkgradient.h \
|
||||
gtkgrid.h \
|
||||
gtkiconfactory.h \
|
||||
@@ -286,6 +290,8 @@ gtk_public_h_sources = \
|
||||
gtkpagesetup.h \
|
||||
gtkpaned.h \
|
||||
gtkpapersize.h \
|
||||
gtkpinchpangesture.h \
|
||||
gtkpinchpanrecognizer.h \
|
||||
gtkplug.h \
|
||||
gtkprintcontext.h \
|
||||
gtkprintoperation.h \
|
||||
@@ -313,6 +319,7 @@ gtk_public_h_sources = \
|
||||
gtkseparator.h \
|
||||
gtkseparatormenuitem.h \
|
||||
gtkseparatortoolitem.h \
|
||||
gtksequence.h \
|
||||
gtksettings.h \
|
||||
gtkshow.h \
|
||||
gtksizegroup.h \
|
||||
@@ -326,6 +333,8 @@ gtk_public_h_sources = \
|
||||
gtkstylecontext.h \
|
||||
gtkstyleproperties.h \
|
||||
gtkstyleprovider.h \
|
||||
gtkswipegesture.h \
|
||||
gtkswiperecognizer.h \
|
||||
gtkswitch.h \
|
||||
gtksymboliccolor.h \
|
||||
gtktestutils.h \
|
||||
@@ -486,6 +495,7 @@ gtk_private_h_sources = \
|
||||
gtksearchengine.h \
|
||||
gtksearchenginesimple.h \
|
||||
gtkselectionprivate.h \
|
||||
gtksequencetrackerprivate.h \
|
||||
gtksettingsprivate.h \
|
||||
gtkshadowprivate.h \
|
||||
gtksizegroup-private.h \
|
||||
@@ -644,6 +654,8 @@ gtk_base_c_sources = \
|
||||
gtkentrybuffer.c \
|
||||
gtkentrycompletion.c \
|
||||
gtkeventbox.c \
|
||||
gtkeventrecognizer.c \
|
||||
gtkeventtracker.c \
|
||||
gtkexpander.c \
|
||||
gtkfilechooser.c \
|
||||
gtkfilechooserbutton.c \
|
||||
@@ -663,6 +675,8 @@ gtk_base_c_sources = \
|
||||
gtkfontchooserutils.c \
|
||||
gtkfontchooserwidget.c \
|
||||
gtkframe.c \
|
||||
gtkgesture.c \
|
||||
gtkgesturerecognizer.c \
|
||||
gtkgradient.c \
|
||||
gtkgrid.c \
|
||||
gtkiconcache.c \
|
||||
@@ -710,6 +724,8 @@ gtk_base_c_sources = \
|
||||
gtkpango.c \
|
||||
gtkpapersize.c \
|
||||
gtkpathbar.c \
|
||||
gtkpinchpangesture.c \
|
||||
gtkpinchpanrecognizer.c \
|
||||
gtkpressandhold.c \
|
||||
gtkprintcontext.c \
|
||||
gtkprintoperation.c \
|
||||
@@ -745,6 +761,8 @@ gtk_base_c_sources = \
|
||||
gtkseparator.c \
|
||||
gtkseparatormenuitem.c \
|
||||
gtkseparatortoolitem.c \
|
||||
gtksequence.c \
|
||||
gtksequencetracker.c \
|
||||
gtksettings.c \
|
||||
gtksizegroup.c \
|
||||
gtksizerequest.c \
|
||||
@@ -760,6 +778,8 @@ gtk_base_c_sources = \
|
||||
gtkstyleproperty.c \
|
||||
gtkstyleprovider.c \
|
||||
gtkstyleproviderprivate.c \
|
||||
gtkswipegesture.c \
|
||||
gtkswiperecognizer.c \
|
||||
gtkswitch.c \
|
||||
gtksymboliccolor.c \
|
||||
gtktestutils.c \
|
||||
|
@@ -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>
|
||||
@@ -107,6 +109,8 @@
|
||||
#include <gtk/gtkfontchooserdialog.h>
|
||||
#include <gtk/gtkfontchooserwidget.h>
|
||||
#include <gtk/gtkframe.h>
|
||||
#include <gtk/gtkgesture.h>
|
||||
#include <gtk/gtkgesturerecognizer.h>
|
||||
#include <gtk/gtkgradient.h>
|
||||
#include <gtk/gtkgrid.h>
|
||||
#include <gtk/gtkiconfactory.h>
|
||||
@@ -143,6 +147,8 @@
|
||||
#include <gtk/gtkpagesetup.h>
|
||||
#include <gtk/gtkpapersize.h>
|
||||
#include <gtk/gtkpaned.h>
|
||||
#include <gtk/gtkpinchpangesture.h>
|
||||
#include <gtk/gtkpinchpanrecognizer.h>
|
||||
#include <gtk/gtkprintcontext.h>
|
||||
#include <gtk/gtkprintoperation.h>
|
||||
#include <gtk/gtkprintoperationpreview.h>
|
||||
@@ -169,6 +175,7 @@
|
||||
#include <gtk/gtkseparator.h>
|
||||
#include <gtk/gtkseparatormenuitem.h>
|
||||
#include <gtk/gtkseparatortoolitem.h>
|
||||
#include <gtk/gtksequence.h>
|
||||
#include <gtk/gtksettings.h>
|
||||
#include <gtk/gtkshow.h>
|
||||
#include <gtk/gtksizegroup.h>
|
||||
@@ -181,6 +188,8 @@
|
||||
#include <gtk/gtkstylecontext.h>
|
||||
#include <gtk/gtkstyleproperties.h>
|
||||
#include <gtk/gtkstyleprovider.h>
|
||||
#include <gtk/gtkswipegesture.h>
|
||||
#include <gtk/gtkswiperecognizer.h>
|
||||
#include <gtk/gtkswitch.h>
|
||||
#include <gtk/gtksymboliccolor.h>
|
||||
#include <gtk/gtktextattributes.h>
|
||||
|
262
gtk/gtkeventrecognizer.c
Normal file
262
gtk/gtkeventrecognizer.c
Normal file
@@ -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);
|
||||
}
|
||||
|
104
gtk/gtkeventrecognizer.h
Normal file
104
gtk/gtkeventrecognizer.h
Normal file
@@ -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__ */
|
35
gtk/gtkeventrecognizerprivate.h
Normal file
35
gtk/gtkeventrecognizerprivate.h
Normal file
@@ -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__ */
|
456
gtk/gtkeventtracker.c
Normal file
456
gtk/gtkeventtracker.c
Normal file
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
GtkEventTracker *prev;
|
||||
GtkEventTracker *next;
|
||||
|
||||
guint started :1;
|
||||
guint finished :1;
|
||||
guint cancelled :1;
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GtkEventTracker, gtk_event_tracker, G_TYPE_OBJECT)
|
||||
|
||||
static GtkEventTracker *first_tracker = NULL;
|
||||
static GtkEventTracker *last_tracker = NULL;
|
||||
|
||||
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;
|
||||
|
||||
if (priv->prev)
|
||||
priv->prev->priv->next = priv->next;
|
||||
else
|
||||
first_tracker = priv->next;
|
||||
if (priv->next)
|
||||
priv->next->priv->prev = priv->prev;
|
||||
else
|
||||
last_tracker = priv->prev;
|
||||
|
||||
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)
|
||||
{
|
||||
GtkEventTrackerPrivate *priv = tracker->priv;
|
||||
|
||||
g_assert (priv->prev == NULL);
|
||||
g_assert (priv->next == NULL);
|
||||
|
||||
priv->prev = last_tracker;
|
||||
|
||||
if (priv->prev)
|
||||
priv->prev->priv->next = tracker;
|
||||
else
|
||||
first_tracker = tracker;
|
||||
|
||||
last_tracker = tracker;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_event_trackers_invoke (GdkEvent *event)
|
||||
{
|
||||
GtkEventTracker *tracker, *next;
|
||||
gboolean eat_event = FALSE;
|
||||
|
||||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
|
||||
for (tracker = first_tracker; tracker; tracker = next)
|
||||
{
|
||||
g_object_ref (tracker);
|
||||
|
||||
eat_event |= _gtk_event_recognizer_track (tracker->priv->recognizer,
|
||||
tracker,
|
||||
event);
|
||||
|
||||
next = tracker->priv->next;
|
||||
|
||||
g_object_unref (tracker);
|
||||
}
|
||||
|
||||
return eat_event;
|
||||
}
|
||||
|
||||
GtkEventTracker *
|
||||
_gtk_event_tracker_get_first (void)
|
||||
{
|
||||
return first_tracker;
|
||||
}
|
||||
|
||||
GtkEventTracker *
|
||||
_gtk_event_tracker_get_next (GtkEventTracker *tracker)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_EVENT_TRACKER (tracker), NULL);
|
||||
|
||||
return tracker->priv->next;
|
||||
}
|
||||
|
81
gtk/gtkeventtracker.h
Normal file
81
gtk/gtkeventtracker.h
Normal file
@@ -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__ */
|
36
gtk/gtkeventtrackerprivate.h
Normal file
36
gtk/gtkeventtrackerprivate.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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);
|
||||
|
||||
GtkEventTracker * _gtk_event_tracker_get_first (void);
|
||||
GtkEventTracker * _gtk_event_tracker_get_next (GtkEventTracker *tracker);
|
||||
|
||||
|
||||
#endif /* __GTK_EVENT_TRACKER_PRIVATE_H__ */
|
371
gtk/gtkgesture.c
Normal file
371
gtk/gtkgesture.c
Normal file
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
* 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 "gtkgesture.h"
|
||||
|
||||
#include "gtkeventtrackerprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtksequence.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtkgesture
|
||||
* @Short_description: Gesture recognition
|
||||
* @Title: GtkGesture
|
||||
* @See_also: #GtkGestureRecognizer, #GtkEventTracker
|
||||
*
|
||||
* The #GtkGesture object - or rather its subclasses - are #GtkEventTrackers
|
||||
* that cooperates with other #GtkGestures on the recognizing of
|
||||
* #GdkSequences.
|
||||
*
|
||||
* #GtkGesture was added in GTK 3.6.
|
||||
*/
|
||||
|
||||
|
||||
enum {
|
||||
PROP_0
|
||||
};
|
||||
|
||||
struct _GtkGesturePrivate {
|
||||
GPtrArray *sequences;
|
||||
|
||||
guint accepted :1;
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GtkGesture, gtk_gesture, GTK_TYPE_EVENT_TRACKER)
|
||||
|
||||
static void
|
||||
gtk_gesture_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
//GtkGesture *gesture = GTK_GESTURE (object);
|
||||
//GtkGesturePrivate *priv = gesture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gesture_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
//GtkGesture *gesture = GTK_GESTURE (object);
|
||||
//GtkGesturePrivate *priv = gesture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gesture_remove_all_sequences (GtkGesture *gesture)
|
||||
{
|
||||
GtkGesturePrivate *priv = gesture->priv;
|
||||
|
||||
if (priv->accepted)
|
||||
return;
|
||||
|
||||
while (priv->sequences->len > 0)
|
||||
gtk_gesture_remove_sequence (gesture, g_ptr_array_index (priv->sequences,
|
||||
priv->sequences->len - 1));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gesture_dispose (GObject *object)
|
||||
{
|
||||
GtkGesture *gesture = GTK_GESTURE (object);
|
||||
GtkGesturePrivate *priv = gesture->priv;
|
||||
|
||||
gtk_gesture_remove_all_sequences (gesture);
|
||||
|
||||
g_ptr_array_unref (priv->sequences);
|
||||
priv->sequences = NULL;
|
||||
|
||||
G_OBJECT_CLASS (gtk_gesture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gesture_default_sequence_given (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gesture_default_sequence_stolen (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence,
|
||||
GtkGesture *stealer)
|
||||
{
|
||||
gtk_event_tracker_cancel (GTK_EVENT_TRACKER (gesture));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gesture_class_init (GtkGestureClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
klass->sequence_stolen = gtk_gesture_default_sequence_stolen;
|
||||
klass->sequence_given = gtk_gesture_default_sequence_given;
|
||||
|
||||
object_class->dispose = gtk_gesture_dispose;
|
||||
object_class->set_property = gtk_gesture_set_property;
|
||||
object_class->get_property = gtk_gesture_get_property;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GtkGesturePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gesture_init (GtkGesture *gesture)
|
||||
{
|
||||
GtkGesturePrivate *priv;
|
||||
|
||||
priv = gesture->priv = G_TYPE_INSTANCE_GET_PRIVATE (gesture,
|
||||
GTK_TYPE_GESTURE,
|
||||
GtkGesturePrivate);
|
||||
|
||||
priv->sequences = g_ptr_array_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gesture_accept_sequence (GtkGesture *stealer,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
GtkEventTracker *tracker, *next;
|
||||
|
||||
for (tracker = _gtk_event_tracker_get_next (GTK_EVENT_TRACKER (stealer));
|
||||
tracker;
|
||||
tracker = next)
|
||||
{
|
||||
GtkGesture *gesture;
|
||||
|
||||
next = _gtk_event_tracker_get_next (tracker);
|
||||
|
||||
if (!GTK_IS_GESTURE (tracker))
|
||||
continue;
|
||||
|
||||
gesture = GTK_GESTURE (tracker);
|
||||
|
||||
if (!gtk_gesture_has_sequence (gesture, sequence))
|
||||
continue;
|
||||
|
||||
/* need some magic here because a lot of gestures wanna cancel themselves
|
||||
* in this vfunc */
|
||||
g_object_ref (gesture);
|
||||
|
||||
GTK_GESTURE_GET_CLASS (gesture)->sequence_stolen (gesture,
|
||||
sequence,
|
||||
stealer);
|
||||
|
||||
next = _gtk_event_tracker_get_next (tracker);
|
||||
g_object_unref (gesture);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gesture_give_sequence (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
GtkGestureClass *klass = GTK_GESTURE_GET_CLASS (gesture);
|
||||
|
||||
klass->sequence_given (gesture, sequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_gesture_add_sequence:
|
||||
* @gesture: the gesture
|
||||
* @sequence: the sequence to add to @gesture
|
||||
*
|
||||
* Marks @gesture as working with @sequence. If @gesture is or gets
|
||||
* accepted, other gestures will be notified about @gesture using @sequence
|
||||
* and @gesture will be notified if other gestures use @sequence.
|
||||
**/
|
||||
void
|
||||
gtk_gesture_add_sequence (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
GtkGesturePrivate *priv;
|
||||
gboolean new_owner;
|
||||
|
||||
g_return_if_fail (GTK_IS_GESTURE (gesture));
|
||||
g_return_if_fail (sequence != NULL);
|
||||
|
||||
priv = gesture->priv;
|
||||
new_owner = gtk_sequence_get_owner (sequence) == NULL;
|
||||
|
||||
g_ptr_array_add (priv->sequences, sequence);
|
||||
if (new_owner)
|
||||
gtk_gesture_give_sequence (gesture, sequence);
|
||||
if (priv->accepted)
|
||||
gtk_gesture_accept_sequence (gesture, sequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_gesture_remove_sequence:
|
||||
* @gesture: the gesture
|
||||
* @sequence: the sequence to remove. It must have been added with
|
||||
* gtk_gesture_add_sequence() previously.
|
||||
*
|
||||
* Removes the sequence from the list of tracked sequences. This function
|
||||
* does nothing if the gesture has been accepted.
|
||||
*
|
||||
* This function should only be called from #GtkGesture implementations.
|
||||
**/
|
||||
void
|
||||
gtk_gesture_remove_sequence (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
GtkGesturePrivate *priv;
|
||||
gboolean was_owner;
|
||||
|
||||
g_return_if_fail (GTK_IS_GESTURE (gesture));
|
||||
g_return_if_fail (sequence != NULL);
|
||||
|
||||
priv = gesture->priv;
|
||||
|
||||
if (priv->accepted)
|
||||
return;
|
||||
|
||||
was_owner = gtk_gesture_owns_sequence (gesture, sequence);
|
||||
|
||||
g_ptr_array_remove (priv->sequences, sequence);
|
||||
|
||||
if (was_owner)
|
||||
{
|
||||
GtkEventTracker *tracker;
|
||||
|
||||
for (tracker = _gtk_event_tracker_get_next (GTK_EVENT_TRACKER (gesture));
|
||||
tracker;
|
||||
tracker = _gtk_event_tracker_get_next (tracker))
|
||||
{
|
||||
if (GTK_IS_GESTURE (tracker) &&
|
||||
gtk_gesture_has_sequence (GTK_GESTURE (tracker), sequence))
|
||||
{
|
||||
gtk_gesture_give_sequence (GTK_GESTURE (tracker), sequence);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_gesture_has_sequence (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
GtkGesturePrivate *priv;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_GESTURE (gesture), FALSE);
|
||||
g_return_val_if_fail (sequence != NULL, FALSE);
|
||||
|
||||
priv = gesture->priv;
|
||||
|
||||
for (i = 0; i < priv->sequences->len; i++)
|
||||
{
|
||||
if (g_ptr_array_index (priv->sequences, i) == sequence)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_gesture_owns_sequence (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_GESTURE (gesture), FALSE);
|
||||
g_return_val_if_fail (sequence != NULL, FALSE);
|
||||
|
||||
return gtk_sequence_get_owner (sequence) == gesture;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_gesture_owns_all_sequences (GtkGesture *gesture)
|
||||
{
|
||||
GtkGesturePrivate *priv;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_GESTURE (gesture), FALSE);
|
||||
|
||||
priv = gesture->priv;
|
||||
|
||||
for (i = 0; i < priv->sequences->len; i++)
|
||||
{
|
||||
if (!gtk_gesture_owns_sequence (gesture,
|
||||
g_ptr_array_index (priv->sequences, i)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_gesture_accept:
|
||||
* @gesture: the gesture to accept
|
||||
*
|
||||
* Accepts @gesture if it hasn't been accepted yet. An accepted gesture
|
||||
* is a gesture that will successfully finish to recognize itself.
|
||||
*
|
||||
* If a gesture marks itself as accepted, all its sequences that were
|
||||
* added with gtk_gesture_add_sequence() are assumed to be consumed by
|
||||
* this @gesture and other gestures will be notified about this.
|
||||
*
|
||||
* This function should only be called from #GtkGesture implementations.
|
||||
**/
|
||||
void
|
||||
gtk_gesture_accept (GtkGesture *gesture)
|
||||
{
|
||||
GtkGesturePrivate *priv;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (GTK_IS_GESTURE (gesture));
|
||||
|
||||
priv = gesture->priv;
|
||||
|
||||
if (priv->accepted)
|
||||
return;
|
||||
|
||||
priv->accepted = TRUE;
|
||||
|
||||
for (i = 0; i < priv->sequences->len; i++)
|
||||
{
|
||||
gtk_gesture_accept_sequence (gesture,
|
||||
g_ptr_array_index (priv->sequences, i));
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_gesture_is_accepted (GtkGesture *gesture)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_GESTURE (gesture), FALSE);
|
||||
|
||||
return gesture->priv->accepted;
|
||||
}
|
||||
|
89
gtk/gtkgesture.h
Normal file
89
gtk/gtkgesture.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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_GESTURE_H__
|
||||
#define __GTK_GESTURE_H__
|
||||
|
||||
#include <gtk/gtkeventtracker.h>
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_GESTURE (gtk_gesture_get_type ())
|
||||
#define GTK_GESTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_GESTURE, GtkGesture))
|
||||
#define GTK_GESTURE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_GESTURE, GtkGestureClass))
|
||||
#define GTK_IS_GESTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_GESTURE))
|
||||
#define GTK_IS_GESTURE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_GESTURE))
|
||||
#define GTK_GESTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_GESTURE, GtkGestureClass))
|
||||
|
||||
typedef struct _GtkGesture GtkGesture;
|
||||
typedef struct _GtkGestureClass GtkGestureClass;
|
||||
typedef struct _GtkGesturePrivate GtkGesturePrivate;
|
||||
|
||||
struct _GtkGesture
|
||||
{
|
||||
GtkEventTracker parent;
|
||||
|
||||
GtkGesturePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkGestureClass
|
||||
{
|
||||
GtkEventTrackerClass parent_class;
|
||||
|
||||
void (* sequence_given) (GtkGesture * gesture,
|
||||
GdkEventSequence * sequence);
|
||||
void (* sequence_stolen) (GtkGesture * gesture,
|
||||
GdkEventSequence * sequence,
|
||||
GtkGesture * accepter);
|
||||
|
||||
/* 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_gesture_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void gtk_gesture_add_sequence (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence);
|
||||
void gtk_gesture_remove_sequence (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence);
|
||||
gboolean gtk_gesture_has_sequence (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence);
|
||||
gboolean gtk_gesture_owns_sequence (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence);
|
||||
gboolean gtk_gesture_owns_all_sequences(GtkGesture *gesture);
|
||||
|
||||
void gtk_gesture_accept (GtkGesture *gesture);
|
||||
gboolean gtk_gesture_is_accepted (GtkGesture *gesture);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_GESTURE_H__ */
|
60
gtk/gtkgesturerecognizer.c
Normal file
60
gtk/gtkgesturerecognizer.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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 "gtkgesturerecognizer.h"
|
||||
|
||||
#include "gtkgesture.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtkgesturerecognizer
|
||||
* @Short_description: Recognizes gestures
|
||||
* @Title: GtkGestureRecognizer
|
||||
* @See_also: #GtkGesture, #GtkEventRecognizer
|
||||
*
|
||||
* FIXME
|
||||
*
|
||||
* #GtkGestureRecognizer was added in GTK 3.6.
|
||||
*/
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GtkGestureRecognizer, gtk_gesture_recognizer, GTK_TYPE_EVENT_RECOGNIZER)
|
||||
|
||||
static void
|
||||
gtk_gesture_recognizer_finished (GtkEventRecognizer *recognizer,
|
||||
GtkEventTracker *tracker)
|
||||
{
|
||||
gtk_gesture_accept (GTK_GESTURE (tracker));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gesture_recognizer_class_init (GtkGestureRecognizerClass *klass)
|
||||
{
|
||||
GtkEventRecognizerClass *recognizer_class = GTK_EVENT_RECOGNIZER_CLASS (klass);
|
||||
|
||||
recognizer_class->finished = gtk_gesture_recognizer_finished;
|
||||
|
||||
gtk_event_recognizer_class_set_tracker_type (recognizer_class, GTK_TYPE_GESTURE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gesture_recognizer_init (GtkGestureRecognizer *recognizer)
|
||||
{
|
||||
}
|
60
gtk/gtkgesturerecognizer.h
Normal file
60
gtk/gtkgesturerecognizer.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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_GESTURE_RECOGNIZER_H__
|
||||
#define __GTK_GESTURE_RECOGNIZER_H__
|
||||
|
||||
#include <gtk/gtkeventrecognizer.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_GESTURE_RECOGNIZER (gtk_gesture_recognizer_get_type ())
|
||||
#define GTK_GESTURE_RECOGNIZER(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_GESTURE_RECOGNIZER, GtkGestureRecognizer))
|
||||
#define GTK_GESTURE_RECOGNIZER_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_GESTURE_RECOGNIZER, GtkGestureRecognizerClass))
|
||||
#define GTK_IS_GESTURE_RECOGNIZER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_GESTURE_RECOGNIZER))
|
||||
#define GTK_IS_GESTURE_RECOGNIZER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_GESTURE_RECOGNIZER))
|
||||
#define GTK_GESTURE_RECOGNIZER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_GESTURE_RECOGNIZER, GtkGestureRecognizerClass))
|
||||
|
||||
typedef struct _GtkGestureRecognizer GtkGestureRecognizer;
|
||||
typedef struct _GtkGestureRecognizerClass GtkGestureRecognizerClass;
|
||||
typedef struct _GtkGestureRecognizerPrivate GtkGestureRecognizerPrivate;
|
||||
|
||||
struct _GtkGestureRecognizer
|
||||
{
|
||||
GtkEventRecognizer parent;
|
||||
|
||||
GtkGestureRecognizerPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkGestureRecognizerClass
|
||||
{
|
||||
GtkEventRecognizerClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_gesture_recognizer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_GESTURE_RECOGNIZER_H__ */
|
@@ -114,6 +114,7 @@
|
||||
#include "gtkclipboard.h"
|
||||
#include "gtkdebug.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkeventtrackerprivate.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtkmenu.h"
|
||||
#include "gtkmodules.h"
|
||||
@@ -1647,6 +1648,9 @@ gtk_main_do_event (GdkEvent *event)
|
||||
case GDK_WINDOW_STATE:
|
||||
case GDK_GRAB_BROKEN:
|
||||
case GDK_DAMAGE:
|
||||
if (_gtk_event_trackers_invoke (event))
|
||||
break;
|
||||
|
||||
if (!_gtk_widget_captured_event (event_widget, event))
|
||||
gtk_widget_event (event_widget, event);
|
||||
break;
|
||||
@@ -1656,6 +1660,9 @@ gtk_main_do_event (GdkEvent *event)
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
case GDK_TOUCH_BEGIN:
|
||||
if (_gtk_event_trackers_invoke (event))
|
||||
break;
|
||||
|
||||
if (!_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
|
||||
gtk_propagate_event (grab_widget, event);
|
||||
break;
|
||||
@@ -1709,11 +1716,17 @@ gtk_main_do_event (GdkEvent *event)
|
||||
case GDK_TOUCH_UPDATE:
|
||||
case GDK_TOUCH_END:
|
||||
case GDK_TOUCH_CANCEL:
|
||||
if (_gtk_event_trackers_invoke (event))
|
||||
break;
|
||||
|
||||
if (!_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
|
||||
gtk_propagate_event (grab_widget, event);
|
||||
break;
|
||||
|
||||
case GDK_ENTER_NOTIFY:
|
||||
if (_gtk_event_trackers_invoke (event))
|
||||
break;
|
||||
|
||||
if (event->crossing.detail != GDK_NOTIFY_VIRTUAL &&
|
||||
event->crossing.detail != GDK_NOTIFY_NONLINEAR_VIRTUAL)
|
||||
_gtk_widget_set_device_window (event_widget,
|
||||
@@ -1725,6 +1738,9 @@ gtk_main_do_event (GdkEvent *event)
|
||||
break;
|
||||
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
if (_gtk_event_trackers_invoke (event))
|
||||
break;
|
||||
|
||||
if (event->crossing.detail != GDK_NOTIFY_VIRTUAL &&
|
||||
event->crossing.detail != GDK_NOTIFY_NONLINEAR_VIRTUAL)
|
||||
_gtk_widget_set_device_window (event_widget,
|
||||
|
312
gtk/gtkpinchpangesture.c
Normal file
312
gtk/gtkpinchpangesture.c
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* 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 "gtkpinchpangesture.h"
|
||||
|
||||
#include "gtksequencetrackerprivate.h"
|
||||
#include "gtkpinchpanrecognizer.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* SECTION:gtkpinchpangesture
|
||||
* @Short_description: Gesture for pinch, pan and rotation
|
||||
* @Title: GtkPinchPanGesture
|
||||
* @See_also: #GtkPinchPanRecognizer
|
||||
*
|
||||
* The #GtkPinchPanGesture object is used to to track pinch, pan and rotation
|
||||
* gestures. These are usually used to implement scrolling, zooming and rotation
|
||||
* respectively on scrollable widgets.
|
||||
*
|
||||
* #GtkPinchPanGesture was added in GTK 3.6.
|
||||
*/
|
||||
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
};
|
||||
|
||||
struct _GtkPinchPanGesturePrivate {
|
||||
GtkSequenceTracker *sequence[2];
|
||||
double initial_distance;
|
||||
double initial_angle;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkPinchPanGesture, gtk_pinch_pan_gesture, GTK_TYPE_GESTURE)
|
||||
|
||||
static void
|
||||
gtk_pinch_pan_gesture_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
//GtkPinchPanGesture *gesture = GTK_PINCH_PAN_GESTURE (object);
|
||||
//GtkPinchPanGesturePrivate *priv = gesture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_pinch_pan_gesture_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
//GtkPinchPanGesture *gesture = GTK_PINCH_PAN_GESTURE (object);
|
||||
//GtkPinchPanGesturePrivate *priv = gesture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_pinch_pan_gesture_dispose (GObject *object)
|
||||
{
|
||||
//GtkPinchPanGesture *gesture = GTK_PINCH_PAN_GESTURE (object);
|
||||
|
||||
G_OBJECT_CLASS (gtk_pinch_pan_gesture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_pinch_pan_gesture_class_init (GtkPinchPanGestureClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_pinch_pan_gesture_dispose;
|
||||
object_class->set_property = gtk_pinch_pan_gesture_set_property;
|
||||
object_class->get_property = gtk_pinch_pan_gesture_get_property;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GtkPinchPanGesturePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_pinch_pan_gesture_init (GtkPinchPanGesture *gesture)
|
||||
{
|
||||
gesture->priv = G_TYPE_INSTANCE_GET_PRIVATE (gesture,
|
||||
GTK_TYPE_PINCH_PAN_GESTURE,
|
||||
GtkPinchPanGesturePrivate);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_pinch_pan_gesture_begin (GtkPinchPanGesture *gesture,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GtkPinchPanGesturePrivate *priv = gesture->priv;
|
||||
|
||||
if (priv->sequence[1] != NULL)
|
||||
return FALSE;
|
||||
|
||||
if (priv->sequence[0] == NULL)
|
||||
{
|
||||
priv->sequence[0] = _gtk_sequence_tracker_new (event);
|
||||
gtk_gesture_add_sequence (GTK_GESTURE (gesture), event->touch.sequence);
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->sequence[1] = _gtk_sequence_tracker_new (event);
|
||||
gtk_gesture_add_sequence (GTK_GESTURE (gesture), event->touch.sequence);
|
||||
}
|
||||
|
||||
if (priv->sequence[1])
|
||||
{
|
||||
double x, y;
|
||||
_gtk_sequence_tracker_compute_distance (priv->sequence[0],
|
||||
priv->sequence[1],
|
||||
&x, &y);
|
||||
priv->initial_distance = sqrt (x * x + y * y);
|
||||
priv->initial_angle = atan2 (y, x);
|
||||
gtk_event_tracker_start (GTK_EVENT_TRACKER (gesture));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_pinch_pan_gesture_update_for_event (GtkPinchPanGesture *gesture,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GtkPinchPanGesturePrivate *priv = gesture->priv;
|
||||
gboolean result = FALSE;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (priv->sequence[i])
|
||||
result |= _gtk_sequence_tracker_update (priv->sequence[i], event);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_pinch_pan_gesture_update (GtkPinchPanGesture *gesture,
|
||||
GdkEvent *event)
|
||||
{
|
||||
if (gtk_pinch_pan_gesture_update_for_event (gesture, event) &&
|
||||
gtk_event_tracker_is_started (GTK_EVENT_TRACKER (gesture)))
|
||||
gtk_event_tracker_update (GTK_EVENT_TRACKER (gesture));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_pinch_pan_gesture_end (GtkPinchPanGesture *gesture,
|
||||
GdkEvent *event)
|
||||
{
|
||||
if (gtk_pinch_pan_gesture_update_for_event (gesture, event))
|
||||
{
|
||||
if (gesture->priv->sequence[1])
|
||||
gtk_event_tracker_finish (GTK_EVENT_TRACKER (gesture));
|
||||
else
|
||||
gtk_event_tracker_cancel (GTK_EVENT_TRACKER (gesture));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_pinch_pan_gesture_cancel (GtkPinchPanGesture *gesture,
|
||||
GdkEvent *event)
|
||||
{
|
||||
if (gtk_pinch_pan_gesture_update_for_event (gesture, event))
|
||||
gtk_event_tracker_cancel (GTK_EVENT_TRACKER (gesture));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_pinch_pan_gesture_get_offset (GtkPinchPanGesture *gesture,
|
||||
double *x,
|
||||
double *y)
|
||||
{
|
||||
GtkPinchPanGesturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_PINCH_PAN_GESTURE (gesture));
|
||||
|
||||
priv = gesture->priv;
|
||||
|
||||
if (!gtk_event_tracker_is_started (GTK_EVENT_TRACKER (gesture)) ||
|
||||
gtk_event_tracker_is_cancelled (GTK_EVENT_TRACKER (gesture)))
|
||||
{
|
||||
if (x)
|
||||
*x = 0;
|
||||
if (y)
|
||||
*y = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (x)
|
||||
*x = (_gtk_sequence_tracker_get_x_offset (priv->sequence[0])
|
||||
+ _gtk_sequence_tracker_get_x_offset (priv->sequence[1])) / 2;
|
||||
if (y)
|
||||
*y = (_gtk_sequence_tracker_get_y_offset (priv->sequence[0])
|
||||
+ _gtk_sequence_tracker_get_y_offset (priv->sequence[1])) / 2;
|
||||
}
|
||||
|
||||
double
|
||||
gtk_pinch_pan_gesture_get_x_offset (GtkPinchPanGesture *gesture)
|
||||
{
|
||||
GtkPinchPanGesturePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_PINCH_PAN_GESTURE (gesture), 0.0);
|
||||
|
||||
priv = gesture->priv;
|
||||
|
||||
if (!gtk_event_tracker_is_started (GTK_EVENT_TRACKER (gesture)) ||
|
||||
gtk_event_tracker_is_cancelled (GTK_EVENT_TRACKER (gesture)))
|
||||
return 0;
|
||||
|
||||
return (_gtk_sequence_tracker_get_x_offset (priv->sequence[0])
|
||||
+ _gtk_sequence_tracker_get_x_offset (priv->sequence[1])) / 2;
|
||||
}
|
||||
|
||||
double
|
||||
gtk_pinch_pan_gesture_get_y_offset (GtkPinchPanGesture *gesture)
|
||||
{
|
||||
GtkPinchPanGesturePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_PINCH_PAN_GESTURE (gesture), 0.0);
|
||||
|
||||
priv = gesture->priv;
|
||||
|
||||
if (!gtk_event_tracker_is_started (GTK_EVENT_TRACKER (gesture)) ||
|
||||
gtk_event_tracker_is_cancelled (GTK_EVENT_TRACKER (gesture)))
|
||||
return 0;
|
||||
|
||||
return (_gtk_sequence_tracker_get_y_offset (priv->sequence[0])
|
||||
+ _gtk_sequence_tracker_get_y_offset (priv->sequence[1])) / 2;
|
||||
}
|
||||
|
||||
double
|
||||
gtk_pinch_pan_gesture_get_rotation (GtkPinchPanGesture *gesture)
|
||||
{
|
||||
GtkPinchPanGesturePrivate *priv;
|
||||
double x, y, angle;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_PINCH_PAN_GESTURE (gesture), 0.0);
|
||||
|
||||
priv = gesture->priv;
|
||||
|
||||
if (!gtk_event_tracker_is_started (GTK_EVENT_TRACKER (gesture)) ||
|
||||
gtk_event_tracker_is_cancelled (GTK_EVENT_TRACKER (gesture)))
|
||||
return 0;
|
||||
|
||||
_gtk_sequence_tracker_compute_distance (priv->sequence[0],
|
||||
priv->sequence[1],
|
||||
&x, &y);
|
||||
angle = atan2 (y, x);
|
||||
angle -= priv->initial_angle;
|
||||
angle *= 180 / G_PI;
|
||||
angle = fmod (angle + 360, 360);
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
double
|
||||
gtk_pinch_pan_gesture_get_zoom (GtkPinchPanGesture *gesture)
|
||||
{
|
||||
GtkPinchPanGesturePrivate *priv;
|
||||
double x, y;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_PINCH_PAN_GESTURE (gesture), 1.0);
|
||||
|
||||
priv = gesture->priv;
|
||||
|
||||
if (!gtk_event_tracker_is_started (GTK_EVENT_TRACKER (gesture)) ||
|
||||
gtk_event_tracker_is_cancelled (GTK_EVENT_TRACKER (gesture)))
|
||||
return 1;
|
||||
|
||||
_gtk_sequence_tracker_compute_distance (priv->sequence[0],
|
||||
priv->sequence[1],
|
||||
&x, &y);
|
||||
|
||||
return sqrt (x * x + y * y) / priv->initial_distance;
|
||||
}
|
85
gtk/gtkpinchpangesture.h
Normal file
85
gtk/gtkpinchpangesture.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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_PINCH_PAN_GESTURE_H__
|
||||
#define __GTK_PINCH_PAN_GESTURE_H__
|
||||
|
||||
#include <gtk/gtkgesture.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_PINCH_PAN_GESTURE (gtk_pinch_pan_gesture_get_type ())
|
||||
#define GTK_PINCH_PAN_GESTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_PINCH_PAN_GESTURE, GtkPinchPanGesture))
|
||||
#define GTK_PINCH_PAN_GESTURE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_PINCH_PAN_GESTURE, GtkPinchPanGestureClass))
|
||||
#define GTK_IS_PINCH_PAN_GESTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_PINCH_PAN_GESTURE))
|
||||
#define GTK_IS_PINCH_PAN_GESTURE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_PINCH_PAN_GESTURE))
|
||||
#define GTK_PINCH_PAN_GESTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PINCH_PAN_GESTURE, GtkPinchPanGestureClass))
|
||||
|
||||
typedef struct _GtkPinchPanGesture GtkPinchPanGesture;
|
||||
typedef struct _GtkPinchPanGestureClass GtkPinchPanGestureClass;
|
||||
typedef struct _GtkPinchPanGesturePrivate GtkPinchPanGesturePrivate;
|
||||
|
||||
struct _GtkPinchPanGesture
|
||||
{
|
||||
GtkGesture parent;
|
||||
|
||||
GtkPinchPanGesturePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkPinchPanGestureClass
|
||||
{
|
||||
GtkGestureClass 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_pinch_pan_gesture_get_type (void) G_GNUC_CONST;
|
||||
|
||||
double gtk_pinch_pan_gesture_get_rotation (GtkPinchPanGesture *gesture);
|
||||
double gtk_pinch_pan_gesture_get_zoom (GtkPinchPanGesture *gesture);
|
||||
double gtk_pinch_pan_gesture_get_x_offset (GtkPinchPanGesture *gesture);
|
||||
double gtk_pinch_pan_gesture_get_y_offset (GtkPinchPanGesture *gesture);
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
gboolean _gtk_pinch_pan_gesture_begin (GtkPinchPanGesture *gesture,
|
||||
GdkEvent *event);
|
||||
gboolean _gtk_pinch_pan_gesture_update (GtkPinchPanGesture *gesture,
|
||||
GdkEvent *event);
|
||||
gboolean _gtk_pinch_pan_gesture_end (GtkPinchPanGesture *gesture,
|
||||
GdkEvent *event);
|
||||
gboolean _gtk_pinch_pan_gesture_cancel (GtkPinchPanGesture *gesture,
|
||||
GdkEvent *event);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_PINCH_PAN_GESTURE_H__ */
|
95
gtk/gtkpinchpanrecognizer.c
Normal file
95
gtk/gtkpinchpanrecognizer.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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 "gtkpinchpanrecognizer.h"
|
||||
|
||||
#include "gtkpinchpangesture.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtkpinch_panrecognizer
|
||||
* @Short_description: Recognizes vertical and horizontal pinch_pan gestures
|
||||
* @Title: GtkPinchPanRecognizer
|
||||
* @See_also: #GtkPinchPanGesture
|
||||
*
|
||||
* #GtkPinchPanRecoginzer recognizes vertical and horizontal pinch_pan gestures.
|
||||
*
|
||||
* #GtkPinchPanRecognizer was added in GTK 3.6.
|
||||
*/
|
||||
|
||||
G_DEFINE_TYPE (GtkPinchPanRecognizer, gtk_pinch_pan_recognizer, GTK_TYPE_GESTURE_RECOGNIZER)
|
||||
|
||||
static void
|
||||
gtk_pinch_pan_recognizer_recognize (GtkEventRecognizer *recognizer,
|
||||
GtkWidget *widget,
|
||||
GdkEvent *event)
|
||||
{
|
||||
if (event->type == GDK_TOUCH_BEGIN)
|
||||
gtk_event_recognizer_create_tracker (recognizer, widget, event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_pinch_pan_recognizer_track (GtkEventRecognizer *recognizer,
|
||||
GtkEventTracker *tracker,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GtkPinchPanGesture *gesture = GTK_PINCH_PAN_GESTURE (tracker);
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_TOUCH_BEGIN:
|
||||
return _gtk_pinch_pan_gesture_begin (gesture, event);
|
||||
case GDK_TOUCH_END:
|
||||
return _gtk_pinch_pan_gesture_end (gesture, event);
|
||||
case GDK_TOUCH_UPDATE:
|
||||
return _gtk_pinch_pan_gesture_update (gesture, event);
|
||||
case GDK_TOUCH_CANCEL:
|
||||
return _gtk_pinch_pan_gesture_cancel (gesture, event);
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_pinch_pan_recognizer_class_init (GtkPinchPanRecognizerClass *klass)
|
||||
{
|
||||
GtkEventRecognizerClass *recognizer_class = GTK_EVENT_RECOGNIZER_CLASS (klass);
|
||||
|
||||
recognizer_class->recognize = gtk_pinch_pan_recognizer_recognize;
|
||||
recognizer_class->track = gtk_pinch_pan_recognizer_track;
|
||||
|
||||
gtk_event_recognizer_class_set_event_mask (recognizer_class,
|
||||
GDK_TOUCH_MASK);
|
||||
gtk_event_recognizer_class_set_tracker_type (recognizer_class,
|
||||
GTK_TYPE_PINCH_PAN_GESTURE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_pinch_pan_recognizer_init (GtkPinchPanRecognizer *recognizer)
|
||||
{
|
||||
}
|
||||
|
||||
GtkEventRecognizer *
|
||||
gtk_pinch_pan_recognizer_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_PINCH_PAN_RECOGNIZER, NULL);
|
||||
}
|
||||
|
72
gtk/gtkpinchpanrecognizer.h
Normal file
72
gtk/gtkpinchpanrecognizer.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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_PINCH_PAN_RECOGNIZER_H__
|
||||
#define __GTK_PINCH_PAN_RECOGNIZER_H__
|
||||
|
||||
#include <gtk/gtkgesturerecognizer.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_PINCH_PAN_RECOGNIZER (gtk_pinch_pan_recognizer_get_type ())
|
||||
#define GTK_PINCH_PAN_RECOGNIZER(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_PINCH_PAN_RECOGNIZER, GtkPinchPanRecognizer))
|
||||
#define GTK_PINCH_PAN_RECOGNIZER_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_PINCH_PAN_RECOGNIZER, GtkPinchPanRecognizerClass))
|
||||
#define GTK_IS_PINCH_PAN_RECOGNIZER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_PINCH_PAN_RECOGNIZER))
|
||||
#define GTK_IS_PINCH_PAN_RECOGNIZER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_PINCH_PAN_RECOGNIZER))
|
||||
#define GTK_PINCH_PAN_RECOGNIZER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PINCH_PAN_RECOGNIZER, GtkPinchPanRecognizerClass))
|
||||
|
||||
typedef struct _GtkPinchPanRecognizer GtkPinchPanRecognizer;
|
||||
typedef struct _GtkPinchPanRecognizerClass GtkPinchPanRecognizerClass;
|
||||
typedef struct _GtkPinchPanRecognizerPrivate GtkPinchPanRecognizerPrivate;
|
||||
|
||||
struct _GtkPinchPanRecognizer
|
||||
{
|
||||
GtkGestureRecognizer parent;
|
||||
|
||||
GtkPinchPanRecognizerPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkPinchPanRecognizerClass
|
||||
{
|
||||
GtkGestureRecognizerClass 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_pinch_pan_recognizer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkEventRecognizer * gtk_pinch_pan_recognizer_new (void);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_PINCH_PAN_RECOGNIZER_H__ */
|
277
gtk/gtksequencetracker.c
Normal file
277
gtk/gtksequencetracker.c
Normal file
@@ -0,0 +1,277 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2012 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtksequencetrackerprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define GTK_SEQUENCE_TRACKER_HISTORY_SIZE 8
|
||||
|
||||
typedef struct _GtkSequenceTrackerClass GtkSequenceTrackerClass;
|
||||
struct _GtkSequenceTrackerClass {
|
||||
gboolean (* update) (GtkSequenceTracker *tracker,
|
||||
GdkEvent *event,
|
||||
double *x,
|
||||
double *y);
|
||||
};
|
||||
|
||||
struct _GtkSequenceTracker {
|
||||
GtkSequenceTrackerClass *klass;
|
||||
|
||||
struct {
|
||||
guint time;
|
||||
GtkMovementDirection dir;
|
||||
double x; /* x position in pixels - will be compared to start_x */
|
||||
double y; /* y position in pixels - will be compared to start_y */
|
||||
} history[GTK_SEQUENCE_TRACKER_HISTORY_SIZE];
|
||||
guint history_index; /* current item */
|
||||
|
||||
GdkEventSequence *sequence; /* sequence we're tracking */
|
||||
double start_x; /* NOT screen location, but in device coordinates */
|
||||
double start_y; /* NOT screen location, but in device coordinates */
|
||||
};
|
||||
|
||||
/* MOUSE */
|
||||
|
||||
/* FIXME */
|
||||
|
||||
/* TOUCHSCREEN */
|
||||
|
||||
/* FIXME */
|
||||
|
||||
/* TOUCHPAD */
|
||||
|
||||
static gboolean
|
||||
gtk_sequence_tracker_touchpad_update (GtkSequenceTracker *tracker,
|
||||
GdkEvent *event,
|
||||
double *x,
|
||||
double *y)
|
||||
{
|
||||
GdkDevice *device = gdk_event_get_device (event);
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_TOUCH_BEGIN:
|
||||
tracker->sequence = gdk_event_get_event_sequence (event);
|
||||
/* fall through */
|
||||
case GDK_TOUCH_UPDATE:
|
||||
case GDK_TOUCH_END:
|
||||
if (tracker->sequence != gdk_event_get_event_sequence (event))
|
||||
return FALSE;
|
||||
|
||||
if (gdk_device_get_axis (device,
|
||||
event->touch.axes,
|
||||
GDK_AXIS_X_RELATIVE,
|
||||
x))
|
||||
{
|
||||
*x *= gdk_screen_get_width (gdk_display_get_default_screen (gdk_device_get_display (device)));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Could not query X value");
|
||||
*x = 0;
|
||||
}
|
||||
|
||||
if (gdk_device_get_axis (device,
|
||||
event->touch.axes,
|
||||
GDK_AXIS_Y_RELATIVE,
|
||||
y))
|
||||
{
|
||||
*y *= gdk_screen_get_height (gdk_display_get_default_screen (gdk_device_get_display (device)));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Could not query Y value");
|
||||
*y = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
GtkSequenceTrackerClass GTK_SEQUENCE_TRACKER_CLASS_TOUCHPAD = {
|
||||
gtk_sequence_tracker_touchpad_update
|
||||
};
|
||||
|
||||
/* API */
|
||||
|
||||
GtkSequenceTracker *
|
||||
_gtk_sequence_tracker_new (GdkEvent *event)
|
||||
{
|
||||
GtkSequenceTrackerClass *klass;
|
||||
GtkSequenceTracker *tracker;
|
||||
guint i, time;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_TOUCH_BEGIN:
|
||||
if (gdk_device_get_source (gdk_event_get_source_device (event)) == GDK_SOURCE_TOUCHPAD)
|
||||
klass = >K_SEQUENCE_TRACKER_CLASS_TOUCHPAD;
|
||||
else
|
||||
return NULL;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tracker = g_slice_new0 (GtkSequenceTracker);
|
||||
tracker->klass = klass;
|
||||
|
||||
if (!tracker->klass->update (tracker, event, &tracker->start_x, &tracker->start_y))
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
time = gdk_event_get_time (event);
|
||||
|
||||
for (i = 0; i < GTK_SEQUENCE_TRACKER_HISTORY_SIZE; i++)
|
||||
{
|
||||
tracker->history[i].time = time;
|
||||
tracker->history[i].x = tracker->start_x;
|
||||
tracker->history[i].y = tracker->start_y;
|
||||
tracker->history[i].dir = GTK_DIR_ANY;
|
||||
}
|
||||
tracker->history_index = 0;
|
||||
|
||||
return tracker;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_sequence_tracker_free (GtkSequenceTracker *tracker)
|
||||
{
|
||||
g_return_if_fail (tracker != NULL);
|
||||
|
||||
g_slice_free (GtkSequenceTracker, tracker);
|
||||
}
|
||||
|
||||
static GtkMovementDirection
|
||||
gtk_sequence_tracker_compute_direction (double dx,
|
||||
double dy)
|
||||
{
|
||||
double r;
|
||||
int i1, i2;
|
||||
|
||||
if (fabs (dx) < 2 && fabs (dy) < 2)
|
||||
{
|
||||
GtkMovementDirection dir = GTK_DIR_ANY;
|
||||
|
||||
if (dx <= 1)
|
||||
dir &= GTK_DIR_SOUTH | GTK_DIR_SOUTH_WEST | GTK_DIR_WEST | GTK_DIR_NORTH_WEST | GTK_DIR_NORTH;
|
||||
else if (dx >= 1)
|
||||
dir &= GTK_DIR_SOUTH | GTK_DIR_SOUTH_EAST | GTK_DIR_EAST | GTK_DIR_NORTH_EAST | GTK_DIR_NORTH;
|
||||
|
||||
if (dy <= 1)
|
||||
dir &= GTK_DIR_WEST | GTK_DIR_NORTH_WEST | GTK_DIR_NORTH | GTK_DIR_NORTH_EAST | GTK_DIR_EAST;
|
||||
else
|
||||
dir &= GTK_DIR_WEST | GTK_DIR_SOUTH_WEST | GTK_DIR_SOUTH | GTK_DIR_SOUTH_EAST | GTK_DIR_EAST;
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
r = atan2(dy, dx);
|
||||
|
||||
/* Add 360° to avoid r become negative since C has no well-defined
|
||||
* modulo for such cases. */
|
||||
r += 2 * G_PI;
|
||||
|
||||
/* Divide by 45° to get the octant number, e.g.
|
||||
* 0 <= r <= 1 is [0-45]°
|
||||
* 1 <= r <= 2 is [45-90]°
|
||||
* etc. */
|
||||
r /= G_PI / 4;
|
||||
|
||||
/* This intends to flag 2 directions (45 degrees),
|
||||
* except on very well-aligned coordinates. */
|
||||
i1 = (int) (r + 0.1) % 8;
|
||||
i2 = (int) (r + 0.9) % 8;
|
||||
if (i1 < 0 || i1 > 7 || i2 < 0 || i2 > 7)
|
||||
return GTK_DIR_ANY;
|
||||
|
||||
return (1 << i1 | 1 << i2);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_sequence_tracker_update (GtkSequenceTracker *tracker,
|
||||
GdkEvent *event)
|
||||
{
|
||||
double x, y, dx, dy;
|
||||
|
||||
g_return_val_if_fail (tracker != NULL, FALSE);
|
||||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
|
||||
if (!tracker->klass->update (tracker, event, &x, &y))
|
||||
return FALSE;
|
||||
|
||||
dx = x - tracker->history[tracker->history_index].x;
|
||||
dy = y - tracker->history[tracker->history_index].y;
|
||||
|
||||
tracker->history_index = (tracker->history_index + 1) % GTK_SEQUENCE_TRACKER_HISTORY_SIZE;
|
||||
tracker->history[tracker->history_index].time = gdk_event_get_time (event);
|
||||
tracker->history[tracker->history_index].x = x;
|
||||
tracker->history[tracker->history_index].y = y;
|
||||
tracker->history[tracker->history_index].dir = gtk_sequence_tracker_compute_direction (dx, dy);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
double
|
||||
_gtk_sequence_tracker_get_x_offset (GtkSequenceTracker *tracker)
|
||||
{
|
||||
g_return_val_if_fail (tracker != NULL, 0);
|
||||
|
||||
return tracker->history[tracker->history_index].x
|
||||
- tracker->start_x;
|
||||
}
|
||||
|
||||
double
|
||||
_gtk_sequence_tracker_get_y_offset (GtkSequenceTracker *tracker)
|
||||
{
|
||||
g_return_val_if_fail (tracker != NULL, 0);
|
||||
|
||||
return tracker->history[tracker->history_index].y
|
||||
- tracker->start_y;
|
||||
}
|
||||
|
||||
GtkMovementDirection
|
||||
_gtk_sequence_tracker_get_direction (GtkSequenceTracker *tracker)
|
||||
{
|
||||
g_return_val_if_fail (tracker != NULL, GTK_DIR_ANY);
|
||||
|
||||
return tracker->history[tracker->history_index].dir;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_sequence_tracker_compute_distance (GtkSequenceTracker *from,
|
||||
GtkSequenceTracker *to,
|
||||
double *x,
|
||||
double *y)
|
||||
{
|
||||
g_return_if_fail (from != NULL);
|
||||
g_return_if_fail (to != NULL);
|
||||
g_return_if_fail (from->klass == to->klass);
|
||||
/* XXX: compare devices here? */
|
||||
|
||||
if (x)
|
||||
*x = from->history[from->history_index].x - to->history[to->history_index].x;
|
||||
if (y)
|
||||
*y = from->history[from->history_index].y - to->history[to->history_index].y;
|
||||
}
|
||||
|
57
gtk/gtksequencetrackerprivate.h
Normal file
57
gtk/gtksequencetrackerprivate.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2012 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_SEQUENCE_TRACKER_PRIVATE_H__
|
||||
#define __GTK_SEQUENCE_TRACKER_PRIVATE_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GTK_DIR_EAST = (1 << 0),
|
||||
GTK_DIR_SOUTH_EAST = (1 << 1),
|
||||
GTK_DIR_SOUTH = (1 << 2),
|
||||
GTK_DIR_SOUTH_WEST = (1 << 3),
|
||||
GTK_DIR_WEST = (1 << 4),
|
||||
GTK_DIR_NORTH_WEST = (1 << 5),
|
||||
GTK_DIR_NORTH = (1 << 6),
|
||||
GTK_DIR_NORTH_EAST = (1 << 7),
|
||||
GTK_DIR_ANY = (1 << 8) - 1,
|
||||
} GtkMovementDirection;
|
||||
|
||||
typedef struct _GtkSequenceTracker GtkSequenceTracker;
|
||||
|
||||
GtkSequenceTracker * _gtk_sequence_tracker_new (GdkEvent *event);
|
||||
void _gtk_sequence_tracker_free (GtkSequenceTracker *tracker);
|
||||
|
||||
gboolean _gtk_sequence_tracker_update (GtkSequenceTracker *tracker,
|
||||
GdkEvent *event);
|
||||
|
||||
double _gtk_sequence_tracker_get_x_offset (GtkSequenceTracker *tracker);
|
||||
double _gtk_sequence_tracker_get_y_offset (GtkSequenceTracker *tracker);
|
||||
|
||||
GtkMovementDirection _gtk_sequence_tracker_get_direction (GtkSequenceTracker *tracker);
|
||||
|
||||
void _gtk_sequence_tracker_compute_distance (GtkSequenceTracker *from,
|
||||
GtkSequenceTracker *to,
|
||||
double *x,
|
||||
double *y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SEQUENCE_TRACKER_PRIVATE_H__ */
|
241
gtk/gtkswipegesture.c
Normal file
241
gtk/gtkswipegesture.c
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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 "gtkswipegesture.h"
|
||||
|
||||
#include "gtksequencetrackerprivate.h"
|
||||
#include "gtkswiperecognizer.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* SECTION:gtkswipegesture
|
||||
* @Short_description: Tracks the swipes from a #GtkSwipeRecognizer
|
||||
* @Title: GtkSwipeGesture
|
||||
* @See_also: #GtkSwipeRecognizer
|
||||
*
|
||||
* The #GtkSwipeGesture object - or a subclass of it - is used to track
|
||||
* sequences of swipes as recognized by a #GtkSwipeRecognizer. Once the
|
||||
* recognizer finds it can potentially identify a sequence of swipes, it
|
||||
* creates a #GtkSwipeGesture and uses it to store information about the
|
||||
* swipe. See the swipe handling howto for a highlevel overview.
|
||||
*
|
||||
* #GtkSwipeGesture was added in GTK 3.6.
|
||||
*/
|
||||
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
};
|
||||
|
||||
struct _GtkSwipeGesturePrivate {
|
||||
GtkSequenceTracker *sequence[2];
|
||||
GtkMovementDirection direction;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkSwipeGesture, gtk_swipe_gesture, GTK_TYPE_GESTURE)
|
||||
|
||||
static void
|
||||
gtk_swipe_gesture_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
//GtkSwipeGesture *gesture = GTK_SWIPE_GESTURE (object);
|
||||
//GtkSwipeGesturePrivate *priv = gesture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_swipe_gesture_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
//GtkSwipeGesture *gesture = GTK_SWIPE_GESTURE (object);
|
||||
//GtkSwipeGesturePrivate *priv = gesture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_swipe_gesture_dispose (GObject *object)
|
||||
{
|
||||
//GtkSwipeGesture *gesture = GTK_SWIPE_GESTURE (object);
|
||||
|
||||
G_OBJECT_CLASS (gtk_swipe_gesture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_swipe_gesture_class_init (GtkSwipeGestureClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_swipe_gesture_dispose;
|
||||
object_class->set_property = gtk_swipe_gesture_set_property;
|
||||
object_class->get_property = gtk_swipe_gesture_get_property;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GtkSwipeGesturePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_swipe_gesture_init (GtkSwipeGesture *gesture)
|
||||
{
|
||||
GtkSwipeGesturePrivate *priv;
|
||||
|
||||
priv = gesture->priv = G_TYPE_INSTANCE_GET_PRIVATE (gesture,
|
||||
GTK_TYPE_SWIPE_GESTURE,
|
||||
GtkSwipeGesturePrivate);
|
||||
|
||||
priv->direction = GTK_DIR_ANY;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_swipe_gesture_begin (GtkSwipeGesture *gesture,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GtkSwipeGesturePrivate *priv = gesture->priv;
|
||||
|
||||
if (priv->sequence[1] != NULL)
|
||||
return FALSE;
|
||||
|
||||
if (priv->sequence[0] == NULL)
|
||||
{
|
||||
priv->sequence[0] = _gtk_sequence_tracker_new (event);
|
||||
gtk_gesture_add_sequence (GTK_GESTURE (gesture), event->touch.sequence);
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->sequence[1] = _gtk_sequence_tracker_new (event);
|
||||
gtk_gesture_add_sequence (GTK_GESTURE (gesture), event->touch.sequence);
|
||||
}
|
||||
|
||||
if (priv->sequence[1])
|
||||
gtk_event_tracker_start (GTK_EVENT_TRACKER (gesture));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_swipe_gesture_update_for_event (GtkSwipeGesture *gesture,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GtkSwipeGesturePrivate *priv = gesture->priv;
|
||||
gboolean result = FALSE;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (priv->sequence[i] &&
|
||||
_gtk_sequence_tracker_update (priv->sequence[i], event))
|
||||
{
|
||||
priv->direction &= _gtk_sequence_tracker_get_direction (priv->sequence[i]);
|
||||
if (priv->direction == 0)
|
||||
{
|
||||
gtk_event_tracker_cancel (GTK_EVENT_TRACKER (gesture));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
result = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_swipe_gesture_update (GtkSwipeGesture *gesture,
|
||||
GdkEvent *event)
|
||||
{
|
||||
if (gtk_swipe_gesture_update_for_event (gesture, event) &&
|
||||
gtk_event_tracker_is_started (GTK_EVENT_TRACKER (gesture)))
|
||||
gtk_event_tracker_update (GTK_EVENT_TRACKER (gesture));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_swipe_gesture_end (GtkSwipeGesture *gesture,
|
||||
GdkEvent *event)
|
||||
{
|
||||
if (gtk_swipe_gesture_update_for_event (gesture, event))
|
||||
{
|
||||
if (gesture->priv->sequence[1])
|
||||
gtk_event_tracker_finish (GTK_EVENT_TRACKER (gesture));
|
||||
else
|
||||
gtk_event_tracker_cancel (GTK_EVENT_TRACKER (gesture));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_swipe_gesture_cancel (GtkSwipeGesture *gesture,
|
||||
GdkEvent *event)
|
||||
{
|
||||
if (gtk_swipe_gesture_update_for_event (gesture, event))
|
||||
gtk_event_tracker_cancel (GTK_EVENT_TRACKER (gesture));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_swipe_gesture_get_offset (GtkSwipeGesture *gesture,
|
||||
double *x,
|
||||
double *y)
|
||||
{
|
||||
GtkSwipeGesturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_SWIPE_GESTURE (gesture));
|
||||
|
||||
priv = gesture->priv;
|
||||
|
||||
if (!gtk_event_tracker_is_started (GTK_EVENT_TRACKER (gesture)) ||
|
||||
gtk_event_tracker_is_cancelled (GTK_EVENT_TRACKER (gesture)))
|
||||
{
|
||||
if (x)
|
||||
*x = 0;
|
||||
if (y)
|
||||
*y = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (x)
|
||||
*x = (_gtk_sequence_tracker_get_x_offset (priv->sequence[0])
|
||||
+ _gtk_sequence_tracker_get_x_offset (priv->sequence[1])) / 2;
|
||||
if (y)
|
||||
*y = (_gtk_sequence_tracker_get_y_offset (priv->sequence[0])
|
||||
+ _gtk_sequence_tracker_get_y_offset (priv->sequence[1])) / 2;
|
||||
}
|
||||
|
84
gtk/gtkswipegesture.h
Normal file
84
gtk/gtkswipegesture.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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_SWIPE_GESTURE_H__
|
||||
#define __GTK_SWIPE_GESTURE_H__
|
||||
|
||||
#include <gtk/gtkgesture.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_SWIPE_GESTURE (gtk_swipe_gesture_get_type ())
|
||||
#define GTK_SWIPE_GESTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_SWIPE_GESTURE, GtkSwipeGesture))
|
||||
#define GTK_SWIPE_GESTURE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_SWIPE_GESTURE, GtkSwipeGestureClass))
|
||||
#define GTK_IS_SWIPE_GESTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_SWIPE_GESTURE))
|
||||
#define GTK_IS_SWIPE_GESTURE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_SWIPE_GESTURE))
|
||||
#define GTK_SWIPE_GESTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SWIPE_GESTURE, GtkSwipeGestureClass))
|
||||
|
||||
typedef struct _GtkSwipeGesture GtkSwipeGesture;
|
||||
typedef struct _GtkSwipeGestureClass GtkSwipeGestureClass;
|
||||
typedef struct _GtkSwipeGesturePrivate GtkSwipeGesturePrivate;
|
||||
|
||||
struct _GtkSwipeGesture
|
||||
{
|
||||
GtkGesture parent;
|
||||
|
||||
GtkSwipeGesturePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkSwipeGestureClass
|
||||
{
|
||||
GtkGestureClass 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_swipe_gesture_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void gtk_swipe_gesture_get_offset (GtkSwipeGesture *gesture,
|
||||
double *x,
|
||||
double *y);
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
gboolean _gtk_swipe_gesture_begin (GtkSwipeGesture *gesture,
|
||||
GdkEvent *event);
|
||||
gboolean _gtk_swipe_gesture_update (GtkSwipeGesture *gesture,
|
||||
GdkEvent *event);
|
||||
gboolean _gtk_swipe_gesture_end (GtkSwipeGesture *gesture,
|
||||
GdkEvent *event);
|
||||
gboolean _gtk_swipe_gesture_cancel (GtkSwipeGesture *gesture,
|
||||
GdkEvent *event);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SWIPE_GESTURE_H__ */
|
95
gtk/gtkswiperecognizer.c
Normal file
95
gtk/gtkswiperecognizer.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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 "gtkswiperecognizer.h"
|
||||
|
||||
#include "gtkswipegesture.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtkswiperecognizer
|
||||
* @Short_description: Recognizes vertical and horizontal swipe gestures
|
||||
* @Title: GtkSwipeRecognizer
|
||||
* @See_also: #GtkSwipeGesture
|
||||
*
|
||||
* #GtkSwipeRecoginzer recognizes vertical and horizontal swipe gestures.
|
||||
*
|
||||
* #GtkSwipeRecognizer was added in GTK 3.6.
|
||||
*/
|
||||
|
||||
G_DEFINE_TYPE (GtkSwipeRecognizer, gtk_swipe_recognizer, GTK_TYPE_GESTURE_RECOGNIZER)
|
||||
|
||||
static void
|
||||
gtk_swipe_recognizer_recognize (GtkEventRecognizer *recognizer,
|
||||
GtkWidget *widget,
|
||||
GdkEvent *event)
|
||||
{
|
||||
if (event->type == GDK_TOUCH_BEGIN)
|
||||
gtk_event_recognizer_create_tracker (recognizer, widget, event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_swipe_recognizer_track (GtkEventRecognizer *recognizer,
|
||||
GtkEventTracker *tracker,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GtkSwipeGesture *gesture = GTK_SWIPE_GESTURE (tracker);
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_TOUCH_BEGIN:
|
||||
return _gtk_swipe_gesture_begin (gesture, event);
|
||||
case GDK_TOUCH_END:
|
||||
return _gtk_swipe_gesture_end (gesture, event);
|
||||
case GDK_TOUCH_UPDATE:
|
||||
return _gtk_swipe_gesture_update (gesture, event);
|
||||
case GDK_TOUCH_CANCEL:
|
||||
return _gtk_swipe_gesture_cancel (gesture, event);
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_swipe_recognizer_class_init (GtkSwipeRecognizerClass *klass)
|
||||
{
|
||||
GtkEventRecognizerClass *recognizer_class = GTK_EVENT_RECOGNIZER_CLASS (klass);
|
||||
|
||||
recognizer_class->recognize = gtk_swipe_recognizer_recognize;
|
||||
recognizer_class->track = gtk_swipe_recognizer_track;
|
||||
|
||||
gtk_event_recognizer_class_set_event_mask (recognizer_class,
|
||||
GDK_TOUCH_MASK);
|
||||
gtk_event_recognizer_class_set_tracker_type (recognizer_class,
|
||||
GTK_TYPE_SWIPE_GESTURE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_swipe_recognizer_init (GtkSwipeRecognizer *recognizer)
|
||||
{
|
||||
}
|
||||
|
||||
GtkEventRecognizer *
|
||||
gtk_swipe_recognizer_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_SWIPE_RECOGNIZER, NULL);
|
||||
}
|
||||
|
72
gtk/gtkswiperecognizer.h
Normal file
72
gtk/gtkswiperecognizer.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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_SWIPE_RECOGNIZER_H__
|
||||
#define __GTK_SWIPE_RECOGNIZER_H__
|
||||
|
||||
#include <gtk/gtkgesturerecognizer.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_SWIPE_RECOGNIZER (gtk_swipe_recognizer_get_type ())
|
||||
#define GTK_SWIPE_RECOGNIZER(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_SWIPE_RECOGNIZER, GtkSwipeRecognizer))
|
||||
#define GTK_SWIPE_RECOGNIZER_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_SWIPE_RECOGNIZER, GtkSwipeRecognizerClass))
|
||||
#define GTK_IS_SWIPE_RECOGNIZER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_SWIPE_RECOGNIZER))
|
||||
#define GTK_IS_SWIPE_RECOGNIZER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_SWIPE_RECOGNIZER))
|
||||
#define GTK_SWIPE_RECOGNIZER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SWIPE_RECOGNIZER, GtkSwipeRecognizerClass))
|
||||
|
||||
typedef struct _GtkSwipeRecognizer GtkSwipeRecognizer;
|
||||
typedef struct _GtkSwipeRecognizerClass GtkSwipeRecognizerClass;
|
||||
typedef struct _GtkSwipeRecognizerPrivate GtkSwipeRecognizerPrivate;
|
||||
|
||||
struct _GtkSwipeRecognizer
|
||||
{
|
||||
GtkGestureRecognizer parent;
|
||||
|
||||
GtkSwipeRecognizerPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkSwipeRecognizerClass
|
||||
{
|
||||
GtkGestureRecognizerClass 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_swipe_recognizer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkEventRecognizer * gtk_swipe_recognizer_new (void);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SWIPE_RECOGNIZER_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;
|
||||
|
260
gtk/gtkwidget.c
260
gtk/gtkwidget.c
@@ -35,6 +35,7 @@
|
||||
#include "gtkcontainer.h"
|
||||
#include "gtkaccelmapprivate.h"
|
||||
#include "gtkclipboard.h"
|
||||
#include "gtkeventrecognizerprivate.h"
|
||||
#include "gtkiconfactory.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmarshalers.h"
|
||||
@@ -401,6 +402,11 @@ struct _GtkWidgetPrivate
|
||||
/* The widget's parent */
|
||||
GtkWidget *parent;
|
||||
|
||||
/* The recognizers used by widget. Usually equal to the recognizers
|
||||
* of its class, but can be modified.
|
||||
*/
|
||||
GPtrArray *recognizers;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
/* Number of gtk_widget_push_verify_invariants () */
|
||||
guint verifying_invariants_count;
|
||||
@@ -411,6 +417,7 @@ struct _GtkWidgetClassPrivate
|
||||
{
|
||||
GType accessible_type;
|
||||
AtkRole accessible_role;
|
||||
GPtrArray *recognizers;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -542,7 +549,8 @@ struct _GtkStateData
|
||||
static void gtk_widget_base_class_init (gpointer g_class);
|
||||
static void gtk_widget_class_init (GtkWidgetClass *klass);
|
||||
static void gtk_widget_base_class_finalize (GtkWidgetClass *klass);
|
||||
static void gtk_widget_init (GtkWidget *widget);
|
||||
static void gtk_widget_init (GTypeInstance *instance,
|
||||
gpointer g_class);
|
||||
static void gtk_widget_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
@@ -756,7 +764,7 @@ gtk_widget_get_type (void)
|
||||
NULL, /* class_init */
|
||||
sizeof (GtkWidget),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) gtk_widget_init,
|
||||
gtk_widget_init,
|
||||
NULL, /* value_table */
|
||||
};
|
||||
|
||||
@@ -792,8 +800,23 @@ static void
|
||||
gtk_widget_base_class_init (gpointer g_class)
|
||||
{
|
||||
GtkWidgetClass *klass = g_class;
|
||||
GtkWidgetClassPrivate *priv;
|
||||
|
||||
klass->priv = G_TYPE_CLASS_GET_PRIVATE (g_class, GTK_TYPE_WIDGET, GtkWidgetClassPrivate);
|
||||
priv = klass->priv = G_TYPE_CLASS_GET_PRIVATE (g_class, GTK_TYPE_WIDGET, GtkWidgetClassPrivate);
|
||||
|
||||
if (priv->recognizers)
|
||||
{
|
||||
GPtrArray *copy;
|
||||
guint i;
|
||||
|
||||
copy = g_ptr_array_new_full (priv->recognizers->len, g_object_unref);
|
||||
for (i = 0; i < priv->recognizers->len; i++)
|
||||
{
|
||||
g_ptr_array_add (copy, g_object_ref (g_ptr_array_index (priv->recognizers, i)));
|
||||
}
|
||||
|
||||
priv->recognizers = copy;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3288,8 +3311,15 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
static void
|
||||
gtk_widget_base_class_finalize (GtkWidgetClass *klass)
|
||||
{
|
||||
GtkWidgetClassPrivate *priv = klass->priv;
|
||||
GList *list, *node;
|
||||
|
||||
if (priv->recognizers)
|
||||
{
|
||||
g_ptr_array_free (priv->recognizers, TRUE);
|
||||
priv->recognizers = NULL;
|
||||
}
|
||||
|
||||
list = g_param_spec_pool_list_owned (style_property_spec_pool, G_OBJECT_CLASS_TYPE (klass));
|
||||
for (node = list; node; node = node->next)
|
||||
{
|
||||
@@ -3624,8 +3654,9 @@ gtk_widget_get_property (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_init (GtkWidget *widget)
|
||||
gtk_widget_init (GTypeInstance *instance, gpointer g_class)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (instance);
|
||||
GtkWidgetPrivate *priv;
|
||||
|
||||
widget->priv = G_TYPE_INSTANCE_GET_PRIVATE (widget,
|
||||
@@ -3661,6 +3692,12 @@ gtk_widget_init (GtkWidget *widget)
|
||||
|
||||
priv->style = gtk_widget_get_default_style ();
|
||||
g_object_ref (priv->style);
|
||||
|
||||
if (GTK_WIDGET_CLASS (g_class)->priv->recognizers)
|
||||
{
|
||||
priv->recognizers = GTK_WIDGET_CLASS (g_class)->priv->recognizers;
|
||||
g_ptr_array_ref (priv->recognizers);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6258,6 +6295,30 @@ event_window_is_still_viewable (GdkEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_widget_invoke_recognizers (GtkWidget *widget,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GtkWidgetPrivate *priv = widget->priv;
|
||||
guint i;
|
||||
gboolean eat_event = FALSE;
|
||||
|
||||
if (priv->recognizers == NULL)
|
||||
return FALSE;
|
||||
|
||||
g_object_ref (widget);
|
||||
|
||||
for (i = 0; i < priv->recognizers->len; i++)
|
||||
{
|
||||
GtkEventRecognizer *recognizer = g_ptr_array_index (priv->recognizers, i);
|
||||
_gtk_event_recognizer_recognize (recognizer, widget, event);
|
||||
}
|
||||
|
||||
g_object_unref (widget);
|
||||
|
||||
return eat_event;
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_widget_event_internal (GtkWidget *widget,
|
||||
GdkEvent *event)
|
||||
@@ -6272,6 +6333,8 @@ gtk_widget_event_internal (GtkWidget *widget,
|
||||
if (!event_window_is_still_viewable (event))
|
||||
return TRUE;
|
||||
|
||||
gtk_widget_invoke_recognizers (widget, event);
|
||||
|
||||
g_object_ref (widget);
|
||||
|
||||
g_signal_emit (widget, widget_signals[EVENT], 0, event, &return_val);
|
||||
@@ -9551,6 +9614,27 @@ _gtk_widget_restore_size_request (GtkWidget *widget,
|
||||
GTK_QUEUE_RESIZE_INVALIDATE_ONLY);
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_widget_get_recognizer_event_mask (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetPrivate *priv = widget->priv;
|
||||
gint event_mask;
|
||||
guint i;
|
||||
|
||||
if (priv->recognizers == NULL)
|
||||
return 0;
|
||||
|
||||
event_mask = 0;
|
||||
for (i = 0; i < priv->recognizers->len; i++)
|
||||
{
|
||||
event_mask |= gtk_event_recognizer_class_get_event_mask (
|
||||
GTK_EVENT_RECOGNIZER_GET_CLASS (
|
||||
g_ptr_array_index (priv->recognizers, i)));
|
||||
}
|
||||
|
||||
return event_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_set_events:
|
||||
* @widget: a #GtkWidget
|
||||
@@ -9978,9 +10062,14 @@ gtk_widget_get_settings (GtkWidget *widget)
|
||||
gint
|
||||
gtk_widget_get_events (GtkWidget *widget)
|
||||
{
|
||||
gint event_mask;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
|
||||
|
||||
return GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (widget), quark_event_mask));
|
||||
event_mask = GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (widget), quark_event_mask));
|
||||
event_mask |= gtk_widget_get_recognizer_event_mask (widget);
|
||||
|
||||
return event_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -10373,6 +10462,12 @@ gtk_widget_real_destroy (GtkWidget *object)
|
||||
g_object_unref (priv->style);
|
||||
priv->style = gtk_widget_get_default_style ();
|
||||
g_object_ref (priv->style);
|
||||
|
||||
if (priv->recognizers)
|
||||
{
|
||||
g_ptr_array_unref (priv->recognizers);
|
||||
priv->recognizers = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -13778,6 +13873,161 @@ gtk_widget_send_focus_change (GtkWidget *widget,
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_class_add_recognizer:
|
||||
* @widget_class: The widget class
|
||||
* @recognizer: The recognizer to add
|
||||
*
|
||||
* Adds @recognizer to @widget_class. The @recognizer will be
|
||||
* added at the end of the list of recognizers.
|
||||
*
|
||||
* After calling this function, the properties of @recognizer
|
||||
* should not be modified anymore.
|
||||
*
|
||||
* This function should only be called in the class_init function
|
||||
* of @widget_class.
|
||||
**/
|
||||
void
|
||||
gtk_widget_class_add_recognizer (GtkWidgetClass *widget_class,
|
||||
GtkEventRecognizer *recognizer)
|
||||
{
|
||||
GtkWidgetClassPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
|
||||
g_return_if_fail (GTK_IS_EVENT_RECOGNIZER (recognizer));
|
||||
|
||||
priv = widget_class->priv;
|
||||
|
||||
if (priv->recognizers == NULL)
|
||||
priv->recognizers = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
g_object_ref (recognizer);
|
||||
g_ptr_array_add (priv->recognizers, recognizer);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_ensure_custom_recognizers (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetClass *klass = GTK_WIDGET_GET_CLASS (widget);
|
||||
GtkWidgetPrivate *priv = widget->priv;
|
||||
GPtrArray *shared;
|
||||
guint i;
|
||||
|
||||
shared = klass->priv->recognizers;
|
||||
if (priv->recognizers != shared)
|
||||
return;
|
||||
|
||||
priv->recognizers = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
if (shared == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < shared->len; i++)
|
||||
{
|
||||
GtkEventRecognizer *recognizer;
|
||||
|
||||
recognizer = g_ptr_array_index (shared, i);
|
||||
g_object_ref (recognizer);
|
||||
g_ptr_array_add (priv->recognizers, recognizer);
|
||||
}
|
||||
g_object_unref (shared);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_add_recognizer:
|
||||
* @widget: The widget
|
||||
* @recognizer: The recognizer to add
|
||||
*
|
||||
* Adds @recognizer to @widget_class. The @recognizer will be
|
||||
* added at the end of the list of recognizers.
|
||||
**/
|
||||
void
|
||||
gtk_widget_add_recognizer (GtkWidget *widget,
|
||||
GtkEventRecognizer *recognizer)
|
||||
{
|
||||
GtkWidgetPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (GTK_IS_EVENT_RECOGNIZER (recognizer));
|
||||
|
||||
gtk_widget_ensure_custom_recognizers (widget);
|
||||
|
||||
priv = widget->priv;
|
||||
|
||||
g_object_ref (recognizer);
|
||||
g_ptr_array_add (priv->recognizers, recognizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_remove_recognizer:
|
||||
* @widget: The widget to remove the recognizer from
|
||||
* @id: The index
|
||||
*
|
||||
* Removes the recognizer at @id from @widget.
|
||||
**/
|
||||
void
|
||||
gtk_widget_remove_recognizer (GtkWidget *widget,
|
||||
guint id)
|
||||
{
|
||||
GtkWidgetPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
gtk_widget_ensure_custom_recognizers (widget);
|
||||
|
||||
priv = widget->priv;
|
||||
g_return_if_fail (id < priv->recognizers->len);
|
||||
|
||||
g_ptr_array_remove_index (priv->recognizers, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_recognizer:
|
||||
* @widget: The widget
|
||||
* @id: the index of the recognizer. Must be less then the number of
|
||||
* recognizers of @widget.
|
||||
*
|
||||
* Gets the recognizer @id in use by @widget
|
||||
*
|
||||
* Returns: The recognizer
|
||||
**/
|
||||
GtkEventRecognizer *
|
||||
gtk_widget_get_recognizer (GtkWidget *widget,
|
||||
guint id)
|
||||
{
|
||||
GtkWidgetPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||
|
||||
priv = widget->priv;
|
||||
g_return_val_if_fail (priv->recognizers != NULL, NULL);
|
||||
g_return_val_if_fail (id < priv->recognizers->len, NULL);
|
||||
|
||||
return g_ptr_array_index (priv->recognizers, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_n_recognizers:
|
||||
* @widget: the widget
|
||||
*
|
||||
* Gets the number of recognizers in use by @widget.
|
||||
*
|
||||
* Returns: The number of recognizers currently in use by @widget
|
||||
**/
|
||||
guint
|
||||
gtk_widget_get_n_recognizers (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET_CLASS (widget), 0);
|
||||
|
||||
priv = widget->priv;
|
||||
|
||||
if (priv->recognizers == NULL)
|
||||
return 0;
|
||||
|
||||
return priv->recognizers->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_in_destruction:
|
||||
* @widget: a #GtkWidget
|
||||
|
@@ -526,6 +526,17 @@ gint gtk_widget_send_expose (GtkWidget *widget,
|
||||
gboolean gtk_widget_send_focus_change (GtkWidget *widget,
|
||||
GdkEvent *event);
|
||||
|
||||
void gtk_widget_class_add_recognizer(GtkWidgetClass *widget_class,
|
||||
GtkEventRecognizer *recognizer);
|
||||
void gtk_widget_add_recognizer (GtkWidget *widget,
|
||||
GtkEventRecognizer *recognizer);
|
||||
void gtk_widget_remove_recognizer (GtkWidget *widget,
|
||||
guint id);
|
||||
GtkEventRecognizer *
|
||||
gtk_widget_get_recognizer (GtkWidget *widget,
|
||||
guint id);
|
||||
guint gtk_widget_get_n_recognizers (GtkWidget *widget);
|
||||
|
||||
gboolean gtk_widget_activate (GtkWidget *widget);
|
||||
|
||||
void gtk_widget_reparent (GtkWidget *widget,
|
||||
|
@@ -200,8 +200,8 @@ _gtk_win32_theme_part_create_surface (HTHEME theme,
|
||||
cairo_t *cr;
|
||||
int x_offs;
|
||||
int y_offs;
|
||||
gboolean has_alpha;
|
||||
#ifdef G_OS_WIN32
|
||||
gboolean has_alpha;
|
||||
HDC hdc;
|
||||
RECT rect;
|
||||
SIZE size;
|
||||
|
@@ -55,6 +55,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
|
||||
testfontchooserdialog \
|
||||
testframe \
|
||||
testgeometry \
|
||||
testgestures \
|
||||
testgiconpixbuf \
|
||||
testgrid \
|
||||
testgtk \
|
||||
|
@@ -96,6 +96,10 @@ EXTRA_DIST += \
|
||||
css-match-exact.css \
|
||||
css-match-exact.ref.ui \
|
||||
css-match-exact.ui \
|
||||
css-match-import.css \
|
||||
css-match-import-import.css \
|
||||
css-match-import.ui \
|
||||
css-match-import.ref.ui \
|
||||
css-match-inherit.css \
|
||||
css-match-inherit.ref.ui \
|
||||
css-match-inherit.ui \
|
||||
|
7
tests/reftests/css-match-import-import.css
vendored
Normal file
7
tests/reftests/css-match-import-import.css
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
GtkLabel {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
#reference {
|
||||
color: purple;
|
||||
}
|
9
tests/reftests/css-match-import.css
vendored
Normal file
9
tests/reftests/css-match-import.css
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
@import url("css-match-import-import.css");
|
||||
|
||||
GtkLabel {
|
||||
color: purple;
|
||||
}
|
||||
|
||||
#reference {
|
||||
color: purple;
|
||||
}
|
16
tests/reftests/css-match-import.ref.ui
Normal file
16
tests/reftests/css-match-import.ref.ui
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="name">purple</property>
|
||||
<property name="label" translatable="yes">Purple</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
15
tests/reftests/css-match-import.ui
Normal file
15
tests/reftests/css-match-import.ui
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Purple</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
238
tests/testgestures.c
Normal file
238
tests/testgestures.c
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
typedef struct _AreaData AreaData;
|
||||
struct _AreaData {
|
||||
double x_offset;
|
||||
double y_offset;
|
||||
double progress;
|
||||
guint color;
|
||||
cairo_matrix_t matrix;
|
||||
cairo_matrix_t pending;
|
||||
GdkPixbuf *pixbuf;
|
||||
};
|
||||
|
||||
static void
|
||||
update_swipe (GtkEventRecognizer *recognizer,
|
||||
GtkEventTracker *tracker,
|
||||
AreaData *data)
|
||||
{
|
||||
GtkSwipeGesture *swipe = GTK_SWIPE_GESTURE (tracker);
|
||||
GtkWidget *widget = gtk_event_tracker_get_widget (tracker);
|
||||
double x, y;
|
||||
|
||||
gtk_swipe_gesture_get_offset (swipe, &x, &y);
|
||||
x /= gtk_widget_get_allocated_width (widget);
|
||||
y /= gtk_widget_get_allocated_height (widget);
|
||||
data->x_offset = CLAMP (x, -1, 1);
|
||||
data->y_offset = CLAMP (y, -1, 1);
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
finish_swipe (GtkEventRecognizer *recognizer,
|
||||
GtkEventTracker *tracker,
|
||||
AreaData *data)
|
||||
{
|
||||
GtkSwipeGesture *swipe = GTK_SWIPE_GESTURE (tracker);
|
||||
GtkWidget *widget = gtk_event_tracker_get_widget (tracker);
|
||||
double x, y;
|
||||
|
||||
gtk_swipe_gesture_get_offset (swipe, &x, &y);
|
||||
x /= gtk_widget_get_allocated_width (widget);
|
||||
y /= gtk_widget_get_allocated_height (widget);
|
||||
|
||||
if (ABS (x) >= 0.5)
|
||||
data->color ^= 1;
|
||||
if (ABS (y) >= 0.5)
|
||||
data->color ^= 2;
|
||||
|
||||
data->x_offset = 0;
|
||||
data->y_offset = 0;
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_swipe (GtkEventRecognizer *recognizer,
|
||||
GtkEventTracker *tracker,
|
||||
AreaData *data)
|
||||
{
|
||||
GtkWidget *widget = gtk_event_tracker_get_widget (tracker);
|
||||
|
||||
data->x_offset = 0;
|
||||
data->y_offset = 0;
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
pinch_pan_get_matrix (cairo_matrix_t *matrix,
|
||||
GtkPinchPanGesture *pinch)
|
||||
{
|
||||
double scale;
|
||||
|
||||
cairo_matrix_init_identity (matrix);
|
||||
scale = gtk_pinch_pan_gesture_get_zoom (pinch);
|
||||
cairo_matrix_translate (matrix,
|
||||
gtk_pinch_pan_gesture_get_x_offset (pinch),
|
||||
gtk_pinch_pan_gesture_get_y_offset (pinch));
|
||||
cairo_matrix_scale (matrix, scale, scale);
|
||||
cairo_matrix_rotate (matrix, gtk_pinch_pan_gesture_get_rotation (pinch) * G_PI / 180);
|
||||
}
|
||||
|
||||
static void
|
||||
update_pinch_pan (GtkEventRecognizer *recognizer,
|
||||
GtkEventTracker *tracker,
|
||||
AreaData *data)
|
||||
{
|
||||
GtkPinchPanGesture *pinch = GTK_PINCH_PAN_GESTURE (tracker);
|
||||
GtkWidget *widget = gtk_event_tracker_get_widget (tracker);
|
||||
|
||||
if (gtk_gesture_owns_all_sequences (GTK_GESTURE (tracker)))
|
||||
pinch_pan_get_matrix (&data->pending, pinch);
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
finish_pinch_pan (GtkEventRecognizer *recognizer,
|
||||
GtkEventTracker *tracker,
|
||||
AreaData *data)
|
||||
{
|
||||
GtkPinchPanGesture *pinch = GTK_PINCH_PAN_GESTURE (tracker);
|
||||
GtkWidget *widget = gtk_event_tracker_get_widget (tracker);
|
||||
|
||||
pinch_pan_get_matrix (&data->pending, pinch);
|
||||
cairo_matrix_multiply (&data->matrix, &data->matrix, &data->pending);
|
||||
cairo_matrix_init_identity (&data->pending);
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_pinch_pan (GtkEventRecognizer *recognizer,
|
||||
GtkEventTracker *tracker,
|
||||
AreaData *data)
|
||||
{
|
||||
GtkWidget *widget = gtk_event_tracker_get_widget (tracker);
|
||||
|
||||
cairo_matrix_init_identity (&data->pending);
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
draw_area (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
AreaData *data)
|
||||
{
|
||||
static const GdkRGBA colors[4] = {
|
||||
{ 1, 0, 0, 1 },
|
||||
{ 0, 1, 0, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 1, 1, 0, 1 },
|
||||
};
|
||||
int i, x, y, w, h;
|
||||
|
||||
w = gtk_widget_get_allocated_width (widget);
|
||||
h = gtk_widget_get_allocated_height (widget);
|
||||
x = data->x_offset * w;
|
||||
y = data->y_offset * h;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_translate (cr, x, y);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
gdk_cairo_set_source_rgba (cr, &colors[data->color ^ i]);
|
||||
cairo_rectangle (cr,
|
||||
i % 2 ? (x > 0 ? -w : w) : 0,
|
||||
i / 2 ? (y > 0 ? -h : h) : 0,
|
||||
w, h);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
cairo_translate (cr,
|
||||
gtk_widget_get_allocated_width (widget) / 2.0,
|
||||
gtk_widget_get_allocated_height (widget) / 2.0);
|
||||
cairo_transform (cr, &data->pending);
|
||||
cairo_transform (cr, &data->matrix);
|
||||
|
||||
gdk_cairo_set_source_pixbuf (cr,
|
||||
data->pixbuf,
|
||||
- gdk_pixbuf_get_width (data->pixbuf) / 2.0,
|
||||
- gdk_pixbuf_get_height (data->pixbuf) / 2.0);
|
||||
cairo_paint (cr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkEventRecognizer *recognizer;
|
||||
GtkWidget *window, *area;
|
||||
AreaData area_data = { 0 };
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
|
||||
|
||||
area = gtk_drawing_area_new ();
|
||||
gtk_widget_set_has_window (area, TRUE);
|
||||
gtk_widget_set_size_request (area, 400, 300);
|
||||
|
||||
recognizer = gtk_swipe_recognizer_new ();
|
||||
g_signal_connect (recognizer, "started", G_CALLBACK (update_swipe), &area_data);
|
||||
g_signal_connect (recognizer, "updated", G_CALLBACK (update_swipe), &area_data);
|
||||
g_signal_connect (recognizer, "finished", G_CALLBACK (finish_swipe), &area_data);
|
||||
g_signal_connect (recognizer, "cancelled", G_CALLBACK (cancel_swipe), &area_data);
|
||||
gtk_widget_add_recognizer (area, recognizer);
|
||||
|
||||
cairo_matrix_init_identity (&area_data.matrix);
|
||||
cairo_matrix_init_identity (&area_data.pending);
|
||||
area_data.pixbuf = gdk_pixbuf_new_from_file ("gnome-textfile.png", NULL);
|
||||
g_assert (area_data.pixbuf);
|
||||
|
||||
recognizer = gtk_pinch_pan_recognizer_new ();
|
||||
g_signal_connect (recognizer, "started", G_CALLBACK (update_pinch_pan), &area_data);
|
||||
g_signal_connect (recognizer, "updated", G_CALLBACK (update_pinch_pan), &area_data);
|
||||
g_signal_connect (recognizer, "finished", G_CALLBACK (finish_pinch_pan), &area_data);
|
||||
g_signal_connect (recognizer, "cancelled", G_CALLBACK (cancel_pinch_pan), &area_data);
|
||||
gtk_widget_add_recognizer (area, recognizer);
|
||||
|
||||
g_signal_connect_after (area, "draw", G_CALLBACK (draw_area), &area_data);
|
||||
gtk_container_add (GTK_CONTAINER (window), area);
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user