bool wxDropTarget::GetData() { if (m_dataObject == NULL) return false; if ( !CurrentDragHasSupportedFormat() ) return false; bool transferred = false; if ( gTrackingGlobals.m_currentSource != NULL ) { wxDataObject* data = gTrackingGlobals.m_currentSource->GetDataObject(); if (data != NULL) { size_t formatcount = data->GetFormatCount(); wxDataFormat *array = new wxDataFormat[formatcount]; data->GetAllFormats( array ); for (size_t i = 0; !transferred && i < formatcount; i++) { wxDataFormat format = array[i]; if ( m_dataObject->IsSupported( format ) ) { int size = data->GetDataSize( format ); transferred = true; if (size == 0) { m_dataObject->SetData( format, 0, 0 ); } else { char *d = new char[size]; data->GetDataHere( format, (void*)d ); m_dataObject->SetData( format, size, d ); delete [] d; } } } delete [] array; } } if ( !transferred ) { PasteboardRef pasteboard; if ( GetDragPasteboard( (DragReference)m_currentDrag, &pasteboard ) == noErr ) { transferred = m_dataObject->GetFromPasteboard( pasteboard ); } } return transferred; }
pascal OSErr wxMacWindowDragReceiveHandler( WindowPtr theWindow, void *handlerRefCon, DragReference theDrag) { MacTrackingGlobals* trackingGlobals = (MacTrackingGlobals*)handlerRefCon; if ( trackingGlobals->m_currentTarget ) { Point mouse, localMouse; int localx, localy; PasteboardRef pasteboard = 0; GetDragPasteboard( theDrag, &pasteboard ); trackingGlobals->m_currentTarget->SetCurrentDragPasteboard( pasteboard ); GetDragMouse( theDrag, &mouse, 0L ); localMouse = mouse; localx = localMouse.h; localy = localMouse.v; wxNonOwnedWindow* tlw = wxNonOwnedWindow::GetFromWXWindow((WXWindow) theWindow); if ( tlw ) tlw->GetNonOwnedPeer()->ScreenToWindow( &localx, &localy ); // TODO : should we use client coordinates? if ( trackingGlobals->m_currentTargetWindow ) trackingGlobals->m_currentTargetWindow->MacRootWindowToWindow( &localx, &localy ); if ( trackingGlobals->m_currentTarget->OnDrop( localx, localy ) ) { // the option key indicates copy in Mac UI, if it's not pressed do // move by default if it's allowed at all wxDragResult result = !(trackingGlobals->m_flags & wxDrag_AllowMove) || (GetCurrentKeyModifiers() & optionKey) ? wxDragCopy : wxDragMove; trackingGlobals->m_result = trackingGlobals->m_currentTarget->OnData( localx, localy, result ); } } return noErr; }
bool wxDropTarget::CurrentDragHasSupportedFormat() { bool supported = false; if (m_dataObject == NULL) return false; if ( gTrackingGlobals.m_currentSource != NULL ) { wxDataObject* data = gTrackingGlobals.m_currentSource->GetDataObject(); if ( data ) { size_t formatcount = data->GetFormatCount(); wxDataFormat *array = new wxDataFormat[formatcount]; data->GetAllFormats( array ); for (size_t i = 0; !supported && i < formatcount; i++) { wxDataFormat format = array[i]; if ( m_dataObject->IsSupported( format ) ) { supported = true; break; } } delete [] array; } } if ( !supported ) { PasteboardRef pasteboard; if ( GetDragPasteboard( (DragReference)m_currentDrag, &pasteboard ) == noErr ) { supported = m_dataObject->HasDataInPasteboard( pasteboard ); } } return supported; }
pascal OSErr wxMacWindowDragTrackingHandler( DragTrackingMessage theMessage, WindowPtr theWindow, void *handlerRefCon, DragReference theDrag ) { MacTrackingGlobals* trackingGlobals = (MacTrackingGlobals*) handlerRefCon; Point mouse, localMouse; DragAttributes attributes; GetDragAttributes( theDrag, &attributes ); PasteboardRef pasteboard = 0; GetDragPasteboard( theDrag, &pasteboard ); wxNonOwnedWindow* toplevel = wxNonOwnedWindow::GetFromWXWindow( (WXWindow) theWindow ); bool optionDown = GetCurrentKeyModifiers() & optionKey; wxDragResult result = optionDown ? wxDragCopy : wxDragMove; switch (theMessage) { case kDragTrackingEnterHandler: case kDragTrackingLeaveHandler: break; case kDragTrackingEnterWindow: if (trackingGlobals != NULL) { trackingGlobals->m_currentTargetWindow = NULL; trackingGlobals->m_currentTarget = NULL; } break; case kDragTrackingInWindow: if (trackingGlobals == NULL) break; if (toplevel == NULL) break; GetDragMouse( theDrag, &mouse, 0L ); { int x = mouse.h ; int y = mouse.v ; toplevel->GetNonOwnedPeer()->ScreenToWindow( &x, &y ); localMouse.h = x; localMouse.v = y; { wxWindow *win = NULL; ControlPartCode controlPart; ControlRef control = FindControlUnderMouse( localMouse, theWindow, &controlPart ); if ( control ) win = wxFindWindowFromWXWidget( (WXWidget) control ); else win = toplevel; int localx, localy; localx = localMouse.h; localy = localMouse.v; if ( win ) win->MacRootWindowToWindow( &localx, &localy ); if ( win != trackingGlobals->m_currentTargetWindow ) { if ( trackingGlobals->m_currentTargetWindow ) { // this window is left if ( trackingGlobals->m_currentTarget ) { HideDragHilite( theDrag ); trackingGlobals->m_currentTarget->SetCurrentDragPasteboard( pasteboard ); trackingGlobals->m_currentTarget->OnLeave(); trackingGlobals->m_currentTarget = NULL; trackingGlobals->m_currentTargetWindow = NULL; } } if ( win ) { // this window is entered trackingGlobals->m_currentTargetWindow = win; trackingGlobals->m_currentTarget = win->GetDropTarget(); { if ( trackingGlobals->m_currentTarget ) { trackingGlobals->m_currentTarget->SetCurrentDragPasteboard( pasteboard ); result = trackingGlobals->m_currentTarget->OnEnter( localx, localy, result ); } if ( result != wxDragNone ) { int x, y; x = y = 0; win->MacWindowToRootWindow( &x, &y ); RgnHandle hiliteRgn = NewRgn(); Rect r = { y, x, y + win->GetSize().y, x + win->GetSize().x }; RectRgn( hiliteRgn, &r ); ShowDragHilite( theDrag, hiliteRgn, true ); DisposeRgn( hiliteRgn ); } } } } else { if ( trackingGlobals->m_currentTarget ) { trackingGlobals->m_currentTarget->SetCurrentDragPasteboard( pasteboard ); result = trackingGlobals->m_currentTarget->OnDragOver( localx, localy, result ); } } // set cursor for OnEnter and OnDragOver if ( trackingGlobals->m_currentSource && !trackingGlobals->m_currentSource->GiveFeedback( result ) ) { if ( !trackingGlobals->m_currentSource->MacInstallDefaultCursor( result ) ) { wxStockCursor cursorID = wxCURSOR_NONE; switch (result) { case wxDragCopy: cursorID = wxCURSOR_COPY_ARROW; break; case wxDragMove: cursorID = wxCURSOR_ARROW; break; case wxDragNone: cursorID = wxCURSOR_NO_ENTRY; break; case wxDragError: case wxDragLink: case wxDragCancel: default: // put these here to make gcc happy ; } if (cursorID != wxCURSOR_NONE) { wxCursor cursor( cursorID ); cursor.MacInstall(); } } } } } break; case kDragTrackingLeaveWindow: if (trackingGlobals == NULL) break; if (trackingGlobals->m_currentTarget) { trackingGlobals->m_currentTarget->SetCurrentDragPasteboard( pasteboard ); trackingGlobals->m_currentTarget->OnLeave(); HideDragHilite( theDrag ); trackingGlobals->m_currentTarget = NULL; } trackingGlobals->m_currentTargetWindow = NULL; break; default: break; } return noErr; }
static pascal OSStatus MultiCartPaneEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { OSStatus err, result = eventNotHandledErr; HIViewRef view; DragRef drag; PasteboardRef pasteboard; PasteboardItemID itemID; CFArrayRef array; CFStringRef flavorType; CFIndex numFlavors; ItemCount numItems; int index = *((int *) inUserData); switch (GetEventClass(inEvent)) { case kEventClassControl: { switch (GetEventKind(inEvent)) { case kEventControlDraw: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { CGContextRef ctx; err = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(CGContextRef), NULL, &ctx); if (err == noErr) { HIThemeFrameDrawInfo info; HIRect bounds, frame; HIViewGetBounds(view, &bounds); CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f); CGContextFillRect(ctx, bounds); info.version = 0; info.kind = kHIThemeFrameTextFieldSquare; info.state = kThemeStateInactive; info.isFocused = false; err = HIThemeDrawFrame(&bounds, &info, ctx, kHIThemeOrientationNormal); if (multiCartDragHilite == index && systemVersion >= 0x1040) { err = HIThemeSetStroke(kThemeBrushDragHilite, NULL, ctx, kHIThemeOrientationNormal); frame = CGRectInset(bounds, 1, 1); CGContextBeginPath(ctx); CGContextAddRect(ctx, frame); CGContextStrokePath(ctx); } } } result = noErr; break; } case kEventControlDragEnter: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag); if (err == noErr) { err = GetDragPasteboard(drag, &pasteboard); if (err == noErr) { err = PasteboardGetItemCount(pasteboard, &numItems); if (err == noErr && numItems == 1) { err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID); if (err == noErr) { err = PasteboardCopyItemFlavors(pasteboard, itemID, &array); if (err == noErr) { numFlavors = CFArrayGetCount(array); for (CFIndex i = 0; i < numFlavors; i++) { flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i); if (UTTypeConformsTo(flavorType, CFSTR("public.file-url"))) { Boolean accept = true; err = SetEventParameter(inEvent, kEventParamControlWouldAcceptDrop, typeBoolean, sizeof(Boolean), &accept); if (err == noErr) { multiCartDragHilite = index; HIViewSetNeedsDisplay(view, true); result = noErr; } } } CFRelease(array); } } } } } } break; } case kEventControlDragWithin: { result = noErr; break; } case kEventControlDragLeave: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { multiCartDragHilite = -1; HIViewSetNeedsDisplay(view, true); } result = noErr; break; } case kEventControlDragReceive: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag); if (err == noErr) { multiCartDragHilite = -1; HIViewSetNeedsDisplay(view, true); err = GetDragPasteboard(drag, &pasteboard); if (err == noErr) { err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID); if (err == noErr) { err = PasteboardCopyItemFlavors(pasteboard, itemID, &array); if (err == noErr) { numFlavors = CFArrayGetCount(array); for (CFIndex i = 0; i < numFlavors; i++) { flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i); if (UTTypeConformsTo(flavorType, CFSTR("public.file-url"))) { CFDataRef flavorData; err = PasteboardCopyItemFlavorData(pasteboard, itemID, flavorType, &flavorData); if (err == noErr) { CFIndex dataSize; UInt8 *data; dataSize = CFDataGetLength(flavorData); data = (UInt8 *) malloc(dataSize); if (data) { CFDataGetBytes(flavorData, CFRangeMake(0, dataSize), data); HIViewRef ctl; HIViewID cid; CFStringRef str; CFURLRef url; GetControlID(view, &cid); cid.signature = 'MNAM'; HIViewFindByID(view, cid, &ctl); url = CFURLCreateWithBytes(kCFAllocatorDefault, data, dataSize, kCFStringEncodingUTF8, NULL); str = CFURLCopyLastPathComponent(url); SetStaticTextCFString(ctl, str, true); CFRelease(str); str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); if (multiCartPath[cid.id]) CFRelease(multiCartPath[cid.id]); multiCartPath[cid.id] = str; CFRelease(url); result = noErr; free(data); } CFRelease(flavorData); } } } CFRelease(array); } } } } } } } } } return (result); }