1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file. 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ash/system/web_notification/ash_popup_alignment_delegate.h" 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ash/display/display_controller.h" 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ash/shelf/shelf_constants.h" 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ash/shelf/shelf_layout_manager.h" 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ash/shelf/shelf_types.h" 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ash/shelf/shelf_widget.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ash/shell.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/i18n/rtl.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/aura/window.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/gfx/display.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/gfx/geometry/rect.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/gfx/screen.h" 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/message_center/message_center_style.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/message_center/views/message_popup_collection.h" 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace ash { 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace { 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kToastMarginX = 3; 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// If there should be no margin for the first item, this value needs to be 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// substracted to flush the message to the shelf (the width of the border + 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// shadow). 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kNoToastMarginBorderAndShadowOffset = 2; 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 34116680a4aac90f2aa7413d9095a592090648e557Ben MurdochAshPopupAlignmentDelegate::AshPopupAlignmentDelegate() 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : display_id_(gfx::Display::kInvalidDisplayID), 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch screen_(NULL), 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch root_window_(NULL), 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch shelf_(NULL), 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch system_tray_height_(0) { 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 42116680a4aac90f2aa7413d9095a592090648e557Ben MurdochAshPopupAlignmentDelegate::~AshPopupAlignmentDelegate() { 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (screen_) 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch screen_->RemoveObserver(this); 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Shell::GetInstance()->RemoveShellObserver(this); 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (shelf_) 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch shelf_->RemoveObserver(this); 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AshPopupAlignmentDelegate::StartObserving(gfx::Screen* screen, 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const gfx::Display& display) { 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch screen_ = screen; 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch display_id_ = display.id(); 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci work_area_ = display.work_area(); 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) root_window_ = ash::Shell::GetInstance()->display_controller()-> 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetRootWindowForDisplayId(display_id_); 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UpdateShelf(); 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch screen->AddObserver(this); 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Shell::GetInstance()->AddShellObserver(this); 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (system_tray_height_ > 0) 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OnAutoHideStateChanged(shelf_->auto_hide_state()); 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AshPopupAlignmentDelegate::SetSystemTrayHeight(int height) { 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch system_tray_height_ = height; 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If the shelf is shown during auto-hide state, the distance from the edge 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // should be reduced by the height of shelf's shown height. 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (shelf_ && shelf_->visibility_state() == SHELF_AUTO_HIDE && 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch shelf_->auto_hide_state() == SHELF_AUTO_HIDE_SHOWN) { 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch system_tray_height_ -= kShelfSize - ShelfLayoutManager::kAutoHideSize; 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (system_tray_height_ > 0) 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch system_tray_height_ += message_center::kMarginBetweenItems; 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch system_tray_height_ = 0; 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!shelf_) 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DoUpdateIfPossible(); 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint AshPopupAlignmentDelegate::GetToastOriginX( 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const gfx::Rect& toast_bounds) const { 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // In Ash, RTL UI language mirrors the whole ash layout, so the toast 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // widgets should be at the bottom-left instead of bottom right. 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (base::i18n::IsRTL()) 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return work_area_.x() + kToastMarginX; 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (IsFromLeft()) 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return work_area_.x() + kToastMarginX; 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return work_area_.right() - kToastMarginX - toast_bounds.width(); 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint AshPopupAlignmentDelegate::GetBaseLine() const { 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return IsTopDown() 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ? work_area_.y() + kNoToastMarginBorderAndShadowOffset + 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch system_tray_height_ 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : work_area_.bottom() - kNoToastMarginBorderAndShadowOffset - 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch system_tray_height_; 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint AshPopupAlignmentDelegate::GetWorkAreaBottom() const { 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return work_area_.bottom() - system_tray_height_; 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool AshPopupAlignmentDelegate::IsTopDown() const { 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return GetAlignment() == SHELF_ALIGNMENT_TOP; 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool AshPopupAlignmentDelegate::IsFromLeft() const { 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return GetAlignment() == SHELF_ALIGNMENT_LEFT; 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AshPopupAlignmentDelegate::RecomputeAlignment( 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const gfx::Display& display) { 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Nothing needs to be done. 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 122116680a4aac90f2aa7413d9095a592090648e557Ben MurdochShelfAlignment AshPopupAlignmentDelegate::GetAlignment() const { 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return shelf_ ? shelf_->GetAlignment() : SHELF_ALIGNMENT_BOTTOM; 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AshPopupAlignmentDelegate::UpdateShelf() { 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (shelf_) 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) shelf_ = ShelfLayoutManager::ForShelf(root_window_); 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (shelf_) 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch shelf_->AddObserver(this); 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AshPopupAlignmentDelegate::OnDisplayWorkAreaInsetsChanged() { 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UpdateShelf(); 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch work_area_ = Shell::GetScreen()->GetDisplayNearestWindow( 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch shelf_->shelf_widget()->GetNativeView()).work_area(); 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AshPopupAlignmentDelegate::OnAutoHideStateChanged( 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ShelfAutoHideState new_state) { 144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch work_area_ = Shell::GetScreen()->GetDisplayNearestWindow( 145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch shelf_->shelf_widget()->GetNativeView()).work_area(); 146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int width = 0; 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if ((shelf_->visibility_state() == SHELF_AUTO_HIDE) && 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new_state == SHELF_AUTO_HIDE_SHOWN) { 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Since the work_area is already reduced by kAutoHideSize, the inset width 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // should be just the difference. 151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch width = kShelfSize - ShelfLayoutManager::kAutoHideSize; 152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch work_area_.Inset(shelf_->SelectValueForShelfAlignment( 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gfx::Insets(0, 0, width, 0), 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gfx::Insets(0, width, 0, 0), 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gfx::Insets(0, 0, 0, width), 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gfx::Insets(width, 0, 0, 0))); 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DoUpdateIfPossible(); 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AshPopupAlignmentDelegate::OnDisplayAdded( 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const gfx::Display& new_display) { 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AshPopupAlignmentDelegate::OnDisplayRemoved( 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const gfx::Display& old_display) { 168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AshPopupAlignmentDelegate::OnDisplayMetricsChanged( 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const gfx::Display& display, 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32_t metrics) { 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (display.id() == display_id_ && shelf_) 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OnAutoHideStateChanged(shelf_->auto_hide_state()); 175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace ash 178