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

Side by Side Diff: ui/views/animation/ink_drop_impl.cc

Issue 2447523002: [ash-md] Added different highlighting modes to the InkDropImpl. (Closed)
Patch Set: Fixed InkDropHostView::GetInkDrop() to use CreateInkDrop(). Created 4 years, 1 month 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
« no previous file with comments | « ui/views/animation/ink_drop_impl.h ('k') | ui/views/animation/ink_drop_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « ui/views/animation/ink_drop_impl.h ('k') | ui/views/animation/ink_drop_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698