1 // Copyright (c) 2012 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.
5 #include "ash/system/tray/tray_background_view.h"
7 #include "ash/ash_switches.h"
8 #include "ash/root_window_controller.h"
9 #include "ash/screen_util.h"
10 #include "ash/shelf/shelf_layout_manager.h"
11 #include "ash/shelf/shelf_widget.h"
12 #include "ash/shell.h"
13 #include "ash/shell_window_ids.h"
14 #include "ash/system/status_area_widget.h"
15 #include "ash/system/status_area_widget_delegate.h"
16 #include "ash/system/tray/system_tray.h"
17 #include "ash/system/tray/tray_constants.h"
18 #include "ash/system/tray/tray_event_filter.h"
19 #include "ash/wm/window_animations.h"
20 #include "grit/ash_resources.h"
21 #include "ui/accessibility/ax_view_state.h"
22 #include "ui/aura/window.h"
23 #include "ui/aura/window_event_dispatcher.h"
24 #include "ui/base/resource/resource_bundle.h"
25 #include "ui/compositor/layer.h"
26 #include "ui/compositor/layer_animation_element.h"
27 #include "ui/compositor/scoped_layer_animation_settings.h"
28 #include "ui/gfx/animation/tween.h"
29 #include "ui/gfx/canvas.h"
30 #include "ui/gfx/image/image_skia.h"
31 #include "ui/gfx/image/image_skia_operations.h"
32 #include "ui/gfx/rect.h"
33 #include "ui/gfx/screen.h"
34 #include "ui/gfx/skia_util.h"
35 #include "ui/gfx/transform.h"
36 #include "ui/views/background.h"
37 #include "ui/views/layout/box_layout.h"
41 const int kTrayBackgroundAlpha
= 100;
42 const int kTrayBackgroundHoverAlpha
= 150;
43 const SkColor kTrayBackgroundPressedColor
= SkColorSetRGB(66, 129, 244);
45 const int kAnimationDurationForPopupMs
= 200;
47 // Duration of opacity animation for visibility changes.
48 const int kAnimationDurationForVisibilityMs
= 250;
50 // When becoming visible delay the animation so that StatusAreaWidgetDelegate
51 // can animate sibling views out of the position to be occuped by the
52 // TrayBackgroundView.
53 const int kShowAnimationDelayMs
= 100;
57 using views::TrayBubbleView
;
62 const char TrayBackgroundView::kViewClassName
[] = "tray/TrayBackgroundView";
64 // Used to track when the anchor widget changes position on screen so that the
65 // bubble position can be updated.
66 class TrayBackgroundView::TrayWidgetObserver
: public views::WidgetObserver
{
68 explicit TrayWidgetObserver(TrayBackgroundView
* host
)
72 virtual void OnWidgetBoundsChanged(views::Widget
* widget
,
73 const gfx::Rect
& new_bounds
) OVERRIDE
{
74 host_
->AnchorUpdated();
77 virtual void OnWidgetVisibilityChanged(views::Widget
* widget
,
78 bool visible
) OVERRIDE
{
79 host_
->AnchorUpdated();
83 TrayBackgroundView
* host_
;
85 DISALLOW_COPY_AND_ASSIGN(TrayWidgetObserver
);
88 class TrayBackground
: public views::Background
{
90 const static int kImageTypeDefault
= 0;
91 const static int kImageTypeOnBlack
= 1;
92 const static int kImageTypePressed
= 2;
93 const static int kNumStates
= 3;
95 const static int kImageHorizontal
= 0;
96 const static int kImageVertical
= 1;
97 const static int kNumOrientations
= 2;
99 explicit TrayBackground(TrayBackgroundView
* tray_background_view
) :
100 tray_background_view_(tray_background_view
) {
101 set_alpha(kTrayBackgroundAlpha
);
102 ResourceBundle
& rb
= ResourceBundle::GetSharedInstance();
103 leading_images_
[kImageHorizontal
][kImageTypeDefault
] =
104 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_LEFT
).ToImageSkia();
105 middle_images_
[kImageHorizontal
][kImageTypeDefault
] =
106 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_CENTER
).ToImageSkia();
107 trailing_images_
[kImageHorizontal
][kImageTypeDefault
] =
108 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_RIGHT
).ToImageSkia();
110 leading_images_
[kImageHorizontal
][kImageTypeOnBlack
] =
111 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_LEFT_ONBLACK
).ToImageSkia();
112 middle_images_
[kImageHorizontal
][kImageTypeOnBlack
] =
113 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_CENTER_ONBLACK
).ToImageSkia();
114 trailing_images_
[kImageHorizontal
][kImageTypeOnBlack
] =
115 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_RIGHT_ONBLACK
).ToImageSkia();
117 leading_images_
[kImageHorizontal
][kImageTypePressed
] =
118 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_LEFT_PRESSED
).ToImageSkia();
119 middle_images_
[kImageHorizontal
][kImageTypePressed
] =
120 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_CENTER_PRESSED
).ToImageSkia();
121 trailing_images_
[kImageHorizontal
][kImageTypePressed
] =
122 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_RIGHT_PRESSED
).ToImageSkia();
124 leading_images_
[kImageVertical
][kImageTypeDefault
] =
125 rb
.GetImageNamed(IDR_AURA_TRAY_BG_VERTICAL_TOP
).ToImageSkia();
126 middle_images_
[kImageVertical
][kImageTypeDefault
] =
128 IDR_AURA_TRAY_BG_VERTICAL_CENTER
).ToImageSkia();
129 trailing_images_
[kImageVertical
][kImageTypeDefault
] =
130 rb
.GetImageNamed(IDR_AURA_TRAY_BG_VERTICAL_BOTTOM
).ToImageSkia();
132 leading_images_
[kImageVertical
][kImageTypeOnBlack
] =
133 rb
.GetImageNamed(IDR_AURA_TRAY_BG_VERTICAL_TOP_ONBLACK
).ToImageSkia();
134 middle_images_
[kImageVertical
][kImageTypeOnBlack
] =
136 IDR_AURA_TRAY_BG_VERTICAL_CENTER_ONBLACK
).ToImageSkia();
137 trailing_images_
[kImageVertical
][kImageTypeOnBlack
] =
139 IDR_AURA_TRAY_BG_VERTICAL_BOTTOM_ONBLACK
).ToImageSkia();
141 leading_images_
[kImageVertical
][kImageTypePressed
] =
142 rb
.GetImageNamed(IDR_AURA_TRAY_BG_VERTICAL_TOP_PRESSED
).ToImageSkia();
143 middle_images_
[kImageVertical
][kImageTypePressed
] =
145 IDR_AURA_TRAY_BG_VERTICAL_CENTER_PRESSED
).ToImageSkia();
146 trailing_images_
[kImageVertical
][kImageTypePressed
] =
148 IDR_AURA_TRAY_BG_VERTICAL_BOTTOM_PRESSED
).ToImageSkia();
151 virtual ~TrayBackground() {}
153 SkColor
color() { return color_
; }
154 void set_color(SkColor color
) { color_
= color
; }
155 void set_alpha(int alpha
) { color_
= SkColorSetARGB(alpha
, 0, 0, 0); }
158 ShelfWidget
* GetShelfWidget() const {
159 return RootWindowController::ForWindow(tray_background_view_
->
160 status_area_widget()->GetNativeWindow())->shelf();
163 // Overridden from views::Background.
164 virtual void Paint(gfx::Canvas
* canvas
, views::View
* view
) const OVERRIDE
{
165 int orientation
= kImageHorizontal
;
166 ShelfWidget
* shelf_widget
= GetShelfWidget();
168 !shelf_widget
->shelf_layout_manager()->IsHorizontalAlignment())
169 orientation
= kImageVertical
;
171 int state
= kImageTypeDefault
;
172 if (tray_background_view_
->draw_background_as_active())
173 state
= kImageTypePressed
;
174 else if (shelf_widget
&& shelf_widget
->GetDimsShelf())
175 state
= kImageTypeOnBlack
;
177 state
= kImageTypeDefault
;
179 const gfx::ImageSkia
* leading
= leading_images_
[orientation
][state
];
180 const gfx::ImageSkia
* middle
= middle_images_
[orientation
][state
];
181 const gfx::ImageSkia
* trailing
= trailing_images_
[orientation
][state
];
183 gfx::Rect
bounds(view
->GetLocalBounds());
184 gfx::Point leading_location
, trailing_location
;
185 gfx::Rect middle_bounds
;
187 if (orientation
== kImageHorizontal
) {
188 leading_location
= gfx::Point(0, 0);
189 trailing_location
= gfx::Point(bounds
.width() - trailing
->width(), 0);
190 middle_bounds
= gfx::Rect(
193 bounds
.width() - (leading
->width() + trailing
->width()),
196 leading_location
= gfx::Point(0, 0);
197 trailing_location
= gfx::Point(0, bounds
.height() - trailing
->height());
198 middle_bounds
= gfx::Rect(
202 bounds
.height() - (leading
->height() + trailing
->height()));
205 canvas
->DrawImageInt(*leading
,
206 leading_location
.x(),
207 leading_location
.y());
209 canvas
->DrawImageInt(*trailing
,
210 trailing_location
.x(),
211 trailing_location
.y());
213 canvas
->TileImageInt(*middle
,
216 middle_bounds
.width(),
217 middle_bounds
.height());
221 // Reference to the TrayBackgroundView for which this is a background.
222 TrayBackgroundView
* tray_background_view_
;
224 // References to the images used as backgrounds, they are owned by the
225 // resource bundle class.
226 const gfx::ImageSkia
* leading_images_
[kNumOrientations
][kNumStates
];
227 const gfx::ImageSkia
* middle_images_
[kNumOrientations
][kNumStates
];
228 const gfx::ImageSkia
* trailing_images_
[kNumOrientations
][kNumStates
];
230 DISALLOW_COPY_AND_ASSIGN(TrayBackground
);
233 TrayBackgroundView::TrayContainer::TrayContainer(ShelfAlignment alignment
)
234 : alignment_(alignment
) {
238 void TrayBackgroundView::TrayContainer::SetAlignment(ShelfAlignment alignment
) {
239 if (alignment_
== alignment
)
241 alignment_
= alignment
;
245 gfx::Size
TrayBackgroundView::TrayContainer::GetPreferredSize() const {
247 return views::View::GetPreferredSize();
251 void TrayBackgroundView::TrayContainer::ChildPreferredSizeChanged(
252 views::View
* child
) {
253 PreferredSizeChanged();
256 void TrayBackgroundView::TrayContainer::ChildVisibilityChanged(View
* child
) {
257 PreferredSizeChanged();
260 void TrayBackgroundView::TrayContainer::ViewHierarchyChanged(
261 const ViewHierarchyChangedDetails
& details
) {
262 if (details
.parent
== this)
263 PreferredSizeChanged();
266 void TrayBackgroundView::TrayContainer::UpdateLayout() {
267 // Adjust the size of status tray dark background by adding additional
269 if (alignment_
== SHELF_ALIGNMENT_BOTTOM
||
270 alignment_
== SHELF_ALIGNMENT_TOP
) {
271 SetBorder(views::Border::CreateEmptyBorder(
272 kPaddingFromEdgeOfShelf
,
273 kPaddingFromEdgeOfShelf
,
274 kPaddingFromEdgeOfShelf
,
275 kPaddingFromEdgeOfShelf
));
277 views::BoxLayout
* layout
=
278 new views::BoxLayout(views::BoxLayout::kHorizontal
, 0, 0, 0);
279 layout
->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_FILL
);
280 views::View::SetLayoutManager(layout
);
282 SetBorder(views::Border::CreateEmptyBorder(
283 kPaddingFromEdgeOfShelf
,
284 kPaddingFromEdgeOfShelf
,
285 kPaddingFromEdgeOfShelf
,
286 kPaddingFromEdgeOfShelf
));
288 views::BoxLayout
* layout
=
289 new views::BoxLayout(views::BoxLayout::kVertical
, 0, 0, 0);
290 layout
->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_FILL
);
291 views::View::SetLayoutManager(layout
);
293 PreferredSizeChanged();
296 ////////////////////////////////////////////////////////////////////////////////
297 // TrayBackgroundView
299 TrayBackgroundView::TrayBackgroundView(StatusAreaWidget
* status_area_widget
)
300 : status_area_widget_(status_area_widget
),
301 tray_container_(NULL
),
302 shelf_alignment_(SHELF_ALIGNMENT_BOTTOM
),
304 hide_background_animator_(this, 0, kTrayBackgroundAlpha
),
305 hover_background_animator_(
308 kTrayBackgroundHoverAlpha
- kTrayBackgroundAlpha
),
310 draw_background_as_active_(false),
311 widget_observer_(new TrayWidgetObserver(this)) {
312 set_notify_enter_exit_on_child(true);
314 // Initially we want to paint the background, but without the hover effect.
315 hide_background_animator_
.SetPaintsBackground(
316 true, BACKGROUND_CHANGE_IMMEDIATE
);
317 hover_background_animator_
.SetPaintsBackground(
318 false, BACKGROUND_CHANGE_IMMEDIATE
);
320 tray_container_
= new TrayContainer(shelf_alignment_
);
321 SetContents(tray_container_
);
322 tray_event_filter_
.reset(new TrayEventFilter
);
324 SetPaintToLayer(true);
325 SetFillsBoundsOpaquely(false);
326 // Start the tray items not visible, because visibility changes are animated.
327 views::View::SetVisible(false);
330 TrayBackgroundView::~TrayBackgroundView() {
332 GetWidget()->RemoveObserver(widget_observer_
.get());
335 void TrayBackgroundView::Initialize() {
336 GetWidget()->AddObserver(widget_observer_
.get());
340 void TrayBackgroundView::SetVisible(bool visible
) {
341 if (visible
== layer()->GetTargetVisibility())
345 // The alignment of the shelf can change while the TrayBackgroundView is
346 // hidden. Reset the offscreen transform so that the animation to becoming
347 // visible reflects the current layout.
348 HideTransformation();
349 // SetVisible(false) is defered until the animation for hiding is done.
350 // Otherwise the view is immediately hidden and the animation does not
352 views::View::SetVisible(true);
353 // If SetVisible(true) is called while animating to not visible, then
354 // views::View::SetVisible(true) is a no-op. When the previous animation
355 // ends layer->SetVisible(false) is called. To prevent this
356 // layer->SetVisible(true) immediately interrupts the animation of this
357 // property, and keeps the layer visible.
358 layer()->SetVisible(true);
361 ui::ScopedLayerAnimationSettings
animation(layer()->GetAnimator());
362 animation
.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
363 kAnimationDurationForVisibilityMs
));
364 animation
.SetPreemptionStrategy(
365 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET
);
368 animation
.SetTweenType(gfx::Tween::EASE_OUT
);
369 // Show is delayed so as to allow time for other children of
370 // StatusAreaWidget to begin animating to their new positions.
371 layer()->GetAnimator()->SchedulePauseForProperties(
372 base::TimeDelta::FromMilliseconds(kShowAnimationDelayMs
),
373 ui::LayerAnimationElement::OPACITY
|
374 ui::LayerAnimationElement::TRANSFORM
);
375 layer()->SetOpacity(1.0f
);
376 gfx::Transform transform
;
377 transform
.Translate(0.0f
, 0.0f
);
378 layer()->SetTransform(transform
);
380 // Listen only to the hide animation. As we cannot turn off visibility
381 // until the animation is over.
382 animation
.AddObserver(this);
383 animation
.SetTweenType(gfx::Tween::EASE_IN
);
384 layer()->SetOpacity(0.0f
);
385 layer()->SetVisible(false);
386 HideTransformation();
390 const char* TrayBackgroundView::GetClassName() const {
391 return kViewClassName
;
394 void TrayBackgroundView::OnMouseEntered(const ui::MouseEvent
& event
) {
398 void TrayBackgroundView::OnMouseExited(const ui::MouseEvent
& event
) {
402 void TrayBackgroundView::ChildPreferredSizeChanged(views::View
* child
) {
403 PreferredSizeChanged();
406 void TrayBackgroundView::GetAccessibleState(ui::AXViewState
* state
) {
407 state
->role
= ui::AX_ROLE_BUTTON
;
408 state
->name
= GetAccessibleNameForTray();
411 void TrayBackgroundView::AboutToRequestFocusFromTabTraversal(bool reverse
) {
412 // Return focus to the login view. See crbug.com/120500.
413 views::View
* v
= GetNextFocusableView();
415 v
->AboutToRequestFocusFromTabTraversal(reverse
);
418 bool TrayBackgroundView::PerformAction(const ui::Event
& event
) {
422 gfx::Rect
TrayBackgroundView::GetFocusBounds() {
423 // The tray itself expands to the right and bottom edge of the screen to make
424 // sure clicking on the edges brings up the popup. However, the focus border
425 // should be only around the container.
426 return GetContentsBounds();
429 void TrayBackgroundView::UpdateBackground(int alpha
) {
430 // The animator should never fire when the alternate shelf layout is used.
431 if (!background_
|| draw_background_as_active_
)
433 background_
->set_alpha(hide_background_animator_
.alpha() +
434 hover_background_animator_
.alpha());
438 void TrayBackgroundView::SetContents(views::View
* contents
) {
439 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical
, 0, 0, 0));
440 AddChildView(contents
);
443 void TrayBackgroundView::SetPaintsBackground(
444 bool value
, BackgroundAnimatorChangeType change_type
) {
445 hide_background_animator_
.SetPaintsBackground(value
, change_type
);
448 void TrayBackgroundView::SetContentsBackground() {
449 background_
= new TrayBackground(this);
450 tray_container_
->set_background(background_
);
453 ShelfLayoutManager
* TrayBackgroundView::GetShelfLayoutManager() {
454 return ShelfLayoutManager::ForShelf(GetWidget()->GetNativeView());
457 void TrayBackgroundView::SetShelfAlignment(ShelfAlignment alignment
) {
458 shelf_alignment_
= alignment
;
460 tray_container_
->SetAlignment(alignment
);
463 void TrayBackgroundView::SetTrayBorder() {
464 views::View
* parent
= status_area_widget_
->status_area_widget_delegate();
465 // Tray views are laid out right-to-left or bottom-to-top
466 bool on_edge
= (this == parent
->child_at(0));
467 int left_edge
, top_edge
, right_edge
, bottom_edge
;
468 if (shelf_alignment() == SHELF_ALIGNMENT_BOTTOM
) {
469 top_edge
= ShelfLayoutManager::kShelfItemInset
;
471 bottom_edge
= kShelfSize
-
472 ShelfLayoutManager::kShelfItemInset
- kShelfItemHeight
;
473 right_edge
= on_edge
? kPaddingFromEdgeOfShelf
: 0;
474 } else if (shelf_alignment() == SHELF_ALIGNMENT_LEFT
) {
476 left_edge
= kShelfSize
-
477 ShelfLayoutManager::kShelfItemInset
- kShelfItemHeight
;
478 bottom_edge
= on_edge
? kPaddingFromEdgeOfShelf
: 0;
479 right_edge
= ShelfLayoutManager::kShelfItemInset
;
480 } else { // SHELF_ALIGNMENT_RIGHT
482 left_edge
= ShelfLayoutManager::kShelfItemInset
;
483 bottom_edge
= on_edge
? kPaddingFromEdgeOfShelf
: 0;
484 right_edge
= kShelfSize
-
485 ShelfLayoutManager::kShelfItemInset
- kShelfItemHeight
;
487 SetBorder(views::Border::CreateEmptyBorder(
488 top_edge
, left_edge
, bottom_edge
, right_edge
));
491 void TrayBackgroundView::OnImplicitAnimationsCompleted() {
492 // If there is another animation in the queue, the reverse animation was
493 // triggered before the completion of animating to invisible. Do not turn off
494 // the visibility so that the next animation may render. The value of
495 // layer()->GetTargetVisibility() can be incorrect if the hide animation was
496 // aborted to schedule an animation to become visible. As the new animation
497 // is not yet added to the queue. crbug.com/374236
498 if(layer()->GetAnimator()->is_animating() ||
499 layer()->GetTargetVisibility())
501 views::View::SetVisible(false);
504 void TrayBackgroundView::HideTransformation() {
505 gfx::Transform transform
;
506 if (shelf_alignment_
== SHELF_ALIGNMENT_BOTTOM
||
507 shelf_alignment_
== SHELF_ALIGNMENT_TOP
)
508 transform
.Translate(width(), 0.0f
);
510 transform
.Translate(0.0f
, height());
511 layer()->SetTransform(transform
);
514 void TrayBackgroundView::InitializeBubbleAnimations(
515 views::Widget
* bubble_widget
) {
516 wm::SetWindowVisibilityAnimationType(
517 bubble_widget
->GetNativeWindow(),
518 wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE
);
519 wm::SetWindowVisibilityAnimationTransition(
520 bubble_widget
->GetNativeWindow(),
522 wm::SetWindowVisibilityAnimationDuration(
523 bubble_widget
->GetNativeWindow(),
524 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMs
));
527 aura::Window
* TrayBackgroundView::GetBubbleWindowContainer() const {
528 return ash::Shell::GetContainer(
529 tray_container()->GetWidget()->GetNativeWindow()->GetRootWindow(),
530 ash::kShellWindowId_SettingBubbleContainer
);
533 gfx::Rect
TrayBackgroundView::GetBubbleAnchorRect(
534 views::Widget
* anchor_widget
,
535 TrayBubbleView::AnchorType anchor_type
,
536 TrayBubbleView::AnchorAlignment anchor_alignment
) const {
538 if (anchor_widget
&& anchor_widget
->IsVisible()) {
539 rect
= anchor_widget
->GetWindowBoundsInScreen();
540 if (anchor_type
== TrayBubbleView::ANCHOR_TYPE_TRAY
) {
541 if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM
) {
542 bool rtl
= base::i18n::IsRTL();
544 rtl
? kBubblePaddingHorizontalSide
: 0,
545 kBubblePaddingHorizontalBottom
,
546 rtl
? 0 : kBubblePaddingHorizontalSide
,
548 } else if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_LEFT
) {
549 rect
.Inset(0, 0, kBubblePaddingVerticalSide
+ 4,
550 kBubblePaddingVerticalBottom
);
551 } else if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT
) {
552 rect
.Inset(kBubblePaddingVerticalSide
, 0, 0,
553 kBubblePaddingVerticalBottom
);
555 // TODO(bruthig) May need to handle other ANCHOR_ALIGNMENT_ values.
556 // ie. ANCHOR_ALIGNMENT_TOP
557 DCHECK(false) << "Unhandled anchor alignment.";
559 } else if (anchor_type
== TrayBubbleView::ANCHOR_TYPE_BUBBLE
) {
560 // Invert the offsets to align with the bubble below.
561 // Note that with the alternate shelf layout the tips are not shown and
562 // the offsets for left and right alignment do not need to be applied.
563 int vertical_alignment
= 0;
564 int horizontal_alignment
= kBubblePaddingVerticalBottom
;
565 if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_LEFT
)
566 rect
.Inset(vertical_alignment
, 0, 0, horizontal_alignment
);
567 else if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT
)
568 rect
.Inset(0, 0, vertical_alignment
, horizontal_alignment
);
570 DCHECK(false) << "Unhandled anchor type.";
573 aura::Window
* target_root
= anchor_widget
?
574 anchor_widget
->GetNativeView()->GetRootWindow() :
575 Shell::GetPrimaryRootWindow();
576 rect
= target_root
->bounds();
577 if (anchor_type
== TrayBubbleView::ANCHOR_TYPE_TRAY
) {
578 if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM
) {
580 base::i18n::IsRTL() ?
581 kPaddingFromRightEdgeOfScreenBottomAlignment
:
582 rect
.width() - kPaddingFromRightEdgeOfScreenBottomAlignment
,
583 rect
.height() - kPaddingFromBottomOfScreenBottomAlignment
,
585 rect
= ScreenUtil::ConvertRectToScreen(target_root
, rect
);
586 } else if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_LEFT
) {
588 kPaddingFromRightEdgeOfScreenBottomAlignment
,
589 rect
.height() - kPaddingFromBottomOfScreenBottomAlignment
,
591 rect
= ScreenUtil::ConvertRectToScreen(target_root
, rect
);
592 } else if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT
) {
594 rect
.width() - kPaddingFromRightEdgeOfScreenBottomAlignment
,
595 rect
.height() - kPaddingFromBottomOfScreenBottomAlignment
,
597 rect
= ScreenUtil::ConvertRectToScreen(target_root
, rect
);
599 // TODO(bruthig) May need to handle other ANCHOR_ALIGNMENT_ values.
600 // ie. ANCHOR_ALIGNMENT_TOP
601 DCHECK(false) << "Unhandled anchor alignment.";
605 base::i18n::IsRTL() ?
606 kPaddingFromRightEdgeOfScreenBottomAlignment
:
607 rect
.width() - kPaddingFromRightEdgeOfScreenBottomAlignment
,
608 rect
.height() - kPaddingFromBottomOfScreenBottomAlignment
,
615 TrayBubbleView::AnchorAlignment
TrayBackgroundView::GetAnchorAlignment() const {
616 switch (shelf_alignment_
) {
617 case SHELF_ALIGNMENT_BOTTOM
:
618 return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM
;
619 case SHELF_ALIGNMENT_LEFT
:
620 return TrayBubbleView::ANCHOR_ALIGNMENT_LEFT
;
621 case SHELF_ALIGNMENT_RIGHT
:
622 return TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT
;
623 case SHELF_ALIGNMENT_TOP
:
624 return TrayBubbleView::ANCHOR_ALIGNMENT_TOP
;
627 return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM
;
630 void TrayBackgroundView::SetDrawBackgroundAsActive(bool visible
) {
631 draw_background_as_active_
= visible
;
635 // Do not change gradually, changing color between grey and blue is weird.
636 if (draw_background_as_active_
)
637 background_
->set_color(kTrayBackgroundPressedColor
);
639 background_
->set_alpha(kTrayBackgroundHoverAlpha
);
641 background_
->set_alpha(kTrayBackgroundAlpha
);
645 void TrayBackgroundView::UpdateBubbleViewArrow(
646 views::TrayBubbleView
* bubble_view
) {
647 // Nothing to do here.