]>
git.saurik.com Git - wxWidgets.git/blob - samples/dnd/dnd.cpp
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 is on the clipboard") );
302 wxLogMessage( _T("There is text is 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 is on the clipboard") );
323 wxLogMessage( _T("A bitmap is 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 wxFileDialog
dialog(this, "Open a PNG file", "", "", "PNG files (*.png)|*.png", 0);
440 if (dialog
.ShowModal() != wxID_OK
)
442 wxLogMessage( _T("Aborted file open") );
446 if (dialog
.GetPath().IsEmpty())
448 wxLogMessage( _T("Returned empty string.") );
452 if (!wxFileExists(dialog
.GetPath()))
454 wxLogMessage( _T("File doesn't exist.") );
459 image
.LoadFile( dialog
.GetPath(), wxBITMAP_TYPE_PNG
);
462 wxLogMessage( _T("Invalid image file...") );
466 wxLogMessage( _T("Decoding image file...") );
469 wxBitmap
bitmap( image
.ConvertToBitmap() );
471 if ( !wxTheClipboard
->Open() )
473 wxLogError(_T("Can't open clipboard."));
478 wxLogMessage( _T("Creating wxBitmapDataObject...") );
481 if ( !wxTheClipboard
->AddData(new wxBitmapDataObject(bitmap
)) )
483 wxLogError(_T("Can't copy image to the clipboard."));
487 wxLogMessage(_T("Image has been put on the clipboard.") );
488 wxLogMessage(_T("You can paste it now and look at it.") );
491 wxTheClipboard
->Close();
494 void DnDFrame::OnPasteBitmap(wxCommandEvent
& WXUNUSED(event
))
496 if ( !wxTheClipboard
->Open() )
498 wxLogError(_T("Can't open clipboard."));
503 if ( !wxTheClipboard
->IsSupported(wxDF_BITMAP
) )
505 wxLogWarning(_T("No bitmap on clipboard"));
507 wxTheClipboard
->Close();
511 wxBitmapDataObject data
;
512 if ( !wxTheClipboard
->GetData(&data
) )
514 wxLogError(_T("Can't paste bitmap from the clipboard"));
518 wxLogMessage(_T("Bitmap pasted from the clipboard") );
519 m_bitmap
= data
.GetBitmap();
523 wxTheClipboard
->Close();
526 // ---------------------------------------------------------------------------
528 // ---------------------------------------------------------------------------
530 void DnDFrame::OnCopy(wxCommandEvent
& WXUNUSED(event
))
532 if ( !wxTheClipboard
->Open() )
534 wxLogError(_T("Can't open clipboard."));
539 if ( !wxTheClipboard
->AddData(new wxTextDataObject(m_strText
)) )
541 wxLogError(_T("Can't copy data to the clipboard"));
545 wxLogMessage(_T("Text '%s' put on the clipboard"), m_strText
.c_str());
548 wxTheClipboard
->Close();
551 void DnDFrame::OnPaste(wxCommandEvent
& WXUNUSED(event
))
553 if ( !wxTheClipboard
->Open() )
555 wxLogError(_T("Can't open clipboard."));
560 if ( !wxTheClipboard
->IsSupported(wxDF_TEXT
) )
562 wxLogWarning(_T("No text data on clipboard"));
564 wxTheClipboard
->Close();
568 wxTextDataObject text
;
569 if ( !wxTheClipboard
->GetData(&text
) )
571 wxLogError(_T("Can't paste data from the clipboard"));
575 wxLogMessage(_T("Text '%s' pasted from the clipboard"),
576 text
.GetText().c_str());
579 wxTheClipboard
->Close();
582 // ----------------------------------------------------------------------------
583 // Notifications called by the base class
584 // ----------------------------------------------------------------------------
586 bool DnDText::OnDropText( wxDropPointCoord
, wxDropPointCoord
, const wxChar
*psz
)
588 m_pOwner
->Append(psz
);
593 bool DnDFile::OnDropFiles( wxDropPointCoord
, wxDropPointCoord
, size_t nFiles
,
594 const wxChar
* const aszFiles
[])
597 str
.Printf( _T("%d files dropped"), nFiles
);
598 m_pOwner
->Append(str
);
599 for ( size_t n
= 0; n
< nFiles
; n
++ ) {
600 m_pOwner
->Append(aszFiles
[n
]);