1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/dnd.mm
3 // Purpose: wxDropTarget, wxDropSource implementations
4 // Author: Stefan Csomor
8 // Copyright: (c) 1998 Stefan Csomor
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
15 #include "wx/object.h"
18 #if wxUSE_DRAG_AND_DROP
24 #include "wx/toplevel.h"
25 #include "wx/gdicmn.h"
29 #include "wx/evtloop.h"
31 #include "wx/osx/private.h"
33 wxDropSource* gCurrentSource = NULL;
35 wxDragResult NSDragOperationToWxDragResult(NSDragOperation code)
39 case NSDragOperationGeneric:
41 case NSDragOperationCopy:
43 case NSDragOperationMove:
45 case NSDragOperationLink:
47 case NSDragOperationNone:
50 wxFAIL_MSG("Unexpected result code");
55 @interface DropSourceDelegate : NSObject
62 - (void)setImplementation: (wxDropSource *)dropSource;
64 - (NSDragOperation)code;
65 - (void)draggedImage:(NSImage *)anImage movedTo:(NSPoint)aPoint;
66 - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation;
69 @implementation DropSourceDelegate
75 resultCode = NSDragOperationNone;
80 - (void)setImplementation: (wxDropSource *)dropSource
90 - (NSDragOperation)code
95 - (void)draggedImage:(NSImage *)anImage movedTo:(NSPoint)aPoint
97 wxUnusedVar( anImage );
98 wxUnusedVar( aPoint );
100 bool optionDown = GetCurrentKeyModifiers() & optionKey;
101 wxDragResult result = optionDown ? wxDragCopy : wxDragMove;
103 if (wxDropSource* source = impl)
105 if (!source->GiveFeedback(result))
107 wxStockCursor cursorID = wxCURSOR_NONE;
112 cursorID = wxCURSOR_COPY_ARROW;
116 cursorID = wxCURSOR_ARROW;
120 cursorID = wxCURSOR_NO_ENTRY;
127 // put these here to make gcc happy
131 if (cursorID != wxCURSOR_NONE)
133 // TODO under 10.6 the os itself deals with the cursor, remove if things
134 // work properly everywhere
136 wxCursor cursor( cursorID );
144 - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
146 wxUnusedVar( anImage );
147 wxUnusedVar( aPoint );
149 resultCode = operation;
155 wxDropTarget::wxDropTarget( wxDataObject *data )
156 : wxDropTargetBase( data )
161 //-------------------------------------------------------------------------
163 //-------------------------------------------------------------------------
165 wxDropSource::wxDropSource(wxWindow *win,
166 const wxCursor &cursorCopy,
167 const wxCursor &cursorMove,
168 const wxCursor &cursorStop)
169 : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
174 wxDropSource::wxDropSource(wxDataObject& data,
176 const wxCursor &cursorCopy,
177 const wxCursor &cursorMove,
178 const wxCursor &cursorStop)
179 : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
185 wxDropSource* wxDropSource::GetCurrentDropSource()
187 return gCurrentSource;
190 wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags))
192 wxASSERT_MSG( m_data, wxT("Drop source: no data") );
194 wxDragResult result = wxDragNone;
195 if ((m_data == NULL) || (m_data->GetFormatCount() == 0))
198 NSView* view = m_window->GetPeer()->GetWXWidget();
201 NSPasteboard *pboard;
203 pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
205 OSStatus err = noErr;
206 PasteboardRef pboardRef;
207 PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
209 err = PasteboardClear( pboardRef );
212 CFRelease( pboardRef );
215 PasteboardSynchronize( pboardRef );
217 m_data->AddToPasteboard( pboardRef, 1 );
219 NSEvent* theEvent = (NSEvent*)wxTheApp->MacGetCurrentEvent();
220 wxASSERT_MSG(theEvent, "DoDragDrop must be called in response to a mouse down or drag event.");
222 NSPoint down = [theEvent locationInWindow];
223 NSPoint p = [view convertPoint:down fromView:nil];
225 gCurrentSource = this;
227 // add a dummy square as dragged image for the moment,
228 // TODO: proper drag image for data
229 NSSize sz = NSMakeSize(16,16);
230 NSRect fillRect = NSMakeRect(0, 0, 16, 16);
231 NSImage* image = [[NSImage alloc] initWithSize: sz];
235 [[[NSColor whiteColor] colorWithAlphaComponent:0.8] set];
236 NSRectFill(fillRect);
237 [[NSColor blackColor] set];
238 NSFrameRectWithWidthUsingOperation(fillRect,1.0f,NSCompositeDestinationOver);
243 DropSourceDelegate* delegate = [[DropSourceDelegate alloc] init];
244 [delegate setImplementation: this];
245 [view dragImage:image at:p offset:NSMakeSize(0.0,0.0)
246 event: theEvent pasteboard: pboard source:delegate slideBack: NO];
248 wxEventLoopBase * const loop = wxEventLoop::GetActive();
249 while ( ![delegate finished] )
252 result = NSDragOperationToWxDragResult([delegate code]);
256 wxWindow* mouseUpTarget = wxWindow::GetCapture();
258 if ( mouseUpTarget == NULL )
260 mouseUpTarget = m_window;
263 if ( mouseUpTarget != NULL )
265 wxMouseEvent wxevent(wxEVT_LEFT_DOWN);
266 ((wxWidgetCocoaImpl*)mouseUpTarget->GetPeer())->SetupMouseEvent(wxevent , theEvent) ;
267 wxevent.SetEventType(wxEVT_LEFT_UP);
269 mouseUpTarget->HandleWindowEvent(wxevent);
272 gCurrentSource = NULL;
279 #endif // wxUSE_DRAG_AND_DROP