From: Kevin Ollivier Date: Sat, 6 Feb 2010 01:45:58 +0000 (+0000) Subject: Add an accessor to get the current drop source from window.mm so that we can implemen... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/808cbd174a5c7d0946df7dcaf1891e881a94f64f Add an accessor to get the current drop source from window.mm so that we can implement GiveFeedback support, and also move a couple functions that check the current drop source into common DND OS X code as a result. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63412 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/osx/dnd.h b/include/wx/osx/dnd.h index f4762f2b03..0bb4e9daf9 100644 --- a/include/wx/osx/dnd.h +++ b/include/wx/osx/dnd.h @@ -96,6 +96,7 @@ public: wxWindow* GetWindow() { return m_window ; } void SetCurrentDragPasteboard( void* dragpasteboard ) { m_currentDragPasteboard = dragpasteboard ; } bool MacInstallDefaultCursor(wxDragResult effect) ; + static wxDropSource* GetCurrentDropSource(); protected : wxWindow *m_window; diff --git a/src/osx/carbon/dnd.cpp b/src/osx/carbon/dnd.cpp index b46737b0aa..0ad4565b4a 100644 --- a/src/osx/carbon/dnd.cpp +++ b/src/osx/carbon/dnd.cpp @@ -162,6 +162,11 @@ wxDropSource::wxDropSource(wxWindow *win, m_window = win; } +wxDropSource* wxDropSource::GetCurrentDropSource() +{ + return gTrackingGlobals.m_currentSource; +} + wxDropSource::wxDropSource(wxDataObject& data, wxWindow *win, const wxCursor &cursorCopy, diff --git a/src/osx/cocoa/dnd.mm b/src/osx/cocoa/dnd.mm index 4429d80708..1345e62b0f 100644 --- a/src/osx/cocoa/dnd.mm +++ b/src/osx/cocoa/dnd.mm @@ -26,6 +26,8 @@ #include #include "wx/osx/private.h" +wxDropSource* gCurrentSource = NULL; + wxDragResult NSDragOperationToWxDragResult(NSDragOperation code) { switch (code) @@ -96,25 +98,6 @@ wxDropTarget::wxDropTarget( wxDataObject *data ) } -bool wxDropTarget::CurrentDragHasSupportedFormat() -{ - if (m_dataObject == NULL) - return false; - - return m_dataObject->HasDataInPasteboard( m_currentDragPasteboard ); -} - -bool wxDropTarget::GetData() -{ - if (m_dataObject == NULL) - return false; - - if ( !CurrentDragHasSupportedFormat() ) - return false; - - return m_dataObject->GetFromPasteboard( m_currentDragPasteboard ); -} - //------------------------------------------------------------------------- // wxDropSource //------------------------------------------------------------------------- @@ -139,6 +122,11 @@ wxDropSource::wxDropSource(wxDataObject& data, m_window = win; } +wxDropSource* wxDropSource::GetCurrentDropSource() +{ + return gCurrentSource; +} + wxDragResult wxDropSource::DoDragDrop(int flags) { wxASSERT_MSG( m_data, wxT("Drop source: no data") ); @@ -171,6 +159,7 @@ wxDragResult wxDropSource::DoDragDrop(int flags) NSEvent* theEvent = (NSEvent*)wxTheApp->MacGetCurrentEvent(); wxASSERT_MSG(theEvent, "DoDragDrop must be called in response to a mouse down or drag event."); + gCurrentSource = this; NSImage* image = [[NSImage alloc] initWithSize: NSMakeSize(16,16)]; DropSourceDelegate* delegate = [[DropSourceDelegate alloc] init]; [delegate setImplementation: this]; @@ -184,6 +173,7 @@ wxDragResult wxDropSource::DoDragDrop(int flags) result = NSDragOperationToWxDragResult([delegate code]); [delegate release]; [image release]; + gCurrentSource = NULL; } diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index 83a5e7f79a..6d14e6b459 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -880,6 +880,45 @@ unsigned int wxWidgetCocoaImpl::draggingUpdated(void* s, WXWidget WXUNUSED(slf), else if ( sourceDragMask & NSDragOperationMove ) result = wxDragMove; + // FIXME: This doesn't seem the right place for the code, as GiveFeedback + // will only get called when the drop target is inside the app itself + // but at least some cases will work now. + if (wxDropSource* source = wxDropSource::GetCurrentDropSource()) + { + if (!source->GiveFeedback(result)) + { + wxStockCursor cursorID = wxCURSOR_NONE; + + switch (result) + { + case wxDragCopy: + cursorID = wxCURSOR_COPY_ARROW; + break; + + case wxDragMove: + cursorID = wxCURSOR_ARROW; + break; + + case wxDragNone: + cursorID = wxCURSOR_NO_ENTRY; + break; + + case wxDragError: + case wxDragLink: + case wxDragCancel: + default: + // put these here to make gcc happy + ; + } + + if (cursorID != wxCURSOR_NONE) + { + wxCursor cursor( cursorID ); + cursor.MacInstall(); + } + } + } + PasteboardRef pboardRef; PasteboardCreate((CFStringRef)[pboard name], &pboardRef); target->SetCurrentDragPasteboard(pboardRef); diff --git a/src/osx/dnd_osx.cpp b/src/osx/dnd_osx.cpp index c19bf6eb8f..b64858930a 100644 --- a/src/osx/dnd_osx.cpp +++ b/src/osx/dnd_osx.cpp @@ -61,6 +61,95 @@ wxDragResult wxDropTarget::OnData( return GetData() ? def : wxDragNone; } +bool wxDropTarget::CurrentDragHasSupportedFormat() +{ + bool supported = false; + if (m_dataObject == NULL) + return false; + + if ( wxDropSource* currentSource = wxDropSource::GetCurrentDropSource() ) + { + wxDataObject* data = currentSource->GetDataObject(); + + if ( data ) + { + size_t formatcount = data->GetFormatCount(); + wxDataFormat *array = new wxDataFormat[formatcount]; + data->GetAllFormats( array ); + for (size_t i = 0; !supported && i < formatcount; i++) + { + wxDataFormat format = array[i]; + if ( m_dataObject->IsSupported( format ) ) + { + supported = true; + break; + } + } + + delete [] array; + } + } + + if ( !supported ) + { + supported = m_dataObject->HasDataInPasteboard( m_currentDragPasteboard ); + } + + return supported; +} + +bool wxDropTarget::GetData() +{ + if (m_dataObject == NULL) + return false; + + if ( !CurrentDragHasSupportedFormat() ) + return false; + + bool transferred = false; + if ( wxDropSource* currentSource = wxDropSource::GetCurrentDropSource() ) + { + wxDataObject* data = currentSource->GetDataObject(); + + if (data != NULL) + { + size_t formatcount = data->GetFormatCount(); + wxDataFormat *array = new wxDataFormat[formatcount]; + data->GetAllFormats( array ); + for (size_t i = 0; !transferred && i < formatcount; i++) + { + wxDataFormat format = array[i]; + if ( m_dataObject->IsSupported( format ) ) + { + int size = data->GetDataSize( format ); + transferred = true; + + if (size == 0) + { + m_dataObject->SetData( format, 0, 0 ); + } + else + { + char *d = new char[size]; + data->GetDataHere( format, (void*)d ); + m_dataObject->SetData( format, size, d ); + delete [] d; + } + } + } + + delete [] array; + } + } + + if ( !transferred ) + { + transferred = m_dataObject->GetFromPasteboard( m_currentDragPasteboard ); + } + + return transferred; +} + //------------------------------------------------------------------------- // wxDropSource //-------------------------------------------------------------------------