| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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_FALSE( 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, false, 0 ), |
| "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_FALSE( 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_FALSE( 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_FALSE( 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 ) ); |
| } |
| |
| } |
| } |