| 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..b5436bd0ab59431804d0fd79ed3d911b1726df1e
|
| --- /dev/null
|
| +++ b/chrome/browser/chromeos/ui/accessibility_focus_ring_layer.cc
|
| @@ -0,0 +1,131 @@
|
| +// 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/display/display_controller.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);
|
| +
|
| + gfx::Display display =
|
| + gfx::Screen::GetNativeScreen()->GetDisplayMatching(bounds);
|
| + aura::Window* root_window = ash::Shell::GetInstance()->display_controller()
|
| + ->GetRootWindowForDisplayId(display.id());
|
| + CreateOrUpdateLayer(root_window, "AccessibilityFocusRing");
|
| +
|
| + // 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
|
|
|