android: Update app-specific/MIME type icons
[LibreOffice.git] / slideshow / source / engine / transitions / slidetransitionfactory.cxx
blobfcee18e262c32b4a23928fde1927d41fbd8a1599
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 <comphelper/diagnose_ex.hxx>
21 #include <sal/log.hxx>
23 #include <basegfx/matrix/b2dhommatrix.hxx>
25 #include <cppcanvas/customsprite.hxx>
27 #include <com/sun/star/animations/TransitionType.hpp>
28 #include <com/sun/star/animations/TransitionSubType.hpp>
30 #include "slidechangebase.hxx"
31 #include <transitionfactory.hxx>
32 #include "transitionfactorytab.hxx"
33 #include "parametricpolypolygonfactory.hxx"
34 #include "clippingfunctor.hxx"
35 #include "combtransition.hxx"
36 #include <tools.hxx>
37 #include <memory>
38 #include <utility>
41 /***************************************************
42 *** ***
43 *** Slide Transition Effects ***
44 *** ***
45 ***************************************************/
47 using namespace com::sun::star;
49 namespace slideshow::internal {
51 namespace {
53 // helper methods
54 // =============================================
56 void fillPage( const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
57 const ::basegfx::B2DSize& rPageSizePixel,
58 const RGBColor& rFillColor )
60 // need to render without any transformation (we
61 // assume rPageSizePixel to represent device units)
62 const ::cppcanvas::CanvasSharedPtr pDevicePixelCanvas(
63 rDestinationCanvas->clone() );
64 pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
66 // TODO(F2): Properly respect clip here.
67 // Might have to be transformed, too.
68 const ::basegfx::B2DHomMatrix aViewTransform(
69 rDestinationCanvas->getTransformation() );
70 const ::basegfx::B2DPoint aOutputPosPixel(
71 aViewTransform * ::basegfx::B2DPoint() );
73 fillRect( pDevicePixelCanvas,
74 ::basegfx::B2DRectangle(
75 aOutputPosPixel.getX(),
76 aOutputPosPixel.getY(),
77 aOutputPosPixel.getX() + rPageSizePixel.getWidth(),
78 aOutputPosPixel.getY() + rPageSizePixel.getHeight() ),
79 rFillColor.getIntegerColor() );
82 class PluginSlideChange: public SlideChangeBase
84 struct TransitionViewPair {
85 uno::Reference<presentation::XTransition> mxTransition;
86 UnoViewSharedPtr mpView;
88 TransitionViewPair( uno::Reference<presentation::XTransition> xTransition, UnoViewSharedPtr xView )
89 : mxTransition(std::move(xTransition)), mpView(std::move(xView))
93 ~TransitionViewPair()
95 mxTransition.clear();
96 mpView.reset();
99 void update( double t )
101 mxTransition->update( t );
105 public:
106 /** Create a new SlideChanger, for the given leaving and
107 entering slide bitmaps, which uses super secret OpenGL
108 stuff.
110 PluginSlideChange( sal_Int16 nTransitionType,
111 sal_Int16 nTransitionSubType,
112 const RGBColor& rTransitionFadeColor,
113 std::optional<SlideSharedPtr> const& leavingSlide_,
114 const SlideSharedPtr& pEnteringSlide,
115 const UnoViewContainer& rViewContainer,
116 ScreenUpdater& rScreenUpdater,
117 uno::Reference<
118 presentation::XTransitionFactory> xFactory,
119 const SoundPlayerSharedPtr& pSoundPlayer,
120 EventMultiplexer& rEventMultiplexer) :
121 SlideChangeBase( leavingSlide_,
122 pEnteringSlide,
123 pSoundPlayer,
124 rViewContainer,
125 rScreenUpdater,
126 rEventMultiplexer ),
127 maTransitions(),
128 mbSuccess( false ),
129 mnTransitionType( nTransitionType ),
130 mnTransitionSubType( nTransitionSubType ),
131 mnTransitionFadeColor( rTransitionFadeColor ),
132 mxFactory(std::move( xFactory ))
134 // create one transition per view
135 for( const auto& rView : rViewContainer )
137 if( !addTransition( rView ) )
138 return;
140 ENSURE_OR_THROW(maTransitions.back() && maTransitions.back()->mxTransition.is(),
141 "Failed to create plugin transition");
143 mbSuccess = true;
146 virtual ~PluginSlideChange() override
148 mxFactory.clear();
151 bool addTransition( const UnoViewSharedPtr& rView )
153 uno::Reference<presentation::XTransition> rTransition = mxFactory->createTransition(
154 mnTransitionType,
155 mnTransitionSubType,
156 RGBAColor2UnoColor( mnTransitionFadeColor.getIntegerColor()),
157 rView->getUnoView(),
158 getLeavingBitmap(ViewEntry(rView))->getXBitmap(),
159 getEnteringBitmap(ViewEntry(rView))->getXBitmap() );
161 if( rTransition.is() )
162 maTransitions.emplace_back( new TransitionViewPair( rTransition, rView ) );
163 else
164 return false;
166 return true;
169 virtual bool operator()( double t ) override
171 for( const auto& pTransition : maTransitions )
172 pTransition->update( t );
173 return true;
176 bool Success()
178 return mbSuccess;
181 // ViewEventHandler
182 virtual void viewAdded( const UnoViewSharedPtr& rView ) override
184 SAL_INFO("slideshow", "PluginSlideChange viewAdded");
185 SlideChangeBase::viewAdded( rView );
187 for( const auto& pCurrView : maTransitions )
189 if( pCurrView->mpView == rView )
190 return;
193 SAL_INFO("slideshow", "need to be added" );
194 addTransition( rView );
197 virtual void viewRemoved( const UnoViewSharedPtr& rView ) override
199 SAL_INFO("slideshow", "PluginSlideChange viewRemoved");
200 SlideChangeBase::viewRemoved( rView );
202 auto aIter = std::find_if(maTransitions.begin(), maTransitions.end(),
203 [&rView](const std::unique_ptr<TransitionViewPair>& rxTransition) { return rxTransition->mpView == rView; });
204 if (aIter != maTransitions.end())
206 SAL_INFO("slideshow", "view removed" );
207 maTransitions.erase( aIter );
211 virtual void viewChanged( const UnoViewSharedPtr& rView ) override
213 SAL_INFO("slideshow", "PluginSlideChange viewChanged");
214 SlideChangeBase::viewChanged( rView );
216 for( const auto& pCurrView : maTransitions )
218 if( pCurrView->mpView == rView )
220 SAL_INFO("slideshow", "view changed" );
221 pCurrView->mxTransition->viewChanged( rView->getUnoView(),
222 getLeavingBitmap(ViewEntry(rView))->getXBitmap(),
223 getEnteringBitmap(ViewEntry(rView))->getXBitmap() );
225 else
226 SAL_INFO("slideshow", "view did not change" );
230 virtual void viewsChanged() override
232 SAL_INFO("slideshow", "PluginSlideChange viewsChanged");
233 SlideChangeBase::viewsChanged();
235 for( const auto& pCurrView : maTransitions )
237 SAL_INFO("slideshow", "view changed" );
238 UnoViewSharedPtr pView = pCurrView->mpView;
239 pCurrView->mxTransition->viewChanged( pView->getUnoView(),
240 getLeavingBitmap(ViewEntry(pView))->getXBitmap(),
241 getEnteringBitmap(ViewEntry(pView))->getXBitmap() );
245 private:
246 // One transition object per view
247 std::vector< std::unique_ptr<TransitionViewPair> > maTransitions;
249 // bool
250 bool mbSuccess;
252 sal_Int16 mnTransitionType;
253 sal_Int16 mnTransitionSubType;
254 RGBColor mnTransitionFadeColor;
256 uno::Reference<presentation::XTransitionFactory> mxFactory;
259 class ClippedSlideChange : public SlideChangeBase
261 public:
262 /** Create a new SlideChanger, for the given leaving and
263 entering slide bitmaps, which applies the given clip
264 polygon.
266 ClippedSlideChange(
267 const SlideSharedPtr& pEnteringSlide,
268 const ParametricPolyPolygonSharedPtr& rPolygon,
269 const TransitionInfo& rTransitionInfo,
270 const UnoViewContainer& rViewContainer,
271 ScreenUpdater& rScreenUpdater,
272 EventMultiplexer& rEventMultiplexer,
273 bool bDirectionForward,
274 const SoundPlayerSharedPtr& pSoundPlayer ) :
275 SlideChangeBase(
276 // leaving bitmap is empty, we're leveraging the fact that the
277 // old slide is still displayed in the background:
278 std::optional<SlideSharedPtr>(),
279 pEnteringSlide,
280 pSoundPlayer,
281 rViewContainer,
282 rScreenUpdater,
283 rEventMultiplexer ),
284 maClippingFunctor( rPolygon,
285 rTransitionInfo,
286 bDirectionForward,
287 true )
290 virtual void performIn(
291 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
292 const ViewEntry& rViewEntry,
293 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
294 double t ) override;
296 virtual void performOut(
297 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
298 const ViewEntry& rViewEntry,
299 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
300 double t ) override;
302 private:
303 ClippingFunctor maClippingFunctor;
306 void ClippedSlideChange::performIn(
307 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
308 const ViewEntry& rViewEntry,
309 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
310 double t )
312 // #i46602# Better work in device coordinate space here,
313 // otherwise, we too easily suffer from roundoffs. Apart from
314 // that, getEnteringSizePixel() _guarantees_ to cover the whole
315 // slide bitmap. There's a catch, though: this removes any effect
316 // of the view transformation (e.g. rotation) from the transition.
317 rSprite->setClipPixel(
318 maClippingFunctor( t,
319 ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) ) );
322 void ClippedSlideChange::performOut(
323 const ::cppcanvas::CustomSpriteSharedPtr& /*rSprite*/,
324 const ViewEntry& /*rViewEntry*/,
325 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
326 double /*t*/ )
328 // not needed here
332 class FadingSlideChange : public SlideChangeBase
334 public:
335 /** Create a new SlideChanger, for the given leaving and
336 entering slides, which applies a fade effect.
338 FadingSlideChange(
339 std::optional<SlideSharedPtr> const & leavingSlide,
340 const SlideSharedPtr& pEnteringSlide,
341 std::optional<RGBColor> const& rFadeColor,
342 const SoundPlayerSharedPtr& pSoundPlayer,
343 const UnoViewContainer& rViewContainer,
344 ScreenUpdater& rScreenUpdater,
345 EventMultiplexer& rEventMultiplexer )
346 : SlideChangeBase( leavingSlide,
347 pEnteringSlide,
348 pSoundPlayer,
349 rViewContainer,
350 rScreenUpdater,
351 rEventMultiplexer ),
352 maFadeColor( rFadeColor )
355 virtual void prepareForRun(
356 const ViewEntry& rViewEntry,
357 const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) override;
359 virtual void performIn(
360 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
361 const ViewEntry& rViewEntry,
362 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
363 double t ) override;
365 virtual void performOut(
366 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
367 const ViewEntry& rViewEntry,
368 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
369 double t ) override;
371 private:
372 const std::optional< RGBColor > maFadeColor;
375 void FadingSlideChange::prepareForRun(
376 const ViewEntry& rViewEntry,
377 const cppcanvas::CanvasSharedPtr& rDestinationCanvas )
379 if ( maFadeColor )
381 // clear page to given fade color. 'Leaving' slide is
382 // painted atop of that, but slowly fading out.
383 fillPage( rDestinationCanvas,
384 ::basegfx::B2DSize( getEnteringSlideSizePixel( rViewEntry.mpView ) ),
385 *maFadeColor );
389 void FadingSlideChange::performIn(
390 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
391 const ViewEntry& /*rViewEntry*/,
392 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
393 double t )
395 ENSURE_OR_THROW(
396 rSprite,
397 "FadingSlideChange::performIn(): Invalid sprite" );
399 if( maFadeColor )
400 // After half of the active time, fade in new slide
401 rSprite->setAlpha( t > 0.5 ? 2.0*(t-0.5) : 0.0 );
402 else
403 // Fade in new slide over full active time
404 rSprite->setAlpha( t );
407 void FadingSlideChange::performOut(
408 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
409 const ViewEntry& /* rViewEntry */,
410 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
411 double t )
413 ENSURE_OR_THROW(
414 rSprite,
415 "FadingSlideChange::performOut(): Invalid sprite" );
416 ENSURE_OR_THROW(
417 rDestinationCanvas,
418 "FadingSlideChange::performOut(): Invalid dest canvas" );
420 // only needed for color fades
421 if( maFadeColor )
423 // Until half of the active time, fade out old
424 // slide. After half of the active time, old slide
425 // will be invisible.
426 rSprite->setAlpha( t > 0.5 ? 0.0 : 2.0*(0.5-t) );
430 class CutSlideChange : public SlideChangeBase
432 public:
433 /** Create a new SlideChanger, for the given leaving and
434 entering slides, which applies a cut effect.
436 CutSlideChange(
437 std::optional<SlideSharedPtr> const & leavingSlide,
438 const SlideSharedPtr& pEnteringSlide,
439 const RGBColor& rFadeColor,
440 const SoundPlayerSharedPtr& pSoundPlayer,
441 const UnoViewContainer& rViewContainer,
442 ScreenUpdater& rScreenUpdater,
443 EventMultiplexer& rEventMultiplexer )
444 : SlideChangeBase( leavingSlide,
445 pEnteringSlide,
446 pSoundPlayer,
447 rViewContainer,
448 rScreenUpdater,
449 rEventMultiplexer ),
450 maFadeColor( rFadeColor )
453 virtual void prepareForRun(
454 const ViewEntry& rViewEntry,
455 const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) override;
457 virtual void performIn(
458 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
459 const ViewEntry& rViewEntry,
460 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
461 double t ) override;
463 virtual void performOut(
464 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
465 const ViewEntry& rViewEntry,
466 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
467 double t ) override;
469 private:
470 RGBColor maFadeColor;
473 void CutSlideChange::prepareForRun(
474 const ViewEntry& rViewEntry,
475 const cppcanvas::CanvasSharedPtr& rDestinationCanvas )
477 // clear page to given fade color. 'Leaving' slide is
478 // painted atop of that
479 fillPage( rDestinationCanvas,
480 ::basegfx::B2DSize( getEnteringSlideSizePixel( rViewEntry.mpView ) ),
481 maFadeColor );
484 void CutSlideChange::performIn(
485 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
486 const ViewEntry& /*rViewEntry*/,
487 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
488 double t )
490 ENSURE_OR_THROW(
491 rSprite,
492 "CutSlideChange::performIn(): Invalid sprite" );
494 // After 2/3rd of the active time, display new slide
495 rSprite->setAlpha( t > 2/3.0 ? 1.0 : 0.0 );
498 void CutSlideChange::performOut(
499 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
500 const ViewEntry& /* rViewEntry */,
501 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
502 double t )
504 ENSURE_OR_THROW(
505 rSprite,
506 "CutSlideChange::performOut(): Invalid sprite" );
507 ENSURE_OR_THROW(
508 rDestinationCanvas,
509 "CutSlideChange::performOut(): Invalid dest canvas" );
511 // Until 1/3rd of the active time, display old slide.
512 rSprite->setAlpha( t > 1/3.0 ? 0.0 : 1.0 );
515 class MovingSlideChange : public SlideChangeBase
517 /// Direction vector for leaving slide,
518 const ::basegfx::B2DVector maLeavingDirection;
520 /// Direction vector for entering slide,
521 const ::basegfx::B2DVector maEnteringDirection;
523 public:
524 /** Create a new SlideChanger, for the given entering slide
525 bitmaps, which performs a moving slide change effect
527 @param rLeavingDirection
528 Direction vector. The move is performed along this
529 direction vector, starting at a position where the leaving
530 slide is fully visible, and ending at a position where the
531 leaving slide is just not visible. The vector must have
532 unit length.
534 @param rEnteringDirection
535 Direction vector. The move is performed along this
536 direction vector, starting at a position where the
537 entering slide is just not visible, and ending at the
538 final slide position. The vector must have unit length.
540 MovingSlideChange(
541 const std::optional<SlideSharedPtr>& leavingSlide,
542 const SlideSharedPtr& pEnteringSlide,
543 const SoundPlayerSharedPtr& pSoundPlayer,
544 const UnoViewContainer& rViewContainer,
545 ScreenUpdater& rScreenUpdater,
546 EventMultiplexer& rEventMultiplexer,
547 const ::basegfx::B2DVector& rLeavingDirection,
548 const ::basegfx::B2DVector& rEnteringDirection )
549 : SlideChangeBase(
550 leavingSlide, pEnteringSlide, pSoundPlayer,
551 rViewContainer, rScreenUpdater, rEventMultiplexer,
552 // Optimization: when leaving bitmap is given,
553 // but it does not move, don't create sprites for it,
554 // we simply paint it once at startup:
555 !rLeavingDirection.equalZero() /* bCreateLeavingSprites */,
556 !rEnteringDirection.equalZero() /* bCreateEnteringSprites */ ),
557 // TODO(F1): calc correct length of direction
558 // vector. Directions not strictly horizontal or vertical
559 // must travel a longer distance.
560 maLeavingDirection( rLeavingDirection ),
561 // TODO(F1): calc correct length of direction
562 // vector. Directions not strictly horizontal or vertical
563 // must travel a longer distance.
564 maEnteringDirection( rEnteringDirection )
567 virtual void prepareForRun(
568 const ViewEntry& rViewEntry,
569 const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) override;
571 virtual void performIn(
572 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
573 const ViewEntry& rViewEntry,
574 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
575 double t ) override;
577 virtual void performOut(
578 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
579 const ViewEntry& rViewEntry,
580 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
581 double t ) override;
584 void MovingSlideChange::prepareForRun(
585 const ViewEntry& rViewEntry,
586 const cppcanvas::CanvasSharedPtr& rDestinationCanvas )
588 if ( maLeavingDirection.equalZero() )
589 renderBitmap( getLeavingBitmap( rViewEntry ), rDestinationCanvas );
590 else if ( maEnteringDirection.equalZero() )
591 renderBitmap( getEnteringBitmap( rViewEntry ), rDestinationCanvas );
594 void MovingSlideChange::performIn(
595 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
596 const ViewEntry& rViewEntry,
597 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
598 double t )
600 // intro sprite moves:
602 ENSURE_OR_THROW(
603 rSprite,
604 "MovingSlideChange::performIn(): Invalid sprite" );
605 ENSURE_OR_THROW(
606 rDestinationCanvas,
607 "MovingSlideChange::performIn(): Invalid dest canvas" );
609 // TODO(F1): This does not account for non-translational
610 // transformations! If the canvas is rotated, we still
611 // move the sprite unrotated (which might or might not
612 // produce the intended effect).
613 const basegfx::B2DHomMatrix aViewTransform(
614 rDestinationCanvas->getTransformation() );
615 const basegfx::B2DPoint aPageOrigin(
616 aViewTransform * basegfx::B2DPoint() );
618 // move sprite
619 rSprite->movePixel(
620 aPageOrigin +
621 ((t - 1.0) *
622 basegfx::B2DVector( getEnteringSlideSizePixel(rViewEntry.mpView) ) *
623 maEnteringDirection) );
626 void MovingSlideChange::performOut(
627 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
628 const ViewEntry& rViewEntry,
629 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
630 double t )
632 // outro sprite moves:
634 ENSURE_OR_THROW(
635 rSprite,
636 "MovingSlideChange::performOut(): Invalid sprite" );
637 ENSURE_OR_THROW(
638 rDestinationCanvas,
639 "MovingSlideChange::performOut(): Invalid dest canvas" );
641 // TODO(F1): This does not account for non-translational
642 // transformations! If the canvas is rotated, we still
643 // move the sprite unrotated (which might or might not
644 // produce the intended effect).
645 const basegfx::B2DHomMatrix aViewTransform(
646 rDestinationCanvas->getTransformation() );
647 const basegfx::B2DPoint aPageOrigin(
648 aViewTransform * basegfx::B2DPoint() );
650 // move sprite
651 rSprite->movePixel(
652 aPageOrigin + (t *
653 basegfx::B2DVector( getEnteringSlideSizePixel(rViewEntry.mpView) ) *
654 maLeavingDirection) );
658 NumberAnimationSharedPtr createPushWipeTransition(
659 std::optional<SlideSharedPtr> const & leavingSlide_,
660 const SlideSharedPtr& pEnteringSlide,
661 const UnoViewContainer& rViewContainer,
662 ScreenUpdater& rScreenUpdater,
663 EventMultiplexer& rEventMultiplexer,
664 sal_Int16 /*nTransitionType*/,
665 sal_Int16 nTransitionSubType,
666 bool /*bTransitionDirection*/,
667 const SoundPlayerSharedPtr& pSoundPlayer )
669 std::optional<SlideSharedPtr> leavingSlide; // no bitmap
670 if (leavingSlide_ && *leavingSlide_ != nullptr)
672 // opt: only page, if we've an
673 // actual slide to move out here. We
674 // _don't_ need a fake black background
675 // bitmap, neither for push nor for comb
676 // wipes.
677 leavingSlide = leavingSlide_;
680 // setup direction vector
681 bool bComb( false );
682 ::basegfx::B2DVector aDirection;
683 switch( nTransitionSubType )
685 default:
686 OSL_FAIL(
687 "createPushWipeTransition(): Unexpected transition "
688 "subtype for animations::TransitionType::PUSHWIPE "
689 "transitions" );
690 return NumberAnimationSharedPtr();
692 case animations::TransitionSubType::FROMTOP:
693 aDirection = ::basegfx::B2DVector( 0.0, 1.0 );
694 break;
696 case animations::TransitionSubType::FROMBOTTOM:
697 aDirection = ::basegfx::B2DVector( 0.0, -1.0 );
698 break;
700 case animations::TransitionSubType::FROMLEFT:
701 aDirection = ::basegfx::B2DVector( 1.0, 0.0 );
702 break;
704 case animations::TransitionSubType::FROMRIGHT:
705 aDirection = ::basegfx::B2DVector( -1.0, 0.0 );
706 break;
708 case animations::TransitionSubType::FROMBOTTOMRIGHT:
709 aDirection = ::basegfx::B2DVector( -1.0, -1.0 );
710 break;
712 case animations::TransitionSubType::FROMBOTTOMLEFT:
713 aDirection = ::basegfx::B2DVector( 1.0, -1.0 );
714 break;
716 case animations::TransitionSubType::FROMTOPRIGHT:
717 aDirection = ::basegfx::B2DVector( -1.0, 1.0 );
718 break;
720 case animations::TransitionSubType::FROMTOPLEFT:
721 aDirection = ::basegfx::B2DVector( 1.0, 1.0 );
722 break;
724 case animations::TransitionSubType::COMBHORIZONTAL:
725 aDirection = ::basegfx::B2DVector( 1.0, 0.0 );
726 bComb = true;
727 break;
729 case animations::TransitionSubType::COMBVERTICAL:
730 aDirection = ::basegfx::B2DVector( 0.0, 1.0 );
731 bComb = true;
732 break;
735 if( bComb )
737 return std::make_shared<CombTransition>( leavingSlide,
738 pEnteringSlide,
739 pSoundPlayer,
740 rViewContainer,
741 rScreenUpdater,
742 rEventMultiplexer,
743 aDirection,
744 24 /* comb with 12 stripes */ );
746 else
748 return std::make_shared<MovingSlideChange>( leavingSlide,
749 pEnteringSlide,
750 pSoundPlayer,
751 rViewContainer,
752 rScreenUpdater,
753 rEventMultiplexer,
754 aDirection,
755 aDirection );
759 NumberAnimationSharedPtr createSlideWipeTransition(
760 std::optional<SlideSharedPtr> const & leavingSlide,
761 const SlideSharedPtr& pEnteringSlide,
762 const UnoViewContainer& rViewContainer,
763 ScreenUpdater& rScreenUpdater,
764 EventMultiplexer& rEventMultiplexer,
765 sal_Int16 /*nTransitionType*/,
766 sal_Int16 nTransitionSubType,
767 bool bTransitionDirection,
768 const SoundPlayerSharedPtr& pSoundPlayer )
770 // setup 'in' direction vector
771 ::basegfx::B2DVector aInDirection;
772 switch( nTransitionSubType )
774 default:
775 OSL_FAIL(
776 "createSlideWipeTransition(): Unexpected transition "
777 "subtype for animations::TransitionType::SLIDEWIPE "
778 "transitions" );
779 return NumberAnimationSharedPtr();
781 case animations::TransitionSubType::FROMTOP:
782 aInDirection = ::basegfx::B2DVector( 0.0, 1.0 );
783 break;
785 case animations::TransitionSubType::FROMRIGHT:
786 aInDirection = ::basegfx::B2DVector( -1.0, 0.0 );
787 break;
789 case animations::TransitionSubType::FROMLEFT:
790 aInDirection = ::basegfx::B2DVector( 1.0, 0.0 );
791 break;
793 case animations::TransitionSubType::FROMBOTTOM:
794 aInDirection = ::basegfx::B2DVector( 0.0, -1.0 );
795 break;
797 case animations::TransitionSubType::FROMBOTTOMRIGHT:
798 aInDirection = ::basegfx::B2DVector( -1.0, -1.0 );
799 break;
801 case animations::TransitionSubType::FROMBOTTOMLEFT:
802 aInDirection = ::basegfx::B2DVector( 1.0, -1.0 );
803 break;
805 case animations::TransitionSubType::FROMTOPRIGHT:
806 aInDirection = ::basegfx::B2DVector( -1.0, 1.0 );
807 break;
809 case animations::TransitionSubType::FROMTOPLEFT:
810 aInDirection = ::basegfx::B2DVector( 1.0, 1.0 );
811 break;
814 if( bTransitionDirection )
816 // normal, 'forward' slide wipe effect. Since the old
817 // content is still on screen (and does not move), we omit
818 // the 'leaving' slide.
821 return std::make_shared<MovingSlideChange>(
822 std::optional<SlideSharedPtr>() /* no slide */,
823 pEnteringSlide,
824 pSoundPlayer,
825 rViewContainer,
826 rScreenUpdater,
827 rEventMultiplexer,
828 basegfx::B2DVector(),
829 aInDirection );
831 else
833 // 'reversed' slide wipe effect. Reverse for slide wipes
834 // means, that the new slide is in the back, statically,
835 // and the old one is moving off in the foreground.
838 return std::make_shared<MovingSlideChange>( leavingSlide,
839 pEnteringSlide,
840 pSoundPlayer,
841 rViewContainer,
842 rScreenUpdater,
843 rEventMultiplexer,
844 aInDirection,
845 basegfx::B2DVector() );
849 NumberAnimationSharedPtr createPluginTransition(
850 sal_Int16 nTransitionType,
851 sal_Int16 nTransitionSubType,
852 const RGBColor& rTransitionFadeColor,
853 std::optional<SlideSharedPtr> const& pLeavingSlide,
854 const SlideSharedPtr& pEnteringSlide,
855 const UnoViewContainer& rViewContainer,
856 ScreenUpdater& rScreenUpdater,
857 const uno::Reference<
858 presentation::XTransitionFactory>& xFactory,
859 const SoundPlayerSharedPtr& pSoundPlayer,
860 EventMultiplexer& rEventMultiplexer)
862 auto pTransition =
863 std::make_shared<PluginSlideChange>(
864 nTransitionType,
865 nTransitionSubType,
866 rTransitionFadeColor,
867 pLeavingSlide,
868 pEnteringSlide,
869 rViewContainer,
870 rScreenUpdater,
871 xFactory,
872 pSoundPlayer,
873 rEventMultiplexer );
875 if( !pTransition->Success() )
876 return nullptr;
877 return pTransition;
880 } // anon namespace
883 NumberAnimationSharedPtr TransitionFactory::createSlideTransition(
884 const SlideSharedPtr& pLeavingSlide,
885 const SlideSharedPtr& pEnteringSlide,
886 const UnoViewContainer& rViewContainer,
887 ScreenUpdater& rScreenUpdater,
888 EventMultiplexer& rEventMultiplexer,
889 const uno::Reference<presentation::XTransitionFactory>& xOptionalFactory,
890 sal_Int16 nTransitionType,
891 sal_Int16 nTransitionSubType,
892 bool bTransitionDirection,
893 const RGBColor& rTransitionFadeColor,
894 const SoundPlayerSharedPtr& pSoundPlayer )
896 // xxx todo: change to TransitionType::NONE, TransitionSubType::NONE:
897 if (nTransitionType == 0 && nTransitionSubType == 0) {
898 // just play sound, no slide transition:
899 if (pSoundPlayer) {
900 pSoundPlayer->startPlayback();
901 // xxx todo: for now, presentation.cxx takes care about the slide
902 // #i50492# transition sound object, so just release it here
904 return NumberAnimationSharedPtr();
907 ENSURE_OR_THROW(
908 pEnteringSlide,
909 "TransitionFactory::createSlideTransition(): Invalid entering slide" );
911 if( xOptionalFactory.is() &&
912 xOptionalFactory->hasTransition(nTransitionType, nTransitionSubType) )
914 // #i82460# - optional plugin factory claims this transition. delegate.
915 NumberAnimationSharedPtr pTransition(
916 createPluginTransition(
917 nTransitionType,
918 nTransitionSubType,
919 rTransitionFadeColor,
920 std::make_optional(pLeavingSlide),
921 pEnteringSlide,
922 rViewContainer,
923 rScreenUpdater,
924 xOptionalFactory,
925 pSoundPlayer,
926 rEventMultiplexer ));
928 if( pTransition )
929 return pTransition;
932 const TransitionInfo* pTransitionInfo(
933 getTransitionInfo( nTransitionType, nTransitionSubType ) );
935 if( pTransitionInfo != nullptr )
937 switch( pTransitionInfo->meTransitionClass )
939 default:
940 case TransitionInfo::TRANSITION_INVALID:
941 SAL_WARN("slideshow",
942 "TransitionFactory::createSlideTransition(): "
943 "Invalid type/subtype combination encountered."
944 << nTransitionType << " " << nTransitionSubType );
945 return NumberAnimationSharedPtr();
948 case TransitionInfo::TRANSITION_CLIP_POLYPOLYGON:
950 // generate parametric poly-polygon
951 ParametricPolyPolygonSharedPtr pPoly(
952 ParametricPolyPolygonFactory::createClipPolyPolygon(
953 nTransitionType, nTransitionSubType ) );
955 // create a clip transition from that
956 return std::make_shared<ClippedSlideChange>( pEnteringSlide,
957 pPoly,
958 *pTransitionInfo,
959 rViewContainer,
960 rScreenUpdater,
961 rEventMultiplexer,
962 bTransitionDirection,
963 pSoundPlayer );
966 case TransitionInfo::TRANSITION_SPECIAL:
968 switch( nTransitionType )
970 default:
971 OSL_FAIL(
972 "TransitionFactory::createSlideTransition(): "
973 "Unexpected transition type for "
974 "TRANSITION_SPECIAL transitions" );
975 return NumberAnimationSharedPtr();
977 case animations::TransitionType::RANDOM:
979 // select randomly one of the effects from the
980 // TransitionFactoryTable
982 const TransitionInfo* pRandomTransitionInfo(
983 getRandomTransitionInfo() );
985 ENSURE_OR_THROW(
986 pRandomTransitionInfo != nullptr,
987 "TransitionFactory::createSlideTransition(): "
988 "Got invalid random transition info" );
990 ENSURE_OR_THROW(
991 pRandomTransitionInfo->mnTransitionType !=
992 animations::TransitionType::RANDOM,
993 "TransitionFactory::createSlideTransition(): "
994 "Got random again for random input!" );
996 // and recurse
997 return createSlideTransition(
998 pLeavingSlide,
999 pEnteringSlide,
1000 rViewContainer,
1001 rScreenUpdater,
1002 rEventMultiplexer,
1003 xOptionalFactory,
1004 pRandomTransitionInfo->mnTransitionType,
1005 pRandomTransitionInfo->mnTransitionSubType,
1006 bTransitionDirection,
1007 rTransitionFadeColor,
1008 pSoundPlayer );
1011 case animations::TransitionType::PUSHWIPE:
1013 return createPushWipeTransition(
1014 std::make_optional(pLeavingSlide),
1015 pEnteringSlide,
1016 rViewContainer,
1017 rScreenUpdater,
1018 rEventMultiplexer,
1019 nTransitionType,
1020 nTransitionSubType,
1021 bTransitionDirection,
1022 pSoundPlayer );
1025 case animations::TransitionType::SLIDEWIPE:
1027 return createSlideWipeTransition(
1028 std::make_optional(pLeavingSlide),
1029 pEnteringSlide,
1030 rViewContainer,
1031 rScreenUpdater,
1032 rEventMultiplexer,
1033 nTransitionType,
1034 nTransitionSubType,
1035 bTransitionDirection,
1036 pSoundPlayer );
1039 case animations::TransitionType::BARWIPE:
1040 case animations::TransitionType::FADE:
1042 // black page:
1043 std::optional<SlideSharedPtr> leavingSlide;
1044 std::optional<RGBColor> aFadeColor;
1046 switch( nTransitionSubType )
1048 case animations::TransitionSubType::CROSSFADE:
1049 // crossfade needs no further setup,
1050 // just blend new slide over current
1051 // slide.
1052 break;
1054 // TODO(F1): Implement toColor/fromColor fades
1055 case animations::TransitionSubType::FADETOCOLOR:
1056 case animations::TransitionSubType::FADEFROMCOLOR:
1057 case animations::TransitionSubType::FADEOVERCOLOR:
1058 if (pLeavingSlide) {
1059 // only generate, if fade
1060 // effect really needs it.
1061 leavingSlide = pLeavingSlide;
1063 aFadeColor = rTransitionFadeColor;
1064 break;
1066 default:
1067 ENSURE_OR_THROW( false,
1068 "SlideTransitionFactory::createSlideTransition(): Unknown FADE subtype" );
1071 if( nTransitionType == animations::TransitionType::FADE )
1072 return std::make_shared<FadingSlideChange>(
1073 leavingSlide,
1074 pEnteringSlide,
1075 aFadeColor,
1076 pSoundPlayer,
1077 rViewContainer,
1078 rScreenUpdater,
1079 rEventMultiplexer );
1080 else
1081 return std::make_shared<CutSlideChange>(
1082 leavingSlide,
1083 pEnteringSlide,
1084 rTransitionFadeColor,
1085 pSoundPlayer,
1086 rViewContainer,
1087 rScreenUpdater,
1088 rEventMultiplexer );
1092 break;
1096 // No animation generated, maybe no table entry for given
1097 // transition?
1098 SAL_WARN("slideshow",
1099 "TransitionFactory::createSlideTransition(): "
1100 "Unknown type/subtype combination encountered "
1101 << nTransitionType << " " << nTransitionSubType );
1102 OSL_FAIL(
1103 "TransitionFactory::createSlideTransition(): "
1104 "Unknown type/subtype combination encountered" );
1106 return NumberAnimationSharedPtr();
1109 } // namespace presentation
1111 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */