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/base/animation/multi_animation.h" 6 7#include "base/logging.h" 8#include "ui/base/animation/animation_delegate.h" 9 10namespace ui { 11 12// Default interval, in ms. 13static const int kDefaultTimerInterval = 20; 14 15static 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 24MultiAnimation::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 35MultiAnimation::~MultiAnimation() {} 36 37// static. 38base::TimeDelta MultiAnimation::GetDefaultTimerInterval() { 39 return base::TimeDelta::FromMilliseconds(kDefaultTimerInterval); 40} 41 42double MultiAnimation::GetCurrentValue() const { 43 return current_value_; 44} 45 46void 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 70void MultiAnimation::SetStartTime(base::TimeTicks start_time) { 71 Animation::SetStartTime(start_time); 72 current_value_ = 0; 73 current_part_index_ = 0; 74} 75 76const 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 ui 95