1 // Copyright 2016 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/accessibility/accessibility_cursor_ring_layer.h"
6
7 #include "ash/shell.h"
8 #include "third_party/skia/include/core/SkPaint.h"
9 #include "third_party/skia/include/core/SkPath.h"
10 #include "ui/aura/window.h"
11 #include "ui/compositor/layer.h"
12 #include "ui/compositor/paint_recorder.h"
13 #include "ui/display/display.h"
14 #include "ui/display/screen.h"
15 #include "ui/gfx/canvas.h"
16 #include "ui/wm/core/coordinate_conversion.h"
17
18 namespace ash {
19
20 namespace {
21
22 // The number of pixels in the color gradient that fades to transparent.
23 const int kGradientWidth = 8;
24
25 // The radius of the ring in pixels.
26 const int kCursorRingRadius = 24;
27
28 // Extra margin to add to the layer in pixels.
29 const int kLayerMargin = 8;
30
31 } // namespace
32
AccessibilityCursorRingLayer(AccessibilityLayerDelegate * delegate,int red,int green,int blue)33 AccessibilityCursorRingLayer::AccessibilityCursorRingLayer(
34 AccessibilityLayerDelegate* delegate,
35 int red,
36 int green,
37 int blue)
38 : FocusRingLayer(delegate), red_(red), green_(green), blue_(blue) {}
39
40 AccessibilityCursorRingLayer::~AccessibilityCursorRingLayer() = default;
41
Set(const gfx::Point & location)42 void AccessibilityCursorRingLayer::Set(const gfx::Point& location) {
43 location_ = location;
44
45 gfx::Rect bounds = gfx::Rect(location.x(), location.y(), 0, 0);
46 int inset = kGradientWidth + kCursorRingRadius + kLayerMargin;
47 bounds.Inset(-inset, -inset, -inset, -inset);
48
49 display::Display display =
50 display::Screen::GetScreen()->GetDisplayMatching(bounds);
51 aura::Window* root_window = Shell::GetRootWindowForDisplayId(display.id());
52 ::wm::ConvertRectFromScreen(root_window, &bounds);
53 CreateOrUpdateLayer(root_window, "AccessibilityCursorRing", bounds);
54 }
55
OnPaintLayer(const ui::PaintContext & context)56 void AccessibilityCursorRingLayer::OnPaintLayer(
57 const ui::PaintContext& context) {
58 ui::PaintRecorder recorder(context, layer()->size());
59
60 cc::PaintFlags flags;
61 flags.setAntiAlias(true);
62 flags.setStyle(cc::PaintFlags::kStroke_Style);
63 flags.setStrokeWidth(2);
64
65 gfx::Rect r = layer()->bounds();
66 r.Offset(-r.OffsetFromOrigin());
67 r.Inset(kLayerMargin, kLayerMargin, kLayerMargin, kLayerMargin);
68 const int w = kGradientWidth;
69 for (int i = 0; i < w; ++i) {
70 flags.setColor(SkColorSetARGB(255 * i * i / (w * w), red_, green_, blue_));
71 SkPath path;
72 path.addOval(SkRect::MakeXYWH(r.x(), r.y(), r.width(), r.height()));
73 r.Inset(1, 1, 1, 1);
74 recorder.canvas()->DrawPath(path, flags);
75 }
76 }
77
78 } // namespace ash
79