/************************************************************** * * 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" #include #include #include #include #include #include #include #include #include #include "transitionfactory.hxx" #include "transitiontools.hxx" #include "parametricpolypolygonfactory.hxx" #include "animationfactory.hxx" #include "clippingfunctor.hxx" #include using namespace ::com::sun::star; namespace slideshow { namespace internal { /*************************************************** *** *** *** Shape Transition Effects *** *** *** ***************************************************/ namespace { class ClippingAnimation : public NumberAnimation { public: ClippingAnimation( const ParametricPolyPolygonSharedPtr& rPolygon, const ShapeManagerSharedPtr& rShapeManager, const TransitionInfo& rTransitionInfo, bool bDirectionForward, bool bModeIn ); ~ClippingAnimation(); // Animation interface // ------------------- virtual void prefetch( const AnimatableShapeSharedPtr& rShape, const ShapeAttributeLayerSharedPtr& rAttrLayer ); virtual void start( const AnimatableShapeSharedPtr& rShape, const ShapeAttributeLayerSharedPtr& rAttrLayer ); virtual void end(); // NumberAnimation interface // ----------------------- virtual bool operator()( double nValue ); virtual double getUnderlyingValue() const; private: void end_(); AnimatableShapeSharedPtr mpShape; ShapeAttributeLayerSharedPtr mpAttrLayer; ShapeManagerSharedPtr mpShapeManager; ClippingFunctor maClippingFunctor; bool mbSpriteActive; }; ClippingAnimation::ClippingAnimation( const ParametricPolyPolygonSharedPtr& rPolygon, const ShapeManagerSharedPtr& rShapeManager, const TransitionInfo& rTransitionInfo, bool bDirectionForward, bool bModeIn ) : mpShape(), mpAttrLayer(), mpShapeManager( rShapeManager ), maClippingFunctor( rPolygon, rTransitionInfo, bDirectionForward, bModeIn ), mbSpriteActive(false) { ENSURE_OR_THROW( rShapeManager, "ClippingAnimation::ClippingAnimation(): Invalid ShapeManager" ); } ClippingAnimation::~ClippingAnimation() { try { end_(); } catch (uno::Exception &) { OSL_ENSURE( false, rtl::OUStringToOString( comphelper::anyToString( cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 ).getStr() ); } } void ClippingAnimation::prefetch( const AnimatableShapeSharedPtr&, const ShapeAttributeLayerSharedPtr& ) { } void ClippingAnimation::start( const AnimatableShapeSharedPtr& rShape, const ShapeAttributeLayerSharedPtr& rAttrLayer ) { OSL_ENSURE( !mpShape, "ClippingAnimation::start(): Shape already set" ); OSL_ENSURE( !mpAttrLayer, "ClippingAnimation::start(): Attribute layer already set" ); mpShape = rShape; mpAttrLayer = rAttrLayer; ENSURE_OR_THROW( rShape, "ClippingAnimation::start(): Invalid shape" ); ENSURE_OR_THROW( rAttrLayer, "ClippingAnimation::start(): Invalid attribute layer" ); mpShape = rShape; mpAttrLayer = rAttrLayer; if( !mbSpriteActive ) { mpShapeManager->enterAnimationMode( mpShape ); mbSpriteActive = true; } } void ClippingAnimation::end() { end_(); } void ClippingAnimation::end_() { if( mbSpriteActive ) { mbSpriteActive = false; mpShapeManager->leaveAnimationMode( mpShape ); if( mpShape->isContentChanged() ) mpShapeManager->notifyShapeUpdate( mpShape ); } } bool ClippingAnimation::operator()( double nValue ) { ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape, "ClippingAnimation::operator(): Invalid ShapeAttributeLayer" ); // set new clip mpAttrLayer->setClip( maClippingFunctor( nValue, mpShape->getDomBounds().getRange() ) ); if( mpShape->isContentChanged() ) mpShapeManager->notifyShapeUpdate( mpShape ); return true; } double ClippingAnimation::getUnderlyingValue() const { ENSURE_OR_THROW( mpAttrLayer, "ClippingAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" ); return 0.0; // though this should be used in concert with // ActivitiesFactory::createSimpleActivity, better // explicitly name our start value. // Permissible range for operator() above is [0,1] } } // anon namespace AnimationActivitySharedPtr TransitionFactory::createShapeTransition( const ActivitiesFactory::CommonParameters& rParms, const AnimatableShapeSharedPtr& rShape, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& rSlideSize, uno::Reference< animations::XTransitionFilter > const& xTransition ) { return createShapeTransition( rParms, rShape, rShapeManager, rSlideSize, xTransition, xTransition->getTransition(), xTransition->getSubtype() ); } AnimationActivitySharedPtr TransitionFactory::createShapeTransition( const ActivitiesFactory::CommonParameters& rParms, const AnimatableShapeSharedPtr& rShape, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& rSlideSize, ::com::sun::star::uno::Reference< ::com::sun::star::animations::XTransitionFilter > const& xTransition, sal_Int16 nType, sal_Int16 nSubType ) { ENSURE_OR_THROW( xTransition.is(), "TransitionFactory::createShapeTransition(): Invalid XTransition" ); const TransitionInfo* pTransitionInfo( getTransitionInfo( nType, nSubType ) ); AnimationActivitySharedPtr pGeneratedActivity; if( pTransitionInfo != NULL ) { switch( pTransitionInfo->meTransitionClass ) { default: case TransitionInfo::TRANSITION_INVALID: OSL_ENSURE( false, "TransitionFactory::createShapeTransition(): Invalid transition type. " "Don't ask me for a 0 TransitionType, have no XTransitionFilter node instead!" ); return AnimationActivitySharedPtr(); case TransitionInfo::TRANSITION_CLIP_POLYPOLYGON: { // generate parametric poly-polygon ParametricPolyPolygonSharedPtr pPoly( ParametricPolyPolygonFactory::createClipPolyPolygon( nType, nSubType ) ); // create a clip activity from that pGeneratedActivity = ActivitiesFactory::createSimpleActivity( rParms, NumberAnimationSharedPtr( new ClippingAnimation( pPoly, rShapeManager, *pTransitionInfo, xTransition->getDirection(), xTransition->getMode() ) ), true ); } break; case TransitionInfo::TRANSITION_SPECIAL: { switch( nType ) { case animations::TransitionType::RANDOM: { // select randomly one of the effects from the // TransitionFactoryTable const TransitionInfo* pRandomTransitionInfo( getRandomTransitionInfo() ); ENSURE_OR_THROW( pRandomTransitionInfo != NULL, "TransitionFactory::createShapeTransition(): Got invalid random transition info" ); ENSURE_OR_THROW( pRandomTransitionInfo->mnTransitionType != animations::TransitionType::RANDOM, "TransitionFactory::createShapeTransition(): Got random again for random input!" ); // and recurse pGeneratedActivity = createShapeTransition( rParms, rShape, rShapeManager, rSlideSize, xTransition, pRandomTransitionInfo->mnTransitionType, pRandomTransitionInfo->mnTransitionSubType ); } break; // TODO(F3): Implement slidewipe for shape case animations::TransitionType::SLIDEWIPE: { sal_Int16 nBarWipeSubType(0); bool bDirectionForward(true); // map slidewipe to BARWIPE, for now switch( nSubType ) { case animations::TransitionSubType::FROMLEFT: nBarWipeSubType = animations::TransitionSubType::LEFTTORIGHT; bDirectionForward = true; break; case animations::TransitionSubType::FROMRIGHT: nBarWipeSubType = animations::TransitionSubType::LEFTTORIGHT; bDirectionForward = false; break; case animations::TransitionSubType::FROMTOP: nBarWipeSubType = animations::TransitionSubType::TOPTOBOTTOM; bDirectionForward = true; break; case animations::TransitionSubType::FROMBOTTOM: nBarWipeSubType = animations::TransitionSubType::TOPTOBOTTOM; bDirectionForward = false; break; default: ENSURE_OR_THROW( false, "TransitionFactory::createShapeTransition(): Unexpected subtype for SLIDEWIPE" ); break; } // generate parametric poly-polygon ParametricPolyPolygonSharedPtr pPoly( ParametricPolyPolygonFactory::createClipPolyPolygon( animations::TransitionType::BARWIPE, nBarWipeSubType ) ); // create a clip activity from that pGeneratedActivity = ActivitiesFactory::createSimpleActivity( rParms, NumberAnimationSharedPtr( new ClippingAnimation( pPoly, rShapeManager, *getTransitionInfo( animations::TransitionType::BARWIPE, nBarWipeSubType ), bDirectionForward, xTransition->getMode() ) ), true ); } break; default: { // TODO(F1): Check whether there's anything left, anyway, // for _shape_ transitions. AFAIK, there are no special // effects for shapes... // for now, map all to fade effect pGeneratedActivity = ActivitiesFactory::createSimpleActivity( rParms, AnimationFactory::createNumberPropertyAnimation( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Opacity") ), rShape, rShapeManager, rSlideSize ), xTransition->getMode() ); } break; } } break; } } if( !pGeneratedActivity ) { // No animation generated, maybe no table entry for given // transition? OSL_TRACE( "TransitionFactory::createShapeTransition(): Unknown type/subtype (%d/%d) " "combination encountered", xTransition->getTransition(), xTransition->getSubtype() ); OSL_ENSURE( false, "TransitionFactory::createShapeTransition(): Unknown type/subtype " "combination encountered" ); } return pGeneratedActivity; } } }