]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/dnd.cpp
Warning fix.
[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 }
63c6e6c8 248#if wxUSE_UNICODE
2b2832ef 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 }
63c6e6c8 255#endif
e40298d5
JS
256 else if ( theType == kDragFlavorTypeHFS )
257 {
63c6e6c8
DS
258 wxFileDataObject *fdo = dynamic_cast<wxFileDataObject*>(m_dataObject);
259 wxASSERT( fdo != NULL );
260
261 if ((theData != NULL) && (fdo != NULL))
e40298d5 262 {
63c6e6c8
DS
263 HFSFlavor* theFile = (HFSFlavor*) theData ;
264 wxString name = wxMacFSSpec2MacFilename( &theFile->fileSpec ) ;
265
266 if ( !firstFileAdded )
267 {
268 // reset file list
269 fdo->SetData( 0 , "" ) ;
270 firstFileAdded = true ;
271 }
272
273 if (!name.IsEmpty())
274 fdo->AddFile( name ) ;
e40298d5
JS
275 }
276 }
277 else
278 {
279 m_dataObject->SetData( format, dataSize, theData );
280 }
6eae1f7d
DS
281
282 delete [] theData;
a07c1212 283 }
e40298d5
JS
284 break ;
285 }
a07c1212 286 }
e40298d5 287 }
a07c1212 288 }
6eae1f7d
DS
289
290 return true ;
e9576ca5
SC
291}
292
293//-------------------------------------------------------------------------
294// wxDropSource
295//-------------------------------------------------------------------------
296
297//-----------------------------------------------------------------------------
298// drag request
299
a07c1212 300wxDropSource::wxDropSource(wxWindow *win,
da804130
SC
301 const wxCursor &cursorCopy,
302 const wxCursor &cursorMove,
303 const wxCursor &cursorStop)
304 : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
e9576ca5 305{
a07c1212 306 wxMacEnsureTrackingHandlersInstalled() ;
e22ab33a 307
a07c1212
SC
308 m_window = win;
309}
e9576ca5 310
a07c1212
SC
311wxDropSource::wxDropSource(wxDataObject& data,
312 wxWindow *win,
da804130
SC
313 const wxCursor &cursorCopy,
314 const wxCursor &cursorMove,
315 const wxCursor &cursorStop)
316 : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
a07c1212
SC
317{
318 wxMacEnsureTrackingHandlersInstalled() ;
e22ab33a 319
a07c1212
SC
320 SetData( data );
321 m_window = win;
322}
e9576ca5 323
a07c1212 324wxDropSource::~wxDropSource()
e9576ca5 325{
a07c1212 326}
e9576ca5 327
525ae3fe 328wxDragResult wxDropSource::DoDragDrop(int flags)
e9576ca5 329{
a07c1212 330 wxASSERT_MSG( m_data, wxT("Drop source: no data") );
6eae1f7d 331
a07c1212
SC
332 if (!m_data)
333 return (wxDragResult) wxDragNone;
a07c1212
SC
334 if (m_data->GetFormatCount() == 0)
335 return (wxDragResult) wxDragNone;
6eae1f7d 336
a07c1212
SC
337 OSErr result;
338 DragReference theDrag;
339 RgnHandle dragRegion;
6eae1f7d 340 if ((result = NewDrag(&theDrag)) != noErr)
a07c1212 341 return wxDragNone ;
6eae1f7d 342
a07c1212
SC
343 // add data to drag
344 size_t formatCount = m_data->GetFormatCount() ;
345 wxDataFormat *formats = new wxDataFormat[formatCount] ;
346 m_data->GetAllFormats( formats ) ;
347 ItemReference theItem = 1 ;
6eae1f7d 348
0cd51b2d 349 for ( size_t i = 0 ; i < formatCount ; ++i )
a07c1212
SC
350 {
351 size_t dataSize = m_data->GetDataSize( formats[i] ) ;
352 Ptr dataPtr = new char[dataSize] ;
353 m_data->GetDataHere( formats[i] , dataPtr ) ;
354 OSType type = formats[i].GetFormatId() ;
6ac23e25 355 if ( type == 'TEXT' || type == 'utxt' )
a07c1212 356 {
6ac23e25
SC
357 if ( dataSize > 0 )
358 dataSize-- ;
427ff662 359 dataPtr[ dataSize ] = 0 ;
6ac23e25
SC
360 if ( type == 'utxt' )
361 {
362 if ( dataSize > 0 )
363 dataSize-- ;
364 dataPtr[ dataSize ] = 0 ;
365 }
6eae1f7d 366
e22ab33a 367 AddDragItemFlavor( theDrag, theItem, type , dataPtr, dataSize, 0 );
a07c1212
SC
368 }
369 else if (type == kDragFlavorTypeHFS )
370 {
e40298d5
JS
371 HFSFlavor theFlavor ;
372 OSErr err = noErr;
373 CInfoPBRec cat;
6eae1f7d 374
e22ab33a 375 wxMacFilename2FSSpec( wxString( dataPtr, *wxConvCurrent ), &theFlavor.fileSpec ) ;
6eae1f7d
DS
376
377 memset( &cat, 0, sizeof(cat) );
e40298d5
JS
378 cat.hFileInfo.ioNamePtr = theFlavor.fileSpec.name;
379 cat.hFileInfo.ioVRefNum = theFlavor.fileSpec.vRefNum;
380 cat.hFileInfo.ioDirID = theFlavor.fileSpec.parID;
381 cat.hFileInfo.ioFDirIndex = 0;
e22ab33a 382 err = PBGetCatInfoSync( &cat );
6eae1f7d 383 if (err == noErr)
e40298d5
JS
384 {
385 theFlavor.fdFlags = cat.hFileInfo.ioFlFndrInfo.fdFlags;
6eae1f7d
DS
386 if (theFlavor.fileSpec.parID == fsRtParID)
387 {
e40298d5
JS
388 theFlavor.fileCreator = 'MACS';
389 theFlavor.fileType = 'disk';
6eae1f7d
DS
390 }
391 else if ((cat.hFileInfo.ioFlAttrib & ioDirMask) != 0)
392 {
e40298d5
JS
393 theFlavor.fileCreator = 'MACS';
394 theFlavor.fileType = 'fold';
6eae1f7d
DS
395 }
396 else
397 {
e40298d5
JS
398 theFlavor.fileCreator = cat.hFileInfo.ioFlFndrInfo.fdCreator;
399 theFlavor.fileType = cat.hFileInfo.ioFlFndrInfo.fdType;
400 }
6eae1f7d 401
e22ab33a 402 AddDragItemFlavor( theDrag, theItem, type , &theFlavor, sizeof(theFlavor), 0 );
6eae1f7d 403 }
a07c1212
SC
404 }
405 else
406 {
e22ab33a 407 AddDragItemFlavor( theDrag, theItem, type , dataPtr, dataSize, 0 );
a07c1212 408 }
6eae1f7d
DS
409
410 delete [] dataPtr ;
a07c1212 411 }
6eae1f7d
DS
412
413 delete [] formats ;
414
a07c1212
SC
415 dragRegion = NewRgn();
416 RgnHandle tempRgn = NewRgn() ;
6eae1f7d 417
45a0fd37 418 EventRecord* ev = NULL ;
6eae1f7d 419
45a0fd37 420#if !TARGET_CARBON // TODO
e40298d5 421 ev = (EventRecord*) wxTheApp->MacGetCurrentEvent() ;
45a0fd37 422#else
6eae1f7d
DS
423 {
424 EventRecord rec ;
425 ev = &rec ;
426 wxMacConvertEventToRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) ;
427 }
45a0fd37 428#endif
6eae1f7d 429
a07c1212
SC
430 const short dragRegionOuterBoundary = 10 ;
431 const short dragRegionInnerBoundary = 9 ;
6eae1f7d
DS
432
433 SetRectRgn(
434 dragRegion , ev->where.h - dragRegionOuterBoundary ,
e40298d5 435 ev->where.v - dragRegionOuterBoundary ,
6eae1f7d 436 ev->where.h + dragRegionOuterBoundary ,
e40298d5 437 ev->where.v + dragRegionOuterBoundary ) ;
6eae1f7d
DS
438
439 SetRectRgn(
440 tempRgn , ev->where.h - dragRegionInnerBoundary ,
e40298d5 441 ev->where.v - dragRegionInnerBoundary ,
6eae1f7d 442 ev->where.h + dragRegionInnerBoundary ,
e40298d5 443 ev->where.v + dragRegionInnerBoundary ) ;
6eae1f7d 444
a07c1212 445 DiffRgn( dragRegion , tempRgn , dragRegion ) ;
6eae1f7d
DS
446 DisposeRgn( tempRgn ) ;
447
e22ab33a
DS
448 // TODO: work with promises in order to return data
449 // only when drag was successfully completed
6eae1f7d 450
e22ab33a
DS
451 gTrackingGlobals.m_currentSource = this;
452 result = TrackDrag( theDrag, ev, dragRegion );
453 DisposeRgn( dragRegion );
454 DisposeDrag( theDrag );
455 gTrackingGlobals.m_currentSource = NULL;
6eae1f7d 456
e22ab33a
DS
457 bool optionDown = GetCurrentKeyModifiers() & optionKey;
458 wxDragResult dndresult = wxDragCopy;
6eae1f7d 459 if ( flags != wxDrag_CopyOnly )
525ae3fe
SC
460 // on mac the option key is always the indication for copy
461 dndresult = optionDown ? wxDragCopy : wxDragMove;
6eae1f7d 462
f43084de 463 return dndresult;
a07c1212
SC
464}
465
da804130
SC
466bool wxDropSource::MacInstallDefaultCursor(wxDragResult effect)
467{
468 const wxCursor& cursor = GetCursor(effect);
6eae1f7d
DS
469 bool result = cursor.Ok();
470
471 if ( result )
e22ab33a 472 cursor.MacInstall();
da804130 473
6eae1f7d 474 return result;
da804130
SC
475}
476
a07c1212
SC
477bool gTrackingGlobalsInstalled = false ;
478
479// passing the globals via refcon is not needed by the CFM and later architectures anymore
480// but I'll leave it in there, just in case...
481
6eae1f7d
DS
482pascal OSErr wxMacWindowDragTrackingHandler(
483 DragTrackingMessage theMessage, WindowPtr theWindow,
e22ab33a 484 void *handlerRefCon, DragReference theDrag );
6eae1f7d
DS
485pascal OSErr wxMacWindowDragReceiveHandler(
486 WindowPtr theWindow, void *handlerRefCon,
e22ab33a 487 DragReference theDrag );
a07c1212
SC
488
489void wxMacEnsureTrackingHandlersInstalled()
e9576ca5 490{
6eae1f7d 491 if ( !gTrackingGlobalsInstalled )
a07c1212
SC
492 {
493 OSErr result;
494
e22ab33a
DS
495 result = InstallTrackingHandler( NewDragTrackingHandlerUPP(wxMacWindowDragTrackingHandler), 0L, &gTrackingGlobals );
496 wxASSERT( result == noErr );
6eae1f7d 497
e22ab33a
DS
498 result = InstallReceiveHandler( NewDragReceiveHandlerUPP(wxMacWindowDragReceiveHandler), 0L, &gTrackingGlobals );
499 wxASSERT( result == noErr );
e9576ca5 500
e22ab33a 501 gTrackingGlobalsInstalled = true;
a07c1212
SC
502 }
503}
504
6eae1f7d
DS
505pascal OSErr wxMacWindowDragTrackingHandler(
506 DragTrackingMessage theMessage, WindowPtr theWindow,
e22ab33a 507 void *handlerRefCon, DragReference theDrag )
6eae1f7d 508{
a07c1212 509 MacTrackingGlobals* trackingGlobals = (MacTrackingGlobals*) handlerRefCon;
e22ab33a 510
a07c1212
SC
511 Point mouse, localMouse;
512 DragAttributes attributes;
e22ab33a
DS
513
514 GetDragAttributes( theDrag, &attributes );
515
6eae1f7d 516 wxTopLevelWindowMac* toplevel = wxFindWinFromMacWindow( theWindow ) ;
f43084de 517
02becaf4 518 bool optionDown = GetCurrentKeyModifiers() & optionKey ;
f43084de
JS
519 wxDragResult result = optionDown ? wxDragCopy : wxDragMove;
520
6eae1f7d 521 switch (theMessage)
a07c1212
SC
522 {
523 case kDragTrackingEnterHandler:
a07c1212
SC
524 case kDragTrackingLeaveHandler:
525 break;
6eae1f7d 526
a07c1212 527 case kDragTrackingEnterWindow:
e22ab33a
DS
528 if (trackingGlobals != NULL)
529 {
530 trackingGlobals->m_currentTargetWindow = NULL ;
531 trackingGlobals->m_currentTarget = NULL ;
532 }
a07c1212 533 break;
6eae1f7d 534
a07c1212 535 case kDragTrackingInWindow:
e22ab33a
DS
536 if (trackingGlobals == NULL)
537 break;
a07c1212
SC
538 if (toplevel == NULL)
539 break;
540
e22ab33a 541 GetDragMouse( theDrag, &mouse, 0L );
a07c1212 542 localMouse = mouse;
e22ab33a 543 GlobalToLocal( &localMouse );
f43084de 544
a07c1212 545 {
a07c1212 546 wxWindow *win = NULL ;
2877659b 547 ControlPartCode controlPart ;
6eae1f7d 548 ControlRef control = wxMacFindControlUnderMouse(
e22ab33a 549 toplevel , localMouse , theWindow , &controlPart ) ;
2877659b
SC
550 if ( control )
551 win = wxFindControlFromMacControl( control ) ;
7adabb9a
SC
552 else
553 win = toplevel ;
6eae1f7d 554
a07c1212
SC
555 int localx , localy ;
556 localx = localMouse.h ;
557 localy = localMouse.v ;
7adabb9a 558
a07c1212
SC
559 if ( win )
560 win->MacRootWindowToWindow( &localx , &localy ) ;
561 if ( win != trackingGlobals->m_currentTargetWindow )
562 {
563 if ( trackingGlobals->m_currentTargetWindow )
564 {
565 // this window is left
566 if ( trackingGlobals->m_currentTarget )
567 {
6eae1f7d 568 HideDragHilite( theDrag );
876b960a
DS
569 trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag );
570 trackingGlobals->m_currentTarget->OnLeave();
a07c1212 571 trackingGlobals->m_currentTarget = NULL;
876b960a 572 trackingGlobals->m_currentTargetWindow = NULL;
a07c1212
SC
573 }
574 }
6eae1f7d 575
a07c1212
SC
576 if ( win )
577 {
578 // this window is entered
579 trackingGlobals->m_currentTargetWindow = win ;
580 trackingGlobals->m_currentTarget = win->GetDropTarget() ;
a07c1212 581 {
6eae1f7d
DS
582 if ( trackingGlobals->m_currentTarget )
583 {
584 trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ;
585 result = trackingGlobals->m_currentTarget->OnEnter( localx , localy , result ) ;
da804130 586 }
6eae1f7d 587
da804130 588 if ( result != wxDragNone )
a07c1212 589 {
da804130 590 int x , y ;
6eae1f7d 591
da804130
SC
592 x = y = 0 ;
593 win->MacWindowToRootWindow( &x , &y ) ;
594 RgnHandle hiliteRgn = NewRgn() ;
6eae1f7d 595 Rect r = { y , x , y + win->GetSize().y , x + win->GetSize().x } ;
2877659b 596 RectRgn( hiliteRgn , &r ) ;
876b960a 597 ShowDragHilite( theDrag, hiliteRgn, true );
da804130 598 DisposeRgn( hiliteRgn ) ;
a07c1212
SC
599 }
600 }
601 }
602 }
603 else
604 {
6eae1f7d 605 if ( trackingGlobals->m_currentTarget )
a07c1212
SC
606 {
607 trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ;
6eae1f7d 608 trackingGlobals->m_currentTarget->OnDragOver( localx , localy , result ) ;
f43084de
JS
609 }
610 }
611
612 // set cursor for OnEnter and OnDragOver
bf473da7 613 if ( trackingGlobals->m_currentSource && !trackingGlobals->m_currentSource->GiveFeedback( result ) )
f43084de 614 {
6eae1f7d 615 if ( !trackingGlobals->m_currentSource->MacInstallDefaultCursor( result ) )
f43084de 616 {
6eae1f7d 617 switch ( result )
f43084de 618 {
eb7f8ac5
VZ
619 case wxDragCopy :
620 {
621 wxCursor cursor(wxCURSOR_COPY_ARROW) ;
622 cursor.MacInstall() ;
623 }
624 break ;
6eae1f7d 625
eb7f8ac5
VZ
626 case wxDragMove :
627 {
628 wxCursor cursor(wxCURSOR_ARROW) ;
629 cursor.MacInstall() ;
630 }
631 break ;
6eae1f7d 632
eb7f8ac5
VZ
633 case wxDragNone :
634 {
635 wxCursor cursor(wxCURSOR_NO_ENTRY) ;
636 cursor.MacInstall() ;
637 }
638 break ;
639
640 case wxDragError:
641 case wxDragLink:
642 case wxDragCancel:
6eae1f7d 643 default:
eb7f8ac5
VZ
644 // put these here to make gcc happy
645 ;
f43084de 646 }
6eae1f7d 647 }
a07c1212 648 }
7adabb9a 649 }
a07c1212 650 break;
6eae1f7d 651
a07c1212 652 case kDragTrackingLeaveWindow:
e22ab33a
DS
653 if (trackingGlobals == NULL)
654 break;
655
6eae1f7d 656 if (trackingGlobals->m_currentTarget)
a07c1212 657 {
876b960a
DS
658 trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag );
659 trackingGlobals->m_currentTarget->OnLeave();
660 HideDragHilite( theDrag );
661 trackingGlobals->m_currentTarget = NULL;
a07c1212 662 }
876b960a 663 trackingGlobals->m_currentTargetWindow = NULL;
a07c1212 664 break;
6eae1f7d
DS
665
666 default:
667 break;
a07c1212 668 }
6eae1f7d
DS
669
670 return noErr;
a07c1212
SC
671}
672
6eae1f7d
DS
673pascal OSErr wxMacWindowDragReceiveHandler(
674 WindowPtr theWindow,
675 void *handlerRefCon,
676 DragReference theDrag)
677{
678 MacTrackingGlobals* trackingGlobals = (MacTrackingGlobals*)handlerRefCon;
a07c1212
SC
679 if ( trackingGlobals->m_currentTarget )
680 {
6eae1f7d
DS
681 Point mouse, localMouse ;
682 int localx, localy ;
683
a07c1212
SC
684 trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ;
685 GetDragMouse(theDrag, &mouse, 0L);
686 localMouse = mouse;
687 GlobalToLocal(&localMouse);
688 localx = localMouse.h ;
689 localy = localMouse.v ;
6eae1f7d
DS
690
691 // TODO : should we use client coordinates?
a07c1212
SC
692 if ( trackingGlobals->m_currentTargetWindow )
693 trackingGlobals->m_currentTargetWindow->MacRootWindowToWindow( &localx , &localy ) ;
694 if ( trackingGlobals->m_currentTarget->OnDrop( localx , localy ) )
695 {
02becaf4 696 bool optionDown = GetCurrentKeyModifiers() & optionKey ;
f43084de
JS
697 wxDragResult result = optionDown ? wxDragCopy : wxDragMove;
698 trackingGlobals->m_currentTarget->OnData( localx , localy , result ) ;
a07c1212
SC
699 }
700 }
6eae1f7d
DS
701
702 return noErr;
a07c1212 703}
6eae1f7d 704
03e11df5 705#endif