1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/gfx/animation/multi_animation.h" 6 7 #include "base/logging.h" 8 #include "ui/gfx/animation/animation_delegate.h" 9 10 namespace gfx { 11 12 // Default interval, in ms. 13 static const int kDefaultTimerInterval = 20; 14 15 static int TotalTime(const MultiAnimation::Parts& parts) { 16 int time_ms = 0; 17 for (size_t i = 0; i < parts.size(); ++i) { 18 DCHECK(parts[i].end_time_ms - parts[i].start_time_ms >= parts[i].time_ms); 19 time_ms += parts[i].time_ms; 20 } 21 return time_ms; 22 } 23 24 MultiAnimation::MultiAnimation(const Parts& parts, 25 base::TimeDelta timer_interval) 26 : Animation(timer_interval), 27 parts_(parts), 28 cycle_time_ms_(TotalTime(parts)), 29 current_value_(0), 30 current_part_index_(0), 31 continuous_(true) { 32 DCHECK(!parts_.empty()); 33 } 34 35 MultiAnimation::~MultiAnimation() {} 36 37 // static. 38 base::TimeDelta MultiAnimation::GetDefaultTimerInterval() { 39 return base::TimeDelta::FromMilliseconds(kDefaultTimerInterval); 40 } 41 42 double MultiAnimation::GetCurrentValue() const { 43 return current_value_; 44 } 45 46 void MultiAnimation::Step(base::TimeTicks time_now) { 47 double last_value = current_value_; 48 size_t last_index = current_part_index_; 49 50 int delta = static_cast<int>((time_now - start_time()).InMilliseconds()); 51 if (delta >= cycle_time_ms_ && !continuous_) { 52 current_part_index_ = parts_.size() - 1; 53 current_value_ = Tween::CalculateValue(parts_[current_part_index_].type, 1); 54 Stop(); 55 return; 56 } 57 delta %= cycle_time_ms_; 58 const Part& part = GetPart(&delta, ¤t_part_index_); 59 double percent = static_cast<double>(delta + part.start_time_ms) / 60 static_cast<double>(part.end_time_ms); 61 DCHECK(percent <= 1); 62 current_value_ = Tween::CalculateValue(part.type, percent); 63 64 if ((current_value_ != last_value || current_part_index_ != last_index) && 65 delegate()) { 66 delegate()->AnimationProgressed(this); 67 } 68 } 69 70 void MultiAnimation::SetStartTime(base::TimeTicks start_time) { 71 Animation::SetStartTime(start_time); 72 current_value_ = 0; 73 current_part_index_ = 0; 74 } 75 76 const MultiAnimation::Part& MultiAnimation::GetPart(int* time_ms, 77 size_t* part_index) { 78 DCHECK(*time_ms < cycle_time_ms_); 79 80 for (size_t i = 0; i < parts_.size(); ++i) { 81 if (*time_ms < parts_[i].time_ms) { 82 *part_index = i; 83 return parts_[i]; 84 } 85 86 *time_ms -= parts_[i].time_ms; 87 } 88 NOTREACHED(); 89 *time_ms = 0; 90 *part_index = 0; 91 return parts_[0]; 92 } 93 94 } // namespace gfx 95