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