Added control focus state change to KeyboardFocusManager 10/114710/7
authorDavid Steele <david.steele@samsung.com>
Tue, 14 Feb 2017 13:10:59 +0000 (13:10 +0000)
committerRichard Huang <r.huang@samsung.com>
Thu, 16 Feb 2017 17:00:51 +0000 (09:00 -0800)
Change-Id: Ib58a577df67ce16888b66dd49d4c299d90270181
Signed-off-by: David Steele <david.steele@samsung.com>
automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp
dali-toolkit/internal/builder/builder-impl.cpp
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp
dali-toolkit/public-api/controls/control-impl.cpp

index 7d40e9e..a480204 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali/integration-api/events/key-event-integ.h>
 
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali/integration-api/events/key-event-integ.h>
-
+#include <dali-toolkit/devel-api/controls/control-devel.h>
 
 using namespace Dali;
 using namespace Dali::Toolkit;
 
 using namespace Dali;
 using namespace Dali::Toolkit;
@@ -899,3 +899,214 @@ int UtcDaliKeyboardFocusManagerChangeFocusDirectionByKeyEvents(void)
 }
 
 
 }
 
 
+
+
+
+int UtcDaliKeyboardFocusManagerMoveFocusTestStateChange(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline(" UtcDaliKeyboardFocusManagerMoveFocusTestStateChange");
+
+  // Register Type
+  TypeInfo type;
+  type = TypeRegistry::Get().GetTypeInfo( "KeyboardFocusManager" );
+  DALI_TEST_CHECK( type );
+  BaseHandle handle = type.CreateInstance();
+  DALI_TEST_CHECK( handle );
+
+  KeyboardFocusManager manager = KeyboardFocusManager::Get();
+  DALI_TEST_CHECK(manager);
+
+  bool preFocusChangeSignalVerified = false;
+  PreFocusChangeCallback preFocusChangeCallback(preFocusChangeSignalVerified);
+  manager.PreFocusChangeSignal().Connect( &preFocusChangeCallback, &PreFocusChangeCallback::Callback );
+
+  bool focusChangedSignalVerified = false;
+  FocusChangedCallback focusChangedCallback(focusChangedSignalVerified);
+  manager.FocusChangedSignal().Connect( &focusChangedCallback, &FocusChangedCallback::Callback );
+
+  // Create the first actor and add it to the stage
+  Control first = Control::New();
+  first.SetKeyboardFocusable(true);
+  Stage::GetCurrent().Add(first);
+
+  // Create the second actor and add it to the stage
+  Control second = Control::New();
+  second.SetKeyboardFocusable(true);
+  Stage::GetCurrent().Add(second);
+
+  // Move the focus to the right
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == false);
+
+  // Because no layout control in the stage and no actor is focused, it should emit the PreFocusChange signal
+  DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
+  DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == Actor());
+  DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
+  DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::KeyboardFocus::RIGHT);
+  preFocusChangeCallback.Reset();
+
+  // Check that the focus is set on the first actor
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == Actor());
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == first);
+  DALI_TEST_EQUALS(first.GetProperty<std::string>(DevelControl::Property::STATE), "FOCUSED", TEST_LOCATION );
+  focusChangedCallback.Reset();
+
+  // Move the focus towards right
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == false);
+
+  // Because no layout control in the stage and the first actor is focused, it should emit the PreFocusChange signal
+  DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
+  DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == first);
+  DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
+  DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::KeyboardFocus::RIGHT);
+  preFocusChangeCallback.Reset();
+
+  // Check that the focus is set on the second actor
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == first);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == second);
+  DALI_TEST_EQUALS(first.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(second.GetProperty<std::string>(DevelControl::Property::STATE), "FOCUSED", TEST_LOCATION );
+  focusChangedCallback.Reset();
+
+  // Move the focus towards up
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::UP) == false);
+
+  // Because no layout control in the stage and no actor is focused, it should emit the PreFocusChange signal
+  DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
+  DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == second);
+  DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
+  DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::KeyboardFocus::UP);
+  preFocusChangeCallback.Reset();
+  DALI_TEST_CHECK(!focusChangedCallback.mSignalVerified);
+
+  // Create a 2x2 table view and try to move focus inside it
+  TableView tableView = TableView::New( 2, 2 );
+  Stage::GetCurrent().Add(tableView);
+
+  // Create the third actor
+  Control third = Control::New();
+  third.SetKeyboardFocusable(true);
+
+  // Create the fourth actor
+  Control fourth = Control::New();
+  fourth.SetKeyboardFocusable(true);
+
+  // Add the four children to table view
+  tableView.AddChild(first, TableView::CellPosition(0, 0));
+  tableView.AddChild(second, TableView::CellPosition(0, 1));
+  tableView.AddChild(third, TableView::CellPosition(1, 0));
+  tableView.AddChild(fourth, TableView::CellPosition(1, 1));
+
+  // Set the focus to the first actor
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == second);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == first);
+
+  DALI_TEST_EQUALS(first.GetProperty<std::string>(DevelControl::Property::STATE), "FOCUSED", TEST_LOCATION );
+  DALI_TEST_EQUALS(second.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+
+  focusChangedCallback.Reset();
+
+  // Move the focus towards right
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == first);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == second);
+  DALI_TEST_EQUALS(first.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(second.GetProperty<std::string>(DevelControl::Property::STATE), "FOCUSED", TEST_LOCATION );
+
+  focusChangedCallback.Reset();
+
+  // Move the focus towards down
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::DOWN) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == fourth);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == second);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == fourth);
+
+  DALI_TEST_EQUALS(first.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(second.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(third.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(fourth.GetProperty<std::string>(DevelControl::Property::STATE), "FOCUSED", TEST_LOCATION );
+
+  focusChangedCallback.Reset();
+
+  // Move the focus towards left
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == third);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == fourth);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == third);
+
+  DALI_TEST_EQUALS(first.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(second.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(third.GetProperty<std::string>(DevelControl::Property::STATE), "FOCUSED", TEST_LOCATION );
+  DALI_TEST_EQUALS(fourth.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+
+  focusChangedCallback.Reset();
+
+  // Move the focus towards up
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::UP) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == third);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == first);
+  DALI_TEST_EQUALS(first.GetProperty<std::string>(DevelControl::Property::STATE), "FOCUSED", TEST_LOCATION );
+  DALI_TEST_EQUALS(second.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(third.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(fourth.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  focusChangedCallback.Reset();
+
+  // Move the focus towards left. The focus move will fail as no way to move it upwards
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == false);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
+  DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
+  DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == first);
+  DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
+  DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::KeyboardFocus::LEFT);
+  DALI_TEST_EQUALS(first.GetProperty<std::string>(DevelControl::Property::STATE), "FOCUSED", TEST_LOCATION );
+  DALI_TEST_EQUALS(second.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(third.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(fourth.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+
+  preFocusChangeCallback.Reset();
+  DALI_TEST_CHECK(!focusChangedCallback.mSignalVerified);
+
+  // Enable the loop
+  manager.SetFocusGroupLoop(true);
+  DALI_TEST_CHECK(manager.GetFocusGroupLoop() == true);
+
+  // Move the focus towards left again. The focus should move to the fourth actor.
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == fourth);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == first);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == fourth);
+
+  DALI_TEST_EQUALS(first.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(second.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(third.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(fourth.GetProperty<std::string>(DevelControl::Property::STATE), "FOCUSED", TEST_LOCATION );
+
+  focusChangedCallback.Reset();
+
+  // Clear the focus
+  manager.ClearFocus();
+  DALI_TEST_EQUALS(first.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(second.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(third.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+  DALI_TEST_EQUALS(fourth.GetProperty<std::string>(DevelControl::Property::STATE), "NORMAL", TEST_LOCATION );
+
+
+  END_TEST;
+}
index 9b6daa0..ac5ea3e 100644 (file)
@@ -1258,7 +1258,7 @@ void Builder::RecordStyle( StylePtr           style,
       }
       else
       {
       }
       else
       {
-        DALI_LOG_WARNING( "RecordState() Node \"%s\" is not a JSON array or object\n", key.c_str() );
+        DALI_LOG_WARNING( "RecordStyle() Node \"%s\" is not a JSON array or object\n", key.c_str() );
       }
     }
     else if( key == KEYNAME_TYPE ||
       }
     }
     else if( key == KEYNAME_TYPE ||
index 197550f..989997b 100644 (file)
@@ -38,6 +38,7 @@
 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
 #include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
 #include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -162,9 +163,18 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor( const unsigned int actorID )
       actor.Add( GetFocusIndicatorActor() );
     }
     // Send notification for the change of focus actor
       actor.Add( GetFocusIndicatorActor() );
     }
     // Send notification for the change of focus actor
+    Actor currentFocusedActor = GetCurrentFocusActor();
+
     if( !mFocusChangedSignal.Empty() )
     {
     if( !mFocusChangedSignal.Empty() )
     {
-      mFocusChangedSignal.Emit(GetCurrentFocusActor(), actor);
+      mFocusChangedSignal.Emit(currentFocusedActor, actor);
+    }
+
+    Toolkit::Control currentlyFocusedControl = Toolkit::Control::DownCast(currentFocusedActor);
+    if( currentlyFocusedControl )
+    {
+      // Do we need it to remember if it was previously DISABLED?
+      currentlyFocusedControl.SetProperty(DevelControl::Property::STATE, DevelControl::NORMAL );
     }
 
     DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Focus Changed\n", __FUNCTION__, __LINE__);
     }
 
     DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Focus Changed\n", __FUNCTION__, __LINE__);
@@ -172,6 +182,12 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor( const unsigned int actorID )
     // Save the current focused actor
     mCurrentFocusActor = actorID;
 
     // Save the current focused actor
     mCurrentFocusActor = actorID;
 
+    Toolkit::Control newlyFocusedControl = Toolkit::Control::DownCast(actor);
+    if( newlyFocusedControl )
+    {
+      newlyFocusedControl.SetProperty(DevelControl::Property::STATE, DevelControl::FOCUSED );
+    }
+
     // Push Current Focused Actor to FocusHistory
     mFocusHistory.PushBack( &actor.GetBaseObject() );
 
     // Push Current Focused Actor to FocusHistory
     mFocusHistory.PushBack( &actor.GetBaseObject() );
 
@@ -404,17 +420,23 @@ void KeyboardFocusManager::DoKeyboardEnter(Actor actor)
 void KeyboardFocusManager::ClearFocus()
 {
   Actor actor = GetCurrentFocusActor();
 void KeyboardFocusManager::ClearFocus()
 {
   Actor actor = GetCurrentFocusActor();
-  if(actor)
+  if( actor )
   {
   {
-    if(mFocusIndicatorActor)
+    if( mFocusIndicatorActor )
     {
     {
-      actor.Remove(mFocusIndicatorActor);
+      actor.Remove( mFocusIndicatorActor );
     }
 
     // Send notification for the change of focus actor
     if( !mFocusChangedSignal.Empty() )
     {
     }
 
     // Send notification for the change of focus actor
     if( !mFocusChangedSignal.Empty() )
     {
-      mFocusChangedSignal.Emit(actor, Actor());
+      mFocusChangedSignal.Emit( actor, Actor() );
+    }
+
+    Toolkit::Control currentlyFocusedControl = Toolkit::Control::DownCast( actor );
+    if( currentlyFocusedControl )
+    {
+      currentlyFocusedControl.SetProperty( DevelControl::Property::STATE, DevelControl::NORMAL );
     }
   }
 
     }
   }
 
index 5d3248e..3f58064 100644 (file)
@@ -54,6 +54,7 @@
 
 namespace Dali
 {
 
 namespace Dali
 {
+extern bool CaseInsensitiveStringCompare( const std::string& a, const std::string& b );
 
 namespace Toolkit
 {
 
 namespace Toolkit
 {
@@ -322,7 +323,7 @@ public:
 
         case Toolkit::DevelControl::Property::STATE:
         {
 
         case Toolkit::DevelControl::Property::STATE:
         {
-          Toolkit::DevelControl::State state( DevelControl::NORMAL );
+          Toolkit::DevelControl::State state( controlImpl.mImpl->mState );
 
           if( Scripting::GetEnumerationProperty< Toolkit::DevelControl::State >( value, ControlStateTable, ControlStateTableCount, state ) )
           {
 
           if( Scripting::GetEnumerationProperty< Toolkit::DevelControl::State >( value, ControlStateTable, ControlStateTableCount, state ) )
           {
@@ -506,6 +507,8 @@ public:
   {
     if( mState != state )
     {
   {
     if( mState != state )
     {
+      // If mState was Disabled, and new state is Focused, should probably
+      // store that fact, e.g. in another property that FocusManager can access.
       mState = state;
 
       // Trigger state change and transitions
       mState = state;
 
       // Trigger state change and transitions