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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/ui/accessibility_focus_ring_layer.cc
diff --git a/chrome/browser/chromeos/ui/accessibility_focus_ring_layer.cc b/chrome/browser/chromeos/ui/accessibility_focus_ring_layer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b0fafba3c8bff7d5e13dce6eab7fa91ca6bcc4e6
--- /dev/null
+++ b/chrome/browser/chromeos/ui/accessibility_focus_ring_layer.cc
@@ -0,0 +1,138 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/ui/accessibility_focus_ring_layer.h"
+
+#include "ash/shell.h"
+#include "base/bind.h"
+#include "ui/aura/window.h"
+#include "ui/compositor/layer.h"
+#include "ui/gfx/canvas.h"
+
+namespace chromeos {
+
+namespace {
+
+// The number of pixels in the color gradient that fades to transparent.
+const int kGradientWidth = 10;
+
+// The color of the focus ring. In the future this might be a parameter.
+const int kFocusRingColorRed = 247;
+const int kFocusRingColorGreen = 152;
+const int kFocusRingColorBlue = 58;
+
+int sign(int x) {
+ return ((x > 0) ? 1 : (x == 0) ? 0 : -1);
+}
+
+SkPath MakePath(const AccessibilityFocusRing& input_ring,
+ int outset,
+ const gfx::Vector2d& offset) {
+ AccessibilityFocusRing ring = input_ring;
+
+ for (int i = 0; i < 36; i++) {
+ gfx::Point p = input_ring.points[i];
+ gfx::Point prev;
+ gfx::Point next;
+
+ int prev_index = i;
+ do {
+ prev_index = (prev_index + 35) % 36;
+ prev = input_ring.points[prev_index];
+ } while (prev.x() == p.x() && prev.y() == p.y());
+
+ int next_index = i;
+ do {
+ next_index = (next_index + 1) % 36;
+ next = input_ring.points[next_index];
+ } while (next.x() == p.x() && next.y() == p.y());
+
+ gfx::Point delta0 = gfx::Point(sign(p.x() - prev.x()),
+ sign(p.y() - prev.y()));
+ gfx::Point delta1 = gfx::Point(sign(next.x() - p.x()),
+ sign(next.y() - p.y()));
+
+ if (delta0.x() == delta1.x() && delta0.y() == delta1.y()) {
+ ring.points[i] = gfx::Point(
+ input_ring.points[i].x() + outset * delta0.y(),
+ input_ring.points[i].y() - outset * delta0.x());
+ } else {
+ ring.points[i] = gfx::Point(
+ input_ring.points[i].x() + ((i + 13) % 36 >= 18 ? outset : -outset),
+ input_ring.points[i].y() + ((i + 4) % 36 >= 18 ? outset : -outset));
+ }
+ }
+
+ SkPath path;
+ gfx::Point p0 = ring.points[0] - offset;
+ path.moveTo(SkIntToScalar(p0.x()), SkIntToScalar(p0.y()));
+ for (int i = 0; i < 12; i++) {
+ int index0 = ((3 * i) + 1) % 36;
+ int index1 = ((3 * i) + 2) % 36;
+ int index2 = ((3 * i) + 3) % 36;
+ gfx::Point p0 = ring.points[index0] - offset;
+ gfx::Point p1 = ring.points[index1] - offset;
+ gfx::Point p2 = ring.points[index2] - offset;
+ path.lineTo(SkIntToScalar(p0.x()), SkIntToScalar(p0.y()));
+ path.quadTo(SkIntToScalar(p1.x()), SkIntToScalar(p1.y()),
+ SkIntToScalar(p2.x()), SkIntToScalar(p2.y()));
+ }
+
+ return path;
+}
+
+} // namespace
+
+AccessibilityFocusRingLayer::AccessibilityFocusRingLayer(
+ FocusRingLayerDelegate* delegate)
+ : FocusRingLayer(delegate) {
+}
+
+AccessibilityFocusRingLayer::~AccessibilityFocusRingLayer() {}
+
+void AccessibilityFocusRingLayer::Set(const AccessibilityFocusRing& ring) {
+ ring_ = ring;
+
+ gfx::Rect bounds = ring.GetBounds();
+ int inset = kGradientWidth;
+ bounds.Inset(-inset, -inset, -inset, -inset);
+
+ if (!layer_) {
+ 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
+ ui::Layer* root_layer = root_window->layer();
+ layer_.reset(new ui::Layer(ui::LAYER_TEXTURED));
+ layer_->set_name("AccessibilityFocusRing");
+ layer_->set_delegate(this);
+ layer_->SetFillsBoundsOpaquely(false);
+ root_layer->Add(layer_.get());
+ }
+
+ // Keep moving it to the top in case new layers have been added
+ // since we created this layer.
+ layer_->parent()->StackAtTop(layer_.get());
+
+ // Update the layer bounds.
+ layer_->SetBounds(bounds);
+}
+
+void AccessibilityFocusRingLayer::OnPaintLayer(gfx::Canvas* canvas) {
+ gfx::Vector2d offset = layer_->bounds().OffsetFromOrigin();
+
+ SkPaint paint;
+ paint.setFlags(SkPaint::kAntiAlias_Flag);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(2);
+
+ SkPath path;
+ for (int i = 0; i < kGradientWidth; i++) {
+ paint.setColor(
+ SkColorSetARGBMacro(
+ 255 - (255 * i / kGradientWidth),
+ kFocusRingColorRed, kFocusRingColorGreen, kFocusRingColorBlue));
+ path = MakePath(ring_, i, offset);
+ canvas->DrawPath(path, paint);
+ }
+}
+
+} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698