Home | History | Annotate | Download | only in cocoa
      1 // Copyright (c) 2013 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/message_center/cocoa/tray_controller.h"
      6 
      7 #include "ui/base/cocoa/window_size_constants.h"
      8 #include "ui/base/resource/resource_bundle.h"
      9 #import "ui/message_center/cocoa/popup_collection.h"
     10 #import "ui/message_center/cocoa/tray_view_controller.h"
     11 #include "ui/message_center/message_center_tray.h"
     12 #include "ui/message_center/message_center_tray_delegate.h"
     13 
     14 @interface MCTrayWindow : NSPanel
     15 @end
     16 
     17 @implementation MCTrayWindow
     18 
     19 - (BOOL)canBecomeKeyWindow {
     20   return YES;
     21 }
     22 
     23 - (void)cancelOperation:(id)sender {
     24   [self orderOut:self];
     25 }
     26 
     27 @end
     28 
     29 @implementation MCTrayController
     30 
     31 - (id)initWithMessageCenterTray:(message_center::MessageCenterTray*)tray {
     32   base::scoped_nsobject<MCTrayWindow> window(
     33       [[MCTrayWindow alloc] initWithContentRect:ui::kWindowSizeDeterminedLater
     34                                       styleMask:NSBorderlessWindowMask |
     35                                                 NSNonactivatingPanelMask
     36                                         backing:NSBackingStoreBuffered
     37                                           defer:NO]);
     38   if ((self = [super initWithWindow:window])) {
     39     tray_ = tray;
     40 
     41     [window setDelegate:self];
     42     [window setHasShadow:YES];
     43     [window setHidesOnDeactivate:NO];
     44     [window setLevel:NSFloatingWindowLevel];
     45 
     46     viewController_.reset([[MCTrayViewController alloc] initWithMessageCenter:
     47         tray_->message_center()]);
     48     NSView* contentView = [viewController_ view];
     49     [window setFrame:[contentView frame] display:NO];
     50     [window setContentView:contentView];
     51 
     52     // The global event monitor will close the tray in response to events
     53     // delivered to other applications, and -windowDidResignKey: will catch
     54     // events within the application.
     55     __block typeof(self) weakSelf = self;
     56     clickEventMonitor_ =
     57         [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask |
     58                                                        NSRightMouseDownMask |
     59                                                        NSOtherMouseDownMask
     60             handler:^(NSEvent* event) {
     61                 [weakSelf windowDidResignKey:nil];
     62             }];
     63   }
     64   return self;
     65 }
     66 
     67 - (void)dealloc {
     68   [NSEvent removeMonitor:clickEventMonitor_];
     69   [super dealloc];
     70 }
     71 
     72 - (MCTrayViewController*)viewController {
     73   return viewController_.get();
     74 }
     75 
     76 - (void)close {
     77   [viewController_ onWindowClosing];
     78   [super close];
     79 }
     80 
     81 - (void)showTrayAtRightOf:(NSPoint)rightPoint atLeftOf:(NSPoint)leftPoint {
     82   NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
     83   NSRect screenFrame = [screen visibleFrame];
     84 
     85   NSRect frame = [[viewController_ view] frame];
     86 
     87   if (rightPoint.x + NSWidth(frame) < NSMaxX(screenFrame)) {
     88     frame.origin.x = rightPoint.x;
     89     frame.origin.y = rightPoint.y - NSHeight(frame);
     90   } else {
     91     frame.origin.x = leftPoint.x - NSWidth(frame);
     92     frame.origin.y = leftPoint.y - NSHeight(frame);
     93   }
     94 
     95   [[self window] setFrame:frame display:YES];
     96   [viewController_ scrollToTop];
     97   [self showWindow:nil];
     98 }
     99 
    100 - (void)onMessageCenterTrayChanged {
    101   [viewController_ onMessageCenterTrayChanged];
    102 }
    103 
    104 - (void)windowDidResignKey:(NSNotification*)notification {
    105   // The settings bubble data structures assume that the settings dialog is
    106   // visible only for short periods of time: There's a fixed list of permissions
    107   // for example.
    108   [viewController_ cleanupSettings];
    109 
    110   tray_->HideMessageCenterBubble();
    111 }
    112 
    113 @end
    114