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