]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/osx/cocoa/dnd.mm
Fit modeless preferences dialog to its contents too.
[wxWidgets.git] / src / osx / cocoa / dnd.mm
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/osx/cocoa/dnd.mm
3// Purpose: wxDropTarget, wxDropSource implementations
4// Author: Stefan Csomor
5// Modified by:
6// Created: 1998-01-01
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Stefan Csomor
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#ifndef WX_PRECOMP
15#include "wx/object.h"
16#endif
17
18#if wxUSE_DRAG_AND_DROP
19
20#include "wx/dnd.h"
21
22#ifndef WX_PRECOMP
23 #include "wx/app.h"
24 #include "wx/toplevel.h"
25 #include "wx/gdicmn.h"
26 #include "wx/wx.h"
27#endif // WX_PRECOMP
28
29#include "wx/evtloop.h"
30
31#include "wx/osx/private.h"
32
33wxDropSource* gCurrentSource = NULL;
34
35wxDragResult NSDragOperationToWxDragResult(NSDragOperation code)
36{
37 switch (code)
38 {
39 case NSDragOperationGeneric:
40 return wxDragCopy;
41 case NSDragOperationCopy:
42 return wxDragCopy;
43 case NSDragOperationMove:
44 return wxDragMove;
45 case NSDragOperationLink:
46 return wxDragLink;
47 case NSDragOperationNone:
48 return wxDragNone;
49 default:
50 wxFAIL_MSG("Unexpected result code");
51 }
52 return wxDragNone;
53}
54
55@interface DropSourceDelegate : NSObject
56{
57 BOOL dragFinished;
58 int resultCode;
59 wxDropSource* impl;
60}
61
62- (void)setImplementation: (wxDropSource *)dropSource;
63- (BOOL)finished;
64- (NSDragOperation)code;
65- (void)draggedImage:(NSImage *)anImage movedTo:(NSPoint)aPoint;
66- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation;
67@end
68
69@implementation DropSourceDelegate
70
71- (id)init
72{
73 self = [super init];
74 dragFinished = NO;
75 resultCode = NSDragOperationNone;
76 impl = 0;
77 return self;
78}
79
80- (void)setImplementation: (wxDropSource *)dropSource
81{
82 impl = dropSource;
83}
84
85- (BOOL)finished
86{
87 return dragFinished;
88}
89
90- (NSDragOperation)code
91{
92 return resultCode;
93}
94
95- (void)draggedImage:(NSImage *)anImage movedTo:(NSPoint)aPoint
96{
97 wxUnusedVar( anImage );
98 wxUnusedVar( aPoint );
99
100 bool optionDown = GetCurrentKeyModifiers() & optionKey;
101 wxDragResult result = optionDown ? wxDragCopy : wxDragMove;
102
103 if (wxDropSource* source = impl)
104 {
105 if (!source->GiveFeedback(result))
106 {
107 wxStockCursor cursorID = wxCURSOR_NONE;
108
109 switch (result)
110 {
111 case wxDragCopy:
112 cursorID = wxCURSOR_COPY_ARROW;
113 break;
114
115 case wxDragMove:
116 cursorID = wxCURSOR_ARROW;
117 break;
118
119 case wxDragNone:
120 cursorID = wxCURSOR_NO_ENTRY;
121 break;
122
123 case wxDragError:
124 case wxDragLink:
125 case wxDragCancel:
126 default:
127 // put these here to make gcc happy
128 ;
129 }
130
131 if (cursorID != wxCURSOR_NONE)
132 {
133 // TODO under 10.6 the os itself deals with the cursor, remove if things
134 // work properly everywhere
135#if 0
136 wxCursor cursor( cursorID );
137 cursor.MacInstall();
138#endif
139 }
140 }
141 }
142}
143
144- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
145{
146 wxUnusedVar( anImage );
147 wxUnusedVar( aPoint );
148
149 resultCode = operation;
150 dragFinished = YES;
151}
152
153@end
154
155wxDropTarget::wxDropTarget( wxDataObject *data )
156 : wxDropTargetBase( data )
157{
158
159}
160
161//-------------------------------------------------------------------------
162// wxDropSource
163//-------------------------------------------------------------------------
164
165wxDropSource::wxDropSource(wxWindow *win,
166 const wxCursor &cursorCopy,
167 const wxCursor &cursorMove,
168 const wxCursor &cursorStop)
169 : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
170{
171 m_window = win;
172}
173
174wxDropSource::wxDropSource(wxDataObject& data,
175 wxWindow *win,
176 const wxCursor &cursorCopy,
177 const wxCursor &cursorMove,
178 const wxCursor &cursorStop)
179 : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
180{
181 SetData( data );
182 m_window = win;
183}
184
185wxDropSource* wxDropSource::GetCurrentDropSource()
186{
187 return gCurrentSource;
188}
189
190wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags))
191{
192 wxASSERT_MSG( m_data, wxT("Drop source: no data") );
193
194 wxDragResult result = wxDragNone;
195 if ((m_data == NULL) || (m_data->GetFormatCount() == 0))
196 return result;
197
198 NSView* view = m_window->GetPeer()->GetWXWidget();
199 if (view)
200 {
201 NSPasteboard *pboard;
202
203 pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
204
205 OSStatus err = noErr;
206 PasteboardRef pboardRef;
207 PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
208
209 err = PasteboardClear( pboardRef );
210 if ( err != noErr )
211 {
212 CFRelease( pboardRef );
213 return wxDragNone;
214 }
215 PasteboardSynchronize( pboardRef );
216
217 m_data->AddToPasteboard( pboardRef, 1 );
218
219 NSEvent* theEvent = (NSEvent*)wxTheApp->MacGetCurrentEvent();
220 wxASSERT_MSG(theEvent, "DoDragDrop must be called in response to a mouse down or drag event.");
221
222 NSPoint down = [theEvent locationInWindow];
223 NSPoint p = [view convertPoint:down fromView:nil];
224
225 gCurrentSource = this;
226
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];
232
233 [image lockFocus];
234
235 [[[NSColor whiteColor] colorWithAlphaComponent:0.8] set];
236 NSRectFill(fillRect);
237 [[NSColor blackColor] set];
238 NSFrameRectWithWidthUsingOperation(fillRect,1.0f,NSCompositeDestinationOver);
239
240 [image unlockFocus];
241
242
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];
247
248 wxEventLoopBase * const loop = wxEventLoop::GetActive();
249 while ( ![delegate finished] )
250 loop->Dispatch();
251
252 result = NSDragOperationToWxDragResult([delegate code]);
253 [delegate release];
254 [image release];
255
256 wxWindow* mouseUpTarget = wxWindow::GetCapture();
257
258 if ( mouseUpTarget == NULL )
259 {
260 mouseUpTarget = m_window;
261 }
262
263 if ( mouseUpTarget != NULL )
264 {
265 wxMouseEvent wxevent(wxEVT_LEFT_DOWN);
266 ((wxWidgetCocoaImpl*)mouseUpTarget->GetPeer())->SetupMouseEvent(wxevent , theEvent) ;
267 wxevent.SetEventType(wxEVT_LEFT_UP);
268
269 mouseUpTarget->HandleWindowEvent(wxevent);
270 }
271
272 gCurrentSource = NULL;
273 }
274
275
276 return result;
277}
278
279#endif // wxUSE_DRAG_AND_DROP
280