| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "ui/views/animation/ink_drop_impl.h" | 5 #include "ui/views/animation/ink_drop_impl.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/timer/timer.h" | 8 #include "base/timer/timer.h" |
| 9 #include "ui/compositor/layer.h" | 9 #include "ui/compositor/layer.h" |
| 10 #include "ui/views/animation/ink_drop_highlight.h" | 10 #include "ui/views/animation/ink_drop_highlight.h" |
| 11 #include "ui/views/animation/ink_drop_host.h" | 11 #include "ui/views/animation/ink_drop_host.h" |
| 12 #include "ui/views/animation/square_ink_drop_ripple.h" | 12 #include "ui/views/animation/square_ink_drop_ripple.h" |
| 13 | 13 |
| 14 namespace views { | 14 namespace views { |
| 15 | 15 |
| 16 namespace { | 16 namespace { |
| 17 | 17 |
| 18 // The duration, in milliseconds, of the highlight state fade in animation when | 18 // The duration, in milliseconds for the highlight state fade in/out animations |
| 19 // it is triggered by user input. | 19 // when it is triggered by a hover changed event. |
| 20 const int kHighlightFadeInFromUserInputDurationMs = 250; | 20 const int kHighlightFadeInOnHoverChangeDurationMs = 250; |
| 21 const int kHighlightFadeOutOnHoverChangeDurationMs = 250; |
| 21 | 22 |
| 22 // The duration, in milliseconds, of the highlight state fade out animation when | 23 // The duration, in milliseconds for the highlight state fade in/out animations |
| 23 // it is triggered by user input. | 24 // when it is triggered by a focus changed event. |
| 24 const int kHighlightFadeOutFromUserInputDurationMs = 250; | 25 const int kHighlightFadeInOnFocusChangeDurationMs = 0; |
| 26 const int kHighlightFadeOutOnFocusChangeDurationMs = 0; |
| 25 | 27 |
| 26 // The duration, in milliseconds, of the highlight state fade in animation when | 28 // The duration, in milliseconds, for showing/hiding the highlight when |
| 27 // it is triggered by an ink drop ripple animation ending. | 29 // triggered by ripple visibility changes for the HIDE_ON_RIPPLE |
| 28 const int kHighlightFadeInAfterRippleDurationMs = 250; | 30 // AutoHighlightMode. |
| 31 const int kHighlightFadeInOnRippleHidingDurationMs = 250; |
| 32 const int kHighlightFadeOutOnRippleShowingDurationMs = 120; |
| 29 | 33 |
| 30 // The duration, in milliseconds, of the highlight state fade out animation when | 34 // The duration, in milliseconds, for showing/hiding the highlight when |
| 31 // it is triggered by an ink drop ripple animation starting. | 35 // triggered by ripple visibility changes for the SHOW_ON_RIPPLE |
| 32 const int kHighlightFadeOutBeforeRippleDurationMs = 120; | 36 // AutoHighlightMode. |
| 37 const int kHighlightFadeInOnRippleShowingDurationMs = 250; |
| 38 const int kHighlightFadeOutOnRippleHidingDurationMs = 120; |
| 33 | 39 |
| 34 // The amount of time in milliseconds that |highlight_| should delay after a | 40 // The amount of time in milliseconds that |highlight_| should delay after a |
| 35 // ripple animation before fading in, for highlight due to mouse hover. | 41 // ripple animation before fading in, for highlight due to mouse hover. |
| 36 const int kHoverFadeInAfterRippleDelayMs = 1000; | 42 const int kHoverFadeInAfterRippleDelayMs = 1000; |
| 37 | 43 |
| 38 // Returns true if an ink drop with the given |ink_drop_state| should | 44 // Returns true if an ink drop with the given |ink_drop_state| should |
| 39 // automatically transition to the InkDropState::HIDDEN state. | 45 // automatically transition to the InkDropState::HIDDEN state. |
| 40 bool ShouldAnimateToHidden(InkDropState ink_drop_state) { | 46 bool ShouldAnimateToHidden(InkDropState ink_drop_state) { |
| 41 switch (ink_drop_state) { | 47 switch (ink_drop_state) { |
| 42 case views::InkDropState::ACTION_TRIGGERED: | 48 case views::InkDropState::ACTION_TRIGGERED: |
| 43 case views::InkDropState::ALTERNATE_ACTION_TRIGGERED: | 49 case views::InkDropState::ALTERNATE_ACTION_TRIGGERED: |
| 44 case views::InkDropState::DEACTIVATED: | 50 case views::InkDropState::DEACTIVATED: |
| 45 return true; | 51 return true; |
| 46 default: | 52 default: |
| 47 return false; | 53 return false; |
| 48 } | 54 } |
| 49 } | 55 } |
| 50 | 56 |
| 51 } // namespace | 57 } // namespace |
| 52 | 58 |
| 59 // HighlightState definition |
| 60 |
| 61 InkDropImpl* InkDropImpl::HighlightState::GetInkDrop() { |
| 62 return state_factory_->ink_drop(); |
| 63 } |
| 64 |
| 65 // |
| 66 // AutoHighlightMode::NONE states |
| 67 // |
| 68 |
| 69 // Animates the highlight to hidden upon entering this state. Transitions to a |
| 70 // visible state based on hover/focus changes. |
| 71 class InkDropImpl::NoAutoHighlightHiddenState |
| 72 : public InkDropImpl::HighlightState { |
| 73 public: |
| 74 NoAutoHighlightHiddenState(HighlightStateFactory* state_factory, |
| 75 base::TimeDelta animation_duration, |
| 76 bool explode); |
| 77 |
| 78 // InkDropImpl::HighlightState: |
| 79 void Enter() override; |
| 80 void ShowOnHoverChanged() override; |
| 81 void OnHoverChanged() override; |
| 82 void ShowOnFocusChanged() override; |
| 83 void OnFocusChanged() override; |
| 84 void AnimationStarted(InkDropState ink_drop_state) override; |
| 85 void AnimationEnded(InkDropState ink_drop_state, |
| 86 InkDropAnimationEndedReason reason) override; |
| 87 |
| 88 private: |
| 89 // Handles all changes to the hover/focus status and transitions to a visible |
| 90 // state if necessary. |
| 91 void HandleHoverAndFocusChangeChanges(int animation_duration_ms); |
| 92 |
| 93 // The fade out animation duration. |
| 94 base::TimeDelta animation_duration_; |
| 95 |
| 96 // True when the highlight should explode while fading out. |
| 97 bool explode_; |
| 98 |
| 99 DISALLOW_COPY_AND_ASSIGN(NoAutoHighlightHiddenState); |
| 100 }; |
| 101 |
| 102 // Animates the highlight to visible upon entering this state. Transitions to a |
| 103 // hidden state based on hover/focus changes. |
| 104 class InkDropImpl::NoAutoHighlightVisibleState |
| 105 : public InkDropImpl::HighlightState { |
| 106 public: |
| 107 NoAutoHighlightVisibleState(HighlightStateFactory* state_factory, |
| 108 base::TimeDelta animation_duration, |
| 109 bool explode); |
| 110 |
| 111 // InkDropImpl::HighlightState: |
| 112 void Enter() override; |
| 113 void Exit() override {} |
| 114 void ShowOnHoverChanged() override; |
| 115 void OnHoverChanged() override; |
| 116 void ShowOnFocusChanged() override; |
| 117 void OnFocusChanged() override; |
| 118 void AnimationStarted(InkDropState ink_drop_state) override; |
| 119 void AnimationEnded(InkDropState ink_drop_state, |
| 120 InkDropAnimationEndedReason reason) override; |
| 121 |
| 122 private: |
| 123 // Handles all changes to the hover/focus status and transitions to a hidden |
| 124 // state if necessary. |
| 125 void HandleHoverAndFocusChangeChanges(int animation_duration_ms); |
| 126 |
| 127 // The fade in animation duration. |
| 128 base::TimeDelta animation_duration_; |
| 129 |
| 130 // True when the highlight should explode while fading in. |
| 131 bool explode_; |
| 132 |
| 133 DISALLOW_COPY_AND_ASSIGN(NoAutoHighlightVisibleState); |
| 134 }; |
| 135 |
| 136 // NoAutoHighlightHiddenState definition |
| 137 |
| 138 InkDropImpl::NoAutoHighlightHiddenState::NoAutoHighlightHiddenState( |
| 139 HighlightStateFactory* state_factory, |
| 140 base::TimeDelta animation_duration, |
| 141 bool explode) |
| 142 : InkDropImpl::HighlightState(state_factory), |
| 143 animation_duration_(animation_duration), |
| 144 explode_(explode) {} |
| 145 |
| 146 void InkDropImpl::NoAutoHighlightHiddenState::Enter() { |
| 147 GetInkDrop()->SetHighlight(false, animation_duration_, explode_); |
| 148 } |
| 149 |
| 150 void InkDropImpl::NoAutoHighlightHiddenState::ShowOnHoverChanged() { |
| 151 HandleHoverAndFocusChangeChanges(kHighlightFadeInOnHoverChangeDurationMs); |
| 152 } |
| 153 |
| 154 void InkDropImpl::NoAutoHighlightHiddenState::OnHoverChanged() { |
| 155 HandleHoverAndFocusChangeChanges(kHighlightFadeInOnHoverChangeDurationMs); |
| 156 } |
| 157 |
| 158 void InkDropImpl::NoAutoHighlightHiddenState::ShowOnFocusChanged() { |
| 159 HandleHoverAndFocusChangeChanges(kHighlightFadeInOnFocusChangeDurationMs); |
| 160 } |
| 161 |
| 162 void InkDropImpl::NoAutoHighlightHiddenState::OnFocusChanged() { |
| 163 HandleHoverAndFocusChangeChanges(kHighlightFadeInOnFocusChangeDurationMs); |
| 164 } |
| 165 |
| 166 void InkDropImpl::NoAutoHighlightHiddenState::HandleHoverAndFocusChangeChanges( |
| 167 int animation_duration_ms) { |
| 168 if (GetInkDrop()->ShouldHighlight()) { |
| 169 GetInkDrop()->SetHighlightState(state_factory()->CreateVisibleState( |
| 170 base::TimeDelta::FromMilliseconds(animation_duration_ms), false)); |
| 171 } |
| 172 } |
| 173 |
| 174 void InkDropImpl::NoAutoHighlightHiddenState::AnimationStarted( |
| 175 InkDropState ink_drop_state) {} |
| 176 |
| 177 void InkDropImpl::NoAutoHighlightHiddenState::AnimationEnded( |
| 178 InkDropState ink_drop_state, |
| 179 InkDropAnimationEndedReason reason) {} |
| 180 |
| 181 // NoAutoHighlightVisibleState definition |
| 182 |
| 183 InkDropImpl::NoAutoHighlightVisibleState::NoAutoHighlightVisibleState( |
| 184 HighlightStateFactory* state_factory, |
| 185 base::TimeDelta animation_duration, |
| 186 bool explode) |
| 187 : InkDropImpl::HighlightState(state_factory), |
| 188 animation_duration_(animation_duration), |
| 189 explode_(explode) {} |
| 190 |
| 191 void InkDropImpl::NoAutoHighlightVisibleState::Enter() { |
| 192 GetInkDrop()->SetHighlight(true, animation_duration_, explode_); |
| 193 } |
| 194 |
| 195 void InkDropImpl::NoAutoHighlightVisibleState::ShowOnHoverChanged() { |
| 196 HandleHoverAndFocusChangeChanges(kHighlightFadeOutOnHoverChangeDurationMs); |
| 197 } |
| 198 |
| 199 void InkDropImpl::NoAutoHighlightVisibleState::OnHoverChanged() { |
| 200 HandleHoverAndFocusChangeChanges(kHighlightFadeOutOnHoverChangeDurationMs); |
| 201 } |
| 202 |
| 203 void InkDropImpl::NoAutoHighlightVisibleState::ShowOnFocusChanged() { |
| 204 HandleHoverAndFocusChangeChanges(kHighlightFadeOutOnFocusChangeDurationMs); |
| 205 } |
| 206 |
| 207 void InkDropImpl::NoAutoHighlightVisibleState::OnFocusChanged() { |
| 208 HandleHoverAndFocusChangeChanges(kHighlightFadeOutOnFocusChangeDurationMs); |
| 209 } |
| 210 |
| 211 void InkDropImpl::NoAutoHighlightVisibleState::HandleHoverAndFocusChangeChanges( |
| 212 int animation_duration_ms) { |
| 213 if (!GetInkDrop()->ShouldHighlight()) { |
| 214 GetInkDrop()->SetHighlightState(state_factory()->CreateHiddenState( |
| 215 base::TimeDelta::FromMilliseconds(animation_duration_ms), false)); |
| 216 } |
| 217 } |
| 218 |
| 219 void InkDropImpl::NoAutoHighlightVisibleState::AnimationStarted( |
| 220 InkDropState ink_drop_state) {} |
| 221 |
| 222 void InkDropImpl::NoAutoHighlightVisibleState::AnimationEnded( |
| 223 InkDropState ink_drop_state, |
| 224 InkDropAnimationEndedReason reason) {} |
| 225 |
| 226 // |
| 227 // AutoHighlightMode::HIDE_ON_RIPPLE states |
| 228 // |
| 229 |
| 230 // Extends the base hidden state to re-show the highlight after the ripple |
| 231 // becomes hidden. |
| 232 class InkDropImpl::HideHighlightOnRippleHiddenState |
| 233 : public InkDropImpl::NoAutoHighlightHiddenState { |
| 234 public: |
| 235 HideHighlightOnRippleHiddenState(HighlightStateFactory* state_factory, |
| 236 base::TimeDelta animation_duration, |
| 237 bool explode); |
| 238 |
| 239 // InkDropImpl::NoAutoHighlightHiddenState: |
| 240 void ShowOnHoverChanged() override; |
| 241 void OnHoverChanged() override; |
| 242 void ShowOnFocusChanged() override; |
| 243 void OnFocusChanged() override; |
| 244 void AnimationStarted(InkDropState ink_drop_state) override; |
| 245 void AnimationEnded(InkDropState ink_drop_state, |
| 246 InkDropAnimationEndedReason reason) override; |
| 247 |
| 248 private: |
| 249 // Starts the |highlight_after_ripple_timer_|. This will stop the current |
| 250 // |highlight_after_ripple_timer_| instance if it exists. |
| 251 void StartHighlightAfterRippleTimer(); |
| 252 |
| 253 // Callback for when the |highlight_after_ripple_timer_| fires. Transitions to |
| 254 // a visible state if the ink drop should be highlighted. |
| 255 void HighlightAfterRippleTimerFired(); |
| 256 |
| 257 // The timer used to delay the highlight fade in after an ink drop ripple |
| 258 // animation. |
| 259 std::unique_ptr<base::Timer> highlight_after_ripple_timer_; |
| 260 |
| 261 DISALLOW_COPY_AND_ASSIGN(HideHighlightOnRippleHiddenState); |
| 262 }; |
| 263 |
| 264 // Extends the base visible state to hide the highlight when the ripple becomes |
| 265 // visible. |
| 266 class InkDropImpl::HideHighlightOnRippleVisibleState |
| 267 : public InkDropImpl::NoAutoHighlightVisibleState { |
| 268 public: |
| 269 HideHighlightOnRippleVisibleState(HighlightStateFactory* state_factory, |
| 270 base::TimeDelta animation_duration, |
| 271 bool explode); |
| 272 |
| 273 // InkDropImpl::NoAutoHighlightVisibleState: |
| 274 void AnimationStarted(InkDropState ink_drop_state) override; |
| 275 |
| 276 private: |
| 277 DISALLOW_COPY_AND_ASSIGN(HideHighlightOnRippleVisibleState); |
| 278 }; |
| 279 |
| 280 // HideHighlightOnRippleHiddenState definition |
| 281 |
| 282 InkDropImpl::HideHighlightOnRippleHiddenState::HideHighlightOnRippleHiddenState( |
| 283 HighlightStateFactory* state_factory, |
| 284 base::TimeDelta animation_duration, |
| 285 bool explode) |
| 286 : InkDropImpl::NoAutoHighlightHiddenState(state_factory, |
| 287 animation_duration, |
| 288 explode), |
| 289 highlight_after_ripple_timer_(nullptr) {} |
| 290 |
| 291 void InkDropImpl::HideHighlightOnRippleHiddenState::ShowOnHoverChanged() { |
| 292 if (GetInkDrop()->GetTargetInkDropState() != InkDropState::HIDDEN) |
| 293 return; |
| 294 NoAutoHighlightHiddenState::ShowOnHoverChanged(); |
| 295 } |
| 296 |
| 297 void InkDropImpl::HideHighlightOnRippleHiddenState::OnHoverChanged() { |
| 298 if (GetInkDrop()->GetTargetInkDropState() != InkDropState::HIDDEN) |
| 299 return; |
| 300 NoAutoHighlightHiddenState::OnHoverChanged(); |
| 301 } |
| 302 |
| 303 void InkDropImpl::HideHighlightOnRippleHiddenState::ShowOnFocusChanged() { |
| 304 if (GetInkDrop()->GetTargetInkDropState() != InkDropState::HIDDEN) |
| 305 return; |
| 306 NoAutoHighlightHiddenState::ShowOnFocusChanged(); |
| 307 } |
| 308 |
| 309 void InkDropImpl::HideHighlightOnRippleHiddenState::OnFocusChanged() { |
| 310 if (GetInkDrop()->GetTargetInkDropState() != InkDropState::HIDDEN) |
| 311 return; |
| 312 NoAutoHighlightHiddenState::OnFocusChanged(); |
| 313 } |
| 314 |
| 315 void InkDropImpl::HideHighlightOnRippleHiddenState::AnimationStarted( |
| 316 InkDropState ink_drop_state) { |
| 317 if (ink_drop_state == views::InkDropState::DEACTIVATED && |
| 318 GetInkDrop()->is_focused_) { |
| 319 GetInkDrop()->ink_drop_ripple_->HideImmediately(); |
| 320 GetInkDrop()->SetHighlightState( |
| 321 state_factory()->CreateVisibleState(base::TimeDelta(), false)); |
| 322 } |
| 323 } |
| 324 |
| 325 void InkDropImpl::HideHighlightOnRippleHiddenState::AnimationEnded( |
| 326 InkDropState ink_drop_state, |
| 327 InkDropAnimationEndedReason reason) { |
| 328 if (ink_drop_state == InkDropState::HIDDEN) { |
| 329 // Re-highlight, as necessary. For hover, there's a delay; for focus, jump |
| 330 // straight into the animation. |
| 331 if (GetInkDrop()->ShouldHighlightBasedOnFocus()) { |
| 332 GetInkDrop()->SetHighlightState( |
| 333 state_factory()->CreateVisibleState(base::TimeDelta(), false)); |
| 334 return; |
| 335 } else { |
| 336 StartHighlightAfterRippleTimer(); |
| 337 } |
| 338 } |
| 339 } |
| 340 |
| 341 void InkDropImpl::HideHighlightOnRippleHiddenState:: |
| 342 StartHighlightAfterRippleTimer() { |
| 343 highlight_after_ripple_timer_.reset(new base::OneShotTimer); |
| 344 highlight_after_ripple_timer_->Start( |
| 345 FROM_HERE, |
| 346 base::TimeDelta::FromMilliseconds(kHoverFadeInAfterRippleDelayMs), |
| 347 base::Bind(&InkDropImpl::HideHighlightOnRippleHiddenState:: |
| 348 HighlightAfterRippleTimerFired, |
| 349 base::Unretained(this))); |
| 350 } |
| 351 |
| 352 void InkDropImpl::HideHighlightOnRippleHiddenState:: |
| 353 HighlightAfterRippleTimerFired() { |
| 354 highlight_after_ripple_timer_.reset(); |
| 355 if (GetInkDrop()->GetTargetInkDropState() == InkDropState::HIDDEN && |
| 356 GetInkDrop()->ShouldHighlight()) { |
| 357 GetInkDrop()->SetHighlightState(state_factory()->CreateVisibleState( |
| 358 base::TimeDelta::FromMilliseconds( |
| 359 kHighlightFadeInOnRippleHidingDurationMs), |
| 360 true)); |
| 361 } |
| 362 } |
| 363 |
| 364 // HideHighlightOnRippleVisibleState definition |
| 365 |
| 366 InkDropImpl::HideHighlightOnRippleVisibleState:: |
| 367 HideHighlightOnRippleVisibleState(HighlightStateFactory* state_factory, |
| 368 base::TimeDelta animation_duration, |
| 369 bool explode) |
| 370 : InkDropImpl::NoAutoHighlightVisibleState(state_factory, |
| 371 animation_duration, |
| 372 explode) {} |
| 373 |
| 374 void InkDropImpl::HideHighlightOnRippleVisibleState::AnimationStarted( |
| 375 InkDropState ink_drop_state) { |
| 376 if (ink_drop_state != InkDropState::HIDDEN) { |
| 377 GetInkDrop()->SetHighlightState(state_factory()->CreateHiddenState( |
| 378 base::TimeDelta::FromMilliseconds( |
| 379 kHighlightFadeOutOnRippleShowingDurationMs), |
| 380 true)); |
| 381 } |
| 382 } |
| 383 |
| 384 // |
| 385 // AutoHighlightMode::SHOW_ON_RIPPLE states |
| 386 // |
| 387 |
| 388 // Extends the base hidden state to show the highlight when the ripple becomes |
| 389 // visible. |
| 390 class InkDropImpl::ShowHighlightOnRippleHiddenState |
| 391 : public InkDropImpl::NoAutoHighlightHiddenState { |
| 392 public: |
| 393 ShowHighlightOnRippleHiddenState(HighlightStateFactory* state_factory, |
| 394 base::TimeDelta animation_duration, |
| 395 bool explode); |
| 396 |
| 397 // InkDropImpl::NoAutoHighlightHiddenState: |
| 398 void AnimationStarted(InkDropState ink_drop_state) override; |
| 399 |
| 400 private: |
| 401 DISALLOW_COPY_AND_ASSIGN(ShowHighlightOnRippleHiddenState); |
| 402 }; |
| 403 |
| 404 // Extends the base visible state to hide the highlight when the ripple becomes |
| 405 // hidden. |
| 406 class InkDropImpl::ShowHighlightOnRippleVisibleState |
| 407 : public InkDropImpl::NoAutoHighlightVisibleState { |
| 408 public: |
| 409 ShowHighlightOnRippleVisibleState(HighlightStateFactory* state_factory, |
| 410 base::TimeDelta animation_duration, |
| 411 bool explode); |
| 412 |
| 413 // InkDropImpl::NoAutoHighlightVisibleState: |
| 414 void ShowOnHoverChanged() override; |
| 415 void OnHoverChanged() override; |
| 416 void ShowOnFocusChanged() override; |
| 417 void OnFocusChanged() override; |
| 418 void AnimationStarted(InkDropState ink_drop_state) override; |
| 419 |
| 420 private: |
| 421 DISALLOW_COPY_AND_ASSIGN(ShowHighlightOnRippleVisibleState); |
| 422 }; |
| 423 |
| 424 // ShowHighlightOnRippleHiddenState definition |
| 425 |
| 426 InkDropImpl::ShowHighlightOnRippleHiddenState::ShowHighlightOnRippleHiddenState( |
| 427 HighlightStateFactory* state_factory, |
| 428 base::TimeDelta animation_duration, |
| 429 bool explode) |
| 430 : InkDropImpl::NoAutoHighlightHiddenState(state_factory, |
| 431 animation_duration, |
| 432 explode) {} |
| 433 |
| 434 void InkDropImpl::ShowHighlightOnRippleHiddenState::AnimationStarted( |
| 435 InkDropState ink_drop_state) { |
| 436 if (ink_drop_state != views::InkDropState::HIDDEN) { |
| 437 GetInkDrop()->SetHighlightState(state_factory()->CreateVisibleState( |
| 438 base::TimeDelta::FromMilliseconds( |
| 439 kHighlightFadeInOnRippleShowingDurationMs), |
| 440 false)); |
| 441 } |
| 442 } |
| 443 |
| 444 // ShowHighlightOnRippleVisibleState definition |
| 445 |
| 446 InkDropImpl::ShowHighlightOnRippleVisibleState:: |
| 447 ShowHighlightOnRippleVisibleState(HighlightStateFactory* state_factory, |
| 448 base::TimeDelta animation_duration, |
| 449 bool explode) |
| 450 : InkDropImpl::NoAutoHighlightVisibleState(state_factory, |
| 451 animation_duration, |
| 452 explode) {} |
| 453 |
| 454 void InkDropImpl::ShowHighlightOnRippleVisibleState::ShowOnHoverChanged() { |
| 455 if (GetInkDrop()->GetTargetInkDropState() != InkDropState::HIDDEN) |
| 456 return; |
| 457 NoAutoHighlightVisibleState::ShowOnHoverChanged(); |
| 458 } |
| 459 |
| 460 void InkDropImpl::ShowHighlightOnRippleVisibleState::OnHoverChanged() { |
| 461 if (GetInkDrop()->GetTargetInkDropState() != InkDropState::HIDDEN) |
| 462 return; |
| 463 NoAutoHighlightVisibleState::OnHoverChanged(); |
| 464 } |
| 465 |
| 466 void InkDropImpl::ShowHighlightOnRippleVisibleState::ShowOnFocusChanged() { |
| 467 if (GetInkDrop()->GetTargetInkDropState() != InkDropState::HIDDEN) |
| 468 return; |
| 469 NoAutoHighlightVisibleState::ShowOnFocusChanged(); |
| 470 } |
| 471 |
| 472 void InkDropImpl::ShowHighlightOnRippleVisibleState::OnFocusChanged() { |
| 473 if (GetInkDrop()->GetTargetInkDropState() != InkDropState::HIDDEN) |
| 474 return; |
| 475 NoAutoHighlightVisibleState::OnFocusChanged(); |
| 476 } |
| 477 |
| 478 void InkDropImpl::ShowHighlightOnRippleVisibleState::AnimationStarted( |
| 479 InkDropState ink_drop_state) { |
| 480 if (ink_drop_state == InkDropState::HIDDEN && |
| 481 !GetInkDrop()->ShouldHighlight()) { |
| 482 GetInkDrop()->SetHighlightState(state_factory()->CreateHiddenState( |
| 483 base::TimeDelta::FromMilliseconds( |
| 484 kHighlightFadeOutOnRippleHidingDurationMs), |
| 485 false)); |
| 486 } |
| 487 } |
| 488 |
| 489 InkDropImpl::HighlightStateFactory::HighlightStateFactory( |
| 490 InkDropImpl::AutoHighlightMode highlight_mode, |
| 491 InkDropImpl* ink_drop) |
| 492 : highlight_mode_(highlight_mode), ink_drop_(ink_drop) {} |
| 493 |
| 494 std::unique_ptr<InkDropImpl::HighlightState> |
| 495 InkDropImpl::HighlightStateFactory::CreateStartState() { |
| 496 switch (highlight_mode_) { |
| 497 case InkDropImpl::AutoHighlightMode::NONE: |
| 498 return base::MakeUnique<NoAutoHighlightHiddenState>( |
| 499 this, base::TimeDelta(), false); |
| 500 case InkDropImpl::AutoHighlightMode::HIDE_ON_RIPPLE: |
| 501 return base::MakeUnique<HideHighlightOnRippleHiddenState>( |
| 502 this, base::TimeDelta(), false); |
| 503 case InkDropImpl::AutoHighlightMode::SHOW_ON_RIPPLE: |
| 504 return base::MakeUnique<ShowHighlightOnRippleHiddenState>( |
| 505 this, base::TimeDelta(), false); |
| 506 } |
| 507 // Required for some compilers. |
| 508 NOTREACHED(); |
| 509 return nullptr; |
| 510 } |
| 511 |
| 512 std::unique_ptr<InkDropImpl::HighlightState> |
| 513 InkDropImpl::HighlightStateFactory::CreateHiddenState( |
| 514 base::TimeDelta animation_duration, |
| 515 bool explode) { |
| 516 switch (highlight_mode_) { |
| 517 case InkDropImpl::AutoHighlightMode::NONE: |
| 518 return base::MakeUnique<NoAutoHighlightHiddenState>( |
| 519 this, animation_duration, explode); |
| 520 case InkDropImpl::AutoHighlightMode::HIDE_ON_RIPPLE: |
| 521 return base::MakeUnique<HideHighlightOnRippleHiddenState>( |
| 522 this, animation_duration, explode); |
| 523 case InkDropImpl::AutoHighlightMode::SHOW_ON_RIPPLE: |
| 524 return base::MakeUnique<ShowHighlightOnRippleHiddenState>( |
| 525 this, animation_duration, explode); |
| 526 } |
| 527 // Required for some compilers. |
| 528 NOTREACHED(); |
| 529 return nullptr; |
| 530 } |
| 531 |
| 532 std::unique_ptr<InkDropImpl::HighlightState> |
| 533 InkDropImpl::HighlightStateFactory::CreateVisibleState( |
| 534 base::TimeDelta animation_duration, |
| 535 bool explode) { |
| 536 switch (highlight_mode_) { |
| 537 case InkDropImpl::AutoHighlightMode::NONE: |
| 538 return base::MakeUnique<NoAutoHighlightVisibleState>( |
| 539 this, animation_duration, explode); |
| 540 case InkDropImpl::AutoHighlightMode::HIDE_ON_RIPPLE: |
| 541 return base::MakeUnique<HideHighlightOnRippleVisibleState>( |
| 542 this, animation_duration, explode); |
| 543 case InkDropImpl::AutoHighlightMode::SHOW_ON_RIPPLE: |
| 544 return base::MakeUnique<ShowHighlightOnRippleVisibleState>( |
| 545 this, animation_duration, explode); |
| 546 } |
| 547 // Required for some compilers. |
| 548 NOTREACHED(); |
| 549 return nullptr; |
| 550 } |
| 551 |
| 53 InkDropImpl::InkDropImpl(InkDropHost* ink_drop_host) | 552 InkDropImpl::InkDropImpl(InkDropHost* ink_drop_host) |
| 54 : ink_drop_host_(ink_drop_host), | 553 : ink_drop_host_(ink_drop_host), |
| 55 root_layer_(new ui::Layer(ui::LAYER_NOT_DRAWN)), | 554 root_layer_(new ui::Layer(ui::LAYER_NOT_DRAWN)), |
| 56 root_layer_added_to_host_(false), | 555 root_layer_added_to_host_(false), |
| 556 show_highlight_on_hover_(true), |
| 557 show_highlight_on_focus_(false), |
| 57 is_hovered_(false), | 558 is_hovered_(false), |
| 58 is_focused_(false), | 559 is_focused_(false), |
| 59 highlight_after_ripple_timer_(nullptr) { | 560 exiting_highlight_state_(false) { |
| 561 SetAutoHighlightMode(AutoHighlightMode::NONE); |
| 60 root_layer_->set_name("InkDropImpl:RootLayer"); | 562 root_layer_->set_name("InkDropImpl:RootLayer"); |
| 61 } | 563 } |
| 62 | 564 |
| 63 InkDropImpl::~InkDropImpl() { | 565 InkDropImpl::~InkDropImpl() { |
| 64 // Explicitly destroy the InkDropRipple so that this still exists if | 566 // Explicitly destroy the InkDropRipple so that this still exists if |
| 65 // views::InkDropRippleObserver methods are called on this. | 567 // views::InkDropRippleObserver methods are called on this. |
| 66 DestroyInkDropRipple(); | 568 DestroyInkDropRipple(); |
| 67 DestroyInkDropHighlight(); | 569 DestroyInkDropHighlight(); |
| 68 } | 570 } |
| 69 | 571 |
| 572 void InkDropImpl::SetShowHighlightOnHover(bool show_highlight_on_hover) { |
| 573 show_highlight_on_hover_ = show_highlight_on_hover; |
| 574 highlight_state_->ShowOnHoverChanged(); |
| 575 } |
| 576 |
| 577 void InkDropImpl::SetShowHighlightOnFocus(bool show_highlight_on_focus) { |
| 578 show_highlight_on_focus_ = show_highlight_on_focus; |
| 579 highlight_state_->ShowOnFocusChanged(); |
| 580 } |
| 581 |
| 582 void InkDropImpl::SetAutoHighlightMode(AutoHighlightMode auto_highlight_mode) { |
| 583 // Exit the current state completely first in case state tear down accesses |
| 584 // the current |highlight_state_factory_| instance. |
| 585 ExitHighlightState(); |
| 586 highlight_state_factory_ = |
| 587 base::MakeUnique<HighlightStateFactory>(auto_highlight_mode, this); |
| 588 SetHighlightState(highlight_state_factory_->CreateStartState()); |
| 589 } |
| 590 |
| 70 InkDropState InkDropImpl::GetTargetInkDropState() const { | 591 InkDropState InkDropImpl::GetTargetInkDropState() const { |
| 71 if (!ink_drop_ripple_) | 592 if (!ink_drop_ripple_) |
| 72 return InkDropState::HIDDEN; | 593 return InkDropState::HIDDEN; |
| 73 return ink_drop_ripple_->target_ink_drop_state(); | 594 return ink_drop_ripple_->target_ink_drop_state(); |
| 74 } | 595 } |
| 75 | 596 |
| 76 void InkDropImpl::AnimateToState(InkDropState ink_drop_state) { | 597 void InkDropImpl::AnimateToState(InkDropState ink_drop_state) { |
| 77 // Never animate hidden -> hidden, since that will add layers which may never | 598 // Never animate hidden -> hidden, since that will add layers which may never |
| 78 // be needed. Other same-state transitions may restart animations. | 599 // be needed. Other same-state transitions may restart animations. |
| 79 if (ink_drop_state == InkDropState::HIDDEN && | 600 if (ink_drop_state == InkDropState::HIDDEN && |
| 80 GetTargetInkDropState() == InkDropState::HIDDEN) | 601 GetTargetInkDropState() == InkDropState::HIDDEN) |
| 81 return; | 602 return; |
| 82 | 603 |
| 83 DestroyHiddenTargetedAnimations(); | 604 DestroyHiddenTargetedAnimations(); |
| 84 if (!ink_drop_ripple_) | 605 if (!ink_drop_ripple_) |
| 85 CreateInkDropRipple(); | 606 CreateInkDropRipple(); |
| 86 | |
| 87 if (ink_drop_ripple_->OverridesHighlight()) { | |
| 88 // When deactivating and the host is focused, snap back to the highlight | |
| 89 // state. (In the case of highlighting due to hover, we'll animate the | |
| 90 // highlight back in after a delay.) | |
| 91 if (ink_drop_state == views::InkDropState::DEACTIVATED && is_focused_) { | |
| 92 ink_drop_ripple_->HideImmediately(); | |
| 93 SetHighlight(true, base::TimeDelta(), false); | |
| 94 return; | |
| 95 } | |
| 96 | |
| 97 if (ink_drop_state != views::InkDropState::HIDDEN) { | |
| 98 SetHighlight(false, base::TimeDelta::FromMilliseconds( | |
| 99 kHighlightFadeOutBeforeRippleDurationMs), | |
| 100 true); | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 ink_drop_ripple_->AnimateToState(ink_drop_state); | 607 ink_drop_ripple_->AnimateToState(ink_drop_state); |
| 105 } | 608 } |
| 106 | 609 |
| 107 void InkDropImpl::SnapToActivated() { | 610 void InkDropImpl::SnapToActivated() { |
| 108 DestroyHiddenTargetedAnimations(); | 611 DestroyHiddenTargetedAnimations(); |
| 109 if (!ink_drop_ripple_) | 612 if (!ink_drop_ripple_) |
| 110 CreateInkDropRipple(); | 613 CreateInkDropRipple(); |
| 111 | |
| 112 if (ink_drop_ripple_->OverridesHighlight()) | |
| 113 SetHighlight(false, base::TimeDelta(), false); | |
| 114 | |
| 115 ink_drop_ripple_->SnapToActivated(); | 614 ink_drop_ripple_->SnapToActivated(); |
| 116 } | 615 } |
| 117 | 616 |
| 118 void InkDropImpl::SetHovered(bool is_hovered) { | 617 void InkDropImpl::SetHovered(bool is_hovered) { |
| 119 is_hovered_ = is_hovered; | 618 is_hovered_ = is_hovered; |
| 120 SetHighlight(ShouldHighlight(), | 619 highlight_state_->OnHoverChanged(); |
| 121 ShouldHighlight() | |
| 122 ? base::TimeDelta::FromMilliseconds( | |
| 123 kHighlightFadeInFromUserInputDurationMs) | |
| 124 : base::TimeDelta::FromMilliseconds( | |
| 125 kHighlightFadeOutFromUserInputDurationMs), | |
| 126 false); | |
| 127 } | 620 } |
| 128 | 621 |
| 129 void InkDropImpl::SetFocused(bool is_focused) { | 622 void InkDropImpl::SetFocused(bool is_focused) { |
| 130 is_focused_ = is_focused; | 623 is_focused_ = is_focused; |
| 131 SetHighlight(ShouldHighlight(), base::TimeDelta(), false); | 624 highlight_state_->OnFocusChanged(); |
| 132 } | 625 } |
| 133 | 626 |
| 134 void InkDropImpl::DestroyHiddenTargetedAnimations() { | 627 void InkDropImpl::DestroyHiddenTargetedAnimations() { |
| 135 if (ink_drop_ripple_ && | 628 if (ink_drop_ripple_ && |
| 136 (ink_drop_ripple_->target_ink_drop_state() == InkDropState::HIDDEN || | 629 (ink_drop_ripple_->target_ink_drop_state() == InkDropState::HIDDEN || |
| 137 ShouldAnimateToHidden(ink_drop_ripple_->target_ink_drop_state()))) { | 630 ShouldAnimateToHidden(ink_drop_ripple_->target_ink_drop_state()))) { |
| 138 DestroyInkDropRipple(); | 631 DestroyInkDropRipple(); |
| 139 } | 632 } |
| 140 } | 633 } |
| 141 | 634 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 152 return; | 645 return; |
| 153 root_layer_->Remove(ink_drop_ripple_->GetRootLayer()); | 646 root_layer_->Remove(ink_drop_ripple_->GetRootLayer()); |
| 154 ink_drop_ripple_.reset(); | 647 ink_drop_ripple_.reset(); |
| 155 RemoveRootLayerFromHostIfNeeded(); | 648 RemoveRootLayerFromHostIfNeeded(); |
| 156 } | 649 } |
| 157 | 650 |
| 158 void InkDropImpl::CreateInkDropHighlight() { | 651 void InkDropImpl::CreateInkDropHighlight() { |
| 159 DestroyInkDropHighlight(); | 652 DestroyInkDropHighlight(); |
| 160 | 653 |
| 161 highlight_ = ink_drop_host_->CreateInkDropHighlight(); | 654 highlight_ = ink_drop_host_->CreateInkDropHighlight(); |
| 655 // TODO(bruthig): Remove check for null since all CreateInkDropHighlight() |
| 656 // methods should return a valid instance. |
| 162 if (!highlight_) | 657 if (!highlight_) |
| 163 return; | 658 return; |
| 164 highlight_->set_observer(this); | 659 highlight_->set_observer(this); |
| 165 root_layer_->Add(highlight_->layer()); | 660 root_layer_->Add(highlight_->layer()); |
| 166 AddRootLayerToHostIfNeeded(); | 661 AddRootLayerToHostIfNeeded(); |
| 167 } | 662 } |
| 168 | 663 |
| 169 void InkDropImpl::DestroyInkDropHighlight() { | 664 void InkDropImpl::DestroyInkDropHighlight() { |
| 170 if (!highlight_) | 665 if (!highlight_) |
| 171 return; | 666 return; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 191 } | 686 } |
| 192 } | 687 } |
| 193 | 688 |
| 194 bool InkDropImpl::IsHighlightFadingInOrVisible() const { | 689 bool InkDropImpl::IsHighlightFadingInOrVisible() const { |
| 195 return highlight_ && highlight_->IsFadingInOrVisible(); | 690 return highlight_ && highlight_->IsFadingInOrVisible(); |
| 196 } | 691 } |
| 197 | 692 |
| 198 // ----------------------------------------------------------------------------- | 693 // ----------------------------------------------------------------------------- |
| 199 // views::InkDropRippleObserver: | 694 // views::InkDropRippleObserver: |
| 200 | 695 |
| 201 void InkDropImpl::AnimationStarted(InkDropState ink_drop_state) {} | 696 void InkDropImpl::AnimationStarted(InkDropState ink_drop_state) { |
| 697 highlight_state_->AnimationStarted(ink_drop_state); |
| 698 } |
| 202 | 699 |
| 203 void InkDropImpl::AnimationEnded(InkDropState ink_drop_state, | 700 void InkDropImpl::AnimationEnded(InkDropState ink_drop_state, |
| 204 InkDropAnimationEndedReason reason) { | 701 InkDropAnimationEndedReason reason) { |
| 702 highlight_state_->AnimationEnded(ink_drop_state, reason); |
| 205 if (reason != InkDropAnimationEndedReason::SUCCESS) | 703 if (reason != InkDropAnimationEndedReason::SUCCESS) |
| 206 return; | 704 return; |
| 207 if (ShouldAnimateToHidden(ink_drop_state)) { | 705 if (ShouldAnimateToHidden(ink_drop_state)) { |
| 208 ink_drop_ripple_->AnimateToState(views::InkDropState::HIDDEN); | 706 ink_drop_ripple_->AnimateToState(views::InkDropState::HIDDEN); |
| 209 } else if (ink_drop_state == views::InkDropState::HIDDEN) { | 707 } else if (ink_drop_state == views::InkDropState::HIDDEN) { |
| 210 // Re-highlight, as necessary. For hover, there's a delay; for focus, jump | |
| 211 // straight into the animation. | |
| 212 if (!IsHighlightFadingInOrVisible()) { | |
| 213 if (is_focused_) | |
| 214 HighlightAfterRippleTimerFired(); | |
| 215 else if (is_hovered_) | |
| 216 StartHighlightAfterRippleTimer(); | |
| 217 } | |
| 218 | |
| 219 // TODO(bruthig): Investigate whether creating and destroying | 708 // TODO(bruthig): Investigate whether creating and destroying |
| 220 // InkDropRipples is expensive and consider creating an | 709 // InkDropRipples is expensive and consider creating an |
| 221 // InkDropRipplePool. See www.crbug.com/522175. | 710 // InkDropRipplePool. See www.crbug.com/522175. |
| 222 DestroyInkDropRipple(); | 711 DestroyInkDropRipple(); |
| 223 } | 712 } |
| 224 } | 713 } |
| 225 | 714 |
| 226 // ----------------------------------------------------------------------------- | 715 // ----------------------------------------------------------------------------- |
| 227 // views::InkDropHighlightObserver: | 716 // views::InkDropHighlightObserver: |
| 228 | 717 |
| 229 void InkDropImpl::AnimationStarted( | 718 void InkDropImpl::AnimationStarted( |
| 230 InkDropHighlight::AnimationType animation_type) {} | 719 InkDropHighlight::AnimationType animation_type) {} |
| 231 | 720 |
| 232 void InkDropImpl::AnimationEnded(InkDropHighlight::AnimationType animation_type, | 721 void InkDropImpl::AnimationEnded(InkDropHighlight::AnimationType animation_type, |
| 233 InkDropAnimationEndedReason reason) { | 722 InkDropAnimationEndedReason reason) { |
| 234 if (animation_type == InkDropHighlight::FADE_OUT && | 723 if (animation_type == InkDropHighlight::FADE_OUT && |
| 235 reason == InkDropAnimationEndedReason::SUCCESS) { | 724 reason == InkDropAnimationEndedReason::SUCCESS) { |
| 236 DestroyInkDropHighlight(); | 725 DestroyInkDropHighlight(); |
| 237 } | 726 } |
| 238 } | 727 } |
| 239 | 728 |
| 240 void InkDropImpl::SetHighlight(bool should_highlight, | 729 void InkDropImpl::SetHighlight(bool should_highlight, |
| 241 base::TimeDelta animation_duration, | 730 base::TimeDelta animation_duration, |
| 242 bool explode) { | 731 bool explode) { |
| 243 highlight_after_ripple_timer_.reset(); | |
| 244 | |
| 245 if (IsHighlightFadingInOrVisible() == should_highlight) | 732 if (IsHighlightFadingInOrVisible() == should_highlight) |
| 246 return; | 733 return; |
| 247 | 734 |
| 248 if (should_highlight) { | 735 if (should_highlight) { |
| 249 CreateInkDropHighlight(); | 736 CreateInkDropHighlight(); |
| 250 if (highlight_ && | 737 // TODO(bruthig): Remove check for null since all CreateInkDropHighlight() |
| 251 !(ink_drop_ripple_ && ink_drop_ripple_->IsVisible() && | 738 // methods should return a valid instance. |
| 252 ink_drop_ripple_->OverridesHighlight())) { | 739 if (highlight_) |
| 253 highlight_->FadeIn(animation_duration); | 740 highlight_->FadeIn(animation_duration); |
| 254 } | |
| 255 } else { | 741 } else { |
| 256 highlight_->FadeOut(animation_duration, explode); | 742 highlight_->FadeOut(animation_duration, explode); |
| 257 } | 743 } |
| 258 } | 744 } |
| 259 | 745 |
| 260 bool InkDropImpl::ShouldHighlight() const { | 746 bool InkDropImpl::ShouldHighlight() const { |
| 261 return is_focused_ || is_hovered_; | 747 return ShouldHighlightBasedOnFocus() || |
| 748 (show_highlight_on_hover_ && is_hovered_); |
| 262 } | 749 } |
| 263 | 750 |
| 264 void InkDropImpl::StartHighlightAfterRippleTimer() { | 751 bool InkDropImpl::ShouldHighlightBasedOnFocus() const { |
| 265 highlight_after_ripple_timer_.reset(new base::OneShotTimer); | 752 return show_highlight_on_focus_ && is_focused_; |
| 266 highlight_after_ripple_timer_->Start( | |
| 267 FROM_HERE, | |
| 268 base::TimeDelta::FromMilliseconds(kHoverFadeInAfterRippleDelayMs), | |
| 269 base::Bind(&InkDropImpl::HighlightAfterRippleTimerFired, | |
| 270 base::Unretained(this))); | |
| 271 } | 753 } |
| 272 | 754 |
| 273 void InkDropImpl::HighlightAfterRippleTimerFired() { | 755 void InkDropImpl::SetHighlightState( |
| 274 SetHighlight(true, base::TimeDelta::FromMilliseconds( | 756 std::unique_ptr<HighlightState> highlight_state) { |
| 275 kHighlightFadeInAfterRippleDurationMs), | 757 ExitHighlightState(); |
| 276 true); | 758 highlight_state_ = std::move(highlight_state); |
| 277 highlight_after_ripple_timer_.reset(); | 759 highlight_state_->Enter(); |
| 760 } |
| 761 |
| 762 void InkDropImpl::ExitHighlightState() { |
| 763 DCHECK(!exiting_highlight_state_) << "HighlightStates should not be changed " |
| 764 "within a call to " |
| 765 "HighlightState::Exit()."; |
| 766 if (highlight_state_) { |
| 767 base::AutoReset<bool> exit_guard(&exiting_highlight_state_, true); |
| 768 highlight_state_->Exit(); |
| 769 } |
| 770 highlight_state_ = nullptr; |
| 278 } | 771 } |
| 279 | 772 |
| 280 } // namespace views | 773 } // namespace views |
| OLD | NEW |