Add KeyboardFocus History Stack 37/97137/16
authorminho.sun <minho.sun@samsung.com>
Fri, 11 Nov 2016 08:21:05 +0000 (17:21 +0900)
committerminho.sun <minho.sun@samsung.com>
Tue, 6 Dec 2016 09:22:12 +0000 (18:22 +0900)
Make KeyboardFocus History stack to support return(or back) UX.

Refer KeyInputFocus stack to make this.

When SetCurrentFocusActor() is called, focused actor's base object pointer is pushed to
History Stack.

If the number of pushed actor is over HISTORY_MAX_NUM( current 30 ),
KeyboardFocusManager pops the oldest one before pushing new one.

User can track focus history with "Escape" key now.

Change-Id: I024ec6da430c523945ab0a5bb3704efe56246575
Signed-off-by: minho.sun <minho.sun@samsung.com>
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/public-api/focus-manager/keyboard-focus-manager.cpp
dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h

index 6ef6e9e..c7a2a12 100644 (file)
@@ -695,3 +695,70 @@ int UtcDaliKeyboardFocusManagerSignals(void)
 
   END_TEST;
 }
 
   END_TEST;
 }
+
+int UtcDaliKeyboardFocusManagerMoveFocusBackward(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline(" UtcDaliKeyboardFocusManagerMoveFocusBackward");
+
+  KeyboardFocusManager manager = KeyboardFocusManager::Get();
+  DALI_TEST_CHECK(manager);
+
+  // Make history stack full
+  for(int i = 0 ; i < 31 ; i ++)
+  {
+    Actor actor = Actor::New();
+    actor.SetKeyboardFocusable(true);
+    Stage::GetCurrent().Add(actor);
+    manager.SetCurrentFocusActor(actor);
+  }
+
+  // Create the first actor and add it to the stage
+  Actor first = Actor::New();
+  first.SetKeyboardFocusable(true);
+  Stage::GetCurrent().Add(first);
+
+  // Create the second actor and add it to the stage
+  Actor second = Actor::New();
+  second.SetKeyboardFocusable(true);
+  Stage::GetCurrent().Add(second);
+
+  // Create the second actor and add it to the stage
+  Actor third = Actor::New();
+  third.SetKeyboardFocusable(true);
+  Stage::GetCurrent().Add(third);
+
+  // Check that the focus is set on the second actor
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
+
+  // Check that the focus is set on the second actor
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
+
+  // Check that the focus is set on the third  actor
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(third) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == third);
+
+  // Move the focus backward
+  manager.MoveFocusBackward();
+
+  // Check that it current focused actor is second actor
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
+
+  // Check that the focus is set on the third actor
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(third) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == third);
+
+  // Remove the second actor on stage
+  second.Unparent();
+
+  // Move the focus backward
+  manager.MoveFocusBackward();
+
+  // Check that it current focused actor is first actor
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
+
+  END_TEST;
+}
index e6ed691..1645dcd 100644 (file)
@@ -86,6 +86,8 @@ DALI_SIGNAL_REGISTRATION( Toolkit, KeyboardFocusManager, "keyboardFocusedActorEn
 
 DALI_TYPE_REGISTRATION_END()
 
 
 DALI_TYPE_REGISTRATION_END()
 
+const unsigned int MAX_HISTORY_AMOUNT = 30; ///< Max length of focus history stack
+
 } // unnamed namespace
 
 Toolkit::KeyboardFocusManager KeyboardFocusManager::Get()
 } // unnamed namespace
 
 Toolkit::KeyboardFocusManager KeyboardFocusManager::Get()
@@ -165,6 +167,16 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor( const unsigned int actorID )
     // Save the current focused actor
     mCurrentFocusActor = actorID;
 
     // Save the current focused actor
     mCurrentFocusActor = actorID;
 
+    // Push Current Focused Actor to FocusHistory
+    mFocusHistory.PushBack( &actor.GetBaseObject() );
+
+    // Delete first element before add new element when Stack is full.
+    if( mFocusHistory.Count() > MAX_HISTORY_AMOUNT )
+    {
+       FocusStackIterator beginPos = mFocusHistory.Begin();
+       mFocusHistory.Erase( beginPos );
+    }
+
     DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] SUCCEED\n", __FUNCTION__, __LINE__);
     success = true;
   }
     DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] SUCCEED\n", __FUNCTION__, __LINE__);
     success = true;
   }
@@ -187,6 +199,33 @@ Actor KeyboardFocusManager::GetCurrentFocusGroup()
   return GetFocusGroup(GetCurrentFocusActor());
 }
 
   return GetFocusGroup(GetCurrentFocusActor());
 }
 
+void KeyboardFocusManager::MoveFocusBackward()
+{
+  // Find Pre Focused Actor when the list size is more than 1
+  if( mFocusHistory.Count() > 1 )
+  {
+    // Delete current focused actor in history
+    FocusStackIterator endPos = mFocusHistory.End();
+    endPos = mFocusHistory.Erase( --endPos );
+
+    // If pre-focused actors are not on stage, remove them in stack
+    while( !Dali::Actor::DownCast(BaseHandle(mFocusHistory[ mFocusHistory.Count() - 1 ])).OnStage() )
+    {
+      endPos = mFocusHistory.Erase( --endPos );
+    }
+
+    // Get pre focused actor
+    BaseObject* object = mFocusHistory[ mFocusHistory.Count() - 1 ];
+    BaseHandle handle( object );
+    Actor preFocusedActor = Dali::Actor::DownCast( handle );
+
+    // Delete pre focused actor in history because it will pushed again by SetCurrentFocusActor()
+    mFocusHistory.Erase( --endPos );
+
+    SetCurrentFocusActor( preFocusedActor );
+ }
+}
+
 bool KeyboardFocusManager::IsLayoutControl(Actor actor) const
 {
   Toolkit::Control control = Toolkit::Control::DownCast(actor);
 bool KeyboardFocusManager::IsLayoutControl(Actor actor) const
 {
   Toolkit::Control control = Toolkit::Control::DownCast(actor);
@@ -624,6 +663,9 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     {
       // Emit signal to go back to the previous view???
     }
     {
       // Emit signal to go back to the previous view???
     }
+    else if (keyName == "Escape" && !isAccessibilityEnabled)
+    {
+    }
   }
   else if(event.state == KeyEvent::Up)
   {
   }
   else if(event.state == KeyEvent::Up)
   {
index 4eba5d3..aa5bcd3 100644 (file)
@@ -107,6 +107,11 @@ public:
    */
   Actor GetFocusIndicatorActor();
 
    */
   Actor GetFocusIndicatorActor();
 
+  /**
+   * Move current focus to backward
+   */
+  void MoveFocusBackward();
+
 public:
 
   /**
 public:
 
   /**
@@ -149,6 +154,9 @@ protected:
 
 private:
 
 
 private:
 
+  typedef Dali::Vector< Dali::BaseObject* > FocusStack; ///< Define Dali::Vector< Dali::BaseObject* > as FocusStack to contain focus history
+  typedef FocusStack::Iterator FocusStackIterator; ///< Define FocusStack::Iterator as FocusStackIterator to navigate FocusStack
+
   /**
    * Get the focus group of current focused actor.
    * @pre The FocusManager has been initialized.
   /**
    * Get the focus group of current focused actor.
    * @pre The FocusManager has been initialized.
@@ -252,7 +260,12 @@ private:
 
   bool mIsWaitingKeyboardFocusChangeCommit:1; /// A flag to indicate PreFocusChangeSignal emitted but the proposed focus actor is not commited by the application yet.
 
 
   bool mIsWaitingKeyboardFocusChangeCommit:1; /// A flag to indicate PreFocusChangeSignal emitted but the proposed focus actor is not commited by the application yet.
 
+  FocusStack mFocusHistory; ///< Stack to contain pre-focused actor's BaseObject*
+
+  FocusStackIterator mFocusHistoryIter; ///< Iterator for mFocusHistory
+
   SlotDelegate< KeyboardFocusManager > mSlotDelegate;
   SlotDelegate< KeyboardFocusManager > mSlotDelegate;
+
 };
 
 } // namespace Internal
 };
 
 } // namespace Internal
index a816ca2..d42a344 100644 (file)
@@ -107,6 +107,11 @@ Actor KeyboardFocusManager::GetFocusIndicatorActor()
   return GetImpl(*this).GetFocusIndicatorActor();
 }
 
   return GetImpl(*this).GetFocusIndicatorActor();
 }
 
+void KeyboardFocusManager::MoveFocusBackward()
+{
+  return GetImpl(*this).MoveFocusBackward();
+}
+
 KeyboardFocusManager::PreFocusChangeSignalType& KeyboardFocusManager::PreFocusChangeSignal()
 {
   return GetImpl(*this).PreFocusChangeSignal();
 KeyboardFocusManager::PreFocusChangeSignalType& KeyboardFocusManager::PreFocusChangeSignal()
 {
   return GetImpl(*this).PreFocusChangeSignal();
index 457f222..0ec2cad 100644 (file)
@@ -217,6 +217,13 @@ public:
    */
   Actor GetFocusIndicatorActor();
 
    */
   Actor GetFocusIndicatorActor();
 
+  /**
+   * @brief Move the focus to prev focused actor
+   *
+   * @SINCE_1_2.17
+   */
+  void MoveFocusBackward();
+
 public: // Signals
 
   /**
 public: // Signals
 
   /**