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_svx.hxx"
30 #include <svx/sdr/animation/animationstate.hxx>
31 #include <tools/debug.hxx>
32 #include <svx/sdr/contact/viewobjectcontact.hxx>
33 #include <svx/sdr/animation/objectanimator.hxx>
34 #include <svx/sdr/contact/objectcontact.hxx>
35 #include <svx/sdr/contact/viewcontact.hxx>
36 #include <drawinglayer/primitive2d/animatedprimitive2d.hxx>
37 #include <drawinglayer/animation/animationtiming.hxx>
38 
39 //////////////////////////////////////////////////////////////////////////////
40 
41 namespace sdr
42 {
43 	namespace animation
44 	{
45 		double PrimitiveAnimation::getSmallestNextTime(double fCurrentTime)
46 		{
47 			double fRetval(0.0);
48 
49 			if(maAnimatedPrimitives.hasElements())
50 			{
51 				const sal_Int32 nCount(maAnimatedPrimitives.getLength());
52 
53 				for(sal_Int32 a(0L); a < nCount; a++)
54 				{
55 					const drawinglayer::primitive2d::Primitive2DReference xRef(maAnimatedPrimitives[a]);
56 					const drawinglayer::primitive2d::AnimatedSwitchPrimitive2D* pCandidate = dynamic_cast< const drawinglayer::primitive2d::AnimatedSwitchPrimitive2D* >(xRef.get());
57 					OSL_ENSURE(pCandidate, "PrimitiveAnimation::getSmallestNextTime: wrong primitive in animated list (!)");
58 
59 					if(pCandidate)
60 					{
61 						const drawinglayer::animation::AnimationEntry& rAnimEntry = pCandidate->getAnimationEntry();
62 						const double fNextTime(rAnimEntry.getNextEventTime(fCurrentTime));
63 
64 						if(!::basegfx::fTools::equalZero(fNextTime))
65 						{
66 							if(::basegfx::fTools::equalZero(fRetval))
67 							{
68 								fRetval = fNextTime;
69 							}
70 							else if(::basegfx::fTools::less(fNextTime, fRetval))
71 							{
72 								fRetval = fNextTime;
73 							}
74 						}
75 					}
76 				}
77 			}
78 
79 			return fRetval;
80 		}
81 
82 		void PrimitiveAnimation::prepareNextEvent()
83 		{
84 			const double fCurrentTime(mrVOContact.GetObjectContact().getPrimitiveAnimator().GetTime());
85 			const double fNextTime(getSmallestNextTime(fCurrentTime));
86 
87 			// getSmallestNextTime will be zero when animation ended. If not zero, a next step
88 			// exists
89 			if(!::basegfx::fTools::equalZero(fNextTime))
90 			{
91 				// next time point exists, use it
92 				sal_uInt32 nNextTime;
93 
94 				if(fNextTime >= (double)0xffffff00)
95 				{
96 					// take care for very late points in time, e.g. when a text animation stops
97 					// in a defined AnimationEntryFixed with endless (0xffffffff) duration
98 					nNextTime = GetTime() + (1000 * 60 * 60); // one hour, works with vcl timers, 0xffffff00 was too much...
99 				}
100 				else
101 				{
102 					nNextTime = (sal_uInt32)fNextTime;
103 				}
104 
105 				// ensure step forward in integer timing, the floating step difference maybe smaller than 1.0. Use
106 				// at least 25ms for next step
107 				const sal_uInt32 nMinimumStepTime((sal_uInt32)fCurrentTime + 25L);
108 
109 				if(nNextTime <= nMinimumStepTime)
110 				{
111 					nNextTime = nMinimumStepTime;
112 				}
113 
114 				// set time and reactivate by re-adding to the scheduler
115 				SetTime(nNextTime);
116 				mrVOContact.GetObjectContact().getPrimitiveAnimator().InsertEvent(this);
117 			}
118 		}
119 
120 		PrimitiveAnimation::PrimitiveAnimation(sdr::contact::ViewObjectContact& rVOContact, const drawinglayer::primitive2d::Primitive2DSequence& rAnimatedPrimitives)
121 		:	Event(0L),
122 			mrVOContact(rVOContact),
123 			maAnimatedPrimitives(rAnimatedPrimitives)
124 		{
125 			// setup initially
126 			prepareNextEvent();
127 		}
128 
129 		PrimitiveAnimation::~PrimitiveAnimation()
130 		{
131 			// ensure that Event member is removed from PrimitiveAnimator
132 			mrVOContact.GetObjectContact().getPrimitiveAnimator().RemoveEvent(this);
133 		}
134 
135 		// execute event, from base class Event
136 		void PrimitiveAnimation::Trigger(sal_uInt32 /*nTime*/)
137 		{
138 			// schedule a repaint of associated object
139 			mrVOContact.ActionChanged();
140 
141 			// re-setup
142 			prepareNextEvent();
143 		}
144 	} // end of namespace animation
145 } // end of namespace sdr
146 
147 //////////////////////////////////////////////////////////////////////////////
148 // eof
149