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

Side by Side Diff: chrome/browser/chromeos/ui/accessibility_focus_ring_layer.cc

Issue 557393003: Introduce AccessibilityFocusRing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@accessibility_private_histograms
Patch Set: Created 6 years, 3 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 2014 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 "chrome/browser/chromeos/ui/accessibility_focus_ring_layer.h"
6
7 #include "ash/shell.h"
8 #include "base/bind.h"
9 #include "ui/aura/window.h"
10 #include "ui/compositor/layer.h"
11 #include "ui/gfx/canvas.h"
12
13 namespace chromeos {
14
15 namespace {
16
17 // The number of pixels in the color gradient that fades to transparent.
18 const int kGradientWidth = 10;
19
20 // The color of the focus ring. In the future this might be a parameter.
21 const int kFocusRingColorRed = 247;
22 const int kFocusRingColorGreen = 152;
23 const int kFocusRingColorBlue = 58;
24
25 int sign(int x) {
26 return ((x > 0) ? 1 : (x == 0) ? 0 : -1);
27 }
28
29 SkPath MakePath(const AccessibilityFocusRing& input_ring,
30 int outset,
31 const gfx::Vector2d& offset) {
32 AccessibilityFocusRing ring = input_ring;
33
34 for (int i = 0; i < 36; i++) {
35 gfx::Point p = input_ring.points[i];
36 gfx::Point prev;
37 gfx::Point next;
38
39 int prev_index = i;
40 do {
41 prev_index = (prev_index + 35) % 36;
42 prev = input_ring.points[prev_index];
43 } while (prev.x() == p.x() && prev.y() == p.y());
44
45 int next_index = i;
46 do {
47 next_index = (next_index + 1) % 36;
48 next = input_ring.points[next_index];
49 } while (next.x() == p.x() && next.y() == p.y());
50
51 gfx::Point delta0 = gfx::Point(sign(p.x() - prev.x()),
52 sign(p.y() - prev.y()));
53 gfx::Point delta1 = gfx::Point(sign(next.x() - p.x()),
54 sign(next.y() - p.y()));
55
56 if (delta0.x() == delta1.x() && delta0.y() == delta1.y()) {
57 ring.points[i] = gfx::Point(
58 input_ring.points[i].x() + outset * delta0.y(),
59 input_ring.points[i].y() - outset * delta0.x());
60 } else {
61 ring.points[i] = gfx::Point(
62 input_ring.points[i].x() + ((i + 13) % 36 >= 18 ? outset : -outset),
63 input_ring.points[i].y() + ((i + 4) % 36 >= 18 ? outset : -outset));
64 }
65 }
66
67 SkPath path;
68 gfx::Point p0 = ring.points[0] - offset;
69 path.moveTo(SkIntToScalar(p0.x()), SkIntToScalar(p0.y()));
70 for (int i = 0; i < 12; i++) {
71 int index0 = ((3 * i) + 1) % 36;
72 int index1 = ((3 * i) + 2) % 36;
73 int index2 = ((3 * i) + 3) % 36;
74 gfx::Point p0 = ring.points[index0] - offset;
75 gfx::Point p1 = ring.points[index1] - offset;
76 gfx::Point p2 = ring.points[index2] - offset;
77 path.lineTo(SkIntToScalar(p0.x()), SkIntToScalar(p0.y()));
78 path.quadTo(SkIntToScalar(p1.x()), SkIntToScalar(p1.y()),
79 SkIntToScalar(p2.x()), SkIntToScalar(p2.y()));
80 }
81
82 return path;
83 }
84
85 } // namespace
86
87 AccessibilityFocusRingLayer::AccessibilityFocusRingLayer(
88 FocusRingLayerDelegate* delegate)
89 : FocusRingLayer(delegate) {
90 }
91
92 AccessibilityFocusRingLayer::~AccessibilityFocusRingLayer() {}
93
94 void AccessibilityFocusRingLayer::Set(const AccessibilityFocusRing& ring) {
95 ring_ = ring;
96
97 gfx::Rect bounds = ring.GetBounds();
98 int inset = kGradientWidth;
99 bounds.Inset(-inset, -inset, -inset, -inset);
100
101 if (!layer_) {
102 aura::Window* root_window = ash::Shell::GetPrimaryRootWindow();
xiyuan 2014/09/11 03:57:45 Primary root window might not always be right. We
dmazzoni 2014/09/11 21:44:39 Great! I knew this needed to be done but wasn't su
103 ui::Layer* root_layer = root_window->layer();
104 layer_.reset(new ui::Layer(ui::LAYER_TEXTURED));
105 layer_->set_name("AccessibilityFocusRing");
106 layer_->set_delegate(this);
107 layer_->SetFillsBoundsOpaquely(false);
108 root_layer->Add(layer_.get());
109 }
110
111 // Keep moving it to the top in case new layers have been added
112 // since we created this layer.
113 layer_->parent()->StackAtTop(layer_.get());
114
115 // Update the layer bounds.
116 layer_->SetBounds(bounds);
117 }
118
119 void AccessibilityFocusRingLayer::OnPaintLayer(gfx::Canvas* canvas) {
120 gfx::Vector2d offset = layer_->bounds().OffsetFromOrigin();
121
122 SkPaint paint;
123 paint.setFlags(SkPaint::kAntiAlias_Flag);
124 paint.setStyle(SkPaint::kStroke_Style);
125 paint.setStrokeWidth(2);
126
127 SkPath path;
128 for (int i = 0; i < kGradientWidth; i++) {
129 paint.setColor(
130 SkColorSetARGBMacro(
131 255 - (255 * i / kGradientWidth),
132 kFocusRingColorRed, kFocusRingColorGreen, kFocusRingColorBlue));
133 path = MakePath(ring_, i, offset);
134 canvas->DrawPath(path, paint);
135 }
136 }
137
138 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698