Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: chrome/browser/cocoa/bookmark_button.mm

Issue 180036: Make download items drag sources on OS X. (Closed)
Patch Set: comments Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/logging.h" 5 #include "base/logging.h"
6 #import "base/scoped_nsobject.h" 6 #import "base/scoped_nsobject.h"
7 #import "chrome/browser/cocoa/bookmark_button.h" 7 #import "chrome/browser/cocoa/bookmark_button.h"
8 #import "chrome/browser/cocoa/bookmark_button_cell.h" 8 #import "chrome/browser/cocoa/bookmark_button_cell.h"
9 #import "third_party/GTM/AppKit/GTMTheme.h"
10
11 namespace {
12
13 // Code taken from <http://codereview.chromium.org/180036/diff/3001/3004>.
14 // TODO(viettrungluu): Do we want common, standard code for drag hysteresis?
15 const CGFloat kWebDragStartHysteresisX = 5.0;
16 const CGFloat kWebDragStartHysteresisY = 5.0;
17 9
18 // The opacity of the bookmark button drag image. 10 // The opacity of the bookmark button drag image.
19 const CGFloat kDragImageOpacity = 0.7; 11 static const CGFloat kDragImageOpacity = 0.7;
20
21 }
22 12
23 @interface BookmarkButton(Private) 13 @interface BookmarkButton(Private)
24 14
25 // Make a drag image for the button. 15 // Make a drag image for the button.
26 - (NSImage*)dragImage; 16 - (NSImage*)dragImage;
27 17
28 @end // @interface BookmarkButton(Private) 18 @end // @interface BookmarkButton(Private)
29 19
30 @implementation BookmarkButton 20 @implementation BookmarkButton
31 21
32 @synthesize draggable = draggable_;
33 @synthesize delegate = delegate_; 22 @synthesize delegate = delegate_;
34 23
35 - (id)initWithFrame:(NSRect)frame {
36 if ((self = [super initWithFrame:frame])) {
37 draggable_ = YES;
38 }
39 return self;
40 }
41
42 // By default, NSButton ignores middle-clicks. 24 // By default, NSButton ignores middle-clicks.
43 - (void)otherMouseUp:(NSEvent*)event { 25 - (void)otherMouseUp:(NSEvent*)event {
44 [self performClick:self]; 26 [self performClick:self];
45 } 27 }
46 28
29 // Overridden from DraggableButton.
47 - (void)beginDrag:(NSEvent*)event { 30 - (void)beginDrag:(NSEvent*)event {
48 // Starting drag. Never start another drag until another mouse down.
49 mayDragStart_ = NO;
50
51 if (delegate_) { 31 if (delegate_) {
52 // Ask our delegate to fill the pasteboard for us. 32 // Ask our delegate to fill the pasteboard for us.
53 NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; 33 NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
54 34
55 [delegate_ fillPasteboard:pboard forDragOfButton:self]; 35 [delegate_ fillPasteboard:pboard forDragOfButton:self];
56 36
57 // At the moment, moving bookmarks causes their buttons (like me!) 37 // At the moment, moving bookmarks causes their buttons (like me!)
58 // to be destroyed and rebuilt. Make sure we don't go away while on 38 // to be destroyed and rebuilt. Make sure we don't go away while on
59 // the stack. 39 // the stack.
60 [self retain]; 40 [self retain];
61 41
62 CGFloat yAt = [self bounds].size.height; 42 CGFloat yAt = [self bounds].size.height;
63 NSSize dragOffset = NSMakeSize(0.0, 0.0); 43 NSSize dragOffset = NSMakeSize(0.0, 0.0);
64 [self dragImage:[self dragImage] at:NSMakePoint(0, yAt) offset:dragOffset 44 [self dragImage:[self dragImage] at:NSMakePoint(0, yAt) offset:dragOffset
65 event:event pasteboard:pboard source:self slideBack:YES]; 45 event:event pasteboard:pboard source:self slideBack:YES];
66 46
67 // And we're done. 47 // And we're done.»
68 [self autorelease]; 48 [self autorelease];
69 } else { 49 } else {
70 // Avoid blowing up, but we really shouldn't get here. 50 // Avoid blowing up, but we really shouldn't get here.
71 NOTREACHED(); 51 NOTREACHED();
72 } 52 }
73 } 53 }
74 54
75 - (void)draggedImage:(NSImage*)anImage 55 - (void)draggedImage:(NSImage*)anImage
76 endedAt:(NSPoint)aPoint 56 endedAt:(NSPoint)aPoint
77 operation:(NSDragOperation)operation { 57 operation:(NSDragOperation)operation {
78 beingDragged_ = NO; 58 [super endDrag];
79 [[self cell] setHighlighted:NO];
80 } 59 }
81 60
82 - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { 61 - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal {
83 return isLocal ? NSDragOperationCopy | NSDragOperationMove 62 return isLocal ? NSDragOperationCopy | NSDragOperationMove
84 : NSDragOperationCopy; 63 : NSDragOperationCopy;
85 } 64 }
86 65
87 - (void)mouseUp:(NSEvent*)theEvent {
88 // Make sure that we can't start a drag until we see a mouse down again.
89 mayDragStart_ = NO;
90
91 // This conditional is never true (DnD loops in Cocoa eat the mouse
92 // up) but I added it in case future versions of Cocoa do unexpected
93 // things.
94 if (beingDragged_) {
95 NOTREACHED();
96 return [super mouseUp:theEvent];
97 }
98
99 // There are non-drag cases where a mouseUp: may happen
100 // (e.g. mouse-down, cmd-tab to another application, move mouse,
101 // mouse-up). So we check.
102 NSPoint viewLocal = [self convertPoint:[theEvent locationInWindow]
103 fromView:[[self window] contentView]];
104 if (NSPointInRect(viewLocal, [self bounds])) {
105 [self performClick:self];
106 } else {
107 [[self cell] setHighlighted:NO];
108 }
109 }
110
111 // Mimic "begin a click" operation visually. Do NOT follow through
112 // with normal button event handling.
113 - (void)mouseDown:(NSEvent*)theEvent {
114 mayDragStart_ = YES;
115 [[self cell] setHighlighted:YES];
116 initialMouseDownLocation_ = [theEvent locationInWindow];
117 }
118
119 // Return YES if we have crossed a threshold of movement after
120 // mouse-down when we should begin a drag. Else NO.
121 - (BOOL)hasCrossedDragThreshold:(NSEvent*)theEvent {
122 NSPoint currentLocation = [theEvent locationInWindow];
123 if ((abs(currentLocation.x - initialMouseDownLocation_.x) >
124 kWebDragStartHysteresisX) ||
125 (abs(currentLocation.y - initialMouseDownLocation_.y) >
126 kWebDragStartHysteresisY)) {
127 return YES;
128 } else {
129 return NO;
130 }
131 }
132
133 - (void)mouseDragged:(NSEvent*)theEvent {
134 if (beingDragged_) {
135 [super mouseDragged:theEvent];
136 } else if (draggable_ && mayDragStart_ &&
137 [self hasCrossedDragThreshold:theEvent]) {
138 [self beginDrag:theEvent];
139 }
140 }
141
142 @end 66 @end
143 67
144 @implementation BookmarkButton(Private) 68 @implementation BookmarkButton(Private)
145 69
146 - (NSImage*)dragImage { 70 - (NSImage*)dragImage {
147 NSRect bounds = [self bounds]; 71 NSRect bounds = [self bounds];
148 72
149 // Grab the image from the screen and put it in an |NSImage|. We can't use 73 // Grab the image from the screen and put it in an |NSImage|. We can't use
150 // this directly since we need to clip it and set its opacity. This won't work 74 // this directly since we need to clip it and set its opacity. This won't work
151 // if the source view is clipped. Fortunately, we don't display clipped 75 // if the source view is clipped. Fortunately, we don't display clipped
(...skipping 18 matching lines...) Expand all
170 [image drawAtPoint:NSMakePoint(0, 0) 94 [image drawAtPoint:NSMakePoint(0, 0)
171 fromRect:NSMakeRect(0, 0, NSWidth(bounds), NSHeight(bounds)) 95 fromRect:NSMakeRect(0, 0, NSWidth(bounds), NSHeight(bounds))
172 operation:NSCompositeSourceOver 96 operation:NSCompositeSourceOver
173 fraction:kDragImageOpacity]; 97 fraction:kDragImageOpacity];
174 98
175 [dragImage unlockFocus]; 99 [dragImage unlockFocus];
176 return dragImage; 100 return dragImage;
177 } 101 }
178 102
179 @end // @implementation BookmarkButton(Private) 103 @end // @implementation BookmarkButton(Private)
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/bookmark_button.h ('k') | chrome/browser/cocoa/bookmark_button_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698