OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #import "chrome/browser/ui/cocoa/wrench_menu/menu_tracked_button.h" | 5 #import "chrome/browser/ui/cocoa/wrench_menu/menu_tracked_button.h" |
6 | 6 |
7 #include "base/mac/mac_util.h" | 7 #include "base/mac/mac_util.h" |
8 | 8 |
9 @interface MenuTrackedButton (Private) | 9 @interface MenuTrackedButton (Private) |
10 - (void)doHighlight:(BOOL)highlight; | 10 - (void)doHighlight:(BOOL)highlight; |
11 - (void)checkMouseInRect; | 11 - (void)checkMouseInRect; |
12 - (NSRect)insetBounds; | 12 - (NSRect)insetBounds; |
13 - (BOOL)shouldHighlightOnHover; | |
14 @end | 13 @end |
15 | 14 |
16 @implementation MenuTrackedButton | 15 @implementation MenuTrackedButton |
17 | 16 |
18 @synthesize tracking = tracking_; | 17 @synthesize tracking = tracking_; |
19 | 18 |
20 - (void)updateTrackingAreas { | 19 - (void)updateTrackingAreas { |
21 [super updateTrackingAreas]; | 20 [super updateTrackingAreas]; |
22 [self removeTrackingRect:trackingTag_]; | 21 [self removeTrackingRect:trackingTag_]; |
23 trackingTag_ = [self addTrackingRect:NSInsetRect([self bounds], 1, 1) | 22 trackingTag_ = [self addTrackingRect:NSInsetRect([self bounds], 1, 1) |
(...skipping 27 matching lines...) Expand all Loading... |
51 | 50 |
52 NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil]; | 51 NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil]; |
53 BOOL highlight = NSPointInRect(point, [self insetBounds]); | 52 BOOL highlight = NSPointInRect(point, [self insetBounds]); |
54 [self doHighlight:highlight]; | 53 [self doHighlight:highlight]; |
55 | 54 |
56 // If tracking in non-sticky mode, poll the mouse cursor to see if it is still | 55 // If tracking in non-sticky mode, poll the mouse cursor to see if it is still |
57 // over the button and thus needs to be highlighted. The delay is the | 56 // over the button and thus needs to be highlighted. The delay is the |
58 // smallest that still produces the effect while minimizing jank. Smaller | 57 // smallest that still produces the effect while minimizing jank. Smaller |
59 // values make the selector fire too close to immediately/now for the mouse to | 58 // values make the selector fire too close to immediately/now for the mouse to |
60 // have moved off the receiver, and larger values produce lag. | 59 // have moved off the receiver, and larger values produce lag. |
61 if (tracking_ && [self shouldHighlightOnHover]) { | 60 if (tracking_) { |
62 [self performSelector:@selector(checkMouseInRect) | 61 [self performSelector:@selector(checkMouseInRect) |
63 withObject:nil | 62 withObject:nil |
64 afterDelay:0.05 | 63 afterDelay:0.05 |
65 inModes:[NSArray arrayWithObject:NSEventTrackingRunLoopMode]]; | 64 inModes:[NSArray arrayWithObject:NSEventTrackingRunLoopMode]]; |
66 } | 65 } |
67 [super mouseDragged:theEvent]; | 66 [super mouseDragged:theEvent]; |
68 } | 67 } |
69 | 68 |
70 - (void)mouseUp:(NSEvent*)theEvent { | 69 - (void)mouseUp:(NSEvent*)theEvent { |
71 [self doHighlight:NO]; | 70 [self doHighlight:NO]; |
72 if (!tracking_) { | 71 if (!tracking_) { |
73 return [super mouseUp:theEvent]; | 72 return [super mouseUp:theEvent]; |
74 } | 73 } |
75 [self performClick:self]; | 74 [self performClick:self]; |
76 tracking_ = NO; | 75 tracking_ = NO; |
77 } | 76 } |
78 | 77 |
79 - (void)doHighlight:(BOOL)highlight { | 78 - (void)doHighlight:(BOOL)highlight { |
80 if (![self shouldHighlightOnHover]) { | |
81 return; | |
82 } | |
83 [[self cell] setHighlighted:highlight]; | 79 [[self cell] setHighlighted:highlight]; |
84 [self setNeedsDisplay]; | 80 [self setNeedsDisplay]; |
85 } | 81 } |
86 | 82 |
87 // Checks if the user's current mouse location is over this button. If it is, | 83 // Checks if the user's current mouse location is over this button. If it is, |
88 // the user is merely hovering here. If it is not, then disable the highlight. | 84 // the user is merely hovering here. If it is not, then disable the highlight. |
89 // If the menu is opened in non-sticky mode, the button does not receive enter/ | 85 // If the menu is opened in non-sticky mode, the button does not receive enter/ |
90 // exit mouse events and thus polling is necessary. | 86 // exit mouse events and thus polling is necessary. |
91 - (void)checkMouseInRect { | 87 - (void)checkMouseInRect { |
92 NSPoint point = [NSEvent mouseLocation]; | 88 NSPoint point = [NSEvent mouseLocation]; |
93 point = [[self window] convertScreenToBase:point]; | 89 point = [[self window] convertScreenToBase:point]; |
94 point = [self convertPoint:point fromView:nil]; | 90 point = [self convertPoint:point fromView:nil]; |
95 if (!NSPointInRect(point, [self insetBounds])) { | 91 if (!NSPointInRect(point, [self insetBounds])) { |
96 [self doHighlight:NO]; | 92 [self doHighlight:NO]; |
97 } | 93 } |
98 } | 94 } |
99 | 95 |
100 // Returns the bounds of the receiver slightly inset to avoid highlighting both | 96 // Returns the bounds of the receiver slightly inset to avoid highlighting both |
101 // buttons in a pair that overlap. | 97 // buttons in a pair that overlap. |
102 - (NSRect)insetBounds { | 98 - (NSRect)insetBounds { |
103 return NSInsetRect([self bounds], 2, 1); | 99 return NSInsetRect([self bounds], 2, 1); |
104 } | 100 } |
105 | 101 |
106 - (BOOL)shouldHighlightOnHover { | |
107 // There's a cell drawing bug in 10.5 that was fixed on 10.6. Hover states | |
108 // look terrible due to this, so disable highlighting on 10.5. | |
109 return base::mac::IsOSSnowLeopardOrLater(); | |
110 } | |
111 | |
112 @end | 102 @end |
OLD | NEW |