Add VisualEventSignal to Control and a property to AnimatedVectorImageVisual 21/196221/6
authorHeeyong Song <heeyong.song@samsung.com>
Wed, 26 Dec 2018 09:31:20 +0000 (18:31 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Mon, 14 Jan 2019 01:49:50 +0000 (10:49 +0900)
- Add VisualEventSignal to Control
- Add DevelImageVisual::Property::PLAY_STATE
- Add DevelAnimatedVectorImageVisual::Signal::ANIMATION_FINISHED
- Remove DevelAnimatedVectorImageVisual::Action::RESUME

Change-Id: Ic3b75971e58bab8b6f9d97d3220041ead22a2f86

22 files changed:
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
dali-toolkit/devel-api/controls/control-devel.cpp
dali-toolkit/devel-api/controls/control-devel.h
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h
dali-toolkit/devel-api/visuals/animated-vector-image-visual-signals-devel.h [new file with mode: 0644]
dali-toolkit/devel-api/visuals/image-visual-properties-devel.h
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.h
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h
dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.h
dali-toolkit/internal/visuals/visual-base-data-impl.cpp
dali-toolkit/internal/visuals/visual-base-data-impl.h
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.h
dali-toolkit/internal/visuals/visual-event-observer.h [new file with mode: 0644]
dali-toolkit/internal/visuals/visual-resource-observer.h [deleted file]

index 9825b56..b8ddd29 100644 (file)
@@ -188,7 +188,17 @@ void DummyControlImpl::SetProperty( BaseObject* object, Dali::Property::Index in
 
 Property::Value DummyControlImpl::GetProperty( BaseObject* object, Dali::Property::Index propertyIndex )
 {
 
 Property::Value DummyControlImpl::GetProperty( BaseObject* object, Dali::Property::Index propertyIndex )
 {
-  Dali::Property::Value value;
+  Toolkit::DummyControl control = Toolkit::DummyControl::DownCast( Dali::BaseHandle( object ) );
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>( control.GetImplementation() );
+
+  Visual::Base visual = dummyImpl.GetVisual( propertyIndex );
+  Property::Map map;
+  if( visual )
+  {
+    visual.CreatePropertyMap( map );
+  }
+  Dali::Property::Value value = map;
+
   return value;
 }
 
   return value;
 }
 
index c0fee41..4c80bf2 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h>
+#include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-signals-devel.h>
 #include "dummy-control.h"
 
 using namespace Dali;
 #include "dummy-control.h"
 
 using namespace Dali;
@@ -45,6 +46,16 @@ namespace
 
 const char* TEST_VECTOR_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR  "/insta_camera.json";
 
 
 const char* TEST_VECTOR_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR  "/insta_camera.json";
 
+bool gAnimationFinishedSignalFired = false;
+
+void VisualEventSignal( Control control, Dali::Property::Index visualIndex, Dali::Property::Index signalId )
+{
+  if( visualIndex == DummyControl::Property::TEST_VISUAL && signalId == DevelAnimatedVectorImageVisual::Signal::ANIMATION_FINISHED )
+  {
+    gAnimationFinishedSignalFired = true;
+  }
+}
+
 }
 
 int UtcDaliVisualFactoryGetAnimatedVectorImageVisual01(void)
 }
 
 int UtcDaliVisualFactoryGetAnimatedVectorImageVisual01(void)
@@ -273,7 +284,9 @@ int UtcDaliAnimatedVectorImageVisualPlayback(void)
 
     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
 
 
     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
 
-    // test
+    Property::Map map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
+    Property::Value* value = map.Find( DevelImageVisual::Property::PLAY_STATE );
+    DALI_TEST_CHECK( value->Get< int >() == static_cast< int >( DevelImageVisual::PlayState::PLAYING ) );
 
     tet_infoline( "Test Pause action" );
     DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PAUSE, attributes );
 
     tet_infoline( "Test Pause action" );
     DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PAUSE, attributes );
@@ -281,15 +294,19 @@ int UtcDaliAnimatedVectorImageVisualPlayback(void)
     application.SendNotification();
     application.Render(16);
 
     application.SendNotification();
     application.Render(16);
 
-    // test
+    map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
+    value = map.Find( DevelImageVisual::Property::PLAY_STATE );
+    DALI_TEST_CHECK( value->Get< int >() == static_cast< int >( DevelImageVisual::PlayState::PAUSED ) );
 
 
-    tet_infoline( "Test Resume action" );
-    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::RESUME, attributes );
+    tet_infoline( "Test Play action" );
+    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
 
     application.SendNotification();
     application.Render(16);
 
 
     application.SendNotification();
     application.Render(16);
 
-    // test
+    map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
+    value = map.Find( DevelImageVisual::Property::PLAY_STATE );
+    DALI_TEST_CHECK( value->Get< int >() == static_cast< int >( DevelImageVisual::PlayState::PLAYING ) );
 
     tet_infoline( "Test Stop action" );
     DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::STOP, attributes );
 
     tet_infoline( "Test Stop action" );
     DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::STOP, attributes );
@@ -297,7 +314,9 @@ int UtcDaliAnimatedVectorImageVisualPlayback(void)
     application.SendNotification();
     application.Render(16);
 
     application.SendNotification();
     application.Render(16);
 
-    // test
+    map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
+    value = map.Find( DevelImageVisual::Property::PLAY_STATE );
+    DALI_TEST_CHECK( value->Get< int >() == static_cast< int >( DevelImageVisual::PlayState::STOPPED ) );
 
     tet_infoline( "Test Stop action again" );
     DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::STOP, attributes );
 
     tet_infoline( "Test Stop action again" );
     DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::STOP, attributes );
@@ -305,7 +324,9 @@ int UtcDaliAnimatedVectorImageVisualPlayback(void)
     application.SendNotification();
     application.Render(16);
 
     application.SendNotification();
     application.Render(16);
 
-    // test
+    map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
+    value = map.Find( DevelImageVisual::Property::PLAY_STATE );
+    DALI_TEST_CHECK( value->Get< int >() == static_cast< int >( DevelImageVisual::PlayState::STOPPED ) );
 
     tet_infoline( "Test Play action" );
     DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
 
     tet_infoline( "Test Play action" );
     DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
@@ -313,15 +334,20 @@ int UtcDaliAnimatedVectorImageVisualPlayback(void)
     application.SendNotification();
     application.Render(16);
 
     application.SendNotification();
     application.Render(16);
 
-    // test
+    map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
+    value = map.Find( DevelImageVisual::Property::PLAY_STATE );
+    DALI_TEST_CHECK( value->Get< int >() == static_cast< int >( DevelImageVisual::PlayState::PLAYING ) );
 
 
-    dummyControl.SetSize( 100.0f, 100.0f );
+    // Change Size
+    Vector3 newSize( 100.0f, 100.0f, 0.0f );
+    dummyControl.SetSize( newSize );
 
     application.SendNotification();
     application.Render(16);
 
 
     application.SendNotification();
     application.Render(16);
 
-    // test
     // Size should be changed
     // Size should be changed
+    Vector3 naturalSize = dummyControl.GetNaturalSize();
+    DALI_TEST_CHECK( naturalSize == newSize );
 
     dummyControl.Unparent();
   }
 
     dummyControl.Unparent();
   }
@@ -439,7 +465,8 @@ int UtcDaliAnimatedVectorImageVisualLoopCount(void)
   application.SendNotification();
   application.Render();
 
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  // Trigger count is 2 - resource ready and animation finished
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 2 ), true, TEST_LOCATION );
 
   // renderer is added to actor
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
 
   // renderer is added to actor
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
@@ -488,3 +515,45 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
 
   END_TEST;
 }
 
   END_TEST;
 }
+
+int UtcDaliAnimatedVectorImageVisualAnimationFinishedSignal(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliAnimatedVectorImageVisualAnimationFinishedSignal" );
+
+  Property::Map propertyMap;
+  propertyMap.Add( Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE )
+             .Add( ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME  )
+             .Add( DevelImageVisual::Property::LOOP_COUNT, 3  );
+
+  Visual::Base visual = VisualFactory::Get().CreateVisual( propertyMap );
+  DALI_TEST_CHECK( visual );
+
+  DummyControl actor = DummyControl::New( true );
+  DummyControlImpl& dummyImpl = static_cast< DummyControlImpl& >( actor.GetImplementation() );
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+
+  DevelControl::VisualEventSignal( actor ).Connect( &VisualEventSignal );
+
+  Vector2 controlSize( 20.f, 30.f );
+  actor.SetSize( controlSize );
+
+  Stage::GetCurrent().Add( actor );
+
+  Property::Map attributes;
+  DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
+
+  application.SendNotification();
+  application.Render();
+
+  // Wait for animation finish
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 2 ), true, TEST_LOCATION );
+
+  Property::Map map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
+  Property::Value* value = map.Find( DevelImageVisual::Property::PLAY_STATE );
+  DALI_TEST_CHECK( value->Get< int >() == static_cast< int >( DevelImageVisual::PlayState::STOPPED ) );
+
+  DALI_TEST_EQUALS( gAnimationFinishedSignalFired, true, TEST_LOCATION );
+
+  END_TEST;
+}
index 98ff461..29370b7 100644 (file)
@@ -836,7 +836,8 @@ int UtcDaliImageViewSetImageOnstageN(void)
   DALI_TEST_CHECK( !value.Get( url ) );
 
   Property::Map map;
   DALI_TEST_CHECK( !value.Get( url ) );
 
   Property::Map map;
-  DALI_TEST_CHECK( !value.Get( map ) );
+  value.Get( map );
+  DALI_TEST_CHECK( map.Empty() );
 
   END_TEST;
 }
 
   END_TEST;
 }
@@ -931,7 +932,8 @@ int UtcDaliImageViewSetImageOffstageN(void)
   DALI_TEST_CHECK( !value.Get( url ) );
 
   Property::Map map;
   DALI_TEST_CHECK( !value.Get( url ) );
 
   Property::Map map;
-  DALI_TEST_CHECK( !value.Get( map ) );
+  value.Get( map );
+  DALI_TEST_CHECK( map.Empty() );
 
   END_TEST;
 }
 
   END_TEST;
 }
@@ -951,7 +953,8 @@ int UtcDaliImageViewSetImageN(void)
   DALI_TEST_CHECK( !value.Get( url ) );
 
   Property::Map map;
   DALI_TEST_CHECK( !value.Get( url ) );
 
   Property::Map map;
-  DALI_TEST_CHECK( !value.Get( map ) );
+  value.Get( map );
+  DALI_TEST_CHECK( map.Empty() );
 
   std::string resource_url;
   Property::Value val = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) );
 
   std::string resource_url;
   Property::Value val = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) );
@@ -980,7 +983,8 @@ int UtcDaliImageViewSetImageTypeChangesP(void)
   application.Render( 16 );
 
   DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty
   application.Render( 16 );
 
   DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty
-  DALI_TEST_CHECK( ! value.Get( map ) ); // Value should be empty
+  value.Get( map );
+  DALI_TEST_CHECK( map.Empty() );        // Value should be empty
   DALI_TEST_CHECK( ! visual );           // Visual should be invalid
 
   // Set a URL
   DALI_TEST_CHECK( ! visual );           // Visual should be invalid
 
   // Set a URL
@@ -1006,7 +1010,8 @@ int UtcDaliImageViewSetImageTypeChangesP(void)
   visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE );
 
   DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty
   visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE );
 
   DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty
-  DALI_TEST_CHECK( ! value.Get( map ) ); // Value should be empty
+  value.Get( map );
+  DALI_TEST_CHECK( map.Empty() );        // Value should be empty
   DALI_TEST_CHECK( ! visual );           // Visual should be invalid
 
   // Set an Image
   DALI_TEST_CHECK( ! visual );           // Visual should be invalid
 
   // Set an Image
@@ -1033,7 +1038,8 @@ int UtcDaliImageViewSetImageTypeChangesP(void)
   visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE );
 
   DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty
   visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE );
 
   DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty
-  DALI_TEST_CHECK( ! value.Get( map ) ); // Value should be empty
+  value.Get( map );
+  DALI_TEST_CHECK( map.Empty() );        // Value should be empty
   DALI_TEST_CHECK( ! visual );           // Visual should be invalid
 
   // Set a URL in property map
   DALI_TEST_CHECK( ! visual );           // Visual should be invalid
 
   // Set a URL in property map
index c17b944..01548d1 100755 (executable)
@@ -166,6 +166,13 @@ bool IsLayoutingRequired( Control control )
   return controlDataImpl.IsLayoutingRequired();
 }
 
   return controlDataImpl.IsLayoutingRequired();
 }
 
+VisualEventSignalType& VisualEventSignal( Control control )
+{
+  Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
+  Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( internalControl );
+  return controlDataImpl.VisualEventSignal();
+}
+
 } // namespace DevelControl
 
 } // namespace Toolkit
 } // namespace DevelControl
 
 } // namespace Toolkit
index 404a9ec..dad426f 100755 (executable)
@@ -270,14 +270,14 @@ DALI_TOOLKIT_API void DoAction( Control& control, Dali::Property::Index visualIn
  */
 DALI_TOOLKIT_API void SetInputMethodContext( Internal::Control& control, InputMethodContext& inputMethodContext );
 
  */
 DALI_TOOLKIT_API void SetInputMethodContext( Internal::Control& control, InputMethodContext& inputMethodContext );
 
-/*
+/**
  * @brief Get the layout associated with this control, if any.
  *
  * @return A handle to the layout, or empty.
  */
 DALI_TOOLKIT_API Toolkit::LayoutItem GetLayout( Internal::Control& control );
 
  * @brief Get the layout associated with this control, if any.
  *
  * @return A handle to the layout, or empty.
  */
 DALI_TOOLKIT_API Toolkit::LayoutItem GetLayout( Internal::Control& control );
 
-/*
+/**
  * @brief Get the layout associated with a control, if any.
  *
  * @return A handle to the layout, or empty.
  * @brief Get the layout associated with a control, if any.
  *
  * @return A handle to the layout, or empty.
@@ -328,6 +328,22 @@ DALI_TOOLKIT_API void SetLayoutingRequired( Control control, bool layoutingRequi
  */
 DALI_TOOLKIT_API bool IsLayoutingRequired( Control control );
 
  */
 DALI_TOOLKIT_API bool IsLayoutingRequired( Control control );
 
+/**
+ * @brief Visual Event signal type
+ */
+using VisualEventSignalType = Signal< void ( Control, Dali::Property::Index, Dali::Property::Index ) >;
+
+/**
+ * @brief This signal is emitted when a visual has an event to notify.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ *   void YourCallbackName( Control control, Dali::Property::Index visualIndex, Dali::Property::Index signalId );
+ * @endcode
+ * @return The signal to connect to
+ */
+DALI_TOOLKIT_API VisualEventSignalType& VisualEventSignal( Control control );
+
 } // namespace DevelControl
 
 } // namespace Toolkit
 } // namespace DevelControl
 
 } // namespace Toolkit
index ebb9631..9fe075e 100755 (executable)
@@ -132,6 +132,7 @@ devel_api_visuals_header_files = \
   $(devel_api_src_dir)/visuals/animated-gradient-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/animated-image-visual-actions-devel.h \
   $(devel_api_src_dir)/visuals/animated-vector-image-visual-actions-devel.h \
   $(devel_api_src_dir)/visuals/animated-gradient-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/animated-image-visual-actions-devel.h \
   $(devel_api_src_dir)/visuals/animated-vector-image-visual-actions-devel.h \
+  $(devel_api_src_dir)/visuals/animated-vector-image-visual-signals-devel.h \
   $(devel_api_src_dir)/visuals/color-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/image-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/image-visual-actions-devel.h \
   $(devel_api_src_dir)/visuals/color-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/image-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/image-visual-actions-devel.h \
index 6e40c69..1f05bd7 100644 (file)
@@ -39,7 +39,6 @@ enum Type
 {
   PLAY,        ///< Play the animated vector image.
   PAUSE,       ///< Pause the animated vector image.
 {
   PLAY,        ///< Play the animated vector image.
   PAUSE,       ///< Pause the animated vector image.
-  RESUME,      ///< Resume the animated vector image.
   STOP         ///< Stop the animated vector image. This is also Default playback mode.
 };
 
   STOP         ///< Stop the animated vector image. This is also Default playback mode.
 };
 
diff --git a/dali-toolkit/devel-api/visuals/animated-vector-image-visual-signals-devel.h b/dali-toolkit/devel-api/visuals/animated-vector-image-visual-signals-devel.h
new file mode 100644 (file)
index 0000000..3ab14e1
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef DALI_TOOLKIT_DEVEL_API_VISUALS_ANIMATED_VECTOR_IMAGE_VISUAL_SIGNALS_DEVEL_H
+#define DALI_TOOLKIT_DEVEL_API_VISUALS_ANIMATED_VECTOR_IMAGE_VISUAL_SIGNALS_DEVEL_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace DevelAnimatedVectorImageVisual
+{
+
+/**
+ * @brief Signal that the animated vector image visual can emit.
+ */
+namespace Signal
+{
+/**
+ * @brief The available signals for this visual
+ */
+enum Type
+{
+  ANIMATION_FINISHED      ///< Animation has finished.
+};
+
+} // namespace Signal
+
+} // namespace DevelAnimatedVectorImageVisual
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_DEVEL_API_VISUALS_ANIMATED_VECTOR_IMAGE_VISUAL_SIGNALS_DEVEL_H
index eb39aa6..2ae2726 100644 (file)
@@ -92,12 +92,29 @@ enum Type
    * @details Name "playRange", Type Property::VECTOR2, between 0 and 1
    * @note Default 0 and 1
    */
    * @details Name "playRange", Type Property::VECTOR2, between 0 and 1
    * @note Default 0 and 1
    */
-  PLAY_RANGE = ORIENTATION_CORRECTION + 4
+  PLAY_RANGE = ORIENTATION_CORRECTION + 4,
+
+  /**
+   * @brief The playing state the AnimatedVectorImageVisual will use.
+   * @details Name "playState", type PlayState (Property::INTEGER)
+   * @note This property is read-only.
+   */
+  PLAY_STATE = ORIENTATION_CORRECTION + 5
 
 };
 
 } //namespace Property
 
 
 };
 
 } //namespace Property
 
+/**
+ * @brief Enumeration for what state the animation is in.
+ */
+enum class PlayState
+{
+  STOPPED,   ///< Animation has stopped
+  PLAYING,   ///< The animation is playing
+  PAUSED     ///< The animation is paused
+};
+
 } // namespace DevelImageVisual
 
 } // namespace Toolkit
 } // namespace DevelImageVisual
 
 } // namespace Toolkit
index 5e94e8f..0367037 100755 (executable)
@@ -334,6 +334,7 @@ Control::Impl::Impl( Control& controlImpl )
   mKeyInputFocusGainedSignal(),
   mKeyInputFocusLostSignal(),
   mResourceReadySignal(),
   mKeyInputFocusGainedSignal(),
   mKeyInputFocusLostSignal(),
   mResourceReadySignal(),
+  mVisualEventSignal(),
   mPinchGestureDetector(),
   mPanGestureDetector(),
   mTapGestureDetector(),
   mPinchGestureDetector(),
   mPanGestureDetector(),
   mTapGestureDetector(),
@@ -626,15 +627,15 @@ void Control::Impl::StopObservingVisual( Toolkit::Visual::Base& visual )
   Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
 
   // Stop observing the visual
   Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
 
   // Stop observing the visual
-  visualImpl.RemoveResourceObserver( *this );
+  visualImpl.RemoveEventObserver( *this );
 }
 
 void Control::Impl::StartObservingVisual( Toolkit::Visual::Base& visual)
 {
   Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
 
 }
 
 void Control::Impl::StartObservingVisual( Toolkit::Visual::Base& visual)
 {
   Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
 
-  // start observing the visual for resource ready
-  visualImpl.AddResourceObserver( *this );
+  // start observing the visual for events
+  visualImpl.AddEventObserver( *this );
 }
 
 // Called by a Visual when it's resource is ready
 }
 
 // Called by a Visual when it's resource is ready
@@ -680,6 +681,20 @@ void Control::Impl::ResourceReady( Visual::Base& object)
   }
 }
 
   }
 }
 
+void Control::Impl::NotifyVisualEvent( Visual::Base& object, Property::Index signalId )
+{
+  for( auto registeredIter = mVisuals.Begin(),  end = mVisuals.End(); registeredIter != end; ++registeredIter )
+  {
+    Internal::Visual::Base& registeredVisualImpl = Toolkit::GetImplementation( (*registeredIter)->visual );
+    if( &object == &registeredVisualImpl )
+    {
+      Dali::Toolkit::Control handle( mControlImpl.GetOwner() );
+      mVisualEventSignal.Emit( handle, (*registeredIter)->index, signalId );
+      break;
+    }
+  }
+}
+
 bool Control::Impl::IsResourceReady() const
 {
   // Iterate through and check all the enabled visuals are ready
 bool Control::Impl::IsResourceReady() const
 {
   // Iterate through and check all the enabled visuals are ready
@@ -1489,6 +1504,11 @@ bool Control::Impl::IsLayoutingRequired()
   return mControlImpl.mImpl->mIsLayoutingRequired;
 }
 
   return mControlImpl.mImpl->mIsLayoutingRequired;
 }
 
+DevelControl::VisualEventSignalType& Control::Impl::VisualEventSignal()
+{
+  return mVisualEventSignal;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
 } // namespace Internal
 
 } // namespace Toolkit
index 1afa0a2..634e7f6 100755 (executable)
@@ -24,7 +24,7 @@
 #include <string>
 
 // INTERNAL INCLUDES
 #include <string>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/internal/visuals/visual-resource-observer.h>
+#include <dali-toolkit/internal/visuals/visual-event-observer.h>
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali/devel-api/common/owner-container.h>
 #include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali/devel-api/common/owner-container.h>
 #include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
@@ -65,7 +65,7 @@ typedef Dali::OwnerContainer< RegisteredVisual* > RegisteredVisualContainer;
 /**
  * @brief Holds the Implementation for the internal control class
  */
 /**
  * @brief Holds the Implementation for the internal control class
  */
-class Control::Impl : public ConnectionTracker, public Visual::ResourceObserver
+class Control::Impl : public ConnectionTracker, public Visual::EventObserver
 {
 
 public:
 {
 
 public:
@@ -124,9 +124,17 @@ public:
   /**
    * @brief Called when a resource is ready.
    * @param[in] object The visual whose resources are ready
   /**
    * @brief Called when a resource is ready.
    * @param[in] object The visual whose resources are ready
-   * @note Overriding method in Visual::ResourceObserver.
+   * @note Overriding method in Visual::EventObserver.
    */
    */
-  virtual void ResourceReady( Visual::Base& object );
+  virtual void ResourceReady( Visual::Base& object ) override;
+
+  /**
+   * @brief Called when an event occurs.
+   * @param[in] object The visual whose events occur
+   * @param[in] signalId The signal to emit. See Visual to find supported signals
+   * @note Overriding method in Visual::EventObserver.
+   */
+  virtual void NotifyVisualEvent( Visual::Base& object, Property::Index signalId ) override;
 
   /**
    * @copydoc Dali::Toolkit::DevelControl::RegisterVisual()
 
   /**
    * @copydoc Dali::Toolkit::DevelControl::RegisterVisual()
@@ -355,6 +363,11 @@ public:
    */
   bool IsLayoutingRequired();
 
    */
   bool IsLayoutingRequired();
 
+  /**
+   * @copydoc DevelControl::VisualEventSignal()
+   */
+  DevelControl::VisualEventSignalType& VisualEventSignal();
+
 private:
 
   /**
 private:
 
   /**
@@ -418,6 +431,7 @@ public:
   Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusGainedSignal;
   Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusLostSignal;
   Toolkit::Control::ResourceReadySignalType mResourceReadySignal;
   Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusGainedSignal;
   Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusLostSignal;
   Toolkit::Control::ResourceReadySignalType mResourceReadySignal;
+  DevelControl::VisualEventSignalType mVisualEventSignal;
 
   // Gesture Detection
   PinchGestureDetector mPinchGestureDetector;
 
   // Gesture Detection
   PinchGestureDetector mPinchGestureDetector;
index 890312c..96b1b78 100755 (executable)
@@ -463,9 +463,15 @@ Property::Value ImageView::GetProperty( BaseObject* object, Property::Index prop
           Scripting::CreatePropertyMap( impl.mImage, map );
           value = map;
         }
           Scripting::CreatePropertyMap( impl.mImage, map );
           value = map;
         }
-        else if( !impl.mPropertyMap.Empty() )
+        else
         {
         {
-          value = impl.mPropertyMap;
+          Property::Map map;
+          Toolkit::Visual::Base visual = DevelControl::GetVisual( impl, Toolkit::ImageView::Property::IMAGE );
+          if( visual )
+          {
+            visual.CreatePropertyMap( map );
+          }
+          value = map;
         }
         break;
       }
         }
         break;
       }
index 96c7ddd..f4a733b 100644 (file)
@@ -27,6 +27,7 @@
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-signals-devel.h>
 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
@@ -99,6 +100,15 @@ void AnimatedVectorImageVisual::DoCreatePropertyMap( Property::Map& map ) const
   }
   map.Insert( Toolkit::DevelImageVisual::Property::LOOP_COUNT, static_cast< int >( mLoopCount ) );
   map.Insert( Toolkit::DevelImageVisual::Property::PLAY_RANGE, static_cast< Vector2 >( mPlayRange ) );
   }
   map.Insert( Toolkit::DevelImageVisual::Property::LOOP_COUNT, static_cast< int >( mLoopCount ) );
   map.Insert( Toolkit::DevelImageVisual::Property::PLAY_RANGE, static_cast< Vector2 >( mPlayRange ) );
+
+  if( mVectorRasterizeThread )
+  {
+    map.Insert( Toolkit::DevelImageVisual::Property::PLAY_STATE, static_cast< int >( mVectorRasterizeThread->GetPlayState() ) );
+  }
+  else
+  {
+    map.Insert( Toolkit::DevelImageVisual::Property::PLAY_STATE, static_cast< int >( DevelImageVisual::PlayState::STOPPED ) );
+  }
 }
 
 void AnimatedVectorImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
 }
 
 void AnimatedVectorImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
@@ -250,6 +260,7 @@ void AnimatedVectorImageVisual::OnSetTransform()
         mVectorRasterizeThread = std::unique_ptr< VectorRasterizeThread >( new VectorRasterizeThread( mUrl.GetUrl(), mImpl->mRenderer, width, height ) );
 
         mVectorRasterizeThread->SetResourceReadyCallback( new EventThreadCallback( MakeCallback( this, &AnimatedVectorImageVisual::OnResourceReady ) ) );
         mVectorRasterizeThread = std::unique_ptr< VectorRasterizeThread >( new VectorRasterizeThread( mUrl.GetUrl(), mImpl->mRenderer, width, height ) );
 
         mVectorRasterizeThread->SetResourceReadyCallback( new EventThreadCallback( MakeCallback( this, &AnimatedVectorImageVisual::OnResourceReady ) ) );
+        mVectorRasterizeThread->SetAnimationFinishedCallback( new EventThreadCallback( MakeCallback( this, &AnimatedVectorImageVisual::OnAnimationFinished ) ) );
         mVectorRasterizeThread->SetLoopCount( mLoopCount );
         mVectorRasterizeThread->SetPlayRange( mPlayRange );
 
         mVectorRasterizeThread->SetLoopCount( mLoopCount );
         mVectorRasterizeThread->SetPlayRange( mPlayRange );
 
@@ -279,11 +290,6 @@ void AnimatedVectorImageVisual::OnSetTransform()
 
 void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, const Property::Value& attributes )
 {
 
 void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, const Property::Value& attributes )
 {
-  if( actionId == mActionStatus )
-  {
-    return;
-  }
-
   // Check if action is valid for this visual type and perform action if possible
   switch( actionId )
   {
   // Check if action is valid for this visual type and perform action if possible
   switch( actionId )
   {
@@ -310,22 +316,23 @@ void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, cons
       mActionStatus = DevelAnimatedVectorImageVisual::Action::PAUSE;
       break;
     }
       mActionStatus = DevelAnimatedVectorImageVisual::Action::PAUSE;
       break;
     }
-    case DevelAnimatedVectorImageVisual::Action::RESUME:
-    {
-      if( mVectorRasterizeThread )
-      {
-        mVectorRasterizeThread->ResumeAnimation();
-        DevelStage::SetRenderingBehavior( Stage::GetCurrent(), DevelStage::Rendering::CONTINUOUSLY );
-      }
-      mActionStatus = DevelAnimatedVectorImageVisual::Action::RESUME;
-      break;
-    }
     case DevelAnimatedVectorImageVisual::Action::STOP:
     {
       if( mVectorRasterizeThread )
       {
     case DevelAnimatedVectorImageVisual::Action::STOP:
     {
       if( mVectorRasterizeThread )
       {
+        bool emitSignal = false;
+        if( mVectorRasterizeThread->GetPlayState() != DevelImageVisual::PlayState::STOPPED )
+        {
+          emitSignal = true;
+        }
+
         mVectorRasterizeThread->StopAnimation();
         DevelStage::SetRenderingBehavior( Stage::GetCurrent(), DevelStage::Rendering::IF_REQUIRED );
         mVectorRasterizeThread->StopAnimation();
         DevelStage::SetRenderingBehavior( Stage::GetCurrent(), DevelStage::Rendering::IF_REQUIRED );
+
+        if( emitSignal )
+        {
+          OnAnimationFinished();
+        }
       }
       mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
       break;
       }
       mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
       break;
@@ -347,6 +354,14 @@ void AnimatedVectorImageVisual::OnResourceReady()
   }
 }
 
   }
 }
 
+void AnimatedVectorImageVisual::OnAnimationFinished()
+{
+  if( mImpl->mEventObserver )
+  {
+    mImpl->mEventObserver->NotifyVisualEvent( *this, DevelAnimatedVectorImageVisual::Signal::ANIMATION_FINISHED );
+  }
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
 } // namespace Internal
 
 } // namespace Toolkit
index 268cb06..28d79a4 100644 (file)
@@ -150,6 +150,11 @@ private:
    */
   void OnResourceReady();
 
    */
   void OnResourceReady();
 
+  /**
+   * @brief Event callback from rasterize thread. This is called after the animation is finished.
+   */
+  void OnAnimationFinished();
+
   // Undefined
   AnimatedVectorImageVisual( const AnimatedVectorImageVisual& visual ) = delete;
 
   // Undefined
   AnimatedVectorImageVisual( const AnimatedVectorImageVisual& visual ) = delete;
 
index 52c6541..536c208 100644 (file)
@@ -50,8 +50,10 @@ VectorRasterizeThread::VectorRasterizeThread( const std::string& url, Renderer r
   mVectorRenderer(),
   mConditionalWait(),
   mMutex(),
   mVectorRenderer(),
   mConditionalWait(),
   mMutex(),
-  mResourceReadyTrigger( NULL ),
+  mResourceReadyTrigger(),
+  mAnimationFinishedTrigger(),
   mPlayRange( 0.0f, 1.0f ),
   mPlayRange( 0.0f, 1.0f ),
+  mPlayState( DevelImageVisual::PlayState::STOPPED ),
   mCurrentFrame( 0 ),
   mTotalFrame( 0 ),
   mStartFrame( 0 ),
   mCurrentFrame( 0 ),
   mTotalFrame( 0 ),
   mStartFrame( 0 ),
@@ -61,8 +63,6 @@ VectorRasterizeThread::VectorRasterizeThread( const std::string& url, Renderer r
   mLoopCount( LOOP_FOREVER ),
   mCurrentLoop( 0 ),
   mNeedRender( false ),
   mLoopCount( LOOP_FOREVER ),
   mCurrentLoop( 0 ),
   mNeedRender( false ),
-  mPlaying( false ),
-  mPaused( false ),
   mDestroyThread( false ),
   mResourceReady( false ),
   mLogFactory( Dali::Adaptor::Get().GetLogFactory() )
   mDestroyThread( false ),
   mResourceReady( false ),
   mLogFactory( Dali::Adaptor::Get().GetLogFactory() )
@@ -85,8 +85,6 @@ VectorRasterizeThread::~VectorRasterizeThread()
   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::~VectorRasterizeThread: Join\n" );
 
   Join();
   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::~VectorRasterizeThread: Join\n" );
 
   Join();
-
-  delete mResourceReadyTrigger;
 }
 
 void VectorRasterizeThread::Run()
 }
 
 void VectorRasterizeThread::Run()
@@ -114,10 +112,16 @@ void VectorRasterizeThread::SetSize( uint32_t width, uint32_t height )
 void VectorRasterizeThread::StartAnimation()
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
 void VectorRasterizeThread::StartAnimation()
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
-  if( !mPlaying )
+  if( mPlayState != DevelImageVisual::PlayState::PLAYING )
   {
   {
-    mPlaying = true;
-    mPaused = false;
+    if( mPlayState == DevelImageVisual::PlayState::STOPPED )
+    {
+      // Reset the current frame and the current loop
+      mCurrentFrame = mStartFrame;
+      mCurrentLoop = 0;
+    }
+
+    mPlayState = DevelImageVisual::PlayState::PLAYING;
     mConditionalWait.Notify( lock );
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartAnimation: Start\n" );
     mConditionalWait.Notify( lock );
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartAnimation: Start\n" );
@@ -127,10 +131,9 @@ void VectorRasterizeThread::StartAnimation()
 void VectorRasterizeThread::StopAnimation()
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
 void VectorRasterizeThread::StopAnimation()
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
-  if( mPlaying )
+  if( mPlayState != DevelImageVisual::PlayState::STOPPED )
   {
   {
-    mPlaying = false;
-    mPaused = false;
+    mPlayState = DevelImageVisual::PlayState::STOPPED;
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StopAnimation: Stop\n" );
   }
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StopAnimation: Stop\n" );
   }
@@ -139,26 +142,14 @@ void VectorRasterizeThread::StopAnimation()
 void VectorRasterizeThread::PauseAnimation()
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
 void VectorRasterizeThread::PauseAnimation()
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
-  if( mPlaying && !mPaused )
+  if( mPlayState == DevelImageVisual::PlayState::PLAYING )
   {
   {
-    mPaused = true;
+    mPlayState = DevelImageVisual::PlayState::PAUSED;
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::PauseAnimation: Pause\n" );
   }
 }
 
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::PauseAnimation: Pause\n" );
   }
 }
 
-void VectorRasterizeThread::ResumeAnimation()
-{
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-  if( mPlaying && mPaused )
-  {
-    mPaused = false;
-    mConditionalWait.Notify( lock );
-
-    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::ResumeAnimation: Resume\n" );
-  }
-}
-
 void VectorRasterizeThread::RenderFrame()
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
 void VectorRasterizeThread::RenderFrame()
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
@@ -171,7 +162,13 @@ void VectorRasterizeThread::RenderFrame()
 void VectorRasterizeThread::SetResourceReadyCallback( EventThreadCallback* callback )
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
 void VectorRasterizeThread::SetResourceReadyCallback( EventThreadCallback* callback )
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
-  mResourceReadyTrigger = callback;
+  mResourceReadyTrigger = std::unique_ptr< EventThreadCallback >( callback );
+}
+
+void VectorRasterizeThread::SetAnimationFinishedCallback( EventThreadCallback* callback )
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+  mAnimationFinishedTrigger = std::unique_ptr< EventThreadCallback >( callback );
 }
 
 void VectorRasterizeThread::SetLoopCount( int16_t count )
 }
 
 void VectorRasterizeThread::SetLoopCount( int16_t count )
@@ -198,20 +195,19 @@ void VectorRasterizeThread::SetPlayRange( Vector2 range )
   }
 }
 
   }
 }
 
+DevelImageVisual::PlayState VectorRasterizeThread::GetPlayState()
+{
+  return mPlayState;
+}
+
 bool VectorRasterizeThread::IsThreadReady()
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
 
 bool VectorRasterizeThread::IsThreadReady()
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
 
-  if( ( !mPlaying || mPaused ) && !mNeedRender && !mDestroyThread )
+  if( mPlayState != DevelImageVisual::PlayState::PLAYING && !mNeedRender && !mDestroyThread )
   {
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::IsThreadReady: Wait\n" );
 
   {
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::IsThreadReady: Wait\n" );
 
-    if( !mPlaying )
-    {
-      mCurrentFrame = mStartFrame;
-      mCurrentLoop = 0;
-    }
-
     mConditionalWait.Wait( lock );
   }
 
     mConditionalWait.Wait( lock );
   }
 
@@ -243,7 +239,7 @@ void VectorRasterizeThread::Rasterize()
   // Rasterize
   mVectorRenderer.Render( mCurrentFrame );
 
   // Rasterize
   mVectorRenderer.Render( mCurrentFrame );
 
-  if( mPlaying && !mPaused )
+  if( mPlayState == DevelImageVisual::PlayState::PLAYING )
   {
     if( ++mCurrentFrame >= mEndFrame )
     {
   {
     if( ++mCurrentFrame >= mEndFrame )
     {
@@ -258,7 +254,11 @@ void VectorRasterizeThread::Rasterize()
         if( mCurrentLoop >= mLoopCount )
         {
           // Animation is finished
         if( mCurrentLoop >= mLoopCount )
         {
           // Animation is finished
-          mPlaying = false;
+          mPlayState = DevelImageVisual::PlayState::STOPPED;
+
+          mAnimationFinishedTrigger->Trigger();
+
+          DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Animation is finished\n" );
         }
         else
         {
         }
         else
         {
index f05f8b6..8ee52be 100644 (file)
 #include <dali/devel-api/threading/thread.h>
 #include <dali/integration-api/adaptors/log-factory-interface.h>
 #include <string>
 #include <dali/devel-api/threading/thread.h>
 #include <dali/integration-api/adaptors/log-factory-interface.h>
 #include <string>
+#include <memory>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -81,11 +85,6 @@ public:
   void PauseAnimation();
 
   /**
   void PauseAnimation();
 
   /**
-   * @brief Resume the vector animation.
-   */
-  void ResumeAnimation();
-
-  /**
    * @brief Render one frame. The current frame number will be increased.
    */
   void RenderFrame();
    * @brief Render one frame. The current frame number will be increased.
    */
   void RenderFrame();
@@ -97,6 +96,12 @@ public:
   void SetResourceReadyCallback( EventThreadCallback* callback );
 
   /**
   void SetResourceReadyCallback( EventThreadCallback* callback );
 
   /**
+   * @brief This callback is called after the animation is finished.
+   * @param[in] callback The animation finished callback
+   */
+  void SetAnimationFinishedCallback( EventThreadCallback* callback );
+
+  /**
    * @brief Enable looping for 'count' repeats. -1 means to repeat forever.
    * @param[in] count The number of times to loop
    */
    * @brief Enable looping for 'count' repeats. -1 means to repeat forever.
    * @param[in] count The number of times to loop
    */
@@ -109,6 +114,12 @@ public:
    */
   void SetPlayRange( Vector2 range );
 
    */
   void SetPlayRange( Vector2 range );
 
+  /**
+   * @brief Get the play state
+   * @return The play state
+   */
+  DevelImageVisual::PlayState GetPlayState();
+
 protected:
 
   /**
 protected:
 
   /**
@@ -143,25 +154,25 @@ private:
 
 private:
 
 
 private:
 
-  std::string                mUrl;
-  VectorAnimationRenderer    mVectorRenderer;
-  ConditionalWait            mConditionalWait;
-  Dali::Mutex                mMutex;
-  EventThreadCallback*       mResourceReadyTrigger;
-  Vector2                    mPlayRange;
-  uint32_t                   mCurrentFrame;
-  uint32_t                   mTotalFrame;
-  uint32_t                   mStartFrame;
-  uint32_t                   mEndFrame;
-  uint32_t                   mWidth;
-  uint32_t                   mHeight;
-  int16_t                    mLoopCount;
-  int16_t                    mCurrentLoop;
-  bool                       mNeedRender;
-  bool                       mPlaying;
-  bool                       mPaused;
-  bool                       mDestroyThread;  ///< Whether the thread be destroyed
-  bool                       mResourceReady;
+  std::string                 mUrl;
+  VectorAnimationRenderer     mVectorRenderer;
+  ConditionalWait             mConditionalWait;
+  Dali::Mutex                 mMutex;
+  std::unique_ptr< EventThreadCallback > mResourceReadyTrigger;
+  std::unique_ptr< EventThreadCallback > mAnimationFinishedTrigger;
+  Vector2                     mPlayRange;
+  DevelImageVisual::PlayState mPlayState;
+  uint32_t                    mCurrentFrame;
+  uint32_t                    mTotalFrame;
+  uint32_t                    mStartFrame;
+  uint32_t                    mEndFrame;
+  uint32_t                    mWidth;
+  uint32_t                    mHeight;
+  int16_t                     mLoopCount;
+  int16_t                     mCurrentLoop;
+  bool                        mNeedRender;
+  bool                        mDestroyThread;  ///< Whether the thread be destroyed
+  bool                        mResourceReady;
   const Dali::LogFactoryInterface& mLogFactory; ///< The log factory
 
 };
   const Dali::LogFactoryInterface& mLogFactory; ///< The log factory
 
 };
index 0e7f396..3702aa3 100644 (file)
@@ -117,7 +117,7 @@ bool GetPolicyFromValue( const Property::Value& value, Vector2& policy )
 Internal::Visual::Base::Impl::Impl(FittingMode fittingMode)
 : mCustomShader( NULL ),
   mBlendSlotDelegate( NULL ),
 Internal::Visual::Base::Impl::Impl(FittingMode fittingMode)
 : mCustomShader( NULL ),
   mBlendSlotDelegate( NULL ),
-  mResourceObserver( NULL ),
+  mEventObserver( NULL ),
   mTransform(),
   mMixColor( Color::WHITE ),
   mControlSize( Vector2::ZERO ),
   mTransform(),
   mMixColor( Color::WHITE ),
   mControlSize( Vector2::ZERO ),
index 1f59ec0..4adcc5a 100644 (file)
@@ -24,7 +24,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
-#include <dali-toolkit/internal/visuals/visual-resource-observer.h>
+#include <dali-toolkit/internal/visuals/visual-event-observer.h>
 #include <dali-toolkit/public-api/align-enumerations.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/public-api/align-enumerations.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
@@ -119,7 +119,7 @@ struct Base::Impl
   Renderer        mRenderer;
   CustomShader*   mCustomShader;
   SlotDelegate<Visual::Base>* mBlendSlotDelegate; ///< Used to own mix color animation connection
   Renderer        mRenderer;
   CustomShader*   mCustomShader;
   SlotDelegate<Visual::Base>* mBlendSlotDelegate; ///< Used to own mix color animation connection
-  ResourceObserver* mResourceObserver;  ///< Allows controls to observe when the visual resources are loaded and ready
+  EventObserver*  mEventObserver;  ///< Allows controls to observe when the visual has events to notify
   std::string     mName;
   Transform       mTransform;
   Vector4         mMixColor;
   std::string     mName;
   Transform       mTransform;
   Vector4         mMixColor;
index 1ae6411..d14dcd3 100755 (executable)
@@ -435,14 +435,14 @@ const Vector4& Visual::Base::GetMixColor() const
   return mImpl->mMixColor;
 }
 
   return mImpl->mMixColor;
 }
 
-void Visual::Base::AddResourceObserver( Visual::ResourceObserver& observer)
+void Visual::Base::AddEventObserver( Visual::EventObserver& observer)
 {
 {
-  mImpl->mResourceObserver = &observer;
+  mImpl->mEventObserver = &observer;
 }
 
 }
 
-void Visual::Base::RemoveResourceObserver( Visual::ResourceObserver& observer )
+void Visual::Base::RemoveEventObserver( Visual::EventObserver& observer )
 {
 {
-  mImpl->mResourceObserver = NULL;
+  mImpl->mEventObserver = NULL;
 }
 
 void Visual::Base::ResourceReady(Toolkit::Visual::ResourceStatus resourceStatus)
 }
 
 void Visual::Base::ResourceReady(Toolkit::Visual::ResourceStatus resourceStatus)
@@ -451,10 +451,10 @@ void Visual::Base::ResourceReady(Toolkit::Visual::ResourceStatus resourceStatus)
   {
     mImpl->mResourceStatus = resourceStatus;
 
   {
     mImpl->mResourceStatus = resourceStatus;
 
-    if( mImpl->mResourceObserver )
+    if( mImpl->mEventObserver )
     {
       // observer is currently a control impl
     {
       // observer is currently a control impl
-      mImpl->mResourceObserver->ResourceReady( *this );
+      mImpl->mEventObserver->ResourceReady( *this );
     }
   }
 }
     }
   }
 }
index 02419d2..754c838 100644 (file)
@@ -47,7 +47,7 @@ namespace Internal
 namespace Visual
 {
 
 namespace Visual
 {
 
-class ResourceObserver;
+class EventObserver;
 
 using FittingMode = DevelVisual::FittingMode;
 
 
 using FittingMode = DevelVisual::FittingMode;
 
@@ -227,16 +227,15 @@ public:
                         Internal::TransitionData::Animator& animator );
 
   /**
                         Internal::TransitionData::Animator& animator );
 
   /**
-   * @brief Add an observer to watch for when the Visuals resources are loaded.
+   * @brief Add an observer to watch for when the Visuals have events to notify
    * Currently only supports a single observer
    * Currently only supports a single observer
-   *
    */
    */
-  void AddResourceObserver( Visual::ResourceObserver& observer );
+  void AddEventObserver( Visual::EventObserver& observer );
 
   /**
    * @brief Remove an observer
    */
 
   /**
    * @brief Remove an observer
    */
-  void RemoveResourceObserver( Visual::ResourceObserver& observer );
+  void RemoveEventObserver( Visual::EventObserver& observer );
 
   /**
    * @brief Called when the visuals resources are loaded / ready
 
   /**
    * @brief Called when the visuals resources are loaded / ready
diff --git a/dali-toolkit/internal/visuals/visual-event-observer.h b/dali-toolkit/internal/visuals/visual-event-observer.h
new file mode 100644 (file)
index 0000000..d816c34
--- /dev/null
@@ -0,0 +1,82 @@
+#ifndef DALI_INTERNAL_TOOLKIT_VISUAL_EVENT_OBSERVER_H
+#define DALI_INTERNAL_TOOLKIT_VISUAL_EVENT_OBSERVER_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/property-value.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+namespace Visual
+{
+
+class Base;
+
+/**
+ * Observer to be informed when visuals have events.
+ */
+class EventObserver
+{
+public:
+
+  /**
+   * Inform the observer of the object when a resource is ready.
+   * @param[in] object The connection owner
+   */
+  virtual void ResourceReady( Visual::Base& object ) = 0;
+
+  /**
+   * Inform the observer of the object when an event occurs.
+   * @param[in] object The connection owner
+   * @param[in] signalId The signal to emit. See Visual to find supported signals
+   */
+  virtual void NotifyVisualEvent( Visual::Base& object, Property::Index signalId ) = 0;
+
+protected:
+
+  /**
+   * constructor
+   */
+  EventObserver()
+  {
+  }
+
+  /**
+   * virtual destructor
+   */
+  virtual ~EventObserver()
+  {
+  }
+
+  // Undefined copy constructor.
+  EventObserver( const EventObserver& ) = delete;
+
+  // Undefined assignment operator.
+  EventObserver& operator=( const EventObserver& ) = delete;
+};
+
+} // Visual
+} // Internal
+} // Toolkit
+} // Dali
+
+#endif // DALI_INTERNAL_TOOLKIT_VISUAL_EVENT_OBSERVER_H
diff --git a/dali-toolkit/internal/visuals/visual-resource-observer.h b/dali-toolkit/internal/visuals/visual-resource-observer.h
deleted file mode 100644 (file)
index f671adc..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef DALI_INTERNAL_TOOLKIT_VISUAL_RESOURCE_OBSERVER_H
-#define DALI_INTERNAL_TOOLKIT_VISUAL_RESOURCE_OBSERVER_H
-
-/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-namespace Dali
-{
-namespace Toolkit
-{
-namespace Internal
-{
-namespace Visual
-{
-
-class Base;
-
-
-/**
- * Observer to be informed when a visuals resources are ready.
- */
-class ResourceObserver
-{
-  public:
-
-    /**
-     * Inform the observer of the object that it's connections have changed
-     * @param[in] object The connection owner
-     */
-    virtual void ResourceReady( Visual::Base& object) = 0;
-
-  protected:
-
-    /**
-     * constructor
-     */
-    ResourceObserver()
-    {
-    };
-
-    /**
-     * virtual destructor
-     */
-    virtual ~ResourceObserver()
-    {
-    };
-
-    // Undefined copy constructor.
-    ResourceObserver( const ResourceObserver& );
-
-    // Undefined assignment operator.
-    ResourceObserver& operator=( const ResourceObserver& );
-};
-} // Visual
-} // Internal
-} // Toolkit
-} // Dali
-
-#endif // DALI_INTERNAL_TOOLKIT_VISUAL_RESOURCE_OBSERVER_H