Drag and drop support: refactoring of image from link and image from selection
authorenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Jan 2011 20:12:03 +0000 (20:12 +0000)
committerenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Jan 2011 20:12:03 +0000 (20:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=52496

Reviewed by Alexey Proskuryakov.

Source/WebCore:

This work cleans up the Mac code and makes it more similar to the Windows implementation,
avoiding the use of an NSView when the FrameView can be used.
The refactoring is a necessary step towards the complete support of drag and drop
in WebKit2.

* page/mac/FrameMac.mm:
(WebCore::Frame::imageFromRect): Modified to use FrameView instead of NSView
to generate the image for drag.

Source/WebKit/mac:

This work cleans up the Mac code and makes it more similar to the Windows implementation,
avoiding the use of an NSView when the FrameView can be used.
The refactoring is a necessary step towards the complete support of drag and drop
in WebKit2.

* WebCoreSupport/WebDragClient.mm:
(WebDragClient::createDragImageForLink): Added.
* WebView/WebHTMLView.mm: Removed dragImageFromLink and dragImageFromURL.
* WebView/WebHTMLViewPrivate.h: Removed dragImageFromLink and dragImageFromURL.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@75963 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/page/mac/FrameMac.mm
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebCoreSupport/WebDragClient.mm
Source/WebKit/mac/WebView/WebHTMLView.mm
Source/WebKit/mac/WebView/WebHTMLViewPrivate.h

index 9816af3b7f882bba922693cd86710aa791253829..0941f4038dc2fc41c588dd1f3cae597916148ec9 100644 (file)
@@ -1,3 +1,19 @@
+2011-01-17  Enrica Casucci  <enrica@apple.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Drag and drop support: refactoring of image from link and image from selection
+        https://bugs.webkit.org/show_bug.cgi?id=52496
+
+        This work cleans up the Mac code and makes it more similar to the Windows implementation,
+        avoiding the use of an NSView when the FrameView can be used.
+        The refactoring is a necessary step towards the complete support of drag and drop
+        in WebKit2.
+        
+        * page/mac/FrameMac.mm:
+        (WebCore::Frame::imageFromRect): Modified to use FrameView instead of NSView
+        to generate the image for drag.
+
 2011-01-17  Dan Bernstein  <mitz@apple.com>
 
         Rubber-stamped by Mark Rowe.
index d4e4098cb09b6945f3ab9a15ad1ab2ce6828878e..b49fffb642d9d23ea4b99c8b4746f23866607e97 100644 (file)
@@ -255,50 +255,33 @@ NSString* Frame::matchLabelsAgainstElement(NSArray* labels, Element* element)
 
 NSImage* Frame::imageFromRect(NSRect rect) const
 {
-    NSView* view = m_view->documentView();
-    if (!view)
-        return nil;
-    if (![view respondsToSelector:@selector(drawSingleRect:)])
-        return nil;
+    PaintBehavior oldBehavior = m_view->paintBehavior();
+    m_view->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
     
-    PaintBehavior oldPaintBehavior = m_view->paintBehavior();
-    m_view->setPaintBehavior(oldPaintBehavior | PaintBehaviorFlattenCompositingLayers);
-
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
     
-    NSRect bounds = [view bounds];
-    
-    // Round image rect size in window coordinate space to avoid pixel cracks at HiDPI (4622794)
-    rect = [view convertRect:rect toView:nil];
-    rect.size.height = roundf(rect.size.height);
-    rect.size.width = roundf(rect.size.width);
-    rect = [view convertRect:rect fromView:nil];
-    
     NSImage* resultImage = [[[NSImage alloc] initWithSize:rect.size] autorelease];
-
+    
     if (rect.size.width != 0 && rect.size.height != 0) {
         [resultImage setFlipped:YES];
         [resultImage lockFocus];
-        CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
-        CGContextSaveGState(context);
-        CGContextTranslateCTM(context, bounds.origin.x - rect.origin.x, bounds.origin.y - rect.origin.y);
 
-        // Note: Must not call drawRect: here, because drawRect: assumes that it's called from AppKit's
-        // display machinery. It calls getRectsBeingDrawn:count:, which can only be called inside
-        // when a real AppKit display is underway.
-        [view drawSingleRect:rect];
+        GraphicsContext graphicsContext((CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]);        
+        graphicsContext.save();
+        graphicsContext.translate(-rect.origin.x, -rect.origin.y);
+        m_view->paintContents(&graphicsContext, IntRect(rect));
+        graphicsContext.restore();
 
-        CGContextRestoreGState(context);
         [resultImage unlockFocus];
         [resultImage setFlipped:NO];
     }
-
-    m_view->setPaintBehavior(oldPaintBehavior);
+    
+    m_view->setPaintBehavior(oldBehavior);
     return resultImage;
-
+    
     END_BLOCK_OBJC_EXCEPTIONS;
     
-    m_view->setPaintBehavior(oldPaintBehavior);
+    m_view->setPaintBehavior(oldBehavior);
     return nil;
 }
 
index 0646b1330e83c8a76cbfed6c85bcc0209752affd..de2aff02bb05c66fefd230670f2bc9f2e84e4bac 100644 (file)
@@ -1,3 +1,20 @@
+2011-01-17  Enrica Casucci  <enrica@apple.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Drag and drop support: refactoring of image from link and image from selection
+        https://bugs.webkit.org/show_bug.cgi?id=52496
+
+        This work cleans up the Mac code and makes it more similar to the Windows implementation,
+        avoiding the use of an NSView when the FrameView can be used.
+        The refactoring is a necessary step towards the complete support of drag and drop
+        in WebKit2.
+
+        * WebCoreSupport/WebDragClient.mm:
+        (WebDragClient::createDragImageForLink): Added.
+        * WebView/WebHTMLView.mm: Removed dragImageFromLink and dragImageFromURL.
+        * WebView/WebHTMLViewPrivate.h: Removed dragImageFromLink and dragImageFromURL.
+
 2011-01-17  Pavel Feldman  <pfeldman@chromium.org>
 
         Reviewed by Yury Semikhatsky.
index 42c3d334bd18abf96c3b9dd4ae6d29fe0d3fa3de..b3af6582d3e20970f8341df2637a36cbed591f6d 100644 (file)
 #import "WebHTMLViewInternal.h"
 #import "WebHTMLViewPrivate.h"
 #import "WebKitLogging.h"
+#import "WebKitNSStringExtras.h"
 #import "WebNSPasteboardExtras.h"
 #import "WebNSURLExtras.h"
+#import "WebStringTruncator.h"
 #import "WebUIDelegate.h"
 #import "WebUIDelegatePrivate.h"
 #import "WebViewInternal.h"
 #import <WebCore/ClipboardMac.h>
 #import <WebCore/DragData.h>
+#import <WebCore/Editor.h>
+#import <WebCore/EditorClient.h>
 #import <WebCore/EventHandler.h>
 #import <WebCore/Frame.h>
 #import <WebCore/FrameView.h>
 
 using namespace WebCore;
 
+const float DragLabelBorderX = 4;
+//Keep border_y in synch with DragController::LinkDragBorderInset
+const float DragLabelBorderY = 2;
+const float DragLabelRadius = 5;
+const float LabelBorderYOffset = 2;
+
+const float MinDragLabelWidthBeforeClip = 120;
+const float MaxDragLabelWidth = 320;
+
+const float DragLinkLabelFontsize = 11;
+const float DragLinkUrlFontSize = 10;
+
 WebDragClient::WebDragClient(WebView* webView)
     : m_webView(webView) 
 {
@@ -120,15 +136,83 @@ DragImageRef WebDragClient::createDragImageForLink(KURL& url, const String& titl
 {
     if (!frame)
         return nil;
-    WebHTMLView *htmlView = (WebHTMLView *)[[kit(frame) frameView] documentView];
     NSString *label = 0;
     if (!title.isEmpty())
         label = title;
     NSURL *cocoaURL = url;
-    return [htmlView _dragImageForURL:[cocoaURL _web_userVisibleString] withLabel:label];
+    NSString *urlString = [cocoaURL _web_userVisibleString];
+
+    BOOL drawURLString = YES;
+    BOOL clipURLString = NO;
+    BOOL clipLabelString = NO;
+
+    if (!label) {
+        drawURLString = NO;
+        label = urlString;
+    }
+
+    NSFont *labelFont = [[NSFontManager sharedFontManager] convertFont:[NSFont systemFontOfSize:DragLinkLabelFontsize]
+                                                           toHaveTrait:NSBoldFontMask];
+    NSFont *urlFont = [NSFont systemFontOfSize:DragLinkUrlFontSize];
+    NSSize labelSize;
+    labelSize.width = [label _web_widthWithFont: labelFont];
+    labelSize.height = [labelFont ascender] - [labelFont descender];
+    if (labelSize.width > MaxDragLabelWidth){
+        labelSize.width = MaxDragLabelWidth;
+        clipLabelString = YES;
+    }
+
+    NSSize imageSize;
+    imageSize.width = labelSize.width + DragLabelBorderX * 2;
+    imageSize.height = labelSize.height + DragLabelBorderY * 2;
+    if (drawURLString) {
+        NSSize urlStringSize;
+        urlStringSize.width = [urlString _web_widthWithFont: urlFont];
+        urlStringSize.height = [urlFont ascender] - [urlFont descender];
+        imageSize.height += urlStringSize.height;
+        if (urlStringSize.width > MaxDragLabelWidth) {
+            imageSize.width = max(MaxDragLabelWidth + DragLabelBorderY * 2, MinDragLabelWidthBeforeClip);
+            clipURLString = YES;
+        } else
+              imageSize.width = max(labelSize.width + DragLabelBorderX * 2, urlStringSize.width + DragLabelBorderX * 2);
+    }
+    NSImage *dragImage = [[[NSImage alloc] initWithSize: imageSize] autorelease];
+    [dragImage lockFocus];
+
+    [[NSColor colorWithDeviceRed: 0.7f green: 0.7f blue: 0.7f alpha: 0.8f] set];
+
+    // Drag a rectangle with rounded corners
+    NSBezierPath *path = [NSBezierPath bezierPath];
+    [path appendBezierPathWithOvalInRect: NSMakeRect(0, 0, DragLabelRadius * 2, DragLabelRadius * 2)];
+    [path appendBezierPathWithOvalInRect: NSMakeRect(0, imageSize.height - DragLabelRadius * 2, DragLabelRadius * 2, DragLabelRadius * 2)];
+    [path appendBezierPathWithOvalInRect: NSMakeRect(imageSize.width - DragLabelRadius * 2, imageSize.height - DragLabelRadius * 2, DragLabelRadius * 2, DragLabelRadius * 2)];
+    [path appendBezierPathWithOvalInRect: NSMakeRect(imageSize.width - DragLabelRadius * 2, 0, DragLabelRadius * 2, DragLabelRadius * 2)];
+
+    [path appendBezierPathWithRect: NSMakeRect(DragLabelRadius, 0, imageSize.width - DragLabelRadius * 2, imageSize.height)];
+    [path appendBezierPathWithRect: NSMakeRect(0, DragLabelRadius, DragLabelRadius + 10, imageSize.height - 2 * DragLabelRadius)];
+    [path appendBezierPathWithRect: NSMakeRect(imageSize.width - DragLabelRadius - 20, DragLabelRadius, DragLabelRadius + 20, imageSize.height - 2 * DragLabelRadius)];
+    [path fill];
+
+    NSColor *topColor = [NSColor colorWithDeviceWhite:0.0f alpha:0.75f];
+    NSColor *bottomColor = [NSColor colorWithDeviceWhite:1.0f alpha:0.5f];
+    if (drawURLString) {
+        if (clipURLString)
+            urlString = [WebStringTruncator centerTruncateString: urlString toWidth:imageSize.width - (DragLabelBorderX * 2) withFont:urlFont];
+
+       [urlString _web_drawDoubledAtPoint:NSMakePoint(DragLabelBorderX, DragLabelBorderY - [urlFont descender]) 
+                             withTopColor:topColor bottomColor:bottomColor font:urlFont];
+    }
+
+    if (clipLabelString)
+        label = [WebStringTruncator rightTruncateString: label toWidth:imageSize.width - (DragLabelBorderX * 2) withFont:labelFont];
+    [label _web_drawDoubledAtPoint:NSMakePoint (DragLabelBorderX, imageSize.height - LabelBorderYOffset - [labelFont pointSize])
+                      withTopColor:topColor bottomColor:bottomColor font:labelFont];
+
+    [dragImage unlockFocus];
+
+    return dragImage;
 }
 
-
 void WebDragClient::declareAndWriteDragImage(NSPasteboard* pasteboard, DOMElement* element, NSURL* URL, NSString* title, WebCore::Frame* frame) 
 {
     ASSERT(pasteboard);
index bf91af9f286a6f103fc07881e75d341acb247bf0..ec5ff519b5438cd518eaa5d512d6c7e119f4df9c 100644 (file)
@@ -68,7 +68,6 @@
 #import "WebPreferences.h"
 #import "WebPreferencesPrivate.h"
 #import "WebResourcePrivate.h"
-#import "WebStringTruncator.h"
 #import "WebTextCompletionController.h"
 #import "WebTypesInternal.h"
 #import "WebUIDelegatePrivate.h"
@@ -360,18 +359,6 @@ const float _WebHTMLViewPrintingMaximumShrinkFactor = 2;
 
 #define AUTOSCROLL_INTERVAL             0.1f
 
-#define DRAG_LABEL_BORDER_X             4.0f
-//Keep border_y in synch with DragController::LinkDragBorderInset
-#define DRAG_LABEL_BORDER_Y             2.0f
-#define DRAG_LABEL_RADIUS               5.0f
-#define DRAG_LABEL_BORDER_Y_OFFSET              2.0f
-
-#define MIN_DRAG_LABEL_WIDTH_BEFORE_CLIP        120.0f
-#define MAX_DRAG_LABEL_WIDTH                    320.0f
-
-#define DRAG_LINK_LABEL_FONT_SIZE   11.0f
-#define DRAG_LINK_URL_FONT_SIZE   10.0f
-
 // Any non-zero value will do, but using something recognizable might help us debug some day.
 #define TRACKING_RECT_TAG 0xBADFACE
 
@@ -1739,87 +1726,6 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
     return [NSArray arrayWithObjects:WebArchivePboardType, NSRTFDPboardType, NSRTFPboardType, NSStringPboardType, nil];
 }
 
-- (NSImage *)_dragImageForURL:(NSString*)urlString withLabel:(NSString*)label
-{
-    BOOL drawURLString = YES;
-    BOOL clipURLString = NO, clipLabelString = NO;
-    
-    if (!label) {
-        drawURLString = NO;
-        label = urlString;
-    }
-    
-    NSFont *labelFont = [[NSFontManager sharedFontManager] convertFont:[NSFont systemFontOfSize:DRAG_LINK_LABEL_FONT_SIZE]
-                                                           toHaveTrait:NSBoldFontMask];
-    NSFont *urlFont = [NSFont systemFontOfSize: DRAG_LINK_URL_FONT_SIZE];
-    NSSize labelSize;
-    labelSize.width = [label _web_widthWithFont: labelFont];
-    labelSize.height = [labelFont ascender] - [labelFont descender];
-    if (labelSize.width > MAX_DRAG_LABEL_WIDTH){
-        labelSize.width = MAX_DRAG_LABEL_WIDTH;
-        clipLabelString = YES;
-    }
-    
-    NSSize imageSize, urlStringSize;
-    imageSize.width = labelSize.width + DRAG_LABEL_BORDER_X * 2.0f;
-    imageSize.height = labelSize.height + DRAG_LABEL_BORDER_Y * 2.0f;
-    if (drawURLString) {
-        urlStringSize.width = [urlString _web_widthWithFont: urlFont];
-        urlStringSize.height = [urlFont ascender] - [urlFont descender];
-        imageSize.height += urlStringSize.height;
-        if (urlStringSize.width > MAX_DRAG_LABEL_WIDTH) {
-            imageSize.width = max(MAX_DRAG_LABEL_WIDTH + DRAG_LABEL_BORDER_X * 2, MIN_DRAG_LABEL_WIDTH_BEFORE_CLIP);
-            clipURLString = YES;
-        } else {
-            imageSize.width = max(labelSize.width + DRAG_LABEL_BORDER_X * 2, urlStringSize.width + DRAG_LABEL_BORDER_X * 2);
-        }
-    }
-    NSImage *dragImage = [[[NSImage alloc] initWithSize: imageSize] autorelease];
-    [dragImage lockFocus];
-    
-    [[NSColor colorWithDeviceRed: 0.7f green: 0.7f blue: 0.7f alpha: 0.8f] set];
-    
-    // Drag a rectangle with rounded corners/
-    NSBezierPath *path = [NSBezierPath bezierPath];
-    [path appendBezierPathWithOvalInRect: NSMakeRect(0.0f, 0.0f, DRAG_LABEL_RADIUS * 2.0f, DRAG_LABEL_RADIUS * 2.0f)];
-    [path appendBezierPathWithOvalInRect: NSMakeRect(0, imageSize.height - DRAG_LABEL_RADIUS * 2.0f, DRAG_LABEL_RADIUS * 2.0f, DRAG_LABEL_RADIUS * 2.0f)];
-    [path appendBezierPathWithOvalInRect: NSMakeRect(imageSize.width - DRAG_LABEL_RADIUS * 2.0f, imageSize.height - DRAG_LABEL_RADIUS * 2.0f, DRAG_LABEL_RADIUS * 2.0f, DRAG_LABEL_RADIUS * 2.0f)];
-    [path appendBezierPathWithOvalInRect: NSMakeRect(imageSize.width - DRAG_LABEL_RADIUS * 2.0f, 0.0f, DRAG_LABEL_RADIUS * 2.0f, DRAG_LABEL_RADIUS * 2.0f)];
-    
-    [path appendBezierPathWithRect: NSMakeRect(DRAG_LABEL_RADIUS, 0.0f, imageSize.width - DRAG_LABEL_RADIUS * 2.0f, imageSize.height)];
-    [path appendBezierPathWithRect: NSMakeRect(0.0f, DRAG_LABEL_RADIUS, DRAG_LABEL_RADIUS + 10.0f, imageSize.height - 2.0f * DRAG_LABEL_RADIUS)];
-    [path appendBezierPathWithRect: NSMakeRect(imageSize.width - DRAG_LABEL_RADIUS - 20.0f, DRAG_LABEL_RADIUS, DRAG_LABEL_RADIUS + 20.0f, imageSize.height - 2.0f * DRAG_LABEL_RADIUS)];
-    [path fill];
-    
-    NSColor *topColor = [NSColor colorWithDeviceWhite:0.0f alpha:0.75f];
-    NSColor *bottomColor = [NSColor colorWithDeviceWhite:1.0f alpha:0.5f];
-    if (drawURLString) {
-        if (clipURLString)
-            urlString = [WebStringTruncator centerTruncateString: urlString toWidth:imageSize.width - (DRAG_LABEL_BORDER_X * 2.0f) withFont:urlFont];
-        
-        [urlString _web_drawDoubledAtPoint:NSMakePoint(DRAG_LABEL_BORDER_X, DRAG_LABEL_BORDER_Y - [urlFont descender]) 
-                              withTopColor:topColor bottomColor:bottomColor font:urlFont];
-    }
-    
-    if (clipLabelString)
-        label = [WebStringTruncator rightTruncateString: label toWidth:imageSize.width - (DRAG_LABEL_BORDER_X * 2.0f) withFont:labelFont];
-    [label _web_drawDoubledAtPoint:NSMakePoint (DRAG_LABEL_BORDER_X, imageSize.height - DRAG_LABEL_BORDER_Y_OFFSET - [labelFont pointSize])
-                      withTopColor:topColor bottomColor:bottomColor font:labelFont];
-    
-    [dragImage unlockFocus];
-    
-    return dragImage;
-}
-
-- (NSImage *)_dragImageForLinkElement:(NSDictionary *)element
-{
-    NSURL *linkURL = [element objectForKey: WebElementLinkURLKey];
-    
-    NSString *label = [element objectForKey: WebElementLinkLabelKey];
-    NSString *urlString = [linkURL _web_userVisibleString];
-    return [self _dragImageForURL:urlString withLabel:label];
-}
-
 - (void)pasteboardChangedOwner:(NSPasteboard *)pasteboard
 {
     [self setPromisedDragTIFFDataSource:0];
index c62713f9d922ab66ac24d52df54c952c36352b8c..9ee807d454916421bde83bf496d93a711479d69b 100644 (file)
@@ -77,8 +77,6 @@ extern const float _WebHTMLViewPrintingMaximumShrinkFactor;
 
 - (void)_frameOrBoundsChanged;
 
-- (NSImage *)_dragImageForLinkElement:(NSDictionary *)element;
-- (NSImage *)_dragImageForURL:(NSString*)linkURL withLabel:(NSString*)label;
 - (void)_handleAutoscrollForMouseDragged:(NSEvent *)event;
 - (WebPluginController *)_pluginController;