(Vector) Stop the animation when the actor is off-stage or invisible
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / animated-vector-image / animated-vector-image-visual.cpp
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/common/stage.h>
23 #include <dali/devel-api/rendering/renderer-devel.h>
24 #include <dali/devel-api/adaptor-framework/window-devel.h>
25 #include <dali/integration-api/debug.h>
26
27 // INTERNAL INCLUDES
28 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
29 #include <dali-toolkit/public-api/visuals/visual-properties.h>
30 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
31 #include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-signals-devel.h>
32 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
33 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
34 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
35 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
36
37 namespace Dali
38 {
39
40 namespace Toolkit
41 {
42
43 namespace Internal
44 {
45
46 namespace
47 {
48
49 constexpr auto LOOP_FOREVER = -1;
50
51 const Dali::Vector4 FULL_TEXTURE_RECT( 0.f, 0.f, 1.f, 1.f );
52
53 // Flags for re-sending data to the rasterize thread
54 enum Flags
55 {
56   RESEND_PLAY_RANGE    = 1 << 0,
57   RESEND_LOOP_COUNT    = 1 << 1,
58   RESEND_STOP_BEHAVIOR = 1 << 2,
59   RESEND_LOOPING_MODE  = 1 << 3
60 };
61
62 // stop behavior
63 DALI_ENUM_TO_STRING_TABLE_BEGIN( STOP_BEHAVIOR )
64 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::StopBehavior, CURRENT_FRAME )
65 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::StopBehavior, FIRST_FRAME )
66 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::StopBehavior, LAST_FRAME )
67 DALI_ENUM_TO_STRING_TABLE_END( STOP_BEHAVIOR )
68
69 // looping mode
70 DALI_ENUM_TO_STRING_TABLE_BEGIN( LOOPING_MODE )
71 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::LoopingMode, RESTART )
72 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::LoopingMode, AUTO_REVERSE )
73 DALI_ENUM_TO_STRING_TABLE_END( LOOPING_MODE )
74
75 #if defined(DEBUG_ENABLED)
76 Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VECTOR_ANIMATION" );
77 #endif
78
79 } // unnamed namespace
80
81 AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties )
82 {
83   AnimatedVectorImageVisualPtr visual( new AnimatedVectorImageVisual( factoryCache, shaderFactory, imageUrl ) );
84   visual->SetProperties( properties );
85
86   return visual;
87 }
88
89 AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
90 {
91   AnimatedVectorImageVisualPtr visual( new AnimatedVectorImageVisual( factoryCache, shaderFactory, imageUrl ) );
92
93   return visual;
94 }
95
96 AnimatedVectorImageVisual::AnimatedVectorImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
97 : Visual::Base( factoryCache, Visual::FittingMode::FILL ),
98   mUrl( imageUrl ),
99   mVectorAnimationTask( new VectorAnimationTask( factoryCache, imageUrl.GetUrl() ) ),
100   mImageVisualShaderFactory( shaderFactory ),
101   mVisualSize(),
102   mVisualScale( Vector2::ONE ),
103   mPlayRange(),
104   mPlacementActor(),
105   mLoopCount( LOOP_FOREVER ),
106   mResendFlag( 0 ),
107   mActionStatus( DevelAnimatedVectorImageVisual::Action::STOP ),
108   mStopBehavior( DevelImageVisual::StopBehavior::CURRENT_FRAME ),
109   mLoopingMode( DevelImageVisual::LoopingMode::RESTART ),
110   mRendererAdded( false )
111 {
112   // the rasterized image is with pre-multiplied alpha format
113   mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA;
114
115   mVectorAnimationTask->UploadCompletedSignal().Connect( this, &AnimatedVectorImageVisual::OnUploadCompleted );
116   mVectorAnimationTask->SetAnimationFinishedCallback( new EventThreadCallback( MakeCallback( this, &AnimatedVectorImageVisual::OnAnimationFinished ) ) );
117 }
118
119 AnimatedVectorImageVisual::~AnimatedVectorImageVisual()
120 {
121   // Finalize animation task in the main thread
122   mVectorAnimationTask->Finalize();
123 }
124
125 void AnimatedVectorImageVisual::GetNaturalSize( Vector2& naturalSize )
126 {
127   if( mVisualSize != Vector2::ZERO )
128   {
129     naturalSize = mVisualSize;
130   }
131   else
132   {
133     uint32_t width, height;
134     mVectorAnimationTask->GetDefaultSize( width, height );
135     naturalSize.x = width;
136     naturalSize.y = height;
137   }
138
139   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::GetNaturalSize: w = %f, h = %f [%p]\n", naturalSize.width, naturalSize.height, this );
140 }
141
142 void AnimatedVectorImageVisual::DoCreatePropertyMap( Property::Map& map ) const
143 {
144   map.Clear();
145   map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE );
146   if( mUrl.IsValid() )
147   {
148     map.Insert( Toolkit::ImageVisual::Property::URL, mUrl.GetUrl() );
149   }
150   map.Insert( Toolkit::DevelImageVisual::Property::LOOP_COUNT, mLoopCount );
151
152   uint32_t startFrame, endFrame;
153   mVectorAnimationTask->GetPlayRange( startFrame, endFrame );
154
155   Property::Array playRange;
156   playRange.PushBack( static_cast< int32_t >( startFrame ) );
157   playRange.PushBack( static_cast< int32_t >( endFrame ) );
158   map.Insert( Toolkit::DevelImageVisual::Property::PLAY_RANGE, playRange );
159
160   map.Insert( Toolkit::DevelImageVisual::Property::PLAY_STATE, static_cast< int32_t >( mVectorAnimationTask->GetPlayState() ) );
161   map.Insert( Toolkit::DevelImageVisual::Property::CURRENT_FRAME_NUMBER, static_cast< int32_t >( mVectorAnimationTask->GetCurrentFrameNumber() ) );
162   map.Insert( Toolkit::DevelImageVisual::Property::TOTAL_FRAME_NUMBER, static_cast< int32_t >( mVectorAnimationTask->GetTotalFrameNumber() ) );
163
164   map.Insert( Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mStopBehavior );
165   map.Insert( Toolkit::DevelImageVisual::Property::LOOPING_MODE, mLoopingMode );
166
167   Property::Map layerInfo;
168   mVectorAnimationTask->GetLayerInfo( layerInfo );
169   map.Insert( Toolkit::DevelImageVisual::Property::CONTENT_INFO, layerInfo );
170 }
171
172 void AnimatedVectorImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
173 {
174   // Do nothing
175 }
176
177 void AnimatedVectorImageVisual::DoSetProperties( const Property::Map& propertyMap )
178 {
179   // url already passed in from constructor
180   for( Property::Map::SizeType iter = 0; iter < propertyMap.Count(); ++iter )
181   {
182     KeyValuePair keyValue = propertyMap.GetKeyValue( iter );
183     if( keyValue.first.type == Property::Key::INDEX )
184     {
185       DoSetProperty( keyValue.first.indexKey, keyValue.second );
186     }
187     else
188     {
189        if( keyValue.first == LOOP_COUNT_NAME )
190        {
191           DoSetProperty( Toolkit::DevelImageVisual::Property::LOOP_COUNT, keyValue.second );
192        }
193        else if( keyValue.first == PLAY_RANGE_NAME )
194        {
195           DoSetProperty( Toolkit::DevelImageVisual::Property::PLAY_RANGE, keyValue.second );
196        }
197        else if( keyValue.first == STOP_BEHAVIOR_NAME )
198        {
199           DoSetProperty( Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, keyValue.second );
200        }
201        else if( keyValue.first == LOOPING_MODE_NAME )
202        {
203           DoSetProperty( Toolkit::DevelImageVisual::Property::LOOPING_MODE, keyValue.second );
204        }
205     }
206   }
207 }
208
209 void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Property::Value& value )
210 {
211   switch(index)
212   {
213     case Toolkit::DevelImageVisual::Property::LOOP_COUNT:
214     {
215       int32_t loopCount;
216       if( value.Get( loopCount ) )
217       {
218         mLoopCount = loopCount;
219         mResendFlag |= RESEND_LOOP_COUNT;
220       }
221       break;
222     }
223     case Toolkit::DevelImageVisual::Property::PLAY_RANGE:
224     {
225       Property::Array* array = value.GetArray();
226       if( array )
227       {
228         mPlayRange = *array;
229         mResendFlag |= RESEND_PLAY_RANGE;
230       }
231       break;
232     }
233     case Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR:
234     {
235       int32_t stopBehavior = mStopBehavior;
236       if( Scripting::GetEnumerationProperty( value, STOP_BEHAVIOR_TABLE, STOP_BEHAVIOR_TABLE_COUNT, stopBehavior ) )
237       {
238         mStopBehavior = DevelImageVisual::StopBehavior::Type( stopBehavior );
239         mResendFlag |= RESEND_STOP_BEHAVIOR;
240       }
241       break;
242     }
243     case Toolkit::DevelImageVisual::Property::LOOPING_MODE:
244     {
245       int32_t loopingMode = mLoopingMode;
246       if( Scripting::GetEnumerationProperty( value, LOOPING_MODE_TABLE, LOOPING_MODE_TABLE_COUNT, loopingMode ) )
247       {
248         mLoopingMode = DevelImageVisual::LoopingMode::Type( loopingMode );
249         mResendFlag |= RESEND_LOOPING_MODE;
250       }
251       break;
252     }
253   }
254 }
255
256 void AnimatedVectorImageVisual::DoSetOnStage( Actor& actor )
257 {
258   Shader shader;
259
260   if( mImpl->mCustomShader )
261   {
262     shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource() : mImpl->mCustomShader->mVertexShader,
263                           mImpl->mCustomShader->mFragmentShader.empty() ? mImageVisualShaderFactory.GetFragmentShaderSource() : mImpl->mCustomShader->mFragmentShader,
264                           mImpl->mCustomShader->mHints );
265
266     shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
267   }
268   else
269   {
270     shader = mImageVisualShaderFactory.GetShader( mFactoryCache, false, true );
271   }
272
273   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
274
275   mImpl->mRenderer = Renderer::New( geometry, shader );
276
277   TextureSet textureSet = TextureSet::New();
278   mImpl->mRenderer.SetTextures( textureSet );
279
280   // Register transform properties
281   mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
282
283   // Defer the rasterisation task until we get given a size (by Size Negotiation algorithm)
284
285   // Hold the weak handle of the placement actor and delay the adding of renderer until the rasterization is finished.
286   mPlacementActor = actor;
287
288   mVectorAnimationTask->SetRenderer( mImpl->mRenderer );
289
290   // Add property notification for scaling & size
291   mScaleNotification = actor.AddPropertyNotification( Actor::Property::WORLD_SCALE, StepCondition( 0.1f, 1.0f ) );
292   mScaleNotification.NotifySignal().Connect( this, &AnimatedVectorImageVisual::OnScaleNotification );
293
294   mSizeNotification = actor.AddPropertyNotification( Actor::Property::SIZE, StepCondition( 3.0f ) );
295   mSizeNotification.NotifySignal().Connect( this, &AnimatedVectorImageVisual::OnSizeNotification );
296
297   DevelActor::VisibilityChangedSignal( actor ).Connect( this, &AnimatedVectorImageVisual::OnControlVisibilityChanged );
298
299   Window window = DevelWindow::Get( actor );
300   if( window )
301   {
302     DevelWindow::VisibilityChangedSignal( window ).Connect( this, &AnimatedVectorImageVisual::OnWindowVisibilityChanged );
303   }
304
305   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::DoSetOnStage [%p]\n", this );
306 }
307
308 void AnimatedVectorImageVisual::DoSetOffStage( Actor& actor )
309 {
310   StopAnimation();
311
312   if( mImpl->mRenderer )
313   {
314     actor.RemoveRenderer( mImpl->mRenderer );
315     mImpl->mRenderer.Reset();
316
317     mRendererAdded = false;
318   }
319
320   // Remove property notification
321   actor.RemovePropertyNotification( mScaleNotification );
322   actor.RemovePropertyNotification( mSizeNotification );
323
324   DevelActor::VisibilityChangedSignal( actor ).Disconnect( this, &AnimatedVectorImageVisual::OnControlVisibilityChanged );
325
326   Window window = DevelWindow::Get( actor );
327   if( window )
328   {
329     DevelWindow::VisibilityChangedSignal( window ).Disconnect( this, &AnimatedVectorImageVisual::OnWindowVisibilityChanged );
330   }
331
332   mPlacementActor.Reset();
333
334   // Reset the visual size to zero so that when adding the actor back to stage the rasterization is forced
335   mVisualSize = Vector2::ZERO;
336   mVisualScale = Vector2::ONE;
337
338   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::DoSetOffStage [%p]\n", this );
339 }
340
341 void AnimatedVectorImageVisual::OnSetTransform()
342 {
343   Vector2 visualSize = mImpl->mTransform.GetVisualSize( mImpl->mControlSize );
344
345   if( IsOnStage() && visualSize != mVisualSize )
346   {
347     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnSetTransform: width = %f, height = %f [%p]\n", visualSize.width, visualSize.height, this );
348
349     mVisualSize = visualSize;
350
351     SetVectorImageSize();
352
353     SendAnimationData();
354
355     if( mActionStatus == DevelAnimatedVectorImageVisual::Action::PLAY )
356     {
357       mVectorAnimationTask->PlayAnimation();
358
359       mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY );
360     }
361     else
362     {
363       // Render one frame
364       mVectorAnimationTask->RenderFrame();
365     }
366   }
367 }
368
369 void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, const Property::Value& attributes )
370 {
371   // Check if action is valid for this visual type and perform action if possible
372   switch( actionId )
373   {
374     case DevelAnimatedVectorImageVisual::Action::PLAY:
375     {
376       if( IsOnStage() && mVisualSize != Vector2::ZERO )
377       {
378         mVectorAnimationTask->PlayAnimation();
379
380         mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY );
381       }
382       mActionStatus = DevelAnimatedVectorImageVisual::Action::PLAY;
383       break;
384     }
385     case DevelAnimatedVectorImageVisual::Action::PAUSE:
386     {
387       mVectorAnimationTask->PauseAnimation();
388
389       if( mImpl->mRenderer )
390       {
391         mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
392       }
393
394       mActionStatus = DevelAnimatedVectorImageVisual::Action::PAUSE;
395       break;
396     }
397     case DevelAnimatedVectorImageVisual::Action::STOP:
398     {
399       if( mVectorAnimationTask->GetPlayState() != DevelImageVisual::PlayState::STOPPED )
400       {
401         mVectorAnimationTask->StopAnimation();
402       }
403
404       if( mImpl->mRenderer )
405       {
406         mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
407       }
408
409       mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
410       break;
411     }
412     case DevelAnimatedVectorImageVisual::Action::JUMP_TO:
413     {
414       int32_t frameNumber;
415       if( attributes.Get( frameNumber ) )
416       {
417         mVectorAnimationTask->SetCurrentFrameNumber( frameNumber );
418
419         if( IsOnStage() && mVectorAnimationTask->GetPlayState() != DevelImageVisual::PlayState::PLAYING )
420         {
421           mVectorAnimationTask->RenderFrame();
422           Stage::GetCurrent().KeepRendering( 0.0f );    // Trigger rendering
423         }
424       }
425       break;
426     }
427     case DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY:
428     {
429       Property::Map* map = attributes.GetMap();
430       if( map )
431       {
432         DoSetProperties( *map );
433
434         SendAnimationData();
435       }
436       break;
437     }
438   }
439 }
440
441 void AnimatedVectorImageVisual::OnUploadCompleted()
442 {
443   // If weak handle is holding a placement actor, it is the time to add the renderer to actor.
444   Actor actor = mPlacementActor.GetHandle();
445   if( actor && !mRendererAdded )
446   {
447     actor.AddRenderer( mImpl->mRenderer );
448     mRendererAdded = true;
449
450     ResourceReady( Toolkit::Visual::ResourceStatus::READY );
451
452     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnUploadCompleted: Renderer is added [%p]\n", this );
453   }
454 }
455
456 void AnimatedVectorImageVisual::OnAnimationFinished()
457 {
458   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnAnimationFinished: action state = %d [%p]\n", mActionStatus, this );
459
460   if( mActionStatus != DevelAnimatedVectorImageVisual::Action::STOP )
461   {
462     mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
463
464     if( mImpl->mEventObserver )
465     {
466       mImpl->mEventObserver->NotifyVisualEvent( *this, DevelAnimatedVectorImageVisual::Signal::ANIMATION_FINISHED );
467     }
468   }
469
470   if( mImpl->mRenderer )
471   {
472     mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
473   }
474 }
475
476 void AnimatedVectorImageVisual::SendAnimationData()
477 {
478   if( mResendFlag )
479   {
480     bool isPlaying = false;
481     if( mVectorAnimationTask->GetPlayState() == DevelImageVisual::PlayState::PLAYING )
482     {
483       mVectorAnimationTask->PauseAnimation();
484       isPlaying = true;
485     }
486
487     if( mResendFlag & RESEND_LOOP_COUNT )
488     {
489       mVectorAnimationTask->SetLoopCount( mLoopCount );
490     }
491
492     if( mResendFlag & RESEND_PLAY_RANGE )
493     {
494       mVectorAnimationTask->SetPlayRange( mPlayRange );
495     }
496
497     if( mResendFlag & RESEND_STOP_BEHAVIOR )
498     {
499       mVectorAnimationTask->SetStopBehavior( mStopBehavior );
500     }
501
502     if( mResendFlag & RESEND_LOOPING_MODE )
503     {
504       mVectorAnimationTask->SetLoopingMode( mLoopingMode );
505     }
506
507     if( IsOnStage() )
508     {
509       if( isPlaying )
510       {
511         mVectorAnimationTask->PlayAnimation();
512       }
513       else
514       {
515         mVectorAnimationTask->RenderFrame();
516         Stage::GetCurrent().KeepRendering( 0.0f );
517       }
518     }
519
520     mResendFlag = 0;
521   }
522 }
523
524 void AnimatedVectorImageVisual::SetVectorImageSize()
525 {
526   uint32_t width = static_cast< uint32_t >( mVisualSize.width * mVisualScale.width );
527   uint32_t height = static_cast< uint32_t >( mVisualSize.height * mVisualScale.height );
528
529   mVectorAnimationTask->SetSize( width, height );
530
531   if( IsOnStage() && mVectorAnimationTask->GetPlayState() != DevelImageVisual::PlayState::PLAYING )
532   {
533     mVectorAnimationTask->RenderFrame();
534     Stage::GetCurrent().KeepRendering( 0.0f );    // Trigger rendering
535   }
536 }
537
538 void AnimatedVectorImageVisual::StopAnimation()
539 {
540   if( mActionStatus != DevelAnimatedVectorImageVisual::Action::STOP )
541   {
542     mVectorAnimationTask->StopAnimation();
543
544     mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
545
546     if( mImpl->mRenderer )
547     {
548       mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
549     }
550   }
551 }
552
553 void AnimatedVectorImageVisual::OnScaleNotification( PropertyNotification& source )
554 {
555   Actor actor = mPlacementActor.GetHandle();
556   if( actor )
557   {
558     Vector3 scale = actor.GetProperty< Vector3 >( Actor::Property::WORLD_SCALE );
559     mVisualScale.width = scale.width;
560     mVisualScale.height = scale.height;
561
562     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnScaleNotification: scale = %f, %f [%p]\n", mVisualScale.width, mVisualScale.height, this );
563
564     SetVectorImageSize();
565   }
566 }
567
568 void AnimatedVectorImageVisual::OnSizeNotification( PropertyNotification& source )
569 {
570   Actor actor = mPlacementActor.GetHandle();
571   if( actor )
572   {
573     Vector3 size = actor.GetCurrentSize();
574     mVisualSize.width = size.width;
575     mVisualSize.height = size.height;
576
577     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnSizeNotification: size = %f, %f [%p]\n", mVisualSize.width, mVisualSize.height, this );
578
579     SetVectorImageSize();
580   }
581 }
582
583 void AnimatedVectorImageVisual::OnControlVisibilityChanged( Actor actor, bool visible, DevelActor::VisibilityChange::Type type )
584 {
585   if( !visible )
586   {
587     StopAnimation();
588
589     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnControlVisibilityChanged: invisibile. Pause animation [%p]\n", this );
590   }
591 }
592
593 void AnimatedVectorImageVisual::OnWindowVisibilityChanged( Window window, bool visible )
594 {
595   if( !visible )
596   {
597     StopAnimation();
598
599     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnWindowVisibilityChanged: invisibile. Pause animation [%p]\n", this );
600   }
601 }
602
603 } // namespace Internal
604
605 } // namespace Toolkit
606
607 } // namespace Dali