📄 dnd.cpp
字号:
size_t dataSize = m_data->GetDataSize( formats[i] );
Ptr dataPtr = new char[dataSize];
m_data->GetDataHere( formats[i], dataPtr );
OSType type = formats[i].GetFormatId();
if ( type == 'TEXT' || type == 'utxt' )
{
if ( dataSize > 0 )
dataSize--;
dataPtr[ dataSize ] = 0;
if ( type == 'utxt' )
{
if ( dataSize > 0 )
dataSize--;
dataPtr[ dataSize ] = 0;
}
AddDragItemFlavor( theDrag, theItem, type, dataPtr, dataSize, 0 );
}
else if (type == kDragFlavorTypeHFS )
{
HFSFlavor theFlavor;
OSErr err = noErr;
CInfoPBRec cat;
wxMacFilename2FSSpec( wxString( dataPtr, *wxConvCurrent ), &theFlavor.fileSpec );
memset( &cat, 0, sizeof(cat) );
cat.hFileInfo.ioNamePtr = theFlavor.fileSpec.name;
cat.hFileInfo.ioVRefNum = theFlavor.fileSpec.vRefNum;
cat.hFileInfo.ioDirID = theFlavor.fileSpec.parID;
cat.hFileInfo.ioFDirIndex = 0;
err = PBGetCatInfoSync( &cat );
if (err == noErr)
{
theFlavor.fdFlags = cat.hFileInfo.ioFlFndrInfo.fdFlags;
if (theFlavor.fileSpec.parID == fsRtParID)
{
theFlavor.fileCreator = 'MACS';
theFlavor.fileType = 'disk';
}
else if ((cat.hFileInfo.ioFlAttrib & ioDirMask) != 0)
{
theFlavor.fileCreator = 'MACS';
theFlavor.fileType = 'fold';
}
else
{
theFlavor.fileCreator = cat.hFileInfo.ioFlFndrInfo.fdCreator;
theFlavor.fileType = cat.hFileInfo.ioFlFndrInfo.fdType;
}
AddDragItemFlavor( theDrag, theItem, type, &theFlavor, sizeof(theFlavor), 0 );
}
}
else
{
AddDragItemFlavor( theDrag, theItem, type, dataPtr, dataSize, 0 );
}
delete [] dataPtr;
}
delete [] formats;
dragRegion = NewRgn();
RgnHandle tempRgn = NewRgn();
EventRecord* ev = NULL;
#if !TARGET_CARBON // TODO
ev = (EventRecord*) wxTheApp->MacGetCurrentEvent();
#else
EventRecord rec;
ev = &rec;
wxMacConvertEventToRecord( (EventRef) wxTheApp->MacGetCurrentEvent(), &rec );
#endif
const short dragRegionOuterBoundary = 10;
const short dragRegionInnerBoundary = 9;
SetRectRgn(
dragRegion,
ev->where.h - dragRegionOuterBoundary,
ev->where.v - dragRegionOuterBoundary,
ev->where.h + dragRegionOuterBoundary,
ev->where.v + dragRegionOuterBoundary );
SetRectRgn(
tempRgn,
ev->where.h - dragRegionInnerBoundary,
ev->where.v - dragRegionInnerBoundary,
ev->where.h + dragRegionInnerBoundary,
ev->where.v + dragRegionInnerBoundary );
DiffRgn( dragRegion, tempRgn, dragRegion );
DisposeRgn( tempRgn );
// TODO: work with promises in order to return data
// only when drag was successfully completed
gTrackingGlobals.m_currentSource = this;
result = TrackDrag( theDrag, ev, dragRegion );
DisposeRgn( dragRegion );
DisposeDrag( theDrag );
gTrackingGlobals.m_currentSource = NULL;
bool optionDown = GetCurrentKeyModifiers() & optionKey;
wxDragResult dndresult = wxDragCopy;
if ( flags != wxDrag_CopyOnly )
// on mac the option key is always the indication for copy
dndresult = optionDown ? wxDragCopy : wxDragMove;
return dndresult;
}
bool wxDropSource::MacInstallDefaultCursor(wxDragResult effect)
{
const wxCursor& cursor = GetCursor(effect);
bool result = cursor.Ok();
if ( result )
cursor.MacInstall();
return result;
}
bool gTrackingGlobalsInstalled = false;
// passing the globals via refcon is not needed by the CFM and later architectures anymore
// but I'll leave it in there, just in case...
pascal OSErr wxMacWindowDragTrackingHandler(
DragTrackingMessage theMessage, WindowPtr theWindow,
void *handlerRefCon, DragReference theDrag );
pascal OSErr wxMacWindowDragReceiveHandler(
WindowPtr theWindow, void *handlerRefCon,
DragReference theDrag );
void wxMacEnsureTrackingHandlersInstalled()
{
if ( !gTrackingGlobalsInstalled )
{
OSStatus err;
err = InstallTrackingHandler( NewDragTrackingHandlerUPP(wxMacWindowDragTrackingHandler), 0L, &gTrackingGlobals );
verify_noerr( err );
err = InstallReceiveHandler( NewDragReceiveHandlerUPP(wxMacWindowDragReceiveHandler), 0L, &gTrackingGlobals );
verify_noerr( err );
gTrackingGlobalsInstalled = true;
}
}
pascal OSErr wxMacWindowDragTrackingHandler(
DragTrackingMessage theMessage, WindowPtr theWindow,
void *handlerRefCon, DragReference theDrag )
{
MacTrackingGlobals* trackingGlobals = (MacTrackingGlobals*) handlerRefCon;
Point mouse, localMouse;
DragAttributes attributes;
GetDragAttributes( theDrag, &attributes );
wxTopLevelWindowMac* toplevel = wxFindWinFromMacWindow( 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 );
localMouse = mouse;
GlobalToLocal( &localMouse );
{
wxWindow *win = NULL;
ControlPartCode controlPart;
ControlRef control = wxMacFindControlUnderMouse(
toplevel, localMouse, theWindow, &controlPart );
if ( control )
win = wxFindControlFromMacControl( 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->SetCurrentDrag( theDrag );
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->SetCurrentDrag( theDrag );
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->SetCurrentDrag( theDrag );
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 ) )
{
int 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->SetCurrentDrag( theDrag );
trackingGlobals->m_currentTarget->OnLeave();
HideDragHilite( theDrag );
trackingGlobals->m_currentTarget = NULL;
}
trackingGlobals->m_currentTargetWindow = NULL;
break;
default:
break;
}
return noErr;
}
pascal OSErr wxMacWindowDragReceiveHandler(
WindowPtr theWindow,
void *handlerRefCon,
DragReference theDrag)
{
MacTrackingGlobals* trackingGlobals = (MacTrackingGlobals*)handlerRefCon;
if ( trackingGlobals->m_currentTarget )
{
Point mouse, localMouse;
int localx, localy;
trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag );
GetDragMouse( theDrag, &mouse, 0L );
localMouse = mouse;
GlobalToLocal( &localMouse );
localx = localMouse.h;
localy = localMouse.v;
// TODO : should we use client coordinates?
if ( trackingGlobals->m_currentTargetWindow )
trackingGlobals->m_currentTargetWindow->MacRootWindowToWindow( &localx, &localy );
if ( trackingGlobals->m_currentTarget->OnDrop( localx, localy ) )
{
bool optionDown = GetCurrentKeyModifiers() & optionKey;
wxDragResult result = optionDown ? wxDragCopy : wxDragMove;
trackingGlobals->m_currentTarget->OnData( localx, localy, result );
}
}
return noErr;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -