1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/dnd.mm
3 // Purpose: wxDropTarget, wxDropSource implementations
4 // Author: Stefan Csomor
7 // Copyright: (c) 1998 Stefan Csomor
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 #include "wx/wxprec.h"
14 #include "wx/object.h"
17 #if wxUSE_DRAG_AND_DROP
23 #include "wx/toplevel.h"
24 #include "wx/gdicmn.h"
28 #include "wx/evtloop.h"
30 #include "wx/osx/private.h"
32 wxDropSource* gCurrentSource = NULL;
34 wxDragResult NSDragOperationToWxDragResult(NSDragOperation code)
38 case NSDragOperationGeneric:
40 case NSDragOperationCopy:
42 case NSDragOperationMove:
44 case NSDragOperationLink:
46 case NSDragOperationNone:
49 wxFAIL_MSG("Unexpected result code");
54 @interface DropSourceDelegate : NSObject
61 - (void)setImplementation: (wxDropSource *)dropSource;
63 - (NSDragOperation)code;
64 - (void)draggedImage:(NSImage *)anImage movedTo:(NSPoint)aPoint;
65 - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation;
68 @implementation DropSourceDelegate
74 resultCode = NSDragOperationNone;
79 - (void)setImplementation: (wxDropSource *)dropSource
89 - (NSDragOperation)code
94 - (void)draggedImage:(NSImage *)anImage movedTo:(NSPoint)aPoint
96 wxUnusedVar( anImage );
97 wxUnusedVar( aPoint );
99 bool optionDown = GetCurrentKeyModifiers() & optionKey;
100 wxDragResult result = optionDown ? wxDragCopy : wxDragMove;
102 if (wxDropSource* source = impl)
104 if (!source->GiveFeedback(result))
106 wxStockCursor cursorID = wxCURSOR_NONE;
111 cursorID = wxCURSOR_COPY_ARROW;
115 cursorID = wxCURSOR_ARROW;
119 cursorID = wxCURSOR_NO_ENTRY;
126 // put these here to make gcc happy
130 if (cursorID != wxCURSOR_NONE)
132 // TODO under 10.6 the os itself deals with the cursor, remove if things
133 // work properly everywhere
135 wxCursor cursor( cursorID );
143 - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
145 wxUnusedVar( anImage );
146 wxUnusedVar( aPoint );
148 resultCode = operation;
154 wxDropTarget::wxDropTarget( wxDataObject *data )
155 : wxDropTargetBase( data )
160 //-------------------------------------------------------------------------
162 //-------------------------------------------------------------------------
164 wxDropSource::wxDropSource(wxWindow *win,
165 const wxCursor &cursorCopy,
166 const wxCursor &cursorMove,
167 const wxCursor &cursorStop)
168 : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
173 wxDropSource::wxDropSource(wxDataObject& data,
175 const wxCursor &cursorCopy,
176 const wxCursor &cursorMove,
177 const wxCursor &cursorStop)
178 : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
184 wxDropSource* wxDropSource::GetCurrentDropSource()
186 return gCurrentSource;
189 wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags))
191 wxASSERT_MSG( m_data, wxT("Drop source: no data") );
193 wxDragResult result = wxDragNone;
194 if ((m_data == NULL) || (m_data->GetFormatCount() == 0))
197 NSView* view = m_window->GetPeer()->GetWXWidget();
200 NSPasteboard *pboard;
202 pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
204 OSStatus err = noErr;
205 PasteboardRef pboardRef;
206 PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
208 err = PasteboardClear( pboardRef );
211 CFRelease( pboardRef );
214 PasteboardSynchronize( pboardRef );
216 m_data->AddToPasteboard( pboardRef, 1 );
218 NSEvent* theEvent = (NSEvent*)wxTheApp->MacGetCurrentEvent();
219 wxASSERT_MSG(theEvent, "DoDragDrop must be called in response to a mouse down or drag event.");
221 NSPoint down = [theEvent locationInWindow];
222 NSPoint p = [view convertPoint:down fromView:nil];
224 gCurrentSource = this;
226 // add a dummy square as dragged image for the moment,
227 // TODO: proper drag image for data
228 NSSize sz = NSMakeSize(16,16);
229 NSRect fillRect = NSMakeRect(0, 0, 16, 16);
230 NSImage* image = [[NSImage alloc] initWithSize: sz];
234 [[[NSColor whiteColor] colorWithAlphaComponent:0.8] set];
235 NSRectFill(fillRect);
236 [[NSColor blackColor] set];
237 NSFrameRectWithWidthUsingOperation(fillRect,1.0f,NSCompositeDestinationOver);
242 DropSourceDelegate* delegate = [[DropSourceDelegate alloc] init];
243 [delegate setImplementation: this];
244 [view dragImage:image at:p offset:NSMakeSize(0.0,0.0)
245 event: theEvent pasteboard: pboard source:delegate slideBack: NO];
247 wxEventLoopBase * const loop = wxEventLoop::GetActive();
248 while ( ![delegate finished] )
251 result = NSDragOperationToWxDragResult([delegate code]);
255 wxWindow* mouseUpTarget = wxWindow::GetCapture();
257 if ( mouseUpTarget == NULL )
259 mouseUpTarget = m_window;
262 if ( mouseUpTarget != NULL )
264 wxMouseEvent wxevent(wxEVT_LEFT_DOWN);
265 ((wxWidgetCocoaImpl*)mouseUpTarget->GetPeer())->SetupMouseEvent(wxevent , theEvent) ;
266 wxevent.SetEventType(wxEVT_LEFT_UP);
268 mouseUpTarget->HandleWindowEvent(wxevent);
271 gCurrentSource = NULL;
278 #endif // wxUSE_DRAG_AND_DROP