]>
git.saurik.com Git - wxWidgets.git/blob - samples/dnd/dnd.cpp
c5159b990520ddd09493926286ebf319a93fb894
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 // ----------------------------------------------------------------------------
139 BEGIN_EVENT_TABLE(DnDFrame
, wxFrame
)
140 EVT_MENU(Menu_Quit
, DnDFrame::OnQuit
)
141 EVT_MENU(Menu_About
, DnDFrame::OnAbout
)
142 EVT_MENU(Menu_Drag
, DnDFrame::OnDrag
)
143 EVT_MENU(Menu_Help
, DnDFrame::OnHelp
)
144 EVT_MENU(Menu_Clear
, DnDFrame::OnLogClear
)
145 EVT_MENU(Menu_Copy
, DnDFrame::OnCopy
)
146 EVT_MENU(Menu_Paste
, DnDFrame::OnPaste
)
147 EVT_MENU(Menu_CopyBitmap
, DnDFrame::OnCopyBitmap
)
148 EVT_MENU(Menu_PasteBitmap
,DnDFrame::OnPasteBitmap
)
149 EVT_MENU(Menu_HasText
, DnDFrame::OnClipboardHasText
)
150 EVT_MENU(Menu_HasBitmap
, DnDFrame::OnClipboardHasBitmap
)
152 EVT_LEFT_DOWN( DnDFrame::OnLeftDown
)
153 EVT_RIGHT_DOWN( DnDFrame::OnRightDown
)
154 EVT_PAINT( DnDFrame::OnPaint
)
157 // `Main program' equivalent, creating windows and returning main app frame
158 bool DnDApp::OnInit()
161 wxImage::AddHandler( new wxPNGHandler
);
164 // create the main frame window
165 DnDFrame
*frame
= new DnDFrame((wxFrame
*) NULL
,
166 "Drag-and-Drop/Clipboard wxWindows Sample",
177 DnDFrame::DnDFrame(wxFrame
*frame
, char *title
, int x
, int y
, int w
, int h
)
178 : wxFrame(frame
, -1, title
, wxPoint(x
, y
), wxSize(w
, h
)),
179 m_strText("wxWindows drag & drop works :-)")
182 // frame icon and status bar
183 SetIcon(wxICON(mondrian
));
188 wxMenu
*file_menu
= new wxMenu
;
189 file_menu
->Append(Menu_Drag
, "&Test drag...");
190 file_menu
->AppendSeparator();
191 file_menu
->Append(Menu_Quit
, "E&xit");
193 wxMenu
*log_menu
= new wxMenu
;
194 log_menu
->Append(Menu_Clear
, "Clear");
196 wxMenu
*help_menu
= new wxMenu
;
197 help_menu
->Append(Menu_Help
, "&Help...");
198 help_menu
->AppendSeparator();
199 help_menu
->Append(Menu_About
, "&About");
201 wxMenu
*clip_menu
= new wxMenu
;
202 clip_menu
->Append(Menu_Copy
, "&Copy text\tCtrl+C");
203 clip_menu
->Append(Menu_Paste
, "&Paste text\tCtrl+V");
204 clip_menu
->AppendSeparator();
205 clip_menu
->Append(Menu_CopyBitmap
, "&Copy bitmap");
206 clip_menu
->Append(Menu_PasteBitmap
, "&Paste bitmap");
207 clip_menu
->AppendSeparator();
208 clip_menu
->Append(Menu_HasText
, "Clipboard has &text\tCtrl+T");
209 clip_menu
->Append(Menu_HasBitmap
, "Clipboard has a &bitmap\tCtrl+B");
211 wxMenuBar
*menu_bar
= new wxMenuBar
;
212 menu_bar
->Append(file_menu
, "&File");
213 menu_bar
->Append(log_menu
, "&Log");
214 menu_bar
->Append(clip_menu
, "&Clipboard");
215 menu_bar
->Append(help_menu
, "&Help");
217 SetMenuBar(menu_bar
);
219 // make a panel with 3 subwindows
221 wxSize
size(400, 200);
223 wxString
strFile("Drop files here!"), strText("Drop text on me");
225 m_ctrlFile
= new wxListBox(this, -1, pos
, size
, 1, &strFile
, wxLB_HSCROLL
| wxLB_ALWAYS_SB
);
226 m_ctrlText
= new wxListBox(this, -1, pos
, size
, 1, &strText
, wxLB_HSCROLL
| wxLB_ALWAYS_SB
);
228 m_ctrlLog
= new wxTextCtrl(this, -1, "", pos
, size
,
229 wxTE_MULTILINE
| wxTE_READONLY
|
231 // redirect log messages to the text window (don't forget to delete it!)
232 m_pLog
= new wxLogTextCtrl(m_ctrlLog
);
233 m_pLogPrev
= wxLog::SetActiveTarget(m_pLog
);
235 // associate drop targets with 2 text controls
236 m_ctrlFile
->SetDropTarget(new DnDFile(m_ctrlFile
));
237 m_ctrlText
->SetDropTarget(new DnDText(m_ctrlText
));
239 wxLayoutConstraints
*c
;
242 c
= new wxLayoutConstraints
;
243 c
->left
.SameAs(this, wxLeft
);
244 c
->top
.SameAs(this, wxTop
);
245 c
->right
.PercentOf(this, wxRight
, 50);
246 c
->height
.PercentOf(this, wxHeight
, 30);
247 m_ctrlFile
->SetConstraints(c
);
250 c
= new wxLayoutConstraints
;
251 c
->left
.SameAs (m_ctrlFile
, wxRight
);
252 c
->top
.SameAs (this, wxTop
);
253 c
->right
.SameAs (this, wxRight
);
254 c
->height
.PercentOf(this, wxHeight
, 30);
255 m_ctrlText
->SetConstraints(c
);
257 // Lower text control
258 c
= new wxLayoutConstraints
;
259 c
->left
.SameAs (this, wxLeft
);
260 c
->right
.SameAs (this, wxRight
);
261 c
->height
.PercentOf(this, wxHeight
, 30);
262 c
->top
.SameAs(m_ctrlText
, wxBottom
);
263 m_ctrlLog
->SetConstraints(c
);
268 void DnDFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
273 void DnDFrame::OnPaint(wxPaintEvent
& WXUNUSED(event
))
277 GetClientSize( &w
, &h
);
280 dc
.SetFont( wxFont( 24, wxDECORATIVE
, wxNORMAL
, wxNORMAL
, FALSE
, "charter" ) );
281 dc
.DrawText( "Drag text from here!", 20, h
-50 );
284 dc
.DrawBitmap( m_bitmap
, 280, h
-120, TRUE
);
287 void DnDFrame::OnClipboardHasText(wxCommandEvent
& WXUNUSED(event
))
289 if ( !wxTheClipboard
->Open() )
291 wxLogError( _T("Can't open clipboard.") );
296 if ( !wxTheClipboard
->IsSupported( wxDF_TEXT
) )
298 wxLogMessage( _T("No text on the clipboard") );
302 wxLogMessage( _T("There is text on the clipboard") );
305 wxTheClipboard
->Close();
308 void DnDFrame::OnClipboardHasBitmap(wxCommandEvent
& WXUNUSED(event
))
310 if ( !wxTheClipboard
->Open() )
312 wxLogError( _T("Can't open clipboard.") );
317 if ( !wxTheClipboard
->IsSupported( wxDF_BITMAP
) )
319 wxLogMessage( _T("No bitmap on the clipboard") );
323 wxLogMessage( _T("There is a bitmap on the clipboard") );
326 wxTheClipboard
->Close();
329 void DnDFrame::OnDrag(wxCommandEvent
& WXUNUSED(event
))
331 wxString strText
= wxGetTextFromUser
333 "After you enter text in this dialog, press any mouse\n"
334 "button in the bottom (empty) part of the frame and \n"
335 "drag it anywhere - you will be in fact dragging the\n"
336 "text object containing this text",
337 "Please enter some text", m_strText
, this
343 void DnDFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
345 wxMessageBox("Drag-&-Drop Demo\n"
346 "Please see \"Help|Help...\" for details\n"
347 "Copyright (c) 1998 Vadim Zeitlin",
349 wxICON_INFORMATION
| wxOK
,
353 void DnDFrame::OnHelp(wxCommandEvent
& /* event */)
355 wxMessageDialog
dialog(this,
356 "This small program demonstrates drag & drop support in wxWindows. The program window\n"
357 "consists of 3 parts: the bottom pane is for debug messages, so that you can see what's\n"
358 "going on inside. The top part is split into 2 listboxes, the left one accepts files\n"
359 "and the right one accepts text.\n"
361 "To test wxDropTarget: open wordpad (write.exe), select some text in it and drag it to\n"
362 "the right listbox (you'll notice the usual visual feedback, i.e. the cursor will change).\n"
363 "Also, try dragging some files (you can select several at once) from Windows Explorer (or \n"
364 "File Manager) to the left pane. Hold down Ctrl/Shift keys when you drop text (doesn't \n"
365 "work with files) and see what changes.\n"
367 "To test wxDropSource: just press any mouse button on the empty zone of the window and drag\n"
368 "it to wordpad or any other droptarget accepting text (and of course you can just drag it\n"
369 "to the right pane). Due to a lot of trace messages, the cursor might take some time to \n"
370 "change, don't release the mouse button until it does. You can change the string being\n"
371 "dragged in in \"File|Test drag...\" dialog.\n"
374 "Please send all questions/bug reports/suggestions &c to \n"
375 "Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>",
381 void DnDFrame::OnLogClear(wxCommandEvent
& /* event */ )
386 void DnDFrame::OnLeftDown(wxMouseEvent
&WXUNUSED(event
) )
388 if ( !m_strText
.IsEmpty() )
390 // start drag operation
392 wxTextDataObject
textData(m_strText
);
393 wxDropSource
dragSource( textData
, this );
395 wxDropSource
dragSource( new wxTextDataObject (m_strText
), this, wxIcon(mondrian_xpm
) );
399 switch ( dragSource
.DoDragDrop(TRUE
) )
401 case wxDragError
: pc
= "Error!"; break;
402 case wxDragNone
: pc
= "Nothing"; break;
403 case wxDragCopy
: pc
= "Copied"; break;
404 case wxDragMove
: pc
= "Moved"; break;
405 case wxDragCancel
: pc
= "Cancelled"; break;
406 default: pc
= "Huh?"; break;
409 SetStatusText(wxString("Drag result: ") + pc
);
413 void DnDFrame::OnRightDown(wxMouseEvent
&event
)
415 wxMenu
*menu
= new wxMenu
;
417 menu
->Append(Menu_Drag
, "&Test drag...");
418 menu
->Append(Menu_About
, "&About");
419 menu
->Append(Menu_Quit
, "E&xit");
421 PopupMenu( menu
, event
.GetX(), event
.GetY() );
424 DnDFrame::~DnDFrame()
426 if ( m_pLog
!= NULL
) {
427 if ( wxLog::SetActiveTarget(m_pLogPrev
) == m_pLog
)
432 // ---------------------------------------------------------------------------
434 // ---------------------------------------------------------------------------
436 void DnDFrame::OnCopyBitmap(wxCommandEvent
& WXUNUSED(event
))
438 // PNG support is not always compiled in under Windows, so use BMP there
440 wxFileDialog
dialog(this, "Open a BMP file", "", "", "BMP files (*.bmp)|*.bmp", 0);
442 wxFileDialog
dialog(this, "Open a PNG file", "", "", "PNG files (*.png)|*.png", 0);
445 if (dialog
.ShowModal() != wxID_OK
)
447 wxLogMessage( _T("Aborted file open") );
451 if (dialog
.GetPath().IsEmpty())
453 wxLogMessage( _T("Returned empty string.") );
457 if (!wxFileExists(dialog
.GetPath()))
459 wxLogMessage( _T("File doesn't exist.") );
464 image
.LoadFile( dialog
.GetPath(),
473 wxLogMessage( _T("Invalid image file...") );
477 wxLogMessage( _T("Decoding image file...") );
480 wxBitmap
bitmap( image
.ConvertToBitmap() );
482 if ( !wxTheClipboard
->Open() )
484 wxLogError(_T("Can't open clipboard."));
489 wxLogMessage( _T("Creating wxBitmapDataObject...") );
492 if ( !wxTheClipboard
->AddData(new wxBitmapDataObject(bitmap
)) )
494 wxLogError(_T("Can't copy image to the clipboard."));
498 wxLogMessage(_T("Image has been put on the clipboard.") );
499 wxLogMessage(_T("You can paste it now and look at it.") );
502 wxTheClipboard
->Close();
505 void DnDFrame::OnPasteBitmap(wxCommandEvent
& WXUNUSED(event
))
507 if ( !wxTheClipboard
->Open() )
509 wxLogError(_T("Can't open clipboard."));
514 if ( !wxTheClipboard
->IsSupported(wxDF_BITMAP
) )
516 wxLogWarning(_T("No bitmap on clipboard"));
518 wxTheClipboard
->Close();
522 wxBitmapDataObject data
;
523 if ( !wxTheClipboard
->GetData(&data
) )
525 wxLogError(_T("Can't paste bitmap from the clipboard"));
529 wxLogMessage(_T("Bitmap pasted from the clipboard") );
530 m_bitmap
= data
.GetBitmap();
534 wxTheClipboard
->Close();
537 // ---------------------------------------------------------------------------
539 // ---------------------------------------------------------------------------
541 void DnDFrame::OnCopy(wxCommandEvent
& WXUNUSED(event
))
543 if ( !wxTheClipboard
->Open() )
545 wxLogError(_T("Can't open clipboard."));
550 if ( !wxTheClipboard
->AddData(new wxTextDataObject(m_strText
)) )
552 wxLogError(_T("Can't copy data to the clipboard"));
556 wxLogMessage(_T("Text '%s' put on the clipboard"), m_strText
.c_str());
559 wxTheClipboard
->Close();
562 void DnDFrame::OnPaste(wxCommandEvent
& WXUNUSED(event
))
564 if ( !wxTheClipboard
->Open() )
566 wxLogError(_T("Can't open clipboard."));
571 if ( !wxTheClipboard
->IsSupported(wxDF_TEXT
) )
573 wxLogWarning(_T("No text data on clipboard"));
575 wxTheClipboard
->Close();
579 wxTextDataObject text
;
580 if ( !wxTheClipboard
->GetData(&text
) )
582 wxLogError(_T("Can't paste data from the clipboard"));
586 wxLogMessage(_T("Text '%s' pasted from the clipboard"),
587 text
.GetText().c_str());
590 wxTheClipboard
->Close();
593 // ----------------------------------------------------------------------------
594 // Notifications called by the base class
595 // ----------------------------------------------------------------------------
597 bool DnDText::OnDropText( wxDropPointCoord
, wxDropPointCoord
, const wxChar
*psz
)
599 m_pOwner
->Append(psz
);
604 bool DnDFile::OnDropFiles( wxDropPointCoord
, wxDropPointCoord
, size_t nFiles
,
605 const wxChar
* const aszFiles
[])
608 str
.Printf( _T("%d files dropped"), nFiles
);
609 m_pOwner
->Append(str
);
610 for ( size_t n
= 0; n
< nFiles
; n
++ ) {
611 m_pOwner
->Append(aszFiles
[n
]);