diff --git a/slideshow/source/engine/animationnodes/basecontainernode.cxx b/slideshow/source/engine/animationnodes/basecontainernode.cxx index bb3c7e3739a7..d48df81161cb 100644 --- a/slideshow/source/engine/animationnodes/basecontainernode.cxx +++ b/slideshow/source/engine/animationnodes/basecontainernode.cxx @@ -41,6 +41,7 @@ BaseContainerNode::BaseContainerNode( maChildren(), mnFinishedChildren(0), mnLeftIterations(0), + mbRepeatIndefinite(xNode->getRepeatCount().hasValue() && isIndefiniteTiming(xNode->getRepeatCount())), mbDurationIndefinite( isIndefiniteTiming( xNode->getEnd() ) && isIndefiniteTiming( xNode->getDuration() ) ) { @@ -137,12 +138,9 @@ bool BaseContainerNode::notifyDeactivatedChild( ++mnFinishedChildren; bool bFinished = (mnFinishedChildren >= nSize); - // all children finished, and we've got indefinite duration? - // think of ParallelTimeContainer::notifyDeactivating() - // if duration given, we will be deactivated by some end event - // @see fillCommonParameters() - if (bFinished && isDurationIndefinite()) { - if( mnLeftIterations >= 1.0 ) + // Handle repetition here. + if (bFinished) { + if(!mbRepeatIndefinite && mnLeftIterations >= 1.0) { mnLeftIterations -= 1.0; } @@ -155,7 +153,7 @@ bool BaseContainerNode::notifyDeactivatedChild( "BaseContainerNode::repeat"); getContext().mrEventQueue.addEvent( aRepetitionEvent ); } - else + else if (isDurationIndefinite()) { deactivate(); } @@ -166,6 +164,10 @@ bool BaseContainerNode::notifyDeactivatedChild( void BaseContainerNode::repeat() { + // Prevent repeat event scheduled before deactivation. + if (getState() == FROZEN || getState() == ENDED) + return; + forEachChildNode( std::mem_fn(&AnimationNode::end), ~ENDED ); bool bState = init_children(); if( bState ) diff --git a/slideshow/source/engine/animationnodes/basenode.cxx b/slideshow/source/engine/animationnodes/basenode.cxx index f47076e57ae1..afe0a0111e50 100644 --- a/slideshow/source/engine/animationnodes/basenode.cxx +++ b/slideshow/source/engine/animationnodes/basenode.cxx @@ -539,12 +539,26 @@ void BaseNode::scheduleDeactivationEvent( EventSharedPtr const& pEvent ) // if anim base node has no activity, this is called to schedule deactivation, // but what if it does not schedule anything? - // TODO(F2): Handle end time attribute, too auto self(mpSelf); - mpCurrentEvent = generateEvent( - mxAnimationNode->getDuration(), - [self] () { self->deactivate(); }, - maContext, 0.0 ); + if (mxAnimationNode->getEnd().hasValue()) + { + // TODO: We may need to calculate the duration if the end value is numeric. + // We expect that the end value contains EventTrigger::ON_NEXT here. + // LibreOffice does not generate numeric values, so we can leave it + // until we find a test case. + mpCurrentEvent = generateEvent( + mxAnimationNode->getEnd(), + [self] () { self->deactivate(); }, + maContext, 0.0 ); + + } + else + { + mpCurrentEvent = generateEvent( + mxAnimationNode->getDuration(), + [self] () { self->deactivate(); }, + maContext, 0.0 ); + } } } diff --git a/slideshow/source/inc/basecontainernode.hxx b/slideshow/source/inc/basecontainernode.hxx index 94547302d7e6..ca07eff16687 100644 --- a/slideshow/source/inc/basecontainernode.hxx +++ b/slideshow/source/inc/basecontainernode.hxx @@ -85,6 +85,7 @@ protected: double mnLeftIterations; private: + const bool mbRepeatIndefinite; const bool mbDurationIndefinite; };