diff options
-rw-r--r-- | cocoa/ScintillaCocoa.mm | 84 | ||||
-rw-r--r-- | cocoa/ScintillaView.h | 6 | ||||
-rw-r--r-- | cocoa/ScintillaView.mm | 63 |
3 files changed, 120 insertions, 33 deletions
diff --git a/cocoa/ScintillaCocoa.mm b/cocoa/ScintillaCocoa.mm index ced7be3d6..be5ec9445 100644 --- a/cocoa/ScintillaCocoa.mm +++ b/cocoa/ScintillaCocoa.mm @@ -1242,6 +1242,60 @@ void ScintillaCocoa::DragScroll() } +//----------------- DragProviderSource ------------------------------------------------------- + +@interface DragProviderSource : NSObject <NSPasteboardItemDataProvider> +{ + SelectionText selectedText; +} + +@end + +@implementation DragProviderSource + +- (id)initWithSelectedText:(const SelectionText *)other +{ + self = [super init]; + + if (self) { + selectedText.Copy(*other); + } + + return self; +} + +- (void)pasteboard:(NSPasteboard *)pasteboard item:(NSPasteboardItem *)item provideDataForType:(NSString *)type +{ + if (selectedText.Length() == 0) + return; + + if (([type compare: NSPasteboardTypeString] != NSOrderedSame) && + ([type compare: ScintillaRecPboardType] != NSOrderedSame)) + return; + + CFStringEncoding encoding = EncodingFromCharacterSet(selectedText.codePage == SC_CP_UTF8, + selectedText.characterSet); + CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault, + reinterpret_cast<const UInt8 *>(selectedText.Data()), + selectedText.Length(), encoding, false); + + if ([type compare: NSPasteboardTypeString] == NSOrderedSame) + { + [pasteboard setString:(NSString *)cfsVal forType: NSStringPboardType]; + } + else if ([type compare: ScintillaRecPboardType] == NSOrderedSame) + { + // This is specific to scintilla, allows us to drag rectangular selections around the document. + if (selectedText.rectangular) + [pasteboard setString:(NSString *)cfsVal forType: ScintillaRecPboardType]; + } + + if (cfsVal) + CFRelease(cfsVal); +} + +@end + //-------------------------------------------------------------------------------------------------- /** @@ -1335,7 +1389,7 @@ void ScintillaCocoa::StartDrag() // Prepare drag image. NSRect selectionRectangle = PRectangleToNSRect(rcSel); - NSView* content = ContentView(); + SCIContentView* content = ContentView(); // To get a bitmap of the text we're dragging, we just use Paint on a pixmap surface. SurfaceImpl *sw = new SurfaceImpl(); @@ -1401,13 +1455,27 @@ void ScintillaCocoa::StartDrag() NSPoint startPoint; startPoint.x = selectionRectangle.origin.x + client.left; startPoint.y = selectionRectangle.origin.y + selectionRectangle.size.height + client.top; - [content dragImage: dragImage - at: startPoint - offset: NSZeroSize - event: lastMouseEvent // Set in MouseMove. - pasteboard: pasteboard - source: content - slideBack: YES]; + + NSPasteboardItem *pbItem = [NSPasteboardItem new]; + DragProviderSource *dps = [[[DragProviderSource alloc] initWithSelectedText:&selectedText] autorelease]; + + NSArray *pbTypes = selectedText.rectangular ? + @[NSPasteboardTypeString, ScintillaRecPboardType] : + @[NSPasteboardTypeString]; + [pbItem setDataProvider:dps forTypes:pbTypes]; + NSDraggingItem *dragItem = [[NSDraggingItem alloc ]initWithPasteboardWriter:pbItem]; + [pbItem release]; + + NSScrollView *scrollContainer = ScrollContainer(); + NSRect contentRect = [[scrollContainer contentView] bounds]; + NSRect draggingRect = NSOffsetRect(selectionRectangle, contentRect.origin.x, contentRect.origin.y); + [dragItem setDraggingFrame:draggingRect contents:dragImage]; + NSDraggingSession *dragSession = + [content beginDraggingSessionWithItems:@[[dragItem autorelease]] + event:lastMouseEvent + source:content]; + dragSession.animatesToStartingPositionsOnCancelOrFail = YES; + dragSession.draggingFormation = NSDraggingFormationNone; } //-------------------------------------------------------------------------------------------------- diff --git a/cocoa/ScintillaView.h b/cocoa/ScintillaView.h index e328646a5..ec2c8ee14 100644 --- a/cocoa/ScintillaView.h +++ b/cocoa/ScintillaView.h @@ -70,7 +70,11 @@ extern NSString *const SCIUpdateUINotification; * SCIContentView is the Cocoa interface to the Scintilla backend. It handles text input and * provides a canvas for painting the output. */ -@interface SCIContentView : NSView <NSTextInputClient, NSUserInterfaceValidations> +@interface SCIContentView : NSView < + NSTextInputClient, + NSUserInterfaceValidations, + NSDraggingSource, + NSDraggingDestination> { @private ScintillaView* mOwner; diff --git a/cocoa/ScintillaView.mm b/cocoa/ScintillaView.mm index d5f658755..13dd1d4f9 100644 --- a/cocoa/ScintillaView.mm +++ b/cocoa/ScintillaView.mm @@ -731,6 +731,45 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) //-------------------------------------------------------------------------------------------------- /** + * Implement NSDraggingSource. + */ + +- (NSDragOperation)draggingSession: (NSDraggingSession *) session +sourceOperationMaskForDraggingContext: (NSDraggingContext) context +{ + switch(context) + { + case NSDraggingContextOutsideApplication: + return NSDragOperationCopy | NSDragOperationMove | NSDragOperationDelete; + + case NSDraggingContextWithinApplication: + default: + return NSDragOperationCopy | NSDragOperationMove | NSDragOperationDelete; + } +} + +- (void)draggingSession:(NSDraggingSession *)session + movedToPoint:(NSPoint)screenPoint +{ +} + +- (void)draggingSession:(NSDraggingSession *)session + endedAtPoint:(NSPoint)screenPoint + operation:(NSDragOperation)operation +{ + if (operation == NSDragOperationDelete) + { + mOwner.backend->WndProc(SCI_CLEAR, 0, 0); + } +} + +/** + * Implement NSDraggingDestination. + */ + +//-------------------------------------------------------------------------------------------------- + +/** * Called when an external drag operation enters the view. */ - (NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender @@ -776,30 +815,6 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) //-------------------------------------------------------------------------------------------------- /** - * Returns operations we allow as drag source. - */ -- (NSDragOperation) draggingSourceOperationMaskForLocal: (BOOL) isLocal -{ -// Scintilla does not choose different operations for other applications -#pragma unused(isLocal) - return NSDragOperationCopy | NSDragOperationMove | NSDragOperationDelete; -} - -//-------------------------------------------------------------------------------------------------- - -/** - * Finished a drag: may need to delete selection. - */ - -- (void)draggedImage:(NSImage *)image endedAt:(NSPoint)screenPoint operation:(NSDragOperation)operation { - if (operation == NSDragOperationDelete) { - mOwner.backend->WndProc(SCI_CLEAR, 0, 0); - } -} - -//-------------------------------------------------------------------------------------------------- - -/** * Drag operation is done. Notify editor. */ - (void) concludeDragOperation: (id <NSDraggingInfo>) sender |