diff options
5 files changed, 37 insertions, 4 deletions
diff --git a/slideshow/source/engine/animationnodes/animationbasenode.cxx b/slideshow/source/engine/animationnodes/animationbasenode.cxx index 107ac68650a6..ed4d157c526f 100644 --- a/slideshow/source/engine/animationnodes/animationbasenode.cxx +++ b/slideshow/source/engine/animationnodes/animationbasenode.cxx @@ -24,6 +24,7 @@ #include <com/sun/star/presentation/ParagraphTarget.hpp> #include <com/sun/star/animations/Timing.hpp> #include <com/sun/star/animations/AnimationAdditiveMode.hpp> +#include <com/sun/star/animations/AnimationFill.hpp> #include <com/sun/star/presentation/ShapeAnimationSubType.hpp> #include "nodetools.hxx" @@ -52,6 +53,7 @@ AnimationBaseNode::AnimationBaseNode( mpShape(), mpShapeSubset(), mpSubsetManager(rContext.maContext.mpSubsettableShapeManager), + mbPreservedVisibility(true), mbIsIndependentSubset( rContext.mbIsIndependentSubset ) { // extract native node targets @@ -234,8 +236,11 @@ bool AnimationBaseNode::resolve_st() void AnimationBaseNode::activate_st() { + AttributableShapeSharedPtr const pShape(getShape()); + mbPreservedVisibility = pShape->isVisible(); + // create new attribute layer - maAttributeLayerHolder.createAttributeLayer( getShape() ); + maAttributeLayerHolder.createAttributeLayer(pShape); ENSURE_OR_THROW( maAttributeLayerHolder.get(), "Could not generate shape attribute layer" ); @@ -354,6 +359,16 @@ void AnimationBaseNode::deactivate_st( NodeState eDestState ) } } +void AnimationBaseNode::removeEffect() +{ + if (!isDependentSubsettedShape()) { + AttributableShapeSharedPtr const pShape(getShape()); + pShape->setVisibility(!mbPreservedVisibility); + getContext().mpSubsettableShapeManager->notifyShapeUpdate( pShape ); + pShape->setVisibility(mbPreservedVisibility); + } +} + bool AnimationBaseNode::hasPendingAnimation() const { // TODO(F1): This might not always be true. Are there 'inactive' diff --git a/slideshow/source/engine/animationnodes/animationbasenode.hxx b/slideshow/source/engine/animationnodes/animationbasenode.hxx index 55ec060ac4ad..7751642517aa 100644 --- a/slideshow/source/engine/animationnodes/animationbasenode.hxx +++ b/slideshow/source/engine/animationnodes/animationbasenode.hxx @@ -46,6 +46,7 @@ public: #if defined(DBG_UTIL) virtual void showState() const override; #endif + virtual void removeEffect() override; protected: virtual void dispose() override; @@ -87,6 +88,7 @@ private: /// When valid, this is a subsetted target shape ShapeSubsetSharedPtr mpShapeSubset; SubsettableShapeManagerSharedPtr const mpSubsetManager; + bool mbPreservedVisibility; bool mbIsIndependentSubset; }; diff --git a/slideshow/source/engine/animationnodes/basecontainernode.cxx b/slideshow/source/engine/animationnodes/basecontainernode.cxx index e8e5dfbd7f88..02668ae7fd28 100644 --- a/slideshow/source/engine/animationnodes/basecontainernode.cxx +++ b/slideshow/source/engine/animationnodes/basecontainernode.cxx @@ -20,6 +20,7 @@ #include <basecontainernode.hxx> #include <com/sun/star/animations/AnimationRestart.hpp> +#include <com/sun/star/animations/AnimationFill.hpp> #include <eventqueue.hxx> #include <tools.hxx> #include "nodetools.hxx" @@ -161,6 +162,11 @@ bool BaseContainerNode::notifyDeactivatedChild( } if(mnLeftIterations >= 1.0 || mbRestart) { + // SMIL spec said that "Accumulate" controls whether or not the animation + // is cumulative, but XTimeContainer do not have this attribute, so always + // remove the effect before next repeat. + forEachChildNode(std::mem_fn(&AnimationNode::removeEffect), -1); + if (mnLeftIterations >= 1.0) bFinished = false; @@ -172,6 +178,8 @@ bool BaseContainerNode::notifyDeactivatedChild( } else if (isDurationIndefinite()) { + if (getFillMode() == animations::AnimationFill::REMOVE) + forEachChildNode(std::mem_fn(&AnimationNode::removeEffect), -1); deactivate(); } } diff --git a/slideshow/source/inc/animationnode.hxx b/slideshow/source/inc/animationnode.hxx index 3eb5a7295668..34eca1da91ed 100644 --- a/slideshow/source/inc/animationnode.hxx +++ b/slideshow/source/inc/animationnode.hxx @@ -136,6 +136,13 @@ public: virtual void notifyDeactivating( const AnimationNodeSharedPtr& rNotifier ) = 0; + /** Called by the container to remove the animation effect + to make the painted shape correct if it restart because + of repeat or rewind ( fill mode is AnimationFill::REMOVE ) + to start state. + */ + virtual void removeEffect() = 0; + /** Query node whether it has an animation pending. @return true, if this node (or at least one of its children) diff --git a/slideshow/source/inc/basenode.hxx b/slideshow/source/inc/basenode.hxx index bbfc2f78a03c..bc4eb9420b83 100644 --- a/slideshow/source/inc/basenode.hxx +++ b/slideshow/source/inc/basenode.hxx @@ -123,6 +123,10 @@ public: bool isMainSequenceRootNode() const { return mbIsMainSequenceRootNode; } + /// Get the node's fill mode + sal_Int16 getFillMode(); + + virtual void removeEffect() override {} protected: void scheduleDeactivationEvent( EventSharedPtr const& pEvent = EventSharedPtr() ); @@ -163,9 +167,6 @@ private: */ sal_Int16 getRestartDefaultMode() const; - /// Get the node's fill mode - sal_Int16 getFillMode(); - /** Get the default fill mode. If this node's default mode is AnimationFill::DEFAULT, |