summaryrefslogtreecommitdiff
path: root/chromium/ash/system/tray/tray_background_view.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ash/system/tray/tray_background_view.cc')
-rw-r--r--chromium/ash/system/tray/tray_background_view.cc634
1 files changed, 634 insertions, 0 deletions
diff --git a/chromium/ash/system/tray/tray_background_view.cc b/chromium/ash/system/tray/tray_background_view.cc
new file mode 100644
index 00000000000..80cac07e364
--- /dev/null
+++ b/chromium/ash/system/tray/tray_background_view.cc
@@ -0,0 +1,634 @@
+// 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/tray/tray_background_view.h"
+
+#include "ash/ash_switches.h"
+#include "ash/root_window_controller.h"
+#include "ash/screen_ash.h"
+#include "ash/shelf/shelf_layout_manager.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/status_area_widget_delegate.h"
+#include "ash/system/tray/system_tray.h"
+#include "ash/system/tray/tray_constants.h"
+#include "ash/system/tray/tray_event_filter.h"
+#include "ash/wm/window_animations.h"
+#include "grit/ash_resources.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/window.h"
+#include "ui/base/accessibility/accessible_view_state.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/image/image_skia_operations.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/screen.h"
+#include "ui/gfx/skia_util.h"
+#include "ui/views/background.h"
+#include "ui/views/layout/box_layout.h"
+
+namespace {
+
+const int kTrayBackgroundAlpha = 100;
+const int kTrayBackgroundHoverAlpha = 150;
+const SkColor kTrayBackgroundPressedColor = SkColorSetRGB(66, 129, 244);
+
+// Adjust the size of TrayContainer with additional padding.
+const int kTrayContainerVerticalPaddingBottomAlignment = 1;
+const int kTrayContainerHorizontalPaddingBottomAlignment = 1;
+const int kTrayContainerVerticalPaddingVerticalAlignment = 1;
+const int kTrayContainerHorizontalPaddingVerticalAlignment = 1;
+
+const int kAnimationDurationForPopupMS = 200;
+
+} // namespace
+
+using views::TrayBubbleView;
+
+namespace ash {
+namespace internal {
+
+// static
+const char TrayBackgroundView::kViewClassName[] = "tray/TrayBackgroundView";
+
+// Used to track when the anchor widget changes position on screen so that the
+// bubble position can be updated.
+class TrayBackgroundView::TrayWidgetObserver : public views::WidgetObserver {
+ public:
+ explicit TrayWidgetObserver(TrayBackgroundView* host)
+ : host_(host) {
+ }
+
+ virtual void OnWidgetBoundsChanged(views::Widget* widget,
+ const gfx::Rect& new_bounds) OVERRIDE {
+ host_->AnchorUpdated();
+ }
+
+ virtual void OnWidgetVisibilityChanged(views::Widget* widget,
+ bool visible) OVERRIDE {
+ host_->AnchorUpdated();
+ }
+
+ private:
+ TrayBackgroundView* host_;
+
+ DISALLOW_COPY_AND_ASSIGN(TrayWidgetObserver);
+};
+
+class TrayBackground : public views::Background {
+ public:
+ const static int kImageTypeDefault = 0;
+ const static int kImageTypeOnBlack = 1;
+ const static int kImageTypePressed = 2;
+ const static int kNumStates = 3;
+
+ const static int kImageHorizontal = 0;
+ const static int kImageVertical = 1;
+ const static int kNumOrientations = 2;
+
+ explicit TrayBackground(TrayBackgroundView* tray_background_view) :
+ tray_background_view_(tray_background_view) {
+ set_alpha(kTrayBackgroundAlpha);
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ leading_images_[kImageHorizontal][kImageTypeDefault] =
+ rb.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_LEFT).ToImageSkia();
+ middle_images_[kImageHorizontal][kImageTypeDefault] =
+ rb.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_CENTER).ToImageSkia();
+ trailing_images_[kImageHorizontal][kImageTypeDefault] =
+ rb.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_RIGHT).ToImageSkia();
+
+ leading_images_[kImageHorizontal][kImageTypeOnBlack] =
+ rb.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_LEFT_ONBLACK).ToImageSkia();
+ middle_images_[kImageHorizontal][kImageTypeOnBlack] =
+ rb.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_CENTER_ONBLACK).ToImageSkia();
+ trailing_images_[kImageHorizontal][kImageTypeOnBlack] =
+ rb.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_RIGHT_ONBLACK).ToImageSkia();
+
+ leading_images_[kImageHorizontal][kImageTypePressed] =
+ rb.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_LEFT_PRESSED).ToImageSkia();
+ middle_images_[kImageHorizontal][kImageTypePressed] =
+ rb.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_CENTER_PRESSED).ToImageSkia();
+ trailing_images_[kImageHorizontal][kImageTypePressed] =
+ rb.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_RIGHT_PRESSED).ToImageSkia();
+
+ leading_images_[kImageVertical][kImageTypeDefault] =
+ rb.GetImageNamed(IDR_AURA_TRAY_BG_VERTICAL_TOP).ToImageSkia();
+ middle_images_[kImageVertical][kImageTypeDefault] =
+ rb.GetImageNamed(
+ IDR_AURA_TRAY_BG_VERTICAL_CENTER).ToImageSkia();
+ trailing_images_[kImageVertical][kImageTypeDefault] =
+ rb.GetImageNamed(IDR_AURA_TRAY_BG_VERTICAL_BOTTOM).ToImageSkia();
+
+ leading_images_[kImageVertical][kImageTypeOnBlack] =
+ rb.GetImageNamed(IDR_AURA_TRAY_BG_VERTICAL_TOP_ONBLACK).ToImageSkia();
+ middle_images_[kImageVertical][kImageTypeOnBlack] =
+ rb.GetImageNamed(
+ IDR_AURA_TRAY_BG_VERTICAL_CENTER_ONBLACK).ToImageSkia();
+ trailing_images_[kImageVertical][kImageTypeOnBlack] =
+ rb.GetImageNamed(
+ IDR_AURA_TRAY_BG_VERTICAL_BOTTOM_ONBLACK).ToImageSkia();
+
+ leading_images_[kImageVertical][kImageTypePressed] =
+ rb.GetImageNamed(IDR_AURA_TRAY_BG_VERTICAL_TOP_PRESSED).ToImageSkia();
+ middle_images_[kImageVertical][kImageTypePressed] =
+ rb.GetImageNamed(
+ IDR_AURA_TRAY_BG_VERTICAL_CENTER_PRESSED).ToImageSkia();
+ trailing_images_[kImageVertical][kImageTypePressed] =
+ rb.GetImageNamed(
+ IDR_AURA_TRAY_BG_VERTICAL_BOTTOM_PRESSED).ToImageSkia();
+ }
+
+ virtual ~TrayBackground() {}
+
+ SkColor color() { return color_; }
+ void set_color(SkColor color) { color_ = color; }
+ void set_alpha(int alpha) { color_ = SkColorSetARGB(alpha, 0, 0, 0); }
+
+ private:
+ ShelfWidget* GetShelfWidget() const {
+ return RootWindowController::ForWindow(tray_background_view_->
+ status_area_widget()->GetNativeWindow())->shelf();
+ }
+
+ void PaintForAlternateShelf(gfx::Canvas* canvas, views::View* view) const {
+ int orientation = kImageHorizontal;
+ ShelfWidget* shelf_widget = GetShelfWidget();
+ if (shelf_widget &&
+ !shelf_widget->shelf_layout_manager()->IsHorizontalAlignment())
+ orientation = kImageVertical;
+
+ int state = kImageTypeDefault;
+ if (tray_background_view_->draw_background_as_active())
+ state = kImageTypePressed;
+ else if (shelf_widget && shelf_widget->GetDimsShelf())
+ state = kImageTypeOnBlack;
+ else
+ state = kImageTypeDefault;
+
+ const gfx::ImageSkia* leading = leading_images_[orientation][state];
+ const gfx::ImageSkia* middle = middle_images_[orientation][state];
+ const gfx::ImageSkia* trailing = trailing_images_[orientation][state];
+
+ gfx::Rect bounds(view->GetLocalBounds());
+ gfx::Point leading_location, trailing_location;
+ gfx::Rect middle_bounds;
+
+ if (orientation == kImageHorizontal) {
+ leading_location = gfx::Point(0, 0);
+ trailing_location = gfx::Point(bounds.width() - trailing->width(), 0);
+ middle_bounds = gfx::Rect(
+ leading->width(),
+ 0,
+ bounds.width() - (leading->width() + trailing->width()),
+ bounds.height());
+ } else {
+ leading_location = gfx::Point(0, 0);
+ trailing_location = gfx::Point(0, bounds.height() - trailing->height());
+ middle_bounds = gfx::Rect(
+ 0,
+ leading->height(),
+ bounds.width(),
+ bounds.height() - (leading->height() + trailing->height()));
+ }
+
+ canvas->DrawImageInt(*leading,
+ leading_location.x(),
+ leading_location.y());
+
+ canvas->DrawImageInt(*trailing,
+ trailing_location.x(),
+ trailing_location.y());
+
+ canvas->TileImageInt(*middle,
+ middle_bounds.x(),
+ middle_bounds.y(),
+ middle_bounds.width(),
+ middle_bounds.height());
+ }
+
+ // Overridden from views::Background.
+ virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE {
+ if (ash::switches::UseAlternateShelfLayout()) {
+ PaintForAlternateShelf(canvas, view);
+ } else {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setColor(color_);
+ SkPath path;
+ gfx::Rect bounds(view->GetLocalBounds());
+ SkScalar radius = SkIntToScalar(kTrayRoundedBorderRadius);
+ path.addRoundRect(gfx::RectToSkRect(bounds), radius, radius);
+ canvas->DrawPath(path, paint);
+ }
+ }
+
+ SkColor color_;
+ // Reference to the TrayBackgroundView for which this is a background.
+ TrayBackgroundView* tray_background_view_;
+
+ // References to the images used as backgrounds, they are owned by the
+ // resource bundle class.
+ const gfx::ImageSkia* leading_images_[kNumOrientations][kNumStates];
+ const gfx::ImageSkia* middle_images_[kNumOrientations][kNumStates];
+ const gfx::ImageSkia* trailing_images_[kNumOrientations][kNumStates];
+
+ DISALLOW_COPY_AND_ASSIGN(TrayBackground);
+};
+
+TrayBackgroundView::TrayContainer::TrayContainer(ShelfAlignment alignment)
+ : alignment_(alignment) {
+ UpdateLayout();
+}
+
+void TrayBackgroundView::TrayContainer::SetAlignment(ShelfAlignment alignment) {
+ if (alignment_ == alignment)
+ return;
+ alignment_ = alignment;
+ UpdateLayout();
+}
+
+gfx::Size TrayBackgroundView::TrayContainer::GetPreferredSize() {
+ if (size_.IsEmpty())
+ return views::View::GetPreferredSize();
+ return size_;
+}
+
+void TrayBackgroundView::TrayContainer::ChildPreferredSizeChanged(
+ views::View* child) {
+ PreferredSizeChanged();
+}
+
+void TrayBackgroundView::TrayContainer::ChildVisibilityChanged(View* child) {
+ PreferredSizeChanged();
+}
+
+void TrayBackgroundView::TrayContainer::ViewHierarchyChanged(
+ const ViewHierarchyChangedDetails& details) {
+ if (details.parent == this)
+ PreferredSizeChanged();
+}
+
+void TrayBackgroundView::TrayContainer::UpdateLayout() {
+ // Adjust the size of status tray dark background by adding additional
+ // empty border.
+ if (alignment_ == SHELF_ALIGNMENT_BOTTOM ||
+ alignment_ == SHELF_ALIGNMENT_TOP) {
+ int vertical_padding = kTrayContainerVerticalPaddingBottomAlignment;
+ int horizontal_padding = kTrayContainerHorizontalPaddingBottomAlignment;
+ if (ash::switches::UseAlternateShelfLayout()) {
+ vertical_padding = kPaddingFromEdgeOfShelf;
+ horizontal_padding = kPaddingFromEdgeOfShelf;
+ }
+ set_border(views::Border::CreateEmptyBorder(
+ vertical_padding,
+ horizontal_padding,
+ vertical_padding,
+ horizontal_padding));
+
+ views::BoxLayout* layout =
+ new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0);
+ layout->set_spread_blank_space(true);
+ views::View::SetLayoutManager(layout);
+ } else {
+ int vertical_padding = kTrayContainerVerticalPaddingVerticalAlignment;
+ int horizontal_padding = kTrayContainerHorizontalPaddingVerticalAlignment;
+ if (ash::switches::UseAlternateShelfLayout()) {
+ vertical_padding = kPaddingFromEdgeOfShelf;
+ horizontal_padding = kPaddingFromEdgeOfShelf;
+ }
+ set_border(views::Border::CreateEmptyBorder(
+ vertical_padding,
+ horizontal_padding,
+ vertical_padding,
+ horizontal_padding));
+
+ views::BoxLayout* layout =
+ new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
+ layout->set_spread_blank_space(true);
+ views::View::SetLayoutManager(layout);
+ }
+ PreferredSizeChanged();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TrayBackgroundView
+
+TrayBackgroundView::TrayBackgroundView(
+ internal::StatusAreaWidget* status_area_widget)
+ : status_area_widget_(status_area_widget),
+ tray_container_(NULL),
+ shelf_alignment_(SHELF_ALIGNMENT_BOTTOM),
+ background_(NULL),
+ hide_background_animator_(this, 0, kTrayBackgroundAlpha),
+ hover_background_animator_(
+ this, 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha),
+ hovered_(false),
+ draw_background_as_active_(false),
+ widget_observer_(new TrayWidgetObserver(this)) {
+ set_notify_enter_exit_on_child(true);
+
+ // Initially we want to paint the background, but without the hover effect.
+ hide_background_animator_.SetPaintsBackground(
+ true, BACKGROUND_CHANGE_IMMEDIATE);
+ hover_background_animator_.SetPaintsBackground(
+ false, BACKGROUND_CHANGE_IMMEDIATE);
+
+ tray_container_ = new TrayContainer(shelf_alignment_);
+ SetContents(tray_container_);
+ tray_event_filter_.reset(new TrayEventFilter);
+}
+
+TrayBackgroundView::~TrayBackgroundView() {
+ if (GetWidget())
+ GetWidget()->RemoveObserver(widget_observer_.get());
+}
+
+void TrayBackgroundView::Initialize() {
+ GetWidget()->AddObserver(widget_observer_.get());
+ SetBorder();
+}
+
+const char* TrayBackgroundView::GetClassName() const {
+ return kViewClassName;
+}
+
+void TrayBackgroundView::OnMouseEntered(const ui::MouseEvent& event) {
+ hovered_ = true;
+ if (!background_ || draw_background_as_active_ ||
+ ash::switches::UseAlternateShelfLayout())
+ return;
+ hover_background_animator_.SetPaintsBackground(
+ true, BACKGROUND_CHANGE_ANIMATE);
+}
+
+void TrayBackgroundView::OnMouseExited(const ui::MouseEvent& event) {
+ hovered_ = false;
+ if (!background_ || draw_background_as_active_ ||
+ ash::switches::UseAlternateShelfLayout())
+ return;
+ hover_background_animator_.SetPaintsBackground(
+ false, BACKGROUND_CHANGE_ANIMATE);
+}
+
+void TrayBackgroundView::ChildPreferredSizeChanged(views::View* child) {
+ PreferredSizeChanged();
+}
+
+void TrayBackgroundView::GetAccessibleState(ui::AccessibleViewState* state) {
+ state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
+ state->name = GetAccessibleNameForTray();
+}
+
+void TrayBackgroundView::AboutToRequestFocusFromTabTraversal(bool reverse) {
+ // Return focus to the login view. See crbug.com/120500.
+ views::View* v = GetNextFocusableView();
+ if (v)
+ v->AboutToRequestFocusFromTabTraversal(reverse);
+}
+
+bool TrayBackgroundView::PerformAction(const ui::Event& event) {
+ return false;
+}
+
+gfx::Rect TrayBackgroundView::GetFocusBounds() {
+ // The tray itself expands to the right and bottom edge of the screen to make
+ // sure clicking on the edges brings up the popup. However, the focus border
+ // should be only around the container.
+ return GetContentsBounds();
+}
+
+void TrayBackgroundView::UpdateBackground(int alpha) {
+ // The animator should never fire when the alternate shelf layout is used.
+ if (!background_ || draw_background_as_active_)
+ return;
+ DCHECK(!ash::switches::UseAlternateShelfLayout());
+ background_->set_alpha(hide_background_animator_.alpha() +
+ hover_background_animator_.alpha());
+ SchedulePaint();
+}
+
+void TrayBackgroundView::SetContents(views::View* contents) {
+ SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
+ AddChildView(contents);
+}
+
+void TrayBackgroundView::SetPaintsBackground(
+ bool value, BackgroundAnimatorChangeType change_type) {
+ DCHECK(!ash::switches::UseAlternateShelfLayout());
+ hide_background_animator_.SetPaintsBackground(value, change_type);
+}
+
+void TrayBackgroundView::SetContentsBackground() {
+ background_ = new internal::TrayBackground(this);
+ tray_container_->set_background(background_);
+}
+
+ShelfLayoutManager* TrayBackgroundView::GetShelfLayoutManager() {
+ return ShelfLayoutManager::ForLauncher(GetWidget()->GetNativeView());
+}
+
+void TrayBackgroundView::SetShelfAlignment(ShelfAlignment alignment) {
+ shelf_alignment_ = alignment;
+ SetBorder();
+ tray_container_->SetAlignment(alignment);
+}
+
+void TrayBackgroundView::SetBorder() {
+ views::View* parent = status_area_widget_->status_area_widget_delegate();
+ // Tray views are laid out right-to-left or bottom-to-top
+ bool on_edge = (this == parent->child_at(0));
+ int left_edge, top_edge, right_edge, bottom_edge;
+ if (ash::switches::UseAlternateShelfLayout()) {
+ if (shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) {
+ top_edge = ShelfLayoutManager::kShelfItemInset;
+ left_edge = 0;
+ bottom_edge = ShelfLayoutManager::GetPreferredShelfSize() -
+ ShelfLayoutManager::kShelfItemInset - GetShelfItemHeight();
+ right_edge = on_edge ? kPaddingFromEdgeOfShelf : 0;
+ } else if (shelf_alignment() == SHELF_ALIGNMENT_LEFT) {
+ top_edge = 0;
+ left_edge = ShelfLayoutManager::GetPreferredShelfSize() -
+ ShelfLayoutManager::kShelfItemInset - GetShelfItemHeight();
+ bottom_edge = on_edge ? kPaddingFromEdgeOfShelf : 0;
+ right_edge = ShelfLayoutManager::kShelfItemInset;
+ } else { // SHELF_ALIGNMENT_RIGHT
+ top_edge = 0;
+ left_edge = ShelfLayoutManager::kShelfItemInset;
+ bottom_edge = on_edge ? kPaddingFromEdgeOfShelf : 0;
+ right_edge = ShelfLayoutManager::GetPreferredShelfSize() -
+ ShelfLayoutManager::kShelfItemInset - GetShelfItemHeight();
+ }
+ } else {
+ // Change the border padding for different shelf alignment.
+ if (shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) {
+ top_edge = 0;
+ left_edge = 0;
+ bottom_edge = on_edge ? kPaddingFromBottomOfScreenBottomAlignment :
+ kPaddingFromBottomOfScreenBottomAlignment - 1;
+ right_edge = on_edge ? kPaddingFromRightEdgeOfScreenBottomAlignment : 0;
+ } else if (shelf_alignment() == SHELF_ALIGNMENT_TOP) {
+ top_edge = on_edge ? kPaddingFromBottomOfScreenBottomAlignment :
+ kPaddingFromBottomOfScreenBottomAlignment - 1;
+ left_edge = 0;
+ bottom_edge = 0;
+ right_edge = on_edge ? kPaddingFromRightEdgeOfScreenBottomAlignment : 0;
+ } else if (shelf_alignment() == SHELF_ALIGNMENT_LEFT) {
+ top_edge = 0;
+ left_edge = kPaddingFromOuterEdgeOfLauncherVerticalAlignment;
+ bottom_edge = on_edge ? kPaddingFromBottomOfScreenVerticalAlignment : 0;
+ right_edge = kPaddingFromInnerEdgeOfLauncherVerticalAlignment;
+ } else {
+ top_edge = 0;
+ left_edge = kPaddingFromInnerEdgeOfLauncherVerticalAlignment;
+ bottom_edge = on_edge ? kPaddingFromBottomOfScreenVerticalAlignment : 0;
+ right_edge = kPaddingFromOuterEdgeOfLauncherVerticalAlignment;
+ }
+ }
+ set_border(views::Border::CreateEmptyBorder(
+ top_edge, left_edge, bottom_edge, right_edge));
+}
+
+void TrayBackgroundView::InitializeBubbleAnimations(
+ views::Widget* bubble_widget) {
+ views::corewm::SetWindowVisibilityAnimationType(
+ bubble_widget->GetNativeWindow(),
+ views::corewm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
+ views::corewm::SetWindowVisibilityAnimationTransition(
+ bubble_widget->GetNativeWindow(),
+ views::corewm::ANIMATE_HIDE);
+ views::corewm::SetWindowVisibilityAnimationDuration(
+ bubble_widget->GetNativeWindow(),
+ base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
+}
+
+aura::Window* TrayBackgroundView::GetBubbleWindowContainer() const {
+ return ash::Shell::GetContainer(
+ tray_container()->GetWidget()->GetNativeWindow()->GetRootWindow(),
+ ash::internal::kShellWindowId_SettingBubbleContainer);
+}
+
+gfx::Rect TrayBackgroundView::GetBubbleAnchorRect(
+ views::Widget* anchor_widget,
+ TrayBubbleView::AnchorType anchor_type,
+ TrayBubbleView::AnchorAlignment anchor_alignment) const {
+ gfx::Rect rect;
+ if (anchor_widget && anchor_widget->IsVisible()) {
+ rect = anchor_widget->GetWindowBoundsInScreen();
+ if (anchor_type == TrayBubbleView::ANCHOR_TYPE_TRAY) {
+ if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM) {
+ bool rtl = base::i18n::IsRTL();
+ if (!ash::switches::UseAlternateShelfLayout()) {
+ rect.Inset(
+ rtl ? kPaddingFromRightEdgeOfScreenBottomAlignment : 0,
+ kTrayBubbleAnchorTopInsetBottomAnchor,
+ rtl ? 0 : kPaddingFromRightEdgeOfScreenBottomAlignment,
+ kPaddingFromBottomOfScreenBottomAlignment);
+ } else {
+ rect.Inset(
+ rtl ? kAlternateLayoutBubblePaddingHorizontalSide : 0,
+ kAlternateLayoutBubblePaddingHorizontalBottom,
+ rtl ? 0 : kAlternateLayoutBubblePaddingHorizontalSide,
+ 0);
+ }
+ } else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_LEFT) {
+ if (!ash::switches::UseAlternateShelfLayout()) {
+ rect.Inset(0, 0, kPaddingFromInnerEdgeOfLauncherVerticalAlignment + 5,
+ kPaddingFromBottomOfScreenVerticalAlignment);
+ } else {
+ rect.Inset(0, 0, kAlternateLayoutBubblePaddingVerticalSide + 4,
+ kAlternateLayoutBubblePaddingVerticalBottom);
+ }
+ } else {
+ if (!ash::switches::UseAlternateShelfLayout()) {
+ rect.Inset(kPaddingFromInnerEdgeOfLauncherVerticalAlignment + 1,
+ 0, 0, kPaddingFromBottomOfScreenVerticalAlignment);
+ } else {
+ rect.Inset(kAlternateLayoutBubblePaddingVerticalSide, 0, 0,
+ kAlternateLayoutBubblePaddingVerticalBottom);
+ }
+ }
+ } else if (anchor_type == TrayBubbleView::ANCHOR_TYPE_BUBBLE) {
+ // Invert the offsets to align with the bubble below.
+ // Note that with the alternate shelf layout the tips are not shown and
+ // the offsets for left and right alignment do not need to be applied.
+ int vertical_alignment = ash::switches::UseAlternateShelfLayout() ?
+ 0 :
+ kPaddingFromInnerEdgeOfLauncherVerticalAlignment;
+ int horizontal_alignment = ash::switches::UseAlternateShelfLayout() ?
+ kAlternateLayoutBubblePaddingVerticalBottom :
+ kPaddingFromBottomOfScreenVerticalAlignment;
+ if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_LEFT)
+ rect.Inset(vertical_alignment, 0, 0, horizontal_alignment);
+ else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT)
+ rect.Inset(0, 0, vertical_alignment, horizontal_alignment);
+ }
+ }
+
+ // TODO(jennyz): May need to add left/right alignment in the following code.
+ if (rect.IsEmpty()) {
+ aura::Window* target_root = anchor_widget ?
+ anchor_widget->GetNativeView()->GetRootWindow() :
+ Shell::GetPrimaryRootWindow();
+ rect = target_root->bounds();
+ rect = gfx::Rect(
+ base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreenBottomAlignment :
+ rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment,
+ rect.height() - kPaddingFromBottomOfScreenBottomAlignment,
+ 0, 0);
+ rect = ScreenAsh::ConvertRectToScreen(target_root, rect);
+ }
+ return rect;
+}
+
+TrayBubbleView::AnchorAlignment TrayBackgroundView::GetAnchorAlignment() const {
+ switch (shelf_alignment_) {
+ case SHELF_ALIGNMENT_BOTTOM:
+ return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM;
+ case SHELF_ALIGNMENT_LEFT:
+ return TrayBubbleView::ANCHOR_ALIGNMENT_LEFT;
+ case SHELF_ALIGNMENT_RIGHT:
+ return TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT;
+ case SHELF_ALIGNMENT_TOP:
+ return TrayBubbleView::ANCHOR_ALIGNMENT_TOP;
+ }
+ NOTREACHED();
+ return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM;
+}
+
+void TrayBackgroundView::SetDrawBackgroundAsActive(bool visible) {
+ draw_background_as_active_ = visible;
+ if (!background_ || !switches::UseAlternateShelfLayout())
+ return;
+
+ // Do not change gradually, changing color between grey and blue is weird.
+ if (draw_background_as_active_)
+ background_->set_color(kTrayBackgroundPressedColor);
+ else if (hovered_)
+ background_->set_alpha(kTrayBackgroundHoverAlpha);
+ else
+ background_->set_alpha(kTrayBackgroundAlpha);
+ SchedulePaint();
+}
+
+void TrayBackgroundView::UpdateBubbleViewArrow(
+ views::TrayBubbleView* bubble_view) {
+ if (switches::UseAlternateShelfLayout())
+ return;
+
+ aura::Window* root_window =
+ bubble_view->GetWidget()->GetNativeView()->GetRootWindow();
+ ash::internal::ShelfLayoutManager* shelf =
+ ShelfLayoutManager::ForLauncher(root_window);
+ bubble_view->SetArrowPaintType(
+ (shelf && shelf->IsVisible()) ?
+ views::BubbleBorder::PAINT_NORMAL :
+ views::BubbleBorder::PAINT_TRANSPARENT);
+}
+
+} // namespace internal
+} // namespace ash