Commit 4fced468 authored by Juan Pablo Ugarte's avatar Juan Pablo Ugarte

Drag&Drop clean up.

Added private _GladeDrag interface. (only used internaly in gladeui)

Implemented _GladeDrag in GladePlaceholder GladeWidget GladeDesignView and GladeDesignLayout

Added drag-dest property to GladeWidget to enable/disable drag support
(used in GtkFixed GtkLayout and GtkOverlay containers)

Made GladeInspector a drag source by implementing GtkTreeDragSource interface in GladeProject
parent 5edf71dc
......@@ -121,7 +121,9 @@ libgladeui_2_la_SOURCES = \
glade-widget.c \
glade-widget-action.c \
glade-widget-adaptor.c \
glade-xml-utils.c
glade-xml-utils.c \
glade-drag.c \
glade-dnd.c
libgladeui_2_la_CPPFLAGS = \
$(common_defines) \
......@@ -189,7 +191,9 @@ noinst_HEADERS = \
glade-preview.h \
glade-preview-tokens.h \
glade-project-properties.h \
gladeui-resources.h
gladeui-resources.h \
glade-drag.h \
glade-dnd.h
if PLATFORM_WIN32
libgladeui_2_la_LDFLAGS += -no-undefined
......
......@@ -2,7 +2,7 @@
* glade-design-layout.c
*
* Copyright (C) 2006-2007 Vincent Geddes
* 2011 Juan Pablo Ugarte
* 2011-2013 Juan Pablo Ugarte
*
* Authors:
* Vincent Geddes <vgeddes@gnome.org>
......@@ -110,8 +110,8 @@ struct _GladeDesignLayoutPrivate
/* Drag & Drop */
GtkWidget *drag_source;
GtkWidget *drag_icon;
gint drag_x, drag_y;
GladeWidget *drag_dest;
/* Properties */
GladeDesignView *view;
......@@ -382,9 +382,9 @@ glade_design_layout_motion_notify_event (GtkWidget *widget, GdkEventMotion *ev)
static GtkTargetList *target = NULL;
if (target == NULL)
target = gtk_target_list_new (_glade_design_layout_get_dnd_target (), 1);
target = gtk_target_list_new (_glade_dnd_get_target (), 1);
gtk_drag_begin (widget, target, GDK_ACTION_COPY, 1, (GdkEvent*)ev);
gtk_drag_begin_with_coordinates (widget, target, 0, 1, (GdkEvent*)ev, x, y);
return TRUE;
}
......@@ -1472,6 +1472,30 @@ draw_selection_nodes (cairo_t *cr,
cairo_restore (cr);
}
static inline void
draw_drag_dest (GladeDesignLayout *layout, cairo_t *cr, GladeWidget *drag)
{
GladeDesignLayoutPrivate *priv = layout->priv;
GObject *obj = glade_widget_get_object (drag);
const double dashes = 3;
GtkWidget *widget;
gint x, y;
if (!GTK_IS_WIDGET (obj))
return;
widget = GTK_WIDGET (obj);
gtk_widget_translate_coordinates (widget, GTK_WIDGET (layout), 0, 0, &x, &y);
cairo_set_line_width (cr, 2);
cairo_set_dash (cr, &dashes, 1, 0);
gdk_cairo_set_source_rgba (cr, &priv->frame_color_active[0]);
cairo_rectangle (cr, x+1, y+1,
gtk_widget_get_allocated_width (widget)-2,
gtk_widget_get_allocated_height(widget)-2);
cairo_stroke (cr);
}
static gboolean
glade_design_layout_draw (GtkWidget *widget, cairo_t *cr)
{
......@@ -1537,6 +1561,9 @@ glade_design_layout_draw (GtkWidget *widget, cairo_t *cr)
/* Draw selection nodes if we are in margins edit mode */
if (priv->selection && gtk_widget_is_ancestor (priv->selection, child))
draw_selection_nodes (cr, priv, widget);
if (priv->drag_dest)
draw_drag_dest (GLADE_DESIGN_LAYOUT (widget), cr, priv->drag_dest);
}
}
else if (gtk_cairo_should_draw_window (cr, priv->offscreen_window))
......@@ -1934,7 +1961,8 @@ glade_design_layout_finalize (GObject *object)
GladeDesignLayoutPrivate *priv = layout->priv;
g_clear_object (&priv->default_context);
g_clear_object (&priv->drag_dest);
g_signal_handlers_disconnect_by_func (priv->project,
on_project_selection_changed,
layout);
......@@ -1945,121 +1973,24 @@ glade_design_layout_finalize (GObject *object)
G_OBJECT_CLASS (glade_design_layout_parent_class)->finalize (object);
}
static gboolean
on_drag_icon_draw (GtkWidget *widget, cairo_t *cr)
{
GtkStyleContext *context = gtk_widget_get_style_context (widget);
cairo_pattern_t *gradient;
GtkAllocation alloc;
gint x, y, w, h;
gdouble h2;
GdkRGBA bg;
/* Not needed acording to GtkWidget:draw documentation
* But seems like there is a bug when used as a drag_icon that makes the
* cairo translation used here persist when drawind children.
*/
cairo_save (cr);
/* Clear BG */
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_paint (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
gtk_widget_get_allocation (widget, &alloc);
x = alloc.x;
y = alloc.y;
w = alloc.width;
h = alloc.height;
h2 = h/2.0;
gtk_style_context_get_background_color (context, GTK_STATE_NORMAL, &bg);
gradient = cairo_pattern_create_linear (x, y, x, y+h);
cairo_pattern_add_color_stop_rgba (gradient, 0, bg.red, bg.green, bg.blue, 0);
cairo_pattern_add_color_stop_rgba (gradient, .5, bg.red, bg.green, bg.blue, .8);
cairo_pattern_add_color_stop_rgba (gradient, 1, bg.red, bg.green, bg.blue, 0);
cairo_set_source (cr, gradient);
cairo_rectangle (cr, x+h2, y, w-h, h);
cairo_fill (cr);
cairo_pattern_destroy (gradient);
gradient = cairo_pattern_create_radial (x+h2, y+h2, 0, x+h2, y+h2, h2);
cairo_pattern_add_color_stop_rgba (gradient, 0, bg.red, bg.green, bg.blue, .8);
cairo_pattern_add_color_stop_rgba (gradient, 1, bg.red, bg.green, bg.blue, 0);
cairo_set_source (cr, gradient);
cairo_rectangle (cr, x, y, h2, h);
cairo_fill (cr);
cairo_translate (cr, w-h, 0);
cairo_set_source (cr, gradient);
cairo_rectangle (cr, x+h2, y, h2, h);
cairo_fill (cr);
cairo_pattern_destroy (gradient);
cairo_restore (cr);
return FALSE;
}
GtkWidget *
_glade_design_layout_dnd_icon_widget_new (GdkDragContext *context,
const gchar *icon_name,
const gchar *description)
{
GtkWidget *window, *box, *label, *icon;
GdkScreen *screen;
GdkVisual *visual;
screen = gdk_window_get_screen (gdk_drag_context_get_source_window (context));
visual = gdk_screen_get_rgba_visual (screen);
window = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DND);
gtk_window_set_screen (GTK_WINDOW (window), screen);
gtk_widget_set_visual (window, visual);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_container_set_border_width (GTK_CONTAINER (box), 12);
icon = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON);
gtk_widget_set_opacity (icon, .8);
label = gtk_label_new (description);
gtk_box_pack_start (GTK_BOX (box), icon, FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (box), label, FALSE, TRUE, 0);
gtk_widget_show_all (box);
gtk_container_add (GTK_CONTAINER (window), box);
gtk_widget_set_app_paintable (window, TRUE);
g_signal_connect (window, "draw", G_CALLBACK (on_drag_icon_draw), NULL);
return window;
}
static void
glade_design_layout_drag_begin (GtkWidget *widget, GdkDragContext *context)
{
GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
GladeWidgetAdaptor *adaptor;
GladeWidget *gwidget;
const gchar *icon_name;
gchar *description;
gwidget = glade_widget_get_from_gobject (priv->drag_source);
adaptor = glade_widget_get_adaptor (gwidget);
icon_name = glade_widget_adaptor_get_icon_name (adaptor);
description = g_strdup_printf ("%s [%s]",
glade_widget_adaptor_get_name (adaptor),
glade_widget_get_name (gwidget));
priv->drag_icon = _glade_design_layout_dnd_icon_widget_new (context, icon_name, description);
g_object_ref_sink (priv->drag_icon);
gtk_drag_set_icon_widget (context, priv->drag_icon, 0, 0);
_glade_dnd_set_icon_widget (context,
glade_widget_adaptor_get_icon_name (adaptor),
description);
g_free (description);
}
......@@ -2071,25 +2002,13 @@ glade_design_layout_drag_data_get (GtkWidget *widget,
guint time)
{
GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
if (priv->drag_source)
{
static GdkAtom type = 0;
if (!type)
type = gdk_atom_intern_static_string (GDL_DND_TARGET_WIDGET);
gtk_selection_data_set (data, type, sizeof (gpointer),
(const guchar *)&priv->drag_source, sizeof (gpointer));
}
_glade_dnd_set_data (data, G_OBJECT (priv->drag_source));
}
static void
glade_design_layout_drag_end (GtkWidget *widget, GdkDragContext *context)
{
GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
g_clear_object (&priv->drag_icon);
priv->drag_source = NULL;
}
......@@ -2278,13 +2197,6 @@ _glade_design_layout_get_colors (GtkStyleContext *context,
c1->blue += off;
}
GtkTargetEntry *
_glade_design_layout_get_dnd_target (void)
{
static GtkTargetEntry target = {GDL_DND_TARGET_WIDGET, GTK_TARGET_SAME_APP, GDL_DND_INFO_WIDGET};
return &target;
}
void
_glade_design_layout_get_hot_point (GladeDesignLayout *layout,
gint *x,
......@@ -2299,6 +2211,20 @@ _glade_design_layout_get_hot_point (GladeDesignLayout *layout,
*y = priv->drag_y;
}
void
_glade_design_layout_set_highlight (GladeDesignLayout *layout,
GladeWidget *drag)
{
GladeDesignLayoutPrivate *priv = layout->priv;
g_clear_object (&priv->drag_dest);
if (drag)
priv->drag_dest = g_object_ref (drag);
gtk_widget_queue_draw (GTK_WIDGET (layout));
}
typedef struct
{
GtkWidget *toplevel;
......@@ -2484,7 +2410,8 @@ gdl_drag_source_check (GladeDesignLayout *layout,
GObject *source;
if (gwidget && (source = glade_widget_get_object (gwidget)) &&
!(event->button.state & GDK_SHIFT_MASK))
!(event->button.state & GDK_SHIFT_MASK) &&
_glade_drag_can_drag (GLADE_DRAG (gwidget)))
{
priv->drag_source = GTK_WIDGET (source);
......@@ -2503,6 +2430,12 @@ gdl_drag_source_check (GladeDesignLayout *layout,
}
}
GladeWidget *
_glade_design_layout_get_child (GladeDesignLayout *layout)
{
return layout->priv->gchild;
}
/*
* _glade_design_layout_do_event:
* @layout: A #GladeDesignLayout
......
......@@ -25,11 +25,9 @@
#ifndef __GLADE_DESIGN_PRIVATE_H__
#define __GLADE_DESIGN_PRIVATE_H__
#define GDL_DND_INFO_WIDGET 15956
#define GDL_DND_TARGET_WIDGET "glade/x-widget"
#include "glade-design-view.h"
#include "glade-design-layout.h"
#include "glade-dnd.h"
G_BEGIN_DECLS
......@@ -53,20 +51,19 @@ void _glade_design_layout_draw_pushpin (cairo_t *cr,
GdkRGBA *bg,
GdkRGBA *fg);
void _glade_design_layout_get_hot_point (GladeDesignLayout *layout,
gint *x,
gint *y);
GtkTargetEntry *_glade_design_layout_get_dnd_target (void);
void _glade_design_layout_get_hot_point (GladeDesignLayout *layout,
gint *x,
gint *y);
GtkWidget *_glade_design_layout_dnd_icon_widget_new (GdkDragContext *context,
const gchar *icon_name,
const gchar *description);
GladeWidget * _glade_design_layout_get_child (GladeDesignLayout *layout);
GtkWidget *_glade_design_layout_get_child_at_position (GtkWidget *widget,
gint x,
gint y);
void _glade_design_layout_set_highlight (GladeDesignLayout *layout,
GladeWidget *drag);
G_END_DECLS
#endif /* __GLADE_DESIGN_PRIVATE_H__ */
This diff is collapsed.
......@@ -69,9 +69,6 @@ GladeProject *glade_design_view_get_project (GladeDesignView *view);
GladeDesignView *glade_design_view_get_from_project (GladeProject *project);
void glade_design_view_set_drag_source (GladeDesignView *view,
GtkToolPalette *source);
G_END_DECLS
#endif /* __GLADE_DESIGN_VIEW_H__ */
/*
* glade-dnd.c
*
* Copyright (C) 2013 Juan Pablo Ugarte
*
* Authors:
* Juan Pablo Ugarte <juanpablougarte@gmail.com>
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "glade.h"
#include "glade-dnd.h"
GtkTargetEntry *
_glade_dnd_get_target (void)
{
static GtkTargetEntry target = {GLADE_DND_TARGET_DATA, GTK_TARGET_SAME_APP, GLADE_DND_INFO_DATA};
return &target;
}
void
_glade_dnd_dest_set (GtkWidget *target)
{
GtkTargetEntry targets[1];
targets[0] = *_glade_dnd_get_target ();
gtk_drag_dest_set (target, 0, targets, 2, GDK_ACTION_COPY);
}
GObject *
_glade_dnd_get_data (GdkDragContext *context,
GtkSelectionData *selection,
guint info)
{
GdkAtom target = gtk_selection_data_get_target (selection);
if (info == GLADE_DND_INFO_DATA &&
g_strcmp0 (gdk_atom_name (target), GLADE_DND_TARGET_DATA) == 0)
{
const guchar *data = gtk_selection_data_get_data (selection);
if (data)
return *((GObject **)data);
}
return NULL;
}
void
_glade_dnd_set_data (GtkSelectionData *selection, GObject *data)
{
static GdkAtom type = 0;
if (!type)
type = gdk_atom_intern_static_string (GLADE_DND_TARGET_DATA);
gtk_selection_data_set (selection, type, sizeof (gpointer),
(const guchar *)&data,
sizeof (gpointer));
}
static gboolean
on_drag_icon_draw (GtkWidget *widget, cairo_t *cr)
{
GtkStyleContext *context = gtk_widget_get_style_context (widget);
cairo_pattern_t *gradient;
GtkAllocation alloc;
gint x, y, w, h;
gdouble h2;
GdkRGBA bg;
/* Not needed acording to GtkWidget:draw documentation
* But seems like there is a bug when used as a drag_icon that makes the
* cairo translation used here persist when drawing children.
*/
cairo_save (cr);
/* Clear BG */
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_paint (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
gtk_widget_get_allocation (widget, &alloc);
x = alloc.x;
y = alloc.y;
w = alloc.width;
h = alloc.height;
h2 = h/2.0;
gtk_style_context_get_background_color (context, GTK_STATE_NORMAL, &bg);
gradient = cairo_pattern_create_linear (x, y, x, y+h);
cairo_pattern_add_color_stop_rgba (gradient, 0, bg.red, bg.green, bg.blue, 0);
cairo_pattern_add_color_stop_rgba (gradient, .5, bg.red, bg.green, bg.blue, .8);
cairo_pattern_add_color_stop_rgba (gradient, 1, bg.red, bg.green, bg.blue, 0);
cairo_set_source (cr, gradient);
cairo_rectangle (cr, x+h2, y, w-h, h);
cairo_fill (cr);
cairo_pattern_destroy (gradient);
gradient = cairo_pattern_create_radial (x+h2, y+h2, 0, x+h2, y+h2, h2);
cairo_pattern_add_color_stop_rgba (gradient, 0, bg.red, bg.green, bg.blue, .8);
cairo_pattern_add_color_stop_rgba (gradient, 1, bg.red, bg.green, bg.blue, 0);
cairo_set_source (cr, gradient);
cairo_rectangle (cr, x, y, h2, h);
cairo_fill (cr);
cairo_translate (cr, w-h, 0);
cairo_set_source (cr, gradient);
cairo_rectangle (cr, x+h2, y, h2, h);
cairo_fill (cr);
cairo_pattern_destroy (gradient);
cairo_restore (cr);
return FALSE;
}
void
_glade_dnd_set_icon_widget (GdkDragContext *context,
const gchar *icon_name,
const gchar *description)
{
GtkWidget *window, *box, *label, *icon;
GdkScreen *screen;
GdkVisual *visual;
screen = gdk_window_get_screen (gdk_drag_context_get_source_window (context));
window = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DND);
gtk_window_set_screen (GTK_WINDOW (window), screen);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_container_set_border_width (GTK_CONTAINER (box), 12);
icon = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON);
gtk_widget_set_opacity (icon, .8);
label = gtk_label_new (description);
gtk_box_pack_start (GTK_BOX (box), icon, FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (box), label, FALSE, TRUE, 0);
gtk_widget_show_all (box);
gtk_container_add (GTK_CONTAINER (window), box);
if ((visual = gdk_screen_get_rgba_visual (screen)))
{
gtk_widget_set_visual (window, visual);
gtk_widget_set_app_paintable (window, TRUE);
g_signal_connect (window, "draw", G_CALLBACK (on_drag_icon_draw), NULL);
}
g_object_ref_sink (window);
gtk_drag_set_icon_widget (context, window, 0, 0);
g_object_unref (window);
}
/*
* glade-dnd.h
*
* Copyright (C) 2013 Juan Pablo Ugarte
*
* Authors:
* Juan Pablo Ugarte <juanpablougarte@gmail.com>
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef __GLADE_DND_H__
#define __GLADE_DND_H__
#define GLADE_DND_INFO_DATA 96323
#define GLADE_DND_TARGET_DATA "glade/x-drag-data"
#include "glade-drag.h"
G_BEGIN_DECLS
GtkTargetEntry *_glade_dnd_get_target (void);
void _glade_dnd_dest_set (GtkWidget *target);
void _glade_dnd_set_data (GtkSelectionData *selection,
GObject *data);
GObject *_glade_dnd_get_data (GdkDragContext *context,
GtkSelectionData *selection,
guint info);
void _glade_dnd_set_icon_widget (GdkDragContext *context,
const gchar *icon_name,
const gchar *description);
G_END_DECLS
#endif /* __GLADE_DND_H__ */
/*
* glade-drag.c
*
* Copyright (C) 2013 Juan Pablo Ugarte
*
* Authors:
* Juan Pablo Ugarte <juanpablougarte@gmail.com>
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "glade-drag.h"
G_DEFINE_INTERFACE (_GladeDrag, _glade_drag, G_TYPE_OBJECT);
static void
_glade_drag_default_init (_GladeDragInterface *iface)
{
}
gboolean
_glade_drag_can_drag (_GladeDrag *source)
{
_GladeDragInterface *iface;
g_return_val_if_fail (GLADE_IS_DRAG (source), FALSE);
iface = GLADE_DRAG_GET_INTERFACE (source);
if (iface->can_drag)
return iface->can_drag (source);
else
return FALSE;
}
gboolean
_glade_drag_can_drop (_GladeDrag *dest, gint x, gint y, GObject *data)
{
_GladeDragInterface *iface;
g_return_val_if_fail (GLADE_IS_DRAG (dest), FALSE);
iface = GLADE_DRAG_GET_INTERFACE (dest);
if (iface->can_drop)
return iface->can_drop (dest, x, y, data);
else
return FALSE;
}
gboolean
_glade_drag_drop (_GladeDrag *dest, gint x, gint y, GObject *data)
{
_GladeDragInterface *iface;
g_return_val_if_fail (GLADE_IS_DRAG (dest), FALSE);
iface = GLADE_DRAG_GET_INTERFACE (dest);
if (iface->drop)
return iface->drop (dest, x, y, data);
else
return FALSE;
}
void
_glade_drag_highlight (_GladeDrag *dest, gint x, gint y)
{
_GladeDragInterface *iface;
g_return_if_fail (GLADE_IS_DRAG (dest));
iface = GLADE_DRAG_GET_INTERFACE (dest);
if (iface->highlight)
iface->highlight (dest, x, y);
}
/*
* glade-drag.h
*
* Copyright (C) 2013 Juan Pablo Ugarte
*
* Authors:
* Juan Pablo Ugarte <juanpablougarte@gmail.com>
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef _GLADE_DRAG_H_
#define _GLADE_DRAG_H_
#include "glade-widget-adaptor.h"
G_BEGIN_DECLS
#define GLADE_TYPE_DRAG (_glade_drag_get_type ())
#define GLADE_DRAG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_DRAG, _GladeDrag))
#define GLADE_IS_DRAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_DRAG))
#define GLADE_DRAG_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GLADE_TYPE_DRAG, _GladeDragInterface))
typedef struct __GladeDrag _GladeDrag;
typedef struct __GladeDragInterface _GladeDragInterface;
struct __GladeDragInterface
{
GTypeInterface parent_instance;
gboolean (*can_drag) (_GladeDrag *source);
gboolean (*can_drop) (_GladeDrag *dest,
gint x,
gint y,
GObject *data);
gboolean (*drop) (_GladeDrag *dest,
gint x,
gint y,
GObject *data);
void (*highlight) (_GladeDrag *dest,
gint x,
gint y);
};
GType _glade_drag_get_type (void) G_GNUC_CONST;