diff options
Diffstat (limited to 'chromium/ash/system/web_notification/web_notification_tray.cc')
-rw-r--r-- | chromium/ash/system/web_notification/web_notification_tray.cc | 624 |
1 files changed, 0 insertions, 624 deletions
diff --git a/chromium/ash/system/web_notification/web_notification_tray.cc b/chromium/ash/system/web_notification/web_notification_tray.cc deleted file mode 100644 index b0b75d87dfc..00000000000 --- a/chromium/ash/system/web_notification/web_notification_tray.cc +++ /dev/null @@ -1,624 +0,0 @@ -// Copyright (c) 2012 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. - -#include "ash/system/web_notification/web_notification_tray.h" - -#include "ash/ash_switches.h" -#include "ash/root_window_controller.h" -#include "ash/shelf/shelf_layout_manager.h" -#include "ash/shelf/shelf_layout_manager_observer.h" -#include "ash/shelf/shelf_widget.h" -#include "ash/shell.h" -#include "ash/shell_window_ids.h" -#include "ash/system/status_area_widget.h" -#include "ash/system/tray/system_tray.h" -#include "ash/system/tray/tray_background_view.h" -#include "ash/system/tray/tray_bubble_wrapper.h" -#include "ash/system/tray/tray_constants.h" -#include "ash/system/tray/tray_utils.h" -#include "base/auto_reset.h" -#include "base/i18n/number_formatting.h" -#include "base/i18n/rtl.h" -#include "base/strings/utf_string_conversions.h" -#include "grit/ash_strings.h" -#include "grit/ui_strings.h" -#include "ui/aura/root_window.h" -#include "ui/aura/window.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/gfx/screen.h" -#include "ui/message_center/message_center_style.h" -#include "ui/message_center/message_center_tray_delegate.h" -#include "ui/message_center/message_center_util.h" -#include "ui/message_center/views/message_bubble_base.h" -#include "ui/message_center/views/message_center_bubble.h" -#include "ui/message_center/views/message_popup_collection.h" -#include "ui/views/bubble/tray_bubble_view.h" -#include "ui/views/controls/button/custom_button.h" -#include "ui/views/controls/image_view.h" -#include "ui/views/controls/label.h" -#include "ui/views/controls/menu/menu_runner.h" -#include "ui/views/layout/fill_layout.h" - -#if defined(OS_CHROMEOS) - -namespace message_center { - -MessageCenterTrayDelegate* CreateMessageCenterTray() { - // On Windows+Ash the Tray will not be hosted in ash::Shell. - NOTREACHED(); - return NULL; -} - -} // namespace message_center - -#endif // defined(OS_CHROMEOS) - -namespace ash { -namespace { - -// Menu commands -const int kToggleQuietMode = 0; -const int kEnableQuietModeDay = 2; - -} - -namespace internal { -namespace { - -const SkColor kWebNotificationColorNoUnread = SkColorSetA(SK_ColorWHITE, 128); -const SkColor kWebNotificationColorWithUnread = SK_ColorWHITE; - -} - -// Observes the change of work area (including temporary change by auto-hide) -// and notifies MessagePopupCollection. -class WorkAreaObserver : public ShelfLayoutManagerObserver, - public ShellObserver { - public: - WorkAreaObserver(); - virtual ~WorkAreaObserver(); - - void SetSystemTrayHeight(int height); - - // Starts observing |shelf| and shell and sends the change to |collection|. - void StartObserving(message_center::MessagePopupCollection* collection, - aura::Window* root_window); - - // Stops the observing session. - void StopObserving(); - - // Overridden from ShellObserver: - virtual void OnDisplayWorkAreaInsetsChanged() OVERRIDE; - - // Overridden from ShelfLayoutManagerObserver: - virtual void OnAutoHideStateChanged(ShelfAutoHideState new_state) OVERRIDE; - - private: - // Updates |shelf_| from |root_window_|. - void UpdateShelf(); - - message_center::MessagePopupCollection* collection_; - aura::Window* root_window_; - ShelfLayoutManager* shelf_; - int system_tray_height_; - - DISALLOW_COPY_AND_ASSIGN(WorkAreaObserver); -}; - -WorkAreaObserver::WorkAreaObserver() - : collection_(NULL), - root_window_(NULL), - shelf_(NULL), - system_tray_height_(0) { -} - -WorkAreaObserver::~WorkAreaObserver() { - StopObserving(); -} - -void WorkAreaObserver::SetSystemTrayHeight(int height) { - system_tray_height_ = height; - - // If the shelf is shown during auto-hide state, the distance from the edge - // should be reduced by the height of shelf's shown height. - if (shelf_ && shelf_->visibility_state() == SHELF_AUTO_HIDE && - shelf_->auto_hide_state() == SHELF_AUTO_HIDE_SHOWN) { - system_tray_height_ -= ShelfLayoutManager::GetPreferredShelfSize() - - ShelfLayoutManager::kAutoHideSize; - } - - if (system_tray_height_ > 0 && ash::switches::UseAlternateShelfLayout()) - system_tray_height_ += message_center::kMarginBetweenItems; - - if (!shelf_) - return; - - OnAutoHideStateChanged(shelf_->auto_hide_state()); -} - -void WorkAreaObserver::StartObserving( - message_center::MessagePopupCollection* collection, - aura::Window* root_window) { - DCHECK(collection); - collection_ = collection; - root_window_ = root_window; - UpdateShelf(); - Shell::GetInstance()->AddShellObserver(this); - if (system_tray_height_ > 0) - OnAutoHideStateChanged(shelf_->auto_hide_state()); -} - -void WorkAreaObserver::StopObserving() { - Shell::GetInstance()->RemoveShellObserver(this); - if (shelf_) - shelf_->RemoveObserver(this); - collection_ = NULL; - shelf_ = NULL; -} - -void WorkAreaObserver::OnDisplayWorkAreaInsetsChanged() { - UpdateShelf(); - - collection_->OnDisplayBoundsChanged( - Shell::GetScreen()->GetDisplayNearestWindow( - shelf_->shelf_widget()->GetNativeView())); -} - -void WorkAreaObserver::OnAutoHideStateChanged(ShelfAutoHideState new_state) { - gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow( - shelf_->shelf_widget()->GetNativeView()); - gfx::Rect work_area = display.work_area(); - int width = 0; - if ((shelf_->visibility_state() == SHELF_AUTO_HIDE) && - new_state == SHELF_AUTO_HIDE_SHOWN) { - // Since the work_area is already reduced by kAutoHideSize, the inset width - // should be just the difference. - width = ShelfLayoutManager::GetPreferredShelfSize() - - ShelfLayoutManager::kAutoHideSize; - } - work_area.Inset(shelf_->SelectValueForShelfAlignment( - gfx::Insets(0, 0, width, 0), - gfx::Insets(0, width, 0, 0), - gfx::Insets(0, 0, 0, width), - gfx::Insets(width, 0, 0, 0))); - if (system_tray_height_ > 0) { - work_area.set_height( - std::max(0, work_area.height() - system_tray_height_)); - if (shelf_->GetAlignment() == SHELF_ALIGNMENT_TOP) - work_area.set_y(work_area.y() + system_tray_height_); - } - collection_->SetDisplayInfo(work_area, display.bounds()); -} - -void WorkAreaObserver::UpdateShelf() { - if (shelf_) - return; - - shelf_ = ShelfLayoutManager::ForLauncher(root_window_); - if (shelf_) - shelf_->AddObserver(this); -} - -// Class to initialize and manage the WebNotificationBubble and -// TrayBubbleWrapper instances for a bubble. -class WebNotificationBubbleWrapper { - public: - // Takes ownership of |bubble| and creates |bubble_wrapper_|. - WebNotificationBubbleWrapper(WebNotificationTray* tray, - message_center::MessageBubbleBase* bubble) { - bubble_.reset(bubble); - views::TrayBubbleView::AnchorAlignment anchor_alignment = - tray->GetAnchorAlignment(); - views::TrayBubbleView::InitParams init_params = - bubble->GetInitParams(anchor_alignment); - views::View* anchor = tray->tray_container(); - if (anchor_alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM) { - gfx::Point bounds(anchor->width() / 2, 0); - views::View::ConvertPointToWidget(anchor, &bounds); - init_params.arrow_offset = bounds.x(); - } - views::TrayBubbleView* bubble_view = views::TrayBubbleView::Create( - tray->GetBubbleWindowContainer(), anchor, tray, &init_params); - if (ash::switches::UseAlternateShelfLayout()) - bubble_view->SetArrowPaintType(views::BubbleBorder::PAINT_NONE); - bubble_wrapper_.reset(new TrayBubbleWrapper(tray, bubble_view)); - bubble->InitializeContents(bubble_view); - } - - message_center::MessageBubbleBase* bubble() const { return bubble_.get(); } - - // Convenience accessors. - views::TrayBubbleView* bubble_view() const { return bubble_->bubble_view(); } - - private: - scoped_ptr<message_center::MessageBubbleBase> bubble_; - scoped_ptr<internal::TrayBubbleWrapper> bubble_wrapper_; - - DISALLOW_COPY_AND_ASSIGN(WebNotificationBubbleWrapper); -}; - -class WebNotificationButton : public views::CustomButton { - public: - WebNotificationButton(views::ButtonListener* listener) - : views::CustomButton(listener), - is_bubble_visible_(false), - unread_count_(0) { - SetLayoutManager(new views::FillLayout); - unread_label_ = new views::Label(); - SetupLabelForTray(unread_label_); - AddChildView(unread_label_); - } - - void SetBubbleVisible(bool visible) { - if (visible == is_bubble_visible_) - return; - - is_bubble_visible_ = visible; - UpdateIconVisibility(); - } - - void SetUnreadCount(int unread_count) { - // base::FormatNumber doesn't convert to arabic numeric characters. - // TODO(mukai): use ICU to support conversion for such locales. - unread_count_ = unread_count; - // TODO(mukai): move NINE_PLUS message to ui_strings, it doesn't need to be - // in ash_strings. - unread_label_->SetText((unread_count > 9) ? - l10n_util::GetStringUTF16(IDS_ASH_NOTIFICATION_UNREAD_COUNT_NINE_PLUS) : - base::FormatNumber(unread_count)); - UpdateIconVisibility(); - } - - protected: - // Overridden from views::ImageButton: - virtual gfx::Size GetPreferredSize() OVERRIDE { - const int notification_item_size = GetShelfItemHeight(); - return gfx::Size(notification_item_size, notification_item_size); - } - - virtual int GetHeightForWidth(int width) OVERRIDE { - return GetPreferredSize().height(); - } - - private: - void UpdateIconVisibility() { - unread_label_->SetEnabledColor( - (!is_bubble_visible_ && unread_count_ > 0) ? - kWebNotificationColorWithUnread : kWebNotificationColorNoUnread); - SchedulePaint(); - } - - bool is_bubble_visible_; - int unread_count_; - - views::Label* unread_label_; - - DISALLOW_COPY_AND_ASSIGN(WebNotificationButton); -}; - -} // namespace internal - -WebNotificationTray::WebNotificationTray( - internal::StatusAreaWidget* status_area_widget) - : TrayBackgroundView(status_area_widget), - button_(NULL), - show_message_center_on_unlock_(false), - should_update_tray_content_(false), - should_block_shelf_auto_hide_(false) { - button_ = new internal::WebNotificationButton(this); - button_->set_triggerable_event_flags( - ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON); - tray_container()->AddChildView(button_); - SetContentsBackground(); - tray_container()->set_border(NULL); - SetVisible(false); - message_center_tray_.reset(new message_center::MessageCenterTray( - this, - message_center::MessageCenter::Get())); - work_area_observer_.reset(new internal::WorkAreaObserver()); - OnMessageCenterTrayChanged(); -} - -WebNotificationTray::~WebNotificationTray() { - // Release any child views that might have back pointers before ~View(). - message_center_bubble_.reset(); - popup_collection_.reset(); - work_area_observer_.reset(); -} - -// Public methods. - -bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) { - if (!ShouldShowMessageCenter()) - return false; - - should_block_shelf_auto_hide_ = true; - message_center::MessageCenterBubble* message_center_bubble = - new message_center::MessageCenterBubble( - message_center(), - message_center_tray_.get(), - ash::switches::UseAlternateShelfLayout()); - - int max_height = 0; - aura::Window* status_area_window = status_area_widget()->GetNativeView(); - switch (GetShelfLayoutManager()->GetAlignment()) { - case SHELF_ALIGNMENT_BOTTOM: { - gfx::Rect shelf_bounds = GetShelfLayoutManager()->GetIdealBounds(); - max_height = shelf_bounds.y(); - break; - } - case SHELF_ALIGNMENT_TOP: { - aura::Window* root = status_area_window->GetRootWindow(); - max_height = - root->bounds().height() - status_area_window->bounds().height(); - break; - } - case SHELF_ALIGNMENT_LEFT: - case SHELF_ALIGNMENT_RIGHT: { - // Assume that the bottom line of the status area widget and the bubble - // are aligned. - max_height = status_area_window->GetBoundsInRootWindow().bottom(); - break; - } - default: - NOTREACHED(); - } - - message_center_bubble->SetMaxHeight(std::max(0, - max_height - GetTraySpacing())); - if (show_settings) - message_center_bubble->SetSettingsVisible(); - message_center_bubble_.reset( - new internal::WebNotificationBubbleWrapper(this, message_center_bubble)); - - status_area_widget()->SetHideSystemNotifications(true); - GetShelfLayoutManager()->UpdateAutoHideState(); - button_->SetBubbleVisible(true); - SetDrawBackgroundAsActive(true); - return true; -} - -bool WebNotificationTray::ShowMessageCenter() { - return ShowMessageCenterInternal(false /* show_settings */); -} - -void WebNotificationTray::HideMessageCenter() { - if (!message_center_bubble()) - return; - SetDrawBackgroundAsActive(false); - message_center_bubble_.reset(); - should_block_shelf_auto_hide_ = false; - show_message_center_on_unlock_ = false; - status_area_widget()->SetHideSystemNotifications(false); - GetShelfLayoutManager()->UpdateAutoHideState(); - button_->SetBubbleVisible(false); -} - -void WebNotificationTray::SetSystemTrayHeight(int height) { - work_area_observer_->SetSystemTrayHeight(height); -} - -bool WebNotificationTray::ShowPopups() { - if (message_center_bubble()) - return false; - - popup_collection_.reset(new message_center::MessagePopupCollection( - ash::Shell::GetContainer( - GetWidget()->GetNativeView()->GetRootWindow(), - internal::kShellWindowId_StatusContainer), - message_center(), - message_center_tray_.get(), - ash::switches::UseAlternateShelfLayout())); - work_area_observer_->StartObserving( - popup_collection_.get(), GetWidget()->GetNativeView()->GetRootWindow()); - return true; -} - -void WebNotificationTray::HidePopups() { - DCHECK(popup_collection_.get()); - - popup_collection_->MarkAllPopupsShown(); - popup_collection_.reset(); - work_area_observer_->StopObserving(); -} - -// Private methods. - -bool WebNotificationTray::ShouldShowMessageCenter() { - return status_area_widget()->login_status() != user::LOGGED_IN_LOCKED && - !(status_area_widget()->system_tray() && - status_area_widget()->system_tray()->HasNotificationBubble()); -} - -bool WebNotificationTray::ShouldBlockLauncherAutoHide() const { - return should_block_shelf_auto_hide_; -} - -bool WebNotificationTray::IsMessageCenterBubbleVisible() const { - return (message_center_bubble() && - message_center_bubble()->bubble()->IsVisible()); -} - -bool WebNotificationTray::IsMouseInNotificationBubble() const { - return false; -} - -void WebNotificationTray::ShowMessageCenterBubble() { - if (!IsMessageCenterBubbleVisible()) - message_center_tray_->ShowMessageCenterBubble(); -} - -void WebNotificationTray::UpdateAfterLoginStatusChange( - user::LoginStatus login_status) { - OnMessageCenterTrayChanged(); -} - -void WebNotificationTray::SetShelfAlignment(ShelfAlignment alignment) { - if (alignment == shelf_alignment()) - return; - internal::TrayBackgroundView::SetShelfAlignment(alignment); - tray_container()->set_border(NULL); - // Destroy any existing bubble so that it will be rebuilt correctly. - message_center_tray_->HideMessageCenterBubble(); - message_center_tray_->HidePopupBubble(); -} - -void WebNotificationTray::AnchorUpdated() { - if (message_center_bubble()) { - message_center_bubble()->bubble_view()->UpdateBubble(); - UpdateBubbleViewArrow(message_center_bubble()->bubble_view()); - } -} - -base::string16 WebNotificationTray::GetAccessibleNameForTray() { - return l10n_util::GetStringUTF16( - IDS_MESSAGE_CENTER_ACCESSIBLE_NAME); -} - -void WebNotificationTray::HideBubbleWithView( - const views::TrayBubbleView* bubble_view) { - if (message_center_bubble() && - bubble_view == message_center_bubble()->bubble_view()) { - message_center_tray_->HideMessageCenterBubble(); - } else if (popup_collection_.get()) { - message_center_tray_->HidePopupBubble(); - } -} - -bool WebNotificationTray::PerformAction(const ui::Event& event) { - if (message_center_bubble()) - message_center_tray_->HideMessageCenterBubble(); - else - message_center_tray_->ShowMessageCenterBubble(); - return true; -} - -void WebNotificationTray::BubbleViewDestroyed() { - if (message_center_bubble()) - message_center_bubble()->bubble()->BubbleViewDestroyed(); -} - -void WebNotificationTray::OnMouseEnteredView() {} - -void WebNotificationTray::OnMouseExitedView() {} - -base::string16 WebNotificationTray::GetAccessibleNameForBubble() { - return GetAccessibleNameForTray(); -} - -gfx::Rect WebNotificationTray::GetAnchorRect( - views::Widget* anchor_widget, - views::TrayBubbleView::AnchorType anchor_type, - views::TrayBubbleView::AnchorAlignment anchor_alignment) { - return GetBubbleAnchorRect(anchor_widget, anchor_type, anchor_alignment); -} - -void WebNotificationTray::HideBubble(const views::TrayBubbleView* bubble_view) { - HideBubbleWithView(bubble_view); -} - -bool WebNotificationTray::ShowNotifierSettings() { - if (message_center_bubble()) { - static_cast<message_center::MessageCenterBubble*>( - message_center_bubble()->bubble())->SetSettingsVisible(); - return true; - } - return ShowMessageCenterInternal(true /* show_settings */); -} - -message_center::MessageCenterTray* WebNotificationTray::GetMessageCenterTray() { - return message_center_tray_.get(); -} - -bool WebNotificationTray::IsCommandIdChecked(int command_id) const { - if (command_id != kToggleQuietMode) - return false; - return message_center()->IsQuietMode(); -} - -bool WebNotificationTray::IsCommandIdEnabled(int command_id) const { - return true; -} - -bool WebNotificationTray::GetAcceleratorForCommandId( - int command_id, - ui::Accelerator* accelerator) { - return false; -} - -void WebNotificationTray::ExecuteCommand(int command_id, int event_flags) { - if (command_id == kToggleQuietMode) { - bool in_quiet_mode = message_center()->IsQuietMode(); - message_center()->SetQuietMode(!in_quiet_mode); - return; - } - base::TimeDelta expires_in = command_id == kEnableQuietModeDay ? - base::TimeDelta::FromDays(1): - base::TimeDelta::FromHours(1); - message_center()->EnterQuietModeWithExpire(expires_in); -} - -void WebNotificationTray::ButtonPressed(views::Button* sender, - const ui::Event& event) { - DCHECK_EQ(button_, sender); - PerformAction(event); -} - -void WebNotificationTray::OnMessageCenterTrayChanged() { - // Do not update the tray contents directly. Multiple change events can happen - // consecutively, and calling Update in the middle of those events will show - // intermediate unread counts for a moment. - should_update_tray_content_ = true; - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&WebNotificationTray::UpdateTrayContent, AsWeakPtr())); -} - -void WebNotificationTray::UpdateTrayContent() { - if (!should_update_tray_content_) - return; - should_update_tray_content_ = false; - - message_center::MessageCenter* message_center = - message_center_tray_->message_center(); - button_->SetUnreadCount(message_center->UnreadNotificationCount()); - if (IsMessageCenterBubbleVisible()) - button_->SetState(views::CustomButton::STATE_PRESSED); - else - button_->SetState(views::CustomButton::STATE_NORMAL); - SetVisible((status_area_widget()->login_status() != user::LOGGED_IN_NONE) && - (status_area_widget()->login_status() != user::LOGGED_IN_LOCKED) && - (message_center->NotificationCount() > 0)); - Layout(); - SchedulePaint(); -} - -bool WebNotificationTray::ClickedOutsideBubble() { - // Only hide the message center - if (!message_center_bubble()) - return false; - - message_center_tray_->HideMessageCenterBubble(); - return true; -} - -message_center::MessageCenter* WebNotificationTray::message_center() const { - return message_center_tray_->message_center(); -} - -// Methods for testing - -bool WebNotificationTray::IsPopupVisible() const { - return message_center_tray_->popups_visible(); -} - -message_center::MessageCenterBubble* -WebNotificationTray::GetMessageCenterBubbleForTest() { - if (!message_center_bubble()) - return NULL; - return static_cast<message_center::MessageCenterBubble*>( - message_center_bubble()->bubble()); -} - -} // namespace ash |