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/root_window_controller.h"
8 #include "ash/screen_util.h"
9 #include "ash/shelf/shelf_layout_manager.h"
10 #include "ash/shelf/shelf_widget.h"
11 #include "ash/shell.h"
12 #include "ash/shell_window_ids.h"
13 #include "ash/system/status_area_widget.h"
14 #include "ash/system/status_area_widget_delegate.h"
15 #include "ash/system/tray/system_tray.h"
16 #include "ash/system/tray/tray_constants.h"
17 #include "ash/system/tray/tray_event_filter.h"
18 #include "ash/wm/window_animations.h"
19 #include "base/command_line.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/base/ui_base_switches_util.h"
26 #include "ui/compositor/layer.h"
27 #include "ui/compositor/layer_animation_element.h"
28 #include "ui/compositor/scoped_layer_animation_settings.h"
29 #include "ui/events/event_constants.h"
30 #include "ui/gfx/animation/tween.h"
31 #include "ui/gfx/canvas.h"
32 #include "ui/gfx/image/image_skia.h"
33 #include "ui/gfx/image/image_skia_operations.h"
34 #include "ui/gfx/rect.h"
35 #include "ui/gfx/screen.h"
36 #include "ui/gfx/skia_util.h"
37 #include "ui/gfx/transform.h"
38 #include "ui/views/background.h"
39 #include "ui/views/layout/box_layout.h"
43 const int kTrayBackgroundAlpha
= 100;
44 const int kTrayBackgroundHoverAlpha
= 150;
45 const SkColor kTrayBackgroundPressedColor
= SkColorSetRGB(66, 129, 244);
47 const int kAnimationDurationForPopupMs
= 200;
49 // Duration of opacity animation for visibility changes.
50 const int kAnimationDurationForVisibilityMs
= 250;
52 // When becoming visible delay the animation so that StatusAreaWidgetDelegate
53 // can animate sibling views out of the position to be occuped by the
54 // TrayBackgroundView.
55 const int kShowAnimationDelayMs
= 100;
59 using views::TrayBubbleView
;
64 const char TrayBackgroundView::kViewClassName
[] = "tray/TrayBackgroundView";
66 // Used to track when the anchor widget changes position on screen so that the
67 // bubble position can be updated.
68 class TrayBackgroundView::TrayWidgetObserver
: public views::WidgetObserver
{
70 explicit TrayWidgetObserver(TrayBackgroundView
* host
)
74 virtual void OnWidgetBoundsChanged(views::Widget
* widget
,
75 const gfx::Rect
& new_bounds
) override
{
76 host_
->AnchorUpdated();
79 virtual void OnWidgetVisibilityChanged(views::Widget
* widget
,
80 bool visible
) override
{
81 host_
->AnchorUpdated();
85 TrayBackgroundView
* host_
;
87 DISALLOW_COPY_AND_ASSIGN(TrayWidgetObserver
);
90 class TrayBackground
: public views::Background
{
92 const static int kImageTypeDefault
= 0;
93 const static int kImageTypeOnBlack
= 1;
94 const static int kImageTypePressed
= 2;
95 const static int kNumStates
= 3;
97 const static int kImageHorizontal
= 0;
98 const static int kImageVertical
= 1;
99 const static int kNumOrientations
= 2;
101 explicit TrayBackground(TrayBackgroundView
* tray_background_view
) :
102 tray_background_view_(tray_background_view
) {
103 set_alpha(kTrayBackgroundAlpha
);
104 ResourceBundle
& rb
= ResourceBundle::GetSharedInstance();
105 leading_images_
[kImageHorizontal
][kImageTypeDefault
] =
106 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_LEFT
).ToImageSkia();
107 middle_images_
[kImageHorizontal
][kImageTypeDefault
] =
108 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_CENTER
).ToImageSkia();
109 trailing_images_
[kImageHorizontal
][kImageTypeDefault
] =
110 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_RIGHT
).ToImageSkia();
112 leading_images_
[kImageHorizontal
][kImageTypeOnBlack
] =
113 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_LEFT_ONBLACK
).ToImageSkia();
114 middle_images_
[kImageHorizontal
][kImageTypeOnBlack
] =
115 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_CENTER_ONBLACK
).ToImageSkia();
116 trailing_images_
[kImageHorizontal
][kImageTypeOnBlack
] =
117 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_RIGHT_ONBLACK
).ToImageSkia();
119 leading_images_
[kImageHorizontal
][kImageTypePressed
] =
120 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_LEFT_PRESSED
).ToImageSkia();
121 middle_images_
[kImageHorizontal
][kImageTypePressed
] =
122 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_CENTER_PRESSED
).ToImageSkia();
123 trailing_images_
[kImageHorizontal
][kImageTypePressed
] =
124 rb
.GetImageNamed(IDR_AURA_TRAY_BG_HORIZ_RIGHT_PRESSED
).ToImageSkia();
126 leading_images_
[kImageVertical
][kImageTypeDefault
] =
127 rb
.GetImageNamed(IDR_AURA_TRAY_BG_VERTICAL_TOP
).ToImageSkia();
128 middle_images_
[kImageVertical
][kImageTypeDefault
] =
130 IDR_AURA_TRAY_BG_VERTICAL_CENTER
).ToImageSkia();
131 trailing_images_
[kImageVertical
][kImageTypeDefault
] =
132 rb
.GetImageNamed(IDR_AURA_TRAY_BG_VERTICAL_BOTTOM
).ToImageSkia();
134 leading_images_
[kImageVertical
][kImageTypeOnBlack
] =
135 rb
.GetImageNamed(IDR_AURA_TRAY_BG_VERTICAL_TOP_ONBLACK
).ToImageSkia();
136 middle_images_
[kImageVertical
][kImageTypeOnBlack
] =
138 IDR_AURA_TRAY_BG_VERTICAL_CENTER_ONBLACK
).ToImageSkia();
139 trailing_images_
[kImageVertical
][kImageTypeOnBlack
] =
141 IDR_AURA_TRAY_BG_VERTICAL_BOTTOM_ONBLACK
).ToImageSkia();
143 leading_images_
[kImageVertical
][kImageTypePressed
] =
144 rb
.GetImageNamed(IDR_AURA_TRAY_BG_VERTICAL_TOP_PRESSED
).ToImageSkia();
145 middle_images_
[kImageVertical
][kImageTypePressed
] =
147 IDR_AURA_TRAY_BG_VERTICAL_CENTER_PRESSED
).ToImageSkia();
148 trailing_images_
[kImageVertical
][kImageTypePressed
] =
150 IDR_AURA_TRAY_BG_VERTICAL_BOTTOM_PRESSED
).ToImageSkia();
153 virtual ~TrayBackground() {}
155 SkColor
color() { return color_
; }
156 void set_color(SkColor color
) { color_
= color
; }
157 void set_alpha(int alpha
) { color_
= SkColorSetARGB(alpha
, 0, 0, 0); }
160 ShelfWidget
* GetShelfWidget() const {
161 return RootWindowController::ForWindow(tray_background_view_
->
162 status_area_widget()->GetNativeWindow())->shelf();
165 // Overridden from views::Background.
166 virtual void Paint(gfx::Canvas
* canvas
, views::View
* view
) const override
{
167 int orientation
= kImageHorizontal
;
168 ShelfWidget
* shelf_widget
= GetShelfWidget();
170 !shelf_widget
->shelf_layout_manager()->IsHorizontalAlignment())
171 orientation
= kImageVertical
;
173 int state
= kImageTypeDefault
;
174 if (tray_background_view_
->draw_background_as_active())
175 state
= kImageTypePressed
;
176 else if (shelf_widget
&& shelf_widget
->GetDimsShelf())
177 state
= kImageTypeOnBlack
;
179 state
= kImageTypeDefault
;
181 const gfx::ImageSkia
* leading
= leading_images_
[orientation
][state
];
182 const gfx::ImageSkia
* middle
= middle_images_
[orientation
][state
];
183 const gfx::ImageSkia
* trailing
= trailing_images_
[orientation
][state
];
185 gfx::Rect
bounds(view
->GetLocalBounds());
186 gfx::Point leading_location
, trailing_location
;
187 gfx::Rect middle_bounds
;
189 if (orientation
== kImageHorizontal
) {
190 leading_location
= gfx::Point(0, 0);
191 trailing_location
= gfx::Point(bounds
.width() - trailing
->width(), 0);
192 middle_bounds
= gfx::Rect(
195 bounds
.width() - (leading
->width() + trailing
->width()),
198 leading_location
= gfx::Point(0, 0);
199 trailing_location
= gfx::Point(0, bounds
.height() - trailing
->height());
200 middle_bounds
= gfx::Rect(
204 bounds
.height() - (leading
->height() + trailing
->height()));
207 canvas
->DrawImageInt(*leading
,
208 leading_location
.x(),
209 leading_location
.y());
211 canvas
->DrawImageInt(*trailing
,
212 trailing_location
.x(),
213 trailing_location
.y());
215 canvas
->TileImageInt(*middle
,
218 middle_bounds
.width(),
219 middle_bounds
.height());
223 // Reference to the TrayBackgroundView for which this is a background.
224 TrayBackgroundView
* tray_background_view_
;
226 // References to the images used as backgrounds, they are owned by the
227 // resource bundle class.
228 const gfx::ImageSkia
* leading_images_
[kNumOrientations
][kNumStates
];
229 const gfx::ImageSkia
* middle_images_
[kNumOrientations
][kNumStates
];
230 const gfx::ImageSkia
* trailing_images_
[kNumOrientations
][kNumStates
];
232 DISALLOW_COPY_AND_ASSIGN(TrayBackground
);
235 TrayBackgroundView::TrayContainer::TrayContainer(ShelfAlignment alignment
)
236 : alignment_(alignment
) {
240 void TrayBackgroundView::TrayContainer::SetAlignment(ShelfAlignment alignment
) {
241 if (alignment_
== alignment
)
243 alignment_
= alignment
;
247 gfx::Size
TrayBackgroundView::TrayContainer::GetPreferredSize() const {
249 return views::View::GetPreferredSize();
253 void TrayBackgroundView::TrayContainer::ChildPreferredSizeChanged(
254 views::View
* child
) {
255 PreferredSizeChanged();
258 void TrayBackgroundView::TrayContainer::ChildVisibilityChanged(View
* child
) {
259 PreferredSizeChanged();
262 void TrayBackgroundView::TrayContainer::ViewHierarchyChanged(
263 const ViewHierarchyChangedDetails
& details
) {
264 if (details
.parent
== this)
265 PreferredSizeChanged();
268 void TrayBackgroundView::TrayContainer::UpdateLayout() {
269 // Adjust the size of status tray dark background by adding additional
271 if (alignment_
== SHELF_ALIGNMENT_BOTTOM
||
272 alignment_
== SHELF_ALIGNMENT_TOP
) {
273 SetBorder(views::Border::CreateEmptyBorder(
274 kPaddingFromEdgeOfShelf
,
275 kPaddingFromEdgeOfShelf
,
276 kPaddingFromEdgeOfShelf
,
277 kPaddingFromEdgeOfShelf
));
279 views::BoxLayout
* layout
=
280 new views::BoxLayout(views::BoxLayout::kHorizontal
, 0, 0, 0);
281 layout
->SetDefaultFlex(1);
282 views::View::SetLayoutManager(layout
);
284 SetBorder(views::Border::CreateEmptyBorder(
285 kPaddingFromEdgeOfShelf
,
286 kPaddingFromEdgeOfShelf
,
287 kPaddingFromEdgeOfShelf
,
288 kPaddingFromEdgeOfShelf
));
290 views::BoxLayout
* layout
=
291 new views::BoxLayout(views::BoxLayout::kVertical
, 0, 0, 0);
292 layout
->SetDefaultFlex(1);
293 views::View::SetLayoutManager(layout
);
295 PreferredSizeChanged();
298 ////////////////////////////////////////////////////////////////////////////////
299 // TrayBackgroundView
301 TrayBackgroundView::TrayBackgroundView(StatusAreaWidget
* status_area_widget
)
302 : status_area_widget_(status_area_widget
),
303 tray_container_(NULL
),
304 shelf_alignment_(SHELF_ALIGNMENT_BOTTOM
),
306 hide_background_animator_(this, 0, kTrayBackgroundAlpha
),
307 hover_background_animator_(
310 kTrayBackgroundHoverAlpha
- kTrayBackgroundAlpha
),
312 draw_background_as_active_(false),
313 widget_observer_(new TrayWidgetObserver(this)) {
314 set_notify_enter_exit_on_child(true);
316 // Initially we want to paint the background, but without the hover effect.
317 hide_background_animator_
.SetPaintsBackground(
318 true, BACKGROUND_CHANGE_IMMEDIATE
);
319 hover_background_animator_
.SetPaintsBackground(
320 false, BACKGROUND_CHANGE_IMMEDIATE
);
322 tray_container_
= new TrayContainer(shelf_alignment_
);
323 SetContents(tray_container_
);
324 tray_event_filter_
.reset(new TrayEventFilter
);
326 SetPaintToLayer(true);
327 SetFillsBoundsOpaquely(false);
328 // Start the tray items not visible, because visibility changes are animated.
329 views::View::SetVisible(false);
332 TrayBackgroundView::~TrayBackgroundView() {
334 GetWidget()->RemoveObserver(widget_observer_
.get());
337 void TrayBackgroundView::Initialize() {
338 GetWidget()->AddObserver(widget_observer_
.get());
342 void TrayBackgroundView::SetVisible(bool visible
) {
343 if (visible
== layer()->GetTargetVisibility())
347 // The alignment of the shelf can change while the TrayBackgroundView is
348 // hidden. Reset the offscreen transform so that the animation to becoming
349 // visible reflects the current layout.
350 HideTransformation();
351 // SetVisible(false) is defered until the animation for hiding is done.
352 // Otherwise the view is immediately hidden and the animation does not
354 views::View::SetVisible(true);
355 // If SetVisible(true) is called while animating to not visible, then
356 // views::View::SetVisible(true) is a no-op. When the previous animation
357 // ends layer->SetVisible(false) is called. To prevent this
358 // layer->SetVisible(true) immediately interrupts the animation of this
359 // property, and keeps the layer visible.
360 layer()->SetVisible(true);
363 ui::ScopedLayerAnimationSettings
animation(layer()->GetAnimator());
364 animation
.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
365 kAnimationDurationForVisibilityMs
));
366 animation
.SetPreemptionStrategy(
367 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET
);
370 animation
.SetTweenType(gfx::Tween::EASE_OUT
);
371 // Show is delayed so as to allow time for other children of
372 // StatusAreaWidget to begin animating to their new positions.
373 layer()->GetAnimator()->SchedulePauseForProperties(
374 base::TimeDelta::FromMilliseconds(kShowAnimationDelayMs
),
375 ui::LayerAnimationElement::OPACITY
|
376 ui::LayerAnimationElement::TRANSFORM
);
377 layer()->SetOpacity(1.0f
);
378 gfx::Transform transform
;
379 transform
.Translate(0.0f
, 0.0f
);
380 layer()->SetTransform(transform
);
382 // Listen only to the hide animation. As we cannot turn off visibility
383 // until the animation is over.
384 animation
.AddObserver(this);
385 animation
.SetTweenType(gfx::Tween::EASE_IN
);
386 layer()->SetOpacity(0.0f
);
387 layer()->SetVisible(false);
388 HideTransformation();
392 const char* TrayBackgroundView::GetClassName() const {
393 return kViewClassName
;
396 void TrayBackgroundView::OnMouseEntered(const ui::MouseEvent
& event
) {
400 void TrayBackgroundView::OnMouseExited(const ui::MouseEvent
& event
) {
404 void TrayBackgroundView::ChildPreferredSizeChanged(views::View
* child
) {
405 PreferredSizeChanged();
408 void TrayBackgroundView::GetAccessibleState(ui::AXViewState
* state
) {
409 state
->role
= ui::AX_ROLE_BUTTON
;
410 state
->name
= GetAccessibleNameForTray();
413 void TrayBackgroundView::AboutToRequestFocusFromTabTraversal(bool reverse
) {
414 // Return focus to the login view. See crbug.com/120500.
415 views::View
* v
= GetNextFocusableView();
417 v
->AboutToRequestFocusFromTabTraversal(reverse
);
420 bool TrayBackgroundView::PerformAction(const ui::Event
& event
) {
424 gfx::Rect
TrayBackgroundView::GetFocusBounds() {
425 // The tray itself expands to the right and bottom edge of the screen to make
426 // sure clicking on the edges brings up the popup. However, the focus border
427 // should be only around the container.
428 return GetContentsBounds();
431 void TrayBackgroundView::OnGestureEvent(ui::GestureEvent
* event
) {
432 if (switches::IsTouchFeedbackEnabled()) {
433 if (event
->type() == ui::ET_GESTURE_TAP_DOWN
) {
434 SetDrawBackgroundAsActive(true);
435 } else if (event
->type() == ui::ET_GESTURE_SCROLL_BEGIN
||
436 event
->type() == ui::ET_GESTURE_TAP_CANCEL
) {
437 SetDrawBackgroundAsActive(false);
440 ActionableView::OnGestureEvent(event
);
443 void TrayBackgroundView::UpdateBackground(int alpha
) {
444 // The animator should never fire when the alternate shelf layout is used.
445 if (!background_
|| draw_background_as_active_
)
447 background_
->set_alpha(hide_background_animator_
.alpha() +
448 hover_background_animator_
.alpha());
452 void TrayBackgroundView::SetContents(views::View
* contents
) {
453 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical
, 0, 0, 0));
454 AddChildView(contents
);
457 void TrayBackgroundView::SetPaintsBackground(
458 bool value
, BackgroundAnimatorChangeType change_type
) {
459 hide_background_animator_
.SetPaintsBackground(value
, change_type
);
462 void TrayBackgroundView::SetContentsBackground() {
463 background_
= new TrayBackground(this);
464 tray_container_
->set_background(background_
);
467 ShelfLayoutManager
* TrayBackgroundView::GetShelfLayoutManager() {
468 return ShelfLayoutManager::ForShelf(GetWidget()->GetNativeView());
471 void TrayBackgroundView::SetShelfAlignment(ShelfAlignment alignment
) {
472 shelf_alignment_
= alignment
;
474 tray_container_
->SetAlignment(alignment
);
477 void TrayBackgroundView::SetTrayBorder() {
478 views::View
* parent
= status_area_widget_
->status_area_widget_delegate();
479 // Tray views are laid out right-to-left or bottom-to-top
480 bool on_edge
= (this == parent
->child_at(0));
481 int left_edge
, top_edge
, right_edge
, bottom_edge
;
482 if (shelf_alignment() == SHELF_ALIGNMENT_BOTTOM
) {
483 top_edge
= ShelfLayoutManager::kShelfItemInset
;
485 bottom_edge
= kShelfSize
-
486 ShelfLayoutManager::kShelfItemInset
- kShelfItemHeight
;
487 right_edge
= on_edge
? kPaddingFromEdgeOfShelf
: 0;
488 } else if (shelf_alignment() == SHELF_ALIGNMENT_LEFT
) {
490 left_edge
= kShelfSize
-
491 ShelfLayoutManager::kShelfItemInset
- kShelfItemHeight
;
492 bottom_edge
= on_edge
? kPaddingFromEdgeOfShelf
: 0;
493 right_edge
= ShelfLayoutManager::kShelfItemInset
;
494 } else { // SHELF_ALIGNMENT_RIGHT
496 left_edge
= ShelfLayoutManager::kShelfItemInset
;
497 bottom_edge
= on_edge
? kPaddingFromEdgeOfShelf
: 0;
498 right_edge
= kShelfSize
-
499 ShelfLayoutManager::kShelfItemInset
- kShelfItemHeight
;
501 SetBorder(views::Border::CreateEmptyBorder(
502 top_edge
, left_edge
, bottom_edge
, right_edge
));
505 void TrayBackgroundView::OnImplicitAnimationsCompleted() {
506 // If there is another animation in the queue, the reverse animation was
507 // triggered before the completion of animating to invisible. Do not turn off
508 // the visibility so that the next animation may render. The value of
509 // layer()->GetTargetVisibility() can be incorrect if the hide animation was
510 // aborted to schedule an animation to become visible. As the new animation
511 // is not yet added to the queue. crbug.com/374236
512 if(layer()->GetAnimator()->is_animating() ||
513 layer()->GetTargetVisibility())
515 views::View::SetVisible(false);
518 void TrayBackgroundView::HideTransformation() {
519 gfx::Transform transform
;
520 if (shelf_alignment_
== SHELF_ALIGNMENT_BOTTOM
||
521 shelf_alignment_
== SHELF_ALIGNMENT_TOP
)
522 transform
.Translate(width(), 0.0f
);
524 transform
.Translate(0.0f
, height());
525 layer()->SetTransform(transform
);
528 void TrayBackgroundView::InitializeBubbleAnimations(
529 views::Widget
* bubble_widget
) {
530 wm::SetWindowVisibilityAnimationType(
531 bubble_widget
->GetNativeWindow(),
532 wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE
);
533 wm::SetWindowVisibilityAnimationTransition(
534 bubble_widget
->GetNativeWindow(),
536 wm::SetWindowVisibilityAnimationDuration(
537 bubble_widget
->GetNativeWindow(),
538 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMs
));
541 aura::Window
* TrayBackgroundView::GetBubbleWindowContainer() const {
542 return ash::Shell::GetContainer(
543 tray_container()->GetWidget()->GetNativeWindow()->GetRootWindow(),
544 ash::kShellWindowId_SettingBubbleContainer
);
547 gfx::Rect
TrayBackgroundView::GetBubbleAnchorRect(
548 views::Widget
* anchor_widget
,
549 TrayBubbleView::AnchorType anchor_type
,
550 TrayBubbleView::AnchorAlignment anchor_alignment
) const {
552 if (anchor_widget
&& anchor_widget
->IsVisible()) {
553 rect
= anchor_widget
->GetWindowBoundsInScreen();
554 if (anchor_type
== TrayBubbleView::ANCHOR_TYPE_TRAY
) {
555 if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM
) {
556 bool rtl
= base::i18n::IsRTL();
558 rtl
? kBubblePaddingHorizontalSide
: 0,
559 kBubblePaddingHorizontalBottom
,
560 rtl
? 0 : kBubblePaddingHorizontalSide
,
562 } else if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_LEFT
) {
563 rect
.Inset(0, 0, kBubblePaddingVerticalSide
+ 4,
564 kBubblePaddingVerticalBottom
);
565 } else if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT
) {
566 rect
.Inset(kBubblePaddingVerticalSide
, 0, 0,
567 kBubblePaddingVerticalBottom
);
569 // TODO(bruthig) May need to handle other ANCHOR_ALIGNMENT_ values.
570 // ie. ANCHOR_ALIGNMENT_TOP
571 DCHECK(false) << "Unhandled anchor alignment.";
573 } else if (anchor_type
== TrayBubbleView::ANCHOR_TYPE_BUBBLE
) {
574 // Invert the offsets to align with the bubble below.
575 // Note that with the alternate shelf layout the tips are not shown and
576 // the offsets for left and right alignment do not need to be applied.
577 int vertical_alignment
= 0;
578 int horizontal_alignment
= kBubblePaddingVerticalBottom
;
579 if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_LEFT
)
580 rect
.Inset(vertical_alignment
, 0, 0, horizontal_alignment
);
581 else if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT
)
582 rect
.Inset(0, 0, vertical_alignment
, horizontal_alignment
);
584 DCHECK(false) << "Unhandled anchor type.";
587 aura::Window
* target_root
= anchor_widget
?
588 anchor_widget
->GetNativeView()->GetRootWindow() :
589 Shell::GetPrimaryRootWindow();
590 rect
= target_root
->bounds();
591 if (anchor_type
== TrayBubbleView::ANCHOR_TYPE_TRAY
) {
592 if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM
) {
594 base::i18n::IsRTL() ?
595 kPaddingFromRightEdgeOfScreenBottomAlignment
:
596 rect
.width() - kPaddingFromRightEdgeOfScreenBottomAlignment
,
597 rect
.height() - kPaddingFromBottomOfScreenBottomAlignment
,
599 rect
= ScreenUtil::ConvertRectToScreen(target_root
, rect
);
600 } else if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_LEFT
) {
602 kPaddingFromRightEdgeOfScreenBottomAlignment
,
603 rect
.height() - kPaddingFromBottomOfScreenBottomAlignment
,
605 rect
= ScreenUtil::ConvertRectToScreen(target_root
, rect
);
606 } else if (anchor_alignment
== TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT
) {
608 rect
.width() - kPaddingFromRightEdgeOfScreenBottomAlignment
,
609 rect
.height() - kPaddingFromBottomOfScreenBottomAlignment
,
611 rect
= ScreenUtil::ConvertRectToScreen(target_root
, rect
);
613 // TODO(bruthig) May need to handle other ANCHOR_ALIGNMENT_ values.
614 // ie. ANCHOR_ALIGNMENT_TOP
615 DCHECK(false) << "Unhandled anchor alignment.";
619 base::i18n::IsRTL() ?
620 kPaddingFromRightEdgeOfScreenBottomAlignment
:
621 rect
.width() - kPaddingFromRightEdgeOfScreenBottomAlignment
,
622 rect
.height() - kPaddingFromBottomOfScreenBottomAlignment
,
629 TrayBubbleView::AnchorAlignment
TrayBackgroundView::GetAnchorAlignment() const {
630 switch (shelf_alignment_
) {
631 case SHELF_ALIGNMENT_BOTTOM
:
632 return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM
;
633 case SHELF_ALIGNMENT_LEFT
:
634 return TrayBubbleView::ANCHOR_ALIGNMENT_LEFT
;
635 case SHELF_ALIGNMENT_RIGHT
:
636 return TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT
;
637 case SHELF_ALIGNMENT_TOP
:
638 return TrayBubbleView::ANCHOR_ALIGNMENT_TOP
;
641 return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM
;
644 void TrayBackgroundView::SetDrawBackgroundAsActive(bool visible
) {
645 if (draw_background_as_active_
== visible
)
647 draw_background_as_active_
= visible
;
651 // Do not change gradually, changing color between grey and blue is weird.
652 if (draw_background_as_active_
)
653 background_
->set_color(kTrayBackgroundPressedColor
);
655 background_
->set_alpha(kTrayBackgroundHoverAlpha
);
657 background_
->set_alpha(kTrayBackgroundAlpha
);
661 void TrayBackgroundView::UpdateBubbleViewArrow(
662 views::TrayBubbleView
* bubble_view
) {
663 // Nothing to do here.