2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali-toolkit-test-suite-utils.h>
19 #include <dali-toolkit/dali-toolkit.h>
20 #include <dali-toolkit/devel-api/controls/control-devel.h>
21 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
22 #include <dali/devel-api/common/stage-devel.h>
23 #include <dali/integration-api/events/key-event-integ.h>
27 #include "dummy-control.h"
30 using namespace Toolkit;
35 * Callback class for KeyInputFocusChanged signal.
37 class KeyInputFocusChangedCallback : public Dali::ConnectionTracker
42 * @param[in] gainActor Ref to the actor that should be set as the one that gains key input focus.
43 * @param[in] lostActor Ref to the actor that should be set as the one that loses key input focus.
45 KeyInputFocusChangedCallback(Control& gainActor, Control& lostActor)
46 : mActorGain(gainActor),
51 void Callback(Control gainingActor, Control lostActor)
53 mActorGain = gainingActor;
54 mActorLost = lostActor;
61 // Stores data that is populated in the callback and will be read by the TET cases
65 : functorCalled(false)
71 functorCalled = false;
73 receivedKeyEvent.Reset();
77 KeyEvent receivedKeyEvent;
81 * Callback class for KeyEvent signal of control.
83 class KeyEventCallback : public Dali::ConnectionTracker
88 * @param[in] returnValue Set return value of KeyEvent callback.
90 KeyEventCallback(bool consumed)
91 : mConsumed(consumed),
96 bool Callback(Control control, const KeyEvent& keyEvent)
102 void Callback(const KeyEvent& keyEvent)
113 void key_input_focus_manager_startup(void)
115 test_return_value = TET_UNDEF;
118 void key_input_focus_manager_cleanup(void)
120 test_return_value = TET_PASS;
123 int UtcDaliKeyInputFocusManagerGet(void)
125 ToolkitTestApplication application;
127 tet_infoline(" UtcDaliKeyInputFocusManagerGet");
129 KeyInputFocusManager manager;
131 manager = KeyInputFocusManager::Get();
132 DALI_TEST_CHECK(manager);
135 KeyInputFocusManager newManager = KeyInputFocusManager::Get();
136 DALI_TEST_CHECK(newManager);
138 // Check that focus manager is a singleton
139 DALI_TEST_CHECK(manager == newManager);
144 int UtcDaliKeyInputFocusManagerSetFocus01(void)
146 ToolkitTestApplication application;
147 Integration::Scene stage = application.GetScene();
149 tet_infoline(" Check that there is no focused control. Set focus to control. Check it is now the focused actor and receives KeyInputFocusGained signal");
151 KeyInputFocusManager manager = KeyInputFocusManager::Get();
152 DALI_TEST_CHECK(manager);
154 Control focusedControl = manager.GetCurrentFocusControl();
155 DALI_TEST_CHECK(!focusedControl);
157 DummyControl dummy = DummyControl::New(true);
158 Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummy.GetImplementation());
159 dummy.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
161 DALI_TEST_CHECK(!dummyImpl.keyInputFocusGained);
163 manager.SetFocus(dummy);
164 DALI_TEST_CHECK(dummy.HasKeyInputFocus()); // Also tests IsKeyboardListener() API
165 DALI_TEST_CHECK(dummyImpl.keyInputFocusGained);
167 focusedControl = manager.GetCurrentFocusControl();
168 DALI_TEST_CHECK(focusedControl);
169 DALI_TEST_CHECK(focusedControl == dummy);
174 int UtcDaliKeyInputFocusManagerSetFocus02(void)
176 ToolkitTestApplication application;
177 Integration::Scene stage = application.GetScene();
179 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");
181 KeyInputFocusManager manager = KeyInputFocusManager::Get();
182 DALI_TEST_CHECK(manager);
184 DummyControl dummy1 = DummyControl::New(true);
185 Impl::DummyControl& dummy1Impl = static_cast<Impl::DummyControl&>(dummy1.GetImplementation());
186 dummy1.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
188 DALI_TEST_CHECK(!dummy1Impl.keyInputFocusGained);
189 DALI_TEST_CHECK(!dummy1Impl.keyInputFocusLost);
191 manager.SetFocus(dummy1);
192 DALI_TEST_CHECK(dummy1.HasKeyInputFocus()); // Also tests IsKeyboardListener() API
193 DALI_TEST_CHECK(dummy1Impl.keyInputFocusGained);
194 dummy1Impl.keyInputFocusGained = false;
196 DummyControl dummy2 = DummyControl::New(true);
197 Impl::DummyControl& dummy2Impl = static_cast<Impl::DummyControl&>(dummy2.GetImplementation());
198 dummy2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
200 DALI_TEST_CHECK(!dummy2Impl.keyInputFocusGained);
201 DALI_TEST_CHECK(!dummy1Impl.keyInputFocusLost);
203 manager.SetFocus(dummy2);
204 DALI_TEST_CHECK(dummy2.HasKeyInputFocus()); // Also tests IsKeyboardListener() API
205 DALI_TEST_CHECK(dummy2Impl.keyInputFocusGained);
206 dummy1Impl.keyInputFocusGained = false;
208 DALI_TEST_CHECK(!dummy1Impl.keyInputFocusGained);
209 DALI_TEST_CHECK(dummy1Impl.keyInputFocusLost);
214 int UtcDaliKeyInputFocusManagerKeyEventPropagation01(void)
216 ToolkitTestApplication application;
217 Integration::Scene stage = application.GetScene();
219 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");
221 KeyInputFocusManager manager = KeyInputFocusManager::Get();
222 DALI_TEST_CHECK(manager);
224 KeyEventCallback stageCallback(false);
225 stage.KeyEventSignal().Connect(&stageCallback, &KeyEventCallback::Callback);
227 DummyControl dummy1 = DummyControl::New(true);
228 dummy1.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
229 KeyEventCallback callback1(false);
230 dummy1.KeyEventSignal().Connect(&callback1, &KeyEventCallback::Callback);
233 DummyControl dummy2 = DummyControl::New(true);
234 dummy2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
235 KeyEventCallback callback2(false);
236 dummy2.KeyEventSignal().Connect(&callback2, &KeyEventCallback::Callback);
239 DummyControl dummy3 = DummyControl::New(true);
240 Impl::DummyControl& dummy3Impl = static_cast<Impl::DummyControl&>(dummy3.GetImplementation());
241 dummy3.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
242 KeyEventCallback callback3(false);
243 dummy3.KeyEventSignal().Connect(&callback3, &KeyEventCallback::Callback);
245 DALI_TEST_CHECK(!dummy3Impl.keyInputFocusGained);
246 DALI_TEST_CHECK(!dummy3Impl.keyInputFocusLost);
248 manager.SetFocus(dummy3);
249 DALI_TEST_CHECK(dummy3Impl.keyInputFocusGained);
251 Integration::KeyEvent event("a", "", "a", 0, 0, 0, Integration::KeyEvent::UP, "", "", Device::Class::TOUCH, Device::Subclass::NONE);
252 application.ProcessEvent(event);
254 DALI_TEST_CHECK(callback1.mIsCalled);
255 DALI_TEST_CHECK(callback2.mIsCalled);
256 DALI_TEST_CHECK(callback3.mIsCalled);
257 DALI_TEST_CHECK(stageCallback.mIsCalled);
262 int UtcDaliKeyInputFocusManagerKeyEventPropagation02(void)
264 ToolkitTestApplication application;
265 Integration::Scene stage = application.GetScene();
267 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");
269 KeyInputFocusManager manager = KeyInputFocusManager::Get();
270 DALI_TEST_CHECK(manager);
272 DummyControl dummy1 = DummyControl::New(true);
273 dummy1.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
274 KeyEventCallback callback1(false);
275 dummy1.KeyEventSignal().Connect(&callback1, &KeyEventCallback::Callback);
278 DummyControl dummy2 = DummyControl::New(true);
279 dummy2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
280 KeyEventCallback callback2(true);
281 dummy2.KeyEventSignal().Connect(&callback2, &KeyEventCallback::Callback);
284 DummyControl dummy3 = DummyControl::New(true);
285 Impl::DummyControl& dummy3Impl = static_cast<Impl::DummyControl&>(dummy3.GetImplementation());
286 dummy3.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
287 KeyEventCallback callback3(false);
288 dummy3.KeyEventSignal().Connect(&callback3, &KeyEventCallback::Callback);
290 DALI_TEST_CHECK(!dummy3Impl.keyInputFocusGained);
291 DALI_TEST_CHECK(!dummy3Impl.keyInputFocusLost);
293 manager.SetFocus(dummy3);
294 DALI_TEST_CHECK(dummy3Impl.keyInputFocusGained);
296 Integration::KeyEvent event("a", "", "a", 0, 0, 0, Integration::KeyEvent::UP, "", "", Device::Class::TOUCH, Device::Subclass::NONE);
297 application.ProcessEvent(event);
299 DALI_TEST_CHECK(!callback1.mIsCalled);
300 DALI_TEST_CHECK(callback2.mIsCalled);
301 DALI_TEST_CHECK(callback3.mIsCalled);
306 int UtcDaliKeyInputFocusManagerDispatchKeyEvents(void)
308 ToolkitTestApplication application;
309 Integration::Scene stage = application.GetScene();
311 tet_infoline("Test KeyEvents propagation. If DISPATCH_KEY_EVENTS property is false, the KeyEvent is also not received.");
313 KeyInputFocusManager manager = KeyInputFocusManager::Get();
314 DALI_TEST_CHECK(manager);
316 DummyControl dummy1 = DummyControl::New(true);
317 dummy1.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
318 KeyEventCallback callback1(false);
319 dummy1.KeyEventSignal().Connect(&callback1, &KeyEventCallback::Callback);
322 DummyControl dummy2 = DummyControl::New(true);
323 dummy2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
324 KeyEventCallback callback2(false);
325 dummy2.KeyEventSignal().Connect(&callback2, &KeyEventCallback::Callback);
326 // dummy2 set DISPATCH_KEY_EVENTS property to false.
327 dummy2.SetProperty(Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS, false);
330 DummyControl dummy3 = DummyControl::New(true);
331 Impl::DummyControl& dummy3Impl = static_cast<Impl::DummyControl&>(dummy3.GetImplementation());
332 dummy3.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
333 KeyEventCallback callback3(false);
334 dummy3.KeyEventSignal().Connect(&callback3, &KeyEventCallback::Callback);
336 DALI_TEST_CHECK(!dummy3Impl.keyInputFocusGained);
337 DALI_TEST_CHECK(!dummy3Impl.keyInputFocusLost);
339 manager.SetFocus(dummy3);
340 DALI_TEST_CHECK(dummy3Impl.keyInputFocusGained);
342 Integration::KeyEvent event("a", "", "a", 0, 0, 0, Integration::KeyEvent::UP, "", "", Device::Class::TOUCH, Device::Subclass::NONE);
343 application.ProcessEvent(event);
345 DALI_TEST_CHECK(!callback1.mIsCalled);
346 DALI_TEST_CHECK(!callback2.mIsCalled);
347 DALI_TEST_CHECK(!callback3.mIsCalled);
352 int UtcDaliKeyInputFocusManagerGetCurrentFocusControl(void)
354 ToolkitTestApplication application;
355 Integration::Scene stage = application.GetScene();
357 tet_infoline(" Add 2 controls, check they each get focused. Re-focus the first control - ensure it's now got focus (check signals)");
359 KeyInputFocusManager manager = KeyInputFocusManager::Get();
360 DALI_TEST_CHECK(manager);
362 DummyControl dummy1 = DummyControl::New(true);
363 Impl::DummyControl& dummy1Impl = static_cast<Impl::DummyControl&>(dummy1.GetImplementation());
364 dummy1.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
366 DALI_TEST_CHECK(!dummy1Impl.keyInputFocusGained);
367 DALI_TEST_CHECK(!dummy1Impl.keyInputFocusLost);
369 DummyControl dummy2 = DummyControl::New(true);
370 Impl::DummyControl& dummy2Impl = static_cast<Impl::DummyControl&>(dummy2.GetImplementation());
371 dummy2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
373 DALI_TEST_CHECK(!dummy2Impl.keyInputFocusGained);
374 DALI_TEST_CHECK(!dummy2Impl.keyInputFocusLost);
376 manager.SetFocus(dummy1);
377 DALI_TEST_CHECK(dummy1 == manager.GetCurrentFocusControl());
378 DALI_TEST_CHECK(dummy1Impl.keyInputFocusGained);
379 DALI_TEST_CHECK(!dummy1Impl.keyInputFocusLost);
380 dummy1Impl.keyInputFocusGained = false;
381 dummy1Impl.keyInputFocusLost = false;
383 manager.SetFocus(dummy2);
384 DALI_TEST_CHECK(dummy2 == manager.GetCurrentFocusControl());
385 DALI_TEST_CHECK(dummy1Impl.keyInputFocusLost);
386 DALI_TEST_CHECK(dummy2Impl.keyInputFocusGained);
387 DALI_TEST_CHECK(!dummy1Impl.keyInputFocusGained);
388 DALI_TEST_CHECK(!dummy2Impl.keyInputFocusLost);
389 // Reset signal received
390 dummy1Impl.keyInputFocusGained = false;
391 dummy1Impl.keyInputFocusLost = false;
392 dummy2Impl.keyInputFocusGained = false;
393 dummy2Impl.keyInputFocusLost = false;
395 manager.SetFocus(dummy1);
396 DALI_TEST_CHECK(dummy1 == manager.GetCurrentFocusControl());
397 DALI_TEST_CHECK(dummy1Impl.keyInputFocusGained);
398 DALI_TEST_CHECK(dummy2Impl.keyInputFocusLost);
399 DALI_TEST_CHECK(!dummy1Impl.keyInputFocusLost);
400 DALI_TEST_CHECK(!dummy2Impl.keyInputFocusGained);
404 int UtcDaliKeyInputFocusManagerRemoveFocus(void)
406 ToolkitTestApplication application;
407 Integration::Scene stage = application.GetScene();
409 tet_infoline(" Add focus controls. Test that removing focus from control which has focus. ");
411 KeyInputFocusManager manager = KeyInputFocusManager::Get();
412 DALI_TEST_CHECK(manager);
414 DummyControl dummy1 = DummyControl::New(true);
415 Impl::DummyControl& dummy1Impl = static_cast<Impl::DummyControl&>(dummy1.GetImplementation());
416 dummy1.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
418 DALI_TEST_CHECK(!dummy1Impl.keyInputFocusGained);
419 DALI_TEST_CHECK(!dummy1Impl.keyInputFocusLost);
421 manager.SetFocus(dummy1);
422 DALI_TEST_CHECK(dummy1 == manager.GetCurrentFocusControl());
423 dummy1Impl.keyInputFocusGained = false;
424 dummy1Impl.keyInputFocusLost = false;
426 manager.RemoveFocus(dummy1);
427 DALI_TEST_CHECK(Control() == manager.GetCurrentFocusControl());
428 DALI_TEST_CHECK(dummy1Impl.keyInputFocusLost);
429 DALI_TEST_CHECK(!dummy1Impl.keyInputFocusGained);
434 int UtcDaliKeyInputFocusManagerSignalKeyInputFocusChanged(void)
436 ToolkitTestApplication application;
437 KeyInputFocusManager manager = KeyInputFocusManager::Get();
438 Integration::Scene stage = application.GetScene();
440 tet_infoline(" UtcDaliKeyInputFocusManagerSignalKeyInputFocusChanged");
442 PushButton pushButton1 = PushButton::New();
443 PushButton pushButton2 = PushButton::New();
445 stage.Add(pushButton1);
446 stage.Add(pushButton2);
448 PushButton gainActor, lostActor;
449 KeyInputFocusChangedCallback callback(gainActor, lostActor);
450 manager.KeyInputFocusChangedSignal().Connect(&callback, &KeyInputFocusChangedCallback::Callback);
452 manager.SetFocus(pushButton1);
454 DALI_TEST_CHECK(gainActor == pushButton1);
455 DALI_TEST_CHECK(lostActor == Control());
460 manager.SetFocus(pushButton2);
462 DALI_TEST_CHECK(gainActor == pushButton2);
463 DALI_TEST_CHECK(lostActor == pushButton1);
468 // Removing the focus actor from the stage would also result in signal emission.
469 stage.Remove(pushButton1);
470 stage.Remove(pushButton2);
472 DALI_TEST_CHECK(gainActor == Control());
473 DALI_TEST_CHECK(lostActor == Control());
477 int UtcDaliKeyInputFocusManagerSignalKeyInputFocusChangedforNewWindow(void)
479 ToolkitTestApplication application;
480 KeyInputFocusManager manager = KeyInputFocusManager::Get();
482 tet_infoline(" UtcDaliKeyInputFocusManagerSignalKeyInputFocusChanged");
484 PushButton pushButton1 = PushButton::New();
485 PushButton pushButton2 = PushButton::New();
487 Window window = Window::New(PositionSize(0, 0, 0, 0), "", false);
488 DALI_TEST_CHECK(window);
490 window.Add(pushButton1);
491 window.Add(pushButton2);
493 PushButton gainActor, lostActor;
494 KeyInputFocusChangedCallback callback(gainActor, lostActor);
495 manager.KeyInputFocusChangedSignal().Connect(&callback, &KeyInputFocusChangedCallback::Callback);
497 manager.SetFocus(pushButton1);
499 DALI_TEST_CHECK(gainActor == pushButton1);
500 DALI_TEST_CHECK(lostActor == Control());
505 manager.SetFocus(pushButton2);
507 DALI_TEST_CHECK(gainActor == pushButton2);
508 DALI_TEST_CHECK(lostActor == pushButton1);
513 // Removing the focus actor from the window would also result in signal emission.
514 window.Remove(pushButton1);
515 window.Remove(pushButton2);
516 DALI_TEST_CHECK(gainActor == Control());
517 DALI_TEST_CHECK(lostActor == Control());