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