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

Side by Side Diff: ui/base/cocoa/hover_button.mm

Issue 2898343002: [Mac] Update tab close button when user drags outside (Closed)
Patch Set: Add retain, comment on key events. Created 3 years, 6 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
« no previous file with comments | « ui/base/cocoa/hover_button.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 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 #import "ui/base/cocoa/hover_button.h" 5 #import "ui/base/cocoa/hover_button.h"
6 6
7 @implementation HoverButton 7 @implementation HoverButton
8 8
9 @synthesize hoverState = hoverState_; 9 @synthesize hoverState = hoverState_;
10 10
11 - (id)initWithFrame:(NSRect)frameRect { 11 - (id)initWithFrame:(NSRect)frameRect {
12 if ((self = [super initWithFrame:frameRect])) { 12 if ((self = [super initWithFrame:frameRect])) {
13 [self setTrackingEnabled:YES]; 13 [self commonInit];
14 hoverState_ = kHoverStateNone;
15 [self updateTrackingAreas];
16 } 14 }
17 return self; 15 return self;
18 } 16 }
19 17
20 - (void)awakeFromNib { 18 - (void)awakeFromNib {
19 [self commonInit];
20 }
21
22 - (void)commonInit {
21 [self setTrackingEnabled:YES]; 23 [self setTrackingEnabled:YES];
22 self.hoverState = kHoverStateNone; 24 self.hoverState = kHoverStateNone;
23 [self updateTrackingAreas]; 25 [self updateTrackingAreas];
24 } 26 }
25 27
26 - (void)dealloc { 28 - (void)dealloc {
27 [self setTrackingEnabled:NO]; 29 [self setTrackingEnabled:NO];
28 [super dealloc]; 30 [super dealloc];
29 } 31 }
30 32
31 - (void)mouseEntered:(NSEvent*)theEvent { 33 - (void)mouseEntered:(NSEvent*)theEvent {
32 if (trackingArea_.get()) 34 if (trackingArea_.get())
33 self.hoverState = kHoverStateMouseOver; 35 self.hoverState = kHoverStateMouseOver;
34 } 36 }
35 37
38 - (void)mouseMoved:(NSEvent*)theEvent {
39 [self checkImageState];
40 }
41
36 - (void)mouseExited:(NSEvent*)theEvent { 42 - (void)mouseExited:(NSEvent*)theEvent {
37 if (trackingArea_.get()) 43 if (trackingArea_.get())
38 self.hoverState = kHoverStateNone; 44 self.hoverState = kHoverStateNone;
39 } 45 }
40 46
41 - (void)mouseMoved:(NSEvent*)theEvent { 47 - (void)mouseDown:(NSEvent*)theEvent {
42 [self checkImageState]; 48 mouseDown_ = YES;
43 } 49 self.hoverState = kHoverStateMouseDown;
44 50
45 - (void)mouseDown:(NSEvent*)theEvent {
46 self.hoverState = kHoverStateMouseDown;
47 // The hover button needs to hold onto itself here for a bit. Otherwise, 51 // The hover button needs to hold onto itself here for a bit. Otherwise,
48 // it can be freed while |super mouseDown:| is in its loop, and the 52 // it can be freed while in the tracking loop below.
49 // |checkImageState| call will crash.
50 // http://crbug.com/28220 53 // http://crbug.com/28220
51 base::scoped_nsobject<HoverButton> myself([self retain]); 54 base::scoped_nsobject<HoverButton> myself([self retain]);
52 55
53 [super mouseDown:theEvent]; 56 // Begin tracking the mouse.
54 // We need to check the image state after the mouseDown event loop finishes. 57 if ([theEvent type] == NSLeftMouseDown) {
55 // It's possible that we won't get a mouseExited event if the button was 58 NSWindow* window = [self window];
56 // moved under the mouse during tab resize, instead of the mouse moving over 59 NSEvent* nextEvent = nil;
57 // the button. 60
58 // http://crbug.com/31279 61 // For the tracking loop ignore key events so that they don't pile up in
59 [self checkImageState]; 62 // the queue and get processed after the user releases the mouse.
63 const NSEventMask eventMask = (NSLeftMouseDraggedMask | NSLeftMouseUpMask |
64 NSKeyDownMask | NSKeyUpMask);
65
66 while ((nextEvent = [window nextEventMatchingMask:eventMask])) {
67 // Update the image state, which will change if the user moves the mouse
68 // into or out of the button.
69 [self checkImageState];
70
71 if ([nextEvent type] == NSLeftMouseUp) {
72 break;
73 }
74 }
75 }
76
77 // If the mouse is still over the button, it means the user clicked the
78 // button.
79 if (self.hoverState == kHoverStateMouseDown) {
80 [self performClick:nil];
81 }
82
83 // Clean up.
84 mouseDown_ = NO;
60 } 85 }
61 86
62 - (void)setAccessibilityTitle:(NSString*)accessibilityTitle { 87 - (void)setAccessibilityTitle:(NSString*)accessibilityTitle {
63 NSCell* cell = [self cell]; 88 NSCell* cell = [self cell];
64 [cell accessibilitySetOverrideValue:accessibilityTitle 89 [cell accessibilitySetOverrideValue:accessibilityTitle
65 forAttribute:NSAccessibilityTitleAttribute]; 90 forAttribute:NSAccessibilityTitleAttribute];
66 } 91 }
67 92
68 - (void)setTrackingEnabled:(BOOL)enabled { 93 - (void)setTrackingEnabled:(BOOL)enabled {
69 if (enabled) { 94 if (enabled) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 [self checkImageState]; 126 [self checkImageState];
102 } 127 }
103 128
104 - (void)checkImageState { 129 - (void)checkImageState {
105 if (!trackingArea_.get()) 130 if (!trackingArea_.get())
106 return; 131 return;
107 132
108 // Update the button's state if the button has moved. 133 // Update the button's state if the button has moved.
109 NSPoint mouseLoc = [[self window] mouseLocationOutsideOfEventStream]; 134 NSPoint mouseLoc = [[self window] mouseLocationOutsideOfEventStream];
110 mouseLoc = [self convertPoint:mouseLoc fromView:nil]; 135 mouseLoc = [self convertPoint:mouseLoc fromView:nil];
111 self.hoverState = NSPointInRect(mouseLoc, [self bounds]) ? 136 BOOL mouseInBounds = NSPointInRect(mouseLoc, [self bounds]);
112 kHoverStateMouseOver : kHoverStateNone; 137 if (mouseDown_ && mouseInBounds) {
138 self.hoverState = kHoverStateMouseDown;
139 } else {
140 self.hoverState = mouseInBounds ? kHoverStateMouseOver : kHoverStateNone;
141 }
113 } 142 }
114 143
115 - (void)setHoverState:(HoverState)state { 144 - (void)setHoverState:(HoverState)state {
116 BOOL stateChanged = (hoverState_ != state); 145 BOOL stateChanged = (hoverState_ != state);
117 hoverState_ = state; 146 hoverState_ = state;
118 [self setNeedsDisplay:stateChanged]; 147 [self setNeedsDisplay:stateChanged];
119 } 148 }
120 149
121 @end 150 @end
OLDNEW
« no previous file with comments | « ui/base/cocoa/hover_button.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698