1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <canvas/debug.hxx>
22 #include <tools/diagnose_ex.h>
23 #include <tools/helpers.hxx>
24 #include <canvas/elapsedtime.hxx>
25 #include <basegfx/polygon/b2dpolygontools.hxx>
27 #include <comphelper/anytostring.hxx>
28 #include <cppuhelper/exc_hlp.hxx>
30 #include <rtl/math.hxx>
31 #include <vcl/metric.hxx>
32 #include <vcl/canvastools.hxx>
33 #include <vcl/metaact.hxx>
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 #include <com/sun/star/drawing/TextAnimationKind.hpp>
36 #include <com/sun/star/drawing/TextAnimationDirection.hpp>
37 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
38 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
39 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
40 #include <com/sun/star/awt/Rectangle.hpp>
42 #include "activity.hxx"
43 #include "wakeupevent.hxx"
44 #include "eventqueue.hxx"
45 #include "drawinglayeranimation.hxx"
46 #include "drawshapesubsetting.hxx"
47 #include "drawshape.hxx"
48 #include "shapesubset.hxx"
49 #include "shapeattributelayerholder.hxx"
50 #include "slideshowcontext.hxx"
52 #include "gdimtftools.hxx"
53 #include "eventmultiplexer.hxx"
54 #include "intrinsicanimationactivity.hxx"
55 #include "intrinsicanimationeventhandler.hxx"
57 #include <boost/weak_ptr.hpp>
58 #include <boost/enable_shared_from_this.hpp>
59 #include <boost/noncopyable.hpp>
62 using namespace com::sun::star
;
63 using namespace ::slideshow::internal
;
67 class ScrollTextAnimNode
69 sal_uInt32 mnDuration
; // single duration
70 sal_uInt32 mnRepeat
; // 0 -> endless
73 sal_uInt32 mnFrequency
; // in ms
74 // forth and back change at mnRepeat%2:
79 sal_uInt32 nDuration
, sal_uInt32 nRepeat
, double fStart
, double fStop
,
80 sal_uInt32 nFrequency
, bool bAlternate
)
81 : mnDuration(nDuration
),
85 mnFrequency(nFrequency
),
86 mbAlternate(bAlternate
)
89 sal_uInt32
GetRepeat() const { return mnRepeat
; }
90 sal_uInt32
GetFullTime() const { return mnDuration
* mnRepeat
; }
91 double GetStop() const { return mfStop
; }
92 sal_uInt32
GetFrequency() const { return mnFrequency
; }
93 bool DoAlternate() const { return mbAlternate
; }
95 double GetStateAtRelativeTime(sal_uInt32 nRelativeTime
) const;
98 double ScrollTextAnimNode::GetStateAtRelativeTime(
99 sal_uInt32 nRelativeTime
) const
101 // Avoid division by zero.
102 if( mnDuration
== 0 )
108 const sal_uInt32
nRepeatCount(nRelativeTime
/ mnDuration
);
109 sal_uInt32
nFrameTime(nRelativeTime
- (nRepeatCount
* mnDuration
));
111 if(DoAlternate() && (nRepeatCount
+ 1L) % 2L)
112 nFrameTime
= mnDuration
- nFrameTime
;
114 return mfStart
+ ((mfStop
- mfStart
) *
115 (double(nFrameTime
) / mnDuration
));
120 sal_uInt32
nFrameTime(nRelativeTime
% mnDuration
);
124 const sal_uInt32
nRepeatCount(nRelativeTime
/ mnDuration
);
126 if((nRepeatCount
+ 1L) % 2L)
127 nFrameTime
= mnDuration
- nFrameTime
;
130 return mfStart
+ ((mfStop
- mfStart
) * (double(nFrameTime
) / mnDuration
));
134 class ActivityImpl
: public Activity
,
135 public boost::enable_shared_from_this
<ActivityImpl
>,
136 private boost::noncopyable
139 virtual ~ActivityImpl();
142 SlideShowContext
const& rContext
,
143 boost::shared_ptr
<WakeupEvent
> const& pWakeupEvent
,
144 boost::shared_ptr
<DrawShape
> const& pDrawShape
);
146 bool enableAnimations();
149 virtual void dispose() SAL_OVERRIDE
;
151 virtual double calcTimeLag() const SAL_OVERRIDE
;
152 virtual bool perform() SAL_OVERRIDE
;
153 virtual bool isActive() const SAL_OVERRIDE
;
154 virtual void dequeued() SAL_OVERRIDE
;
155 virtual void end() SAL_OVERRIDE
;
158 void updateShapeAttributes( double fTime
,
159 basegfx::B2DRectangle
const& parentBounds
);
161 // Access to VisibleWhenSTarted flags
162 bool IsVisibleWhenStarted() const { return mbVisibleWhenStarted
; }
163 bool IsVisibleWhenStopped() const { return mbVisibleWhenStopped
; }
165 // scroll horizontal? if sal_False, scroll is vertical.
166 bool ScrollHorizontal() const {
167 return (drawing::TextAnimationDirection_LEFT
== meDirection
||
168 drawing::TextAnimationDirection_RIGHT
== meDirection
);
171 // Access to StepWidth in logical units
172 sal_uInt32
GetStepWidthLogic() const;
174 // is the animation direction opposite?
175 bool DoScrollForward() const {
176 return (drawing::TextAnimationDirection_RIGHT
== meDirection
||
177 drawing::TextAnimationDirection_DOWN
== meDirection
);
180 // do alternate text directions?
181 bool DoAlternate() const { return mbAlternate
; }
184 bool DoScrollIn() const { return mbScrollIn
; }
186 // Scroll helper methods
187 void ImpForceScrollTextAnimNodes();
188 ScrollTextAnimNode
* ImpGetScrollTextAnimNode(
189 sal_uInt32 nTime
, sal_uInt32
& rRelativeTime
);
190 sal_uInt32
ImpRegisterAgainScrollTextMixerState(
193 // calculate the MixerState value for given time
194 double GetMixerState(sal_uInt32 nTime
);
198 SlideShowContext maContext
;
199 boost::shared_ptr
<WakeupEvent
> mpWakeupEvent
;
200 boost::weak_ptr
<DrawShape
> mpParentDrawShape
;
201 DrawShapeSharedPtr mpDrawShape
;
202 ShapeAttributeLayerHolder maShapeAttrLayer
;
203 GDIMetaFileSharedPtr mpMetaFile
;
204 IntrinsicAnimationEventHandlerSharedPtr mpListener
;
205 canvas::tools::ElapsedTime maTimer
;
206 double mfRotationAngle
;
207 bool mbIsShapeAnimated
;
210 drawing::TextAnimationKind meAnimKind
;
212 // The blink frequency in ms
213 sal_uInt32 mnFrequency
;
215 // The repeat count, init to 0L which means endless
218 // Flag to decide if text will be shown when animation has ended
219 bool mbVisibleWhenStopped
;
220 bool mbVisibleWhenStarted
;
222 // Flag decides if TextScroll alternates. Default is sal_False.
225 // Flag to remember if this is a simple scrollin text
228 // start time for this animation
229 sal_uInt32 mnStartTime
;
231 // The AnimationDirection
232 drawing::TextAnimationDirection meDirection
;
234 // Get width per Step. Negative means pixel, positive logical units
235 sal_Int32 mnStepWidth
;
237 // The single anim steps
238 std::vector
< ScrollTextAnimNode
> maVector
;
240 // the scroll rectangle
241 Rectangle maScrollRectangleLogic
;
243 // the paint rectangle
244 Rectangle maPaintRectangleLogic
;
249 class IntrinsicAnimationListener
: public IntrinsicAnimationEventHandler
,
250 private boost::noncopyable
253 explicit IntrinsicAnimationListener( ActivityImpl
& rActivity
) :
254 mrActivity( rActivity
)
259 virtual bool enableAnimations() SAL_OVERRIDE
{ return mrActivity
.enableAnimations(); }
260 virtual bool disableAnimations() SAL_OVERRIDE
{ mrActivity
.end(); return true; }
262 ActivityImpl
& mrActivity
;
267 double ActivityImpl::GetMixerState( sal_uInt32 nTime
)
269 if( meAnimKind
== drawing::TextAnimationKind_BLINK
)
271 // from AInfoBlinkText:
274 const sal_uInt32
nLoopTime(2 * mnFrequency
);
278 const sal_uInt32
nEndTime(mnRepeat
* nLoopTime
);
280 if(nTime
>= nEndTime
)
282 if(mbVisibleWhenStopped
)
293 sal_uInt32
nTimeInLoop(nTime
% nLoopTime
);
294 fRetval
= double(nTimeInLoop
) / nLoopTime
;
301 // from AInfoScrollText:
303 ImpForceScrollTextAnimNodes();
305 if(!maVector
.empty())
307 sal_uInt32 nRelativeTime
;
308 ScrollTextAnimNode
* pNode
=
309 ImpGetScrollTextAnimNode(nTime
, nRelativeTime
);
314 fRetval
= pNode
->GetStateAtRelativeTime(nRelativeTime
);
318 // end of animation, take last entry's end
319 fRetval
= maVector
[maVector
.size() - 1L].GetStop();
327 // Access to StepWidth in logical units
328 sal_uInt32
ActivityImpl::GetStepWidthLogic() const
330 // #i69847# Assuming higher DPI
331 sal_uInt32
const PIXEL_TO_LOGIC
= 30;
333 sal_uInt32
nRetval(0L);
337 // is in pixels, convert to logical units
338 nRetval
= (-mnStepWidth
* PIXEL_TO_LOGIC
);
340 else if(mnStepWidth
> 0L)
342 // is in logical units
343 nRetval
= mnStepWidth
;
348 // step 1 pixel, canned value
350 // with very high DPIs like in PDF export, this can
351 // still get zero. for that cases, set a default, too (taken
352 // from ainfoscrolltext.cxx)
359 void ActivityImpl::ImpForceScrollTextAnimNodes()
364 sal_uInt32 nLoopTime
;
365 double fZeroLogic
, fOneLogic
, fInitLogic
, fDistanceLogic
;
366 double fZeroLogicAlternate
= 0.0, fOneLogicAlternate
= 0.0;
367 double fZeroRelative
, fOneRelative
, fInitRelative
;
369 if(ScrollHorizontal())
373 if(maPaintRectangleLogic
.GetWidth() >
374 maScrollRectangleLogic
.GetWidth())
376 fZeroLogicAlternate
= maScrollRectangleLogic
.Right() - maPaintRectangleLogic
.GetWidth();
377 fOneLogicAlternate
= maScrollRectangleLogic
.Left();
381 fZeroLogicAlternate
= maScrollRectangleLogic
.Left();
382 fOneLogicAlternate
= maScrollRectangleLogic
.Right() - maPaintRectangleLogic
.GetWidth();
386 fZeroLogic
= maScrollRectangleLogic
.Left() - maPaintRectangleLogic
.GetWidth();
387 fOneLogic
= maScrollRectangleLogic
.Right();
388 fInitLogic
= maPaintRectangleLogic
.Left();
394 if(maPaintRectangleLogic
.GetHeight() > maScrollRectangleLogic
.GetHeight())
396 fZeroLogicAlternate
= maScrollRectangleLogic
.Bottom() - maPaintRectangleLogic
.GetHeight();
397 fOneLogicAlternate
= maScrollRectangleLogic
.Top();
401 fZeroLogicAlternate
= maScrollRectangleLogic
.Top();
402 fOneLogicAlternate
= maScrollRectangleLogic
.Bottom() - maPaintRectangleLogic
.GetHeight();
406 fZeroLogic
= maScrollRectangleLogic
.Top() - maPaintRectangleLogic
.GetHeight();
407 fOneLogic
= maScrollRectangleLogic
.Bottom();
408 fInitLogic
= maPaintRectangleLogic
.Top();
411 fDistanceLogic
= fOneLogic
- fZeroLogic
;
412 fInitRelative
= (fInitLogic
- fZeroLogic
) / fDistanceLogic
;
417 (fZeroLogicAlternate
- fZeroLogic
) / fDistanceLogic
;
419 (fOneLogicAlternate
- fZeroLogic
) / fDistanceLogic
;
430 ScrollTextAnimNode
aStartNode(
431 mnStartTime
, 1L, 0.0, 0.0, mnStartTime
, false);
432 maVector
.push_back(aStartNode
);
435 if(IsVisibleWhenStarted())
437 double fRelativeStartValue
, fRelativeEndValue
,fRelativeDistance
;
439 if(DoScrollForward())
441 fRelativeStartValue
= fInitRelative
;
442 fRelativeEndValue
= fOneRelative
;
443 fRelativeDistance
= fRelativeEndValue
- fRelativeStartValue
;
447 fRelativeStartValue
= fInitRelative
;
448 fRelativeEndValue
= fZeroRelative
;
449 fRelativeDistance
= fRelativeStartValue
- fRelativeEndValue
;
452 const double fNumberSteps
=
453 (fRelativeDistance
* fDistanceLogic
) / GetStepWidthLogic();
454 nLoopTime
= FRound(fNumberSteps
* mnFrequency
);
457 ScrollTextAnimNode
aInitNode(
459 fRelativeStartValue
, fRelativeEndValue
,
461 maVector
.push_back(aInitNode
);
464 // prepare main loop values
466 double fRelativeStartValue
, fRelativeEndValue
, fRelativeDistance
;
468 if(DoScrollForward())
470 fRelativeStartValue
= fZeroRelative
;
471 fRelativeEndValue
= fOneRelative
;
472 fRelativeDistance
= fRelativeEndValue
- fRelativeStartValue
;
476 fRelativeStartValue
= fOneRelative
;
477 fRelativeEndValue
= fZeroRelative
;
478 fRelativeDistance
= fRelativeStartValue
- fRelativeEndValue
;
481 const double fNumberSteps
=
482 (fRelativeDistance
* fDistanceLogic
) / GetStepWidthLogic();
483 nLoopTime
= FRound(fNumberSteps
* mnFrequency
);
490 ScrollTextAnimNode
aMainNode(
492 fRelativeStartValue
, fRelativeEndValue
,
493 mnFrequency
, DoAlternate());
494 maVector
.push_back(aMainNode
);
499 sal_uInt32
nNumRepeat(mnRepeat
);
501 if(DoAlternate() && (nNumRepeat
+ 1L) % 2L)
505 ScrollTextAnimNode
aMainNode(
506 nLoopTime
, nNumRepeat
,
507 fRelativeStartValue
, fRelativeEndValue
,
508 mnFrequency
, DoAlternate());
509 maVector
.push_back(aMainNode
);
513 if(IsVisibleWhenStopped())
515 double fRelativeStartValue
, fRelativeEndValue
, fRelativeDistance
;
517 if(DoScrollForward())
519 fRelativeStartValue
= fZeroRelative
;
520 fRelativeEndValue
= fInitRelative
;
521 fRelativeDistance
= fRelativeEndValue
- fRelativeStartValue
;
525 fRelativeStartValue
= fOneRelative
;
526 fRelativeEndValue
= fInitRelative
;
527 fRelativeDistance
= fRelativeStartValue
- fRelativeEndValue
;
530 const double fNumberSteps
=
531 (fRelativeDistance
* fDistanceLogic
) / GetStepWidthLogic();
532 nLoopTime
= FRound(fNumberSteps
* mnFrequency
);
535 ScrollTextAnimNode
aExitNode(
537 fRelativeStartValue
, fRelativeEndValue
, mnFrequency
, false);
538 maVector
.push_back(aExitNode
);
543 ScrollTextAnimNode
* ActivityImpl::ImpGetScrollTextAnimNode(
544 sal_uInt32 nTime
, sal_uInt32
& rRelativeTime
)
546 ScrollTextAnimNode
* pRetval
= 0L;
547 ImpForceScrollTextAnimNodes();
549 if(!maVector
.empty())
551 rRelativeTime
= nTime
;
553 for(sal_uInt32
a(0L); !pRetval
&& a
< maVector
.size(); a
++)
555 ScrollTextAnimNode
& rNode
= maVector
[a
];
556 if(!rNode
.GetRepeat())
558 // endless loop, use it
561 else if(rNode
.GetFullTime() > rRelativeTime
)
569 rRelativeTime
-= rNode
.GetFullTime();
577 sal_uInt32
ActivityImpl::ImpRegisterAgainScrollTextMixerState(sal_uInt32 nTime
)
579 sal_uInt32
nRetval(0L);
580 ImpForceScrollTextAnimNodes();
582 if(!maVector
.empty())
584 sal_uInt32 nRelativeTime
;
585 ScrollTextAnimNode
* pNode
= ImpGetScrollTextAnimNode(nTime
, nRelativeTime
);
589 // take register time
590 nRetval
= pNode
->GetFrequency();
595 // #i38135# not initialized, return default
596 nRetval
= mnFrequency
;
602 void ActivityImpl::updateShapeAttributes(
603 double fTime
, basegfx::B2DRectangle
const& parentBounds
)
605 OSL_ASSERT( meAnimKind
!= drawing::TextAnimationKind_NONE
);
606 if( meAnimKind
== drawing::TextAnimationKind_NONE
)
609 double const fMixerState
= GetMixerState(
610 static_cast<sal_uInt32
>(fTime
* 1000.0) );
612 if( meAnimKind
== drawing::TextAnimationKind_BLINK
)
615 maShapeAttrLayer
.get()->setVisibility( fMixerState
< 0.5 );
617 else if(mpMetaFile
) // scroll mode:
620 // keep care: the below code is highly sensible to changes...
623 // rectangle of the pure text:
624 double const fPaintWidth
= maPaintRectangleLogic
.GetWidth();
625 double const fPaintHeight
= maPaintRectangleLogic
.GetHeight();
626 // rectangle where the scrolling takes place (-> clipping):
627 double const fScrollWidth
= maScrollRectangleLogic
.GetWidth();
628 double const fScrollHeight
= maScrollRectangleLogic
.GetHeight();
630 basegfx::B2DPoint pos
, clipPos
;
632 if(ScrollHorizontal())
634 double const fOneEquiv( fScrollWidth
);
635 double const fZeroEquiv( -fPaintWidth
);
637 pos
.setX( fZeroEquiv
+ (fMixerState
* (fOneEquiv
- fZeroEquiv
)) );
639 clipPos
.setX( -pos
.getX() );
640 clipPos
.setY( -pos
.getY() );
642 // #i69844# Compensation for text-wider-than-shape case
643 if( fPaintWidth
> fScrollWidth
)
644 pos
.setX( pos
.getX() + (fPaintWidth
-fScrollWidth
) / 2.0 );
649 double const fOneEquiv( fScrollHeight
);
650 double const fZeroEquiv( -fPaintHeight
);
652 pos
.setY( fZeroEquiv
+ (fMixerState
* (fOneEquiv
- fZeroEquiv
)) );
654 clipPos
.setX( -pos
.getX() );
655 clipPos
.setY( -pos
.getY() );
657 // #i69844# Compensation for text-higher-than-shape case
658 if( fPaintHeight
> fScrollHeight
)
659 pos
.setY( pos
.getY() + (fPaintHeight
-fScrollHeight
) / 2.0 );
662 basegfx::B2DPolygon
clipPoly(
663 basegfx::tools::createPolygonFromRect(
664 basegfx::B2DRectangle( clipPos
.getX(),
666 clipPos
.getX() + fScrollWidth
,
667 clipPos
.getY() + fScrollHeight
) ) );
669 if( !::basegfx::fTools::equalZero( mfRotationAngle
))
671 maShapeAttrLayer
.get()->setRotationAngle( mfRotationAngle
);
672 double const fRotate
= (mfRotationAngle
* M_PI
/ 180.0);
673 basegfx::B2DHomMatrix aTransform
;
675 aTransform
.rotate( fRotate
);
679 pos
+= parentBounds
.getCenter();
680 maShapeAttrLayer
.get()->setPosition( pos
);
681 maShapeAttrLayer
.get()->setClip( basegfx::B2DPolyPolygon(clipPoly
) );
685 bool ActivityImpl::perform()
690 ENSURE_OR_RETURN_FALSE(
692 "ActivityImpl::perform(): still active, but NULL draw shape" );
694 DrawShapeSharedPtr
const pParentDrawShape( mpParentDrawShape
);
695 if( !pParentDrawShape
)
696 return false; // parent has vanished
698 if( pParentDrawShape
->isVisible() )
700 if( !mbIsShapeAnimated
)
702 mpDrawShape
->setVisibility(true); // shape may be initially hidden
703 maContext
.mpSubsettableShapeManager
->enterAnimationMode( mpDrawShape
);
705 mbIsShapeAnimated
= true;
707 // update attributes related to current time:
708 basegfx::B2DRectangle
const parentBounds(
709 pParentDrawShape
->getBounds() );
711 const double nCurrTime( maTimer
.getElapsedTime() );
712 updateShapeAttributes( nCurrTime
, parentBounds
);
714 const sal_uInt32
nFrequency(
715 ImpRegisterAgainScrollTextMixerState(
716 static_cast<sal_uInt32
>(nCurrTime
* 1000.0)) );
720 mpWakeupEvent
->start();
721 mpWakeupEvent
->setNextTimeout(
722 std::max(0.1,nFrequency
/1000.0) );
723 maContext
.mrEventQueue
.addEvent( mpWakeupEvent
);
725 if( mpDrawShape
->isContentChanged() )
726 maContext
.mpSubsettableShapeManager
->notifyShapeUpdate( mpDrawShape
);
728 // else: finished, not need to wake up again.
732 // busy-wait, until parent shape gets visible
733 mpWakeupEvent
->start();
734 mpWakeupEvent
->setNextTimeout( 2.0 );
737 // don't reinsert, WakeupEvent will perform that after the given timeout:
741 ActivityImpl::ActivityImpl(
742 SlideShowContext
const& rContext
,
743 boost::shared_ptr
<WakeupEvent
> const& pWakeupEvent
,
744 boost::shared_ptr
<DrawShape
> const& pParentDrawShape
)
745 : maContext(rContext
),
746 mpWakeupEvent(pWakeupEvent
),
747 mpParentDrawShape(pParentDrawShape
),
748 mpListener( new IntrinsicAnimationListener(*this) ),
749 maTimer(rContext
.mrEventQueue
.getTimer()),
750 mfRotationAngle(0.0),
751 mbIsShapeAnimated(false),
754 meAnimKind(drawing::TextAnimationKind_NONE
),
755 mbVisibleWhenStopped(false),
756 mbVisibleWhenStarted(false),
761 sal_Int32
const nNodes
= pParentDrawShape
->getNumberOfTreeNodes(
762 DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH
);
764 DocTreeNode
scrollTextNode(
765 pParentDrawShape
->getTreeNode(
766 0, DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH
));
767 // xxx todo: remove this hack
769 scrollTextNode
.setEndIndex(
770 pParentDrawShape
->getTreeNode(
772 DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH
).getEndIndex());
774 // TODO(Q3): Doing this manually, instead of using
775 // ShapeSubset. This is because of lifetime issues (ShapeSubset
776 // generates circular references to parent shape)
777 mpDrawShape
= boost::dynamic_pointer_cast
<DrawShape
>(
778 maContext
.mpSubsettableShapeManager
->getSubsetShape(
782 mpMetaFile
= mpDrawShape
->forceScrollTextMetaFile();
784 // make scroll text invisible for slide transition bitmaps
785 mpDrawShape
->setVisibility(false);
787 basegfx::B2DRectangle aScrollRect
, aPaintRect
;
788 ENSURE_OR_THROW( getRectanglesFromScrollMtf( aScrollRect
,
791 "ActivityImpl::ActivityImpl(): Could not extract "
792 "scroll anim rectangles from mtf" );
794 maScrollRectangleLogic
= vcl::unotools::rectangleFromB2DRectangle(
796 maPaintRectangleLogic
= vcl::unotools::rectangleFromB2DRectangle(
799 maShapeAttrLayer
.createAttributeLayer(mpDrawShape
);
801 uno::Reference
<drawing::XShape
> const xShape( mpDrawShape
->getXShape() );
802 uno::Reference
<beans::XPropertySet
> const xProps( xShape
, uno::UNO_QUERY_THROW
);
804 getPropertyValue( meAnimKind
, xProps
, "TextAnimationKind" );
805 OSL_ASSERT( meAnimKind
!= drawing::TextAnimationKind_NONE
);
806 mbAlternate
= (meAnimKind
== drawing::TextAnimationKind_ALTERNATE
);
807 mbScrollIn
= (meAnimKind
== drawing::TextAnimationKind_SLIDE
);
809 // adopted from in AInfoBlinkText::ImplInit():
810 sal_Int16
nRepeat(0);
811 getPropertyValue( nRepeat
, xProps
, "TextAnimationCount" );
816 // force visible when started for scroll-forth-and-back, because
817 // slide has been coming in with visible text in the middle:
818 mbVisibleWhenStarted
= true;
822 getPropertyValue( mbVisibleWhenStarted
, xProps
,
823 "TextAnimationStartInside" );
826 // set visible when stopped
827 getPropertyValue( mbVisibleWhenStopped
, xProps
,
828 "TextAnimatiogonStopInside" );
830 getPropertyValue( mfRotationAngle
, xProps
,
832 mfRotationAngle
/= -100.0; // (switching direction)
836 getPropertyValue( nDelay
, xProps
, "TextAnimationDelay" );
837 // set delay if not automatic
838 mnFrequency
= (nDelay
? nDelay
:
840 meAnimKind
== drawing::TextAnimationKind_BLINK
843 // adopted from in AInfoScrollText::ImplInit():
845 // If it is a simple m_bScrollIn, reset some parameters
848 // most parameters are set correctly from the dialog logic, but
849 // eg VisisbleWhenStopped is grayed out and needs to be corrected here.
850 mbVisibleWhenStopped
= true;
851 mbVisibleWhenStarted
= false;
855 // Get animation direction
856 getPropertyValue( meDirection
, xProps
, "TextAnimationDirection" );
858 // Get step width. Negative means pixel, positive logical units
859 getPropertyValue( mnStepWidth
, xProps
, "TextAnimationAmount" );
861 maContext
.mpSubsettableShapeManager
->addIntrinsicAnimationHandler(
865 bool ActivityImpl::enableAnimations()
868 return maContext
.mrActivitiesQueue
.addActivity(
869 shared_from_this() );
872 ActivityImpl::~ActivityImpl()
876 void ActivityImpl::dispose()
882 // only remove subset here, since end() is called on slide end
883 // (and we must not spoil the slide preview bitmap with scroll
885 maShapeAttrLayer
.reset();
888 // TODO(Q3): Doing this manually, instead of using
889 // ShapeSubset. This is because of lifetime issues
890 // (ShapeSubset generates circular references to parent
892 DrawShapeSharedPtr
pParent( mpParentDrawShape
.lock() );
894 maContext
.mpSubsettableShapeManager
->revokeSubset(
901 mpParentDrawShape
.reset();
902 mpWakeupEvent
.reset();
906 maContext
.mpSubsettableShapeManager
->removeIntrinsicAnimationHandler(
911 double ActivityImpl::calcTimeLag() const
916 bool ActivityImpl::isActive() const
921 void ActivityImpl::dequeued()
926 void ActivityImpl::end()
931 if( mbIsShapeAnimated
)
933 maContext
.mpSubsettableShapeManager
->leaveAnimationMode( mpDrawShape
);
934 mbIsShapeAnimated
= false;
940 namespace slideshow
{
943 boost::shared_ptr
<Activity
> createDrawingLayerAnimActivity(
944 SlideShowContext
const& rContext
,
945 boost::shared_ptr
<DrawShape
> const& pDrawShape
)
947 boost::shared_ptr
<Activity
> pActivity
;
951 boost::shared_ptr
<WakeupEvent
> const pWakeupEvent(
952 new WakeupEvent( rContext
.mrEventQueue
.getTimer(),
953 rContext
.mrActivitiesQueue
) );
954 pActivity
.reset( new ActivityImpl( rContext
, pWakeupEvent
, pDrawShape
) );
955 pWakeupEvent
->setActivity( pActivity
);
957 catch( uno::RuntimeException
& )
961 catch( uno::Exception
& )
963 // translate any error into empty factory product.
964 OSL_FAIL( OUStringToOString(
965 comphelper::anyToString( cppu::getCaughtException() ),
966 RTL_TEXTENCODING_UTF8
).getStr() );
972 } // namespace internal
973 } // namespace presentation
975 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */