Update V8 to version 4.7.45.
[chromium-blink-merge.git] / ui / base / cocoa / hover_button.mm
blobe763c0cdb69bf8281dd0b981dab4a676bbf7487a
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
3 // found in the LICENSE file.
5 #import "ui/base/cocoa/hover_button.h"
7 @implementation HoverButton
9 @synthesize hoverState = hoverState_;
11 - (id)initWithFrame:(NSRect)frameRect {
12   if ((self = [super initWithFrame:frameRect])) {
13     [self setTrackingEnabled:YES];
14     hoverState_ = kHoverStateNone;
15     [self updateTrackingAreas];
16   }
17   return self;
20 - (void)awakeFromNib {
21   [self setTrackingEnabled:YES];
22   self.hoverState = kHoverStateNone;
23   [self updateTrackingAreas];
26 - (void)dealloc {
27   [self setTrackingEnabled:NO];
28   [super dealloc];
31 - (void)mouseEntered:(NSEvent*)theEvent {
32   if (trackingArea_.get())
33     self.hoverState = kHoverStateMouseOver;
36 - (void)mouseExited:(NSEvent*)theEvent {
37   if (trackingArea_.get())
38     self.hoverState = kHoverStateNone;
41 - (void)mouseMoved:(NSEvent*)theEvent {
42   [self checkImageState];
45 - (void)mouseDown:(NSEvent*)theEvent {
46   self.hoverState = kHoverStateMouseDown;
47   // 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
49   // |checkImageState| call will crash.
50   // http://crbug.com/28220
51   base::scoped_nsobject<HoverButton> myself([self retain]);
53   [super mouseDown:theEvent];
54   // We need to check the image state after the mouseDown event loop finishes.
55   // It's possible that we won't get a mouseExited event if the button was
56   // moved under the mouse during tab resize, instead of the mouse moving over
57   // the button.
58   // http://crbug.com/31279
59   [self checkImageState];
62 - (void)setAccessibilityTitle:(NSString*)accessibilityTitle {
63   NSCell* cell = [self cell];
64   [cell accessibilitySetOverrideValue:accessibilityTitle
65                          forAttribute:NSAccessibilityTitleAttribute];
68 - (void)setTrackingEnabled:(BOOL)enabled {
69   if (enabled) {
70     trackingArea_.reset(
71         [[CrTrackingArea alloc] initWithRect:NSZeroRect
72                                      options:NSTrackingMouseEnteredAndExited |
73                                              NSTrackingMouseMoved |
74                                              NSTrackingActiveAlways |
75                                              NSTrackingInVisibleRect
76                                        owner:self
77                                     userInfo:nil]);
78     [self addTrackingArea:trackingArea_.get()];
80     // If you have a separate window that overlaps the close button, and you
81     // move the mouse directly over the close button without entering another
82     // part of the tab strip, we don't get any mouseEntered event since the
83     // tracking area was disabled when we entered.
84     // Done with a delay of 0 because sometimes an event appears to be missed
85     // between the activation of the tracking area and the call to
86     // checkImageState resulting in the button state being incorrect.
87     [self performSelector:@selector(checkImageState)
88                withObject:nil
89                afterDelay:0];
90   } else {
91     if (trackingArea_.get()) {
92       self.hoverState = kHoverStateNone;
93       [self removeTrackingArea:trackingArea_.get()];
94       trackingArea_.reset(nil);
95     }
96   }
99 - (void)updateTrackingAreas {
100   [super updateTrackingAreas];
101   [self checkImageState];
104 - (void)checkImageState {
105   if (!trackingArea_.get())
106     return;
108   // Update the button's state if the button has moved.
109   NSPoint mouseLoc = [[self window] mouseLocationOutsideOfEventStream];
110   mouseLoc = [self convertPoint:mouseLoc fromView:nil];
111   self.hoverState = NSPointInRect(mouseLoc, [self bounds]) ?
112       kHoverStateMouseOver : kHoverStateNone;
115 - (void)setHoverState:(HoverState)state {
116   BOOL stateChanged = (hoverState_ != state);
117   hoverState_ = state;
118   [self setNeedsDisplay:stateChanged];
121 @end