From c14e39b4db65670dcc6c17f03a95035f364c80e5 Mon Sep 17 00:00:00 2001 From: Joogab Yun Date: Thu, 3 Jun 2021 15:42:30 +0900 Subject: [PATCH] Add TOUCH_FOCUSABLE property This is a property that allows you to have focus even when touched. It works only when KEYBOARD_FOCUSABLE is set to true. KEYBOARD_FOCUSABLE : whether the view can have focus or not TOUCH_FOCUSABLE : Whether the user can focus by touch Change-Id: Ie308c75931df2cf74f45d851bc76e662c055635a --- .../dali-toolkit/utc-Dali-KeyboardFocusManager.cpp | 90 +++++++++++++++++++++- .../focus-manager/keyboard-focus-manager-impl.cpp | 17 +++- 2 files changed, 102 insertions(+), 5 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp b/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp index be3cf44..55de778 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp @@ -20,10 +20,11 @@ // Need to override adaptor classes for toolkit test harness, so include // test harness headers before dali headers. +#include +#include +#include #include - #include -#include #include #include #include @@ -1785,3 +1786,88 @@ int UtcDaliKeyboardFocusManagerWithoutFocusablePropertiesMoveFocus(void) END_TEST; } + +int UtcDaliKeyboardFocusManagerSetAndGetCurrentFocusActorInTouchMode(void) +{ + ToolkitTestApplication application; + + tet_infoline(" UtcDaliKeyboardFocusManagerSetAndGetCurrentFocusActorInTouchMode"); + + KeyboardFocusManager manager = KeyboardFocusManager::Get(); + DALI_TEST_CHECK(manager); + + // Create the first actor and add it to the stage + Actor first = Actor::New(); + first.SetProperty(Actor::Property::SIZE, Vector2( 50, 50 )); + first.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); + first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + first.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE,true); + first.SetProperty(DevelActor::Property::TOUCH_FOCUSABLE,true); + application.GetScene().Add(first); + + // Create the second actor and add it to the stage + Actor second = Actor::New(); + second.SetProperty(Actor::Property::SIZE, Vector2( 50, 50 )); + second.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 0.0f)); + second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + second.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE,true); + application.GetScene().Add(second); + + // flush the queue and render once + application.SendNotification(); + application.Render(); + + // Check that no actor is being focused yet. + DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor()); + + // Check that it will fail to set focus on an invalid actor + DALI_TEST_CHECK(manager.SetCurrentFocusActor(Actor()) == false); + + + Dali::Integration::TouchEvent event1 = Dali::Integration::TouchEvent(); + Dali::Integration::Point pointDown1; + pointDown1.SetState( PointState::DOWN ); + pointDown1.SetDeviceId(1); + // touch first actor + pointDown1.SetScreenPosition( Vector2( 10.0f, 10.0f ) ); + event1.AddPoint(pointDown1); + application.ProcessEvent( event1 ); + + // flush the queue and render once + application.SendNotification(); + application.Render(); + + // Check that the focus is successfully to the first actor + DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first); + + Dali::Integration::TouchEvent event2 = Dali::Integration::TouchEvent(); + Dali::Integration::Point pointDown2; + pointDown2.SetState( PointState::DOWN ); + pointDown2.SetDeviceId(1); + // touch second actor + pointDown2.SetScreenPosition( Vector2( 110.0f, 10.0f ) ); + event2.AddPoint(pointDown2); + application.ProcessEvent( event2 ); + + // flush the queue and render once + application.SendNotification(); + application.Render(); + + // Check that the focus is successfully to clear + DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor()); + + // Make the second actor focusableInTouchMode + second.SetProperty( DevelActor::Property::TOUCH_FOCUSABLE,true); + + // touch second actor + application.ProcessEvent( event2 ); + + // flush the queue and render once + application.SendNotification(); + application.Render(); + + // Check that the focus is successfully to the second actor + DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second); + + END_TEST; +} \ No newline at end of file diff --git a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp index b06edea..0aa9ed1 100644 --- a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp +++ b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp @@ -19,6 +19,7 @@ #include "keyboard-focus-manager-impl.h" // EXTERNAL INCLUDES +#include #include #include #include @@ -965,10 +966,20 @@ void KeyboardFocusManager::OnTouch(const TouchEvent& touch) // Clear the focus when user touch the screen. // We only do this on a Down event, otherwise the clear action may override a manually focused actor. - // If mClearFocusOnTouch is false, do not clear the focus even if user touch the screen. - if(((touch.GetPointCount() < 1) || (touch.GetState(0) == PointState::DOWN)) && mClearFocusOnTouch) + if(((touch.GetPointCount() < 1) || (touch.GetState(0) == PointState::DOWN))) { - ClearFocus(); + // If mClearFocusOnTouch is false, do not clear the focus even if user touch the screen. + if(mClearFocusOnTouch) + { + ClearFocus(); + } + + // If KEYBOARD_FOCUSABLE and TOUCH_FOCUSABLE is true, set focus actor + Actor hitActor = touch.GetHitActor(0); + if(hitActor && hitActor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) && hitActor.GetProperty(DevelActor::Property::TOUCH_FOCUSABLE)) + { + SetCurrentFocusActor(hitActor); + } } } -- 2.7.4