Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include <canvas/debug.hxx>
22 : #include <tools/diagnose_ex.h>
23 :
24 : #include <comphelper/anytostring.hxx>
25 : #include <cppuhelper/exc_hlp.hxx>
26 : #include <basegfx/numeric/ftools.hxx>
27 : #include <basegfx/matrix/b2dhommatrix.hxx>
28 : #include <basegfx/polygon/b2dpolypolygontools.hxx>
29 :
30 : #include <com/sun/star/animations/TransitionType.hpp>
31 : #include <com/sun/star/animations/TransitionSubType.hpp>
32 :
33 : #include "transitionfactory.hxx"
34 : #include "transitionfactorytab.hxx"
35 : #include "transitiontools.hxx"
36 : #include "parametricpolypolygonfactory.hxx"
37 : #include "animationfactory.hxx"
38 : #include "clippingfunctor.hxx"
39 :
40 : using namespace ::com::sun::star;
41 :
42 : namespace slideshow {
43 : namespace internal {
44 :
45 : /***************************************************
46 : *** ***
47 : *** Shape Transition Effects ***
48 : *** ***
49 : ***************************************************/
50 :
51 : namespace {
52 :
53 : class ClippingAnimation : public NumberAnimation
54 : {
55 : public:
56 : ClippingAnimation(
57 : const ParametricPolyPolygonSharedPtr& rPolygon,
58 : const ShapeManagerSharedPtr& rShapeManager,
59 : const TransitionInfo& rTransitionInfo,
60 : bool bDirectionForward,
61 : bool bModeIn );
62 :
63 : virtual ~ClippingAnimation();
64 :
65 : // Animation interface
66 :
67 : virtual void prefetch( const AnimatableShapeSharedPtr& rShape,
68 : const ShapeAttributeLayerSharedPtr& rAttrLayer ) SAL_OVERRIDE;
69 : virtual void start( const AnimatableShapeSharedPtr& rShape,
70 : const ShapeAttributeLayerSharedPtr& rAttrLayer ) SAL_OVERRIDE;
71 : virtual void end() SAL_OVERRIDE;
72 :
73 : // NumberAnimation interface
74 :
75 : virtual bool operator()( double nValue ) SAL_OVERRIDE;
76 : virtual double getUnderlyingValue() const SAL_OVERRIDE;
77 :
78 : private:
79 : void end_();
80 :
81 : AnimatableShapeSharedPtr mpShape;
82 : ShapeAttributeLayerSharedPtr mpAttrLayer;
83 : ShapeManagerSharedPtr mpShapeManager;
84 : ClippingFunctor maClippingFunctor;
85 : bool mbSpriteActive;
86 : };
87 :
88 0 : ClippingAnimation::ClippingAnimation(
89 : const ParametricPolyPolygonSharedPtr& rPolygon,
90 : const ShapeManagerSharedPtr& rShapeManager,
91 : const TransitionInfo& rTransitionInfo,
92 : bool bDirectionForward,
93 : bool bModeIn ) :
94 : mpShape(),
95 : mpAttrLayer(),
96 : mpShapeManager( rShapeManager ),
97 : maClippingFunctor( rPolygon,
98 : rTransitionInfo,
99 : bDirectionForward,
100 : bModeIn ),
101 0 : mbSpriteActive(false)
102 : {
103 0 : ENSURE_OR_THROW(
104 : rShapeManager,
105 : "ClippingAnimation::ClippingAnimation(): Invalid ShapeManager" );
106 0 : }
107 :
108 0 : ClippingAnimation::~ClippingAnimation()
109 : {
110 : try
111 : {
112 0 : end_();
113 : }
114 0 : catch (uno::Exception &)
115 : {
116 : OSL_FAIL( OUStringToOString(
117 : comphelper::anyToString(
118 : cppu::getCaughtException() ),
119 : RTL_TEXTENCODING_UTF8 ).getStr() );
120 : }
121 0 : }
122 :
123 0 : void ClippingAnimation::prefetch( const AnimatableShapeSharedPtr&,
124 : const ShapeAttributeLayerSharedPtr& )
125 : {
126 0 : }
127 :
128 0 : void ClippingAnimation::start( const AnimatableShapeSharedPtr& rShape,
129 : const ShapeAttributeLayerSharedPtr& rAttrLayer )
130 : {
131 : OSL_ENSURE( !mpShape,
132 : "ClippingAnimation::start(): Shape already set" );
133 : OSL_ENSURE( !mpAttrLayer,
134 : "ClippingAnimation::start(): Attribute layer already set" );
135 0 : ENSURE_OR_THROW( rShape,
136 : "ClippingAnimation::start(): Invalid shape" );
137 0 : ENSURE_OR_THROW( rAttrLayer,
138 : "ClippingAnimation::start(): Invalid attribute layer" );
139 :
140 0 : mpShape = rShape;
141 0 : mpAttrLayer = rAttrLayer;
142 :
143 0 : if( !mbSpriteActive )
144 : {
145 0 : mpShapeManager->enterAnimationMode( mpShape );
146 0 : mbSpriteActive = true;
147 : }
148 0 : }
149 :
150 0 : void ClippingAnimation::end()
151 : {
152 0 : end_();
153 0 : }
154 :
155 0 : void ClippingAnimation::end_()
156 : {
157 0 : if( mbSpriteActive )
158 : {
159 0 : mbSpriteActive = false;
160 0 : mpShapeManager->leaveAnimationMode( mpShape );
161 :
162 0 : if( mpShape->isContentChanged() )
163 0 : mpShapeManager->notifyShapeUpdate( mpShape );
164 : }
165 0 : }
166 :
167 0 : bool ClippingAnimation::operator()( double nValue )
168 : {
169 0 : ENSURE_OR_RETURN_FALSE(
170 : mpAttrLayer && mpShape,
171 : "ClippingAnimation::operator(): Invalid ShapeAttributeLayer" );
172 :
173 : // set new clip
174 : mpAttrLayer->setClip( maClippingFunctor( nValue,
175 0 : mpShape->getDomBounds().getRange() ) );
176 :
177 0 : if( mpShape->isContentChanged() )
178 0 : mpShapeManager->notifyShapeUpdate( mpShape );
179 :
180 0 : return true;
181 : }
182 :
183 0 : double ClippingAnimation::getUnderlyingValue() const
184 : {
185 0 : ENSURE_OR_THROW(
186 : mpAttrLayer,
187 : "ClippingAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
188 :
189 0 : return 0.0; // though this should be used in concert with
190 : // ActivitiesFactory::createSimpleActivity, better
191 : // explicitly name our start value.
192 : // Permissible range for operator() above is [0,1]
193 : }
194 :
195 0 : AnimationActivitySharedPtr createShapeTransitionByType(
196 : const ActivitiesFactory::CommonParameters& rParms,
197 : const AnimatableShapeSharedPtr& rShape,
198 : const ShapeManagerSharedPtr& rShapeManager,
199 : const ::basegfx::B2DVector& rSlideSize,
200 : ::com::sun::star::uno::Reference<
201 : ::com::sun::star::animations::XTransitionFilter > const& xTransition,
202 : sal_Int16 nType,
203 : sal_Int16 nSubType )
204 : {
205 0 : ENSURE_OR_THROW(
206 : xTransition.is(),
207 : "createShapeTransitionByType(): Invalid XTransition" );
208 :
209 : const TransitionInfo* pTransitionInfo(
210 0 : getTransitionInfo( nType, nSubType ) );
211 :
212 0 : AnimationActivitySharedPtr pGeneratedActivity;
213 0 : if( pTransitionInfo != NULL )
214 : {
215 0 : switch( pTransitionInfo->meTransitionClass )
216 : {
217 : default:
218 : case TransitionInfo::TRANSITION_INVALID:
219 : OSL_FAIL( "createShapeTransitionByType(): Invalid transition type. "
220 : "Don't ask me for a 0 TransitionType, have no XTransitionFilter node instead!" );
221 0 : return AnimationActivitySharedPtr();
222 :
223 :
224 : case TransitionInfo::TRANSITION_CLIP_POLYPOLYGON:
225 : {
226 : // generate parametric poly-polygon
227 : ParametricPolyPolygonSharedPtr pPoly(
228 : ParametricPolyPolygonFactory::createClipPolyPolygon(
229 0 : nType, nSubType ) );
230 :
231 : // create a clip activity from that
232 0 : pGeneratedActivity = ActivitiesFactory::createSimpleActivity(
233 : rParms,
234 : NumberAnimationSharedPtr(
235 : new ClippingAnimation(
236 : pPoly,
237 : rShapeManager,
238 : *pTransitionInfo,
239 0 : xTransition->getDirection(),
240 0 : xTransition->getMode() ) ),
241 0 : true );
242 : }
243 0 : break;
244 :
245 : case TransitionInfo::TRANSITION_SPECIAL:
246 : {
247 0 : switch( nType )
248 : {
249 : case animations::TransitionType::RANDOM:
250 : {
251 : // select randomly one of the effects from the
252 : // TransitionFactoryTable
253 :
254 0 : const TransitionInfo* pRandomTransitionInfo( getRandomTransitionInfo() );
255 :
256 0 : ENSURE_OR_THROW( pRandomTransitionInfo != NULL,
257 : "createShapeTransitionByType(): Got invalid random transition info" );
258 :
259 0 : ENSURE_OR_THROW( pRandomTransitionInfo->mnTransitionType != animations::TransitionType::RANDOM,
260 : "createShapeTransitionByType(): Got random again for random input!" );
261 :
262 : // and recurse
263 0 : pGeneratedActivity = createShapeTransitionByType( rParms,
264 : rShape,
265 : rShapeManager,
266 : rSlideSize,
267 : xTransition,
268 : pRandomTransitionInfo->mnTransitionType,
269 0 : pRandomTransitionInfo->mnTransitionSubType );
270 : }
271 0 : break;
272 :
273 : // TODO(F3): Implement slidewipe for shape
274 : case animations::TransitionType::SLIDEWIPE:
275 : {
276 0 : sal_Int16 nBarWipeSubType(0);
277 0 : bool bDirectionForward(true);
278 :
279 : // map slidewipe to BARWIPE, for now
280 0 : switch( nSubType )
281 : {
282 : case animations::TransitionSubType::FROMLEFT:
283 0 : nBarWipeSubType = animations::TransitionSubType::LEFTTORIGHT;
284 0 : bDirectionForward = true;
285 0 : break;
286 :
287 : case animations::TransitionSubType::FROMRIGHT:
288 0 : nBarWipeSubType = animations::TransitionSubType::LEFTTORIGHT;
289 0 : bDirectionForward = false;
290 0 : break;
291 :
292 : case animations::TransitionSubType::FROMTOP:
293 0 : nBarWipeSubType = animations::TransitionSubType::TOPTOBOTTOM;
294 0 : bDirectionForward = true;
295 0 : break;
296 :
297 : case animations::TransitionSubType::FROMBOTTOM:
298 0 : nBarWipeSubType = animations::TransitionSubType::TOPTOBOTTOM;
299 0 : bDirectionForward = false;
300 0 : break;
301 :
302 : default:
303 0 : ENSURE_OR_THROW( false,
304 : "createShapeTransitionByType(): Unexpected subtype for SLIDEWIPE" );
305 : break;
306 : }
307 :
308 : // generate parametric poly-polygon
309 : ParametricPolyPolygonSharedPtr pPoly(
310 : ParametricPolyPolygonFactory::createClipPolyPolygon(
311 : animations::TransitionType::BARWIPE,
312 0 : nBarWipeSubType ) );
313 :
314 : // create a clip activity from that
315 0 : pGeneratedActivity = ActivitiesFactory::createSimpleActivity(
316 : rParms,
317 : NumberAnimationSharedPtr(
318 : new ClippingAnimation(
319 : pPoly,
320 : rShapeManager,
321 : *getTransitionInfo( animations::TransitionType::BARWIPE,
322 0 : nBarWipeSubType ),
323 : bDirectionForward,
324 0 : xTransition->getMode() ) ),
325 0 : true );
326 : }
327 0 : break;
328 :
329 : default:
330 : {
331 : // TODO(F1): Check whether there's anything left, anyway,
332 : // for _shape_ transitions. AFAIK, there are no special
333 : // effects for shapes...
334 :
335 : // for now, map all to fade effect
336 0 : pGeneratedActivity = ActivitiesFactory::createSimpleActivity(
337 : rParms,
338 : AnimationFactory::createNumberPropertyAnimation(
339 : OUString("Opacity"),
340 : rShape,
341 : rShapeManager,
342 : rSlideSize ),
343 0 : xTransition->getMode() );
344 : }
345 0 : break;
346 : }
347 : }
348 0 : break;
349 : }
350 : }
351 :
352 0 : if( !pGeneratedActivity )
353 : {
354 : // No animation generated, maybe no table entry for given
355 : // transition?
356 : OSL_TRACE(
357 : "createShapeTransitionByType(): Unknown type/subtype (%d/%d) "
358 : "combination encountered",
359 : xTransition->getTransition(),
360 : xTransition->getSubtype() );
361 : OSL_FAIL(
362 : "createShapeTransitionByType(): Unknown type/subtype "
363 : "combination encountered" );
364 : }
365 :
366 0 : return pGeneratedActivity;
367 : }
368 :
369 : } // anon namespace
370 :
371 0 : AnimationActivitySharedPtr TransitionFactory::createShapeTransition(
372 : const ActivitiesFactory::CommonParameters& rParms,
373 : const AnimatableShapeSharedPtr& rShape,
374 : const ShapeManagerSharedPtr& rShapeManager,
375 : const ::basegfx::B2DVector& rSlideSize,
376 : uno::Reference< animations::XTransitionFilter > const& xTransition )
377 : {
378 : return createShapeTransitionByType( rParms,
379 : rShape,
380 : rShapeManager,
381 : rSlideSize,
382 : xTransition,
383 0 : xTransition->getTransition(),
384 0 : xTransition->getSubtype() );
385 : }
386 :
387 : }
388 : }
389 :
390 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|