OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "ash/system/tray/tray_background_view.h" | |
6 | |
7 #include "ash/common/material_design/material_design_controller.h" | |
8 #include "ash/common/shelf/shelf_constants.h" | |
9 #include "ash/common/shelf/wm_shelf.h" | |
10 #include "ash/common/shelf/wm_shelf_util.h" | |
11 #include "ash/common/shell_window_ids.h" | |
12 #include "ash/common/system/tray/tray_constants.h" | |
13 #include "ash/screen_util.h" | |
14 #include "ash/shell.h" | |
15 #include "ash/system/status_area_widget.h" | |
16 #include "ash/system/status_area_widget_delegate.h" | |
17 #include "ash/system/tray/system_tray.h" | |
18 #include "ash/system/tray/tray_event_filter.h" | |
19 #include "ash/wm/window_animations.h" | |
20 #include "base/command_line.h" | |
21 #include "grit/ash_resources.h" | |
22 #include "ui/accessibility/ax_view_state.h" | |
23 #include "ui/aura/window.h" | |
24 #include "ui/aura/window_event_dispatcher.h" | |
25 #include "ui/base/nine_image_painter_factory.h" | |
26 #include "ui/base/ui_base_switches_util.h" | |
27 #include "ui/compositor/layer.h" | |
28 #include "ui/compositor/layer_animation_element.h" | |
29 #include "ui/compositor/scoped_layer_animation_settings.h" | |
30 #include "ui/events/event_constants.h" | |
31 #include "ui/gfx/animation/tween.h" | |
32 #include "ui/gfx/canvas.h" | |
33 #include "ui/gfx/geometry/rect.h" | |
34 #include "ui/gfx/image/image_skia.h" | |
35 #include "ui/gfx/image/image_skia_operations.h" | |
36 #include "ui/gfx/nine_image_painter.h" | |
37 #include "ui/gfx/skia_util.h" | |
38 #include "ui/gfx/transform.h" | |
39 #include "ui/views/background.h" | |
40 #include "ui/views/layout/box_layout.h" | |
41 #include "ui/wm/core/window_animations.h" | |
42 | |
43 namespace { | |
44 | |
45 const int kAnimationDurationForPopupMs = 200; | |
46 | |
47 // Duration of opacity animation for visibility changes. | |
48 const int kAnimationDurationForVisibilityMs = 250; | |
49 | |
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; | |
54 | |
55 } // namespace | |
56 | |
57 using views::TrayBubbleView; | |
58 | |
59 namespace ash { | |
60 | |
61 // static | |
62 const char TrayBackgroundView::kViewClassName[] = "tray/TrayBackgroundView"; | |
63 | |
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 { | |
67 public: | |
68 explicit TrayWidgetObserver(TrayBackgroundView* host) | |
69 : host_(host) { | |
70 } | |
71 | |
72 void OnWidgetBoundsChanged(views::Widget* widget, | |
73 const gfx::Rect& new_bounds) override { | |
74 host_->AnchorUpdated(); | |
75 } | |
76 | |
77 void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override { | |
78 host_->AnchorUpdated(); | |
79 } | |
80 | |
81 private: | |
82 TrayBackgroundView* host_; | |
83 | |
84 DISALLOW_COPY_AND_ASSIGN(TrayWidgetObserver); | |
85 }; | |
86 | |
87 class TrayBackground : public views::Background { | |
88 public: | |
89 const static int kImageTypeDefault = 0; | |
90 const static int kImageTypeOnBlack = 1; | |
91 const static int kImageTypePressed = 2; | |
92 const static int kNumStates = 3; | |
93 | |
94 const static int kImageHorizontal = 0; | |
95 const static int kImageVertical = 1; | |
96 const static int kNumOrientations = 2; | |
97 | |
98 explicit TrayBackground(TrayBackgroundView* tray_background_view) : | |
99 tray_background_view_(tray_background_view) { | |
100 } | |
101 | |
102 ~TrayBackground() override {} | |
103 | |
104 private: | |
105 WmShelf* GetShelf() const { | |
106 return tray_background_view_->GetShelf(); | |
107 } | |
108 | |
109 void PaintMaterial(gfx::Canvas* canvas, views::View* view) const { | |
110 SkColor background_color = SK_ColorTRANSPARENT; | |
111 if (GetShelf()->GetBackgroundType() == | |
112 ShelfBackgroundType::SHELF_BACKGROUND_DEFAULT) { | |
113 background_color = SkColorSetA(kShelfBaseColor, | |
114 GetShelfConstant(SHELF_BACKGROUND_ALPHA)); | |
115 } | |
116 | |
117 // TODO(bruthig|tdanderson): The background should be changed using a | |
118 // fade in/out animation. | |
119 const int kCornerRadius = 2; | |
120 | |
121 SkPaint background_paint; | |
122 background_paint.setFlags(SkPaint::kAntiAlias_Flag); | |
123 background_paint.setColor(background_color); | |
124 canvas->DrawRoundRect(view->GetLocalBounds(), kCornerRadius, | |
125 background_paint); | |
126 | |
127 if (tray_background_view_->draw_background_as_active()) { | |
128 SkPaint highlight_paint; | |
129 highlight_paint.setFlags(SkPaint::kAntiAlias_Flag); | |
130 highlight_paint.setColor(kShelfButtonActivatedHighlightColor); | |
131 canvas->DrawRoundRect(view->GetLocalBounds(), kCornerRadius, | |
132 highlight_paint); | |
133 } | |
134 } | |
135 | |
136 void PaintNonMaterial(gfx::Canvas* canvas, views::View* view) const { | |
137 const int kGridSizeForPainter = 9; | |
138 const int kImages[kNumOrientations][kNumStates][kGridSizeForPainter] = { | |
139 { // Horizontal | |
140 IMAGE_GRID_HORIZONTAL(IDR_AURA_TRAY_BG_HORIZ), | |
141 IMAGE_GRID_HORIZONTAL(IDR_AURA_TRAY_BG_HORIZ_ONBLACK), | |
142 IMAGE_GRID_HORIZONTAL(IDR_AURA_TRAY_BG_HORIZ_PRESSED), | |
143 }, | |
144 { // Vertical | |
145 IMAGE_GRID_VERTICAL(IDR_AURA_TRAY_BG_VERTICAL), | |
146 IMAGE_GRID_VERTICAL(IDR_AURA_TRAY_BG_VERTICAL_ONBLACK), | |
147 IMAGE_GRID_VERTICAL(IDR_AURA_TRAY_BG_VERTICAL_PRESSED), | |
148 } | |
149 }; | |
150 | |
151 WmShelf* shelf = GetShelf(); | |
152 const int orientation = IsHorizontalAlignment(shelf->GetAlignment()) | |
153 ? kImageHorizontal | |
154 : kImageVertical; | |
155 | |
156 int state = kImageTypeDefault; | |
157 if (tray_background_view_->draw_background_as_active()) | |
158 state = kImageTypePressed; | |
159 else if (shelf->IsDimmed()) | |
160 state = kImageTypeOnBlack; | |
161 else | |
162 state = kImageTypeDefault; | |
163 | |
164 ui::CreateNineImagePainter(kImages[orientation][state]) | |
165 ->Paint(canvas, view->GetLocalBounds()); | |
166 } | |
167 | |
168 // Overridden from views::Background. | |
169 void Paint(gfx::Canvas* canvas, views::View* view) const override { | |
170 if (MaterialDesignController::IsShelfMaterial()) | |
171 PaintMaterial(canvas, view); | |
172 else | |
173 PaintNonMaterial(canvas, view); | |
174 } | |
175 | |
176 // Reference to the TrayBackgroundView for which this is a background. | |
177 TrayBackgroundView* tray_background_view_; | |
178 | |
179 DISALLOW_COPY_AND_ASSIGN(TrayBackground); | |
180 }; | |
181 | |
182 TrayBackgroundView::TrayContainer::TrayContainer(ShelfAlignment alignment) | |
183 : alignment_(alignment) { | |
184 UpdateLayout(); | |
185 } | |
186 | |
187 void TrayBackgroundView::TrayContainer::SetAlignment(ShelfAlignment alignment) { | |
188 if (alignment_ == alignment) | |
189 return; | |
190 alignment_ = alignment; | |
191 UpdateLayout(); | |
192 } | |
193 | |
194 gfx::Size TrayBackgroundView::TrayContainer::GetPreferredSize() const { | |
195 if (size_.IsEmpty()) | |
196 return views::View::GetPreferredSize(); | |
197 return size_; | |
198 } | |
199 | |
200 void TrayBackgroundView::TrayContainer::ChildPreferredSizeChanged( | |
201 views::View* child) { | |
202 PreferredSizeChanged(); | |
203 } | |
204 | |
205 void TrayBackgroundView::TrayContainer::ChildVisibilityChanged(View* child) { | |
206 PreferredSizeChanged(); | |
207 } | |
208 | |
209 void TrayBackgroundView::TrayContainer::ViewHierarchyChanged( | |
210 const ViewHierarchyChangedDetails& details) { | |
211 if (details.parent == this) | |
212 PreferredSizeChanged(); | |
213 } | |
214 | |
215 // TODO(tdanderson): Adjust TrayContainer borders according to the material | |
216 // design specs. See crbug.com/617295. | |
217 void TrayBackgroundView::TrayContainer::UpdateLayout() { | |
218 // Adjust the size of status tray dark background by adding additional | |
219 // empty border. | |
220 views::BoxLayout::Orientation orientation = | |
221 IsHorizontalAlignment(alignment_) ? views::BoxLayout::kHorizontal | |
222 : views::BoxLayout::kVertical; | |
223 SetBorder(views::Border::CreateEmptyBorder( | |
224 kAdjustBackgroundPadding, kAdjustBackgroundPadding, | |
225 kAdjustBackgroundPadding, kAdjustBackgroundPadding)); | |
226 | |
227 views::BoxLayout* layout = new views::BoxLayout(orientation, 0, 0, 0); | |
228 layout->SetDefaultFlex(1); | |
229 views::View::SetLayoutManager(layout); | |
230 PreferredSizeChanged(); | |
231 } | |
232 | |
233 //////////////////////////////////////////////////////////////////////////////// | |
234 // TrayBackgroundView | |
235 | |
236 TrayBackgroundView::TrayBackgroundView(StatusAreaWidget* status_area_widget) | |
237 : status_area_widget_(status_area_widget), | |
238 tray_container_(NULL), | |
239 shelf_alignment_(SHELF_ALIGNMENT_BOTTOM), | |
240 background_(NULL), | |
241 draw_background_as_active_(false), | |
242 widget_observer_(new TrayWidgetObserver(this)) { | |
243 DCHECK(status_area_widget->wm_shelf()); | |
244 set_notify_enter_exit_on_child(true); | |
245 | |
246 tray_container_ = new TrayContainer(shelf_alignment_); | |
247 SetContents(tray_container_); | |
248 tray_event_filter_.reset(new TrayEventFilter); | |
249 | |
250 SetPaintToLayer(true); | |
251 layer()->SetFillsBoundsOpaquely(false); | |
252 // Start the tray items not visible, because visibility changes are animated. | |
253 views::View::SetVisible(false); | |
254 } | |
255 | |
256 TrayBackgroundView::~TrayBackgroundView() { | |
257 if (GetWidget()) | |
258 GetWidget()->RemoveObserver(widget_observer_.get()); | |
259 StopObservingImplicitAnimations(); | |
260 } | |
261 | |
262 void TrayBackgroundView::Initialize() { | |
263 GetWidget()->AddObserver(widget_observer_.get()); | |
264 } | |
265 | |
266 // static | |
267 void TrayBackgroundView::InitializeBubbleAnimations( | |
268 views::Widget* bubble_widget) { | |
269 aura::Window* window = bubble_widget->GetNativeWindow(); | |
270 ::wm::SetWindowVisibilityAnimationType( | |
271 window, ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); | |
272 ::wm::SetWindowVisibilityAnimationTransition(window, ::wm::ANIMATE_HIDE); | |
273 ::wm::SetWindowVisibilityAnimationDuration( | |
274 window, base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMs)); | |
275 } | |
276 | |
277 void TrayBackgroundView::SetVisible(bool visible) { | |
278 if (visible == layer()->GetTargetVisibility()) | |
279 return; | |
280 | |
281 if (visible) { | |
282 // The alignment of the shelf can change while the TrayBackgroundView is | |
283 // hidden. Reset the offscreen transform so that the animation to becoming | |
284 // visible reflects the current layout. | |
285 HideTransformation(); | |
286 // SetVisible(false) is defered until the animation for hiding is done. | |
287 // Otherwise the view is immediately hidden and the animation does not | |
288 // render. | |
289 views::View::SetVisible(true); | |
290 // If SetVisible(true) is called while animating to not visible, then | |
291 // views::View::SetVisible(true) is a no-op. When the previous animation | |
292 // ends layer->SetVisible(false) is called. To prevent this | |
293 // layer->SetVisible(true) immediately interrupts the animation of this | |
294 // property, and keeps the layer visible. | |
295 layer()->SetVisible(true); | |
296 } | |
297 | |
298 ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator()); | |
299 animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds( | |
300 kAnimationDurationForVisibilityMs)); | |
301 animation.SetPreemptionStrategy( | |
302 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
303 | |
304 if (visible) { | |
305 animation.SetTweenType(gfx::Tween::EASE_OUT); | |
306 // Show is delayed so as to allow time for other children of | |
307 // StatusAreaWidget to begin animating to their new positions. | |
308 layer()->GetAnimator()->SchedulePauseForProperties( | |
309 base::TimeDelta::FromMilliseconds(kShowAnimationDelayMs), | |
310 ui::LayerAnimationElement::OPACITY | | |
311 ui::LayerAnimationElement::TRANSFORM); | |
312 layer()->SetOpacity(1.0f); | |
313 gfx::Transform transform; | |
314 transform.Translate(0.0f, 0.0f); | |
315 layer()->SetTransform(transform); | |
316 } else { | |
317 // Listen only to the hide animation. As we cannot turn off visibility | |
318 // until the animation is over. | |
319 animation.AddObserver(this); | |
320 animation.SetTweenType(gfx::Tween::EASE_IN); | |
321 layer()->SetOpacity(0.0f); | |
322 layer()->SetVisible(false); | |
323 HideTransformation(); | |
324 } | |
325 } | |
326 | |
327 const char* TrayBackgroundView::GetClassName() const { | |
328 return kViewClassName; | |
329 } | |
330 | |
331 void TrayBackgroundView::ChildPreferredSizeChanged(views::View* child) { | |
332 PreferredSizeChanged(); | |
333 } | |
334 | |
335 void TrayBackgroundView::GetAccessibleState(ui::AXViewState* state) { | |
336 ActionableView::GetAccessibleState(state); | |
337 state->name = GetAccessibleNameForTray(); | |
338 } | |
339 | |
340 void TrayBackgroundView::AboutToRequestFocusFromTabTraversal(bool reverse) { | |
341 // Return focus to the login view. See crbug.com/120500. | |
342 views::View* v = GetNextFocusableView(); | |
343 if (v) | |
344 v->AboutToRequestFocusFromTabTraversal(reverse); | |
345 } | |
346 | |
347 bool TrayBackgroundView::PerformAction(const ui::Event& event) { | |
348 return false; | |
349 } | |
350 | |
351 gfx::Rect TrayBackgroundView::GetFocusBounds() { | |
352 // The tray itself expands to the right and bottom edge of the screen to make | |
353 // sure clicking on the edges brings up the popup. However, the focus border | |
354 // should be only around the container. | |
355 return GetContentsBounds(); | |
356 } | |
357 | |
358 void TrayBackgroundView::OnGestureEvent(ui::GestureEvent* event) { | |
359 if (switches::IsTouchFeedbackEnabled()) { | |
360 if (event->type() == ui::ET_GESTURE_TAP_DOWN) { | |
361 SetDrawBackgroundAsActive(true); | |
362 } else if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN || | |
363 event->type() == ui::ET_GESTURE_TAP_CANCEL) { | |
364 SetDrawBackgroundAsActive(false); | |
365 } | |
366 } | |
367 ActionableView::OnGestureEvent(event); | |
368 } | |
369 | |
370 void TrayBackgroundView::UpdateBackground(int alpha) { | |
371 // The animator should never fire when the alternate shelf layout is used. | |
372 if (!background_ || draw_background_as_active_) | |
373 return; | |
374 SchedulePaint(); | |
375 } | |
376 | |
377 void TrayBackgroundView::SetContents(views::View* contents) { | |
378 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); | |
379 AddChildView(contents); | |
380 } | |
381 void TrayBackgroundView::SetContentsBackground() { | |
382 background_ = new TrayBackground(this); | |
383 tray_container_->set_background(background_); | |
384 } | |
385 | |
386 WmShelf* TrayBackgroundView::GetShelf() { | |
387 return status_area_widget_->wm_shelf(); | |
388 } | |
389 | |
390 void TrayBackgroundView::SetShelfAlignment(ShelfAlignment alignment) { | |
391 shelf_alignment_ = alignment; | |
392 tray_container_->SetAlignment(alignment); | |
393 } | |
394 | |
395 void TrayBackgroundView::OnImplicitAnimationsCompleted() { | |
396 // If there is another animation in the queue, the reverse animation was | |
397 // triggered before the completion of animating to invisible. Do not turn off | |
398 // the visibility so that the next animation may render. The value of | |
399 // layer()->GetTargetVisibility() can be incorrect if the hide animation was | |
400 // aborted to schedule an animation to become visible. As the new animation | |
401 // is not yet added to the queue. crbug.com/374236 | |
402 if(layer()->GetAnimator()->is_animating() || | |
403 layer()->GetTargetVisibility()) | |
404 return; | |
405 views::View::SetVisible(false); | |
406 } | |
407 | |
408 bool TrayBackgroundView::RequiresNotificationWhenAnimatorDestroyed() const { | |
409 // This is needed so that OnImplicitAnimationsCompleted() is called even upon | |
410 // destruction of the animator. This can occure when parallel animations | |
411 // caused by ScreenRotationAnimator end before the animations of | |
412 // TrayBackgroundView. This allows for a proper update to the visual state of | |
413 // the view. (crbug.com/476667) | |
414 return true; | |
415 } | |
416 | |
417 void TrayBackgroundView::HideTransformation() { | |
418 gfx::Transform transform; | |
419 if (IsHorizontalAlignment(shelf_alignment_)) | |
420 transform.Translate(width(), 0.0f); | |
421 else | |
422 transform.Translate(0.0f, height()); | |
423 layer()->SetTransform(transform); | |
424 } | |
425 | |
426 gfx::Rect TrayBackgroundView::GetBubbleAnchorRect( | |
427 views::Widget* anchor_widget, | |
428 TrayBubbleView::AnchorType anchor_type, | |
429 TrayBubbleView::AnchorAlignment anchor_alignment) const { | |
430 gfx::Rect rect; | |
431 if (anchor_widget && anchor_widget->IsVisible()) { | |
432 rect = anchor_widget->GetWindowBoundsInScreen(); | |
433 if (anchor_type == TrayBubbleView::ANCHOR_TYPE_TRAY) { | |
434 if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM) { | |
435 bool rtl = base::i18n::IsRTL(); | |
436 rect.Inset( | |
437 rtl ? kBubblePaddingHorizontalSide : 0, | |
438 kBubblePaddingHorizontalBottom, | |
439 rtl ? 0 : kBubblePaddingHorizontalSide, | |
440 0); | |
441 } else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_LEFT) { | |
442 rect.Inset(0, 0, kBubblePaddingVerticalSide + 4, | |
443 kBubblePaddingVerticalBottom); | |
444 } else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT) { | |
445 rect.Inset(kBubblePaddingVerticalSide, 0, 0, | |
446 kBubblePaddingVerticalBottom); | |
447 } else { | |
448 // TODO(bruthig) May need to handle other ANCHOR_ALIGNMENT_ values. | |
449 // ie. ANCHOR_ALIGNMENT_TOP | |
450 DCHECK(false) << "Unhandled anchor alignment."; | |
451 } | |
452 } else if (anchor_type == TrayBubbleView::ANCHOR_TYPE_BUBBLE) { | |
453 // Invert the offsets to align with the bubble below. | |
454 // Note that with the alternate shelf layout the tips are not shown and | |
455 // the offsets for left and right alignment do not need to be applied. | |
456 int vertical_alignment = 0; | |
457 int horizontal_alignment = kBubblePaddingVerticalBottom; | |
458 if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_LEFT) | |
459 rect.Inset(vertical_alignment, 0, 0, horizontal_alignment); | |
460 else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT) | |
461 rect.Inset(0, 0, vertical_alignment, horizontal_alignment); | |
462 } else { | |
463 DCHECK(false) << "Unhandled anchor type."; | |
464 } | |
465 } else { | |
466 aura::Window* target_root = anchor_widget ? | |
467 anchor_widget->GetNativeView()->GetRootWindow() : | |
468 Shell::GetPrimaryRootWindow(); | |
469 rect = target_root->bounds(); | |
470 if (anchor_type == TrayBubbleView::ANCHOR_TYPE_TRAY) { | |
471 if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM) { | |
472 rect = gfx::Rect( | |
473 base::i18n::IsRTL() ? | |
474 kPaddingFromRightEdgeOfScreenBottomAlignment : | |
475 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment, | |
476 rect.height() - kPaddingFromBottomOfScreenBottomAlignment, | |
477 0, 0); | |
478 rect = ScreenUtil::ConvertRectToScreen(target_root, rect); | |
479 } else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_LEFT) { | |
480 rect = gfx::Rect( | |
481 kPaddingFromRightEdgeOfScreenBottomAlignment, | |
482 rect.height() - kPaddingFromBottomOfScreenBottomAlignment, | |
483 1, 1); | |
484 rect = ScreenUtil::ConvertRectToScreen(target_root, rect); | |
485 } else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT) { | |
486 rect = gfx::Rect( | |
487 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment, | |
488 rect.height() - kPaddingFromBottomOfScreenBottomAlignment, | |
489 1, 1); | |
490 rect = ScreenUtil::ConvertRectToScreen(target_root, rect); | |
491 } else { | |
492 // TODO(bruthig) May need to handle other ANCHOR_ALIGNMENT_ values. | |
493 // ie. ANCHOR_ALIGNMENT_TOP | |
494 DCHECK(false) << "Unhandled anchor alignment."; | |
495 } | |
496 } else { | |
497 rect = gfx::Rect( | |
498 base::i18n::IsRTL() ? | |
499 kPaddingFromRightEdgeOfScreenBottomAlignment : | |
500 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment, | |
501 rect.height() - kPaddingFromBottomOfScreenBottomAlignment, | |
502 0, 0); | |
503 } | |
504 } | |
505 return rect; | |
506 } | |
507 | |
508 TrayBubbleView::AnchorAlignment TrayBackgroundView::GetAnchorAlignment() const { | |
509 if (shelf_alignment_ == SHELF_ALIGNMENT_LEFT) | |
510 return TrayBubbleView::ANCHOR_ALIGNMENT_LEFT; | |
511 if (shelf_alignment_ == SHELF_ALIGNMENT_RIGHT) | |
512 return TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT; | |
513 return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM; | |
514 } | |
515 | |
516 void TrayBackgroundView::SetDrawBackgroundAsActive(bool visible) { | |
517 if (draw_background_as_active_ == visible) | |
518 return; | |
519 draw_background_as_active_ = visible; | |
520 if (!background_) | |
521 return; | |
522 SchedulePaint(); | |
523 } | |
524 | |
525 void TrayBackgroundView::UpdateBubbleViewArrow( | |
526 views::TrayBubbleView* bubble_view) { | |
527 // Nothing to do here. | |
528 } | |
529 | |
530 } // namespace ash | |
OLD | NEW |