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