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

Unified Diff: chrome/browser/chromeos/ui/accessibility_focus_ring_controller.cc

Issue 602813003: Animate the accessibility focus ring and fix some minor visual issues. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@focus_ring_in_chromevox
Patch Set: Fix unit tests 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_controller.cc
diff --git a/chrome/browser/chromeos/ui/accessibility_focus_ring_controller.cc b/chrome/browser/chromeos/ui/accessibility_focus_ring_controller.cc
index aaca4c5199bbd39b983223edf8f44c68596c5b8c..b2c93a80312310a6239b2c9041c5518244bee748 100644
--- a/chrome/browser/chromeos/ui/accessibility_focus_ring_controller.cc
+++ b/chrome/browser/chromeos/ui/accessibility_focus_ring_controller.cc
@@ -4,7 +4,11 @@
#include "chrome/browser/chromeos/ui/accessibility_focus_ring_controller.h"
+#include "ash/display/display_controller.h"
+#include "ash/shell.h"
+#include "base/logging.h"
#include "chrome/browser/chromeos/ui/focus_ring_layer.h"
+#include "ui/gfx/screen.h"
namespace chromeos {
@@ -13,7 +17,10 @@ namespace {
// The number of pixels the focus ring is outset from the object it outlines,
// which also determines the border radius of the rounded corners.
// TODO(dmazzoni): take display resolution into account.
-const int kAccessibilityFocusRingMargin = 16;
+const int kAccessibilityFocusRingMargin = 7;
+
+// Time to transition between one location and the next.
+const int kTransitionTimeMilliseconds = 300;
// A Region is an unordered collection of Rects that maintains its
// bounding box. Used in the middle of an algorithm that groups
@@ -35,7 +42,8 @@ AccessibilityFocusRingController*
return Singleton<AccessibilityFocusRingController>::get();
}
-AccessibilityFocusRingController::AccessibilityFocusRingController() {
+AccessibilityFocusRingController::AccessibilityFocusRingController()
+ : compositor_(NULL) {
}
AccessibilityFocusRingController::~AccessibilityFocusRingController() {
@@ -48,22 +56,57 @@ void AccessibilityFocusRingController::SetFocusRing(
}
void AccessibilityFocusRingController::Update() {
+ previous_rings_.swap(rings_);
rings_.clear();
RectsToRings(rects_, &rings_);
+ layers_.resize(rings_.size());
+ for (size_t i = 0; i < rings_.size(); ++i) {
+ if (!layers_[i])
+ layers_[i].reset(new AccessibilityFocusRingLayer(this));
+
+ if (i > 0) {
+ // Focus rings other than the first one don't animate.
+ layers_[i]->Set(rings_[i]);
+ continue;
+ }
- if (!main_focus_ring_layer_)
- main_focus_ring_layer_.reset(new AccessibilityFocusRingLayer(this));
+ gfx::Rect bounds = rings_[0].GetBounds();
+ gfx::Display display =
+ gfx::Screen::GetNativeScreen()->GetDisplayMatching(bounds);
+ aura::Window* root_window = ash::Shell::GetInstance()->display_controller()
+ ->GetRootWindowForDisplayId(display.id());
+ ui::Compositor* compositor = root_window->layer()->GetCompositor();
+ if (!compositor || root_window != layers_[0]->root_window()) {
+ layers_[0]->Set(rings_[0]);
+ if (compositor_ && compositor_->HasAnimationObserver(this)) {
+ compositor_->RemoveAnimationObserver(this);
+ compositor_ = NULL;
+ }
+ continue;
+ }
- if (!rings_.empty())
- main_focus_ring_layer_->Set(rings_[0]);
+ focus_change_time_ = base::TimeTicks::Now();
+ if (!compositor->HasAnimationObserver(this)) {
+ compositor_ = compositor;
+ compositor_->AddAnimationObserver(this);
+ }
+ }
}
void AccessibilityFocusRingController::RectsToRings(
- const std::vector<gfx::Rect>& rects,
+ const std::vector<gfx::Rect>& src_rects,
std::vector<AccessibilityFocusRing>* rings) const {
- if (rects.empty())
+ if (src_rects.empty())
return;
+ // Give all of the rects a margin.
+ std::vector<gfx::Rect> rects;
+ rects.resize(src_rects.size());
+ for (size_t i = 0; i < src_rects.size(); ++i) {
+ rects[i] = src_rects[i];
+ rects[i].Inset(-GetMargin(), -GetMargin());
+ }
+
// Split the rects into contiguous regions.
std::vector<Region> regions;
regions.push_back(Region(rects[0]));
@@ -244,4 +287,33 @@ void AccessibilityFocusRingController::OnDeviceScaleFactorChanged() {
Update();
}
+void AccessibilityFocusRingController::OnAnimationStep(
+ base::TimeTicks timestamp) {
+ if (rings_.empty())
+ return;
+
+ CHECK(compositor_);
+ CHECK(!rings_.empty());
+ CHECK(!layers_.empty());
+ CHECK(layers_[0]);
+
+ base::TimeDelta delta = timestamp - focus_change_time_;
+ base::TimeDelta transition_time =
+ base::TimeDelta::FromMilliseconds(kTransitionTimeMilliseconds);
+ if (delta >= transition_time) {
+ layers_[0]->Set(rings_[0]);
+ compositor_->RemoveAnimationObserver(this);
+ compositor_ = NULL;
+ return;
+ }
+
+ double fraction = delta.InSecondsF() / transition_time.InSecondsF();
+
+ // Ease-in effect.
+ fraction = pow(fraction, 0.3);
+
+ layers_[0]->Set(AccessibilityFocusRing::Interpolate(
+ previous_rings_[0], rings_[0], fraction));
+}
+
} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698