From 9795d65d103bdf0524aa92e96475019eff2705f3 Mon Sep 17 00:00:00 2001 From: "minho.sun" Date: Thu, 30 Mar 2017 20:57:10 +0900 Subject: [PATCH] New propagation rule for KeyEvent New KeyEvent propagation rule is added. The rule is If focused control doesn't consume KeyEvent, it is propagated along scene tree. Because of this new propagation rule, Stack in KeyInputFocusManager isn't needed anymore. So, remove stack from KeyInputFocusManager. Change-Id: I820ac86891e95ef6def3445e5a3c8ff3429487c1 Signed-off-by: minho.sun --- .../dali-toolkit/utc-Dali-KeyInputFocusManager.cpp | 416 +++++---------------- .../focus-manager/keyinput-focus-manager.cpp | 10 - .../focus-manager/keyinput-focus-manager.h | 21 -- .../focus-manager/keyboard-focus-manager-impl.cpp | 3 +- .../focus-manager/keyinput-focus-manager-impl.cpp | 143 ++----- .../focus-manager/keyinput-focus-manager-impl.h | 40 +- dali-toolkit/public-api/controls/control-impl.cpp | 6 +- 7 files changed, 138 insertions(+), 501 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-KeyInputFocusManager.cpp b/automated-tests/src/dali-toolkit/utc-Dali-KeyInputFocusManager.cpp index 8231d2e..b208a35 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-KeyInputFocusManager.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-KeyInputFocusManager.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "dummy-control.h" @@ -79,20 +80,34 @@ struct SignalData }; /** - * Callback class to test SignalUnhandledKeyEvent signal + * Callback class for KeyEvent signal of control. */ -class SignalUnhandledKeyEventCallback : public Dali::ConnectionTracker +class KeyEventCallback : public Dali::ConnectionTracker { public: - SignalUnhandledKeyEventCallback( SignalData& data ) : mSignalData( data ) { } + /** + * Constructor + * @param[in] returnValue Set return value of KeyEvent callback. + * */ + KeyEventCallback( bool consumed ) + : mConsumed( consumed ), + mIsCalled( false ) + { + } - void Callback(const KeyEvent& event) + bool Callback( Control control, const KeyEvent& keyEvent ) { - mSignalData.functorCalled = true; - mSignalData.receivedKeyEvent = event; + mIsCalled = true; + return mConsumed; } - SignalData& mSignalData; + void Callback( const KeyEvent& keyEvent ) + { + mIsCalled = true; + } + + bool mConsumed; + bool mIsCalled; }; } // namespace @@ -132,7 +147,7 @@ int UtcDaliKeyInputFocusManagerSetFocus01(void) ToolkitTestApplication application; Stage stage = Stage::GetCurrent(); - tet_infoline(" Check that there is no focused control. Add a control to the stack. Check it is now the focused actor and receives KeyInputFocusGained signal"); + tet_infoline(" Check that there is no focused control. Set focus to control. Check it is now the focused actor and receives KeyInputFocusGained signal"); KeyInputFocusManager manager = KeyInputFocusManager::Get(); DALI_TEST_CHECK(manager); @@ -162,7 +177,7 @@ int UtcDaliKeyInputFocusManagerSetFocus02(void) ToolkitTestApplication application; Stage stage = Stage::GetCurrent(); - tet_infoline(" Add a control to the stack. Check it is now the focused actor and receives KeyInputFocusGained signal. Add another control - check that the first control receives KeyInputFocusLost"); + tet_infoline(" Set focus to control. Check it is now the focused actor and receives KeyInputFocusGained signal. Set focuse to another control - check that the first control receives KeyInputFocusLost"); KeyInputFocusManager manager = KeyInputFocusManager::Get(); DALI_TEST_CHECK(manager); @@ -174,8 +189,6 @@ int UtcDaliKeyInputFocusManagerSetFocus02(void) DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained ); DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); - stage.Add( dummy1 ); - manager.SetFocus( dummy1 ); DALI_TEST_CHECK( dummy1.HasKeyInputFocus()); // Also tests IsKeyboardListener() API DALI_TEST_CHECK( dummy1Impl.keyInputFocusGained ); @@ -188,8 +201,6 @@ int UtcDaliKeyInputFocusManagerSetFocus02(void) DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained ); DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); - stage.Add( dummy2 ); - manager.SetFocus( dummy2 ); DALI_TEST_CHECK( dummy2.HasKeyInputFocus()); // Also tests IsKeyboardListener() API DALI_TEST_CHECK( dummy2Impl.keyInputFocusGained ); @@ -198,187 +209,109 @@ int UtcDaliKeyInputFocusManagerSetFocus02(void) DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained ); DALI_TEST_CHECK( dummy1Impl.keyInputFocusLost ); - END_TEST; } -int UtcDaliKeyInputFocusManagerGetCurrentFocusControl(void) +int UtcDaliKeyInputFocusManagerKeyEventPropagation01(void) { - ToolkitTestApplication application; - Stage stage = Stage::GetCurrent(); - - tet_infoline(" Add 2 controls, check they each get focused. Re-focus the first control - ensure it's now got focus (check signals)"); - - KeyInputFocusManager manager = KeyInputFocusManager::Get(); - DALI_TEST_CHECK(manager); - - DummyControl dummy1 = DummyControl::New(true); - Impl::DummyControl& dummy1Impl = static_cast(dummy1.GetImplementation()); - dummy1.SetSize(100.0f, 100.0f); - stage.Add( dummy1 ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); - - DummyControl dummy2 = DummyControl::New(true); - Impl::DummyControl& dummy2Impl = static_cast(dummy2.GetImplementation()); - dummy2.SetSize(100.0f, 100.0f); - stage.Add( dummy2 ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusLost ); - manager.SetFocus(dummy1); - DALI_TEST_CHECK( dummy1 == manager.GetCurrentFocusControl() ); - DALI_TEST_CHECK( dummy1Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); - dummy1Impl.keyInputFocusGained = false; - dummy1Impl.keyInputFocusLost = false; - - manager.SetFocus(dummy2); - DALI_TEST_CHECK( dummy2 == manager.GetCurrentFocusControl() ); - DALI_TEST_CHECK( dummy1Impl.keyInputFocusLost ); - DALI_TEST_CHECK( dummy2Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusLost ); - // Reset signal received - dummy1Impl.keyInputFocusGained = false; - dummy1Impl.keyInputFocusLost = false; - dummy2Impl.keyInputFocusGained = false; - dummy2Impl.keyInputFocusLost = false; - - manager.SetFocus(dummy1); - DALI_TEST_CHECK( dummy1 == manager.GetCurrentFocusControl()); - DALI_TEST_CHECK( dummy1Impl.keyInputFocusGained ); - DALI_TEST_CHECK( dummy2Impl.keyInputFocusLost ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained ); - END_TEST; -} - -int UtcDaliKeyInputFocusManagerRemoveFocus01(void) -{ ToolkitTestApplication application; Stage stage = Stage::GetCurrent(); - tet_infoline(" Add 3 focus controls. Test that removing the topmost informs the next control that it now has focus, Test that the bottommost control doesn't receive anything. "); + tet_infoline("Test KeyEvent propagation. If focused control doesn't consume KeyEvent, KeyEvent will be recursively delivered to the control and its parents, until the event is consumed or the stage is reached. In this case, KeyEvent is delivered to KeyboardFocusManager via Stage's KeyEventSignal"); KeyInputFocusManager manager = KeyInputFocusManager::Get(); DALI_TEST_CHECK(manager); + KeyEventCallback stageCallback( false ); + stage.KeyEventSignal().Connect( &stageCallback, &KeyEventCallback::Callback ); + DummyControl dummy1 = DummyControl::New(true); - Impl::DummyControl& dummy1Impl = static_cast(dummy1.GetImplementation()); dummy1.SetSize(100.0f, 100.0f); + KeyEventCallback callback1( false ); + dummy1.KeyEventSignal().Connect( &callback1, &KeyEventCallback::Callback ); stage.Add( dummy1 ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); DummyControl dummy2 = DummyControl::New(true); - Impl::DummyControl& dummy2Impl = static_cast(dummy2.GetImplementation()); dummy2.SetSize(100.0f, 100.0f); - stage.Add( dummy2 ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusLost ); + KeyEventCallback callback2( false ); + dummy2.KeyEventSignal().Connect( &callback2, &KeyEventCallback::Callback ); + dummy1.Add( dummy2 ); - manager.SetFocus(dummy1); - DALI_TEST_CHECK(dummy1 == manager.GetCurrentFocusControl()); + DummyControl dummy3 = DummyControl::New(true); + Impl::DummyControl& dummy3Impl = static_cast(dummy3.GetImplementation()); + dummy3.SetSize(100.0f, 100.0f); + KeyEventCallback callback3( false ); + dummy3.KeyEventSignal().Connect( &callback3, &KeyEventCallback::Callback ); + dummy2.Add( dummy3 ); + DALI_TEST_CHECK( ! dummy3Impl.keyInputFocusGained ); + DALI_TEST_CHECK( ! dummy3Impl.keyInputFocusLost ); - manager.SetFocus(dummy2); - DALI_TEST_CHECK(dummy2 == manager.GetCurrentFocusControl()); - dummy1Impl.keyInputFocusGained = false; - dummy1Impl.keyInputFocusLost = false; - dummy2Impl.keyInputFocusGained = false; - dummy2Impl.keyInputFocusLost = false; + manager.SetFocus( dummy3 ); + DALI_TEST_CHECK( dummy3Impl.keyInputFocusGained ); - manager.RemoveFocus(dummy2); - DALI_TEST_CHECK(dummy1 == manager.GetCurrentFocusControl()); - DALI_TEST_CHECK( dummy1Impl.keyInputFocusGained ); - DALI_TEST_CHECK( dummy2Impl.keyInputFocusLost ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained ); - dummy1Impl.keyInputFocusGained = false; - dummy1Impl.keyInputFocusLost = false; - dummy2Impl.keyInputFocusGained = false; - dummy2Impl.keyInputFocusLost = false; + Integration::KeyEvent event("a", "a", 0, 0, 0, Integration::KeyEvent::Up); + application.ProcessEvent(event); - manager.RemoveFocus(dummy1); - DALI_TEST_CHECK(Control() == manager.GetCurrentFocusControl()); - DALI_TEST_CHECK( dummy1Impl.keyInputFocusLost ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusLost ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained ); + DALI_TEST_CHECK( callback1.mIsCalled ); + DALI_TEST_CHECK( callback2.mIsCalled ); + DALI_TEST_CHECK( callback3.mIsCalled ); + DALI_TEST_CHECK( stageCallback.mIsCalled ); END_TEST; } -int UtcDaliKeyInputFocusManagerRemoveFocus02(void) +int UtcDaliKeyInputFocusManagerKeyEventPropagation02(void) { + ToolkitTestApplication application; Stage stage = Stage::GetCurrent(); - tet_infoline(" Add 3 focus controls. Test that removing the bottommost doesn't change the focused control" ); + tet_infoline("Test KeyEvent propagation. If focused control doesn't consume KeyEvent, KeyEvent will be recursively delivered to the control and its parents, until the event is consumed or the stage is reached. In this case, KeyEvent is delivered from dummy3 to dummy2"); KeyInputFocusManager manager = KeyInputFocusManager::Get(); DALI_TEST_CHECK(manager); DummyControl dummy1 = DummyControl::New(true); - Impl::DummyControl& dummy1Impl = static_cast(dummy1.GetImplementation()); dummy1.SetSize(100.0f, 100.0f); + KeyEventCallback callback1( false ); + dummy1.KeyEventSignal().Connect( &callback1, &KeyEventCallback::Callback ); stage.Add( dummy1 ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); DummyControl dummy2 = DummyControl::New(true); - Impl::DummyControl& dummy2Impl = static_cast(dummy2.GetImplementation()); dummy2.SetSize(100.0f, 100.0f); - stage.Add( dummy2 ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusLost ); + KeyEventCallback callback2( true ); + dummy2.KeyEventSignal().Connect( &callback2, &KeyEventCallback::Callback ); + dummy1.Add( dummy2 ); DummyControl dummy3 = DummyControl::New(true); Impl::DummyControl& dummy3Impl = static_cast(dummy3.GetImplementation()); dummy3.SetSize(100.0f, 100.0f); - stage.Add( dummy3 ); + KeyEventCallback callback3( false ); + dummy3.KeyEventSignal().Connect( &callback3, &KeyEventCallback::Callback ); + dummy2.Add( dummy3 ); DALI_TEST_CHECK( ! dummy3Impl.keyInputFocusGained ); DALI_TEST_CHECK( ! dummy3Impl.keyInputFocusLost ); - manager.SetFocus(dummy1); - DALI_TEST_CHECK(dummy1 == manager.GetCurrentFocusControl()); + manager.SetFocus( dummy3 ); + DALI_TEST_CHECK( dummy3Impl.keyInputFocusGained ); - manager.SetFocus(dummy2); - DALI_TEST_CHECK(dummy2 == manager.GetCurrentFocusControl()); + Integration::KeyEvent event("a", "a", 0, 0, 0, Integration::KeyEvent::Up); + application.ProcessEvent(event); - manager.SetFocus(dummy3); - DALI_TEST_CHECK(dummy3 == manager.GetCurrentFocusControl()); - dummy1Impl.keyInputFocusGained = false; - dummy1Impl.keyInputFocusLost = false; - dummy2Impl.keyInputFocusGained = false; - dummy2Impl.keyInputFocusLost = false; - dummy3Impl.keyInputFocusGained = false; - dummy3Impl.keyInputFocusLost = false; - - manager.RemoveFocus(dummy1); - DALI_TEST_CHECK(dummy3 == manager.GetCurrentFocusControl()); - DALI_TEST_CHECK( dummy1Impl.keyInputFocusLost ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusLost ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy3Impl.keyInputFocusLost ); - DALI_TEST_CHECK( ! dummy3Impl.keyInputFocusGained ); - dummy1Impl.keyInputFocusGained = false; - dummy1Impl.keyInputFocusLost = false; - dummy2Impl.keyInputFocusGained = false; - dummy2Impl.keyInputFocusLost = false; - dummy3Impl.keyInputFocusGained = false; - dummy3Impl.keyInputFocusLost = false; + DALI_TEST_CHECK( !callback1.mIsCalled ); + DALI_TEST_CHECK( callback2.mIsCalled ); + DALI_TEST_CHECK( callback3.mIsCalled ); END_TEST; } -int UtcDaliKeyInputFocusManagerRemoveFocus03(void) +int UtcDaliKeyInputFocusManagerGetCurrentFocusControl(void) { ToolkitTestApplication application; Stage stage = Stage::GetCurrent(); - tet_infoline(" Add 2 focus controls. Remove each of them from the bottom up. Test that the stack is now empty. Add a new control - check that it correctly has focus" ); + tet_infoline(" Add 2 controls, check they each get focused. Re-focus the first control - ensure it's now got focus (check signals)"); KeyInputFocusManager manager = KeyInputFocusManager::Get(); DALI_TEST_CHECK(manager); @@ -398,121 +331,39 @@ int UtcDaliKeyInputFocusManagerRemoveFocus03(void) DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusLost ); manager.SetFocus(dummy1); - DALI_TEST_CHECK(dummy1 == manager.GetCurrentFocusControl()); - - manager.SetFocus(dummy2); - DALI_TEST_CHECK(dummy2 == manager.GetCurrentFocusControl()); - + DALI_TEST_CHECK( dummy1 == manager.GetCurrentFocusControl() ); + DALI_TEST_CHECK( dummy1Impl.keyInputFocusGained ); + DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); dummy1Impl.keyInputFocusGained = false; dummy1Impl.keyInputFocusLost = false; - dummy2Impl.keyInputFocusGained = false; - dummy2Impl.keyInputFocusLost = false; - manager.RemoveFocus(dummy1); - DALI_TEST_CHECK(dummy2 == manager.GetCurrentFocusControl()); + manager.SetFocus(dummy2); + DALI_TEST_CHECK( dummy2 == manager.GetCurrentFocusControl() ); DALI_TEST_CHECK( dummy1Impl.keyInputFocusLost ); + DALI_TEST_CHECK( dummy2Impl.keyInputFocusGained ); DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained ); DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusLost ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained ); - dummy1Impl.keyInputFocusGained = false; - dummy1Impl.keyInputFocusLost = false; - dummy2Impl.keyInputFocusGained = false; - dummy2Impl.keyInputFocusLost = false; - - manager.RemoveFocus(dummy2); - DALI_TEST_CHECK(Control() == manager.GetCurrentFocusControl()); - DALI_TEST_CHECK( dummy2Impl.keyInputFocusLost ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained ); + // Reset signal received dummy1Impl.keyInputFocusGained = false; dummy1Impl.keyInputFocusLost = false; dummy2Impl.keyInputFocusGained = false; dummy2Impl.keyInputFocusLost = false; - PushButton pushButton1 = PushButton::New(); - stage.Add( pushButton1 ); - manager.SetFocus( pushButton1 ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusLost ); - DALI_TEST_CHECK( pushButton1 == manager.GetCurrentFocusControl()); - END_TEST; -} - -int UtcDaliKeyInputFocusManagerRemoveFocus04(void) -{ - ToolkitTestApplication application; - Stage stage = Stage::GetCurrent(); - - tet_infoline(" Test what happens if the removed control is not on the focus stack"); - KeyInputFocusManager manager = KeyInputFocusManager::Get(); - DALI_TEST_CHECK(manager); - - PushButton pushButton1 = PushButton::New(); - PushButton pushButton2 = PushButton::New(); - stage.Add( pushButton1 ); - stage.Add( pushButton2 ); - manager.SetFocus( pushButton1 ); - manager.SetFocus( pushButton2 ); - - PushButton pushButton3 = PushButton::New(); - stage.Add( pushButton3 ); - manager.RemoveFocus( pushButton3 ); - DALI_TEST_CHECK( pushButton2 == manager.GetCurrentFocusControl()); - END_TEST; -} - -int UtcDaliKeyInputFocusManagerDestroyObject01(void) -{ - ToolkitTestApplication application; - Stage stage = Stage::GetCurrent(); - - tet_infoline(" Add 2 controls to the stack. Unparent and destroy the topmost. Check that it is removed from the stack, and that the bottommost is correctly focused" ); - - KeyInputFocusManager manager = KeyInputFocusManager::Get(); - DALI_TEST_CHECK(manager); - - DummyControl dummy1 = DummyControl::New(true); - Impl::DummyControl& dummy1Impl = static_cast(dummy1.GetImplementation()); - dummy1.SetSize(100.0f, 100.0f); - stage.Add( dummy1 ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); - - { - DummyControl dummy2 = DummyControl::New(true); - Impl::DummyControl& dummy2Impl = static_cast(dummy2.GetImplementation()); - dummy2.SetSize(100.0f, 100.0f); - stage.Add( dummy2 ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusLost ); - - manager.SetFocus(dummy1); - DALI_TEST_CHECK(dummy1 == manager.GetCurrentFocusControl()); - - manager.SetFocus(dummy2); - DALI_TEST_CHECK(dummy2 == manager.GetCurrentFocusControl()); - - dummy1Impl.keyInputFocusGained = false; - dummy1Impl.keyInputFocusLost = false; - dummy2Impl.keyInputFocusGained = false; - dummy2Impl.keyInputFocusLost = false; - - stage.Remove(dummy2); - } - - DALI_TEST_CHECK(dummy1 == manager.GetCurrentFocusControl()); + manager.SetFocus(dummy1); + DALI_TEST_CHECK( dummy1 == manager.GetCurrentFocusControl()); DALI_TEST_CHECK( dummy1Impl.keyInputFocusGained ); + DALI_TEST_CHECK( dummy2Impl.keyInputFocusLost ); DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); + DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained ); END_TEST; } -int UtcDaliKeyInputFocusManagerDestroyObject02(void) +int UtcDaliKeyInputFocusManagerRemoveFocus(void) { ToolkitTestApplication application; Stage stage = Stage::GetCurrent(); - tet_infoline(" Add 2 controls to the stack. Destroy a different actor entirely. Check that the stack is un-affected."); + tet_infoline(" Add focus controls. Test that removing focus from control which has focus. "); KeyInputFocusManager manager = KeyInputFocusManager::Get(); DALI_TEST_CHECK(manager); @@ -524,75 +375,16 @@ int UtcDaliKeyInputFocusManagerDestroyObject02(void) DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained ); DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost ); - - DummyControl dummy2 = DummyControl::New(true); - Impl::DummyControl& dummy2Impl = static_cast(dummy2.GetImplementation()); - dummy2.SetSize(100.0f, 100.0f); - stage.Add( dummy2 ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained ); - DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusLost ); - manager.SetFocus(dummy1); DALI_TEST_CHECK(dummy1 == manager.GetCurrentFocusControl()); - - manager.SetFocus(dummy2); - DALI_TEST_CHECK(dummy2 == manager.GetCurrentFocusControl()); - dummy1Impl.keyInputFocusGained = false; dummy1Impl.keyInputFocusLost = false; - dummy2Impl.keyInputFocusGained = false; - dummy2Impl.keyInputFocusLost = false; - - { - BufferImage image = CreateBufferImage(); - Actor actor = CreateRenderableActor( image ); - stage.Add( actor ); - actor.SetSize(100, 100); - - application.SendNotification(); - application.Render(); - - stage.Remove( actor ); - } - - DALI_TEST_CHECK( dummy2 == manager.GetCurrentFocusControl()); - END_TEST; -} - -int UtcDaliKeyInputFocusManagerIsKeyboardListener(void) -{ - ToolkitTestApplication application; - Stage stage = Stage::GetCurrent(); - - tet_infoline(" UtcDaliKeyInputFocusManagerIsKeyboardListener"); - - KeyInputFocusManager manager = KeyInputFocusManager::Get(); - DALI_TEST_CHECK(manager); - PushButton pushButton1 = PushButton::New(); - PushButton pushButton2 = PushButton::New(); - stage.Add( pushButton1 ); - stage.Add( pushButton2 ); - - manager.SetFocus(pushButton1); - DALI_TEST_CHECK(pushButton1 == manager.GetCurrentFocusControl()); - - manager.SetFocus(pushButton2); - DALI_TEST_CHECK(pushButton2 == manager.GetCurrentFocusControl()); - - DALI_TEST_CHECK(manager.IsKeyboardListener(pushButton1)); - DALI_TEST_CHECK(manager.IsKeyboardListener(pushButton2)); - - manager.RemoveFocus(pushButton2); - DALI_TEST_CHECK(!manager.IsKeyboardListener(pushButton2)); - - manager.RemoveFocus(pushButton1); - DALI_TEST_CHECK(!manager.IsKeyboardListener(pushButton1)); + manager.RemoveFocus(dummy1); + DALI_TEST_CHECK(Control() == manager.GetCurrentFocusControl()); + DALI_TEST_CHECK( dummy1Impl.keyInputFocusLost ); + DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained ); - manager.SetFocus(pushButton2); - DALI_TEST_CHECK(manager.IsKeyboardListener(pushButton2)); - pushButton2.ClearKeyInputFocus(); - DALI_TEST_CHECK(!manager.IsKeyboardListener(pushButton2)); END_TEST; } @@ -638,37 +430,3 @@ int UtcDaliKeyInputFocusManagerSignalKeyInputFocusChanged(void) DALI_TEST_CHECK( lostActor == Control() ); END_TEST; } - -int UtcDaliKeyInputFocusManagerSignalUnhandledKeyEvent(void) -{ - ToolkitTestApplication application; - - tet_infoline("UtcDaliKeyInputFocusManagerSignalUnhandledKeyEvent"); - - SignalData data; - SignalUnhandledKeyEventCallback callback( data ); - - KeyInputFocusManager manager = KeyInputFocusManager::Get(); - manager.UnhandledKeyEventSignal().Connect( &callback, &SignalUnhandledKeyEventCallback::Callback ); - - - Integration::KeyEvent event("a", "a", 0, 0, 0, Integration::KeyEvent::Up); - application.ProcessEvent(event); - - DALI_TEST_CHECK(data.functorCalled); - DALI_TEST_CHECK(event.keyName == data.receivedKeyEvent.keyPressedName ); - DALI_TEST_CHECK(event.keyCode == data.receivedKeyEvent.keyCode); - DALI_TEST_CHECK(event.keyString == data.receivedKeyEvent.keyPressed ); - DALI_TEST_CHECK(event.state == static_cast(data.receivedKeyEvent.state) ); - - data.Reset(); - - Integration::KeyEvent event2("v", "v", 0, 0, 0, Integration::KeyEvent::Up); - application.ProcessEvent(event2); - - DALI_TEST_CHECK(data.functorCalled); - DALI_TEST_CHECK(event2.keyName == data.receivedKeyEvent.keyPressedName ); - DALI_TEST_CHECK(event2.keyCode == data.receivedKeyEvent.keyCode); - DALI_TEST_CHECK(event2.keyString == data.receivedKeyEvent.keyPressed ); - END_TEST; -} diff --git a/dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.cpp b/dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.cpp index f851a12..8f11b45 100644 --- a/dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.cpp +++ b/dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.cpp @@ -84,21 +84,11 @@ void KeyInputFocusManager::RemoveFocus(Control control) GetImpl(*this).RemoveFocus(control); } -bool KeyInputFocusManager::IsKeyboardListener(Control control) -{ - return GetImpl(*this).IsKeyboardListener(control); -} - KeyInputFocusManager::KeyInputFocusChangedSignalType& KeyInputFocusManager::KeyInputFocusChangedSignal() { return GetImpl(*this).KeyInputFocusChangedSignal(); } -KeyInputFocusManager::UnhandledKeyEventSignalType& KeyInputFocusManager::UnhandledKeyEventSignal() -{ - return GetImpl(*this).UnhandledKeyEventSignal(); -} - } // namespace Toolkit } // namespace Dali diff --git a/dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h b/dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h index 330f0be..3161990 100644 --- a/dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h +++ b/dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h @@ -44,7 +44,6 @@ class KeyInputFocusManager; * | %Signal Name | Method | * |----------------------|-----------------------------------| * | keyInputFocusChanged | @ref KeyInputFocusChangedSignal() | - * | unhandledKeyEvent | @ref UnhandledKeyEventSignal() | */ class DALI_IMPORT_API KeyInputFocusManager : public BaseHandle { @@ -53,9 +52,6 @@ public: // KeyInputFocusChanged typedef Signal< void (Control, Control) > KeyInputFocusChangedSignalType; - // Unhandled Key Event - typedef Signal< void (const KeyEvent&) > UnhandledKeyEventSignalType; - public: /** @@ -103,13 +99,6 @@ public: */ void RemoveFocus(Control control); - /** - * Queries whether a control is currently part of the focus stack. - * @param [in] control which should be queried. - * @return True if it is part of the foucus stack False otherwise. - */ - bool IsKeyboardListener(Control control); - public: // Signals /** @@ -124,16 +113,6 @@ public: // Signals */ KeyInputFocusChangedSignalType& KeyInputFocusChangedSignal(); - /** - * This signal is emitted when a key event was received, and none of the focused controls on the stage have consumed it. - * A callback of the following type may be connected: - * @code - * void YourCallbackName(const KeyEvent& event); - * @endcode - * @return The signal to connect to. - */ - UnhandledKeyEventSignalType& UnhandledKeyEventSignal(); - private: explicit DALI_INTERNAL KeyInputFocusManager(Internal::KeyInputFocusManager *impl); 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 72f9359..57fe076 100644 --- a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp +++ b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include namespace Dali @@ -125,7 +124,7 @@ KeyboardFocusManager::KeyboardFocusManager() mCustomAlgorithmInterface(NULL) { // TODO: Get FocusIndicatorEnable constant from stylesheet to set mIsFocusIndicatorEnabled. - Toolkit::KeyInputFocusManager::Get().UnhandledKeyEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnKeyEvent); + Stage::GetCurrent().KeyEventSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnKeyEvent); Stage::GetCurrent().TouchSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnTouch ); } diff --git a/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp b/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp index cdcc8e2..f188281 100644 --- a/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp +++ b/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp @@ -22,6 +22,7 @@ #include // for strcmp #include #include +#include // INTERNAL INCLUDES #include @@ -42,16 +43,14 @@ namespace // Signals const char* const SIGNAL_KEY_INPUT_FOCUS_CHANGED = "keyInputFocusChanged"; -const char* const SIGNAL_UNHANDLED_KEY_EVENT = "unhandledKeyEvent"; } KeyInputFocusManager::KeyInputFocusManager() -: mSlotDelegate( this ) +: mSlotDelegate( this ), + mCurrentFocusControl() { - Stage::GetCurrent().KeyEventSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnKeyEvent); - mObjectRegistry = Dali::Stage::GetCurrent().GetObjectRegistry(); - mObjectRegistry.ObjectDestroyedSignal().Connect( this, &KeyInputFocusManager::OnObjectDestroyed ); + DevelStage::KeyEventGeneratedSignal( Stage::GetCurrent() ).Connect(mSlotDelegate, &KeyInputFocusManager::OnKeyEvent); } KeyInputFocusManager::~KeyInputFocusManager() @@ -66,23 +65,13 @@ void KeyInputFocusManager::SetFocus( Toolkit::Control control ) return; } - FocusStackIterator pos = FindFocusControlInStack( control ); - - if( ( mFocusStack.Count() != 0 ) && ( pos == mFocusStack.End()-1 ) ) + if( control == mCurrentFocusControl ) { - // Control already in front, so No-op + // Control already has focus return; } - if( pos != mFocusStack.End() ) - { - // A previously focused control wants to regain focus - mFocusStack.Erase( pos ); - } - else - { - control.OffStageSignal().Connect( mSlotDelegate, &KeyInputFocusManager::OnFocusControlStageDisconnection ); - } + control.OffStageSignal().Connect( mSlotDelegate, &KeyInputFocusManager::OnFocusControlStageDisconnection ); Dali::Toolkit::Control previousFocusControl = GetCurrentFocusControl(); if( previousFocusControl ) @@ -91,7 +80,8 @@ void KeyInputFocusManager::SetFocus( Toolkit::Control control ) GetImplementation( previousFocusControl ).OnKeyInputFocusLost(); } - mFocusStack.PushBack( &control.GetBaseObject() ); + // Set control to currentFocusControl + mCurrentFocusControl = control; // Tell the new actor that it has gained focus. GetImplementation( control ).OnKeyInputFocusGained(); @@ -105,61 +95,20 @@ void KeyInputFocusManager::SetFocus( Toolkit::Control control ) void KeyInputFocusManager::RemoveFocus( Toolkit::Control control ) { - if( control ) + if( control == mCurrentFocusControl ) { - FocusStackIterator pos = FindFocusControlInStack( control ); - if( pos != mFocusStack.End() ) - { - control.OffStageSignal().Disconnect( mSlotDelegate, &KeyInputFocusManager::OnFocusControlStageDisconnection ); + control.OffStageSignal().Disconnect( mSlotDelegate, &KeyInputFocusManager::OnFocusControlStageDisconnection ); - // Notify the control that it has lost key input focus - GetImplementation( control ).OnKeyInputFocusLost(); + // Notify the control that it has lost key input focus + GetImplementation( control ).OnKeyInputFocusLost(); - // If this is the top-most actor, pop it and change focus to the previous control - if( pos == mFocusStack.End() - 1 ) - { - mFocusStack.Erase( pos ); - - Toolkit::Control previouslyFocusedControl = GetCurrentFocusControl(); - if( previouslyFocusedControl ) - { - // Tell the control that it has gained focus. - GetImplementation( previouslyFocusedControl ).OnKeyInputFocusGained(); - } - } - else - { - // If the removed control is not currently focused, then no need to emit signal. - mFocusStack.Erase( pos ); - } - } + mCurrentFocusControl.Reset(); } } Toolkit::Control KeyInputFocusManager::GetCurrentFocusControl() const { - Toolkit::Control currentControl; - - FocusStack::SizeType count = mFocusStack.Count(); - if( count != 0 ) - { - BaseObject* object = mFocusStack[ count - 1 ]; - BaseHandle handle( object ); - currentControl = Dali::Toolkit::Control::DownCast( handle ); - } - return currentControl; -} - -bool KeyInputFocusManager::IsKeyboardListener( Toolkit::Control control ) const -{ - bool result = false; - - if( FindFocusControlInStack( control ) != mFocusStack.End() ) - { - result = true; - } - - return result; + return mCurrentFocusControl; } Toolkit::KeyInputFocusManager::KeyInputFocusChangedSignalType& KeyInputFocusManager::KeyInputFocusChangedSignal() @@ -167,46 +116,41 @@ Toolkit::KeyInputFocusManager::KeyInputFocusChangedSignalType& KeyInputFocusMana return mKeyInputFocusChangedSignal; } -Toolkit::KeyInputFocusManager::UnhandledKeyEventSignalType& KeyInputFocusManager::UnhandledKeyEventSignal() +bool KeyInputFocusManager::OnKeyEvent( const KeyEvent& event ) { - return mUnhandledKeyEventSignal; -} + bool consumed = false; -KeyInputFocusManager::FocusStackIterator KeyInputFocusManager::FindFocusControlInStack( Toolkit::Control control ) const -{ - BaseObject* controlObject = &control.GetBaseObject(); - return std::find( mFocusStack.Begin(), mFocusStack.End(), controlObject ); + Toolkit::Control control = GetCurrentFocusControl(); + if( control ) + { + // Notify the control about the key event + consumed = EmitKeyEventSignal( control, event ); + } + + return consumed; } -void KeyInputFocusManager::OnKeyEvent( const KeyEvent& event ) +bool KeyInputFocusManager::EmitKeyEventSignal( Toolkit::Control control, const KeyEvent& event ) { bool consumed = false; - if( mFocusStack.Count() > 0 ) + if( control ) { - FocusStack::SizeType index = mFocusStack.Count(); - while( mFocusStack.Count() != 0 && !consumed && index > 0 ) + consumed = GetImplementation( control ).EmitKeyEventSignal( event ); + + // if control doesn't consume KeyEvent, give KeyEvent to its parent. + if( !consumed ) { - --index; - BaseObject* object = mFocusStack[ index ]; - BaseHandle handle( object ); - Toolkit::Control control = Toolkit::Control::DownCast( object ); - if( control ) + Toolkit::Control parent = Toolkit::Control::DownCast( control.GetParent() ); + + if( parent ) { - // Notify the control about the key event - consumed = GetImplementation( control ).EmitKeyEventSignal( event ); + consumed = EmitKeyEventSignal( parent, event ); } } } - if( !consumed ) - { - // Emit signal to inform that a key event is not consumed. - if( !mUnhandledKeyEventSignal.Empty() ) - { - mUnhandledKeyEventSignal.Emit(event); - } - } + return consumed; } void KeyInputFocusManager::OnFocusControlStageDisconnection( Dali::Actor actor ) @@ -214,17 +158,6 @@ void KeyInputFocusManager::OnFocusControlStageDisconnection( Dali::Actor actor ) RemoveFocus( Dali::Toolkit::Control::DownCast( actor ) ); } -void KeyInputFocusManager::OnObjectDestroyed( const Dali::RefObject* object ) -{ - // The object is already destroyed. Don't create handles to it, or try sending - // signals to it. Remove it's pointer from the stack. - const BaseObject* baseObject = static_cast( object ); - FocusStackIterator pos = std::find( mFocusStack.Begin(), mFocusStack.End(), baseObject ); - if( pos != mFocusStack.End() ) - { - mFocusStack.Erase( pos ); - } -} bool KeyInputFocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor ) { @@ -237,10 +170,6 @@ bool KeyInputFocusManager::DoConnectSignal( BaseObject* object, ConnectionTracke { manager->KeyInputFocusChangedSignal().Connect( tracker, functor ); } - else if( 0 == strcmp( signalName.c_str(), SIGNAL_UNHANDLED_KEY_EVENT ) ) - { - manager->UnhandledKeyEventSignal().Connect( tracker, functor ); - } else { // signalName does not match any signal diff --git a/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.h b/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.h index 4a17c17..e1d1a94 100644 --- a/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.h +++ b/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.h @@ -44,9 +44,6 @@ class KeyInputFocusManager; class KeyInputFocusManager : public Dali::BaseObject, public Dali::ConnectionTracker { public: - typedef Dali::Vector< Dali::BaseObject* > FocusStack; - typedef FocusStack::Iterator FocusStackIterator; - /** * Construct a new KeyInputFocusManager. */ @@ -67,11 +64,6 @@ public: */ Toolkit::Control GetCurrentFocusControl() const; - /** - * @copydoc Toolkit::IsKeyboardListener - */ - bool IsKeyboardListener(Toolkit::Control control) const; - public: /** @@ -80,11 +72,6 @@ public: Toolkit::KeyInputFocusManager::KeyInputFocusChangedSignalType& KeyInputFocusChangedSignal(); /** - * @copydoc Toolkit::KeyInputFocusManager::UnhandledKeyEventSignal() - */ - Toolkit::KeyInputFocusManager::UnhandledKeyEventSignalType& UnhandledKeyEventSignal(); - - /** * Connects a callback function with the object's signals. * @param[in] object The object providing the signal. * @param[in] tracker Used to disconnect the signal. @@ -105,18 +92,10 @@ protected: private: /** - * Search for a control in the focus stack. - * @param[in] control The control for which to search - * @return An iterator to the control. If not found, this will equate to the - * mFocusStack.End() iterator. - */ - FocusStackIterator FindFocusControlInStack( Toolkit::Control control ) const; - - /** * Callback for the key event when no actor in the stage has gained the key input focus * @param[in] event The KeyEvent event. */ - void OnKeyEvent(const KeyEvent& event); + bool OnKeyEvent(const KeyEvent& event); /** * Signal handler called when a focused Control is removed from Stage. @@ -125,9 +104,12 @@ private: void OnFocusControlStageDisconnection( Dali::Actor control ); /** - * Signal handler called when an actor is destroyed. - */ - void OnObjectDestroyed(const Dali::RefObject* object); + * Recursively deliver events to the control and its parents, until the event is consumed or the stage is reached. + * @param[in] control The control got KeyEvent. + * @param[in] event The KeyEvent. + * @return True if KeyEvent is consumed. + */ + bool EmitKeyEventSignal( Toolkit::Control control, const KeyEvent& event ); private: @@ -141,13 +123,9 @@ private: // The key input focus change signal Toolkit::KeyInputFocusManager::KeyInputFocusChangedSignalType mKeyInputFocusChangedSignal; - // The un-handled key event signal - Toolkit::KeyInputFocusManager::UnhandledKeyEventSignalType mUnhandledKeyEventSignal; - - // Keyboard events are sent to the current focus actor, which will be the actor on the top of the focus actors stack. - FocusStack mFocusStack; SlotDelegate< KeyInputFocusManager > mSlotDelegate; - ObjectRegistry mObjectRegistry; + + Toolkit::Control mCurrentFocusControl; ///< The current focused control }; } // namespace Internal diff --git a/dali-toolkit/public-api/controls/control-impl.cpp b/dali-toolkit/public-api/controls/control-impl.cpp index c4ee219..fffbe69 100644 --- a/dali-toolkit/public-api/controls/control-impl.cpp +++ b/dali-toolkit/public-api/controls/control-impl.cpp @@ -1142,7 +1142,11 @@ bool Control::HasKeyInputFocus() bool result = false; if( Self().OnStage() ) { - result = Toolkit::KeyInputFocusManager::Get().IsKeyboardListener(Toolkit::Control::DownCast(Self())); + Toolkit::Control control = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl(); + if( Self() == control ) + { + result = true; + } } return result; } -- 2.7.4