LibreOffice Module slideshow (master) 1
slidetransitionfactory.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
21#include <sal/log.hxx>
22
24
26
27#include <com/sun/star/animations/TransitionType.hpp>
28#include <com/sun/star/animations/TransitionSubType.hpp>
29
30#include "slidechangebase.hxx"
31#include <transitionfactory.hxx>
34#include "clippingfunctor.hxx"
35#include "combtransition.hxx"
36#include <tools.hxx>
37#include <memory>
38#include <utility>
39
40
41/***************************************************
42 *** ***
43 *** Slide Transition Effects ***
44 *** ***
45 ***************************************************/
46
47using namespace com::sun::star;
48
49namespace slideshow::internal {
50
51namespace {
52
53// helper methods
54// =============================================
55
56void fillPage( const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
57 const ::basegfx::B2DSize& rPageSizePixel,
58 const RGBColor& rFillColor )
59{
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() );
65
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() );
72
73 fillRect( pDevicePixelCanvas,
75 aOutputPosPixel.getX(),
76 aOutputPosPixel.getY(),
77 aOutputPosPixel.getX() + rPageSizePixel.getWidth(),
78 aOutputPosPixel.getY() + rPageSizePixel.getHeight() ),
79 rFillColor.getIntegerColor() );
80}
81
82class PluginSlideChange: public SlideChangeBase
83{
84 struct TransitionViewPair {
85 uno::Reference<presentation::XTransition> mxTransition;
87
88 TransitionViewPair( uno::Reference<presentation::XTransition> xTransition, UnoViewSharedPtr xView )
89 : mxTransition(std::move(xTransition)), mpView(std::move(xView))
90 {
91 }
92
93 ~TransitionViewPair()
94 {
95 mxTransition.clear();
96 mpView.reset();
97 }
98
99 void update( double t )
100 {
101 mxTransition->update( t );
102 }
103 };
104
105public:
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 ),
128 mbSuccess( false ),
129 mnTransitionType( nTransitionType ),
130 mnTransitionSubType( nTransitionSubType ),
131 mnTransitionFadeColor( rTransitionFadeColor ),
132 mxFactory(std::move( xFactory ))
133 {
134 // create one transition per view
135 for( const auto& rView : rViewContainer )
136 {
137 if( !addTransition( rView ) )
138 return;
139
140 ENSURE_OR_THROW(maTransitions.back() && maTransitions.back()->mxTransition.is(),
141 "Failed to create plugin transition");
142 }
143 mbSuccess = true;
144 }
145
146 virtual ~PluginSlideChange() override
147 {
148 mxFactory.clear();
149 }
150
151 bool addTransition( const UnoViewSharedPtr& rView )
152 {
153 uno::Reference<presentation::XTransition> rTransition = mxFactory->createTransition(
156 RGBAColor2UnoColor( mnTransitionFadeColor.getIntegerColor()),
157 rView->getUnoView(),
158 getLeavingBitmap(ViewEntry(rView))->getXBitmap(),
159 getEnteringBitmap(ViewEntry(rView))->getXBitmap() );
160
161 if( rTransition.is() )
162 maTransitions.emplace_back( new TransitionViewPair( rTransition, rView ) );
163 else
164 return false;
165
166 return true;
167 }
168
169 virtual bool operator()( double t ) override
170 {
171 for( const auto& pTransition : maTransitions )
172 pTransition->update( t );
173 return true;
174 }
175
176 bool Success()
177 {
178 return mbSuccess;
179 }
180
181 // ViewEventHandler
182 virtual void viewAdded( const UnoViewSharedPtr& rView ) override
183 {
184 SAL_INFO("slideshow", "PluginSlideChange viewAdded");
186
187 for( const auto& pCurrView : maTransitions )
188 {
189 if( pCurrView->mpView == rView )
190 return;
191 }
192
193 SAL_INFO("slideshow", "need to be added" );
194 addTransition( rView );
195 }
196
197 virtual void viewRemoved( const UnoViewSharedPtr& rView ) override
198 {
199 SAL_INFO("slideshow", "PluginSlideChange viewRemoved");
201
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())
205 {
206 SAL_INFO("slideshow", "view removed" );
207 maTransitions.erase( aIter );
208 }
209 }
210
211 virtual void viewChanged( const UnoViewSharedPtr& rView ) override
212 {
213 SAL_INFO("slideshow", "PluginSlideChange viewChanged");
215
216 for( const auto& pCurrView : maTransitions )
217 {
218 if( pCurrView->mpView == rView )
219 {
220 SAL_INFO("slideshow", "view changed" );
221 pCurrView->mxTransition->viewChanged( rView->getUnoView(),
222 getLeavingBitmap(ViewEntry(rView))->getXBitmap(),
223 getEnteringBitmap(ViewEntry(rView))->getXBitmap() );
224 }
225 else
226 SAL_INFO("slideshow", "view did not change" );
227 }
228 }
229
230 virtual void viewsChanged() override
231 {
232 SAL_INFO("slideshow", "PluginSlideChange viewsChanged");
234
235 for( const auto& pCurrView : maTransitions )
236 {
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() );
242 }
243 }
244
245private:
246 // One transition object per view
247 std::vector< std::unique_ptr<TransitionViewPair> > maTransitions;
248
249 // bool
251
255
256 uno::Reference<presentation::XTransitionFactory> mxFactory;
257};
258
259class ClippedSlideChange : public SlideChangeBase
260{
261public:
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 )
288 {}
289
290 virtual void performIn(
291 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
292 const ViewEntry& rViewEntry,
293 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
294 double t ) override;
295
296 virtual void performOut(
297 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
298 const ViewEntry& rViewEntry,
299 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
300 double t ) override;
301
302private:
303 ClippingFunctor maClippingFunctor;
304};
305
306void ClippedSlideChange::performIn(
307 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
308 const ViewEntry& rViewEntry,
309 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
310 double t )
311{
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(
319 ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) ) );
320}
321
322void ClippedSlideChange::performOut(
323 const ::cppcanvas::CustomSpriteSharedPtr& /*rSprite*/,
324 const ViewEntry& /*rViewEntry*/,
325 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
326 double /*t*/ )
327{
328 // not needed here
329}
330
331
332class FadingSlideChange : public SlideChangeBase
333{
334public:
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 )
353 {}
354
355 virtual void prepareForRun(
356 const ViewEntry& rViewEntry,
357 const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) override;
358
359 virtual void performIn(
360 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
361 const ViewEntry& rViewEntry,
362 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
363 double t ) override;
364
365 virtual void performOut(
366 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
367 const ViewEntry& rViewEntry,
368 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
369 double t ) override;
370
371private:
372 const std::optional< RGBColor > maFadeColor;
373};
374
375void FadingSlideChange::prepareForRun(
376 const ViewEntry& rViewEntry,
377 const cppcanvas::CanvasSharedPtr& rDestinationCanvas )
378{
379 if ( maFadeColor )
380 {
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 );
386 }
387}
388
389void FadingSlideChange::performIn(
390 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
391 const ViewEntry& /*rViewEntry*/,
392 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
393 double t )
394{
396 rSprite,
397 "FadingSlideChange::performIn(): Invalid sprite" );
398
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 );
405}
406
407void FadingSlideChange::performOut(
408 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
409 const ViewEntry& /* rViewEntry */,
410 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
411 double t )
412{
414 rSprite,
415 "FadingSlideChange::performOut(): Invalid sprite" );
417 rDestinationCanvas,
418 "FadingSlideChange::performOut(): Invalid dest canvas" );
419
420 // only needed for color fades
421 if( maFadeColor )
422 {
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) );
427 }
428}
429
430class CutSlideChange : public SlideChangeBase
431{
432public:
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 )
451 {}
452
453 virtual void prepareForRun(
454 const ViewEntry& rViewEntry,
455 const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) override;
456
457 virtual void performIn(
458 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
459 const ViewEntry& rViewEntry,
460 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
461 double t ) override;
462
463 virtual void performOut(
464 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
465 const ViewEntry& rViewEntry,
466 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
467 double t ) override;
468
469private:
470 RGBColor maFadeColor;
471};
472
473void CutSlideChange::prepareForRun(
474 const ViewEntry& rViewEntry,
475 const cppcanvas::CanvasSharedPtr& rDestinationCanvas )
476{
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 );
482}
483
484void CutSlideChange::performIn(
485 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
486 const ViewEntry& /*rViewEntry*/,
487 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
488 double t )
489{
491 rSprite,
492 "CutSlideChange::performIn(): Invalid sprite" );
493
494 // After 2/3rd of the active time, display new slide
495 rSprite->setAlpha( t > 2/3.0 ? 1.0 : 0.0 );
496}
497
498void CutSlideChange::performOut(
499 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
500 const ViewEntry& /* rViewEntry */,
501 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
502 double t )
503{
505 rSprite,
506 "CutSlideChange::performOut(): Invalid sprite" );
508 rDestinationCanvas,
509 "CutSlideChange::performOut(): Invalid dest canvas" );
510
511 // Until 1/3rd of the active time, display old slide.
512 rSprite->setAlpha( t > 1/3.0 ? 0.0 : 1.0 );
513}
514
515class MovingSlideChange : public SlideChangeBase
516{
518 const ::basegfx::B2DVector maLeavingDirection;
519
521 const ::basegfx::B2DVector maEnteringDirection;
522
523public:
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 )
565 {}
566
567 virtual void prepareForRun(
568 const ViewEntry& rViewEntry,
569 const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) override;
570
571 virtual void performIn(
572 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
573 const ViewEntry& rViewEntry,
574 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
575 double t ) override;
576
577 virtual void performOut(
578 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
579 const ViewEntry& rViewEntry,
580 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
581 double t ) override;
582};
583
584void MovingSlideChange::prepareForRun(
585 const ViewEntry& rViewEntry,
586 const cppcanvas::CanvasSharedPtr& rDestinationCanvas )
587{
589 renderBitmap( getLeavingBitmap( rViewEntry ), rDestinationCanvas );
590 else if ( maEnteringDirection.equalZero() )
591 renderBitmap( getEnteringBitmap( rViewEntry ), rDestinationCanvas );
592}
593
594void MovingSlideChange::performIn(
595 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
596 const ViewEntry& rViewEntry,
597 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
598 double t )
599{
600 // intro sprite moves:
601
603 rSprite,
604 "MovingSlideChange::performIn(): Invalid sprite" );
606 rDestinationCanvas,
607 "MovingSlideChange::performIn(): Invalid dest canvas" );
608
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() );
617
618 // move sprite
619 auto aSlideSizePixel = getEnteringSlideSizePixel(rViewEntry.mpView);
620 rSprite->movePixel(
621 aPageOrigin +
622 ((t - 1.0) *
623 basegfx::B2DVector( aSlideSizePixel.getWidth(), aSlideSizePixel.getHeight()) *
625}
626
627void MovingSlideChange::performOut(
628 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
629 const ViewEntry& rViewEntry,
630 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
631 double t )
632{
633 // outro sprite moves:
634
636 rSprite,
637 "MovingSlideChange::performOut(): Invalid sprite" );
639 rDestinationCanvas,
640 "MovingSlideChange::performOut(): Invalid dest canvas" );
641
642 // TODO(F1): This does not account for non-translational
643 // transformations! If the canvas is rotated, we still
644 // move the sprite unrotated (which might or might not
645 // produce the intended effect).
646 const basegfx::B2DHomMatrix aViewTransform(
647 rDestinationCanvas->getTransformation() );
648 const basegfx::B2DPoint aPageOrigin(
649 aViewTransform * basegfx::B2DPoint() );
650
651 // move sprite
652 auto aSlideSizePixel = getEnteringSlideSizePixel(rViewEntry.mpView);
653 rSprite->movePixel(
654 aPageOrigin + (t *
655 basegfx::B2DVector(aSlideSizePixel.getWidth(), aSlideSizePixel.getHeight()) *
657}
658
659
660NumberAnimationSharedPtr createPushWipeTransition(
661 std::optional<SlideSharedPtr> const & leavingSlide_,
662 const SlideSharedPtr& pEnteringSlide,
663 const UnoViewContainer& rViewContainer,
664 ScreenUpdater& rScreenUpdater,
665 EventMultiplexer& rEventMultiplexer,
666 sal_Int16 /*nTransitionType*/,
667 sal_Int16 nTransitionSubType,
668 bool /*bTransitionDirection*/,
669 const SoundPlayerSharedPtr& pSoundPlayer )
670{
671 std::optional<SlideSharedPtr> leavingSlide; // no bitmap
672 if (leavingSlide_ && *leavingSlide_ != nullptr)
673 {
674 // opt: only page, if we've an
675 // actual slide to move out here. We
676 // _don't_ need a fake black background
677 // bitmap, neither for push nor for comb
678 // wipes.
679 leavingSlide = leavingSlide_;
680 }
681
682 // setup direction vector
683 bool bComb( false );
685 switch( nTransitionSubType )
686 {
687 default:
688 OSL_FAIL(
689 "createPushWipeTransition(): Unexpected transition "
690 "subtype for animations::TransitionType::PUSHWIPE "
691 "transitions" );
693
694 case animations::TransitionSubType::FROMTOP:
695 aDirection = ::basegfx::B2DVector( 0.0, 1.0 );
696 break;
697
698 case animations::TransitionSubType::FROMBOTTOM:
699 aDirection = ::basegfx::B2DVector( 0.0, -1.0 );
700 break;
701
702 case animations::TransitionSubType::FROMLEFT:
703 aDirection = ::basegfx::B2DVector( 1.0, 0.0 );
704 break;
705
706 case animations::TransitionSubType::FROMRIGHT:
707 aDirection = ::basegfx::B2DVector( -1.0, 0.0 );
708 break;
709
710 case animations::TransitionSubType::FROMBOTTOMRIGHT:
711 aDirection = ::basegfx::B2DVector( -1.0, -1.0 );
712 break;
713
714 case animations::TransitionSubType::FROMBOTTOMLEFT:
715 aDirection = ::basegfx::B2DVector( 1.0, -1.0 );
716 break;
717
718 case animations::TransitionSubType::FROMTOPRIGHT:
719 aDirection = ::basegfx::B2DVector( -1.0, 1.0 );
720 break;
721
722 case animations::TransitionSubType::FROMTOPLEFT:
723 aDirection = ::basegfx::B2DVector( 1.0, 1.0 );
724 break;
725
726 case animations::TransitionSubType::COMBHORIZONTAL:
727 aDirection = ::basegfx::B2DVector( 1.0, 0.0 );
728 bComb = true;
729 break;
730
731 case animations::TransitionSubType::COMBVERTICAL:
732 aDirection = ::basegfx::B2DVector( 0.0, 1.0 );
733 bComb = true;
734 break;
735 }
736
737 if( bComb )
738 {
739 return std::make_shared<CombTransition>( leavingSlide,
740 pEnteringSlide,
741 pSoundPlayer,
742 rViewContainer,
743 rScreenUpdater,
744 rEventMultiplexer,
745 aDirection,
746 24 /* comb with 12 stripes */ );
747 }
748 else
749 {
750 return std::make_shared<MovingSlideChange>( leavingSlide,
751 pEnteringSlide,
752 pSoundPlayer,
753 rViewContainer,
754 rScreenUpdater,
755 rEventMultiplexer,
756 aDirection,
757 aDirection );
758 }
759}
760
761NumberAnimationSharedPtr createSlideWipeTransition(
762 std::optional<SlideSharedPtr> const & leavingSlide,
763 const SlideSharedPtr& pEnteringSlide,
764 const UnoViewContainer& rViewContainer,
765 ScreenUpdater& rScreenUpdater,
766 EventMultiplexer& rEventMultiplexer,
767 sal_Int16 /*nTransitionType*/,
768 sal_Int16 nTransitionSubType,
769 bool bTransitionDirection,
770 const SoundPlayerSharedPtr& pSoundPlayer )
771{
772 // setup 'in' direction vector
773 ::basegfx::B2DVector aInDirection;
774 switch( nTransitionSubType )
775 {
776 default:
777 OSL_FAIL(
778 "createSlideWipeTransition(): Unexpected transition "
779 "subtype for animations::TransitionType::SLIDEWIPE "
780 "transitions" );
782
783 case animations::TransitionSubType::FROMTOP:
784 aInDirection = ::basegfx::B2DVector( 0.0, 1.0 );
785 break;
786
787 case animations::TransitionSubType::FROMRIGHT:
788 aInDirection = ::basegfx::B2DVector( -1.0, 0.0 );
789 break;
790
791 case animations::TransitionSubType::FROMLEFT:
792 aInDirection = ::basegfx::B2DVector( 1.0, 0.0 );
793 break;
794
795 case animations::TransitionSubType::FROMBOTTOM:
796 aInDirection = ::basegfx::B2DVector( 0.0, -1.0 );
797 break;
798
799 case animations::TransitionSubType::FROMBOTTOMRIGHT:
800 aInDirection = ::basegfx::B2DVector( -1.0, -1.0 );
801 break;
802
803 case animations::TransitionSubType::FROMBOTTOMLEFT:
804 aInDirection = ::basegfx::B2DVector( 1.0, -1.0 );
805 break;
806
807 case animations::TransitionSubType::FROMTOPRIGHT:
808 aInDirection = ::basegfx::B2DVector( -1.0, 1.0 );
809 break;
810
811 case animations::TransitionSubType::FROMTOPLEFT:
812 aInDirection = ::basegfx::B2DVector( 1.0, 1.0 );
813 break;
814 }
815
816 if( bTransitionDirection )
817 {
818 // normal, 'forward' slide wipe effect. Since the old
819 // content is still on screen (and does not move), we omit
820 // the 'leaving' slide.
821
822
823 return std::make_shared<MovingSlideChange>(
824 std::optional<SlideSharedPtr>() /* no slide */,
825 pEnteringSlide,
826 pSoundPlayer,
827 rViewContainer,
828 rScreenUpdater,
829 rEventMultiplexer,
831 aInDirection );
832 }
833 else
834 {
835 // 'reversed' slide wipe effect. Reverse for slide wipes
836 // means, that the new slide is in the back, statically,
837 // and the old one is moving off in the foreground.
838
839
840 return std::make_shared<MovingSlideChange>( leavingSlide,
841 pEnteringSlide,
842 pSoundPlayer,
843 rViewContainer,
844 rScreenUpdater,
845 rEventMultiplexer,
846 aInDirection,
848 }
849}
850
851NumberAnimationSharedPtr createPluginTransition(
852 sal_Int16 nTransitionType,
853 sal_Int16 nTransitionSubType,
854 const RGBColor& rTransitionFadeColor,
855 std::optional<SlideSharedPtr> const& pLeavingSlide,
856 const SlideSharedPtr& pEnteringSlide,
857 const UnoViewContainer& rViewContainer,
858 ScreenUpdater& rScreenUpdater,
859 const uno::Reference<
860 presentation::XTransitionFactory>& xFactory,
861 const SoundPlayerSharedPtr& pSoundPlayer,
862 EventMultiplexer& rEventMultiplexer)
863{
864 auto pTransition =
865 std::make_shared<PluginSlideChange>(
866 nTransitionType,
867 nTransitionSubType,
868 rTransitionFadeColor,
869 pLeavingSlide,
870 pEnteringSlide,
871 rViewContainer,
872 rScreenUpdater,
873 xFactory,
874 pSoundPlayer,
875 rEventMultiplexer );
876
877 if( !pTransition->Success() )
878 return nullptr;
879 return pTransition;
880}
881
882} // anon namespace
883
884
886 const SlideSharedPtr& pLeavingSlide,
887 const SlideSharedPtr& pEnteringSlide,
888 const UnoViewContainer& rViewContainer,
889 ScreenUpdater& rScreenUpdater,
890 EventMultiplexer& rEventMultiplexer,
891 const uno::Reference<presentation::XTransitionFactory>& xOptionalFactory,
892 sal_Int16 nTransitionType,
893 sal_Int16 nTransitionSubType,
894 bool bTransitionDirection,
895 const RGBColor& rTransitionFadeColor,
896 const SoundPlayerSharedPtr& pSoundPlayer )
897{
898 // xxx todo: change to TransitionType::NONE, TransitionSubType::NONE:
899 if (nTransitionType == 0 && nTransitionSubType == 0) {
900 // just play sound, no slide transition:
901 if (pSoundPlayer) {
902 pSoundPlayer->startPlayback();
903 // xxx todo: for now, presentation.cxx takes care about the slide
904 // #i50492# transition sound object, so just release it here
905 }
907 }
908
910 pEnteringSlide,
911 "TransitionFactory::createSlideTransition(): Invalid entering slide" );
912
913 if( xOptionalFactory.is() &&
914 xOptionalFactory->hasTransition(nTransitionType, nTransitionSubType) )
915 {
916 // #i82460# - optional plugin factory claims this transition. delegate.
917 NumberAnimationSharedPtr pTransition(
918 createPluginTransition(
919 nTransitionType,
920 nTransitionSubType,
921 rTransitionFadeColor,
922 std::make_optional(pLeavingSlide),
923 pEnteringSlide,
924 rViewContainer,
925 rScreenUpdater,
926 xOptionalFactory,
927 pSoundPlayer,
928 rEventMultiplexer ));
929
930 if( pTransition )
931 return pTransition;
932 }
933
934 const TransitionInfo* pTransitionInfo(
935 getTransitionInfo( nTransitionType, nTransitionSubType ) );
936
937 if( pTransitionInfo != nullptr )
938 {
939 switch( pTransitionInfo->meTransitionClass )
940 {
941 default:
943 SAL_WARN("slideshow",
944 "TransitionFactory::createSlideTransition(): "
945 "Invalid type/subtype combination encountered."
946 << nTransitionType << " " << nTransitionSubType );
948
949
951 {
952 // generate parametric poly-polygon
955 nTransitionType, nTransitionSubType ) );
956
957 // create a clip transition from that
958 return std::make_shared<ClippedSlideChange>( pEnteringSlide,
959 pPoly,
960 *pTransitionInfo,
961 rViewContainer,
962 rScreenUpdater,
963 rEventMultiplexer,
964 bTransitionDirection,
965 pSoundPlayer );
966 }
967
969 {
970 switch( nTransitionType )
971 {
972 default:
973 OSL_FAIL(
974 "TransitionFactory::createSlideTransition(): "
975 "Unexpected transition type for "
976 "TRANSITION_SPECIAL transitions" );
978
979 case animations::TransitionType::RANDOM:
980 {
981 // select randomly one of the effects from the
982 // TransitionFactoryTable
983
984 const TransitionInfo* pRandomTransitionInfo(
986
988 pRandomTransitionInfo != nullptr,
989 "TransitionFactory::createSlideTransition(): "
990 "Got invalid random transition info" );
991
993 pRandomTransitionInfo->mnTransitionType !=
994 animations::TransitionType::RANDOM,
995 "TransitionFactory::createSlideTransition(): "
996 "Got random again for random input!" );
997
998 // and recurse
1000 pLeavingSlide,
1001 pEnteringSlide,
1002 rViewContainer,
1003 rScreenUpdater,
1004 rEventMultiplexer,
1005 xOptionalFactory,
1006 pRandomTransitionInfo->mnTransitionType,
1007 pRandomTransitionInfo->mnTransitionSubType,
1008 bTransitionDirection,
1009 rTransitionFadeColor,
1010 pSoundPlayer );
1011 }
1012
1013 case animations::TransitionType::PUSHWIPE:
1014 {
1015 return createPushWipeTransition(
1016 std::make_optional(pLeavingSlide),
1017 pEnteringSlide,
1018 rViewContainer,
1019 rScreenUpdater,
1020 rEventMultiplexer,
1021 nTransitionType,
1022 nTransitionSubType,
1023 bTransitionDirection,
1024 pSoundPlayer );
1025 }
1026
1027 case animations::TransitionType::SLIDEWIPE:
1028 {
1029 return createSlideWipeTransition(
1030 std::make_optional(pLeavingSlide),
1031 pEnteringSlide,
1032 rViewContainer,
1033 rScreenUpdater,
1034 rEventMultiplexer,
1035 nTransitionType,
1036 nTransitionSubType,
1037 bTransitionDirection,
1038 pSoundPlayer );
1039 }
1040
1041 case animations::TransitionType::BARWIPE:
1042 case animations::TransitionType::FADE:
1043 {
1044 // black page:
1045 std::optional<SlideSharedPtr> leavingSlide;
1046 std::optional<RGBColor> aFadeColor;
1047
1048 switch( nTransitionSubType )
1049 {
1050 case animations::TransitionSubType::CROSSFADE:
1051 // crossfade needs no further setup,
1052 // just blend new slide over current
1053 // slide.
1054 break;
1055
1056 // TODO(F1): Implement toColor/fromColor fades
1057 case animations::TransitionSubType::FADETOCOLOR:
1058 case animations::TransitionSubType::FADEFROMCOLOR:
1059 case animations::TransitionSubType::FADEOVERCOLOR:
1060 if (pLeavingSlide) {
1061 // only generate, if fade
1062 // effect really needs it.
1063 leavingSlide = pLeavingSlide;
1064 }
1065 aFadeColor = rTransitionFadeColor;
1066 break;
1067
1068 default:
1069 ENSURE_OR_THROW( false,
1070 "SlideTransitionFactory::createSlideTransition(): Unknown FADE subtype" );
1071 }
1072
1073 if( nTransitionType == animations::TransitionType::FADE )
1074 return std::make_shared<FadingSlideChange>(
1075 leavingSlide,
1076 pEnteringSlide,
1077 aFadeColor,
1078 pSoundPlayer,
1079 rViewContainer,
1080 rScreenUpdater,
1081 rEventMultiplexer );
1082 else
1083 return std::make_shared<CutSlideChange>(
1084 leavingSlide,
1085 pEnteringSlide,
1086 rTransitionFadeColor,
1087 pSoundPlayer,
1088 rViewContainer,
1089 rScreenUpdater,
1090 rEventMultiplexer );
1091 }
1092 }
1093 }
1094 break;
1095 }
1096 }
1097
1098 // No animation generated, maybe no table entry for given
1099 // transition?
1100 SAL_WARN("slideshow",
1101 "TransitionFactory::createSlideTransition(): "
1102 "Unknown type/subtype combination encountered "
1103 << nTransitionType << " " << nTransitionSubType );
1104 OSL_FAIL(
1105 "TransitionFactory::createSlideTransition(): "
1106 "Unknown type/subtype combination encountered" );
1107
1108 return NumberAnimationSharedPtr();
1109}
1110
1111} // namespace presentation
1112
1113/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XPropertyListType t
bool equalZero() const
virtual void viewRemoved(const UnoViewSharedPtr &rView) override
Notify removed view.
virtual void viewAdded(const UnoViewSharedPtr &rView) override
Notify new view.
virtual void viewChanged(const UnoViewSharedPtr &rView) override
Notify changed view.
virtual void viewsChanged() override
Notify that all views changed.
#define ENSURE_OR_THROW(c, m)
Reference< XSingleServiceFactory > xFactory
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
bool equalZero(const T &rfVal)
std::shared_ptr< Canvas > CanvasSharedPtr
ParametricPolyPolygonSharedPtr createClipPolyPolygon(sal_Int16 nTransitionType, sal_Int16 nTransitionSubType)
NumberAnimationSharedPtr createSlideTransition(const SlideSharedPtr &rLeavingSlide, const SlideSharedPtr &rEnteringSlide, const UnoViewContainer &rViewContainer, ScreenUpdater &rScreenUpdater, EventMultiplexer &rEventMultiplexer, const css::uno::Reference< css::presentation::XTransitionFactory > &xOptionalFactory, sal_Int16 nTransitionType, sal_Int16 nTransitionSubType, bool bTransitionDirection, const RGBColor &rTransitionFadeColor, const SoundPlayerSharedPtr &rSoundPlayer)
Create a transition effect for slides.
::std::shared_ptr< NumberAnimation > NumberAnimationSharedPtr
sal_Int32 RGBAColor2UnoColor(::cppcanvas::IntSRGBA aColor)
Definition: tools.cxx:646
::std::shared_ptr< SoundPlayer > SoundPlayerSharedPtr
const TransitionInfo * getRandomTransitionInfo()
const TransitionInfo * getTransitionInfo(sal_Int16 nTransitionType, sal_Int16 nTransitionSubType)
void fillRect(const ::cppcanvas::CanvasSharedPtr &rCanvas, const ::basegfx::B2DRectangle &rRect, ::cppcanvas::IntSRGBA aFillColor)
Definition: tools.cxx:657
::std::shared_ptr< Slide > SlideSharedPtr
Definition: slide.hxx:148
std::shared_ptr< UnoView > UnoViewSharedPtr
::std::shared_ptr< ParametricPolyPolygon > ParametricPolyPolygonSharedPtr
ClippingFunctor maClippingFunctor
UnoViewSharedPtr mpView
sal_Int16 mnTransitionType
const std::optional< RGBColor > maFadeColor
std::vector< std::unique_ptr< TransitionViewPair > > maTransitions
uno::Reference< presentation::XTransitionFactory > mxFactory
uno::Reference< presentation::XTransition > mxTransition
const ::basegfx::B2DVector maEnteringDirection
Direction vector for entering slide,.
bool mbSuccess
RGBColor mnTransitionFadeColor
sal_Int16 mnTransitionSubType
const ::basegfx::B2DVector maLeavingDirection
Direction vector for leaving slide,.
@ TRANSITION_SPECIAL
Transition expressed by hand-crafted function.
@ TRANSITION_CLIP_POLYPOLYGON
Transition expressed by parametric clip polygon.
css::drawing::Direction3D aDirection
bool update()