Bump version to 6.0-36
[LibreOffice.git] / slideshow / source / engine / transitions / slidetransitionfactory.cxx
blob2f7310410719815f017ad743a63038c86b82a9a3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
45 #include <tools.hxx>
46 #include <memory>
49 /***************************************************
50 *** ***
51 *** Slide Transition Effects ***
52 *** ***
53 ***************************************************/
55 using namespace com::sun::star;
57 namespace slideshow {
58 namespace internal {
60 namespace {
62 // helper methods
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;
100 mpView = rView;
103 ~TransitionViewPair()
105 mxTransition.clear();
106 mpView.reset();
109 void update( double t )
111 mxTransition->update( t );
115 public:
116 /** Create a new SlideChanger, for the given leaving and
117 entering slide bitmaps, which uses super secret OpenGL
118 stuff.
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_,
131 pEnteringSlide,
132 pSoundPlayer,
133 rViewContainer,
134 rScreenUpdater,
135 rEventMultiplexer ),
136 maTransitions(),
137 mbSuccess( false ),
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 ) )
146 return;
148 ENSURE_OR_THROW(maTransitions.back() && maTransitions.back()->mxTransition.is(),
149 "Failed to create plugin transition");
151 mbSuccess = true;
154 virtual ~PluginSlideChange() override
156 mxFactory.clear();
158 for( const auto& pCurrView : maTransitions )
160 delete pCurrView;
163 maTransitions.clear();
166 bool addTransition( const UnoViewSharedPtr& rView )
168 uno::Reference<presentation::XTransition> rTransition = mxFactory->createTransition(
169 mnTransitionType,
170 mnTransitionSubType,
171 rView->getUnoView(),
172 getLeavingBitmap(ViewEntry(rView))->getXBitmap(),
173 getEnteringBitmap(ViewEntry(rView))->getXBitmap() );
175 if( rTransition.is() )
176 maTransitions.push_back( new TransitionViewPair( rTransition, rView ) );
177 else
178 return false;
180 return true;
183 virtual bool operator()( double t ) override
185 for( const auto& pTransition : maTransitions )
186 pTransition->update( t );
187 return true;
190 bool Success()
192 return mbSuccess;
195 // ViewEventHandler
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 )
204 return;
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();
218 aIter != aEnd;
219 ++aIter )
221 if( ( *aIter )->mpView == rView )
223 SAL_INFO("slideshow", "view removed" );
224 delete ( *aIter );
225 maTransitions.erase( aIter );
226 break;
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() );
245 else
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() );
265 private:
266 // One transition object per view
267 std::vector< TransitionViewPair* > maTransitions;
269 // bool
270 bool mbSuccess;
272 sal_Int16 mnTransitionType;
273 sal_Int16 mnTransitionSubType;
275 uno::Reference<presentation::XTransitionFactory> mxFactory;
278 class ClippedSlideChange : public SlideChangeBase
280 public:
281 /** Create a new SlideChanger, for the given leaving and
282 entering slide bitmaps, which applies the given clip
283 polygon.
285 ClippedSlideChange(
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 ) :
294 SlideChangeBase(
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>(),
298 pEnteringSlide,
299 pSoundPlayer,
300 rViewContainer,
301 rScreenUpdater,
302 rEventMultiplexer ),
303 maClippingFunctor( rPolygon,
304 rTransitionInfo,
305 bDirectionForward,
306 true )
309 virtual void performIn(
310 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
311 const ViewEntry& rViewEntry,
312 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
313 double t ) override;
315 virtual void performOut(
316 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
317 const ViewEntry& rViewEntry,
318 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
319 double t ) override;
321 private:
322 ClippingFunctor maClippingFunctor;
325 void ClippedSlideChange::performIn(
326 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
327 const ViewEntry& rViewEntry,
328 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
329 double t )
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*/,
345 double /*t*/ )
347 // not needed here
351 class FadingSlideChange : public SlideChangeBase
353 public:
354 /** Create a new SlideChanger, for the given leaving and
355 entering slides, which applies a fade effect.
357 FadingSlideChange(
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,
366 pEnteringSlide,
367 pSoundPlayer,
368 rViewContainer,
369 rScreenUpdater,
370 rEventMultiplexer ),
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,
382 double t ) override;
384 virtual void performOut(
385 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
386 const ViewEntry& rViewEntry,
387 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
388 double t ) override;
390 private:
391 const boost::optional< RGBColor > maFadeColor;
394 void FadingSlideChange::prepareForRun(
395 const ViewEntry& rViewEntry,
396 const cppcanvas::CanvasSharedPtr& rDestinationCanvas )
398 if ( maFadeColor )
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 ) ),
404 *maFadeColor );
408 void FadingSlideChange::performIn(
409 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
410 const ViewEntry& /*rViewEntry*/,
411 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
412 double t )
414 ENSURE_OR_THROW(
415 rSprite,
416 "FadingSlideChange::performIn(): Invalid sprite" );
418 if( maFadeColor )
419 // After half of the active time, fade in new slide
420 rSprite->setAlpha( t > 0.5 ? 2.0*(t-0.5) : 0.0 );
421 else
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,
430 double t )
432 ENSURE_OR_THROW(
433 rSprite,
434 "FadingSlideChange::performOut(): Invalid sprite" );
435 ENSURE_OR_THROW(
436 rDestinationCanvas,
437 "FadingSlideChange::performOut(): Invalid dest canvas" );
439 // only needed for color fades
440 if( maFadeColor )
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
451 public:
452 /** Create a new SlideChanger, for the given leaving and
453 entering slides, which applies a cut effect.
455 CutSlideChange(
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,
464 pEnteringSlide,
465 pSoundPlayer,
466 rViewContainer,
467 rScreenUpdater,
468 rEventMultiplexer ),
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,
480 double t ) override;
482 virtual void performOut(
483 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
484 const ViewEntry& rViewEntry,
485 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
486 double t ) override;
488 private:
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 ) ),
500 maFadeColor );
503 void CutSlideChange::performIn(
504 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
505 const ViewEntry& /*rViewEntry*/,
506 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
507 double t )
509 ENSURE_OR_THROW(
510 rSprite,
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,
521 double t )
523 ENSURE_OR_THROW(
524 rSprite,
525 "CutSlideChange::performOut(): Invalid sprite" );
526 ENSURE_OR_THROW(
527 rDestinationCanvas,
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;
542 public:
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
551 unit length.
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.
559 MovingSlideChange(
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 )
568 : SlideChangeBase(
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,
594 double t ) override;
596 virtual void performOut(
597 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
598 const ViewEntry& rViewEntry,
599 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
600 double t ) override;
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,
617 double t )
619 // intro sprite moves:
621 ENSURE_OR_THROW(
622 rSprite,
623 "MovingSlideChange::performIn(): Invalid sprite" );
624 ENSURE_OR_THROW(
625 rDestinationCanvas,
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() );
637 // move sprite
638 rSprite->movePixel(
639 aPageOrigin +
640 ((t - 1.0) *
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,
649 double t )
651 // outro sprite moves:
653 ENSURE_OR_THROW(
654 rSprite,
655 "MovingSlideChange::performOut(): Invalid sprite" );
656 ENSURE_OR_THROW(
657 rDestinationCanvas,
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() );
669 // move sprite
670 rSprite->movePixel(
671 aPageOrigin + (t *
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
695 // wipes.
696 leavingSlide = leavingSlide_;
699 // setup direction vector
700 bool bComb( false );
701 ::basegfx::B2DVector aDirection;
702 switch( nTransitionSubType )
704 default:
705 OSL_FAIL(
706 "createPushWipeTransition(): Unexpected transition "
707 "subtype for animations::TransitionType::PUSHWIPE "
708 "transitions" );
709 return NumberAnimationSharedPtr();
711 case animations::TransitionSubType::FROMTOP:
712 aDirection = ::basegfx::B2DVector( 0.0, 1.0 );
713 break;
715 case animations::TransitionSubType::FROMBOTTOM:
716 aDirection = ::basegfx::B2DVector( 0.0, -1.0 );
717 break;
719 case animations::TransitionSubType::FROMLEFT:
720 aDirection = ::basegfx::B2DVector( 1.0, 0.0 );
721 break;
723 case animations::TransitionSubType::FROMRIGHT:
724 aDirection = ::basegfx::B2DVector( -1.0, 0.0 );
725 break;
727 case animations::TransitionSubType::FROMBOTTOMRIGHT:
728 aDirection = ::basegfx::B2DVector( -1.0, -1.0 );
729 break;
731 case animations::TransitionSubType::FROMBOTTOMLEFT:
732 aDirection = ::basegfx::B2DVector( 1.0, -1.0 );
733 break;
735 case animations::TransitionSubType::FROMTOPRIGHT:
736 aDirection = ::basegfx::B2DVector( -1.0, 1.0 );
737 break;
739 case animations::TransitionSubType::FROMTOPLEFT:
740 aDirection = ::basegfx::B2DVector( 1.0, 1.0 );
741 break;
743 case animations::TransitionSubType::COMBHORIZONTAL:
744 aDirection = ::basegfx::B2DVector( 1.0, 0.0 );
745 bComb = true;
746 break;
748 case animations::TransitionSubType::COMBVERTICAL:
749 aDirection = ::basegfx::B2DVector( 0.0, 1.0 );
750 bComb = true;
751 break;
754 if( bComb )
756 return NumberAnimationSharedPtr(
757 new CombTransition( leavingSlide,
758 pEnteringSlide,
759 pSoundPlayer,
760 rViewContainer,
761 rScreenUpdater,
762 rEventMultiplexer,
763 aDirection,
764 24 /* comb with 12 stripes */ ));
766 else
768 return NumberAnimationSharedPtr(
769 new MovingSlideChange( leavingSlide,
770 pEnteringSlide,
771 pSoundPlayer,
772 rViewContainer,
773 rScreenUpdater,
774 rEventMultiplexer,
775 aDirection,
776 aDirection ));
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 )
795 default:
796 OSL_FAIL(
797 "createSlideWipeTransition(): Unexpected transition "
798 "subtype for animations::TransitionType::SLIDEWIPE "
799 "transitions" );
800 return NumberAnimationSharedPtr();
802 case animations::TransitionSubType::FROMTOP:
803 aInDirection = ::basegfx::B2DVector( 0.0, 1.0 );
804 break;
806 case animations::TransitionSubType::FROMRIGHT:
807 aInDirection = ::basegfx::B2DVector( -1.0, 0.0 );
808 break;
810 case animations::TransitionSubType::FROMLEFT:
811 aInDirection = ::basegfx::B2DVector( 1.0, 0.0 );
812 break;
814 case animations::TransitionSubType::FROMBOTTOM:
815 aInDirection = ::basegfx::B2DVector( 0.0, -1.0 );
816 break;
818 case animations::TransitionSubType::FROMBOTTOMRIGHT:
819 aInDirection = ::basegfx::B2DVector( -1.0, -1.0 );
820 break;
822 case animations::TransitionSubType::FROMBOTTOMLEFT:
823 aInDirection = ::basegfx::B2DVector( 1.0, -1.0 );
824 break;
826 case animations::TransitionSubType::FROMTOPRIGHT:
827 aInDirection = ::basegfx::B2DVector( -1.0, 1.0 );
828 break;
830 case animations::TransitionSubType::FROMTOPLEFT:
831 aInDirection = ::basegfx::B2DVector( 1.0, 1.0 );
832 break;
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 */,
845 pEnteringSlide,
846 pSoundPlayer,
847 rViewContainer,
848 rScreenUpdater,
849 rEventMultiplexer,
850 basegfx::B2DVector(),
851 aInDirection ));
853 else
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,
862 pEnteringSlide,
863 pSoundPlayer,
864 rViewContainer,
865 rScreenUpdater,
866 rEventMultiplexer,
867 aInDirection,
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(
886 nTransitionType,
887 nTransitionSubType,
888 pLeavingSlide,
889 pEnteringSlide,
890 rViewContainer,
891 rScreenUpdater,
892 xFactory,
893 pSoundPlayer,
894 rEventMultiplexer ));
896 if( pTransition->Success() )
897 return NumberAnimationSharedPtr( pTransition.release() );
898 else
900 return NumberAnimationSharedPtr();
904 } // anon namespace
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:
923 if (pSoundPlayer) {
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();
931 ENSURE_OR_THROW(
932 pEnteringSlide,
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(
941 nTransitionType,
942 nTransitionSubType,
943 boost::make_optional(pLeavingSlide),
944 pEnteringSlide,
945 rViewContainer,
946 rScreenUpdater,
947 xOptionalFactory,
948 pSoundPlayer,
949 rEventMultiplexer ));
951 if( pTransition.get() )
952 return pTransition;
955 const TransitionInfo* pTransitionInfo(
956 getTransitionInfo( nTransitionType, nTransitionSubType ) );
958 if( pTransitionInfo != nullptr )
960 switch( pTransitionInfo->meTransitionClass )
962 default:
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,
981 pPoly,
982 *pTransitionInfo,
983 rViewContainer,
984 rScreenUpdater,
985 rEventMultiplexer,
986 bTransitionDirection,
987 pSoundPlayer ));
990 case TransitionInfo::TRANSITION_SPECIAL:
992 switch( nTransitionType )
994 default:
995 OSL_FAIL(
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() );
1009 ENSURE_OR_THROW(
1010 pRandomTransitionInfo != nullptr,
1011 "TransitionFactory::createSlideTransition(): "
1012 "Got invalid random transition info" );
1014 ENSURE_OR_THROW(
1015 pRandomTransitionInfo->mnTransitionType !=
1016 animations::TransitionType::RANDOM,
1017 "TransitionFactory::createSlideTransition(): "
1018 "Got random again for random input!" );
1020 // and recurse
1021 return createSlideTransition(
1022 pLeavingSlide,
1023 pEnteringSlide,
1024 rViewContainer,
1025 rScreenUpdater,
1026 rEventMultiplexer,
1027 xOptionalFactory,
1028 pRandomTransitionInfo->mnTransitionType,
1029 pRandomTransitionInfo->mnTransitionSubType,
1030 bTransitionDirection,
1031 rTransitionFadeColor,
1032 pSoundPlayer );
1035 case animations::TransitionType::PUSHWIPE:
1037 return createPushWipeTransition(
1038 boost::make_optional(pLeavingSlide),
1039 pEnteringSlide,
1040 rViewContainer,
1041 rScreenUpdater,
1042 rEventMultiplexer,
1043 nTransitionType,
1044 nTransitionSubType,
1045 bTransitionDirection,
1046 pSoundPlayer );
1049 case animations::TransitionType::SLIDEWIPE:
1051 return createSlideWipeTransition(
1052 boost::make_optional(pLeavingSlide),
1053 pEnteringSlide,
1054 rViewContainer,
1055 rScreenUpdater,
1056 rEventMultiplexer,
1057 nTransitionType,
1058 nTransitionSubType,
1059 bTransitionDirection,
1060 pSoundPlayer );
1063 case animations::TransitionType::BARWIPE:
1064 case animations::TransitionType::FADE:
1066 // black page:
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
1075 // slide.
1076 break;
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;
1090 break;
1092 default:
1093 ENSURE_OR_THROW( false,
1094 "SlideTransitionFactory::createSlideTransition(): Unknown FADE subtype" );
1097 if( nTransitionType == animations::TransitionType::FADE )
1098 return NumberAnimationSharedPtr(
1099 new FadingSlideChange(
1100 leavingSlide,
1101 pEnteringSlide,
1102 aFadeColor,
1103 pSoundPlayer,
1104 rViewContainer,
1105 rScreenUpdater,
1106 rEventMultiplexer ));
1107 else
1108 return NumberAnimationSharedPtr(
1109 new CutSlideChange(
1110 leavingSlide,
1111 pEnteringSlide,
1112 rTransitionFadeColor,
1113 pSoundPlayer,
1114 rViewContainer,
1115 rScreenUpdater,
1116 rEventMultiplexer ));
1120 break;
1124 // No animation generated, maybe no table entry for given
1125 // transition?
1126 SAL_WARN("slideshow",
1127 "TransitionFactory::createSlideTransition(): "
1128 "Unknown type/subtype combination encountered "
1129 << nTransitionType << " " << nTransitionSubType );
1130 OSL_FAIL(
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: */