1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sdext.hxx"
30 
31 #include "PresenterPaneAnimator.hxx"
32 
33 #include "PresenterAnimation.hxx"
34 #include "PresenterAnimator.hxx"
35 #include "PresenterCanvasHelper.hxx"
36 #include "PresenterController.hxx"
37 #include "PresenterGeometryHelper.hxx"
38 #include "PresenterPaintManager.hxx"
39 #include "PresenterPaneContainer.hxx"
40 #include "PresenterPaneFactory.hxx"
41 #include "PresenterSprite.hxx"
42 #include "PresenterSpritePane.hxx"
43 #include "PresenterWindowManager.hxx"
44 
45 #include <com/sun/star/awt/PosSize.hpp>
46 #include <com/sun/star/awt/XWindowPeer.hpp>
47 #include <com/sun/star/rendering/CompositeOperation.hpp>
48 #include <boost/bind.hpp>
49 #include <boost/bind/protect.hpp>
50 #include <boost/enable_shared_from_this.hpp>
51 
52 using namespace ::com::sun::star;
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::drawing::framework;
55 using ::rtl::OUString;
56 using ::std::vector;
57 
58 namespace sdext { namespace presenter {
59 
60 namespace {
61 
62     class PaneGroup;
63 
64     class PresenterPaneAnimatorBase
65         : public ::boost::enable_shared_from_this<PresenterPaneAnimatorBase>,
66           public PresenterPaneAnimator
67     {
68     public:
69         PresenterPaneAnimatorBase (
70             const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
71             const ::rtl::Reference<PresenterController>& rpPresenterController,
72             const bool bAnimate,
73             const EndActions& rShowEndActions,
74             const EndActions& rEndEndActions);
75         virtual ~PresenterPaneAnimatorBase (void);
76 
77         typedef ::std::vector< ::boost::function<void()> > EndOperators;
78 
79         void ActivatePanes (void);
80         void ActivatePane (
81             const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId);
82         void RestoreFrozenWindows (void);
83         void FreezePanes (const Reference<rendering::XSpriteCanvas>& rxCanvas);
84 
85     protected:
86         ::rtl::Reference<PresenterController> mpPresenterController;
87         ::rtl::Reference<PresenterPaneContainer> mpPaneContainer;
88         ::rtl::Reference<PresenterWindowManager> mpWindowManager;
89         ::std::vector< ::boost::shared_ptr<PaneGroup> > maPaneGroups;
90         css::uno::Reference<css::drawing::framework::XResourceId> mxCenterPaneId;
91         bool mbDoAnimation;
92         EndActions maShowEndActions;
93         EndActions maHideEndActions;
94 
95         void DeactivatePanes (void);
96         void ResizePane (
97             const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
98             const geometry::RealRectangle2D& rBox);
99         void DeactivatePane (
100             const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId);
101     };
102 
103 
104     class UnfoldInCenterAnimator : public PresenterPaneAnimatorBase
105     {
106     public:
107         UnfoldInCenterAnimator (
108             const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
109             const ::rtl::Reference<PresenterController>& rpPresenterController,
110             const bool bAnimate,
111             const EndActions& rShowEndActions,
112             const EndActions& rEndEndActions);
113 
114         virtual ~UnfoldInCenterAnimator (void);
115 
116         virtual void ShowPane (void);
117 
118         virtual void HidePane (void);
119 
120     private:
121         geometry::RealRectangle2D maCenterPaneBox;
122 
123         void SetupPaneGroups (void);
124         geometry::RealRectangle2D MovePanesAway (
125             const css::geometry::RealRectangle2D& rFreeCenterArea);
126     };
127 
128 
129     class MoveInFromBottomAnimator : public PresenterPaneAnimatorBase
130     {
131     public:
132         MoveInFromBottomAnimator(
133             const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
134             const ::rtl::Reference<PresenterController>& rpPresenterController,
135             const bool bAnimate,
136             const EndActions& rShowEndActions,
137             const EndActions& rEndEndActions);
138         virtual ~MoveInFromBottomAnimator (void);
139 
140         virtual void ShowPane (void);
141         virtual void HidePane (void);
142 
143     private:
144         ::boost::shared_ptr<PresenterSprite> maNewPaneSprite;
145         geometry::RealRectangle2D maCenterPaneBox;
146 
147         void CreateShowAnimation (
148             const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
149             const EndOperators& rpEndOperators,
150             const css::uno::Reference<css::rendering::XSpriteCanvas>& rxSpriteCanvas,
151             const bool bAnimate,
152             const css::geometry::RealPoint2D& rStartLocation,
153             const css::geometry::RealPoint2D& rEndLocation);
154     };
155 
156 
157     class TransparentOverlayAnimator : public PresenterPaneAnimatorBase
158     {
159     public:
160         TransparentOverlayAnimator(
161             const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
162             const ::rtl::Reference<PresenterController>& rpPresenterController,
163             const bool bAnimate,
164             const EndActions& rShowEndActions,
165             const EndActions& rEndEndActions);
166         virtual ~TransparentOverlayAnimator (void);
167 
168         virtual void ShowPane (void);
169         virtual void HidePane (void);
170 
171     private:
172         PresenterSprite maBackgroundSprite;
173         void CreateBackgroundSprite (void);
174     };
175 
176 
177     class PaneDescriptor
178     {
179     public:
180         PresenterPaneContainer::SharedPaneDescriptor mpPaneDescriptor;
181 
182         PaneDescriptor (const PresenterPaneContainer::SharedPaneDescriptor& rpDescriptor);
183         void Restore (void) const;
184     private:
185         double mnLeft;
186         double mnTop;
187         double mnRight;
188         double mnBottom;
189     };
190 
191     class MultiAnimation : public PresenterAnimation
192     {
193     public:
194         typedef ::boost::function<void(double)> Animation;
195         MultiAnimation (const sal_uInt32 nDuration);
196         void AddAnimation (const Animation& rAnimation);
197         virtual void Run (const double nProgress, const sal_uInt64 nCurrentTime);
198     private:
199         vector<Animation> maAnimations;
200     };
201 
202 
203     class PaneGroup
204     {
205     public:
206         PaneGroup (void);
207         ~PaneGroup (void);
208         void AddPane (const PresenterPaneContainer::SharedPaneDescriptor& rpPane);
209         void CreateSubstitution (const Reference<rendering::XSpriteCanvas>& rxCanvas);
210         void ThawPanes (void);
211         void Restore (void);
212         ::boost::shared_ptr<PresenterSprite> GetSubstitution (void);
213         css::geometry::RealRectangle2D GetOriginalBoundingBox (void) const;
214         css::geometry::RealRectangle2D GetCurrentBoundingBox (void) const;
215         void MovePanes (
216             const double nXOffset,
217             const double nYOffset,
218             const ::rtl::Reference<PresenterWindowManager>& rpWindowManager);
219         void ActivatePanes (void);
220         void DeactivatePanes (void);
221         void HidePanes (void);
222         void ShowPanes (void);
223 
224     private:
225         vector<PaneDescriptor> maPanes;
226         awt::Rectangle maOriginalBoundingBox;
227         css::geometry::RealRectangle2D maCurrentBoundingBox;
228         ::boost::shared_ptr<PresenterSprite> mpSubstitution;
229 
230     };
231     typedef ::boost::shared_ptr<PaneGroup> SharedPaneGroup;
232 
233     void InterpolatePosition (
234         const ::boost::function<void(geometry::RealPoint2D)>& rSetter,
235         double nP,
236         const geometry::RealPoint2D rInitialBox,
237         const geometry::RealPoint2D rFinalBox);
238 
239     template<typename T>
240     void InterpolateValue (
241         const ::boost::function<void(T)>& rSetter,
242         double nP,
243         const T aInitialValue,
244         const T aFinalValue);
245 
246     void SpriteTransform(
247         const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
248         const Reference<XResourceId>& rxPaneId,
249         const Reference<awt::XWindow>& rxSpriteOwnerWindow,
250         const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
251         const bool bAppear,
252         const double nX,
253         const double nInitialTop,
254         const double nFinalTop,
255         const double nP);
256 
257     void SpritePaneMove (
258         const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
259         const Reference<XResourceId>& rxPaneId,
260         const geometry::RealPoint2D& rLocation);
261 
262     geometry::RealPoint2D GetLocation (const geometry::RealRectangle2D& rBox);
263     geometry::RealSize2D GetSize (const geometry::RealRectangle2D& rBox);
264 
265 
266 } // end of anonymous namespace
267 
268 
269 
270 
271 //=============================================================================
272 
273 
274 ::boost::shared_ptr<PresenterPaneAnimator> CreateUnfoldInCenterAnimator (
275     const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
276     const ::rtl::Reference<PresenterController>& rpPresenterController,
277     const bool bAnimate,
278     const EndActions& rShowEndActions,
279     const EndActions& rEndEndActions)
280 {
281     return ::boost::shared_ptr<PresenterPaneAnimator>(
282         new UnfoldInCenterAnimator(rxPaneId, rpPresenterController, bAnimate,
283             rShowEndActions, rEndEndActions));
284 }
285 
286 
287 
288 
289 ::boost::shared_ptr<PresenterPaneAnimator> CreateMoveInFromBottomAnimator (
290         const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
291         const ::rtl::Reference<PresenterController>& rpPresenterController,
292         const bool bAnimate,
293         const EndActions& rShowEndActions,
294         const EndActions& rEndEndActions)
295 {
296     return ::boost::shared_ptr<PresenterPaneAnimator>(
297         new MoveInFromBottomAnimator(rxPaneId, rpPresenterController, bAnimate,
298             rShowEndActions, rEndEndActions));
299 }
300 
301 
302 
303 
304 ::boost::shared_ptr<PresenterPaneAnimator> CreateTransparentOverlay (
305         const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
306         const ::rtl::Reference<PresenterController>& rpPresenterController,
307         const bool bAnimate,
308         const EndActions& rShowEndActions,
309         const EndActions& rEndEndActions)
310 {
311     return ::boost::shared_ptr<PresenterPaneAnimator>(
312         new TransparentOverlayAnimator(rxPaneId, rpPresenterController, bAnimate,
313             rShowEndActions, rEndEndActions));
314 }
315 
316 
317 
318 
319 //===== PresenterPaneAnimator =================================================
320 
321 namespace {
322 
323 PresenterPaneAnimatorBase::PresenterPaneAnimatorBase (
324     const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
325     const ::rtl::Reference<PresenterController>& rpPresenterController,
326     const bool bAnimate,
327     const EndActions& rShowEndActions,
328     const EndActions& rHideEndActions)
329     : mpPresenterController(rpPresenterController),
330       mpPaneContainer(rpPresenterController->GetPaneContainer()),
331       mpWindowManager(rpPresenterController->GetWindowManager()),
332       maPaneGroups(),
333       mxCenterPaneId(rxPaneId),
334       mbDoAnimation(bAnimate),
335       maShowEndActions(rShowEndActions),
336       maHideEndActions(rHideEndActions)
337 {
338 }
339 
340 
341 
342 
343 PresenterPaneAnimatorBase::~PresenterPaneAnimatorBase (void)
344 {
345 }
346 
347 
348 
349 
350 void PresenterPaneAnimatorBase::FreezePanes (const Reference<rendering::XSpriteCanvas>& rxCanvas)
351 {
352     ::std::vector<SharedPaneGroup>::const_iterator iGroup;
353     for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
354     {
355         (*iGroup)->CreateSubstitution(rxCanvas);
356         (*iGroup)->GetSubstitution()->MoveTo(GetLocation((*iGroup)->GetOriginalBoundingBox()));
357     }
358 }
359 
360 
361 
362 
363 void PresenterPaneAnimatorBase::ActivatePanes (void)
364 {
365     ActivatePane(mxCenterPaneId);
366 
367     ::std::vector<SharedPaneGroup>::const_iterator iGroup;
368     for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
369     {
370         (*iGroup)->ShowPanes();
371         (*iGroup)->ActivatePanes();
372         (*iGroup)->GetSubstitution()->Hide();
373     }
374 
375     mpWindowManager->Update();
376 }
377 
378 
379 
380 
381 void PresenterPaneAnimatorBase::DeactivatePanes (void)
382 {
383     ::std::vector<SharedPaneGroup>::const_iterator iGroup;
384     for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
385     {
386         (*iGroup)->GetSubstitution()->Show();
387         (*iGroup)->DeactivatePanes();
388         (*iGroup)->HidePanes();
389     }
390 
391     mpWindowManager->Update();
392 }
393 
394 
395 
396 
397 void PresenterPaneAnimatorBase::ResizePane (
398     const Reference<drawing::framework::XResourceId>& rxPaneId,
399     const geometry::RealRectangle2D& rBox)
400 {
401     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
402         mpPaneContainer->FindPaneId(rxPaneId));
403     if (pDescriptor.get() != NULL)
404     {
405         mpWindowManager->SetPanePosSizeAbsolute (
406             rxPaneId->getResourceURL(),
407             rBox.X1,
408             rBox.Y1,
409             rBox.X2-rBox.X1,
410             rBox.Y2-rBox.Y1);
411         mpWindowManager->Layout();
412         if ( ! pDescriptor->maSpriteProvider.empty())
413         {
414             pDescriptor->maSpriteProvider()->Resize(GetSize(rBox));
415         }
416     }
417 }
418 
419 
420 
421 
422 void PresenterPaneAnimatorBase::RestoreFrozenWindows (void)
423 {
424     ::std::vector<SharedPaneGroup>::const_iterator iGroup;
425     for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
426     {
427         (*iGroup)->Restore();
428         (*iGroup)->ShowPanes();
429         (*iGroup)->ActivatePanes();
430         (*iGroup)->GetSubstitution()->Hide();
431     }
432     maPaneGroups.clear();
433 
434     ActivatePane(mxCenterPaneId);
435 
436     mpWindowManager->Update();
437 }
438 
439 
440 
441 
442 void PresenterPaneAnimatorBase::ActivatePane (
443     const Reference<drawing::framework::XResourceId>& rxPaneId)
444 {
445     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
446         mpPaneContainer->FindPaneId(rxPaneId));
447     if (pDescriptor.get() != NULL)
448         pDescriptor->SetActivationState(true);
449 }
450 
451 
452 
453 
454 void PresenterPaneAnimatorBase::DeactivatePane (
455     const Reference<drawing::framework::XResourceId>& rxPaneId)
456 {
457     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
458         mpPaneContainer->FindPaneId(rxPaneId));
459     if (pDescriptor.get() != NULL)
460         pDescriptor->SetActivationState(false);
461 }
462 
463 
464 
465 
466 //===== UnfoldInCenterAnimator ================================================
467 
468 UnfoldInCenterAnimator::UnfoldInCenterAnimator (
469     const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
470     const ::rtl::Reference<PresenterController>& rpPresenterController,
471     const bool bAnimate,
472     const EndActions& rShowEndActions,
473     const EndActions& rEndEndActions)
474     : PresenterPaneAnimatorBase(rxPaneId, rpPresenterController, bAnimate,
475         rShowEndActions, rEndEndActions)
476 {
477 }
478 
479 
480 
481 
482 UnfoldInCenterAnimator::~UnfoldInCenterAnimator (void)
483 {
484 }
485 
486 
487 
488 
489 void UnfoldInCenterAnimator::ShowPane (void)
490 {
491     OSL_ASSERT(mpWindowManager.get()!=NULL);
492 
493     Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
494     if ( ! xParentWindow.is())
495         return;
496 
497     Reference<rendering::XSpriteCanvas> xCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
498     if ( ! xCanvas.is())
499         return;
500 
501     Reference<rendering::XBitmap> xParentBitmap (xCanvas, UNO_QUERY);
502     if ( ! xParentBitmap.is())
503         return;
504 
505     Reference<rendering::XGraphicDevice> xDevice(xCanvas->getDevice());
506     if ( ! xDevice.is())
507         return;
508 
509     awt::Rectangle aWindowBox (xParentWindow->getPosSize());
510 
511     // Create two pane groups that will be moved together.  One contains the
512     // notes view, the other group contains all other panes.
513     SetupPaneGroups();
514 
515     // Setup the places where the two pane groups are moved to.
516     maCenterPaneBox
517         = MovePanesAway(geometry::RealRectangle2D(0,200,aWindowBox.Width, aWindowBox.Height-200));
518 
519     // Setup the final size of the new pane so that it fits into the space
520     // between the two pane groups.
521     ResizePane(mxCenterPaneId, maCenterPaneBox);
522 
523     // Avoid that the center pane updates its previews while being animated.
524     DeactivatePane(mxCenterPaneId);
525 
526     // Replace the pane groups with sprites that look like the panes but can
527     // be moved around much faster.
528     FreezePanes(xCanvas);
529 
530     // The vertical center of the new pane.
531     const double nY0 ((maPaneGroups[0]->GetOriginalBoundingBox().Y2
532             + maPaneGroups[1]->GetOriginalBoundingBox().Y1) / 2);
533 
534     // Make sure that the new pane is painted once before the animation starts.
535     SpriteTransform(
536         mpPaneContainer,
537         mxCenterPaneId,
538         xParentWindow,
539         mpPresenterController->GetPaintManager(),
540         true,
541         maCenterPaneBox.X1,
542         nY0,
543         maCenterPaneBox.Y1,
544         0);
545     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
546         mpPaneContainer->FindPaneId(mxCenterPaneId));
547     if (pDescriptor.get() != NULL)
548     {
549         mpPresenterController->GetPaintManager()->Invalidate(
550             pDescriptor->mxBorderWindow,
551             true);
552     }
553 
554     // Animate the upper and lower window bitmaps.
555     ::boost::shared_ptr<MultiAnimation> pMultiAnimation (
556         new MultiAnimation(mbDoAnimation ? 500 : 0));
557 
558     // Animate the pane group sprites to be moved up or down.
559     vector<SharedPaneGroup>::const_iterator iGroup;
560     for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
561     {
562         pMultiAnimation->AddAnimation(
563             ::boost::bind(
564                 InterpolatePosition,
565                 ::boost::protect(::boost::bind(
566                     &PresenterSprite::MoveTo, (*iGroup)->GetSubstitution(), _1)),
567                 _1,
568                 GetLocation((*iGroup)->GetOriginalBoundingBox()),
569                 GetLocation((*iGroup)->GetCurrentBoundingBox())));
570     }
571 
572     // Animate the new center pane to expand.
573     pMultiAnimation->AddAnimation(
574         ::boost::bind(
575             SpriteTransform,
576             mpPaneContainer,
577             mxCenterPaneId,
578             xParentWindow,
579             mpPresenterController->GetPaintManager(),
580             true,
581             maCenterPaneBox.X1,
582             nY0,
583             maCenterPaneBox.Y1,
584             _1));
585 
586     // Call updateScreen after each animation step.
587     if (xCanvas.is())
588         pMultiAnimation->AddAnimation(
589             ::boost::bind(&rendering::XSpriteCanvas::updateScreen, xCanvas, sal_False));
590 
591     // Activate the panes when the animation is over.
592     pMultiAnimation->AddEndCallback(
593         ::boost::bind(&PresenterPaneAnimatorBase::ActivatePanes, shared_from_this()));
594     EndActions::const_iterator iAction;
595     for (iAction=maShowEndActions.begin(); iAction!=maShowEndActions.end(); ++iAction)
596         pMultiAnimation->AddEndCallback(*iAction);
597 
598     // Start the animation.
599     ::boost::shared_ptr<PresenterAnimator> pAnimator (mpPresenterController->GetAnimator());
600     OSL_ASSERT(pAnimator.get()!=NULL);
601     pAnimator->AddAnimation(SharedPresenterAnimation(pMultiAnimation));
602 
603     mpWindowManager->Update();
604 }
605 
606 
607 
608 
609 void UnfoldInCenterAnimator::HidePane (void)
610 {
611     OSL_ASSERT(mpWindowManager.get()!=NULL);
612 
613     Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
614     if ( ! xParentWindow.is())
615         return;
616 
617     DeactivatePanes();
618     DeactivatePane(mxCenterPaneId);
619 
620     ::boost::shared_ptr<PresenterAnimator> pAnimator (mpPresenterController->GetAnimator());
621     const awt::Rectangle aWindowBox (xParentWindow->getPosSize());
622     const rendering::ViewState aViewState (
623         geometry::AffineMatrix2D(1,0,0, 0,1,0),
624         NULL);
625     const rendering::RenderState aRenderState (
626         geometry::AffineMatrix2D(1,0,0, 0,1,0),
627         NULL,
628         Sequence<double>(4),
629         rendering::CompositeOperation::SOURCE);
630 
631     // Animate the uppder and lower window bitmaps.
632     Reference<rendering::XSpriteCanvas> xSpriteCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
633     ::boost::shared_ptr<MultiAnimation> pMultiAnimation (new MultiAnimation(mbDoAnimation ? 500 : 1));
634 
635     vector<SharedPaneGroup>::const_iterator iGroup;
636     for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
637     {
638         pMultiAnimation->AddAnimation(
639             ::boost::bind(
640                 InterpolatePosition,
641                 ::boost::protect(::boost::bind(
642                     &PresenterSprite::MoveTo, (*iGroup)->GetSubstitution(), _1)),
643                 _1,
644                 GetLocation((*iGroup)->GetCurrentBoundingBox()),
645                 GetLocation((*iGroup)->GetOriginalBoundingBox())));
646     }
647 
648     // Animate the new center pane to collapse.
649     const double nY0 ((maPaneGroups[0]->GetOriginalBoundingBox().Y2
650             + maPaneGroups[1]->GetOriginalBoundingBox().Y1) / 2);
651     pMultiAnimation->AddAnimation(
652         ::boost::bind(
653             SpriteTransform,
654             mpPaneContainer,
655             mxCenterPaneId,
656             xParentWindow,
657             mpPresenterController->GetPaintManager(),
658             false,
659             maCenterPaneBox.X1,
660             nY0,
661             maCenterPaneBox.Y1,
662             _1));
663 
664     if (mbDoAnimation)
665     {
666         pMultiAnimation->AddAnimation(
667             ::boost::bind(&rendering::XSpriteCanvas::updateScreen, xSpriteCanvas, sal_False));
668     }
669     pMultiAnimation->AddEndCallback(
670         ::boost::bind(&PresenterPaneAnimatorBase::RestoreFrozenWindows, shared_from_this()));
671     EndActions::const_iterator iAction;
672     for (iAction=maHideEndActions.begin(); iAction!=maHideEndActions.end(); ++iAction)
673         pMultiAnimation->AddEndCallback(*iAction);
674 
675     pAnimator->AddAnimation(SharedPresenterAnimation(pMultiAnimation));
676 }
677 
678 
679 
680 
681 void UnfoldInCenterAnimator::SetupPaneGroups (void)
682 {
683     maPaneGroups.clear();
684 
685     // Setup the upper pane group.
686     SharedPaneGroup pUpperPanes (new PaneGroup());
687     pUpperPanes->AddPane(mpPaneContainer->FindPaneURL(
688         PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
689     pUpperPanes->AddPane(mpPaneContainer->FindPaneURL(
690         PresenterPaneFactory::msNextSlidePreviewPaneURL));
691     pUpperPanes->AddPane(mpPaneContainer->FindPaneURL(
692         PresenterPaneFactory::msToolBarPaneURL));
693     pUpperPanes->AddPane(mpPaneContainer->FindPaneURL(
694         PresenterPaneFactory::msHelpPaneURL));
695     maPaneGroups.push_back(pUpperPanes);
696 
697     // Setup the lower pane group.
698     SharedPaneGroup pLowerPanes (new PaneGroup());
699     pLowerPanes->AddPane(mpPaneContainer->FindPaneURL(
700         PresenterPaneFactory::msNotesPaneURL));
701     maPaneGroups.push_back(pLowerPanes);
702 }
703 
704 
705 
706 
707 geometry::RealRectangle2D UnfoldInCenterAnimator::MovePanesAway (
708     const geometry::RealRectangle2D& rFreeCenterArea)
709 {
710     SharedPaneGroup aUpperPanes = maPaneGroups[0];
711     SharedPaneGroup aLowerPanes = maPaneGroups[1];
712 
713     // Move upper pane group out of the way.
714     const double nTop (rFreeCenterArea.Y1);
715     const double nUpperVerticalOffset (nTop - aUpperPanes->GetOriginalBoundingBox().Y2);
716     aUpperPanes->MovePanes(0, nUpperVerticalOffset, mpWindowManager);
717 
718     // Move lower pane group out of the way.
719     const double nBottom (rFreeCenterArea.Y2);
720     const double nLowerVerticalOffset (nBottom - aLowerPanes->GetOriginalBoundingBox().Y1);
721     aLowerPanes->MovePanes(0, nLowerVerticalOffset, mpWindowManager);
722 
723     return geometry::RealRectangle2D(
724         ::std::min(
725             aUpperPanes->GetOriginalBoundingBox().X1,
726             aLowerPanes->GetOriginalBoundingBox().X1),
727         nTop+20,
728         ::std::max(
729             aUpperPanes->GetOriginalBoundingBox().X2,
730             aLowerPanes->GetOriginalBoundingBox().X2),
731         nBottom-20);
732 }
733 
734 
735 
736 
737 //===== MoveInFromBottomAnimator ==============================================
738 
739 MoveInFromBottomAnimator::MoveInFromBottomAnimator (
740     const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
741     const ::rtl::Reference<PresenterController>& rpPresenterController,
742     const bool bAnimate,
743     const EndActions& rShowEndActions,
744     const EndActions& rEndEndActions)
745     : PresenterPaneAnimatorBase(rxPaneId, rpPresenterController, bAnimate,
746         rShowEndActions, rEndEndActions),
747       maNewPaneSprite()
748 {
749 }
750 
751 
752 
753 
754 MoveInFromBottomAnimator::~MoveInFromBottomAnimator (void)
755 {
756 }
757 
758 
759 
760 
761 void MoveInFromBottomAnimator::ShowPane (void)
762 {
763     OSL_ASSERT(mpWindowManager.get()!=NULL);
764 
765     Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
766     if ( ! xParentWindow.is())
767         return;
768 
769     Reference<rendering::XSpriteCanvas> xCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
770     if ( ! xCanvas.is())
771         return;
772 
773     Reference<rendering::XBitmap> xParentBitmap (xCanvas, UNO_QUERY);
774     if ( ! xParentBitmap.is())
775         return;
776 
777     Reference<rendering::XGraphicDevice> xDevice(xCanvas->getDevice());
778     if ( ! xDevice.is())
779         return;
780 
781     awt::Rectangle aWindowBox (xParentWindow->getPosSize());
782 
783     // Create a pane group that just contains the notes view.
784     SharedPaneGroup pLowerPanes (new PaneGroup());
785     pLowerPanes->AddPane(mpPaneContainer->FindPaneURL(
786         PresenterPaneFactory::msNotesPaneURL));
787     maPaneGroups.push_back(pLowerPanes);
788 
789     // Deactivate the panes that will take place in the animation.
790     pLowerPanes->DeactivatePanes();
791     DeactivatePane(mxCenterPaneId);
792 
793     // Set the size of the new pane.
794     maCenterPaneBox = pLowerPanes->GetOriginalBoundingBox();
795     ResizePane(mxCenterPaneId, maCenterPaneBox);
796 
797     geometry::RealPoint2D aStartLocation (maCenterPaneBox.X1, aWindowBox.Height);
798     geometry::RealPoint2D aEndLocation (maCenterPaneBox.X1, maCenterPaneBox.Y1);
799 
800     // Get the sprite of the new pane, make it visible and move it to the
801     // start location.
802     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
803         mpPaneContainer->FindPaneId(mxCenterPaneId));
804     if (pDescriptor.get() != NULL)
805     {
806         if (pDescriptor->mxBorderWindow.is())
807             pDescriptor->mxBorderWindow->setVisible(sal_True);
808 
809         maNewPaneSprite = pDescriptor->maSpriteProvider();
810         if (maNewPaneSprite.get() != NULL)
811         {
812             maNewPaneSprite->MoveTo(aStartLocation);
813             maNewPaneSprite->Show();
814         }
815         xCanvas->updateScreen(sal_False);
816     }
817 
818     CreateShowAnimation(
819         mxCenterPaneId,
820         maShowEndActions,
821         xCanvas,
822         mbDoAnimation,
823         aStartLocation,
824         aEndLocation);
825 
826     mpWindowManager->Update();
827 }
828 
829 
830 
831 
832 void MoveInFromBottomAnimator::HidePane (void)
833 {
834     OSL_ASSERT(mpWindowManager.get()!=NULL);
835 
836     Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
837     if ( ! xParentWindow.is())
838         return;
839 
840     Reference<rendering::XSpriteCanvas> xCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
841     if ( ! xCanvas.is())
842         return;
843 
844     DeactivatePanes();
845     DeactivatePane(mxCenterPaneId);
846 
847     SharedPaneGroup aPanes (maPaneGroups[0]);
848 
849     aPanes->ShowPanes();
850 
851     ::boost::shared_ptr<MultiAnimation> pMultiAnimation (
852         new MultiAnimation(mbDoAnimation ? 500 : 0));
853     awt::Rectangle aWindowBox (xParentWindow->getPosSize());
854 
855     // Animate the new center pane to collapse.
856     pMultiAnimation->AddAnimation(
857         ::boost::bind(
858             InterpolatePosition,
859             ::boost::protect(::boost::bind(&SpritePaneMove, mpPaneContainer, mxCenterPaneId, _1)),
860             _1,
861             geometry::RealPoint2D(maCenterPaneBox.X1, maCenterPaneBox.Y1),
862             geometry::RealPoint2D(maCenterPaneBox.X1, aWindowBox.Height)));
863 
864     if (mbDoAnimation)
865     {
866         pMultiAnimation->AddAnimation(
867             ::boost::bind(&rendering::XSpriteCanvas::updateScreen, xCanvas, sal_False));
868     }
869     pMultiAnimation->AddEndCallback(
870         ::boost::bind(&PresenterPaneAnimatorBase::RestoreFrozenWindows, shared_from_this()));
871     EndActions::const_iterator iAction;
872     for (iAction=maHideEndActions.begin(); iAction!=maHideEndActions.end(); ++iAction)
873         pMultiAnimation->AddEndCallback(*iAction);
874 
875     ::boost::shared_ptr<PresenterAnimator> pAnimator (mpPresenterController->GetAnimator());
876     pAnimator->AddAnimation(SharedPresenterAnimation(pMultiAnimation));
877 }
878 
879 
880 
881 
882 void MoveInFromBottomAnimator::CreateShowAnimation (
883     const Reference<drawing::framework::XResourceId>& rxPaneId,
884     const EndOperators& rEndOperators,
885     const Reference<rendering::XSpriteCanvas>& rxSpriteCanvas,
886     const bool bAnimate,
887     const geometry::RealPoint2D& rStartLocation,
888     const geometry::RealPoint2D& rEndLocation)
889 {
890     // Animate the uppder and lower window bitmaps.
891     ::boost::shared_ptr<MultiAnimation> pMultiAnimation (new MultiAnimation(bAnimate ? 500 : 0));
892 
893     // Animate new pane to move in from the buttom.
894     pMultiAnimation->AddAnimation(
895         ::boost::bind(
896             InterpolatePosition,
897             ::boost::protect(::boost::bind(&SpritePaneMove, mpPaneContainer, rxPaneId, _1)),
898             _1,
899             rStartLocation,
900             rEndLocation));
901 
902     // Call updateScreen after each animation step.
903     if (rxSpriteCanvas.is())
904         pMultiAnimation->AddAnimation(
905             ::boost::bind(&rendering::XSpriteCanvas::updateScreen, rxSpriteCanvas, sal_False));
906 
907     // Activate the panes when the animation is over.
908     pMultiAnimation->AddEndCallback(
909         ::boost::bind(&PaneGroup::HidePanes, maPaneGroups[0]));
910     pMultiAnimation->AddEndCallback(
911         ::boost::bind(&PresenterPaneAnimatorBase::ActivatePane, shared_from_this(), mxCenterPaneId));
912     EndActions::const_iterator iAction;
913     for (iAction=rEndOperators.begin(); iAction!=rEndOperators.end(); ++iAction)
914         pMultiAnimation->AddEndCallback(*iAction);
915 
916     // Start the animation.
917     ::boost::shared_ptr<PresenterAnimator> pAnimator (mpPresenterController->GetAnimator());
918     OSL_ASSERT(pAnimator.get()!=NULL);
919     pAnimator->AddAnimation(SharedPresenterAnimation(pMultiAnimation));
920 }
921 
922 
923 
924 
925 
926 //===== TransparentOverlayAnimator ============================================
927 
928 TransparentOverlayAnimator::TransparentOverlayAnimator (
929     const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
930     const ::rtl::Reference<PresenterController>& rpPresenterController,
931     const bool bAnimate,
932     const EndActions& rShowEndActions,
933     const EndActions& rEndEndActions)
934     : PresenterPaneAnimatorBase(
935         rxPaneId,
936         rpPresenterController,
937         bAnimate,
938         rShowEndActions,
939         rEndEndActions),
940       maBackgroundSprite()
941 {
942 }
943 
944 
945 
946 
947 TransparentOverlayAnimator::~TransparentOverlayAnimator (void)
948 {
949 }
950 
951 
952 
953 
954 void TransparentOverlayAnimator::ShowPane (void)
955 {
956     EndActions::const_iterator iAction;
957     for (iAction=maShowEndActions.begin(); iAction!=maShowEndActions.end(); ++iAction)
958         (*iAction)();
959 
960     CreateBackgroundSprite();
961 
962     Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
963     if (xParentWindow.is())
964     {
965         const awt::Rectangle aWindowBox (xParentWindow->getPosSize());
966         SharedPaneGroup pAllPanes (new PaneGroup());
967         pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
968             PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
969         pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
970             PresenterPaneFactory::msNextSlidePreviewPaneURL));
971         pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
972             PresenterPaneFactory::msToolBarPaneURL));
973         pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
974             PresenterPaneFactory::msHelpPaneURL));
975         pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
976             PresenterPaneFactory::msNotesPaneURL));
977         maPaneGroups.push_back(pAllPanes);
978         pAllPanes->DeactivatePanes();
979         mpWindowManager->Update();
980     }
981 
982     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
983         mpPaneContainer->FindPaneId(mxCenterPaneId));
984     if (pDescriptor.get() != NULL)
985     {
986         PresenterSpritePane* pPane = dynamic_cast<PresenterSpritePane*>(
987             pDescriptor->mxPane.get());
988         if (pPane != NULL)
989             pPane->ShowTransparentBorder();
990 
991         pDescriptor->SetActivationState(true);
992         if (pDescriptor->mxBorderWindow.is())
993             pDescriptor->mxBorderWindow->setVisible(sal_True);
994     }
995 }
996 
997 
998 
999 
1000 void TransparentOverlayAnimator::HidePane (void)
1001 {
1002     maPaneGroups[0]->ActivatePanes();
1003     EndActions::const_iterator iAction;
1004     for (iAction=maHideEndActions.begin(); iAction!=maHideEndActions.end(); ++iAction)
1005         (*iAction)();
1006     mpWindowManager->Update();
1007 }
1008 
1009 
1010 
1011 
1012 void TransparentOverlayAnimator::CreateBackgroundSprite (void)
1013 {
1014     Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
1015     Reference<rendering::XSpriteCanvas> xParentCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
1016     if (xParentWindow.is() && xParentCanvas.is())
1017     {
1018         const awt::Rectangle aWindowBox (xParentWindow->getPosSize());
1019         maBackgroundSprite.SetFactory(xParentCanvas);
1020         maBackgroundSprite.Resize(
1021             geometry::RealSize2D(aWindowBox.Width, aWindowBox.Height));
1022         maBackgroundSprite.MoveTo(
1023             geometry::RealPoint2D(aWindowBox.X, aWindowBox.Y));
1024         maBackgroundSprite.SetAlpha(0.5);
1025         maBackgroundSprite.Show();
1026 
1027         Reference<rendering::XCanvas> xCanvas (maBackgroundSprite.GetCanvas());
1028 
1029         if (xCanvas.is())
1030         {
1031             rendering::ViewState aViewState(
1032                 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1033                 NULL);
1034 
1035             rendering::RenderState aRenderState(
1036                 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1037                 NULL,
1038                 Sequence<double>(4),
1039                 rendering::CompositeOperation::SOURCE);
1040             PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x80808080));
1041 
1042             Reference<rendering::XPolyPolygon2D> xPolygon (
1043                 PresenterGeometryHelper::CreatePolygon(aWindowBox, xCanvas->getDevice()));
1044             if (xPolygon.is())
1045                 xCanvas->fillPolyPolygon(
1046                     xPolygon,
1047                     aViewState,
1048                     aRenderState);
1049         }
1050     }
1051 }
1052 
1053 
1054 
1055 
1056 //===== PaneGroup =============================================================
1057 
1058 PaneGroup::PaneGroup (void)
1059     : maPanes(),
1060       maOriginalBoundingBox(),
1061       maCurrentBoundingBox(),
1062       mpSubstitution(new PresenterSprite())
1063 {
1064 }
1065 
1066 
1067 
1068 
1069 PaneGroup::~PaneGroup (void)
1070 {
1071     mpSubstitution.reset();
1072 }
1073 
1074 
1075 
1076 
1077 void PaneGroup::AddPane (const PresenterPaneContainer::SharedPaneDescriptor& rpPane)
1078 {
1079     OSL_ASSERT(rpPane.get() != NULL);
1080 
1081     if (rpPane->mxBorderWindow.is())
1082     {
1083         PaneDescriptor aDescriptor (rpPane);
1084         maPanes.push_back(aDescriptor);
1085         maOriginalBoundingBox = PresenterGeometryHelper::Union(
1086             maOriginalBoundingBox,
1087             rpPane->mxBorderWindow->getPosSize());
1088     }
1089 }
1090 
1091 
1092 
1093 
1094 void PaneGroup::CreateSubstitution (const Reference<rendering::XSpriteCanvas>& rxCanvas)
1095 {
1096     // Get the bitmap of the background.
1097     Reference<rendering::XBitmap> xBackgroundBitmap (rxCanvas, UNO_QUERY);
1098     if ( ! xBackgroundBitmap.is())
1099         return;
1100 
1101     // Create the sprite.
1102     mpSubstitution->SetFactory(rxCanvas);
1103     mpSubstitution->Resize(
1104         geometry::RealSize2D(maOriginalBoundingBox.Width, maOriginalBoundingBox.Height));
1105 
1106     // Fill it with the background inside the bounding box.
1107     const rendering::ViewState aViewState (
1108         geometry::AffineMatrix2D(1,0,0, 0,1,0),
1109         NULL);
1110     const rendering::RenderState aRenderState (
1111         geometry::AffineMatrix2D(1,0,-maOriginalBoundingBox.X, 0,1,-maOriginalBoundingBox.Y),
1112         NULL,
1113         Sequence<double>(4),
1114         rendering::CompositeOperation::SOURCE);
1115 
1116     Reference<rendering::XCanvas> xSpriteCanvas (mpSubstitution->GetCanvas());
1117     if (xSpriteCanvas.is())
1118         xSpriteCanvas->drawBitmap(xBackgroundBitmap, aViewState, aRenderState);
1119 }
1120 
1121 
1122 
1123 
1124 void PaneGroup::Restore (void)
1125 {
1126     vector<PaneDescriptor>::iterator iPane;
1127     for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
1128     {
1129         iPane->Restore();
1130     }
1131 }
1132 
1133 
1134 
1135 
1136 ::boost::shared_ptr<PresenterSprite> PaneGroup::GetSubstitution (void)
1137 {
1138     return mpSubstitution;
1139 }
1140 
1141 
1142 
1143 
1144 geometry::RealRectangle2D PaneGroup::GetOriginalBoundingBox (void) const
1145 {
1146     return geometry::RealRectangle2D(
1147         maOriginalBoundingBox.X,
1148         maOriginalBoundingBox.Y,
1149         maOriginalBoundingBox.X + maOriginalBoundingBox.Width,
1150         maOriginalBoundingBox.Y + maOriginalBoundingBox.Height);
1151 }
1152 
1153 
1154 
1155 
1156 geometry::RealRectangle2D PaneGroup::GetCurrentBoundingBox (void) const
1157 {
1158     return maCurrentBoundingBox;
1159 }
1160 
1161 
1162 
1163 
1164 void PaneGroup::MovePanes (
1165     const double nXOffset,
1166     const double nYOffset,
1167     const ::rtl::Reference<PresenterWindowManager>& rpWindowManager
1168     )
1169 {
1170     awt::Rectangle aBBox;
1171     vector<PaneDescriptor>::iterator iPane;
1172     for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
1173     {
1174         awt::Rectangle aBox (iPane->mpPaneDescriptor->mxBorderWindow->getPosSize());
1175         aBox.X += sal_Int32(nXOffset);
1176         aBox.Y += sal_Int32(nYOffset);
1177         rpWindowManager->SetPanePosSizeAbsolute(
1178             iPane->mpPaneDescriptor->mxPaneId->getResourceURL(),
1179             aBox.X,
1180             aBox.Y,
1181             aBox.Width,
1182             aBox.Height);
1183         aBBox = PresenterGeometryHelper::Union(aBBox, aBox);
1184     }
1185     maCurrentBoundingBox = geometry::RealRectangle2D(
1186         aBBox.X, aBBox.Y, aBBox.X+aBBox.Width, aBBox.Y+aBBox.Height);
1187 }
1188 
1189 
1190 
1191 
1192 void PaneGroup::ActivatePanes (void)
1193 {
1194     vector<PaneDescriptor>::iterator iPane;
1195     for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
1196     {
1197         iPane->mpPaneDescriptor->SetActivationState(true);
1198     }
1199 }
1200 
1201 
1202 
1203 
1204 void PaneGroup::DeactivatePanes (void)
1205 {
1206     vector<PaneDescriptor>::iterator iPane;
1207     for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
1208     {
1209         iPane->mpPaneDescriptor->SetActivationState(false);
1210     }
1211 }
1212 
1213 
1214 
1215 
1216 void PaneGroup::ShowPanes (void)
1217 {
1218     vector<PaneDescriptor>::iterator iPane;
1219     for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
1220     {
1221         iPane->mpPaneDescriptor->mxBorderWindow->setVisible(sal_True);
1222         iPane->mpPaneDescriptor->mxContentWindow->setVisible(sal_True);
1223     }
1224 }
1225 
1226 
1227 
1228 
1229 void PaneGroup::HidePanes (void)
1230 {
1231     vector<PaneDescriptor>::iterator iPane;
1232     for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
1233     {
1234         iPane->mpPaneDescriptor->mxBorderWindow->setVisible(sal_False);
1235         iPane->mpPaneDescriptor->mxContentWindow->setVisible(sal_False);
1236     }
1237 }
1238 
1239 
1240 
1241 
1242 //===== PaneDescriptor ========================================================
1243 
1244 PaneDescriptor::PaneDescriptor (const PresenterPaneContainer::SharedPaneDescriptor& rpDescriptor)
1245     : mpPaneDescriptor(rpDescriptor),
1246       mnLeft(rpDescriptor->mnLeft),
1247       mnTop(rpDescriptor->mnTop),
1248       mnRight(rpDescriptor->mnRight),
1249       mnBottom(rpDescriptor->mnBottom)
1250 {
1251 }
1252 
1253 
1254 
1255 
1256 void PaneDescriptor::Restore (void) const
1257 {
1258     mpPaneDescriptor->mnLeft = mnLeft;
1259     mpPaneDescriptor->mnTop = mnTop;
1260     mpPaneDescriptor->mnRight = mnRight;
1261     mpPaneDescriptor->mnBottom = mnBottom;
1262 }
1263 
1264 
1265 
1266 
1267 //===== MultiAnimation ========================================================
1268 
1269 MultiAnimation::MultiAnimation (const sal_uInt32 nDuration)
1270     : PresenterAnimation(0, nDuration, 1000/50),
1271       maAnimations()
1272 {
1273 }
1274 
1275 
1276 
1277 
1278 void MultiAnimation::AddAnimation (const Animation& rAnimation)
1279 {
1280     maAnimations.push_back(rAnimation);
1281 }
1282 
1283 
1284 
1285 
1286 void MultiAnimation::Run (const double nProgress, const sal_uInt64 nCurrentTime)
1287 {
1288     (void)nCurrentTime;
1289     vector<Animation>::const_iterator iAnimation (maAnimations.begin());
1290     vector<Animation>::const_iterator iEnd (maAnimations.end());
1291     for ( ; iAnimation!=iEnd; ++iAnimation)
1292         (*iAnimation)(nProgress);
1293 }
1294 
1295 
1296 
1297 
1298 //===== functors ==============================================================
1299 
1300 void InterpolatePosition (
1301     const ::boost::function<void(geometry::RealPoint2D)>& rSetter,
1302     double nP,
1303     const geometry::RealPoint2D rInitialBox,
1304     const geometry::RealPoint2D rFinalBox)
1305 {
1306     const double nQ (1 - nP);
1307 
1308     OSL_TRACE("InterpolatePosition %f\n", nP);
1309     rSetter(
1310         geometry::RealPoint2D(
1311             nQ * rInitialBox.X + nP * rFinalBox.X,
1312             nQ * rInitialBox.Y + nP * rFinalBox.Y));
1313 }
1314 
1315 
1316 
1317 
1318 template<typename T>
1319     void InterpolateValue (
1320         const ::boost::function<void(T)>& rSetter,
1321         double nP,
1322         const T aInitialValue,
1323         const T aFinalValue)
1324 {
1325     const double nQ (1 - nP);
1326 
1327     rSetter(T(nQ * aInitialValue + nP * aFinalValue));
1328 }
1329 
1330 
1331 
1332 
1333 void SpriteTransform(
1334     const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
1335     const Reference<XResourceId>& rxPaneId,
1336     const Reference<awt::XWindow>& rxSpriteOwnerWindow,
1337     const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
1338     const bool bAppear,
1339     const double nX,
1340     const double nInitialTop,
1341     const double nFinalTop,
1342     const double nP)
1343 {
1344     OSL_ASSERT(rpPaintManager.get()!=NULL);
1345 
1346     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
1347         rpPaneContainer->FindPaneId(rxPaneId));
1348     if (pDescriptor.get() != NULL
1349         && ! pDescriptor->maSpriteProvider.empty()
1350         && pDescriptor->mxBorderWindow.is())
1351     {
1352         ::boost::shared_ptr<PresenterSprite> pSprite (pDescriptor->maSpriteProvider());
1353         if (pSprite.get())
1354         {
1355             // There seems to be a problem with sprites not correctly
1356             // invalidating the background when being transformed.  As a
1357             // workaround invalidate the background in the bounding box of
1358             // the sprite before the transformation.
1359             rpPaintManager->Invalidate(
1360                 rxSpriteOwnerWindow,
1361                 awt::Rectangle(
1362                     sal::static_int_cast<sal_Int32>(pSprite->GetLocation().X),
1363                     sal::static_int_cast<sal_Int32>(pSprite->GetLocation().Y),
1364                     sal::static_int_cast<sal_Int32>(pSprite->GetSize().Width),
1365                     sal::static_int_cast<sal_Int32>(pSprite->GetSize().Height)));
1366 
1367             const double nYScale (bAppear ? nP : 1-nP);
1368             pSprite->Transform(geometry::AffineMatrix2D(
1369                 1, 0, 0,
1370                 0, nYScale, 0));
1371             pSprite->MoveTo(
1372                 geometry::RealPoint2D(nX, nYScale*nFinalTop + (1-nYScale)*nInitialTop));
1373             pSprite->Show();
1374 
1375             pDescriptor->mxBorderWindow->setVisible(sal_True);
1376         }
1377     }
1378 }
1379 
1380 
1381 
1382 
1383 void SpritePaneMove (
1384     const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
1385     const Reference<XResourceId>& rxPaneId,
1386     const geometry::RealPoint2D& rLocation)
1387 {
1388     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
1389         rpPaneContainer->FindPaneId(rxPaneId));
1390     if (pDescriptor.get() != NULL
1391         && ! pDescriptor->maSpriteProvider.empty()
1392         && pDescriptor->mxBorderWindow.is())
1393     {
1394         ::boost::shared_ptr<PresenterSprite> pSprite (pDescriptor->maSpriteProvider());
1395         if (pSprite.get() != NULL)
1396         {
1397             pDescriptor->mxBorderWindow->setVisible(sal_True);
1398             pSprite->MoveTo(rLocation);
1399         }
1400     }
1401 }
1402 
1403 
1404 
1405 
1406 geometry::RealPoint2D GetLocation (const geometry::RealRectangle2D& rBox)
1407 {
1408     return geometry::RealPoint2D(rBox.X1, rBox.Y1);
1409 }
1410 
1411 
1412 
1413 
1414 geometry::RealSize2D GetSize (const geometry::RealRectangle2D& rBox)
1415 {
1416     return geometry::RealSize2D(rBox.X2-rBox.X1, rBox.Y2-rBox.Y1);
1417 }
1418 
1419 } // end of anonymous namespace
1420 
1421 
1422 
1423 
1424 } } // end of namespace ::sdext::presenter
1425