Initial Cocoa drag and drop support.
parent
29e747c4f1
commit
461ab912a5
|
|
@ -15,6 +15,7 @@
|
|||
@interface LLOpenGLView : NSOpenGLView
|
||||
{
|
||||
NSPoint mousePos;
|
||||
std::string mLastDraggedUrl;
|
||||
}
|
||||
|
||||
- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
|
||||
|
|
|
|||
|
|
@ -61,12 +61,13 @@
|
|||
|
||||
- (id) init
|
||||
{
|
||||
//[self registerForDraggedTypes:[NSArray arrayWithObjects:NSURLPboardType, NSFilenamesPboardType, nil]];
|
||||
return [self initWithFrame:[self bounds] withSamples:2 andVsync:TRUE];
|
||||
}
|
||||
|
||||
- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync
|
||||
{
|
||||
|
||||
[self registerForDraggedTypes:[NSArray arrayWithObject:NSURLPboardType]];
|
||||
[self initWithFrame:frame];
|
||||
|
||||
// Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6.
|
||||
|
|
@ -234,6 +235,49 @@
|
|||
return [_window resignFirstResponder];
|
||||
}
|
||||
|
||||
- (NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender
|
||||
{
|
||||
NSPasteboard *pboard;
|
||||
NSDragOperation sourceDragMask;
|
||||
|
||||
sourceDragMask = [sender draggingSourceOperationMask];
|
||||
|
||||
pboard = [sender draggingPasteboard];
|
||||
|
||||
if ([[pboard types] containsObject:NSURLPboardType])
|
||||
{
|
||||
if (sourceDragMask & NSDragOperationLink) {
|
||||
NSURL *fileUrl = [[pboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:[NSDictionary dictionary]] objectAtIndex:0];
|
||||
mLastDraggedUrl = [[fileUrl absoluteString] UTF8String];
|
||||
return NSDragOperationLink;
|
||||
}
|
||||
}
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
callHandleDragUpdated(mLastDraggedUrl);
|
||||
|
||||
return NSDragOperationLink;
|
||||
}
|
||||
|
||||
- (void) draggingExited:(id<NSDraggingInfo>)sender
|
||||
{
|
||||
callHandleDragExited(mLastDraggedUrl);
|
||||
}
|
||||
|
||||
- (BOOL)prepareForDragOperation:(id < NSDraggingInfo >)sender
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL) performDragOperation:(id<NSDraggingInfo>)sender
|
||||
{
|
||||
callHandleDragDropped(mLastDraggedUrl);
|
||||
return true;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// We use a custom NSWindow for our event handling.
|
||||
|
|
@ -244,7 +288,7 @@
|
|||
|
||||
- (id) init
|
||||
{
|
||||
//[self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType, nil]];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
@ -378,6 +422,8 @@
|
|||
callMouseExit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view
|
||||
{
|
||||
NSScreen *currentScreen = [NSScreen currentScreenForMouseLocation];
|
||||
|
|
|
|||
|
|
@ -24,14 +24,6 @@
|
|||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#include <boost/tr1/functional.hpp>
|
||||
typedef std::tr1::function<void(unsigned short, unsigned int)> KeyCallback;
|
||||
typedef std::tr1::function<void(unsigned int)> ModifierCallback;
|
||||
typedef std::tr1::function<void(float*, unsigned int)> MouseCallback;
|
||||
typedef std::tr1::function<void(wchar_t, unsigned int)> UnicodeCallback;
|
||||
typedef std::tr1::function<void(unsigned int, unsigned int)> ResizeCallback;
|
||||
typedef std::tr1::function<void(float)> ScrollWheelCallback;
|
||||
typedef std::tr1::function<void()> VoidCallback;
|
||||
|
||||
// This will actually hold an NSCursor*, but that type is only available in objective C.
|
||||
typedef void *CursorRef;
|
||||
|
|
@ -59,6 +51,7 @@ void setIBeamCursor();
|
|||
void setPointingHandCursor();
|
||||
void setCopyCursor();
|
||||
void setCrossCursor();
|
||||
void setNotAllowedCursor();
|
||||
void hideNSCursor();
|
||||
void showNSCursor();
|
||||
void hideNSCursorTillMove(bool hide);
|
||||
|
|
@ -103,6 +96,12 @@ void callMiddleMouseUp(float *pos, unsigned int mask);
|
|||
void callFocus();
|
||||
void callFocusLost();
|
||||
|
||||
#include <string>
|
||||
void callHandleDragEntered(std::string url);
|
||||
void callHandleDragExited(std::string url);
|
||||
void callHandleDragUpdated(std::string url);
|
||||
void callHandleDragDropped(std::string url);
|
||||
|
||||
NSWindowRef getMainAppWindow();
|
||||
GLViewRef getGLView();
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,12 @@ void setCrossCursor()
|
|||
[cursor set];
|
||||
}
|
||||
|
||||
void setNotAllowedCursor()
|
||||
{
|
||||
NSCursor *cursor = [NSCursor operationNotAllowedCursor];
|
||||
[cursor set];
|
||||
}
|
||||
|
||||
void hideNSCursor()
|
||||
{
|
||||
[NSCursor hide];
|
||||
|
|
|
|||
|
|
@ -248,7 +248,6 @@ void callLeftMouseDown(float *pos, MASK mask)
|
|||
outCoords.mX = llround(pos[0]);
|
||||
outCoords.mY = llround(pos[1]);
|
||||
gWindowImplementation->getCallbacks()->handleMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
|
||||
LL_INFOS("Window") << outCoords.mX << ", " << outCoords.mY << LL_ENDL;
|
||||
}
|
||||
|
||||
void callLeftMouseUp(float *pos, MASK mask)
|
||||
|
|
@ -285,7 +284,6 @@ void callMouseMoved(float *pos, MASK mask)
|
|||
gWindowImplementation->getMouseDeltas(deltas);
|
||||
outCoords.mX += deltas[0];
|
||||
outCoords.mY += deltas[1];
|
||||
LL_INFOS("Mouse Movement") << "Moved coords: " << outCoords.mX << ", " << outCoords.mY << LL_ENDL;
|
||||
gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
|
||||
gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0);
|
||||
}
|
||||
|
|
@ -339,6 +337,26 @@ void callMiddleMouseUp(float *pos, MASK mask)
|
|||
gWindowImplementation->getCallbacks()->handleMiddleMouseUp(gWindowImplementation, outCoords, mask);
|
||||
}
|
||||
|
||||
void callHandleDragEntered(std::string url)
|
||||
{
|
||||
gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_START_TRACKING);
|
||||
}
|
||||
|
||||
void callHandleDragExited(std::string url)
|
||||
{
|
||||
gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_STOP_TRACKING);
|
||||
}
|
||||
|
||||
void callHandleDragUpdated(std::string url)
|
||||
{
|
||||
gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_TRACK);
|
||||
}
|
||||
|
||||
void callHandleDragDropped(std::string url)
|
||||
{
|
||||
gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_DROPPED);
|
||||
}
|
||||
|
||||
void LLWindowMacOSX::updateMouseDeltas(float* deltas)
|
||||
{
|
||||
if (mCursorDecoupled)
|
||||
|
|
@ -1784,7 +1802,6 @@ S16 LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef t
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefCon,
|
||||
DragRef drag)
|
||||
{
|
||||
|
|
@ -1792,73 +1809,18 @@ OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefC
|
|||
return self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_DROPPED);
|
||||
|
||||
}
|
||||
|
||||
OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDropAction action)
|
||||
*/
|
||||
void LLWindowMacOSX::handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action)
|
||||
{
|
||||
OSErr result = dragNotAcceptedErr; // overall function result
|
||||
OSErr err = noErr; // for local error handling
|
||||
MASK mask = LLWindowMacOSX::modifiersToMask(getModifiers());
|
||||
|
||||
// Get the mouse position and modifiers of this drag.
|
||||
SInt16 modifiers, mouseDownModifiers, mouseUpModifiers;
|
||||
::GetDragModifiers(drag, &modifiers, &mouseDownModifiers, &mouseUpModifiers);
|
||||
MASK mask = LLWindowMacOSX::modifiersToMask(modifiers);
|
||||
|
||||
Point mouse_point;
|
||||
float mouse_point[2];
|
||||
// This will return the mouse point in global screen coords
|
||||
::GetDragMouse(drag, &mouse_point, NULL);
|
||||
LLCoordScreen screen_coords(mouse_point.h, mouse_point.v);
|
||||
getCursorPos(mWindow, mouse_point);
|
||||
LLCoordScreen screen_coords(mouse_point[0], mouse_point[1]);
|
||||
LLCoordGL gl_pos;
|
||||
convertCoords(screen_coords, &gl_pos);
|
||||
|
||||
// Look at the pasteboard and try to extract an URL from it
|
||||
PasteboardRef pasteboard;
|
||||
if(GetDragPasteboard(drag, &pasteboard) == noErr)
|
||||
{
|
||||
ItemCount num_items = 0;
|
||||
// Treat an error here as an item count of 0
|
||||
(void)PasteboardGetItemCount(pasteboard, &num_items);
|
||||
|
||||
// Only deal with single-item drags.
|
||||
if(num_items == 1)
|
||||
{
|
||||
PasteboardItemID item_id = NULL;
|
||||
CFArrayRef flavors = NULL;
|
||||
CFDataRef data = NULL;
|
||||
|
||||
err = PasteboardGetItemIdentifier(pasteboard, 1, &item_id); // Yes, this really is 1-based.
|
||||
|
||||
// Try to extract an URL from the pasteboard
|
||||
if(err == noErr)
|
||||
{
|
||||
err = PasteboardCopyItemFlavors( pasteboard, item_id, &flavors);
|
||||
}
|
||||
|
||||
if(err == noErr)
|
||||
{
|
||||
if(CFArrayContainsValue(flavors, CFRangeMake(0, CFArrayGetCount(flavors)), kUTTypeURL))
|
||||
{
|
||||
// This is an URL.
|
||||
err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeURL, &data);
|
||||
}
|
||||
else if(CFArrayContainsValue(flavors, CFRangeMake(0, CFArrayGetCount(flavors)), kUTTypeUTF8PlainText))
|
||||
{
|
||||
// This is a string that might be an URL.
|
||||
err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeUTF8PlainText, &data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(flavors != NULL)
|
||||
{
|
||||
CFRelease(flavors);
|
||||
}
|
||||
|
||||
if(data != NULL)
|
||||
{
|
||||
std::string url;
|
||||
url.assign((char*)CFDataGetBytePtr(data), CFDataGetLength(data));
|
||||
CFRelease(data);
|
||||
|
||||
if(!url.empty())
|
||||
{
|
||||
LLWindowCallbacks::DragNDropResult res =
|
||||
|
|
@ -1868,23 +1830,17 @@ OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDrop
|
|||
case LLWindowCallbacks::DND_NONE: // No drop allowed
|
||||
if (action == LLWindowCallbacks::DNDA_TRACK)
|
||||
{
|
||||
mDragOverrideCursor = kThemeNotAllowedCursor;
|
||||
mDragOverrideCursor = 0;
|
||||
}
|
||||
else {
|
||||
mDragOverrideCursor = -1;
|
||||
}
|
||||
break;
|
||||
case LLWindowCallbacks::DND_MOVE: // Drop accepted would result in a "move" operation
|
||||
mDragOverrideCursor = kThemePointingHandCursor;
|
||||
result = noErr;
|
||||
mDragOverrideCursor = UI_CURSOR_NO;
|
||||
break;
|
||||
case LLWindowCallbacks::DND_COPY: // Drop accepted would result in a "copy" operation
|
||||
mDragOverrideCursor = kThemeCopyArrowCursor;
|
||||
result = noErr;
|
||||
break;
|
||||
case LLWindowCallbacks::DND_LINK: // Drop accepted would result in a "link" operation:
|
||||
mDragOverrideCursor = kThemeAliasArrowCursor;
|
||||
result = noErr;
|
||||
mDragOverrideCursor = UI_CURSOR_ARROWCOPY;
|
||||
break;
|
||||
default:
|
||||
mDragOverrideCursor = -1;
|
||||
|
|
@ -1903,15 +1859,19 @@ OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDrop
|
|||
}
|
||||
else {
|
||||
// Override the cursor
|
||||
SetThemeCursor(mDragOverrideCursor);
|
||||
}
|
||||
|
||||
}
|
||||
switch (mDragOverrideCursor) {
|
||||
case 0:
|
||||
setArrowCursor();
|
||||
break;
|
||||
case UI_CURSOR_NO:
|
||||
setNotAllowedCursor();
|
||||
case UI_CURSOR_ARROWCOPY:
|
||||
setCopyCursor();
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
#endif // LL_OS_DRAGDROP_ENABLED
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ public:
|
|||
void updateMouseDeltas(float* deltas);
|
||||
void getMouseDeltas(float* delta);
|
||||
|
||||
void handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action);
|
||||
|
||||
protected:
|
||||
LLWindowMacOSX(LLWindowCallbacks* callbacks,
|
||||
|
|
@ -164,12 +165,11 @@ protected:
|
|||
static MASK modifiersToMask(S16 modifiers);
|
||||
|
||||
#if LL_OS_DRAGDROP_ENABLED
|
||||
/*
|
||||
static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
|
||||
void * handlerRefCon, DragRef theDrag);
|
||||
static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
|
||||
OSErr handleDragNDrop(DragRef theDrag, LLWindowCallbacks::DragNDropAction action);
|
||||
*/
|
||||
|
||||
//static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
|
||||
//static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
|
||||
|
||||
|
||||
#endif // LL_OS_DRAGDROP_ENABLED
|
||||
|
||||
//
|
||||
|
|
|
|||
Loading…
Reference in New Issue