]> git.saurik.com Git - wxWidgets.git/blob - samples/dnd/dnd.cpp
GTK's dnd is broken, not mine
[wxWidgets.git] / samples / dnd / dnd.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: dnd.cpp
3 // Purpose: Drag and drop sample
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID:
8 // Copyright:
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #ifndef WX_PRECOMP
19 #include "wx/wx.h"
20 #endif
21
22 #include "wx/intl.h"
23 #include "wx/log.h"
24
25 #include "wx/dnd.h"
26
27 #ifdef __WXGTK__
28 #include "mondrian.xpm"
29 #endif
30
31 // ----------------------------------------------------------------------------
32 // Derive 2 simple classes which just put in the listbox the strings (text or
33 // file names) we drop on them
34 // ----------------------------------------------------------------------------
35 class DnDText : public wxTextDropTarget
36 {
37 public:
38 DnDText(wxListBox *pOwner) { m_pOwner = pOwner; }
39
40 virtual bool OnDropText(long x, long y, const char *psz);
41
42 private:
43 wxListBox *m_pOwner;
44 };
45
46 class DnDFile : public wxFileDropTarget
47 {
48 public:
49 DnDFile(wxListBox *pOwner) { m_pOwner = pOwner; }
50
51 virtual bool OnDropFiles(long x, long y,
52 size_t nFiles, const char * const aszFiles[]);
53
54 private:
55 wxListBox *m_pOwner;
56 };
57
58 // ----------------------------------------------------------------------------
59 // Define a new application type
60 // ----------------------------------------------------------------------------
61 class DnDApp : public wxApp
62 {
63 public:
64 bool OnInit();
65 };
66
67 IMPLEMENT_APP(DnDApp);
68
69 // ----------------------------------------------------------------------------
70 // Define a new frame type
71 // ----------------------------------------------------------------------------
72 class DnDFrame : public wxFrame
73 {
74 public:
75 DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
76 ~DnDFrame();
77
78 void OnPaint(wxPaintEvent& event);
79 void OnQuit (wxCommandEvent& event);
80 void OnAbout(wxCommandEvent& event);
81 void OnDrag (wxCommandEvent& event);
82 void OnHelp (wxCommandEvent& event);
83 void OnLogClear(wxCommandEvent& event);
84
85 void OnLeftDown(wxMouseEvent& event);
86 void OnRightDown(wxMouseEvent& event);
87
88 bool OnClose();
89
90 DECLARE_EVENT_TABLE()
91
92 private:
93 wxListBox *m_ctrlFile,
94 *m_ctrlText;
95 wxTextCtrl *m_ctrlLog;
96
97 wxLog *m_pLog, *m_pLogPrev;
98
99 wxString m_strText;
100 };
101
102 // ----------------------------------------------------------------------------
103 // IDs for the menu commands
104 // ----------------------------------------------------------------------------
105 enum
106 {
107 Menu_Quit = 1,
108 Menu_Drag,
109 Menu_About = 101,
110 Menu_Help,
111 Menu_Clear,
112 };
113
114 BEGIN_EVENT_TABLE(DnDFrame, wxFrame)
115 EVT_MENU(Menu_Quit, DnDFrame::OnQuit)
116 EVT_MENU(Menu_About, DnDFrame::OnAbout)
117 EVT_MENU(Menu_Drag, DnDFrame::OnDrag)
118 EVT_MENU(Menu_Help, DnDFrame::OnHelp)
119 EVT_MENU(Menu_Clear, DnDFrame::OnLogClear)
120 EVT_LEFT_DOWN(OnLeftDown)
121 EVT_RIGHT_DOWN(OnRightDown)
122 END_EVENT_TABLE()
123
124 // `Main program' equivalent, creating windows and returning main app frame
125 bool DnDApp::OnInit(void)
126 {
127 // create the main frame window
128 DnDFrame *frame = new DnDFrame((wxFrame *) NULL, "Drag & Drop wxWindows App",
129 50, 50, 450, 340);
130
131 // activate it
132 frame->Show(TRUE);
133
134 SetTopWindow(frame);
135
136 return TRUE;
137 }
138
139 DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
140 : wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h)),
141 m_strText("wxWindows drag & drop works :-)")
142
143 {
144
145 #ifdef __WXMSW__
146 // frame icon and status bar
147 SetIcon(wxIcon("mondrian"));
148 #else
149 SetIcon(wxIcon(mondrian_xpm));
150 #endif
151
152 // const int widths[] = { -1 };
153 CreateStatusBar();
154
155 // construct menu
156 wxMenu *file_menu = new wxMenu;
157 file_menu->Append(Menu_Drag, "&Test drag...");
158 file_menu->AppendSeparator();
159 file_menu->Append(Menu_Quit, "E&xit");
160
161 wxMenu *log_menu = new wxMenu;
162 log_menu->Append(Menu_Clear, "Clear");
163
164 wxMenu *help_menu = new wxMenu;
165 help_menu->Append(Menu_Help, "&Help...");
166 help_menu->AppendSeparator();
167 help_menu->Append(Menu_About, "&About");
168
169 wxMenuBar *menu_bar = new wxMenuBar;
170 menu_bar->Append(file_menu, "&File");
171 menu_bar->Append(log_menu, "&Log");
172 menu_bar->Append(help_menu, "&Help");
173
174 SetMenuBar(menu_bar);
175
176 // make a panel with 3 subwindows
177 wxPoint pos(0, 0);
178 wxSize size(400, 200);
179
180 wxString strFile("Drop files here!"), strText("Drop text on me");
181
182 m_ctrlFile = new wxListBox(this, -1, pos, size, 1, &strFile, wxLB_HSCROLL);
183 m_ctrlText = new wxListBox(this, -1, pos, size, 1, &strText, wxLB_HSCROLL);
184
185 /*
186 m_ctrlLog = new wxTextCtrl(this, -1, "", pos, size,
187 wxTE_MULTILINE | wxTE_READONLY |
188 wxSUNKEN_BORDER| wxHSCROLL);
189
190 // redirect log messages to the text window (don't forget to delete it!)
191 m_pLog = new wxLogTextCtrl(m_ctrlLog);
192 m_pLogPrev = wxLog::SetActiveTarget(m_pLog);
193 */
194
195 wxStaticText *m_testLabel = new wxStaticText( this, -1, "Hallo", pos, size );
196 m_testLabel->SetDropTarget( new wxTextDropTarget() );
197
198 // associate drop targets with 2 text controls
199 m_ctrlFile->SetDropTarget(new DnDFile(m_ctrlFile));
200 m_ctrlText->SetDropTarget(new DnDText(m_ctrlText));
201
202 wxLayoutConstraints *c;
203
204 // Top-left listbox
205 c = new wxLayoutConstraints;
206 c->left.SameAs (this, wxLeft);
207 c->top.SameAs (this, wxTop);
208 c->right.PercentOf(this, wxRight, 50);
209 c->height.PercentOf(this, wxHeight, 40);
210 m_ctrlFile->SetConstraints(c);
211
212 // Top-right listbox
213 c = new wxLayoutConstraints;
214 c->left.SameAs (m_ctrlFile, wxRight);
215 c->top.SameAs (this, wxTop);
216 c->right.SameAs (this, wxRight);
217 c->height.PercentOf(this, wxHeight, 40);
218 m_ctrlText->SetConstraints(c);
219
220 /*
221 // Lower text control
222 c = new wxLayoutConstraints;
223 c->left.SameAs (this, wxLeft);
224 c->right.SameAs (this, wxRight);
225 c->height.PercentOf(this, wxHeight, 40);
226 c->top.SameAs(m_ctrlText, wxBottom);
227 m_ctrlLog->SetConstraints(c);
228 */
229
230 // Lower label control
231 c = new wxLayoutConstraints;
232 c->left.SameAs (this, wxLeft);
233 c->right.SameAs (this, wxRight);
234 c->height.PercentOf(this, wxHeight, 40);
235 c->top.SameAs(m_ctrlText, wxBottom);
236 m_testLabel->SetConstraints(c);
237
238
239 SetAutoLayout(TRUE);
240 }
241
242 void DnDFrame::OnQuit(wxCommandEvent& /* event */)
243 {
244 Close(TRUE);
245 }
246
247 void DnDFrame::OnDrag(wxCommandEvent& /* event */)
248 {
249 wxString strText = wxGetTextFromUser
250 (
251 "After you enter text in this dialog, press any mouse\n"
252 "button in the bottom (empty) part of the frame and \n"
253 "drag it anywhere - you will be in fact dragging the\n"
254 "text object containing this text",
255 "Please enter some text", m_strText, this
256 );
257
258 m_strText = strText;
259 }
260
261 void DnDFrame::OnAbout(wxCommandEvent& /* event */)
262 {
263 wxMessageDialog dialog(this,
264 "Drag-&-Drop Demo\n"
265 "Please see \"Help|Help...\" for details\n"
266 "Copyright (c) 1998 Vadim Zeitlin",
267 "About wxDnD");
268
269 dialog.ShowModal();
270 }
271
272 void DnDFrame::OnHelp(wxCommandEvent& /* event */)
273 {
274 wxMessageDialog dialog(this,
275 "This small program demonstrates drag & drop support in wxWindows. The program window\n"
276 "consists of 3 parts: the bottom pane is for debug messages, so that you can see what's\n"
277 "going on inside. The top part is split into 2 listboxes, the left one accepts files\n"
278 "and the right one accepts text.\n"
279 "\n"
280 "To test wxDropTarget: open wordpad (write.exe), select some text in it and drag it to\n"
281 "the right listbox (you'll notice the usual visual feedback, i.e. the cursor will change).\n"
282 "Also, try dragging some files (you can select several at once) from Windows Explorer (or \n"
283 "File Manager) to the left pane. Hold down Ctrl/Shift keys when you drop text (doesn't \n"
284 "work with files) and see what changes.\n"
285 "\n"
286 "To test wxDropSource: just press any mouse button on the empty zone of the window and drag\n"
287 "it to wordpad or any other droptarget accepting text (and of course you can just drag it\n"
288 "to the right pane). Due to a lot of trace messages, the cursor might take some time to \n"
289 "change, don't release the mouse button until it does. You can change the string being\n"
290 "dragged in in \"File|Test drag...\" dialog.\n"
291 "\n"
292 "\n"
293 "Please send all questions/bug reports/suggestions &c to \n"
294 "Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>",
295 "wxDnD Help");
296
297 dialog.ShowModal();
298 }
299
300 void DnDFrame::OnLogClear(wxCommandEvent& /* event */ )
301 {
302 // m_ctrlLog->Clear();
303 }
304
305 bool DnDFrame::OnClose()
306 {
307 return TRUE;
308 }
309
310 void DnDFrame::OnLeftDown(wxMouseEvent &WXUNUSED(event) )
311 {
312 if ( !m_strText.IsEmpty() ) {
313 // start drag operation
314
315 wxTextDataObject data(m_strText);
316 wxDropSource dragSource(data, this);
317 const char *pc;
318
319 switch ( dragSource.DoDragDrop(TRUE) ) {
320 case wxDragError: pc = "Error!"; break;
321 case wxDragNone: pc = "Nothing"; break;
322 case wxDragCopy: pc = "Copied"; break;
323 case wxDragMove: pc = "Moved"; break;
324 case wxDragCancel: pc = "Cancelled"; break;
325 default: pc = "Huh?"; break;
326 }
327
328 SetStatusText(wxString("Drag result: ") + pc);
329 }
330 }
331
332 void DnDFrame::OnRightDown(wxMouseEvent &event )
333 {
334 wxMenu *menu = new wxMenu;
335
336 menu->Append(Menu_Drag, "&Test drag...");
337 menu->Append(Menu_About, "&About");
338 menu->Append(Menu_Quit, "E&xit");
339
340 PopupMenu( menu, event.GetX(), event.GetY() );
341 }
342
343 DnDFrame::~DnDFrame()
344 {
345 if ( m_pLog != NULL ) {
346 if ( wxLog::SetActiveTarget(m_pLogPrev) == m_pLog )
347 delete m_pLog;
348 }
349 }
350
351 // ----------------------------------------------------------------------------
352 // Notifications called by the base class
353 // ----------------------------------------------------------------------------
354 bool DnDText::OnDropText(long, long, const char *psz)
355 {
356 m_pOwner->Append(psz);
357
358 return TRUE;
359 }
360
361 bool DnDFile::OnDropFiles(long, long, size_t nFiles,
362 const char * const aszFiles[])
363 {
364 wxString str;
365 str.Printf("%d files dropped", nFiles);
366 m_pOwner->Append(str);
367 for ( size_t n = 0; n < nFiles; n++ ) {
368 m_pOwner->Append(aszFiles[n]);
369 }
370
371 return TRUE;
372 }