Home | History | Annotate | Download | only in cocoa
      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