diff options
Diffstat (limited to 'slideshow/source/engine/transitions/shapetransitionfactory.cxx')
-rw-r--r-- | slideshow/source/engine/transitions/shapetransitionfactory.cxx | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/slideshow/source/engine/transitions/shapetransitionfactory.cxx b/slideshow/source/engine/transitions/shapetransitionfactory.cxx new file mode 100644 index 000000000..3586cff71 --- /dev/null +++ b/slideshow/source/engine/transitions/shapetransitionfactory.cxx @@ -0,0 +1,370 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + + +#include <tools/diagnose_ex.h> + +#include <sal/log.hxx> + +#include <com/sun/star/animations/TransitionType.hpp> +#include <com/sun/star/animations/TransitionSubType.hpp> + +#include <transitionfactory.hxx> +#include "transitionfactorytab.hxx" +#include "parametricpolypolygonfactory.hxx" +#include <animationfactory.hxx> +#include "clippingfunctor.hxx" + +using namespace ::com::sun::star; + +namespace slideshow::internal { + +/*************************************************** + *** *** + *** Shape Transition Effects *** + *** *** + ***************************************************/ + +namespace { + +class ClippingAnimation : public NumberAnimation +{ +public: + ClippingAnimation( + const ParametricPolyPolygonSharedPtr& rPolygon, + const ShapeManagerSharedPtr& rShapeManager, + const TransitionInfo& rTransitionInfo, + bool bDirectionForward, + bool bModeIn ); + + virtual ~ClippingAnimation() override; + + // Animation interface + + virtual void prefetch() override; + virtual void start( const AnimatableShapeSharedPtr& rShape, + const ShapeAttributeLayerSharedPtr& rAttrLayer ) override; + virtual void end() override; + + // NumberAnimation interface + + virtual bool operator()( double nValue ) override; + virtual double getUnderlyingValue() const override; + +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 (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("slideshow", ""); + } +} + +void ClippingAnimation::prefetch() +{ +} + +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" ); + 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] +} + +AnimationActivitySharedPtr createShapeTransitionByType( + const ActivitiesFactory::CommonParameters& rParms, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + css::uno::Reference< css::animations::XTransitionFilter > const& xTransition, + sal_Int16 nType, + sal_Int16 nSubType ) +{ + ENSURE_OR_THROW( + xTransition.is(), + "createShapeTransitionByType(): Invalid XTransition" ); + + const TransitionInfo* pTransitionInfo( + getTransitionInfo( nType, nSubType ) ); + + AnimationActivitySharedPtr pGeneratedActivity; + if( pTransitionInfo != nullptr ) + { + switch( pTransitionInfo->meTransitionClass ) + { + default: + case TransitionInfo::TRANSITION_INVALID: + OSL_FAIL( "createShapeTransitionByType(): 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, + std::make_shared<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 != nullptr, + "createShapeTransitionByType(): Got invalid random transition info" ); + + ENSURE_OR_THROW( pRandomTransitionInfo->mnTransitionType != animations::TransitionType::RANDOM, + "createShapeTransitionByType(): Got random again for random input!" ); + + // and recurse + pGeneratedActivity = createShapeTransitionByType( 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, + "createShapeTransitionByType(): 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, + std::make_shared<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( + "Opacity", + rShape, + rShapeManager, + rSlideSize, + nullptr ), + xTransition->getMode() ); + } + break; + } + } + break; + } + } + + if( !pGeneratedActivity ) + { + // No animation generated, maybe no table entry for given + // transition? + SAL_WARN("slideshow", + "createShapeTransitionByType(): Unknown type/subtype combination encountered: " + << xTransition->getTransition() << " " << xTransition->getSubtype() ); + } + + return pGeneratedActivity; +} + +} // 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 createShapeTransitionByType( rParms, + rShape, + rShapeManager, + rSlideSize, + xTransition, + xTransition->getTransition(), + xTransition->getSubtype() ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |