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