From 4b39e83277d8bdd962e5a2933aedcfe10df75f83 Mon Sep 17 00:00:00 2001 From: Umar Date: Thu, 22 Dec 2016 18:31:42 +0000 Subject: [PATCH] Added nested TableView KeyboardFocus support Change-Id: I108501a26b13a85efb2b71e7878b1580f0f06ea7 --- .../src/dali-toolkit/utc-Dali-TableView.cpp | 124 +++++++++++++++++++++ .../controls/table-view/table-view-impl.cpp | 35 +++++- .../internal/controls/table-view/table-view-impl.h | 2 + 3 files changed, 159 insertions(+), 2 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TableView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TableView.cpp index 7beeb96..590614e 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TableView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TableView.cpp @@ -915,3 +915,127 @@ int UtcDaliTableViewKeyboardFocus(void) END_TEST; } + +int UtcDaliTableViewKeyboardFocusInNestedTableView(void) +{ + ToolkitTestApplication application; + + TableView tableView = TableView::New(3, 3); + tableView.SetKeyboardFocusable( true ); + tableView.SetName( "TableView"); + + for ( int row = 0; row < 3; ++row ) + { + for ( int col = 0; col < 3; ++col ) + { + std::ostringstream str; + str << row << "-" << col; + + if (row == 1 && col ==1) + { + // Add a nested 2x2 table view in the middle cell of the parent table view + TableView childTableView = TableView::New(2, 2); + childTableView.SetName( str.str() ); + + for(int childRow = 0; childRow < 2; childRow++) + { + for(int childCol = 0; childCol < 2; childCol++) + { + Control control = Control::New(); + std::ostringstream nameStr; + nameStr << row << "-" << col << "-" << childRow << "-" << childCol; + control.SetName( nameStr.str() ); + control.SetKeyboardFocusable( true ); + childTableView.AddChild( control, TableView::CellPosition( childRow, childCol ) ); + } + } + tableView.AddChild( childTableView, TableView::CellPosition( row, col ) ); + } + else + { + Control control = Control::New(); + control.SetName( str.str() ); + control.SetKeyboardFocusable( true ); + tableView.AddChild( control, TableView::CellPosition( row, col ) ); + } + } + } + + Stage::GetCurrent().Add( tableView ); + + application.SendNotification(); + application.Render(); + + Actor firstFocusActor = Toolkit::Internal::GetImplementation( tableView ).GetNextKeyboardFocusableActor( Actor(), Control::KeyboardFocus::RIGHT, true ); + DALI_TEST_CHECK( firstFocusActor ); + DALI_TEST_CHECK( firstFocusActor.GetName() == "0-0" ); + + KeyboardFocusManager manager = KeyboardFocusManager::Get(); + manager.SetFocusGroupLoop( false ); + manager.SetCurrentFocusActor( firstFocusActor ); + + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-0" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-1" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-2" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-0" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-0" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-1" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-0" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-1" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-2" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-0" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-1" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-2" ); + + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-1" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-0" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-2" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-1" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-0" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-1" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-0" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-0" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-2" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-1" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-0" ); + + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-1" ); + manager.MoveFocus( Control::KeyboardFocus::DOWN ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-0" ); + manager.MoveFocus( Control::KeyboardFocus::DOWN ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-0" ); + manager.MoveFocus( Control::KeyboardFocus::DOWN ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-1" ); + + manager.MoveFocus( Control::KeyboardFocus::UP ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-1" ); + manager.MoveFocus( Control::KeyboardFocus::UP ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-1" ); + manager.MoveFocus( Control::KeyboardFocus::UP ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-1" ); + + END_TEST; +} diff --git a/dali-toolkit/internal/controls/table-view/table-view-impl.cpp b/dali-toolkit/internal/controls/table-view/table-view-impl.cpp index dea576c..b616fcf 100644 --- a/dali-toolkit/internal/controls/table-view/table-view-impl.cpp +++ b/dali-toolkit/internal/controls/table-view/table-view-impl.cpp @@ -1077,6 +1077,8 @@ TableView::TableView( unsigned int initialRows, unsigned int initialColumns ) mRowDirty( true ), // Force recalculation first time mColumnDirty( true ) { + mCurrentColumn = 0; + mCurrentRow = 0; SetKeyboardNavigationSupport( true ); ResizeContainers( initialRows, initialColumns ); } @@ -1398,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)); + } + } } } diff --git a/dali-toolkit/internal/controls/table-view/table-view-impl.h b/dali-toolkit/internal/controls/table-view/table-view-impl.h index d6e62b6..be1f702 100644 --- a/dali-toolkit/internal/controls/table-view/table-view-impl.h +++ b/dali-toolkit/internal/controls/table-view/table-view-impl.h @@ -497,6 +497,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 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 -- 2.7.4