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