• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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