Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F20064480
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
14 KB
Subscribers
None
View Options
diff --git a/src/dndtest.c b/src/dndtest.c
index 51aeded..e80032a 100644
--- a/src/dndtest.c
+++ b/src/dndtest.c
@@ -1,407 +1,407 @@
/* TestDnD - main.c : Simple tutorial for GTK+ Drag-N-Drop
* Copyright (C) 2005 Ryan McDougall.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <gtk/gtk.h>
#include <string.h>
/******************************************************************************/
#define _BYTE 8
#define _WORD 16
#define _DWORD 32
/******************************************************************************/
/* Define a list of data types called "targets" that a destination widget will
* accept. The string type is arbitrary, and negotiated between DnD widgets by
* the developer. An enum or GQuark can serve as the integer target id. */
enum {
TARGET_INT32,
TARGET_STRING,
TARGET_URIS,
TARGET_ROOTWIN
};
/* datatype (string), restrictions on DnD (GtkTargetFlags), datatype (int) */
static GtkTargetEntry target_list[] = {
{ "INTEGER", 0, TARGET_INT32 },
{ "STRING", 0, TARGET_STRING },
{ "text/plain", 0, TARGET_STRING },
{ "text/uri-list", 0, TARGET_URIS },
{ "application/x-rootwindow-drop", 0, TARGET_ROOTWIN }
};
static guint n_targets = G_N_ELEMENTS (target_list);
/******************************************************************************/
/* Signal receivable by destination */
/* Emitted when the data has been received from the source. It should check
* the GtkSelectionData sent by the source, and do something with it. Finally
* it needs to finish the operation by calling gtk_drag_finish, which will emit
* the "data-delete" signal if told to. */
static void
drag_data_received_handl
(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
GtkSelectionData *selection_data, guint target_type, guint tim,
gpointer data)
{
glong *_idata;
gchar *_sdata;
gboolean dnd_success = FALSE;
gboolean delete_selection_data = FALSE;
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_data_received_handl\n", name);
/* Deal with what we are given from source */
if((selection_data != NULL) && (gtk_selection_data_get_length(selection_data) >= 0))
{
GdkDragAction drag_action = gdk_drag_context_get_suggested_action(context);
if (drag_action == GDK_ACTION_ASK)
{
/* Ask the user to move or copy, then set the context action. */
}
if (drag_action == GDK_ACTION_MOVE)
delete_selection_data = TRUE;
/* Check that we got the format we can use */
g_print (" Receiving ");
switch (target_type)
{
case TARGET_INT32:
_idata = (glong*)gtk_selection_data_get_data(selection_data);
g_print ("integer: %ld", *_idata);
dnd_success = TRUE;
break;
case TARGET_STRING:
_sdata = (gchar*)gtk_selection_data_get_data(selection_data);
g_print ("string: %s", _sdata);
dnd_success = TRUE;
break;
case TARGET_URIS:
_sdata = (gchar*)gtk_selection_data_get_data(selection_data);
g_print ("uris: %s", _sdata);
dnd_success = TRUE;
break;
default:
g_print ("nothing good");
}
g_print (".\n");
}
if (dnd_success == FALSE)
{
g_print ("DnD data transfer failed!\n");
}
gtk_drag_finish (context, dnd_success, delete_selection_data, tim);
}
/* Emitted when a drag is over the destination */
static gboolean
drag_motion_handl
(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint t,
gpointer user_data)
{
// Fancy stuff here. This signal spams the console something horrible.
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_motion_handl\n", name);
return FALSE;
}
/* Emitted when a drag leaves the destination */
static void
drag_leave_handl
(GtkWidget *widget, GdkDragContext *context, guint tim, gpointer user_data)
{
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_leave_handl\n", name);
}
/* Emitted when the user releases (drops) the selection. It should check that
* the drop is over a valid part of the widget (if its a complex widget), and
* itself to return true if the operation should continue. Next choose the
* target type it wishes to ask the source for. Finally call gtk_drag_get_data
* which will emit "drag-data-get" on the source. */
static gboolean
drag_drop_handl
(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint tim,
gpointer user_data)
{
gboolean is_valid_drop_site;
GdkAtom target_type;
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_drop_handl\n", name);
/* Check to see if (x,y) is a valid drop site within widget */
is_valid_drop_site = TRUE;
GList *targets = gdk_drag_context_list_targets(context);
/* If the source offers a target */
if (targets)
{
/* Choose the best target type */
target_type = GDK_POINTER_TO_ATOM
(g_list_nth_data (targets, TARGET_INT32));
/* Request the data from the source. */
gtk_drag_get_data
(
widget, /* will receive 'drag-data-received' signal */
context, /* represents the current state of the DnD */
target_type, /* the target type we want */
tim /* time stamp */
);
}
/* No target offered by source => error */
else
{
is_valid_drop_site = FALSE;
}
return is_valid_drop_site;
}
/******************************************************************************/
/* Signals receivable by source */
/* Emitted after "drag-data-received" is handled, and gtk_drag_finish is called
* with the "delete" parameter set to TRUE (when DnD is GDK_ACTION_MOVE). */
static void
drag_data_delete_handl
(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
{
// We aren't moving or deleting anything here
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_data_delete_handl\n", name);
}
/* Emitted when the destination requests data from the source via
* gtk_drag_get_data. It should attempt to provide its data in the form
* requested in the target_type passed to it from the destination. If it cannot,
* it should default to a "safe" type such as a string or text, even if only to
* print an error. Then use gtk_selection_data_set to put the source data into
* the allocated selection_data object, which will then be passed to the
* destination. This will cause "drag-data-received" to be emitted on the
* destination. GdkSelectionData is based on X's selection mechanism which,
* via X properties, is only capable of storing data in blocks of 8, 16, or
* 32 bit units. */
static void
drag_data_get_handl
(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data,
guint target_type, guint tim, gpointer user_data)
{
const gchar *name = gtk_widget_get_name (widget);
const gchar *string_data = "This is data from the source.";
const glong integer_data = 42;
g_print ("%s: drag_data_get_handl\n", name);
g_assert (selection_data != NULL);
GdkAtom target = gtk_selection_data_get_target(selection_data);
g_print (" Sending ");
switch (target_type)
{
/* case TARGET_SOME_OBJECT:
* Serialize the object and send as a string of bytes.
* Pixbufs, (UTF-8) text, and URIs have their own convenience
* setter functions */
case TARGET_INT32:
g_print ("integer: %ld", integer_data);
gtk_selection_data_set
(
selection_data, /* Allocated GdkSelectionData object */
target,/* target type */
_DWORD, /* number of bits per 'unit' */
(guchar*) &integer_data,/* pointer to data to be sent */
sizeof (integer_data) /* length of data in units */
);
break;
case TARGET_STRING:
g_print ("string: %s", string_data);
gtk_selection_data_set
(
selection_data,
target,
_BYTE,
(guchar*) string_data,
strlen (string_data)
);
break;
case TARGET_URIS:
g_print ("uris: %s", string_data);
gtk_selection_data_set
(
selection_data,
target,
_BYTE,
(guchar*) string_data,
strlen (string_data)
);
break;
case TARGET_ROOTWIN:
g_print ("Dropped on the root window!\n");
break;
default:
/* Default to some a safe target instead of fail. */
g_assert_not_reached ();
}
g_print (".\n");
}
/* Emitted when DnD begins. This is often used to present custom graphics. */
static void
drag_begin_handl
(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
{
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_begin_handl\n", name);
}
/* Emitted when DnD ends. This is used to clean up any leftover data. */
static void
drag_end_handl
(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
{
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_end_handl\n", name);
}
/******************************************************************************/
int
main (int argc, char **argv)
{
GtkWidget *window;
GtkWidget *hbox;
GtkWidget *coin_source;
GtkWidget *well_dest;
GtkWidget *directions_label;
guint win_xsize = 450;
guint win_ysize = 50;
guint spacing = 5;
/* Always start GTK+ first! */
gtk_init (&argc, &argv);
/* Create the widgets */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- hbox = gtk_hbox_new (FALSE, spacing);
+ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, spacing);
coin_source = gtk_button_new_with_label ("[coins]");
well_dest = gtk_label_new ("[a well]");
directions_label = gtk_label_new ("drag a coin and drop it in the well");
/* Pack the widgets */
gtk_container_add (GTK_CONTAINER (window), hbox);
gtk_container_add (GTK_CONTAINER (hbox), coin_source);
gtk_container_add (GTK_CONTAINER (hbox), directions_label);
gtk_container_add (GTK_CONTAINER (hbox), well_dest);
/* Make the window big enough for some DnD action */
gtk_window_set_default_size (GTK_WINDOW(window), win_xsize, win_ysize);
/* Make the "well label" a DnD destination. */
gtk_drag_dest_set
(
well_dest, /* widget that will accept a drop */
GTK_DEST_DEFAULT_MOTION /* default actions for dest on DnD */
| GTK_DEST_DEFAULT_HIGHLIGHT,
target_list, /* lists of target to support */
n_targets, /* size of list */
GDK_ACTION_COPY /* what to do with data after dropped */
);
/* Make the "coin button" a DnD source. */
/* Why doesn't GtkLabel work here? */
gtk_drag_source_set
(
coin_source, /* widget will be drag-able */
GDK_BUTTON1_MASK, /* modifier that will start a drag */
target_list, /* lists of target to support */
n_targets, /* size of list */
GDK_ACTION_COPY /* what to do with data after dropped */
);
/* Connect the signals */
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
/* All possible destination signals */
g_signal_connect (well_dest, "drag-data-received",
G_CALLBACK(drag_data_received_handl), NULL);
g_signal_connect (well_dest, "drag-leave",
G_CALLBACK (drag_leave_handl), NULL);
g_signal_connect (well_dest, "drag-motion",
G_CALLBACK (drag_motion_handl), NULL);
g_signal_connect (well_dest, "drag-drop",
G_CALLBACK (drag_drop_handl), NULL);
/* All possible source signals */
g_signal_connect (coin_source, "drag-data-get",
G_CALLBACK (drag_data_get_handl), NULL);
g_signal_connect (coin_source, "drag-data-delete",
G_CALLBACK (drag_data_delete_handl), NULL);
g_signal_connect (coin_source, "drag-begin",
G_CALLBACK (drag_begin_handl), NULL);
g_signal_connect (coin_source, "drag-end",
G_CALLBACK (drag_end_handl), NULL);
/* Show the widgets */
gtk_widget_show_all (window);
/* Start the even loop */
gtk_main ();
return 0;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Feb 23, 7:16 PM (46 m, 11 s)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
fc/d3/46d1afec3f4a14c3df7777d601ad
Attached To
rGPA Gnu Privacy Assistant
Event Timeline
Log In to Comment