| /* |
| * Copyright (C) 2007 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of |
| * its contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef AnimationBase_h |
| #define AnimationBase_h |
| |
| #include "CSSPropertyNames.h" |
| #include "core/platform/animation/CSSAnimationData.h" |
| #include "core/rendering/style/RenderStyleConstants.h" |
| #include "wtf/RefCounted.h" |
| |
| namespace WebCore { |
| |
| class AnimationBase; |
| class AnimationController; |
| class CompositeAnimation; |
| class Element; |
| class Node; |
| class RenderObject; |
| class RenderStyle; |
| class TimingFunction; |
| |
| class AnimationBase : public RefCounted<AnimationBase> { |
| friend class CompositeAnimation; |
| friend class CSSPropertyAnimation; |
| |
| public: |
| AnimationBase(const CSSAnimationData* transition, RenderObject& renderer, CompositeAnimation* compAnim); |
| virtual ~AnimationBase() { } |
| |
| RenderObject* renderer() const { return m_object; } |
| void clear() |
| { |
| endAnimation(); |
| m_object = 0; |
| m_compAnim = 0; |
| } |
| |
| double duration() const; |
| |
| // Animations and Transitions go through the states below. When entering the STARTED state |
| // the animation is started. This may or may not require deferred response from the animator. |
| // If so, we stay in this state until that response is received (and it returns the start time). |
| // Otherwise, we use the current time as the start time and go immediately to AnimationStateLooping |
| // or AnimationStateEnding. |
| enum AnimState { |
| AnimationStateNew, // animation just created, animation not running yet |
| AnimationStateStartWaitTimer, // start timer running, waiting for fire |
| AnimationStateStartWaitStyleAvailable, // waiting for style setup so we can start animations |
| AnimationStateStartWaitResponse, // animation started, waiting for response |
| AnimationStateLooping, // response received, animation running, loop timer running, waiting for fire |
| AnimationStateEnding, // received, animation running, end timer running, waiting for fire |
| AnimationStatePausedWaitTimer, // in pause mode when animation started |
| AnimationStatePausedWaitStyleAvailable, // in pause mode when waiting for style setup |
| AnimationStatePausedWaitResponse, // animation paused when in STARTING state |
| AnimationStatePausedRun, // animation paused when in LOOPING or ENDING state |
| AnimationStateDone, // end timer fired, animation finished and removed |
| AnimationStateFillingForwards // animation has ended and is retaining its final value |
| }; |
| |
| enum AnimStateInput { |
| AnimationStateInputMakeNew, // reset back to new from any state |
| AnimationStateInputStartAnimation, // animation requests a start |
| AnimationStateInputRestartAnimation, // force a restart from any state |
| AnimationStateInputStartTimerFired, // start timer fired |
| AnimationStateInputStyleAvailable, // style is setup, ready to start animating |
| AnimationStateInputStartTimeSet, // m_startTime was set |
| AnimationStateInputLoopTimerFired, // loop timer fired |
| AnimationStateInputEndTimerFired, // end timer fired |
| AnimationStateInputPauseOverride, // pause an animation due to override |
| AnimationStateInputResumeOverride, // resume an overridden animation |
| AnimationStateInputPlayStateRunning, // play state paused -> running |
| AnimationStateInputPlayStatePaused, // play state running -> paused |
| AnimationStateInputEndAnimation // force an end from any state |
| }; |
| |
| // Called when animation is in AnimationStateNew to start animation |
| void updateStateMachine(AnimStateInput, double param); |
| |
| // Animation has actually started, at passed time |
| void onAnimationStartResponse(double startTime) |
| { |
| updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, startTime); |
| } |
| |
| // Called to change to or from paused state |
| void updatePlayState(EAnimPlayState); |
| bool playStatePlaying() const; |
| |
| bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer; } |
| bool preActive() const |
| { |
| return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer || m_animState == AnimationStateStartWaitStyleAvailable || m_animState == AnimationStateStartWaitResponse; |
| } |
| |
| bool postActive() const { return m_animState == AnimationStateDone; } |
| bool active() const { return !postActive() && !preActive(); } |
| bool running() const { return !isNew() && !postActive(); } |
| bool paused() const { return m_pauseTime >= 0; } |
| bool isNew() const { return m_animState == AnimationStateNew; } |
| bool waitingForStartTime() const { return m_animState == AnimationStateStartWaitResponse; } |
| bool waitingForStyleAvailable() const { return m_animState == AnimationStateStartWaitStyleAvailable; } |
| |
| virtual double timeToNextService(); |
| |
| double progress(double scale, double offset, const TimingFunction*) const; |
| |
| virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* /*currentStyle*/, RenderStyle* /*targetStyle*/, RefPtr<RenderStyle>& /*animatedStyle*/) = 0; |
| virtual void getAnimatedStyle(RefPtr<RenderStyle>& /*animatedStyle*/) = 0; |
| |
| virtual bool shouldFireEvents() const { return false; } |
| |
| void fireAnimationEventsIfNeeded(); |
| |
| void setAnimation(const CSSAnimationData* anim) { m_animation = const_cast<CSSAnimationData*>(anim); } |
| |
| // Return true if this animation is overridden. This will only be the case for |
| // ImplicitAnimations and is used to determine whether or not we should force |
| // set the start time. If an animation is overridden, it will probably not get |
| // back the AnimationStateInputStartTimeSet input. |
| virtual bool overridden() const { return false; } |
| |
| // Does this animation/transition involve the given property? |
| virtual bool affectsProperty(CSSPropertyID /*property*/) const { return false; } |
| |
| bool isAnimatingProperty(CSSPropertyID property, bool acceleratedOnly, bool isRunningNow) const |
| { |
| if (acceleratedOnly && !m_isAccelerated) |
| return false; |
| |
| if (isRunningNow) |
| return (!waitingToStart() && !postActive()) && affectsProperty(property); |
| |
| return !postActive() && affectsProperty(property); |
| } |
| |
| // FIXME: rename this using the "lists match" terminology. |
| bool isTransformFunctionListValid() const { return m_transformFunctionListValid; } |
| bool filterFunctionListsMatch() const { return m_filterFunctionListsMatch; } |
| |
| // Freeze the animation; used by DumpRenderTree. |
| void freezeAtTime(double t); |
| |
| double beginAnimationUpdateTime() const; |
| |
| double getElapsedTime() const; |
| |
| void styleAvailable() |
| { |
| ASSERT(waitingForStyleAvailable()); |
| updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1); |
| } |
| |
| const CSSAnimationData* animation() const { return m_animation.get(); } |
| |
| protected: |
| virtual void overrideAnimations() { } |
| virtual void resumeOverriddenAnimations() { } |
| |
| CompositeAnimation* compositeAnimation() { return m_compAnim; } |
| |
| // These are called when the corresponding timer fires so subclasses can do any extra work |
| virtual void onAnimationStart(double /*elapsedTime*/) { } |
| virtual void onAnimationIteration(double /*elapsedTime*/) { } |
| virtual void onAnimationEnd(double /*elapsedTime*/) { } |
| |
| // timeOffset is an offset from the current time when the animation should start. Negative values are OK. |
| virtual void startAnimation(double /*timeOffset*/) { } |
| // timeOffset is the time at which the animation is being paused. |
| virtual void pauseAnimation(double /*timeOffset*/) { } |
| virtual void endAnimation() { } |
| |
| void goIntoEndingOrLoopingState(); |
| |
| bool isAccelerated() const { return m_isAccelerated; } |
| |
| static void setNeedsStyleRecalc(Node*); |
| |
| void getTimeToNextEvent(double& time, bool& isLooping) const; |
| |
| double fractionalTime(double scale, double elapsedTime, double offset) const; |
| |
| AnimState m_animState; |
| |
| bool m_isAccelerated; |
| bool m_transformFunctionListValid; |
| bool m_filterFunctionListsMatch; |
| double m_startTime; |
| double m_pauseTime; |
| double m_requestedStartTime; |
| |
| double m_totalDuration; |
| double m_nextIterationDuration; |
| |
| RenderObject* m_object; |
| |
| RefPtr<CSSAnimationData> m_animation; |
| CompositeAnimation* m_compAnim; |
| }; |
| |
| } // namespace WebCore |
| |
| #endif // AnimationBase_h |