Added nested TableView KeyboardFocus support
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / table-view / table-view-impl.cpp
index 398b7ad..b616fcf 100644 (file)
@@ -1071,12 +1071,14 @@ void TableView::OnChildRemove( Actor& child )
 }
 
 TableView::TableView( unsigned int initialRows, unsigned int initialColumns )
-: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
+: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
   mCellData( initialRows, initialColumns ),
   mLayoutingChild( false ),
   mRowDirty( true ),     // Force recalculation first time
   mColumnDirty( true )
 {
+  mCurrentColumn = 0;
+  mCurrentRow = 0;
   SetKeyboardNavigationSupport( true );
   ResizeContainers( initialRows, initialColumns );
 }
@@ -1319,51 +1321,78 @@ Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolki
       int numberOfColumns = GetColumns();
       int numberOfRows = GetRows();
 
+      bool lastCell = false;
+      Actor nextValidActor;
+
       switch ( direction )
       {
         case Toolkit::Control::KeyboardFocus::LEFT:
         {
-          if(--currentColumn < 0)
+          do
           {
-            currentColumn = numberOfColumns - 1;
-            if(--currentRow < 0)
+            if(--currentColumn < 0)
             {
-              currentRow = loopEnabled ? numberOfRows - 1 : 0;
-              focusLost = (currentRow == 0);
+              currentColumn = numberOfColumns - 1;
+              if(--currentRow < 0)
+              {
+                lastCell = true;
+                currentRow = loopEnabled ? numberOfRows - 1 : 0;
+                focusLost = (currentRow == 0);
+              }
             }
-          }
+            nextValidActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
+          } while ( !nextValidActor && !lastCell );
           break;
         }
         case Toolkit::Control::KeyboardFocus::RIGHT:
         {
-          if(++currentColumn > numberOfColumns - 1)
+          do
           {
-            currentColumn = 0;
-            if(++currentRow > numberOfRows - 1)
+            if(++currentColumn > numberOfColumns - 1)
             {
-              currentRow = loopEnabled ? 0 : numberOfRows - 1;
-              focusLost = (currentRow == numberOfRows - 1);
+              currentColumn = 0;
+              if(++currentRow > numberOfRows - 1)
+              {
+                lastCell = true;
+                currentRow = loopEnabled ? 0 : numberOfRows - 1;
+                focusLost = (currentRow == numberOfRows - 1);
+              }
             }
-          }
+            nextValidActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
+          } while ( !nextValidActor && !lastCell );
           break;
         }
         case Toolkit::Control::KeyboardFocus::UP:
         {
-          if(--currentRow < 0)
+          do
           {
-            currentRow = loopEnabled ? numberOfRows - 1 : 0;
-            focusLost = (currentRow == 0);
-          }
+            if(--currentRow < 0)
+            {
+              lastCell = true;
+              currentRow = loopEnabled ? numberOfRows - 1 : 0;
+              focusLost = (currentRow == 0);
+            }
+            nextValidActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
+          } while ( !nextValidActor && !lastCell );
           break;
         }
         case Toolkit::Control::KeyboardFocus::DOWN:
 
         {
-          if(++currentRow > numberOfRows - 1)
+          do
           {
-            currentRow = loopEnabled ? 0 : numberOfRows - 1;
-            focusLost = (currentRow == numberOfRows - 1);
-          }
+            if(++currentRow > numberOfRows - 1)
+            {
+              lastCell = true;
+              currentRow = loopEnabled ? 0 : numberOfRows - 1;
+              focusLost = (currentRow == numberOfRows - 1);
+            }
+            nextValidActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
+          } while ( !nextValidActor && !lastCell );
+          break;
+        }
+        default:
+        {
           break;
         }
       }
@@ -1371,13 +1400,42 @@ 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));
       }
     }
     else
     {
-      // The current focused actor is not within table view, so the child in the first cell should be focused.
-      nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(0, 0));
+      // The current focused actor is not within TableView.
+      // This means that the TableView has gained the Focus again.
+
+      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
+      {
+        // 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.
+
+        // 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);
+      }
+      else
+      {
+        // Otherwise, move the focus to either the first or the last cell according to the given direction.
+        if(direction == Toolkit::Control::KeyboardFocus::LEFT || direction == Toolkit::Control::KeyboardFocus::UP)
+        {
+          nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(numberOfRows - 1, numberOfColumns - 1));
+        }
+        else
+        {
+          nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(0, 0));
+        }
+      }
     }
   }