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/compositor/paint_recorder.h"
11 #include "ui/gfx/canvas.h"
17 const int kShadowRadius
= 10;
18 const int kShadowAlpha
= 90;
19 const SkColor kShadowColor
= SkColorSetRGB(77, 144, 254);
23 FocusRingLayerDelegate::~FocusRingLayerDelegate() {}
25 FocusRingLayer::FocusRingLayer(FocusRingLayerDelegate
* delegate
)
26 : delegate_(delegate
),
30 FocusRingLayer::~FocusRingLayer() {}
32 void FocusRingLayer::Set(aura::Window
* root_window
, const gfx::Rect
& bounds
) {
34 CreateOrUpdateLayer(root_window
, "FocusRing");
36 // Update the layer bounds.
37 gfx::Rect layer_bounds
= bounds
;
38 int inset
= -(kShadowRadius
+ 2);
39 layer_bounds
.Inset(inset
, inset
, inset
, inset
);
40 layer_
->SetBounds(layer_bounds
);
43 void FocusRingLayer::CreateOrUpdateLayer(
44 aura::Window
* root_window
, const char* layer_name
) {
45 if (!layer_
|| root_window
!= root_window_
) {
46 root_window_
= root_window
;
47 ui::Layer
* root_layer
= root_window
->layer();
48 layer_
.reset(new ui::Layer(ui::LAYER_TEXTURED
));
49 layer_
->set_name(layer_name
);
50 layer_
->set_delegate(this);
51 layer_
->SetFillsBoundsOpaquely(false);
52 root_layer
->Add(layer_
.get());
55 // Keep moving it to the top in case new layers have been added
56 // since we created this layer.
57 layer_
->parent()->StackAtTop(layer_
.get());
60 void FocusRingLayer::OnPaintLayer(const ui::PaintContext
& context
) {
61 if (!root_window_
|| focus_ring_
.IsEmpty())
64 ui::PaintRecorder
recorder(context
, layer_
->size());
67 paint
.setColor(kShadowColor
);
68 paint
.setFlags(SkPaint::kAntiAlias_Flag
);
69 paint
.setStyle(SkPaint::kStroke_Style
);
70 paint
.setStrokeWidth(2);
72 gfx::Rect bounds
= focus_ring_
- layer_
->bounds().OffsetFromOrigin();
73 int r
= kShadowRadius
;
74 for (int i
= 0; i
< r
; i
++) {
75 // Fade out alpha quadratically.
76 paint
.setAlpha((kShadowAlpha
* (r
- i
) * (r
- i
)) / (r
* r
));
77 gfx::Rect outsetRect
= bounds
;
78 outsetRect
.Inset(-i
, -i
, -i
, -i
);
79 recorder
.canvas()->DrawRect(outsetRect
, paint
);
83 void FocusRingLayer::OnDelegatedFrameDamage(
84 const gfx::Rect
& damage_rect_in_dip
) {
87 void FocusRingLayer::OnDeviceScaleFactorChanged(float device_scale_factor
) {
89 delegate_
->OnDeviceScaleFactorChanged();
92 base::Closure
FocusRingLayer::PrepareForLayerBoundsChange() {
93 return base::Bind(&base::DoNothing
);
96 } // namespace chromeos