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;
  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));

  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);

  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++;
}
Beispiel #2
0
static void
gtk_color_swatch_init (GtkColorSwatch *swatch)
{
  swatch->priv = gtk_color_swatch_get_instance_private (swatch);
  swatch->priv->use_alpha = TRUE;
  swatch->priv->selectable = TRUE;
  swatch->priv->has_menu = TRUE;

  gtk_widget_set_can_focus (GTK_WIDGET (swatch), TRUE);
  gtk_widget_set_has_window (GTK_WIDGET (swatch), FALSE);

  swatch->priv->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (swatch));
  gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (swatch->priv->long_press_gesture),
                                     TRUE);
  g_signal_connect (swatch->priv->long_press_gesture, "pressed",
                    G_CALLBACK (hold_action), swatch);

  swatch->priv->multipress_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (swatch));
  gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (swatch->priv->multipress_gesture), 0);
  g_signal_connect (swatch->priv->multipress_gesture, "pressed",
                    G_CALLBACK (tap_action), swatch);
}
Beispiel #3
0
static void
gtk_app_chooser_widget_init (GtkAppChooserWidget *self)
{
  GtkTreeSelection *selection;
  GtkTreeModel *sort;
  GtkGesture *gesture;

  self->priv = gtk_app_chooser_widget_get_instance_private (self);

  gtk_widget_set_has_surface (GTK_WIDGET (self), FALSE);

  gtk_widget_init_template (GTK_WIDGET (self));

  /* Various parts of the GtkTreeView code need custom code to setup, mostly
   * because we lack signals to connect to, or properties to set.
   */
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list));
  gtk_tree_selection_set_select_function (selection, gtk_app_chooser_selection_func,
                                          self, NULL);

  sort = gtk_tree_view_get_model (GTK_TREE_VIEW (self->priv->program_list));
  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort),
                                        COLUMN_NAME,
                                        GTK_SORT_ASCENDING);
  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sort),
                                   COLUMN_NAME,
                                   gtk_app_chooser_sort_func,
                                   self, NULL);

  gtk_tree_view_set_search_column (GTK_TREE_VIEW (self->priv->program_list), COLUMN_NAME);
  gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (self->priv->program_list),
                                       gtk_app_chooser_search_equal_func,
                                       NULL, NULL);

  gtk_tree_view_column_set_cell_data_func (self->priv->column,
					   self->priv->secondary_padding,
                                           padding_cell_renderer_func,
                                           NULL, NULL);

  self->priv->monitor = g_app_info_monitor_get ();
  g_signal_connect (self->priv->monitor, "changed",
		    G_CALLBACK (app_info_changed), self);

  gesture = gtk_gesture_multi_press_new ();
  gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
  g_signal_connect (gesture, "pressed",
                    G_CALLBACK (gtk_app_chooser_row_pressed_cb), self);
  gtk_widget_add_controller (self->priv->program_list, GTK_EVENT_CONTROLLER (gesture));
}
Beispiel #4
0
static void
gtk_gesture_multi_press_update (GtkGesture       *gesture,
                                GdkEventSequence *sequence)
{
    GtkGestureMultiPress *multi_press;
    GdkEventSequence *current;
    gdouble x, y;

    multi_press = GTK_GESTURE_MULTI_PRESS (gesture);
    current = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
    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);
}
Beispiel #5
0
static void
gtk_gesture_single_set_property (GObject      *object,
                                 guint         prop_id,
                                 const GValue *value,
                                 GParamSpec   *pspec)
{
  switch (prop_id)
    {
    case PROP_TOUCH_ONLY:
      gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (object),
                                         g_value_get_boolean (value));
      break;
    case PROP_EXCLUSIVE:
      gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (object),
                                        g_value_get_boolean (value));
      break;
    case PROP_BUTTON:
      gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (object),
                                     g_value_get_uint (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}
Beispiel #6
0
static void
gtk_button_init (GtkButton *button)
{
  GtkButtonPrivate *priv;

  button->priv = gtk_button_get_instance_private (button);
  priv = button->priv;

  gtk_widget_set_can_focus (GTK_WIDGET (button), TRUE);
  gtk_widget_set_receives_default (GTK_WIDGET (button), TRUE);
  gtk_widget_set_has_window (GTK_WIDGET (button), FALSE);

  priv->in_button = FALSE;
  priv->button_down = FALSE;
  priv->use_underline = FALSE;
  priv->child_type = WIDGET_CHILD;

  priv->gesture = gtk_gesture_multi_press_new (GTK_WIDGET (button));
  gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->gesture), FALSE);
  gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (priv->gesture), TRUE);
  gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->gesture), GDK_BUTTON_PRIMARY);
  g_signal_connect (priv->gesture, "pressed", G_CALLBACK (multipress_pressed_cb), button);
  g_signal_connect (priv->gesture, "released", G_CALLBACK (multipress_released_cb), button);
  g_signal_connect (priv->gesture, "update", G_CALLBACK (multipress_gesture_update_cb), button);
  g_signal_connect (priv->gesture, "cancel", G_CALLBACK (multipress_gesture_cancel_cb), button);
  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->gesture), GTK_PHASE_BUBBLE);

  priv->gadget = gtk_css_custom_gadget_new_for_node (gtk_widget_get_css_node (GTK_WIDGET (button)),
                                                     GTK_WIDGET (button),
                                                     gtk_button_measure,
                                                     gtk_button_allocate,
                                                     gtk_button_render,
                                                     NULL,
                                                     NULL);

}
void GestureController::DragGesture::update(DragGesture* dragGesture, double x, double y, GtkGesture* gesture)
{
    GdkEventSequence* sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
    gtk_gesture_set_sequence_state(gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);

    GtkWidget* widget = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture));
    if (!dragGesture->m_inDrag && gtk_drag_check_threshold(widget, dragGesture->m_start.x(), dragGesture->m_start.y(), dragGesture->m_start.x() + x, dragGesture->m_start.y() + y)) {
        dragGesture->m_inDrag = true;
        dragGesture->m_longPressTimeout.cancel();
    }

    if (dragGesture->m_inDrag)
        dragGesture->handleDrag(gtk_gesture_get_last_event(gesture, sequence), x, y);
    dragGesture->m_offset.set(x, y);
}
void GestureController::DragGesture::begin(DragGesture* dragGesture, double x, double y, GtkGesture* gesture)
{
    GdkEventSequence* sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
    gtk_gesture_set_sequence_state(gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);
    dragGesture->m_inDrag = false;
    dragGesture->m_start.set(x, y);
    dragGesture->m_offset.set(0, 0);

    GtkWidget* widget = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture));
    unsigned delay;
    g_object_get(gtk_widget_get_settings(widget), "gtk-long-press-time", &delay, nullptr);
    dragGesture->m_longPressTimeout.scheduleAfterDelay("[WebKit] DragGesture long press timeout", [dragGesture]() {
        dragGesture->m_inDrag = true;
    }, std::chrono::milliseconds(delay));
}
static void
cb_media_image_widget_init (CbMediaImageWidget *self)
{
  self->image = gtk_image_new ();
  gtk_container_add (GTK_CONTAINER (self), self->image);

  self->initial_scroll_x = 0.5;
  self->initial_scroll_y = 0.5;

  self->drag_gesture = gtk_gesture_drag_new (GTK_WIDGET (self));
  gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (self->drag_gesture), GDK_BUTTON_MIDDLE);
  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (self->drag_gesture), GTK_PHASE_CAPTURE);
  g_signal_connect (self->drag_gesture, "drag-begin", G_CALLBACK (drag_begin_cb), self);
  g_signal_connect (self->drag_gesture, "drag-update", G_CALLBACK (drag_update_cb), self);
}
Beispiel #10
0
static void
gtk_switch_multipress_gesture_released (GtkGestureMultiPress *gesture,
                                        gint                  n_press,
                                        gdouble               x,
                                        gdouble               y,
                                        GtkSwitch            *sw)
{
  GtkSwitchPrivate *priv = sw->priv;
  GdkEventSequence *sequence;

  sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));

  if (priv->in_switch &&
      gtk_gesture_handles_sequence (GTK_GESTURE (gesture), sequence))
    gtk_switch_begin_toggle_animation (sw);
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
0
static void
tap_action (GtkGestureMultiPress *gesture,
            gint                  n_press,
            gdouble               x,
            gdouble               y,
            GtkColorSwatch       *swatch)
{
    guint button;

    button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));

    if (button == GDK_BUTTON_PRIMARY)
    {
        if (n_press == 1)
            swatch_primary_action (swatch);
        else if (n_press > 1)
            g_signal_emit (swatch, signals[ACTIVATE], 0);
    }
    else if (button == GDK_BUTTON_SECONDARY)
    {
        if (swatch->priv->has_color && swatch->priv->has_menu)
            do_popup (swatch);
    }
}
Beispiel #14
0
static void
multipress_gesture_update_cb (GtkGesture       *gesture,
                              GdkEventSequence *sequence,
                              GtkButton        *button)
{
  GtkButtonPrivate *priv = button->priv;
  GtkAllocation allocation;
  gboolean in_button;
  gdouble x, y;

  if (sequence != gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture)))
    return;

  gtk_widget_get_allocation (GTK_WIDGET (button), &allocation);
  gtk_gesture_get_point (gesture, sequence, &x, &y);

  in_button = (x >= 0 && y >= 0 && x < allocation.width && y < allocation.height);

  if (priv->in_button != in_button)
    {
      priv->in_button = in_button;
      gtk_button_update_state (button);
    }
}
Beispiel #15
0
static void
multipress_released_cb (GtkGestureMultiPress *gesture,
                        guint                 n_press,
                        gdouble               x,
                        gdouble               y,
                        GtkWidget            *widget)
{
  GtkButton *button = GTK_BUTTON (widget);
  GtkButtonPrivate *priv = button->priv;
  GdkEventSequence *sequence;

  gtk_button_do_release (button,
                         gtk_widget_is_sensitive (GTK_WIDGET (button)) &&
                         (button->priv->in_button ||
                          touch_release_in_button (button)));

  sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));

  if (sequence)
    {
      priv->in_button = FALSE;
      gtk_button_update_state (button);
    }
}
Beispiel #16
0
static void
gtk_switch_pan_gesture_drag_end (GtkGestureDrag *gesture,
                                 gdouble         x,
                                 gdouble         y,
                                 GtkSwitch      *sw)
{
  GtkSwitchPrivate *priv = sw->priv;
  GdkEventSequence *sequence;
  GtkAllocation allocation;
  gboolean active = FALSE;

  sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));

  if (gtk_gesture_get_sequence_state (GTK_GESTURE (gesture), sequence) == GTK_EVENT_SEQUENCE_CLAIMED)
    {
      gtk_widget_get_allocation (GTK_WIDGET (sw), &allocation);

      /* if half the handle passed the middle of the switch, then we
       * consider it to be on
       */
      if ((priv->handle_x + (allocation.width / 4)) >= (allocation.width / 2))
        active = TRUE;
    }
  else if (!gtk_gesture_handles_sequence (priv->multipress_gesture, sequence))
    active = priv->is_active;
  else
    return;

  if (active)
    priv->handle_x = allocation.width / 2;
  else
    priv->handle_x = 0;

  gtk_switch_set_active (sw, active);
  gtk_widget_queue_draw (GTK_WIDGET (sw));
}
Beispiel #17
0
GtkWidget *
do_clipboard (GtkWidget *do_widget)
{
  if (!window)
    {
      GtkWidget *vbox, *hbox;
      GtkWidget *label;
      GtkWidget *entry, *button;
      GtkWidget *image;
      GtkGesture *gesture;

      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_display (GTK_WINDOW (window),
                              gtk_widget_get_display (do_widget));
      gtk_window_set_title (GTK_WINDOW (window), "Clipboard");

      g_signal_connect (window, "destroy",
                        G_CALLBACK (gtk_widget_destroyed), &window);

      vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
      g_object_set (vbox, "margin", 8, NULL);

      gtk_container_add (GTK_CONTAINER (window), vbox);

      label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard");

      gtk_container_add (GTK_CONTAINER (vbox), label);

      hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
      g_object_set (hbox, "margin", 8, NULL);
      gtk_container_add (GTK_CONTAINER (vbox), hbox);

      /* Create the first entry */
      entry = gtk_entry_new ();
      gtk_container_add (GTK_CONTAINER (hbox), entry);

      /* Create the button */
      button = gtk_button_new_with_mnemonic (_("_Copy"));
      gtk_container_add (GTK_CONTAINER (hbox), button);
      g_signal_connect (button, "clicked",
                        G_CALLBACK (copy_button_clicked), entry);

      label = gtk_label_new ("\"Paste\" will paste the text from the clipboard to the entry");
      gtk_container_add (GTK_CONTAINER (vbox), label);

      hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
      g_object_set (hbox, "margin", 8, NULL);
      gtk_container_add (GTK_CONTAINER (vbox), hbox);

      /* Create the second entry */
      entry = gtk_entry_new ();
      gtk_container_add (GTK_CONTAINER (hbox), entry);

      /* Create the button */
      button = gtk_button_new_with_mnemonic (_("_Paste"));
      gtk_container_add (GTK_CONTAINER (hbox), button);
      g_signal_connect (button, "clicked",
                        G_CALLBACK (paste_button_clicked), entry);

      label = gtk_label_new ("Images can be transferred via the clipboard, too");
      gtk_container_add (GTK_CONTAINER (vbox), label);

      hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
      g_object_set (hbox, "margin", 8, NULL);
      gtk_container_add (GTK_CONTAINER (vbox), hbox);

      /* Create the first image */
      image = gtk_image_new_from_icon_name ("dialog-warning");
      gtk_container_add (GTK_CONTAINER (hbox), image);

      /* make image a drag source */
      gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, GDK_ACTION_COPY);
      gtk_drag_source_add_image_targets (image);
      g_signal_connect (image, "drag-begin",
                        G_CALLBACK (drag_begin), image);
      g_signal_connect (image, "drag-data-get",
                        G_CALLBACK (drag_data_get), image);

      /* accept drops on image */
      gtk_drag_dest_set (image, GTK_DEST_DEFAULT_ALL,
                         NULL, GDK_ACTION_COPY);
      gtk_drag_dest_add_image_targets (image);
      g_signal_connect (image, "drag-data-received",
                        G_CALLBACK (drag_data_received), image);

      /* context menu on image */
      gesture = gtk_gesture_multi_press_new ();
      gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
      g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
      gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));

      /* Create the second image */
      image = gtk_image_new_from_icon_name ("process-stop");
      gtk_container_add (GTK_CONTAINER (hbox), image);

      /* make image a drag source */
      gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, GDK_ACTION_COPY);
      gtk_drag_source_add_image_targets (image);
      g_signal_connect (image, "drag-begin",
                        G_CALLBACK (drag_begin), image);
      g_signal_connect (image, "drag-data-get",
                        G_CALLBACK (drag_data_get), image);

      /* accept drops on image */
      gtk_drag_dest_set (image, GTK_DEST_DEFAULT_ALL,
                         NULL, GDK_ACTION_COPY);
      gtk_drag_dest_add_image_targets (image);
      g_signal_connect (image, "drag-data-received",
                        G_CALLBACK (drag_data_received), image);

      /* context menu on image */
      gesture = gtk_gesture_multi_press_new ();
      gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
      g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
      gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
    }

  if (!gtk_widget_get_visible (window))
    gtk_widget_show (window);
  else
    gtk_widget_destroy (window);

  return window;
}
Beispiel #18
0
GtkWidget *
do_drawingarea (GtkWidget *do_widget)
{
  GtkWidget *frame;
  GtkWidget *vbox;
  GtkWidget *da;
  GtkWidget *label;
  GtkGesture *drag;

  if (!window)
    {
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_display (GTK_WINDOW (window),
                              gtk_widget_get_display (do_widget));
      gtk_window_set_title (GTK_WINDOW (window), "Drawing Area");

      g_signal_connect (window, "destroy",
                        G_CALLBACK (close_window), NULL);

      vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
      g_object_set (vbox, "margin", 16, NULL);
      gtk_container_add (GTK_CONTAINER (window), vbox);

      /*
       * Create the checkerboard area
       */

      label = gtk_label_new (NULL);
      gtk_label_set_markup (GTK_LABEL (label),
                            "<u>Checkerboard pattern</u>");
      gtk_container_add (GTK_CONTAINER (vbox), label);

      frame = gtk_frame_new (NULL);
      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
      gtk_widget_set_vexpand (frame, TRUE);
      gtk_container_add (GTK_CONTAINER (vbox), frame);

      da = gtk_drawing_area_new ();
      gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
      gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 100);
      gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), checkerboard_draw, NULL, NULL);
      gtk_container_add (GTK_CONTAINER (frame), da);

      /*
       * Create the scribble area
       */

      label = gtk_label_new (NULL);
      gtk_label_set_markup (GTK_LABEL (label),
                            "<u>Scribble area</u>");
      gtk_container_add (GTK_CONTAINER (vbox), label);

      frame = gtk_frame_new (NULL);
      gtk_widget_set_vexpand (frame, TRUE);
      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
      gtk_container_add (GTK_CONTAINER (vbox), frame);

      da = gtk_drawing_area_new ();
      gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
      gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 100);
      gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), scribble_draw, NULL, NULL);
      gtk_container_add (GTK_CONTAINER (frame), da);

      g_signal_connect (da, "size-allocate",
                        G_CALLBACK (scribble_size_allocate), NULL);

      drag = gtk_gesture_drag_new ();
      gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), GDK_BUTTON_PRIMARY);
      gtk_widget_add_controller (da, GTK_EVENT_CONTROLLER (drag));

      g_signal_connect (drag, "drag-begin", G_CALLBACK (drag_begin), da);
      g_signal_connect (drag, "drag-update", G_CALLBACK (drag_update), da);
      g_signal_connect (drag, "drag-end", G_CALLBACK (drag_end), da);

    }

  if (!gtk_widget_get_visible (window))
      gtk_widget_show (window);
  else
      gtk_widget_destroy (window);

  return window;
}
static void
photos_preview_nav_buttons_constructed (GObject *object)
{
  PhotosPreviewNavButtons *self = PHOTOS_PREVIEW_NAV_BUTTONS (object);
  GtkStyleContext *context;
  GtkWidget *button;
  GtkWidget *image;

  G_OBJECT_CLASS (photos_preview_nav_buttons_parent_class)->constructed (object);

  self->prev_widget = g_object_ref_sink (gtk_revealer_new ());
  gtk_widget_set_halign (self->prev_widget, GTK_ALIGN_START);
  gtk_widget_set_margin_start (self->prev_widget, 30);
  gtk_widget_set_margin_end (self->prev_widget, 30);
  gtk_widget_set_valign (self->prev_widget, GTK_ALIGN_CENTER);
  gtk_revealer_set_transition_type (GTK_REVEALER (self->prev_widget), GTK_REVEALER_TRANSITION_TYPE_CROSSFADE);
  gtk_overlay_add_overlay (GTK_OVERLAY (self->overlay), self->prev_widget);

  image = gtk_image_new_from_icon_name (PHOTOS_ICON_GO_PREVIOUS_SYMBOLIC, GTK_ICON_SIZE_INVALID);
  gtk_image_set_pixel_size (GTK_IMAGE (image), 16);

  button = gtk_button_new ();
  gtk_button_set_image (GTK_BUTTON (button), image);
  gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "app.load-previous");
  context = gtk_widget_get_style_context (button);
  gtk_style_context_add_class (context, "osd");
  gtk_container_add (GTK_CONTAINER (self->prev_widget), button);
  g_signal_connect_swapped (button,
                            "enter-notify-event",
                            G_CALLBACK (photos_preview_nav_buttons_enter_notify),
                            self);
  g_signal_connect_swapped (button,
                            "leave-notify-event",
                            G_CALLBACK (photos_preview_nav_buttons_leave_notify),
                            self);

  self->next_widget = g_object_ref_sink (gtk_revealer_new ());
  gtk_widget_set_halign (self->next_widget, GTK_ALIGN_END);
  gtk_widget_set_margin_start (self->next_widget, 30);
  gtk_widget_set_margin_end (self->next_widget, 30);
  gtk_widget_set_valign (self->next_widget, GTK_ALIGN_CENTER);
  gtk_revealer_set_transition_type (GTK_REVEALER (self->next_widget), GTK_REVEALER_TRANSITION_TYPE_CROSSFADE);
  gtk_overlay_add_overlay (GTK_OVERLAY (self->overlay), self->next_widget);

  image = gtk_image_new_from_icon_name (PHOTOS_ICON_GO_NEXT_SYMBOLIC, GTK_ICON_SIZE_INVALID);
  gtk_image_set_pixel_size (GTK_IMAGE (image), 16);

  button = gtk_button_new ();
  gtk_button_set_image (GTK_BUTTON (button), image);
  gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "app.load-next");
  context = gtk_widget_get_style_context (button);
  gtk_style_context_add_class (context, "osd");
  gtk_container_add (GTK_CONTAINER (self->next_widget), button);
  g_signal_connect_swapped (button,
                            "enter-notify-event",
                            G_CALLBACK (photos_preview_nav_buttons_enter_notify),
                            self);
  g_signal_connect_swapped (button,
                            "leave-notify-event",
                            G_CALLBACK (photos_preview_nav_buttons_leave_notify),
                            self);

  g_signal_connect_swapped (self->overlay,
                            "motion-notify-event",
                            G_CALLBACK (photos_preview_nav_buttons_motion_notify),
                            self);

  self->tap_gesture = gtk_gesture_multi_press_new (self->preview_view);
  gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (self->tap_gesture), TRUE);
  g_signal_connect_swapped (self->tap_gesture,
                            "released",
                            G_CALLBACK (photos_preview_nav_buttons_multi_press_released),
                            self);
  g_signal_connect_swapped (self->tap_gesture,
                            "stopped",
                            G_CALLBACK (photos_preview_nav_buttons_multi_press_stopped),
                            self);

  /* We will not need them any more */
  self->overlay = NULL;
  self->preview_view = NULL;
}
/* The multi-press gesture used by the flowbox to select a child
 * forbid us to use dnd so we need to catch it here and select yourself
 * the child
 */
static void
gstyle_color_widget_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
                                                guint                 n_press,
                                                gdouble               x,
                                                gdouble               y,
                                                GstyleColorWidget    *self)
{
  GtkWidget *container;
  GtkWidget *child;
  GtkWidget *popover;
  GtkBuilder *builder;
  GtkWidget *button_rename;
  GtkWidget *button_remove;
  GtkWidget *ancestor;
  gint button;

  button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
  gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);

  child = gtk_widget_get_parent (GTK_WIDGET (self));
  if (child != NULL && button == GDK_BUTTON_PRIMARY)
    {
      if (GTK_IS_LIST_BOX_ROW (child))
        {
          container = gtk_widget_get_parent (GTK_WIDGET (child));
          if (container != NULL && GTK_IS_LIST_BOX (container))
            {
              gtk_list_box_select_row (GTK_LIST_BOX (container), GTK_LIST_BOX_ROW (child));
              gtk_widget_grab_focus (GTK_WIDGET (self));
              if (n_press == 2)
                g_signal_emit_by_name (container, "row-activated", child);
            }
        }
      else if (GTK_IS_FLOW_BOX_CHILD (child))
        {
          container = gtk_widget_get_parent (GTK_WIDGET (child));
          if (container != NULL && GTK_IS_FLOW_BOX (container))
            {
              gtk_flow_box_select_child (GTK_FLOW_BOX (container), GTK_FLOW_BOX_CHILD (child));
              gtk_widget_grab_focus (GTK_WIDGET (self));
              if (n_press == 2)
                g_signal_emit_by_name (container, "child-activated", child);
            }
        }
    }

  if (button == GDK_BUTTON_SECONDARY)
    {
      ancestor = gtk_widget_get_ancestor (GTK_WIDGET (self), GSTYLE_TYPE_PALETTE_WIDGET);
      if (ancestor != NULL)
        {
          builder = gtk_builder_new_from_resource ("/org/gnome/libgstyle/ui/gstyle-color-widget.ui");
          popover = GTK_WIDGET (gtk_builder_get_object (builder, "popover"));
          button_rename = GTK_WIDGET (gtk_builder_get_object (builder, "button_rename"));
          g_signal_connect_object (button_rename, "button-release-event",
                                   G_CALLBACK (popover_button_rename_clicked_cb), self, G_CONNECT_SWAPPED);

          button_remove = GTK_WIDGET (gtk_builder_get_object (builder, "button_remove"));
          g_signal_connect_object (button_remove, "button-release-event",
                                   G_CALLBACK (popover_button_remove_clicked_cb), self, G_CONNECT_SWAPPED);

          gtk_popover_set_relative_to (GTK_POPOVER (popover), GTK_WIDGET (self));
          g_signal_connect_swapped (popover, "closed", G_CALLBACK (contextual_popover_closed_cb), self);
          gtk_widget_show (popover);
          g_object_unref (builder);
        }
    }
}
static void
gstyle_color_widget_drag_gesture_update (GtkGestureDrag    *gesture,
                                         gdouble            offset_x,
                                         gdouble            offset_y,
                                         GstyleColorWidget *self)
{
  GdkDragContext *context;
  GdkEventSequence *sequence;
  const GdkEvent *event;
  gdouble start_x, start_y;
  GtkAllocation allocation;
  GstylePaletteWidgetDndLockFlags dnd_lock;
  GtkWidget *container;
  GdkDragAction drag_action;
  gint button;

  g_assert (GTK_IS_GESTURE (gesture));
  g_assert (GSTYLE_IS_COLOR_WIDGET (self));

  dnd_lock = get_palette_widget_dnd_lock (self);
  if ((dnd_lock & GSTYLE_PALETTE_WIDGET_DND_LOCK_FLAGS_DRAG) != 0)
    return;

  button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
  if (!gtk_drag_check_threshold (GTK_WIDGET (self), 0, 0, offset_x, offset_y) ||
      button != GDK_BUTTON_PRIMARY)
    return;

  gtk_widget_get_allocation (GTK_WIDGET (self), &allocation);
  self->dnd_color_widget = gstyle_color_widget_copy (self);

  if (self->filter_func != NULL && GSTYLE_IS_COLOR (self->filtered_color))
    gstyle_color_widget_set_color (self->dnd_color_widget, self->filtered_color);

  self->dnd_window = gtk_window_new (GTK_WINDOW_POPUP);

  gtk_widget_set_size_request (self->dnd_window, allocation.width, allocation.height);
  gtk_window_set_screen (GTK_WINDOW (self->dnd_window), gtk_widget_get_screen (GTK_WIDGET (self)));

  gtk_container_add (GTK_CONTAINER (self->dnd_window), GTK_WIDGET (self->dnd_color_widget));
  gtk_widget_show_all (self->dnd_window);
  gtk_widget_set_opacity (self->dnd_window, GSTYLE_COLOR_WIDGET_DRAG_ICON_OPACITY);

  sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
  gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (gesture), &start_x, &start_y);
  event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);

  container = gtk_widget_get_ancestor (GTK_WIDGET (self), GSTYLE_TYPE_PALETTE_WIDGET);
  if (container != NULL && GSTYLE_IS_PALETTE_WIDGET (container))
    drag_action = (GDK_ACTION_MOVE | GDK_ACTION_COPY);
  else
    drag_action = GDK_ACTION_COPY;

  context = gtk_drag_begin_with_coordinates (GTK_WIDGET (self),
                                             self->target_list,
                                             drag_action,
                                             button,
                                             (GdkEvent*)event,
                                             start_x, start_y);

  gtk_drag_set_icon_widget (context, self->dnd_window, 0, 0);
}
Beispiel #22
0
static gboolean
gtk_gesture_single_handle_event (GtkEventController *controller,
                                 const GdkEvent     *event)
{
  GdkEventSequence *sequence = NULL;
  GtkGestureSinglePrivate *priv;
  GdkDevice *source_device;
  GdkInputSource source;
  guint button = 0, i;
  gboolean retval, test_touchscreen = FALSE;

  source_device = gdk_event_get_source_device (event);

  if (!source_device)
    return FALSE;

  priv = gtk_gesture_single_get_instance_private (GTK_GESTURE_SINGLE (controller));
  source = gdk_device_get_source (source_device);

  if (source != GDK_SOURCE_TOUCHSCREEN)
    test_touchscreen = gtk_simulate_touchscreen ();

  switch (event->type)
    {
    case GDK_TOUCH_BEGIN:
    case GDK_TOUCH_END:
    case GDK_TOUCH_UPDATE:
      if (priv->exclusive && !event->touch.emulating_pointer)
        return FALSE;

      sequence = event->touch.sequence;
      button = 1;
      break;
    case GDK_BUTTON_PRESS:
    case GDK_BUTTON_RELEASE:
      if (priv->touch_only && !test_touchscreen && source != GDK_SOURCE_TOUCHSCREEN)
        return FALSE;

      button = event->button.button;
      break;
    case GDK_MOTION_NOTIFY:
      if (!gtk_gesture_handles_sequence (GTK_GESTURE (controller), sequence))
        return FALSE;
      if (priv->touch_only && !test_touchscreen && source != GDK_SOURCE_TOUCHSCREEN)
        return FALSE;

      if (priv->current_button > 0 && priv->current_button <= 5 &&
          (event->motion.state & (GDK_BUTTON1_MASK << (priv->current_button - 1))))
        button = priv->current_button;
      else if (priv->current_button == 0)
        {
          /* No current button, find out from the mask */
          for (i = 0; i < 3; i++)
            {
              if ((event->motion.state & (GDK_BUTTON1_MASK << i)) == 0)
                continue;
              button = i + 1;
              break;
            }
        }

      break;
    case GDK_TOUCH_CANCEL:
    case GDK_GRAB_BROKEN:
      return GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_single_parent_class)->handle_event (controller,
                                                                                         event);
      break;
    default:
      return FALSE;
    }

  if (button == 0 ||
      (priv->button != 0 && priv->button != button) ||
      (priv->current_button != 0 && priv->current_button != button))
    {
      if (gtk_gesture_is_active (GTK_GESTURE (controller)))
        gtk_event_controller_reset (controller);
      return FALSE;
    }

  if (event->type == GDK_BUTTON_PRESS || event->type == GDK_TOUCH_BEGIN ||
      event->type == GDK_MOTION_NOTIFY || event->type == GDK_TOUCH_UPDATE)
    {
      if (!gtk_gesture_is_active (GTK_GESTURE (controller)))
        priv->current_sequence = sequence;

      priv->current_button = button;
    }

  retval = GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_single_parent_class)->handle_event (controller, event);

  if (sequence == priv->current_sequence &&
      (event->type == GDK_BUTTON_RELEASE || event->type == GDK_TOUCH_END))
    priv->current_button = 0;
  else if (priv->current_sequence == sequence &&
           !gtk_gesture_handles_sequence (GTK_GESTURE (controller), sequence))
    {
      if (button == priv->current_button && event->type == GDK_BUTTON_PRESS)
        priv->current_button = 0;
      else if (sequence == priv->current_sequence && event->type == GDK_TOUCH_BEGIN)
        priv->current_sequence = NULL;
    }

  return retval;
}