]> git.saurik.com Git - wxWidgets.git/blob - samples/dnd/dnd.cpp
some really minor changes (the most important one: small memory hole in
[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: $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( DnDFrame::OnLeftDown)
121 EVT_RIGHT_DOWN( DnDFrame::OnRightDown)
122 EVT_PAINT( DnDFrame::OnPaint)
123 END_EVENT_TABLE()
124
125 // `Main program' equivalent, creating windows and returning main app frame
126 bool DnDApp::OnInit()
127 {
128 // create the main frame window
129 DnDFrame *frame = new DnDFrame((wxFrame *) NULL, "Drag & Drop wxWindows App",
130 50, 50, 450, 340);
131
132 // activate it
133 frame->Show(TRUE);
134
135 SetTopWindow(frame);
136
137 return TRUE;
138 }
139
140 DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
141 : wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h)),
142 m_strText("wxWindows drag & drop works :-)")
143
144 {
145
146 // frame icon and status bar
147 SetIcon(wxICON(mondrian));
148
149 // const int widths[] = { -1 };
150 CreateStatusBar();
151
152 // construct menu
153 wxMenu *file_menu = new wxMenu;
154 file_menu->Append(Menu_Drag, "&Test drag...");
155 file_menu->AppendSeparator();
156 file_menu->Append(Menu_Quit, "E&xit");
157
158 wxMenu *log_menu = new wxMenu;
159 log_menu->Append(Menu_Clear, "Clear");
160
161 wxMenu *help_menu = new wxMenu;
162 help_menu->Append(Menu_Help, "&Help...");
163 help_menu->AppendSeparator();
164 help_menu->Append(Menu_About, "&About");
165
166 wxMenuBar *menu_bar = new wxMenuBar;
167 menu_bar->Append(file_menu, "&File");
168 menu_bar->Append(log_menu, "&Log");
169 menu_bar->Append(help_menu, "&Help");
170
171 SetMenuBar(menu_bar);
172
173 // make a panel with 3 subwindows
174 wxPoint pos(0, 0);
175 wxSize size(400, 200);
176
177 wxString strFile("Drop files here!"), strText("Drop text on me");
178
179 m_ctrlFile = new wxListBox(this, -1, pos, size, 1, &strFile, wxLB_HSCROLL);
180 m_ctrlText = new wxListBox(this, -1, pos, size, 1, &strText, wxLB_HSCROLL);
181
182 m_ctrlLog = new wxTextCtrl(this, -1, "", pos, size,
183 wxTE_MULTILINE | wxTE_READONLY |
184 wxSUNKEN_BORDER| wxHSCROLL);
185
186 // redirect log messages to the text window (don't forget to delete it!)
187 m_pLog = new wxLogTextCtrl(m_ctrlLog);
188 m_pLogPrev = wxLog::SetActiveTarget(m_pLog);
189
190 // associate drop targets with 2 text controls
191 m_ctrlFile->SetDropTarget(new DnDFile(m_ctrlFile));
192 m_ctrlText->SetDropTarget(new DnDText(m_ctrlText));
193
194 wxLayoutConstraints *c;
195
196 // Top-left listbox
197 c = new wxLayoutConstraints;
198 c->left.SameAs(this, wxLeft);
199 c->top.SameAs(this, wxTop);
200 c->right.PercentOf(this, wxRight, 50);
201 c->height.PercentOf(this, wxHeight, 40);
202 m_ctrlFile->SetConstraints(c);
203
204 // Top-right listbox
205 c = new wxLayoutConstraints;
206 c->left.SameAs (m_ctrlFile, wxRight);
207 c->top.SameAs (this, wxTop);
208 c->right.SameAs (this, wxRight);
209 c->height.PercentOf(this, wxHeight, 40);
210 m_ctrlText->SetConstraints(c);
211
212 // Lower text control
213 c = new wxLayoutConstraints;
214 c->left.SameAs (this, wxLeft);
215 c->right.SameAs (this, wxRight);
216 c->height.PercentOf(this, wxHeight, 40);
217 c->top.SameAs(m_ctrlText, wxBottom);
218 m_ctrlLog->SetConstraints(c);
219
220 SetAutoLayout(TRUE);
221 }
222
223 void DnDFrame::OnQuit(wxCommandEvent& /* event */)
224 {
225 Close(TRUE);
226 }
227
228 void DnDFrame::OnPaint(wxPaintEvent& /*event*/)
229 {
230 int w = 0;
231 int h = 0;
232 GetClientSize( &w, &h );
233
234 wxPaintDC dc(this);
235 dc.SetFont( wxFont( 24, wxDECORATIVE, wxNORMAL, wxNORMAL ) );
236 dc.DrawText( "Drag text from here!", 20, h-20 );
237 }
238
239 void DnDFrame::OnDrag(wxCommandEvent& /* event */)
240 {
241 wxString strText = wxGetTextFromUser
242 (
243 "After you enter text in this dialog, press any mouse\n"
244 "button in the bottom (empty) part of the frame and \n"
245 "drag it anywhere - you will be in fact dragging the\n"
246 "text object containing this text",
247 "Please enter some text", m_strText, this
248 );
249
250 m_strText = strText;
251 }
252
253 void DnDFrame::OnAbout(wxCommandEvent& /* event */)
254 {
255 wxMessageDialog dialog(this,
256 "Drag-&-Drop Demo\n"
257 "Please see \"Help|Help...\" for details\n"
258 "Copyright (c) 1998 Vadim Zeitlin",
259 "About wxDnD");
260
261 dialog.ShowModal();
262 }
263
264 void DnDFrame::OnHelp(wxCommandEvent& /* event */)
265 {
266 wxMessageDialog dialog(this,
267 "This small program demonstrates drag & drop support in wxWindows. The program window\n"
268 "consists of 3 parts: the bottom pane is for debug messages, so that you can see what's\n"
269 "going on inside. The top part is split into 2 listboxes, the left one accepts files\n"
270 "and the right one accepts text.\n"
271 "\n"
272 "To test wxDropTarget: open wordpad (write.exe), select some text in it and drag it to\n"
273 "the right listbox (you'll notice the usual visual feedback, i.e. the cursor will change).\n"
274 "Also, try dragging some files (you can select several at once) from Windows Explorer (or \n"
275 "File Manager) to the left pane. Hold down Ctrl/Shift keys when you drop text (doesn't \n"
276 "work with files) and see what changes.\n"
277 "\n"
278 "To test wxDropSource: just press any mouse button on the empty zone of the window and drag\n"
279 "it to wordpad or any other droptarget accepting text (and of course you can just drag it\n"
280 "to the right pane). Due to a lot of trace messages, the cursor might take some time to \n"
281 "change, don't release the mouse button until it does. You can change the string being\n"
282 "dragged in in \"File|Test drag...\" dialog.\n"
283 "\n"
284 "\n"
285 "Please send all questions/bug reports/suggestions &c to \n"
286 "Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>",
287 "wxDnD Help");
288
289 dialog.ShowModal();
290 }
291
292 void DnDFrame::OnLogClear(wxCommandEvent& /* event */ )
293 {
294 m_ctrlLog->Clear();
295 }
296
297 bool DnDFrame::OnClose()
298 {
299 return TRUE;
300 }
301
302 void DnDFrame::OnLeftDown(wxMouseEvent &WXUNUSED(event) )
303 {
304 if ( !m_strText.IsEmpty() ) {
305 // start drag operation
306
307 wxTextDataObject data(m_strText);
308 wxDropSource dragSource(data, this);
309 const char *pc;
310
311 switch ( dragSource.DoDragDrop(TRUE) ) {
312 case wxDragError: pc = "Error!"; break;
313 case wxDragNone: pc = "Nothing"; break;
314 case wxDragCopy: pc = "Copied"; break;
315 case wxDragMove: pc = "Moved"; break;
316 case wxDragCancel: pc = "Cancelled"; break;
317 default: pc = "Huh?"; break;
318 }
319
320 SetStatusText(wxString("Drag result: ") + pc);
321 }
322 }
323
324 void DnDFrame::OnRightDown(wxMouseEvent &event )
325 {
326 wxMenu *menu = new wxMenu;
327
328 menu->Append(Menu_Drag, "&Test drag...");
329 menu->Append(Menu_About, "&About");
330 menu->Append(Menu_Quit, "E&xit");
331
332 PopupMenu( menu, event.GetX(), event.GetY() );
333 }
334
335 DnDFrame::~DnDFrame()
336 {
337 if ( m_pLog != NULL ) {
338 if ( wxLog::SetActiveTarget(m_pLogPrev) == m_pLog )
339 delete m_pLog;
340 }
341 }
342
343 // ----------------------------------------------------------------------------
344 // Notifications called by the base class
345 // ----------------------------------------------------------------------------
346 bool DnDText::OnDropText(long, long, const char *psz)
347 {
348 m_pOwner->Append(psz);
349
350 return TRUE;
351 }
352
353 bool DnDFile::OnDropFiles(long, long, size_t nFiles,
354 const char * const aszFiles[])
355 {
356 wxString str;
357 str.Printf("%d files dropped", nFiles);
358 m_pOwner->Append(str);
359 for ( size_t n = 0; n < nFiles; n++ ) {
360 m_pOwner->Append(aszFiles[n]);
361 }
362
363 return TRUE;
364 }