1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_slideshow.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <canvas/debug.hxx>
28*b1cdbd2cSJim Jagielski #include <tools/diagnose_ex.h>
29*b1cdbd2cSJim Jagielski #include <canvas/elapsedtime.hxx>
30*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolygontools.hxx>
31*b1cdbd2cSJim Jagielski 
32*b1cdbd2cSJim Jagielski #include <comphelper/anytostring.hxx>
33*b1cdbd2cSJim Jagielski #include <cppuhelper/exc_hlp.hxx>
34*b1cdbd2cSJim Jagielski 
35*b1cdbd2cSJim Jagielski #include <rtl/math.hxx>
36*b1cdbd2cSJim Jagielski #include <vcl/metric.hxx>
37*b1cdbd2cSJim Jagielski #include <vcl/salbtype.hxx>
38*b1cdbd2cSJim Jagielski #include <vcl/canvastools.hxx>
39*b1cdbd2cSJim Jagielski #include <vcl/metaact.hxx>
40*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/XPropertySet.hpp>
41*b1cdbd2cSJim Jagielski #include <com/sun/star/drawing/TextAnimationKind.hpp>
42*b1cdbd2cSJim Jagielski #include <com/sun/star/drawing/TextAnimationDirection.hpp>
43*b1cdbd2cSJim Jagielski #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
44*b1cdbd2cSJim Jagielski #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
45*b1cdbd2cSJim Jagielski #include <com/sun/star/drawing/HomogenMatrix3.hpp>
46*b1cdbd2cSJim Jagielski #include <com/sun/star/awt/Rectangle.hpp>
47*b1cdbd2cSJim Jagielski 
48*b1cdbd2cSJim Jagielski #include "activity.hxx"
49*b1cdbd2cSJim Jagielski #include "wakeupevent.hxx"
50*b1cdbd2cSJim Jagielski #include "eventqueue.hxx"
51*b1cdbd2cSJim Jagielski #include "drawshapesubsetting.hxx"
52*b1cdbd2cSJim Jagielski #include "drawshape.hxx"
53*b1cdbd2cSJim Jagielski #include "shapesubset.hxx"
54*b1cdbd2cSJim Jagielski #include "shapeattributelayerholder.hxx"
55*b1cdbd2cSJim Jagielski #include "slideshowcontext.hxx"
56*b1cdbd2cSJim Jagielski #include "tools.hxx"
57*b1cdbd2cSJim Jagielski #include "gdimtftools.hxx"
58*b1cdbd2cSJim Jagielski #include "eventmultiplexer.hxx"
59*b1cdbd2cSJim Jagielski #include "intrinsicanimationactivity.hxx"
60*b1cdbd2cSJim Jagielski #include "intrinsicanimationeventhandler.hxx"
61*b1cdbd2cSJim Jagielski 
62*b1cdbd2cSJim Jagielski #include <boost/weak_ptr.hpp>
63*b1cdbd2cSJim Jagielski #include <boost/enable_shared_from_this.hpp>
64*b1cdbd2cSJim Jagielski #include <boost/noncopyable.hpp>
65*b1cdbd2cSJim Jagielski #include <vector>
66*b1cdbd2cSJim Jagielski 
67*b1cdbd2cSJim Jagielski using namespace com::sun::star;
68*b1cdbd2cSJim Jagielski using namespace ::slideshow::internal;
69*b1cdbd2cSJim Jagielski 
70*b1cdbd2cSJim Jagielski namespace {
71*b1cdbd2cSJim Jagielski 
72*b1cdbd2cSJim Jagielski class ScrollTextAnimNode
73*b1cdbd2cSJim Jagielski {
74*b1cdbd2cSJim Jagielski     sal_uInt32  mnDuration; // single duration
75*b1cdbd2cSJim Jagielski     sal_uInt32  mnRepeat; // 0 -> endless
76*b1cdbd2cSJim Jagielski     double      mfStart;
77*b1cdbd2cSJim Jagielski     double      mfStop;
78*b1cdbd2cSJim Jagielski     sal_uInt32  mnFrequency; // in ms
79*b1cdbd2cSJim Jagielski     // forth and back change at mnRepeat%2:
80*b1cdbd2cSJim Jagielski     bool        mbAlternate;
81*b1cdbd2cSJim Jagielski 
82*b1cdbd2cSJim Jagielski public:
ScrollTextAnimNode(sal_uInt32 nDuration,sal_uInt32 nRepeat,double fStart,double fStop,sal_uInt32 nFrequency,bool bAlternate)83*b1cdbd2cSJim Jagielski     ScrollTextAnimNode(
84*b1cdbd2cSJim Jagielski         sal_uInt32 nDuration, sal_uInt32 nRepeat, double fStart, double fStop,
85*b1cdbd2cSJim Jagielski         sal_uInt32 nFrequency, bool bAlternate)
86*b1cdbd2cSJim Jagielski         :   mnDuration(nDuration),
87*b1cdbd2cSJim Jagielski             mnRepeat(nRepeat),
88*b1cdbd2cSJim Jagielski             mfStart(fStart),
89*b1cdbd2cSJim Jagielski             mfStop(fStop),
90*b1cdbd2cSJim Jagielski             mnFrequency(nFrequency),
91*b1cdbd2cSJim Jagielski             mbAlternate(bAlternate)
92*b1cdbd2cSJim Jagielski         {}
93*b1cdbd2cSJim Jagielski 
GetDuration() const94*b1cdbd2cSJim Jagielski     sal_uInt32 GetDuration() const { return mnDuration; }
GetRepeat() const95*b1cdbd2cSJim Jagielski     sal_uInt32 GetRepeat() const { return mnRepeat; }
GetFullTime() const96*b1cdbd2cSJim Jagielski     sal_uInt32 GetFullTime() const { return mnDuration * mnRepeat; }
GetStart() const97*b1cdbd2cSJim Jagielski     double GetStart() const { return mfStart; }
GetStop() const98*b1cdbd2cSJim Jagielski     double GetStop() const { return mfStop; }
GetFrequency() const99*b1cdbd2cSJim Jagielski     sal_uInt32 GetFrequency() const { return mnFrequency; }
DoAlternate() const100*b1cdbd2cSJim Jagielski     bool DoAlternate() const { return mbAlternate; }
101*b1cdbd2cSJim Jagielski 
102*b1cdbd2cSJim Jagielski     double GetStateAtRelativeTime(sal_uInt32 nRelativeTime) const;
103*b1cdbd2cSJim Jagielski };
104*b1cdbd2cSJim Jagielski 
GetStateAtRelativeTime(sal_uInt32 nRelativeTime) const105*b1cdbd2cSJim Jagielski double ScrollTextAnimNode::GetStateAtRelativeTime(
106*b1cdbd2cSJim Jagielski     sal_uInt32 nRelativeTime) const
107*b1cdbd2cSJim Jagielski {
108*b1cdbd2cSJim Jagielski     // #151174# Avoid division by zero.
109*b1cdbd2cSJim Jagielski     if( mnDuration == 0 )
110*b1cdbd2cSJim Jagielski         return mfStop;
111*b1cdbd2cSJim Jagielski 
112*b1cdbd2cSJim Jagielski     if(mnRepeat)
113*b1cdbd2cSJim Jagielski     {
114*b1cdbd2cSJim Jagielski         // ending
115*b1cdbd2cSJim Jagielski         const sal_uInt32 nRepeatCount(nRelativeTime / mnDuration);
116*b1cdbd2cSJim Jagielski         sal_uInt32 nFrameTime(nRelativeTime - (nRepeatCount * mnDuration));
117*b1cdbd2cSJim Jagielski 
118*b1cdbd2cSJim Jagielski         if(DoAlternate() && (nRepeatCount + 1L) % 2L)
119*b1cdbd2cSJim Jagielski             nFrameTime = mnDuration - nFrameTime;
120*b1cdbd2cSJim Jagielski 
121*b1cdbd2cSJim Jagielski         return mfStart + ((mfStop - mfStart) *
122*b1cdbd2cSJim Jagielski                           (double(nFrameTime) / mnDuration));
123*b1cdbd2cSJim Jagielski     }
124*b1cdbd2cSJim Jagielski     else
125*b1cdbd2cSJim Jagielski     {
126*b1cdbd2cSJim Jagielski         // endless
127*b1cdbd2cSJim Jagielski         sal_uInt32 nFrameTime(nRelativeTime % mnDuration);
128*b1cdbd2cSJim Jagielski 
129*b1cdbd2cSJim Jagielski         if(DoAlternate())
130*b1cdbd2cSJim Jagielski         {
131*b1cdbd2cSJim Jagielski             const sal_uInt32 nRepeatCount(nRelativeTime / mnDuration);
132*b1cdbd2cSJim Jagielski 
133*b1cdbd2cSJim Jagielski             if((nRepeatCount + 1L) % 2L)
134*b1cdbd2cSJim Jagielski                 nFrameTime = mnDuration - nFrameTime;
135*b1cdbd2cSJim Jagielski         }
136*b1cdbd2cSJim Jagielski 
137*b1cdbd2cSJim Jagielski         return mfStart + ((mfStop - mfStart) * (double(nFrameTime) / mnDuration));
138*b1cdbd2cSJim Jagielski     }
139*b1cdbd2cSJim Jagielski }
140*b1cdbd2cSJim Jagielski 
141*b1cdbd2cSJim Jagielski class ActivityImpl : public Activity,
142*b1cdbd2cSJim Jagielski                      public boost::enable_shared_from_this<ActivityImpl>,
143*b1cdbd2cSJim Jagielski                      private boost::noncopyable
144*b1cdbd2cSJim Jagielski {
145*b1cdbd2cSJim Jagielski public:
146*b1cdbd2cSJim Jagielski     virtual ~ActivityImpl();
147*b1cdbd2cSJim Jagielski 
148*b1cdbd2cSJim Jagielski     ActivityImpl(
149*b1cdbd2cSJim Jagielski         SlideShowContext const& rContext,
150*b1cdbd2cSJim Jagielski         boost::shared_ptr<WakeupEvent> const& pWakeupEvent,
151*b1cdbd2cSJim Jagielski         boost::shared_ptr<DrawShape> const& pDrawShape );
152*b1cdbd2cSJim Jagielski 
153*b1cdbd2cSJim Jagielski     bool enableAnimations();
154*b1cdbd2cSJim Jagielski 
155*b1cdbd2cSJim Jagielski     // Disposable:
156*b1cdbd2cSJim Jagielski     virtual void dispose();
157*b1cdbd2cSJim Jagielski     // Activity:
158*b1cdbd2cSJim Jagielski     virtual double calcTimeLag() const;
159*b1cdbd2cSJim Jagielski     virtual bool perform();
160*b1cdbd2cSJim Jagielski     virtual bool isActive() const;
161*b1cdbd2cSJim Jagielski     virtual void dequeued();
162*b1cdbd2cSJim Jagielski     virtual void end();
163*b1cdbd2cSJim Jagielski 
164*b1cdbd2cSJim Jagielski private:
165*b1cdbd2cSJim Jagielski     void updateShapeAttributes( double fTime,
166*b1cdbd2cSJim Jagielski                                 basegfx::B2DRectangle const& parentBounds );
167*b1cdbd2cSJim Jagielski 
168*b1cdbd2cSJim Jagielski     // Access to VisibleWhenSTarted flags
IsVisibleWhenStarted() const169*b1cdbd2cSJim Jagielski     sal_Bool IsVisibleWhenStarted() const { return mbVisibleWhenStarted; }
IsVisibleWhenStopped() const170*b1cdbd2cSJim Jagielski     sal_Bool IsVisibleWhenStopped() const { return mbVisibleWhenStopped; }
171*b1cdbd2cSJim Jagielski 
172*b1cdbd2cSJim Jagielski     // scroll horizontal? if sal_False, scroll is vertical.
ScrollHorizontal() const173*b1cdbd2cSJim Jagielski     bool ScrollHorizontal() const {
174*b1cdbd2cSJim Jagielski         return (drawing::TextAnimationDirection_LEFT == meDirection ||
175*b1cdbd2cSJim Jagielski                 drawing::TextAnimationDirection_RIGHT == meDirection);
176*b1cdbd2cSJim Jagielski     }
177*b1cdbd2cSJim Jagielski 
178*b1cdbd2cSJim Jagielski     // Access to StepWidth in logical units
179*b1cdbd2cSJim Jagielski     sal_uInt32 GetStepWidthLogic() const;
180*b1cdbd2cSJim Jagielski 
181*b1cdbd2cSJim Jagielski     // is the animation direction opposite?
DoScrollForward() const182*b1cdbd2cSJim Jagielski     bool DoScrollForward() const {
183*b1cdbd2cSJim Jagielski         return (drawing::TextAnimationDirection_RIGHT == meDirection ||
184*b1cdbd2cSJim Jagielski                 drawing::TextAnimationDirection_DOWN == meDirection);
185*b1cdbd2cSJim Jagielski     }
186*b1cdbd2cSJim Jagielski 
187*b1cdbd2cSJim Jagielski     // do alternate text directions?
DoAlternate() const188*b1cdbd2cSJim Jagielski     bool DoAlternate() const { return mbAlternate; }
189*b1cdbd2cSJim Jagielski 
190*b1cdbd2cSJim Jagielski     // do scroll in?
DoScrollIn() const191*b1cdbd2cSJim Jagielski     bool DoScrollIn() const { return mbScrollIn; }
192*b1cdbd2cSJim Jagielski 
193*b1cdbd2cSJim Jagielski     // Scroll helper methods
194*b1cdbd2cSJim Jagielski     void ImpForceScrollTextAnimNodes();
195*b1cdbd2cSJim Jagielski     ScrollTextAnimNode* ImpGetScrollTextAnimNode(
196*b1cdbd2cSJim Jagielski         sal_uInt32 nTime, sal_uInt32& rRelativeTime );
197*b1cdbd2cSJim Jagielski     sal_uInt32 ImpRegisterAgainScrollTextMixerState(
198*b1cdbd2cSJim Jagielski         sal_uInt32 nTime);
199*b1cdbd2cSJim Jagielski 
200*b1cdbd2cSJim Jagielski     // calculate the MixerState value for given time
201*b1cdbd2cSJim Jagielski     double GetMixerState(sal_uInt32 nTime);
202*b1cdbd2cSJim Jagielski 
203*b1cdbd2cSJim Jagielski     ////////////////////////////////////////////////////////////////////
204*b1cdbd2cSJim Jagielski 
205*b1cdbd2cSJim Jagielski     SlideShowContext                            maContext;
206*b1cdbd2cSJim Jagielski     boost::shared_ptr<WakeupEvent>              mpWakeupEvent;
207*b1cdbd2cSJim Jagielski     boost::weak_ptr<DrawShape>                  mpParentDrawShape;
208*b1cdbd2cSJim Jagielski     DrawShapeSharedPtr                          mpDrawShape;
209*b1cdbd2cSJim Jagielski     ShapeAttributeLayerHolder                   maShapeAttrLayer;
210*b1cdbd2cSJim Jagielski     GDIMetaFileSharedPtr                        mpMetaFile;
211*b1cdbd2cSJim Jagielski     IntrinsicAnimationEventHandlerSharedPtr     mpListener;
212*b1cdbd2cSJim Jagielski     canvas::tools::ElapsedTime                  maTimer;
213*b1cdbd2cSJim Jagielski     double                                      mfRotationAngle;
214*b1cdbd2cSJim Jagielski     bool                                        mbIsShapeAnimated;
215*b1cdbd2cSJim Jagielski     bool                                        mbIsDisposed;
216*b1cdbd2cSJim Jagielski     bool                                        mbIsActive;
217*b1cdbd2cSJim Jagielski     drawing::TextAnimationKind                  meAnimKind;
218*b1cdbd2cSJim Jagielski 
219*b1cdbd2cSJim Jagielski     // The blink frequency in ms
220*b1cdbd2cSJim Jagielski     sal_uInt32                                  mnFrequency;
221*b1cdbd2cSJim Jagielski 
222*b1cdbd2cSJim Jagielski     // The repeat count, init to 0L which means endless
223*b1cdbd2cSJim Jagielski     sal_uInt32                                  mnRepeat;
224*b1cdbd2cSJim Jagielski 
225*b1cdbd2cSJim Jagielski     // Flag to decide if text will be shown when animation has ended
226*b1cdbd2cSJim Jagielski     bool                                        mbVisibleWhenStopped;
227*b1cdbd2cSJim Jagielski     bool                                        mbVisibleWhenStarted;
228*b1cdbd2cSJim Jagielski 
229*b1cdbd2cSJim Jagielski     // Flag decides if TextScroll alternates. Default is sal_False.
230*b1cdbd2cSJim Jagielski     bool                                        mbAlternate;
231*b1cdbd2cSJim Jagielski 
232*b1cdbd2cSJim Jagielski     // Flag to remember if this is a simple scrollin text
233*b1cdbd2cSJim Jagielski     bool                                        mbScrollIn;
234*b1cdbd2cSJim Jagielski 
235*b1cdbd2cSJim Jagielski     // start time for this animation
236*b1cdbd2cSJim Jagielski     sal_uInt32                                  mnStartTime;
237*b1cdbd2cSJim Jagielski 
238*b1cdbd2cSJim Jagielski     // The AnimationDirection
239*b1cdbd2cSJim Jagielski     drawing::TextAnimationDirection             meDirection;
240*b1cdbd2cSJim Jagielski 
241*b1cdbd2cSJim Jagielski     // Get width per Step. Negative means pixel, positive logical units
242*b1cdbd2cSJim Jagielski     sal_Int32                                   mnStepWidth;
243*b1cdbd2cSJim Jagielski 
244*b1cdbd2cSJim Jagielski     // The single anim steps
245*b1cdbd2cSJim Jagielski     std::vector< ScrollTextAnimNode >           maVector;
246*b1cdbd2cSJim Jagielski 
247*b1cdbd2cSJim Jagielski     // the scroll rectangle
248*b1cdbd2cSJim Jagielski     Rectangle                                   maScrollRectangleLogic;
249*b1cdbd2cSJim Jagielski 
250*b1cdbd2cSJim Jagielski     // the paint rectangle
251*b1cdbd2cSJim Jagielski     Rectangle                                   maPaintRectangleLogic;
252*b1cdbd2cSJim Jagielski };
253*b1cdbd2cSJim Jagielski 
254*b1cdbd2cSJim Jagielski //////////////////////////////////////////////////////////////////////
255*b1cdbd2cSJim Jagielski 
256*b1cdbd2cSJim Jagielski class IntrinsicAnimationListener : public IntrinsicAnimationEventHandler,
257*b1cdbd2cSJim Jagielski                                    private boost::noncopyable
258*b1cdbd2cSJim Jagielski {
259*b1cdbd2cSJim Jagielski public:
IntrinsicAnimationListener(ActivityImpl & rActivity)260*b1cdbd2cSJim Jagielski     explicit IntrinsicAnimationListener( ActivityImpl& rActivity ) :
261*b1cdbd2cSJim Jagielski         mrActivity( rActivity )
262*b1cdbd2cSJim Jagielski     {}
263*b1cdbd2cSJim Jagielski 
264*b1cdbd2cSJim Jagielski private:
265*b1cdbd2cSJim Jagielski 
enableAnimations()266*b1cdbd2cSJim Jagielski     virtual bool enableAnimations() { return mrActivity.enableAnimations(); }
disableAnimations()267*b1cdbd2cSJim Jagielski     virtual bool disableAnimations() { mrActivity.end(); return true; }
268*b1cdbd2cSJim Jagielski 
269*b1cdbd2cSJim Jagielski     ActivityImpl& mrActivity;
270*b1cdbd2cSJim Jagielski };
271*b1cdbd2cSJim Jagielski 
272*b1cdbd2cSJim Jagielski //////////////////////////////////////////////////////////////////////
273*b1cdbd2cSJim Jagielski 
GetMixerState(sal_uInt32 nTime)274*b1cdbd2cSJim Jagielski double ActivityImpl::GetMixerState( sal_uInt32 nTime )
275*b1cdbd2cSJim Jagielski {
276*b1cdbd2cSJim Jagielski     if( meAnimKind == drawing::TextAnimationKind_BLINK )
277*b1cdbd2cSJim Jagielski     {
278*b1cdbd2cSJim Jagielski         // from AInfoBlinkText:
279*b1cdbd2cSJim Jagielski         double fRetval(0.0);
280*b1cdbd2cSJim Jagielski         sal_Bool bDone(sal_False);
281*b1cdbd2cSJim Jagielski         const sal_uInt32 nLoopTime(2 * mnFrequency);
282*b1cdbd2cSJim Jagielski 
283*b1cdbd2cSJim Jagielski         if(mnRepeat)
284*b1cdbd2cSJim Jagielski         {
285*b1cdbd2cSJim Jagielski             const sal_uInt32 nEndTime(mnRepeat * nLoopTime);
286*b1cdbd2cSJim Jagielski 
287*b1cdbd2cSJim Jagielski             if(nTime >= nEndTime)
288*b1cdbd2cSJim Jagielski             {
289*b1cdbd2cSJim Jagielski                 if(mbVisibleWhenStopped)
290*b1cdbd2cSJim Jagielski                     fRetval = 0.0;
291*b1cdbd2cSJim Jagielski                 else
292*b1cdbd2cSJim Jagielski                     fRetval = 1.0;
293*b1cdbd2cSJim Jagielski 
294*b1cdbd2cSJim Jagielski                 bDone = sal_True;
295*b1cdbd2cSJim Jagielski             }
296*b1cdbd2cSJim Jagielski         }
297*b1cdbd2cSJim Jagielski 
298*b1cdbd2cSJim Jagielski         if(!bDone)
299*b1cdbd2cSJim Jagielski         {
300*b1cdbd2cSJim Jagielski             sal_uInt32 nTimeInLoop(nTime % nLoopTime);
301*b1cdbd2cSJim Jagielski             fRetval = double(nTimeInLoop) / nLoopTime;
302*b1cdbd2cSJim Jagielski         }
303*b1cdbd2cSJim Jagielski 
304*b1cdbd2cSJim Jagielski         return fRetval;
305*b1cdbd2cSJim Jagielski     }
306*b1cdbd2cSJim Jagielski     else
307*b1cdbd2cSJim Jagielski     {
308*b1cdbd2cSJim Jagielski         // from AInfoScrollText:
309*b1cdbd2cSJim Jagielski         double fRetval(0.0);
310*b1cdbd2cSJim Jagielski         ImpForceScrollTextAnimNodes();
311*b1cdbd2cSJim Jagielski 
312*b1cdbd2cSJim Jagielski         if(!maVector.empty())
313*b1cdbd2cSJim Jagielski         {
314*b1cdbd2cSJim Jagielski             sal_uInt32 nRelativeTime;
315*b1cdbd2cSJim Jagielski             ScrollTextAnimNode* pNode =
316*b1cdbd2cSJim Jagielski                 ImpGetScrollTextAnimNode(nTime, nRelativeTime);
317*b1cdbd2cSJim Jagielski 
318*b1cdbd2cSJim Jagielski             if(pNode)
319*b1cdbd2cSJim Jagielski             {
320*b1cdbd2cSJim Jagielski                 // use node
321*b1cdbd2cSJim Jagielski                 fRetval = pNode->GetStateAtRelativeTime(nRelativeTime);
322*b1cdbd2cSJim Jagielski             }
323*b1cdbd2cSJim Jagielski             else
324*b1cdbd2cSJim Jagielski             {
325*b1cdbd2cSJim Jagielski                 // end of animation, take last entry's end
326*b1cdbd2cSJim Jagielski                 fRetval = maVector[maVector.size() - 1L].GetStop();
327*b1cdbd2cSJim Jagielski             }
328*b1cdbd2cSJim Jagielski         }
329*b1cdbd2cSJim Jagielski 
330*b1cdbd2cSJim Jagielski         return fRetval;
331*b1cdbd2cSJim Jagielski     }
332*b1cdbd2cSJim Jagielski }
333*b1cdbd2cSJim Jagielski 
334*b1cdbd2cSJim Jagielski // Access to StepWidth in logical units
GetStepWidthLogic() const335*b1cdbd2cSJim Jagielski sal_uInt32 ActivityImpl::GetStepWidthLogic() const
336*b1cdbd2cSJim Jagielski {
337*b1cdbd2cSJim Jagielski     // #i69847# Assuming higher DPI
338*b1cdbd2cSJim Jagielski     sal_uInt32 const PIXEL_TO_LOGIC = 30;
339*b1cdbd2cSJim Jagielski 
340*b1cdbd2cSJim Jagielski     sal_uInt32 nRetval(0L);
341*b1cdbd2cSJim Jagielski 
342*b1cdbd2cSJim Jagielski     if(mnStepWidth < 0L)
343*b1cdbd2cSJim Jagielski     {
344*b1cdbd2cSJim Jagielski         // is in pixels, convert to logical units
345*b1cdbd2cSJim Jagielski         nRetval = (-mnStepWidth * PIXEL_TO_LOGIC);
346*b1cdbd2cSJim Jagielski     }
347*b1cdbd2cSJim Jagielski     else if(mnStepWidth > 0L)
348*b1cdbd2cSJim Jagielski     {
349*b1cdbd2cSJim Jagielski         // is in logical units
350*b1cdbd2cSJim Jagielski         nRetval = mnStepWidth;
351*b1cdbd2cSJim Jagielski     }
352*b1cdbd2cSJim Jagielski 
353*b1cdbd2cSJim Jagielski     if(0L == nRetval)
354*b1cdbd2cSJim Jagielski     {
355*b1cdbd2cSJim Jagielski         // step 1 pixel, canned value
356*b1cdbd2cSJim Jagielski 
357*b1cdbd2cSJim Jagielski         // #128389# with very high DPIs like in PDF export, this can
358*b1cdbd2cSJim Jagielski         // still get zero.  for that cases, set a default, too (taken
359*b1cdbd2cSJim Jagielski         // from ainfoscrolltext.cxx)
360*b1cdbd2cSJim Jagielski         nRetval = 100L;
361*b1cdbd2cSJim Jagielski     }
362*b1cdbd2cSJim Jagielski 
363*b1cdbd2cSJim Jagielski     return nRetval;
364*b1cdbd2cSJim Jagielski }
365*b1cdbd2cSJim Jagielski 
ImpForceScrollTextAnimNodes()366*b1cdbd2cSJim Jagielski void ActivityImpl::ImpForceScrollTextAnimNodes()
367*b1cdbd2cSJim Jagielski {
368*b1cdbd2cSJim Jagielski     if(maVector.empty())
369*b1cdbd2cSJim Jagielski     {
370*b1cdbd2cSJim Jagielski         // prepare values
371*b1cdbd2cSJim Jagielski         sal_uInt32 nLoopTime;
372*b1cdbd2cSJim Jagielski         double fZeroLogic, fOneLogic, fInitLogic, fDistanceLogic;
373*b1cdbd2cSJim Jagielski         double fZeroLogicAlternate = 0.0, fOneLogicAlternate = 0.0;
374*b1cdbd2cSJim Jagielski         double fZeroRelative, fOneRelative, fInitRelative,fDistanceRelative;
375*b1cdbd2cSJim Jagielski 
376*b1cdbd2cSJim Jagielski         if(ScrollHorizontal())
377*b1cdbd2cSJim Jagielski         {
378*b1cdbd2cSJim Jagielski             if(DoAlternate())
379*b1cdbd2cSJim Jagielski             {
380*b1cdbd2cSJim Jagielski                 if(maPaintRectangleLogic.GetWidth() >
381*b1cdbd2cSJim Jagielski                    maScrollRectangleLogic.GetWidth())
382*b1cdbd2cSJim Jagielski                 {
383*b1cdbd2cSJim Jagielski                     fZeroLogicAlternate = maScrollRectangleLogic.Right() - maPaintRectangleLogic.GetWidth();
384*b1cdbd2cSJim Jagielski                     fOneLogicAlternate = maScrollRectangleLogic.Left();
385*b1cdbd2cSJim Jagielski                 }
386*b1cdbd2cSJim Jagielski                 else
387*b1cdbd2cSJim Jagielski                 {
388*b1cdbd2cSJim Jagielski                     fZeroLogicAlternate = maScrollRectangleLogic.Left();
389*b1cdbd2cSJim Jagielski                     fOneLogicAlternate = maScrollRectangleLogic.Right() - maPaintRectangleLogic.GetWidth();
390*b1cdbd2cSJim Jagielski                 }
391*b1cdbd2cSJim Jagielski             }
392*b1cdbd2cSJim Jagielski 
393*b1cdbd2cSJim Jagielski             fZeroLogic = maScrollRectangleLogic.Left() - maPaintRectangleLogic.GetWidth();
394*b1cdbd2cSJim Jagielski             fOneLogic = maScrollRectangleLogic.Right();
395*b1cdbd2cSJim Jagielski             fInitLogic = maPaintRectangleLogic.Left();
396*b1cdbd2cSJim Jagielski         }
397*b1cdbd2cSJim Jagielski         else
398*b1cdbd2cSJim Jagielski         {
399*b1cdbd2cSJim Jagielski             if(DoAlternate())
400*b1cdbd2cSJim Jagielski             {
401*b1cdbd2cSJim Jagielski                 if(maPaintRectangleLogic.GetHeight() > maScrollRectangleLogic.GetHeight())
402*b1cdbd2cSJim Jagielski                 {
403*b1cdbd2cSJim Jagielski                     fZeroLogicAlternate = maScrollRectangleLogic.Bottom() - maPaintRectangleLogic.GetHeight();
404*b1cdbd2cSJim Jagielski                     fOneLogicAlternate = maScrollRectangleLogic.Top();
405*b1cdbd2cSJim Jagielski                 }
406*b1cdbd2cSJim Jagielski                 else
407*b1cdbd2cSJim Jagielski                 {
408*b1cdbd2cSJim Jagielski                     fZeroLogicAlternate = maScrollRectangleLogic.Top();
409*b1cdbd2cSJim Jagielski                     fOneLogicAlternate = maScrollRectangleLogic.Bottom() - maPaintRectangleLogic.GetHeight();
410*b1cdbd2cSJim Jagielski                 }
411*b1cdbd2cSJim Jagielski             }
412*b1cdbd2cSJim Jagielski 
413*b1cdbd2cSJim Jagielski             fZeroLogic = maScrollRectangleLogic.Top() - maPaintRectangleLogic.GetHeight();
414*b1cdbd2cSJim Jagielski             fOneLogic = maScrollRectangleLogic.Bottom();
415*b1cdbd2cSJim Jagielski             fInitLogic = maPaintRectangleLogic.Top();
416*b1cdbd2cSJim Jagielski         }
417*b1cdbd2cSJim Jagielski 
418*b1cdbd2cSJim Jagielski         fDistanceLogic = fOneLogic - fZeroLogic;
419*b1cdbd2cSJim Jagielski         fInitRelative = (fInitLogic - fZeroLogic) / fDistanceLogic;
420*b1cdbd2cSJim Jagielski 
421*b1cdbd2cSJim Jagielski         if(DoAlternate())
422*b1cdbd2cSJim Jagielski         {
423*b1cdbd2cSJim Jagielski             fZeroRelative =
424*b1cdbd2cSJim Jagielski                 (fZeroLogicAlternate - fZeroLogic) / fDistanceLogic;
425*b1cdbd2cSJim Jagielski             fOneRelative =
426*b1cdbd2cSJim Jagielski                 (fOneLogicAlternate - fZeroLogic) / fDistanceLogic;
427*b1cdbd2cSJim Jagielski             fDistanceRelative = fOneRelative - fZeroRelative;
428*b1cdbd2cSJim Jagielski         }
429*b1cdbd2cSJim Jagielski         else
430*b1cdbd2cSJim Jagielski         {
431*b1cdbd2cSJim Jagielski             fZeroRelative = 0.0;
432*b1cdbd2cSJim Jagielski             fOneRelative = 1.0;
433*b1cdbd2cSJim Jagielski             fDistanceRelative = 1.0;
434*b1cdbd2cSJim Jagielski         }
435*b1cdbd2cSJim Jagielski 
436*b1cdbd2cSJim Jagielski         if(mnStartTime)
437*b1cdbd2cSJim Jagielski         {
438*b1cdbd2cSJim Jagielski             // Start time loop
439*b1cdbd2cSJim Jagielski             ScrollTextAnimNode aStartNode(
440*b1cdbd2cSJim Jagielski                 mnStartTime, 1L, 0.0, 0.0, mnStartTime, false);
441*b1cdbd2cSJim Jagielski             maVector.push_back(aStartNode);
442*b1cdbd2cSJim Jagielski         }
443*b1cdbd2cSJim Jagielski 
444*b1cdbd2cSJim Jagielski         if(IsVisibleWhenStarted())
445*b1cdbd2cSJim Jagielski         {
446*b1cdbd2cSJim Jagielski             double fRelativeStartValue, fRelativeEndValue,fRelativeDistance;
447*b1cdbd2cSJim Jagielski 
448*b1cdbd2cSJim Jagielski             if(DoScrollForward())
449*b1cdbd2cSJim Jagielski             {
450*b1cdbd2cSJim Jagielski                 fRelativeStartValue = fInitRelative;
451*b1cdbd2cSJim Jagielski                 fRelativeEndValue = fOneRelative;
452*b1cdbd2cSJim Jagielski                 fRelativeDistance = fRelativeEndValue - fRelativeStartValue;
453*b1cdbd2cSJim Jagielski             }
454*b1cdbd2cSJim Jagielski             else
455*b1cdbd2cSJim Jagielski             {
456*b1cdbd2cSJim Jagielski                 fRelativeStartValue = fInitRelative;
457*b1cdbd2cSJim Jagielski                 fRelativeEndValue = fZeroRelative;
458*b1cdbd2cSJim Jagielski                 fRelativeDistance = fRelativeStartValue - fRelativeEndValue;
459*b1cdbd2cSJim Jagielski             }
460*b1cdbd2cSJim Jagielski 
461*b1cdbd2cSJim Jagielski             const double fNumberSteps =
462*b1cdbd2cSJim Jagielski                 (fRelativeDistance * fDistanceLogic) / GetStepWidthLogic();
463*b1cdbd2cSJim Jagielski             nLoopTime = FRound(fNumberSteps * mnFrequency);
464*b1cdbd2cSJim Jagielski 
465*b1cdbd2cSJim Jagielski             // init loop
466*b1cdbd2cSJim Jagielski             ScrollTextAnimNode aInitNode(
467*b1cdbd2cSJim Jagielski                 nLoopTime, 1L,
468*b1cdbd2cSJim Jagielski                 fRelativeStartValue, fRelativeEndValue,
469*b1cdbd2cSJim Jagielski                 mnFrequency, false);
470*b1cdbd2cSJim Jagielski             maVector.push_back(aInitNode);
471*b1cdbd2cSJim Jagielski         }
472*b1cdbd2cSJim Jagielski 
473*b1cdbd2cSJim Jagielski         // prepare main loop values
474*b1cdbd2cSJim Jagielski         {
475*b1cdbd2cSJim Jagielski             double fRelativeStartValue, fRelativeEndValue, fRelativeDistance;
476*b1cdbd2cSJim Jagielski 
477*b1cdbd2cSJim Jagielski             if(DoScrollForward())
478*b1cdbd2cSJim Jagielski             {
479*b1cdbd2cSJim Jagielski                 fRelativeStartValue = fZeroRelative;
480*b1cdbd2cSJim Jagielski                 fRelativeEndValue = fOneRelative;
481*b1cdbd2cSJim Jagielski                 fRelativeDistance = fRelativeEndValue - fRelativeStartValue;
482*b1cdbd2cSJim Jagielski             }
483*b1cdbd2cSJim Jagielski             else
484*b1cdbd2cSJim Jagielski             {
485*b1cdbd2cSJim Jagielski                 fRelativeStartValue = fOneRelative;
486*b1cdbd2cSJim Jagielski                 fRelativeEndValue = fZeroRelative;
487*b1cdbd2cSJim Jagielski                 fRelativeDistance = fRelativeStartValue - fRelativeEndValue;
488*b1cdbd2cSJim Jagielski             }
489*b1cdbd2cSJim Jagielski 
490*b1cdbd2cSJim Jagielski             const double fNumberSteps =
491*b1cdbd2cSJim Jagielski                 (fRelativeDistance * fDistanceLogic) / GetStepWidthLogic();
492*b1cdbd2cSJim Jagielski             nLoopTime = FRound(fNumberSteps * mnFrequency);
493*b1cdbd2cSJim Jagielski 
494*b1cdbd2cSJim Jagielski             if(0L == mnRepeat)
495*b1cdbd2cSJim Jagielski             {
496*b1cdbd2cSJim Jagielski                 if(!DoScrollIn())
497*b1cdbd2cSJim Jagielski                 {
498*b1cdbd2cSJim Jagielski                     // endless main loop
499*b1cdbd2cSJim Jagielski                     ScrollTextAnimNode aMainNode(
500*b1cdbd2cSJim Jagielski                         nLoopTime, 0L,
501*b1cdbd2cSJim Jagielski                         fRelativeStartValue, fRelativeEndValue,
502*b1cdbd2cSJim Jagielski                         mnFrequency, DoAlternate());
503*b1cdbd2cSJim Jagielski                     maVector.push_back(aMainNode);
504*b1cdbd2cSJim Jagielski                 }
505*b1cdbd2cSJim Jagielski             }
506*b1cdbd2cSJim Jagielski             else
507*b1cdbd2cSJim Jagielski             {
508*b1cdbd2cSJim Jagielski                 sal_uInt32 nNumRepeat(mnRepeat);
509*b1cdbd2cSJim Jagielski 
510*b1cdbd2cSJim Jagielski                 if(DoAlternate() && (nNumRepeat + 1L) % 2L)
511*b1cdbd2cSJim Jagielski                     nNumRepeat += 1L;
512*b1cdbd2cSJim Jagielski 
513*b1cdbd2cSJim Jagielski                 // ending main loop
514*b1cdbd2cSJim Jagielski                 ScrollTextAnimNode aMainNode(
515*b1cdbd2cSJim Jagielski                     nLoopTime, nNumRepeat,
516*b1cdbd2cSJim Jagielski                     fRelativeStartValue, fRelativeEndValue,
517*b1cdbd2cSJim Jagielski                     mnFrequency, DoAlternate());
518*b1cdbd2cSJim Jagielski                 maVector.push_back(aMainNode);
519*b1cdbd2cSJim Jagielski             }
520*b1cdbd2cSJim Jagielski         }
521*b1cdbd2cSJim Jagielski 
522*b1cdbd2cSJim Jagielski         if(IsVisibleWhenStopped())
523*b1cdbd2cSJim Jagielski         {
524*b1cdbd2cSJim Jagielski             double fRelativeStartValue, fRelativeEndValue, fRelativeDistance;
525*b1cdbd2cSJim Jagielski 
526*b1cdbd2cSJim Jagielski             if(DoScrollForward())
527*b1cdbd2cSJim Jagielski             {
528*b1cdbd2cSJim Jagielski                 fRelativeStartValue = fZeroRelative;
529*b1cdbd2cSJim Jagielski                 fRelativeEndValue = fInitRelative;
530*b1cdbd2cSJim Jagielski                 fRelativeDistance = fRelativeEndValue - fRelativeStartValue;
531*b1cdbd2cSJim Jagielski             }
532*b1cdbd2cSJim Jagielski             else
533*b1cdbd2cSJim Jagielski             {
534*b1cdbd2cSJim Jagielski                 fRelativeStartValue = fOneRelative;
535*b1cdbd2cSJim Jagielski                 fRelativeEndValue = fInitRelative;
536*b1cdbd2cSJim Jagielski                 fRelativeDistance = fRelativeStartValue - fRelativeEndValue;
537*b1cdbd2cSJim Jagielski             }
538*b1cdbd2cSJim Jagielski 
539*b1cdbd2cSJim Jagielski             const double fNumberSteps =
540*b1cdbd2cSJim Jagielski                 (fRelativeDistance * fDistanceLogic) / GetStepWidthLogic();
541*b1cdbd2cSJim Jagielski             nLoopTime = FRound(fNumberSteps * mnFrequency);
542*b1cdbd2cSJim Jagielski 
543*b1cdbd2cSJim Jagielski             // exit loop
544*b1cdbd2cSJim Jagielski             ScrollTextAnimNode aExitNode(
545*b1cdbd2cSJim Jagielski                 nLoopTime, 1L,
546*b1cdbd2cSJim Jagielski                 fRelativeStartValue, fRelativeEndValue, mnFrequency, false);
547*b1cdbd2cSJim Jagielski             maVector.push_back(aExitNode);
548*b1cdbd2cSJim Jagielski         }
549*b1cdbd2cSJim Jagielski     }
550*b1cdbd2cSJim Jagielski }
551*b1cdbd2cSJim Jagielski 
ImpGetScrollTextAnimNode(sal_uInt32 nTime,sal_uInt32 & rRelativeTime)552*b1cdbd2cSJim Jagielski ScrollTextAnimNode* ActivityImpl::ImpGetScrollTextAnimNode(
553*b1cdbd2cSJim Jagielski     sal_uInt32 nTime, sal_uInt32& rRelativeTime )
554*b1cdbd2cSJim Jagielski {
555*b1cdbd2cSJim Jagielski     ScrollTextAnimNode* pRetval = 0L;
556*b1cdbd2cSJim Jagielski     ImpForceScrollTextAnimNodes();
557*b1cdbd2cSJim Jagielski 
558*b1cdbd2cSJim Jagielski     if(!maVector.empty())
559*b1cdbd2cSJim Jagielski     {
560*b1cdbd2cSJim Jagielski         rRelativeTime = nTime;
561*b1cdbd2cSJim Jagielski 
562*b1cdbd2cSJim Jagielski         for(sal_uInt32 a(0L); !pRetval && a < maVector.size(); a++)
563*b1cdbd2cSJim Jagielski         {
564*b1cdbd2cSJim Jagielski             ScrollTextAnimNode & rNode = maVector[a];
565*b1cdbd2cSJim Jagielski             if(!rNode.GetRepeat())
566*b1cdbd2cSJim Jagielski             {
567*b1cdbd2cSJim Jagielski                 // endless loop, use it
568*b1cdbd2cSJim Jagielski                 pRetval = &rNode;
569*b1cdbd2cSJim Jagielski             }
570*b1cdbd2cSJim Jagielski             else if(rNode.GetFullTime() > rRelativeTime)
571*b1cdbd2cSJim Jagielski             {
572*b1cdbd2cSJim Jagielski                 // ending node
573*b1cdbd2cSJim Jagielski                 pRetval = &rNode;
574*b1cdbd2cSJim Jagielski             }
575*b1cdbd2cSJim Jagielski             else
576*b1cdbd2cSJim Jagielski             {
577*b1cdbd2cSJim Jagielski                 // look at next
578*b1cdbd2cSJim Jagielski                 rRelativeTime -= rNode.GetFullTime();
579*b1cdbd2cSJim Jagielski             }
580*b1cdbd2cSJim Jagielski         }
581*b1cdbd2cSJim Jagielski     }
582*b1cdbd2cSJim Jagielski 
583*b1cdbd2cSJim Jagielski     return pRetval;
584*b1cdbd2cSJim Jagielski }
585*b1cdbd2cSJim Jagielski 
ImpRegisterAgainScrollTextMixerState(sal_uInt32 nTime)586*b1cdbd2cSJim Jagielski sal_uInt32 ActivityImpl::ImpRegisterAgainScrollTextMixerState(sal_uInt32 nTime)
587*b1cdbd2cSJim Jagielski {
588*b1cdbd2cSJim Jagielski     sal_uInt32 nRetval(0L);
589*b1cdbd2cSJim Jagielski     ImpForceScrollTextAnimNodes();
590*b1cdbd2cSJim Jagielski 
591*b1cdbd2cSJim Jagielski     if(maVector.size())
592*b1cdbd2cSJim Jagielski     {
593*b1cdbd2cSJim Jagielski         sal_uInt32 nRelativeTime;
594*b1cdbd2cSJim Jagielski         ScrollTextAnimNode* pNode = ImpGetScrollTextAnimNode(nTime, nRelativeTime);
595*b1cdbd2cSJim Jagielski 
596*b1cdbd2cSJim Jagielski         if(pNode)
597*b1cdbd2cSJim Jagielski         {
598*b1cdbd2cSJim Jagielski             // take register time
599*b1cdbd2cSJim Jagielski             nRetval = pNode->GetFrequency();
600*b1cdbd2cSJim Jagielski         }
601*b1cdbd2cSJim Jagielski     }
602*b1cdbd2cSJim Jagielski     else
603*b1cdbd2cSJim Jagielski     {
604*b1cdbd2cSJim Jagielski         // #i38135# not initialized, return default
605*b1cdbd2cSJim Jagielski         nRetval = mnFrequency;
606*b1cdbd2cSJim Jagielski     }
607*b1cdbd2cSJim Jagielski 
608*b1cdbd2cSJim Jagielski     return nRetval;
609*b1cdbd2cSJim Jagielski }
610*b1cdbd2cSJim Jagielski 
updateShapeAttributes(double fTime,basegfx::B2DRectangle const & parentBounds)611*b1cdbd2cSJim Jagielski void ActivityImpl::updateShapeAttributes(
612*b1cdbd2cSJim Jagielski     double fTime, basegfx::B2DRectangle const& parentBounds )
613*b1cdbd2cSJim Jagielski {
614*b1cdbd2cSJim Jagielski     OSL_ASSERT( meAnimKind != drawing::TextAnimationKind_NONE );
615*b1cdbd2cSJim Jagielski     if( meAnimKind == drawing::TextAnimationKind_NONE )
616*b1cdbd2cSJim Jagielski         return;
617*b1cdbd2cSJim Jagielski 
618*b1cdbd2cSJim Jagielski     double const fMixerState = GetMixerState(
619*b1cdbd2cSJim Jagielski         static_cast<sal_uInt32>(fTime * 1000.0) );
620*b1cdbd2cSJim Jagielski 
621*b1cdbd2cSJim Jagielski     if( meAnimKind == drawing::TextAnimationKind_BLINK )
622*b1cdbd2cSJim Jagielski     {
623*b1cdbd2cSJim Jagielski         // show/hide text:
624*b1cdbd2cSJim Jagielski         maShapeAttrLayer.get()->setVisibility( fMixerState < 0.5 );
625*b1cdbd2cSJim Jagielski     }
626*b1cdbd2cSJim Jagielski     else if(mpMetaFile) // scroll mode:
627*b1cdbd2cSJim Jagielski     {
628*b1cdbd2cSJim Jagielski         //
629*b1cdbd2cSJim Jagielski         // keep care: the below code is highly sensible to changes...
630*b1cdbd2cSJim Jagielski         //
631*b1cdbd2cSJim Jagielski 
632*b1cdbd2cSJim Jagielski         // rectangle of the pure text:
633*b1cdbd2cSJim Jagielski         double const fPaintWidth = maPaintRectangleLogic.GetWidth();
634*b1cdbd2cSJim Jagielski         double const fPaintHeight = maPaintRectangleLogic.GetHeight();
635*b1cdbd2cSJim Jagielski         // rectangle where the scrolling takes place (-> clipping):
636*b1cdbd2cSJim Jagielski         double const fScrollWidth = maScrollRectangleLogic.GetWidth();
637*b1cdbd2cSJim Jagielski         double const fScrollHeight = maScrollRectangleLogic.GetHeight();
638*b1cdbd2cSJim Jagielski 
639*b1cdbd2cSJim Jagielski         basegfx::B2DPoint pos, clipPos;
640*b1cdbd2cSJim Jagielski 
641*b1cdbd2cSJim Jagielski         if(ScrollHorizontal())
642*b1cdbd2cSJim Jagielski         {
643*b1cdbd2cSJim Jagielski             double const fOneEquiv( fScrollWidth );
644*b1cdbd2cSJim Jagielski             double const fZeroEquiv( -fPaintWidth );
645*b1cdbd2cSJim Jagielski 
646*b1cdbd2cSJim Jagielski             pos.setX( fZeroEquiv + (fMixerState * (fOneEquiv - fZeroEquiv)) );
647*b1cdbd2cSJim Jagielski 
648*b1cdbd2cSJim Jagielski             clipPos.setX( -pos.getX() );
649*b1cdbd2cSJim Jagielski             clipPos.setY( -pos.getY() );
650*b1cdbd2cSJim Jagielski 
651*b1cdbd2cSJim Jagielski             // #i69844# Compensation for text-wider-than-shape case
652*b1cdbd2cSJim Jagielski             if( fPaintWidth > fScrollWidth )
653*b1cdbd2cSJim Jagielski                 pos.setX( pos.getX() + (fPaintWidth-fScrollWidth) / 2.0 );
654*b1cdbd2cSJim Jagielski         }
655*b1cdbd2cSJim Jagielski         else
656*b1cdbd2cSJim Jagielski         {
657*b1cdbd2cSJim Jagielski             // scroll vertical:
658*b1cdbd2cSJim Jagielski             double const fOneEquiv( fScrollHeight );
659*b1cdbd2cSJim Jagielski             double const fZeroEquiv( -fPaintHeight );
660*b1cdbd2cSJim Jagielski 
661*b1cdbd2cSJim Jagielski             pos.setY( fZeroEquiv + (fMixerState * (fOneEquiv - fZeroEquiv)) );
662*b1cdbd2cSJim Jagielski 
663*b1cdbd2cSJim Jagielski             clipPos.setX( -pos.getX() );
664*b1cdbd2cSJim Jagielski             clipPos.setY( -pos.getY() );
665*b1cdbd2cSJim Jagielski 
666*b1cdbd2cSJim Jagielski             // #i69844# Compensation for text-higher-than-shape case
667*b1cdbd2cSJim Jagielski             if( fPaintHeight > fScrollHeight )
668*b1cdbd2cSJim Jagielski                 pos.setY( pos.getY() + (fPaintHeight-fScrollHeight) / 2.0 );
669*b1cdbd2cSJim Jagielski         }
670*b1cdbd2cSJim Jagielski 
671*b1cdbd2cSJim Jagielski         basegfx::B2DPolygon clipPoly(
672*b1cdbd2cSJim Jagielski             basegfx::tools::createPolygonFromRect(
673*b1cdbd2cSJim Jagielski                 basegfx::B2DRectangle( clipPos.getX(),
674*b1cdbd2cSJim Jagielski                                        clipPos.getY(),
675*b1cdbd2cSJim Jagielski                                        clipPos.getX() + fScrollWidth,
676*b1cdbd2cSJim Jagielski                                        clipPos.getY() + fScrollHeight ) ) );
677*b1cdbd2cSJim Jagielski 
678*b1cdbd2cSJim Jagielski         if( !::basegfx::fTools::equalZero( mfRotationAngle ))
679*b1cdbd2cSJim Jagielski         {
680*b1cdbd2cSJim Jagielski             maShapeAttrLayer.get()->setRotationAngle( mfRotationAngle );
681*b1cdbd2cSJim Jagielski             double const fRotate = (mfRotationAngle * M_PI / 180.0);
682*b1cdbd2cSJim Jagielski             basegfx::B2DHomMatrix aTransform;
683*b1cdbd2cSJim Jagielski             // position:
684*b1cdbd2cSJim Jagielski             aTransform.rotate( fRotate );
685*b1cdbd2cSJim Jagielski             pos *= aTransform;
686*b1cdbd2cSJim Jagielski         }
687*b1cdbd2cSJim Jagielski 
688*b1cdbd2cSJim Jagielski         pos += parentBounds.getCenter();
689*b1cdbd2cSJim Jagielski         maShapeAttrLayer.get()->setPosition( pos );
690*b1cdbd2cSJim Jagielski         maShapeAttrLayer.get()->setClip( basegfx::B2DPolyPolygon(clipPoly) );
691*b1cdbd2cSJim Jagielski     }
692*b1cdbd2cSJim Jagielski }
693*b1cdbd2cSJim Jagielski 
perform()694*b1cdbd2cSJim Jagielski bool ActivityImpl::perform()
695*b1cdbd2cSJim Jagielski {
696*b1cdbd2cSJim Jagielski     if( !isActive() )
697*b1cdbd2cSJim Jagielski         return false;
698*b1cdbd2cSJim Jagielski 
699*b1cdbd2cSJim Jagielski     ENSURE_OR_RETURN_FALSE(
700*b1cdbd2cSJim Jagielski         mpDrawShape,
701*b1cdbd2cSJim Jagielski         "ActivityImpl::perform(): still active, but NULL draw shape" );
702*b1cdbd2cSJim Jagielski 
703*b1cdbd2cSJim Jagielski     DrawShapeSharedPtr const pParentDrawShape( mpParentDrawShape );
704*b1cdbd2cSJim Jagielski     if( !pParentDrawShape )
705*b1cdbd2cSJim Jagielski         return false; // parent has vanished
706*b1cdbd2cSJim Jagielski 
707*b1cdbd2cSJim Jagielski     if( pParentDrawShape->isVisible() )
708*b1cdbd2cSJim Jagielski     {
709*b1cdbd2cSJim Jagielski         if( !mbIsShapeAnimated )
710*b1cdbd2cSJim Jagielski         {
711*b1cdbd2cSJim Jagielski             mpDrawShape->setVisibility(true); // shape may be initially hidden
712*b1cdbd2cSJim Jagielski             maContext.mpSubsettableShapeManager->enterAnimationMode( mpDrawShape );
713*b1cdbd2cSJim Jagielski             maTimer.reset();
714*b1cdbd2cSJim Jagielski             mbIsShapeAnimated = true;
715*b1cdbd2cSJim Jagielski         }
716*b1cdbd2cSJim Jagielski         // update attributes related to current time:
717*b1cdbd2cSJim Jagielski         basegfx::B2DRectangle const parentBounds(
718*b1cdbd2cSJim Jagielski             pParentDrawShape->getBounds() );
719*b1cdbd2cSJim Jagielski 
720*b1cdbd2cSJim Jagielski         const double nCurrTime( maTimer.getElapsedTime() );
721*b1cdbd2cSJim Jagielski         updateShapeAttributes( nCurrTime, parentBounds );
722*b1cdbd2cSJim Jagielski 
723*b1cdbd2cSJim Jagielski         const sal_uInt32 nFrequency(
724*b1cdbd2cSJim Jagielski             ImpRegisterAgainScrollTextMixerState(
725*b1cdbd2cSJim Jagielski                 static_cast<sal_uInt32>(nCurrTime * 1000.0)) );
726*b1cdbd2cSJim Jagielski 
727*b1cdbd2cSJim Jagielski         if(nFrequency)
728*b1cdbd2cSJim Jagielski         {
729*b1cdbd2cSJim Jagielski             mpWakeupEvent->start();
730*b1cdbd2cSJim Jagielski             mpWakeupEvent->setNextTimeout(
731*b1cdbd2cSJim Jagielski                 std::max(0.1,nFrequency/1000.0) );
732*b1cdbd2cSJim Jagielski             maContext.mrEventQueue.addEvent( mpWakeupEvent );
733*b1cdbd2cSJim Jagielski 
734*b1cdbd2cSJim Jagielski             if( mpDrawShape->isContentChanged() )
735*b1cdbd2cSJim Jagielski                 maContext.mpSubsettableShapeManager->notifyShapeUpdate( mpDrawShape );
736*b1cdbd2cSJim Jagielski         }
737*b1cdbd2cSJim Jagielski         // else: finished, not need to wake up again.
738*b1cdbd2cSJim Jagielski     }
739*b1cdbd2cSJim Jagielski     else
740*b1cdbd2cSJim Jagielski     {
741*b1cdbd2cSJim Jagielski         // busy-wait, until parent shape gets visible
742*b1cdbd2cSJim Jagielski         mpWakeupEvent->start();
743*b1cdbd2cSJim Jagielski         mpWakeupEvent->setNextTimeout( 2.0 );
744*b1cdbd2cSJim Jagielski     }
745*b1cdbd2cSJim Jagielski 
746*b1cdbd2cSJim Jagielski     // don't reinsert, WakeupEvent will perform that after the given timeout:
747*b1cdbd2cSJim Jagielski     return false;
748*b1cdbd2cSJim Jagielski }
749*b1cdbd2cSJim Jagielski 
ActivityImpl(SlideShowContext const & rContext,boost::shared_ptr<WakeupEvent> const & pWakeupEvent,boost::shared_ptr<DrawShape> const & pParentDrawShape)750*b1cdbd2cSJim Jagielski ActivityImpl::ActivityImpl(
751*b1cdbd2cSJim Jagielski     SlideShowContext const& rContext,
752*b1cdbd2cSJim Jagielski     boost::shared_ptr<WakeupEvent> const& pWakeupEvent,
753*b1cdbd2cSJim Jagielski     boost::shared_ptr<DrawShape> const& pParentDrawShape )
754*b1cdbd2cSJim Jagielski     : maContext(rContext),
755*b1cdbd2cSJim Jagielski       mpWakeupEvent(pWakeupEvent),
756*b1cdbd2cSJim Jagielski       mpParentDrawShape(pParentDrawShape),
757*b1cdbd2cSJim Jagielski       mpListener( new IntrinsicAnimationListener(*this) ),
758*b1cdbd2cSJim Jagielski       maTimer(rContext.mrEventQueue.getTimer()),
759*b1cdbd2cSJim Jagielski       mbIsShapeAnimated(false),
760*b1cdbd2cSJim Jagielski       mbIsDisposed(false),
761*b1cdbd2cSJim Jagielski       mbIsActive(true),
762*b1cdbd2cSJim Jagielski       meAnimKind(drawing::TextAnimationKind_NONE),
763*b1cdbd2cSJim Jagielski       mnStartTime(0L)
764*b1cdbd2cSJim Jagielski {
765*b1cdbd2cSJim Jagielski     // get doctreenode:
766*b1cdbd2cSJim Jagielski     sal_Int32 const nNodes = pParentDrawShape->getNumberOfTreeNodes(
767*b1cdbd2cSJim Jagielski         DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH );
768*b1cdbd2cSJim Jagielski 
769*b1cdbd2cSJim Jagielski     DocTreeNode scrollTextNode(
770*b1cdbd2cSJim Jagielski         pParentDrawShape->getTreeNode(
771*b1cdbd2cSJim Jagielski             0, DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH ));
772*b1cdbd2cSJim Jagielski     // xxx todo: remove this hack
773*b1cdbd2cSJim Jagielski     if( nNodes > 1 )
774*b1cdbd2cSJim Jagielski         scrollTextNode.setEndIndex(
775*b1cdbd2cSJim Jagielski             pParentDrawShape->getTreeNode(
776*b1cdbd2cSJim Jagielski                 nNodes - 1,
777*b1cdbd2cSJim Jagielski                 DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH ).getEndIndex());
778*b1cdbd2cSJim Jagielski 
779*b1cdbd2cSJim Jagielski     // TODO(Q3): Doing this manually, instead of using
780*b1cdbd2cSJim Jagielski     // ShapeSubset. This is because of lifetime issues (ShapeSubset
781*b1cdbd2cSJim Jagielski     // generates circular references to parent shape)
782*b1cdbd2cSJim Jagielski     mpDrawShape = boost::dynamic_pointer_cast<DrawShape>(
783*b1cdbd2cSJim Jagielski         maContext.mpSubsettableShapeManager->getSubsetShape(
784*b1cdbd2cSJim Jagielski             pParentDrawShape,
785*b1cdbd2cSJim Jagielski             scrollTextNode ));
786*b1cdbd2cSJim Jagielski 
787*b1cdbd2cSJim Jagielski     mpMetaFile = mpDrawShape->forceScrollTextMetaFile();
788*b1cdbd2cSJim Jagielski 
789*b1cdbd2cSJim Jagielski     // make scroll text invisible for slide transition bitmaps
790*b1cdbd2cSJim Jagielski     mpDrawShape->setVisibility(false);
791*b1cdbd2cSJim Jagielski 
792*b1cdbd2cSJim Jagielski     basegfx::B2DRectangle aScrollRect, aPaintRect;
793*b1cdbd2cSJim Jagielski     ENSURE_OR_THROW( getRectanglesFromScrollMtf( aScrollRect,
794*b1cdbd2cSJim Jagielski                                                   aPaintRect,
795*b1cdbd2cSJim Jagielski                                                   mpMetaFile ),
796*b1cdbd2cSJim Jagielski                       "ActivityImpl::ActivityImpl(): Could not extract "
797*b1cdbd2cSJim Jagielski                       "scroll anim rectangles from mtf" );
798*b1cdbd2cSJim Jagielski 
799*b1cdbd2cSJim Jagielski     maScrollRectangleLogic = vcl::unotools::rectangleFromB2DRectangle(
800*b1cdbd2cSJim Jagielski         aScrollRect );
801*b1cdbd2cSJim Jagielski     maPaintRectangleLogic = vcl::unotools::rectangleFromB2DRectangle(
802*b1cdbd2cSJim Jagielski         aPaintRect );
803*b1cdbd2cSJim Jagielski 
804*b1cdbd2cSJim Jagielski     maShapeAttrLayer.createAttributeLayer(mpDrawShape);
805*b1cdbd2cSJim Jagielski 
806*b1cdbd2cSJim Jagielski     uno::Reference<drawing::XShape> const xShape( mpDrawShape->getXShape() );
807*b1cdbd2cSJim Jagielski     uno::Reference<beans::XPropertySet> const xProps( xShape, uno::UNO_QUERY_THROW );
808*b1cdbd2cSJim Jagielski 
809*b1cdbd2cSJim Jagielski     getPropertyValue( meAnimKind, xProps, OUSTR("TextAnimationKind") );
810*b1cdbd2cSJim Jagielski     OSL_ASSERT( meAnimKind != drawing::TextAnimationKind_NONE );
811*b1cdbd2cSJim Jagielski     mbAlternate = (meAnimKind == drawing::TextAnimationKind_ALTERNATE);
812*b1cdbd2cSJim Jagielski     mbScrollIn = (meAnimKind == drawing::TextAnimationKind_SLIDE);
813*b1cdbd2cSJim Jagielski 
814*b1cdbd2cSJim Jagielski     // adopted from in AInfoBlinkText::ImplInit():
815*b1cdbd2cSJim Jagielski     sal_Int16 nRepeat(0);
816*b1cdbd2cSJim Jagielski     getPropertyValue( nRepeat, xProps, OUSTR("TextAnimationCount") );
817*b1cdbd2cSJim Jagielski     mnRepeat = nRepeat;
818*b1cdbd2cSJim Jagielski 
819*b1cdbd2cSJim Jagielski     if(mbAlternate)
820*b1cdbd2cSJim Jagielski     {
821*b1cdbd2cSJim Jagielski         // force visible when started for scroll-forth-and-back, because
822*b1cdbd2cSJim Jagielski         // slide has been coming in with visible text in the middle:
823*b1cdbd2cSJim Jagielski         mbVisibleWhenStarted = true;
824*b1cdbd2cSJim Jagielski     }
825*b1cdbd2cSJim Jagielski     else
826*b1cdbd2cSJim Jagielski     {
827*b1cdbd2cSJim Jagielski         getPropertyValue( mbVisibleWhenStarted, xProps,
828*b1cdbd2cSJim Jagielski                           OUSTR("TextAnimationStartInside") );
829*b1cdbd2cSJim Jagielski     }
830*b1cdbd2cSJim Jagielski 
831*b1cdbd2cSJim Jagielski     // set visible when stopped
832*b1cdbd2cSJim Jagielski     getPropertyValue( mbVisibleWhenStopped, xProps,
833*b1cdbd2cSJim Jagielski                       OUSTR("TextAnimatiogonStopInside") );
834*b1cdbd2cSJim Jagielski     // rotation:
835*b1cdbd2cSJim Jagielski     getPropertyValue( mfRotationAngle, xProps,
836*b1cdbd2cSJim Jagielski                       OUSTR("RotateAngle") );
837*b1cdbd2cSJim Jagielski     mfRotationAngle /= -100.0; // (switching direction)
838*b1cdbd2cSJim Jagielski 
839*b1cdbd2cSJim Jagielski     // set frequency
840*b1cdbd2cSJim Jagielski     sal_Int16 nDelay(0);
841*b1cdbd2cSJim Jagielski     getPropertyValue( nDelay, xProps, OUSTR("TextAnimationDelay") );
842*b1cdbd2cSJim Jagielski     // set delay if not automatic
843*b1cdbd2cSJim Jagielski     mnFrequency = (nDelay ? nDelay :
844*b1cdbd2cSJim Jagielski                    // default:
845*b1cdbd2cSJim Jagielski                    meAnimKind == drawing::TextAnimationKind_BLINK
846*b1cdbd2cSJim Jagielski                    ? 250L : 50L );
847*b1cdbd2cSJim Jagielski 
848*b1cdbd2cSJim Jagielski     // adopted from in AInfoScrollText::ImplInit():
849*b1cdbd2cSJim Jagielski 
850*b1cdbd2cSJim Jagielski     // If it is a simple m_bScrollIn, reset some parameters
851*b1cdbd2cSJim Jagielski     if( DoScrollIn() )
852*b1cdbd2cSJim Jagielski     {
853*b1cdbd2cSJim Jagielski         // most parameters are set correctly from the dialog logic, but
854*b1cdbd2cSJim Jagielski         // eg VisisbleWhenStopped is grayed out and needs to be corrected here.
855*b1cdbd2cSJim Jagielski         mbVisibleWhenStopped = true;
856*b1cdbd2cSJim Jagielski         mbVisibleWhenStarted = false;
857*b1cdbd2cSJim Jagielski         mnRepeat = 0L;
858*b1cdbd2cSJim Jagielski     }
859*b1cdbd2cSJim Jagielski 
860*b1cdbd2cSJim Jagielski     // Get animation direction
861*b1cdbd2cSJim Jagielski     getPropertyValue( meDirection, xProps, OUSTR("TextAnimationDirection") );
862*b1cdbd2cSJim Jagielski 
863*b1cdbd2cSJim Jagielski     // Get step width. Negative means pixel, positive logical units
864*b1cdbd2cSJim Jagielski     getPropertyValue( mnStepWidth, xProps, OUSTR("TextAnimationAmount") );
865*b1cdbd2cSJim Jagielski 
866*b1cdbd2cSJim Jagielski     maContext.mpSubsettableShapeManager->addIntrinsicAnimationHandler(
867*b1cdbd2cSJim Jagielski         mpListener );
868*b1cdbd2cSJim Jagielski }
869*b1cdbd2cSJim Jagielski 
enableAnimations()870*b1cdbd2cSJim Jagielski bool ActivityImpl::enableAnimations()
871*b1cdbd2cSJim Jagielski {
872*b1cdbd2cSJim Jagielski     mbIsActive = true;
873*b1cdbd2cSJim Jagielski     return maContext.mrActivitiesQueue.addActivity(
874*b1cdbd2cSJim Jagielski         shared_from_this() );
875*b1cdbd2cSJim Jagielski }
876*b1cdbd2cSJim Jagielski 
~ActivityImpl()877*b1cdbd2cSJim Jagielski ActivityImpl::~ActivityImpl()
878*b1cdbd2cSJim Jagielski {
879*b1cdbd2cSJim Jagielski }
880*b1cdbd2cSJim Jagielski 
dispose()881*b1cdbd2cSJim Jagielski void ActivityImpl::dispose()
882*b1cdbd2cSJim Jagielski {
883*b1cdbd2cSJim Jagielski     if( !mbIsDisposed )
884*b1cdbd2cSJim Jagielski     {
885*b1cdbd2cSJim Jagielski         end();
886*b1cdbd2cSJim Jagielski 
887*b1cdbd2cSJim Jagielski         // only remove subset here, since end() is called on slide end
888*b1cdbd2cSJim Jagielski         // (and we must not spoil the slide preview bitmap with scroll
889*b1cdbd2cSJim Jagielski         // text)
890*b1cdbd2cSJim Jagielski         maShapeAttrLayer.reset();
891*b1cdbd2cSJim Jagielski         if( mpDrawShape )
892*b1cdbd2cSJim Jagielski         {
893*b1cdbd2cSJim Jagielski             // TODO(Q3): Doing this manually, instead of using
894*b1cdbd2cSJim Jagielski             // ShapeSubset. This is because of lifetime issues
895*b1cdbd2cSJim Jagielski             // (ShapeSubset generates circular references to parent
896*b1cdbd2cSJim Jagielski             // shape)
897*b1cdbd2cSJim Jagielski             DrawShapeSharedPtr pParent( mpParentDrawShape.lock() );
898*b1cdbd2cSJim Jagielski             if( pParent )
899*b1cdbd2cSJim Jagielski                 maContext.mpSubsettableShapeManager->revokeSubset(
900*b1cdbd2cSJim Jagielski                     pParent,
901*b1cdbd2cSJim Jagielski                     mpDrawShape );
902*b1cdbd2cSJim Jagielski         }
903*b1cdbd2cSJim Jagielski 
904*b1cdbd2cSJim Jagielski         mpMetaFile.reset();
905*b1cdbd2cSJim Jagielski         mpDrawShape.reset();
906*b1cdbd2cSJim Jagielski         mpParentDrawShape.reset();
907*b1cdbd2cSJim Jagielski         mpWakeupEvent.reset();
908*b1cdbd2cSJim Jagielski         maContext.dispose();
909*b1cdbd2cSJim Jagielski         mbIsDisposed = true;
910*b1cdbd2cSJim Jagielski 
911*b1cdbd2cSJim Jagielski         maContext.mpSubsettableShapeManager->removeIntrinsicAnimationHandler(
912*b1cdbd2cSJim Jagielski             mpListener );
913*b1cdbd2cSJim Jagielski     }
914*b1cdbd2cSJim Jagielski }
915*b1cdbd2cSJim Jagielski 
calcTimeLag() const916*b1cdbd2cSJim Jagielski double ActivityImpl::calcTimeLag() const
917*b1cdbd2cSJim Jagielski {
918*b1cdbd2cSJim Jagielski     return 0.0;
919*b1cdbd2cSJim Jagielski }
920*b1cdbd2cSJim Jagielski 
isActive() const921*b1cdbd2cSJim Jagielski bool ActivityImpl::isActive() const
922*b1cdbd2cSJim Jagielski {
923*b1cdbd2cSJim Jagielski     return mbIsActive;
924*b1cdbd2cSJim Jagielski }
925*b1cdbd2cSJim Jagielski 
dequeued()926*b1cdbd2cSJim Jagielski void ActivityImpl::dequeued()
927*b1cdbd2cSJim Jagielski {
928*b1cdbd2cSJim Jagielski     // not used here
929*b1cdbd2cSJim Jagielski }
930*b1cdbd2cSJim Jagielski 
end()931*b1cdbd2cSJim Jagielski void ActivityImpl::end()
932*b1cdbd2cSJim Jagielski {
933*b1cdbd2cSJim Jagielski     // not used here
934*b1cdbd2cSJim Jagielski     mbIsActive = false;
935*b1cdbd2cSJim Jagielski 
936*b1cdbd2cSJim Jagielski     if( mbIsShapeAnimated )
937*b1cdbd2cSJim Jagielski     {
938*b1cdbd2cSJim Jagielski         maContext.mpSubsettableShapeManager->leaveAnimationMode( mpDrawShape );
939*b1cdbd2cSJim Jagielski         mbIsShapeAnimated = false;
940*b1cdbd2cSJim Jagielski     }
941*b1cdbd2cSJim Jagielski }
942*b1cdbd2cSJim Jagielski 
943*b1cdbd2cSJim Jagielski } // anon namespace
944*b1cdbd2cSJim Jagielski 
945*b1cdbd2cSJim Jagielski namespace slideshow {
946*b1cdbd2cSJim Jagielski namespace internal {
947*b1cdbd2cSJim Jagielski 
createDrawingLayerAnimActivity(SlideShowContext const & rContext,boost::shared_ptr<DrawShape> const & pDrawShape)948*b1cdbd2cSJim Jagielski boost::shared_ptr<Activity> createDrawingLayerAnimActivity(
949*b1cdbd2cSJim Jagielski     SlideShowContext const& rContext,
950*b1cdbd2cSJim Jagielski     boost::shared_ptr<DrawShape> const& pDrawShape )
951*b1cdbd2cSJim Jagielski {
952*b1cdbd2cSJim Jagielski     boost::shared_ptr<Activity> pActivity;
953*b1cdbd2cSJim Jagielski 
954*b1cdbd2cSJim Jagielski     try
955*b1cdbd2cSJim Jagielski     {
956*b1cdbd2cSJim Jagielski         boost::shared_ptr<WakeupEvent> const pWakeupEvent(
957*b1cdbd2cSJim Jagielski             new WakeupEvent( rContext.mrEventQueue.getTimer(),
958*b1cdbd2cSJim Jagielski                              rContext.mrActivitiesQueue ) );
959*b1cdbd2cSJim Jagielski         pActivity.reset( new ActivityImpl( rContext, pWakeupEvent, pDrawShape ) );
960*b1cdbd2cSJim Jagielski         pWakeupEvent->setActivity( pActivity );
961*b1cdbd2cSJim Jagielski     }
962*b1cdbd2cSJim Jagielski     catch( uno::RuntimeException& )
963*b1cdbd2cSJim Jagielski     {
964*b1cdbd2cSJim Jagielski         throw;
965*b1cdbd2cSJim Jagielski     }
966*b1cdbd2cSJim Jagielski     catch( uno::Exception& )
967*b1cdbd2cSJim Jagielski     {
968*b1cdbd2cSJim Jagielski         // translate any error into empty factory product.
969*b1cdbd2cSJim Jagielski         OSL_ENSURE( false,
970*b1cdbd2cSJim Jagielski                     rtl::OUStringToOString(
971*b1cdbd2cSJim Jagielski                         comphelper::anyToString( cppu::getCaughtException() ),
972*b1cdbd2cSJim Jagielski                         RTL_TEXTENCODING_UTF8 ).getStr() );
973*b1cdbd2cSJim Jagielski     }
974*b1cdbd2cSJim Jagielski 
975*b1cdbd2cSJim Jagielski     return pActivity;
976*b1cdbd2cSJim Jagielski }
977*b1cdbd2cSJim Jagielski 
978*b1cdbd2cSJim Jagielski } // namespace internal
979*b1cdbd2cSJim Jagielski } // namespace presentation
980*b1cdbd2cSJim Jagielski 
981