• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3// found in the LICENSE file.
4
5#include "ui/base/cocoa/base_view.h"
6
7NSString* kViewDidBecomeFirstResponder =
8    @"Chromium.kViewDidBecomeFirstResponder";
9NSString* kSelectionDirection = @"Chromium.kSelectionDirection";
10
11const int kTrackingOptions = NSTrackingMouseMoved |
12                             NSTrackingMouseEnteredAndExited |
13                             NSTrackingActiveAlways;
14
15@implementation BaseView
16
17- (void)dealloc {
18  if (trackingArea_.get())
19    [self removeTrackingArea:trackingArea_.get()];
20  trackingArea_.reset(nil);
21
22  [super dealloc];
23}
24
25- (void)mouseEvent:(NSEvent*)theEvent {
26  // This method left intentionally blank.
27}
28
29- (EventHandled)keyEvent:(NSEvent*)theEvent {
30  // The default implementation of this method does not handle any key events.
31  // Derived classes should return kEventHandled if they handled an event,
32  // otherwise it will be forwarded on to |super|.
33  return kEventNotHandled;
34}
35
36- (void)mouseDown:(NSEvent*)theEvent {
37  dragging_ = YES;
38  [self mouseEvent:theEvent];
39}
40
41- (void)rightMouseDown:(NSEvent*)theEvent {
42  [self mouseEvent:theEvent];
43}
44
45- (void)otherMouseDown:(NSEvent*)theEvent {
46  [self mouseEvent:theEvent];
47}
48
49- (void)mouseUp:(NSEvent*)theEvent {
50  [self mouseEvent:theEvent];
51
52  dragging_ = NO;
53  if (pendingExitEvent_.get()) {
54    NSEvent* exitEvent =
55        [NSEvent enterExitEventWithType:NSMouseExited
56                               location:[theEvent locationInWindow]
57                          modifierFlags:[theEvent modifierFlags]
58                              timestamp:[theEvent timestamp]
59                           windowNumber:[theEvent windowNumber]
60                                context:[theEvent context]
61                            eventNumber:[pendingExitEvent_.get() eventNumber]
62                         trackingNumber:[pendingExitEvent_.get() trackingNumber]
63                               userData:[pendingExitEvent_.get() userData]];
64    [self mouseEvent:exitEvent];
65    pendingExitEvent_.reset();
66  }
67}
68
69- (void)rightMouseUp:(NSEvent*)theEvent {
70  [self mouseEvent:theEvent];
71}
72
73- (void)otherMouseUp:(NSEvent*)theEvent {
74  [self mouseEvent:theEvent];
75}
76
77- (void)mouseMoved:(NSEvent*)theEvent {
78  [self mouseEvent:theEvent];
79}
80
81- (void)mouseDragged:(NSEvent*)theEvent {
82  [self mouseEvent:theEvent];
83}
84
85- (void)rightMouseDragged:(NSEvent*)theEvent {
86  [self mouseEvent:theEvent];
87}
88
89- (void)otherMouseDragged:(NSEvent*)theEvent {
90  [self mouseEvent:theEvent];
91}
92
93- (void)mouseEntered:(NSEvent*)theEvent {
94  if (pendingExitEvent_.get()) {
95    pendingExitEvent_.reset();
96    return;
97  }
98
99  [self mouseEvent:theEvent];
100}
101
102- (void)mouseExited:(NSEvent*)theEvent {
103  // The tracking area will send an exit event even during a drag, which isn't
104  // how the event flow for drags should work. This stores the exit event, and
105  // sends it when the drag completes instead.
106  if (dragging_) {
107    pendingExitEvent_.reset([theEvent retain]);
108    return;
109  }
110
111  [self mouseEvent:theEvent];
112}
113
114- (void)keyDown:(NSEvent*)theEvent {
115  if ([self keyEvent:theEvent] != kEventHandled)
116    [super keyDown:theEvent];
117}
118
119- (void)keyUp:(NSEvent*)theEvent {
120  if ([self keyEvent:theEvent] != kEventHandled)
121    [super keyUp:theEvent];
122}
123
124- (void)flagsChanged:(NSEvent*)theEvent {
125  if ([self keyEvent:theEvent] != kEventHandled)
126    [super flagsChanged:theEvent];
127}
128
129- (gfx::Rect)flipNSRectToRect:(NSRect)rect {
130  gfx::Rect new_rect(NSRectToCGRect(rect));
131  new_rect.set_y(NSHeight([self bounds]) - new_rect.bottom());
132  return new_rect;
133}
134
135- (NSRect)flipRectToNSRect:(gfx::Rect)rect {
136  NSRect new_rect(NSRectFromCGRect(rect.ToCGRect()));
137  new_rect.origin.y = NSHeight([self bounds]) - NSMaxY(new_rect);
138  return new_rect;
139}
140
141- (void)updateTrackingAreas {
142  [super updateTrackingAreas];
143
144  // NSTrackingInVisibleRect doesn't work correctly with Lion's window resizing,
145  // http://crbug.com/176725 / http://openradar.appspot.com/radar?id=2773401 .
146  // Tear down old tracking area and create a new one as workaround.
147  if (trackingArea_.get())
148    [self removeTrackingArea:trackingArea_.get()];
149  trackingArea_.reset([[CrTrackingArea alloc] initWithRect:[self bounds]
150                                                   options:kTrackingOptions
151                                                     owner:self
152                                                  userInfo:nil]);
153  [self addTrackingArea:trackingArea_.get()];
154}
155
156@end
157