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