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 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 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 131 void ClippingAnimation::prefetch( const AnimatableShapeSharedPtr&, 132 const ShapeAttributeLayerSharedPtr& ) 133 { 134 } 135 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 162 void ClippingAnimation::end() 163 { 164 end_(); 165 } 166 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 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 195 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 // explicitely name our start value. 204 // Permissible range for operator() above is [0,1] 205 } 206 207 } // anon namespace 208 209 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 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