]>
git.saurik.com Git - wxWidgets.git/blob - samples/dnd/dnd.cpp
046f9431995d0aaa490e4267d8e1aad4755b2bf8
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Drag and drop sample
4 // Author: Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
26 #include "wx/dirdlg.h"
29 #error Sorry, drag and drop is not yet implemented on wxMotif.
32 #if defined(__WXGTK__) || defined(__WXMOTIF__)
33 #include "mondrian.xpm"
36 #include "wx/clipbrd.h"
38 // ----------------------------------------------------------------------------
39 // Derive two simple classes which just put in the listbox the strings (text or
40 // file names) we drop on them
41 // ----------------------------------------------------------------------------
43 typedef long wxDropPointCoord
;
45 class DnDText
: public wxTextDropTarget
48 DnDText(wxListBox
*pOwner
) { m_pOwner
= pOwner
; }
50 virtual bool OnDropText(wxDropPointCoord x
, wxDropPointCoord y
,
57 class DnDFile
: public wxFileDropTarget
60 DnDFile(wxListBox
*pOwner
) { m_pOwner
= pOwner
; }
62 virtual bool OnDropFiles(wxDropPointCoord x
, wxDropPointCoord y
,
63 size_t nFiles
, const wxChar
* const aszFiles
[] );
69 // ----------------------------------------------------------------------------
70 // Define a new application type
71 // ----------------------------------------------------------------------------
73 class DnDApp
: public wxApp
79 IMPLEMENT_APP(DnDApp
);
81 // ----------------------------------------------------------------------------
82 // Define a new frame type
83 // ----------------------------------------------------------------------------
84 class DnDFrame
: public wxFrame
87 DnDFrame(wxFrame
*frame
, char *title
, int x
, int y
, int w
, int h
);
90 void OnPaint(wxPaintEvent
& event
);
91 void OnQuit (wxCommandEvent
& event
);
92 void OnAbout(wxCommandEvent
& event
);
93 void OnDrag (wxCommandEvent
& event
);
94 void OnHelp (wxCommandEvent
& event
);
95 void OnLogClear(wxCommandEvent
& event
);
96 void OnCopy(wxCommandEvent
& event
);
97 void OnPaste(wxCommandEvent
& event
);
99 void OnLeftDown(wxMouseEvent
& event
);
100 void OnRightDown(wxMouseEvent
& event
);
102 DECLARE_EVENT_TABLE()
105 wxListBox
*m_ctrlFile
,
107 wxTextCtrl
*m_ctrlLog
;
109 wxLog
*m_pLog
, *m_pLogPrev
;
114 // ----------------------------------------------------------------------------
115 // IDs for the menu commands
116 // ----------------------------------------------------------------------------
129 BEGIN_EVENT_TABLE(DnDFrame
, wxFrame
)
130 EVT_MENU(Menu_Quit
, DnDFrame::OnQuit
)
131 EVT_MENU(Menu_About
, DnDFrame::OnAbout
)
132 EVT_MENU(Menu_Drag
, DnDFrame::OnDrag
)
133 EVT_MENU(Menu_Help
, DnDFrame::OnHelp
)
134 EVT_MENU(Menu_Clear
, DnDFrame::OnLogClear
)
135 EVT_MENU(Menu_Copy
, DnDFrame::OnCopy
)
136 EVT_MENU(Menu_Paste
, DnDFrame::OnPaste
)
138 EVT_LEFT_DOWN( DnDFrame::OnLeftDown
)
139 EVT_RIGHT_DOWN( DnDFrame::OnRightDown
)
140 EVT_PAINT( DnDFrame::OnPaint
)
143 // `Main program' equivalent, creating windows and returning main app frame
144 bool DnDApp::OnInit()
146 // create the main frame window
147 DnDFrame
*frame
= new DnDFrame((wxFrame
*) NULL
,
148 "Drag-and-Drop/Clipboard wxWindows Sample",
159 DnDFrame::DnDFrame(wxFrame
*frame
, char *title
, int x
, int y
, int w
, int h
)
160 : wxFrame(frame
, -1, title
, wxPoint(x
, y
), wxSize(w
, h
)),
161 m_strText("wxWindows drag & drop works :-)")
164 // frame icon and status bar
165 SetIcon(wxICON(mondrian
));
170 wxMenu
*file_menu
= new wxMenu
;
171 file_menu
->Append(Menu_Drag
, "&Test drag...");
172 file_menu
->AppendSeparator();
173 file_menu
->Append(Menu_Quit
, "E&xit");
175 wxMenu
*log_menu
= new wxMenu
;
176 log_menu
->Append(Menu_Clear
, "Clear");
178 wxMenu
*help_menu
= new wxMenu
;
179 help_menu
->Append(Menu_Help
, "&Help...");
180 help_menu
->AppendSeparator();
181 help_menu
->Append(Menu_About
, "&About");
183 wxMenu
*clip_menu
= new wxMenu
;
184 clip_menu
->Append(Menu_Copy
, "&Copy\tCtrl+C");
185 clip_menu
->Append(Menu_Paste
, "&Paste\tCtrl+V");
187 wxMenuBar
*menu_bar
= new wxMenuBar
;
188 menu_bar
->Append(file_menu
, "&File");
189 menu_bar
->Append(log_menu
, "&Log");
190 menu_bar
->Append(clip_menu
, "&Clipboard");
191 menu_bar
->Append(help_menu
, "&Help");
193 SetMenuBar(menu_bar
);
195 // make a panel with 3 subwindows
197 wxSize
size(400, 200);
199 wxString
strFile("Drop files here!"), strText("Drop text on me");
201 m_ctrlFile
= new wxListBox(this, -1, pos
, size
, 1, &strFile
, wxLB_HSCROLL
);
202 m_ctrlText
= new wxListBox(this, -1, pos
, size
, 1, &strText
, wxLB_HSCROLL
);
204 m_ctrlLog
= new wxTextCtrl(this, -1, "", pos
, size
,
205 wxTE_MULTILINE
| wxTE_READONLY
|
208 #if wxUSE_STD_IOSTREAM
209 // redirect log messages to the text window (don't forget to delete it!)
210 m_pLog
= new wxLogTextCtrl(m_ctrlLog
);
211 m_pLogPrev
= wxLog::SetActiveTarget(m_pLog
);
214 // associate drop targets with 2 text controls
215 m_ctrlFile
->SetDropTarget(new DnDFile(m_ctrlFile
));
216 m_ctrlText
->SetDropTarget(new DnDText(m_ctrlText
));
218 wxLayoutConstraints
*c
;
221 c
= new wxLayoutConstraints
;
222 c
->left
.SameAs(this, wxLeft
);
223 c
->top
.SameAs(this, wxTop
);
224 c
->right
.PercentOf(this, wxRight
, 50);
225 c
->height
.PercentOf(this, wxHeight
, 40);
226 m_ctrlFile
->SetConstraints(c
);
229 c
= new wxLayoutConstraints
;
230 c
->left
.SameAs (m_ctrlFile
, wxRight
);
231 c
->top
.SameAs (this, wxTop
);
232 c
->right
.SameAs (this, wxRight
);
233 c
->height
.PercentOf(this, wxHeight
, 40);
234 m_ctrlText
->SetConstraints(c
);
236 // Lower text control
237 c
= new wxLayoutConstraints
;
238 c
->left
.SameAs (this, wxLeft
);
239 c
->right
.SameAs (this, wxRight
);
240 c
->height
.PercentOf(this, wxHeight
, 40);
241 c
->top
.SameAs(m_ctrlText
, wxBottom
);
242 m_ctrlLog
->SetConstraints(c
);
247 void DnDFrame::OnQuit(wxCommandEvent
& /* event */)
252 void DnDFrame::OnPaint(wxPaintEvent
& /*event*/)
256 GetClientSize( &w
, &h
);
259 dc
.SetFont( wxFont( 24, wxDECORATIVE
, wxNORMAL
, wxNORMAL
, FALSE
, "charter" ) );
260 dc
.DrawText( "Drag text from here!", 20, h
-35 );
263 void DnDFrame::OnDrag(wxCommandEvent
& /* event */)
265 wxString strText
= wxGetTextFromUser
267 "After you enter text in this dialog, press any mouse\n"
268 "button in the bottom (empty) part of the frame and \n"
269 "drag it anywhere - you will be in fact dragging the\n"
270 "text object containing this text",
271 "Please enter some text", m_strText
, this
277 void DnDFrame::OnAbout(wxCommandEvent
& /* event */)
279 wxMessageBox("Drag-&-Drop Demo\n"
280 "Please see \"Help|Help...\" for details\n"
281 "Copyright (c) 1998 Vadim Zeitlin",
283 wxICON_INFORMATION
| wxOK
,
287 void DnDFrame::OnHelp(wxCommandEvent
& /* event */)
289 wxMessageDialog
dialog(this,
290 "This small program demonstrates drag & drop support in wxWindows. The program window\n"
291 "consists of 3 parts: the bottom pane is for debug messages, so that you can see what's\n"
292 "going on inside. The top part is split into 2 listboxes, the left one accepts files\n"
293 "and the right one accepts text.\n"
295 "To test wxDropTarget: open wordpad (write.exe), select some text in it and drag it to\n"
296 "the right listbox (you'll notice the usual visual feedback, i.e. the cursor will change).\n"
297 "Also, try dragging some files (you can select several at once) from Windows Explorer (or \n"
298 "File Manager) to the left pane. Hold down Ctrl/Shift keys when you drop text (doesn't \n"
299 "work with files) and see what changes.\n"
301 "To test wxDropSource: just press any mouse button on the empty zone of the window and drag\n"
302 "it to wordpad or any other droptarget accepting text (and of course you can just drag it\n"
303 "to the right pane). Due to a lot of trace messages, the cursor might take some time to \n"
304 "change, don't release the mouse button until it does. You can change the string being\n"
305 "dragged in in \"File|Test drag...\" dialog.\n"
308 "Please send all questions/bug reports/suggestions &c to \n"
309 "Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>",
315 void DnDFrame::OnLogClear(wxCommandEvent
& /* event */ )
320 void DnDFrame::OnLeftDown(wxMouseEvent
&WXUNUSED(event
) )
322 if ( !m_strText
.IsEmpty() )
324 // start drag operation
326 wxTextDataObject
textData(m_strText
);
327 wxDropSource
dragSource( textData
, this );
329 wxDropSource
dragSource( new wxTextDataObject (m_strText
), this, wxIcon(mondrian_xpm
) );
333 switch ( dragSource
.DoDragDrop(TRUE
) )
335 case wxDragError
: pc
= "Error!"; break;
336 case wxDragNone
: pc
= "Nothing"; break;
337 case wxDragCopy
: pc
= "Copied"; break;
338 case wxDragMove
: pc
= "Moved"; break;
339 case wxDragCancel
: pc
= "Cancelled"; break;
340 default: pc
= "Huh?"; break;
343 SetStatusText(wxString("Drag result: ") + pc
);
347 void DnDFrame::OnRightDown(wxMouseEvent
&event
)
349 wxMenu
*menu
= new wxMenu
;
351 menu
->Append(Menu_Drag
, "&Test drag...");
352 menu
->Append(Menu_About
, "&About");
353 menu
->Append(Menu_Quit
, "E&xit");
355 PopupMenu( menu
, event
.GetX(), event
.GetY() );
358 DnDFrame::~DnDFrame()
360 #if wxUSE_STD_IOSTREAM
361 if ( m_pLog
!= NULL
) {
362 if ( wxLog::SetActiveTarget(m_pLogPrev
) == m_pLog
)
368 // ---------------------------------------------------------------------------
370 // ---------------------------------------------------------------------------
372 void DnDFrame::OnCopy(wxCommandEvent
& WXUNUSED(event
))
374 if ( !wxTheClipboard
->Open() )
376 wxLogError(_T("Can't open clipboard."));
381 if ( !wxTheClipboard
->AddData(new wxTextDataObject(m_strText
)) )
383 wxLogError(_T("Can't copy data to the clipboard"));
387 wxLogMessage(_T("Text '%s' put on the clipboard"), m_strText
.c_str());
390 wxTheClipboard
->Close();
393 void DnDFrame::OnPaste(wxCommandEvent
& WXUNUSED(event
))
395 if ( !wxTheClipboard
->Open() )
397 wxLogError(_T("Can't open clipboard."));
402 if ( !wxTheClipboard
->IsSupported(wxDF_TEXT
) )
404 wxLogWarning(_T("No text data on clipboard"));
409 wxTextDataObject text
;
410 if ( !wxTheClipboard
->GetData(&text
) )
412 wxLogError(_T("Can't paste data from the clipboard"));
416 wxLogMessage(_T("Text '%s' pasted from the clipboard"),
417 text
.GetText().c_str());
420 wxTheClipboard
->Close();
423 // ----------------------------------------------------------------------------
424 // Notifications called by the base class
425 // ----------------------------------------------------------------------------
426 bool DnDText::OnDropText( wxDropPointCoord
, wxDropPointCoord
, const wxChar
*psz
)
428 m_pOwner
->Append(psz
);
433 bool DnDFile::OnDropFiles( wxDropPointCoord
, wxDropPointCoord
, size_t nFiles
,
434 const wxChar
* const aszFiles
[])
437 str
.Printf( _T("%d files dropped"), nFiles
);
438 m_pOwner
->Append(str
);
439 for ( size_t n
= 0; n
< nFiles
; n
++ ) {
440 m_pOwner
->Append(aszFiles
[n
]);