Refactor DND code into Carbon and Cocoa parts, and provide a basic OS X Cocoa implementation for wxDropSource::DoDragDrop.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63365 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Kevin Ollivier
2010-02-03 05:31:31 +00:00
parent 803e2857b3
commit 7dab9892b3
5 changed files with 297 additions and 84 deletions

View File

@@ -2236,6 +2236,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/osx/checklst_osx.cpp
src/osx/choice_osx.cpp
src/osx/combobox_osx.cpp
src/osx/dnd_osx.cpp
src/osx/gauge_osx.cpp
src/osx/listbox_osx.cpp
src/osx/menu_osx.cpp
@@ -2277,7 +2278,6 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/osx/carbon/dcscreen.cpp
src/osx/core/glgrab.cpp
src/osx/carbon/graphics.cpp
src/osx/carbon/dnd.cpp
src/osx/carbon/font.cpp
src/osx/carbon/frame.cpp
src/osx/carbon/mdi.cpp
@@ -2317,6 +2317,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/osx/carbon/colordlg.cpp
src/osx/carbon/dialog.cpp
src/osx/carbon/dirdlg.cpp
src/osx/carbon/dnd.cpp
src/osx/carbon/evtloop.cpp
src/osx/carbon/filedlg.cpp
src/osx/carbon/gauge.cpp
@@ -2473,6 +2474,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/osx/cocoa/combobox.mm
src/osx/cocoa/dialog.mm
src/osx/cocoa/dirdlg.mm
src/osx/cocoa/dnd.mm
src/osx/cocoa/evtloop.mm
src/osx/cocoa/filedlg.mm
src/osx/cocoa/gauge.mm

View File

@@ -40,9 +40,17 @@ MacTrackingGlobals gTrackingGlobals;
void wxMacEnsureTrackingHandlersInstalled();
//----------------------------------------------------------------------------
// wxDropTarget
//----------------------------------------------------------------------------
OSStatus wxMacPromiseKeeper(PasteboardRef WXUNUSED(inPasteboard),
PasteboardItemID WXUNUSED(inItem),
CFStringRef WXUNUSED(inFlavorType),
void * WXUNUSED(inContext))
{
OSStatus err = noErr;
// we might add promises here later, inContext is the wxDropSource*
return err;
}
wxDropTarget::wxDropTarget( wxDataObject *data )
: wxDropTargetBase( data )
@@ -50,40 +58,6 @@ wxDropTarget::wxDropTarget( wxDataObject *data )
wxMacEnsureTrackingHandlersInstalled();
}
wxDragResult wxDropTarget::OnDragOver(
wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
wxDragResult def )
{
return CurrentDragHasSupportedFormat() ? def : wxDragNone;
}
wxDataFormat wxDropTarget::GetMatchingPair()
{
wxFAIL_MSG("wxDropTarget::GetMatchingPair() not implemented in src/osx/carbon/dnd.cpp");
return wxDF_INVALID;
}
bool wxDropTarget::OnDrop( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y) )
{
if (m_dataObject == NULL)
return false;
return CurrentDragHasSupportedFormat();
}
wxDragResult wxDropTarget::OnData(
wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
wxDragResult def )
{
if (m_dataObject == NULL)
return wxDragNone;
if (!CurrentDragHasSupportedFormat())
return wxDragNone;
return GetData() ? def : wxDragNone;
}
bool wxDropTarget::CurrentDragHasSupportedFormat()
{
bool supported = false;
@@ -177,9 +151,6 @@ bool wxDropTarget::GetData()
// wxDropSource
//-------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// drag request
wxDropSource::wxDropSource(wxWindow *win,
const wxCursor &cursorCopy,
const wxCursor &cursorMove,
@@ -204,22 +175,6 @@ wxDropSource::wxDropSource(wxDataObject& data,
m_window = win;
}
wxDropSource::~wxDropSource()
{
}
OSStatus wxMacPromiseKeeper(PasteboardRef WXUNUSED(inPasteboard),
PasteboardItemID WXUNUSED(inItem),
CFStringRef WXUNUSED(inFlavorType),
void * WXUNUSED(inContext))
{
OSStatus err = noErr;
// we might add promises here later, inContext is the wxDropSource*
return err;
}
wxDragResult wxDropSource::DoDragDrop(int flags)
{
wxASSERT_MSG( m_data, wxT("Drop source: no data") );
@@ -227,7 +182,6 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
if ((m_data == NULL) || (m_data->GetFormatCount() == 0))
return (wxDragResult)wxDragNone;
#if wxOSX_USE_CARBON
DragReference theDrag;
RgnHandle dragRegion;
OSStatus err = noErr;
@@ -302,41 +256,24 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
DisposeDrag( theDrag );
CFRelease( pasteboard );
gTrackingGlobals.m_currentSource = NULL;
#else
wxUnusedVar(flags);
#endif
return gTrackingGlobals.m_result;
}
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...
#if wxOSX_USE_CARBON
pascal OSErr wxMacWindowDragTrackingHandler(
DragTrackingMessage theMessage, WindowPtr theWindow,
void *handlerRefCon, DragReference theDrag );
pascal OSErr wxMacWindowDragReceiveHandler(
WindowPtr theWindow, void *handlerRefCon,
DragReference theDrag );
#endif
void wxMacEnsureTrackingHandlersInstalled()
{
#if wxOSX_USE_CARBON
if ( !gTrackingGlobalsInstalled )
{
OSStatus err;
@@ -349,10 +286,8 @@ void wxMacEnsureTrackingHandlersInstalled()
gTrackingGlobalsInstalled = true;
}
#endif
}
#if wxOSX_USE_CARBON
pascal OSErr wxMacWindowDragTrackingHandler(
DragTrackingMessage theMessage, WindowPtr theWindow,
void *handlerRefCon, DragReference theDrag )
@@ -420,9 +355,7 @@ pascal OSErr wxMacWindowDragTrackingHandler(
// this window is left
if ( trackingGlobals->m_currentTarget )
{
#ifndef __LP64__
HideDragHilite( theDrag );
#endif
trackingGlobals->m_currentTarget->SetCurrentDragPasteboard( pasteboard );
trackingGlobals->m_currentTarget->OnLeave();
trackingGlobals->m_currentTarget = NULL;
@@ -451,9 +384,7 @@ pascal OSErr wxMacWindowDragTrackingHandler(
RgnHandle hiliteRgn = NewRgn();
Rect r = { y, x, y + win->GetSize().y, x + win->GetSize().x };
RectRgn( hiliteRgn, &r );
#ifndef __LP64__
ShowDragHilite( theDrag, hiliteRgn, true );
#endif
DisposeRgn( hiliteRgn );
}
}
@@ -516,9 +447,7 @@ pascal OSErr wxMacWindowDragTrackingHandler(
{
trackingGlobals->m_currentTarget->SetCurrentDragPasteboard( pasteboard );
trackingGlobals->m_currentTarget->OnLeave();
#ifndef __LP64__
HideDragHilite( theDrag );
#endif
trackingGlobals->m_currentTarget = NULL;
}
trackingGlobals->m_currentTargetWindow = NULL;
@@ -572,7 +501,6 @@ pascal OSErr wxMacWindowDragReceiveHandler(
return noErr;
}
#endif
#endif // wxUSE_DRAG_AND_DROP

194
src/osx/cocoa/dnd.mm Normal file
View File

@@ -0,0 +1,194 @@
///////////////////////////////////////////////////////////////////////////////
// Name: src/osx/cocoa/dnd.mm
// Purpose: wxDropTarget, wxDropSource implementations
// Author: Stefan Csomor
// Modified by:
// Created: 1998-01-01
// RCS-ID: $Id: dnd.cpp 61724 2009-08-21 10:41:26Z VZ $
// Copyright: (c) 1998 Stefan Csomor
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
#if wxUSE_DRAG_AND_DROP
#include "wx/dnd.h"
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/evtloop.h"
#include "wx/toplevel.h"
#include "wx/gdicmn.h"
#include "wx/wx.h"
#endif // WX_PRECOMP
#include <AppKit/AppKit.h>
#include "wx/osx/private.h"
wxDragResult NSDragOperationToWxDragResult(NSDragOperation code)
{
switch (code)
{
case NSDragOperationCopy:
return wxDragCopy;
case NSDragOperationMove:
return wxDragMove;
case NSDragOperationLink:
return wxDragLink;
case NSDragOperationNone:
return wxDragNone;
default:
wxFAIL_MSG("Unexpected result code");
}
}
@interface DropSourceDelegate : NSObject
{
BOOL dragFinished;
int resultCode;
wxDropSource* impl;
}
- (void)setImplementation: (wxDropSource *)dropSource;
- (BOOL)finished;
- (NSDragOperation)code;
- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation;
@end
@implementation DropSourceDelegate
- (id)init
{
[super init];
dragFinished = NO;
resultCode = NSDragOperationNone;
impl = 0;
return self;
}
- (void)setImplementation: (wxDropSource *)dropSource
{
impl = dropSource;
}
- (BOOL)finished
{
return dragFinished;
}
- (NSDragOperation)code
{
return resultCode;
}
- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
{
resultCode = operation;
dragFinished = YES;
}
@end
wxDropTarget::wxDropTarget( wxDataObject *data )
: wxDropTargetBase( data )
{
}
bool wxDropTarget::CurrentDragHasSupportedFormat()
{
if (m_dataObject == NULL)
return false;
return m_dataObject->HasDataInPasteboard( m_currentDragPasteboard );
}
bool wxDropTarget::GetData()
{
if (m_dataObject == NULL)
return false;
if ( !CurrentDragHasSupportedFormat() )
return false;
return m_dataObject->GetFromPasteboard( m_currentDragPasteboard );
}
//-------------------------------------------------------------------------
// wxDropSource
//-------------------------------------------------------------------------
wxDropSource::wxDropSource(wxWindow *win,
const wxCursor &cursorCopy,
const wxCursor &cursorMove,
const wxCursor &cursorStop)
: wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
{
m_window = win;
}
wxDropSource::wxDropSource(wxDataObject& data,
wxWindow *win,
const wxCursor &cursorCopy,
const wxCursor &cursorMove,
const wxCursor &cursorStop)
: wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
{
SetData( data );
m_window = win;
}
wxDragResult wxDropSource::DoDragDrop(int flags)
{
wxASSERT_MSG( m_data, wxT("Drop source: no data") );
wxDragResult result = wxDragNone;
if ((m_data == NULL) || (m_data->GetFormatCount() == 0))
return result;
NSView* view = m_window->GetPeer()->GetWXWidget();
if (view)
{
NSPasteboard *pboard;
pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
OSStatus err = noErr;
PasteboardRef pboardRef;
PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
err = PasteboardClear( pboardRef );
if ( err != noErr )
{
CFRelease( pboardRef );
return wxDragNone;
}
PasteboardSynchronize( pboardRef );
m_data->AddToPasteboard( pboardRef, 1 );
NSEvent* theEvent = (NSEvent*)wxTheApp->MacGetCurrentEvent();
wxASSERT_MSG(theEvent, "DoDragDrop must be called in response to a mouse down or drag event.");
NSImage* image = [[NSImage alloc] initWithSize: NSMakeSize(16,16)];
DropSourceDelegate* delegate = [[DropSourceDelegate alloc] init];
[delegate setImplementation: this];
[view dragImage:image at:NSMakePoint(0.0, 16.0) offset:NSMakeSize(0.0,0.0)
event: theEvent pasteboard: pboard source:delegate slideBack: NO];
wxEventLoopBase * const loop = wxEventLoop::GetActive();
while ( ![delegate finished] )
loop->Dispatch();
result = NSDragOperationToWxDragResult([delegate code]);
[delegate release];
[image release];
}
return result;
}
#endif // wxUSE_DRAG_AND_DROP

View File

@@ -121,6 +121,8 @@ bool wxGUIEventLoop::Dispatch()
inMode:NSDefaultRunLoopMode
dequeue: YES])
{
if (wxTheApp)
wxTheApp->MacSetCurrentEvent(event, NULL);
m_sleepTime = 0.0;
[NSApp sendEvent: event];
}

87
src/osx/dnd_osx.cpp Normal file
View File

@@ -0,0 +1,87 @@
///////////////////////////////////////////////////////////////////////////////
// Name: src/osx/dnd_osx.cpp
// Purpose: Mac common wxDropTarget, wxDropSource implementations
// Author: Stefan Csomor
// Modified by:
// Created: 1998-01-01
// RCS-ID: $Id: dnd.cpp 61724 2009-08-21 10:41:26Z VZ $
// Copyright: (c) 1998 Stefan Csomor
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
#if wxUSE_DRAG_AND_DROP
#include "wx/dnd.h"
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/toplevel.h"
#include "wx/gdicmn.h"
#endif // WX_PRECOMP
#include "wx/osx/private.h"
//----------------------------------------------------------------------------
// wxDropTarget
//----------------------------------------------------------------------------
wxDragResult wxDropTarget::OnDragOver(
wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
wxDragResult def )
{
return CurrentDragHasSupportedFormat() ? def : wxDragNone;
}
wxDataFormat wxDropTarget::GetMatchingPair()
{
wxFAIL_MSG("wxDropTarget::GetMatchingPair() not implemented in src/osx/carbon/dnd.cpp");
return wxDF_INVALID;
}
bool wxDropTarget::OnDrop( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y) )
{
if (m_dataObject == NULL)
return false;
return CurrentDragHasSupportedFormat();
}
wxDragResult wxDropTarget::OnData(
wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
wxDragResult def )
{
if (m_dataObject == NULL)
return wxDragNone;
if (!CurrentDragHasSupportedFormat())
return wxDragNone;
return GetData() ? def : wxDragNone;
}
//-------------------------------------------------------------------------
// wxDropSource
//-------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// drag request
wxDropSource::~wxDropSource()
{
}
bool wxDropSource::MacInstallDefaultCursor(wxDragResult effect)
{
const wxCursor& cursor = GetCursor(effect);
bool result = cursor.Ok();
if ( result )
cursor.MacInstall();
return result;
}
#endif // wxUSE_DRAG_AND_DROP