1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/diagnose_ex.h>
22 #include <basegfx/matrix/b2dhommatrix.hxx>
23 #include <basegfx/utils/canvastools.hxx>
24 #include <basegfx/polygon/b2dpolygontools.hxx>
25 #include <basegfx/polygon/b2dpolypolygontools.hxx>
27 #include <cppcanvas/basegfxfactory.hxx>
29 #include <comphelper/make_shared_from_uno.hxx>
31 #include <com/sun/star/rendering/XIntegerBitmap.hpp>
32 #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
33 #include <com/sun/star/animations/TransitionType.hpp>
34 #include <com/sun/star/animations/TransitionSubType.hpp>
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include "slidechangebase.hxx"
38 #include <transitionfactory.hxx>
39 #include "transitionfactorytab.hxx"
40 #include "transitiontools.hxx"
41 #include "parametricpolypolygonfactory.hxx"
42 #include <animationfactory.hxx>
43 #include "clippingfunctor.hxx"
44 #include "combtransition.hxx"
49 /***************************************************
51 *** Slide Transition Effects ***
53 ***************************************************/
55 using namespace com::sun::star
;
63 // =============================================
65 void fillPage( const ::cppcanvas::CanvasSharedPtr
& rDestinationCanvas
,
66 const ::basegfx::B2DSize
& rPageSizePixel
,
67 const RGBColor
& rFillColor
)
69 // need to render without any transformation (we
70 // assume rPageSizePixel to represent device units)
71 const ::cppcanvas::CanvasSharedPtr
pDevicePixelCanvas(
72 rDestinationCanvas
->clone() );
73 pDevicePixelCanvas
->setTransformation( ::basegfx::B2DHomMatrix() );
75 // TODO(F2): Properly respect clip here.
76 // Might have to be transformed, too.
77 const ::basegfx::B2DHomMatrix
aViewTransform(
78 rDestinationCanvas
->getTransformation() );
79 const ::basegfx::B2DPoint
aOutputPosPixel(
80 aViewTransform
* ::basegfx::B2DPoint() );
82 fillRect( pDevicePixelCanvas
,
83 ::basegfx::B2DRectangle(
84 aOutputPosPixel
.getX(),
85 aOutputPosPixel
.getY(),
86 aOutputPosPixel
.getX() + rPageSizePixel
.getX(),
87 aOutputPosPixel
.getY() + rPageSizePixel
.getY() ),
88 rFillColor
.getIntegerColor() );
91 class PluginSlideChange
: public SlideChangeBase
93 struct TransitionViewPair
{
94 uno::Reference
<presentation::XTransition
> mxTransition
;
95 UnoViewSharedPtr mpView
;
97 TransitionViewPair( uno::Reference
<presentation::XTransition
> const & xTransition
, const UnoViewSharedPtr
& rView
)
99 mxTransition
= xTransition
;
103 ~TransitionViewPair()
105 mxTransition
.clear();
109 void update( double t
)
111 mxTransition
->update( t
);
116 /** Create a new SlideChanger, for the given leaving and
117 entering slide bitmaps, which uses super secret OpenGL
120 PluginSlideChange( sal_Int16 nTransitionType
,
121 sal_Int16 nTransitionSubType
,
122 boost::optional
<SlideSharedPtr
> const& leavingSlide_
,
123 const SlideSharedPtr
& pEnteringSlide
,
124 const UnoViewContainer
& rViewContainer
,
125 ScreenUpdater
& rScreenUpdater
,
126 const uno::Reference
<
127 presentation::XTransitionFactory
>& xFactory
,
128 const SoundPlayerSharedPtr
& pSoundPlayer
,
129 EventMultiplexer
& rEventMultiplexer
) :
130 SlideChangeBase( leavingSlide_
,
138 mnTransitionType( nTransitionType
),
139 mnTransitionSubType( nTransitionSubType
),
140 mxFactory( xFactory
)
142 // create one transition per view
143 for( const auto& rView
: rViewContainer
)
145 if( !addTransition( rView
) )
148 ENSURE_OR_THROW(maTransitions
.back() && maTransitions
.back()->mxTransition
.is(),
149 "Failed to create plugin transition");
154 virtual ~PluginSlideChange() override
158 for( const auto& pCurrView
: maTransitions
)
163 maTransitions
.clear();
166 bool addTransition( const UnoViewSharedPtr
& rView
)
168 uno::Reference
<presentation::XTransition
> rTransition
= mxFactory
->createTransition(
172 getLeavingBitmap(ViewEntry(rView
))->getXBitmap(),
173 getEnteringBitmap(ViewEntry(rView
))->getXBitmap() );
175 if( rTransition
.is() )
176 maTransitions
.push_back( new TransitionViewPair( rTransition
, rView
) );
183 virtual bool operator()( double t
) override
185 for( const auto& pTransition
: maTransitions
)
186 pTransition
->update( t
);
196 virtual void viewAdded( const UnoViewSharedPtr
& rView
) override
198 SAL_INFO("slideshow", "PluginSlideChange viewAdded");
199 SlideChangeBase::viewAdded( rView
);
201 for( const auto& pCurrView
: maTransitions
)
203 if( pCurrView
->mpView
== rView
)
207 SAL_INFO("slideshow", "need to be added" );
208 addTransition( rView
);
211 virtual void viewRemoved( const UnoViewSharedPtr
& rView
) override
213 SAL_INFO("slideshow", "PluginSlideChange viewRemoved");
214 SlideChangeBase::viewRemoved( rView
);
216 ::std::vector
< TransitionViewPair
* >::const_iterator
aEnd(maTransitions
.end());
217 for( ::std::vector
< TransitionViewPair
* >::iterator aIter
=maTransitions
.begin();
221 if( ( *aIter
)->mpView
== rView
)
223 SAL_INFO("slideshow", "view removed" );
225 maTransitions
.erase( aIter
);
231 virtual void viewChanged( const UnoViewSharedPtr
& rView
) override
233 SAL_INFO("slideshow", "PluginSlideChange viewChanged");
234 SlideChangeBase::viewChanged( rView
);
236 for( const auto& pCurrView
: maTransitions
)
238 if( pCurrView
->mpView
== rView
)
240 SAL_INFO("slideshow", "view changed" );
241 pCurrView
->mxTransition
->viewChanged( rView
->getUnoView(),
242 getLeavingBitmap(ViewEntry(rView
))->getXBitmap(),
243 getEnteringBitmap(ViewEntry(rView
))->getXBitmap() );
246 SAL_INFO("slideshow", "view did not change" );
250 virtual void viewsChanged() override
252 SAL_INFO("slideshow", "PluginSlideChange viewsChanged");
253 SlideChangeBase::viewsChanged();
255 for( const auto& pCurrView
: maTransitions
)
257 SAL_INFO("slideshow", "view changed" );
258 UnoViewSharedPtr pView
= pCurrView
->mpView
;
259 pCurrView
->mxTransition
->viewChanged( pView
->getUnoView(),
260 getLeavingBitmap(ViewEntry(pView
))->getXBitmap(),
261 getEnteringBitmap(ViewEntry(pView
))->getXBitmap() );
266 // One transition object per view
267 std::vector
< TransitionViewPair
* > maTransitions
;
272 sal_Int16 mnTransitionType
;
273 sal_Int16 mnTransitionSubType
;
275 uno::Reference
<presentation::XTransitionFactory
> mxFactory
;
278 class ClippedSlideChange
: public SlideChangeBase
281 /** Create a new SlideChanger, for the given leaving and
282 entering slide bitmaps, which applies the given clip
286 const SlideSharedPtr
& pEnteringSlide
,
287 const ParametricPolyPolygonSharedPtr
& rPolygon
,
288 const TransitionInfo
& rTransitionInfo
,
289 const UnoViewContainer
& rViewContainer
,
290 ScreenUpdater
& rScreenUpdater
,
291 EventMultiplexer
& rEventMultiplexer
,
292 bool bDirectionForward
,
293 const SoundPlayerSharedPtr
& pSoundPlayer
) :
295 // leaving bitmap is empty, we're leveraging the fact that the
296 // old slide is still displayed in the background:
297 boost::optional
<SlideSharedPtr
>(),
303 maClippingFunctor( rPolygon
,
309 virtual void performIn(
310 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
311 const ViewEntry
& rViewEntry
,
312 const ::cppcanvas::CanvasSharedPtr
& rDestinationCanvas
,
315 virtual void performOut(
316 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
317 const ViewEntry
& rViewEntry
,
318 const ::cppcanvas::CanvasSharedPtr
& rDestinationCanvas
,
322 ClippingFunctor maClippingFunctor
;
325 void ClippedSlideChange::performIn(
326 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
327 const ViewEntry
& rViewEntry
,
328 const ::cppcanvas::CanvasSharedPtr
& /*rDestinationCanvas*/,
331 // #i46602# Better work in device coordinate space here,
332 // otherwise, we too easily suffer from roundoffs. Apart from
333 // that, getEnteringSizePixel() _guarantees_ to cover the whole
334 // slide bitmap. There's a catch, though: this removes any effect
335 // of the view transformation (e.g. rotation) from the transition.
336 rSprite
->setClipPixel(
337 maClippingFunctor( t
,
338 ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry
.mpView
) ) ) );
341 void ClippedSlideChange::performOut(
342 const ::cppcanvas::CustomSpriteSharedPtr
& /*rSprite*/,
343 const ViewEntry
& /*rViewEntry*/,
344 const ::cppcanvas::CanvasSharedPtr
& /*rDestinationCanvas*/,
351 class FadingSlideChange
: public SlideChangeBase
354 /** Create a new SlideChanger, for the given leaving and
355 entering slides, which applies a fade effect.
358 boost::optional
<SlideSharedPtr
> const & leavingSlide
,
359 const SlideSharedPtr
& pEnteringSlide
,
360 boost::optional
<RGBColor
> const& rFadeColor
,
361 const SoundPlayerSharedPtr
& pSoundPlayer
,
362 const UnoViewContainer
& rViewContainer
,
363 ScreenUpdater
& rScreenUpdater
,
364 EventMultiplexer
& rEventMultiplexer
)
365 : SlideChangeBase( leavingSlide
,
371 maFadeColor( rFadeColor
)
374 virtual void prepareForRun(
375 const ViewEntry
& rViewEntry
,
376 const cppcanvas::CanvasSharedPtr
& rDestinationCanvas
) override
;
378 virtual void performIn(
379 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
380 const ViewEntry
& rViewEntry
,
381 const ::cppcanvas::CanvasSharedPtr
& rDestinationCanvas
,
384 virtual void performOut(
385 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
386 const ViewEntry
& rViewEntry
,
387 const ::cppcanvas::CanvasSharedPtr
& rDestinationCanvas
,
391 const boost::optional
< RGBColor
> maFadeColor
;
394 void FadingSlideChange::prepareForRun(
395 const ViewEntry
& rViewEntry
,
396 const cppcanvas::CanvasSharedPtr
& rDestinationCanvas
)
400 // clear page to given fade color. 'Leaving' slide is
401 // painted atop of that, but slowly fading out.
402 fillPage( rDestinationCanvas
,
403 ::basegfx::B2DSize( getEnteringSlideSizePixel( rViewEntry
.mpView
) ),
408 void FadingSlideChange::performIn(
409 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
410 const ViewEntry
& /*rViewEntry*/,
411 const ::cppcanvas::CanvasSharedPtr
& /*rDestinationCanvas*/,
416 "FadingSlideChange::performIn(): Invalid sprite" );
419 // After half of the active time, fade in new slide
420 rSprite
->setAlpha( t
> 0.5 ? 2.0*(t
-0.5) : 0.0 );
422 // Fade in new slide over full active time
423 rSprite
->setAlpha( t
);
426 void FadingSlideChange::performOut(
427 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
428 const ViewEntry
& /* rViewEntry */,
429 const ::cppcanvas::CanvasSharedPtr
& rDestinationCanvas
,
434 "FadingSlideChange::performOut(): Invalid sprite" );
437 "FadingSlideChange::performOut(): Invalid dest canvas" );
439 // only needed for color fades
442 // Until half of the active time, fade out old
443 // slide. After half of the active time, old slide
444 // will be invisible.
445 rSprite
->setAlpha( t
> 0.5 ? 0.0 : 2.0*(0.5-t
) );
449 class CutSlideChange
: public SlideChangeBase
452 /** Create a new SlideChanger, for the given leaving and
453 entering slides, which applies a cut effect.
456 boost::optional
<SlideSharedPtr
> const & leavingSlide
,
457 const SlideSharedPtr
& pEnteringSlide
,
458 const RGBColor
& rFadeColor
,
459 const SoundPlayerSharedPtr
& pSoundPlayer
,
460 const UnoViewContainer
& rViewContainer
,
461 ScreenUpdater
& rScreenUpdater
,
462 EventMultiplexer
& rEventMultiplexer
)
463 : SlideChangeBase( leavingSlide
,
469 maFadeColor( rFadeColor
)
472 virtual void prepareForRun(
473 const ViewEntry
& rViewEntry
,
474 const cppcanvas::CanvasSharedPtr
& rDestinationCanvas
) override
;
476 virtual void performIn(
477 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
478 const ViewEntry
& rViewEntry
,
479 const ::cppcanvas::CanvasSharedPtr
& rDestinationCanvas
,
482 virtual void performOut(
483 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
484 const ViewEntry
& rViewEntry
,
485 const ::cppcanvas::CanvasSharedPtr
& rDestinationCanvas
,
489 RGBColor maFadeColor
;
492 void CutSlideChange::prepareForRun(
493 const ViewEntry
& rViewEntry
,
494 const cppcanvas::CanvasSharedPtr
& rDestinationCanvas
)
496 // clear page to given fade color. 'Leaving' slide is
497 // painted atop of that
498 fillPage( rDestinationCanvas
,
499 ::basegfx::B2DSize( getEnteringSlideSizePixel( rViewEntry
.mpView
) ),
503 void CutSlideChange::performIn(
504 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
505 const ViewEntry
& /*rViewEntry*/,
506 const ::cppcanvas::CanvasSharedPtr
& /*rDestinationCanvas*/,
511 "CutSlideChange::performIn(): Invalid sprite" );
513 // After 2/3rd of the active time, display new slide
514 rSprite
->setAlpha( t
> 2/3.0 ? 1.0 : 0.0 );
517 void CutSlideChange::performOut(
518 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
519 const ViewEntry
& /* rViewEntry */,
520 const ::cppcanvas::CanvasSharedPtr
& rDestinationCanvas
,
525 "CutSlideChange::performOut(): Invalid sprite" );
528 "CutSlideChange::performOut(): Invalid dest canvas" );
530 // Until 1/3rd of the active time, display old slide.
531 rSprite
->setAlpha( t
> 1/3.0 ? 0.0 : 1.0 );
534 class MovingSlideChange
: public SlideChangeBase
536 /// Direction vector for leaving slide,
537 const ::basegfx::B2DVector maLeavingDirection
;
539 /// Direction vector for entering slide,
540 const ::basegfx::B2DVector maEnteringDirection
;
543 /** Create a new SlideChanger, for the given entering slide
544 bitmaps, which performs a moving slide change effect
546 @param rLeavingDirection
547 Direction vector. The move is performed along this
548 direction vector, starting at a position where the leaving
549 slide is fully visible, and ending at a position where the
550 leaving slide is just not visible. The vector must have
553 @param rEnteringDirection
554 Direction vector. The move is performed along this
555 direction vector, starting at a position where the
556 entering slide is just not visible, and ending at the
557 final slide position. The vector must have unit length.
560 const boost::optional
<SlideSharedPtr
>& leavingSlide
,
561 const SlideSharedPtr
& pEnteringSlide
,
562 const SoundPlayerSharedPtr
& pSoundPlayer
,
563 const UnoViewContainer
& rViewContainer
,
564 ScreenUpdater
& rScreenUpdater
,
565 EventMultiplexer
& rEventMultiplexer
,
566 const ::basegfx::B2DVector
& rLeavingDirection
,
567 const ::basegfx::B2DVector
& rEnteringDirection
)
569 leavingSlide
, pEnteringSlide
, pSoundPlayer
,
570 rViewContainer
, rScreenUpdater
, rEventMultiplexer
,
571 // Optimization: when leaving bitmap is given,
572 // but it does not move, don't create sprites for it,
573 // we simply paint it once at startup:
574 !rLeavingDirection
.equalZero() /* bCreateLeavingSprites */,
575 !rEnteringDirection
.equalZero() /* bCreateEnteringSprites */ ),
576 // TODO(F1): calc correct length of direction
577 // vector. Directions not strictly horizontal or vertical
578 // must travel a longer distance.
579 maLeavingDirection( rLeavingDirection
),
580 // TODO(F1): calc correct length of direction
581 // vector. Directions not strictly horizontal or vertical
582 // must travel a longer distance.
583 maEnteringDirection( rEnteringDirection
)
586 virtual void prepareForRun(
587 const ViewEntry
& rViewEntry
,
588 const cppcanvas::CanvasSharedPtr
& rDestinationCanvas
) override
;
590 virtual void performIn(
591 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
592 const ViewEntry
& rViewEntry
,
593 const ::cppcanvas::CanvasSharedPtr
& rDestinationCanvas
,
596 virtual void performOut(
597 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
598 const ViewEntry
& rViewEntry
,
599 const ::cppcanvas::CanvasSharedPtr
& rDestinationCanvas
,
603 void MovingSlideChange::prepareForRun(
604 const ViewEntry
& rViewEntry
,
605 const cppcanvas::CanvasSharedPtr
& rDestinationCanvas
)
607 if ( maLeavingDirection
.equalZero() )
608 renderBitmap( getLeavingBitmap( rViewEntry
), rDestinationCanvas
);
609 else if ( maEnteringDirection
.equalZero() )
610 renderBitmap( getEnteringBitmap( rViewEntry
), rDestinationCanvas
);
613 void MovingSlideChange::performIn(
614 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
615 const ViewEntry
& rViewEntry
,
616 const ::cppcanvas::CanvasSharedPtr
& rDestinationCanvas
,
619 // intro sprite moves:
623 "MovingSlideChange::performIn(): Invalid sprite" );
626 "MovingSlideChange::performIn(): Invalid dest canvas" );
628 // TODO(F1): This does not account for non-translational
629 // transformations! If the canvas is rotated, we still
630 // move the sprite unrotated (which might or might not
631 // produce the intended effect).
632 const basegfx::B2DHomMatrix
aViewTransform(
633 rDestinationCanvas
->getTransformation() );
634 const basegfx::B2DPoint
aPageOrigin(
635 aViewTransform
* basegfx::B2DPoint() );
641 ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry
.mpView
) ) *
642 maEnteringDirection
) );
645 void MovingSlideChange::performOut(
646 const ::cppcanvas::CustomSpriteSharedPtr
& rSprite
,
647 const ViewEntry
& rViewEntry
,
648 const ::cppcanvas::CanvasSharedPtr
& rDestinationCanvas
,
651 // outro sprite moves:
655 "MovingSlideChange::performOut(): Invalid sprite" );
658 "MovingSlideChange::performOut(): Invalid dest canvas" );
660 // TODO(F1): This does not account for non-translational
661 // transformations! If the canvas is rotated, we still
662 // move the sprite unrotated (which might or might not
663 // produce the intended effect).
664 const basegfx::B2DHomMatrix
aViewTransform(
665 rDestinationCanvas
->getTransformation() );
666 const basegfx::B2DPoint
aPageOrigin(
667 aViewTransform
* basegfx::B2DPoint() );
672 ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry
.mpView
) ) *
673 maLeavingDirection
) );
677 NumberAnimationSharedPtr
createPushWipeTransition(
678 boost::optional
<SlideSharedPtr
> const & leavingSlide_
,
679 const SlideSharedPtr
& pEnteringSlide
,
680 const UnoViewContainer
& rViewContainer
,
681 ScreenUpdater
& rScreenUpdater
,
682 EventMultiplexer
& rEventMultiplexer
,
683 sal_Int16
/*nTransitionType*/,
684 sal_Int16 nTransitionSubType
,
685 bool /*bTransitionDirection*/,
686 const SoundPlayerSharedPtr
& pSoundPlayer
)
688 boost::optional
<SlideSharedPtr
> leavingSlide
; // no bitmap
689 if (leavingSlide_
&& (*leavingSlide_
).get() != nullptr)
691 // opt: only page, if we've an
692 // actual slide to move out here. We
693 // _don't_ need a fake black background
694 // bitmap, neither for push nor for comb
696 leavingSlide
= leavingSlide_
;
699 // setup direction vector
701 ::basegfx::B2DVector aDirection
;
702 switch( nTransitionSubType
)
706 "createPushWipeTransition(): Unexpected transition "
707 "subtype for animations::TransitionType::PUSHWIPE "
709 return NumberAnimationSharedPtr();
711 case animations::TransitionSubType::FROMTOP
:
712 aDirection
= ::basegfx::B2DVector( 0.0, 1.0 );
715 case animations::TransitionSubType::FROMBOTTOM
:
716 aDirection
= ::basegfx::B2DVector( 0.0, -1.0 );
719 case animations::TransitionSubType::FROMLEFT
:
720 aDirection
= ::basegfx::B2DVector( 1.0, 0.0 );
723 case animations::TransitionSubType::FROMRIGHT
:
724 aDirection
= ::basegfx::B2DVector( -1.0, 0.0 );
727 case animations::TransitionSubType::FROMBOTTOMRIGHT
:
728 aDirection
= ::basegfx::B2DVector( -1.0, -1.0 );
731 case animations::TransitionSubType::FROMBOTTOMLEFT
:
732 aDirection
= ::basegfx::B2DVector( 1.0, -1.0 );
735 case animations::TransitionSubType::FROMTOPRIGHT
:
736 aDirection
= ::basegfx::B2DVector( -1.0, 1.0 );
739 case animations::TransitionSubType::FROMTOPLEFT
:
740 aDirection
= ::basegfx::B2DVector( 1.0, 1.0 );
743 case animations::TransitionSubType::COMBHORIZONTAL
:
744 aDirection
= ::basegfx::B2DVector( 1.0, 0.0 );
748 case animations::TransitionSubType::COMBVERTICAL
:
749 aDirection
= ::basegfx::B2DVector( 0.0, 1.0 );
756 return NumberAnimationSharedPtr(
757 new CombTransition( leavingSlide
,
764 24 /* comb with 12 stripes */ ));
768 return NumberAnimationSharedPtr(
769 new MovingSlideChange( leavingSlide
,
780 NumberAnimationSharedPtr
createSlideWipeTransition(
781 boost::optional
<SlideSharedPtr
> const & leavingSlide
,
782 const SlideSharedPtr
& pEnteringSlide
,
783 const UnoViewContainer
& rViewContainer
,
784 ScreenUpdater
& rScreenUpdater
,
785 EventMultiplexer
& rEventMultiplexer
,
786 sal_Int16
/*nTransitionType*/,
787 sal_Int16 nTransitionSubType
,
788 bool bTransitionDirection
,
789 const SoundPlayerSharedPtr
& pSoundPlayer
)
791 // setup 'in' direction vector
792 ::basegfx::B2DVector aInDirection
;
793 switch( nTransitionSubType
)
797 "createSlideWipeTransition(): Unexpected transition "
798 "subtype for animations::TransitionType::SLIDEWIPE "
800 return NumberAnimationSharedPtr();
802 case animations::TransitionSubType::FROMTOP
:
803 aInDirection
= ::basegfx::B2DVector( 0.0, 1.0 );
806 case animations::TransitionSubType::FROMRIGHT
:
807 aInDirection
= ::basegfx::B2DVector( -1.0, 0.0 );
810 case animations::TransitionSubType::FROMLEFT
:
811 aInDirection
= ::basegfx::B2DVector( 1.0, 0.0 );
814 case animations::TransitionSubType::FROMBOTTOM
:
815 aInDirection
= ::basegfx::B2DVector( 0.0, -1.0 );
818 case animations::TransitionSubType::FROMBOTTOMRIGHT
:
819 aInDirection
= ::basegfx::B2DVector( -1.0, -1.0 );
822 case animations::TransitionSubType::FROMBOTTOMLEFT
:
823 aInDirection
= ::basegfx::B2DVector( 1.0, -1.0 );
826 case animations::TransitionSubType::FROMTOPRIGHT
:
827 aInDirection
= ::basegfx::B2DVector( -1.0, 1.0 );
830 case animations::TransitionSubType::FROMTOPLEFT
:
831 aInDirection
= ::basegfx::B2DVector( 1.0, 1.0 );
835 if( bTransitionDirection
)
837 // normal, 'forward' slide wipe effect. Since the old
838 // content is still on screen (and does not move), we omit
839 // the 'leaving' slide.
842 return NumberAnimationSharedPtr(
843 new MovingSlideChange(
844 boost::optional
<SlideSharedPtr
>() /* no slide */,
850 basegfx::B2DVector(),
855 // 'reversed' slide wipe effect. Reverse for slide wipes
856 // means, that the new slide is in the back, statically,
857 // and the old one is moving off in the foreground.
860 return NumberAnimationSharedPtr(
861 new MovingSlideChange( leavingSlide
,
868 basegfx::B2DVector() ));
872 NumberAnimationSharedPtr
createPluginTransition(
873 sal_Int16 nTransitionType
,
874 sal_Int16 nTransitionSubType
,
875 boost::optional
<SlideSharedPtr
> const& pLeavingSlide
,
876 const SlideSharedPtr
& pEnteringSlide
,
877 const UnoViewContainer
& rViewContainer
,
878 ScreenUpdater
& rScreenUpdater
,
879 const uno::Reference
<
880 presentation::XTransitionFactory
>& xFactory
,
881 const SoundPlayerSharedPtr
& pSoundPlayer
,
882 EventMultiplexer
& rEventMultiplexer
)
884 std::unique_ptr
<PluginSlideChange
> pTransition(
885 new PluginSlideChange(
894 rEventMultiplexer
));
896 if( pTransition
->Success() )
897 return NumberAnimationSharedPtr( pTransition
.release() );
900 return NumberAnimationSharedPtr();
907 NumberAnimationSharedPtr
TransitionFactory::createSlideTransition(
908 const SlideSharedPtr
& pLeavingSlide
,
909 const SlideSharedPtr
& pEnteringSlide
,
910 const UnoViewContainer
& rViewContainer
,
911 ScreenUpdater
& rScreenUpdater
,
912 EventMultiplexer
& rEventMultiplexer
,
913 const uno::Reference
<presentation::XTransitionFactory
>& xOptionalFactory
,
914 sal_Int16 nTransitionType
,
915 sal_Int16 nTransitionSubType
,
916 bool bTransitionDirection
,
917 const RGBColor
& rTransitionFadeColor
,
918 const SoundPlayerSharedPtr
& pSoundPlayer
)
920 // xxx todo: change to TransitionType::NONE, TransitionSubType::NONE:
921 if (nTransitionType
== 0 && nTransitionSubType
== 0) {
922 // just play sound, no slide transition:
924 pSoundPlayer
->startPlayback();
925 // xxx todo: for now, presentation.cxx takes care about the slide
926 // #i50492# transition sound object, so just release it here
928 return NumberAnimationSharedPtr();
933 "TransitionFactory::createSlideTransition(): Invalid entering slide" );
935 if( xOptionalFactory
.is() &&
936 xOptionalFactory
->hasTransition(nTransitionType
, nTransitionSubType
) )
938 // #i82460# - optional plugin factory claims this transition. delegate.
939 NumberAnimationSharedPtr
pTransition(
940 createPluginTransition(
943 boost::make_optional(pLeavingSlide
),
949 rEventMultiplexer
));
951 if( pTransition
.get() )
955 const TransitionInfo
* pTransitionInfo(
956 getTransitionInfo( nTransitionType
, nTransitionSubType
) );
958 if( pTransitionInfo
!= nullptr )
960 switch( pTransitionInfo
->meTransitionClass
)
963 case TransitionInfo::TRANSITION_INVALID
:
964 SAL_WARN("slideshow",
965 "TransitionFactory::createSlideTransition(): "
966 "Invalid type/subtype combination encountered."
967 << nTransitionType
<< " " << nTransitionSubType
);
968 return NumberAnimationSharedPtr();
971 case TransitionInfo::TRANSITION_CLIP_POLYPOLYGON
:
973 // generate parametric poly-polygon
974 ParametricPolyPolygonSharedPtr
pPoly(
975 ParametricPolyPolygonFactory::createClipPolyPolygon(
976 nTransitionType
, nTransitionSubType
) );
978 // create a clip transition from that
979 return NumberAnimationSharedPtr(
980 new ClippedSlideChange( pEnteringSlide
,
986 bTransitionDirection
,
990 case TransitionInfo::TRANSITION_SPECIAL
:
992 switch( nTransitionType
)
996 "TransitionFactory::createSlideTransition(): "
997 "Unexpected transition type for "
998 "TRANSITION_SPECIAL transitions" );
999 return NumberAnimationSharedPtr();
1001 case animations::TransitionType::RANDOM
:
1003 // select randomly one of the effects from the
1004 // TransitionFactoryTable
1006 const TransitionInfo
* pRandomTransitionInfo(
1007 getRandomTransitionInfo() );
1010 pRandomTransitionInfo
!= nullptr,
1011 "TransitionFactory::createSlideTransition(): "
1012 "Got invalid random transition info" );
1015 pRandomTransitionInfo
->mnTransitionType
!=
1016 animations::TransitionType::RANDOM
,
1017 "TransitionFactory::createSlideTransition(): "
1018 "Got random again for random input!" );
1021 return createSlideTransition(
1028 pRandomTransitionInfo
->mnTransitionType
,
1029 pRandomTransitionInfo
->mnTransitionSubType
,
1030 bTransitionDirection
,
1031 rTransitionFadeColor
,
1035 case animations::TransitionType::PUSHWIPE
:
1037 return createPushWipeTransition(
1038 boost::make_optional(pLeavingSlide
),
1045 bTransitionDirection
,
1049 case animations::TransitionType::SLIDEWIPE
:
1051 return createSlideWipeTransition(
1052 boost::make_optional(pLeavingSlide
),
1059 bTransitionDirection
,
1063 case animations::TransitionType::BARWIPE
:
1064 case animations::TransitionType::FADE
:
1067 boost::optional
<SlideSharedPtr
> leavingSlide
;
1068 boost::optional
<RGBColor
> aFadeColor
;
1070 switch( nTransitionSubType
)
1072 case animations::TransitionSubType::CROSSFADE
:
1073 // crossfade needs no further setup,
1074 // just blend new slide over current
1078 // TODO(F1): Implement toColor/fromColor fades
1079 case animations::TransitionSubType::FADETOCOLOR
:
1080 // FALLTHROUGH intended
1081 case animations::TransitionSubType::FADEFROMCOLOR
:
1082 // FALLTHROUGH intended
1083 case animations::TransitionSubType::FADEOVERCOLOR
:
1084 if (pLeavingSlide
) {
1085 // only generate, if fade
1086 // effect really needs it.
1087 leavingSlide
.reset( pLeavingSlide
);
1089 aFadeColor
= rTransitionFadeColor
;
1093 ENSURE_OR_THROW( false,
1094 "SlideTransitionFactory::createSlideTransition(): Unknown FADE subtype" );
1097 if( nTransitionType
== animations::TransitionType::FADE
)
1098 return NumberAnimationSharedPtr(
1099 new FadingSlideChange(
1106 rEventMultiplexer
));
1108 return NumberAnimationSharedPtr(
1112 rTransitionFadeColor
,
1116 rEventMultiplexer
));
1124 // No animation generated, maybe no table entry for given
1126 SAL_WARN("slideshow",
1127 "TransitionFactory::createSlideTransition(): "
1128 "Unknown type/subtype combination encountered "
1129 << nTransitionType
<< " " << nTransitionSubType
);
1131 "TransitionFactory::createSlideTransition(): "
1132 "Unknown type/subtype combination encountered" );
1134 return NumberAnimationSharedPtr();
1137 } // namespace internal
1138 } // namespace presentation
1140 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */