diff options
Diffstat (limited to 'slideshow/source/engine/animationnodes/animationnodefactory.cxx')
-rw-r--r-- | slideshow/source/engine/animationnodes/animationnodefactory.cxx | 621 |
1 files changed, 0 insertions, 621 deletions
diff --git a/slideshow/source/engine/animationnodes/animationnodefactory.cxx b/slideshow/source/engine/animationnodes/animationnodefactory.cxx deleted file mode 100644 index feeb9aeec..000000000 --- a/slideshow/source/engine/animationnodes/animationnodefactory.cxx +++ /dev/null @@ -1,621 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_slideshow.hxx" - -// must be first -#include <canvas/debug.hxx> -#include <canvas/verbosetrace.hxx> - -#include <com/sun/star/drawing/XShape.hpp> -#include <com/sun/star/animations/XAnimate.hpp> -#include <com/sun/star/animations/AnimationNodeType.hpp> -#include <com/sun/star/presentation/EffectNodeType.hpp> -#include <com/sun/star/presentation/TextAnimationType.hpp> -#include <com/sun/star/animations/XAnimateSet.hpp> -#include <com/sun/star/animations/XIterateContainer.hpp> -#include <com/sun/star/presentation/ShapeAnimationSubType.hpp> -#include <com/sun/star/animations/XAnimateMotion.hpp> -#include <com/sun/star/animations/XAnimateColor.hpp> -#include <com/sun/star/animations/XAnimateTransform.hpp> -#include <com/sun/star/animations/AnimationTransformType.hpp> -#include <com/sun/star/animations/XTransitionFilter.hpp> -#include <com/sun/star/animations/XAudio.hpp> -#include <com/sun/star/presentation/ParagraphTarget.hpp> -#include <com/sun/star/beans/XPropertySet.hpp> -#include <animations/animationnodehelper.hxx> -#include <basegfx/numeric/ftools.hxx> - -#include "animationnodefactory.hxx" -#include "paralleltimecontainer.hxx" -#include "sequentialtimecontainer.hxx" -#include "propertyanimationnode.hxx" -#include "animationsetnode.hxx" -#include "animationpathmotionnode.hxx" -#include "animationcolornode.hxx" -#include "animationtransformnode.hxx" -#include "animationtransitionfilternode.hxx" -#include "animationaudionode.hxx" -#include "animationcommandnode.hxx" -#include "nodetools.hxx" -#include "tools.hxx" - -#include <boost/bind.hpp> - -using namespace ::com::sun::star; - -namespace slideshow { -namespace internal { - -namespace { - -// forward declaration needed by NodeCreator -BaseNodeSharedPtr implCreateAnimationNode( - const uno::Reference< animations::XAnimationNode >& xNode, - const BaseContainerNodeSharedPtr& rParent, - const NodeContext& rContext ); - -class NodeCreator -{ -public: - NodeCreator( BaseContainerNodeSharedPtr& rParent, - const NodeContext& rContext ) - : mrParent( rParent ), mrContext( rContext ) {} - - void operator()( - const uno::Reference< animations::XAnimationNode >& xChildNode ) const - { - createChild( xChildNode, mrContext ); - } - -protected: - void createChild( - const uno::Reference< animations::XAnimationNode >& xChildNode, - const NodeContext& rContext ) const - { - BaseNodeSharedPtr pChild( implCreateAnimationNode( xChildNode, - mrParent, - rContext ) ); - - OSL_ENSURE( pChild, - "NodeCreator::operator(): child creation failed" ); - - // TODO(Q1): This yields circular references, which, it seems, is - // unavoidable here - if( pChild ) - mrParent->appendChildNode( pChild ); - } - - BaseContainerNodeSharedPtr& mrParent; - const NodeContext& mrContext; -}; - -/** Same as NodeCreator, only that NodeContext's - SubsetShape is cloned for every child node. - - This is used for iterated animation node generation -*/ -class CloningNodeCreator : private NodeCreator -{ -public: - CloningNodeCreator( BaseContainerNodeSharedPtr& rParent, - const NodeContext& rContext ) - : NodeCreator( rParent, rContext ) {} - - void operator()( - const uno::Reference< animations::XAnimationNode >& xChildNode ) const - { - NodeContext aContext( mrContext ); - - // TODO(Q1): There's a catch here. If you clone a - // subset whose actual subsetting has already been - // realized (i.e. if enableSubsetShape() has been - // called already), and the original of your clone - // goes out of scope, then your subset will be - // gone (SubsettableShapeManager::revokeSubset() be - // called). As of now, this behaviour is not - // triggered here (we either clone, XOR we enable - // subset initially), but one might consider - // reworking DrawShape/ShapeSubset to avoid this. - - // clone ShapeSubset, since each node needs their - // own version of the ShapeSubset (otherwise, - // e.g. activity counting does not work - subset - // would be removed after first animation node - // disables it). - // - // NOTE: this is only a problem for animation - // nodes that explicitely call - // disableSubsetShape(). Independent shape subsets - // (like those created for ParagraphTargets) - // solely rely on the ShapeSubset destructor to - // normalize things, which does the right thing - // here: the subset is only removed after _the - // last_ animation node releases the shared ptr. - aContext.mpMasterShapeSubset.reset( - new ShapeSubset( *aContext.mpMasterShapeSubset ) ); - - createChild( xChildNode, aContext ); - } -}; - -/** Create animation nodes for text iterations - - This method clones the animation nodes below xIterNode - for every iterated shape entity. -*/ -bool implCreateIteratedNodes( - const uno::Reference< animations::XIterateContainer >& xIterNode, - BaseContainerNodeSharedPtr& rParent, - const NodeContext& rContext ) -{ - ENSURE_OR_THROW( xIterNode.is(), - "implCreateIteratedNodes(): Invalid node" ); - - const double nIntervalTimeout( xIterNode->getIterateInterval() ); - - // valid iterate interval? We're ruling out monstrous - // values here, to avoid pseudo 'hangs' in the - // presentation - if( nIntervalTimeout < 0.0 || - nIntervalTimeout > 1000.0 ) - { - return false; // not an active iteration - } - - if( ::basegfx::fTools::equalZero( nIntervalTimeout ) ) - OSL_TRACE( "implCreateIteratedNodes(): " - "iterate interval close to zero, there's " - "no point in defining such an effect " - "(visually equivalent to whole-shape effect)" ); - - // Determine target shape (or subset) - // ================================== - - // TODO(E1): I'm not too sure what to expect here... - ENSURE_OR_RETURN_FALSE( - xIterNode->getTarget().hasValue(), - "implCreateIteratedNodes(): no target on ITERATE node" ); - - uno::Reference< drawing::XShape > xTargetShape( xIterNode->getTarget(), - uno::UNO_QUERY ); - - presentation::ParagraphTarget aTarget; - sal_Int16 nSubItem( xIterNode->getSubItem() ); - bool bParagraphTarget( false ); - - if( !xTargetShape.is() ) - { - // no shape provided. Maybe a ParagraphTarget? - if( !(xIterNode->getTarget() >>= aTarget) ) - ENSURE_OR_RETURN_FALSE( - false, - "implCreateIteratedNodes(): could not extract any " - "target information" ); - - xTargetShape = aTarget.Shape; - - ENSURE_OR_RETURN_FALSE( - xTargetShape.is(), - "implCreateIteratedNodes(): invalid shape in ParagraphTarget" ); - - // we've a paragraph target to iterate over, thus, - // the whole animation container refers only to - // the text - nSubItem = presentation::ShapeAnimationSubType::ONLY_TEXT; - - bParagraphTarget = true; - } - - // Lookup shape, and fill NodeContext - // ================================== - - AttributableShapeSharedPtr pTargetShape( - lookupAttributableShape( rContext.maContext.mpSubsettableShapeManager, - xTargetShape ) ); - - const DocTreeNodeSupplier& rTreeNodeSupplier( - pTargetShape->getTreeNodeSupplier() ); - - ShapeSubsetSharedPtr pTargetSubset; - - NodeContext aContext( rContext ); - - // paragraph targets already need a subset as the - // master shape (they're representing only a single - // paragraph) - if( bParagraphTarget ) - { - ENSURE_OR_RETURN_FALSE( - aTarget.Paragraph >= 0 && - rTreeNodeSupplier.getNumberOfTreeNodes( - DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH ) > aTarget.Paragraph, - "implCreateIteratedNodes(): paragraph index out of range" ); - - pTargetSubset.reset( - new ShapeSubset( - pTargetShape, - // retrieve index aTarget.Paragraph of - // type PARAGRAPH from this shape - rTreeNodeSupplier.getTreeNode( - aTarget.Paragraph, - DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH ), - rContext.maContext.mpSubsettableShapeManager ) ); - - // iterate target is not the whole shape, but only - // the selected paragraph - subset _must_ be - // independent, to be able to affect visibility - // independent of master shape - aContext.mbIsIndependentSubset = true; - - // already enable parent subset right here, to - // make potentially generated subsets subtract - // their content from the parent subset (and not - // the original shape). Otherwise, already - // subsetted parents (e.g. paragraphs) would not - // have their characters removed, when the child - // iterations start. - // Furthermore, the setup of initial shape - // attributes of course needs the subset shape - // generated, to apply e.g. visibility changes. - pTargetSubset->enableSubsetShape(); - } - else - { - pTargetSubset.reset( - new ShapeSubset( pTargetShape, - rContext.maContext.mpSubsettableShapeManager )); - } - - aContext.mpMasterShapeSubset = pTargetSubset; - uno::Reference< animations::XAnimationNode > xNode( xIterNode, - uno::UNO_QUERY_THROW ); - - // Generate subsets - // ================ - - if( bParagraphTarget || - nSubItem != presentation::ShapeAnimationSubType::ONLY_TEXT ) - { - // prepend with animations for - // full Shape (will be subtracted - // from the subset parts within - // the Shape::createSubset() - // method). For ONLY_TEXT effects, - // we skip this part, to animate - // only the text. - // - // OR - // - // prepend with subset animation for full - // _paragraph_, from which the individual - // paragraph subsets are subtracted. Note that the - // subitem is superfluous here, we always assume - // ONLY_TEXT, if a paragraph is referenced as the - // master of an iteration effect. - NodeCreator aCreator( rParent, aContext ); - if( !::anim::for_each_childNode( xNode, - aCreator ) ) - { - ENSURE_OR_RETURN_FALSE( - false, - "implCreateIteratedNodes(): iterated child node creation failed" ); - } - } - - // TODO(F2): This does not do the correct - // thing. Having nSubItem be set to ONLY_BACKGROUND - // should result in the text staying unanimated in the - // foreground, while the shape moves in the background - // (this behaviour is perfectly possible with the - // slideshow engine, only that the text won't be - // currently visible, because animations are always in - // the foreground) - if( nSubItem != presentation::ShapeAnimationSubType::ONLY_BACKGROUND ) - { - // determine type of subitem iteration (logical - // text unit to animate) - DocTreeNode::NodeType eIterateNodeType( - DocTreeNode::NODETYPE_LOGICAL_CHARACTER_CELL ); - - switch( xIterNode->getIterateType() ) - { - case presentation::TextAnimationType::BY_PARAGRAPH: - eIterateNodeType = DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH; - break; - - case presentation::TextAnimationType::BY_WORD: - eIterateNodeType = DocTreeNode::NODETYPE_LOGICAL_WORD; - break; - - case presentation::TextAnimationType::BY_LETTER: - eIterateNodeType = DocTreeNode::NODETYPE_LOGICAL_CHARACTER_CELL; - break; - - default: - ENSURE_OR_THROW( - false, "implCreateIteratedNodes(): " - "Unexpected IterateType on XIterateContainer"); - break; - } - - if( bParagraphTarget && - eIterateNodeType != DocTreeNode::NODETYPE_LOGICAL_WORD && - eIterateNodeType != DocTreeNode::NODETYPE_LOGICAL_CHARACTER_CELL ) - { - // will not animate the whole paragraph, when - // only the paragraph is animated at all. - OSL_FAIL( "implCreateIteratedNodes(): Ignoring paragraph iteration for paragraph master" ); - } - else - { - // setup iteration parameters - // -------------------------- - - // iterate target is the whole shape (or the - // whole parent subshape), thus, can save - // loads of subset shapes by generating them - // only when the effects become active - - // before and after the effect active - // duration, all attributes are shared by - // master shape and subset (since the iterated - // effects are all the same). - aContext.mbIsIndependentSubset = false; - - // determine number of nodes for given subitem - // type - sal_Int32 nTreeNodes( 0 ); - if( bParagraphTarget ) - { - // create the iterated subset _relative_ to - // the given paragraph index (i.e. animate the - // given subset type, but only when it's part - // of the given paragraph) - nTreeNodes = rTreeNodeSupplier.getNumberOfSubsetTreeNodes( - pTargetSubset->getSubset(), - eIterateNodeType ); - } - else - { - // generate normal subset - nTreeNodes = rTreeNodeSupplier.getNumberOfTreeNodes( - eIterateNodeType ); - } - - - // iterate node, generate copies of the children for each subset - // ------------------------------------------------------------- - - // NodeContext::mnStartDelay contains additional node delay. - // This will make the duplicated nodes for each iteration start - // increasingly later. - aContext.mnStartDelay = nIntervalTimeout; - - for( sal_Int32 i=0; i<nTreeNodes; ++i ) - { - // create subset with the corresponding tree nodes - if( bParagraphTarget ) - { - // create subsets relative to paragraph subset - aContext.mpMasterShapeSubset.reset( - new ShapeSubset( - pTargetSubset, - rTreeNodeSupplier.getSubsetTreeNode( - pTargetSubset->getSubset(), - i, - eIterateNodeType ) ) ); - } - else - { - // create subsets from main shape - aContext.mpMasterShapeSubset.reset( - new ShapeSubset( pTargetSubset, - rTreeNodeSupplier.getTreeNode( - i, - eIterateNodeType ) ) ); - } - - CloningNodeCreator aCreator( rParent, aContext ); - if( !::anim::for_each_childNode( xNode, - aCreator ) ) - { - ENSURE_OR_RETURN_FALSE( - false, "implCreateIteratedNodes(): " - "iterated child node creation failed" ); - } - - aContext.mnStartDelay += nIntervalTimeout; - } - } - } - - // done with iterate child generation - return true; -} - -BaseNodeSharedPtr implCreateAnimationNode( - const uno::Reference< animations::XAnimationNode >& xNode, - const BaseContainerNodeSharedPtr& rParent, - const NodeContext& rContext ) -{ - ENSURE_OR_THROW( xNode.is(), - "implCreateAnimationNode(): invalid XAnimationNode" ); - - BaseNodeSharedPtr pCreatedNode; - BaseContainerNodeSharedPtr pCreatedContainer; - - // create the internal node, corresponding to xNode - switch( xNode->getType() ) - { - case animations::AnimationNodeType::CUSTOM: - OSL_FAIL( "implCreateAnimationNode(): " - "CUSTOM not yet implemented" ); - return pCreatedNode; - - case animations::AnimationNodeType::PAR: - pCreatedNode = pCreatedContainer = BaseContainerNodeSharedPtr( - new ParallelTimeContainer( xNode, rParent, rContext ) ); - break; - - case animations::AnimationNodeType::ITERATE: - // map iterate container to ParallelTimeContainer. - // the iterating functionality is to be found - // below, (see method implCreateIteratedNodes) - pCreatedNode = pCreatedContainer = BaseContainerNodeSharedPtr( - new ParallelTimeContainer( xNode, rParent, rContext ) ); - break; - - case animations::AnimationNodeType::SEQ: - pCreatedNode = pCreatedContainer = BaseContainerNodeSharedPtr( - new SequentialTimeContainer( xNode, rParent, rContext ) ); - break; - - case animations::AnimationNodeType::ANIMATE: - pCreatedNode.reset( new PropertyAnimationNode( - xNode, rParent, rContext ) ); - break; - - case animations::AnimationNodeType::SET: - pCreatedNode.reset( new AnimationSetNode( - xNode, rParent, rContext ) ); - break; - - case animations::AnimationNodeType::ANIMATEMOTION: - pCreatedNode.reset( new AnimationPathMotionNode( - xNode, rParent, rContext ) ); - break; - - case animations::AnimationNodeType::ANIMATECOLOR: - pCreatedNode.reset( new AnimationColorNode( - xNode, rParent, rContext ) ); - break; - - case animations::AnimationNodeType::ANIMATETRANSFORM: - pCreatedNode.reset( new AnimationTransformNode( - xNode, rParent, rContext ) ); - break; - - case animations::AnimationNodeType::TRANSITIONFILTER: - pCreatedNode.reset( new AnimationTransitionFilterNode( - xNode, rParent, rContext ) ); - break; - - case animations::AnimationNodeType::AUDIO: - pCreatedNode.reset( new AnimationAudioNode( - xNode, rParent, rContext ) ); - break; - - case animations::AnimationNodeType::COMMAND: - pCreatedNode.reset( new AnimationCommandNode( - xNode, rParent, rContext ) ); - break; - - default: - OSL_FAIL( "implCreateAnimationNode(): " - "invalid AnimationNodeType" ); - return pCreatedNode; - } - - // TODO(Q1): This yields circular references, which, it seems, is - // unavoidable here - - // HACK: node objects need shared_ptr to themselves, - // which we pass them here. - pCreatedNode->setSelf( pCreatedNode ); - - // if we've got a container node object, recursively add - // its children - if( pCreatedContainer ) - { - uno::Reference< animations::XIterateContainer > xIterNode( - xNode, uno::UNO_QUERY ); - - // when this node is an XIterateContainer with - // active iterations, this method will generate - // the appropriate children - if( xIterNode.is() ) - { - // note that implCreateIteratedNodes() might - // choose not to generate any child nodes - // (e.g. when the iterate timeout is outside - // sensible limits). Then, no child nodes are - // generated at all, since typically, child - // node attribute are incomplete for iteration - // children. - implCreateIteratedNodes( xIterNode, - pCreatedContainer, - rContext ); - } - else - { - // no iterate subset node, just plain child generation now - NodeCreator aCreator( pCreatedContainer, rContext ); - if( !::anim::for_each_childNode( xNode, aCreator ) ) - { - OSL_FAIL( "implCreateAnimationNode(): " - "child node creation failed" ); - return BaseNodeSharedPtr(); - } - } - } - - return pCreatedNode; -} - -} // anon namespace - -AnimationNodeSharedPtr AnimationNodeFactory::createAnimationNode( - const uno::Reference< animations::XAnimationNode >& xNode, - const ::basegfx::B2DVector& rSlideSize, - const SlideShowContext& rContext ) -{ - ENSURE_OR_THROW( - xNode.is(), - "AnimationNodeFactory::createAnimationNode(): invalid XAnimationNode" ); - - return BaseNodeSharedPtr( implCreateAnimationNode( - xNode, - BaseContainerNodeSharedPtr(), // no parent - NodeContext( rContext, - rSlideSize ))); -} - -#if defined(VERBOSE) && defined(DBG_UTIL) -void AnimationNodeFactory::showTree( AnimationNodeSharedPtr& pRootNode ) -{ - if( pRootNode ) - DEBUG_NODES_SHOWTREE( boost::dynamic_pointer_cast<BaseContainerNode>( - pRootNode).get() ); -} -#endif - -} // namespace internal -} // namespace slideshow - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |