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