1 // Copyright 2013 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 "chrome/browser/chromeos/ui/focus_ring_layer.h"
8 #include "ui/aura/window.h"
9 #include "ui/compositor/layer.h"
10 #include "ui/gfx/canvas.h"
16 const int kShadowRadius
= 10;
17 const int kShadowAlpha
= 90;
18 const SkColor kShadowColor
= SkColorSetRGB(77, 144, 254);
22 FocusRingLayerDelegate::~FocusRingLayerDelegate() {}
24 FocusRingLayer::FocusRingLayer(FocusRingLayerDelegate
* delegate
)
25 : delegate_(delegate
),
29 FocusRingLayer::~FocusRingLayer() {}
31 void FocusRingLayer::Set(aura::Window
* root_window
, const gfx::Rect
& bounds
) {
33 CreateOrUpdateLayer(root_window
, "FocusRing");
35 // Update the layer bounds.
36 gfx::Rect layer_bounds
= bounds
;
37 int inset
= -(kShadowRadius
+ 2);
38 layer_bounds
.Inset(inset
, inset
, inset
, inset
);
39 layer_
->SetBounds(layer_bounds
);
42 void FocusRingLayer::CreateOrUpdateLayer(
43 aura::Window
* root_window
, const char* layer_name
) {
44 if (!layer_
|| root_window
!= root_window_
) {
45 root_window_
= root_window
;
46 ui::Layer
* root_layer
= root_window
->layer();
47 layer_
.reset(new ui::Layer(ui::LAYER_TEXTURED
));
48 layer_
->set_name(layer_name
);
49 layer_
->set_delegate(this);
50 layer_
->SetFillsBoundsOpaquely(false);
51 root_layer
->Add(layer_
.get());
54 // Keep moving it to the top in case new layers have been added
55 // since we created this layer.
56 layer_
->parent()->StackAtTop(layer_
.get());
59 void FocusRingLayer::OnPaintLayer(gfx::Canvas
* canvas
) {
60 if (!root_window_
|| focus_ring_
.IsEmpty())
63 gfx::Rect bounds
= focus_ring_
- layer_
->bounds().OffsetFromOrigin();
65 paint
.setColor(kShadowColor
);
66 paint
.setFlags(SkPaint::kAntiAlias_Flag
);
67 paint
.setStyle(SkPaint::kStroke_Style
);
68 paint
.setStrokeWidth(2);
69 int r
= kShadowRadius
;
70 for (int i
= 0; i
< r
; i
++) {
71 // Fade out alpha quadratically.
72 paint
.setAlpha((kShadowAlpha
* (r
- i
) * (r
- i
)) / (r
* r
));
73 gfx::Rect outsetRect
= bounds
;
74 outsetRect
.Inset(-i
, -i
, -i
, -i
);
75 canvas
->DrawRect(outsetRect
, paint
);
79 void FocusRingLayer::OnDelegatedFrameDamage(
80 const gfx::Rect
& damage_rect_in_dip
) {
83 void FocusRingLayer::OnDeviceScaleFactorChanged(float device_scale_factor
) {
85 delegate_
->OnDeviceScaleFactorChanged();
88 base::Closure
FocusRingLayer::PrepareForLayerBoundsChange() {
89 return base::Bind(&base::DoNothing
);
92 } // namespace chromeos