]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/dnd.cpp
Added bitmaps and icons to samples
[wxWidgets.git] / src / gtk / dnd.cpp
CommitLineData
c801d85f
KB
1///////////////////////////////////////////////////////////////////////////////
2// Name: dnd.cpp
3// Purpose: wxDropTarget class
4// Author: Robert Roebling
5// Copyright: Robert Roebling
6// Licence: wxWindows license
7///////////////////////////////////////////////////////////////////////////////
8
9#ifdef __GNUG__
10#pragma implementation "dnd.h"
11#endif
12
13#include "wx/dnd.h"
14#include "wx/window.h"
15#include "wx/app.h"
16#include "wx/gdicmn.h"
17
18#include "gdk/gdkprivate.h"
19
20#include <X11/Xlib.h>
21
22// ----------------------------------------------------------------------------
23// global
24// ----------------------------------------------------------------------------
25
26extern bool g_blockEventsOnDrag;
27
28// ----------------------------------------------------------------------------
29// wxDropTarget
30// ----------------------------------------------------------------------------
31
32wxDropTarget::wxDropTarget()
33{
34};
35
36wxDropTarget::~wxDropTarget()
37{
38};
39
40void wxDropTarget::Drop( GdkEvent *event, int x, int y )
41{
42 printf( "Drop data is of type %s.\n", event->dropdataavailable.data_type );
43
44 OnDrop( x, y, (char *)event->dropdataavailable.data);
45};
46
47void wxDropTarget::UnregisterWidget( GtkWidget *widget )
48{
e3e65dac
RR
49 if (!widget) return;
50
c801d85f
KB
51 gtk_widget_dnd_drop_set( widget, FALSE, NULL, 0, FALSE );
52};
53
e3e65dac
RR
54void wxDropTarget::RegisterWidget( GtkWidget *widget )
55{
56 wxString formats;
57 int valid = 0;
58
59 for ( uint i = 0; i < GetFormatCount(); i++ )
60 {
61 wxDataFormat df = GetFormat( i );
62 switch (df)
63 {
64 case wxDF_TEXT:
65 if (i > 0) formats += ";";
66 formats += "text/plain";
67 valid++;
68 break;
69 case wxDF_FILENAME:
70 if (i > 0) formats += ";";
71 formats += "url:any";
72 valid++;
73 break;
74 default:
75 break;
76 };
77 }
78
79 char *str = WXSTRINGCAST formats;
80
81 gtk_widget_dnd_drop_set( widget, TRUE, &str, valid, FALSE );
82};
83
c801d85f
KB
84// ----------------------------------------------------------------------------
85// wxTextDropTarget
86// ----------------------------------------------------------------------------
87
88bool wxTextDropTarget::OnDrop( long x, long y, const void *pData )
89{
90 OnDropText( x, y, (const char*)pData );
91 return TRUE;
92};
93
94bool wxTextDropTarget::OnDropText( long x, long y, const char *psz )
95{
96 printf( "Got dropped text: %s.\n", psz );
97 printf( "At x: %d, y: %d.\n", (int)x, (int)y );
98 return TRUE;
99};
100
e3e65dac 101size_t wxTextDropTarget::GetFormatCount() const
c801d85f 102{
e3e65dac
RR
103 return 1;
104}
105
106wxDataFormat wxTextDropTarget::GetFormat(size_t WXUNUSED(n)) const
107{
108 return wxDF_TEXT;
109}
110
111// ----------------------------------------------------------------------------
112// wxFileDropTarget
113// ----------------------------------------------------------------------------
114
115bool wxFileDropTarget::OnDropFiles( long x, long y, size_t nFiles, const char * const WXUNUSED(aszFiles)[] )
116{
117 printf( "Got %d dropped files.\n", (int)nFiles );
118 printf( "At x: %d, y: %d.\n", (int)x, (int)y );
119 return TRUE;
120}
121
122bool wxFileDropTarget::OnDrop(long x, long y, const void *WXUNUSED(pData) )
123{
124 char *str = "/this/is/a/path.txt";
125
126 return OnDropFiles(x, y, 1, &str );
127}
128
129size_t wxFileDropTarget::GetFormatCount() const
130{
131 return 1;
132}
133
134wxDataFormat wxFileDropTarget::GetFormat(size_t WXUNUSED(n)) const
135{
136 return wxDF_FILENAME;
137}
c801d85f
KB
138
139//-------------------------------------------------------------------------
e3e65dac 140// wxDropSource
c801d85f
KB
141//-------------------------------------------------------------------------
142
143//-----------------------------------------------------------------------------
144// drag request
145
e3e65dac 146void gtk_drag_callback( GtkWidget *widget, GdkEvent *event, wxDataObject *data )
c801d85f 147{
e3e65dac
RR
148 printf( "Data requested for dropping.\n" );
149
150 uint size = data->GetDataSize();
151 char *ptr = new char[size];
152 data->GetDataHere( ptr );
153
154 gtk_widget_dnd_data_set( widget, event, ptr, size );
c801d85f 155
e3e65dac 156 delete ptr;
c801d85f
KB
157};
158
e3e65dac 159wxDropSource::wxDropSource( wxWindow *win )
c801d85f
KB
160{
161 g_blockEventsOnDrag = TRUE;
e3e65dac 162
c801d85f
KB
163 m_window = win;
164 m_widget = win->m_widget;
165 if (win->m_wxwindow) m_widget = win->m_wxwindow;
c801d85f 166
e3e65dac
RR
167 m_data = NULL;
168
c801d85f
KB
169 m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY );
170 m_goaheadCursor = wxCursor( wxCURSOR_HAND );
171};
172
e3e65dac 173wxDropSource::wxDropSource( wxDataObject &data, wxWindow *win )
c801d85f 174{
e3e65dac
RR
175 g_blockEventsOnDrag = TRUE;
176
177 m_window = win;
178 m_widget = win->m_widget;
179 if (win->m_wxwindow) m_widget = win->m_wxwindow;
180
181 m_data = &data;
182
183 m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY );
184 m_goaheadCursor = wxCursor( wxCURSOR_HAND );
c801d85f 185};
e3e65dac
RR
186
187void wxDropSource::SetData( wxDataObject &data )
c801d85f 188{
e3e65dac 189 m_data = &data;
c801d85f
KB
190};
191
e3e65dac 192wxDropSource::~wxDropSource(void)
c801d85f 193{
e3e65dac
RR
194// if (m_data) delete m_data;
195
196 g_blockEventsOnDrag = FALSE;
197};
198
199wxDropSource::DragResult wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove) )
200{
201 if (gdk_dnd.dnd_grabbed) return None;
202 if (gdk_dnd.drag_really) return None;
203
204 if (!m_data) return None;
205 if (m_data->GetDataSize() == 0) return None;
c801d85f
KB
206
207 GdkWindowPrivate *wp = (GdkWindowPrivate*) m_widget->window;
208
209 RegisterWindow();
c801d85f
KB
210
211 gdk_dnd.drag_perhaps = TRUE;
212
213 gdk_dnd.dnd_drag_start.x = 5;
214 gdk_dnd.dnd_drag_start.y = 5;
215 gdk_dnd.real_sw = wp;
216
217 if (gdk_dnd.drag_startwindows)
218 {
219 g_free( gdk_dnd.drag_startwindows );
220 gdk_dnd.drag_startwindows = NULL;
221 };
222 gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0;
223
224 XWindowAttributes dnd_winattr;
225 XGetWindowAttributes( gdk_display, wp->xwindow, &dnd_winattr );
226 wp->dnd_drag_savedeventmask = dnd_winattr.your_event_mask;
227
228 gdk_dnd_drag_addwindow( m_widget->window );
229
230 GdkEventDragBegin ev;
231 ev.type = GDK_DRAG_BEGIN;
232 ev.window = m_widget->window;
233 ev.u.allflags = 0;
234 ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
235
236 gdk_event_put( (GdkEvent*)&ev );
237
238 XGrabPointer( gdk_display, wp->xwindow, False,
239 ButtonMotionMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
240 GrabModeAsync, GrabModeAsync, gdk_root_window, None, CurrentTime );
241
242 gdk_dnd_set_drag_cursors( m_defaultCursor.GetCursor(), m_goaheadCursor.GetCursor() );
243
244 gdk_dnd.dnd_grabbed = TRUE;
245 gdk_dnd.drag_really = 1;
e3e65dac
RR
246
247 int x = 0;
248 int y = 0;
249 gdk_window_get_pointer( m_widget->window, &x, &y, NULL );
250
c801d85f
KB
251 gdk_dnd_display_drag_cursor( x, y, FALSE, TRUE );
252
253 while (gdk_dnd.drag_really || gdk_dnd.drag_perhaps) wxYield();
254
c801d85f 255 UnregisterWindow();
e3e65dac
RR
256
257 return Copy;
c801d85f
KB
258};
259
e3e65dac 260void wxDropSource::RegisterWindow(void)
c801d85f 261{
e3e65dac 262 if (!m_data) return;
c801d85f 263
e3e65dac
RR
264 wxString formats;
265
266 wxDataFormat df = m_data->GetPreferredFormat();
c801d85f 267
e3e65dac
RR
268 switch (df)
269 {
270 case wxDF_TEXT:
271 formats += "text/plain";
272 break;
273 case wxDF_FILENAME:
274 formats += "url:any";
275 break;
276 default:
277 break;
278 }
c801d85f 279
e3e65dac 280 char *str = WXSTRINGCAST formats;
c801d85f 281
e3e65dac 282 gtk_widget_dnd_drag_set( m_widget, TRUE, &str, 1 );
c801d85f 283
e3e65dac
RR
284 gtk_signal_connect( GTK_OBJECT(m_widget), "drag_request_event",
285 GTK_SIGNAL_FUNC(gtk_drag_callback), (gpointer)m_data );
c801d85f
KB
286};
287
e3e65dac 288void wxDropSource::UnregisterWindow(void)
c801d85f
KB
289{
290 if (!m_widget) return;
291
e3e65dac
RR
292 gtk_widget_dnd_drag_set( m_widget, FALSE, NULL, 0 );
293
294 gtk_signal_disconnect_by_data( GTK_OBJECT(m_widget), (gpointer)m_data );
c801d85f 295};