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

Side by Side Diff: ash/wm/session_state_animator_impl.cc

Issue 326813004: Added quick lock mechanism while in Touchview (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add docs for TestSessionStateAnimator::AnimationSequence. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ash/wm/session_state_animator.h" 5 #include "ash/wm/session_state_animator_impl.h"
6
7 #include <vector>
6 8
7 #include "ash/shell.h" 9 #include "ash/shell.h"
8 #include "ash/shell_window_ids.h" 10 #include "ash/shell_window_ids.h"
9 #include "ash/wm/window_animations.h" 11 #include "ash/wm/window_animations.h"
10 #include "ui/aura/client/aura_constants.h" 12 #include "ui/aura/client/aura_constants.h"
11 #include "ui/aura/window_event_dispatcher.h" 13 #include "ui/aura/window_event_dispatcher.h"
12 #include "ui/compositor/layer_animation_observer.h" 14 #include "ui/compositor/layer_animation_observer.h"
13 #include "ui/compositor/layer_animation_sequence.h" 15 #include "ui/compositor/layer_animation_sequence.h"
14 #include "ui/compositor/scoped_layer_animation_settings.h" 16 #include "ui/compositor/scoped_layer_animation_settings.h"
15 #include "ui/views/widget/widget.h" 17 #include "ui/views/widget/widget.h"
(...skipping 13 matching lines...) Expand all
29 31
30 // Returns the transform that should be applied to containers for the slow-close 32 // Returns the transform that should be applied to containers for the slow-close
31 // animation. 33 // animation.
32 gfx::Transform GetSlowCloseTransform() { 34 gfx::Transform GetSlowCloseTransform() {
33 gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size(); 35 gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
34 gfx::Transform transform; 36 gfx::Transform transform;
35 transform.Translate( 37 transform.Translate(
36 floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.width() + 0.5), 38 floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.width() + 0.5),
37 floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.height() + 0.5)); 39 floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.height() + 0.5));
38 transform.Scale(kSlowCloseSizeRatio, kSlowCloseSizeRatio); 40 transform.Scale(kSlowCloseSizeRatio, kSlowCloseSizeRatio);
39 return transform; 41 return transform;
40 } 42 }
41 43
42 // Returns the transform that should be applied to containers for the fast-close 44 // Returns the transform that should be applied to containers for the fast-close
43 // animation. 45 // animation.
44 gfx::Transform GetFastCloseTransform() { 46 gfx::Transform GetFastCloseTransform() {
45 gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size(); 47 gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
46 gfx::Transform transform; 48 gfx::Transform transform;
49
47 transform.Translate(floor(0.5 * root_size.width() + 0.5), 50 transform.Translate(floor(0.5 * root_size.width() + 0.5),
48 floor(0.5 * root_size.height() + 0.5)); 51 floor(0.5 * root_size.height() + 0.5));
49 transform.Scale(kMinimumScale, kMinimumScale); 52 transform.Scale(kMinimumScale, kMinimumScale);
50 return transform; 53 return transform;
51 } 54 }
52 55
53 // Slowly shrinks |window| to a slightly-smaller size. 56 // Slowly shrinks |window| to a slightly-smaller size.
54 void StartSlowCloseAnimationForWindow(aura::Window* window, 57 void StartSlowCloseAnimationForWindow(aura::Window* window,
55 base::TimeDelta duration, 58 base::TimeDelta duration,
56 ui::LayerAnimationObserver* observer) { 59 ui::LayerAnimationObserver* observer) {
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 animator->set_preemption_strategy( 278 animator->set_preemption_strategy(
276 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 279 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
277 280
278 animator->StartTogether(animations); 281 animator->StartTogether(animations);
279 } 282 }
280 283
281 // Animation observer that will drop animated foreground once animation is 284 // Animation observer that will drop animated foreground once animation is
282 // finished. It is used in when undoing shutdown animation. 285 // finished. It is used in when undoing shutdown animation.
283 class CallbackAnimationObserver : public ui::LayerAnimationObserver { 286 class CallbackAnimationObserver : public ui::LayerAnimationObserver {
284 public: 287 public:
285 explicit CallbackAnimationObserver(base::Callback<void(void)> &callback) 288 explicit CallbackAnimationObserver(base::Closure callback)
286 : callback_(callback) { 289 : callback_(callback) {
287 } 290 }
288 virtual ~CallbackAnimationObserver() { 291 virtual ~CallbackAnimationObserver() {
289 } 292 }
290 293
291 private: 294 private:
292 // Overridden from ui::LayerAnimationObserver: 295 // Overridden from ui::LayerAnimationObserver:
293 virtual void OnLayerAnimationEnded(ui::LayerAnimationSequence* seq) 296 virtual void OnLayerAnimationEnded(ui::LayerAnimationSequence* seq)
294 OVERRIDE { 297 OVERRIDE {
295 // Drop foreground once animation is over. 298 // Drop foreground once animation is over.
296 callback_.Run(); 299 callback_.Run();
297 delete this; 300 delete this;
298 } 301 }
299 302
300 virtual void OnLayerAnimationAborted(ui::LayerAnimationSequence* seq) 303 virtual void OnLayerAnimationAborted(ui::LayerAnimationSequence* seq)
301 OVERRIDE { 304 OVERRIDE {
302 // Drop foreground once animation is over. 305 // Drop foreground once animation is over.
303 callback_.Run(); 306 callback_.Run();
304 delete this; 307 delete this;
305 } 308 }
306 309
307 virtual void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq) 310 virtual void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq)
308 OVERRIDE {} 311 OVERRIDE {}
309 312
310 base::Callback<void(void)> callback_; 313 base::Closure callback_;
311 314
312 DISALLOW_COPY_AND_ASSIGN(CallbackAnimationObserver); 315 DISALLOW_COPY_AND_ASSIGN(CallbackAnimationObserver);
313 }; 316 };
314 317
315 318
316 bool IsLayerAnimated(ui::Layer* layer, 319 bool IsLayerAnimated(ui::Layer* layer,
317 SessionStateAnimator::AnimationType type) { 320 SessionStateAnimator::AnimationType type) {
318 switch (type) { 321 switch (type) {
319 case SessionStateAnimator::ANIMATION_PARTIAL_CLOSE: 322 case SessionStateAnimator::ANIMATION_PARTIAL_CLOSE:
320 if (layer->GetTargetTransform() != GetSlowCloseTransform()) 323 if (layer->GetTargetTransform() != GetSlowCloseTransform())
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 break; 381 break;
379 default: 382 default:
380 NOTREACHED() << "Unhandled animation type " << type; 383 NOTREACHED() << "Unhandled animation type " << type;
381 return false; 384 return false;
382 } 385 }
383 return true; 386 return true;
384 } 387 }
385 388
386 } // namespace 389 } // namespace
387 390
388 bool SessionStateAnimator::TestApi::ContainersAreAnimated( 391 // This observer is intended to use in cases when some action has to be taken
392 // once some animation successfully completes (i.e. it was not aborted).
393 // Observer will count a number of sequences it is attached to, and a number of
394 // finished sequences (either Ended or Aborted). Once these two numbers are
395 // equal, observer will delete itself, calling callback passed to constructor if
396 // there were no aborted animations.
397 // This way it can be either used to wait for some animation to be finished in
398 // multiple layers, to wait once a sequence of animations is finished in one
399 // layer or the mixture of both.
400 class SessionStateAnimatorImpl::AnimationSequence
401 : public SessionStateAnimator::AnimationSequence,
402 public ui::LayerAnimationObserver {
403 public:
404 explicit AnimationSequence(
405 SessionStateAnimatorImpl* animator,
406 base::Closure callback);
407
408 // SessionStateAnimator::AnimationSequence:
409 virtual void StartAnimation(
410 int container_mask,
411 SessionStateAnimator::AnimationType type,
412 SessionStateAnimator::AnimationSpeed speed) OVERRIDE;
413
414 private:
415 virtual ~AnimationSequence();
416
417 // ui::LayerAnimationObserver:
418 virtual void OnLayerAnimationEnded(
419 ui::LayerAnimationSequence* sequence) OVERRIDE;
420
421 virtual void OnLayerAnimationAborted(
422 ui::LayerAnimationSequence* sequence) OVERRIDE;
423
424 virtual void OnLayerAnimationScheduled(
425 ui::LayerAnimationSequence* sequence) OVERRIDE;
426
427 virtual void OnAttachedToSequence(
428 ui::LayerAnimationSequence* sequence) OVERRIDE;
429
430 SessionStateAnimatorImpl* animator_;
Daniel Erat 2014/09/08 16:16:03 nit: document that the animator isn't owned by thi
bruthig 2014/09/09 17:32:34 Done.
431
432 // Number of sequences this observer was attached to.
433 int sequences_attached_;
434
435 // Number of sequences either ended or aborted.
436 int sequences_completed_;
437
438 DISALLOW_COPY_AND_ASSIGN(AnimationSequence);
439 };
440
441 SessionStateAnimatorImpl::AnimationSequence::AnimationSequence(
Daniel Erat 2014/09/08 16:16:03 nit: these are all short; consider inlining them i
bruthig 2014/09/09 17:32:34 Done.
442 SessionStateAnimatorImpl* animator,
443 base::Closure callback)
444 : SessionStateAnimator::AnimationSequence(callback),
445 animator_(animator),
446 sequences_attached_(0),
447 sequences_completed_(0) {
448 }
449
450 SessionStateAnimatorImpl::AnimationSequence::
451 ~AnimationSequence() {
452 }
453
454 void SessionStateAnimatorImpl::AnimationSequence::StartAnimation(
455 int container_mask,
456 SessionStateAnimator::AnimationType type,
457 SessionStateAnimator::AnimationSpeed speed) {
458 animator_->StartAnimationInSequence(container_mask, type, speed, this);
459 }
460
461 void SessionStateAnimatorImpl::AnimationSequence::OnLayerAnimationEnded(
462 ui::LayerAnimationSequence* sequence) {
463 sequences_completed_++;
464 if (sequences_completed_ == sequences_attached_) {
465 OnAnimationCompleted();
466 }
467 }
468
469 void SessionStateAnimatorImpl::AnimationSequence::
470 OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) {
471 sequences_completed_++;
472 if (sequences_completed_ == sequences_attached_)
473 OnAnimationAborted();
474 }
475
476 void SessionStateAnimatorImpl::AnimationSequence::
477 OnLayerAnimationScheduled(ui::LayerAnimationSequence* sequence) {
478 }
479
480 void SessionStateAnimatorImpl::AnimationSequence::OnAttachedToSequence(
481 ui::LayerAnimationSequence* sequence) {
482 LayerAnimationObserver::OnAttachedToSequence(sequence);
483 sequences_attached_++;
484 }
485
486 bool SessionStateAnimatorImpl::TestApi::ContainersAreAnimated(
389 int container_mask, AnimationType type) const { 487 int container_mask, AnimationType type) const {
390 aura::Window::Windows containers; 488 aura::Window::Windows containers;
391 animator_->GetContainers(container_mask, &containers); 489 animator_->GetContainers(container_mask, &containers);
392 for (aura::Window::Windows::const_iterator it = containers.begin(); 490 for (aura::Window::Windows::const_iterator it = containers.begin();
393 it != containers.end(); ++it) { 491 it != containers.end(); ++it) {
394 aura::Window* window = *it; 492 aura::Window* window = *it;
395 ui::Layer* layer = window->layer(); 493 ui::Layer* layer = window->layer();
396 if (!IsLayerAnimated(layer, type)) 494 if (!IsLayerAnimated(layer, type))
397 return false; 495 return false;
398 } 496 }
399 return true; 497 return true;
400 } 498 }
401 499
402 bool SessionStateAnimator::TestApi::RootWindowIsAnimated(AnimationType type) 500 bool SessionStateAnimatorImpl::TestApi::RootWindowIsAnimated(AnimationType type)
403 const { 501 const {
404 aura::Window* root_window = Shell::GetPrimaryRootWindow(); 502 aura::Window* root_window = Shell::GetPrimaryRootWindow();
405 ui::Layer* layer = root_window->layer(); 503 ui::Layer* layer = root_window->layer();
406 return IsLayerAnimated(layer, type); 504 return IsLayerAnimated(layer, type);
407 } 505 }
408 506
409 const int SessionStateAnimator::kAllLockScreenContainersMask = 507 SessionStateAnimatorImpl::SessionStateAnimatorImpl() {
410 SessionStateAnimator::LOCK_SCREEN_BACKGROUND |
411 SessionStateAnimator::LOCK_SCREEN_CONTAINERS |
412 SessionStateAnimator::LOCK_SCREEN_RELATED_CONTAINERS;
413
414 const int SessionStateAnimator::kAllContainersMask =
415 SessionStateAnimator::kAllLockScreenContainersMask |
416 SessionStateAnimator::DESKTOP_BACKGROUND |
417 SessionStateAnimator::LAUNCHER |
418 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS;
419
420 SessionStateAnimator::SessionStateAnimator() {
421 } 508 }
422 509
423 SessionStateAnimator::~SessionStateAnimator() { 510 SessionStateAnimatorImpl::~SessionStateAnimatorImpl() {
424 }
425
426 base::TimeDelta SessionStateAnimator::GetDuration(AnimationSpeed speed) {
427 switch (speed) {
428 case ANIMATION_SPEED_IMMEDIATE:
429 return base::TimeDelta();
430 case ANIMATION_SPEED_UNDOABLE:
431 return base::TimeDelta::FromMilliseconds(400);
432 case ANIMATION_SPEED_REVERT:
433 return base::TimeDelta::FromMilliseconds(150);
434 case ANIMATION_SPEED_FAST:
435 return base::TimeDelta::FromMilliseconds(150);
436 case ANIMATION_SPEED_SHOW_LOCK_SCREEN:
437 return base::TimeDelta::FromMilliseconds(200);
438 case ANIMATION_SPEED_MOVE_WINDOWS:
439 return base::TimeDelta::FromMilliseconds(350);
440 case ANIMATION_SPEED_UNDO_MOVE_WINDOWS:
441 return base::TimeDelta::FromMilliseconds(350);
442 case ANIMATION_SPEED_SHUTDOWN:
443 return base::TimeDelta::FromMilliseconds(1000);
444 case ANIMATION_SPEED_REVERT_SHUTDOWN:
445 return base::TimeDelta::FromMilliseconds(500);
446 }
447 // Satisfy compilers that do not understand that we will return from switch
448 // above anyway.
449 DCHECK(false) << "Unhandled animation speed " << speed;
450 return base::TimeDelta();
451 } 511 }
452 512
453 // Fills |containers| with the containers described by |container_mask|. 513 // Fills |containers| with the containers described by |container_mask|.
454 void SessionStateAnimator::GetContainers(int container_mask, 514 void SessionStateAnimatorImpl::GetContainers(int container_mask,
455 aura::Window::Windows* containers) { 515 aura::Window::Windows* containers) {
456 aura::Window* root_window = Shell::GetPrimaryRootWindow(); 516 aura::Window* root_window = Shell::GetPrimaryRootWindow();
457 containers->clear(); 517 containers->clear();
458 518
519 if (container_mask & ROOT_CONTAINER) {
520 containers->push_back(Shell::GetPrimaryRootWindow());
521 }
522
459 if (container_mask & DESKTOP_BACKGROUND) { 523 if (container_mask & DESKTOP_BACKGROUND) {
460 containers->push_back(Shell::GetContainer( 524 containers->push_back(Shell::GetContainer(
461 root_window, kShellWindowId_DesktopBackgroundContainer)); 525 root_window, kShellWindowId_DesktopBackgroundContainer));
462 } 526 }
463 if (container_mask & LAUNCHER) { 527 if (container_mask & LAUNCHER) {
464 containers->push_back( 528 containers->push_back(
465 Shell::GetContainer(root_window, kShellWindowId_ShelfContainer)); 529 Shell::GetContainer(root_window, kShellWindowId_ShelfContainer));
466 } 530 }
467 if (container_mask & NON_LOCK_SCREEN_CONTAINERS) { 531 if (container_mask & NON_LOCK_SCREEN_CONTAINERS) {
468 // TODO(antrim): Figure out a way to eliminate a need to exclude launcher 532 // TODO(antrim): Figure out a way to eliminate a need to exclude launcher
(...skipping 17 matching lines...) Expand all
486 if (container_mask & LOCK_SCREEN_CONTAINERS) { 550 if (container_mask & LOCK_SCREEN_CONTAINERS) {
487 containers->push_back(Shell::GetContainer( 551 containers->push_back(Shell::GetContainer(
488 root_window, kShellWindowId_LockScreenContainersContainer)); 552 root_window, kShellWindowId_LockScreenContainersContainer));
489 } 553 }
490 if (container_mask & LOCK_SCREEN_RELATED_CONTAINERS) { 554 if (container_mask & LOCK_SCREEN_RELATED_CONTAINERS) {
491 containers->push_back(Shell::GetContainer( 555 containers->push_back(Shell::GetContainer(
492 root_window, kShellWindowId_LockScreenRelatedContainersContainer)); 556 root_window, kShellWindowId_LockScreenRelatedContainersContainer));
493 } 557 }
494 } 558 }
495 559
496 void SessionStateAnimator::StartAnimation(int container_mask, 560 void SessionStateAnimatorImpl::StartAnimation(int container_mask,
Daniel Erat 2014/09/08 16:16:03 nit: move "int container_mask" to the next line an
bruthig 2014/09/09 17:32:34 Done.
497 AnimationType type, 561 SessionStateAnimator::AnimationType type,
Daniel Erat 2014/09/08 16:16:03 hmm, is the SessionStateAnimator:: needed here eve
bruthig 2014/09/09 17:32:34 Done.
498 AnimationSpeed speed) { 562 SessionStateAnimator::AnimationSpeed speed) {
499 aura::Window::Windows containers; 563 aura::Window::Windows containers;
500 GetContainers(container_mask, &containers); 564 GetContainers(container_mask, &containers);
501 for (aura::Window::Windows::const_iterator it = containers.begin(); 565 for (aura::Window::Windows::const_iterator it = containers.begin();
502 it != containers.end(); ++it) { 566 it != containers.end(); ++it) {
503 RunAnimationForWindow(*it, type, speed, NULL); 567 RunAnimationForWindow(*it, type, speed, NULL);
504 } 568 }
505 } 569 }
506 570
507 void SessionStateAnimator::StartAnimationWithCallback( 571 void SessionStateAnimatorImpl::StartAnimationWithCallback(
508 int container_mask, 572 int container_mask,
509 AnimationType type, 573 SessionStateAnimator::AnimationType type,
510 AnimationSpeed speed, 574 SessionStateAnimator::AnimationSpeed speed,
511 base::Callback<void(void)>& callback) { 575 base::Closure callback) {
512 aura::Window::Windows containers; 576 aura::Window::Windows containers;
513 GetContainers(container_mask, &containers); 577 GetContainers(container_mask, &containers);
514 for (aura::Window::Windows::const_iterator it = containers.begin(); 578 for (aura::Window::Windows::const_iterator it = containers.begin();
515 it != containers.end(); ++it) { 579 it != containers.end(); ++it) {
516 ui::LayerAnimationObserver* observer = 580 ui::LayerAnimationObserver* observer =
517 new CallbackAnimationObserver(callback); 581 new CallbackAnimationObserver(callback);
518 RunAnimationForWindow(*it, type, speed, observer); 582 RunAnimationForWindow(*it, type, speed, observer);
519 } 583 }
520 } 584 }
521 585
522 void SessionStateAnimator::StartAnimationWithObserver( 586 SessionStateAnimator::AnimationSequence*
587 SessionStateAnimatorImpl::BeginAnimationSequence(base::Closure callback) {
Daniel Erat 2014/09/08 16:16:03 nit: indent four spaces instead of two
bruthig 2014/09/09 17:32:34 Done.
588 return new AnimationSequence(this, callback);
589 }
590
591 void SessionStateAnimatorImpl::StartAnimationInSequence(
523 int container_mask, 592 int container_mask,
524 AnimationType type, 593 SessionStateAnimator::AnimationType type,
525 AnimationSpeed speed, 594 SessionStateAnimator::AnimationSpeed speed,
526 ui::LayerAnimationObserver* observer) { 595 AnimationSequence* observer) {
527 aura::Window::Windows containers; 596 aura::Window::Windows containers;
528 GetContainers(container_mask, &containers); 597 GetContainers(container_mask, &containers);
529 for (aura::Window::Windows::const_iterator it = containers.begin(); 598 for (aura::Window::Windows::const_iterator it = containers.begin();
530 it != containers.end(); ++it) { 599 it != containers.end(); ++it) {
531 RunAnimationForWindow(*it, type, speed, observer); 600 RunAnimationForWindow(*it, type, speed, observer);
532 } 601 }
533 } 602 }
534 603
535 void SessionStateAnimator::StartGlobalAnimation(AnimationType type, 604 void SessionStateAnimatorImpl::RunAnimationForWindow(
536 AnimationSpeed speed) {
537 aura::Window* root_window = Shell::GetPrimaryRootWindow();
538 RunAnimationForWindow(root_window, type, speed, NULL);
539 }
540
541 void SessionStateAnimator::RunAnimationForWindow(
542 aura::Window* window, 605 aura::Window* window,
543 AnimationType type, 606 SessionStateAnimator::AnimationType type,
544 AnimationSpeed speed, 607 SessionStateAnimator::AnimationSpeed speed,
545 ui::LayerAnimationObserver* observer) { 608 ui::LayerAnimationObserver* observer) {
546 base::TimeDelta duration = GetDuration(speed); 609 base::TimeDelta duration = GetDuration(speed);
547 610
548 switch (type) { 611 switch (type) {
549 case ANIMATION_PARTIAL_CLOSE: 612 case ANIMATION_PARTIAL_CLOSE:
550 StartSlowCloseAnimationForWindow(window, duration, observer); 613 StartSlowCloseAnimationForWindow(window, duration, observer);
551 break; 614 break;
552 case ANIMATION_UNDO_PARTIAL_CLOSE: 615 case ANIMATION_UNDO_PARTIAL_CLOSE:
553 StartUndoSlowCloseAnimationForWindow(window, duration, observer); 616 StartUndoSlowCloseAnimationForWindow(window, duration, observer);
554 break; 617 break;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 window, 1.0, duration, gfx::Tween::EASE_IN, observer); 662 window, 1.0, duration, gfx::Tween::EASE_IN, observer);
600 break; 663 break;
601 case ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS: 664 case ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS:
602 StartGrayscaleBrightnessAnimationForWindow( 665 StartGrayscaleBrightnessAnimationForWindow(
603 window, 0.0, duration, gfx::Tween::EASE_IN_OUT, observer); 666 window, 0.0, duration, gfx::Tween::EASE_IN_OUT, observer);
604 break; 667 break;
605 } 668 }
606 } 669 }
607 670
608 } // namespace ash 671 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698