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

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

Issue 2038093003: Refactor accessible focus ring code so the layers are animation observers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@improve_highlights
Patch Set: Created 4 years, 6 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/ui/accessibility_focus_ring_controller.h" 5 #include "chrome/browser/chromeos/ui/accessibility_focus_ring_controller.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
11 #include "ash/display/window_tree_host_manager.h"
12 #include "ash/shell.h" 11 #include "ash/shell.h"
13 #include "base/logging.h" 12 #include "base/logging.h"
14 #include "chrome/browser/chromeos/ui/focus_ring_layer.h" 13 #include "chrome/browser/chromeos/ui/focus_ring_layer.h"
15 #include "ui/display/screen.h"
16 14
17 namespace chromeos { 15 namespace chromeos {
18 16
19 namespace { 17 namespace {
20 18
21 // The number of pixels the focus ring is outset from the object it outlines, 19 // The number of pixels the focus ring is outset from the object it outlines,
22 // which also determines the border radius of the rounded corners. 20 // which also determines the border radius of the rounded corners.
23 // TODO(dmazzoni): take display resolution into account. 21 // TODO(dmazzoni): take display resolution into account.
24 const int kAccessibilityFocusRingMargin = 7; 22 const int kAccessibilityFocusRingMargin = 7;
25 23
(...skipping 27 matching lines...) Expand all
53 51
54 } // namespace 52 } // namespace
55 53
56 // static 54 // static
57 AccessibilityFocusRingController* 55 AccessibilityFocusRingController*
58 AccessibilityFocusRingController::GetInstance() { 56 AccessibilityFocusRingController::GetInstance() {
59 return base::Singleton<AccessibilityFocusRingController>::get(); 57 return base::Singleton<AccessibilityFocusRingController>::get();
60 } 58 }
61 59
62 AccessibilityFocusRingController::AccessibilityFocusRingController() 60 AccessibilityFocusRingController::AccessibilityFocusRingController()
63 : compositor_(nullptr), cursor_opacity_(0), cursor_compositor_(nullptr) {} 61 : cursor_opacity_(0) {}
64 62
65 AccessibilityFocusRingController::~AccessibilityFocusRingController() { 63 AccessibilityFocusRingController::~AccessibilityFocusRingController() {
66 } 64 }
67 65
68 void AccessibilityFocusRingController::SetFocusRing( 66 void AccessibilityFocusRingController::SetFocusRing(
69 const std::vector<gfx::Rect>& rects) { 67 const std::vector<gfx::Rect>& rects) {
70 rects_ = rects; 68 rects_ = rects;
71 Update(); 69 Update();
72 } 70 }
73 71
74 void AccessibilityFocusRingController::Update() { 72 void AccessibilityFocusRingController::Update() {
75 previous_rings_.swap(rings_); 73 previous_rings_.swap(rings_);
76 rings_.clear(); 74 rings_.clear();
77 RectsToRings(rects_, &rings_); 75 RectsToRings(rects_, &rings_);
78 layers_.resize(rings_.size()); 76 layers_.resize(rings_.size());
79 if (rings_.empty()) 77 if (rings_.empty())
80 return; 78 return;
81 79
82 for (size_t i = 0; i < rings_.size(); ++i) { 80 for (size_t i = 0; i < rings_.size(); ++i) {
83 if (!layers_[i]) 81 if (!layers_[i])
84 layers_[i] = new AccessibilityFocusRingLayer(this); 82 layers_[i] = new AccessibilityFocusRingLayer(this);
85 83
86 if (i > 0) { 84 if (i > 0) {
87 // Focus rings other than the first one don't animate. 85 // Focus rings other than the first one don't animate.
88 layers_[i]->Set(rings_[i]); 86 layers_[i]->Set(rings_[i]);
89 } 87 }
90 } 88 }
91 89
92 ui::Compositor* compositor = CompositorForBounds(rings_[0].GetBounds()); 90 if (layers_[0]->CanAnimate()) {
93 if (compositor != compositor_) {
94 RemoveAnimationObservers();
95 compositor_ = compositor;
96 AddAnimationObservers();
97 }
98
99 if (compositor_ && compositor_->HasAnimationObserver(this)) {
100 focus_change_time_ = base::TimeTicks::Now(); 91 focus_change_time_ = base::TimeTicks::Now();
101 } else { 92 } else {
102 // If we can't animate, set the location of the first ring. 93 // If we can't animate, set the location of the first ring.
103 layers_[0]->Set(rings_[0]); 94 layers_[0]->Set(rings_[0]);
104 } 95 }
105 } 96 }
106 97
107 ui::Compositor* AccessibilityFocusRingController::CompositorForBounds(
108 const gfx::Rect& bounds) {
109 display::Display display =
110 display::Screen::GetScreen()->GetDisplayMatching(bounds);
111 aura::Window* root_window = ash::Shell::GetInstance()
112 ->window_tree_host_manager()
113 ->GetRootWindowForDisplayId(display.id());
114 return root_window->layer()->GetCompositor();
115 }
116
117 void AccessibilityFocusRingController::RemoveAnimationObservers() {
118 if (compositor_ && compositor_->HasAnimationObserver(this))
119 compositor_->RemoveAnimationObserver(this);
120 if (cursor_compositor_ && cursor_compositor_->HasAnimationObserver(this))
121 cursor_compositor_->RemoveAnimationObserver(this);
122 }
123
124 void AccessibilityFocusRingController::AddAnimationObservers() {
125 if (compositor_ && !compositor_->HasAnimationObserver(this))
126 compositor_->AddAnimationObserver(this);
127 if (cursor_compositor_ && !cursor_compositor_->HasAnimationObserver(this))
128 cursor_compositor_->AddAnimationObserver(this);
129 }
130
131 void AccessibilityFocusRingController::SetCursorRing( 98 void AccessibilityFocusRingController::SetCursorRing(
132 const gfx::Point& location) { 99 const gfx::Point& location) {
133 cursor_location_ = location; 100 cursor_location_ = location;
134 cursor_change_time_ = base::TimeTicks::Now(); 101 cursor_change_time_ = base::TimeTicks::Now();
135 if (cursor_opacity_ == 0) 102 if (cursor_opacity_ == 0)
136 cursor_start_time_ = cursor_change_time_; 103 cursor_start_time_ = cursor_change_time_;
137 104
138 if (!cursor_layer_) { 105 if (!cursor_layer_) {
139 cursor_layer_.reset(new AccessibilityCursorRingLayer( 106 cursor_layer_.reset(new AccessibilityCursorRingLayer(
140 this, kCursorRingColorRed, kCursorRingColorGreen, 107 this, kCursorRingColorRed, kCursorRingColorGreen,
141 kCursorRingColorBlue)); 108 kCursorRingColorBlue));
142 } 109 }
143 cursor_layer_->Set(location); 110 cursor_layer_->Set(location);
144
145 ui::Compositor* compositor =
146 CompositorForBounds(gfx::Rect(location.x(), location.y(), 0, 0));
147 if (compositor != cursor_compositor_) {
148 RemoveAnimationObservers();
149 cursor_compositor_ = compositor;
150 AddAnimationObservers();
151 }
152 } 111 }
153 112
154 void AccessibilityFocusRingController::SetCaretRing( 113 void AccessibilityFocusRingController::SetCaretRing(
155 const gfx::Point& location) { 114 const gfx::Point& location) {
156 caret_location_ = location; 115 caret_location_ = location;
157 116
158 if (!caret_layer_) { 117 if (!caret_layer_) {
159 caret_layer_.reset(new AccessibilityCursorRingLayer( 118 caret_layer_.reset(new AccessibilityCursorRingLayer(
160 this, kCaretRingColorRed, kCaretRingColorGreen, kCaretRingColorBlue)); 119 this, kCaretRingColorRed, kCaretRingColorGreen, kCaretRingColorBlue));
161 } 120 }
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 r2.y() <= r1.bottom() + slop && 311 r2.y() <= r1.bottom() + slop &&
353 r2.bottom() >= r1.y() - slop); 312 r2.bottom() >= r1.y() - slop);
354 } 313 }
355 314
356 void AccessibilityFocusRingController::OnDeviceScaleFactorChanged() { 315 void AccessibilityFocusRingController::OnDeviceScaleFactorChanged() {
357 Update(); 316 Update();
358 } 317 }
359 318
360 void AccessibilityFocusRingController::OnAnimationStep( 319 void AccessibilityFocusRingController::OnAnimationStep(
361 base::TimeTicks timestamp) { 320 base::TimeTicks timestamp) {
362 if (!rings_.empty() && compositor_) 321 if (!rings_.empty() && layers_[0]->CanAnimate())
363 AnimateFocusRings(timestamp); 322 AnimateFocusRings(timestamp);
364 323
365 if (cursor_layer_ && cursor_compositor_) 324 if (cursor_layer_ && cursor_layer_->CanAnimate())
366 AnimateCursorRing(timestamp); 325 AnimateCursorRing(timestamp);
367 } 326 }
368 327
369 void AccessibilityFocusRingController::AnimateFocusRings( 328 void AccessibilityFocusRingController::AnimateFocusRings(
370 base::TimeTicks timestamp) { 329 base::TimeTicks timestamp) {
371 CHECK(!rings_.empty()); 330 CHECK(!rings_.empty());
372 CHECK(!layers_.empty()); 331 CHECK(!layers_.empty());
373 CHECK(layers_[0]); 332 CHECK(layers_[0]);
374 333
375 // It's quite possible for the first 1 or 2 animation frames to be 334 // It's quite possible for the first 1 or 2 animation frames to be
376 // for a timestamp that's earlier than the time we received the 335 // for a timestamp that's earlier than the time we received the
377 // focus change, so we just treat those as a delta of zero. 336 // focus change, so we just treat those as a delta of zero.
378 if (timestamp < focus_change_time_) 337 if (timestamp < focus_change_time_)
379 timestamp = focus_change_time_; 338 timestamp = focus_change_time_;
380 339
381 base::TimeDelta delta = timestamp - focus_change_time_; 340 base::TimeDelta delta = timestamp - focus_change_time_;
382 base::TimeDelta transition_time = 341 base::TimeDelta transition_time =
383 base::TimeDelta::FromMilliseconds(kTransitionTimeMilliseconds); 342 base::TimeDelta::FromMilliseconds(kTransitionTimeMilliseconds);
384 if (delta >= transition_time) { 343 if (delta >= transition_time) {
385 layers_[0]->Set(rings_[0]); 344 layers_[0]->Set(rings_[0]);
386
387 RemoveAnimationObservers();
388 compositor_ = nullptr;
389 AddAnimationObservers();
390 return; 345 return;
391 } 346 }
392 347
393 double fraction = delta.InSecondsF() / transition_time.InSecondsF(); 348 double fraction = delta.InSecondsF() / transition_time.InSecondsF();
394 349
395 // Ease-in effect. 350 // Ease-in effect.
396 fraction = pow(fraction, 0.3); 351 fraction = pow(fraction, 0.3);
397 352
398 // Handle corner case where we're animating but we don't have previous 353 // Handle corner case where we're animating but we don't have previous
399 // rings. 354 // rings.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 cursor_opacity_ = 1.0; 388 cursor_opacity_ = 1.0;
434 } else { 389 } else {
435 cursor_opacity_ = 1.0 - (change_delta.InSecondsF() / 390 cursor_opacity_ = 1.0 - (change_delta.InSecondsF() /
436 (fade_in_time + fade_out_time).InSecondsF()); 391 (fade_in_time + fade_out_time).InSecondsF());
437 if (cursor_opacity_ < 0.0) 392 if (cursor_opacity_ < 0.0)
438 cursor_opacity_ = 0.0; 393 cursor_opacity_ = 0.0;
439 } 394 }
440 cursor_layer_->SetOpacity(cursor_opacity_); 395 cursor_layer_->SetOpacity(cursor_opacity_);
441 } 396 }
442 397
443 void AccessibilityFocusRingController::OnCompositingShuttingDown(
444 ui::Compositor* compositor) {
445 if (compositor == compositor_ || compositor == cursor_compositor_)
446 compositor->RemoveAnimationObserver(this);
447
448 if (compositor == compositor_)
449 compositor_ = nullptr;
450 if (compositor == cursor_compositor_)
451 cursor_compositor_ = nullptr;
452 }
453
454 } // namespace chromeos 398 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698