summaryrefslogtreecommitdiff
path: root/slideshow/source/engine/animationfactory.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'slideshow/source/engine/animationfactory.cxx')
-rw-r--r--slideshow/source/engine/animationfactory.cxx1389
1 files changed, 1389 insertions, 0 deletions
diff --git a/slideshow/source/engine/animationfactory.cxx b/slideshow/source/engine/animationfactory.cxx
new file mode 100644
index 000000000000..61e65981f6ce
--- /dev/null
+++ b/slideshow/source/engine/animationfactory.cxx
@@ -0,0 +1,1389 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: animationfactory.cxx,v $
+ * $Revision: 1.16 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_slideshow.hxx"
+
+// must be first
+#include <canvas/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <canvas/verbosetrace.hxx>
+
+#include <animationfactory.hxx>
+#include <attributemap.hxx>
+
+#include <com/sun/star/animations/AnimationAdditiveMode.hpp>
+#include <com/sun/star/animations/AnimationTransformType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+
+#include <functional>
+
+
+using namespace ::com::sun::star;
+
+
+namespace slideshow
+{
+ namespace internal
+ {
+ namespace
+ {
+ // attention, there is a similar implementation of Animation in
+ // transitions/transitionfactory.cxx
+
+ template< typename ValueT > class TupleAnimation : public PairAnimation
+ {
+ public:
+ TupleAnimation( const ShapeManagerSharedPtr& rShapeManager,
+ int nFlags,
+ bool (ShapeAttributeLayer::*pIs1stValid)() const,
+ bool (ShapeAttributeLayer::*pIs2ndValid)() const,
+ const ValueT& rDefaultValue,
+ const ::basegfx::B2DSize& rReferenceSize,
+ double (ShapeAttributeLayer::*pGet1stValue)() const,
+ double (ShapeAttributeLayer::*pGet2ndValue)() const,
+ void (ShapeAttributeLayer::*pSetValue)( const ValueT& ) ) :
+ mpShape(),
+ mpAttrLayer(),
+ mpShapeManager( rShapeManager ),
+ mpIs1stValidFunc(pIs1stValid),
+ mpIs2ndValidFunc(pIs2ndValid),
+ mpGet1stValueFunc(pGet1stValue),
+ mpGet2ndValueFunc(pGet2ndValue),
+ mpSetValueFunc(pSetValue),
+ mnFlags( nFlags ),
+ maReferenceSize( rReferenceSize ),
+ maDefaultValue( rDefaultValue ),
+ mbAnimationStarted( false )
+ {
+ ENSURE_OR_THROW( rShapeManager,
+ "TupleAnimation::TupleAnimation(): Invalid ShapeManager" );
+ ENSURE_OR_THROW( pIs1stValid && pIs2ndValid && pGet1stValue && pGet2ndValue && pSetValue,
+ "TupleAnimation::TupleAnimation(): One of the method pointers is NULL" );
+ }
+
+ ~TupleAnimation()
+ {
+ end_();
+ }
+
+ // Animation interface
+ // -------------------
+ virtual void prefetch( const AnimatableShapeSharedPtr&,
+ const ShapeAttributeLayerSharedPtr& )
+ {}
+
+ virtual void start( const AnimatableShapeSharedPtr& rShape,
+ const ShapeAttributeLayerSharedPtr& rAttrLayer )
+ {
+ OSL_ENSURE( !mpShape,
+ "TupleAnimation::start(): Shape already set" );
+ OSL_ENSURE( !mpAttrLayer,
+ "TupleAnimation::start(): Attribute layer already set" );
+
+ mpShape = rShape;
+ mpAttrLayer = rAttrLayer;
+
+ ENSURE_OR_THROW( rShape,
+ "TupleAnimation::start(): Invalid shape" );
+ ENSURE_OR_THROW( rAttrLayer,
+ "TupleAnimation::start(): Invalid attribute layer" );
+
+ if( !mbAnimationStarted )
+ {
+ mbAnimationStarted = true;
+
+ if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
+ mpShapeManager->enterAnimationMode( mpShape );
+ }
+ }
+
+ virtual void end() { end_(); }
+ void end_()
+ {
+ if( mbAnimationStarted )
+ {
+ mbAnimationStarted = false;
+
+ if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
+ mpShapeManager->leaveAnimationMode( mpShape );
+
+ if( mpShape->isContentChanged() )
+ mpShapeManager->notifyShapeUpdate( mpShape );
+ }
+ }
+
+ // PairAnimation interface
+ // -----------------------
+
+ virtual bool operator()( const ::basegfx::B2DTuple& rValue )
+ {
+ ENSURE_OR_RETURN( mpAttrLayer && mpShape,
+ "TupleAnimation::operator(): Invalid ShapeAttributeLayer" );
+
+ ValueT aValue( rValue.getX(),
+ rValue.getY() );
+
+ // Activitis get values from the expression parser,
+ // which returns _relative_ sizes/positions.
+ // Convert back relative to reference coordinate system
+ aValue *= maReferenceSize;
+
+ ((*mpAttrLayer).*mpSetValueFunc)( aValue );
+
+ if( mpShape->isContentChanged() )
+ mpShapeManager->notifyShapeUpdate( mpShape );
+
+ return true;
+ }
+
+ virtual ::basegfx::B2DTuple getUnderlyingValue() const
+ {
+ ENSURE_OR_THROW( mpAttrLayer,
+ "TupleAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
+
+ ::basegfx::B2DTuple aRetVal;
+
+ // deviated from the (*shared_ptr).*mpFuncPtr
+ // notation here, since gcc does not seem to parse
+ // that as a member function call anymore.
+ aRetVal.setX( (mpAttrLayer.get()->*mpIs1stValidFunc)() ?
+ (mpAttrLayer.get()->*mpGet1stValueFunc)() :
+ maDefaultValue.getX() );
+ aRetVal.setY( (mpAttrLayer.get()->*mpIs2ndValidFunc)() ?
+ (mpAttrLayer.get()->*mpGet2ndValueFunc)() :
+ maDefaultValue.getY() );
+
+ // Activities get values from the expression
+ // parser, which returns _relative_
+ // sizes/positions. Convert start value to the
+ // same coordinate space (i.e. relative to given
+ // reference size).
+ aRetVal /= maReferenceSize;
+
+ return aRetVal;
+ }
+
+ private:
+ AnimatableShapeSharedPtr mpShape;
+ ShapeAttributeLayerSharedPtr mpAttrLayer;
+ ShapeManagerSharedPtr mpShapeManager;
+ bool (ShapeAttributeLayer::*mpIs1stValidFunc)() const;
+ bool (ShapeAttributeLayer::*mpIs2ndValidFunc)() const;
+ double (ShapeAttributeLayer::*mpGet1stValueFunc)() const;
+ double (ShapeAttributeLayer::*mpGet2ndValueFunc)() const;
+ void (ShapeAttributeLayer::*mpSetValueFunc)( const ValueT& );
+
+ const int mnFlags;
+
+ const ::basegfx::B2DSize maReferenceSize;
+ const ValueT maDefaultValue;
+ bool mbAnimationStarted;
+ };
+
+
+ class PathAnimation : public NumberAnimation
+ {
+ public:
+ PathAnimation( const ::rtl::OUString& rSVGDPath,
+ sal_Int16 nAdditive,
+ const ShapeManagerSharedPtr& rShapeManager,
+ const ::basegfx::B2DVector& rSlideSize,
+ int nFlags ) :
+ maPathPoly(),
+ mpShape(),
+ mpAttrLayer(),
+ mpShapeManager( rShapeManager ),
+ maPageSize( rSlideSize ),
+ maShapeOrig(),
+ mnFlags( nFlags ),
+ mbAnimationStarted( false ),
+ mnAdditive( nAdditive )
+ {
+ ENSURE_OR_THROW( rShapeManager,
+ "PathAnimation::PathAnimation(): Invalid ShapeManager" );
+
+ ::basegfx::B2DPolyPolygon aPolyPoly;
+
+ ENSURE_OR_THROW( ::basegfx::tools::importFromSvgD( aPolyPoly, rSVGDPath ),
+ "PathAnimation::PathAnimation(): failed to parse SVG:d path" );
+ ENSURE_OR_THROW( aPolyPoly.count() == 1,
+ "PathAnimation::PathAnimation(): motion path consists of multiple/zero polygon(s)" );
+
+ // TODO(F2): Since getPositionRelative() currently
+ // cannot handle beziers, have to subdivide.
+ // AW: Should be no longer necessary; getPositionRelative is now bezier-safe
+ maPathPoly = ::basegfx::tools::adaptiveSubdivideByAngle(aPolyPoly.getB2DPolygon(0) );
+ }
+
+ ~PathAnimation()
+ {
+ end_();
+ }
+
+ // Animation interface
+ // -------------------
+ virtual void prefetch( const AnimatableShapeSharedPtr&,
+ const ShapeAttributeLayerSharedPtr& )
+ {}
+
+ virtual void start( const AnimatableShapeSharedPtr& rShape,
+ const ShapeAttributeLayerSharedPtr& rAttrLayer )
+ {
+ OSL_ENSURE( !mpShape,
+ "PathAnimation::start(): Shape already set" );
+ OSL_ENSURE( !mpAttrLayer,
+ "PathAnimation::start(): Attribute layer already set" );
+
+ mpShape = rShape;
+ mpAttrLayer = rAttrLayer;
+
+ ENSURE_OR_THROW( rShape,
+ "PathAnimation::start(): Invalid shape" );
+ ENSURE_OR_THROW( rAttrLayer,
+ "PathAnimation::start(): Invalid attribute layer" );
+
+ // TODO(F1): Check whether _shape_ bounds are correct here.
+ // Theoretically, our AttrLayer is way down the stack, and
+ // we only have to consider _that_ value, not the one from
+ // the top of the stack as returned by Shape::getBounds()
+ if( mnAdditive == animations::AnimationAdditiveMode::SUM )
+ maShapeOrig = mpShape->getBounds().getCenter();
+ else
+ maShapeOrig = mpShape->getDomBounds().getCenter();
+
+ if( !mbAnimationStarted )
+ {
+ mbAnimationStarted = true;
+
+ if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
+ mpShapeManager->enterAnimationMode( mpShape );
+ }
+ }
+
+ virtual void end() { end_(); }
+ void end_()
+ {
+ if( mbAnimationStarted )
+ {
+ mbAnimationStarted = false;
+
+ if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
+ mpShapeManager->leaveAnimationMode( mpShape );
+
+ if( mpShape->isContentChanged() )
+ mpShapeManager->notifyShapeUpdate( mpShape );
+ }
+ }
+
+ // NumberAnimation interface
+ // -----------------------
+
+ virtual bool operator()( double nValue )
+ {
+ ENSURE_OR_RETURN( mpAttrLayer && mpShape,
+ "PathAnimation::operator(): Invalid ShapeAttributeLayer" );
+
+ ::basegfx::B2DPoint rOutPos = ::basegfx::tools::getPositionRelative( maPathPoly,
+ nValue );
+
+ // TODO(F1): Determine whether the path is
+ // absolute, or shape-relative.
+
+ // interpret path as page-relative. Scale up with page size
+ rOutPos *= maPageSize;
+
+ // TODO(F1): Determine whether the path origin is
+ // absolute, or shape-relative.
+
+ // interpret path as shape-originated. Offset to shape position
+
+ rOutPos += maShapeOrig;
+
+ mpAttrLayer->setPosition( rOutPos );
+
+ if( mpShape->isContentChanged() )
+ mpShapeManager->notifyShapeUpdate( mpShape );
+
+ return true;
+ }
+
+ virtual double getUnderlyingValue() const
+ {
+ ENSURE_OR_THROW( mpAttrLayer,
+ "PathAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
+
+ return 0.0; // though this should be used in concert with
+ // ActivitiesFactory::createSimpleActivity, better
+ // explicitely name our start value.
+ // Permissible range for operator() above is [0,1]
+ }
+
+ private:
+ ::basegfx::B2DPolygon maPathPoly;
+ AnimatableShapeSharedPtr mpShape;
+ ShapeAttributeLayerSharedPtr mpAttrLayer;
+ ShapeManagerSharedPtr mpShapeManager;
+ const ::basegfx::B2DSize maPageSize;
+ ::basegfx::B2DPoint maShapeOrig;
+ const int mnFlags;
+ bool mbAnimationStarted;
+ sal_Int16 mnAdditive;
+ };
+
+
+ /** GenericAnimation template
+
+ This template makes heavy use of SFINAE, only one of
+ the operator()() methods will compile for each of the
+ base classes.
+
+ Note that we omit the virtual keyword on the
+ operator()() overrides and getUnderlyingValue() methods on
+ purpose; those that actually do override baseclass
+ virtual methods inherit the property, and the others
+ won't increase our vtable. What's more, having all
+ those methods in the vtable actually creates POIs for
+ them, which breaks the whole SFINAE concept (IOW, this
+ template won't compile any longer).
+
+ @tpl AnimationBase
+ Type of animation to generate (determines the
+ interface GenericAnimation will implement). Must be
+ one of NumberAnimation, ColorAnimation,
+ StringAnimation, PairAnimation or BoolAnimation.
+
+ @tpl ModifierFunctor
+ Type of a functor object, which can optionally be used to
+ modify the getter/setter values.
+ */
+ template< typename AnimationBase, typename ModifierFunctor > class GenericAnimation : public AnimationBase
+ {
+ public:
+ typedef typename AnimationBase::ValueType ValueT;
+
+ /** Create generic animation
+
+ @param pIsValid
+ Function pointer to one of the is*Valid
+ methods. Used to either take the given getter
+ method, or the given default value for the start value.
+
+ @param rDefaultValue
+ Default value, to take as the start value if
+ is*Valid returns false.
+
+ @param pGetValue
+ Getter method, to fetch start value if valid.
+
+ @param pSetValue
+ Setter method. This one puts the current animation
+ value to the ShapeAttributeLayer.
+
+ @param rGetterModifier
+ Modifies up values retrieved from the pGetValue method.
+ Must provide operator()( const ValueT& ) method.
+
+ @param rSetterModifier
+ Modifies up values before passing them to the pSetValue method.
+ Must provide operator()( const ValueT& ) method.
+ */
+ GenericAnimation( const ShapeManagerSharedPtr& rShapeManager,
+ int nFlags,
+ bool (ShapeAttributeLayer::*pIsValid)() const,
+ const ValueT& rDefaultValue,
+ ValueT (ShapeAttributeLayer::*pGetValue)() const,
+ void (ShapeAttributeLayer::*pSetValue)( const ValueT& ),
+ const ModifierFunctor& rGetterModifier,
+ const ModifierFunctor& rSetterModifier ) :
+ mpShape(),
+ mpAttrLayer(),
+ mpShapeManager( rShapeManager ),
+ mpIsValidFunc(pIsValid),
+ mpGetValueFunc(pGetValue),
+ mpSetValueFunc(pSetValue),
+ maGetterModifier( rGetterModifier ),
+ maSetterModifier( rSetterModifier ),
+ mnFlags( nFlags ),
+ maDefaultValue(rDefaultValue),
+ mbAnimationStarted( false )
+ {
+ ENSURE_OR_THROW( rShapeManager,
+ "GenericAnimation::GenericAnimation(): Invalid ShapeManager" );
+ ENSURE_OR_THROW( pIsValid && pGetValue && pSetValue,
+ "GenericAnimation::GenericAnimation(): One of the method pointers is NULL" );
+ }
+
+ ~GenericAnimation()
+ {
+ end_();
+ }
+
+ // Animation interface
+ // -------------------
+ virtual void prefetch( const AnimatableShapeSharedPtr&,
+ const ShapeAttributeLayerSharedPtr& )
+ {}
+
+ virtual void start( const AnimatableShapeSharedPtr& rShape,
+ const ShapeAttributeLayerSharedPtr& rAttrLayer )
+ {
+ OSL_ENSURE( !mpShape,
+ "GenericAnimation::start(): Shape already set" );
+ OSL_ENSURE( !mpAttrLayer,
+ "GenericAnimation::start(): Attribute layer already set" );
+
+ mpShape = rShape;
+ mpAttrLayer = rAttrLayer;
+
+ ENSURE_OR_THROW( rShape,
+ "GenericAnimation::start(): Invalid shape" );
+ ENSURE_OR_THROW( rAttrLayer,
+ "GenericAnimation::start(): Invalid attribute layer" );
+
+ // only start animation once per repeated start() call,
+ // and only if sprites should be used for display
+ if( !mbAnimationStarted )
+ {
+ mbAnimationStarted = true;
+
+ if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
+ mpShapeManager->enterAnimationMode( mpShape );
+ }
+ }
+
+ virtual void end() { end_(); }
+ void end_()
+ {
+ // TODO(Q2): Factor out common code (most
+ // prominently start() and end()) into base class
+
+ // only stop animation once per repeated end() call,
+ // and only if sprites are used for display
+ if( mbAnimationStarted )
+ {
+ mbAnimationStarted = false;
+
+ if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
+ mpShapeManager->leaveAnimationMode( mpShape );
+
+ // Attention, this notifyShapeUpdate() is
+ // somewhat delicate here. Calling it
+ // unconditional (i.e. not guarded by
+ // mbAnimationStarted) will lead to shapes
+ // snapping back to their original state just
+ // before the slide ends. Not calling it at
+ // all might swallow final animation
+ // states. The current implementation relies
+ // on the fact that end() is either called by
+ // the Activity (then, the last animation
+ // state has been set, and corresponds to the
+ // shape's hold state), or by the animation
+ // node (then, it's a forced end, and we
+ // _have_ to snap back).
+ //
+ // To reiterate: normally, we're called from
+ // the Activity first, thus the
+ // notifyShapeUpdate() below will update to
+ // the last activity value.
+
+ // force shape update, activity might have changed
+ // state in the last round.
+ if( mpShape->isContentChanged() )
+ mpShapeManager->notifyShapeUpdate( mpShape );
+ }
+ }
+
+ // Derived Animation interface
+ // ---------------------------
+
+ /** For by-reference interfaces (B2DTuple, OUString)
+ */
+ bool operator()( const ValueT& x )
+ {
+ ENSURE_OR_RETURN( mpAttrLayer && mpShape,
+ "GenericAnimation::operator(): Invalid ShapeAttributeLayer" );
+
+ ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) );
+
+ if( mpShape->isContentChanged() )
+ mpShapeManager->notifyShapeUpdate( mpShape );
+
+ return true;
+ }
+
+ /** For by-value interfaces (bool, double)
+ */
+ bool operator()( ValueT x )
+ {
+ ENSURE_OR_RETURN( mpAttrLayer && mpShape,
+ "GenericAnimation::operator(): Invalid ShapeAttributeLayer" );
+
+ ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) );
+
+ if( mpShape->isContentChanged() )
+ mpShapeManager->notifyShapeUpdate( mpShape );
+
+ return true;
+ }
+
+ ValueT getUnderlyingValue() const
+ {
+ ENSURE_OR_THROW( mpAttrLayer,
+ "GenericAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
+
+ // deviated from the (*shared_ptr).*mpFuncPtr
+ // notation here, since gcc does not seem to parse
+ // that as a member function call anymore.
+ if( (mpAttrLayer.get()->*mpIsValidFunc)() )
+ return maGetterModifier( ((*mpAttrLayer).*mpGetValueFunc)() );
+ else
+ return maDefaultValue;
+ }
+
+ private:
+ AnimatableShapeSharedPtr mpShape;
+ ShapeAttributeLayerSharedPtr mpAttrLayer;
+ ShapeManagerSharedPtr mpShapeManager;
+ bool (ShapeAttributeLayer::*mpIsValidFunc)() const;
+ ValueT (ShapeAttributeLayer::*mpGetValueFunc)() const;
+ void (ShapeAttributeLayer::*mpSetValueFunc)( const ValueT& );
+
+ ModifierFunctor maGetterModifier;
+ ModifierFunctor maSetterModifier;
+
+ const int mnFlags;
+
+ const ValueT maDefaultValue;
+ bool mbAnimationStarted;
+ };
+
+ /** Function template wrapper around GenericAnimation template
+
+ @tpl AnimationBase
+ Type of animation to generate (determines the
+ interface GenericAnimation will implement).
+ */
+ template< typename AnimationBase > ::boost::shared_ptr< AnimationBase >
+ makeGenericAnimation( const ShapeManagerSharedPtr& rShapeManager,
+ int nFlags,
+ bool (ShapeAttributeLayer::*pIsValid)() const,
+ const typename AnimationBase::ValueType& rDefaultValue,
+ typename AnimationBase::ValueType (ShapeAttributeLayer::*pGetValue)() const,
+ void (ShapeAttributeLayer::*pSetValue)( const typename AnimationBase::ValueType& ) )
+ {
+ return ::boost::shared_ptr< AnimationBase >(
+ new GenericAnimation< AnimationBase,
+ ::std::identity< typename AnimationBase::ValueType > >(
+ rShapeManager,
+ nFlags,
+ pIsValid,
+ rDefaultValue,
+ pGetValue,
+ pSetValue,
+ // no modification necessary, use identity functor here
+ ::std::identity< typename AnimationBase::ValueType >(),
+ ::std::identity< typename AnimationBase::ValueType >() ) );
+ }
+
+ class Scaler
+ {
+ public:
+ Scaler( double nScale ) :
+ mnScale( nScale )
+ {
+ }
+
+ double operator()( double nVal ) const
+ {
+ return mnScale * nVal;
+ }
+
+ private:
+ double mnScale;
+ };
+
+ /** Overload for NumberAnimations which need scaling (width,height,x,y currently)
+ */
+ NumberAnimationSharedPtr makeGenericAnimation( const ShapeManagerSharedPtr& rShapeManager,
+ int nFlags,
+ bool (ShapeAttributeLayer::*pIsValid)() const,
+ double nDefaultValue,
+ double (ShapeAttributeLayer::*pGetValue)() const,
+ void (ShapeAttributeLayer::*pSetValue)( const double& ),
+ double nScaleValue )
+ {
+ return NumberAnimationSharedPtr(
+ new GenericAnimation< NumberAnimation, Scaler >( rShapeManager,
+ nFlags,
+ pIsValid,
+ nDefaultValue / nScaleValue,
+ pGetValue,
+ pSetValue,
+ Scaler( 1.0/nScaleValue ),
+ Scaler( nScaleValue ) ) );
+ }
+
+
+ uno::Any getShapeDefault( const AnimatableShapeSharedPtr& rShape,
+ const ::rtl::OUString& rPropertyName )
+ {
+ uno::Reference< drawing::XShape > xShape( rShape->getXShape() );
+
+ if( !xShape.is() )
+ return uno::Any(); // no regular shape, no defaults available
+
+
+ // extract relevant value from XShape's PropertySet
+ uno::Reference< beans::XPropertySet > xPropSet( xShape,
+ uno::UNO_QUERY );
+
+ ENSURE_OR_THROW( xPropSet.is(),
+ "getShapeDefault(): Cannot query property set from shape" );
+
+ return xPropSet->getPropertyValue( rPropertyName );
+ }
+
+ template< typename ValueType > ValueType getDefault( const AnimatableShapeSharedPtr& rShape,
+ const ::rtl::OUString& rPropertyName )
+ {
+ const uno::Any& rAny( getShapeDefault( rShape,
+ rPropertyName ) );
+
+ if( !rAny.hasValue() )
+ {
+ OSL_ENSURE( false, "getDefault(): cannot get requested shape property" );
+ OSL_TRACE( "getDefault(): cannot get '%s' shape property",
+ ::rtl::OUStringToOString( rPropertyName,
+ RTL_TEXTENCODING_ASCII_US ).getStr() );
+ return ValueType();
+ }
+ else
+ {
+ ValueType aValue = ValueType();
+
+ if( !(rAny >>= aValue) )
+ {
+ OSL_ENSURE( false, "getDefault(): cannot extract requested shape property" );
+ OSL_TRACE( "getDefault(): cannot extract '%s' shape property",
+ ::rtl::OUStringToOString( rPropertyName,
+ RTL_TEXTENCODING_ASCII_US ).getStr() );
+ return ValueType();
+ }
+
+ return aValue;
+ }
+ }
+
+ template<> RGBColor getDefault< RGBColor >( const AnimatableShapeSharedPtr& rShape,
+ const ::rtl::OUString& rPropertyName )
+ {
+ const uno::Any& rAny( getShapeDefault( rShape,
+ rPropertyName ) );
+
+ if( !rAny.hasValue() )
+ {
+ OSL_ENSURE( false, "getDefault(): cannot get requested shape color property" );
+ OSL_TRACE( "getDefault(): cannot get '%s' shape color property",
+ ::rtl::OUStringToOString( rPropertyName,
+ RTL_TEXTENCODING_ASCII_US ).getStr() );
+ return RGBColor();
+ }
+ else
+ {
+ sal_Int32 nValue = 0;
+
+ if( !(rAny >>= nValue) )
+ {
+ OSL_ENSURE( false, "getDefault(): cannot extract requested shape color property" );
+ OSL_TRACE( "getDefault(): cannot extract '%s' shape color property",
+ ::rtl::OUStringToOString( rPropertyName,
+ RTL_TEXTENCODING_ASCII_US ).getStr() );
+ return RGBColor();
+ }
+
+ // convert from 0xAARRGGBB API color to 0xRRGGBB00
+ // canvas color
+ return RGBColor( (nValue << 8U) & 0xFFFFFF00U );
+ }
+ }
+ }
+
+ AnimationFactory::AttributeClass AnimationFactory::classifyAttributeName( const ::rtl::OUString& rAttrName )
+ {
+ // ATTENTION: When changing this map, also the create*PropertyAnimation() methods must
+ // be checked and possibly adapted in their switch statements
+
+ // TODO(Q2): Since this map must be coherent with the various switch statements
+ // in the create*PropertyAnimation methods, try to unify into a single method or table
+ switch( mapAttributeName( rAttrName ) )
+ {
+ default:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_INVALID:
+ return CLASS_UNKNOWN_PROPERTY;
+
+ case ATTRIBUTE_CHAR_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_DIMCOLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_FILL_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_LINE_COLOR:
+ return CLASS_COLOR_PROPERTY;
+
+ case ATTRIBUTE_CHAR_FONT_NAME:
+ return CLASS_STRING_PROPERTY;
+
+ case ATTRIBUTE_VISIBILITY:
+ return CLASS_BOOL_PROPERTY;
+
+ case ATTRIBUTE_CHAR_HEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_WEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_ROTATION:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_HEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_OPACITY:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_ROTATE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_SKEW_X:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_SKEW_Y:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_WIDTH:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_POS_X:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_POS_Y:
+ return CLASS_NUMBER_PROPERTY;
+
+ case ATTRIBUTE_CHAR_UNDERLINE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_FILL_STYLE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_LINE_STYLE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_POSTURE:
+ return CLASS_ENUM_PROPERTY;
+ }
+ }
+
+ NumberAnimationSharedPtr AnimationFactory::createNumberPropertyAnimation( const ::rtl::OUString& rAttrName,
+ const AnimatableShapeSharedPtr& rShape,
+ const ShapeManagerSharedPtr& rShapeManager,
+ const ::basegfx::B2DVector& rSlideSize,
+ int nFlags )
+ {
+ // ATTENTION: When changing this map, also the classifyAttributeName() method must
+ // be checked and possibly adapted in their switch statement
+ switch( mapAttributeName( rAttrName ) )
+ {
+ default:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_INVALID:
+ ENSURE_OR_THROW( false,
+ "AnimationFactory::createNumberPropertyAnimation(): Unknown attribute" );
+ break;
+
+ case ATTRIBUTE_CHAR_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_FONT_NAME:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_POSTURE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_UNDERLINE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_DIMCOLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_FILL_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_FILL_STYLE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_LINE_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_LINE_STYLE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_VISIBILITY:
+ ENSURE_OR_THROW( false,
+ "AnimationFactory::createNumberPropertyAnimation(): Attribute type mismatch" );
+ break;
+
+ case ATTRIBUTE_CHAR_HEIGHT:
+ return makeGenericAnimation<NumberAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isCharScaleValid,
+ 1.0, // CharHeight is a relative attribute, thus
+ // default is 1.0
+ &ShapeAttributeLayer::getCharScale,
+ &ShapeAttributeLayer::setCharScale );
+
+ case ATTRIBUTE_CHAR_WEIGHT:
+ return makeGenericAnimation<NumberAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isCharWeightValid,
+ getDefault<double>( rShape, rAttrName ),
+ &ShapeAttributeLayer::getCharWeight,
+ &ShapeAttributeLayer::setCharWeight );
+
+ case ATTRIBUTE_CHAR_ROTATION:
+ return makeGenericAnimation<NumberAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isCharRotationAngleValid,
+ getDefault<double>( rShape, rAttrName ),
+ &ShapeAttributeLayer::getCharRotationAngle,
+ &ShapeAttributeLayer::setCharRotationAngle );
+
+ case ATTRIBUTE_HEIGHT:
+ return makeGenericAnimation( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isHeightValid,
+ // TODO(F1): Check whether _shape_ bounds are correct here.
+ // Theoretically, our AttrLayer is way down the stack, and
+ // we only have to consider _that_ value, not the one from
+ // the top of the stack as returned by Shape::getBounds()
+ rShape->getBounds().getHeight(),
+ &ShapeAttributeLayer::getHeight,
+ &ShapeAttributeLayer::setHeight,
+ // convert expression parser value from relative page size
+ rSlideSize.getY() );
+
+ case ATTRIBUTE_OPACITY:
+ return makeGenericAnimation<NumberAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isAlphaValid,
+ // TODO(F1): Provide shape default here (FillTransparency?)
+ 1.0,
+ &ShapeAttributeLayer::getAlpha,
+ &ShapeAttributeLayer::setAlpha );
+
+ case ATTRIBUTE_ROTATE:
+ return makeGenericAnimation<NumberAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isRotationAngleValid,
+ // NOTE: Since we paint the shape as-is from metafile,
+ // rotation angle is always 0.0, even for rotated shapes
+ 0.0,
+ &ShapeAttributeLayer::getRotationAngle,
+ &ShapeAttributeLayer::setRotationAngle );
+
+ case ATTRIBUTE_SKEW_X:
+ return makeGenericAnimation<NumberAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isShearXAngleValid,
+ // TODO(F1): Is there any shape property for skew?
+ 0.0,
+ &ShapeAttributeLayer::getShearXAngle,
+ &ShapeAttributeLayer::setShearXAngle );
+
+ case ATTRIBUTE_SKEW_Y:
+ return makeGenericAnimation<NumberAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isShearYAngleValid,
+ // TODO(F1): Is there any shape property for skew?
+ 0.0,
+ &ShapeAttributeLayer::getShearYAngle,
+ &ShapeAttributeLayer::setShearYAngle );
+
+ case ATTRIBUTE_WIDTH:
+ return makeGenericAnimation( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isWidthValid,
+ // TODO(F1): Check whether _shape_ bounds are correct here.
+ // Theoretically, our AttrLayer is way down the stack, and
+ // we only have to consider _that_ value, not the one from
+ // the top of the stack as returned by Shape::getBounds()
+ rShape->getBounds().getWidth(),
+ &ShapeAttributeLayer::getWidth,
+ &ShapeAttributeLayer::setWidth,
+ // convert expression parser value from relative page size
+ rSlideSize.getX() );
+
+ case ATTRIBUTE_POS_X:
+ return makeGenericAnimation( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isPosXValid,
+ // TODO(F1): Check whether _shape_ bounds are correct here.
+ // Theoretically, our AttrLayer is way down the stack, and
+ // we only have to consider _that_ value, not the one from
+ // the top of the stack as returned by Shape::getBounds()
+ rShape->getBounds().getCenterX(),
+ &ShapeAttributeLayer::getPosX,
+ &ShapeAttributeLayer::setPosX,
+ // convert expression parser value from relative page size
+ rSlideSize.getX() );
+
+ case ATTRIBUTE_POS_Y:
+ return makeGenericAnimation( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isPosYValid,
+ // TODO(F1): Check whether _shape_ bounds are correct here.
+ // Theoretically, our AttrLayer is way down the stack, and
+ // we only have to consider _that_ value, not the one from
+ // the top of the stack as returned by Shape::getBounds()
+ rShape->getBounds().getCenterY(),
+ &ShapeAttributeLayer::getPosY,
+ &ShapeAttributeLayer::setPosY,
+ // convert expression parser value from relative page size
+ rSlideSize.getY() );
+ }
+
+ return NumberAnimationSharedPtr();
+ }
+
+ EnumAnimationSharedPtr AnimationFactory::createEnumPropertyAnimation( const ::rtl::OUString& rAttrName,
+ const AnimatableShapeSharedPtr& rShape,
+ const ShapeManagerSharedPtr& rShapeManager,
+ const ::basegfx::B2DVector& /*rSlideSize*/,
+ int nFlags )
+ {
+ // ATTENTION: When changing this map, also the classifyAttributeName() method must
+ // be checked and possibly adapted in their switch statement
+ switch( mapAttributeName( rAttrName ) )
+ {
+ default:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_INVALID:
+ ENSURE_OR_THROW( false,
+ "AnimationFactory::createEnumPropertyAnimation(): Unknown attribute" );
+ break;
+
+ case ATTRIBUTE_CHAR_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_FONT_NAME:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_DIMCOLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_FILL_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_LINE_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_VISIBILITY:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_HEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_WEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_ROTATION:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_HEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_OPACITY:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_ROTATE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_SKEW_X:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_SKEW_Y:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_WIDTH:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_POS_X:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_POS_Y:
+ ENSURE_OR_THROW( false,
+ "AnimationFactory::createEnumPropertyAnimation(): Attribute type mismatch" );
+ break;
+
+
+ case ATTRIBUTE_FILL_STYLE:
+ return makeGenericAnimation<EnumAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isFillStyleValid,
+ sal::static_int_cast<sal_Int16>(
+ getDefault<drawing::FillStyle>( rShape, rAttrName )),
+ &ShapeAttributeLayer::getFillStyle,
+ &ShapeAttributeLayer::setFillStyle );
+
+ case ATTRIBUTE_LINE_STYLE:
+ return makeGenericAnimation<EnumAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isLineStyleValid,
+ sal::static_int_cast<sal_Int16>(
+ getDefault<drawing::LineStyle>( rShape, rAttrName )),
+ &ShapeAttributeLayer::getLineStyle,
+ &ShapeAttributeLayer::setLineStyle );
+
+ case ATTRIBUTE_CHAR_POSTURE:
+ return makeGenericAnimation<EnumAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isCharPostureValid,
+ sal::static_int_cast<sal_Int16>(
+ getDefault<awt::FontSlant>( rShape, rAttrName )),
+ &ShapeAttributeLayer::getCharPosture,
+ &ShapeAttributeLayer::setCharPosture );
+
+ case ATTRIBUTE_CHAR_UNDERLINE:
+ return makeGenericAnimation<EnumAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isUnderlineModeValid,
+ getDefault<sal_Int16>( rShape, rAttrName ),
+ &ShapeAttributeLayer::getUnderlineMode,
+ &ShapeAttributeLayer::setUnderlineMode );
+ }
+
+ return EnumAnimationSharedPtr();
+ }
+
+ ColorAnimationSharedPtr AnimationFactory::createColorPropertyAnimation( const ::rtl::OUString& rAttrName,
+ const AnimatableShapeSharedPtr& rShape,
+ const ShapeManagerSharedPtr& rShapeManager,
+ const ::basegfx::B2DVector& /*rSlideSize*/,
+ int nFlags )
+ {
+ // ATTENTION: When changing this map, also the classifyAttributeName() method must
+ // be checked and possibly adapted in their switch statement
+ switch( mapAttributeName( rAttrName ) )
+ {
+ default:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_INVALID:
+ ENSURE_OR_THROW( false,
+ "AnimationFactory::createColorPropertyAnimation(): Unknown attribute" );
+ break;
+
+ case ATTRIBUTE_CHAR_FONT_NAME:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_HEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_POSTURE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_ROTATION:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_UNDERLINE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_WEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_FILL_STYLE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_HEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_LINE_STYLE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_OPACITY:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_ROTATE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_SKEW_X:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_SKEW_Y:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_VISIBILITY:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_WIDTH:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_POS_X:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_POS_Y:
+ ENSURE_OR_THROW( false,
+ "AnimationFactory::createColorPropertyAnimation(): Attribute type mismatch" );
+ break;
+
+ case ATTRIBUTE_CHAR_COLOR:
+ return makeGenericAnimation<ColorAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isCharColorValid,
+ getDefault<RGBColor>( rShape, rAttrName ),
+ &ShapeAttributeLayer::getCharColor,
+ &ShapeAttributeLayer::setCharColor );
+
+ case ATTRIBUTE_COLOR:
+ // TODO(F2): This is just mapped to fill color to make it work
+ return makeGenericAnimation<ColorAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isFillColorValid,
+ getDefault<RGBColor>( rShape, rAttrName ),
+ &ShapeAttributeLayer::getFillColor,
+ &ShapeAttributeLayer::setFillColor );
+
+ case ATTRIBUTE_DIMCOLOR:
+ return makeGenericAnimation<ColorAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isDimColorValid,
+ getDefault<RGBColor>( rShape, rAttrName ),
+ &ShapeAttributeLayer::getDimColor,
+ &ShapeAttributeLayer::setDimColor );
+
+ case ATTRIBUTE_FILL_COLOR:
+ return makeGenericAnimation<ColorAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isFillColorValid,
+ getDefault<RGBColor>( rShape, rAttrName ),
+ &ShapeAttributeLayer::getFillColor,
+ &ShapeAttributeLayer::setFillColor );
+
+ case ATTRIBUTE_LINE_COLOR:
+ return makeGenericAnimation<ColorAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isLineColorValid,
+ getDefault<RGBColor>( rShape, rAttrName ),
+ &ShapeAttributeLayer::getLineColor,
+ &ShapeAttributeLayer::setLineColor );
+ }
+
+ return ColorAnimationSharedPtr();
+ }
+
+ PairAnimationSharedPtr AnimationFactory::createPairPropertyAnimation( const AnimatableShapeSharedPtr& rShape,
+ const ShapeManagerSharedPtr& rShapeManager,
+ const ::basegfx::B2DVector& rSlideSize,
+ sal_Int16 nTransformType,
+ int nFlags )
+ {
+ const ::basegfx::B2DRectangle& rBounds( rShape->getBounds() );
+
+ switch( nTransformType )
+ {
+ case animations::AnimationTransformType::SCALE:
+ return PairAnimationSharedPtr(
+ new TupleAnimation< ::basegfx::B2DSize >(
+ rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isWidthValid,
+ &ShapeAttributeLayer::isHeightValid,
+ // TODO(F1): Check whether _shape_ bounds are correct here.
+ // Theoretically, our AttrLayer is way down the stack, and
+ // we only have to consider _that_ value, not the one from
+ // the top of the stack as returned by Shape::getBounds()
+ rBounds.getRange(),
+ rBounds.getRange(),
+ &ShapeAttributeLayer::getWidth,
+ &ShapeAttributeLayer::getHeight,
+ &ShapeAttributeLayer::setSize ) );
+
+ case animations::AnimationTransformType::TRANSLATE:
+ return PairAnimationSharedPtr(
+ new TupleAnimation< ::basegfx::B2DPoint >(
+ rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isPosXValid,
+ &ShapeAttributeLayer::isPosYValid,
+ // TODO(F1): Check whether _shape_ bounds are correct here.
+ // Theoretically, our AttrLayer is way down the stack, and
+ // we only have to consider _that_ value, not the one from
+ // the top of the stack as returned by Shape::getBounds()
+ rBounds.getCenter(),
+ rSlideSize,
+ &ShapeAttributeLayer::getPosX,
+ &ShapeAttributeLayer::getPosY,
+ &ShapeAttributeLayer::setPosition ) );
+
+ default:
+ ENSURE_OR_THROW( false,
+ "AnimationFactory::createPairPropertyAnimation(): Attribute type mismatch" );
+ break;
+ }
+
+ return PairAnimationSharedPtr();
+ }
+
+ StringAnimationSharedPtr AnimationFactory::createStringPropertyAnimation( const ::rtl::OUString& rAttrName,
+ const AnimatableShapeSharedPtr& rShape,
+ const ShapeManagerSharedPtr& rShapeManager,
+ const ::basegfx::B2DVector& /*rSlideSize*/,
+ int nFlags )
+ {
+ // ATTENTION: When changing this map, also the classifyAttributeName() method must
+ // be checked and possibly adapted in their switch statement
+ switch( mapAttributeName( rAttrName ) )
+ {
+ default:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_INVALID:
+ ENSURE_OR_THROW( false,
+ "AnimationFactory::createStringPropertyAnimation(): Unknown attribute" );
+ break;
+
+ case ATTRIBUTE_CHAR_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_HEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_ROTATION:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_UNDERLINE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_DIMCOLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_FILL_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_HEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_LINE_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_OPACITY:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_ROTATE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_SKEW_X:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_SKEW_Y:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_VISIBILITY:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_WIDTH:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_POS_X:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_POS_Y:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_POSTURE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_WEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_FILL_STYLE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_LINE_STYLE:
+ ENSURE_OR_THROW( false,
+ "AnimationFactory::createStringPropertyAnimation(): Attribute type mismatch" );
+ break;
+
+ case ATTRIBUTE_CHAR_FONT_NAME:
+ return makeGenericAnimation<StringAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isFontFamilyValid,
+ getDefault< ::rtl::OUString >( rShape, rAttrName ),
+ &ShapeAttributeLayer::getFontFamily,
+ &ShapeAttributeLayer::setFontFamily );
+ }
+
+ return StringAnimationSharedPtr();
+ }
+
+ BoolAnimationSharedPtr AnimationFactory::createBoolPropertyAnimation( const ::rtl::OUString& rAttrName,
+ const AnimatableShapeSharedPtr& /*rShape*/,
+ const ShapeManagerSharedPtr& rShapeManager,
+ const ::basegfx::B2DVector& /*rSlideSize*/,
+ int nFlags )
+ {
+ // ATTENTION: When changing this map, also the classifyAttributeName() method must
+ // be checked and possibly adapted in their switch statement
+ switch( mapAttributeName( rAttrName ) )
+ {
+ default:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_INVALID:
+ ENSURE_OR_THROW( false,
+ "AnimationFactory::createBoolPropertyAnimation(): Unknown attribute" );
+ break;
+
+ case ATTRIBUTE_CHAR_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_FONT_NAME:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_HEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_POSTURE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_ROTATION:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_WEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_DIMCOLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_FILL_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_FILL_STYLE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_HEIGHT:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_LINE_COLOR:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_LINE_STYLE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_OPACITY:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_ROTATE:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_SKEW_X:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_SKEW_Y:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_WIDTH:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_POS_X:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_POS_Y:
+ // FALLTHROUGH intended
+ case ATTRIBUTE_CHAR_UNDERLINE:
+ ENSURE_OR_THROW( false,
+ "AnimationFactory::createBoolPropertyAnimation(): Attribute type mismatch" );
+ break;
+
+ case ATTRIBUTE_VISIBILITY:
+ return makeGenericAnimation<BoolAnimation>( rShapeManager,
+ nFlags,
+ &ShapeAttributeLayer::isVisibilityValid,
+ // TODO(F1): Is there a corresponding shape property?
+ true,
+ &ShapeAttributeLayer::getVisibility,
+ &ShapeAttributeLayer::setVisibility );
+ }
+
+ return BoolAnimationSharedPtr();
+ }
+
+ NumberAnimationSharedPtr AnimationFactory::createPathMotionAnimation( const ::rtl::OUString& rSVGDPath,
+ sal_Int16 nAdditive,
+ const AnimatableShapeSharedPtr& /*rShape*/,
+ const ShapeManagerSharedPtr& rShapeManager,
+ const ::basegfx::B2DVector& rSlideSize,
+ int nFlags )
+ {
+ return NumberAnimationSharedPtr(
+ new PathAnimation( rSVGDPath, nAdditive,
+ rShapeManager,
+ rSlideSize,
+ nFlags ) );
+ }
+
+ }
+}