summaryrefslogtreecommitdiffstats
path: root/slideshow/source/engine/transitions/shapetransitionfactory.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'slideshow/source/engine/transitions/shapetransitionfactory.cxx')
-rw-r--r--slideshow/source/engine/transitions/shapetransitionfactory.cxx370
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: */