[dali_2.0.15] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / utc-Dali-KeyInputFocusManager.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include <iostream>
19 #include <stdlib.h>
20 #include <dali-toolkit-test-suite-utils.h>
21 #include <dali-toolkit/dali-toolkit.h>
22 #include <dali/integration-api/events/key-event-integ.h>
23 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
24 #include <dali/devel-api/common/stage-devel.h>
25
26 #include "dummy-control.h"
27
28 using namespace Dali;
29 using namespace Toolkit;
30
31 namespace
32 {
33
34 /**
35  * Callback class for KeyInputFocusChanged signal.
36  */
37 class KeyInputFocusChangedCallback : public Dali::ConnectionTracker
38 {
39 public:
40   /**
41    * Constructor
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.
44    */
45   KeyInputFocusChangedCallback( Control& gainActor, Control& lostActor )
46   : mActorGain( gainActor ),
47     mActorLost( lostActor )
48   {
49   }
50
51   void Callback( Control gainingActor, Control lostActor )
52   {
53     mActorGain = gainingActor;
54     mActorLost = lostActor;
55   }
56
57   Control& mActorGain;
58   Control& mActorLost;
59 };
60
61 // Stores data that is populated in the callback and will be read by the TET cases
62 struct SignalData
63 {
64   SignalData()
65   : functorCalled(false)
66   {}
67
68   void Reset()
69   {
70     functorCalled = false;
71
72     receivedKeyEvent.Reset();
73
74   }
75
76   bool functorCalled;
77   KeyEvent receivedKeyEvent;
78 };
79
80 /**
81  * Callback class for KeyEvent signal of control.
82  */
83 class KeyEventCallback : public Dali::ConnectionTracker
84 {
85 public:
86   /**
87    * Constructor
88    * @param[in]  returnValue  Set return value of KeyEvent callback.
89    * */
90   KeyEventCallback( bool consumed )
91   : mConsumed( consumed ),
92     mIsCalled( false )
93   {
94   }
95
96   bool Callback( Control control, const KeyEvent& keyEvent )
97   {
98     mIsCalled = true;
99     return mConsumed;
100   }
101
102   void Callback( const KeyEvent& keyEvent )
103   {
104     mIsCalled = true;
105   }
106
107   bool mConsumed;
108   bool mIsCalled;
109 };
110
111 } // namespace
112
113 void key_input_focus_manager_startup(void)
114 {
115   test_return_value = TET_UNDEF;
116 }
117
118 void key_input_focus_manager_cleanup(void)
119 {
120   test_return_value = TET_PASS;
121 }
122
123 int UtcDaliKeyInputFocusManagerGet(void)
124 {
125   ToolkitTestApplication application;
126
127   tet_infoline(" UtcDaliKeyInputFocusManagerGet");
128
129   KeyInputFocusManager manager;
130   {
131     manager = KeyInputFocusManager::Get();
132     DALI_TEST_CHECK(manager);
133   }
134
135   KeyInputFocusManager newManager = KeyInputFocusManager::Get();
136   DALI_TEST_CHECK(newManager);
137
138   // Check that focus manager is a singleton
139   DALI_TEST_CHECK(manager == newManager);
140
141   END_TEST;
142 }
143
144 int UtcDaliKeyInputFocusManagerSetFocus01(void)
145 {
146   ToolkitTestApplication application;
147   Integration::Scene stage = application.GetScene();
148
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");
150
151   KeyInputFocusManager manager = KeyInputFocusManager::Get();
152   DALI_TEST_CHECK(manager);
153
154   Control focusedControl = manager.GetCurrentFocusControl();
155   DALI_TEST_CHECK( ! focusedControl );
156
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) );
160   stage.Add( dummy );
161   DALI_TEST_CHECK( ! dummyImpl.keyInputFocusGained );
162
163   manager.SetFocus( dummy );
164   DALI_TEST_CHECK( dummy.HasKeyInputFocus()); // Also tests IsKeyboardListener() API
165   DALI_TEST_CHECK( dummyImpl.keyInputFocusGained );
166
167   focusedControl = manager.GetCurrentFocusControl();
168   DALI_TEST_CHECK( focusedControl );
169   DALI_TEST_CHECK( focusedControl == dummy );
170
171   END_TEST;
172 }
173
174 int UtcDaliKeyInputFocusManagerSetFocus02(void)
175 {
176   ToolkitTestApplication application;
177   Integration::Scene stage = application.GetScene();
178
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");
180
181   KeyInputFocusManager manager = KeyInputFocusManager::Get();
182   DALI_TEST_CHECK(manager);
183
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) );
187   stage.Add( dummy1 );
188   DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained );
189   DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost );
190
191   manager.SetFocus( dummy1 );
192   DALI_TEST_CHECK( dummy1.HasKeyInputFocus()); // Also tests IsKeyboardListener() API
193   DALI_TEST_CHECK( dummy1Impl.keyInputFocusGained );
194   dummy1Impl.keyInputFocusGained = false;
195
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) );
199   stage.Add( dummy2 );
200   DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained );
201   DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost );
202
203   manager.SetFocus( dummy2 );
204   DALI_TEST_CHECK( dummy2.HasKeyInputFocus()); // Also tests IsKeyboardListener() API
205   DALI_TEST_CHECK( dummy2Impl.keyInputFocusGained );
206   dummy1Impl.keyInputFocusGained = false;
207
208   DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained );
209   DALI_TEST_CHECK( dummy1Impl.keyInputFocusLost );
210
211   END_TEST;
212 }
213
214 int UtcDaliKeyInputFocusManagerKeyEventPropagation01(void)
215 {
216
217   ToolkitTestApplication application;
218   Integration::Scene stage = application.GetScene();
219
220   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
222   KeyInputFocusManager manager = KeyInputFocusManager::Get();
223   DALI_TEST_CHECK(manager);
224
225   KeyEventCallback stageCallback( false );
226   stage.KeyEventSignal().Connect( &stageCallback, &KeyEventCallback::Callback );
227
228   DummyControl dummy1 = DummyControl::New(true);
229   dummy1.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) );
230   KeyEventCallback callback1( false );
231   dummy1.KeyEventSignal().Connect( &callback1, &KeyEventCallback::Callback );
232   stage.Add( dummy1 );
233
234   DummyControl dummy2 = DummyControl::New(true);
235   dummy2.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) );
236   KeyEventCallback callback2( false );
237   dummy2.KeyEventSignal().Connect( &callback2, &KeyEventCallback::Callback );
238   dummy1.Add( dummy2 );
239
240   DummyControl dummy3 = DummyControl::New(true);
241   Impl::DummyControl& dummy3Impl = static_cast<Impl::DummyControl&>(dummy3.GetImplementation());
242   dummy3.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) );
243   KeyEventCallback callback3( false );
244   dummy3.KeyEventSignal().Connect( &callback3, &KeyEventCallback::Callback );
245   dummy2.Add( dummy3 );
246   DALI_TEST_CHECK( ! dummy3Impl.keyInputFocusGained );
247   DALI_TEST_CHECK( ! dummy3Impl.keyInputFocusLost );
248
249   manager.SetFocus( dummy3 );
250   DALI_TEST_CHECK( dummy3Impl.keyInputFocusGained );
251
252   Integration::KeyEvent event( "a", "", "a", 0, 0, 0, Integration::KeyEvent::UP, "", "", Device::Class::TOUCH, Device::Subclass::NONE );
253   application.ProcessEvent(event);
254
255   DALI_TEST_CHECK( callback1.mIsCalled );
256   DALI_TEST_CHECK( callback2.mIsCalled );
257   DALI_TEST_CHECK( callback3.mIsCalled );
258   DALI_TEST_CHECK( stageCallback.mIsCalled );
259
260   END_TEST;
261 }
262
263 int UtcDaliKeyInputFocusManagerKeyEventPropagation02(void)
264 {
265
266   ToolkitTestApplication application;
267   Integration::Scene stage = application.GetScene();
268
269   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");
270
271   KeyInputFocusManager manager = KeyInputFocusManager::Get();
272   DALI_TEST_CHECK(manager);
273
274   DummyControl dummy1 = DummyControl::New(true);
275   dummy1.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) );
276   KeyEventCallback callback1( false );
277   dummy1.KeyEventSignal().Connect( &callback1, &KeyEventCallback::Callback );
278   stage.Add( dummy1 );
279
280   DummyControl dummy2 = DummyControl::New(true);
281   dummy2.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) );
282   KeyEventCallback callback2( true );
283   dummy2.KeyEventSignal().Connect( &callback2, &KeyEventCallback::Callback );
284   dummy1.Add( dummy2 );
285
286   DummyControl dummy3 = DummyControl::New(true);
287   Impl::DummyControl& dummy3Impl = static_cast<Impl::DummyControl&>(dummy3.GetImplementation());
288   dummy3.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) );
289   KeyEventCallback callback3( false );
290   dummy3.KeyEventSignal().Connect( &callback3, &KeyEventCallback::Callback );
291   dummy2.Add( dummy3 );
292   DALI_TEST_CHECK( ! dummy3Impl.keyInputFocusGained );
293   DALI_TEST_CHECK( ! dummy3Impl.keyInputFocusLost );
294
295   manager.SetFocus( dummy3 );
296   DALI_TEST_CHECK( dummy3Impl.keyInputFocusGained );
297
298   Integration::KeyEvent event( "a", "", "a", 0, 0, 0, Integration::KeyEvent::UP, "", "", Device::Class::TOUCH, Device::Subclass::NONE );
299   application.ProcessEvent(event);
300
301   DALI_TEST_CHECK( !callback1.mIsCalled );
302   DALI_TEST_CHECK( callback2.mIsCalled );
303   DALI_TEST_CHECK( callback3.mIsCalled );
304
305   END_TEST;
306 }
307
308 int UtcDaliKeyInputFocusManagerGetCurrentFocusControl(void)
309 {
310   ToolkitTestApplication application;
311   Integration::Scene stage = application.GetScene();
312
313   tet_infoline(" Add 2 controls, check they each get focused. Re-focus the first control - ensure it's now got focus (check signals)");
314
315   KeyInputFocusManager manager = KeyInputFocusManager::Get();
316   DALI_TEST_CHECK(manager);
317
318   DummyControl dummy1 = DummyControl::New(true);
319   Impl::DummyControl& dummy1Impl = static_cast<Impl::DummyControl&>(dummy1.GetImplementation());
320   dummy1.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) );
321   stage.Add( dummy1 );
322   DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained );
323   DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost );
324
325   DummyControl dummy2 = DummyControl::New(true);
326   Impl::DummyControl& dummy2Impl = static_cast<Impl::DummyControl&>(dummy2.GetImplementation());
327   dummy2.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) );
328   stage.Add( dummy2 );
329   DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained );
330   DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusLost );
331
332   manager.SetFocus(dummy1);
333   DALI_TEST_CHECK( dummy1 == manager.GetCurrentFocusControl() );
334   DALI_TEST_CHECK( dummy1Impl.keyInputFocusGained );
335   DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost );
336   dummy1Impl.keyInputFocusGained = false;
337   dummy1Impl.keyInputFocusLost = false;
338
339   manager.SetFocus(dummy2);
340   DALI_TEST_CHECK( dummy2 == manager.GetCurrentFocusControl() );
341   DALI_TEST_CHECK( dummy1Impl.keyInputFocusLost );
342   DALI_TEST_CHECK( dummy2Impl.keyInputFocusGained );
343   DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained );
344   DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusLost );
345   // Reset signal received
346   dummy1Impl.keyInputFocusGained = false;
347   dummy1Impl.keyInputFocusLost = false;
348   dummy2Impl.keyInputFocusGained = false;
349   dummy2Impl.keyInputFocusLost = false;
350
351   manager.SetFocus(dummy1);
352   DALI_TEST_CHECK( dummy1 == manager.GetCurrentFocusControl());
353   DALI_TEST_CHECK( dummy1Impl.keyInputFocusGained );
354   DALI_TEST_CHECK( dummy2Impl.keyInputFocusLost );
355   DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost );
356   DALI_TEST_CHECK( ! dummy2Impl.keyInputFocusGained );
357   END_TEST;
358 }
359
360 int UtcDaliKeyInputFocusManagerRemoveFocus(void)
361 {
362   ToolkitTestApplication application;
363   Integration::Scene stage = application.GetScene();
364
365   tet_infoline(" Add focus controls. Test that removing focus from control which has focus. ");
366
367   KeyInputFocusManager manager = KeyInputFocusManager::Get();
368   DALI_TEST_CHECK(manager);
369
370   DummyControl dummy1 = DummyControl::New(true);
371   Impl::DummyControl& dummy1Impl = static_cast<Impl::DummyControl&>(dummy1.GetImplementation());
372   dummy1.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) );
373   stage.Add( dummy1 );
374   DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained );
375   DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusLost );
376
377   manager.SetFocus(dummy1);
378   DALI_TEST_CHECK(dummy1 == manager.GetCurrentFocusControl());
379   dummy1Impl.keyInputFocusGained = false;
380   dummy1Impl.keyInputFocusLost = false;
381
382   manager.RemoveFocus(dummy1);
383   DALI_TEST_CHECK(Control() == manager.GetCurrentFocusControl());
384   DALI_TEST_CHECK( dummy1Impl.keyInputFocusLost );
385   DALI_TEST_CHECK( ! dummy1Impl.keyInputFocusGained );
386
387   END_TEST;
388 }
389
390 int UtcDaliKeyInputFocusManagerSignalKeyInputFocusChanged(void)
391 {
392   ToolkitTestApplication application;
393   KeyInputFocusManager manager = KeyInputFocusManager::Get();
394   Integration::Scene stage = application.GetScene();
395
396   tet_infoline(" UtcDaliKeyInputFocusManagerSignalKeyInputFocusChanged");
397
398   PushButton pushButton1 = PushButton::New();
399   PushButton pushButton2 = PushButton::New();
400
401   stage.Add( pushButton1 );
402   stage.Add( pushButton2 );
403
404   PushButton gainActor, lostActor;
405   KeyInputFocusChangedCallback callback( gainActor, lostActor );
406   manager.KeyInputFocusChangedSignal().Connect( &callback, &KeyInputFocusChangedCallback::Callback );
407
408   manager.SetFocus(pushButton1);
409
410   DALI_TEST_CHECK( gainActor == pushButton1 );
411   DALI_TEST_CHECK( lostActor == Control() );
412
413   gainActor.Reset();
414   lostActor.Reset();
415
416   manager.SetFocus(pushButton2);
417
418   DALI_TEST_CHECK( gainActor == pushButton2 );
419   DALI_TEST_CHECK( lostActor == pushButton1 );
420
421   gainActor.Reset();
422   lostActor.Reset();
423
424   // Removing the focus actor from the stage would also result in signal emission.
425   stage.Remove( pushButton1 );
426   stage.Remove( pushButton2 );
427
428   DALI_TEST_CHECK( gainActor == Control() );
429   DALI_TEST_CHECK( lostActor == Control() );
430   END_TEST;
431 }
432
433 int UtcDaliKeyInputFocusManagerSignalKeyInputFocusChangedforNewWindow(void)
434 {
435   ToolkitTestApplication application;
436   KeyInputFocusManager manager = KeyInputFocusManager::Get();
437
438   tet_infoline(" UtcDaliKeyInputFocusManagerSignalKeyInputFocusChanged");
439
440   PushButton pushButton1 = PushButton::New();
441   PushButton pushButton2 = PushButton::New();
442
443   Window window = Window::New(PositionSize(0,0,0,0) ,"", false);
444   DALI_TEST_CHECK( window );
445
446   window.Add( pushButton1 );
447   window.Add( pushButton2 );
448
449   PushButton gainActor, lostActor;
450   KeyInputFocusChangedCallback callback( gainActor, lostActor );
451   manager.KeyInputFocusChangedSignal().Connect( &callback, &KeyInputFocusChangedCallback::Callback );
452
453   manager.SetFocus(pushButton1);
454
455   DALI_TEST_CHECK( gainActor == pushButton1 );
456   DALI_TEST_CHECK( lostActor == Control() );
457
458   gainActor.Reset();
459   lostActor.Reset();
460
461   manager.SetFocus(pushButton2);
462
463   DALI_TEST_CHECK( gainActor == pushButton2 );
464   DALI_TEST_CHECK( lostActor == pushButton1 );
465
466   gainActor.Reset();
467   lostActor.Reset();
468
469   // Removing the focus actor from the window would also result in signal emission.
470   window.Remove( pushButton1 );
471   window.Remove( pushButton2 );
472   DALI_TEST_CHECK( gainActor == Control() );
473   DALI_TEST_CHECK( lostActor == Control() );
474
475   window.Reset();
476   END_TEST;
477 }