| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |