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