]> git.saurik.com Git - wxWidgets.git/blame - samples/dnd/dnd.cpp
Compilation fixes
[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
8bbe427f 7// RCS-ID: $Id$
43d811ea 8// Copyright:
8bbe427f 9// Licence: wxWindows licence
43d811ea
JS
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
8bbe427f 62{
457814b5
JS
63public:
64 bool OnInit();
65};
66
67IMPLEMENT_APP(DnDApp);
68
69// ----------------------------------------------------------------------------
70// Define a new frame type
71// ----------------------------------------------------------------------------
72class DnDFrame : public wxFrame
8bbe427f 73{
457814b5
JS
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);
8bbe427f 87
457814b5 88 bool OnClose();
8bbe427f 89
457814b5
JS
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)
b527aac5
RR
120 EVT_LEFT_DOWN( DnDFrame::OnLeftDown)
121 EVT_RIGHT_DOWN( DnDFrame::OnRightDown)
122 EVT_PAINT( DnDFrame::OnPaint)
457814b5
JS
123END_EVENT_TABLE()
124
125// `Main program' equivalent, creating windows and returning main app frame
8bbe427f 126bool DnDApp::OnInit()
457814b5
JS
127{
128 // create the main frame window
8bbe427f 129 DnDFrame *frame = new DnDFrame((wxFrame *) NULL, "Drag & Drop wxWindows App",
457814b5
JS
130 50, 50, 450, 340);
131
132 // activate it
133 frame->Show(TRUE);
134
135 SetTopWindow(frame);
136
137 return TRUE;
138}
139
140DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
43d811ea
JS
141 : wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h)),
142 m_strText("wxWindows drag & drop works :-)")
143
457814b5 144{
e3e65dac 145
43d811ea 146 // frame icon and status bar
b527aac5 147 SetIcon(wxICON(mondrian));
8bbe427f 148
cb43b372 149// const int widths[] = { -1 };
43d811ea 150 CreateStatusBar();
457814b5
JS
151
152 // construct menu
153 wxMenu *file_menu = new wxMenu;
43d811ea 154 file_menu->Append(Menu_Drag, "&Test drag...");
457814b5
JS
155 file_menu->AppendSeparator();
156 file_menu->Append(Menu_Quit, "E&xit");
43d811ea
JS
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
457814b5
JS
166 wxMenuBar *menu_bar = new wxMenuBar;
167 menu_bar->Append(file_menu, "&File");
43d811ea
JS
168 menu_bar->Append(log_menu, "&Log");
169 menu_bar->Append(help_menu, "&Help");
170
457814b5 171 SetMenuBar(menu_bar);
8bbe427f 172
457814b5
JS
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);
e3e65dac 181
8bbe427f
VZ
182 m_ctrlLog = new wxTextCtrl(this, -1, "", pos, size,
183 wxTE_MULTILINE | wxTE_READONLY |
457814b5
JS
184 wxSUNKEN_BORDER| wxHSCROLL);
185
186 // redirect log messages to the text window (don't forget to delete it!)
43d811ea
JS
187 m_pLog = new wxLogTextCtrl(m_ctrlLog);
188 m_pLogPrev = wxLog::SetActiveTarget(m_pLog);
457814b5
JS
189
190 // associate drop targets with 2 text controls
bb14db2d 191 m_ctrlFile->SetDropTarget(new DnDFile(m_ctrlFile));
8bbe427f 192 m_ctrlText->SetDropTarget(new DnDText(m_ctrlText));
457814b5 193
bb14db2d 194 wxLayoutConstraints *c;
457814b5 195
40e1a9c0 196 // Top-left listbox
457814b5 197 c = new wxLayoutConstraints;
8bbe427f
VZ
198 c->left.SameAs(this, wxLeft);
199 c->top.SameAs(this, wxTop);
457814b5 200 c->right.PercentOf(this, wxRight, 50);
43d811ea 201 c->height.PercentOf(this, wxHeight, 40);
457814b5
JS
202 m_ctrlFile->SetConstraints(c);
203
40e1a9c0 204 // Top-right listbox
457814b5
JS
205 c = new wxLayoutConstraints;
206 c->left.SameAs (m_ctrlFile, wxRight);
207 c->top.SameAs (this, wxTop);
208 c->right.SameAs (this, wxRight);
43d811ea 209 c->height.PercentOf(this, wxHeight, 40);
457814b5
JS
210 m_ctrlText->SetConstraints(c);
211
40e1a9c0 212 // Lower text control
457814b5
JS
213 c = new wxLayoutConstraints;
214 c->left.SameAs (this, wxLeft);
215 c->right.SameAs (this, wxRight);
43d811ea
JS
216 c->height.PercentOf(this, wxHeight, 40);
217 c->top.SameAs(m_ctrlText, wxBottom);
457814b5
JS
218 m_ctrlLog->SetConstraints(c);
219
220 SetAutoLayout(TRUE);
221}
222
223void DnDFrame::OnQuit(wxCommandEvent& /* event */)
224{
225 Close(TRUE);
226}
227
b527aac5
RR
228void DnDFrame::OnPaint(wxPaintEvent& /*event*/)
229{
230 int w = 0;
231 int h = 0;
232 GetClientSize( &w, &h );
8bbe427f 233
b527aac5
RR
234 wxPaintDC dc(this);
235 dc.SetFont( wxFont( 24, wxDECORATIVE, wxNORMAL, wxNORMAL ) );
236 dc.DrawText( "Drag text from here!", 20, h-20 );
237}
238
43d811ea
JS
239void 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
457814b5
JS
253void DnDFrame::OnAbout(wxCommandEvent& /* event */)
254{
8bbe427f 255 wxMessageDialog dialog(this,
457814b5 256 "Drag-&-Drop Demo\n"
43d811ea
JS
257 "Please see \"Help|Help...\" for details\n"
258 "Copyright (c) 1998 Vadim Zeitlin",
457814b5
JS
259 "About wxDnD");
260
261 dialog.ShowModal();
262}
263
264void DnDFrame::OnHelp(wxCommandEvent& /* event */)
265{
8bbe427f 266 wxMessageDialog dialog(this,
66bd6b93
RR
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"
8bbe427f 269"going on inside. The top part is split into 2 listboxes, the left one accepts files\n"
bb14db2d 270"and the right one accepts text.\n"
66bd6b93 271"\n"
8bbe427f
VZ
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"
66bd6b93
RR
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"
bb14db2d 276"work with files) and see what changes.\n"
66bd6b93 277"\n"
8bbe427f 278"To test wxDropSource: just press any mouse button on the empty zone of the window and drag\n"
66bd6b93
RR
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"
8bbe427f 281"change, don't release the mouse button until it does. You can change the string being\n"
66bd6b93 282"dragged in in \"File|Test drag...\" dialog.\n"
bb14db2d
VZ
283"\n"
284"\n"
66bd6b93 285"Please send all questions/bug reports/suggestions &c to \n"
457814b5
JS
286"Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>",
287 "wxDnD Help");
288
289 dialog.ShowModal();
290}
291
e3e65dac 292void DnDFrame::OnLogClear(wxCommandEvent& /* event */ )
43d811ea 293{
8bbe427f 294 m_ctrlLog->Clear();
43d811ea
JS
295}
296
8bbe427f
VZ
297bool DnDFrame::OnClose()
298{
299 return TRUE;
457814b5
JS
300}
301
30dea054 302void DnDFrame::OnLeftDown(wxMouseEvent &WXUNUSED(event) )
43d811ea
JS
303{
304 if ( !m_strText.IsEmpty() ) {
305 // start drag operation
8bbe427f 306
43d811ea 307 wxTextDataObject data(m_strText);
e3e65dac 308 wxDropSource dragSource(data, this);
43d811ea
JS
309 const char *pc;
310
311 switch ( dragSource.DoDragDrop(TRUE) ) {
46ccb510
JS
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;
43d811ea
JS
317 default: pc = "Huh?"; break;
318 }
319
320 SetStatusText(wxString("Drag result: ") + pc);
321 }
322}
323
30dea054
RR
324void DnDFrame::OnRightDown(wxMouseEvent &event )
325{
326 wxMenu *menu = new wxMenu;
8bbe427f 327
30dea054
RR
328 menu->Append(Menu_Drag, "&Test drag...");
329 menu->Append(Menu_About, "&About");
330 menu->Append(Menu_Quit, "E&xit");
8bbe427f 331
30dea054
RR
332 PopupMenu( menu, event.GetX(), event.GetY() );
333}
334
457814b5
JS
335DnDFrame::~DnDFrame()
336{
337 if ( m_pLog != NULL ) {
43d811ea 338 if ( wxLog::SetActiveTarget(m_pLogPrev) == m_pLog )
457814b5
JS
339 delete m_pLog;
340 }
341}
342
343// ----------------------------------------------------------------------------
344// Notifications called by the base class
345// ----------------------------------------------------------------------------
346bool DnDText::OnDropText(long, long, const char *psz)
347{
348 m_pOwner->Append(psz);
349
350 return TRUE;
351}
352
8bbe427f 353bool DnDFile::OnDropFiles(long, long, size_t nFiles,
457814b5
JS
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}