1// Copyright 2014 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/views/desktop_popup_alignment_delegate.h" 6 7#include "ui/gfx/display.h" 8#include "ui/gfx/geometry/rect.h" 9#include "ui/gfx/screen.h" 10#include "ui/message_center/message_center_style.h" 11#include "ui/message_center/views/message_popup_collection.h" 12 13namespace message_center { 14 15DesktopPopupAlignmentDelegate::DesktopPopupAlignmentDelegate() 16 : alignment_(POPUP_ALIGNMENT_BOTTOM | POPUP_ALIGNMENT_RIGHT), 17 display_id_(gfx::Display::kInvalidDisplayID), 18 screen_(NULL) { 19} 20 21DesktopPopupAlignmentDelegate::~DesktopPopupAlignmentDelegate() { 22 if (screen_) 23 screen_->RemoveObserver(this); 24} 25 26void DesktopPopupAlignmentDelegate::StartObserving(gfx::Screen* screen) { 27 if (screen_ || !screen) 28 return; 29 30 screen_ = screen; 31 screen_->AddObserver(this); 32 gfx::Display display = screen_->GetPrimaryDisplay(); 33 display_id_ = display.id(); 34 RecomputeAlignment(display); 35} 36 37int DesktopPopupAlignmentDelegate::GetToastOriginX( 38 const gfx::Rect& toast_bounds) const { 39 if (IsFromLeft()) 40 return work_area_.x() + kMarginBetweenItems; 41 return work_area_.right() - kMarginBetweenItems - toast_bounds.width(); 42} 43 44int DesktopPopupAlignmentDelegate::GetBaseLine() const { 45 return IsTopDown() 46 ? work_area_.y() + kMarginBetweenItems 47 : work_area_.bottom() - kMarginBetweenItems; 48} 49 50int DesktopPopupAlignmentDelegate::GetWorkAreaBottom() const { 51 return work_area_.bottom(); 52} 53 54bool DesktopPopupAlignmentDelegate::IsTopDown() const { 55 return (alignment_ & POPUP_ALIGNMENT_TOP) != 0; 56} 57 58bool DesktopPopupAlignmentDelegate::IsFromLeft() const { 59 return (alignment_ & POPUP_ALIGNMENT_LEFT) != 0; 60} 61 62void DesktopPopupAlignmentDelegate::RecomputeAlignment( 63 const gfx::Display& display) { 64 if (work_area_ == display.work_area()) 65 return; 66 67 work_area_ = display.work_area(); 68 69 // If the taskbar is at the top, render notifications top down. Some platforms 70 // like Gnome can have taskbars at top and bottom. In this case it's more 71 // likely that the systray is on the top one. 72 alignment_ = work_area_.y() > display.bounds().y() ? POPUP_ALIGNMENT_TOP 73 : POPUP_ALIGNMENT_BOTTOM; 74 75 // If the taskbar is on the left show the notifications on the left. Otherwise 76 // show it on right since it's very likely that the systray is on the right if 77 // the taskbar is on the top or bottom. 78 // Since on some platforms like Ubuntu Unity there's also a launcher along 79 // with a taskbar (panel), we need to check that there is really nothing at 80 // the top before concluding that the taskbar is at the left. 81 alignment_ |= (work_area_.x() > display.bounds().x() && 82 work_area_.y() == display.bounds().y()) 83 ? POPUP_ALIGNMENT_LEFT 84 : POPUP_ALIGNMENT_RIGHT; 85} 86 87void DesktopPopupAlignmentDelegate::OnDisplayAdded( 88 const gfx::Display& new_display) { 89} 90 91void DesktopPopupAlignmentDelegate::OnDisplayRemoved( 92 const gfx::Display& old_display) { 93} 94 95void DesktopPopupAlignmentDelegate::OnDisplayMetricsChanged( 96 const gfx::Display& display, 97 uint32_t metrics) { 98 if (display.id() == display_id_) { 99 RecomputeAlignment(display); 100 DoUpdateIfPossible(); 101 } 102} 103 104} // namespace message_center 105