]> git.saurik.com Git - wxWidgets.git/blame - samples/dnd/dnd.cpp
#ifdef'd out some parts for non-supported systems.
[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
128 DnDFrame *frame = new DnDFrame(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
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
43d811ea
JS
152 const int widths[] = { -1 };
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
VZ
194#ifdef __WXMSW__ // it's not supported (yet) on other platforms
195 m_ctrlFile->SetDropTarget(new DnDFile(m_ctrlFile));
196#endif //MSW
e3e65dac 197 m_ctrlText->SetDropTarget(new DnDText(m_ctrlText));
457814b5 198
bb14db2d 199 wxLayoutConstraints *c;
457814b5 200
40e1a9c0 201 // Top-left listbox
457814b5
JS
202 c = new wxLayoutConstraints;
203 c->left.SameAs (this, wxLeft);
204 c->top.SameAs (this, wxTop);
205 c->right.PercentOf(this, wxRight, 50);
43d811ea 206 c->height.PercentOf(this, wxHeight, 40);
457814b5
JS
207 m_ctrlFile->SetConstraints(c);
208
40e1a9c0 209 // Top-right listbox
457814b5
JS
210 c = new wxLayoutConstraints;
211 c->left.SameAs (m_ctrlFile, wxRight);
212 c->top.SameAs (this, wxTop);
213 c->right.SameAs (this, wxRight);
43d811ea 214 c->height.PercentOf(this, wxHeight, 40);
457814b5
JS
215 m_ctrlText->SetConstraints(c);
216
40e1a9c0 217 // Lower text control
457814b5
JS
218 c = new wxLayoutConstraints;
219 c->left.SameAs (this, wxLeft);
220 c->right.SameAs (this, wxRight);
43d811ea
JS
221 c->height.PercentOf(this, wxHeight, 40);
222 c->top.SameAs(m_ctrlText, wxBottom);
457814b5
JS
223
224 m_ctrlLog->SetConstraints(c);
225
226 SetAutoLayout(TRUE);
227}
228
229void DnDFrame::OnQuit(wxCommandEvent& /* event */)
230{
231 Close(TRUE);
232}
233
43d811ea
JS
234void DnDFrame::OnDrag(wxCommandEvent& /* event */)
235{
236 wxString strText = wxGetTextFromUser
237 (
238 "After you enter text in this dialog, press any mouse\n"
239 "button in the bottom (empty) part of the frame and \n"
240 "drag it anywhere - you will be in fact dragging the\n"
241 "text object containing this text",
242 "Please enter some text", m_strText, this
243 );
244
245 m_strText = strText;
246}
247
457814b5
JS
248void DnDFrame::OnAbout(wxCommandEvent& /* event */)
249{
250 wxMessageDialog dialog(this,
251 "Drag-&-Drop Demo\n"
43d811ea
JS
252 "Please see \"Help|Help...\" for details\n"
253 "Copyright (c) 1998 Vadim Zeitlin",
457814b5
JS
254 "About wxDnD");
255
256 dialog.ShowModal();
257}
258
259void DnDFrame::OnHelp(wxCommandEvent& /* event */)
260{
261 wxMessageDialog dialog(this,
66bd6b93
RR
262"This small program demonstrates drag & drop support in wxWindows. The program window\n"
263"consists of 3 parts: the bottom pane is for debug messages, so that you can see what's\n"
264"going on inside. The top part is split into 2 listboxes, the left one accepts files\n"
bb14db2d 265"and the right one accepts text.\n"
66bd6b93
RR
266"\n"
267"To test wxDropTarget: open wordpad (write.exe), select some text in it and drag it to\n"
268"the right listbox (you'll notice the usual visual feedback, i.e. the cursor will change).\n"
269"Also, try dragging some files (you can select several at once) from Windows Explorer (or \n"
270"File Manager) to the left pane. Hold down Ctrl/Shift keys when you drop text (doesn't \n"
bb14db2d 271"work with files) and see what changes.\n"
66bd6b93
RR
272"\n"
273"To test wxDropSource: just press any mouse button on the empty zone of the window and drag\n"
274"it to wordpad or any other droptarget accepting text (and of course you can just drag it\n"
275"to the right pane). Due to a lot of trace messages, the cursor might take some time to \n"
276"change, don't release the mouse button until it does. You can change the string being\n"
277"dragged in in \"File|Test drag...\" dialog.\n"
bb14db2d
VZ
278"\n"
279"\n"
66bd6b93 280"Please send all questions/bug reports/suggestions &c to \n"
457814b5
JS
281"Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>",
282 "wxDnD Help");
283
284 dialog.ShowModal();
285}
286
e3e65dac 287void DnDFrame::OnLogClear(wxCommandEvent& /* event */ )
43d811ea
JS
288{
289 m_ctrlLog->Clear();
290}
291
457814b5
JS
292bool DnDFrame::OnClose()
293{
294 return TRUE;
295}
296
30dea054 297void DnDFrame::OnLeftDown(wxMouseEvent &WXUNUSED(event) )
43d811ea
JS
298{
299 if ( !m_strText.IsEmpty() ) {
300 // start drag operation
30dea054 301
43d811ea 302 wxTextDataObject data(m_strText);
e3e65dac 303 wxDropSource dragSource(data, this);
43d811ea
JS
304 const char *pc;
305
306 switch ( dragSource.DoDragDrop(TRUE) ) {
307 case wxDropSource::Error: pc = "Error!"; break;
308 case wxDropSource::None: pc = "Nothing"; break;
309 case wxDropSource::Copy: pc = "Copied"; break;
310 case wxDropSource::Move: pc = "Moved"; break;
311 case wxDropSource::Cancel: pc = "Cancelled"; break;
312 default: pc = "Huh?"; break;
313 }
314
315 SetStatusText(wxString("Drag result: ") + pc);
316 }
317}
318
30dea054
RR
319void DnDFrame::OnRightDown(wxMouseEvent &event )
320{
321 wxMenu *menu = new wxMenu;
322
323 menu->Append(Menu_Drag, "&Test drag...");
324 menu->Append(Menu_About, "&About");
325 menu->Append(Menu_Quit, "E&xit");
326
327 PopupMenu( menu, event.GetX(), event.GetY() );
328}
329
457814b5
JS
330DnDFrame::~DnDFrame()
331{
332 if ( m_pLog != NULL ) {
43d811ea 333 if ( wxLog::SetActiveTarget(m_pLogPrev) == m_pLog )
457814b5
JS
334 delete m_pLog;
335 }
336}
337
338// ----------------------------------------------------------------------------
339// Notifications called by the base class
340// ----------------------------------------------------------------------------
341bool DnDText::OnDropText(long, long, const char *psz)
342{
343 m_pOwner->Append(psz);
344
345 return TRUE;
346}
347
348bool DnDFile::OnDropFiles(long, long, size_t nFiles,
349 const char * const aszFiles[])
350{
351 wxString str;
352 str.Printf("%d files dropped", nFiles);
353 m_pOwner->Append(str);
354 for ( size_t n = 0; n < nFiles; n++ ) {
355 m_pOwner->Append(aszFiles[n]);
356 }
357
358 return TRUE;
359}