Fix the keyboard focus issue for nested table view 01/112201/1
authorRichard Huang <r.huang@samsung.com>
Fri, 27 Jan 2017 15:13:27 +0000 (15:13 +0000)
committerRichard Huang <r.huang@samsung.com>
Fri, 27 Jan 2017 15:13:27 +0000 (15:13 +0000)
Change-Id: Ia45179b275e5f92f0e58ed5bd8fc3506a014b5fa

dali-toolkit/internal/controls/table-view/table-view-impl.cpp
dali-toolkit/internal/controls/table-view/table-view-impl.h

index a674abb..b683987 100644 (file)
@@ -1078,12 +1078,11 @@ void TableView::OnChildRemove( Actor& child )
 TableView::TableView( unsigned int initialRows, unsigned int initialColumns )
 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
   mCellData( initialRows, initialColumns ),
+  mPreviousFocusedActor(),
   mLayoutingChild( false ),
   mRowDirty( true ),     // Force recalculation first time
   mColumnDirty( true )
 {
-  mCurrentColumn = 0;
-  mCurrentRow = 0;
   SetKeyboardNavigationSupport( true );
   ResizeContainers( initialRows, initialColumns );
 }
@@ -1405,29 +1404,37 @@ Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolki
       // Move the focus if we haven't lost it.
       if(!focusLost)
       {
-        // Save the new focus cell positions of TableView.
-        mCurrentColumn = currentColumn;
-        mCurrentRow = currentRow;
-
         nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
+
+        // Save the focused actor in the TableView.
+        mPreviousFocusedActor = nextFocusableActor;
       }
     }
     else
     {
-      // The current focused actor is not within TableView.
-      // This means that the TableView has gained the Focus again.
+      // The current focused actor is not within this TableView.
 
       unsigned int numberOfColumns = GetColumns();
       unsigned int numberOfRows = GetRows();
 
-      if( (mCurrentRow != 0 && mCurrentColumn != 0) && // Last saved cell was not the first cell
-          (mCurrentRow != numberOfRows - 1 && mCurrentColumn != numberOfColumns - 1) ) // Last saved cell was not the last cell
+      // Check whether the previous focused actor is a focus group (i.e. a layout container)
+      bool wasFocusedOnLayoutContainer = false;
+      Actor previousFocusedActor = mPreviousFocusedActor.GetHandle();
+      if( previousFocusedActor )
       {
-        // This condition handles the cases when parent TableView gained the focus again after the child layout
-        // container (i.e. TableView) has no more items (i.e. actors) to be focused on in a given direction.
+        Toolkit::Control control = Toolkit::Control::DownCast( previousFocusedActor );
+        if( control )
+        {
+          Internal::Control& controlImpl = static_cast<Internal::Control&>(control.GetImplementation());
+          wasFocusedOnLayoutContainer = controlImpl.IsKeyboardFocusGroup();
+        }
+      }
 
-        // Move the focus to next cell towards the given direction in a TableView if the last saved cell was not the first or last cell.
-        nextFocusableActor = GetNextKeyboardFocusableActor(GetChildAt(Toolkit::TableView::CellPosition(mCurrentRow, mCurrentColumn)), direction, loopEnabled);
+      // Check whether the previous focused actor is a layout container and also a child of this TableView
+      Toolkit::TableView::CellPosition position;
+      if( wasFocusedOnLayoutContainer && FindChildPosition( previousFocusedActor, position ) )
+      {
+        nextFocusableActor = GetNextKeyboardFocusableActor(previousFocusedActor, direction, loopEnabled);
       }
       else
       {
index be1f702..a8e8456 100644 (file)
@@ -18,6 +18,9 @@
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/devel-api/object/weak-handle.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/table-view/table-view.h>
@@ -497,8 +500,8 @@ private: // Data
   Size mFixedTotals;             ///< Accumulated totals for fixed width and height
 
   Size mPadding;                 ///< Padding to apply to each cell
-  unsigned int mCurrentRow;      ///< Last / current focused row
-  unsigned int mCurrentColumn;   ///< Last / current focused column
+
+  WeakHandle<Actor> mPreviousFocusedActor; ///< Perviously focused actor
   bool mLayoutingChild;          ///< Can't be a bitfield due to Relayouting lock
   bool mRowDirty : 1;            ///< Flag to indicate the row data is dirty
   bool mColumnDirty : 1;         ///< Flag to indicate the column data is dirty