Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(520)

Unified Diff: ui/message_center/cocoa/tray_view_controller.mm

Issue 1334363002: [Eraser] First pass at removing the notification center panel. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: peter comments Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/message_center/cocoa/tray_view_controller.mm
diff --git a/ui/message_center/cocoa/tray_view_controller.mm b/ui/message_center/cocoa/tray_view_controller.mm
deleted file mode 100644
index a63f3d3ccc02721f37cc127762e222053f207f21..0000000000000000000000000000000000000000
--- a/ui/message_center/cocoa/tray_view_controller.mm
+++ /dev/null
@@ -1,810 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "ui/message_center/cocoa/tray_view_controller.h"
-
-#include <cmath>
-
-#include "base/mac/scoped_nsautorelease_pool.h"
-#include "base/time/time.h"
-#include "skia/ext/skia_utils_mac.h"
-#import "ui/base/cocoa/hover_image_button.h"
-#include "ui/base/l10n/l10n_util_mac.h"
-#include "ui/base/resource/resource_bundle.h"
-#import "ui/message_center/cocoa/notification_controller.h"
-#import "ui/message_center/cocoa/opaque_views.h"
-#import "ui/message_center/cocoa/settings_controller.h"
-#include "ui/message_center/message_center.h"
-#include "ui/message_center/message_center_style.h"
-#include "ui/message_center/notifier_settings.h"
-#include "ui/resources/grit/ui_resources.h"
-#include "ui/strings/grit/ui_strings.h"
-
-const int kBackButtonSize = 16;
-
-// NSClipView subclass.
-@interface MCClipView : NSClipView {
- // If this is set, the visible document area will remain intact no matter how
- // the user scrolls or drags the thumb.
- BOOL frozen_;
-}
-@end
-
-@implementation MCClipView
-- (void)setFrozen:(BOOL)frozen {
- frozen_ = frozen;
-}
-
-- (NSPoint)constrainScrollPoint:(NSPoint)proposedNewOrigin {
- return frozen_ ? [self documentVisibleRect].origin :
- [super constrainScrollPoint:proposedNewOrigin];
-}
-@end
-
-@interface MCTrayViewController (Private)
-// Creates all the views for the control area of the tray.
-- (void)layoutControlArea;
-
-// Update both tray view and window by resizing it to fit its content.
-- (void)updateTrayViewAndWindow;
-
-// Remove notifications dismissed by the user. It is done in the following
-// 3 steps.
-- (void)closeNotificationsByUser;
-
-// Step 1: hide all notifications pending removal with fade-out animation.
-- (void)hideNotificationsPendingRemoval;
-
-// Step 2: move up all remaining notifications to take over the available space
-// due to hiding notifications. The scroll view and the window remain unchanged.
-- (void)moveUpRemainingNotifications;
-
-// Step 3: finalize the tray view and window to get rid of the empty space.
-- (void)finalizeTrayViewAndWindow;
-
-// Clear a notification by sliding it out from left to right. This occurs when
-// "Clear All" is clicked.
-- (void)clearOneNotification;
-
-// When all visible notifications slide out, re-enable controls and remove
-// notifications from the message center.
-- (void)finalizeClearAll;
-
-// Sets the images of the quiet mode button based on the message center state.
-- (void)updateQuietModeButtonImage;
-@end
-
-namespace {
-
-// The duration of fade-out and bounds animation.
-const NSTimeInterval kAnimationDuration = 0.2;
-
-// The delay to start animating clearing next notification since current
-// animation starts.
-const NSTimeInterval kAnimateClearingNextNotificationDelay = 0.04;
-
-// The height of the bar at the top of the tray that contains buttons.
-const CGFloat kControlAreaHeight = 50;
-
-// Amount of spacing between control buttons. There is kMarginBetweenItems
-// between a button and the edge of the tray, though.
-const CGFloat kButtonXMargin = 20;
-
-// Amount of padding to leave between the bottom of the screen and the bottom
-// of the message center tray.
-const CGFloat kTrayBottomMargin = 75;
-
-} // namespace
-
-@implementation MCTrayViewController
-
-- (id)initWithMessageCenter:(message_center::MessageCenter*)messageCenter {
- if ((self = [super initWithNibName:nil bundle:nil])) {
- messageCenter_ = messageCenter;
- animationDuration_ = kAnimationDuration;
- animateClearingNextNotificationDelay_ =
- kAnimateClearingNextNotificationDelay;
- notifications_.reset([[NSMutableArray alloc] init]);
- notificationsPendingRemoval_.reset([[NSMutableArray alloc] init]);
- }
- return self;
-}
-
-- (NSString*)trayTitle {
- return [title_ stringValue];
-}
-
-- (void)setTrayTitle:(NSString*)title {
- [title_ setStringValue:title];
- [title_ sizeToFit];
-}
-
-- (void)onWindowClosing {
- if (animation_) {
- [animation_ stopAnimation];
- [animation_ setDelegate:nil];
- animation_.reset();
- }
- if (clearAllInProgress_) {
- // To stop chain of clearOneNotification calls to start new animations.
- [NSObject cancelPreviousPerformRequestsWithTarget:self];
-
- for (NSViewAnimation* animation in clearAllAnimations_.get()) {
- [animation stopAnimation];
- [animation setDelegate:nil];
- }
- [clearAllAnimations_ removeAllObjects];
- [self finalizeClearAll];
- }
-}
-
-- (void)loadView {
- // Configure the root view as a background-colored box.
- base::scoped_nsobject<NSBox> view([[NSBox alloc] initWithFrame:NSMakeRect(
- 0, 0, [MCTrayViewController trayWidth], kControlAreaHeight)]);
- [view setBorderType:NSNoBorder];
- [view setBoxType:NSBoxCustom];
- [view setContentViewMargins:NSZeroSize];
- [view setFillColor:gfx::SkColorToCalibratedNSColor(
- message_center::kMessageCenterBackgroundColor)];
- [view setTitlePosition:NSNoTitle];
- [view setWantsLayer:YES]; // Needed for notification view shadows.
- [self setView:view];
-
- [self layoutControlArea];
-
- // Configure the scroll view in which all the notifications go.
- base::scoped_nsobject<NSView> documentView(
- [[NSView alloc] initWithFrame:NSZeroRect]);
- scrollView_.reset([[NSScrollView alloc] initWithFrame:[view frame]]);
- clipView_.reset(
- [[MCClipView alloc] initWithFrame:[[scrollView_ contentView] frame]]);
- [scrollView_ setContentView:clipView_];
- [scrollView_ setAutohidesScrollers:YES];
- [scrollView_ setAutoresizingMask:NSViewHeightSizable | NSViewMaxYMargin];
- [scrollView_ setDocumentView:documentView];
- [scrollView_ setDrawsBackground:NO];
- [scrollView_ setHasHorizontalScroller:NO];
- [scrollView_ setHasVerticalScroller:YES];
- [view addSubview:scrollView_];
-
- [self onMessageCenterTrayChanged];
-}
-
-- (void)onMessageCenterTrayChanged {
- if (settingsController_)
- return [self updateTrayViewAndWindow];
-
- std::map<std::string, MCNotificationController*> newMap;
-
- base::scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
- [shadow setShadowColor:[NSColor colorWithDeviceWhite:0 alpha:0.55]];
- [shadow setShadowOffset:NSMakeSize(0, -1)];
- [shadow setShadowBlurRadius:2.0];
-
- CGFloat minY = message_center::kMarginBetweenItems;
-
- // Iterate over the notifications in reverse, since the Cocoa coordinate
- // origin is in the lower-left. Remove from |notificationsMap_| all the
- // ones still in the updated model, so that those that should be removed
- // will remain in the map.
- const auto& modelNotifications = messageCenter_->GetVisibleNotifications();
- for (auto it = modelNotifications.rbegin();
- it != modelNotifications.rend();
- ++it) {
- // Check if this notification is already in the tray.
- const auto& existing = notificationsMap_.find((*it)->id());
- MCNotificationController* notification = nil;
- if (existing == notificationsMap_.end()) {
- base::scoped_nsobject<MCNotificationController> controller(
- [[MCNotificationController alloc]
- initWithNotification:*it
- messageCenter:messageCenter_]);
- [[controller view] setShadow:shadow];
- [[scrollView_ documentView] addSubview:[controller view]];
-
- [notifications_ addObject:controller]; // Transfer ownership.
- messageCenter_->DisplayedNotification(
- (*it)->id(), message_center::DISPLAY_SOURCE_MESSAGE_CENTER);
-
- notification = controller.get();
- } else {
- notification = existing->second;
- [notification updateNotification:*it];
- notificationsMap_.erase(existing);
- }
-
- DCHECK(notification);
-
- NSRect frame = [[notification view] frame];
- frame.origin.x = message_center::kMarginBetweenItems;
- frame.origin.y = minY;
- [[notification view] setFrame:frame];
-
- newMap.insert(std::make_pair((*it)->id(), notification));
-
- minY = NSMaxY(frame) + message_center::kMarginBetweenItems;
- }
-
- // Remove any notifications that are no longer in the model.
- for (const auto& pair : notificationsMap_) {
- [[pair.second view] removeFromSuperview];
- [notifications_ removeObject:pair.second];
- }
-
- // Copy the new map of notifications to replace the old.
- notificationsMap_ = newMap;
-
- [self updateTrayViewAndWindow];
-}
-
-- (void)toggleQuietMode:(id)sender {
- if (messageCenter_->IsQuietMode())
- messageCenter_->SetQuietMode(false);
- else
- messageCenter_->EnterQuietModeWithExpire(base::TimeDelta::FromDays(1));
-
- [self updateQuietModeButtonImage];
-}
-
-- (void)clearAllNotifications:(id)sender {
- if ([self isAnimating]) {
- clearAllDelayed_ = YES;
- return;
- }
-
- // Build a list for all notifications within the visible scroll range
- // in preparation to slide them out one by one.
- NSRect visibleScrollRect = [scrollView_ documentVisibleRect];
- for (MCNotificationController* notification in notifications_.get()) {
- NSRect rect = [[notification view] frame];
- if (!NSIsEmptyRect(NSIntersectionRect(visibleScrollRect, rect))) {
- visibleNotificationsPendingClear_.push_back(notification);
- }
- }
- if (visibleNotificationsPendingClear_.empty())
- return;
-
- // Disbale buttons and freeze scroll bar to prevent the user from clicking on
- // them accidentally.
- [pauseButton_ setEnabled:NO];
- [clearAllButton_ setEnabled:NO];
- [settingsButton_ setEnabled:NO];
- [clipView_ setFrozen:YES];
-
- // Start sliding out the top notification.
- clearAllAnimations_.reset([[NSMutableArray alloc] init]);
- [self clearOneNotification];
-
- clearAllInProgress_ = YES;
-}
-
-- (void)showSettings:(id)sender {
- if (settingsController_)
- return [self showMessages:sender];
-
- message_center::NotifierSettingsProvider* provider =
- messageCenter_->GetNotifierSettingsProvider();
- settingsController_.reset(
- [[MCSettingsController alloc] initWithProvider:provider
- trayViewController:self]);
-
- [[self view] addSubview:[settingsController_ view]];
-
- NSRect titleFrame = [title_ frame];
- titleFrame.origin.x =
- NSMaxX([backButton_ frame]) + message_center::kMarginBetweenItems / 2;
- [title_ setFrame:titleFrame];
- [backButton_ setHidden:NO];
- [clearAllButton_ setEnabled:NO];
-
- [scrollView_ setHidden:YES];
-
- [[[self view] window] recalculateKeyViewLoop];
- messageCenter_->SetVisibility(message_center::VISIBILITY_SETTINGS);
-
- [self updateTrayViewAndWindow];
-}
-
-- (void)updateSettings {
- // TODO(jianli): This class should not be calling -loadView, but instead
- // should just observe a resize notification.
- // (http://crbug.com/270251)
- [[settingsController_ view] removeFromSuperview];
- [settingsController_ loadView];
- [[self view] addSubview:[settingsController_ view]];
-
- [self updateTrayViewAndWindow];
-}
-
-- (void)showMessages:(id)sender {
- messageCenter_->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER);
- [self cleanupSettings];
- [[[self view] window] recalculateKeyViewLoop];
- [self updateTrayViewAndWindow];
-}
-
-- (void)cleanupSettings {
- [scrollView_ setHidden:NO];
-
- [[settingsController_ view] removeFromSuperview];
- settingsController_.reset();
-
- NSRect titleFrame = [title_ frame];
- titleFrame.origin.x = NSMinX([backButton_ frame]);
- [title_ setFrame:titleFrame];
- [backButton_ setHidden:YES];
- [clearAllButton_ setEnabled:YES];
-
-}
-
-- (void)scrollToTop {
- NSPoint topPoint =
- NSMakePoint(0.0, [[scrollView_ documentView] bounds].size.height);
- [[scrollView_ documentView] scrollPoint:topPoint];
-}
-
-- (BOOL)isAnimating {
- return [animation_ isAnimating] || [clearAllAnimations_ count];
-}
-
-+ (CGFloat)maxTrayClientHeight {
- NSRect screenFrame = [[[NSScreen screens] objectAtIndex:0] visibleFrame];
- return NSHeight(screenFrame) - kTrayBottomMargin - kControlAreaHeight;
-}
-
-+ (CGFloat)trayWidth {
- return message_center::kNotificationWidth +
- 2 * message_center::kMarginBetweenItems;
-}
-
-// Testing API /////////////////////////////////////////////////////////////////
-
-- (NSBox*)divider {
- return divider_.get();
-}
-
-- (NSTextField*)emptyDescription {
- return emptyDescription_.get();
-}
-
-- (NSScrollView*)scrollView {
- return scrollView_.get();
-}
-
-- (HoverImageButton*)pauseButton {
- return pauseButton_.get();
-}
-
-- (HoverImageButton*)clearAllButton {
- return clearAllButton_.get();
-}
-
-- (void)setAnimationDuration:(NSTimeInterval)duration {
- animationDuration_ = duration;
-}
-
-- (void)setAnimateClearingNextNotificationDelay:(NSTimeInterval)delay {
- animateClearingNextNotificationDelay_ = delay;
-}
-
-- (void)setAnimationEndedCallback:
- (message_center::TrayAnimationEndedCallback)callback {
- testingAnimationEndedCallback_.reset(Block_copy(callback));
-}
-
-// Private /////////////////////////////////////////////////////////////////////
-
-- (void)layoutControlArea {
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- NSView* view = [self view];
-
- // Create the "Notifications" label at the top of the tray.
- NSFont* font = [NSFont labelFontOfSize:message_center::kTitleFontSize];
- NSColor* color = gfx::SkColorToCalibratedNSColor(
- message_center::kMessageCenterBackgroundColor);
- title_.reset(
- [[MCTextField alloc] initWithFrame:NSZeroRect backgroundColor:color]);
-
- [title_ setFont:font];
- [title_ setStringValue:
- l10n_util::GetNSString(IDS_MESSAGE_CENTER_FOOTER_TITLE)];
- [title_ setTextColor:gfx::SkColorToCalibratedNSColor(
- message_center::kRegularTextColor)];
- [title_ sizeToFit];
-
- NSRect titleFrame = [title_ frame];
- titleFrame.origin.x = message_center::kMarginBetweenItems;
- titleFrame.origin.y = kControlAreaHeight/2 - NSMidY(titleFrame);
- [title_ setFrame:titleFrame];
- [view addSubview:title_];
-
- auto configureButton = ^(HoverImageButton* button) {
- [[button cell] setHighlightsBy:NSOnState];
- [button setTrackingEnabled:YES];
- [button setBordered:NO];
- [button setAutoresizingMask:NSViewMinYMargin];
- [button setTarget:self];
- };
-
- // Back button. On top of the "Notifications" label, hidden by default.
- NSRect backButtonFrame =
- NSMakeRect(NSMinX(titleFrame),
- (kControlAreaHeight - kBackButtonSize) / 2,
- kBackButtonSize,
- kBackButtonSize);
- backButton_.reset([[HoverImageButton alloc] initWithFrame:backButtonFrame]);
- [backButton_ setDefaultImage:
- rb.GetNativeImageNamed(IDR_NOTIFICATION_ARROW).ToNSImage()];
- [backButton_ setHoverImage:
- rb.GetNativeImageNamed(IDR_NOTIFICATION_ARROW_HOVER).ToNSImage()];
- [backButton_ setPressedImage:
- rb.GetNativeImageNamed(IDR_NOTIFICATION_ARROW_PRESSED).ToNSImage()];
- [backButton_ setAction:@selector(showMessages:)];
- configureButton(backButton_);
- [backButton_ setHidden:YES];
- [backButton_ setKeyEquivalent:@"\e"];
- [backButton_ setToolTip:l10n_util::GetNSString(
- IDS_MESSAGE_CENTER_SETTINGS_GO_BACK_BUTTON_TOOLTIP)];
- [[backButton_ cell]
- accessibilitySetOverrideValue:[backButton_ toolTip]
- forAttribute:NSAccessibilityDescriptionAttribute];
- [[self view] addSubview:backButton_];
-
- // Create the divider line between the control area and the notifications.
- divider_.reset(
- [[NSBox alloc] initWithFrame:NSMakeRect(0, 0, NSWidth([view frame]), 1)]);
- [divider_ setAutoresizingMask:NSViewMinYMargin];
- [divider_ setBorderType:NSNoBorder];
- [divider_ setBoxType:NSBoxCustom];
- [divider_ setContentViewMargins:NSZeroSize];
- [divider_ setFillColor:gfx::SkColorToCalibratedNSColor(
- message_center::kFooterDelimiterColor)];
- [divider_ setTitlePosition:NSNoTitle];
- [view addSubview:divider_];
-
-
- auto getButtonFrame = ^NSRect(CGFloat maxX, NSImage* image) {
- NSSize size = [image size];
- return NSMakeRect(
- maxX - size.width,
- kControlAreaHeight/2 - size.height/2,
- size.width,
- size.height);
- };
-
- // Create the settings button at the far-right.
- NSImage* defaultImage =
- rb.GetNativeImageNamed(IDR_NOTIFICATION_SETTINGS).ToNSImage();
- NSRect settingsButtonFrame = getButtonFrame(
- NSWidth([view frame]) - message_center::kMarginBetweenItems,
- defaultImage);
- settingsButton_.reset(
- [[HoverImageButton alloc] initWithFrame:settingsButtonFrame]);
- [settingsButton_ setDefaultImage:defaultImage];
- [settingsButton_ setHoverImage:
- rb.GetNativeImageNamed(IDR_NOTIFICATION_SETTINGS_HOVER).ToNSImage()];
- [settingsButton_ setPressedImage:
- rb.GetNativeImageNamed(IDR_NOTIFICATION_SETTINGS_PRESSED).ToNSImage()];
- [settingsButton_ setToolTip:
- l10n_util::GetNSString(IDS_MESSAGE_CENTER_SETTINGS_BUTTON_LABEL)];
- [[settingsButton_ cell]
- accessibilitySetOverrideValue:[settingsButton_ toolTip]
- forAttribute:NSAccessibilityDescriptionAttribute];
- [settingsButton_ setAction:@selector(showSettings:)];
- configureButton(settingsButton_);
- [view addSubview:settingsButton_];
-
- // Create the clear all button.
- defaultImage = rb.GetNativeImageNamed(IDR_NOTIFICATION_CLEAR_ALL).ToNSImage();
- NSRect clearAllButtonFrame = getButtonFrame(
- NSMinX(settingsButtonFrame) - kButtonXMargin,
- defaultImage);
- clearAllButton_.reset(
- [[HoverImageButton alloc] initWithFrame:clearAllButtonFrame]);
- [clearAllButton_ setDefaultImage:defaultImage];
- [clearAllButton_ setHoverImage:
- rb.GetNativeImageNamed(IDR_NOTIFICATION_CLEAR_ALL_HOVER).ToNSImage()];
- [clearAllButton_ setPressedImage:
- rb.GetNativeImageNamed(IDR_NOTIFICATION_CLEAR_ALL_PRESSED).ToNSImage()];
- [clearAllButton_ setToolTip:
- l10n_util::GetNSString(IDS_MESSAGE_CENTER_CLEAR_ALL)];
- [[clearAllButton_ cell]
- accessibilitySetOverrideValue:[clearAllButton_ toolTip]
- forAttribute:NSAccessibilityDescriptionAttribute];
- [clearAllButton_ setAction:@selector(clearAllNotifications:)];
- configureButton(clearAllButton_);
- [view addSubview:clearAllButton_];
-
- // Create the pause button.
- NSRect pauseButtonFrame = getButtonFrame(
- NSMinX(clearAllButtonFrame) - kButtonXMargin,
- defaultImage);
- pauseButton_.reset([[HoverImageButton alloc] initWithFrame:pauseButtonFrame]);
- [self updateQuietModeButtonImage];
- [pauseButton_ setHoverImage: rb.GetNativeImageNamed(
- IDR_NOTIFICATION_DO_NOT_DISTURB_HOVER).ToNSImage()];
- [pauseButton_ setToolTip:
- l10n_util::GetNSString(IDS_MESSAGE_CENTER_QUIET_MODE_BUTTON_TOOLTIP)];
- [[pauseButton_ cell]
- accessibilitySetOverrideValue:[pauseButton_ toolTip]
- forAttribute:NSAccessibilityDescriptionAttribute];
- [pauseButton_ setAction:@selector(toggleQuietMode:)];
- configureButton(pauseButton_);
- [view addSubview:pauseButton_];
-
- // Create the description field for the empty message center. Initially it is
- // invisible.
- emptyDescription_.reset(
- [[MCTextField alloc] initWithFrame:NSZeroRect backgroundColor:color]);
-
- NSFont* smallFont =
- [NSFont labelFontOfSize:message_center::kEmptyCenterFontSize];
- [emptyDescription_ setFont:smallFont];
- [emptyDescription_ setStringValue:
- l10n_util::GetNSString(IDS_MESSAGE_CENTER_NO_MESSAGES)];
- [emptyDescription_ setTextColor:gfx::SkColorToCalibratedNSColor(
- message_center::kDimTextColor)];
- [emptyDescription_ sizeToFit];
- [emptyDescription_ setHidden:YES];
-
- [view addSubview:emptyDescription_];
-}
-
-- (void)updateTrayViewAndWindow {
- CGFloat scrollContentHeight = message_center::kMinScrollViewHeight;
- if ([notifications_ count]) {
- [emptyDescription_ setHidden:YES];
- [scrollView_ setHidden:NO];
- [divider_ setHidden:NO];
- scrollContentHeight = NSMaxY([[[notifications_ lastObject] view] frame]) +
- message_center::kMarginBetweenItems;;
- } else {
- [emptyDescription_ setHidden:NO];
- [scrollView_ setHidden:YES];
- [divider_ setHidden:YES];
-
- NSRect centeredFrame = [emptyDescription_ frame];
- NSPoint centeredOrigin = NSMakePoint(
- floor((NSWidth([[self view] frame]) - NSWidth(centeredFrame))/2 + 0.5),
- floor((scrollContentHeight - NSHeight(centeredFrame))/2 + 0.5));
-
- centeredFrame.origin = centeredOrigin;
- [emptyDescription_ setFrame:centeredFrame];
- }
-
- // Resize the scroll view's content.
- NSRect scrollViewFrame = [scrollView_ frame];
- NSRect documentFrame = [[scrollView_ documentView] frame];
- documentFrame.size.width = NSWidth(scrollViewFrame);
- documentFrame.size.height = scrollContentHeight;
- [[scrollView_ documentView] setFrame:documentFrame];
-
- // Resize the container view.
- NSRect frame = [[self view] frame];
- CGFloat oldHeight = NSHeight(frame);
- if (settingsController_) {
- frame.size.height = NSHeight([[settingsController_ view] frame]);
- } else {
- frame.size.height = std::min([MCTrayViewController maxTrayClientHeight],
- scrollContentHeight);
- }
- frame.size.height += kControlAreaHeight;
- CGFloat newHeight = NSHeight(frame);
- [[self view] setFrame:frame];
-
- // Resize the scroll view.
- scrollViewFrame.size.height = NSHeight(frame) - kControlAreaHeight;
- [scrollView_ setFrame:scrollViewFrame];
-
- // Resize the window.
- NSRect windowFrame = [[[self view] window] frame];
- CGFloat delta = newHeight - oldHeight;
- windowFrame.origin.y -= delta;
- windowFrame.size.height += delta;
-
- [[[self view] window] setFrame:windowFrame display:YES];
- // Hide the clear-all button if there are no notifications. Simply swap the
- // X position of it and the pause button in that case.
- BOOL hidden = ![notifications_ count];
- if ([clearAllButton_ isHidden] != hidden) {
- [clearAllButton_ setHidden:hidden];
-
- NSRect pauseButtonFrame = [pauseButton_ frame];
- NSRect clearAllButtonFrame = [clearAllButton_ frame];
- std::swap(clearAllButtonFrame.origin.x, pauseButtonFrame.origin.x);
- [pauseButton_ setFrame:pauseButtonFrame];
- [clearAllButton_ setFrame:clearAllButtonFrame];
- }
-}
-
-- (void)animationDidEnd:(NSAnimation*)animation {
- if (clearAllInProgress_) {
- // For clear-all animation.
- [clearAllAnimations_ removeObject:animation];
- if (![clearAllAnimations_ count] &&
- visibleNotificationsPendingClear_.empty()) {
- [self finalizeClearAll];
- }
- } else {
- // For notification removal and reposition animation.
- if ([notificationsPendingRemoval_ count]) {
- [self moveUpRemainingNotifications];
- } else {
- [self finalizeTrayViewAndWindow];
-
- if (clearAllDelayed_)
- [self clearAllNotifications:nil];
- }
- }
-
- // Give the testing code a chance to do something, i.e. quitting the test
- // run loop.
- if (![self isAnimating] && testingAnimationEndedCallback_)
- testingAnimationEndedCallback_.get()();
-}
-
-- (void)closeNotificationsByUser {
- // No need to close individual notification if clear-all is in progress.
- if (clearAllInProgress_)
- return;
-
- if ([self isAnimating])
- return;
- [self hideNotificationsPendingRemoval];
-}
-
-- (void)hideNotificationsPendingRemoval {
- base::scoped_nsobject<NSMutableArray> animationDataArray(
- [[NSMutableArray alloc] init]);
-
- // Fade-out those notifications pending removal.
- for (MCNotificationController* notification in notifications_.get()) {
- if (messageCenter_->FindVisibleNotificationById(
- [notification notificationID]))
- continue;
- [notificationsPendingRemoval_ addObject:notification];
- [animationDataArray addObject:@{
- NSViewAnimationTargetKey : [notification view],
- NSViewAnimationEffectKey : NSViewAnimationFadeOutEffect
- }];
- }
-
- if ([notificationsPendingRemoval_ count] == 0)
- return;
-
- for (MCNotificationController* notification in
- notificationsPendingRemoval_.get()) {
- [notifications_ removeObject:notification];
- }
-
- // Start the animation.
- animation_.reset([[NSViewAnimation alloc]
- initWithViewAnimations:animationDataArray]);
- [animation_ setDuration:animationDuration_];
- [animation_ setDelegate:self];
- [animation_ startAnimation];
-}
-
-- (void)moveUpRemainingNotifications {
- base::scoped_nsobject<NSMutableArray> animationDataArray(
- [[NSMutableArray alloc] init]);
-
- // Compute the position where the remaining notifications should start.
- CGFloat minY = message_center::kMarginBetweenItems;
- for (MCNotificationController* notification in
- notificationsPendingRemoval_.get()) {
- NSView* view = [notification view];
- minY += NSHeight([view frame]) + message_center::kMarginBetweenItems;
- }
-
- // Reposition the remaining notifications starting at the computed position.
- for (MCNotificationController* notification in notifications_.get()) {
- NSView* view = [notification view];
- NSRect frame = [view frame];
- NSRect oldFrame = frame;
- frame.origin.y = minY;
- if (!NSEqualRects(oldFrame, frame)) {
- [animationDataArray addObject:@{
- NSViewAnimationTargetKey : view,
- NSViewAnimationEndFrameKey : [NSValue valueWithRect:frame]
- }];
- }
- minY = NSMaxY(frame) + message_center::kMarginBetweenItems;
- }
-
- // Now remove notifications pending removal.
- for (MCNotificationController* notification in
- notificationsPendingRemoval_.get()) {
- [[notification view] removeFromSuperview];
- notificationsMap_.erase([notification notificationID]);
- }
- [notificationsPendingRemoval_ removeAllObjects];
-
- // Start the animation.
- animation_.reset([[NSViewAnimation alloc]
- initWithViewAnimations:animationDataArray]);
- [animation_ setDuration:animationDuration_];
- [animation_ setDelegate:self];
- [animation_ startAnimation];
-}
-
-- (void)finalizeTrayViewAndWindow {
- // Reposition the remaining notifications starting at the bottom.
- CGFloat minY = message_center::kMarginBetweenItems;
- for (MCNotificationController* notification in notifications_.get()) {
- NSView* view = [notification view];
- NSRect frame = [view frame];
- NSRect oldFrame = frame;
- frame.origin.y = minY;
- if (!NSEqualRects(oldFrame, frame))
- [view setFrame:frame];
- minY = NSMaxY(frame) + message_center::kMarginBetweenItems;
- }
-
- [self updateTrayViewAndWindow];
-
- // Check if there're more notifications pending removal.
- [self closeNotificationsByUser];
-}
-
-- (void)clearOneNotification {
- DCHECK(!visibleNotificationsPendingClear_.empty());
-
- MCNotificationController* notification =
- visibleNotificationsPendingClear_.back();
- visibleNotificationsPendingClear_.pop_back();
-
- // Slide out the notification from left to right with fade-out simultaneously.
- NSRect newFrame = [[notification view] frame];
- newFrame.origin.x = NSMaxX(newFrame) + message_center::kMarginBetweenItems;
- NSDictionary* animationDict = @{
- NSViewAnimationTargetKey : [notification view],
- NSViewAnimationEndFrameKey : [NSValue valueWithRect:newFrame],
- NSViewAnimationEffectKey : NSViewAnimationFadeOutEffect
- };
- base::scoped_nsobject<NSViewAnimation> animation([[NSViewAnimation alloc]
- initWithViewAnimations:[NSArray arrayWithObject:animationDict]]);
- [animation setDuration:animationDuration_];
- [animation setDelegate:self];
- [animation startAnimation];
- [clearAllAnimations_ addObject:animation];
-
- // Schedule to start sliding out next notification after a short delay.
- if (!visibleNotificationsPendingClear_.empty()) {
- [self performSelector:@selector(clearOneNotification)
- withObject:nil
- afterDelay:animateClearingNextNotificationDelay_];
- }
-}
-
-- (void)finalizeClearAll {
- DCHECK(clearAllInProgress_);
- clearAllInProgress_ = NO;
-
- DCHECK(![clearAllAnimations_ count]);
- clearAllAnimations_.reset();
-
- [pauseButton_ setEnabled:YES];
- [clearAllButton_ setEnabled:YES];
- [settingsButton_ setEnabled:YES];
- [clipView_ setFrozen:NO];
-
- messageCenter_->RemoveAllVisibleNotifications(true);
-}
-
-- (void)updateQuietModeButtonImage {
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- if (messageCenter_->IsQuietMode()) {
- [pauseButton_ setTrackingEnabled:NO];
- [pauseButton_ setDefaultImage: rb.GetNativeImageNamed(
- IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED).ToNSImage()];
- } else {
- [pauseButton_ setTrackingEnabled:YES];
- [pauseButton_ setDefaultImage:
- rb.GetNativeImageNamed(IDR_NOTIFICATION_DO_NOT_DISTURB).ToNSImage()];
- }
-}
-
-@end
« no previous file with comments | « ui/message_center/cocoa/tray_view_controller.h ('k') | ui/message_center/cocoa/tray_view_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698