368 lines
14 KiB
C++
368 lines
14 KiB
C++
/* -*- 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 <comphelper/diagnose_ex.hxx>
|
|
|
|
#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
|
|
auto aBounds = mpShape->getDomBounds().getRange();
|
|
mpAttrLayer->setClip( maClippingFunctor(nValue, basegfx::B2DSize(aBounds.getX(), aBounds.getY())) );
|
|
|
|
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;
|
|
break;
|
|
|
|
case animations::TransitionSubType::FROMRIGHT:
|
|
nBarWipeSubType = animations::TransitionSubType::LEFTTORIGHT;
|
|
bDirectionForward = false;
|
|
break;
|
|
|
|
case animations::TransitionSubType::FROMTOP:
|
|
nBarWipeSubType = animations::TransitionSubType::TOPTOBOTTOM;
|
|
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(
|
|
u"Opacity"_ustr,
|
|
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: */
|