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