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_ hideSettings:self]; 109 110 tray_->HideMessageCenterBubble(); 111 } 112 113 @end 114