summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--filter/source/svg/presentation_engine.js142
-rw-r--r--slideshow/source/engine/animationnodes/animationbasenode.cxx10
-rw-r--r--slideshow/source/engine/animationnodes/basecontainernode.cxx40
-rw-r--r--slideshow/source/engine/animationnodes/basecontainernode.hxx4
4 files changed, 155 insertions, 41 deletions
diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index 0c566c843a83..13a0a3b351ef 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -1439,7 +1439,7 @@ var aRegisterEventDebugPrinter = new DebugPrinter();
aRegisterEventDebugPrinter.off();
var aTimerEventQueueDebugPrinter = new DebugPrinter();
-aTimerEventQueueDebugPrinter.off();
+aTimerEventQueueDebugPrinter.on();
var aEventMultiplexerDebugPrinter = new DebugPrinter();
aEventMultiplexerDebugPrinter.off();
@@ -4522,7 +4522,7 @@ function createStateTransitionTable()
aTable[FROZEN_NODE] = INVALID_NODE; // this state is unreachable here
aTable[ENDED_NODE] = ENDED_NODE; // this state is a sink here (cannot restart)
-// transition table for restart=NEVER, fill=FREEZE
+ // transition table for restart=NEVER, fill=FREEZE
aTable =
aSTT[RESTART_MODE_NEVER][FILL_MODE_FREEZE] =
aSTT[RESTART_MODE_NEVER][FILL_MODE_HOLD] =
@@ -5352,8 +5352,8 @@ BaseNode.prototype.resolve = function()
BaseNode.prototype.activate = function()
{
-// log( 'restart mode: ' + aRestartModeOutMap[ this.getRestartMode() ] );
-// log( 'fill mode: ' + aFillModeOutMap[ this.getFillMode() ] );
+ log( 'restart mode: ' + aRestartModeOutMap[ this.getRestartMode() ] );
+ log( 'fill mode: ' + aFillModeOutMap[ this.getFillMode() ] );
if( ! this.checkValidNode() )
return false;
@@ -5687,6 +5687,7 @@ function AnimationBaseNode( aAnimElem, aParentNode, aNodeContext )
this.bIsContainer = false;
this.aTargetElement = null;
this.aAnimatedElement = null;
+ this.nAnimatedElementOriginalState = 0;
this.aActivity = null;
this.nMinFrameCount = undefined;
@@ -5734,7 +5735,7 @@ AnimationBaseNode.prototype.parseElement = function()
if( this.aTargetElement )
{
// set up target element initial visibility
- if( true && aAnimElem.getAttribute( 'attributeName' ) === 'visibility' )
+ if( aAnimElem.getAttribute( 'attributeName' ) === 'visibility' )
{
if( aAnimElem.getAttribute( 'to' ) === 'visible' )
this.aTargetElement.setAttribute( 'visibility', 'hidden' );
@@ -5774,6 +5775,7 @@ AnimationBaseNode.prototype.activate_st = function()
{
if( this.aActivity )
{
+ this.nAnimatedElementOriginalState = this.getAnimatedElement().getCurrentState();
this.aActivity.setTargets( this.getAnimatedElement() );
this.getContext().aActivityQueue.addActivity( this.aActivity );
}
@@ -5842,6 +5844,16 @@ AnimationBaseNode.prototype.hasPendingAnimation = function()
return true;
};
+AnimationBaseNode.prototype.saveStateOfAnimatedElement = function()
+{
+ this.getAnimatedElement().saveState();
+};
+
+AnimationBaseNode.prototype.removeEffect = function()
+{
+ this.getAnimatedElement().setTo( this.nAnimatedElementOriginalState );
+};
+
AnimationBaseNode.prototype.getTargetElement = function()
{
return this.aTargetElement;
@@ -6096,6 +6108,7 @@ function BaseContainerNode( aAnimElem, aParentNode, aNodeContext )
this.aChildrenArray = new Array();
this.nFinishedChildren = 0;
this.bDurationIndefinite = false;
+ this.nLeftIterations = 1;
this.eImpressNodeType = undefined;
this.ePresetClass = undefined;
@@ -6157,6 +6170,13 @@ BaseContainerNode.prototype.appendChildNode = function( aAnimationNode )
BaseContainerNode.prototype.init_st = function()
{
+ this.nLeftIterations = this.getRepeatCount();
+
+ return this.init_children();
+};
+
+BaseContainerNode.prototype.init_children = function()
+{
this.nFinishedChildren = 0;
var nChildrenCount = this.aChildrenArray.length;
var nInitChildren = 0;
@@ -6170,6 +6190,7 @@ BaseContainerNode.prototype.init_st = function()
return ( nChildrenCount == nInitChildren );
};
+
BaseContainerNode.prototype.deactivate_st = function( eDestState )
{
if( eDestState == FROZEN_NODE )
@@ -6245,12 +6266,49 @@ BaseContainerNode.prototype.notifyDeactivatedChild = function( aChildNode )
if( bFinished && this.isDurationIndefinite() )
{
- this.deactivate();
+ if( this.nLeftIterations >= 1.0 )
+ {
+ this.nLeftIterations -= 1.0;
+ }
+ if( this.nLeftIterations >= 1.0 )
+ {
+ bFinished = false;
+ var aRepetitionEvent = makeDelay( bind( this, this.repeat ), 0.0 );
+ this.aContext.aTimerEventQueue.addEvent( aRepetitionEvent );
+ }
+ else
+ {
+ this.deactivate();
+ }
}
return bFinished;
};
+BaseContainerNode.prototype.repeat = function()
+{
+ this.deactivate_st( ENDED_NODE );
+ this.removeEffect();
+ var bInitialized = this.init_children();
+ if( bInitialized )
+ this.activate_st();
+ return bInitialized;
+};
+
+BaseContainerNode.prototype.removeEffect = function()
+{
+ this.forEachChildNode( mem_fn( 'removeEffect' ), FROZEN_NODE | ENDED_NODE );
+};
+
+BaseContainerNode.prototype.saveStateOfAnimatedElement = function()
+{
+ var nChildrenCount = this.aChildrenArray.length;
+ for( var i = 0; i < nChildrenCount; ++i )
+ {
+ this.aChildrenArray[i].saveStateOfAnimatedElement();
+ }
+}
+
BaseContainerNode.prototype.forEachChildNode = function( aFunction, eNodeStateMask )
{
if( !eNodeStateMask )
@@ -6420,6 +6478,11 @@ SequentialTimeContainer.prototype.resolveChild = function( aChildNode )
if( bResolved && this.isMainSequenceRootNode() )
{
+ aChildNode.saveStateOfAnimatedElement();
+ }
+
+ if( bResolved && this.isMainSequenceRootNode() )
+ {
// skip/rewind events handling
}
return bResolved;
@@ -8307,7 +8370,7 @@ function AnimatedElement( aElement )
this.aPreviousElement = null;
this.aElementArray = new Array();
- this.nCurrentState = 0;
+ this.nCurrentState = -1;
this.eAdditiveMode = ADDITIVE_MODE_REPLACE;
this.bIsUpdated = true;
@@ -8316,7 +8379,7 @@ function AnimatedElement( aElement )
this.aICTM = document.documentElement.createSVGMatrix();
this.setCTM();
- this.aElementArray[0] = this.aActiveElement.cloneNode( true );
+ //this.aElementArray[0] = this.aActiveElement.cloneNode( true );
}
AnimatedElement.prototype.initElement = function()
@@ -8382,6 +8445,11 @@ AnimatedElement.prototype.getId = function()
return this.aActiveElement.getAttribute( 'id' );
};
+AnimatedElement.prototype.getCurrentState = function()
+{
+ return this.nCurrentState;
+};
+
AnimatedElement.prototype.isUpdated = function()
{
return this.bIsUpdated;
@@ -8432,26 +8500,35 @@ AnimatedElement.prototype.notifyAnimationEnd = function()
AnimatedElement.prototype.notifyNextEffectStart = function( nEffectIndex )
{
- assert( this.nCurrentState === nEffectIndex,
- 'AnimatedElement(' + this.getId() + ').notifyNextEffectStart: assertion (current state == effect index) failed' );
+// assert( this.nCurrentState === nEffectIndex,
+// 'AnimatedElement(' + this.getId() + ').notifyNextEffectStart: assertion (current state == effect index) failed' );
+//
+// if( this.isUpdated() )
+// {
+// if( !this.aElementArray[ nEffectIndex ] )
+// {
+// this.aElementArray[ nEffectIndex ] = this.aElementArray[ this.nCurrentState ];
+// this.DBG( '.notifyNextEffectStart(' + nEffectIndex + '): new state set to previous one ' );
+// }
+// }
+// else
+// {
+// if( !this.aElementArray[ nEffectIndex ] )
+// {
+// this.aElementArray[ nEffectIndex ] = this.aActiveElement.cloneNode( true );
+// this.DBG( '.notifyNextEffectStart(' + nEffectIndex + '): cloned active state ' );
+// }
+// }
+// ++this.nCurrentState;
+};
- if( this.isUpdated() )
+AnimatedElement.prototype.saveState = function()
+{
+ ++this.nCurrentState;
+ if( !this.aElementArray[ this.nCurrentState ] )
{
- if( !this.aElementArray[ nEffectIndex ] )
- {
- this.aElementArray[ nEffectIndex ] = this.aElementArray[ this.nCurrentState ];
- this.DBG( '.notifyNextEffectStart(' + nEffectIndex + '): new state set to previous one ' );
- }
+ this.aElementArray[ this.nCurrentState ] = this.aActiveElement.cloneNode( true );
}
- else
- {
- if( !this.aElementArray[ nEffectIndex ] )
- {
- this.aElementArray[ nEffectIndex ] = this.aActiveElement.cloneNode( true );
- this.DBG( '.notifyNextEffectStart(' + nEffectIndex + '): cloned active state ' );
- }
- }
- ++this.nCurrentState;
};
AnimatedElement.prototype.setToFirst = function()
@@ -8464,12 +8541,19 @@ AnimatedElement.prototype.setToLast = function()
this.setTo( this.aElementArray.length - 1 );
};
-AnimatedElement.prototype.setTo = function( nEffectIndex )
+AnimatedElement.prototype.setTo = function( nNewState )
{
- var bRet = this.setToElement( this.aElementArray[ nEffectIndex ] );
+ if( !this.aElementArray[ nNewState ] )
+ {
+ log( 'AnimatedElement(' + this.getId() + ').setTo: state '
+ + nNewState + ' is not valid' );
+ return false;
+ }
+
+ var bRet = this.setToElement( this.aElementArray[ nNewState ] );
if( bRet )
{
- this.nCurrentState = nEffectIndex;
+ this.nCurrentState = nNewState;
var aBBox = this.getBBox();
var aBaseBBox = this.getBaseBBox();
@@ -10613,7 +10697,7 @@ function FromToByActivityTemplate( BaseType ) // template parameter
{
if( this.aAnimation )
{
- if( this.isAutoreverse() )
+ if( this.isAutoReverse() )
this.aAnimation.perform( this.aStartValue );
else
this.aAnimation.perform( this.aEndValue );
diff --git a/slideshow/source/engine/animationnodes/animationbasenode.cxx b/slideshow/source/engine/animationnodes/animationbasenode.cxx
index ed6349522f22..719276dbca4b 100644
--- a/slideshow/source/engine/animationnodes/animationbasenode.cxx
+++ b/slideshow/source/engine/animationnodes/animationbasenode.cxx
@@ -422,16 +422,6 @@ AnimationBaseNode::fillCommonParameters() const
else
aRepeats.reset( nRepeats / nDuration );
}
- // This is a temporary workaround:
- // as the repeatCount attribute is defined on the <par> parent node
- // and activities are created only for animation node leaves, that
- // actual performs a shape effect, we get the repeatCount value
- // from the parent node.
- else if( ( getXAnimationNode()->getType() != animations::AnimationNodeType::SET )
- && (getParentNode()->getXAnimationNode()->getRepeatCount() >>= nRepeats) )
- {
- aRepeats.reset( nRepeats );
- }
else
{
// no double value for both values - Timing::INDEFINITE?
diff --git a/slideshow/source/engine/animationnodes/basecontainernode.cxx b/slideshow/source/engine/animationnodes/basecontainernode.cxx
index e9a53ac12bca..3ac076a19a18 100644
--- a/slideshow/source/engine/animationnodes/basecontainernode.cxx
+++ b/slideshow/source/engine/animationnodes/basecontainernode.cxx
@@ -32,10 +32,12 @@
#include <canvas/verbosetrace.hxx>
#include "basecontainernode.hxx"
+#include "eventqueue.hxx"
#include "tools.hxx"
#include "nodetools.hxx"
#include "delayevent.hxx"
+#include <boost/bind.hpp>
#include <boost/mem_fn.hpp>
#include <algorithm>
@@ -65,7 +67,15 @@ void BaseContainerNode::dispose()
bool BaseContainerNode::init_st()
{
+ if( !(getXAnimationNode()->getRepeatCount() >>= mnLeftIterations) )
+ mnLeftIterations = 1.0;
+ return init_children();
+}
+
+bool BaseContainerNode::init_children()
+{
mnFinishedChildren = 0;
+
// initialize all children
return (std::count_if(
maChildren.begin(), maChildren.end(),
@@ -75,6 +85,7 @@ bool BaseContainerNode::init_st()
void BaseContainerNode::deactivate_st( NodeState eDestState )
{
+ mnLeftIterations = 0.0;
if (eDestState == FROZEN) {
// deactivate all children that are not FROZEN or ENDED:
forEachChildNode( boost::mem_fn(&AnimationNode::deactivate),
@@ -137,19 +148,44 @@ bool BaseContainerNode::notifyDeactivatedChild(
std::size_t const nSize = maChildren.size();
OSL_ASSERT( mnFinishedChildren < nSize );
++mnFinishedChildren;
- bool const bFinished = (mnFinishedChildren >= nSize);
+ 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()) {
- deactivate();
+ if( mnLeftIterations >= 1.0 )
+ {
+ mnLeftIterations -= 1.0;
+ }
+ if( mnLeftIterations >= 1.0 )
+ {
+ bFinished = false;
+ EventSharedPtr aRepetitionEvent =
+ makeDelay( boost::bind( &BaseContainerNode::repeat, this ),
+ 0.0,
+ "BaseContainerNode::repeat");
+ getContext().mrEventQueue.addEvent( aRepetitionEvent );
+ }
+ else
+ {
+ deactivate();
+ }
}
return bFinished;
}
+bool BaseContainerNode::repeat()
+{
+ deactivate_st( ENDED );
+ sal_Bool bState = init_children();
+ if( bState )
+ activate_st();
+ return bState;
+}
+
#if OSL_DEBUG_LEVEL >= 2 && defined(DBG_UTIL)
void BaseContainerNode::showState() const
{
diff --git a/slideshow/source/engine/animationnodes/basecontainernode.hxx b/slideshow/source/engine/animationnodes/basecontainernode.hxx
index f4a0d78ac79a..4a9c6cd9057d 100644
--- a/slideshow/source/engine/animationnodes/basecontainernode.hxx
+++ b/slideshow/source/engine/animationnodes/basecontainernode.hxx
@@ -51,6 +51,7 @@ protected:
private:
virtual bool init_st();
+ virtual bool init_children();
virtual void deactivate_st( NodeState eDestState );
virtual bool hasPendingAnimation() const;
// force to be implemented by derived class:
@@ -66,6 +67,8 @@ protected:
/// @return true: if all children have been deactivated
bool notifyDeactivatedChild( AnimationNodeSharedPtr const& pChildNode );
+ bool repeat();
+
template <typename FuncT>
inline void forEachChildNode( FuncT const& func,
int nodeStateMask = -1 ) const
@@ -83,6 +86,7 @@ protected:
typedef ::std::vector<AnimationNodeSharedPtr> VectorOfNodes;
VectorOfNodes maChildren;
::std::size_t mnFinishedChildren;
+ double mnLeftIterations;
private:
const bool mbDurationIndefinite;