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