Branch data 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 : : // must be first
22 : : #include <canvas/debug.hxx>
23 : : #include <tools/diagnose_ex.h>
24 : : #include <canvas/verbosetrace.hxx>
25 : :
26 : : #include <animationfactory.hxx>
27 : : #include <attributemap.hxx>
28 : :
29 : : #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
30 : : #include <com/sun/star/animations/AnimationTransformType.hpp>
31 : : #include <com/sun/star/beans/XPropertySet.hpp>
32 : : #include <com/sun/star/drawing/FillStyle.hpp>
33 : : #include <com/sun/star/drawing/LineStyle.hpp>
34 : : #include <com/sun/star/awt/FontSlant.hpp>
35 : : #include <com/sun/star/awt/FontUnderline.hpp>
36 : : #include <com/sun/star/awt/FontWeight.hpp>
37 : :
38 : : #include <basegfx/polygon/b2dpolygon.hxx>
39 : : #include <basegfx/polygon/b2dpolygontools.hxx>
40 : : #include <basegfx/polygon/b2dpolypolygontools.hxx>
41 : :
42 : : #include <functional>
43 : :
44 : :
45 : : using namespace ::com::sun::star;
46 : :
47 : :
48 : : namespace slideshow
49 : : {
50 : : namespace internal
51 : : {
52 : : namespace
53 : : {
54 : : // attention, there is a similar implementation of Animation in
55 : : // transitions/transitionfactory.cxx
56 : :
57 : : template< typename ValueT > class TupleAnimation : public PairAnimation
58 : : {
59 : : public:
60 : 0 : TupleAnimation( const ShapeManagerSharedPtr& rShapeManager,
61 : : int nFlags,
62 : : bool (ShapeAttributeLayer::*pIs1stValid)() const,
63 : : bool (ShapeAttributeLayer::*pIs2ndValid)() const,
64 : : const ValueT& rDefaultValue,
65 : : const ::basegfx::B2DSize& rReferenceSize,
66 : : double (ShapeAttributeLayer::*pGet1stValue)() const,
67 : : double (ShapeAttributeLayer::*pGet2ndValue)() const,
68 : : void (ShapeAttributeLayer::*pSetValue)( const ValueT& ) ) :
69 : : mpShape(),
70 : : mpAttrLayer(),
71 : : mpShapeManager( rShapeManager ),
72 : : mpIs1stValidFunc(pIs1stValid),
73 : : mpIs2ndValidFunc(pIs2ndValid),
74 : : mpGet1stValueFunc(pGet1stValue),
75 : : mpGet2ndValueFunc(pGet2ndValue),
76 : : mpSetValueFunc(pSetValue),
77 : : mnFlags( nFlags ),
78 : : maReferenceSize( rReferenceSize ),
79 : : maDefaultValue( rDefaultValue ),
80 : 0 : mbAnimationStarted( false )
81 : : {
82 : 0 : ENSURE_OR_THROW( rShapeManager,
83 : : "TupleAnimation::TupleAnimation(): Invalid ShapeManager" );
84 : 0 : ENSURE_OR_THROW( pIs1stValid && pIs2ndValid && pGet1stValue && pGet2ndValue && pSetValue,
85 : : "TupleAnimation::TupleAnimation(): One of the method pointers is NULL" );
86 : 0 : }
87 : :
88 : 0 : ~TupleAnimation()
89 : : {
90 : 0 : end_();
91 : 0 : }
92 : :
93 : : // Animation interface
94 : : // -------------------
95 : 0 : virtual void prefetch( const AnimatableShapeSharedPtr&,
96 : : const ShapeAttributeLayerSharedPtr& )
97 : 0 : {}
98 : :
99 : 0 : virtual void start( const AnimatableShapeSharedPtr& rShape,
100 : : const ShapeAttributeLayerSharedPtr& rAttrLayer )
101 : : {
102 : : OSL_ENSURE( !mpShape,
103 : : "TupleAnimation::start(): Shape already set" );
104 : : OSL_ENSURE( !mpAttrLayer,
105 : : "TupleAnimation::start(): Attribute layer already set" );
106 : :
107 : 0 : mpShape = rShape;
108 : 0 : mpAttrLayer = rAttrLayer;
109 : :
110 : 0 : ENSURE_OR_THROW( rShape,
111 : : "TupleAnimation::start(): Invalid shape" );
112 : 0 : ENSURE_OR_THROW( rAttrLayer,
113 : : "TupleAnimation::start(): Invalid attribute layer" );
114 : :
115 : 0 : if( !mbAnimationStarted )
116 : : {
117 : 0 : mbAnimationStarted = true;
118 : :
119 : 0 : if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
120 : 0 : mpShapeManager->enterAnimationMode( mpShape );
121 : : }
122 : 0 : }
123 : :
124 : 0 : virtual void end() { end_(); }
125 : 0 : void end_()
126 : : {
127 : 0 : if( mbAnimationStarted )
128 : : {
129 : 0 : mbAnimationStarted = false;
130 : :
131 : 0 : if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
132 : 0 : mpShapeManager->leaveAnimationMode( mpShape );
133 : :
134 : 0 : if( mpShape->isContentChanged() )
135 : 0 : mpShapeManager->notifyShapeUpdate( mpShape );
136 : : }
137 : 0 : }
138 : :
139 : : // PairAnimation interface
140 : : // -----------------------
141 : :
142 : 0 : virtual bool operator()( const ::basegfx::B2DTuple& rValue )
143 : : {
144 : 0 : ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
145 : : "TupleAnimation::operator(): Invalid ShapeAttributeLayer" );
146 : :
147 : : ValueT aValue( rValue.getX(),
148 : 0 : rValue.getY() );
149 : :
150 : : // Activitis get values from the expression parser,
151 : : // which returns _relative_ sizes/positions.
152 : : // Convert back relative to reference coordinate system
153 : 0 : aValue *= maReferenceSize;
154 : :
155 : 0 : ((*mpAttrLayer).*mpSetValueFunc)( aValue );
156 : :
157 : 0 : if( mpShape->isContentChanged() )
158 : 0 : mpShapeManager->notifyShapeUpdate( mpShape );
159 : :
160 : 0 : return true;
161 : : }
162 : :
163 : 0 : virtual ::basegfx::B2DTuple getUnderlyingValue() const
164 : : {
165 : 0 : ENSURE_OR_THROW( mpAttrLayer,
166 : : "TupleAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
167 : :
168 : 0 : ::basegfx::B2DTuple aRetVal;
169 : :
170 : : // deviated from the (*shared_ptr).*mpFuncPtr
171 : : // notation here, since gcc does not seem to parse
172 : : // that as a member function call anymore.
173 : 0 : aRetVal.setX( (mpAttrLayer.get()->*mpIs1stValidFunc)() ?
174 : : (mpAttrLayer.get()->*mpGet1stValueFunc)() :
175 : : maDefaultValue.getX() );
176 : 0 : aRetVal.setY( (mpAttrLayer.get()->*mpIs2ndValidFunc)() ?
177 : : (mpAttrLayer.get()->*mpGet2ndValueFunc)() :
178 : : maDefaultValue.getY() );
179 : :
180 : : // Activities get values from the expression
181 : : // parser, which returns _relative_
182 : : // sizes/positions. Convert start value to the
183 : : // same coordinate space (i.e. relative to given
184 : : // reference size).
185 : 0 : aRetVal /= maReferenceSize;
186 : :
187 : 0 : return aRetVal;
188 : : }
189 : :
190 : : private:
191 : : AnimatableShapeSharedPtr mpShape;
192 : : ShapeAttributeLayerSharedPtr mpAttrLayer;
193 : : ShapeManagerSharedPtr mpShapeManager;
194 : : bool (ShapeAttributeLayer::*mpIs1stValidFunc)() const;
195 : : bool (ShapeAttributeLayer::*mpIs2ndValidFunc)() const;
196 : : double (ShapeAttributeLayer::*mpGet1stValueFunc)() const;
197 : : double (ShapeAttributeLayer::*mpGet2ndValueFunc)() const;
198 : : void (ShapeAttributeLayer::*mpSetValueFunc)( const ValueT& );
199 : :
200 : : const int mnFlags;
201 : :
202 : : const ::basegfx::B2DSize maReferenceSize;
203 : : const ValueT maDefaultValue;
204 : : bool mbAnimationStarted;
205 : : };
206 : :
207 : :
208 : : class PathAnimation : public NumberAnimation
209 : : {
210 : : public:
211 : 0 : PathAnimation( const ::rtl::OUString& rSVGDPath,
212 : : sal_Int16 nAdditive,
213 : : const ShapeManagerSharedPtr& rShapeManager,
214 : : const ::basegfx::B2DVector& rSlideSize,
215 : : int nFlags ) :
216 : : maPathPoly(),
217 : : mpShape(),
218 : : mpAttrLayer(),
219 : : mpShapeManager( rShapeManager ),
220 : : maPageSize( rSlideSize ),
221 : : maShapeOrig(),
222 : : mnFlags( nFlags ),
223 : : mbAnimationStarted( false ),
224 : 0 : mnAdditive( nAdditive )
225 : : {
226 : 0 : ENSURE_OR_THROW( rShapeManager,
227 : : "PathAnimation::PathAnimation(): Invalid ShapeManager" );
228 : :
229 : 0 : ::basegfx::B2DPolyPolygon aPolyPoly;
230 : :
231 : 0 : ENSURE_OR_THROW( ::basegfx::tools::importFromSvgD( aPolyPoly, rSVGDPath ),
232 : : "PathAnimation::PathAnimation(): failed to parse SVG:d path" );
233 : 0 : ENSURE_OR_THROW( aPolyPoly.count() == 1,
234 : : "PathAnimation::PathAnimation(): motion path consists of multiple/zero polygon(s)" );
235 : :
236 : : // TODO(F2): Since getPositionRelative() currently
237 : : // cannot handle beziers, have to subdivide.
238 : : // AW: Should be no longer necessary; getPositionRelative is now bezier-safe
239 : 0 : maPathPoly = ::basegfx::tools::adaptiveSubdivideByAngle(aPolyPoly.getB2DPolygon(0) );
240 : 0 : }
241 : :
242 : 0 : ~PathAnimation()
243 : 0 : {
244 : 0 : end_();
245 : 0 : }
246 : :
247 : : // Animation interface
248 : : // -------------------
249 : 0 : virtual void prefetch( const AnimatableShapeSharedPtr&,
250 : : const ShapeAttributeLayerSharedPtr& )
251 : 0 : {}
252 : :
253 : 0 : virtual void start( const AnimatableShapeSharedPtr& rShape,
254 : : const ShapeAttributeLayerSharedPtr& rAttrLayer )
255 : : {
256 : : OSL_ENSURE( !mpShape,
257 : : "PathAnimation::start(): Shape already set" );
258 : : OSL_ENSURE( !mpAttrLayer,
259 : : "PathAnimation::start(): Attribute layer already set" );
260 : :
261 : 0 : mpShape = rShape;
262 : 0 : mpAttrLayer = rAttrLayer;
263 : :
264 : 0 : ENSURE_OR_THROW( rShape,
265 : : "PathAnimation::start(): Invalid shape" );
266 : 0 : ENSURE_OR_THROW( rAttrLayer,
267 : : "PathAnimation::start(): Invalid attribute layer" );
268 : :
269 : : // TODO(F1): Check whether _shape_ bounds are correct here.
270 : : // Theoretically, our AttrLayer is way down the stack, and
271 : : // we only have to consider _that_ value, not the one from
272 : : // the top of the stack as returned by Shape::getBounds()
273 : 0 : if( mnAdditive == animations::AnimationAdditiveMode::SUM )
274 : 0 : maShapeOrig = mpShape->getBounds().getCenter();
275 : : else
276 : 0 : maShapeOrig = mpShape->getDomBounds().getCenter();
277 : :
278 : 0 : if( !mbAnimationStarted )
279 : : {
280 : 0 : mbAnimationStarted = true;
281 : :
282 : 0 : if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
283 : 0 : mpShapeManager->enterAnimationMode( mpShape );
284 : : }
285 : 0 : }
286 : :
287 : 0 : virtual void end() { end_(); }
288 : 0 : void end_()
289 : : {
290 : 0 : if( mbAnimationStarted )
291 : : {
292 : 0 : mbAnimationStarted = false;
293 : :
294 : 0 : if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
295 : 0 : mpShapeManager->leaveAnimationMode( mpShape );
296 : :
297 : 0 : if( mpShape->isContentChanged() )
298 : 0 : mpShapeManager->notifyShapeUpdate( mpShape );
299 : : }
300 : 0 : }
301 : :
302 : : // NumberAnimation interface
303 : : // -----------------------
304 : :
305 : 0 : virtual bool operator()( double nValue )
306 : : {
307 : 0 : ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
308 : : "PathAnimation::operator(): Invalid ShapeAttributeLayer" );
309 : :
310 : : ::basegfx::B2DPoint rOutPos = ::basegfx::tools::getPositionRelative( maPathPoly,
311 : 0 : nValue );
312 : :
313 : : // TODO(F1): Determine whether the path is
314 : : // absolute, or shape-relative.
315 : :
316 : : // interpret path as page-relative. Scale up with page size
317 : 0 : rOutPos *= maPageSize;
318 : :
319 : : // TODO(F1): Determine whether the path origin is
320 : : // absolute, or shape-relative.
321 : :
322 : : // interpret path as shape-originated. Offset to shape position
323 : :
324 : 0 : rOutPos += maShapeOrig;
325 : :
326 : 0 : mpAttrLayer->setPosition( rOutPos );
327 : :
328 : 0 : if( mpShape->isContentChanged() )
329 : 0 : mpShapeManager->notifyShapeUpdate( mpShape );
330 : :
331 : 0 : return true;
332 : : }
333 : :
334 : 0 : virtual double getUnderlyingValue() const
335 : : {
336 : 0 : ENSURE_OR_THROW( mpAttrLayer,
337 : : "PathAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
338 : :
339 : 0 : return 0.0; // though this should be used in concert with
340 : : // ActivitiesFactory::createSimpleActivity, better
341 : : // explicitly name our start value.
342 : : // Permissible range for operator() above is [0,1]
343 : : }
344 : :
345 : : private:
346 : : ::basegfx::B2DPolygon maPathPoly;
347 : : AnimatableShapeSharedPtr mpShape;
348 : : ShapeAttributeLayerSharedPtr mpAttrLayer;
349 : : ShapeManagerSharedPtr mpShapeManager;
350 : : const ::basegfx::B2DSize maPageSize;
351 : : ::basegfx::B2DPoint maShapeOrig;
352 : : const int mnFlags;
353 : : bool mbAnimationStarted;
354 : : sal_Int16 mnAdditive;
355 : : };
356 : :
357 : :
358 : : /** GenericAnimation template
359 : :
360 : : This template makes heavy use of SFINAE, only one of
361 : : the operator()() methods will compile for each of the
362 : : base classes.
363 : :
364 : : Note that we omit the virtual keyword on the
365 : : operator()() overrides and getUnderlyingValue() methods on
366 : : purpose; those that actually do override baseclass
367 : : virtual methods inherit the property, and the others
368 : : won't increase our vtable. What's more, having all
369 : : those methods in the vtable actually creates POIs for
370 : : them, which breaks the whole SFINAE concept (IOW, this
371 : : template won't compile any longer).
372 : :
373 : : @tpl AnimationBase
374 : : Type of animation to generate (determines the
375 : : interface GenericAnimation will implement). Must be
376 : : one of NumberAnimation, ColorAnimation,
377 : : StringAnimation, PairAnimation or BoolAnimation.
378 : :
379 : : @tpl ModifierFunctor
380 : : Type of a functor object, which can optionally be used to
381 : : modify the getter/setter values.
382 : : */
383 : : template< typename AnimationBase, typename ModifierFunctor > class GenericAnimation : public AnimationBase
384 : : {
385 : : public:
386 : : typedef typename AnimationBase::ValueType ValueT;
387 : :
388 : : /** Create generic animation
389 : :
390 : : @param pIsValid
391 : : Function pointer to one of the is*Valid
392 : : methods. Used to either take the given getter
393 : : method, or the given default value for the start value.
394 : :
395 : : @param rDefaultValue
396 : : Default value, to take as the start value if
397 : : is*Valid returns false.
398 : :
399 : : @param pGetValue
400 : : Getter method, to fetch start value if valid.
401 : :
402 : : @param pSetValue
403 : : Setter method. This one puts the current animation
404 : : value to the ShapeAttributeLayer.
405 : :
406 : : @param rGetterModifier
407 : : Modifies up values retrieved from the pGetValue method.
408 : : Must provide operator()( const ValueT& ) method.
409 : :
410 : : @param rSetterModifier
411 : : Modifies up values before passing them to the pSetValue method.
412 : : Must provide operator()( const ValueT& ) method.
413 : : */
414 : 0 : GenericAnimation( const ShapeManagerSharedPtr& rShapeManager,
415 : : int nFlags,
416 : : bool (ShapeAttributeLayer::*pIsValid)() const,
417 : : const ValueT& rDefaultValue,
418 : : ValueT (ShapeAttributeLayer::*pGetValue)() const,
419 : : void (ShapeAttributeLayer::*pSetValue)( const ValueT& ),
420 : : const ModifierFunctor& rGetterModifier,
421 : : const ModifierFunctor& rSetterModifier ) :
422 : : mpShape(),
423 : : mpAttrLayer(),
424 : : mpShapeManager( rShapeManager ),
425 : : mpIsValidFunc(pIsValid),
426 : : mpGetValueFunc(pGetValue),
427 : : mpSetValueFunc(pSetValue),
428 : : maGetterModifier( rGetterModifier ),
429 : : maSetterModifier( rSetterModifier ),
430 : : mnFlags( nFlags ),
431 : : maDefaultValue(rDefaultValue),
432 : 0 : mbAnimationStarted( false )
433 : : {
434 : 0 : ENSURE_OR_THROW( rShapeManager,
435 : : "GenericAnimation::GenericAnimation(): Invalid ShapeManager" );
436 : 0 : ENSURE_OR_THROW( pIsValid && pGetValue && pSetValue,
437 : : "GenericAnimation::GenericAnimation(): One of the method pointers is NULL" );
438 : 0 : }
439 : :
440 : 0 : ~GenericAnimation()
441 : : {
442 : 0 : end_();
443 : 0 : }
444 : :
445 : : // Animation interface
446 : : // -------------------
447 : 0 : virtual void prefetch( const AnimatableShapeSharedPtr&,
448 : : const ShapeAttributeLayerSharedPtr& )
449 : 0 : {}
450 : :
451 : 0 : virtual void start( const AnimatableShapeSharedPtr& rShape,
452 : : const ShapeAttributeLayerSharedPtr& rAttrLayer )
453 : : {
454 : : OSL_ENSURE( !mpShape,
455 : : "GenericAnimation::start(): Shape already set" );
456 : : OSL_ENSURE( !mpAttrLayer,
457 : : "GenericAnimation::start(): Attribute layer already set" );
458 : :
459 : 0 : mpShape = rShape;
460 : 0 : mpAttrLayer = rAttrLayer;
461 : :
462 : 0 : ENSURE_OR_THROW( rShape,
463 : : "GenericAnimation::start(): Invalid shape" );
464 : 0 : ENSURE_OR_THROW( rAttrLayer,
465 : : "GenericAnimation::start(): Invalid attribute layer" );
466 : :
467 : : // only start animation once per repeated start() call,
468 : : // and only if sprites should be used for display
469 : 0 : if( !mbAnimationStarted )
470 : : {
471 : 0 : mbAnimationStarted = true;
472 : :
473 : 0 : if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
474 : 0 : mpShapeManager->enterAnimationMode( mpShape );
475 : : }
476 : 0 : }
477 : :
478 : 0 : virtual void end() { end_(); }
479 : 0 : void end_()
480 : : {
481 : : // TODO(Q2): Factor out common code (most
482 : : // prominently start() and end()) into base class
483 : :
484 : : // only stop animation once per repeated end() call,
485 : : // and only if sprites are used for display
486 : 0 : if( mbAnimationStarted )
487 : : {
488 : 0 : mbAnimationStarted = false;
489 : :
490 : 0 : if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
491 : 0 : mpShapeManager->leaveAnimationMode( mpShape );
492 : :
493 : : // Attention, this notifyShapeUpdate() is
494 : : // somewhat delicate here. Calling it
495 : : // unconditional (i.e. not guarded by
496 : : // mbAnimationStarted) will lead to shapes
497 : : // snapping back to their original state just
498 : : // before the slide ends. Not calling it at
499 : : // all might swallow final animation
500 : : // states. The current implementation relies
501 : : // on the fact that end() is either called by
502 : : // the Activity (then, the last animation
503 : : // state has been set, and corresponds to the
504 : : // shape's hold state), or by the animation
505 : : // node (then, it's a forced end, and we
506 : : // _have_ to snap back).
507 : : //
508 : : // To reiterate: normally, we're called from
509 : : // the Activity first, thus the
510 : : // notifyShapeUpdate() below will update to
511 : : // the last activity value.
512 : :
513 : : // force shape update, activity might have changed
514 : : // state in the last round.
515 : 0 : if( mpShape->isContentChanged() )
516 : 0 : mpShapeManager->notifyShapeUpdate( mpShape );
517 : : }
518 : 0 : }
519 : :
520 : : // Derived Animation interface
521 : : // ---------------------------
522 : :
523 : : /** For by-reference interfaces (B2DTuple, OUString)
524 : : */
525 : 0 : bool operator()( const ValueT& x )
526 : : {
527 : 0 : ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
528 : : "GenericAnimation::operator(): Invalid ShapeAttributeLayer" );
529 : :
530 : 0 : ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) );
531 : :
532 : 0 : if( mpShape->isContentChanged() )
533 : 0 : mpShapeManager->notifyShapeUpdate( mpShape );
534 : :
535 : 0 : return true;
536 : : }
537 : :
538 : : /** For by-value interfaces (bool, double)
539 : : */
540 : 0 : bool operator()( ValueT x )
541 : : {
542 : 0 : ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
543 : : "GenericAnimation::operator(): Invalid ShapeAttributeLayer" );
544 : :
545 : 0 : ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) );
546 : :
547 : 0 : if( mpShape->isContentChanged() )
548 : 0 : mpShapeManager->notifyShapeUpdate( mpShape );
549 : :
550 : 0 : return true;
551 : : }
552 : :
553 : 0 : ValueT getUnderlyingValue() const
554 : : {
555 : 0 : ENSURE_OR_THROW( mpAttrLayer,
556 : : "GenericAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
557 : :
558 : : // deviated from the (*shared_ptr).*mpFuncPtr
559 : : // notation here, since gcc does not seem to parse
560 : : // that as a member function call anymore.
561 : 0 : if( (mpAttrLayer.get()->*mpIsValidFunc)() )
562 : 0 : return maGetterModifier( ((*mpAttrLayer).*mpGetValueFunc)() );
563 : : else
564 : 0 : return maDefaultValue;
565 : : }
566 : :
567 : : private:
568 : : AnimatableShapeSharedPtr mpShape;
569 : : ShapeAttributeLayerSharedPtr mpAttrLayer;
570 : : ShapeManagerSharedPtr mpShapeManager;
571 : : bool (ShapeAttributeLayer::*mpIsValidFunc)() const;
572 : : ValueT (ShapeAttributeLayer::*mpGetValueFunc)() const;
573 : : void (ShapeAttributeLayer::*mpSetValueFunc)( const ValueT& );
574 : :
575 : : ModifierFunctor maGetterModifier;
576 : : ModifierFunctor maSetterModifier;
577 : :
578 : : const int mnFlags;
579 : :
580 : : const ValueT maDefaultValue;
581 : : bool mbAnimationStarted;
582 : : };
583 : :
584 : : //Current c++0x draft (apparently) has std::identity, but not operator()
585 : : template<typename T> struct SGI_identity : public std::unary_function<T,T>
586 : : {
587 : 0 : T& operator()(T& x) const { return x; }
588 : 0 : const T& operator()(const T& x) const { return x; }
589 : : };
590 : :
591 : : /** Function template wrapper around GenericAnimation template
592 : :
593 : : @tpl AnimationBase
594 : : Type of animation to generate (determines the
595 : : interface GenericAnimation will implement).
596 : : */
597 : : template< typename AnimationBase > ::boost::shared_ptr< AnimationBase >
598 : 0 : makeGenericAnimation( const ShapeManagerSharedPtr& rShapeManager,
599 : : int nFlags,
600 : : bool (ShapeAttributeLayer::*pIsValid)() const,
601 : : const typename AnimationBase::ValueType& rDefaultValue,
602 : : typename AnimationBase::ValueType (ShapeAttributeLayer::*pGetValue)() const,
603 : : void (ShapeAttributeLayer::*pSetValue)( const typename AnimationBase::ValueType& ) )
604 : : {
605 : : return ::boost::shared_ptr< AnimationBase >(
606 : : new GenericAnimation< AnimationBase,
607 : : SGI_identity< typename AnimationBase::ValueType > >(
608 : : rShapeManager,
609 : : nFlags,
610 : : pIsValid,
611 : : rDefaultValue,
612 : : pGetValue,
613 : : pSetValue,
614 : : // no modification necessary, use identity functor here
615 : : SGI_identity< typename AnimationBase::ValueType >(),
616 : 0 : SGI_identity< typename AnimationBase::ValueType >() ) );
617 : : }
618 : :
619 : : class Scaler
620 : : {
621 : : public:
622 : 0 : Scaler( double nScale ) :
623 : 0 : mnScale( nScale )
624 : : {
625 : 0 : }
626 : :
627 : 0 : double operator()( double nVal ) const
628 : : {
629 : 0 : return mnScale * nVal;
630 : : }
631 : :
632 : : private:
633 : : double mnScale;
634 : : };
635 : :
636 : : /** Overload for NumberAnimations which need scaling (width,height,x,y currently)
637 : : */
638 : 0 : NumberAnimationSharedPtr makeGenericAnimation( const ShapeManagerSharedPtr& rShapeManager,
639 : : int nFlags,
640 : : bool (ShapeAttributeLayer::*pIsValid)() const,
641 : : double nDefaultValue,
642 : : double (ShapeAttributeLayer::*pGetValue)() const,
643 : : void (ShapeAttributeLayer::*pSetValue)( const double& ),
644 : : double nScaleValue )
645 : : {
646 : : return NumberAnimationSharedPtr(
647 : : new GenericAnimation< NumberAnimation, Scaler >( rShapeManager,
648 : : nFlags,
649 : : pIsValid,
650 : : nDefaultValue / nScaleValue,
651 : : pGetValue,
652 : : pSetValue,
653 : : Scaler( 1.0/nScaleValue ),
654 : 0 : Scaler( nScaleValue ) ) );
655 : : }
656 : :
657 : :
658 : 0 : uno::Any getShapeDefault( const AnimatableShapeSharedPtr& rShape,
659 : : const ::rtl::OUString& rPropertyName )
660 : : {
661 : 0 : uno::Reference< drawing::XShape > xShape( rShape->getXShape() );
662 : :
663 : 0 : if( !xShape.is() )
664 : 0 : return uno::Any(); // no regular shape, no defaults available
665 : :
666 : :
667 : : // extract relevant value from XShape's PropertySet
668 : : uno::Reference< beans::XPropertySet > xPropSet( xShape,
669 : 0 : uno::UNO_QUERY );
670 : :
671 : 0 : ENSURE_OR_THROW( xPropSet.is(),
672 : : "getShapeDefault(): Cannot query property set from shape" );
673 : :
674 : 0 : return xPropSet->getPropertyValue( rPropertyName );
675 : : }
676 : :
677 : 0 : template< typename ValueType > ValueType getDefault( const AnimatableShapeSharedPtr& rShape,
678 : : const ::rtl::OUString& rPropertyName )
679 : : {
680 : : const uno::Any& rAny( getShapeDefault( rShape,
681 : 0 : rPropertyName ) );
682 : :
683 : 0 : if( !rAny.hasValue() )
684 : : {
685 : : OSL_FAIL( "getDefault(): cannot get requested shape property" );
686 : : OSL_TRACE( "getDefault(): cannot get '%s' shape property",
687 : : ::rtl::OUStringToOString( rPropertyName,
688 : : RTL_TEXTENCODING_ASCII_US ).getStr() );
689 : 0 : return ValueType();
690 : : }
691 : : else
692 : : {
693 : 0 : ValueType aValue = ValueType();
694 : :
695 : 0 : if( !(rAny >>= aValue) )
696 : : {
697 : : OSL_FAIL( "getDefault(): cannot extract requested shape property" );
698 : : OSL_TRACE( "getDefault(): cannot extract '%s' shape property",
699 : : ::rtl::OUStringToOString( rPropertyName,
700 : : RTL_TEXTENCODING_ASCII_US ).getStr() );
701 : 0 : return ValueType();
702 : : }
703 : :
704 : 0 : return aValue;
705 : : }
706 : : }
707 : :
708 : 0 : template<> RGBColor getDefault< RGBColor >( const AnimatableShapeSharedPtr& rShape,
709 : : const ::rtl::OUString& rPropertyName )
710 : : {
711 : : const uno::Any& rAny( getShapeDefault( rShape,
712 : 0 : rPropertyName ) );
713 : :
714 : 0 : if( !rAny.hasValue() )
715 : : {
716 : : OSL_FAIL( "getDefault(): cannot get requested shape color property" );
717 : : OSL_TRACE( "getDefault(): cannot get '%s' shape color property",
718 : : ::rtl::OUStringToOString( rPropertyName,
719 : : RTL_TEXTENCODING_ASCII_US ).getStr() );
720 : 0 : return RGBColor();
721 : : }
722 : : else
723 : : {
724 : 0 : sal_Int32 nValue = 0;
725 : :
726 : 0 : if( !(rAny >>= nValue) )
727 : : {
728 : : OSL_FAIL( "getDefault(): cannot extract requested shape color property" );
729 : : OSL_TRACE( "getDefault(): cannot extract '%s' shape color property",
730 : : ::rtl::OUStringToOString( rPropertyName,
731 : : RTL_TEXTENCODING_ASCII_US ).getStr() );
732 : 0 : return RGBColor();
733 : : }
734 : :
735 : : // convert from 0xAARRGGBB API color to 0xRRGGBB00
736 : : // canvas color
737 : 0 : return RGBColor( (nValue << 8U) & 0xFFFFFF00U );
738 : 0 : }
739 : : }
740 : : }
741 : :
742 : 0 : AnimationFactory::AttributeClass AnimationFactory::classifyAttributeName( const ::rtl::OUString& rAttrName )
743 : : {
744 : : // ATTENTION: When changing this map, also the create*PropertyAnimation() methods must
745 : : // be checked and possibly adapted in their switch statements
746 : :
747 : : // TODO(Q2): Since this map must be coherent with the various switch statements
748 : : // in the create*PropertyAnimation methods, try to unify into a single method or table
749 : 0 : switch( mapAttributeName( rAttrName ) )
750 : : {
751 : : default:
752 : : // FALLTHROUGH intended
753 : : case ATTRIBUTE_INVALID:
754 : 0 : return CLASS_UNKNOWN_PROPERTY;
755 : :
756 : : case ATTRIBUTE_CHAR_COLOR:
757 : : // FALLTHROUGH intended
758 : : case ATTRIBUTE_COLOR:
759 : : // FALLTHROUGH intended
760 : : case ATTRIBUTE_DIMCOLOR:
761 : : // FALLTHROUGH intended
762 : : case ATTRIBUTE_FILL_COLOR:
763 : : // FALLTHROUGH intended
764 : : case ATTRIBUTE_LINE_COLOR:
765 : 0 : return CLASS_COLOR_PROPERTY;
766 : :
767 : : case ATTRIBUTE_CHAR_FONT_NAME:
768 : 0 : return CLASS_STRING_PROPERTY;
769 : :
770 : : case ATTRIBUTE_VISIBILITY:
771 : 0 : return CLASS_BOOL_PROPERTY;
772 : :
773 : : case ATTRIBUTE_CHAR_HEIGHT:
774 : : // FALLTHROUGH intended
775 : : case ATTRIBUTE_CHAR_WEIGHT:
776 : : // FALLTHROUGH intended
777 : : case ATTRIBUTE_CHAR_ROTATION:
778 : : // FALLTHROUGH intended
779 : : case ATTRIBUTE_HEIGHT:
780 : : // FALLTHROUGH intended
781 : : case ATTRIBUTE_OPACITY:
782 : : // FALLTHROUGH intended
783 : : case ATTRIBUTE_ROTATE:
784 : : // FALLTHROUGH intended
785 : : case ATTRIBUTE_SKEW_X:
786 : : // FALLTHROUGH intended
787 : : case ATTRIBUTE_SKEW_Y:
788 : : // FALLTHROUGH intended
789 : : case ATTRIBUTE_WIDTH:
790 : : // FALLTHROUGH intended
791 : : case ATTRIBUTE_POS_X:
792 : : // FALLTHROUGH intended
793 : : case ATTRIBUTE_POS_Y:
794 : 0 : return CLASS_NUMBER_PROPERTY;
795 : :
796 : : case ATTRIBUTE_CHAR_UNDERLINE:
797 : : // FALLTHROUGH intended
798 : : case ATTRIBUTE_FILL_STYLE:
799 : : // FALLTHROUGH intended
800 : : case ATTRIBUTE_LINE_STYLE:
801 : : // FALLTHROUGH intended
802 : : case ATTRIBUTE_CHAR_POSTURE:
803 : 0 : return CLASS_ENUM_PROPERTY;
804 : : }
805 : : }
806 : :
807 : 0 : NumberAnimationSharedPtr AnimationFactory::createNumberPropertyAnimation( const ::rtl::OUString& rAttrName,
808 : : const AnimatableShapeSharedPtr& rShape,
809 : : const ShapeManagerSharedPtr& rShapeManager,
810 : : const ::basegfx::B2DVector& rSlideSize,
811 : : int nFlags )
812 : : {
813 : : // ATTENTION: When changing this map, also the classifyAttributeName() method must
814 : : // be checked and possibly adapted in their switch statement
815 : 0 : switch( mapAttributeName( rAttrName ) )
816 : : {
817 : : default:
818 : : // FALLTHROUGH intended
819 : : case ATTRIBUTE_INVALID:
820 : 0 : ENSURE_OR_THROW( false,
821 : : "AnimationFactory::createNumberPropertyAnimation(): Unknown attribute" );
822 : : break;
823 : :
824 : : case ATTRIBUTE_CHAR_COLOR:
825 : : // FALLTHROUGH intended
826 : : case ATTRIBUTE_CHAR_FONT_NAME:
827 : : // FALLTHROUGH intended
828 : : case ATTRIBUTE_CHAR_POSTURE:
829 : : // FALLTHROUGH intended
830 : : case ATTRIBUTE_CHAR_UNDERLINE:
831 : : // FALLTHROUGH intended
832 : : case ATTRIBUTE_COLOR:
833 : : // FALLTHROUGH intended
834 : : case ATTRIBUTE_DIMCOLOR:
835 : : // FALLTHROUGH intended
836 : : case ATTRIBUTE_FILL_COLOR:
837 : : // FALLTHROUGH intended
838 : : case ATTRIBUTE_FILL_STYLE:
839 : : // FALLTHROUGH intended
840 : : case ATTRIBUTE_LINE_COLOR:
841 : : // FALLTHROUGH intended
842 : : case ATTRIBUTE_LINE_STYLE:
843 : : // FALLTHROUGH intended
844 : : case ATTRIBUTE_VISIBILITY:
845 : 0 : ENSURE_OR_THROW( false,
846 : : "AnimationFactory::createNumberPropertyAnimation(): Attribute type mismatch" );
847 : : break;
848 : :
849 : : case ATTRIBUTE_CHAR_HEIGHT:
850 : : return makeGenericAnimation<NumberAnimation>( rShapeManager,
851 : : nFlags,
852 : : &ShapeAttributeLayer::isCharScaleValid,
853 : : 1.0, // CharHeight is a relative attribute, thus
854 : : // default is 1.0
855 : : &ShapeAttributeLayer::getCharScale,
856 : 0 : &ShapeAttributeLayer::setCharScale );
857 : :
858 : : case ATTRIBUTE_CHAR_WEIGHT:
859 : : return makeGenericAnimation<NumberAnimation>( rShapeManager,
860 : : nFlags,
861 : : &ShapeAttributeLayer::isCharWeightValid,
862 : 0 : getDefault<double>( rShape, rAttrName ),
863 : : &ShapeAttributeLayer::getCharWeight,
864 : 0 : &ShapeAttributeLayer::setCharWeight );
865 : :
866 : : case ATTRIBUTE_CHAR_ROTATION:
867 : : return makeGenericAnimation<NumberAnimation>( rShapeManager,
868 : : nFlags,
869 : : &ShapeAttributeLayer::isCharRotationAngleValid,
870 : 0 : getDefault<double>( rShape, rAttrName ),
871 : : &ShapeAttributeLayer::getCharRotationAngle,
872 : 0 : &ShapeAttributeLayer::setCharRotationAngle );
873 : :
874 : : case ATTRIBUTE_HEIGHT:
875 : : return makeGenericAnimation( rShapeManager,
876 : : nFlags,
877 : : &ShapeAttributeLayer::isHeightValid,
878 : : // TODO(F1): Check whether _shape_ bounds are correct here.
879 : : // Theoretically, our AttrLayer is way down the stack, and
880 : : // we only have to consider _that_ value, not the one from
881 : : // the top of the stack as returned by Shape::getBounds()
882 : 0 : rShape->getBounds().getHeight(),
883 : : &ShapeAttributeLayer::getHeight,
884 : : &ShapeAttributeLayer::setHeight,
885 : : // convert expression parser value from relative page size
886 : 0 : rSlideSize.getY() );
887 : :
888 : : case ATTRIBUTE_OPACITY:
889 : : return makeGenericAnimation<NumberAnimation>( rShapeManager,
890 : : nFlags,
891 : : &ShapeAttributeLayer::isAlphaValid,
892 : : // TODO(F1): Provide shape default here (FillTransparency?)
893 : : 1.0,
894 : : &ShapeAttributeLayer::getAlpha,
895 : 0 : &ShapeAttributeLayer::setAlpha );
896 : :
897 : : case ATTRIBUTE_ROTATE:
898 : : return makeGenericAnimation<NumberAnimation>( rShapeManager,
899 : : nFlags,
900 : : &ShapeAttributeLayer::isRotationAngleValid,
901 : : // NOTE: Since we paint the shape as-is from metafile,
902 : : // rotation angle is always 0.0, even for rotated shapes
903 : : 0.0,
904 : : &ShapeAttributeLayer::getRotationAngle,
905 : 0 : &ShapeAttributeLayer::setRotationAngle );
906 : :
907 : : case ATTRIBUTE_SKEW_X:
908 : : return makeGenericAnimation<NumberAnimation>( rShapeManager,
909 : : nFlags,
910 : : &ShapeAttributeLayer::isShearXAngleValid,
911 : : // TODO(F1): Is there any shape property for skew?
912 : : 0.0,
913 : : &ShapeAttributeLayer::getShearXAngle,
914 : 0 : &ShapeAttributeLayer::setShearXAngle );
915 : :
916 : : case ATTRIBUTE_SKEW_Y:
917 : : return makeGenericAnimation<NumberAnimation>( rShapeManager,
918 : : nFlags,
919 : : &ShapeAttributeLayer::isShearYAngleValid,
920 : : // TODO(F1): Is there any shape property for skew?
921 : : 0.0,
922 : : &ShapeAttributeLayer::getShearYAngle,
923 : 0 : &ShapeAttributeLayer::setShearYAngle );
924 : :
925 : : case ATTRIBUTE_WIDTH:
926 : : return makeGenericAnimation( rShapeManager,
927 : : nFlags,
928 : : &ShapeAttributeLayer::isWidthValid,
929 : : // TODO(F1): Check whether _shape_ bounds are correct here.
930 : : // Theoretically, our AttrLayer is way down the stack, and
931 : : // we only have to consider _that_ value, not the one from
932 : : // the top of the stack as returned by Shape::getBounds()
933 : 0 : rShape->getBounds().getWidth(),
934 : : &ShapeAttributeLayer::getWidth,
935 : : &ShapeAttributeLayer::setWidth,
936 : : // convert expression parser value from relative page size
937 : 0 : rSlideSize.getX() );
938 : :
939 : : case ATTRIBUTE_POS_X:
940 : : return makeGenericAnimation( rShapeManager,
941 : : nFlags,
942 : : &ShapeAttributeLayer::isPosXValid,
943 : : // TODO(F1): Check whether _shape_ bounds are correct here.
944 : : // Theoretically, our AttrLayer is way down the stack, and
945 : : // we only have to consider _that_ value, not the one from
946 : : // the top of the stack as returned by Shape::getBounds()
947 : 0 : rShape->getBounds().getCenterX(),
948 : : &ShapeAttributeLayer::getPosX,
949 : : &ShapeAttributeLayer::setPosX,
950 : : // convert expression parser value from relative page size
951 : 0 : rSlideSize.getX() );
952 : :
953 : : case ATTRIBUTE_POS_Y:
954 : : return makeGenericAnimation( rShapeManager,
955 : : nFlags,
956 : : &ShapeAttributeLayer::isPosYValid,
957 : : // TODO(F1): Check whether _shape_ bounds are correct here.
958 : : // Theoretically, our AttrLayer is way down the stack, and
959 : : // we only have to consider _that_ value, not the one from
960 : : // the top of the stack as returned by Shape::getBounds()
961 : 0 : rShape->getBounds().getCenterY(),
962 : : &ShapeAttributeLayer::getPosY,
963 : : &ShapeAttributeLayer::setPosY,
964 : : // convert expression parser value from relative page size
965 : 0 : rSlideSize.getY() );
966 : : }
967 : :
968 : : return NumberAnimationSharedPtr();
969 : : }
970 : :
971 : 0 : EnumAnimationSharedPtr AnimationFactory::createEnumPropertyAnimation( const ::rtl::OUString& rAttrName,
972 : : const AnimatableShapeSharedPtr& rShape,
973 : : const ShapeManagerSharedPtr& rShapeManager,
974 : : const ::basegfx::B2DVector& /*rSlideSize*/,
975 : : int nFlags )
976 : : {
977 : : // ATTENTION: When changing this map, also the classifyAttributeName() method must
978 : : // be checked and possibly adapted in their switch statement
979 : 0 : switch( mapAttributeName( rAttrName ) )
980 : : {
981 : : default:
982 : : // FALLTHROUGH intended
983 : : case ATTRIBUTE_INVALID:
984 : 0 : ENSURE_OR_THROW( false,
985 : : "AnimationFactory::createEnumPropertyAnimation(): Unknown attribute" );
986 : : break;
987 : :
988 : : case ATTRIBUTE_CHAR_COLOR:
989 : : // FALLTHROUGH intended
990 : : case ATTRIBUTE_CHAR_FONT_NAME:
991 : : // FALLTHROUGH intended
992 : : case ATTRIBUTE_COLOR:
993 : : // FALLTHROUGH intended
994 : : case ATTRIBUTE_DIMCOLOR:
995 : : // FALLTHROUGH intended
996 : : case ATTRIBUTE_FILL_COLOR:
997 : : // FALLTHROUGH intended
998 : : case ATTRIBUTE_LINE_COLOR:
999 : : // FALLTHROUGH intended
1000 : : case ATTRIBUTE_VISIBILITY:
1001 : : // FALLTHROUGH intended
1002 : : case ATTRIBUTE_CHAR_HEIGHT:
1003 : : // FALLTHROUGH intended
1004 : : case ATTRIBUTE_CHAR_WEIGHT:
1005 : : // FALLTHROUGH intended
1006 : : case ATTRIBUTE_CHAR_ROTATION:
1007 : : // FALLTHROUGH intended
1008 : : case ATTRIBUTE_HEIGHT:
1009 : : // FALLTHROUGH intended
1010 : : case ATTRIBUTE_OPACITY:
1011 : : // FALLTHROUGH intended
1012 : : case ATTRIBUTE_ROTATE:
1013 : : // FALLTHROUGH intended
1014 : : case ATTRIBUTE_SKEW_X:
1015 : : // FALLTHROUGH intended
1016 : : case ATTRIBUTE_SKEW_Y:
1017 : : // FALLTHROUGH intended
1018 : : case ATTRIBUTE_WIDTH:
1019 : : // FALLTHROUGH intended
1020 : : case ATTRIBUTE_POS_X:
1021 : : // FALLTHROUGH intended
1022 : : case ATTRIBUTE_POS_Y:
1023 : 0 : ENSURE_OR_THROW( false,
1024 : : "AnimationFactory::createEnumPropertyAnimation(): Attribute type mismatch" );
1025 : : break;
1026 : :
1027 : :
1028 : : case ATTRIBUTE_FILL_STYLE:
1029 : : return makeGenericAnimation<EnumAnimation>( rShapeManager,
1030 : : nFlags,
1031 : : &ShapeAttributeLayer::isFillStyleValid,
1032 : : sal::static_int_cast<sal_Int16>(
1033 : 0 : getDefault<drawing::FillStyle>( rShape, rAttrName )),
1034 : : &ShapeAttributeLayer::getFillStyle,
1035 : 0 : &ShapeAttributeLayer::setFillStyle );
1036 : :
1037 : : case ATTRIBUTE_LINE_STYLE:
1038 : : return makeGenericAnimation<EnumAnimation>( rShapeManager,
1039 : : nFlags,
1040 : : &ShapeAttributeLayer::isLineStyleValid,
1041 : : sal::static_int_cast<sal_Int16>(
1042 : 0 : getDefault<drawing::LineStyle>( rShape, rAttrName )),
1043 : : &ShapeAttributeLayer::getLineStyle,
1044 : 0 : &ShapeAttributeLayer::setLineStyle );
1045 : :
1046 : : case ATTRIBUTE_CHAR_POSTURE:
1047 : : return makeGenericAnimation<EnumAnimation>( rShapeManager,
1048 : : nFlags,
1049 : : &ShapeAttributeLayer::isCharPostureValid,
1050 : : sal::static_int_cast<sal_Int16>(
1051 : 0 : getDefault<awt::FontSlant>( rShape, rAttrName )),
1052 : : &ShapeAttributeLayer::getCharPosture,
1053 : 0 : &ShapeAttributeLayer::setCharPosture );
1054 : :
1055 : : case ATTRIBUTE_CHAR_UNDERLINE:
1056 : : return makeGenericAnimation<EnumAnimation>( rShapeManager,
1057 : : nFlags,
1058 : : &ShapeAttributeLayer::isUnderlineModeValid,
1059 : 0 : getDefault<sal_Int16>( rShape, rAttrName ),
1060 : : &ShapeAttributeLayer::getUnderlineMode,
1061 : 0 : &ShapeAttributeLayer::setUnderlineMode );
1062 : : }
1063 : :
1064 : : return EnumAnimationSharedPtr();
1065 : : }
1066 : :
1067 : 0 : ColorAnimationSharedPtr AnimationFactory::createColorPropertyAnimation( const ::rtl::OUString& rAttrName,
1068 : : const AnimatableShapeSharedPtr& rShape,
1069 : : const ShapeManagerSharedPtr& rShapeManager,
1070 : : const ::basegfx::B2DVector& /*rSlideSize*/,
1071 : : int nFlags )
1072 : : {
1073 : : // ATTENTION: When changing this map, also the classifyAttributeName() method must
1074 : : // be checked and possibly adapted in their switch statement
1075 : 0 : switch( mapAttributeName( rAttrName ) )
1076 : : {
1077 : : default:
1078 : : // FALLTHROUGH intended
1079 : : case ATTRIBUTE_INVALID:
1080 : 0 : ENSURE_OR_THROW( false,
1081 : : "AnimationFactory::createColorPropertyAnimation(): Unknown attribute" );
1082 : : break;
1083 : :
1084 : : case ATTRIBUTE_CHAR_FONT_NAME:
1085 : : // FALLTHROUGH intended
1086 : : case ATTRIBUTE_CHAR_HEIGHT:
1087 : : // FALLTHROUGH intended
1088 : : case ATTRIBUTE_CHAR_POSTURE:
1089 : : // FALLTHROUGH intended
1090 : : case ATTRIBUTE_CHAR_ROTATION:
1091 : : // FALLTHROUGH intended
1092 : : case ATTRIBUTE_CHAR_UNDERLINE:
1093 : : // FALLTHROUGH intended
1094 : : case ATTRIBUTE_CHAR_WEIGHT:
1095 : : // FALLTHROUGH intended
1096 : : case ATTRIBUTE_FILL_STYLE:
1097 : : // FALLTHROUGH intended
1098 : : case ATTRIBUTE_HEIGHT:
1099 : : // FALLTHROUGH intended
1100 : : case ATTRIBUTE_LINE_STYLE:
1101 : : // FALLTHROUGH intended
1102 : : case ATTRIBUTE_OPACITY:
1103 : : // FALLTHROUGH intended
1104 : : case ATTRIBUTE_ROTATE:
1105 : : // FALLTHROUGH intended
1106 : : case ATTRIBUTE_SKEW_X:
1107 : : // FALLTHROUGH intended
1108 : : case ATTRIBUTE_SKEW_Y:
1109 : : // FALLTHROUGH intended
1110 : : case ATTRIBUTE_VISIBILITY:
1111 : : // FALLTHROUGH intended
1112 : : case ATTRIBUTE_WIDTH:
1113 : : // FALLTHROUGH intended
1114 : : case ATTRIBUTE_POS_X:
1115 : : // FALLTHROUGH intended
1116 : : case ATTRIBUTE_POS_Y:
1117 : 0 : ENSURE_OR_THROW( false,
1118 : : "AnimationFactory::createColorPropertyAnimation(): Attribute type mismatch" );
1119 : : break;
1120 : :
1121 : : case ATTRIBUTE_CHAR_COLOR:
1122 : : return makeGenericAnimation<ColorAnimation>( rShapeManager,
1123 : : nFlags,
1124 : : &ShapeAttributeLayer::isCharColorValid,
1125 : : getDefault<RGBColor>( rShape, rAttrName ),
1126 : : &ShapeAttributeLayer::getCharColor,
1127 : 0 : &ShapeAttributeLayer::setCharColor );
1128 : :
1129 : : case ATTRIBUTE_COLOR:
1130 : : // TODO(F2): This is just mapped to fill color to make it work
1131 : : return makeGenericAnimation<ColorAnimation>( rShapeManager,
1132 : : nFlags,
1133 : : &ShapeAttributeLayer::isFillColorValid,
1134 : : getDefault<RGBColor>( rShape, rAttrName ),
1135 : : &ShapeAttributeLayer::getFillColor,
1136 : 0 : &ShapeAttributeLayer::setFillColor );
1137 : :
1138 : : case ATTRIBUTE_DIMCOLOR:
1139 : : return makeGenericAnimation<ColorAnimation>( rShapeManager,
1140 : : nFlags,
1141 : : &ShapeAttributeLayer::isDimColorValid,
1142 : : getDefault<RGBColor>( rShape, rAttrName ),
1143 : : &ShapeAttributeLayer::getDimColor,
1144 : 0 : &ShapeAttributeLayer::setDimColor );
1145 : :
1146 : : case ATTRIBUTE_FILL_COLOR:
1147 : : return makeGenericAnimation<ColorAnimation>( rShapeManager,
1148 : : nFlags,
1149 : : &ShapeAttributeLayer::isFillColorValid,
1150 : : getDefault<RGBColor>( rShape, rAttrName ),
1151 : : &ShapeAttributeLayer::getFillColor,
1152 : 0 : &ShapeAttributeLayer::setFillColor );
1153 : :
1154 : : case ATTRIBUTE_LINE_COLOR:
1155 : : return makeGenericAnimation<ColorAnimation>( rShapeManager,
1156 : : nFlags,
1157 : : &ShapeAttributeLayer::isLineColorValid,
1158 : : getDefault<RGBColor>( rShape, rAttrName ),
1159 : : &ShapeAttributeLayer::getLineColor,
1160 : 0 : &ShapeAttributeLayer::setLineColor );
1161 : : }
1162 : :
1163 : : return ColorAnimationSharedPtr();
1164 : : }
1165 : :
1166 : 0 : PairAnimationSharedPtr AnimationFactory::createPairPropertyAnimation( const AnimatableShapeSharedPtr& rShape,
1167 : : const ShapeManagerSharedPtr& rShapeManager,
1168 : : const ::basegfx::B2DVector& rSlideSize,
1169 : : sal_Int16 nTransformType,
1170 : : int nFlags )
1171 : : {
1172 : 0 : const ::basegfx::B2DRectangle& rBounds( rShape->getBounds() );
1173 : :
1174 : 0 : switch( nTransformType )
1175 : : {
1176 : : case animations::AnimationTransformType::SCALE:
1177 : : return PairAnimationSharedPtr(
1178 : : new TupleAnimation< ::basegfx::B2DSize >(
1179 : : rShapeManager,
1180 : : nFlags,
1181 : : &ShapeAttributeLayer::isWidthValid,
1182 : : &ShapeAttributeLayer::isHeightValid,
1183 : : // TODO(F1): Check whether _shape_ bounds are correct here.
1184 : : // Theoretically, our AttrLayer is way down the stack, and
1185 : : // we only have to consider _that_ value, not the one from
1186 : : // the top of the stack as returned by Shape::getBounds()
1187 : : rBounds.getRange(),
1188 : : rBounds.getRange(),
1189 : : &ShapeAttributeLayer::getWidth,
1190 : : &ShapeAttributeLayer::getHeight,
1191 : 0 : &ShapeAttributeLayer::setSize ) );
1192 : :
1193 : : case animations::AnimationTransformType::TRANSLATE:
1194 : : return PairAnimationSharedPtr(
1195 : : new TupleAnimation< ::basegfx::B2DPoint >(
1196 : : rShapeManager,
1197 : : nFlags,
1198 : : &ShapeAttributeLayer::isPosXValid,
1199 : : &ShapeAttributeLayer::isPosYValid,
1200 : : // TODO(F1): Check whether _shape_ bounds are correct here.
1201 : : // Theoretically, our AttrLayer is way down the stack, and
1202 : : // we only have to consider _that_ value, not the one from
1203 : : // the top of the stack as returned by Shape::getBounds()
1204 : : rBounds.getCenter(),
1205 : : rSlideSize,
1206 : : &ShapeAttributeLayer::getPosX,
1207 : : &ShapeAttributeLayer::getPosY,
1208 : 0 : &ShapeAttributeLayer::setPosition ) );
1209 : :
1210 : : default:
1211 : 0 : ENSURE_OR_THROW( false,
1212 : : "AnimationFactory::createPairPropertyAnimation(): Attribute type mismatch" );
1213 : : break;
1214 : : }
1215 : :
1216 : : return PairAnimationSharedPtr();
1217 : : }
1218 : :
1219 : 0 : StringAnimationSharedPtr AnimationFactory::createStringPropertyAnimation( const ::rtl::OUString& rAttrName,
1220 : : const AnimatableShapeSharedPtr& rShape,
1221 : : const ShapeManagerSharedPtr& rShapeManager,
1222 : : const ::basegfx::B2DVector& /*rSlideSize*/,
1223 : : int nFlags )
1224 : : {
1225 : : // ATTENTION: When changing this map, also the classifyAttributeName() method must
1226 : : // be checked and possibly adapted in their switch statement
1227 : 0 : switch( mapAttributeName( rAttrName ) )
1228 : : {
1229 : : default:
1230 : : // FALLTHROUGH intended
1231 : : case ATTRIBUTE_INVALID:
1232 : 0 : ENSURE_OR_THROW( false,
1233 : : "AnimationFactory::createStringPropertyAnimation(): Unknown attribute" );
1234 : : break;
1235 : :
1236 : : case ATTRIBUTE_CHAR_COLOR:
1237 : : // FALLTHROUGH intended
1238 : : case ATTRIBUTE_CHAR_HEIGHT:
1239 : : // FALLTHROUGH intended
1240 : : case ATTRIBUTE_CHAR_ROTATION:
1241 : : // FALLTHROUGH intended
1242 : : case ATTRIBUTE_CHAR_UNDERLINE:
1243 : : // FALLTHROUGH intended
1244 : : case ATTRIBUTE_COLOR:
1245 : : // FALLTHROUGH intended
1246 : : case ATTRIBUTE_DIMCOLOR:
1247 : : // FALLTHROUGH intended
1248 : : case ATTRIBUTE_FILL_COLOR:
1249 : : // FALLTHROUGH intended
1250 : : case ATTRIBUTE_HEIGHT:
1251 : : // FALLTHROUGH intended
1252 : : case ATTRIBUTE_LINE_COLOR:
1253 : : // FALLTHROUGH intended
1254 : : case ATTRIBUTE_OPACITY:
1255 : : // FALLTHROUGH intended
1256 : : case ATTRIBUTE_ROTATE:
1257 : : // FALLTHROUGH intended
1258 : : case ATTRIBUTE_SKEW_X:
1259 : : // FALLTHROUGH intended
1260 : : case ATTRIBUTE_SKEW_Y:
1261 : : // FALLTHROUGH intended
1262 : : case ATTRIBUTE_VISIBILITY:
1263 : : // FALLTHROUGH intended
1264 : : case ATTRIBUTE_WIDTH:
1265 : : // FALLTHROUGH intended
1266 : : case ATTRIBUTE_POS_X:
1267 : : // FALLTHROUGH intended
1268 : : case ATTRIBUTE_POS_Y:
1269 : : // FALLTHROUGH intended
1270 : : case ATTRIBUTE_CHAR_POSTURE:
1271 : : // FALLTHROUGH intended
1272 : : case ATTRIBUTE_CHAR_WEIGHT:
1273 : : // FALLTHROUGH intended
1274 : : case ATTRIBUTE_FILL_STYLE:
1275 : : // FALLTHROUGH intended
1276 : : case ATTRIBUTE_LINE_STYLE:
1277 : 0 : ENSURE_OR_THROW( false,
1278 : : "AnimationFactory::createStringPropertyAnimation(): Attribute type mismatch" );
1279 : : break;
1280 : :
1281 : : case ATTRIBUTE_CHAR_FONT_NAME:
1282 : : return makeGenericAnimation<StringAnimation>( rShapeManager,
1283 : : nFlags,
1284 : : &ShapeAttributeLayer::isFontFamilyValid,
1285 : : getDefault< ::rtl::OUString >( rShape, rAttrName ),
1286 : : &ShapeAttributeLayer::getFontFamily,
1287 : 0 : &ShapeAttributeLayer::setFontFamily );
1288 : : }
1289 : :
1290 : : return StringAnimationSharedPtr();
1291 : : }
1292 : :
1293 : 0 : BoolAnimationSharedPtr AnimationFactory::createBoolPropertyAnimation( const ::rtl::OUString& rAttrName,
1294 : : const AnimatableShapeSharedPtr& /*rShape*/,
1295 : : const ShapeManagerSharedPtr& rShapeManager,
1296 : : const ::basegfx::B2DVector& /*rSlideSize*/,
1297 : : int nFlags )
1298 : : {
1299 : : // ATTENTION: When changing this map, also the classifyAttributeName() method must
1300 : : // be checked and possibly adapted in their switch statement
1301 : 0 : switch( mapAttributeName( rAttrName ) )
1302 : : {
1303 : : default:
1304 : : // FALLTHROUGH intended
1305 : : case ATTRIBUTE_INVALID:
1306 : 0 : ENSURE_OR_THROW( false,
1307 : : "AnimationFactory::createBoolPropertyAnimation(): Unknown attribute" );
1308 : : break;
1309 : :
1310 : : case ATTRIBUTE_CHAR_COLOR:
1311 : : // FALLTHROUGH intended
1312 : : case ATTRIBUTE_CHAR_FONT_NAME:
1313 : : // FALLTHROUGH intended
1314 : : case ATTRIBUTE_CHAR_HEIGHT:
1315 : : // FALLTHROUGH intended
1316 : : case ATTRIBUTE_CHAR_POSTURE:
1317 : : // FALLTHROUGH intended
1318 : : case ATTRIBUTE_CHAR_ROTATION:
1319 : : // FALLTHROUGH intended
1320 : : case ATTRIBUTE_CHAR_WEIGHT:
1321 : : // FALLTHROUGH intended
1322 : : case ATTRIBUTE_COLOR:
1323 : : // FALLTHROUGH intended
1324 : : case ATTRIBUTE_DIMCOLOR:
1325 : : // FALLTHROUGH intended
1326 : : case ATTRIBUTE_FILL_COLOR:
1327 : : // FALLTHROUGH intended
1328 : : case ATTRIBUTE_FILL_STYLE:
1329 : : // FALLTHROUGH intended
1330 : : case ATTRIBUTE_HEIGHT:
1331 : : // FALLTHROUGH intended
1332 : : case ATTRIBUTE_LINE_COLOR:
1333 : : // FALLTHROUGH intended
1334 : : case ATTRIBUTE_LINE_STYLE:
1335 : : // FALLTHROUGH intended
1336 : : case ATTRIBUTE_OPACITY:
1337 : : // FALLTHROUGH intended
1338 : : case ATTRIBUTE_ROTATE:
1339 : : // FALLTHROUGH intended
1340 : : case ATTRIBUTE_SKEW_X:
1341 : : // FALLTHROUGH intended
1342 : : case ATTRIBUTE_SKEW_Y:
1343 : : // FALLTHROUGH intended
1344 : : case ATTRIBUTE_WIDTH:
1345 : : // FALLTHROUGH intended
1346 : : case ATTRIBUTE_POS_X:
1347 : : // FALLTHROUGH intended
1348 : : case ATTRIBUTE_POS_Y:
1349 : : // FALLTHROUGH intended
1350 : : case ATTRIBUTE_CHAR_UNDERLINE:
1351 : 0 : ENSURE_OR_THROW( false,
1352 : : "AnimationFactory::createBoolPropertyAnimation(): Attribute type mismatch" );
1353 : : break;
1354 : :
1355 : : case ATTRIBUTE_VISIBILITY:
1356 : : return makeGenericAnimation<BoolAnimation>( rShapeManager,
1357 : : nFlags,
1358 : : &ShapeAttributeLayer::isVisibilityValid,
1359 : : // TODO(F1): Is there a corresponding shape property?
1360 : : true,
1361 : : &ShapeAttributeLayer::getVisibility,
1362 : 0 : &ShapeAttributeLayer::setVisibility );
1363 : : }
1364 : :
1365 : : return BoolAnimationSharedPtr();
1366 : : }
1367 : :
1368 : 0 : NumberAnimationSharedPtr AnimationFactory::createPathMotionAnimation( const ::rtl::OUString& rSVGDPath,
1369 : : sal_Int16 nAdditive,
1370 : : const AnimatableShapeSharedPtr& /*rShape*/,
1371 : : const ShapeManagerSharedPtr& rShapeManager,
1372 : : const ::basegfx::B2DVector& rSlideSize,
1373 : : int nFlags )
1374 : : {
1375 : : return NumberAnimationSharedPtr(
1376 : : new PathAnimation( rSVGDPath, nAdditive,
1377 : : rShapeManager,
1378 : : rSlideSize,
1379 : 0 : nFlags ) );
1380 : : }
1381 : :
1382 : : }
1383 : : }
1384 : :
1385 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|