1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/dnd.mm
3 // Purpose: wxDropTarget, wxDropSource implementations
4 // Author: Stefan Csomor
7 // RCS-ID: $Id: dnd.cpp 61724 2009-08-21 10:41:26Z VZ $
8 // Copyright: (c) 1998 Stefan Csomor
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
14 #if wxUSE_DRAG_AND_DROP
20 #include "wx/toplevel.h"
21 #include "wx/gdicmn.h"
25 #include "wx/evtloop.h"
27 #include "wx/osx/private.h"
29 wxDropSource* gCurrentSource = NULL;
31 wxDragResult NSDragOperationToWxDragResult(NSDragOperation code)
35 case NSDragOperationCopy:
37 case NSDragOperationMove:
39 case NSDragOperationLink:
41 case NSDragOperationNone:
44 wxFAIL_MSG("Unexpected result code");
49 @interface DropSourceDelegate : NSObject
56 - (void)setImplementation: (wxDropSource *)dropSource;
58 - (NSDragOperation)code;
59 - (void)draggedImage:(NSImage *)anImage movedTo:(NSPoint)aPoint;
60 - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation;
63 @implementation DropSourceDelegate
69 resultCode = NSDragOperationNone;
74 - (void)setImplementation: (wxDropSource *)dropSource
84 - (NSDragOperation)code
89 - (void)draggedImage:(NSImage *)anImage movedTo:(NSPoint)aPoint
91 wxUnusedVar( anImage );
92 wxUnusedVar( aPoint );
94 bool optionDown = GetCurrentKeyModifiers() & optionKey;
95 wxDragResult result = optionDown ? wxDragCopy : wxDragMove;
97 if (wxDropSource* source = impl)
99 if (!source->GiveFeedback(result))
101 wxStockCursor cursorID = wxCURSOR_NONE;
106 cursorID = wxCURSOR_COPY_ARROW;
110 cursorID = wxCURSOR_ARROW;
114 cursorID = wxCURSOR_NO_ENTRY;
121 // put these here to make gcc happy
125 if (cursorID != wxCURSOR_NONE)
127 // TODO under 10.6 the os itself deals with the cursor, remove if things
128 // work properly everywhere
130 wxCursor cursor( cursorID );
138 - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
140 wxUnusedVar( anImage );
141 wxUnusedVar( aPoint );
143 resultCode = operation;
149 wxDropTarget::wxDropTarget( wxDataObject *data )
150 : wxDropTargetBase( data )
155 //-------------------------------------------------------------------------
157 //-------------------------------------------------------------------------
159 wxDropSource::wxDropSource(wxWindow *win,
160 const wxCursor &cursorCopy,
161 const wxCursor &cursorMove,
162 const wxCursor &cursorStop)
163 : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
168 wxDropSource::wxDropSource(wxDataObject& data,
170 const wxCursor &cursorCopy,
171 const wxCursor &cursorMove,
172 const wxCursor &cursorStop)
173 : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
179 wxDropSource* wxDropSource::GetCurrentDropSource()
181 return gCurrentSource;
184 wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags))
186 wxASSERT_MSG( m_data, wxT("Drop source: no data") );
188 wxDragResult result = wxDragNone;
189 if ((m_data == NULL) || (m_data->GetFormatCount() == 0))
192 NSView* view = m_window->GetPeer()->GetWXWidget();
195 NSPasteboard *pboard;
197 pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
199 OSStatus err = noErr;
200 PasteboardRef pboardRef;
201 PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
203 err = PasteboardClear( pboardRef );
206 CFRelease( pboardRef );
209 PasteboardSynchronize( pboardRef );
211 m_data->AddToPasteboard( pboardRef, 1 );
213 NSEvent* theEvent = (NSEvent*)wxTheApp->MacGetCurrentEvent();
214 wxASSERT_MSG(theEvent, "DoDragDrop must be called in response to a mouse down or drag event.");
216 NSPoint down = [theEvent locationInWindow];
217 NSPoint p = [view convertPoint:down toView:nil];
219 gCurrentSource = this;
221 // add a dummy square as dragged image for the moment,
222 // TODO: proper drag image for data
223 NSSize sz = NSMakeSize(16,16);
224 NSRect fillRect = NSMakeRect(0, 0, 16, 16);
225 NSImage* image = [[NSImage alloc] initWithSize: sz];
229 [[[NSColor whiteColor] colorWithAlphaComponent:0.8] set];
230 NSRectFill(fillRect);
231 [[NSColor blackColor] set];
232 NSFrameRectWithWidthUsingOperation(fillRect,1.0f,NSCompositeDestinationOver);
237 DropSourceDelegate* delegate = [[DropSourceDelegate alloc] init];
238 [delegate setImplementation: this];
239 [view dragImage:image at:p offset:NSMakeSize(0.0,0.0)
240 event: theEvent pasteboard: pboard source:delegate slideBack: NO];
242 wxEventLoopBase * const loop = wxEventLoop::GetActive();
243 while ( ![delegate finished] )
246 result = NSDragOperationToWxDragResult([delegate code]);
249 gCurrentSource = NULL;
256 #endif // wxUSE_DRAG_AND_DROP