1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: drawinglayeranimation.cxx,v $
10 * $Revision: 1.5.10.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
34 #include <canvas/debug.hxx>
35 #include <tools/diagnose_ex.h>
36 #include <canvas/elapsedtime.hxx>
37 #include <basegfx/polygon/b2dpolygontools.hxx>
39 #include <comphelper/anytostring.hxx>
40 #include <cppuhelper/exc_hlp.hxx>
42 #include <rtl/math.hxx>
43 #include <vcl/metric.hxx>
44 #include <vcl/salbtype.hxx>
45 #include <vcl/canvastools.hxx>
46 #include <vcl/metaact.hxx>
47 #include <com/sun/star/beans/XPropertySet.hpp>
48 #include <com/sun/star/drawing/TextAnimationKind.hpp>
49 #include <com/sun/star/drawing/TextAnimationDirection.hpp>
50 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
51 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
52 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
53 #include <com/sun/star/awt/Rectangle.hpp>
55 #include "activity.hxx"
56 #include "wakeupevent.hxx"
57 #include "eventqueue.hxx"
58 #include "drawshapesubsetting.hxx"
59 #include "drawshape.hxx"
60 #include "shapesubset.hxx"
61 #include "shapeattributelayerholder.hxx"
62 #include "slideshowcontext.hxx"
64 #include "gdimtftools.hxx"
65 #include "eventmultiplexer.hxx"
66 #include "intrinsicanimationactivity.hxx"
67 #include "intrinsicanimationeventhandler.hxx"
69 #include <boost/weak_ptr.hpp>
70 #include <boost/enable_shared_from_this.hpp>
71 #include <boost/noncopyable.hpp>
74 using namespace com::sun::star
;
75 using namespace ::slideshow::internal
;
79 class ScrollTextAnimNode
81 sal_uInt32 mnDuration
; // single duration
82 sal_uInt32 mnRepeat
; // 0 -> endless
85 sal_uInt32 mnFrequency
; // in ms
86 // forth and back change at mnRepeat%2:
91 sal_uInt32 nDuration
, sal_uInt32 nRepeat
, double fStart
, double fStop
,
92 sal_uInt32 nFrequency
, bool bAlternate
)
93 : mnDuration(nDuration
),
97 mnFrequency(nFrequency
),
98 mbAlternate(bAlternate
)
101 sal_uInt32
GetDuration() const { return mnDuration
; }
102 sal_uInt32
GetRepeat() const { return mnRepeat
; }
103 sal_uInt32
GetFullTime() const { return mnDuration
* mnRepeat
; }
104 double GetStart() const { return mfStart
; }
105 double GetStop() const { return mfStop
; }
106 sal_uInt32
GetFrequency() const { return mnFrequency
; }
107 bool DoAlternate() const { return mbAlternate
; }
109 double GetStateAtRelativeTime(sal_uInt32 nRelativeTime
) const;
112 double ScrollTextAnimNode::GetStateAtRelativeTime(
113 sal_uInt32 nRelativeTime
) const
115 // #151174# Avoid division by zero.
116 if( mnDuration
== 0 )
122 const sal_uInt32
nRepeatCount(nRelativeTime
/ mnDuration
);
123 sal_uInt32
nFrameTime(nRelativeTime
- (nRepeatCount
* mnDuration
));
125 if(DoAlternate() && (nRepeatCount
+ 1L) % 2L)
126 nFrameTime
= mnDuration
- nFrameTime
;
128 return mfStart
+ ((mfStop
- mfStart
) *
129 (double(nFrameTime
) / mnDuration
));
134 sal_uInt32
nFrameTime(nRelativeTime
% mnDuration
);
138 const sal_uInt32
nRepeatCount(nRelativeTime
/ mnDuration
);
140 if((nRepeatCount
+ 1L) % 2L)
141 nFrameTime
= mnDuration
- nFrameTime
;
144 return mfStart
+ ((mfStop
- mfStart
) * (double(nFrameTime
) / mnDuration
));
148 class ActivityImpl
: public Activity
,
149 public boost::enable_shared_from_this
<ActivityImpl
>,
150 private boost::noncopyable
153 virtual ~ActivityImpl();
156 SlideShowContext
const& rContext
,
157 boost::shared_ptr
<WakeupEvent
> const& pWakeupEvent
,
158 boost::shared_ptr
<DrawShape
> const& pDrawShape
);
160 bool enableAnimations();
163 virtual void dispose();
165 virtual double calcTimeLag() const;
166 virtual bool perform();
167 virtual bool isActive() const;
168 virtual void dequeued();
172 void updateShapeAttributes( double fTime
,
173 basegfx::B2DRectangle
const& parentBounds
);
175 // Access to VisibleWhenSTarted flags
176 sal_Bool
IsVisibleWhenStarted() const { return mbVisibleWhenStarted
; }
177 sal_Bool
IsVisibleWhenStopped() const { return mbVisibleWhenStopped
; }
179 // scroll horizontal? if sal_False, scroll is vertical.
180 bool ScrollHorizontal() const {
181 return (drawing::TextAnimationDirection_LEFT
== meDirection
||
182 drawing::TextAnimationDirection_RIGHT
== meDirection
);
185 // Access to StepWidth in logical units
186 sal_uInt32
GetStepWidthLogic() const;
188 // is the animation direction opposite?
189 bool DoScrollForward() const {
190 return (drawing::TextAnimationDirection_RIGHT
== meDirection
||
191 drawing::TextAnimationDirection_DOWN
== meDirection
);
194 // do alternate text directions?
195 bool DoAlternate() const { return mbAlternate
; }
198 bool DoScrollIn() const { return mbScrollIn
; }
200 // Scroll helper methods
201 void ImpForceScrollTextAnimNodes();
202 ScrollTextAnimNode
* ImpGetScrollTextAnimNode(
203 sal_uInt32 nTime
, sal_uInt32
& rRelativeTime
);
204 sal_uInt32
ImpRegisterAgainScrollTextMixerState(
207 // calculate the MixerState value for given time
208 double GetMixerState(sal_uInt32 nTime
);
210 ////////////////////////////////////////////////////////////////////
212 SlideShowContext maContext
;
213 boost::shared_ptr
<WakeupEvent
> mpWakeupEvent
;
214 boost::weak_ptr
<DrawShape
> mpParentDrawShape
;
215 DrawShapeSharedPtr mpDrawShape
;
216 ShapeAttributeLayerHolder maShapeAttrLayer
;
217 GDIMetaFileSharedPtr mpMetaFile
;
218 IntrinsicAnimationEventHandlerSharedPtr mpListener
;
219 canvas::tools::ElapsedTime maTimer
;
220 double mfRotationAngle
;
221 bool mbIsShapeAnimated
;
224 drawing::TextAnimationKind meAnimKind
;
226 // The blink frequency in ms
227 sal_uInt32 mnFrequency
;
229 // The repeat count, init to 0L which means endless
232 // Flag to decide if text will be shown when animation has ended
233 bool mbVisibleWhenStopped
;
234 bool mbVisibleWhenStarted
;
236 // Flag decides if TextScroll alternates. Default is sal_False.
239 // Flag to remember if this is a simple scrollin text
242 // start time for this animation
243 sal_uInt32 mnStartTime
;
245 // The AnimationDirection
246 drawing::TextAnimationDirection meDirection
;
248 // Get width per Step. Negative means pixel, positive logical units
249 sal_Int32 mnStepWidth
;
251 // The single anim steps
252 std::vector
< ScrollTextAnimNode
> maVector
;
254 // the scroll rectangle
255 Rectangle maScrollRectangleLogic
;
257 // the paint rectangle
258 Rectangle maPaintRectangleLogic
;
261 //////////////////////////////////////////////////////////////////////
263 class IntrinsicAnimationListener
: public IntrinsicAnimationEventHandler
,
264 private boost::noncopyable
267 explicit IntrinsicAnimationListener( ActivityImpl
& rActivity
) :
268 mrActivity( rActivity
)
273 virtual bool enableAnimations() { return mrActivity
.enableAnimations(); }
274 virtual bool disableAnimations() { mrActivity
.end(); return true; }
276 ActivityImpl
& mrActivity
;
279 //////////////////////////////////////////////////////////////////////
281 double ActivityImpl::GetMixerState( sal_uInt32 nTime
)
283 if( meAnimKind
== drawing::TextAnimationKind_BLINK
)
285 // from AInfoBlinkText:
287 sal_Bool
bDone(sal_False
);
288 const sal_uInt32
nLoopTime(2 * mnFrequency
);
292 const sal_uInt32
nEndTime(mnRepeat
* nLoopTime
);
294 if(nTime
>= nEndTime
)
296 if(mbVisibleWhenStopped
)
307 sal_uInt32
nTimeInLoop(nTime
% nLoopTime
);
308 fRetval
= double(nTimeInLoop
) / nLoopTime
;
315 // from AInfoScrollText:
317 ImpForceScrollTextAnimNodes();
319 if(!maVector
.empty())
321 sal_uInt32 nRelativeTime
;
322 ScrollTextAnimNode
* pNode
=
323 ImpGetScrollTextAnimNode(nTime
, nRelativeTime
);
328 fRetval
= pNode
->GetStateAtRelativeTime(nRelativeTime
);
332 // end of animation, take last entry's end
333 fRetval
= maVector
[maVector
.size() - 1L].GetStop();
341 // Access to StepWidth in logical units
342 sal_uInt32
ActivityImpl::GetStepWidthLogic() const
344 // #i69847# Assuming higher DPI
345 sal_uInt32
const PIXEL_TO_LOGIC
= 30;
347 sal_uInt32
nRetval(0L);
351 // is in pixels, convert to logical units
352 nRetval
= (-mnStepWidth
* PIXEL_TO_LOGIC
);
354 else if(mnStepWidth
> 0L)
356 // is in logical units
357 nRetval
= mnStepWidth
;
362 // step 1 pixel, canned value
364 // #128389# with very high DPIs like in PDF export, this can
365 // still get zero. for that cases, set a default, too (taken
366 // from ainfoscrolltext.cxx)
373 void ActivityImpl::ImpForceScrollTextAnimNodes()
378 sal_uInt32 nLoopTime
;
379 double fZeroLogic
, fOneLogic
, fInitLogic
, fDistanceLogic
;
380 double fZeroLogicAlternate
= 0.0, fOneLogicAlternate
= 0.0;
381 double fZeroRelative
, fOneRelative
, fInitRelative
,fDistanceRelative
;
383 if(ScrollHorizontal())
387 if(maPaintRectangleLogic
.GetWidth() >
388 maScrollRectangleLogic
.GetWidth())
390 fZeroLogicAlternate
= maScrollRectangleLogic
.Right() - maPaintRectangleLogic
.GetWidth();
391 fOneLogicAlternate
= maScrollRectangleLogic
.Left();
395 fZeroLogicAlternate
= maScrollRectangleLogic
.Left();
396 fOneLogicAlternate
= maScrollRectangleLogic
.Right() - maPaintRectangleLogic
.GetWidth();
400 fZeroLogic
= maScrollRectangleLogic
.Left() - maPaintRectangleLogic
.GetWidth();
401 fOneLogic
= maScrollRectangleLogic
.Right();
402 fInitLogic
= maPaintRectangleLogic
.Left();
408 if(maPaintRectangleLogic
.GetHeight() > maScrollRectangleLogic
.GetHeight())
410 fZeroLogicAlternate
= maScrollRectangleLogic
.Bottom() - maPaintRectangleLogic
.GetHeight();
411 fOneLogicAlternate
= maScrollRectangleLogic
.Top();
415 fZeroLogicAlternate
= maScrollRectangleLogic
.Top();
416 fOneLogicAlternate
= maScrollRectangleLogic
.Bottom() - maPaintRectangleLogic
.GetHeight();
420 fZeroLogic
= maScrollRectangleLogic
.Top() - maPaintRectangleLogic
.GetHeight();
421 fOneLogic
= maScrollRectangleLogic
.Bottom();
422 fInitLogic
= maPaintRectangleLogic
.Top();
425 fDistanceLogic
= fOneLogic
- fZeroLogic
;
426 fInitRelative
= (fInitLogic
- fZeroLogic
) / fDistanceLogic
;
431 (fZeroLogicAlternate
- fZeroLogic
) / fDistanceLogic
;
433 (fOneLogicAlternate
- fZeroLogic
) / fDistanceLogic
;
434 fDistanceRelative
= fOneRelative
- fZeroRelative
;
440 fDistanceRelative
= 1.0;
446 ScrollTextAnimNode
aStartNode(
447 mnStartTime
, 1L, 0.0, 0.0, mnStartTime
, false);
448 maVector
.push_back(aStartNode
);
451 if(IsVisibleWhenStarted())
453 double fRelativeStartValue
, fRelativeEndValue
,fRelativeDistance
;
455 if(DoScrollForward())
457 fRelativeStartValue
= fInitRelative
;
458 fRelativeEndValue
= fOneRelative
;
459 fRelativeDistance
= fRelativeEndValue
- fRelativeStartValue
;
463 fRelativeStartValue
= fInitRelative
;
464 fRelativeEndValue
= fZeroRelative
;
465 fRelativeDistance
= fRelativeStartValue
- fRelativeEndValue
;
468 const double fNumberSteps
=
469 (fRelativeDistance
* fDistanceLogic
) / GetStepWidthLogic();
470 nLoopTime
= FRound(fNumberSteps
* mnFrequency
);
473 ScrollTextAnimNode
aInitNode(
475 fRelativeStartValue
, fRelativeEndValue
,
477 maVector
.push_back(aInitNode
);
480 // prepare main loop values
482 double fRelativeStartValue
, fRelativeEndValue
, fRelativeDistance
;
484 if(DoScrollForward())
486 fRelativeStartValue
= fZeroRelative
;
487 fRelativeEndValue
= fOneRelative
;
488 fRelativeDistance
= fRelativeEndValue
- fRelativeStartValue
;
492 fRelativeStartValue
= fOneRelative
;
493 fRelativeEndValue
= fZeroRelative
;
494 fRelativeDistance
= fRelativeStartValue
- fRelativeEndValue
;
497 const double fNumberSteps
=
498 (fRelativeDistance
* fDistanceLogic
) / GetStepWidthLogic();
499 nLoopTime
= FRound(fNumberSteps
* mnFrequency
);
506 ScrollTextAnimNode
aMainNode(
508 fRelativeStartValue
, fRelativeEndValue
,
509 mnFrequency
, DoAlternate());
510 maVector
.push_back(aMainNode
);
515 sal_uInt32
nNumRepeat(mnRepeat
);
517 if(DoAlternate() && (nNumRepeat
+ 1L) % 2L)
521 ScrollTextAnimNode
aMainNode(
522 nLoopTime
, nNumRepeat
,
523 fRelativeStartValue
, fRelativeEndValue
,
524 mnFrequency
, DoAlternate());
525 maVector
.push_back(aMainNode
);
529 if(IsVisibleWhenStopped())
531 double fRelativeStartValue
, fRelativeEndValue
, fRelativeDistance
;
533 if(DoScrollForward())
535 fRelativeStartValue
= fZeroRelative
;
536 fRelativeEndValue
= fInitRelative
;
537 fRelativeDistance
= fRelativeEndValue
- fRelativeStartValue
;
541 fRelativeStartValue
= fOneRelative
;
542 fRelativeEndValue
= fInitRelative
;
543 fRelativeDistance
= fRelativeStartValue
- fRelativeEndValue
;
546 const double fNumberSteps
=
547 (fRelativeDistance
* fDistanceLogic
) / GetStepWidthLogic();
548 nLoopTime
= FRound(fNumberSteps
* mnFrequency
);
551 ScrollTextAnimNode
aExitNode(
553 fRelativeStartValue
, fRelativeEndValue
, mnFrequency
, false);
554 maVector
.push_back(aExitNode
);
559 ScrollTextAnimNode
* ActivityImpl::ImpGetScrollTextAnimNode(
560 sal_uInt32 nTime
, sal_uInt32
& rRelativeTime
)
562 ScrollTextAnimNode
* pRetval
= 0L;
563 ImpForceScrollTextAnimNodes();
565 if(!maVector
.empty())
567 rRelativeTime
= nTime
;
569 for(sal_uInt32
a(0L); !pRetval
&& a
< maVector
.size(); a
++)
571 ScrollTextAnimNode
& rNode
= maVector
[a
];
572 if(!rNode
.GetRepeat())
574 // endless loop, use it
577 else if(rNode
.GetFullTime() > rRelativeTime
)
585 rRelativeTime
-= rNode
.GetFullTime();
593 sal_uInt32
ActivityImpl::ImpRegisterAgainScrollTextMixerState(sal_uInt32 nTime
)
595 sal_uInt32
nRetval(0L);
596 ImpForceScrollTextAnimNodes();
600 sal_uInt32 nRelativeTime
;
601 ScrollTextAnimNode
* pNode
= ImpGetScrollTextAnimNode(nTime
, nRelativeTime
);
605 // take register time
606 nRetval
= pNode
->GetFrequency();
611 // #i38135# not initialized, return default
612 nRetval
= mnFrequency
;
618 void ActivityImpl::updateShapeAttributes(
619 double fTime
, basegfx::B2DRectangle
const& parentBounds
)
621 OSL_ASSERT( meAnimKind
!= drawing::TextAnimationKind_NONE
);
622 if( meAnimKind
== drawing::TextAnimationKind_NONE
)
625 double const fMixerState
= GetMixerState(
626 static_cast<sal_uInt32
>(fTime
* 1000.0) );
628 if( meAnimKind
== drawing::TextAnimationKind_BLINK
)
631 maShapeAttrLayer
.get()->setVisibility( fMixerState
< 0.5 );
633 else if(mpMetaFile
) // scroll mode:
636 // keep care: the below code is highly sensible to changes...
639 // rectangle of the pure text:
640 double const fPaintWidth
= maPaintRectangleLogic
.GetWidth();
641 double const fPaintHeight
= maPaintRectangleLogic
.GetHeight();
642 // rectangle where the scrolling takes place (-> clipping):
643 double const fScrollWidth
= maScrollRectangleLogic
.GetWidth();
644 double const fScrollHeight
= maScrollRectangleLogic
.GetHeight();
646 basegfx::B2DPoint pos
, clipPos
;
648 if(ScrollHorizontal())
650 double const fOneEquiv( fScrollWidth
);
651 double const fZeroEquiv( -fPaintWidth
);
653 pos
.setX( fZeroEquiv
+ (fMixerState
* (fOneEquiv
- fZeroEquiv
)) );
655 clipPos
.setX( -pos
.getX() );
656 clipPos
.setY( -pos
.getY() );
658 // #i69844# Compensation for text-wider-than-shape case
659 if( fPaintWidth
> fScrollWidth
)
660 pos
.setX( pos
.getX() + (fPaintWidth
-fScrollWidth
) / 2.0 );
665 double const fOneEquiv( fScrollHeight
);
666 double const fZeroEquiv( -fPaintHeight
);
668 pos
.setY( fZeroEquiv
+ (fMixerState
* (fOneEquiv
- fZeroEquiv
)) );
670 clipPos
.setX( -pos
.getX() );
671 clipPos
.setY( -pos
.getY() );
673 // #i69844# Compensation for text-higher-than-shape case
674 if( fPaintHeight
> fScrollHeight
)
675 pos
.setY( pos
.getY() + (fPaintHeight
-fScrollHeight
) / 2.0 );
678 basegfx::B2DPolygon
clipPoly(
679 basegfx::tools::createPolygonFromRect(
680 basegfx::B2DRectangle( clipPos
.getX(),
682 clipPos
.getX() + fScrollWidth
,
683 clipPos
.getY() + fScrollHeight
) ) );
685 if( !::basegfx::fTools::equalZero( mfRotationAngle
))
687 maShapeAttrLayer
.get()->setRotationAngle( mfRotationAngle
);
688 double const fRotate
= (mfRotationAngle
* M_PI
/ 180.0);
689 basegfx::B2DHomMatrix aTransform
;
691 aTransform
.rotate( fRotate
);
695 pos
+= parentBounds
.getCenter();
696 maShapeAttrLayer
.get()->setPosition( pos
);
697 maShapeAttrLayer
.get()->setClip( basegfx::B2DPolyPolygon(clipPoly
) );
701 bool ActivityImpl::perform()
708 "ActivityImpl::perform(): still active, but NULL draw shape" );
710 DrawShapeSharedPtr
const pParentDrawShape( mpParentDrawShape
);
711 if( !pParentDrawShape
)
712 return false; // parent has vanished
714 if( pParentDrawShape
->isVisible() )
716 if( !mbIsShapeAnimated
)
718 mpDrawShape
->setVisibility(true); // shape may be initially hidden
719 maContext
.mpSubsettableShapeManager
->enterAnimationMode( mpDrawShape
);
721 mbIsShapeAnimated
= true;
723 // update attributes related to current time:
724 basegfx::B2DRectangle
const parentBounds(
725 pParentDrawShape
->getBounds() );
727 const double nCurrTime( maTimer
.getElapsedTime() );
728 updateShapeAttributes( nCurrTime
, parentBounds
);
730 const sal_uInt32
nFrequency(
731 ImpRegisterAgainScrollTextMixerState(
732 static_cast<sal_uInt32
>(nCurrTime
* 1000.0)) );
736 mpWakeupEvent
->start();
737 mpWakeupEvent
->setNextTimeout(
738 std::max(0.1,nFrequency
/1000.0) );
739 maContext
.mrEventQueue
.addEvent( mpWakeupEvent
);
741 if( mpDrawShape
->isContentChanged() )
742 maContext
.mpSubsettableShapeManager
->notifyShapeUpdate( mpDrawShape
);
744 // else: finished, not need to wake up again.
748 // busy-wait, until parent shape gets visible
749 mpWakeupEvent
->start();
750 mpWakeupEvent
->setNextTimeout( 2.0 );
753 // don't reinsert, WakeupEvent will perform that after the given timeout:
757 ActivityImpl::ActivityImpl(
758 SlideShowContext
const& rContext
,
759 boost::shared_ptr
<WakeupEvent
> const& pWakeupEvent
,
760 boost::shared_ptr
<DrawShape
> const& pParentDrawShape
)
761 : maContext(rContext
),
762 mpWakeupEvent(pWakeupEvent
),
763 mpParentDrawShape(pParentDrawShape
),
764 mpListener( new IntrinsicAnimationListener(*this) ),
765 maTimer(rContext
.mrEventQueue
.getTimer()),
766 mbIsShapeAnimated(false),
769 meAnimKind(drawing::TextAnimationKind_NONE
),
773 sal_Int32
const nNodes
= pParentDrawShape
->getNumberOfTreeNodes(
774 DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH
);
776 DocTreeNode
scrollTextNode(
777 pParentDrawShape
->getTreeNode(
778 0, DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH
));
779 // xxx todo: remove this hack
781 scrollTextNode
.setEndIndex(
782 pParentDrawShape
->getTreeNode(
784 DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH
).getEndIndex());
786 // TODO(Q3): Doing this manually, instead of using
787 // ShapeSubset. This is because of lifetime issues (ShapeSubset
788 // generates circular references to parent shape)
789 mpDrawShape
= boost::dynamic_pointer_cast
<DrawShape
>(
790 maContext
.mpSubsettableShapeManager
->getSubsetShape(
794 mpMetaFile
= mpDrawShape
->forceScrollTextMetaFile();
796 // make scroll text invisible for slide transition bitmaps
797 mpDrawShape
->setVisibility(false);
799 basegfx::B2DRectangle aScrollRect
, aPaintRect
;
800 ENSURE_OR_THROW( getRectanglesFromScrollMtf( aScrollRect
,
803 "ActivityImpl::ActivityImpl(): Could not extract "
804 "scroll anim rectangles from mtf" );
806 maScrollRectangleLogic
= vcl::unotools::rectangleFromB2DRectangle(
808 maPaintRectangleLogic
= vcl::unotools::rectangleFromB2DRectangle(
811 maShapeAttrLayer
.createAttributeLayer(mpDrawShape
);
813 uno::Reference
<drawing::XShape
> const xShape( mpDrawShape
->getXShape() );
814 uno::Reference
<beans::XPropertySet
> const xProps( xShape
, uno::UNO_QUERY_THROW
);
816 getPropertyValue( meAnimKind
, xProps
, OUSTR("TextAnimationKind") );
817 OSL_ASSERT( meAnimKind
!= drawing::TextAnimationKind_NONE
);
818 mbAlternate
= (meAnimKind
== drawing::TextAnimationKind_ALTERNATE
);
819 mbScrollIn
= (meAnimKind
== drawing::TextAnimationKind_SLIDE
);
821 // adopted from in AInfoBlinkText::ImplInit():
822 sal_Int16
nRepeat(0);
823 getPropertyValue( nRepeat
, xProps
, OUSTR("TextAnimationCount") );
828 // force visible when started for scroll-forth-and-back, because
829 // slide has been coming in with visible text in the middle:
830 mbVisibleWhenStarted
= true;
834 getPropertyValue( mbVisibleWhenStarted
, xProps
,
835 OUSTR("TextAnimationStartInside") );
838 // set visible when stopped
839 getPropertyValue( mbVisibleWhenStopped
, xProps
,
840 OUSTR("TextAnimatiogonStopInside") );
842 getPropertyValue( mfRotationAngle
, xProps
,
843 OUSTR("RotateAngle") );
844 mfRotationAngle
/= -100.0; // (switching direction)
848 getPropertyValue( nDelay
, xProps
, OUSTR("TextAnimationDelay") );
849 // set delay if not automatic
850 mnFrequency
= (nDelay
? nDelay
:
852 meAnimKind
== drawing::TextAnimationKind_BLINK
855 // adopted from in AInfoScrollText::ImplInit():
857 // If it is a simple m_bScrollIn, reset some parameters
860 // most parameters are set correctly from the dialog logic, but
861 // eg VisisbleWhenStopped is grayed out and needs to be corrected here.
862 mbVisibleWhenStopped
= true;
863 mbVisibleWhenStarted
= false;
867 // Get animation direction
868 getPropertyValue( meDirection
, xProps
, OUSTR("TextAnimationDirection") );
870 // Get step width. Negative means pixel, positive logical units
871 getPropertyValue( mnStepWidth
, xProps
, OUSTR("TextAnimationAmount") );
873 maContext
.mpSubsettableShapeManager
->addIntrinsicAnimationHandler(
877 bool ActivityImpl::enableAnimations()
880 return maContext
.mrActivitiesQueue
.addActivity(
881 shared_from_this() );
884 ActivityImpl::~ActivityImpl()
888 void ActivityImpl::dispose()
894 // only remove subset here, since end() is called on slide end
895 // (and we must not spoil the slide preview bitmap with scroll
897 maShapeAttrLayer
.reset();
900 // TODO(Q3): Doing this manually, instead of using
901 // ShapeSubset. This is because of lifetime issues
902 // (ShapeSubset generates circular references to parent
904 DrawShapeSharedPtr
pParent( mpParentDrawShape
.lock() );
906 maContext
.mpSubsettableShapeManager
->revokeSubset(
913 mpParentDrawShape
.reset();
914 mpWakeupEvent
.reset();
918 maContext
.mpSubsettableShapeManager
->removeIntrinsicAnimationHandler(
923 double ActivityImpl::calcTimeLag() const
928 bool ActivityImpl::isActive() const
933 void ActivityImpl::dequeued()
938 void ActivityImpl::end()
943 if( mbIsShapeAnimated
)
945 maContext
.mpSubsettableShapeManager
->leaveAnimationMode( mpDrawShape
);
946 mbIsShapeAnimated
= false;
952 namespace slideshow
{
955 boost::shared_ptr
<Activity
> createDrawingLayerAnimActivity(
956 SlideShowContext
const& rContext
,
957 boost::shared_ptr
<DrawShape
> const& pDrawShape
)
959 boost::shared_ptr
<Activity
> pActivity
;
963 boost::shared_ptr
<WakeupEvent
> const pWakeupEvent(
964 new WakeupEvent( rContext
.mrEventQueue
.getTimer(),
965 rContext
.mrActivitiesQueue
) );
966 pActivity
.reset( new ActivityImpl( rContext
, pWakeupEvent
, pDrawShape
) );
967 pWakeupEvent
->setActivity( pActivity
);
969 catch( uno::RuntimeException
& )
973 catch( uno::Exception
& )
975 // translate any error into empty factory product.
977 rtl::OUStringToOString(
978 comphelper::anyToString( cppu::getCaughtException() ),
979 RTL_TEXTENCODING_UTF8
).getStr() );
985 } // namespace internal
986 } // namespace presentation