Esempio n. 1
0
static gboolean
_gtk_gesture_multi_press_check_within_threshold (GtkGestureMultiPress *gesture,
        gdouble               x,
        gdouble               y)
{
    GtkGestureMultiPressPrivate *priv;
    guint double_click_distance;
    GtkSettings *settings;
    GtkWidget *widget;

    priv = gtk_gesture_multi_press_get_instance_private (gesture);

    if (priv->n_presses == 0)
        return TRUE;

    widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
    settings = gtk_widget_get_settings (widget);
    g_object_get (settings,
                  "gtk-double-click-distance", &double_click_distance,
                  NULL);

    if (ABS (priv->initial_press_x - x) < double_click_distance &&
            ABS (priv->initial_press_y - y) < double_click_distance)
    {
        if (!priv->rect_is_set ||
                (x >= priv->rect.x && x < priv->rect.x + priv->rect.width &&
                 y >= priv->rect.y && y < priv->rect.y + priv->rect.height))
            return TRUE;
    }

    return FALSE;
}
Esempio n. 2
0
static void
gtk_gesture_multi_press_begin (GtkGesture       *gesture,
                               GdkEventSequence *sequence)
{
    GtkGestureMultiPress *multi_press;
    GtkGestureMultiPressPrivate *priv;
    guint n_presses, button = 1;
    GdkEventSequence *current;
    const GdkEvent *event;
    GdkDevice *device;
    gdouble x, y;

    if (!gtk_gesture_handles_sequence (gesture, sequence))
        return;

    multi_press = GTK_GESTURE_MULTI_PRESS (gesture);
    priv = gtk_gesture_multi_press_get_instance_private (multi_press);
    event = gtk_gesture_get_last_event (gesture, sequence);
    current = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
    device = gdk_event_get_source_device (event);

    if (event->type == GDK_BUTTON_PRESS)
        button = event->button.button;
    else if (event->type == GDK_TOUCH_BEGIN)
        button = 1;
    else
        return;

    /* Reset the gesture if the button number changes mid-recognition */
    if (priv->n_presses > 0 &&
            priv->current_button != button)
        _gtk_gesture_multi_press_stop (multi_press);

    /* Reset also if the device changed */
    if (priv->current_device && priv->current_device != device)
        _gtk_gesture_multi_press_stop (multi_press);

    priv->current_device = device;
    priv->current_button = button;
    _gtk_gesture_multi_press_update_timeout (multi_press);
    gtk_gesture_get_point (gesture, current, &x, &y);

    if (!_gtk_gesture_multi_press_check_within_threshold (multi_press, x, y))
        _gtk_gesture_multi_press_stop (multi_press);

    /* Increment later the real counter, just if the gesture is
     * reset on the pressed handler */
    n_presses = priv->n_release = priv->n_presses + 1;

    g_signal_emit (gesture, signals[PRESSED], 0, n_presses, x, y);

    if (priv->n_presses == 0)
    {
        priv->initial_press_x = x;
        priv->initial_press_y = y;
    }

    priv->n_presses++;
}
Esempio n. 3
0
static gboolean
_double_click_timeout_cb (gpointer user_data)
{
    GtkGestureMultiPress *gesture = user_data;
    GtkGestureMultiPressPrivate *priv;

    priv = gtk_gesture_multi_press_get_instance_private (gesture);
    priv->double_click_timeout_id = 0;
    _gtk_gesture_multi_press_stop (gesture);

    return FALSE;
}
static void
_gtk_gesture_multi_press_stop (GtkGestureMultiPress *gesture)
{
  GtkGestureMultiPressPrivate *priv;

  priv = gtk_gesture_multi_press_get_instance_private (gesture);

  if (priv->n_presses == 0)
    return;

  priv->current_button = 0;
  priv->n_presses = 0;
  g_signal_emit (gesture, signals[STOPPED], 0);
  _gtk_gesture_check (GTK_GESTURE (gesture));
}
Esempio n. 5
0
static gboolean
gtk_gesture_multi_press_check (GtkGesture *gesture)
{
    GtkGestureMultiPress *multi_press;
    GtkGestureMultiPressPrivate *priv;
    GList *sequences;
    gboolean active;

    multi_press = GTK_GESTURE_MULTI_PRESS (gesture);
    priv = gtk_gesture_multi_press_get_instance_private (multi_press);
    sequences = gtk_gesture_get_sequences (gesture);

    active = g_list_length (sequences) == 1 || priv->double_click_timeout_id;
    g_list_free (sequences);

    return active;
}
Esempio n. 6
0
static void
gtk_gesture_multi_press_finalize (GObject *object)
{
    GtkGestureMultiPressPrivate *priv;
    GtkGestureMultiPress *gesture;

    gesture = GTK_GESTURE_MULTI_PRESS (object);
    priv = gtk_gesture_multi_press_get_instance_private (gesture);

    if (priv->double_click_timeout_id)
    {
        g_source_remove (priv->double_click_timeout_id);
        priv->double_click_timeout_id = 0;
    }

    G_OBJECT_CLASS (gtk_gesture_multi_press_parent_class)->finalize (object);
}
Esempio n. 7
0
static void
gtk_gesture_multi_press_end (GtkGesture       *gesture,
                             GdkEventSequence *sequence)
{
    GtkGestureMultiPress *multi_press;
    GtkGestureMultiPressPrivate *priv;
    GdkEventSequence *current;
    gdouble x, y;

    multi_press = GTK_GESTURE_MULTI_PRESS (gesture);
    priv = gtk_gesture_multi_press_get_instance_private (multi_press);
    current = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
    gtk_gesture_get_point (gesture, current, &x, &y);

    g_signal_emit (gesture, signals[RELEASED], 0, priv->n_release, x, y);
    priv->n_release = 0;
}
Esempio n. 8
0
/**
 * gtk_gesture_multi_press_set_area:
 * @gesture: a #GtkGestureMultiPress
 * @rect: (allow-none): rectangle to receive coordinates on
 *
 * If @rect is non-%NULL, the press area will be checked to be
 * confined within the rectangle, otherwise the button count
 * will be reset so the press is seen as being the first one.
 * If @rect is %NULL, the area will be reset to an unrestricted
 * state.
 *
 * Note: The rectangle is only used to determine whether any
 * non-first click falls within the expected area. This is not
 * akin to an input shape.
 *
 * Since: 3.14
 **/
void
gtk_gesture_multi_press_set_area (GtkGestureMultiPress *gesture,
                                  const GdkRectangle   *rect)
{
  GtkGestureMultiPressPrivate *priv;

  g_return_if_fail (GTK_IS_GESTURE_MULTI_PRESS (gesture));

  priv = gtk_gesture_multi_press_get_instance_private (gesture);

  if (!rect)
    priv->rect_is_set = FALSE;
  else
    {
      priv->rect_is_set = TRUE;
      priv->rect = *rect;
    }
}
Esempio n. 9
0
static void
_gtk_gesture_multi_press_update_timeout (GtkGestureMultiPress *gesture)
{
    GtkGestureMultiPressPrivate *priv;
    guint double_click_time;
    GtkSettings *settings;
    GtkWidget *widget;

    priv = gtk_gesture_multi_press_get_instance_private (gesture);

    if (priv->double_click_timeout_id)
        g_source_remove (priv->double_click_timeout_id);

    widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
    settings = gtk_widget_get_settings (widget);
    g_object_get (settings, "gtk-double-click-time", &double_click_time, NULL);

    priv->double_click_timeout_id =
        gdk_threads_add_timeout (double_click_time,
                                 _double_click_timeout_cb,
                                 gesture);
}
Esempio n. 10
0
static void
gtk_gesture_multi_press_end (GtkGesture       *gesture,
                             GdkEventSequence *sequence)
{
  GtkGestureMultiPress *multi_press;
  GtkGestureMultiPressPrivate *priv;
  GdkEventSequence *current;
  gdouble x, y;
  gboolean interpreted;
  GtkEventSequenceState state;

  multi_press = GTK_GESTURE_MULTI_PRESS (gesture);
  priv = gtk_gesture_multi_press_get_instance_private (multi_press);
  current = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
  interpreted = gtk_gesture_get_point (gesture, current, &x, &y);
  state = gtk_gesture_get_sequence_state (gesture, current);

  if (state != GTK_EVENT_SEQUENCE_DENIED && interpreted)
    g_signal_emit (gesture, signals[RELEASED], 0, priv->n_release, x, y);

  priv->n_release = 0;
}
Esempio n. 11
0
/**
 * gtk_gesture_multi_press_get_area:
 * @gesture: a #GtkGestureMultiPress
 * @rect: (out): return location for the press area
 *
 * If an area was set through gtk_gesture_multi_press_set_area(),
 * this function will return %TRUE and fill in @rect with the
 * press area. See gtk_gesture_multi_press_set_area() for more
 * details on what the press area represents.
 *
 * Returns: %TRUE if @rect was filled with the press area
 *
 * Since: 3.14
 **/
gboolean
gtk_gesture_multi_press_get_area (GtkGestureMultiPress *gesture,
                                  GdkRectangle         *rect)
{
    GtkGestureMultiPressPrivate *priv;

    g_return_val_if_fail (GTK_IS_GESTURE_MULTI_PRESS (gesture), FALSE);

    priv = gtk_gesture_multi_press_get_instance_private (gesture);

    if (rect)
    {
        if (priv->rect_is_set)
            *rect = priv->rect;
        else
        {
            rect->x = rect->y = G_MININT;
            rect->width = rect->height = G_MAXINT;
        }
    }

    return priv->rect_is_set;
}