]>
git.saurik.com Git - wxWidgets.git/blob - samples/dnd/dnd.cpp
0b3e1c894fc4f87182b30339a64a03bf7620a56d
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Drag and drop sample
4 // Author: Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
28 #error Sorry, drag and drop is not yet implemented on wxMotif.
31 #if defined(__WXGTK__) || defined(__WXMOTIF__)
32 #include "mondrian.xpm"
35 #include "wx/clipbrd.h"
37 // ----------------------------------------------------------------------------
38 // Derive two simple classes which just put in the listbox the strings (text or
39 // file names) we drop on them
40 // ----------------------------------------------------------------------------
42 // FIXME this is ugly and should be fixed in the library itself
44 typedef long wxDropPointCoord
;
46 typedef int wxDropPointCoord
;
49 class DnDText
: public wxTextDropTarget
52 DnDText(wxListBox
*pOwner
) { m_pOwner
= pOwner
; }
54 virtual bool OnDropText(wxDropPointCoord x
, wxDropPointCoord y
,
61 class DnDFile
: public wxFileDropTarget
64 DnDFile(wxListBox
*pOwner
) { m_pOwner
= pOwner
; }
66 virtual bool OnDropFiles(wxDropPointCoord x
, wxDropPointCoord y
,
67 size_t nFiles
, const wxChar
* const aszFiles
[] );
73 // ----------------------------------------------------------------------------
74 // Define a new application type
75 // ----------------------------------------------------------------------------
77 class DnDApp
: public wxApp
83 IMPLEMENT_APP(DnDApp
);
85 // ----------------------------------------------------------------------------
86 // Define a new frame type
87 // ----------------------------------------------------------------------------
88 class DnDFrame
: public wxFrame
91 DnDFrame(wxFrame
*frame
, char *title
, int x
, int y
, int w
, int h
);
94 void OnPaint(wxPaintEvent
& event
);
95 void OnQuit (wxCommandEvent
& event
);
96 void OnAbout(wxCommandEvent
& event
);
97 void OnDrag (wxCommandEvent
& event
);
98 void OnHelp (wxCommandEvent
& event
);
99 void OnLogClear(wxCommandEvent
& event
);
100 void OnCopy(wxCommandEvent
& event
);
101 void OnPaste(wxCommandEvent
& event
);
103 void OnLeftDown(wxMouseEvent
& event
);
104 void OnRightDown(wxMouseEvent
& event
);
106 DECLARE_EVENT_TABLE()
109 wxListBox
*m_ctrlFile
,
111 wxTextCtrl
*m_ctrlLog
;
113 wxLog
*m_pLog
, *m_pLogPrev
;
118 // ----------------------------------------------------------------------------
119 // IDs for the menu commands
120 // ----------------------------------------------------------------------------
133 BEGIN_EVENT_TABLE(DnDFrame
, wxFrame
)
134 EVT_MENU(Menu_Quit
, DnDFrame::OnQuit
)
135 EVT_MENU(Menu_About
, DnDFrame::OnAbout
)
136 EVT_MENU(Menu_Drag
, DnDFrame::OnDrag
)
137 EVT_MENU(Menu_Help
, DnDFrame::OnHelp
)
138 EVT_MENU(Menu_Clear
, DnDFrame::OnLogClear
)
139 EVT_MENU(Menu_Copy
, DnDFrame::OnCopy
)
140 EVT_MENU(Menu_Paste
, DnDFrame::OnPaste
)
142 EVT_LEFT_DOWN( DnDFrame::OnLeftDown
)
143 EVT_RIGHT_DOWN( DnDFrame::OnRightDown
)
144 EVT_PAINT( DnDFrame::OnPaint
)
147 // `Main program' equivalent, creating windows and returning main app frame
148 bool DnDApp::OnInit()
150 // create the main frame window
151 DnDFrame
*frame
= new DnDFrame((wxFrame
*) NULL
,
152 "Drag-and-Drop/Clipboard wxWindows Sample",
163 DnDFrame::DnDFrame(wxFrame
*frame
, char *title
, int x
, int y
, int w
, int h
)
164 : wxFrame(frame
, -1, title
, wxPoint(x
, y
), wxSize(w
, h
)),
165 m_strText("wxWindows drag & drop works :-)")
168 // frame icon and status bar
169 SetIcon(wxICON(mondrian
));
174 wxMenu
*file_menu
= new wxMenu
;
175 file_menu
->Append(Menu_Drag
, "&Test drag...");
176 file_menu
->AppendSeparator();
177 file_menu
->Append(Menu_Quit
, "E&xit");
179 wxMenu
*log_menu
= new wxMenu
;
180 log_menu
->Append(Menu_Clear
, "Clear");
182 wxMenu
*help_menu
= new wxMenu
;
183 help_menu
->Append(Menu_Help
, "&Help...");
184 help_menu
->AppendSeparator();
185 help_menu
->Append(Menu_About
, "&About");
187 wxMenu
*clip_menu
= new wxMenu
;
188 clip_menu
->Append(Menu_Copy
, "&Copy\tCtrl+C");
189 clip_menu
->Append(Menu_Paste
, "&Paste\tCtrl+V");
191 wxMenuBar
*menu_bar
= new wxMenuBar
;
192 menu_bar
->Append(file_menu
, "&File");
193 menu_bar
->Append(log_menu
, "&Log");
194 menu_bar
->Append(clip_menu
, "&Clipboard");
195 menu_bar
->Append(help_menu
, "&Help");
197 SetMenuBar(menu_bar
);
199 // make a panel with 3 subwindows
201 wxSize
size(400, 200);
203 wxString
strFile("Drop files here!"), strText("Drop text on me");
205 m_ctrlFile
= new wxListBox(this, -1, pos
, size
, 1, &strFile
, wxLB_HSCROLL
);
206 m_ctrlText
= new wxListBox(this, -1, pos
, size
, 1, &strText
, wxLB_HSCROLL
);
208 m_ctrlLog
= new wxTextCtrl(this, -1, "", pos
, size
,
209 wxTE_MULTILINE
| wxTE_READONLY
|
212 // redirect log messages to the text window (don't forget to delete it!)
213 m_pLog
= new wxLogTextCtrl(m_ctrlLog
);
214 m_pLogPrev
= wxLog::SetActiveTarget(m_pLog
);
216 // associate drop targets with 2 text controls
217 m_ctrlFile
->SetDropTarget(new DnDFile(m_ctrlFile
));
218 m_ctrlText
->SetDropTarget( new DnDText(m_ctrlText
) );
220 wxLayoutConstraints
*c
;
223 c
= new wxLayoutConstraints
;
224 c
->left
.SameAs(this, wxLeft
);
225 c
->top
.SameAs(this, wxTop
);
226 c
->right
.PercentOf(this, wxRight
, 50);
227 c
->height
.PercentOf(this, wxHeight
, 40);
228 m_ctrlFile
->SetConstraints(c
);
231 c
= new wxLayoutConstraints
;
232 c
->left
.SameAs (m_ctrlFile
, wxRight
);
233 c
->top
.SameAs (this, wxTop
);
234 c
->right
.SameAs (this, wxRight
);
235 c
->height
.PercentOf(this, wxHeight
, 40);
236 m_ctrlText
->SetConstraints(c
);
238 // Lower text control
239 c
= new wxLayoutConstraints
;
240 c
->left
.SameAs (this, wxLeft
);
241 c
->right
.SameAs (this, wxRight
);
242 c
->height
.PercentOf(this, wxHeight
, 40);
243 c
->top
.SameAs(m_ctrlText
, wxBottom
);
244 m_ctrlLog
->SetConstraints(c
);
247 wxMenu
*file_menu
= new wxMenu
;
248 file_menu
->Append(Menu_Drag
, "&Test drag...");
249 file_menu
->AppendSeparator();
250 file_menu
->Append(Menu_Quit
, "E&xit");
252 wxMenu
*log_menu
= new wxMenu
;
253 log_menu
->Append(Menu_Clear
, "Clear");
255 wxMenu
*help_menu
= new wxMenu
;
256 help_menu
->Append(Menu_Help
, "&Help...");
257 help_menu
->AppendSeparator();
258 help_menu
->Append(Menu_About
, "&About");
260 wxMenuBar
*menu_bar
= new wxMenuBar
;
261 menu_bar
->Append(file_menu
, "&File");
262 menu_bar
->Append(log_menu
, "&Log");
263 menu_bar
->Append(help_menu
, "&Help");
265 SetMenuBar(menu_bar
);
267 // make a panel with 3 subwindows
269 wxSize
size(400, 200);
271 wxString
strFile("Drop files here!"), strText("Drop text on me");
273 m_ctrlFile
= new wxListBox(this, -1, pos
, size
, 1, &strFile
, wxLB_HSCROLL
);
274 m_ctrlText
= new wxListBox(this, -1, pos
, size
, 1, &strText
, wxLB_HSCROLL
);
276 m_ctrlLog
= new wxTextCtrl(this, -1, "", pos
, size
,
277 wxTE_MULTILINE
| wxTE_READONLY
|
280 // redirect log messages to the text window (don't forget to delete it!)
281 m_pLog
= new wxLogTextCtrl(m_ctrlLog
);
282 m_pLogPrev
= wxLog::SetActiveTarget(m_pLog
);
284 // associate drop targets with 2 text controls
285 m_ctrlFile
->SetDropTarget(new DnDFile(m_ctrlFile
));
286 m_ctrlText
->SetDropTarget(new DnDText(m_ctrlText
));
288 wxLayoutConstraints
*c
;
291 c
= new wxLayoutConstraints
;
292 c
->left
.SameAs(this, wxLeft
);
293 c
->top
.SameAs(this, wxTop
);
294 c
->right
.PercentOf(this, wxRight
, 50);
295 c
->height
.PercentOf(this, wxHeight
, 40);
296 m_ctrlFile
->SetConstraints(c
);
299 c
= new wxLayoutConstraints
;
300 c
->left
.SameAs (m_ctrlFile
, wxRight
);
301 c
->top
.SameAs (this, wxTop
);
302 c
->right
.SameAs (this, wxRight
);
303 c
->height
.PercentOf(this, wxHeight
, 40);
304 m_ctrlText
->SetConstraints(c
);
306 // Lower text control
307 c
= new wxLayoutConstraints
;
308 c
->left
.SameAs (this, wxLeft
);
309 c
->right
.SameAs (this, wxRight
);
310 c
->height
.PercentOf(this, wxHeight
, 40);
311 c
->top
.SameAs(m_ctrlText
, wxBottom
);
312 m_ctrlLog
->SetConstraints(c
);
317 void DnDFrame::OnQuit(wxCommandEvent
& /* event */)
322 void DnDFrame::OnPaint(wxPaintEvent
& /*event*/)
326 GetClientSize( &w
, &h
);
329 dc
.SetFont( wxFont( 24, wxDECORATIVE
, wxNORMAL
, wxNORMAL
, FALSE
, "charter" ) );
330 dc
.DrawText( "Drag text from here!", 20, h
-35 );
333 void DnDFrame::OnDrag(wxCommandEvent
& /* event */)
335 wxString strText
= wxGetTextFromUser
337 "After you enter text in this dialog, press any mouse\n"
338 "button in the bottom (empty) part of the frame and \n"
339 "drag it anywhere - you will be in fact dragging the\n"
340 "text object containing this text",
341 "Please enter some text", m_strText
, this
347 void DnDFrame::OnAbout(wxCommandEvent
& /* event */)
349 wxMessageBox("Drag-&-Drop Demo\n"
350 "Please see \"Help|Help...\" for details\n"
351 "Copyright (c) 1998 Vadim Zeitlin",
353 wxICON_INFORMATION
| wxOK
,
357 void DnDFrame::OnHelp(wxCommandEvent
& /* event */)
359 wxMessageDialog
dialog(this,
360 "This small program demonstrates drag & drop support in wxWindows. The program window\n"
361 "consists of 3 parts: the bottom pane is for debug messages, so that you can see what's\n"
362 "going on inside. The top part is split into 2 listboxes, the left one accepts files\n"
363 "and the right one accepts text.\n"
365 "To test wxDropTarget: open wordpad (write.exe), select some text in it and drag it to\n"
366 "the right listbox (you'll notice the usual visual feedback, i.e. the cursor will change).\n"
367 "Also, try dragging some files (you can select several at once) from Windows Explorer (or \n"
368 "File Manager) to the left pane. Hold down Ctrl/Shift keys when you drop text (doesn't \n"
369 "work with files) and see what changes.\n"
371 "To test wxDropSource: just press any mouse button on the empty zone of the window and drag\n"
372 "it to wordpad or any other droptarget accepting text (and of course you can just drag it\n"
373 "to the right pane). Due to a lot of trace messages, the cursor might take some time to \n"
374 "change, don't release the mouse button until it does. You can change the string being\n"
375 "dragged in in \"File|Test drag...\" dialog.\n"
378 "Please send all questions/bug reports/suggestions &c to \n"
379 "Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>",
385 void DnDFrame::OnLogClear(wxCommandEvent
& /* event */ )
390 void DnDFrame::OnLeftDown(wxMouseEvent
&WXUNUSED(event
) )
392 if ( !m_strText
.IsEmpty() )
394 // start drag operation
396 wxTextDataObject
textData(m_strText
);
397 wxDropSource
dragSource( textData
, this );
399 wxDropSource
dragSource( new wxTextDataObject (m_strText
), this, wxIcon(mondrian_xpm
) );
403 switch ( dragSource
.DoDragDrop(TRUE
) )
405 case wxDragError
: pc
= "Error!"; break;
406 case wxDragNone
: pc
= "Nothing"; break;
407 case wxDragCopy
: pc
= "Copied"; break;
408 case wxDragMove
: pc
= "Moved"; break;
409 case wxDragCancel
: pc
= "Cancelled"; break;
410 default: pc
= "Huh?"; break;
413 SetStatusText(wxString("Drag result: ") + pc
);
417 void DnDFrame::OnRightDown(wxMouseEvent
&event
)
419 wxMenu
*menu
= new wxMenu
;
421 menu
->Append(Menu_Drag
, "&Test drag...");
422 menu
->Append(Menu_About
, "&About");
423 menu
->Append(Menu_Quit
, "E&xit");
425 PopupMenu( menu
, event
.GetX(), event
.GetY() );
428 DnDFrame::~DnDFrame()
430 if ( m_pLog
!= NULL
) {
431 if ( wxLog::SetActiveTarget(m_pLogPrev
) == m_pLog
)
436 // ---------------------------------------------------------------------------
438 // ---------------------------------------------------------------------------
440 void DnDFrame::OnCopy(wxCommandEvent
& WXUNUSED(event
))
442 if ( !wxTheClipboard
->Open() )
444 wxLogError("Can't open clipboard.");
449 if ( !wxTheClipboard
->AddData(new wxTextDataObject(m_strText
)) )
451 wxLogError("Can't copy data to the clipboard");
455 wxLogMessage("Text '%s' put on the clipboard", m_strText
.c_str());
458 wxTheClipboard
->Close();
461 void DnDFrame::OnPaste(wxCommandEvent
& WXUNUSED(event
))
463 if ( !wxTheClipboard
->Open() )
465 wxLogError("Can't open clipboard.");
470 if ( !wxTheClipboard
->IsSupported(wxDF_TEXT
) )
472 wxLogWarning("No text data on clipboard");
477 wxTextDataObject text
;
478 if ( !wxTheClipboard
->GetData(&text
) )
480 wxLogError("Can't paste data from the clipboard");
484 wxLogMessage("Text '%s' pasted from the clipboard",
485 text
.GetText().c_str());
488 wxTheClipboard
->Close();
491 // ----------------------------------------------------------------------------
492 // Notifications called by the base class
493 // ----------------------------------------------------------------------------
494 bool DnDText::OnDropText( wxDropPointCoord
, wxDropPointCoord
, const wxChar
*psz
)
496 m_pOwner
->Append(psz
);
501 bool DnDFile::OnDropFiles( wxDropPointCoord
, wxDropPointCoord
, size_t nFiles
,
502 const wxChar
* const aszFiles
[])
505 str
.Printf( _T("%d files dropped"), nFiles
);
506 m_pOwner
->Append(str
);
507 for ( size_t n
= 0; n
< nFiles
; n
++ ) {
508 m_pOwner
->Append(aszFiles
[n
]);