xref: /AOO41X/main/slideshow/source/engine/transitions/slidetransitionfactory.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_slideshow.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <canvas/debug.hxx>
32*cdf0e10cSrcweir #include <tools/diagnose_ex.h>
33*cdf0e10cSrcweir 
34*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
35*cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx>
36*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
37*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx>
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include <cppcanvas/basegfxfactory.hxx>
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir #include <comphelper/optional.hxx>
42*cdf0e10cSrcweir #include <comphelper/make_shared_from_uno.hxx>
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir #include <com/sun/star/rendering/XIntegerBitmap.hpp>
45*cdf0e10cSrcweir #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
46*cdf0e10cSrcweir #include <com/sun/star/animations/TransitionType.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/animations/TransitionSubType.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir #include "slidechangebase.hxx"
51*cdf0e10cSrcweir #include "transitionfactory.hxx"
52*cdf0e10cSrcweir #include "transitiontools.hxx"
53*cdf0e10cSrcweir #include "parametricpolypolygonfactory.hxx"
54*cdf0e10cSrcweir #include "animationfactory.hxx"
55*cdf0e10cSrcweir #include "clippingfunctor.hxx"
56*cdf0e10cSrcweir #include "combtransition.hxx"
57*cdf0e10cSrcweir #include "tools.hxx"
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir #include <boost/bind.hpp>
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir /***************************************************
63*cdf0e10cSrcweir  ***                                             ***
64*cdf0e10cSrcweir  ***          Slide Transition Effects           ***
65*cdf0e10cSrcweir  ***                                             ***
66*cdf0e10cSrcweir  ***************************************************/
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir using namespace com::sun::star;
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir namespace slideshow {
71*cdf0e10cSrcweir namespace internal {
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir namespace {
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir // helper methods
76*cdf0e10cSrcweir // =============================================
77*cdf0e10cSrcweir 
78*cdf0e10cSrcweir void fillPage( const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
79*cdf0e10cSrcweir                const ::basegfx::B2DSize&           rPageSizePixel,
80*cdf0e10cSrcweir                const RGBColor&                     rFillColor )
81*cdf0e10cSrcweir {
82*cdf0e10cSrcweir     // need to render without any transformation (we
83*cdf0e10cSrcweir     // assume rPageSizePixel to represent device units)
84*cdf0e10cSrcweir     const ::cppcanvas::CanvasSharedPtr pDevicePixelCanvas(
85*cdf0e10cSrcweir         rDestinationCanvas->clone() );
86*cdf0e10cSrcweir     pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir     // TODO(F2): Properly respect clip here.
89*cdf0e10cSrcweir     // Might have to be transformed, too.
90*cdf0e10cSrcweir     const ::basegfx::B2DHomMatrix aViewTransform(
91*cdf0e10cSrcweir         rDestinationCanvas->getTransformation() );
92*cdf0e10cSrcweir     const ::basegfx::B2DPoint aOutputPosPixel(
93*cdf0e10cSrcweir         aViewTransform * ::basegfx::B2DPoint() );
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir     fillRect( pDevicePixelCanvas,
96*cdf0e10cSrcweir               ::basegfx::B2DRectangle(
97*cdf0e10cSrcweir                   aOutputPosPixel.getX(),
98*cdf0e10cSrcweir                   aOutputPosPixel.getY(),
99*cdf0e10cSrcweir                   aOutputPosPixel.getX() + rPageSizePixel.getX(),
100*cdf0e10cSrcweir                   aOutputPosPixel.getY() + rPageSizePixel.getY() ),
101*cdf0e10cSrcweir               rFillColor.getIntegerColor() );
102*cdf0e10cSrcweir }
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir class PluginSlideChange: public SlideChangeBase
105*cdf0e10cSrcweir {
106*cdf0e10cSrcweir     struct TransitionViewPair {
107*cdf0e10cSrcweir 	uno::Reference<presentation::XTransition> mxTransition;
108*cdf0e10cSrcweir 	UnoViewSharedPtr mpView;
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir 	TransitionViewPair( uno::Reference<presentation::XTransition> xTransition, const UnoViewSharedPtr pView )
111*cdf0e10cSrcweir 	{
112*cdf0e10cSrcweir 	    mxTransition = xTransition;
113*cdf0e10cSrcweir 	    mpView = pView;
114*cdf0e10cSrcweir 	}
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir 	~TransitionViewPair()
117*cdf0e10cSrcweir 	{
118*cdf0e10cSrcweir 	    mxTransition.clear();
119*cdf0e10cSrcweir 	    mpView.reset();;
120*cdf0e10cSrcweir 	}
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir 	void update( double t )
123*cdf0e10cSrcweir 	{
124*cdf0e10cSrcweir 	    mxTransition->update( t );
125*cdf0e10cSrcweir 	}
126*cdf0e10cSrcweir     };
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir public:
129*cdf0e10cSrcweir     /** Create a new SlideChanger, for the given leaving and
130*cdf0e10cSrcweir         entering slide bitmaps, which uses super secret OpenGL
131*cdf0e10cSrcweir         stuff.
132*cdf0e10cSrcweir     */
133*cdf0e10cSrcweir     PluginSlideChange( sal_Int16                                nTransitionType,
134*cdf0e10cSrcweir                        sal_Int16                                nTransitionSubType,
135*cdf0e10cSrcweir                        boost::optional<SlideSharedPtr> const&   leavingSlide_,
136*cdf0e10cSrcweir                        const SlideSharedPtr&                    pEnteringSlide,
137*cdf0e10cSrcweir                        const UnoViewContainer&                  rViewContainer,
138*cdf0e10cSrcweir                        ScreenUpdater&                           rScreenUpdater,
139*cdf0e10cSrcweir                        const uno::Reference<
140*cdf0e10cSrcweir                              presentation::XTransitionFactory>& xFactory,
141*cdf0e10cSrcweir                        const SoundPlayerSharedPtr&              pSoundPlayer,
142*cdf0e10cSrcweir                        EventMultiplexer&                        rEventMultiplexer) :
143*cdf0e10cSrcweir         SlideChangeBase( leavingSlide_,
144*cdf0e10cSrcweir                          pEnteringSlide,
145*cdf0e10cSrcweir                          pSoundPlayer,
146*cdf0e10cSrcweir                          rViewContainer,
147*cdf0e10cSrcweir                          rScreenUpdater,
148*cdf0e10cSrcweir                          rEventMultiplexer ),
149*cdf0e10cSrcweir         maTransitions(),
150*cdf0e10cSrcweir         mbSuccess( false ),
151*cdf0e10cSrcweir 	mnTransitionType( nTransitionType ),
152*cdf0e10cSrcweir 	mnTransitionSubType( nTransitionSubType ),
153*cdf0e10cSrcweir 	mxFactory( xFactory )
154*cdf0e10cSrcweir     {
155*cdf0e10cSrcweir         // create one transition per view
156*cdf0e10cSrcweir         UnoViewVector::const_iterator aCurrView (rViewContainer.begin());
157*cdf0e10cSrcweir         const UnoViewVector::const_iterator aEnd(rViewContainer.end());
158*cdf0e10cSrcweir         while( aCurrView != aEnd )
159*cdf0e10cSrcweir         {
160*cdf0e10cSrcweir 	    if(! addTransition( *aCurrView ) )
161*cdf0e10cSrcweir 		return;
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir             ENSURE_OR_THROW(maTransitions.back() && maTransitions.back()->mxTransition.is(),
164*cdf0e10cSrcweir                             "Failed to create plugin transition");
165*cdf0e10cSrcweir             ++aCurrView;
166*cdf0e10cSrcweir         }
167*cdf0e10cSrcweir 	mbSuccess = true;
168*cdf0e10cSrcweir     }
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir     ~PluginSlideChange()
171*cdf0e10cSrcweir     {
172*cdf0e10cSrcweir 	mxFactory.clear();
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir         ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
175*cdf0e10cSrcweir         ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
176*cdf0e10cSrcweir         while( aCurrView != aEnd )
177*cdf0e10cSrcweir         {
178*cdf0e10cSrcweir 	    delete (*aCurrView);
179*cdf0e10cSrcweir             ++aCurrView;
180*cdf0e10cSrcweir 	}
181*cdf0e10cSrcweir 	maTransitions.clear();
182*cdf0e10cSrcweir     }
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir     bool addTransition( const UnoViewSharedPtr& rView )
185*cdf0e10cSrcweir     {
186*cdf0e10cSrcweir 	uno::Reference<presentation::XTransition> rTransition = mxFactory->createTransition(
187*cdf0e10cSrcweir 	    mnTransitionType,
188*cdf0e10cSrcweir 	    mnTransitionSubType,
189*cdf0e10cSrcweir 	    rView->getUnoView(),
190*cdf0e10cSrcweir 	    getLeavingBitmap(ViewEntry(rView))->getXBitmap(),
191*cdf0e10cSrcweir 	    getEnteringBitmap(ViewEntry(rView))->getXBitmap() );
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir 	if( rTransition.is() )
194*cdf0e10cSrcweir 	    maTransitions.push_back( new TransitionViewPair( rTransition, rView ) );
195*cdf0e10cSrcweir 	else
196*cdf0e10cSrcweir 	    return false;
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir 	return true;
199*cdf0e10cSrcweir     }
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir     virtual bool operator()( double t )
202*cdf0e10cSrcweir     {
203*cdf0e10cSrcweir         std::for_each(maTransitions.begin(),
204*cdf0e10cSrcweir                       maTransitions.end(),
205*cdf0e10cSrcweir                       boost::bind( &TransitionViewPair::update,
206*cdf0e10cSrcweir                                    _1, t) );
207*cdf0e10cSrcweir         return true;
208*cdf0e10cSrcweir     }
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir     bool Success()
211*cdf0e10cSrcweir     {
212*cdf0e10cSrcweir         return mbSuccess;
213*cdf0e10cSrcweir     }
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir     // ViewEventHandler
216*cdf0e10cSrcweir     virtual void viewAdded( const UnoViewSharedPtr& rView )
217*cdf0e10cSrcweir     {
218*cdf0e10cSrcweir 	OSL_TRACE("PluginSlideChange viewAdded");
219*cdf0e10cSrcweir 	SlideChangeBase::viewAdded( rView );
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir         ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
222*cdf0e10cSrcweir         ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
223*cdf0e10cSrcweir 	bool bKnown = false;
224*cdf0e10cSrcweir         while( aCurrView != aEnd )
225*cdf0e10cSrcweir         {
226*cdf0e10cSrcweir 	    if( (*aCurrView)->mpView == rView ) {
227*cdf0e10cSrcweir 		bKnown = true;
228*cdf0e10cSrcweir 		break;
229*cdf0e10cSrcweir 	    }
230*cdf0e10cSrcweir             ++aCurrView;
231*cdf0e10cSrcweir 	}
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir 	if( !bKnown ) {
234*cdf0e10cSrcweir 	    OSL_TRACE("need to be added");
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir 	    addTransition( rView );
237*cdf0e10cSrcweir 	}
238*cdf0e10cSrcweir     }
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir     virtual void viewRemoved( const UnoViewSharedPtr& rView )
241*cdf0e10cSrcweir     {
242*cdf0e10cSrcweir 	OSL_TRACE("PluginSlideChange viewRemoved");
243*cdf0e10cSrcweir 	SlideChangeBase::viewRemoved( rView );
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir         ::std::vector< TransitionViewPair* >::iterator aCurrView (maTransitions.begin());
246*cdf0e10cSrcweir         ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
247*cdf0e10cSrcweir         while( aCurrView != aEnd )
248*cdf0e10cSrcweir         {
249*cdf0e10cSrcweir 	    if( (*aCurrView)->mpView == rView ) {
250*cdf0e10cSrcweir 		OSL_TRACE( "view removed" );
251*cdf0e10cSrcweir 		delete (*aCurrView);
252*cdf0e10cSrcweir 		maTransitions.erase( aCurrView );
253*cdf0e10cSrcweir 		break;
254*cdf0e10cSrcweir 	    }
255*cdf0e10cSrcweir             ++aCurrView;
256*cdf0e10cSrcweir 	}
257*cdf0e10cSrcweir     }
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir     virtual void viewChanged( const UnoViewSharedPtr& rView )
260*cdf0e10cSrcweir     {
261*cdf0e10cSrcweir 	OSL_TRACE("PluginSlideChange viewChanged");
262*cdf0e10cSrcweir 	SlideChangeBase::viewChanged( rView );
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir         ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
265*cdf0e10cSrcweir         ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
266*cdf0e10cSrcweir         while( aCurrView != aEnd )
267*cdf0e10cSrcweir         {
268*cdf0e10cSrcweir 	    if( (*aCurrView)->mpView == rView ) {
269*cdf0e10cSrcweir 		OSL_TRACE( "view changed" );
270*cdf0e10cSrcweir  		(*aCurrView)->mxTransition->viewChanged( rView->getUnoView(),
271*cdf0e10cSrcweir 							 getLeavingBitmap(ViewEntry(rView))->getXBitmap(),
272*cdf0e10cSrcweir 							 getEnteringBitmap(ViewEntry(rView))->getXBitmap() );
273*cdf0e10cSrcweir 	    } else
274*cdf0e10cSrcweir 		OSL_TRACE( "view did not changed" );
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir             ++aCurrView;
277*cdf0e10cSrcweir 	}
278*cdf0e10cSrcweir     }
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir     virtual void viewsChanged()
281*cdf0e10cSrcweir     {
282*cdf0e10cSrcweir 	OSL_TRACE("PluginSlideChange viewsChanged");
283*cdf0e10cSrcweir 	SlideChangeBase::viewsChanged();
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir         ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
286*cdf0e10cSrcweir         ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
287*cdf0e10cSrcweir         while( aCurrView != aEnd )
288*cdf0e10cSrcweir         {
289*cdf0e10cSrcweir 	    OSL_TRACE( "view changed" );
290*cdf0e10cSrcweir 	    (*aCurrView)->mxTransition->viewChanged( (*aCurrView)->mpView->getUnoView(),
291*cdf0e10cSrcweir 						     getLeavingBitmap(ViewEntry((*aCurrView)->mpView))->getXBitmap(),
292*cdf0e10cSrcweir 						     getEnteringBitmap(ViewEntry((*aCurrView)->mpView))->getXBitmap() );
293*cdf0e10cSrcweir             ++aCurrView;
294*cdf0e10cSrcweir 	}
295*cdf0e10cSrcweir     }
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir private:
298*cdf0e10cSrcweir     // One transition object per view
299*cdf0e10cSrcweir     std::vector< TransitionViewPair* > maTransitions;
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir     // bool
302*cdf0e10cSrcweir     bool mbSuccess;
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir     sal_Int16 mnTransitionType;
305*cdf0e10cSrcweir     sal_Int16 mnTransitionSubType;
306*cdf0e10cSrcweir 
307*cdf0e10cSrcweir     uno::Reference<presentation::XTransitionFactory> mxFactory;
308*cdf0e10cSrcweir };
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir class ClippedSlideChange : public SlideChangeBase
311*cdf0e10cSrcweir {
312*cdf0e10cSrcweir public:
313*cdf0e10cSrcweir     /** Create a new SlideChanger, for the given leaving and
314*cdf0e10cSrcweir         entering slide bitmaps, which applies the given clip
315*cdf0e10cSrcweir         polygon.
316*cdf0e10cSrcweir     */
317*cdf0e10cSrcweir     ClippedSlideChange(
318*cdf0e10cSrcweir         const SlideSharedPtr&                   pEnteringSlide,
319*cdf0e10cSrcweir         const ParametricPolyPolygonSharedPtr&   rPolygon,
320*cdf0e10cSrcweir         const TransitionInfo&                   rTransitionInfo,
321*cdf0e10cSrcweir         const UnoViewContainer&                 rViewContainer,
322*cdf0e10cSrcweir         ScreenUpdater&                          rScreenUpdater,
323*cdf0e10cSrcweir         EventMultiplexer&                       rEventMultiplexer,
324*cdf0e10cSrcweir         bool                                    bDirectionForward,
325*cdf0e10cSrcweir         const SoundPlayerSharedPtr&             pSoundPlayer ) :
326*cdf0e10cSrcweir         SlideChangeBase(
327*cdf0e10cSrcweir             // leaving bitmap is empty, we're leveraging the fact that the
328*cdf0e10cSrcweir             // old slide is still displayed in the background:
329*cdf0e10cSrcweir             boost::optional<SlideSharedPtr>(),
330*cdf0e10cSrcweir             pEnteringSlide,
331*cdf0e10cSrcweir             pSoundPlayer,
332*cdf0e10cSrcweir             rViewContainer,
333*cdf0e10cSrcweir             rScreenUpdater,
334*cdf0e10cSrcweir             rEventMultiplexer ),
335*cdf0e10cSrcweir         maClippingFunctor( rPolygon,
336*cdf0e10cSrcweir                            rTransitionInfo,
337*cdf0e10cSrcweir                            bDirectionForward,
338*cdf0e10cSrcweir                            true )
339*cdf0e10cSrcweir         {}
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir     virtual void performIn(
342*cdf0e10cSrcweir         const ::cppcanvas::CustomSpriteSharedPtr&   rSprite,
343*cdf0e10cSrcweir         const ViewEntry&                            rViewEntry,
344*cdf0e10cSrcweir         const ::cppcanvas::CanvasSharedPtr&         rDestinationCanvas,
345*cdf0e10cSrcweir         double                                      t );
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir     virtual void performOut(
348*cdf0e10cSrcweir         const ::cppcanvas::CustomSpriteSharedPtr&  rSprite,
349*cdf0e10cSrcweir         const ViewEntry&                           rViewEntry,
350*cdf0e10cSrcweir         const ::cppcanvas::CanvasSharedPtr&        rDestinationCanvas,
351*cdf0e10cSrcweir         double                                     t );
352*cdf0e10cSrcweir 
353*cdf0e10cSrcweir private:
354*cdf0e10cSrcweir     ClippingFunctor             maClippingFunctor;
355*cdf0e10cSrcweir };
356*cdf0e10cSrcweir 
357*cdf0e10cSrcweir void ClippedSlideChange::performIn(
358*cdf0e10cSrcweir     const ::cppcanvas::CustomSpriteSharedPtr&   rSprite,
359*cdf0e10cSrcweir     const ViewEntry&                            rViewEntry,
360*cdf0e10cSrcweir     const ::cppcanvas::CanvasSharedPtr&         /*rDestinationCanvas*/,
361*cdf0e10cSrcweir     double                                      t )
362*cdf0e10cSrcweir {
363*cdf0e10cSrcweir     // #i46602# Better work in device coordinate space here,
364*cdf0e10cSrcweir     // otherwise, we too easily suffer from roundoffs. Apart from
365*cdf0e10cSrcweir     // that, getEnteringSizePixel() _guarantees_ to cover the whole
366*cdf0e10cSrcweir     // slide bitmap. There's a catch, though: this removes any effect
367*cdf0e10cSrcweir     // of the view transformation (e.g. rotation) from the transition.
368*cdf0e10cSrcweir     rSprite->setClipPixel(
369*cdf0e10cSrcweir         maClippingFunctor( t,
370*cdf0e10cSrcweir                            getEnteringSlideSizePixel(rViewEntry.mpView) ) );
371*cdf0e10cSrcweir }
372*cdf0e10cSrcweir 
373*cdf0e10cSrcweir void ClippedSlideChange::performOut(
374*cdf0e10cSrcweir     const ::cppcanvas::CustomSpriteSharedPtr&  /*rSprite*/,
375*cdf0e10cSrcweir     const ViewEntry&                           /*rViewEntry*/,
376*cdf0e10cSrcweir     const ::cppcanvas::CanvasSharedPtr&        /*rDestinationCanvas*/,
377*cdf0e10cSrcweir     double                                     /*t*/ )
378*cdf0e10cSrcweir {
379*cdf0e10cSrcweir     // not needed here
380*cdf0e10cSrcweir }
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir 
383*cdf0e10cSrcweir class FadingSlideChange : public SlideChangeBase
384*cdf0e10cSrcweir {
385*cdf0e10cSrcweir public:
386*cdf0e10cSrcweir     /** Create a new SlideChanger, for the given leaving and
387*cdf0e10cSrcweir         entering slides, which applies a fade effect.
388*cdf0e10cSrcweir     */
389*cdf0e10cSrcweir     FadingSlideChange(
390*cdf0e10cSrcweir         boost::optional<SlideSharedPtr> const & leavingSlide,
391*cdf0e10cSrcweir         const SlideSharedPtr&                   pEnteringSlide,
392*cdf0e10cSrcweir         boost::optional<RGBColor> const&        rFadeColor,
393*cdf0e10cSrcweir         const SoundPlayerSharedPtr&             pSoundPlayer,
394*cdf0e10cSrcweir         const UnoViewContainer&                 rViewContainer,
395*cdf0e10cSrcweir         ScreenUpdater&                          rScreenUpdater,
396*cdf0e10cSrcweir         EventMultiplexer&                       rEventMultiplexer )
397*cdf0e10cSrcweir         : SlideChangeBase( leavingSlide,
398*cdf0e10cSrcweir                            pEnteringSlide,
399*cdf0e10cSrcweir                            pSoundPlayer,
400*cdf0e10cSrcweir                            rViewContainer,
401*cdf0e10cSrcweir                            rScreenUpdater,
402*cdf0e10cSrcweir                            rEventMultiplexer ),
403*cdf0e10cSrcweir           maFadeColor( rFadeColor ),
404*cdf0e10cSrcweir           mbFirstTurn( true )
405*cdf0e10cSrcweir         {}
406*cdf0e10cSrcweir 
407*cdf0e10cSrcweir     virtual void performIn(
408*cdf0e10cSrcweir         const ::cppcanvas::CustomSpriteSharedPtr&   rSprite,
409*cdf0e10cSrcweir         const ViewEntry&                            rViewEntry,
410*cdf0e10cSrcweir         const ::cppcanvas::CanvasSharedPtr&         rDestinationCanvas,
411*cdf0e10cSrcweir         double                                      t );
412*cdf0e10cSrcweir 
413*cdf0e10cSrcweir     virtual void performOut(
414*cdf0e10cSrcweir         const ::cppcanvas::CustomSpriteSharedPtr&  rSprite,
415*cdf0e10cSrcweir         const ViewEntry&                           rViewEntry,
416*cdf0e10cSrcweir         const ::cppcanvas::CanvasSharedPtr&        rDestinationCanvas,
417*cdf0e10cSrcweir         double                                     t );
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir private:
420*cdf0e10cSrcweir     const boost::optional< RGBColor >               maFadeColor;
421*cdf0e10cSrcweir     bool                                            mbFirstTurn;
422*cdf0e10cSrcweir };
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir void FadingSlideChange::performIn(
425*cdf0e10cSrcweir     const ::cppcanvas::CustomSpriteSharedPtr&   rSprite,
426*cdf0e10cSrcweir     const ViewEntry&                            /*rViewEntry*/,
427*cdf0e10cSrcweir     const ::cppcanvas::CanvasSharedPtr&         /*rDestinationCanvas*/,
428*cdf0e10cSrcweir     double                                      t )
429*cdf0e10cSrcweir {
430*cdf0e10cSrcweir     ENSURE_OR_THROW(
431*cdf0e10cSrcweir         rSprite,
432*cdf0e10cSrcweir         "FadingSlideChange::performIn(): Invalid sprite" );
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir     if( maFadeColor )
435*cdf0e10cSrcweir         // After half of the active time, fade in new slide
436*cdf0e10cSrcweir         rSprite->setAlpha( t > 0.5 ? 2.0*(t-0.5) : 0.0 );
437*cdf0e10cSrcweir     else
438*cdf0e10cSrcweir         // Fade in new slide over full active time
439*cdf0e10cSrcweir         rSprite->setAlpha( t );
440*cdf0e10cSrcweir }
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir void FadingSlideChange::performOut(
443*cdf0e10cSrcweir     const ::cppcanvas::CustomSpriteSharedPtr&  rSprite,
444*cdf0e10cSrcweir     const ViewEntry&                           rViewEntry,
445*cdf0e10cSrcweir     const ::cppcanvas::CanvasSharedPtr&        rDestinationCanvas,
446*cdf0e10cSrcweir     double                                     t )
447*cdf0e10cSrcweir {
448*cdf0e10cSrcweir     ENSURE_OR_THROW(
449*cdf0e10cSrcweir         rSprite,
450*cdf0e10cSrcweir         "FadingSlideChange::performOut(): Invalid sprite" );
451*cdf0e10cSrcweir     ENSURE_OR_THROW(
452*cdf0e10cSrcweir         rDestinationCanvas,
453*cdf0e10cSrcweir         "FadingSlideChange::performOut(): Invalid dest canvas" );
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir     // only needed for color fades
456*cdf0e10cSrcweir     if( maFadeColor )
457*cdf0e10cSrcweir     {
458*cdf0e10cSrcweir         if( mbFirstTurn )
459*cdf0e10cSrcweir         {
460*cdf0e10cSrcweir             mbFirstTurn = false;
461*cdf0e10cSrcweir 
462*cdf0e10cSrcweir             // clear page to given fade color. 'Leaving' slide is
463*cdf0e10cSrcweir             // painted atop of that, but slowly fading out.
464*cdf0e10cSrcweir             fillPage( rDestinationCanvas,
465*cdf0e10cSrcweir                       getEnteringSlideSizePixel( rViewEntry.mpView ),
466*cdf0e10cSrcweir                       *maFadeColor );
467*cdf0e10cSrcweir         }
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir         // Until half of the active time, fade out old
470*cdf0e10cSrcweir         // slide. After half of the active time, old slide
471*cdf0e10cSrcweir         // will be invisible.
472*cdf0e10cSrcweir         rSprite->setAlpha( t > 0.5 ? 0.0 : 2.0*(0.5-t) );
473*cdf0e10cSrcweir     }
474*cdf0e10cSrcweir }
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir class MovingSlideChange : public SlideChangeBase
477*cdf0e10cSrcweir {
478*cdf0e10cSrcweir     /// Direction vector for leaving slide,
479*cdf0e10cSrcweir     const ::basegfx::B2DVector  maLeavingDirection;
480*cdf0e10cSrcweir 
481*cdf0e10cSrcweir     /// Direction vector for entering slide,
482*cdf0e10cSrcweir     const ::basegfx::B2DVector  maEnteringDirection;
483*cdf0e10cSrcweir 
484*cdf0e10cSrcweir     bool                        mbFirstPerformCall;
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir public:
487*cdf0e10cSrcweir     /** Create a new SlideChanger, for the given entering slide
488*cdf0e10cSrcweir         bitmaps, which performes a moving slide change effect
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir         @param rLeavingDirection
491*cdf0e10cSrcweir         Direction vector. The move is performed along this
492*cdf0e10cSrcweir         direction vector, starting at a position where the leaving
493*cdf0e10cSrcweir         slide is fully visible, and ending at a position where the
494*cdf0e10cSrcweir         leaving slide is just not visible. The vector must have
495*cdf0e10cSrcweir         unit length.
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir         @param rEnteringDirection
498*cdf0e10cSrcweir         Direction vector. The move is performed along this
499*cdf0e10cSrcweir         direction vector, starting at a position where the
500*cdf0e10cSrcweir         entering slide is just not visible, and ending at the
501*cdf0e10cSrcweir         final slide position. The vector must have unit length.
502*cdf0e10cSrcweir     */
503*cdf0e10cSrcweir     MovingSlideChange(
504*cdf0e10cSrcweir         const boost::optional<SlideSharedPtr>& leavingSlide,
505*cdf0e10cSrcweir         const SlideSharedPtr&                  pEnteringSlide,
506*cdf0e10cSrcweir         const SoundPlayerSharedPtr&            pSoundPlayer,
507*cdf0e10cSrcweir         const UnoViewContainer&                rViewContainer,
508*cdf0e10cSrcweir         ScreenUpdater&                         rScreenUpdater,
509*cdf0e10cSrcweir         EventMultiplexer&                      rEventMultiplexer,
510*cdf0e10cSrcweir         const ::basegfx::B2DVector&            rLeavingDirection,
511*cdf0e10cSrcweir         const ::basegfx::B2DVector&            rEnteringDirection )
512*cdf0e10cSrcweir         : SlideChangeBase(
513*cdf0e10cSrcweir             leavingSlide, pEnteringSlide, pSoundPlayer,
514*cdf0e10cSrcweir             rViewContainer, rScreenUpdater, rEventMultiplexer,
515*cdf0e10cSrcweir             // Optimization: when leaving bitmap is given,
516*cdf0e10cSrcweir             // but it does not move, don't create sprites for it,
517*cdf0e10cSrcweir             // we simply paint it once at startup:
518*cdf0e10cSrcweir             !rLeavingDirection.equalZero() /* bCreateLeavingSprites */,
519*cdf0e10cSrcweir             !rEnteringDirection.equalZero() /* bCreateEnteringSprites */ ),
520*cdf0e10cSrcweir           // TODO(F1): calc correct length of direction
521*cdf0e10cSrcweir           // vector. Directions not strictly horizontal or vertical
522*cdf0e10cSrcweir           // must travel a longer distance.
523*cdf0e10cSrcweir           maLeavingDirection( rLeavingDirection ),
524*cdf0e10cSrcweir           // TODO(F1): calc correct length of direction
525*cdf0e10cSrcweir           // vector. Directions not strictly horizontal or vertical
526*cdf0e10cSrcweir           // must travel a longer distance.
527*cdf0e10cSrcweir           maEnteringDirection( rEnteringDirection ),
528*cdf0e10cSrcweir           mbFirstPerformCall( true )
529*cdf0e10cSrcweir         {}
530*cdf0e10cSrcweir 
531*cdf0e10cSrcweir     virtual void performIn(
532*cdf0e10cSrcweir         const ::cppcanvas::CustomSpriteSharedPtr&   rSprite,
533*cdf0e10cSrcweir         const ViewEntry&                            rViewEntry,
534*cdf0e10cSrcweir         const ::cppcanvas::CanvasSharedPtr&         rDestinationCanvas,
535*cdf0e10cSrcweir         double                                      t );
536*cdf0e10cSrcweir 
537*cdf0e10cSrcweir     virtual void performOut(
538*cdf0e10cSrcweir         const ::cppcanvas::CustomSpriteSharedPtr&  rSprite,
539*cdf0e10cSrcweir         const ViewEntry&                           rViewEntry,
540*cdf0e10cSrcweir         const ::cppcanvas::CanvasSharedPtr&        rDestinationCanvas,
541*cdf0e10cSrcweir         double                                     t );
542*cdf0e10cSrcweir };
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir void MovingSlideChange::performIn(
545*cdf0e10cSrcweir     const ::cppcanvas::CustomSpriteSharedPtr&   rSprite,
546*cdf0e10cSrcweir     const ViewEntry&                            rViewEntry,
547*cdf0e10cSrcweir     const ::cppcanvas::CanvasSharedPtr&         rDestinationCanvas,
548*cdf0e10cSrcweir     double                                      t )
549*cdf0e10cSrcweir {
550*cdf0e10cSrcweir     // intro sprite moves:
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir     ENSURE_OR_THROW(
553*cdf0e10cSrcweir         rSprite,
554*cdf0e10cSrcweir         "MovingSlideChange::performIn(): Invalid sprite" );
555*cdf0e10cSrcweir     ENSURE_OR_THROW(
556*cdf0e10cSrcweir         rDestinationCanvas,
557*cdf0e10cSrcweir         "MovingSlideChange::performIn(): Invalid dest canvas" );
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir     if (mbFirstPerformCall && maLeavingDirection.equalZero())
560*cdf0e10cSrcweir     {
561*cdf0e10cSrcweir         mbFirstPerformCall = false;
562*cdf0e10cSrcweir         renderBitmap( getLeavingBitmap(rViewEntry), rDestinationCanvas );
563*cdf0e10cSrcweir     }
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir     // TODO(F1): This does not account for non-translational
566*cdf0e10cSrcweir     // transformations! If the canvas is rotated, we still
567*cdf0e10cSrcweir     // move the sprite unrotated (which might or might not
568*cdf0e10cSrcweir     // produce the intended effect).
569*cdf0e10cSrcweir     const basegfx::B2DHomMatrix aViewTransform(
570*cdf0e10cSrcweir         rDestinationCanvas->getTransformation() );
571*cdf0e10cSrcweir     const basegfx::B2DPoint aPageOrigin(
572*cdf0e10cSrcweir         aViewTransform * basegfx::B2DPoint() );
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir     // move sprite
575*cdf0e10cSrcweir     rSprite->movePixel(
576*cdf0e10cSrcweir         aPageOrigin +
577*cdf0e10cSrcweir         ((t - 1.0) *
578*cdf0e10cSrcweir          ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) *
579*cdf0e10cSrcweir          maEnteringDirection) );
580*cdf0e10cSrcweir }
581*cdf0e10cSrcweir 
582*cdf0e10cSrcweir void MovingSlideChange::performOut(
583*cdf0e10cSrcweir     const ::cppcanvas::CustomSpriteSharedPtr&  rSprite,
584*cdf0e10cSrcweir     const ViewEntry&                           rViewEntry,
585*cdf0e10cSrcweir     const ::cppcanvas::CanvasSharedPtr&        rDestinationCanvas,
586*cdf0e10cSrcweir     double                                     t )
587*cdf0e10cSrcweir {
588*cdf0e10cSrcweir     // outro sprite moves:
589*cdf0e10cSrcweir 
590*cdf0e10cSrcweir     ENSURE_OR_THROW(
591*cdf0e10cSrcweir         rSprite,
592*cdf0e10cSrcweir         "MovingSlideChange::performOut(): Invalid sprite" );
593*cdf0e10cSrcweir     ENSURE_OR_THROW(
594*cdf0e10cSrcweir         rDestinationCanvas,
595*cdf0e10cSrcweir         "MovingSlideChange::performOut(): Invalid dest canvas" );
596*cdf0e10cSrcweir 
597*cdf0e10cSrcweir     if (mbFirstPerformCall && maEnteringDirection.equalZero())
598*cdf0e10cSrcweir     {
599*cdf0e10cSrcweir         mbFirstPerformCall = false;
600*cdf0e10cSrcweir         renderBitmap( getEnteringBitmap(rViewEntry), rDestinationCanvas );
601*cdf0e10cSrcweir     }
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir     // TODO(F1): This does not account for non-translational
604*cdf0e10cSrcweir     // transformations! If the canvas is rotated, we still
605*cdf0e10cSrcweir     // move the sprite unrotated (which might or might not
606*cdf0e10cSrcweir     // produce the intended effect).
607*cdf0e10cSrcweir     const basegfx::B2DHomMatrix aViewTransform(
608*cdf0e10cSrcweir         rDestinationCanvas->getTransformation() );
609*cdf0e10cSrcweir     const basegfx::B2DPoint aPageOrigin(
610*cdf0e10cSrcweir         aViewTransform * basegfx::B2DPoint() );
611*cdf0e10cSrcweir 
612*cdf0e10cSrcweir     // move sprite
613*cdf0e10cSrcweir     rSprite->movePixel(
614*cdf0e10cSrcweir         aPageOrigin + (t *
615*cdf0e10cSrcweir                        ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) *
616*cdf0e10cSrcweir                        maLeavingDirection) );
617*cdf0e10cSrcweir }
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir 
620*cdf0e10cSrcweir NumberAnimationSharedPtr createPushWipeTransition(
621*cdf0e10cSrcweir     boost::optional<SlideSharedPtr> const &         leavingSlide_,
622*cdf0e10cSrcweir     const SlideSharedPtr&                           pEnteringSlide,
623*cdf0e10cSrcweir     const UnoViewContainer&                         rViewContainer,
624*cdf0e10cSrcweir     ScreenUpdater&                                  rScreenUpdater,
625*cdf0e10cSrcweir     EventMultiplexer&                               rEventMultiplexer,
626*cdf0e10cSrcweir     sal_Int16                                       /*nTransitionType*/,
627*cdf0e10cSrcweir     sal_Int16                                       nTransitionSubType,
628*cdf0e10cSrcweir     bool                                            /*bTransitionDirection*/,
629*cdf0e10cSrcweir     const SoundPlayerSharedPtr&                     pSoundPlayer )
630*cdf0e10cSrcweir {
631*cdf0e10cSrcweir     boost::optional<SlideSharedPtr> leavingSlide; // no bitmap
632*cdf0e10cSrcweir     if (leavingSlide_ && (*leavingSlide_).get() != 0)
633*cdf0e10cSrcweir     {
634*cdf0e10cSrcweir         // opt: only page, if we've an
635*cdf0e10cSrcweir         // actual slide to move out here. We
636*cdf0e10cSrcweir         // _don't_ need a fake black background
637*cdf0e10cSrcweir         // bitmap, neither for push nor for comb
638*cdf0e10cSrcweir         // wipes.
639*cdf0e10cSrcweir         leavingSlide = leavingSlide_;
640*cdf0e10cSrcweir     }
641*cdf0e10cSrcweir 
642*cdf0e10cSrcweir     // setup direction vector
643*cdf0e10cSrcweir     bool bComb( false );
644*cdf0e10cSrcweir     ::basegfx::B2DVector aDirection;
645*cdf0e10cSrcweir     switch( nTransitionSubType )
646*cdf0e10cSrcweir     {
647*cdf0e10cSrcweir     default:
648*cdf0e10cSrcweir         OSL_ENSURE(
649*cdf0e10cSrcweir             false,
650*cdf0e10cSrcweir             "createPushWipeTransition(): Unexpected transition "
651*cdf0e10cSrcweir             "subtype for animations::TransitionType::PUSHWIPE "
652*cdf0e10cSrcweir             "transitions" );
653*cdf0e10cSrcweir         return NumberAnimationSharedPtr();
654*cdf0e10cSrcweir 
655*cdf0e10cSrcweir     case animations::TransitionSubType::FROMTOP:
656*cdf0e10cSrcweir         aDirection = ::basegfx::B2DVector( 0.0, 1.0 );
657*cdf0e10cSrcweir         break;
658*cdf0e10cSrcweir 
659*cdf0e10cSrcweir     case animations::TransitionSubType::FROMBOTTOM:
660*cdf0e10cSrcweir         aDirection = ::basegfx::B2DVector( 0.0, -1.0 );
661*cdf0e10cSrcweir         break;
662*cdf0e10cSrcweir 
663*cdf0e10cSrcweir     case animations::TransitionSubType::FROMLEFT:
664*cdf0e10cSrcweir         aDirection = ::basegfx::B2DVector( 1.0, 0.0 );
665*cdf0e10cSrcweir         break;
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir     case animations::TransitionSubType::FROMRIGHT:
668*cdf0e10cSrcweir         aDirection = ::basegfx::B2DVector( -1.0, 0.0 );
669*cdf0e10cSrcweir         break;
670*cdf0e10cSrcweir 
671*cdf0e10cSrcweir     case animations::TransitionSubType::FROMBOTTOMRIGHT:
672*cdf0e10cSrcweir         aDirection = ::basegfx::B2DVector( -1.0, -1.0 );
673*cdf0e10cSrcweir         break;
674*cdf0e10cSrcweir 
675*cdf0e10cSrcweir     case animations::TransitionSubType::FROMBOTTOMLEFT:
676*cdf0e10cSrcweir         aDirection = ::basegfx::B2DVector( 1.0, -1.0 );
677*cdf0e10cSrcweir         break;
678*cdf0e10cSrcweir 
679*cdf0e10cSrcweir     case animations::TransitionSubType::FROMTOPRIGHT:
680*cdf0e10cSrcweir         aDirection = ::basegfx::B2DVector( -1.0, 1.0 );
681*cdf0e10cSrcweir         break;
682*cdf0e10cSrcweir 
683*cdf0e10cSrcweir     case animations::TransitionSubType::FROMTOPLEFT:
684*cdf0e10cSrcweir         aDirection = ::basegfx::B2DVector( 1.0, 1.0 );
685*cdf0e10cSrcweir         break;
686*cdf0e10cSrcweir 
687*cdf0e10cSrcweir     case animations::TransitionSubType::COMBHORIZONTAL:
688*cdf0e10cSrcweir         aDirection = ::basegfx::B2DVector( 1.0, 0.0 );
689*cdf0e10cSrcweir         bComb = true;
690*cdf0e10cSrcweir         break;
691*cdf0e10cSrcweir 
692*cdf0e10cSrcweir     case animations::TransitionSubType::COMBVERTICAL:
693*cdf0e10cSrcweir         aDirection = ::basegfx::B2DVector( 0.0, 1.0 );
694*cdf0e10cSrcweir         bComb = true;
695*cdf0e10cSrcweir         break;
696*cdf0e10cSrcweir     }
697*cdf0e10cSrcweir 
698*cdf0e10cSrcweir     if( bComb )
699*cdf0e10cSrcweir     {
700*cdf0e10cSrcweir         return NumberAnimationSharedPtr(
701*cdf0e10cSrcweir             new CombTransition( leavingSlide,
702*cdf0e10cSrcweir                                 pEnteringSlide,
703*cdf0e10cSrcweir                                 pSoundPlayer,
704*cdf0e10cSrcweir                                 rViewContainer,
705*cdf0e10cSrcweir                                 rScreenUpdater,
706*cdf0e10cSrcweir                                 rEventMultiplexer,
707*cdf0e10cSrcweir                                 aDirection,
708*cdf0e10cSrcweir                                 24 /* comb with 12 stripes */ ));
709*cdf0e10cSrcweir     }
710*cdf0e10cSrcweir     else
711*cdf0e10cSrcweir     {
712*cdf0e10cSrcweir         return NumberAnimationSharedPtr(
713*cdf0e10cSrcweir             new MovingSlideChange( leavingSlide,
714*cdf0e10cSrcweir                                    pEnteringSlide,
715*cdf0e10cSrcweir                                    pSoundPlayer,
716*cdf0e10cSrcweir                                    rViewContainer,
717*cdf0e10cSrcweir                                    rScreenUpdater,
718*cdf0e10cSrcweir                                    rEventMultiplexer,
719*cdf0e10cSrcweir                                    aDirection,
720*cdf0e10cSrcweir                                    aDirection ));
721*cdf0e10cSrcweir     }
722*cdf0e10cSrcweir }
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir NumberAnimationSharedPtr createSlideWipeTransition(
725*cdf0e10cSrcweir     boost::optional<SlideSharedPtr> const &         leavingSlide,
726*cdf0e10cSrcweir     const SlideSharedPtr&                           pEnteringSlide,
727*cdf0e10cSrcweir     const UnoViewContainer&                         rViewContainer,
728*cdf0e10cSrcweir     ScreenUpdater&                                  rScreenUpdater,
729*cdf0e10cSrcweir     EventMultiplexer&                               rEventMultiplexer,
730*cdf0e10cSrcweir     sal_Int16                                       /*nTransitionType*/,
731*cdf0e10cSrcweir     sal_Int16                                       nTransitionSubType,
732*cdf0e10cSrcweir     bool                                            bTransitionDirection,
733*cdf0e10cSrcweir     const SoundPlayerSharedPtr&                     pSoundPlayer )
734*cdf0e10cSrcweir {
735*cdf0e10cSrcweir     // setup 'in' direction vector
736*cdf0e10cSrcweir     ::basegfx::B2DVector aInDirection;
737*cdf0e10cSrcweir     switch( nTransitionSubType )
738*cdf0e10cSrcweir     {
739*cdf0e10cSrcweir     default:
740*cdf0e10cSrcweir         OSL_ENSURE(
741*cdf0e10cSrcweir             false,
742*cdf0e10cSrcweir             "createSlideWipeTransition(): Unexpected transition "
743*cdf0e10cSrcweir             "subtype for animations::TransitionType::SLIDEWIPE "
744*cdf0e10cSrcweir             "transitions" );
745*cdf0e10cSrcweir         return NumberAnimationSharedPtr();
746*cdf0e10cSrcweir 
747*cdf0e10cSrcweir     case animations::TransitionSubType::FROMTOP:
748*cdf0e10cSrcweir         aInDirection = ::basegfx::B2DVector( 0.0, 1.0 );
749*cdf0e10cSrcweir         break;
750*cdf0e10cSrcweir 
751*cdf0e10cSrcweir     case animations::TransitionSubType::FROMRIGHT:
752*cdf0e10cSrcweir         aInDirection = ::basegfx::B2DVector( -1.0, 0.0 );
753*cdf0e10cSrcweir         break;
754*cdf0e10cSrcweir 
755*cdf0e10cSrcweir     case animations::TransitionSubType::FROMLEFT:
756*cdf0e10cSrcweir         aInDirection = ::basegfx::B2DVector( 1.0, 0.0 );
757*cdf0e10cSrcweir         break;
758*cdf0e10cSrcweir 
759*cdf0e10cSrcweir     case animations::TransitionSubType::FROMBOTTOM:
760*cdf0e10cSrcweir         aInDirection = ::basegfx::B2DVector( 0.0, -1.0 );
761*cdf0e10cSrcweir         break;
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir     case animations::TransitionSubType::FROMBOTTOMRIGHT:
764*cdf0e10cSrcweir         aInDirection = ::basegfx::B2DVector( -1.0, -1.0 );
765*cdf0e10cSrcweir         break;
766*cdf0e10cSrcweir 
767*cdf0e10cSrcweir     case animations::TransitionSubType::FROMBOTTOMLEFT:
768*cdf0e10cSrcweir         aInDirection = ::basegfx::B2DVector( 1.0, -1.0 );
769*cdf0e10cSrcweir         break;
770*cdf0e10cSrcweir 
771*cdf0e10cSrcweir     case animations::TransitionSubType::FROMTOPRIGHT:
772*cdf0e10cSrcweir         aInDirection = ::basegfx::B2DVector( -1.0, 1.0 );
773*cdf0e10cSrcweir         break;
774*cdf0e10cSrcweir 
775*cdf0e10cSrcweir     case animations::TransitionSubType::FROMTOPLEFT:
776*cdf0e10cSrcweir         aInDirection = ::basegfx::B2DVector( 1.0, 1.0 );
777*cdf0e10cSrcweir         break;
778*cdf0e10cSrcweir     }
779*cdf0e10cSrcweir 
780*cdf0e10cSrcweir     if( bTransitionDirection )
781*cdf0e10cSrcweir     {
782*cdf0e10cSrcweir         // normal, 'forward' slide wipe effect. Since the old
783*cdf0e10cSrcweir         // content is still on screen (and does not move), we omit
784*cdf0e10cSrcweir         // the 'leaving' slide.
785*cdf0e10cSrcweir         // =======================================================
786*cdf0e10cSrcweir 
787*cdf0e10cSrcweir         return NumberAnimationSharedPtr(
788*cdf0e10cSrcweir             new MovingSlideChange(
789*cdf0e10cSrcweir                 boost::optional<SlideSharedPtr>() /* no slide */,
790*cdf0e10cSrcweir                 pEnteringSlide,
791*cdf0e10cSrcweir                 pSoundPlayer,
792*cdf0e10cSrcweir                 rViewContainer,
793*cdf0e10cSrcweir                 rScreenUpdater,
794*cdf0e10cSrcweir                 rEventMultiplexer,
795*cdf0e10cSrcweir                 basegfx::B2DVector(),
796*cdf0e10cSrcweir                 aInDirection ));
797*cdf0e10cSrcweir     }
798*cdf0e10cSrcweir     else
799*cdf0e10cSrcweir     {
800*cdf0e10cSrcweir         // 'reversed' slide wipe effect. Reverse for slide wipes
801*cdf0e10cSrcweir         // means, that the new slide is in the back, statically,
802*cdf0e10cSrcweir         // and the old one is moving off in the foreground.
803*cdf0e10cSrcweir         // =======================================================
804*cdf0e10cSrcweir 
805*cdf0e10cSrcweir         return NumberAnimationSharedPtr(
806*cdf0e10cSrcweir             new MovingSlideChange( leavingSlide,
807*cdf0e10cSrcweir                                    pEnteringSlide,
808*cdf0e10cSrcweir                                    pSoundPlayer,
809*cdf0e10cSrcweir                                    rViewContainer,
810*cdf0e10cSrcweir                                    rScreenUpdater,
811*cdf0e10cSrcweir                                    rEventMultiplexer,
812*cdf0e10cSrcweir                                    aInDirection,
813*cdf0e10cSrcweir                                    basegfx::B2DVector() ));
814*cdf0e10cSrcweir     }
815*cdf0e10cSrcweir }
816*cdf0e10cSrcweir 
817*cdf0e10cSrcweir NumberAnimationSharedPtr createPluginTransition(
818*cdf0e10cSrcweir     sal_Int16                                nTransitionType,
819*cdf0e10cSrcweir     sal_Int16                                nTransitionSubType,
820*cdf0e10cSrcweir     boost::optional<SlideSharedPtr> const&   pLeavingSlide,
821*cdf0e10cSrcweir     const SlideSharedPtr&                    pEnteringSlide,
822*cdf0e10cSrcweir     const UnoViewContainer&                  rViewContainer,
823*cdf0e10cSrcweir     ScreenUpdater&                           rScreenUpdater,
824*cdf0e10cSrcweir     const uno::Reference<
825*cdf0e10cSrcweir           presentation::XTransitionFactory>& xFactory,
826*cdf0e10cSrcweir     const SoundPlayerSharedPtr&              pSoundPlayer,
827*cdf0e10cSrcweir     EventMultiplexer&                        rEventMultiplexer)
828*cdf0e10cSrcweir {
829*cdf0e10cSrcweir     PluginSlideChange* pTransition =
830*cdf0e10cSrcweir         new PluginSlideChange(
831*cdf0e10cSrcweir             nTransitionType,
832*cdf0e10cSrcweir             nTransitionSubType,
833*cdf0e10cSrcweir             pLeavingSlide,
834*cdf0e10cSrcweir             pEnteringSlide,
835*cdf0e10cSrcweir             rViewContainer,
836*cdf0e10cSrcweir             rScreenUpdater,
837*cdf0e10cSrcweir             xFactory,
838*cdf0e10cSrcweir             pSoundPlayer,
839*cdf0e10cSrcweir             rEventMultiplexer );
840*cdf0e10cSrcweir 
841*cdf0e10cSrcweir     if( pTransition->Success() )
842*cdf0e10cSrcweir         return NumberAnimationSharedPtr( pTransition );
843*cdf0e10cSrcweir     else {
844*cdf0e10cSrcweir         delete pTransition;
845*cdf0e10cSrcweir         return NumberAnimationSharedPtr();
846*cdf0e10cSrcweir     }
847*cdf0e10cSrcweir }
848*cdf0e10cSrcweir 
849*cdf0e10cSrcweir } // anon namespace
850*cdf0e10cSrcweir 
851*cdf0e10cSrcweir 
852*cdf0e10cSrcweir NumberAnimationSharedPtr TransitionFactory::createSlideTransition(
853*cdf0e10cSrcweir     const SlideSharedPtr&                                   pLeavingSlide,
854*cdf0e10cSrcweir     const SlideSharedPtr&                                   pEnteringSlide,
855*cdf0e10cSrcweir     const UnoViewContainer&                                 rViewContainer,
856*cdf0e10cSrcweir     ScreenUpdater&                                          rScreenUpdater,
857*cdf0e10cSrcweir     EventMultiplexer&                                       rEventMultiplexer,
858*cdf0e10cSrcweir     const uno::Reference<presentation::XTransitionFactory>& xOptionalFactory,
859*cdf0e10cSrcweir     sal_Int16                                               nTransitionType,
860*cdf0e10cSrcweir     sal_Int16                                               nTransitionSubType,
861*cdf0e10cSrcweir     bool                                                    bTransitionDirection,
862*cdf0e10cSrcweir     const RGBColor&                                         rTransitionFadeColor,
863*cdf0e10cSrcweir     const SoundPlayerSharedPtr&                             pSoundPlayer            )
864*cdf0e10cSrcweir {
865*cdf0e10cSrcweir     // xxx todo: change to TransitionType::NONE, TransitionSubType::NONE:
866*cdf0e10cSrcweir     if (nTransitionType == 0 && nTransitionSubType == 0) {
867*cdf0e10cSrcweir         // just play sound, no slide transition:
868*cdf0e10cSrcweir         if (pSoundPlayer) {
869*cdf0e10cSrcweir             pSoundPlayer->startPlayback();
870*cdf0e10cSrcweir             // xxx todo: for now, presentation.cxx takes care about the slide
871*cdf0e10cSrcweir             // #i50492#  transition sound object, so just release it here
872*cdf0e10cSrcweir         }
873*cdf0e10cSrcweir         return NumberAnimationSharedPtr();
874*cdf0e10cSrcweir     }
875*cdf0e10cSrcweir 
876*cdf0e10cSrcweir     ENSURE_OR_THROW(
877*cdf0e10cSrcweir         pEnteringSlide,
878*cdf0e10cSrcweir         "TransitionFactory::createSlideTransition(): Invalid entering slide" );
879*cdf0e10cSrcweir 
880*cdf0e10cSrcweir     if( xOptionalFactory.is() &&
881*cdf0e10cSrcweir         xOptionalFactory->hasTransition(nTransitionType, nTransitionSubType) )
882*cdf0e10cSrcweir     {
883*cdf0e10cSrcweir         // #i82460# - optional plugin factory claims this transition. delegate.
884*cdf0e10cSrcweir         NumberAnimationSharedPtr pTransition(
885*cdf0e10cSrcweir             createPluginTransition(
886*cdf0e10cSrcweir                 nTransitionType,
887*cdf0e10cSrcweir                 nTransitionSubType,
888*cdf0e10cSrcweir                 comphelper::make_optional(pLeavingSlide),
889*cdf0e10cSrcweir                 pEnteringSlide,
890*cdf0e10cSrcweir                 rViewContainer,
891*cdf0e10cSrcweir                 rScreenUpdater,
892*cdf0e10cSrcweir                 xOptionalFactory,
893*cdf0e10cSrcweir                 pSoundPlayer,
894*cdf0e10cSrcweir                 rEventMultiplexer ));
895*cdf0e10cSrcweir 
896*cdf0e10cSrcweir         if( pTransition.get() )
897*cdf0e10cSrcweir             return pTransition;
898*cdf0e10cSrcweir     }
899*cdf0e10cSrcweir 
900*cdf0e10cSrcweir     const TransitionInfo* pTransitionInfo(
901*cdf0e10cSrcweir         getTransitionInfo( nTransitionType, nTransitionSubType ) );
902*cdf0e10cSrcweir 
903*cdf0e10cSrcweir     if( pTransitionInfo != NULL )
904*cdf0e10cSrcweir     {
905*cdf0e10cSrcweir         switch( pTransitionInfo->meTransitionClass )
906*cdf0e10cSrcweir         {
907*cdf0e10cSrcweir             default:
908*cdf0e10cSrcweir             case TransitionInfo::TRANSITION_INVALID:
909*cdf0e10cSrcweir                 OSL_TRACE(
910*cdf0e10cSrcweir                     "TransitionFactory::createSlideTransition(): "
911*cdf0e10cSrcweir                     "Invalid type/subtype (%d/%d) combination encountered.",
912*cdf0e10cSrcweir                     nTransitionType,
913*cdf0e10cSrcweir                     nTransitionSubType );
914*cdf0e10cSrcweir                 return NumberAnimationSharedPtr();
915*cdf0e10cSrcweir 
916*cdf0e10cSrcweir 
917*cdf0e10cSrcweir             case TransitionInfo::TRANSITION_CLIP_POLYPOLYGON:
918*cdf0e10cSrcweir             {
919*cdf0e10cSrcweir                 // generate parametric poly-polygon
920*cdf0e10cSrcweir                 ParametricPolyPolygonSharedPtr pPoly(
921*cdf0e10cSrcweir                     ParametricPolyPolygonFactory::createClipPolyPolygon(
922*cdf0e10cSrcweir                         nTransitionType, nTransitionSubType ) );
923*cdf0e10cSrcweir 
924*cdf0e10cSrcweir                 // create a clip transition from that
925*cdf0e10cSrcweir                 return NumberAnimationSharedPtr(
926*cdf0e10cSrcweir                     new ClippedSlideChange( pEnteringSlide,
927*cdf0e10cSrcweir                                             pPoly,
928*cdf0e10cSrcweir                                             *pTransitionInfo,
929*cdf0e10cSrcweir                                             rViewContainer,
930*cdf0e10cSrcweir                                             rScreenUpdater,
931*cdf0e10cSrcweir                                             rEventMultiplexer,
932*cdf0e10cSrcweir                                             bTransitionDirection,
933*cdf0e10cSrcweir                                             pSoundPlayer ));
934*cdf0e10cSrcweir             }
935*cdf0e10cSrcweir 
936*cdf0e10cSrcweir             case TransitionInfo::TRANSITION_SPECIAL:
937*cdf0e10cSrcweir             {
938*cdf0e10cSrcweir                 switch( nTransitionType )
939*cdf0e10cSrcweir                 {
940*cdf0e10cSrcweir                     default:
941*cdf0e10cSrcweir                         OSL_ENSURE(
942*cdf0e10cSrcweir                             false,
943*cdf0e10cSrcweir                             "TransitionFactory::createSlideTransition(): "
944*cdf0e10cSrcweir                             "Unexpected transition type for "
945*cdf0e10cSrcweir                             "TRANSITION_SPECIAL transitions" );
946*cdf0e10cSrcweir                         return NumberAnimationSharedPtr();
947*cdf0e10cSrcweir 
948*cdf0e10cSrcweir                     case animations::TransitionType::RANDOM:
949*cdf0e10cSrcweir                     {
950*cdf0e10cSrcweir                         // select randomly one of the effects from the
951*cdf0e10cSrcweir                         // TransitionFactoryTable
952*cdf0e10cSrcweir 
953*cdf0e10cSrcweir                         const TransitionInfo* pRandomTransitionInfo(
954*cdf0e10cSrcweir                             getRandomTransitionInfo() );
955*cdf0e10cSrcweir 
956*cdf0e10cSrcweir                         ENSURE_OR_THROW(
957*cdf0e10cSrcweir                             pRandomTransitionInfo != NULL,
958*cdf0e10cSrcweir                             "TransitionFactory::createSlideTransition(): "
959*cdf0e10cSrcweir                             "Got invalid random transition info" );
960*cdf0e10cSrcweir 
961*cdf0e10cSrcweir                         ENSURE_OR_THROW(
962*cdf0e10cSrcweir                             pRandomTransitionInfo->mnTransitionType !=
963*cdf0e10cSrcweir                             animations::TransitionType::RANDOM,
964*cdf0e10cSrcweir                             "TransitionFactory::createSlideTransition(): "
965*cdf0e10cSrcweir                             "Got random again for random input!" );
966*cdf0e10cSrcweir 
967*cdf0e10cSrcweir                         // and recurse
968*cdf0e10cSrcweir                         return createSlideTransition(
969*cdf0e10cSrcweir                             pLeavingSlide,
970*cdf0e10cSrcweir                             pEnteringSlide,
971*cdf0e10cSrcweir                             rViewContainer,
972*cdf0e10cSrcweir                             rScreenUpdater,
973*cdf0e10cSrcweir                             rEventMultiplexer,
974*cdf0e10cSrcweir                             xOptionalFactory,
975*cdf0e10cSrcweir                             pRandomTransitionInfo->mnTransitionType,
976*cdf0e10cSrcweir                             pRandomTransitionInfo->mnTransitionSubType,
977*cdf0e10cSrcweir                             bTransitionDirection,
978*cdf0e10cSrcweir                             rTransitionFadeColor,
979*cdf0e10cSrcweir                             pSoundPlayer );
980*cdf0e10cSrcweir                     }
981*cdf0e10cSrcweir 
982*cdf0e10cSrcweir                     case animations::TransitionType::PUSHWIPE:
983*cdf0e10cSrcweir                     {
984*cdf0e10cSrcweir                         return createPushWipeTransition(
985*cdf0e10cSrcweir                             comphelper::make_optional(pLeavingSlide),
986*cdf0e10cSrcweir                             pEnteringSlide,
987*cdf0e10cSrcweir                             rViewContainer,
988*cdf0e10cSrcweir                             rScreenUpdater,
989*cdf0e10cSrcweir                             rEventMultiplexer,
990*cdf0e10cSrcweir                             nTransitionType,
991*cdf0e10cSrcweir                             nTransitionSubType,
992*cdf0e10cSrcweir                             bTransitionDirection,
993*cdf0e10cSrcweir                             pSoundPlayer );
994*cdf0e10cSrcweir                     }
995*cdf0e10cSrcweir 
996*cdf0e10cSrcweir                     case animations::TransitionType::SLIDEWIPE:
997*cdf0e10cSrcweir                     {
998*cdf0e10cSrcweir                         return createSlideWipeTransition(
999*cdf0e10cSrcweir                             comphelper::make_optional(pLeavingSlide),
1000*cdf0e10cSrcweir                             pEnteringSlide,
1001*cdf0e10cSrcweir                             rViewContainer,
1002*cdf0e10cSrcweir                             rScreenUpdater,
1003*cdf0e10cSrcweir                             rEventMultiplexer,
1004*cdf0e10cSrcweir                             nTransitionType,
1005*cdf0e10cSrcweir                             nTransitionSubType,
1006*cdf0e10cSrcweir                             bTransitionDirection,
1007*cdf0e10cSrcweir                             pSoundPlayer );
1008*cdf0e10cSrcweir                     }
1009*cdf0e10cSrcweir 
1010*cdf0e10cSrcweir                     case animations::TransitionType::FADE:
1011*cdf0e10cSrcweir                     {
1012*cdf0e10cSrcweir                         // black page:
1013*cdf0e10cSrcweir                         boost::optional<SlideSharedPtr> leavingSlide;
1014*cdf0e10cSrcweir 
1015*cdf0e10cSrcweir                         switch( nTransitionSubType )
1016*cdf0e10cSrcweir                         {
1017*cdf0e10cSrcweir                             case animations::TransitionSubType::CROSSFADE:
1018*cdf0e10cSrcweir                                 // crossfade needs no further setup,
1019*cdf0e10cSrcweir                                 // just blend new slide over existing
1020*cdf0e10cSrcweir                                 // background.
1021*cdf0e10cSrcweir                                 break;
1022*cdf0e10cSrcweir 
1023*cdf0e10cSrcweir                                 // TODO(F1): Implement toColor/fromColor fades
1024*cdf0e10cSrcweir                             case animations::TransitionSubType::FADETOCOLOR:
1025*cdf0e10cSrcweir                                 // FALLTHROUGH intended
1026*cdf0e10cSrcweir                             case animations::TransitionSubType::FADEFROMCOLOR:
1027*cdf0e10cSrcweir                                 // FALLTHROUGH intended
1028*cdf0e10cSrcweir                             case animations::TransitionSubType::FADEOVERCOLOR:
1029*cdf0e10cSrcweir                                 if (pLeavingSlide) {
1030*cdf0e10cSrcweir                                     // only generate, if fade
1031*cdf0e10cSrcweir                                     // effect really needs it.
1032*cdf0e10cSrcweir                                     leavingSlide.reset( pLeavingSlide );
1033*cdf0e10cSrcweir                                 }
1034*cdf0e10cSrcweir                                 break;
1035*cdf0e10cSrcweir 
1036*cdf0e10cSrcweir                             default:
1037*cdf0e10cSrcweir                                 ENSURE_OR_THROW( false,
1038*cdf0e10cSrcweir                                                   "SlideTransitionFactory::createSlideTransition(): Unknown FADE subtype" );
1039*cdf0e10cSrcweir                         }
1040*cdf0e10cSrcweir 
1041*cdf0e10cSrcweir                         return NumberAnimationSharedPtr(
1042*cdf0e10cSrcweir                             new FadingSlideChange(
1043*cdf0e10cSrcweir                                 leavingSlide,
1044*cdf0e10cSrcweir                                 pEnteringSlide,
1045*cdf0e10cSrcweir                                 comphelper::make_optional(
1046*cdf0e10cSrcweir                                     rTransitionFadeColor),
1047*cdf0e10cSrcweir                                 pSoundPlayer,
1048*cdf0e10cSrcweir                                 rViewContainer,
1049*cdf0e10cSrcweir                                 rScreenUpdater,
1050*cdf0e10cSrcweir                                 rEventMultiplexer ));
1051*cdf0e10cSrcweir                     }
1052*cdf0e10cSrcweir                 }
1053*cdf0e10cSrcweir             }
1054*cdf0e10cSrcweir             break;
1055*cdf0e10cSrcweir         }
1056*cdf0e10cSrcweir     }
1057*cdf0e10cSrcweir 
1058*cdf0e10cSrcweir     // No animation generated, maybe no table entry for given
1059*cdf0e10cSrcweir     // transition?
1060*cdf0e10cSrcweir     OSL_TRACE(
1061*cdf0e10cSrcweir         "TransitionFactory::createSlideTransition(): "
1062*cdf0e10cSrcweir         "Unknown type/subtype (%d/%d) combination encountered",
1063*cdf0e10cSrcweir         nTransitionType,
1064*cdf0e10cSrcweir         nTransitionSubType );
1065*cdf0e10cSrcweir     OSL_ENSURE(
1066*cdf0e10cSrcweir         false,
1067*cdf0e10cSrcweir         "TransitionFactory::createSlideTransition(): "
1068*cdf0e10cSrcweir         "Unknown type/subtype combination encountered" );
1069*cdf0e10cSrcweir 
1070*cdf0e10cSrcweir     return NumberAnimationSharedPtr();
1071*cdf0e10cSrcweir }
1072*cdf0e10cSrcweir 
1073*cdf0e10cSrcweir } // namespace internal
1074*cdf0e10cSrcweir } // namespace presentation
1075