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