|
Packit |
1e8aac |
/*
|
|
Packit |
1e8aac |
* glade-dnd.c
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Copyright (C) 2013 Juan Pablo Ugarte
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Authors:
|
|
Packit |
1e8aac |
* Juan Pablo Ugarte <juanpablougarte@gmail.com>
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This library is free software; you can redistribute it and/or modify it
|
|
Packit |
1e8aac |
* under the terms of the GNU Lesser General Public License as
|
|
Packit |
1e8aac |
* published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
1e8aac |
* the License, or (at your option) any later version.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This library is distributed in the hope that it will be useful, but
|
|
Packit |
1e8aac |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
1e8aac |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
1e8aac |
* Lesser General Public License for more details.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
1e8aac |
* License along with this program; if not, write to the Free Software
|
|
Packit |
1e8aac |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include "glade.h"
|
|
Packit |
1e8aac |
#include "glade-dnd.h"
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GtkTargetEntry *
|
|
Packit |
1e8aac |
_glade_dnd_get_target (void)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
static GtkTargetEntry target = {GLADE_DND_TARGET_DATA, GTK_TARGET_SAME_APP, GLADE_DND_INFO_DATA};
|
|
Packit |
1e8aac |
return ⌖
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
_glade_dnd_dest_set (GtkWidget *target)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gtk_drag_dest_set (target, 0, _glade_dnd_get_target (), 1, GDK_ACTION_COPY);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GObject *
|
|
Packit |
1e8aac |
_glade_dnd_get_data (GdkDragContext *context,
|
|
Packit |
1e8aac |
GtkSelectionData *selection,
|
|
Packit |
1e8aac |
guint info)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GdkAtom target = gtk_selection_data_get_target (selection);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (info == GLADE_DND_INFO_DATA &&
|
|
Packit |
1e8aac |
g_strcmp0 (gdk_atom_name (target), GLADE_DND_TARGET_DATA) == 0)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
const guchar *data = gtk_selection_data_get_data (selection);
|
|
Packit |
1e8aac |
if (data)
|
|
Packit |
1e8aac |
return *((GObject **)data);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
return NULL;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
_glade_dnd_set_data (GtkSelectionData *selection, GObject *data)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
static GdkAtom type = 0;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!type)
|
|
Packit |
1e8aac |
type = gdk_atom_intern_static_string (GLADE_DND_TARGET_DATA);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_selection_data_set (selection, type, sizeof (gpointer),
|
|
Packit |
1e8aac |
(const guchar *)&data,
|
|
Packit |
1e8aac |
sizeof (gpointer));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
on_drag_icon_draw (GtkWidget *widget, cairo_t *cr)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkStyleContext *context = gtk_widget_get_style_context (widget);
|
|
Packit |
1e8aac |
cairo_pattern_t *gradient;
|
|
Packit |
1e8aac |
GtkAllocation alloc;
|
|
Packit |
1e8aac |
gint x, y, w, h;
|
|
Packit |
1e8aac |
gdouble h2;
|
|
Packit |
1e8aac |
GdkRGBA bg;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Not needed acording to GtkWidget:draw documentation
|
|
Packit |
1e8aac |
* But seems like there is a bug when used as a drag_icon that makes the
|
|
Packit |
1e8aac |
* cairo translation used here persist when drawing children.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
cairo_save (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Clear BG */
|
|
Packit |
1e8aac |
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
|
|
Packit |
1e8aac |
cairo_paint (cr);
|
|
Packit |
1e8aac |
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_widget_get_allocation (widget, &alloc);
|
|
Packit |
1e8aac |
x = alloc.x;
|
|
Packit |
1e8aac |
y = alloc.y;
|
|
Packit |
1e8aac |
w = alloc.width;
|
|
Packit |
1e8aac |
h = alloc.height;
|
|
Packit |
1e8aac |
h2 = h/2.0;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_style_context_get_background_color (context, gtk_style_context_get_state (context), &bg;;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gradient = cairo_pattern_create_linear (x, y, x, y+h);
|
|
Packit |
1e8aac |
cairo_pattern_add_color_stop_rgba (gradient, 0, bg.red, bg.green, bg.blue, 0);
|
|
Packit |
1e8aac |
cairo_pattern_add_color_stop_rgba (gradient, .5, bg.red, bg.green, bg.blue, .8);
|
|
Packit |
1e8aac |
cairo_pattern_add_color_stop_rgba (gradient, 1, bg.red, bg.green, bg.blue, 0);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_set_source (cr, gradient);
|
|
Packit |
1e8aac |
cairo_rectangle (cr, x+h2, y, w-h, h);
|
|
Packit |
1e8aac |
cairo_fill (cr);
|
|
Packit |
1e8aac |
cairo_pattern_destroy (gradient);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gradient = cairo_pattern_create_radial (x+h2, y+h2, 0, x+h2, y+h2, h2);
|
|
Packit |
1e8aac |
cairo_pattern_add_color_stop_rgba (gradient, 0, bg.red, bg.green, bg.blue, .8);
|
|
Packit |
1e8aac |
cairo_pattern_add_color_stop_rgba (gradient, 1, bg.red, bg.green, bg.blue, 0);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_set_source (cr, gradient);
|
|
Packit |
1e8aac |
cairo_rectangle (cr, x, y, h2, h);
|
|
Packit |
1e8aac |
cairo_fill (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_translate (cr, w-h, 0);
|
|
Packit |
1e8aac |
cairo_set_source (cr, gradient);
|
|
Packit |
1e8aac |
cairo_rectangle (cr, x+h2, y, h2, h);
|
|
Packit |
1e8aac |
cairo_fill (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_pattern_destroy (gradient);
|
|
Packit |
1e8aac |
cairo_restore (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
_glade_dnd_set_icon_widget (GdkDragContext *context,
|
|
Packit |
1e8aac |
const gchar *icon_name,
|
|
Packit |
1e8aac |
const gchar *description)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *window, *box, *label, *icon;
|
|
Packit |
1e8aac |
GdkScreen *screen;
|
|
Packit |
1e8aac |
GdkVisual *visual;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
screen = gdk_window_get_screen (gdk_drag_context_get_source_window (context));
|
|
Packit |
1e8aac |
window = gtk_window_new (GTK_WINDOW_POPUP);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DND);
|
|
Packit |
1e8aac |
gtk_window_set_screen (GTK_WINDOW (window), screen);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
|
Packit |
1e8aac |
gtk_container_set_border_width (GTK_CONTAINER (box), 12);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
icon = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON);
|
|
Packit |
1e8aac |
gtk_widget_set_opacity (icon, .8);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
label = gtk_label_new (description);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_box_pack_start (GTK_BOX (box), icon, FALSE, TRUE, 0);
|
|
Packit |
1e8aac |
gtk_box_pack_start (GTK_BOX (box), label, FALSE, TRUE, 0);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_widget_show_all (box);
|
|
Packit |
1e8aac |
gtk_container_add (GTK_CONTAINER (window), box);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((visual = gdk_screen_get_rgba_visual (screen)))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gtk_widget_set_visual (window, visual);
|
|
Packit |
1e8aac |
gtk_widget_set_app_paintable (window, TRUE);
|
|
Packit |
1e8aac |
g_signal_connect (window, "draw", G_CALLBACK (on_drag_icon_draw), NULL);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_object_ref_sink (window);
|
|
Packit |
1e8aac |
gtk_drag_set_icon_widget (context, window, 0, 0);
|
|
Packit |
1e8aac |
g_object_unref (window);
|
|
Packit |
1e8aac |
}
|