summaryrefslogtreecommitdiff
path: root/indra/llwindow
diff options
context:
space:
mode:
authorGeenz <geenz@geenzo.com>2013-01-22 19:59:49 -0500
committerGeenz <geenz@geenzo.com>2013-01-22 19:59:49 -0500
commit461ab912a58b67579fffdf70ec7e38d682927185 (patch)
tree2489ae49226618c7797478ec5ac7b9cef8d540cf /indra/llwindow
parent29e747c4f17818816c502a3aa653b828e689be4a (diff)
Initial Cocoa drag and drop support.
Diffstat (limited to 'indra/llwindow')
-rw-r--r--indra/llwindow/llopenglview-objc.h1
-rw-r--r--indra/llwindow/llopenglview-objc.mm50
-rw-r--r--indra/llwindow/llwindowmacosx-objc.h15
-rw-r--r--indra/llwindow/llwindowmacosx-objc.mm6
-rw-r--r--indra/llwindow/llwindowmacosx.cpp186
-rw-r--r--indra/llwindow/llwindowmacosx.h16
6 files changed, 143 insertions, 131 deletions
diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index dd2f35aafc..1592e6e01d 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -15,6 +15,7 @@
@interface LLOpenGLView : NSOpenGLView
{
NSPoint mousePos;
+ std::string mLastDraggedUrl;
}
- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index ca66143b78..763cf0c981 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -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];
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 57b3d11296..ebc1633f9d 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -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();
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index b6e5767203..7867226476 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -143,6 +143,12 @@ void setCrossCursor()
[cursor set];
}
+void setNotAllowedCursor()
+{
+ NSCursor *cursor = [NSCursor operationNotAllowedCursor];
+ [cursor set];
+}
+
void hideNSCursor()
{
[NSCursor hide];
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 95ad87d58f..f25fc82896 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -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,126 +1809,69 @@ 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
-
- // Get the mouse position and modifiers of this drag.
- SInt16 modifiers, mouseDownModifiers, mouseUpModifiers;
- ::GetDragModifiers(drag, &modifiers, &mouseDownModifiers, &mouseUpModifiers);
- MASK mask = LLWindowMacOSX::modifiersToMask(modifiers);
+ MASK mask = LLWindowMacOSX::modifiersToMask(getModifiers());
- 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)
+
+ if(!url.empty())
{
- 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))
+ LLWindowCallbacks::DragNDropResult res =
+ mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url);
+
+ switch (res) {
+ case LLWindowCallbacks::DND_NONE: // No drop allowed
+ if (action == LLWindowCallbacks::DNDA_TRACK)
{
- // This is a string that might be an URL.
- err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeUTF8PlainText, &data);
+ mDragOverrideCursor = 0;
}
-
- }
-
- 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 =
- mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url);
-
- switch (res) {
- case LLWindowCallbacks::DND_NONE: // No drop allowed
- if (action == LLWindowCallbacks::DNDA_TRACK)
- {
- mDragOverrideCursor = kThemeNotAllowedCursor;
- }
- else {
- mDragOverrideCursor = -1;
- }
- break;
- case LLWindowCallbacks::DND_MOVE: // Drop accepted would result in a "move" operation
- mDragOverrideCursor = kThemePointingHandCursor;
- result = noErr;
- 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;
- break;
- default:
- mDragOverrideCursor = -1;
- break;
- }
- // This overrides the cursor being set by setCursor.
- // This is a bit of a hack workaround because lots of areas
- // within the viewer just blindly set the cursor.
- if (mDragOverrideCursor == -1)
- {
- // Restore the cursor
- ECursorType temp_cursor = mCurrentCursor;
- // get around the "setting the same cursor" code in setCursor()
- mCurrentCursor = UI_CURSOR_COUNT;
- setCursor(temp_cursor);
- }
- else {
- // Override the cursor
- SetThemeCursor(mDragOverrideCursor);
- }
-
+ else {
+ mDragOverrideCursor = -1;
}
- }
+ break;
+ case LLWindowCallbacks::DND_MOVE: // Drop accepted would result in a "move" operation
+ mDragOverrideCursor = UI_CURSOR_NO;
+ break;
+ case LLWindowCallbacks::DND_COPY: // Drop accepted would result in a "copy" operation
+ mDragOverrideCursor = UI_CURSOR_ARROWCOPY;
+ break;
+ default:
+ mDragOverrideCursor = -1;
+ break;
+ }
+ // This overrides the cursor being set by setCursor.
+ // This is a bit of a hack workaround because lots of areas
+ // within the viewer just blindly set the cursor.
+ if (mDragOverrideCursor == -1)
+ {
+ // Restore the cursor
+ ECursorType temp_cursor = mCurrentCursor;
+ // get around the "setting the same cursor" code in setCursor()
+ mCurrentCursor = UI_CURSOR_COUNT;
+ setCursor(temp_cursor);
+ }
+ else {
+ // Override the cursor
+ 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
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index c5e1b2290b..14d6e70fb3 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -123,7 +123,8 @@ 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
//
@@ -202,7 +202,7 @@ protected:
U32 mFSAASamples;
BOOL mForceRebuild;
- S32 mDragOverrideCursor;
+ S32 mDragOverrideCursor;
F32 mBounceTime;
//NMRec mBounceRec;