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 | 
