OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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" | 9 #import "third_party/GTM/AppKit/GTMTheme.h" |
10 | 10 |
(...skipping 28 matching lines...) Expand all Loading... |
39 } | 39 } |
40 return self; | 40 return self; |
41 } | 41 } |
42 | 42 |
43 // By default, NSButton ignores middle-clicks. | 43 // By default, NSButton ignores middle-clicks. |
44 - (void)otherMouseUp:(NSEvent*)event { | 44 - (void)otherMouseUp:(NSEvent*)event { |
45 [self performClick:self]; | 45 [self performClick:self]; |
46 } | 46 } |
47 | 47 |
48 - (void)beginDrag:(NSEvent*)event { | 48 - (void)beginDrag:(NSEvent*)event { |
| 49 // Starting drag. Never start another drag until another mouse down. |
| 50 mayDragStart_ = NO; |
| 51 |
49 NSSize dragOffset = NSMakeSize(0.0, 0.0); | 52 NSSize dragOffset = NSMakeSize(0.0, 0.0); |
50 NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; | 53 NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; |
51 [pboard declareTypes:[NSArray arrayWithObject:kBookmarkButtonDragType] | 54 [pboard declareTypes:[NSArray arrayWithObject:kBookmarkButtonDragType] |
52 owner:self]; | 55 owner:self]; |
53 | 56 |
54 // This NSData is no longer referenced once the function ends so | 57 // This NSData is no longer referenced once the function ends so |
55 // there is no need to retain/release when placing in here as an | 58 // there is no need to retain/release when placing in here as an |
56 // opaque pointer. | 59 // opaque pointer. |
57 [pboard setData:[NSData dataWithBytes:&self length:sizeof(self)] | 60 [pboard setData:[NSData dataWithBytes:&self length:sizeof(self)] |
58 forType:kBookmarkButtonDragType]; | 61 forType:kBookmarkButtonDragType]; |
(...skipping 16 matching lines...) Expand all Loading... |
75 operation:(NSDragOperation)operation { | 78 operation:(NSDragOperation)operation { |
76 beingDragged_ = NO; | 79 beingDragged_ = NO; |
77 [[self cell] setHighlighted:NO]; | 80 [[self cell] setHighlighted:NO]; |
78 } | 81 } |
79 | 82 |
80 - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { | 83 - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { |
81 return isLocal ? NSDragOperationMove : NSDragOperationNone; | 84 return isLocal ? NSDragOperationMove : NSDragOperationNone; |
82 } | 85 } |
83 | 86 |
84 - (void)mouseUp:(NSEvent*)theEvent { | 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 |
85 // This conditional is never true (DnD loops in Cocoa eat the mouse | 91 // This conditional is never true (DnD loops in Cocoa eat the mouse |
86 // up) but I added it in case future versions of Cocoa do unexpected | 92 // up) but I added it in case future versions of Cocoa do unexpected |
87 // things. | 93 // things. |
88 if (beingDragged_) | 94 if (beingDragged_) { |
| 95 NOTREACHED(); |
89 return [super mouseUp:theEvent]; | 96 return [super mouseUp:theEvent]; |
| 97 } |
90 | 98 |
91 // There are non-drag cases where a mouseUp: may happen | 99 // There are non-drag cases where a mouseUp: may happen |
92 // (e.g. mouse-down, cmd-tab to another application, move mouse, | 100 // (e.g. mouse-down, cmd-tab to another application, move mouse, |
93 // mouse-up). So we check. | 101 // mouse-up). So we check. |
94 NSPoint viewLocal = [self convertPoint:[theEvent locationInWindow] | 102 NSPoint viewLocal = [self convertPoint:[theEvent locationInWindow] |
95 fromView:[[self window] contentView]]; | 103 fromView:[[self window] contentView]]; |
96 if (NSPointInRect(viewLocal, [self bounds])) { | 104 if (NSPointInRect(viewLocal, [self bounds])) { |
97 [self performClick:self]; | 105 [self performClick:self]; |
98 } else { | 106 } else { |
99 [[self cell] setHighlighted:NO]; | 107 [[self cell] setHighlighted:NO]; |
100 } | 108 } |
101 } | 109 } |
102 | 110 |
103 // Mimic "begin a click" operation visually. Do NOT follow through | 111 // Mimic "begin a click" operation visually. Do NOT follow through |
104 // with normal button event handling. | 112 // with normal button event handling. |
105 - (void)mouseDown:(NSEvent*)theEvent { | 113 - (void)mouseDown:(NSEvent*)theEvent { |
| 114 mayDragStart_ = YES; |
106 [[self cell] setHighlighted:YES]; | 115 [[self cell] setHighlighted:YES]; |
107 initialMouseDownLocation_ = [theEvent locationInWindow]; | 116 initialMouseDownLocation_ = [theEvent locationInWindow]; |
108 } | 117 } |
109 | 118 |
110 // Return YES if we have crossed a threshold of movement after | 119 // Return YES if we have crossed a threshold of movement after |
111 // mouse-down when we should begin a drag. Else NO. | 120 // mouse-down when we should begin a drag. Else NO. |
112 - (BOOL)hasCrossedDragThreshold:(NSEvent*)theEvent { | 121 - (BOOL)hasCrossedDragThreshold:(NSEvent*)theEvent { |
113 NSPoint currentLocation = [theEvent locationInWindow]; | 122 NSPoint currentLocation = [theEvent locationInWindow]; |
114 if ((abs(currentLocation.x - initialMouseDownLocation_.x) > | 123 if ((abs(currentLocation.x - initialMouseDownLocation_.x) > |
115 kWebDragStartHysteresisX) || | 124 kWebDragStartHysteresisX) || |
116 (abs(currentLocation.y - initialMouseDownLocation_.y) > | 125 (abs(currentLocation.y - initialMouseDownLocation_.y) > |
117 kWebDragStartHysteresisY)) { | 126 kWebDragStartHysteresisY)) { |
118 return YES; | 127 return YES; |
119 } else { | 128 } else { |
120 return NO; | 129 return NO; |
121 } | 130 } |
122 } | 131 } |
123 | 132 |
124 - (void)mouseDragged:(NSEvent*)theEvent { | 133 - (void)mouseDragged:(NSEvent*)theEvent { |
125 if (beingDragged_) | 134 if (beingDragged_) { |
126 [super mouseDragged:theEvent]; | 135 [super mouseDragged:theEvent]; |
127 else { | 136 } else if (draggable_ && mayDragStart_ && |
128 if (draggable_ && [self hasCrossedDragThreshold:theEvent]) { | 137 [self hasCrossedDragThreshold:theEvent]) { |
129 [self beginDrag:theEvent]; | 138 [self beginDrag:theEvent]; |
130 } | |
131 } | 139 } |
132 } | 140 } |
133 | 141 |
134 @end | 142 @end |
135 | 143 |
136 @implementation BookmarkButton(Private) | 144 @implementation BookmarkButton(Private) |
137 | 145 |
138 - (NSImage*)dragImage { | 146 - (NSImage*)dragImage { |
139 NSRect bounds = [self bounds]; | 147 NSRect bounds = [self bounds]; |
140 | 148 |
(...skipping 21 matching lines...) Expand all Loading... |
162 [image drawAtPoint:NSMakePoint(0, 0) | 170 [image drawAtPoint:NSMakePoint(0, 0) |
163 fromRect:NSMakeRect(0, 0, NSWidth(bounds), NSHeight(bounds)) | 171 fromRect:NSMakeRect(0, 0, NSWidth(bounds), NSHeight(bounds)) |
164 operation:NSCompositeSourceOver | 172 operation:NSCompositeSourceOver |
165 fraction:kDragImageOpacity]; | 173 fraction:kDragImageOpacity]; |
166 | 174 |
167 [dragImage unlockFocus]; | 175 [dragImage unlockFocus]; |
168 return dragImage; | 176 return dragImage; |
169 } | 177 } |
170 | 178 |
171 @end // @implementation BookmarkButton(Private) | 179 @end // @implementation BookmarkButton(Private) |
OLD | NEW |