[Libreoffice-commits] .: Branch 'feature/svg-export' - 9 commits - filter/source sd/source sd/xml
Marco Cecchetti
mcecchetti at kemper.freedesktop.org
Mon Jul 9 01:17:27 PDT 2012
filter/source/svg/presentation_engine.js | 649 ++++++++++++++++++++++++-------
sd/source/core/CustomAnimationEffect.cxx | 13
sd/xml/effects.xml | 12
3 files changed, 524 insertions(+), 150 deletions(-)
New commits:
commit 248f71c2486c8b651827f960b82b8294f9f79913
Author: Marco Cecchetti <mrcekets at gmail.com>
Date: Mon Jul 9 00:59:05 2012 +0200
Added support for interactive animation sequence to the JavaScript engine.
Now it is possible to start an effect by clicking on a given shape.
diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index a5a3a3f..cccbcd0 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -222,7 +222,7 @@ function getDefaultCharCodeDictionary()
}
-function slideOnMouseDown( aEvt )
+function slideOnMouseUp( aEvt )
{
if (!aEvt)
aEvt = window.event;
@@ -236,8 +236,12 @@ function slideOnMouseDown( aEvt )
if( 0 != nOffset )
dispatchEffects( nOffset );
+ return true; // the click has been handled
}
+document.handleClick = slideOnMouseUp;
+
+
/** Event handler for mouse wheel events in slide mode.
* based on http://adomas.org/javascript-mouse-wheel/
*
@@ -309,7 +313,7 @@ function mouseHandlerDispatch( aEvt, anAction )
}
//Set mouse event handler.
-document.onmousedown = function( aEvt ) { return mouseHandlerDispatch( aEvt, MOUSE_DOWN ); };
+document.onmouseup = function( aEvt ) { return mouseHandlerDispatch( aEvt, MOUSE_UP ); };
//document.onmousemove = function( aEvt ) { return mouseHandlerDispatch( aEvt, MOUSE_MOVE ); };
/** Function to supply the default mouse handler dictionary.
@@ -324,13 +328,17 @@ function getDefaultMouseHandlerDictionary()
mouseHandlerDict[INDEX_MODE] = new Object();
// slide mode
- mouseHandlerDict[SLIDE_MODE][MOUSE_DOWN]
- = function( aEvt ) { return slideOnMouseDown( aEvt ); };
+ mouseHandlerDict[SLIDE_MODE][MOUSE_UP]
+ //= function( aEvt ) { return slideOnMouseDown( aEvt ); };
+ = function( aEvt ) { return ( aSlideShow.aEventMultiplexer ) ?
+ aSlideShow.aEventMultiplexer.notifyMouseClick( aEvt )
+ : slideOnMouseUp( aEvt ); };
+
mouseHandlerDict[SLIDE_MODE][MOUSE_WHEEL]
= function( aEvt ) { return slideOnMouseWheel( aEvt ); };
// index mode
- mouseHandlerDict[INDEX_MODE][MOUSE_DOWN]
+ mouseHandlerDict[INDEX_MODE][MOUSE_UP]
= function( aEvt ) { return toggleSlideIndex(); };
// mouseHandlerDict[INDEX_MODE][MOUSE_MOVE]
// = function( aEvt ) { return theSlideIndexPage.updateSelection( aEvt ); };
@@ -1433,7 +1441,7 @@ var NAVDBG = new DebugPrinter();
NAVDBG.off();
var ANIMDBG = new DebugPrinter();
-ANIMDBG.on();
+ANIMDBG.off();
var aRegisterEventDebugPrinter = new DebugPrinter();
aRegisterEventDebugPrinter.off();
@@ -5047,11 +5055,11 @@ NodeContext.prototype.makeSourceEventElement = function( sId, aEventBaseElem )
return null;
}
- if( !this.aAnimationNodeMap[ sId ] )
+ if( !this.aSourceEventElementMap[ sId ] )
{
- this.aAnimationNodeMap[ sId ] = new SourceEventElement( aEventBaseElem, this.aContext.aEventMultiplexer );
+ this.aSourceEventElementMap[ sId ] = new SourceEventElement( sId, aEventBaseElem, this.aContext.aEventMultiplexer );
}
- return this.aAnimationNodeMap[ sId ];
+ return this.aSourceEventElementMap[ sId ];
};
@@ -5323,7 +5331,7 @@ BaseNode.prototype.resolve = function()
{
this.aActivationEvent = makeDelay( bind( this, this.activate ), this.getBegin().getOffset() + this.nStartDelay );
}
- registerEvent( this.getBegin(), this.aActivationEvent, this.aNodeContext );
+ registerEvent( this.getId(), this.getBegin(), this.aActivationEvent, this.aNodeContext );
return true;
}
@@ -9378,6 +9386,7 @@ function SlideAnimations( aSlideShowContext )
this.aAnimatedElementMap = new Object();
this.aSourceEventElementMap = new Object();
this.aNextEffectEventArray = new NextEffectEventArray();
+ this.aInteractiveAnimationSequenceMap = new Object();
this.aEventMultiplexer = new EventMultiplexer( aSlideShowContext.aTimerEventQueue );
this.aRootNode = null;
this.bElementsParsed = false;
@@ -9385,6 +9394,11 @@ function SlideAnimations( aSlideShowContext )
this.aContext.aAnimationNodeMap = this.aAnimationNodeMap;
this.aContext.aAnimatedElementMap = this.aAnimatedElementMap;
this.aContext.aSourceEventElementMap = this.aSourceEventElementMap;
+
+ // We set up a low priority for the invocation of document.handleClick
+ // in order to make clicks on shapes, that start interactive animation
+ // sequence (on click), have an higher priority.
+ this.aEventMultiplexer.registerMouseClickHandler( document, 100 );
}
@@ -9433,7 +9447,12 @@ SlideAnimations.prototype.start = function()
if( !this.bElementsParsed )
return false;
- aSlideShow.setSlideEvents( this.aNextEffectEventArray, this.aEventMultiplexer );
+ this.chargeSourceEvents();
+ this.chargeInterAnimEvents();
+
+ aSlideShow.setSlideEvents( this.aNextEffectEventArray,
+ this.aInteractiveAnimationSequenceMap,
+ this.aEventMultiplexer );
if( this.aContext.bFirstRun == undefined )
this.aContext.bFirstRun = true;
@@ -9489,7 +9508,21 @@ SlideAnimations.prototype.clearNextEffectEvents = function()
this.aContext.bFirstRun = undefined;
};
+SlideAnimations.prototype.chargeSourceEvents = function()
+{
+ for( var id in this.aSourceEventElementMap )
+ {
+ this.aSourceEventElementMap[id].charge();
+ }
+};
+SlideAnimations.prototype.chargeInterAnimEvents = function()
+{
+ for( var id in this.aInteractiveAnimationSequenceMap )
+ {
+ this.aInteractiveAnimationSequenceMap[id].chargeEvents();
+ }
+};
/**********************************************************************************************
* Event classes and helper functions
@@ -9578,7 +9611,7 @@ function makeDelay( aFunctor, nTimeout )
// ------------------------------------------------------------------------------------------ //
-function registerEvent( aTiming, aEvent, aNodeContext )
+function registerEvent( nNodeId, aTiming, aEvent, aNodeContext )
{
var aSlideShowContext = aNodeContext.aContext;
var eTimingType = aTiming.getType();
@@ -9603,6 +9636,14 @@ function registerEvent( aTiming, aEvent, aNodeContext )
log( 'registerEvent: next effect event array not initialized' );
return;
}
+ var aInteractiveAnimationSequenceMap =
+ aSlideShowContext.aInteractiveAnimationSequenceMap;
+ if( !aInteractiveAnimationSequenceMap )
+ {
+ log( 'registerEvent: interactive animation sequence map not initialized' );
+ return;
+ }
+
switch( eTimingType )
{
case EVENT_TIMING:
@@ -9618,6 +9659,12 @@ function registerEvent( aTiming, aEvent, aNodeContext )
}
var aSourceEventElement = aNodeContext.makeSourceEventElement( sEventBaseElemId, aEventBaseElem );
+ if( !aInteractiveAnimationSequenceMap[ nNodeId ] )
+ {
+ var aInteractiveAnimationSequence = new InteractiveAnimationSequence( nNodeId );
+ aInteractiveAnimationSequenceMap[ nNodeId ] = aInteractiveAnimationSequence;
+ }
+
var bEventRegistered = false;
switch( eEventType )
{
@@ -9629,7 +9676,12 @@ function registerEvent( aTiming, aEvent, aNodeContext )
log( 'generateEvent: not handled event type: ' + eEventType );
}
if( bEventRegistered )
- aSourceEventElement.addEventListener( eEventType );
+ {
+ var aStartEvent = aInteractiveAnimationSequenceMap[ nNodeId ].getStartEvent();
+ var aEndEvent = aInteractiveAnimationSequenceMap[ nNodeId ].getEndEvent();
+ aEventMultiplexer.registerEvent( eEventType, aSourceEventElement.getId(), aStartEvent );
+ aEventMultiplexer.registerEvent( EVENT_TRIGGER_END_EVENT, nNodeId, aEndEvent );
+ }
}
else // no base event element present
{
@@ -9680,82 +9732,173 @@ registerEvent.DBG = function( aTiming, nTime )
// ------------------------------------------------------------------------------------------ //
-function SourceEventElement( aElement, aEventMultiplexer )
+function SourceEventElement( sId, aElement, aEventMultiplexer )
{
- this.nId = getUniqueId();
+ this.sId = sId;
this.aElement = aElement;
this.aEventMultiplexer = aEventMultiplexer;
- this.aEventListenerStateArray = new Array();
-}
+ this.aEventMultiplexer.registerMouseClickHandler( this, 1000 );
+
+ this.bClickHandled = false;
+ this.bIsPointerOver = false;
+ this.aElement.addEventListener( 'mouseover', bind2( SourceEventElement.prototype.onMouseEnter, this), false );
+ this.aElement.addEventListener( 'mouseout', bind2( SourceEventElement.prototype.onMouseLeave, this), false );
+}
SourceEventElement.prototype.getId = function()
{
- return this.nId;
+ return this.sId;
};
-SourceEventElement.prototype.isEqualTo = function( aSourceEventElement )
+SourceEventElement.prototype.onMouseEnter = function()
{
- return ( this.getId() == aSourceEventElement.getId() );
+ this.bIsPointerOver = true;
};
-SourceEventElement.prototype.onClick = function()
+SourceEventElement.prototype.onMouseLeave = function()
{
- this.aEventMultiplexer.notifyClickEvent( this );
+ this.bIsPointerOver = false;
};
-SourceEventElement.prototype.isEventListenerRegistered = function( eEventType )
+SourceEventElement.prototype.charge = function()
{
- return this.aEventListenerStateArray[ eEventType ];
+ this.bClickHandled = false;
};
-SourceEventElement.prototype.addEventListener = function( eEventType )
+SourceEventElement.prototype.handleClick = function( aMouseEvent )
{
- if( !this.aElement )
- return false;
+ if( !this.bIsPointerOver ) return false;
- this.aEventListenerStateArray[ eEventType ] = true;
- switch( eEventType )
- {
- case EVENT_TRIGGER_ON_CLICK:
- this.aElement.addEventListener( 'click', this.onClick, false );
- break;
- default:
- log( 'SourceEventElement.addEventListener: not handled event type: ' + eEventType );
- return false;
- }
+ if( this.bClickHandled )
+ return true;
+
+ this.aEventMultiplexer.notifyEvent( EVENT_TRIGGER_ON_CLICK, this.getId() );
+ aSlideShow.update();
+ this.bClickHandled = true;
return true;
};
-SourceEventElement.prototype.removeEventListener = function( eEventType )
+
+
+// ------------------------------------------------------------------------------------------ //
+function InteractiveAnimationSequence( nId )
{
- if( !this.aElement )
- return false;
+ this.nId = nId;
+ this.bIsRunning = false;
+ this.aStartEvent = null;
+ this.aEndEvent = null;
+}
- this.aEventListenerStateArray[ eEventType ] = false;
- switch( eEventType )
+InteractiveAnimationSequence.prototype.getId = function()
+{
+ return this.nId;
+};
+
+InteractiveAnimationSequence.prototype.getStartEvent = function()
+{
+ if( !this.aStartEvent )
{
- case EVENT_TRIGGER_ON_CLICK:
- this.aElement.removeEventListener( 'click', this.onClick, false );
- break;
- default:
- log( 'SourceEventElement.removeEventListener: not handled event type: ' + eEventType );
- return false;
+ this.aStartEvent =
+ makeEvent( bind2( InteractiveAnimationSequence.prototype.start, this ) );
}
- return true;
+ return this.aStartEvent;
};
+InteractiveAnimationSequence.prototype.getEndEvent = function()
+{
+ if( !this.aEndEvent )
+ {
+ this.aEndEvent =
+ makeEvent( bind2( InteractiveAnimationSequence.prototype.end, this ) );
+ }
+ return this.aEndEvent;
+};
+
+InteractiveAnimationSequence.prototype.chargeEvents = function()
+{
+ if( this.aStartEvent ) this.aStartEvent.charge();
+ if( this.aEndEvent ) this.aEndEvent.charge();
+};
+
+InteractiveAnimationSequence.prototype.isRunning = function()
+{
+ return this.bIsRunning;
+};
+
+InteractiveAnimationSequence.prototype.start = function()
+{
+ aSlideShow.notifyInteractiveAnimationSequenceStart( this.getId() );
+ this.bIsRunning = true;
+};
+
+InteractiveAnimationSequence.prototype.end = function()
+{
+ aSlideShow.notifyInteractiveAnimationSequenceEnd( this.getId() );
+ this.bIsRunning = false;
+};
+
+// ------------------------------------------------------------------------------------------ //
+/** class PriorityEntry
+ * It provides an entry type for priority queues.
+ * Higher is the value of nPriority higher is the priority of the created entry.
+ *
+ * @param aValue
+ * The object to be prioritized.
+ * @param nPriority
+ * An integral number representing the object priority.
+ *
+ */
+function PriorityEntry( aValue, nPriority )
+{
+ this.aValue = aValue;
+ this.nPriority = nPriority;
+}
+
+/** EventEntry.compare
+ * Compare priority of two entries.
+ *
+ * @param aLhsEntry
+ * An instance of type PriorityEntry.
+ * @param aRhsEntry
+ * An instance of type PriorityEntry.
+ * @return {Boolean}
+ * True if the first entry has higher priority of the second entry,
+ * false otherwise.
+ */
+PriorityEntry.compare = function( aLhsEntry, aRhsEntry )
+{
+ return ( aLhsEntry.nPriority < aRhsEntry.nPriority );
+};
// ------------------------------------------------------------------------------------------ //
function EventMultiplexer( aTimerEventQueue )
{
this.aTimerEventQueue = aTimerEventQueue;
this.aEventMap = new Object();
+ this.aMouseClickHandlerSet = new PriorityQueue( PriorityEntry.compare );
this.aSkipEffectEvent = null;
this.aRewindCurrentEffectEvent = null;
this.aRewindLastEffectEvent = null;
}
+EventMultiplexer.prototype.registerMouseClickHandler = function( aHandler, nPriority )
+{
+ var aHandlerEntry = new PriorityEntry( aHandler, nPriority );
+ this.aMouseClickHandlerSet.push( aHandlerEntry );
+};
+
+EventMultiplexer.prototype.notifyMouseClick = function( aMouseEvent )
+{
+ var aMouseClickHandlerSet = this.aMouseClickHandlerSet;
+ var nSize = aMouseClickHandlerSet.size();
+ for( var i = 0; i < nSize; ++i )
+ {
+ var aHandlerEntry = aMouseClickHandlerSet.aSequence[i];
+ if( aHandlerEntry.aValue.handleClick( aMouseEvent ) )
+ break;
+ }
+};
EventMultiplexer.prototype.registerEvent = function( eEventType, aNotifierId, aEvent )
{
@@ -11284,12 +11427,17 @@ function SlideShow()
this.aTimerEventQueue = new TimerEventQueue( this.aTimer );
this.aActivityQueue = new ActivityQueue( this.aTimer );
this.aNextEffectEventArray = null;
+ this.aInteractiveAnimationSequenceMap = null;
this.aEventMultiplexer = null;
- this.aContext = new SlideShowContext( this.aTimerEventQueue, this.aEventMultiplexer,
- this.aNextEffectEventArray, this.aActivityQueue );
+ this.aContext = new SlideShowContext( this.aTimerEventQueue,
+ this.aEventMultiplexer,
+ this.aNextEffectEventArray,
+ this.aInteractiveAnimationSequenceMap,
+ this.aActivityQueue );
this.nCurrentEffect = 0;
this.eDirection = FORWARD;
+ this.nTotalInteracAnimSeqRunning = 0;
this.bIsIdle = true;
this.bIsEnabled = true;
this.bIsRewinding = false;
@@ -11299,19 +11447,27 @@ function SlideShow()
}
-SlideShow.prototype.setSlideEvents = function( aNextEffectEventArray, aEventMultiplexer )
+SlideShow.prototype.setSlideEvents = function( aNextEffectEventArray,
+ aInteractiveAnimationSequenceMap,
+ aEventMultiplexer )
{
if( !aNextEffectEventArray )
log( 'SlideShow.setSlideEvents: aNextEffectEventArray is not valid' );
+ if( !aInteractiveAnimationSequenceMap )
+ log( 'SlideShow.setSlideEvents:aInteractiveAnimationSequenceMap is not valid' );
+
if( !aEventMultiplexer )
log( 'SlideShow.setSlideEvents: aEventMultiplexer is not valid' );
this.aContext.aNextEffectEventArray = aNextEffectEventArray;
this.aNextEffectEventArray = aNextEffectEventArray;
+ this.aContext.aInteractiveAnimationSequenceMap = aInteractiveAnimationSequenceMap;
+ this.aInteractiveAnimationSequenceMap = aInteractiveAnimationSequenceMap;
this.aContext.aEventMultiplexer = aEventMultiplexer;
this.aEventMultiplexer = aEventMultiplexer;
this.nCurrentEffect = 0;
+ this.nTotalInteracAnimSeqRunning = 0;
};
SlideShow.prototype.createSlideTransition = function( aSlideTransitionHandler, aLeavingSlide, aEnteringSlide, aTransitionEndEvent )
@@ -11361,6 +11517,11 @@ SlideShow.prototype.isRunning = function()
return !this.bIsIdle;
};
+SlideShow.prototype.isInterAnimSeqRunning = function()
+{
+ return ( this.nTotalInteracAnimSeqRunning > 0 );
+};
+
SlideShow.prototype.isEnabled = function()
{
return this.bIsEnabled;
@@ -11393,11 +11554,27 @@ SlideShow.prototype.notifyTransitionEnd = function( nSlideIndex )
}
};
+SlideShow.prototype.notifyInteractiveAnimationSequenceStart = function( nNodeId )
+{
+ ++this.nTotalInteracAnimSeqRunning;
+};
+
+SlideShow.prototype.notifyInteractiveAnimationSequenceEnd = function( nNodeId )
+{
+ assert( this.nTotalInteracAnimSeqRunning > 0,
+ 'SlideShow.notifyInteractiveAnimationSequenceStart: ' +
+ 'the total number of running interactive application is zero' );
+ --this.nTotalInteracAnimSeqRunning;
+};
+
SlideShow.prototype.nextEffect = function()
{
if( !this.isEnabled() )
return false;
+ if( this.isInterAnimSeqRunning() )
+ return true;
+
if( this.isRunning() )
{
this.skipCurrentEffect();
@@ -11443,6 +11620,9 @@ SlideShow.prototype.skipEffect = function()
if( this.bIsSkipping || this.bIsRewinding )
return true;
+ if( this.isInterAnimSeqRunning() )
+ return true;
+
if( this.isRunning() )
{
this.skipCurrentEffect();
@@ -11478,6 +11658,9 @@ SlideShow.prototype.skipAllEffects = function()
if( this.bIsSkippingAll )
return true;
+ if( this.isInterAnimSeqRunning() )
+ return true;
+
this.bIsSkippingAll = true;
if( this.isRunning() )
{
@@ -11513,6 +11696,9 @@ SlideShow.prototype.rewindEffect = function()
if( this.bIsSkipping || this.bIsRewinding )
return;
+ if( this.isInterAnimSeqRunning() )
+ return true;
+
if( this.nCurrentEffect == 0 )
{
this.rewindToPreviousSlide();
@@ -11717,11 +11903,12 @@ var aSlideShow = null;
// ------------------------------------------------------------------------------------------ //
-function SlideShowContext( aTimerEventQueue, aEventMultiplexer, aNextEffectEventArray, aActivityQueue)
+function SlideShowContext( aTimerEventQueue, aEventMultiplexer, aNextEffectEventArray, aInteractiveAnimationSequenceMap, aActivityQueue)
{
this.aTimerEventQueue = aTimerEventQueue;
this.aEventMultiplexer = aEventMultiplexer;
this.aNextEffectEventArray = aNextEffectEventArray;
+ this.aInteractiveAnimationSequenceMap = aInteractiveAnimationSequenceMap;
this.aActivityQueue = aActivityQueue;
this.bIsSkipping = false;
}
commit 247be8bada5dfb1fe3acb7625a1b230d55b592d3
Author: Marco Cecchetti <mrcekets at gmail.com>
Date: Thu Jul 5 19:17:26 2012 +0200
Bug fix: now the JavaScript engine parse the âcounter-clockwiseâ value correctly.
Previously it expected âcounterclockwiseâ.
diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index 984eaef..a5a3a3f 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -4117,9 +4117,9 @@ aColorSpaceOutMap = [ 'rgb', 'hsl' ];
var CLOCKWISE = 0;
var COUNTERCLOCKWISE = 1;
-aClockDirectionInMap = { 'clockwise': CLOCKWISE, 'counterclockwise': COUNTERCLOCKWISE };
+aClockDirectionInMap = { 'clockwise': CLOCKWISE, 'counter-clockwise': COUNTERCLOCKWISE };
-aClockDirectionOutMap = [ 'clockwise', 'counterclockwise' ];
+aClockDirectionOutMap = [ 'clockwise', 'counter-clockwise' ];
// Attribute Value Types
commit 48265b1ce5b9003c754397415d30425df88e3581
Author: Marco Cecchetti <mrcekets at gmail.com>
Date: Thu Jul 5 18:50:39 2012 +0200
Bug fix: now the darken and lighten effects work in the right way.
Edited the effects.xml and changed effect direction to counterclockwise.
diff --git a/sd/xml/effects.xml b/sd/xml/effects.xml
index be341ef..b555a32 100644
--- a/sd/xml/effects.xml
+++ b/sd/xml/effects.xml
@@ -1172,9 +1172,9 @@
<anim:par smil:begin="indefinite" smil:fill="hold">
<anim:par smil:begin="0" smil:fill="hold">
<anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-darken">
- <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="color" smil:by="hsl(0,-12%,-25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
- <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="fill-color" smil:by="hsl(0,-12%,-25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
- <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="stroke-color" smil:by="hsl(0,-12%,-25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="color" smil:by="hsl(0,-12%,-25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="counterclockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="fill-color" smil:by="hsl(0,-12%,-25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="counterclockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="stroke-color" smil:by="hsl(0,-12%,-25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="counterclockwise"/>
<anim:set smil:dur="0.5" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
</anim:par>
</anim:par>
@@ -1200,9 +1200,9 @@
<anim:par smil:begin="indefinite" smil:fill="hold">
<anim:par smil:begin="0" smil:fill="hold">
<anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-lighten">
- <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="color" smil:by="hsl(0,12%,25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
- <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="fill-color" smil:by="hsl(0,12%,25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
- <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="stroke-color" smil:by="hsl(0,12%,25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="color" smil:by="hsl(0,12%,25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="counterclockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="fill-color" smil:by="hsl(0,12%,25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="counterclockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="stroke-color" smil:by="hsl(0,12%,25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="counterclockwise"/>
<anim:set smil:dur="0.5" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
</anim:par>
</anim:par>
commit 978e9607e63c227e2f7fe865af94485a7042531a
Author: Marco Cecchetti <mrcekets at gmail.com>
Date: Thu Jul 5 16:35:02 2012 +0200
Bug fix: now repeated animations and begin=âafter effect â works properly together.
Modified the CustomAnimationEffect class in order to take into account the repeatCount
attribute value when computing the node effect absolute duration.
diff --git a/sd/source/core/CustomAnimationEffect.cxx b/sd/source/core/CustomAnimationEffect.cxx
index 16756a5..625376f 100644
--- a/sd/source/core/CustomAnimationEffect.cxx
+++ b/sd/source/core/CustomAnimationEffect.cxx
@@ -281,6 +281,10 @@ void CustomAnimationEffect::setNode( const ::com::sun::star::uno::Reference< ::c
}
mfAbsoluteDuration = mfDuration;
+ double fRepeatCount = 1.0;
+ if( (mxNode->getRepeatCount()) >>= fRepeatCount )
+ mfAbsoluteDuration *= fRepeatCount;
+
checkForText();
}
@@ -755,7 +759,9 @@ void CustomAnimationEffect::setDuration( double fDuration )
{
double fScale = fDuration / mfDuration;
mfDuration = fDuration;
- mfAbsoluteDuration = mfDuration;
+ double fRepeatCount = 1.0;
+ getRepeatCount() >>= fRepeatCount;
+ mfAbsoluteDuration = mfDuration * fRepeatCount;
// calculate effect duration and get target shape
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
@@ -954,7 +960,12 @@ sal_Int16 CustomAnimationEffect::getFill() const
void CustomAnimationEffect::setRepeatCount( const Any& rRepeatCount )
{
if( mxNode.is() )
+ {
mxNode->setRepeatCount( rRepeatCount );
+ double fRepeatCount = 1.0;
+ rRepeatCount >>= fRepeatCount;
+ mfAbsoluteDuration = mfDuration * fRepeatCount;
+ }
}
// --------------------------------------------------------------------
commit 2e91423ace0a4b0051b3b1beb9e1e461378437a4
Author: Marco Cecchetti <mrcekets at gmail.com>
Date: Thu Jul 5 10:19:47 2012 +0200
Bug fix: now a clip-based transition works correctly when mode=âoutâ and reverse method involves flipping.
diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index f042263..984eaef 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -7933,8 +7933,10 @@ ClippingFunctor.prototype.perform = function( nT, nWidth, nHeight )
{
var aClipPoly = this.aParametricPolyPolygon.perform( this.bForwardParameterSweep ? nT : (1 - nT) );
- if( this.bFlip )
- aClipPoly.changeOrientation();
+ // Note: even if the reverse method involves flipping we don't need to
+ // change the clip-poly orientation because we utilize the 'nonzero'
+ // clip-rule.
+ // See: http://www.w3.org/TR/SVG11/painting.html#FillRuleProperty
if( this.bSubtractPolygon )
{
commit ef43a2a37ce48ae3d41957034b94c6d0463d16df
Author: Marco Cecchetti <mrcekets at gmail.com>
Date: Wed Jul 4 18:50:46 2012 +0200
Provided support for rewinding to the previous slide and for skipping / rewinding all effects.
The following method of the SlideShow class has been implemented:
skipAllEffects, rewindToPreviousSlide, rewindAllEffects.
Commented out the calls to the initAnimatedElement methods for ValueListActivity and
FromToByActivity class as it is the source of a bug.
diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index 2e66561..f042263 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -150,13 +150,13 @@ function getDefaultKeyCodeDictionary()
keyCodeDict[SLIDE_MODE][RIGHT_KEY]
= function() { return dispatchEffects(1); };
keyCodeDict[SLIDE_MODE][UP_KEY]
- = function() { return skipEffects(-1); };
+ = function() { return aSlideShow.rewindEffect(); };
keyCodeDict[SLIDE_MODE][DOWN_KEY]
= function() { return skipEffects(1); };
keyCodeDict[SLIDE_MODE][PAGE_UP_KEY]
- = function() { return switchSlide( -1, true ); };
+ = function() { return aSlideShow.rewindAllEffects(); };
keyCodeDict[SLIDE_MODE][PAGE_DOWN_KEY]
- = function() { return switchSlide( 1, true ); };
+ = function() { return skipAllEffects(); };
keyCodeDict[SLIDE_MODE][HOME_KEY]
= function() { return aSlideShow.displaySlide( 0, true ); };
keyCodeDict[SLIDE_MODE][END_KEY]
@@ -1433,7 +1433,7 @@ var NAVDBG = new DebugPrinter();
NAVDBG.off();
var ANIMDBG = new DebugPrinter();
-ANIMDBG.off();
+ANIMDBG.on();
var aRegisterEventDebugPrinter = new DebugPrinter();
aRegisterEventDebugPrinter.off();
@@ -2985,6 +2985,15 @@ function dispatchEffects(dir)
}
}
+function skipAllEffects()
+{
+ var bRet = aSlideShow.skipAllEffects();
+ if( !bRet )
+ {
+ switchSlide( 1, true );
+ }
+}
+
function skipEffects(dir)
{
if( dir == 1 )
@@ -2993,12 +3002,12 @@ function skipEffects(dir)
if( !bRet )
{
- switchSlide( 1, false );
+ switchSlide( 1, true );
}
}
else
{
- switchSlide( dir, false );
+ switchSlide( dir, true );
}
}
@@ -10725,7 +10734,7 @@ function FromToByActivityTemplate( BaseType ) // template parameter
this.nIteration = 0;
this.bCumulative = bAccumulate;
- this.initAnimatedElement();
+ //this.initAnimatedElement();
}
extend( FromToByActivity, BaseType );
@@ -10931,7 +10940,7 @@ function ValueListActivityTemplate( BaseType ) // template parameter
this.bCumulative = bAccumulate;
this.aLastValue = this.aValueList[ this.aValueList.length - 1 ];
- this.initAnimatedElement();
+ //this.initAnimatedElement();
}
extend( ValueListActivity, BaseType );
@@ -10943,7 +10952,7 @@ function ValueListActivityTemplate( BaseType ) // template parameter
ANIMDBG.print( 'createValueListActivity: value[' + i + '] = ' + this.aValueList[i] );
}
- this.initAnimatedElement();
+ //this.initAnimatedElement();
};
ValueListActivity.prototype.initAnimatedElement = function()
@@ -11283,6 +11292,7 @@ function SlideShow()
this.bIsEnabled = true;
this.bIsRewinding = false;
this.bIsSkipping = false;
+ this.bIsSkippingAll = false;
this.bNoSlideTransition = false;
}
@@ -11422,30 +11432,6 @@ SlideShow.prototype.skipCurrentEffect = function()
this.bIsSkipping = false;
};
-/** rewindEffect
- * Rewind the current playing effect or the last played one.
- *
- */
-SlideShow.prototype.rewindEffect = function()
-{
- if( this.bIsSkipping || this.bIsRewinding )
- return true;
-
- this.bIsRewinding = true;
- if( this.isRunning() )
- {
- this.aEventMultiplexer.notifyRewindCurrentEffectEvent();
- }
- else
- {
- this.aEventMultiplexer.notifyRewindLastEffectEvent();
- }
- if( this.nCurrentEffect > 0 )
- --this.nCurrentEffect;
- this.update();
- this.bIsRewinding = false;
-};
-
/** skipEffect
* Skip the next effect to be played.
*
@@ -11478,6 +11464,105 @@ SlideShow.prototype.skipEffect = function()
return true;
};
+/** skipAllEffects
+ * Skip all left effects on the current slide.
+ *
+ * @return {Boolean}
+ * True if it already skipping or when it has ended skipping,
+ * false if the next slide needs to be displayed.
+ */
+SlideShow.prototype.skipAllEffects = function()
+{
+ if( this.bIsSkippingAll )
+ return true;
+
+ this.bIsSkippingAll = true;
+ if( this.isRunning() )
+ {
+ this.skipCurrentEffect();
+ }
+ else if( !this.aNextEffectEventArray
+ || ( this.nCurrentEffect >= this.aNextEffectEventArray.size() ) )
+ {
+ this.bIsSkippingAll = false;
+ return false;
+ }
+
+ // Pay attention here: a new next effect event is appended to
+ // aNextEffectEventArray only after the related animation node has been
+ // resolved, that is only after the animation node related to the previous
+ // effect has notified to be deactivated to the main sequence time container.
+ // So you should avoid any optimization here because the size of
+ // aNextEffectEventArray will going on increasing after every skip action.
+ while( this.nCurrentEffect < this.aNextEffectEventArray.size() )
+ {
+ this.skipEffect();
+ }
+ this.bIsSkippingAll = false;
+ return true;
+};
+
+/** rewindEffect
+ * Rewind the current playing effect or the last played one.
+ *
+ */
+SlideShow.prototype.rewindEffect = function()
+{
+ if( this.bIsSkipping || this.bIsRewinding )
+ return;
+
+ if( this.nCurrentEffect == 0 )
+ {
+ this.rewindToPreviousSlide();
+ return;
+ }
+
+ this.bIsRewinding = true;
+ if( this.isRunning() )
+ {
+ this.aEventMultiplexer.notifyRewindCurrentEffectEvent();
+ }
+ else
+ {
+ this.aEventMultiplexer.notifyRewindLastEffectEvent();
+ }
+ if( this.nCurrentEffect > 0 )
+ --this.nCurrentEffect;
+ this.update();
+ this.bIsRewinding = false;
+};
+
+/** rewindToPreviousSlide
+ * Displays the previous slide with all effects played.
+ *
+ */
+SlideShow.prototype.rewindToPreviousSlide = function()
+{
+ if( this.isRunning() )
+ return;
+ var nNewSlide = nCurSlide - 1;
+ this.displaySlide( nNewSlide, true );
+ this.skipAllEffects();
+};
+
+/** rewindAllEffects
+ * Rewind all effects already played on the current slide.
+ *
+ */
+SlideShow.prototype.rewindAllEffects = function()
+{
+ if( this.nCurrentEffect == 0 )
+ {
+ this.rewindToPreviousSlide();
+ return;
+ }
+
+ while( this.nCurrentEffect > 0 )
+ {
+ this.rewindEffect();
+ }
+};
+
SlideShow.prototype.displaySlide = function( nNewSlide, bSkipSlideTransition )
{
var aMetaDoc = theMetaDoc;
commit ecca9699d12a6a24265779668507e9f6d930694c
Author: Marco Cecchetti <mrcekets at gmail.com>
Date: Tue Jul 3 19:22:34 2012 +0200
Performed some clean up and added documentation comments.
diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index 9b62dd7..2e66561 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -6281,6 +6281,7 @@ BaseContainerNode.prototype.removeEffect = function()
var nChildrenCount = this.aChildrenArray.length;
if( nChildrenCount == 0 )
return;
+ // We remove effect in reverse order.
for( var i = nChildrenCount - 1; i >= 0; --i )
{
if( ( this.aChildrenArray[i].getState() & ( FROZEN_NODE | ENDED_NODE ) ) == 0 )
@@ -6465,11 +6466,24 @@ SequentialTimeContainer.prototype.notifyDeactivating = function( aNotifier )
}
};
+/** skipEffect
+ * Skip the current playing shape effect.
+ * Requires: the current node is the main sequence root node.
+ *
+ * @param aChildNode
+ * An animation node representing the root node of the shape effect being
+ * played.
+ */
SequentialTimeContainer.prototype.skipEffect = function( aChildNode )
{
if( this.isChildNode( aChildNode ) )
{
+ // First off we end all queued activities.
this.getContext().aActivityQueue.endAll();
+ // We signal that we are going to skip all subsequent animations by
+ // setting the bIsSkipping flag to 'true', then all queued events are
+ // fired immediately. In such a way the correct order of the various
+ // events that belong to the animation time-line is preserved.
this.getContext().bIsSkipping = true;
this.getContext().aTimerEventQueue.forceEmpty();
this.getContext().bIsSkipping = false;
@@ -6478,63 +6492,122 @@ SequentialTimeContainer.prototype.skipEffect = function( aChildNode )
}
else
{
- log( 'SequentialTimeContainer.skipEffect: unknown child: ' + aChildNode.getId() );
+ log( 'SequentialTimeContainer.skipEffect: unknown child: '
+ + aChildNode.getId() );
}
};
+/** rewindCurrentEffect
+ * Rewind a playing shape effect.
+ * Requires: the current node is the main sequence root node.
+ *
+ * @param aChildNode
+ * An animation node representing the root node of the shape effect being
+ * played
+ */
SequentialTimeContainer.prototype.rewindCurrentEffect = function( aChildNode )
{
if( this.isChildNode( aChildNode ) )
{
- assert( !this.bIsRewinding, 'SequentialTimeContainer.rewindCurrentEffect: is already rewinding.' );
+ assert( !this.bIsRewinding,
+ 'SequentialTimeContainer.rewindCurrentEffect: is already rewinding.' );
+ // We signal we are rewinding so the notifyDeactivating method returns
+ // immediately without increment the finished children counter and
+ // resolve the next child.
this.bIsRewinding = true;
+ // First off we end all queued activities.
this.getContext().aActivityQueue.endAll();
+ // We signal that we are going to skip all subsequent animations by
+ // setting the bIsSkipping flag to 'true', then all queued events are
+ // fired immediately. In such a way the correct order of the various
+ // events that belong to the animation time-line is preserved.
this.getContext().bIsSkipping = true;
this.getContext().aTimerEventQueue.forceEmpty();
this.getContext().bIsSkipping = false;
+ // We end all new activities appended to the activity queue by
+ // the fired events.
this.getContext().aActivityQueue.endAll();
+ // Now we perform a final 'end' and restore the animated shape to
+ // the state it was before the current effect was applied.
aChildNode.end();
aChildNode.removeEffect();
+ // Finally we place the child node to the 'unresolved' state and
+ // resolve it again.
aChildNode.init();
this.resolveChild( aChildNode );
this.bIsRewinding = false;
}
else
{
- log( 'SequentialTimeContainer.rewindCurrentEffect: unknown child: ' + aChildNode.getId() );
+ log( 'SequentialTimeContainer.rewindCurrentEffect: unknown child: '
+ + aChildNode.getId() );
}
};
+/** rewindLastEffect
+ * Rewind the last ended effect.
+ * Requires: the current node is the main sequence root node.
+ *
+ * @param aChildNode
+ * An animation node representing the root node of the next shape effect
+ * to be played.
+ */
SequentialTimeContainer.prototype.rewindLastEffect = function( aChildNode )
{
if( this.isChildNode( aChildNode ) )
{
- assert( !this.bIsRewinding, 'SequentialTimeContainer.rewindLastEffect: is already rewinding.' );
+ assert( !this.bIsRewinding,
+ 'SequentialTimeContainer.rewindLastEffect: is already rewinding.' );
+ // We signal we are rewinding so the notifyDeactivating method returns
+ // immediately without increment the finished children counter and
+ // resolve the next child.
this.bIsRewinding = true;
+ // We end the current effect and remove any change it applies on the
+ // animated shape.
this.getContext().aTimerEventQueue.forceEmpty();
this.getContext().aActivityQueue.clear();
-
aChildNode.end();
aChildNode.removeEffect();
+
+ // As we rewind the previous effect we need to decrease the finished
+ // children counter.
--this.nFinishedChildren;
var aPreviousChildNode = this.aChildrenArray[ this.nFinishedChildren ];
+ // No need to invoke the end method for the previous child as it is
+ // already in the ENDED state.
+
aPreviousChildNode.removeEffect();
+ // We place the child node to the 'unresolved' state.
aPreviousChildNode.init();
- // We need to re-initialize it too, because it is in state ENDED now,
- // and cannot be resolved again later.
+ // We need to re-initialize the old current child too, because it is
+ // in ENDED state now, On the contrary it cannot be resolved again later.
aChildNode.init();
this.resolveChild( aPreviousChildNode );
this.bIsRewinding = false;
}
else
{
- log( 'SequentialTimeContainer.rewindLastEffect: unknown child: ' + aChildNode.getId() );
+ log( 'SequentialTimeContainer.rewindLastEffect: unknown child: '
+ + aChildNode.getId() );
}
};
+/** resolveChild
+ * Resolve the passed child.
+ * In case this node is a main sequence root node events for skipping and
+ * rewinding the effect related to the passed child node are created and
+ * registered.
+ *
+ * @param aChildNode
+ * An animation node representing the root node of the next shape effect
+ * to be played.
+ * @return
+ * It returns true if the passed child has been resolved successfully,
+ * false otherwise.
+ */
SequentialTimeContainer.prototype.resolveChild = function( aChildNode )
{
var bResolved = aChildNode.resolve();
@@ -6551,7 +6624,7 @@ SequentialTimeContainer.prototype.resolveChild = function( aChildNode )
this.aRewindCurrentEffectEvent.dispose();
this.aRewindCurrentEffectEvent = makeEvent( bind2( SequentialTimeContainer.prototype.rewindCurrentEffect, this, aChildNode ) );
- this.aContext.aEventMultiplexer.registerRewindEffectEvent( this.aRewindCurrentEffectEvent );
+ this.aContext.aEventMultiplexer.registerRewindCurrentEffectEvent( this.aRewindCurrentEffectEvent );
if( this.aRewindLastEffectEvent )
this.aRewindLastEffectEvent.dispose();
@@ -8529,11 +8602,6 @@ AnimatedElement.prototype.getId = function()
return this.aActiveElement.getAttribute( 'id' );
};
-AnimatedElement.prototype.isUpdated = function()
-{
- return this.bIsUpdated;
-};
-
AnimatedElement.prototype.getAdditiveMode = function()
{
return this.eAdditiveMode;
@@ -8571,8 +8639,7 @@ AnimatedElement.prototype.notifySlideStart = function()
AnimatedElement.prototype.notifyAnimationStart = function()
{
- this.DBG( '.notifyAnimationStart invoked' );
- this.bIsUpdated = false;
+ // empty body
};
AnimatedElement.prototype.notifyAnimationEnd = function()
@@ -8582,28 +8649,16 @@ AnimatedElement.prototype.notifyAnimationEnd = function()
AnimatedElement.prototype.notifyNextEffectStart = function( nEffectIndex )
{
-// 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;
+ // empty body
};
+/** saveState
+ * Save the state of the managed animated element and append it to aStateSet
+ * using the passed animation node id as key.
+ *
+ * @param nAnimationNodeId
+ * A non negative integer representing the unique id of an animation node.
+ */
AnimatedElement.prototype.saveState = function( nAnimationNodeId )
{
ANIMDBG.print( 'AnimatedElement(' + this.getId() + ').saveState(' + nAnimationNodeId +')' );
@@ -8620,6 +8675,16 @@ AnimatedElement.prototype.saveState = function( nAnimationNodeId )
};
+/** restoreState
+ * Restore the state of the managed animated element to the state with key
+ * the passed animation node id.
+ *
+ * @param nAnimationNodeId
+ * A non negative integer representing the unique id of an animation node.
+ *
+ * @return
+ * True if the restoring operation is successful, false otherwise.
+ */
AnimatedElement.prototype.restoreState = function( nAnimationNodeId )
{
if( !this.aStateSet[ nAnimationNodeId ] )
@@ -9676,7 +9741,7 @@ function EventMultiplexer( aTimerEventQueue )
this.aTimerEventQueue = aTimerEventQueue;
this.aEventMap = new Object();
this.aSkipEffectEvent = null;
- this.aRewindEffectEvent = null;
+ this.aRewindCurrentEffectEvent = null;
this.aRewindLastEffectEvent = null;
}
@@ -9727,17 +9792,17 @@ EventMultiplexer.prototype.notifySkipEffectEvent = function()
}
};
-EventMultiplexer.prototype.registerRewindEffectEvent = function( aEvent )
+EventMultiplexer.prototype.registerRewindCurrentEffectEvent = function( aEvent )
{
- this.aRewindEffectEvent = aEvent;
+ this.aRewindCurrentEffectEvent = aEvent;
};
-EventMultiplexer.prototype.notifyRewindEffectEvent = function()
+EventMultiplexer.prototype.notifyRewindCurrentEffectEvent = function()
{
- if( this.aRewindEffectEvent )
+ if( this.aRewindCurrentEffectEvent )
{
- this.aTimerEventQueue.addEvent( this.aRewindEffectEvent );
- this.aRewindEffectEvent = null;
+ this.aTimerEventQueue.addEvent( this.aRewindCurrentEffectEvent );
+ this.aRewindCurrentEffectEvent = null;
}
};
@@ -11342,6 +11407,10 @@ SlideShow.prototype.nextEffect = function()
return true;
};
+/** skipCurrentEffect
+ * Skip the current playing effect.
+ *
+ */
SlideShow.prototype.skipCurrentEffect = function()
{
if( this.bIsSkipping || this.bIsRewinding )
@@ -11353,6 +11422,10 @@ SlideShow.prototype.skipCurrentEffect = function()
this.bIsSkipping = false;
};
+/** rewindEffect
+ * Rewind the current playing effect or the last played one.
+ *
+ */
SlideShow.prototype.rewindEffect = function()
{
if( this.bIsSkipping || this.bIsRewinding )
@@ -11361,17 +11434,22 @@ SlideShow.prototype.rewindEffect = function()
this.bIsRewinding = true;
if( this.isRunning() )
{
- this.aEventMultiplexer.notifyRewindEffectEvent();
+ this.aEventMultiplexer.notifyRewindCurrentEffectEvent();
}
else
{
this.aEventMultiplexer.notifyRewindLastEffectEvent();
}
- --this.nCurrentEffect;
+ if( this.nCurrentEffect > 0 )
+ --this.nCurrentEffect;
this.update();
this.bIsRewinding = false;
};
+/** skipEffect
+ * Skip the next effect to be played.
+ *
+ */
SlideShow.prototype.skipEffect = function()
{
if( this.bIsSkipping || this.bIsRewinding )
@@ -11400,16 +11478,6 @@ SlideShow.prototype.skipEffect = function()
return true;
};
-//SlideShow.prototype.previousEffect = function()
-//{
-// if( this.nCurrentEffect <= 0 )
-// return false;
-// this.eDirection = BACKWARD;
-// this.aNextEffectEventArray.at( this.nCurrentEffect ).fire();
-// --this.nCurrentEffect;
-// return true;
-//};
-
SlideShow.prototype.displaySlide = function( nNewSlide, bSkipSlideTransition )
{
var aMetaDoc = theMetaDoc;
commit 12a52aaeecd60df958f75323ae9ca7684486e1ed
Author: Marco Cecchetti <mrcekets at gmail.com>
Date: Tue Jul 3 15:39:32 2012 +0200
Changed the rewindCurrentEffect method.
The change was needed because rewinding a playing shape transition effect based on
a clip-path doesnât work properly on Firefox and Internet Explorer.
diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index d705658..9b62dd7 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -6489,8 +6489,11 @@ SequentialTimeContainer.prototype.rewindCurrentEffect = function( aChildNode )
assert( !this.bIsRewinding, 'SequentialTimeContainer.rewindCurrentEffect: is already rewinding.' );
this.bIsRewinding = true;
+ this.getContext().aActivityQueue.endAll();
+ this.getContext().bIsSkipping = true;
this.getContext().aTimerEventQueue.forceEmpty();
- this.getContext().aActivityQueue.clear();
+ this.getContext().bIsSkipping = false;
+ this.getContext().aActivityQueue.endAll();
aChildNode.end();
aChildNode.removeEffect();
commit d501d66a69340869227f2051b912614b04799d2c
Author: Marco Cecchetti <mrcekets at gmail.com>
Date: Mon Jul 2 23:36:35 2012 +0200
Skipping a single effect works in JavaScript even if the effect is rewinded (fill=remove).
Added a bIsSkipping flag to the SlideShowContext class and modified the activate_st method
of the AnimationBaseNode class. Now when we are skipping the managed activity is
not appended to the activity class but the end method is executed immediately.
In such a way the correct order of the various events that belong to the animation time-line
is preserved.
diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index c71cad6..d705658 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -5745,7 +5745,14 @@ AnimationBaseNode.prototype.activate_st = function()
{
this.saveStateOfAnimatedElement();
this.aActivity.setTargets( this.getAnimatedElement() );
- this.getContext().aActivityQueue.addActivity( this.aActivity );
+ if( this.getContext().bIsSkipping )
+ {
+ this.aActivity.end();
+ }
+ else
+ {
+ this.getContext().aActivityQueue.addActivity( this.aActivity );
+ }
}
else
{
@@ -5821,8 +5828,7 @@ AnimationBaseNode.prototype.saveStateOfAnimatedElement = function()
AnimationBaseNode.prototype.removeEffect = function()
{
- log( 'AnimationBaseNode.removeEffect invoked' );
- this.getAnimatedElement().setTo( this.getId() );
+ this.getAnimatedElement().restoreState( this.getId() );
};
AnimationBaseNode.prototype.getTargetElement = function()
@@ -6175,7 +6181,7 @@ BaseContainerNode.prototype.deactivate_st = function( eDestState )
// end all children that are not ENDED:
this.forEachChildNode( mem_fn( 'end' ), ~ENDED_NODE );
if( this.getFillMode() == FILL_MODE_REMOVE )
- this.forEachChildNode( mem_fn( 'removeEffect' ), ENDED_NODE );
+ this.removeEffect();
}
};
@@ -6277,8 +6283,14 @@ BaseContainerNode.prototype.removeEffect = function()
return;
for( var i = nChildrenCount - 1; i >= 0; --i )
{
- if( ( this.aChildrenArray[i].getState() & FROZEN_NODE | ENDED_NODE ) == 0 )
+ if( ( this.aChildrenArray[i].getState() & ( FROZEN_NODE | ENDED_NODE ) ) == 0 )
+ {
+ log( 'BaseContainerNode.removeEffect: child(id:'
+ + this.aChildrenArray[i].getId() + ') is neither frozen nor ended;'
+ + ' state: '
+ + aTransitionModeOutMap[ this.aChildrenArray[i].getState() ] );
continue;
+ }
this.aChildrenArray[i].removeEffect();
}
};
@@ -6458,7 +6470,9 @@ SequentialTimeContainer.prototype.skipEffect = function( aChildNode )
if( this.isChildNode( aChildNode ) )
{
this.getContext().aActivityQueue.endAll();
+ this.getContext().bIsSkipping = true;
this.getContext().aTimerEventQueue.forceEmpty();
+ this.getContext().bIsSkipping = false;
var aEvent = makeEvent( bind2( aChildNode.deactivate, aChildNode ) );
this.getContext().aTimerEventQueue.addEvent( aEvent );
}
@@ -8589,6 +8603,7 @@ AnimatedElement.prototype.notifyNextEffectStart = function( nEffectIndex )
AnimatedElement.prototype.saveState = function( nAnimationNodeId )
{
+ ANIMDBG.print( 'AnimatedElement(' + this.getId() + ').saveState(' + nAnimationNodeId +')' );
if( !this.aStateSet[ nAnimationNodeId ] )
{
this.aStateSet[ nAnimationNodeId ] = new Object();
@@ -8602,15 +8617,17 @@ AnimatedElement.prototype.saveState = function( nAnimationNodeId )
};
-AnimatedElement.prototype.setTo = function( nAnimationNodeId )
+AnimatedElement.prototype.restoreState = function( nAnimationNodeId )
{
if( !this.aStateSet[ nAnimationNodeId ] )
{
- log( 'AnimatedElement(' + this.getId() + ').setTo: state '
+ log( 'AnimatedElement(' + this.getId() + ').restoreState: state '
+nAnimationNodeId + ' is not valid' );
return false;
}
+ ANIMDBG.print( 'AnimatedElement(' + this.getId() + ').restoreState(' + nAnimationNodeId +')' );
+
var aState = this.aStateSet[ nAnimationNodeId ];
var bRet = this.setToElement( aState.aElement );
if( bRet )
@@ -11196,8 +11213,8 @@ function SlideShow()
this.eDirection = FORWARD;
this.bIsIdle = true;
this.bIsEnabled = true;
- this.bIsSkipping = false;
this.bIsRewinding = false;
+ this.bIsSkipping = false;
this.bNoSlideTransition = false;
}
@@ -11548,6 +11565,7 @@ function SlideShowContext( aTimerEventQueue, aEventMultiplexer, aNextEffectEvent
this.aEventMultiplexer = aEventMultiplexer;
this.aNextEffectEventArray = aNextEffectEventArray;
this.aActivityQueue = aActivityQueue;
+ this.bIsSkipping = false;
}
More information about the Libreoffice-commits
mailing list