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 7 NSString* kViewDidBecomeFirstResponder = 8 @"Chromium.kViewDidBecomeFirstResponder"; 9 NSString* kSelectionDirection = @"Chromium.kSelectionDirection"; 10 11 const 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 - (void)keyEvent:(NSEvent*)theEvent { 30 // This method left intentionally blank. 31 } 32 33 - (void)mouseDown:(NSEvent*)theEvent { 34 dragging_ = YES; 35 [self mouseEvent:theEvent]; 36 } 37 38 - (void)rightMouseDown:(NSEvent*)theEvent { 39 [self mouseEvent:theEvent]; 40 } 41 42 - (void)otherMouseDown:(NSEvent*)theEvent { 43 [self mouseEvent:theEvent]; 44 } 45 46 - (void)mouseUp:(NSEvent*)theEvent { 47 [self mouseEvent:theEvent]; 48 49 dragging_ = NO; 50 if (pendingExitEvent_.get()) { 51 NSEvent* exitEvent = 52 [NSEvent enterExitEventWithType:NSMouseExited 53 location:[theEvent locationInWindow] 54 modifierFlags:[theEvent modifierFlags] 55 timestamp:[theEvent timestamp] 56 windowNumber:[theEvent windowNumber] 57 context:[theEvent context] 58 eventNumber:[pendingExitEvent_.get() eventNumber] 59 trackingNumber:[pendingExitEvent_.get() trackingNumber] 60 userData:[pendingExitEvent_.get() userData]]; 61 [self mouseEvent:exitEvent]; 62 pendingExitEvent_.reset(); 63 } 64 } 65 66 - (void)rightMouseUp:(NSEvent*)theEvent { 67 [self mouseEvent:theEvent]; 68 } 69 70 - (void)otherMouseUp:(NSEvent*)theEvent { 71 [self mouseEvent:theEvent]; 72 } 73 74 - (void)mouseMoved:(NSEvent*)theEvent { 75 [self mouseEvent:theEvent]; 76 } 77 78 - (void)mouseDragged:(NSEvent*)theEvent { 79 [self mouseEvent:theEvent]; 80 } 81 82 - (void)rightMouseDragged:(NSEvent*)theEvent { 83 [self mouseEvent:theEvent]; 84 } 85 86 - (void)otherMouseDragged:(NSEvent*)theEvent { 87 [self mouseEvent:theEvent]; 88 } 89 90 - (void)mouseEntered:(NSEvent*)theEvent { 91 if (pendingExitEvent_.get()) { 92 pendingExitEvent_.reset(); 93 return; 94 } 95 96 [self mouseEvent:theEvent]; 97 } 98 99 - (void)mouseExited:(NSEvent*)theEvent { 100 // The tracking area will send an exit event even during a drag, which isn't 101 // how the event flow for drags should work. This stores the exit event, and 102 // sends it when the drag completes instead. 103 if (dragging_) { 104 pendingExitEvent_.reset([theEvent retain]); 105 return; 106 } 107 108 [self mouseEvent:theEvent]; 109 } 110 111 - (void)keyDown:(NSEvent*)theEvent { 112 [self keyEvent:theEvent]; 113 } 114 115 - (void)keyUp:(NSEvent*)theEvent { 116 [self keyEvent:theEvent]; 117 } 118 119 - (void)flagsChanged:(NSEvent*)theEvent { 120 [self keyEvent:theEvent]; 121 } 122 123 - (gfx::Rect)flipNSRectToRect:(NSRect)rect { 124 gfx::Rect new_rect(NSRectToCGRect(rect)); 125 new_rect.set_y(NSHeight([self bounds]) - new_rect.bottom()); 126 return new_rect; 127 } 128 129 - (NSRect)flipRectToNSRect:(gfx::Rect)rect { 130 NSRect new_rect(NSRectFromCGRect(rect.ToCGRect())); 131 new_rect.origin.y = NSHeight([self bounds]) - NSMaxY(new_rect); 132 return new_rect; 133 } 134 135 - (void)updateTrackingAreas { 136 [super updateTrackingAreas]; 137 138 // NSTrackingInVisibleRect doesn't work correctly with Lion's window resizing, 139 // http://crbug.com/176725 / http://openradar.appspot.com/radar?id=2773401 . 140 // Tear down old tracking area and create a new one as workaround. 141 if (trackingArea_.get()) 142 [self removeTrackingArea:trackingArea_.get()]; 143 trackingArea_.reset([[CrTrackingArea alloc] initWithRect:[self bounds] 144 options:kTrackingOptions 145 owner:self 146 userInfo:nil]); 147 [self addTrackingArea:trackingArea_.get()]; 148 } 149 150 @end 151