merge the formfield patch from ooo-build
[ooovba.git] / slideshow / source / engine / transitions / slidetransitionfactory.cxx
blob45a1f0e8affad2f97fb4ffb6cc053b6907908bf0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: slidetransitionfactory.cxx,v $
10 * $Revision: 1.17 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
34 #include <canvas/debug.hxx>
35 #include <tools/diagnose_ex.h>
37 #include <basegfx/matrix/b2dhommatrix.hxx>
38 #include <basegfx/tools/canvastools.hxx>
39 #include <basegfx/polygon/b2dpolygontools.hxx>
40 #include <basegfx/polygon/b2dpolypolygontools.hxx>
42 #include <cppcanvas/basegfxfactory.hxx>
44 #include <comphelper/optional.hxx>
45 #include <comphelper/make_shared_from_uno.hxx>
47 #include <com/sun/star/rendering/XIntegerBitmap.hpp>
48 #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
49 #include <com/sun/star/animations/TransitionType.hpp>
50 #include <com/sun/star/animations/TransitionSubType.hpp>
51 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
53 #include "slidechangebase.hxx"
54 #include "transitionfactory.hxx"
55 #include "transitiontools.hxx"
56 #include "parametricpolypolygonfactory.hxx"
57 #include "animationfactory.hxx"
58 #include "clippingfunctor.hxx"
59 #include "combtransition.hxx"
60 #include "tools.hxx"
62 #include <boost/bind.hpp>
65 /***************************************************
66 *** ***
67 *** Slide Transition Effects ***
68 *** ***
69 ***************************************************/
71 using namespace com::sun::star;
73 namespace slideshow {
74 namespace internal {
76 namespace {
78 // helper methods
79 // =============================================
81 void fillPage( const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
82 const ::basegfx::B2DSize& rPageSizePixel,
83 const RGBColor& rFillColor )
85 // need to render without any transformation (we
86 // assume rPageSizePixel to represent device units)
87 const ::cppcanvas::CanvasSharedPtr pDevicePixelCanvas(
88 rDestinationCanvas->clone() );
89 pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
91 // TODO(F2): Properly respect clip here.
92 // Might have to be transformed, too.
93 const ::basegfx::B2DHomMatrix aViewTransform(
94 rDestinationCanvas->getTransformation() );
95 const ::basegfx::B2DPoint aOutputPosPixel(
96 aViewTransform * ::basegfx::B2DPoint() );
98 fillRect( pDevicePixelCanvas,
99 ::basegfx::B2DRectangle(
100 aOutputPosPixel.getX(),
101 aOutputPosPixel.getY(),
102 aOutputPosPixel.getX() + rPageSizePixel.getX(),
103 aOutputPosPixel.getY() + rPageSizePixel.getY() ),
104 rFillColor.getIntegerColor() );
107 class PluginSlideChange: public SlideChangeBase
109 struct TransitionViewPair {
110 uno::Reference<presentation::XTransition> mxTransition;
111 UnoViewSharedPtr mpView;
113 TransitionViewPair( uno::Reference<presentation::XTransition> xTransition, const UnoViewSharedPtr pView )
115 mxTransition = xTransition;
116 mpView = pView;
119 ~TransitionViewPair()
121 mxTransition.clear();
122 mpView.reset();;
125 void update( double t )
127 mxTransition->update( t );
131 public:
132 /** Create a new SlideChanger, for the given leaving and
133 entering slide bitmaps, which uses super secret OpenGL
134 stuff.
136 PluginSlideChange( sal_Int16 nTransitionType,
137 sal_Int16 nTransitionSubType,
138 boost::optional<SlideSharedPtr> const& leavingSlide_,
139 const SlideSharedPtr& pEnteringSlide,
140 const UnoViewContainer& rViewContainer,
141 ScreenUpdater& rScreenUpdater,
142 const uno::Reference<
143 presentation::XTransitionFactory>& xFactory,
144 const SoundPlayerSharedPtr& pSoundPlayer,
145 EventMultiplexer& rEventMultiplexer) :
146 SlideChangeBase( leavingSlide_,
147 pEnteringSlide,
148 pSoundPlayer,
149 rViewContainer,
150 rScreenUpdater,
151 rEventMultiplexer ),
152 maTransitions(),
153 mbSuccess( false ),
154 mnTransitionType( nTransitionType ),
155 mnTransitionSubType( nTransitionSubType ),
156 mxFactory( xFactory )
158 // create one transition per view
159 UnoViewVector::const_iterator aCurrView (rViewContainer.begin());
160 const UnoViewVector::const_iterator aEnd(rViewContainer.end());
161 while( aCurrView != aEnd )
163 if(! addTransition( *aCurrView ) )
164 return;
166 ENSURE_OR_THROW(maTransitions.back() && maTransitions.back()->mxTransition.is(),
167 "Failed to create plugin transition");
168 ++aCurrView;
170 mbSuccess = true;
173 ~PluginSlideChange()
175 mxFactory.clear();
177 ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
178 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
179 while( aCurrView != aEnd )
181 delete (*aCurrView);
182 ++aCurrView;
184 maTransitions.clear();
187 bool addTransition( const UnoViewSharedPtr& rView )
189 uno::Reference<presentation::XTransition> rTransition = mxFactory->createTransition(
190 mnTransitionType,
191 mnTransitionSubType,
192 rView->getUnoView(),
193 getLeavingBitmap(ViewEntry(rView))->getXBitmap(),
194 getEnteringBitmap(ViewEntry(rView))->getXBitmap() );
196 if( rTransition.is() )
197 maTransitions.push_back( new TransitionViewPair( rTransition, rView ) );
198 else
199 return false;
201 return true;
204 virtual bool operator()( double t )
206 std::for_each(maTransitions.begin(),
207 maTransitions.end(),
208 boost::bind( &TransitionViewPair::update,
209 _1, t) );
210 return true;
213 bool Success()
215 return mbSuccess;
218 // ViewEventHandler
219 virtual void viewAdded( const UnoViewSharedPtr& rView )
221 OSL_TRACE("PluginSlideChange viewAdded");
222 SlideChangeBase::viewAdded( rView );
224 ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
225 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
226 bool bKnown = false;
227 while( aCurrView != aEnd )
229 if( (*aCurrView)->mpView == rView ) {
230 bKnown = true;
231 break;
233 ++aCurrView;
236 if( !bKnown ) {
237 OSL_TRACE("need to be added");
239 addTransition( rView );
243 virtual void viewRemoved( const UnoViewSharedPtr& rView )
245 OSL_TRACE("PluginSlideChange viewRemoved");
246 SlideChangeBase::viewRemoved( rView );
248 ::std::vector< TransitionViewPair* >::iterator aCurrView (maTransitions.begin());
249 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
250 while( aCurrView != aEnd )
252 if( (*aCurrView)->mpView == rView ) {
253 OSL_TRACE( "view removed" );
254 delete (*aCurrView);
255 maTransitions.erase( aCurrView );
256 break;
258 ++aCurrView;
262 virtual void viewChanged( const UnoViewSharedPtr& rView )
264 OSL_TRACE("PluginSlideChange viewChanged");
265 SlideChangeBase::viewChanged( rView );
267 ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
268 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
269 while( aCurrView != aEnd )
271 if( (*aCurrView)->mpView == rView ) {
272 OSL_TRACE( "view changed" );
273 (*aCurrView)->mxTransition->viewChanged( rView->getUnoView(),
274 getLeavingBitmap(ViewEntry(rView))->getXBitmap(),
275 getEnteringBitmap(ViewEntry(rView))->getXBitmap() );
276 } else
277 OSL_TRACE( "view did not changed" );
279 ++aCurrView;
283 virtual void viewsChanged()
285 OSL_TRACE("PluginSlideChange viewsChanged");
286 SlideChangeBase::viewsChanged();
288 ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
289 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
290 while( aCurrView != aEnd )
292 OSL_TRACE( "view changed" );
293 (*aCurrView)->mxTransition->viewChanged( (*aCurrView)->mpView->getUnoView(),
294 getLeavingBitmap(ViewEntry((*aCurrView)->mpView))->getXBitmap(),
295 getEnteringBitmap(ViewEntry((*aCurrView)->mpView))->getXBitmap() );
296 ++aCurrView;
300 private:
301 // One transition object per view
302 std::vector< TransitionViewPair* > maTransitions;
304 // bool
305 bool mbSuccess;
307 sal_Int16 mnTransitionType;
308 sal_Int16 mnTransitionSubType;
310 uno::Reference<presentation::XTransitionFactory> mxFactory;
313 class ClippedSlideChange : public SlideChangeBase
315 public:
316 /** Create a new SlideChanger, for the given leaving and
317 entering slide bitmaps, which applies the given clip
318 polygon.
320 ClippedSlideChange(
321 const SlideSharedPtr& pEnteringSlide,
322 const ParametricPolyPolygonSharedPtr& rPolygon,
323 const TransitionInfo& rTransitionInfo,
324 const UnoViewContainer& rViewContainer,
325 ScreenUpdater& rScreenUpdater,
326 EventMultiplexer& rEventMultiplexer,
327 bool bDirectionForward,
328 const SoundPlayerSharedPtr& pSoundPlayer ) :
329 SlideChangeBase(
330 // leaving bitmap is empty, we're leveraging the fact that the
331 // old slide is still displayed in the background:
332 boost::optional<SlideSharedPtr>(),
333 pEnteringSlide,
334 pSoundPlayer,
335 rViewContainer,
336 rScreenUpdater,
337 rEventMultiplexer ),
338 maClippingFunctor( rPolygon,
339 rTransitionInfo,
340 bDirectionForward,
341 true )
344 virtual void performIn(
345 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
346 const ViewEntry& rViewEntry,
347 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
348 double t );
350 virtual void performOut(
351 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
352 const ViewEntry& rViewEntry,
353 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
354 double t );
356 private:
357 ClippingFunctor maClippingFunctor;
360 void ClippedSlideChange::performIn(
361 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
362 const ViewEntry& rViewEntry,
363 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
364 double t )
366 // #i46602# Better work in device coordinate space here,
367 // otherwise, we too easily suffer from roundoffs. Apart from
368 // that, getEnteringSizePixel() _guarantees_ to cover the whole
369 // slide bitmap. There's a catch, though: this removes any effect
370 // of the view transformation (e.g. rotation) from the transition.
371 rSprite->setClipPixel(
372 maClippingFunctor( t,
373 getEnteringSlideSizePixel(rViewEntry.mpView) ) );
376 void ClippedSlideChange::performOut(
377 const ::cppcanvas::CustomSpriteSharedPtr& /*rSprite*/,
378 const ViewEntry& /*rViewEntry*/,
379 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
380 double /*t*/ )
382 // not needed here
386 class FadingSlideChange : public SlideChangeBase
388 public:
389 /** Create a new SlideChanger, for the given leaving and
390 entering slides, which applies a fade effect.
392 FadingSlideChange(
393 boost::optional<SlideSharedPtr> const & leavingSlide,
394 const SlideSharedPtr& pEnteringSlide,
395 boost::optional<RGBColor> const& rFadeColor,
396 const SoundPlayerSharedPtr& pSoundPlayer,
397 const UnoViewContainer& rViewContainer,
398 ScreenUpdater& rScreenUpdater,
399 EventMultiplexer& rEventMultiplexer )
400 : SlideChangeBase( leavingSlide,
401 pEnteringSlide,
402 pSoundPlayer,
403 rViewContainer,
404 rScreenUpdater,
405 rEventMultiplexer ),
406 maFadeColor( rFadeColor ),
407 mbFirstTurn( true )
410 virtual void performIn(
411 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
412 const ViewEntry& rViewEntry,
413 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
414 double t );
416 virtual void performOut(
417 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
418 const ViewEntry& rViewEntry,
419 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
420 double t );
422 private:
423 const boost::optional< RGBColor > maFadeColor;
424 bool mbFirstTurn;
427 void FadingSlideChange::performIn(
428 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
429 const ViewEntry& /*rViewEntry*/,
430 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
431 double t )
433 ENSURE_OR_THROW(
434 rSprite,
435 "FadingSlideChange::performIn(): Invalid sprite" );
437 if( maFadeColor )
438 // After half of the active time, fade in new slide
439 rSprite->setAlpha( t > 0.5 ? 2.0*(t-0.5) : 0.0 );
440 else
441 // Fade in new slide over full active time
442 rSprite->setAlpha( t );
445 void FadingSlideChange::performOut(
446 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
447 const ViewEntry& rViewEntry,
448 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
449 double t )
451 ENSURE_OR_THROW(
452 rSprite,
453 "FadingSlideChange::performOut(): Invalid sprite" );
454 ENSURE_OR_THROW(
455 rDestinationCanvas,
456 "FadingSlideChange::performOut(): Invalid dest canvas" );
458 // only needed for color fades
459 if( maFadeColor )
461 if( mbFirstTurn )
463 mbFirstTurn = false;
465 // clear page to given fade color. 'Leaving' slide is
466 // painted atop of that, but slowly fading out.
467 fillPage( rDestinationCanvas,
468 getEnteringSlideSizePixel( rViewEntry.mpView ),
469 *maFadeColor );
472 // Until half of the active time, fade out old
473 // slide. After half of the active time, old slide
474 // will be invisible.
475 rSprite->setAlpha( t > 0.5 ? 0.0 : 2.0*(0.5-t) );
479 class CutSlideChange : public SlideChangeBase
481 public:
482 /** Create a new SlideChanger, for the given leaving and
483 entering slides, which applies a cut effect.
485 CutSlideChange(
486 boost::optional<SlideSharedPtr> const & leavingSlide,
487 const SlideSharedPtr& pEnteringSlide,
488 const RGBColor& rFadeColor,
489 const SoundPlayerSharedPtr& pSoundPlayer,
490 const UnoViewContainer& rViewContainer,
491 ScreenUpdater& rScreenUpdater,
492 EventMultiplexer& rEventMultiplexer )
493 : SlideChangeBase( leavingSlide,
494 pEnteringSlide,
495 pSoundPlayer,
496 rViewContainer,
497 rScreenUpdater,
498 rEventMultiplexer ),
499 maFadeColor( rFadeColor ),
500 mbFirstTurn( true )
503 virtual void performIn(
504 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
505 const ViewEntry& rViewEntry,
506 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
507 double t );
509 virtual void performOut(
510 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
511 const ViewEntry& rViewEntry,
512 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
513 double t );
515 private:
516 RGBColor maFadeColor;
517 bool mbFirstTurn;
520 void CutSlideChange::performIn(
521 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
522 const ViewEntry& /*rViewEntry*/,
523 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
524 double t )
526 ENSURE_OR_THROW(
527 rSprite,
528 "CutSlideChange::performIn(): Invalid sprite" );
530 // After 2/3rd of the active time, display new slide
531 rSprite->setAlpha( t > 2/3.0 ? 1.0 : 0.0 );
534 void CutSlideChange::performOut(
535 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
536 const ViewEntry& rViewEntry,
537 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
538 double t )
540 ENSURE_OR_THROW(
541 rSprite,
542 "CutSlideChange::performOut(): Invalid sprite" );
543 ENSURE_OR_THROW(
544 rDestinationCanvas,
545 "FadingSlideChange::performOut(): Invalid dest canvas" );
547 if( mbFirstTurn )
549 mbFirstTurn = false;
551 // clear page to given fade color. 'Leaving' slide is
552 // painted atop of that
553 fillPage( rDestinationCanvas,
554 getEnteringSlideSizePixel( rViewEntry.mpView ),
555 maFadeColor );
558 // Until 1/3rd of the active time, display old slide.
559 rSprite->setAlpha( t > 1/3.0 ? 0.0 : 1.0 );
562 class MovingSlideChange : public SlideChangeBase
564 /// Direction vector for leaving slide,
565 const ::basegfx::B2DVector maLeavingDirection;
567 /// Direction vector for entering slide,
568 const ::basegfx::B2DVector maEnteringDirection;
570 bool mbFirstPerformCall;
572 public:
573 /** Create a new SlideChanger, for the given entering slide
574 bitmaps, which performes a moving slide change effect
576 @param rLeavingDirection
577 Direction vector. The move is performed along this
578 direction vector, starting at a position where the leaving
579 slide is fully visible, and ending at a position where the
580 leaving slide is just not visible. The vector must have
581 unit length.
583 @param rEnteringDirection
584 Direction vector. The move is performed along this
585 direction vector, starting at a position where the
586 entering slide is just not visible, and ending at the
587 final slide position. The vector must have unit length.
589 MovingSlideChange(
590 const boost::optional<SlideSharedPtr>& leavingSlide,
591 const SlideSharedPtr& pEnteringSlide,
592 const SoundPlayerSharedPtr& pSoundPlayer,
593 const UnoViewContainer& rViewContainer,
594 ScreenUpdater& rScreenUpdater,
595 EventMultiplexer& rEventMultiplexer,
596 const ::basegfx::B2DVector& rLeavingDirection,
597 const ::basegfx::B2DVector& rEnteringDirection )
598 : SlideChangeBase(
599 leavingSlide, pEnteringSlide, pSoundPlayer,
600 rViewContainer, rScreenUpdater, rEventMultiplexer,
601 // Optimization: when leaving bitmap is given,
602 // but it does not move, don't create sprites for it,
603 // we simply paint it once at startup:
604 !rLeavingDirection.equalZero() /* bCreateLeavingSprites */,
605 !rEnteringDirection.equalZero() /* bCreateEnteringSprites */ ),
606 // TODO(F1): calc correct length of direction
607 // vector. Directions not strictly horizontal or vertical
608 // must travel a longer distance.
609 maLeavingDirection( rLeavingDirection ),
610 // TODO(F1): calc correct length of direction
611 // vector. Directions not strictly horizontal or vertical
612 // must travel a longer distance.
613 maEnteringDirection( rEnteringDirection ),
614 mbFirstPerformCall( true )
617 virtual void performIn(
618 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
619 const ViewEntry& rViewEntry,
620 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
621 double t );
623 virtual void performOut(
624 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
625 const ViewEntry& rViewEntry,
626 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
627 double t );
630 void MovingSlideChange::performIn(
631 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
632 const ViewEntry& rViewEntry,
633 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
634 double t )
636 // intro sprite moves:
638 ENSURE_OR_THROW(
639 rSprite,
640 "MovingSlideChange::performIn(): Invalid sprite" );
641 ENSURE_OR_THROW(
642 rDestinationCanvas,
643 "MovingSlideChange::performIn(): Invalid dest canvas" );
645 if (mbFirstPerformCall && maLeavingDirection.equalZero())
647 mbFirstPerformCall = false;
648 renderBitmap( getLeavingBitmap(rViewEntry), rDestinationCanvas );
651 // TODO(F1): This does not account for non-translational
652 // transformations! If the canvas is rotated, we still
653 // move the sprite unrotated (which might or might not
654 // produce the intended effect).
655 const basegfx::B2DHomMatrix aViewTransform(
656 rDestinationCanvas->getTransformation() );
657 const basegfx::B2DPoint aPageOrigin(
658 aViewTransform * basegfx::B2DPoint() );
660 // move sprite
661 rSprite->movePixel(
662 aPageOrigin +
663 ((t - 1.0) *
664 ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) *
665 maEnteringDirection) );
668 void MovingSlideChange::performOut(
669 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
670 const ViewEntry& rViewEntry,
671 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
672 double t )
674 // outro sprite moves:
676 ENSURE_OR_THROW(
677 rSprite,
678 "MovingSlideChange::performOut(): Invalid sprite" );
679 ENSURE_OR_THROW(
680 rDestinationCanvas,
681 "MovingSlideChange::performOut(): Invalid dest canvas" );
683 if (mbFirstPerformCall && maEnteringDirection.equalZero())
685 mbFirstPerformCall = false;
686 renderBitmap( getEnteringBitmap(rViewEntry), rDestinationCanvas );
689 // TODO(F1): This does not account for non-translational
690 // transformations! If the canvas is rotated, we still
691 // move the sprite unrotated (which might or might not
692 // produce the intended effect).
693 const basegfx::B2DHomMatrix aViewTransform(
694 rDestinationCanvas->getTransformation() );
695 const basegfx::B2DPoint aPageOrigin(
696 aViewTransform * basegfx::B2DPoint() );
698 // move sprite
699 rSprite->movePixel(
700 aPageOrigin + (t *
701 ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) *
702 maLeavingDirection) );
706 NumberAnimationSharedPtr createPushWipeTransition(
707 boost::optional<SlideSharedPtr> const & leavingSlide_,
708 const SlideSharedPtr& pEnteringSlide,
709 const UnoViewContainer& rViewContainer,
710 ScreenUpdater& rScreenUpdater,
711 EventMultiplexer& rEventMultiplexer,
712 sal_Int16 /*nTransitionType*/,
713 sal_Int16 nTransitionSubType,
714 bool /*bTransitionDirection*/,
715 const SoundPlayerSharedPtr& pSoundPlayer )
717 boost::optional<SlideSharedPtr> leavingSlide; // no bitmap
718 if (leavingSlide_ && (*leavingSlide_).get() != 0)
720 // opt: only page, if we've an
721 // actual slide to move out here. We
722 // _don't_ need a fake black background
723 // bitmap, neither for push nor for comb
724 // wipes.
725 leavingSlide = leavingSlide_;
728 // setup direction vector
729 bool bComb( false );
730 ::basegfx::B2DVector aDirection;
731 switch( nTransitionSubType )
733 default:
734 OSL_ENSURE(
735 false,
736 "createPushWipeTransition(): Unexpected transition "
737 "subtype for animations::TransitionType::PUSHWIPE "
738 "transitions" );
739 return NumberAnimationSharedPtr();
741 case animations::TransitionSubType::FROMTOP:
742 aDirection = ::basegfx::B2DVector( 0.0, 1.0 );
743 break;
745 case animations::TransitionSubType::FROMBOTTOM:
746 aDirection = ::basegfx::B2DVector( 0.0, -1.0 );
747 break;
749 case animations::TransitionSubType::FROMLEFT:
750 aDirection = ::basegfx::B2DVector( 1.0, 0.0 );
751 break;
753 case animations::TransitionSubType::FROMRIGHT:
754 aDirection = ::basegfx::B2DVector( -1.0, 0.0 );
755 break;
757 case animations::TransitionSubType::FROMBOTTOMRIGHT:
758 aDirection = ::basegfx::B2DVector( -1.0, -1.0 );
759 break;
761 case animations::TransitionSubType::FROMBOTTOMLEFT:
762 aDirection = ::basegfx::B2DVector( 1.0, -1.0 );
763 break;
765 case animations::TransitionSubType::FROMTOPRIGHT:
766 aDirection = ::basegfx::B2DVector( -1.0, 1.0 );
767 break;
769 case animations::TransitionSubType::FROMTOPLEFT:
770 aDirection = ::basegfx::B2DVector( 1.0, 1.0 );
771 break;
773 case animations::TransitionSubType::COMBHORIZONTAL:
774 aDirection = ::basegfx::B2DVector( 1.0, 0.0 );
775 bComb = true;
776 break;
778 case animations::TransitionSubType::COMBVERTICAL:
779 aDirection = ::basegfx::B2DVector( 0.0, 1.0 );
780 bComb = true;
781 break;
784 if( bComb )
786 return NumberAnimationSharedPtr(
787 new CombTransition( leavingSlide,
788 pEnteringSlide,
789 pSoundPlayer,
790 rViewContainer,
791 rScreenUpdater,
792 rEventMultiplexer,
793 aDirection,
794 24 /* comb with 12 stripes */ ));
796 else
798 return NumberAnimationSharedPtr(
799 new MovingSlideChange( leavingSlide,
800 pEnteringSlide,
801 pSoundPlayer,
802 rViewContainer,
803 rScreenUpdater,
804 rEventMultiplexer,
805 aDirection,
806 aDirection ));
810 NumberAnimationSharedPtr createSlideWipeTransition(
811 boost::optional<SlideSharedPtr> const & leavingSlide,
812 const SlideSharedPtr& pEnteringSlide,
813 const UnoViewContainer& rViewContainer,
814 ScreenUpdater& rScreenUpdater,
815 EventMultiplexer& rEventMultiplexer,
816 sal_Int16 /*nTransitionType*/,
817 sal_Int16 nTransitionSubType,
818 bool bTransitionDirection,
819 const SoundPlayerSharedPtr& pSoundPlayer )
821 // setup 'in' direction vector
822 ::basegfx::B2DVector aInDirection;
823 switch( nTransitionSubType )
825 default:
826 OSL_ENSURE(
827 false,
828 "createSlideWipeTransition(): Unexpected transition "
829 "subtype for animations::TransitionType::SLIDEWIPE "
830 "transitions" );
831 return NumberAnimationSharedPtr();
833 case animations::TransitionSubType::FROMTOP:
834 aInDirection = ::basegfx::B2DVector( 0.0, 1.0 );
835 break;
837 case animations::TransitionSubType::FROMRIGHT:
838 aInDirection = ::basegfx::B2DVector( -1.0, 0.0 );
839 break;
841 case animations::TransitionSubType::FROMLEFT:
842 aInDirection = ::basegfx::B2DVector( 1.0, 0.0 );
843 break;
845 case animations::TransitionSubType::FROMBOTTOM:
846 aInDirection = ::basegfx::B2DVector( 0.0, -1.0 );
847 break;
849 case animations::TransitionSubType::FROMBOTTOMRIGHT:
850 aInDirection = ::basegfx::B2DVector( -1.0, -1.0 );
851 break;
853 case animations::TransitionSubType::FROMBOTTOMLEFT:
854 aInDirection = ::basegfx::B2DVector( 1.0, -1.0 );
855 break;
857 case animations::TransitionSubType::FROMTOPRIGHT:
858 aInDirection = ::basegfx::B2DVector( -1.0, 1.0 );
859 break;
861 case animations::TransitionSubType::FROMTOPLEFT:
862 aInDirection = ::basegfx::B2DVector( 1.0, 1.0 );
863 break;
866 if( bTransitionDirection )
868 // normal, 'forward' slide wipe effect. Since the old
869 // content is still on screen (and does not move), we omit
870 // the 'leaving' slide.
871 // =======================================================
873 return NumberAnimationSharedPtr(
874 new MovingSlideChange(
875 boost::optional<SlideSharedPtr>() /* no slide */,
876 pEnteringSlide,
877 pSoundPlayer,
878 rViewContainer,
879 rScreenUpdater,
880 rEventMultiplexer,
881 basegfx::B2DVector(),
882 aInDirection ));
884 else
886 // 'reversed' slide wipe effect. Reverse for slide wipes
887 // means, that the new slide is in the back, statically,
888 // and the old one is moving off in the foreground.
889 // =======================================================
891 return NumberAnimationSharedPtr(
892 new MovingSlideChange( leavingSlide,
893 pEnteringSlide,
894 pSoundPlayer,
895 rViewContainer,
896 rScreenUpdater,
897 rEventMultiplexer,
898 aInDirection,
899 basegfx::B2DVector() ));
903 NumberAnimationSharedPtr createPluginTransition(
904 sal_Int16 nTransitionType,
905 sal_Int16 nTransitionSubType,
906 boost::optional<SlideSharedPtr> const& pLeavingSlide,
907 const SlideSharedPtr& pEnteringSlide,
908 const UnoViewContainer& rViewContainer,
909 ScreenUpdater& rScreenUpdater,
910 const uno::Reference<
911 presentation::XTransitionFactory>& xFactory,
912 const SoundPlayerSharedPtr& pSoundPlayer,
913 EventMultiplexer& rEventMultiplexer)
915 PluginSlideChange* pTransition =
916 new PluginSlideChange(
917 nTransitionType,
918 nTransitionSubType,
919 pLeavingSlide,
920 pEnteringSlide,
921 rViewContainer,
922 rScreenUpdater,
923 xFactory,
924 pSoundPlayer,
925 rEventMultiplexer );
927 if( pTransition->Success() )
928 return NumberAnimationSharedPtr( pTransition );
929 else {
930 delete pTransition;
931 return NumberAnimationSharedPtr();
935 } // anon namespace
938 NumberAnimationSharedPtr TransitionFactory::createSlideTransition(
939 const SlideSharedPtr& pLeavingSlide,
940 const SlideSharedPtr& pEnteringSlide,
941 const UnoViewContainer& rViewContainer,
942 ScreenUpdater& rScreenUpdater,
943 EventMultiplexer& rEventMultiplexer,
944 const uno::Reference<presentation::XTransitionFactory>& xOptionalFactory,
945 sal_Int16 nTransitionType,
946 sal_Int16 nTransitionSubType,
947 bool bTransitionDirection,
948 const RGBColor& rTransitionFadeColor,
949 const SoundPlayerSharedPtr& pSoundPlayer )
951 // xxx todo: change to TransitionType::NONE, TransitionSubType::NONE:
952 if (nTransitionType == 0 && nTransitionSubType == 0) {
953 // just play sound, no slide transition:
954 if (pSoundPlayer) {
955 pSoundPlayer->startPlayback();
956 // xxx todo: for now, presentation.cxx takes care about the slide
957 // #i50492# transition sound object, so just release it here
959 return NumberAnimationSharedPtr();
962 ENSURE_OR_THROW(
963 pEnteringSlide,
964 "TransitionFactory::createSlideTransition(): Invalid entering slide" );
966 if( xOptionalFactory.is() &&
967 xOptionalFactory->hasTransition(nTransitionType, nTransitionSubType) )
969 // #i82460# - optional plugin factory claims this transition. delegate.
970 NumberAnimationSharedPtr pTransition(
971 createPluginTransition(
972 nTransitionType,
973 nTransitionSubType,
974 comphelper::make_optional(pLeavingSlide),
975 pEnteringSlide,
976 rViewContainer,
977 rScreenUpdater,
978 xOptionalFactory,
979 pSoundPlayer,
980 rEventMultiplexer ));
982 if( pTransition.get() )
983 return pTransition;
986 const TransitionInfo* pTransitionInfo(
987 getTransitionInfo( nTransitionType, nTransitionSubType ) );
989 if( pTransitionInfo != NULL )
991 switch( pTransitionInfo->meTransitionClass )
993 default:
994 case TransitionInfo::TRANSITION_INVALID:
995 OSL_TRACE(
996 "TransitionFactory::createSlideTransition(): "
997 "Invalid type/subtype (%d/%d) combination encountered.",
998 nTransitionType,
999 nTransitionSubType );
1000 return NumberAnimationSharedPtr();
1003 case TransitionInfo::TRANSITION_CLIP_POLYPOLYGON:
1005 // generate parametric poly-polygon
1006 ParametricPolyPolygonSharedPtr pPoly(
1007 ParametricPolyPolygonFactory::createClipPolyPolygon(
1008 nTransitionType, nTransitionSubType ) );
1010 // create a clip transition from that
1011 return NumberAnimationSharedPtr(
1012 new ClippedSlideChange( pEnteringSlide,
1013 pPoly,
1014 *pTransitionInfo,
1015 rViewContainer,
1016 rScreenUpdater,
1017 rEventMultiplexer,
1018 bTransitionDirection,
1019 pSoundPlayer ));
1022 case TransitionInfo::TRANSITION_SPECIAL:
1024 switch( nTransitionType )
1026 default:
1027 OSL_ENSURE(
1028 false,
1029 "TransitionFactory::createSlideTransition(): "
1030 "Unexpected transition type for "
1031 "TRANSITION_SPECIAL transitions" );
1032 return NumberAnimationSharedPtr();
1034 case animations::TransitionType::RANDOM:
1036 // select randomly one of the effects from the
1037 // TransitionFactoryTable
1039 const TransitionInfo* pRandomTransitionInfo(
1040 getRandomTransitionInfo() );
1042 ENSURE_OR_THROW(
1043 pRandomTransitionInfo != NULL,
1044 "TransitionFactory::createSlideTransition(): "
1045 "Got invalid random transition info" );
1047 ENSURE_OR_THROW(
1048 pRandomTransitionInfo->mnTransitionType !=
1049 animations::TransitionType::RANDOM,
1050 "TransitionFactory::createSlideTransition(): "
1051 "Got random again for random input!" );
1053 // and recurse
1054 return createSlideTransition(
1055 pLeavingSlide,
1056 pEnteringSlide,
1057 rViewContainer,
1058 rScreenUpdater,
1059 rEventMultiplexer,
1060 xOptionalFactory,
1061 pRandomTransitionInfo->mnTransitionType,
1062 pRandomTransitionInfo->mnTransitionSubType,
1063 bTransitionDirection,
1064 rTransitionFadeColor,
1065 pSoundPlayer );
1068 case animations::TransitionType::PUSHWIPE:
1070 return createPushWipeTransition(
1071 comphelper::make_optional(pLeavingSlide),
1072 pEnteringSlide,
1073 rViewContainer,
1074 rScreenUpdater,
1075 rEventMultiplexer,
1076 nTransitionType,
1077 nTransitionSubType,
1078 bTransitionDirection,
1079 pSoundPlayer );
1082 case animations::TransitionType::SLIDEWIPE:
1084 return createSlideWipeTransition(
1085 comphelper::make_optional(pLeavingSlide),
1086 pEnteringSlide,
1087 rViewContainer,
1088 rScreenUpdater,
1089 rEventMultiplexer,
1090 nTransitionType,
1091 nTransitionSubType,
1092 bTransitionDirection,
1093 pSoundPlayer );
1096 case animations::TransitionType::BARWIPE:
1097 case animations::TransitionType::FADE:
1099 // black page:
1100 boost::optional<SlideSharedPtr> leavingSlide;
1102 switch( nTransitionSubType )
1104 case animations::TransitionSubType::CROSSFADE:
1105 // crossfade needs no further setup,
1106 // just blend new slide over existing
1107 // background.
1108 break;
1110 // TODO(F1): Implement toColor/fromColor fades
1111 case animations::TransitionSubType::FADETOCOLOR:
1112 // FALLTHROUGH intended
1113 case animations::TransitionSubType::FADEFROMCOLOR:
1114 // FALLTHROUGH intended
1115 case animations::TransitionSubType::FADEOVERCOLOR:
1116 if (pLeavingSlide) {
1117 // only generate, if fade
1118 // effect really needs it.
1119 leavingSlide.reset( pLeavingSlide );
1121 break;
1123 default:
1124 ENSURE_OR_THROW( false,
1125 "SlideTransitionFactory::createSlideTransition(): Unknown FADE subtype" );
1128 if( nTransitionType == animations::TransitionType::FADE )
1129 return NumberAnimationSharedPtr(
1130 new FadingSlideChange(
1131 leavingSlide,
1132 pEnteringSlide,
1133 comphelper::make_optional(
1134 rTransitionFadeColor),
1135 pSoundPlayer,
1136 rViewContainer,
1137 rScreenUpdater,
1138 rEventMultiplexer ));
1139 else
1140 return NumberAnimationSharedPtr(
1141 new CutSlideChange(
1142 leavingSlide,
1143 pEnteringSlide,
1144 rTransitionFadeColor,
1145 pSoundPlayer,
1146 rViewContainer,
1147 rScreenUpdater,
1148 rEventMultiplexer ));
1152 break;
1156 // No animation generated, maybe no table entry for given
1157 // transition?
1158 OSL_TRACE(
1159 "TransitionFactory::createSlideTransition(): "
1160 "Unknown type/subtype (%d/%d) combination encountered",
1161 nTransitionType,
1162 nTransitionSubType );
1163 OSL_ENSURE(
1164 false,
1165 "TransitionFactory::createSlideTransition(): "
1166 "Unknown type/subtype combination encountered" );
1168 return NumberAnimationSharedPtr();
1171 } // namespace internal
1172 } // namespace presentation