]>
git.saurik.com Git - wxWidgets.git/blob - samples/dnd/dnd.cpp
e78b54aa2b7d52e47ad80fa826426c2d5425880c
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Drag and drop sample
4 // Author: Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
23 #error Sorry, drag and drop is not yet implemented on wxMotif.
30 #include "wx/dirdlg.h"
31 #include "wx/filedlg.h"
33 #include "wx/clipbrd.h"
35 #if defined(__WXGTK__) || defined(__WXMOTIF__)
36 #include "mondrian.xpm"
39 // ----------------------------------------------------------------------------
40 // Derive two simple classes which just put in the listbox the strings (text or
41 // file names) we drop on them
42 // ----------------------------------------------------------------------------
44 typedef long wxDropPointCoord
;
46 class DnDText
: public wxTextDropTarget
49 DnDText(wxListBox
*pOwner
) { m_pOwner
= pOwner
; }
51 virtual bool OnDropText(wxDropPointCoord x
, wxDropPointCoord y
,
58 class DnDFile
: public wxFileDropTarget
61 DnDFile(wxListBox
*pOwner
) { m_pOwner
= pOwner
; }
63 virtual bool OnDropFiles(wxDropPointCoord x
, wxDropPointCoord y
,
64 size_t nFiles
, const wxChar
* const aszFiles
[] );
70 // ----------------------------------------------------------------------------
71 // Define a new application type
72 // ----------------------------------------------------------------------------
74 class DnDApp
: public wxApp
80 IMPLEMENT_APP(DnDApp
);
82 // ----------------------------------------------------------------------------
83 // Define a new frame type
84 // ----------------------------------------------------------------------------
85 class DnDFrame
: public wxFrame
88 DnDFrame(wxFrame
*frame
, char *title
, int x
, int y
, int w
, int h
);
91 void OnPaint(wxPaintEvent
& event
);
92 void OnQuit (wxCommandEvent
& event
);
93 void OnAbout(wxCommandEvent
& event
);
94 void OnDrag (wxCommandEvent
& event
);
95 void OnHelp (wxCommandEvent
& event
);
96 void OnLogClear(wxCommandEvent
& event
);
97 void OnCopy(wxCommandEvent
& event
);
98 void OnPaste(wxCommandEvent
& event
);
99 void OnCopyBitmap(wxCommandEvent
& event
);
100 void OnPasteBitmap(wxCommandEvent
& event
);
101 void OnClipboardHasText(wxCommandEvent
& event
);
102 void OnClipboardHasBitmap(wxCommandEvent
& event
);
104 void OnLeftDown(wxMouseEvent
& event
);
105 void OnRightDown(wxMouseEvent
& event
);
107 DECLARE_EVENT_TABLE()
110 wxListBox
*m_ctrlFile
,
112 wxTextCtrl
*m_ctrlLog
;
114 wxLog
*m_pLog
, *m_pLogPrev
;
120 // ----------------------------------------------------------------------------
121 // IDs for the menu commands
122 // ----------------------------------------------------------------------------
137 Menu_ToBeGreyed
, /* for testing */
138 Menu_ToBeDeleted
/* for testing */
141 BEGIN_EVENT_TABLE(DnDFrame
, wxFrame
)
142 EVT_MENU(Menu_Quit
, DnDFrame::OnQuit
)
143 EVT_MENU(Menu_About
, DnDFrame::OnAbout
)
144 EVT_MENU(Menu_Drag
, DnDFrame::OnDrag
)
145 EVT_MENU(Menu_Help
, DnDFrame::OnHelp
)
146 EVT_MENU(Menu_Clear
, DnDFrame::OnLogClear
)
147 EVT_MENU(Menu_Copy
, DnDFrame::OnCopy
)
148 EVT_MENU(Menu_Paste
, DnDFrame::OnPaste
)
149 EVT_MENU(Menu_CopyBitmap
, DnDFrame::OnCopyBitmap
)
150 EVT_MENU(Menu_PasteBitmap
,DnDFrame::OnPasteBitmap
)
151 EVT_MENU(Menu_HasText
, DnDFrame::OnClipboardHasText
)
152 EVT_MENU(Menu_HasBitmap
, DnDFrame::OnClipboardHasBitmap
)
154 EVT_LEFT_DOWN( DnDFrame::OnLeftDown
)
155 EVT_RIGHT_DOWN( DnDFrame::OnRightDown
)
156 EVT_PAINT( DnDFrame::OnPaint
)
159 // `Main program' equivalent, creating windows and returning main app frame
160 bool DnDApp::OnInit()
163 wxImage::AddHandler( new wxPNGHandler
);
166 // create the main frame window
167 DnDFrame
*frame
= new DnDFrame((wxFrame
*) NULL
,
168 "Drag-and-Drop/Clipboard wxWindows Sample",
179 DnDFrame::DnDFrame(wxFrame
*frame
, char *title
, int x
, int y
, int w
, int h
)
180 : wxFrame(frame
, -1, title
, wxPoint(x
, y
), wxSize(w
, h
)),
181 m_strText("wxWindows drag & drop works :-)")
184 // frame icon and status bar
185 SetIcon(wxICON(mondrian
));
189 // construct sub menu for testing
190 wxMenu
*sub_menu
= new wxMenu
;
191 sub_menu
->Append(Menu_Quit
, "E&xit");
192 sub_menu
->Append(Menu_Quit
, "E&xit");
193 sub_menu
->Append(Menu_Quit
, "E&xit");
196 wxMenu
*file_menu
= new wxMenu
;
197 file_menu
->Append(Menu_Drag
, "&Test drag...");
198 file_menu
->AppendSeparator();
199 file_menu
->Append(Menu_Quit
, "E&xit");
200 file_menu
->AppendSeparator();
201 file_menu
->Append( 0, "More exit menus", sub_menu
);
203 wxMenu
*log_menu
= new wxMenu
;
204 log_menu
->Append(Menu_Clear
, "Clear");
206 wxMenu
*help_menu
= new wxMenu
;
207 help_menu
->Append(Menu_Help
, "&Help...");
208 help_menu
->AppendSeparator();
209 help_menu
->Append(Menu_About
, "&About");
211 wxMenu
*clip_menu
= new wxMenu
;
212 clip_menu
->Append(Menu_Copy
, "&Copy text\tCtrl+C");
213 clip_menu
->Append(Menu_Paste
, "&Paste text\tCtrl+V");
214 clip_menu
->AppendSeparator();
215 clip_menu
->Append(Menu_CopyBitmap
, "&Copy bitmap");
216 clip_menu
->Append(Menu_PasteBitmap
, "&Paste bitmap");
217 clip_menu
->AppendSeparator();
218 clip_menu
->Append(Menu_HasText
, "Clipboard has &text\tCtrl+T");
219 clip_menu
->Append(Menu_HasBitmap
, "Clipboard has a &bitmap\tCtrl+B");
221 wxMenuBar
*menu_bar
= new wxMenuBar
;
222 menu_bar
->Append(file_menu
, "&File");
223 menu_bar
->Append(log_menu
, "&Log");
224 menu_bar
->Append(clip_menu
, "&Clipboard");
225 menu_bar
->Append(help_menu
, "&Help");
227 SetMenuBar(menu_bar
);
229 // make a panel with 3 subwindows
231 wxSize
size(400, 200);
233 wxString
strFile("Drop files here!"), strText("Drop text on me");
235 m_ctrlFile
= new wxListBox(this, -1, pos
, size
, 1, &strFile
, wxLB_HSCROLL
| wxLB_ALWAYS_SB
);
236 m_ctrlText
= new wxListBox(this, -1, pos
, size
, 1, &strText
, wxLB_HSCROLL
| wxLB_ALWAYS_SB
);
238 m_ctrlLog
= new wxTextCtrl(this, -1, "", pos
, size
,
239 wxTE_MULTILINE
| wxTE_READONLY
|
241 // redirect log messages to the text window (don't forget to delete it!)
242 m_pLog
= new wxLogTextCtrl(m_ctrlLog
);
243 m_pLogPrev
= wxLog::SetActiveTarget(m_pLog
);
245 // associate drop targets with 2 text controls
246 m_ctrlFile
->SetDropTarget(new DnDFile(m_ctrlFile
));
247 m_ctrlText
->SetDropTarget(new DnDText(m_ctrlText
));
249 wxLayoutConstraints
*c
;
252 c
= new wxLayoutConstraints
;
253 c
->left
.SameAs(this, wxLeft
);
254 c
->top
.SameAs(this, wxTop
);
255 c
->right
.PercentOf(this, wxRight
, 50);
256 c
->height
.PercentOf(this, wxHeight
, 30);
257 m_ctrlFile
->SetConstraints(c
);
260 c
= new wxLayoutConstraints
;
261 c
->left
.SameAs (m_ctrlFile
, wxRight
);
262 c
->top
.SameAs (this, wxTop
);
263 c
->right
.SameAs (this, wxRight
);
264 c
->height
.PercentOf(this, wxHeight
, 30);
265 m_ctrlText
->SetConstraints(c
);
267 // Lower text control
268 c
= new wxLayoutConstraints
;
269 c
->left
.SameAs (this, wxLeft
);
270 c
->right
.SameAs (this, wxRight
);
271 c
->height
.PercentOf(this, wxHeight
, 30);
272 c
->top
.SameAs(m_ctrlText
, wxBottom
);
273 m_ctrlLog
->SetConstraints(c
);
278 void DnDFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
283 void DnDFrame::OnPaint(wxPaintEvent
& WXUNUSED(event
))
287 GetClientSize( &w
, &h
);
290 dc
.SetFont( wxFont( 24, wxDECORATIVE
, wxNORMAL
, wxNORMAL
, FALSE
, "charter" ) );
291 dc
.DrawText( "Drag text from here!", 20, h
-50 );
294 dc
.DrawBitmap( m_bitmap
, 280, h
-120, TRUE
);
297 void DnDFrame::OnClipboardHasText(wxCommandEvent
& WXUNUSED(event
))
299 if ( !wxTheClipboard
->Open() )
301 wxLogError( _T("Can't open clipboard.") );
306 if ( !wxTheClipboard
->IsSupported( wxDF_TEXT
) )
308 wxLogMessage( _T("No text on the clipboard") );
312 wxLogMessage( _T("There is text on the clipboard") );
315 wxTheClipboard
->Close();
318 void DnDFrame::OnClipboardHasBitmap(wxCommandEvent
& WXUNUSED(event
))
320 if ( !wxTheClipboard
->Open() )
322 wxLogError( _T("Can't open clipboard.") );
327 if ( !wxTheClipboard
->IsSupported( wxDF_BITMAP
) )
329 wxLogMessage( _T("No bitmap on the clipboard") );
333 wxLogMessage( _T("There is a bitmap on the clipboard") );
336 wxTheClipboard
->Close();
339 void DnDFrame::OnDrag(wxCommandEvent
& WXUNUSED(event
))
341 wxString strText
= wxGetTextFromUser
343 "After you enter text in this dialog, press any mouse\n"
344 "button in the bottom (empty) part of the frame and \n"
345 "drag it anywhere - you will be in fact dragging the\n"
346 "text object containing this text",
347 "Please enter some text", m_strText
, this
353 void DnDFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
355 wxMessageBox("Drag-&-Drop Demo\n"
356 "Please see \"Help|Help...\" for details\n"
357 "Copyright (c) 1998 Vadim Zeitlin",
359 wxICON_INFORMATION
| wxOK
,
363 void DnDFrame::OnHelp(wxCommandEvent
& /* event */)
365 wxMessageDialog
dialog(this,
366 "This small program demonstrates drag & drop support in wxWindows. The program window\n"
367 "consists of 3 parts: the bottom pane is for debug messages, so that you can see what's\n"
368 "going on inside. The top part is split into 2 listboxes, the left one accepts files\n"
369 "and the right one accepts text.\n"
371 "To test wxDropTarget: open wordpad (write.exe), select some text in it and drag it to\n"
372 "the right listbox (you'll notice the usual visual feedback, i.e. the cursor will change).\n"
373 "Also, try dragging some files (you can select several at once) from Windows Explorer (or \n"
374 "File Manager) to the left pane. Hold down Ctrl/Shift keys when you drop text (doesn't \n"
375 "work with files) and see what changes.\n"
377 "To test wxDropSource: just press any mouse button on the empty zone of the window and drag\n"
378 "it to wordpad or any other droptarget accepting text (and of course you can just drag it\n"
379 "to the right pane). Due to a lot of trace messages, the cursor might take some time to \n"
380 "change, don't release the mouse button until it does. You can change the string being\n"
381 "dragged in in \"File|Test drag...\" dialog.\n"
384 "Please send all questions/bug reports/suggestions &c to \n"
385 "Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>",
391 void DnDFrame::OnLogClear(wxCommandEvent
& /* event */ )
396 void DnDFrame::OnLeftDown(wxMouseEvent
&WXUNUSED(event
) )
398 if ( !m_strText
.IsEmpty() )
400 // start drag operation
402 wxTextDataObject
textData(m_strText
);
403 wxDropSource
dragSource( textData
, this );
405 wxDropSource
dragSource( new wxTextDataObject (m_strText
), this, wxIcon(mondrian_xpm
) );
409 switch ( dragSource
.DoDragDrop(TRUE
) )
411 case wxDragError
: pc
= "Error!"; break;
412 case wxDragNone
: pc
= "Nothing"; break;
413 case wxDragCopy
: pc
= "Copied"; break;
414 case wxDragMove
: pc
= "Moved"; break;
415 case wxDragCancel
: pc
= "Cancelled"; break;
416 default: pc
= "Huh?"; break;
419 SetStatusText(wxString("Drag result: ") + pc
);
423 void DnDFrame::OnRightDown(wxMouseEvent
&event
)
425 wxMenu
*menu
= new wxMenu
;
427 menu
->Append(Menu_Drag
, "&Test drag...");
428 menu
->Append(Menu_About
, "&About");
429 menu
->Append(Menu_Quit
, "E&xit");
430 menu
->Append(Menu_ToBeDeleted
, "To be deleted");
431 menu
->Append(Menu_ToBeGreyed
, "To be greyed");
433 menu
->Delete( Menu_ToBeDeleted
);
434 menu
->Enable( Menu_ToBeGreyed
, FALSE
);
436 PopupMenu( menu
, event
.GetX(), event
.GetY() );
439 DnDFrame::~DnDFrame()
441 if ( m_pLog
!= NULL
) {
442 if ( wxLog::SetActiveTarget(m_pLogPrev
) == m_pLog
)
447 // ---------------------------------------------------------------------------
449 // ---------------------------------------------------------------------------
451 void DnDFrame::OnCopyBitmap(wxCommandEvent
& WXUNUSED(event
))
453 // PNG support is not always compiled in under Windows, so use BMP there
455 wxFileDialog
dialog(this, "Open a BMP file", "", "", "BMP files (*.bmp)|*.bmp", 0);
457 wxFileDialog
dialog(this, "Open a PNG file", "", "", "PNG files (*.png)|*.png", 0);
460 if (dialog
.ShowModal() != wxID_OK
)
462 wxLogMessage( _T("Aborted file open") );
466 if (dialog
.GetPath().IsEmpty())
468 wxLogMessage( _T("Returned empty string.") );
472 if (!wxFileExists(dialog
.GetPath()))
474 wxLogMessage( _T("File doesn't exist.") );
479 image
.LoadFile( dialog
.GetPath(),
488 wxLogMessage( _T("Invalid image file...") );
492 wxLogMessage( _T("Decoding image file...") );
495 wxBitmap
bitmap( image
.ConvertToBitmap() );
497 if ( !wxTheClipboard
->Open() )
499 wxLogError(_T("Can't open clipboard."));
504 wxLogMessage( _T("Creating wxBitmapDataObject...") );
507 if ( !wxTheClipboard
->AddData(new wxBitmapDataObject(bitmap
)) )
509 wxLogError(_T("Can't copy image to the clipboard."));
513 wxLogMessage(_T("Image has been put on the clipboard.") );
514 wxLogMessage(_T("You can paste it now and look at it.") );
517 wxTheClipboard
->Close();
520 void DnDFrame::OnPasteBitmap(wxCommandEvent
& WXUNUSED(event
))
522 if ( !wxTheClipboard
->Open() )
524 wxLogError(_T("Can't open clipboard."));
529 if ( !wxTheClipboard
->IsSupported(wxDF_BITMAP
) )
531 wxLogWarning(_T("No bitmap on clipboard"));
533 wxTheClipboard
->Close();
537 wxBitmapDataObject data
;
538 if ( !wxTheClipboard
->GetData(&data
) )
540 wxLogError(_T("Can't paste bitmap from the clipboard"));
544 wxLogMessage(_T("Bitmap pasted from the clipboard") );
545 m_bitmap
= data
.GetBitmap();
549 wxTheClipboard
->Close();
552 // ---------------------------------------------------------------------------
554 // ---------------------------------------------------------------------------
556 void DnDFrame::OnCopy(wxCommandEvent
& WXUNUSED(event
))
558 if ( !wxTheClipboard
->Open() )
560 wxLogError(_T("Can't open clipboard."));
565 if ( !wxTheClipboard
->AddData(new wxTextDataObject(m_strText
)) )
567 wxLogError(_T("Can't copy data to the clipboard"));
571 wxLogMessage(_T("Text '%s' put on the clipboard"), m_strText
.c_str());
574 wxTheClipboard
->Close();
577 void DnDFrame::OnPaste(wxCommandEvent
& WXUNUSED(event
))
579 if ( !wxTheClipboard
->Open() )
581 wxLogError(_T("Can't open clipboard."));
586 if ( !wxTheClipboard
->IsSupported(wxDF_TEXT
) )
588 wxLogWarning(_T("No text data on clipboard"));
590 wxTheClipboard
->Close();
594 wxTextDataObject text
;
595 if ( !wxTheClipboard
->GetData(&text
) )
597 wxLogError(_T("Can't paste data from the clipboard"));
601 wxLogMessage(_T("Text '%s' pasted from the clipboard"),
602 text
.GetText().c_str());
605 wxTheClipboard
->Close();
608 // ----------------------------------------------------------------------------
609 // Notifications called by the base class
610 // ----------------------------------------------------------------------------
612 bool DnDText::OnDropText( wxDropPointCoord
, wxDropPointCoord
, const wxChar
*psz
)
614 m_pOwner
->Append(psz
);
619 bool DnDFile::OnDropFiles( wxDropPointCoord
, wxDropPointCoord
, size_t nFiles
,
620 const wxChar
* const aszFiles
[])
623 str
.Printf( _T("%d files dropped"), nFiles
);
624 m_pOwner
->Append(str
);
625 for ( size_t n
= 0; n
< nFiles
; n
++ ) {
626 m_pOwner
->Append(aszFiles
[n
]);