Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: ash/common/system/tray/tray_background_view.cc

Issue 2734653002: chromeos: Move files in //ash/common to //ash (Closed)
Patch Set: fix a11y tests, fix docs Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 <algorithm>
8
9 #include "ash/common/ash_constants.h"
10 #include "ash/common/material_design/material_design_controller.h"
11 #include "ash/common/shelf/shelf_constants.h"
12 #include "ash/common/shelf/wm_shelf.h"
13 #include "ash/common/shelf/wm_shelf_util.h"
14 #include "ash/common/system/tray/system_tray.h"
15 #include "ash/common/system/tray/tray_constants.h"
16 #include "ash/common/system/tray/tray_event_filter.h"
17 #include "ash/common/wm_shell.h"
18 #include "ash/common/wm_window.h"
19 #include "ash/public/cpp/shell_window_ids.h"
20 #include "ash/resources/grit/ash_resources.h"
21 #include "base/memory/ptr_util.h"
22 #include "ui/accessibility/ax_node_data.h"
23 #include "ui/base/nine_image_painter_factory.h"
24 #include "ui/compositor/layer.h"
25 #include "ui/compositor/layer_animation_element.h"
26 #include "ui/compositor/scoped_layer_animation_settings.h"
27 #include "ui/events/event_constants.h"
28 #include "ui/gfx/animation/tween.h"
29 #include "ui/gfx/canvas.h"
30 #include "ui/gfx/geometry/rect.h"
31 #include "ui/gfx/geometry/size.h"
32 #include "ui/gfx/image/image_skia.h"
33 #include "ui/gfx/image/image_skia_operations.h"
34 #include "ui/gfx/nine_image_painter.h"
35 #include "ui/gfx/scoped_canvas.h"
36 #include "ui/gfx/skia_util.h"
37 #include "ui/gfx/transform.h"
38 #include "ui/views/animation/flood_fill_ink_drop_ripple.h"
39 #include "ui/views/animation/ink_drop_highlight.h"
40 #include "ui/views/animation/ink_drop_mask.h"
41 #include "ui/views/background.h"
42 #include "ui/views/layout/box_layout.h"
43 #include "ui/wm/core/window_animations.h"
44
45 namespace {
46
47 const int kAnimationDurationForPopupMs = 200;
48
49 // Duration of opacity animation for visibility changes.
50 const int kAnimationDurationForVisibilityMs = 250;
51
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;
56
57 // Additional padding used to adjust the user-visible size of status tray
58 // and overview button dark background.
59 const int kBackgroundAdjustPadding = 3;
60
61 // Switches left and right insets if RTL mode is active.
62 void MirrorInsetsIfNecessary(gfx::Insets* insets) {
63 if (base::i18n::IsRTL()) {
64 insets->Set(insets->top(), insets->right(), insets->bottom(),
65 insets->left());
66 }
67 }
68
69 // Returns background insets relative to the contents bounds of the view and
70 // mirrored if RTL mode is active.
71 gfx::Insets GetMirroredBackgroundInsets(ash::ShelfAlignment shelf_alignment) {
72 gfx::Insets insets;
73 if (IsHorizontalAlignment(shelf_alignment)) {
74 insets.Set(0, ash::kHitRegionPadding, 0,
75 ash::kHitRegionPadding + ash::kSeparatorWidth);
76 } else {
77 insets.Set(ash::kHitRegionPadding, 0,
78 ash::kHitRegionPadding + ash::kSeparatorWidth, 0);
79 }
80 MirrorInsetsIfNecessary(&insets);
81 return insets;
82 }
83
84 } // namespace
85
86 using views::TrayBubbleView;
87
88 namespace ash {
89
90 // static
91 const char TrayBackgroundView::kViewClassName[] = "tray/TrayBackgroundView";
92
93 // Used to track when the anchor widget changes position on screen so that the
94 // bubble position can be updated.
95 class TrayBackgroundView::TrayWidgetObserver : public views::WidgetObserver {
96 public:
97 explicit TrayWidgetObserver(TrayBackgroundView* host) : host_(host) {}
98
99 void OnWidgetBoundsChanged(views::Widget* widget,
100 const gfx::Rect& new_bounds) override {
101 host_->AnchorUpdated();
102 }
103
104 void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override {
105 host_->AnchorUpdated();
106 }
107
108 private:
109 TrayBackgroundView* host_;
110
111 DISALLOW_COPY_AND_ASSIGN(TrayWidgetObserver);
112 };
113
114 class TrayBackground : public views::Background {
115 public:
116 TrayBackground(TrayBackgroundView* tray_background_view, bool draws_active)
117 : tray_background_view_(tray_background_view),
118 draws_active_(draws_active),
119 color_(SK_ColorTRANSPARENT) {}
120
121 ~TrayBackground() override {}
122
123 void set_color(SkColor color) { color_ = color; }
124
125 private:
126 WmShelf* GetShelf() const { return tray_background_view_->shelf(); }
127
128 void PaintMaterial(gfx::Canvas* canvas, views::View* view) const {
129 cc::PaintFlags background_flags;
130 background_flags.setAntiAlias(true);
131 background_flags.setColor(color_);
132 gfx::Insets insets =
133 GetMirroredBackgroundInsets(GetShelf()->GetAlignment());
134 gfx::Rect bounds = view->GetLocalBounds();
135 bounds.Inset(insets);
136 canvas->DrawRoundRect(bounds, kTrayRoundedBorderRadius, background_flags);
137
138 if (draws_active_ && tray_background_view_->is_active()) {
139 cc::PaintFlags highlight_flags;
140 highlight_flags.setAntiAlias(true);
141 highlight_flags.setColor(kShelfButtonActivatedHighlightColor);
142 canvas->DrawRoundRect(bounds, kTrayRoundedBorderRadius, highlight_flags);
143 }
144 }
145
146 void PaintNonMaterial(gfx::Canvas* canvas, views::View* view) const {
147 const static int kImageTypeDefault = 0;
148 // TODO(estade): leftover type which should be removed along with the rest
149 // of pre-MD code.
150 // const static int kImageTypeOnBlack = 1;
151 const static int kImageTypePressed = 2;
152 const static int kNumStates = 3;
153
154 const static int kImageHorizontal = 0;
155 const static int kImageVertical = 1;
156 const static int kNumOrientations = 2;
157
158 const int kGridSizeForPainter = 9;
159
160 const int kImages[kNumOrientations][kNumStates][kGridSizeForPainter] = {
161 {
162 // Horizontal
163 IMAGE_GRID_HORIZONTAL(IDR_AURA_TRAY_BG_HORIZ),
164 IMAGE_GRID_HORIZONTAL(IDR_AURA_TRAY_BG_HORIZ_ONBLACK),
165 IMAGE_GRID_HORIZONTAL(IDR_AURA_TRAY_BG_HORIZ_PRESSED),
166 },
167 {
168 // Vertical
169 IMAGE_GRID_VERTICAL(IDR_AURA_TRAY_BG_VERTICAL),
170 IMAGE_GRID_VERTICAL(IDR_AURA_TRAY_BG_VERTICAL_ONBLACK),
171 IMAGE_GRID_VERTICAL(IDR_AURA_TRAY_BG_VERTICAL_PRESSED),
172 }};
173
174 WmShelf* shelf = GetShelf();
175 const int orientation = IsHorizontalAlignment(shelf->GetAlignment())
176 ? kImageHorizontal
177 : kImageVertical;
178
179 int state = kImageTypeDefault;
180 if (draws_active_ && tray_background_view_->is_active())
181 state = kImageTypePressed;
182 else
183 state = kImageTypeDefault;
184
185 ui::CreateNineImagePainter(kImages[orientation][state])
186 ->Paint(canvas, view->GetLocalBounds());
187 }
188
189 // Overridden from views::Background.
190 void Paint(gfx::Canvas* canvas, views::View* view) const override {
191 if (MaterialDesignController::IsShelfMaterial())
192 PaintMaterial(canvas, view);
193 else
194 PaintNonMaterial(canvas, view);
195 }
196
197 // Reference to the TrayBackgroundView for which this is a background.
198 TrayBackgroundView* tray_background_view_;
199
200 // Determines whether we should draw an active background for the view when it
201 // is active. This is used in non-MD mode. In material design mode, an active
202 // ink drop ripple would indicate if the view is active or not.
203 // TODO(mohsen): This is used only in non-MD version. Remove when non-MD code
204 // is removed (see https://crbug.com/614453).
205 bool draws_active_;
206
207 SkColor color_;
208
209 DISALLOW_COPY_AND_ASSIGN(TrayBackground);
210 };
211
212 TrayBackgroundView::TrayContainer::TrayContainer(ShelfAlignment alignment)
213 : alignment_(alignment) {
214 UpdateLayout();
215 }
216
217 void TrayBackgroundView::TrayContainer::SetAlignment(ShelfAlignment alignment) {
218 if (alignment_ == alignment)
219 return;
220 alignment_ = alignment;
221 UpdateLayout();
222 }
223
224 void TrayBackgroundView::TrayContainer::SetMargin(int main_axis_margin,
225 int cross_axis_margin) {
226 main_axis_margin_ = main_axis_margin;
227 cross_axis_margin_ = cross_axis_margin;
228 UpdateLayout();
229 }
230
231 void TrayBackgroundView::TrayContainer::ChildPreferredSizeChanged(
232 views::View* child) {
233 PreferredSizeChanged();
234 }
235
236 void TrayBackgroundView::TrayContainer::ChildVisibilityChanged(View* child) {
237 PreferredSizeChanged();
238 }
239
240 void TrayBackgroundView::TrayContainer::ViewHierarchyChanged(
241 const ViewHierarchyChangedDetails& details) {
242 if (details.parent == this)
243 PreferredSizeChanged();
244 }
245
246 void TrayBackgroundView::TrayContainer::UpdateLayout() {
247 bool is_horizontal = IsHorizontalAlignment(alignment_);
248
249 // Adjust the size of status tray dark background by adding additional
250 // empty border.
251 views::BoxLayout::Orientation orientation =
252 is_horizontal ? views::BoxLayout::kHorizontal
253 : views::BoxLayout::kVertical;
254
255 if (ash::MaterialDesignController::IsShelfMaterial()) {
256 const int hit_region_with_separator = kHitRegionPadding + kSeparatorWidth;
257 gfx::Insets insets(
258 is_horizontal
259 ? gfx::Insets(0, kHitRegionPadding, 0, hit_region_with_separator)
260 : gfx::Insets(kHitRegionPadding, 0, hit_region_with_separator, 0));
261 MirrorInsetsIfNecessary(&insets);
262 SetBorder(views::CreateEmptyBorder(insets));
263 } else {
264 SetBorder(views::CreateEmptyBorder(gfx::Insets(kBackgroundAdjustPadding)));
265 }
266
267 int horizontal_margin = main_axis_margin_;
268 int vertical_margin = cross_axis_margin_;
269 if (!is_horizontal)
270 std::swap(horizontal_margin, vertical_margin);
271 views::BoxLayout* layout =
272 new views::BoxLayout(orientation, horizontal_margin, vertical_margin, 0);
273
274 if (!ash::MaterialDesignController::IsShelfMaterial())
275 layout->SetDefaultFlex(1);
276 layout->set_minimum_cross_axis_size(kTrayItemSize);
277 views::View::SetLayoutManager(layout);
278
279 PreferredSizeChanged();
280 }
281
282 ////////////////////////////////////////////////////////////////////////////////
283 // TrayBackgroundView
284
285 TrayBackgroundView::TrayBackgroundView(WmShelf* wm_shelf)
286 // Note the ink drop style is ignored.
287 : ActionableView(nullptr, TrayPopupInkDropStyle::FILL_BOUNDS),
288 wm_shelf_(wm_shelf),
289 tray_container_(NULL),
290 shelf_alignment_(SHELF_ALIGNMENT_BOTTOM),
291 background_(NULL),
292 is_active_(false),
293 separator_visible_(true),
294 widget_observer_(new TrayWidgetObserver(this)) {
295 DCHECK(wm_shelf_);
296 set_notify_enter_exit_on_child(true);
297 set_ink_drop_base_color(kShelfInkDropBaseColor);
298 set_ink_drop_visible_opacity(kShelfInkDropVisibleOpacity);
299
300 tray_container_ = new TrayContainer(shelf_alignment_);
301 SetContents(tray_container_);
302 tray_event_filter_.reset(new TrayEventFilter);
303
304 SetPaintToLayer();
305 layer()->SetFillsBoundsOpaquely(false);
306 // Start the tray items not visible, because visibility changes are animated.
307 views::View::SetVisible(false);
308 }
309
310 TrayBackgroundView::~TrayBackgroundView() {
311 if (GetWidget())
312 GetWidget()->RemoveObserver(widget_observer_.get());
313 StopObservingImplicitAnimations();
314 }
315
316 void TrayBackgroundView::Initialize() {
317 GetWidget()->AddObserver(widget_observer_.get());
318 }
319
320 // static
321 void TrayBackgroundView::InitializeBubbleAnimations(
322 views::Widget* bubble_widget) {
323 WmWindow* window = WmWindow::Get(bubble_widget->GetNativeWindow());
324 window->SetVisibilityAnimationType(
325 ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
326 window->SetVisibilityAnimationTransition(::wm::ANIMATE_HIDE);
327 window->SetVisibilityAnimationDuration(
328 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMs));
329 }
330
331 void TrayBackgroundView::SetVisible(bool visible) {
332 if (visible == layer()->GetTargetVisibility())
333 return;
334
335 if (visible) {
336 // The alignment of the shelf can change while the TrayBackgroundView is
337 // hidden. Reset the offscreen transform so that the animation to becoming
338 // visible reflects the current layout.
339 HideTransformation();
340 // SetVisible(false) is defered until the animation for hiding is done.
341 // Otherwise the view is immediately hidden and the animation does not
342 // render.
343 views::View::SetVisible(true);
344 // If SetVisible(true) is called while animating to not visible, then
345 // views::View::SetVisible(true) is a no-op. When the previous animation
346 // ends layer->SetVisible(false) is called. To prevent this
347 // layer->SetVisible(true) immediately interrupts the animation of this
348 // property, and keeps the layer visible.
349 layer()->SetVisible(true);
350 }
351
352 ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator());
353 animation.SetTransitionDuration(
354 base::TimeDelta::FromMilliseconds(kAnimationDurationForVisibilityMs));
355 animation.SetPreemptionStrategy(
356 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
357
358 if (visible) {
359 animation.SetTweenType(gfx::Tween::EASE_OUT);
360 // Show is delayed so as to allow time for other children of
361 // StatusAreaWidget to begin animating to their new positions.
362 layer()->GetAnimator()->SchedulePauseForProperties(
363 base::TimeDelta::FromMilliseconds(kShowAnimationDelayMs),
364 ui::LayerAnimationElement::OPACITY |
365 ui::LayerAnimationElement::TRANSFORM);
366 layer()->SetOpacity(1.0f);
367 gfx::Transform transform;
368 transform.Translate(0.0f, 0.0f);
369 layer()->SetTransform(transform);
370 } else {
371 // Listen only to the hide animation. As we cannot turn off visibility
372 // until the animation is over.
373 animation.AddObserver(this);
374 animation.SetTweenType(gfx::Tween::EASE_IN);
375 layer()->SetOpacity(0.0f);
376 layer()->SetVisible(false);
377 HideTransformation();
378 }
379 }
380
381 const char* TrayBackgroundView::GetClassName() const {
382 return kViewClassName;
383 }
384
385 void TrayBackgroundView::ChildPreferredSizeChanged(views::View* child) {
386 PreferredSizeChanged();
387 }
388
389 void TrayBackgroundView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
390 ActionableView::GetAccessibleNodeData(node_data);
391 node_data->SetName(GetAccessibleNameForTray());
392 }
393
394 void TrayBackgroundView::AboutToRequestFocusFromTabTraversal(bool reverse) {
395 // Return focus to the login view. See crbug.com/120500.
396 views::View* v = GetNextFocusableView();
397 if (v)
398 v->AboutToRequestFocusFromTabTraversal(reverse);
399 }
400
401 std::unique_ptr<views::InkDropRipple> TrayBackgroundView::CreateInkDropRipple()
402 const {
403 return base::MakeUnique<views::FloodFillInkDropRipple>(
404 size(), GetBackgroundInsets(), GetInkDropCenterBasedOnLastEvent(),
405 GetInkDropBaseColor(), ink_drop_visible_opacity());
406 }
407
408 std::unique_ptr<views::InkDropHighlight>
409 TrayBackgroundView::CreateInkDropHighlight() const {
410 gfx::Rect bounds = GetBackgroundBounds();
411 // Currently, we don't handle view resize. To compensate for that, enlarge the
412 // bounds by two tray icons so that the hightlight looks good even if two more
413 // icons are added when it is visible. Note that ink drop mask handles resize
414 // correctly, so the extra highlight would be clipped.
415 // TODO(mohsen): Remove this extra size when resize is handled properly (see
416 // https://crbug.com/669253).
417 const int icon_size = kTrayIconSize + 2 * kTrayImageItemPadding;
418 bounds.set_width(bounds.width() + 2 * icon_size);
419 bounds.set_height(bounds.height() + 2 * icon_size);
420 std::unique_ptr<views::InkDropHighlight> highlight(
421 new views::InkDropHighlight(bounds.size(), 0,
422 gfx::RectF(bounds).CenterPoint(),
423 GetInkDropBaseColor()));
424 highlight->set_visible_opacity(kTrayPopupInkDropHighlightOpacity);
425 return highlight;
426 }
427
428 void TrayBackgroundView::OnGestureEvent(ui::GestureEvent* event) {
429 // If there is no ink drop, show "touch feedback".
430 // TODO(mohsen): This is used only in non-MD version. Remove when non-MD code
431 // is removed (see https://crbug.com/614453).
432 if (ink_drop_mode() == InkDropMode::OFF) {
433 if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
434 SetIsActive(true);
435 } else if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN ||
436 event->type() == ui::ET_GESTURE_TAP_CANCEL) {
437 SetIsActive(false);
438 }
439 }
440 ActionableView::OnGestureEvent(event);
441 }
442
443 void TrayBackgroundView::SetContents(views::View* contents) {
444 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
445 AddChildView(contents);
446 }
447
448 void TrayBackgroundView::SetContentsBackground(bool draws_active) {
449 background_ = new TrayBackground(this, draws_active);
450 tray_container_->set_background(background_);
451 }
452
453 void TrayBackgroundView::SetShelfAlignment(ShelfAlignment alignment) {
454 shelf_alignment_ = alignment;
455 tray_container_->SetAlignment(alignment);
456 }
457
458 void TrayBackgroundView::OnImplicitAnimationsCompleted() {
459 // If there is another animation in the queue, the reverse animation was
460 // triggered before the completion of animating to invisible. Do not turn off
461 // the visibility so that the next animation may render. The value of
462 // layer()->GetTargetVisibility() can be incorrect if the hide animation was
463 // aborted to schedule an animation to become visible. As the new animation
464 // is not yet added to the queue. crbug.com/374236
465 if (layer()->GetAnimator()->is_animating() || layer()->GetTargetVisibility())
466 return;
467 views::View::SetVisible(false);
468 }
469
470 bool TrayBackgroundView::RequiresNotificationWhenAnimatorDestroyed() const {
471 // This is needed so that OnImplicitAnimationsCompleted() is called even upon
472 // destruction of the animator. This can occure when parallel animations
473 // caused by ScreenRotationAnimator end before the animations of
474 // TrayBackgroundView. This allows for a proper update to the visual state of
475 // the view. (crbug.com/476667)
476 return true;
477 }
478
479 void TrayBackgroundView::HideTransformation() {
480 gfx::Transform transform;
481 if (IsHorizontalAlignment(shelf_alignment_))
482 transform.Translate(width(), 0.0f);
483 else
484 transform.Translate(0.0f, height());
485 layer()->SetTransform(transform);
486 }
487
488 TrayBubbleView::AnchorAlignment TrayBackgroundView::GetAnchorAlignment() const {
489 if (shelf_alignment_ == SHELF_ALIGNMENT_LEFT)
490 return TrayBubbleView::ANCHOR_ALIGNMENT_LEFT;
491 if (shelf_alignment_ == SHELF_ALIGNMENT_RIGHT)
492 return TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT;
493 return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM;
494 }
495
496 void TrayBackgroundView::SetIsActive(bool is_active) {
497 if (is_active_ == is_active)
498 return;
499 is_active_ = is_active;
500 AnimateInkDrop(is_active_ ? views::InkDropState::ACTIVATED
501 : views::InkDropState::DEACTIVATED,
502 nullptr);
503 if (!background_)
504 return;
505 // TODO(mohsen): This is needed for non-MD version. Remove when non-MD code is
506 // removed (see https://crbug.com/614453).
507 SchedulePaint();
508 }
509
510 void TrayBackgroundView::UpdateBubbleViewArrow(
511 views::TrayBubbleView* bubble_view) {
512 // Nothing to do here.
513 }
514
515 void TrayBackgroundView::UpdateShelfItemBackground(SkColor color) {
516 if (background_) {
517 background_->set_color(color);
518 SchedulePaint();
519 }
520 }
521
522 views::View* TrayBackgroundView::GetBubbleAnchor() const {
523 return tray_container_;
524 }
525
526 gfx::Insets TrayBackgroundView::GetBubbleAnchorInsets() const {
527 gfx::Insets anchor_insets = GetBubbleAnchor()->GetInsets();
528 gfx::Insets tray_bg_insets = GetInsets();
529 if (GetAnchorAlignment() == TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM) {
530 return gfx::Insets(-tray_bg_insets.top(), anchor_insets.left(),
531 -tray_bg_insets.bottom(), anchor_insets.right());
532 } else {
533 return gfx::Insets(anchor_insets.top(), -tray_bg_insets.left(),
534 anchor_insets.bottom(), -tray_bg_insets.right());
535 }
536 }
537
538 std::unique_ptr<views::InkDropMask> TrayBackgroundView::CreateInkDropMask()
539 const {
540 return base::MakeUnique<views::RoundRectInkDropMask>(
541 size(), GetBackgroundInsets(), kTrayRoundedBorderRadius);
542 }
543
544 bool TrayBackgroundView::ShouldEnterPushedState(const ui::Event& event) {
545 if (is_active_)
546 return false;
547
548 return ActionableView::ShouldEnterPushedState(event);
549 }
550
551 bool TrayBackgroundView::PerformAction(const ui::Event& event) {
552 return false;
553 }
554
555 void TrayBackgroundView::HandlePerformActionResult(bool action_performed,
556 const ui::Event& event) {
557 // When an action is performed, ink drop ripple is handled in SetIsActive().
558 if (action_performed)
559 return;
560 ActionableView::HandlePerformActionResult(action_performed, event);
561 }
562
563 void TrayBackgroundView::OnPaintFocus(gfx::Canvas* canvas) {
564 // The tray itself expands to the right and bottom edge of the screen to make
565 // sure clicking on the edges brings up the popup. However, the focus border
566 // should be only around the container.
567 gfx::RectF paint_bounds;
568 paint_bounds = gfx::RectF(GetBackgroundBounds());
569 paint_bounds.Inset(gfx::Insets(-kFocusBorderThickness));
570 canvas->DrawSolidFocusRect(paint_bounds, kFocusBorderColor,
571 kFocusBorderThickness);
572 }
573
574 void TrayBackgroundView::OnPaint(gfx::Canvas* canvas) {
575 ActionableView::OnPaint(canvas);
576 if (shelf()->GetBackgroundType() ==
577 ShelfBackgroundType::SHELF_BACKGROUND_DEFAULT ||
578 !separator_visible_) {
579 return;
580 }
581 // In the given |canvas|, for a horizontal shelf draw a separator line to the
582 // right or left of the TrayBackgroundView when the system is LTR or RTL
583 // aligned, respectively. For a vertical shelf draw the separator line
584 // underneath the items instead.
585 const gfx::Rect local_bounds = GetLocalBounds();
586 const SkColor color = SkColorSetA(SK_ColorWHITE, 0x4D);
587
588 if (IsHorizontalAlignment(shelf_alignment_)) {
589 const gfx::PointF point(
590 base::i18n::IsRTL() ? 0 : (local_bounds.width() - kSeparatorWidth),
591 (GetShelfConstant(SHELF_SIZE) - kTrayItemSize) / 2);
592 const gfx::Vector2dF vector(0, kTrayItemSize);
593 canvas->Draw1pxLine(point, point + vector, color);
594 } else {
595 const gfx::PointF point((GetShelfConstant(SHELF_SIZE) - kTrayItemSize) / 2,
596 local_bounds.height() - kSeparatorWidth);
597 const gfx::Vector2dF vector(kTrayItemSize, 0);
598 canvas->Draw1pxLine(point, point + vector, color);
599 }
600 }
601
602 gfx::Insets TrayBackgroundView::GetBackgroundInsets() const {
603 gfx::Insets insets = GetMirroredBackgroundInsets(shelf_alignment_);
604
605 // |insets| are relative to contents bounds. Change them to be relative to
606 // local bounds.
607 gfx::Insets local_contents_insets =
608 GetLocalBounds().InsetsFrom(GetContentsBounds());
609 MirrorInsetsIfNecessary(&local_contents_insets);
610 insets += local_contents_insets;
611
612 return insets;
613 }
614
615 gfx::Rect TrayBackgroundView::GetBackgroundBounds() const {
616 gfx::Insets insets = GetBackgroundInsets();
617 gfx::Rect bounds = GetLocalBounds();
618 bounds.Inset(insets);
619 return bounds;
620 }
621
622 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/system/tray/tray_background_view.h ('k') | ash/common/system/tray/tray_bubble_wrapper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698