[dali_1.4.37] Merge branch 'devel/master' 41/213841/1
authorRichard Huang <r.huang@samsung.com>
Fri, 13 Sep 2019 12:20:30 +0000 (13:20 +0100)
committerRichard Huang <r.huang@samsung.com>
Fri, 13 Sep 2019 12:20:30 +0000 (13:20 +0100)
Change-Id: Ia69635a9ef1cd7184fb327e5b229ee00d7fc433b

14 files changed:
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-scene-holder.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window-impl.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.h
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.h
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index f3029fa..338b71f 100644 (file)
@@ -28,7 +28,8 @@ TestApplication::TestApplication( uint32_t surfaceWidth,
                                   uint32_t  verticalDpi,
                                   ResourcePolicy::DataRetention policy,
                                   bool initialize )
-: mCore( NULL ),
+: mRenderSurface( NULL ),
+  mCore( NULL ),
   mSurfaceWidth( surfaceWidth ),
   mSurfaceHeight( surfaceHeight ),
   mFrame( 0u ),
index 7aec884..bfc1315 100644 (file)
@@ -66,7 +66,7 @@ void SceneHolder::Add( Dali::Actor actor )
 
 void SceneHolder::Remove( Dali::Actor actor )
 {
-  mScene.Add( actor );
+  mScene.Remove( actor );
 }
 
 Dali::Layer SceneHolder::GetRootLayer() const
index 64b0a40..1615e62 100644 (file)
@@ -40,10 +40,10 @@ namespace Adaptor
 class Window : public SceneHolder
 {
 public:
-
   Window( const PositionSize& positionSize );
   virtual ~Window() = default;
   static Window* New(const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent);
+  FocusChangeSignalType mFocusChangeSignal;
 };
 
 } // namespace Adaptor
index 1424f1a..9849f60 100644 (file)
@@ -125,6 +125,41 @@ Integration::RenderSurface& Window::GetRenderSurface()
   return GetImplementation( *this ).GetRenderSurface();
 }
 
+void Window::Add( Actor actor )
+{
+  GetImplementation( *this ).Add( actor );
+}
+
+void Window::Remove( Actor actor )
+{
+  GetImplementation( *this ).Remove( actor );
+}
+
+Dali::Layer Window::GetRootLayer() const
+{
+  return GetImplementation( *this ).GetRootLayer();
+}
+
+void Window::SetBackgroundColor( const Vector4& color )
+{
+  GetImplementation( *this ).SetBackgroundColor( color );
+}
+
+Vector4 Window::GetBackgroundColor() const
+{
+  return GetImplementation( *this ).GetBackgroundColor();
+}
+
+void Window::Raise()
+{
+  GetImplementation( *this ).mFocusChangeSignal.Emit(*this, true);
+}
+
+FocusChangeSignalType& Window::FocusChangeSignal()
+{
+  return GetImplementation( *this ).mFocusChangeSignal;
+}
+
 namespace DevelWindow
 {
 
@@ -140,6 +175,16 @@ Window Get( Actor actor )
   return Dali::Window( windowImpl );
 }
 
+Window DownCast( BaseHandle handle )
+{
+  Internal::Adaptor::Window* windowImpl = nullptr;
+  if ( Dali::Adaptor::IsAvailable() )
+  {
+    windowImpl = dynamic_cast<Dali::Internal::Adaptor::Window*>( handle.GetObjectPtr());
+  }
+  return Dali::Window( windowImpl );
+}
+
 EventProcessingFinishedSignalType& EventProcessingFinishedSignal( Window window )
 {
   return GetImplementation( window ).GetScene().EventProcessingFinishedSignal();
@@ -164,6 +209,7 @@ WheelEventSignalType& WheelEventSignal( Window window )
 {
   return GetImplementation( window ).WheelEventSignal();
 }
+
 } // namespace DevelWindow
 
 } // Dali
index 3fac48d..f261051 100644 (file)
@@ -44,6 +44,9 @@ class Window;
 }
 }
 
+class Window;
+typedef Signal< void (Window,bool) > FocusChangeSignalType;
+
 class Window : public BaseHandle
 {
 public:
@@ -58,6 +61,13 @@ public:
 
   Integration::Scene GetScene();
   Integration::RenderSurface& GetRenderSurface();
+  void Add( Dali::Actor actor );
+  void Remove( Dali::Actor actor );
+  Dali::Layer GetRootLayer() const;
+  void SetBackgroundColor( const Vector4& color );
+  Vector4 GetBackgroundColor() const;
+  void Raise();
+  FocusChangeSignalType& FocusChangeSignal();
 
 public:
   explicit Window( Internal::Adaptor::Window* window );
@@ -75,6 +85,7 @@ typedef Signal< void (const TouchData&) > TouchSignalType;
 typedef Signal< void (const WheelEvent&) > WheelEventSignalType;
 
 Dali::Window Get( Actor actor );
+Dali::Window DownCast(  BaseHandle handle );
 
 EventProcessingFinishedSignalType& EventProcessingFinishedSignal( Window window );
 KeyEventSignalType& KeyEventSignal( Dali::Window window );
index 49f665b..87ff376 100644 (file)
@@ -943,8 +943,8 @@ int UtcDaliAnimatedVectorImageVisualStopBehavior(void)
   // Stop
   DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::STOP, attributes );
 
-  // Trigger count is 1 - animation finished
-  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  application.SendNotification();
+  application.Render( 16 );
 
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::CURRENT_FRAME_NUMBER );
index 0f1d493..a759616 100755 (executable)
@@ -1579,4 +1579,40 @@ int UtcDaliKeyboardFocusManagerCheckConsumedKeyEvent(void)
   END_TEST;
 }
 
+int UtcDaliKeyboardFocusManagerFocusPerWindow(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline( "Ensure Memory focus actors for each window ");
+  KeyboardFocusManager manager = KeyboardFocusManager::Get();
+  DALI_TEST_CHECK( ! manager.GetCurrentFocusActor() );
+
+  Window firstWindow = Window::New(PositionSize(0,0,300,500) ,"", false);
+  DALI_TEST_CHECK( firstWindow );
+  Control first = Control::New();
+  first.SetKeyboardFocusable(true);
+  firstWindow.Add(first);
+
+  Window secondWindow = Window::New(PositionSize(0,0,400,600) ,"", false);
+  DALI_TEST_CHECK( secondWindow );
+  Control second = Control::New();
+  second.SetKeyboardFocusable(true);
+  secondWindow.Add( second );
+
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
+
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
+  firstWindow.Raise();
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
+
+  secondWindow.Remove( second );
+  secondWindow.Raise();
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() != second);
+
+  secondWindow.Reset();
+  END_TEST;
+}
+
 
index bba7702..18bd7a0 100644 (file)
@@ -122,15 +122,16 @@ KeyboardFocusManager::KeyboardFocusManager()
   mFocusedActorEnterKeySignal(),
   mCurrentFocusActor(),
   mFocusIndicatorActor(),
-  mIsFocusIndicatorShown( -1 ),
-  mFocusGroupLoopEnabled( false ),
-  mIsWaitingKeyboardFocusChangeCommit( false ),
-  mClearFocusOnTouch( true ),
-  mEnableFocusIndicator( true ),
-  mAlwaysShowIndicator( true ),
   mFocusHistory(),
   mSlotDelegate( this ),
-  mCustomAlgorithmInterface(NULL)
+  mCustomAlgorithmInterface(NULL),
+  mCurrentFocusedWindow(),
+  mIsFocusIndicatorShown( UNKNOWN ),
+  mEnableFocusIndicator( ENABLE ),
+  mAlwaysShowIndicator( ALWAYS_SHOW ),
+  mFocusGroupLoopEnabled( false ),
+  mIsWaitingKeyboardFocusChangeCommit( false ),
+  mClearFocusOnTouch( true )
 {
   // TODO: Get FocusIndicatorEnable constant from stylesheet to set mIsFocusIndicatorShown.
 
@@ -147,6 +148,11 @@ void KeyboardFocusManager::OnAdaptorInit()
     {
       ( *iter ).KeyEventSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnKeyEvent );
       ( *iter ).TouchSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnTouch );
+      Dali::Window window = DevelWindow::DownCast( *iter );
+      if( window )
+      {
+        window.FocusChangeSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnWindowFocusChanged);
+      }
     }
 
     // Get notified when any new scene holder is created afterwards
@@ -158,6 +164,11 @@ void KeyboardFocusManager::OnSceneHolderCreated( Dali::Integration::SceneHolder&
 {
   sceneHolder.KeyEventSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnKeyEvent );
   sceneHolder.TouchSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnTouch );
+  Dali::Window window = DevelWindow::DownCast( sceneHolder );
+  if( window )
+  {
+    window.FocusChangeSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnWindowFocusChanged);
+  }
 }
 
 KeyboardFocusManager::~KeyboardFocusManager()
@@ -170,9 +181,9 @@ void KeyboardFocusManager::GetConfigurationFromStyleManger()
     if( styleManager )
     {
       Property::Map config = Toolkit::DevelStyleManager::GetConfigurations( styleManager );
-      mAlwaysShowIndicator = config["alwaysShowFocus"].Get<bool>();
-      mIsFocusIndicatorShown = static_cast<int>(mAlwaysShowIndicator);
-      mClearFocusOnTouch = mIsFocusIndicatorShown ? false : true;
+      mAlwaysShowIndicator = config["alwaysShowFocus"].Get<bool>() ? ALWAYS_SHOW : NONE;
+      mIsFocusIndicatorShown = ( mAlwaysShowIndicator == ALWAYS_SHOW )? SHOW : HIDE;
+      mClearFocusOnTouch = ( mIsFocusIndicatorShown == SHOW ) ? false : true;
     }
 }
 
@@ -180,7 +191,7 @@ bool KeyboardFocusManager::SetCurrentFocusActor( Actor actor )
 {
   DALI_ASSERT_DEBUG( !mIsWaitingKeyboardFocusChangeCommit && "Calling this function in the PreFocusChangeSignal callback?" );
 
-  if( mIsFocusIndicatorShown == -1 )
+  if( mIsFocusIndicatorShown == UNKNOWN )
   {
     GetConfigurationFromStyleManger();
   }
@@ -191,6 +202,16 @@ bool KeyboardFocusManager::SetCurrentFocusActor( Actor actor )
 bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor )
 {
   bool success = false;
+  if( actor && actor.IsKeyboardFocusable() && actor.OnStage() )
+  {
+    Integration::SceneHolder currentWindow = Integration::SceneHolder::Get( actor );
+
+    if( currentWindow.GetRootLayer() != mCurrentFocusedWindow.GetHandle())
+    {
+      Layer rootLayer = currentWindow.GetRootLayer();
+      mCurrentFocusedWindow = rootLayer;
+    }
+  }
 
   Actor currentFocusedActor = GetCurrentFocusActor();
 
@@ -207,7 +228,7 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor )
   // Check whether the actor is in the stage and is keyboard focusable.
   if( actor && actor.IsKeyboardFocusable() && actor.OnStage() )
   {
-    if( mIsFocusIndicatorShown && mEnableFocusIndicator )
+    if( ( mIsFocusIndicatorShown == SHOW ) && ( mEnableFocusIndicator == ENABLE ) )
     {
       actor.Add( GetFocusIndicatorActor() );
     }
@@ -231,6 +252,22 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor )
     // Save the current focused actor
     mCurrentFocusActor = actor;
 
+    bool focusedWindowFound = false;
+    for( unsigned int i = 0; i < mCurrentFocusActors.size(); i++ )
+    {
+      if( mCurrentFocusActors[i].first == mCurrentFocusedWindow )
+      {
+        mCurrentFocusActors[i].second = actor;
+        focusedWindowFound = true;
+        break;
+      }
+    }
+    if( !focusedWindowFound)
+    {
+      // A new window gains the focus, so store the focused actor in that window.
+      mCurrentFocusActors.push_back( std::pair< WeakHandle< Layer>, WeakHandle< Actor > >( mCurrentFocusedWindow , actor ));
+    }
+
     Toolkit::Control newlyFocusedControl = Toolkit::Control::DownCast(actor);
     if( newlyFocusedControl )
     {
@@ -262,16 +299,39 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor )
 Actor KeyboardFocusManager::GetCurrentFocusActor()
 {
   Actor actor = mCurrentFocusActor.GetHandle();
+
   if( actor && ! actor.OnStage() )
   {
     // If the actor has been removed from the stage, then it should not be focused
-
     actor.Reset();
     mCurrentFocusActor.Reset();
   }
   return actor;
 }
 
+Actor KeyboardFocusManager::GetFocusActorFromCurrentWindow()
+{
+  Actor actor;
+  unsigned int index;
+  for( index = 0; index < mCurrentFocusActors.size(); index++ )
+  {
+    if( mCurrentFocusActors[index].first == mCurrentFocusedWindow )
+    {
+      actor = mCurrentFocusActors[index].second.GetHandle();
+      break;
+    }
+  }
+
+  if( actor && ! actor.OnStage() )
+  {
+    // If the actor has been removed from the window, then the window doesn't have any focused actor
+    actor.Reset();
+    mCurrentFocusActors.erase( mCurrentFocusActors.begin() + index );
+  }
+
+  return actor;
+}
+
 Actor KeyboardFocusManager::GetCurrentFocusGroup()
 {
   return GetFocusGroup(GetCurrentFocusActor());
@@ -593,7 +653,7 @@ void KeyboardFocusManager::ClearFocus()
   }
 
   mCurrentFocusActor.Reset();
-  mIsFocusIndicatorShown = static_cast<int>(mAlwaysShowIndicator);
+  mIsFocusIndicatorShown = ( mAlwaysShowIndicator == ALWAYS_SHOW ) ? SHOW : HIDE;
 }
 
 void KeyboardFocusManager::SetFocusGroupLoop(bool enabled)
@@ -693,7 +753,7 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
 
   std::string keyName = event.keyPressedName;
 
-  if( mIsFocusIndicatorShown == -1 )
+  if( mIsFocusIndicatorShown == UNKNOWN )
   {
     GetConfigurationFromStyleManger();
   }
@@ -706,10 +766,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     {
       if(!isAccessibilityEnabled)
       {
-        if(!mIsFocusIndicatorShown)
+        if(mIsFocusIndicatorShown == HIDE)
         {
           // Show focus indicator
-          mIsFocusIndicatorShown = 1;
+          mIsFocusIndicatorShown = SHOW;
         }
         else
         {
@@ -729,10 +789,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     {
       if(!isAccessibilityEnabled)
       {
-        if(!mIsFocusIndicatorShown)
+        if( mIsFocusIndicatorShown == HIDE )
         {
           // Show focus indicator
-          mIsFocusIndicatorShown = 1;
+          mIsFocusIndicatorShown = SHOW;
         }
         else
         {
@@ -750,10 +810,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     }
     else if (keyName == "Up" && !isAccessibilityEnabled)
     {
-      if(!mIsFocusIndicatorShown)
+      if( mIsFocusIndicatorShown == HIDE )
       {
         // Show focus indicator
-        mIsFocusIndicatorShown = 1;
+        mIsFocusIndicatorShown = SHOW;
       }
       else
       {
@@ -765,10 +825,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     }
     else if (keyName == "Down" && !isAccessibilityEnabled)
     {
-      if(!mIsFocusIndicatorShown)
+      if( mIsFocusIndicatorShown == HIDE )
       {
         // Show focus indicator
-        mIsFocusIndicatorShown = 1;
+        mIsFocusIndicatorShown = SHOW;
       }
       else
       {
@@ -780,10 +840,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     }
     else if (keyName == "Prior" && !isAccessibilityEnabled)
     {
-      if(!mIsFocusIndicatorShown)
+      if( mIsFocusIndicatorShown == HIDE )
       {
         // Show focus indicator
-        mIsFocusIndicatorShown = 1;
+        mIsFocusIndicatorShown = SHOW;
       }
       else
       {
@@ -795,10 +855,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     }
     else if (keyName == "Next" && !isAccessibilityEnabled)
     {
-      if(!mIsFocusIndicatorShown)
+      if( mIsFocusIndicatorShown == HIDE )
       {
         // Show focus indicator
-        mIsFocusIndicatorShown = 1;
+        mIsFocusIndicatorShown = SHOW;
       }
       else
       {
@@ -810,10 +870,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     }
     else if (keyName == "Tab" && !isAccessibilityEnabled)
     {
-      if(!mIsFocusIndicatorShown)
+      if( mIsFocusIndicatorShown == HIDE )
       {
         // Show focus indicator
-        mIsFocusIndicatorShown = 1;
+        mIsFocusIndicatorShown = SHOW;
       }
       else
       {
@@ -826,10 +886,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     }
     else if (keyName == "space" && !isAccessibilityEnabled)
     {
-      if(!mIsFocusIndicatorShown)
+      if( mIsFocusIndicatorShown == HIDE )
       {
         // Show focus indicator
-        mIsFocusIndicatorShown = 1;
+        mIsFocusIndicatorShown = SHOW;
       }
 
       isFocusStartableKey = true;
@@ -837,10 +897,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     else if (keyName == "" && !isAccessibilityEnabled)
     {
       // Check the fake key event for evas-plugin case
-      if(!mIsFocusIndicatorShown)
+      if( mIsFocusIndicatorShown == HIDE )
       {
         // Show focus indicator
-        mIsFocusIndicatorShown = 1;
+        mIsFocusIndicatorShown = SHOW;
       }
 
       isFocusStartableKey = true;
@@ -857,10 +917,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
   {
     if (keyName == "Return")
     {
-      if(!mIsFocusIndicatorShown && !isAccessibilityEnabled)
+      if((mIsFocusIndicatorShown == HIDE) && !isAccessibilityEnabled)
       {
         // Show focus indicator
-        mIsFocusIndicatorShown = 1;
+        mIsFocusIndicatorShown = SHOW;
       }
       else
       {
@@ -885,12 +945,12 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     }
   }
 
-  if(isFocusStartableKey && mIsFocusIndicatorShown && !isAccessibilityEnabled)
+  if(isFocusStartableKey && ( mIsFocusIndicatorShown == SHOW ) && !isAccessibilityEnabled)
   {
     Actor actor = GetCurrentFocusActor();
     if( actor )
     {
-      if( mEnableFocusIndicator )
+      if( mEnableFocusIndicator == ENABLE )
       {
         // Make sure the focused actor is highlighted
         actor.Add( GetFocusIndicatorActor() );
@@ -907,9 +967,9 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
 
 void KeyboardFocusManager::OnTouch(const TouchData& touch)
 {
-  // if mIsFocusIndicatorShown is -1, it means Configuration is not loaded.
+  // if mIsFocusIndicatorShown is UNKNOWN, it means Configuration is not loaded.
   // Try to load configuration.
-  if( mIsFocusIndicatorShown == -1 )
+  if( mIsFocusIndicatorShown == UNKNOWN )
   {
     GetConfigurationFromStyleManger();
   }
@@ -923,6 +983,27 @@ void KeyboardFocusManager::OnTouch(const TouchData& touch)
   }
 }
 
+void KeyboardFocusManager::OnWindowFocusChanged(Window window, bool focusIn )
+{
+  if( focusIn && mCurrentFocusedWindow.GetHandle() != window.GetRootLayer() )
+  {
+    // Change Current Focused Window
+    Layer rootLayer = window.GetRootLayer();
+    mCurrentFocusedWindow = rootLayer;
+
+    // Get Current Focused Actor from window
+    Actor currentFocusedActor = GetFocusActorFromCurrentWindow();
+    SetCurrentFocusActor( currentFocusedActor );
+
+    if( currentFocusedActor && ( mEnableFocusIndicator == ENABLE ) )
+    {
+      // Make sure the focused actor is highlighted
+      currentFocusedActor.Add( GetFocusIndicatorActor() );
+      mIsFocusIndicatorShown = SHOW;
+    }
+  }
+}
+
 Toolkit::KeyboardFocusManager::PreFocusChangeSignalType& KeyboardFocusManager::PreFocusChangeSignal()
 {
   return mPreFocusChangeSignal;
@@ -987,12 +1068,13 @@ void KeyboardFocusManager::EnableFocusIndicator(bool enable)
     mFocusIndicatorActor.Unparent();
   }
 
-  mEnableFocusIndicator = enable;
+  mEnableFocusIndicator = enable? ENABLE : DISABLE;
+
 }
 
 bool KeyboardFocusManager::IsFocusIndicatorEnabled() const
 {
-  return mEnableFocusIndicator;
+  return ( mEnableFocusIndicator == ENABLE );
 }
 
 } // namespace Internal
index ff79634..176bfce 100644 (file)
@@ -26,6 +26,7 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
 #include <dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
 
 namespace Dali
 {
@@ -52,6 +53,25 @@ public:
 
   typedef Toolkit::DevelKeyboardFocusManager::CustomAlgorithmInterface CustomAlgorithmInterface;
 
+  enum FocusIndicatorState
+  {
+    UNKNOWN = -1,   ///< Unknown state
+    HIDE = 0,          ///< FocusIndicator is hidden
+    SHOW = 1,          ///< FocusIndicator is shown
+  };
+
+  enum EnableFocusedIndicatorState
+  {
+    DISABLE = 0,          ///< FocusIndicator is disable
+    ENABLE = 1,          ///< FocusIndicator is enable
+  };
+
+  enum FocusedIndicatorModeState
+  {
+    NONE = 0,          ///< Set nothing
+    ALWAYS_SHOW = 1,          ///< FocusIndicator is always shown
+  };
+
   /**
    * @copydoc Toolkit::KeyboardFocusManager::Get
    */
@@ -260,7 +280,7 @@ private:
    * Callback for the key event when no actor in the stage has gained the key input focus
    * @param[in] event The KeyEvent event.
    */
-  void OnKeyEvent(const KeyEvent& event);
+  void OnKeyEvent( const KeyEvent& event );
 
   /**
    * Callback for the touch event when the screen is touched and when the touch ends
@@ -269,6 +289,18 @@ private:
    */
   void OnTouch( const TouchData& touch );
 
+  /**
+   * Called when the window focus is changed.
+   * @param[in] window The window whose focus is changed
+   * @param[in] focusIn Whether the focus is in/out
+   */
+  void OnWindowFocusChanged( Window window, bool focusIn );
+
+  /**
+   * Get the focus Actor from current window
+   */
+  Actor GetFocusActorFromCurrentWindow();
+
 private:
 
   // Undefined
@@ -287,24 +319,29 @@ private:
 
   Actor mFocusIndicatorActor; ///< The focus indicator actor shared by all the keyboard focusable actors for highlight
 
-  int mIsFocusIndicatorShown; ///< Whether indicator should be shown / hidden when getting focus. It could be enabled when keyboard focus feature is enabled and navigation keys or 'Tab' key are pressed.
+  FocusStack mFocusHistory; ///< Stack to contain pre-focused actor's BaseObject*
 
-  bool mFocusGroupLoopEnabled:1; ///< Whether the focus movement is looped within the same focus group
+  SlotDelegate< KeyboardFocusManager > mSlotDelegate;
 
-  bool mIsWaitingKeyboardFocusChangeCommit:1; /// A flag to indicate PreFocusChangeSignal emitted but the proposed focus actor is not commited by the application yet.
+  CustomAlgorithmInterface* mCustomAlgorithmInterface; ///< The user's (application / toolkit) implementation of CustomAlgorithmInterface
 
-  bool mClearFocusOnTouch:1; ///< Whether clear focus on touch.
+  typedef std::vector< std::pair< WeakHandle< Layer >, WeakHandle< Actor > > > FocusActorContainer;
 
-  bool mEnableFocusIndicator;  ///< Whether use focus indicator
+  FocusActorContainer mCurrentFocusActors; ///< A container of focused actors
 
-  bool mAlwaysShowIndicator; ///< Whether always show indicator. If true, the indicator would be directly shown when focused.
+  WeakHandle< Layer > mCurrentFocusedWindow; ///< A weak handle to the current focused window's root layer
 
-  FocusStack mFocusHistory; ///< Stack to contain pre-focused actor's BaseObject*
+  FocusIndicatorState mIsFocusIndicatorShown; ///< Whether indicator should be shown / hidden when getting focus. It could be enabled when keyboard focus feature is enabled and navigation keys or 'Tab' key are pressed.
 
-  SlotDelegate< KeyboardFocusManager > mSlotDelegate;
+  EnableFocusedIndicatorState mEnableFocusIndicator;  ///< Whether use focus indicator
 
-  CustomAlgorithmInterface* mCustomAlgorithmInterface; ///< The user's (application / toolkit) implementation of CustomAlgorithmInterface
+  FocusedIndicatorModeState mAlwaysShowIndicator; ///< Whether always show indicator. If true, the indicator would be directly shown when focused
 
+  bool mFocusGroupLoopEnabled:1; ///< Whether the focus movement is looped within the same focus group
+
+  bool mIsWaitingKeyboardFocusChangeCommit:1; /// A flag to indicate PreFocusChangeSignal emitted but the proposed focus actor is not commited by the application yet.
+
+  bool mClearFocusOnTouch:1; ///< Whether clear focus on touch.
 };
 
 } // namespace Internal
index d26787e..5b0c1c4 100644 (file)
@@ -242,18 +242,22 @@ void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Prop
     }
     case Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR:
     {
-      int32_t stopBehavior;
-      Scripting::GetEnumerationProperty( value, STOP_BEHAVIOR_TABLE, STOP_BEHAVIOR_TABLE_COUNT, stopBehavior );
-      mStopBehavior = DevelImageVisual::StopBehavior::Type( stopBehavior );
-      mResendFlag |= RESEND_STOP_BEHAVIOR;
+      int32_t stopBehavior = mStopBehavior;
+      if( Scripting::GetEnumerationProperty( value, STOP_BEHAVIOR_TABLE, STOP_BEHAVIOR_TABLE_COUNT, stopBehavior ) )
+      {
+        mStopBehavior = DevelImageVisual::StopBehavior::Type( stopBehavior );
+        mResendFlag |= RESEND_STOP_BEHAVIOR;
+      }
       break;
     }
     case Toolkit::DevelImageVisual::Property::LOOPING_MODE:
     {
-      int32_t loopingMode;
-      Scripting::GetEnumerationProperty( value, LOOPING_MODE_TABLE, LOOPING_MODE_TABLE_COUNT, loopingMode );
-      mLoopingMode = DevelImageVisual::LoopingMode::Type( loopingMode );
-      mResendFlag |= RESEND_LOOPING_MODE;
+      int32_t loopingMode = mLoopingMode;
+      if( Scripting::GetEnumerationProperty( value, LOOPING_MODE_TABLE, LOOPING_MODE_TABLE_COUNT, loopingMode ) )
+      {
+        mLoopingMode = DevelImageVisual::LoopingMode::Type( loopingMode );
+        mResendFlag |= RESEND_LOOPING_MODE;
+      }
       break;
     }
   }
@@ -393,9 +397,13 @@ void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, cons
       if( mVectorRasterizeThread.GetPlayState() != DevelImageVisual::PlayState::STOPPED )
       {
         mVectorRasterizeThread.StopAnimation();
+      }
 
-        OnAnimationFinished();
+      if( mImpl->mRenderer )
+      {
+        mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
       }
+
       mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
       break;
     }
@@ -445,12 +453,17 @@ void AnimatedVectorImageVisual::OnUploadCompleted()
 
 void AnimatedVectorImageVisual::OnAnimationFinished()
 {
-  if( mImpl->mEventObserver )
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnAnimationFinished: action state = %d [%p]\n", mActionStatus, this );
+
+  if( mActionStatus != DevelAnimatedVectorImageVisual::Action::STOP )
   {
-    mImpl->mEventObserver->NotifyVisualEvent( *this, DevelAnimatedVectorImageVisual::Signal::ANIMATION_FINISHED );
-  }
+    mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
 
-  mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
+    if( mImpl->mEventObserver )
+    {
+      mImpl->mEventObserver->NotifyVisualEvent( *this, DevelAnimatedVectorImageVisual::Signal::ANIMATION_FINISHED );
+    }
+  }
 
   if( mImpl->mRenderer )
   {
index c5f207c..2c39333 100644 (file)
@@ -44,7 +44,8 @@ constexpr auto NANOSECONDS_PER_SECOND( 1e+9 );
 Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VECTOR_ANIMATION" );
 #endif
 
-inline void ResetValue( bool& updated, uint32_t& value, uint32_t newValue, ConditionalWait& conditionalWait )
+template< typename T >
+inline void ResetValue( bool& updated, T& value, T newValue, ConditionalWait& conditionalWait )
 {
   ConditionalWait::ScopedLock lock( conditionalWait );
   if( !updated )
@@ -78,8 +79,10 @@ VectorRasterizeThread::VectorRasterizeThread( const std::string& url )
   mDestroyThread( false ),
   mResourceReady( false ),
   mCurrentFrameUpdated( false ),
+  mCurrentLoopUpdated( false ),
   mForward( true ),
   mUpdateFrameNumber( false ),
+  mNeedAnimationFinishedTrigger( true ),
   mLogFactory( Dali::Adaptor::Get().GetLogFactory() )
 {
   Initialize();
@@ -158,6 +161,7 @@ void VectorRasterizeThread::StopAnimation()
   if( mPlayState != PlayState::STOPPED && mPlayState != PlayState::STOPPING )
   {
     mNeedRender = true;
+    mNeedAnimationFinishedTrigger = false;
     mPlayState = PlayState::STOPPING;
     mConditionalWait.Notify( lock );
 
@@ -202,6 +206,8 @@ void VectorRasterizeThread::SetLoopCount( int32_t count )
     ConditionalWait::ScopedLock lock( mConditionalWait );
 
     mLoopCount = count;
+    mCurrentLoop = 0;
+    mCurrentLoopUpdated = true;
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetLoopCount: [%d] [%p]\n", count, this );
   }
@@ -362,9 +368,9 @@ void VectorRasterizeThread::Initialize()
 
 void VectorRasterizeThread::Rasterize()
 {
-  bool stopped = false;
+  bool stopped = false, needAnimationFinishedTrigger;
   uint32_t currentFrame, startFrame, endFrame;
-  int32_t loopCount;
+  int32_t loopCount, currentLoopCount;
 
   {
     ConditionalWait::ScopedLock lock( mConditionalWait );
@@ -384,11 +390,15 @@ void VectorRasterizeThread::Rasterize()
     startFrame = mStartFrame;
     endFrame = mEndFrame;
     loopCount = mLoopCount;
+    currentLoopCount = mCurrentLoop;
+    needAnimationFinishedTrigger = mNeedAnimationFinishedTrigger;
 
     mResourceReady = true;
     mNeedRender = false;
     mCurrentFrameUpdated = false;
+    mCurrentLoopUpdated = false;
     mUpdateFrameNumber = true;
+    mNeedAnimationFinishedTrigger = true;
   }
 
   auto currentFrameStartTime = std::chrono::system_clock::now();
@@ -412,7 +422,7 @@ void VectorRasterizeThread::Rasterize()
       }
       else
       {
-        if( loopCount < 0 || ++mCurrentLoop < loopCount )   // repeat forever or before the last loop
+        if( loopCount < 0 || ++currentLoopCount < loopCount )   // repeat forever or before the last loop
         {
           ResetValue( mCurrentFrameUpdated, mCurrentFrame, startFrame, mConditionalWait );  // If the current frame is changed in the event thread, don't overwrite it.
           mUpdateFrameNumber = false;
@@ -421,11 +431,12 @@ void VectorRasterizeThread::Rasterize()
         {
           animationFinished = true;   // end of animation
         }
+        ResetValue( mCurrentLoopUpdated, mCurrentLoop, currentLoopCount, mConditionalWait );
       }
     }
     else if( currentFrame == startFrame && !mForward )  // first frame
     {
-      if( loopCount < 0 || ++mCurrentLoop < loopCount )   // repeat forever or before the last loop
+      if( loopCount < 0 || ++currentLoopCount < loopCount )   // repeat forever or before the last loop
       {
         mForward = true;
       }
@@ -433,6 +444,7 @@ void VectorRasterizeThread::Rasterize()
       {
         animationFinished = true;   // end of animation
       }
+      ResetValue( mCurrentLoopUpdated, mCurrentLoop, currentLoopCount, mConditionalWait );
     }
 
     if( animationFinished )
@@ -462,7 +474,10 @@ void VectorRasterizeThread::Rasterize()
     mCurrentLoop = 0;
 
     // Animation is finished
-    mAnimationFinishedTrigger->Trigger();
+    if( needAnimationFinishedTrigger )
+    {
+      mAnimationFinishedTrigger->Trigger();
+    }
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Animation is finished [current = %d] [%p]\n", currentFrame, this );
   }
index 0855f14..f50a66d 100644 (file)
@@ -233,8 +233,10 @@ private:
   bool                        mDestroyThread;  ///< Whether the thread be destroyed
   bool                        mResourceReady;
   bool                        mCurrentFrameUpdated;
+  bool                        mCurrentLoopUpdated;
   bool                        mForward;
   bool                        mUpdateFrameNumber;
+  bool                        mNeedAnimationFinishedTrigger;
   const Dali::LogFactoryInterface& mLogFactory; ///< The log factory
 
 };
index bb3e91e..9a0a1ce 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 4;
-const unsigned int TOOLKIT_MICRO_VERSION = 36;
+const unsigned int TOOLKIT_MICRO_VERSION = 37;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index ebb5794..9d10cdf 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    1.4.36
+Version:    1.4.37
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT