예제 #1
0
static gboolean
egg_tree_multi_drag_motion_event (GtkWidget      *widget,
				  GdkEventMotion *event,
				  gpointer        data)
{
  EggTreeMultiDndData *priv_data;

  priv_data = g_object_get_data (G_OBJECT (widget), EGG_TREE_MULTI_DND_STRING);

  if (! priv_data->pending_event)
    return FALSE;

  if (gtk_drag_check_threshold (widget,
				priv_data->x,
				priv_data->y,
				event->x,
				event->y))
    {
      GList            *path_list = NULL;
      GtkTreeSelection *selection;
      GtkTreeModel     *model;
      GdkDragContext   *context;

      stop_drag_check (widget);

      selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
      gtk_tree_selection_selected_foreach (selection, selection_foreach, &path_list);
      if (path_list == NULL)
	      return FALSE;

      path_list = g_list_reverse (path_list);

      model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
      if (egg_tree_multi_drag_source_row_draggable (EGG_TREE_MULTI_DRAG_SOURCE (model), path_list))
	{
	  GtkTargetList *target_list;
	  GtkTreePath   *tree_path;
	  int            cell_x;
	  int            cell_y;

	  target_list = gtk_target_list_new (target_table, G_N_ELEMENTS (target_table));
	  context = gtk_drag_begin_with_coordinates (widget,
			  	  	  	     target_list,
			  	  	  	     GDK_ACTION_COPY,
			  	  	  	     priv_data->pressed_button,
			  	  	  	     (GdkEvent*) event,
			  	  	  	     event->x,
			  	  	  	     event->y);
	  set_context_data (context, path_list);

	  if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
					     priv_data->x,
					     priv_data->y,
					     &tree_path,
					     NULL,
					     &cell_x,
					     &cell_y))
	  {
		  cairo_surface_t *drag_icon;

		  drag_icon = gtk_tree_view_create_row_drag_icon (GTK_TREE_VIEW (widget), tree_path);

		  if (path_list->next != NULL) {

			  /* create a multi row drag icon */

			  const int        icon_offset = DRAG_ICON_OFFSET;
			  GdkRectangle     icon_extents;
			  cairo_surface_t *multi_drag_icon;
			  cairo_t         *cr;
			  int              n_icons, i, offset;

			  n_icons = MIN (DRAG_ICON_MAX_ROWS, g_list_length (path_list));
			  _gtk_cairo_surface_extents (drag_icon, &icon_extents);

			  multi_drag_icon = gdk_window_create_similar_surface (gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget)),
									       CAIRO_CONTENT_COLOR_ALPHA,
									       icon_extents.width + (icon_offset * (n_icons - 1)),
									       icon_extents.height + (icon_offset * (n_icons - 1)));

			  cr = cairo_create (multi_drag_icon);

			  cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0);
			  cairo_rectangle(cr, 0, 0, icon_extents.width + icon_offset, icon_extents.height + icon_offset);
			  cairo_fill (cr);

			  offset = icon_offset * (n_icons - 1);
			  for (i = 0; i < n_icons; i++) {
				  cairo_set_source_surface (cr, drag_icon, -icon_extents.x + offset, -icon_extents.y + offset);
				  cairo_rectangle (cr, offset, offset, icon_extents.width, icon_extents.height);
				  cairo_fill (cr);
				  offset -= icon_offset;
			  }

			  cairo_destroy (cr);

			  cairo_surface_set_device_offset (multi_drag_icon, - (cell_x + 1), - (cell_y + 1));
			  gtk_drag_set_icon_surface (context, multi_drag_icon);

			  cairo_surface_destroy (multi_drag_icon);
		  }
		  else {
			  cairo_surface_set_device_offset (drag_icon, - (cell_x + 1), - (cell_y + 1));
			  gtk_drag_set_icon_surface (context, drag_icon);
		  }

		  cairo_surface_destroy (drag_icon);
		  gtk_tree_path_free (tree_path);
	  }
	  else
		  gtk_drag_set_icon_default (context);

	  gtk_target_list_unref (target_list);
	}
      else
	{
	  path_list_free (path_list);
	}
    }

  return TRUE;
}
예제 #2
0
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);
}