Home | History | Annotate | Download | only in views
      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 
     13 namespace message_center {
     14 
     15 DesktopPopupAlignmentDelegate::DesktopPopupAlignmentDelegate()
     16     : alignment_(POPUP_ALIGNMENT_BOTTOM | POPUP_ALIGNMENT_RIGHT),
     17       display_id_(gfx::Display::kInvalidDisplayID),
     18       screen_(NULL) {
     19 }
     20 
     21 DesktopPopupAlignmentDelegate::~DesktopPopupAlignmentDelegate() {
     22   if (screen_)
     23     screen_->RemoveObserver(this);
     24 }
     25 
     26 void 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 
     37 int 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 
     44 int DesktopPopupAlignmentDelegate::GetBaseLine() const {
     45   return IsTopDown()
     46       ? work_area_.y() + kMarginBetweenItems
     47       : work_area_.bottom() - kMarginBetweenItems;
     48 }
     49 
     50 int DesktopPopupAlignmentDelegate::GetWorkAreaBottom() const {
     51   return work_area_.bottom();
     52 }
     53 
     54 bool DesktopPopupAlignmentDelegate::IsTopDown() const {
     55   return (alignment_ & POPUP_ALIGNMENT_TOP) != 0;
     56 }
     57 
     58 bool DesktopPopupAlignmentDelegate::IsFromLeft() const {
     59   return (alignment_ & POPUP_ALIGNMENT_LEFT) != 0;
     60 }
     61 
     62 void 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 
     87 void DesktopPopupAlignmentDelegate::OnDisplayAdded(
     88     const gfx::Display& new_display) {
     89 }
     90 
     91 void DesktopPopupAlignmentDelegate::OnDisplayRemoved(
     92     const gfx::Display& old_display) {
     93 }
     94 
     95 void 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