]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/dnd.cpp
cleanup - reformat
[wxWidgets.git] / src / mac / carbon / dnd.cpp
CommitLineData
e9576ca5
SC
1///////////////////////////////////////////////////////////////////////////////
2// Name: dnd.cpp
6eae1f7d 3// Purpose: wxDropTarget, wxDropSource implementations
a31a5f85 4// Author: Stefan Csomor
e9576ca5 5// Modified by:
a31a5f85 6// Created: 1998-01-01
e9576ca5 7// RCS-ID: $Id$
a31a5f85 8// Copyright: (c) 1998 Stefan Csomor
65571936 9// Licence: wxWindows licence
e9576ca5
SC
10///////////////////////////////////////////////////////////////////////////////
11
3d1a4878 12#include "wx/wxprec.h"
ff143598
GD
13
14#if wxUSE_DRAG_AND_DROP
15
e9576ca5
SC
16#include "wx/dnd.h"
17#include "wx/window.h"
ff143598 18#include "wx/toplevel.h"
e9576ca5
SC
19#include "wx/app.h"
20#include "wx/gdicmn.h"
76a5e5d2 21#include "wx/mac/private.h"
e9576ca5 22
64179ebc
DS
23#ifndef __DARWIN__
24 #include <Scrap.h>
25#endif
26
e9576ca5 27// ----------------------------------------------------------------------------
6eae1f7d 28// globals
e9576ca5
SC
29// ----------------------------------------------------------------------------
30
6eae1f7d 31typedef struct
e9576ca5 32{
a07c1212
SC
33 wxWindow* m_currentTargetWindow ;
34 wxDropTarget* m_currentTarget ;
35 wxDropSource* m_currentSource ;
6eae1f7d
DS
36}
37MacTrackingGlobals ;
e9576ca5 38
6eae1f7d
DS
39MacTrackingGlobals gTrackingGlobals ;
40
41void wxMacEnsureTrackingHandlersInstalled() ;
e9576ca5 42
a07c1212
SC
43//----------------------------------------------------------------------------
44// wxDropTarget
45//----------------------------------------------------------------------------
e9576ca5 46
a07c1212
SC
47wxDropTarget::wxDropTarget( wxDataObject *data )
48 : wxDropTargetBase( data )
e9576ca5 49{
a07c1212 50 wxMacEnsureTrackingHandlersInstalled() ;
e9576ca5
SC
51}
52
a07c1212
SC
53wxDragResult wxDropTarget::OnDragOver( wxCoord WXUNUSED(x),
54 wxCoord WXUNUSED(y),
55 wxDragResult def )
e9576ca5 56{
a07c1212
SC
57 return CurrentDragHasSupportedFormat() ? def : wxDragNone;
58}
e9576ca5 59
a07c1212 60bool wxDropTarget::OnDrop( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y) )
e9576ca5 61{
a07c1212 62 if (!m_dataObject)
6eae1f7d 63 return false;
a07c1212
SC
64
65 return CurrentDragHasSupportedFormat() ;
e9576ca5
SC
66}
67
a07c1212
SC
68wxDragResult wxDropTarget::OnData( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
69 wxDragResult def )
e9576ca5 70{
a07c1212
SC
71 if (!m_dataObject)
72 return wxDragNone;
73
74 if (!CurrentDragHasSupportedFormat())
75 return wxDragNone;
76
77 return GetData() ? def : wxDragNone;
e9576ca5
SC
78}
79
6eae1f7d 80bool wxDropTarget::CurrentDragHasSupportedFormat()
e9576ca5 81{
a07c1212
SC
82 bool supported = false ;
83 if ( gTrackingGlobals.m_currentSource != NULL )
84 {
e40298d5 85 wxDataObject* data = gTrackingGlobals.m_currentSource->GetDataObject() ;
6eae1f7d 86
e40298d5 87 if ( data )
a07c1212 88 {
e40298d5
JS
89 size_t formatcount = data->GetFormatCount() ;
90 wxDataFormat *array = new wxDataFormat[ formatcount ];
91 data->GetAllFormats( array );
92 for (size_t i = 0; !supported && i < formatcount ; i++)
a07c1212 93 {
e40298d5 94 wxDataFormat format = array[i] ;
6eae1f7d 95 if ( m_dataObject->IsSupported( format ) )
e40298d5
JS
96 {
97 supported = true ;
98 break ;
99 }
a07c1212 100 }
6eae1f7d
DS
101
102 delete [] array ;
a07c1212 103 }
a07c1212 104 }
6eae1f7d 105
a07c1212
SC
106 if ( !supported )
107 {
e40298d5
JS
108 UInt16 items ;
109 OSErr result;
6eae1f7d
DS
110 ItemReference theItem;
111 FlavorType theType ;
112 UInt16 flavors = 0 ;
113
e40298d5 114 CountDragItems((DragReference)m_currentDrag, &items);
6eae1f7d 115 for (UInt16 index = 1; index <= items && !supported ; ++index)
e40298d5 116 {
6eae1f7d 117 flavors = 0 ;
e40298d5
JS
118 GetDragItemReferenceNumber((DragReference)m_currentDrag, index, &theItem);
119 CountDragItemFlavors( (DragReference)m_currentDrag, theItem , &flavors ) ;
6eae1f7d 120
e40298d5 121 for ( UInt16 flavor = 1 ; flavor <= flavors ; ++flavor )
a07c1212 122 {
e40298d5
JS
123 result = GetFlavorType((DragReference)m_currentDrag, theItem, flavor , &theType);
124 if ( m_dataObject->IsSupportedFormat( wxDataFormat( theType ) ) )
125 {
126 supported = true ;
127 break ;
128 }
a07c1212 129 }
e40298d5 130 }
a07c1212 131 }
6eae1f7d
DS
132
133 return supported ;
e9576ca5
SC
134}
135
a07c1212 136bool wxDropTarget::GetData()
e9576ca5 137{
a07c1212 138 if (!m_dataObject)
6eae1f7d
DS
139 return false;
140
a07c1212 141 if ( !CurrentDragHasSupportedFormat() )
6eae1f7d
DS
142 return false ;
143
144 bool transferred = false ;
a07c1212
SC
145 if ( gTrackingGlobals.m_currentSource != NULL )
146 {
e40298d5 147 wxDataObject* data = gTrackingGlobals.m_currentSource->GetDataObject() ;
6eae1f7d 148
e40298d5 149 if ( data )
a07c1212 150 {
e40298d5 151 size_t formatcount = data->GetFormatCount() ;
6eae1f7d 152 wxDataFormat *array = new wxDataFormat[formatcount];
e40298d5
JS
153 data->GetAllFormats( array );
154 for (size_t i = 0; !transferred && i < formatcount ; i++)
a07c1212 155 {
e40298d5 156 wxDataFormat format = array[i] ;
6eae1f7d 157 if ( m_dataObject->IsSupported( format ) )
e40298d5
JS
158 {
159 int size = data->GetDataSize( format );
160 transferred = true ;
6eae1f7d
DS
161
162 if (size == 0)
e40298d5
JS
163 {
164 m_dataObject->SetData(format , 0 , 0 ) ;
165 }
166 else
167 {
168 char *d = new char[size];
169 data->GetDataHere( format , (void*) d );
170 m_dataObject->SetData( format , size , d ) ;
6eae1f7d 171 delete [] d ;
e40298d5
JS
172 }
173 }
a07c1212 174 }
6eae1f7d
DS
175
176 delete [] array ;
e40298d5 177 }
a07c1212 178 }
6eae1f7d 179
a07c1212
SC
180 if ( !transferred )
181 {
e40298d5
JS
182 UInt16 items ;
183 OSErr result;
6eae1f7d
DS
184 ItemReference theItem;
185 FlavorType theType ;
186 FlavorFlags theFlags;
187 UInt16 flavors ;
e40298d5 188 bool firstFileAdded = false ;
6eae1f7d 189
e40298d5 190 CountDragItems((DragReference)m_currentDrag, &items);
6eae1f7d 191 for (UInt16 index = 1; index <= items; ++index)
e40298d5 192 {
6eae1f7d 193 flavors = 0 ;
e40298d5
JS
194 GetDragItemReferenceNumber((DragReference)m_currentDrag, index, &theItem);
195 CountDragItemFlavors( (DragReference)m_currentDrag, theItem , &flavors ) ;
6db6bfd1
SC
196 bool hasPreferredFormat = false ;
197 wxDataFormat preferredFormat = m_dataObject->GetPreferredFormat( wxDataObject::Set ) ;
6eae1f7d 198
e40298d5 199 for ( UInt16 flavor = 1 ; flavor <= flavors ; ++flavor )
a07c1212 200 {
e40298d5
JS
201 result = GetFlavorType((DragReference)m_currentDrag, theItem, flavor , &theType);
202 wxDataFormat format(theType) ;
6db6bfd1
SC
203 if ( preferredFormat == format )
204 {
205 hasPreferredFormat = true ;
206 break ;
207 }
208 }
6eae1f7d 209
6db6bfd1
SC
210 for ( UInt16 flavor = 1 ; flavor <= flavors ; ++flavor )
211 {
212 result = GetFlavorType((DragReference)m_currentDrag, theItem, flavor , &theType);
213 wxDataFormat format(theType) ;
6eae1f7d 214 if ( (hasPreferredFormat && format == preferredFormat) || (!hasPreferredFormat && m_dataObject->IsSupportedFormat( format )))
e40298d5 215 {
e40298d5 216 result = GetFlavorFlags((DragReference)m_currentDrag, theItem, theType, &theFlags);
6eae1f7d 217 if (result == noErr)
a07c1212 218 {
e40298d5
JS
219 Size dataSize ;
220 Ptr theData ;
6eae1f7d 221
e40298d5 222 GetFlavorDataSize((DragReference)m_currentDrag, theItem, theType, &dataSize);
2b2832ef 223 if ( theType == kScrapFlavorTypeText )
e40298d5
JS
224 {
225 // this increment is only valid for allocating, on the next GetFlavorData
226 // call it is reset again to the original value
227 dataSize++ ;
228 }
2b2832ef
SC
229 else if ( theType == kScrapFlavorTypeUnicode )
230 {
231 // this increment is only valid for allocating, on the next GetFlavorData
232 // call it is reset again to the original value
233 dataSize++ ;
234 dataSize++ ;
235 }
6eae1f7d 236
e40298d5 237 theData = new char[dataSize];
6eae1f7d
DS
238 GetFlavorData((DragReference)m_currentDrag, theItem, theType, (void*) theData, &dataSize, 0L);
239 if ( theType == kScrapFlavorTypeText )
2b2832ef 240 {
6eae1f7d 241 theData[dataSize] = 0 ;
2b2832ef
SC
242 m_dataObject->SetData( wxDataFormat(wxDF_TEXT), dataSize , theData );
243 }
244 #if wxUSE_UNICODE
245 else if ( theType == kScrapFlavorTypeUnicode )
e40298d5 246 {
6eae1f7d
DS
247 theData[dataSize] = 0 ;
248 theData[dataSize + 1] = 0 ;
2b2832ef 249 m_dataObject->SetData( wxDataFormat(wxDF_UNICODETEXT), dataSize , theData );
e40298d5 250 }
2b2832ef 251 #endif
e40298d5
JS
252 else if ( theType == kDragFlavorTypeHFS )
253 {
254 HFSFlavor* theFile = (HFSFlavor*) theData ;
255 wxString name = wxMacFSSpec2MacFilename( &theFile->fileSpec ) ;
ad05b188 256 if ( !firstFileAdded )
e40298d5 257 {
ad05b188
SC
258 // reset file list
259 ((wxFileDataObject*)m_dataObject)->SetData( 0 , "" ) ;
6eae1f7d 260 firstFileAdded = true ;
e40298d5 261 }
6eae1f7d 262
ad05b188 263 ((wxFileDataObject*)m_dataObject)->AddFile( name ) ;
e40298d5
JS
264 }
265 else
266 {
267 m_dataObject->SetData( format, dataSize, theData );
268 }
6eae1f7d
DS
269
270 delete [] theData;
a07c1212 271 }
e40298d5
JS
272 break ;
273 }
a07c1212 274 }
e40298d5 275 }
a07c1212 276 }
6eae1f7d
DS
277
278 return true ;
e9576ca5
SC
279}
280
281//-------------------------------------------------------------------------
282// wxDropSource
283//-------------------------------------------------------------------------
284
285//-----------------------------------------------------------------------------
286// drag request
287
a07c1212 288wxDropSource::wxDropSource(wxWindow *win,
da804130
SC
289 const wxCursor &cursorCopy,
290 const wxCursor &cursorMove,
291 const wxCursor &cursorStop)
292 : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
e9576ca5 293{
a07c1212
SC
294 wxMacEnsureTrackingHandlersInstalled() ;
295 m_window = win;
296}
e9576ca5 297
a07c1212
SC
298wxDropSource::wxDropSource(wxDataObject& data,
299 wxWindow *win,
da804130
SC
300 const wxCursor &cursorCopy,
301 const wxCursor &cursorMove,
302 const wxCursor &cursorStop)
303 : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
a07c1212
SC
304{
305 wxMacEnsureTrackingHandlersInstalled() ;
306 SetData( data );
307 m_window = win;
308}
e9576ca5 309
a07c1212 310wxDropSource::~wxDropSource()
e9576ca5 311{
a07c1212 312}
e9576ca5 313
525ae3fe 314wxDragResult wxDropSource::DoDragDrop(int flags)
e9576ca5 315{
a07c1212 316 wxASSERT_MSG( m_data, wxT("Drop source: no data") );
6eae1f7d 317
a07c1212
SC
318 if (!m_data)
319 return (wxDragResult) wxDragNone;
a07c1212
SC
320 if (m_data->GetFormatCount() == 0)
321 return (wxDragResult) wxDragNone;
6eae1f7d 322
a07c1212
SC
323 OSErr result;
324 DragReference theDrag;
325 RgnHandle dragRegion;
6eae1f7d 326 if ((result = NewDrag(&theDrag)) != noErr)
a07c1212 327 return wxDragNone ;
6eae1f7d 328
a07c1212
SC
329 // add data to drag
330 size_t formatCount = m_data->GetFormatCount() ;
331 wxDataFormat *formats = new wxDataFormat[formatCount] ;
332 m_data->GetAllFormats( formats ) ;
333 ItemReference theItem = 1 ;
6eae1f7d 334
0cd51b2d 335 for ( size_t i = 0 ; i < formatCount ; ++i )
a07c1212
SC
336 {
337 size_t dataSize = m_data->GetDataSize( formats[i] ) ;
338 Ptr dataPtr = new char[dataSize] ;
339 m_data->GetDataHere( formats[i] , dataPtr ) ;
340 OSType type = formats[i].GetFormatId() ;
6ac23e25 341 if ( type == 'TEXT' || type == 'utxt' )
a07c1212 342 {
6ac23e25
SC
343 if ( dataSize > 0 )
344 dataSize-- ;
427ff662 345 dataPtr[ dataSize ] = 0 ;
6ac23e25
SC
346 if ( type == 'utxt' )
347 {
348 if ( dataSize > 0 )
349 dataSize-- ;
350 dataPtr[ dataSize ] = 0 ;
351 }
6eae1f7d
DS
352
353 AddDragItemFlavor(theDrag, theItem, type , dataPtr, dataSize, 0);
a07c1212
SC
354 }
355 else if (type == kDragFlavorTypeHFS )
356 {
e40298d5
JS
357 HFSFlavor theFlavor ;
358 OSErr err = noErr;
359 CInfoPBRec cat;
6eae1f7d 360
a2b77260 361 wxMacFilename2FSSpec( wxString( dataPtr , *wxConvCurrent ) , &theFlavor.fileSpec ) ;
6eae1f7d
DS
362
363 memset( &cat, 0, sizeof(cat) );
e40298d5
JS
364 cat.hFileInfo.ioNamePtr = theFlavor.fileSpec.name;
365 cat.hFileInfo.ioVRefNum = theFlavor.fileSpec.vRefNum;
366 cat.hFileInfo.ioDirID = theFlavor.fileSpec.parID;
367 cat.hFileInfo.ioFDirIndex = 0;
368 err = PBGetCatInfoSync(&cat);
6eae1f7d 369 if (err == noErr)
e40298d5
JS
370 {
371 theFlavor.fdFlags = cat.hFileInfo.ioFlFndrInfo.fdFlags;
6eae1f7d
DS
372 if (theFlavor.fileSpec.parID == fsRtParID)
373 {
e40298d5
JS
374 theFlavor.fileCreator = 'MACS';
375 theFlavor.fileType = 'disk';
6eae1f7d
DS
376 }
377 else if ((cat.hFileInfo.ioFlAttrib & ioDirMask) != 0)
378 {
e40298d5
JS
379 theFlavor.fileCreator = 'MACS';
380 theFlavor.fileType = 'fold';
6eae1f7d
DS
381 }
382 else
383 {
e40298d5
JS
384 theFlavor.fileCreator = cat.hFileInfo.ioFlFndrInfo.fdCreator;
385 theFlavor.fileType = cat.hFileInfo.ioFlFndrInfo.fdType;
386 }
6eae1f7d
DS
387
388 AddDragItemFlavor(theDrag, theItem, type , &theFlavor, sizeof(theFlavor), 0);
389 }
a07c1212
SC
390 }
391 else
392 {
6eae1f7d 393 AddDragItemFlavor(theDrag, theItem, type , dataPtr, dataSize, 0);
a07c1212 394 }
6eae1f7d
DS
395
396 delete [] dataPtr ;
a07c1212 397 }
6eae1f7d
DS
398
399 delete [] formats ;
400
a07c1212
SC
401 dragRegion = NewRgn();
402 RgnHandle tempRgn = NewRgn() ;
6eae1f7d 403
45a0fd37 404 EventRecord* ev = NULL ;
6eae1f7d 405
45a0fd37 406#if !TARGET_CARBON // TODO
e40298d5 407 ev = (EventRecord*) wxTheApp->MacGetCurrentEvent() ;
45a0fd37 408#else
6eae1f7d
DS
409 {
410 EventRecord rec ;
411 ev = &rec ;
412 wxMacConvertEventToRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) ;
413 }
45a0fd37 414#endif
6eae1f7d 415
a07c1212
SC
416 const short dragRegionOuterBoundary = 10 ;
417 const short dragRegionInnerBoundary = 9 ;
6eae1f7d
DS
418
419 SetRectRgn(
420 dragRegion , ev->where.h - dragRegionOuterBoundary ,
e40298d5 421 ev->where.v - dragRegionOuterBoundary ,
6eae1f7d 422 ev->where.h + dragRegionOuterBoundary ,
e40298d5 423 ev->where.v + dragRegionOuterBoundary ) ;
6eae1f7d
DS
424
425 SetRectRgn(
426 tempRgn , ev->where.h - dragRegionInnerBoundary ,
e40298d5 427 ev->where.v - dragRegionInnerBoundary ,
6eae1f7d 428 ev->where.h + dragRegionInnerBoundary ,
e40298d5 429 ev->where.v + dragRegionInnerBoundary ) ;
6eae1f7d 430
a07c1212 431 DiffRgn( dragRegion , tempRgn , dragRegion ) ;
6eae1f7d
DS
432 DisposeRgn( tempRgn ) ;
433
a07c1212
SC
434 // TODO:work with promises in order to return data only when drag
435 // was successfully completed
6eae1f7d 436
a07c1212
SC
437 gTrackingGlobals.m_currentSource = this ;
438 result = TrackDrag(theDrag, ev , dragRegion);
439 DisposeRgn(dragRegion);
440 DisposeDrag(theDrag);
441 gTrackingGlobals.m_currentSource = NULL ;
6eae1f7d 442
02becaf4 443 bool optionDown = GetCurrentKeyModifiers() & optionKey ;
525ae3fe 444 wxDragResult dndresult = wxDragCopy ;
6eae1f7d 445 if ( flags != wxDrag_CopyOnly )
525ae3fe
SC
446 // on mac the option key is always the indication for copy
447 dndresult = optionDown ? wxDragCopy : wxDragMove;
6eae1f7d 448
f43084de 449 return dndresult;
a07c1212
SC
450}
451
da804130
SC
452bool wxDropSource::MacInstallDefaultCursor(wxDragResult effect)
453{
454 const wxCursor& cursor = GetCursor(effect);
6eae1f7d
DS
455 bool result = cursor.Ok();
456
457 if ( result )
da804130
SC
458 cursor.MacInstall() ;
459
6eae1f7d 460 return result;
da804130
SC
461}
462
a07c1212
SC
463bool gTrackingGlobalsInstalled = false ;
464
465// passing the globals via refcon is not needed by the CFM and later architectures anymore
466// but I'll leave it in there, just in case...
467
6eae1f7d
DS
468pascal OSErr wxMacWindowDragTrackingHandler(
469 DragTrackingMessage theMessage, WindowPtr theWindow,
470 void *handlerRefCon, DragReference theDrag) ;
471pascal OSErr wxMacWindowDragReceiveHandler(
472 WindowPtr theWindow, void *handlerRefCon,
473 DragReference theDrag) ;
a07c1212
SC
474
475void wxMacEnsureTrackingHandlersInstalled()
e9576ca5 476{
6eae1f7d 477 if ( !gTrackingGlobalsInstalled )
a07c1212
SC
478 {
479 OSErr result;
480
481 result = InstallTrackingHandler(NewDragTrackingHandlerUPP(wxMacWindowDragTrackingHandler), 0L,&gTrackingGlobals);
482 wxASSERT( result == noErr ) ;
6eae1f7d 483
a07c1212
SC
484 result = InstallReceiveHandler(NewDragReceiveHandlerUPP(wxMacWindowDragReceiveHandler), 0L, &gTrackingGlobals);
485 wxASSERT( result == noErr ) ;
e9576ca5 486
a07c1212
SC
487 gTrackingGlobalsInstalled = true ;
488 }
489}
490
6eae1f7d
DS
491pascal OSErr wxMacWindowDragTrackingHandler(
492 DragTrackingMessage theMessage, WindowPtr theWindow,
493 void *handlerRefCon, DragReference theDrag)
494{
a07c1212
SC
495 MacTrackingGlobals* trackingGlobals = (MacTrackingGlobals*) handlerRefCon;
496 Point mouse, localMouse;
497 DragAttributes attributes;
a07c1212 498 GetDragAttributes(theDrag, &attributes);
6eae1f7d 499 wxTopLevelWindowMac* toplevel = wxFindWinFromMacWindow( theWindow ) ;
f43084de 500
02becaf4 501 bool optionDown = GetCurrentKeyModifiers() & optionKey ;
f43084de
JS
502 wxDragResult result = optionDown ? wxDragCopy : wxDragMove;
503
6eae1f7d 504 switch (theMessage)
a07c1212
SC
505 {
506 case kDragTrackingEnterHandler:
a07c1212
SC
507 case kDragTrackingLeaveHandler:
508 break;
6eae1f7d 509
a07c1212 510 case kDragTrackingEnterWindow:
e40298d5 511 trackingGlobals->m_currentTargetWindow = NULL ;
a07c1212
SC
512 trackingGlobals->m_currentTarget = NULL ;
513 break;
6eae1f7d 514
a07c1212
SC
515 case kDragTrackingInWindow:
516 if (toplevel == NULL)
517 break;
518
519 GetDragMouse(theDrag, &mouse, 0L);
520 localMouse = mouse;
521 GlobalToLocal(&localMouse);
f43084de 522
a07c1212 523 {
a07c1212 524 wxWindow *win = NULL ;
2877659b 525 ControlPartCode controlPart ;
6eae1f7d
DS
526 ControlRef control = wxMacFindControlUnderMouse(
527 toplevel , localMouse ,
2877659b
SC
528 theWindow , &controlPart ) ;
529 if ( control )
530 win = wxFindControlFromMacControl( control ) ;
7adabb9a
SC
531 else
532 win = toplevel ;
6eae1f7d 533
a07c1212
SC
534 int localx , localy ;
535 localx = localMouse.h ;
536 localy = localMouse.v ;
7adabb9a 537
a07c1212
SC
538 if ( win )
539 win->MacRootWindowToWindow( &localx , &localy ) ;
540 if ( win != trackingGlobals->m_currentTargetWindow )
541 {
542 if ( trackingGlobals->m_currentTargetWindow )
543 {
544 // this window is left
545 if ( trackingGlobals->m_currentTarget )
546 {
6eae1f7d 547 HideDragHilite( theDrag );
a07c1212
SC
548 trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ;
549 trackingGlobals->m_currentTarget->OnLeave() ;
550 trackingGlobals->m_currentTarget = NULL;
551 trackingGlobals->m_currentTargetWindow = NULL ;
552 }
553 }
6eae1f7d 554
a07c1212
SC
555 if ( win )
556 {
557 // this window is entered
558 trackingGlobals->m_currentTargetWindow = win ;
559 trackingGlobals->m_currentTarget = win->GetDropTarget() ;
a07c1212 560 {
6eae1f7d
DS
561 if ( trackingGlobals->m_currentTarget )
562 {
563 trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ;
564 result = trackingGlobals->m_currentTarget->OnEnter( localx , localy , result ) ;
da804130 565 }
6eae1f7d 566
da804130 567 if ( result != wxDragNone )
a07c1212 568 {
da804130 569 int x , y ;
6eae1f7d 570
da804130
SC
571 x = y = 0 ;
572 win->MacWindowToRootWindow( &x , &y ) ;
573 RgnHandle hiliteRgn = NewRgn() ;
6eae1f7d 574 Rect r = { y , x , y + win->GetSize().y , x + win->GetSize().x } ;
2877659b 575 RectRgn( hiliteRgn , &r ) ;
da804130
SC
576 ShowDragHilite(theDrag, hiliteRgn, true);
577 DisposeRgn( hiliteRgn ) ;
a07c1212
SC
578 }
579 }
580 }
581 }
582 else
583 {
6eae1f7d 584 if ( trackingGlobals->m_currentTarget )
a07c1212
SC
585 {
586 trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ;
6eae1f7d 587 trackingGlobals->m_currentTarget->OnDragOver( localx , localy , result ) ;
f43084de
JS
588 }
589 }
590
591 // set cursor for OnEnter and OnDragOver
6eae1f7d 592 if ( !trackingGlobals->m_currentSource && trackingGlobals->m_currentSource->GiveFeedback( result ) )
f43084de 593 {
6eae1f7d 594 if ( !trackingGlobals->m_currentSource->MacInstallDefaultCursor( result ) )
f43084de 595 {
6eae1f7d 596 switch ( result )
f43084de 597 {
eb7f8ac5
VZ
598 case wxDragCopy :
599 {
600 wxCursor cursor(wxCURSOR_COPY_ARROW) ;
601 cursor.MacInstall() ;
602 }
603 break ;
6eae1f7d 604
eb7f8ac5
VZ
605 case wxDragMove :
606 {
607 wxCursor cursor(wxCURSOR_ARROW) ;
608 cursor.MacInstall() ;
609 }
610 break ;
6eae1f7d 611
eb7f8ac5
VZ
612 case wxDragNone :
613 {
614 wxCursor cursor(wxCURSOR_NO_ENTRY) ;
615 cursor.MacInstall() ;
616 }
617 break ;
618
619 case wxDragError:
620 case wxDragLink:
621 case wxDragCancel:
6eae1f7d 622 default:
eb7f8ac5
VZ
623 // put these here to make gcc happy
624 ;
f43084de 625 }
6eae1f7d 626 }
a07c1212 627 }
7adabb9a 628 }
a07c1212 629 break;
6eae1f7d 630
a07c1212 631 case kDragTrackingLeaveWindow:
6eae1f7d 632 if (trackingGlobals->m_currentTarget)
a07c1212
SC
633 {
634 trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ;
635 trackingGlobals->m_currentTarget->OnLeave() ;
636 HideDragHilite(theDrag);
637 trackingGlobals->m_currentTarget = NULL ;
638 }
639 trackingGlobals->m_currentTargetWindow = NULL ;
640 break;
6eae1f7d
DS
641
642 default:
643 break;
a07c1212 644 }
6eae1f7d
DS
645
646 return noErr;
a07c1212
SC
647}
648
6eae1f7d
DS
649pascal OSErr wxMacWindowDragReceiveHandler(
650 WindowPtr theWindow,
651 void *handlerRefCon,
652 DragReference theDrag)
653{
654 MacTrackingGlobals* trackingGlobals = (MacTrackingGlobals*)handlerRefCon;
a07c1212
SC
655 if ( trackingGlobals->m_currentTarget )
656 {
6eae1f7d
DS
657 Point mouse, localMouse ;
658 int localx, localy ;
659
a07c1212
SC
660 trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ;
661 GetDragMouse(theDrag, &mouse, 0L);
662 localMouse = mouse;
663 GlobalToLocal(&localMouse);
664 localx = localMouse.h ;
665 localy = localMouse.v ;
6eae1f7d
DS
666
667 // TODO : should we use client coordinates?
a07c1212
SC
668 if ( trackingGlobals->m_currentTargetWindow )
669 trackingGlobals->m_currentTargetWindow->MacRootWindowToWindow( &localx , &localy ) ;
670 if ( trackingGlobals->m_currentTarget->OnDrop( localx , localy ) )
671 {
02becaf4 672 bool optionDown = GetCurrentKeyModifiers() & optionKey ;
f43084de
JS
673 wxDragResult result = optionDown ? wxDragCopy : wxDragMove;
674 trackingGlobals->m_currentTarget->OnData( localx , localy , result ) ;
a07c1212
SC
675 }
676 }
6eae1f7d
DS
677
678 return noErr;
a07c1212 679}
6eae1f7d 680
03e11df5 681#endif