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