66f6ab99e738c4bc1b40e824bef1b50feeaaec9f
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / utc-Dali-KeyboardFocusManager.cpp
1 /*
2  * Copyright (c) 2014 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
21 // Need to override adaptor classes for toolkit test harness, so include
22 // test harness headers before dali headers.
23 #include <dali-toolkit-test-suite-utils.h>
24
25 #include <dali-toolkit/dali-toolkit.h>
26 #include <dali/integration-api/events/key-event-integ.h>
27
28 using namespace Dali;
29 using namespace Dali::Toolkit;
30
31 void utc_dali_toolkit_keyboard_focus_manager_startup(void)
32 {
33   test_return_value = TET_UNDEF;
34 }
35
36 void utc_dali_toolkit_keyboard_focus_manager_cleanup(void)
37 {
38   test_return_value = TET_PASS;
39 }
40
41
42 namespace
43 {
44
45 // Functors to test whether PreFocusChange signal is emitted when the keyboard focus is about to change
46 class PreFocusChangeCallback : public Dali::ConnectionTracker
47 {
48 public:
49   PreFocusChangeCallback(bool& signalReceived)
50   : mSignalVerified(signalReceived),
51     mCurrentFocusedActor(),
52     mProposedActorToFocus(),
53     mDirection(Control::Left)
54   {
55   }
56
57   Actor Callback(Actor currentFocusedActor, Actor proposedActorToFocus, Control::KeyboardFocusNavigationDirection direction)
58   {
59     tet_infoline("Verifying PreFocusChangeCallback()");
60
61     mSignalVerified = true;
62
63     mCurrentFocusedActor = currentFocusedActor;
64     mProposedActorToFocus = proposedActorToFocus;
65     mDirection = direction;
66
67     return mProposedActorToFocus;
68   }
69
70   void Reset()
71   {
72     mSignalVerified = false;
73     mCurrentFocusedActor = Actor();
74     mProposedActorToFocus = Actor();
75     mDirection = Control::Left;
76   }
77
78   bool& mSignalVerified;
79   Actor mCurrentFocusedActor;
80   Actor mProposedActorToFocus;
81   Control::KeyboardFocusNavigationDirection mDirection;
82 };
83
84 // Functors to test whether focus changed signal is emitted when the keyboard focus is changed
85 class FocusChangedCallback : public Dali::ConnectionTracker
86 {
87 public:
88   FocusChangedCallback(bool& signalReceived)
89   : mSignalVerified(signalReceived),
90     mOriginalFocusedActor(),
91     mCurrentFocusedActor()
92   {
93   }
94
95   void Callback(Actor originalFocusedActor, Actor currentFocusedActor)
96   {
97     tet_infoline("Verifying FocusChangedCallback()");
98
99     if(originalFocusedActor == mCurrentFocusedActor)
100     {
101       mSignalVerified = true;
102     }
103
104     mOriginalFocusedActor = originalFocusedActor;
105     mCurrentFocusedActor = currentFocusedActor;
106   }
107
108   void Reset()
109   {
110     mSignalVerified = false;
111   }
112
113   bool& mSignalVerified;
114   Actor mOriginalFocusedActor;
115   Actor mCurrentFocusedActor;
116 };
117
118 // Functors to test whether focus group changed signal is emitted when the keyboard focus group is changed
119 class FocusGroupChangedCallback : public Dali::ConnectionTracker
120 {
121 public:
122   FocusGroupChangedCallback(bool& signalReceived)
123   : mSignalVerified(signalReceived),
124     mCurrentFocusedActor(),
125     mForward(true)
126   {
127   }
128
129   void Callback(Actor currentFocusedActor, bool forward)
130   {
131     tet_infoline("Verifying FocusGroupChangedCallback()");
132
133     mSignalVerified = true;
134
135     mCurrentFocusedActor = currentFocusedActor;
136     mForward = forward;
137   }
138
139   void Reset()
140   {
141     mSignalVerified = false;
142   }
143
144   bool& mSignalVerified;
145   Actor mCurrentFocusedActor;
146   bool mForward;
147 };
148
149 // Functors to test whether focused actor activated signal is emitted when the focused actor is activated
150 class FocusedActorActivatedCallback : public Dali::ConnectionTracker
151 {
152 public:
153   FocusedActorActivatedCallback(bool& signalReceived)
154   : mSignalVerified(signalReceived),
155     mActivatedActor()
156   {
157   }
158
159   void Callback(Actor activatedActor)
160   {
161     tet_infoline("Verifying FocusedActorActivatedCallback()");
162
163     mSignalVerified = true;
164
165     mActivatedActor = activatedActor;
166   }
167
168   void Reset()
169   {
170     mSignalVerified = false;
171   }
172
173   bool& mSignalVerified;
174   Actor mActivatedActor;
175 };
176
177 } // namespace
178
179
180 int UtcDaliKeyboardFocusManagerGet(void)
181 {
182   ToolkitTestApplication application;
183
184   tet_infoline(" UtcDaliKeyboardKeyboardFocusManagerGet");
185
186   KeyboardFocusManager manager;
187
188   manager = KeyboardFocusManager::Get();
189   DALI_TEST_CHECK(manager);
190
191   KeyboardFocusManager newManager = KeyboardFocusManager::Get();
192   DALI_TEST_CHECK(newManager);
193
194   // Check that focus manager is a singleton
195   DALI_TEST_CHECK(manager == newManager);
196   END_TEST;
197 }
198
199 int UtcDaliKeyboardFocusManagerSetAndGetCurrentFocusActor(void)
200 {
201   ToolkitTestApplication application;
202
203   tet_infoline(" UtcDaliKeyboardFocusManagerSetAndGetCurrentFocusActor");
204
205   KeyboardFocusManager manager = KeyboardFocusManager::Get();
206   DALI_TEST_CHECK(manager);
207
208   // Create the first actor and add it to the stage
209   Actor first = Actor::New();
210   first.SetKeyboardFocusable(true);
211   Stage::GetCurrent().Add(first);
212
213   // Create the second actor and add it to the stage
214   Actor second = Actor::New();
215   second.SetKeyboardFocusable(true);
216   Stage::GetCurrent().Add(second);
217
218   // Create the third actor but don't add it to the stage
219   Actor third = Actor::New();
220
221   // Check that no actor is being focused yet.
222   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
223
224   // Check that it will fail to set focus on an invalid actor
225   DALI_TEST_CHECK(manager.SetCurrentFocusActor(Actor()) == false);
226
227   // Check that the focus is set on the first actor
228   DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
229   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
230
231   // Check that the focus is set on the second actor
232   DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
233   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
234
235   // Check that it will fail to set focus on the third actor as it's not in the stage
236   DALI_TEST_CHECK(manager.SetCurrentFocusActor(third) == false);
237   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
238
239   // Add the third actor to the stage
240   Stage::GetCurrent().Add(third);
241
242   // Check that it will fail to set focus on the third actor as it's not focusable
243   DALI_TEST_CHECK(manager.SetCurrentFocusActor(third) == false);
244   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
245
246   // Make the third actor focusable
247   third.SetKeyboardFocusable(true);
248
249   // Check that the focus is successfully moved to the third actor
250   DALI_TEST_CHECK(manager.SetCurrentFocusActor(third) == true);
251   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == third);
252   END_TEST;
253 }
254
255 int UtcDaliKeyboardFocusManagerMoveFocus(void)
256 {
257   ToolkitTestApplication application;
258
259   tet_infoline(" UtcDaliKeyboardFocusManagerMoveFocus");
260
261   KeyboardFocusManager manager = KeyboardFocusManager::Get();
262   DALI_TEST_CHECK(manager);
263
264   bool preFocusChangeSignalVerified = false;
265   PreFocusChangeCallback preFocusChangeCallback(preFocusChangeSignalVerified);
266   manager.PreFocusChangeSignal().Connect( &preFocusChangeCallback, &PreFocusChangeCallback::Callback );
267
268   bool focusChangedSignalVerified = false;
269   FocusChangedCallback focusChangedCallback(focusChangedSignalVerified);
270   manager.FocusChangedSignal().Connect( &focusChangedCallback, &FocusChangedCallback::Callback );
271
272   // Create the first actor and add it to the stage
273   Actor first = Actor::New();
274   first.SetKeyboardFocusable(true);
275   Stage::GetCurrent().Add(first);
276
277   // Create the second actor and add it to the stage
278   Actor second = Actor::New();
279   second.SetKeyboardFocusable(true);
280   Stage::GetCurrent().Add(second);
281
282   // Move the focus to the right
283   DALI_TEST_CHECK(manager.MoveFocus(Control::Right) == false);
284
285   // Because no layout control in the stage and no actor is focused, it should emit the PreFocusChange signal
286   DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
287   DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == Actor());
288   DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
289   DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::Right);
290   preFocusChangeCallback.Reset();
291
292   // Check that the focus is set on the first actor
293   DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
294   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
295   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
296   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == Actor());
297   DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == first);
298   focusChangedCallback.Reset();
299
300   // Move the focus towards right
301   DALI_TEST_CHECK(manager.MoveFocus(Control::Right) == false);
302
303   // Because no layout control in the stage and the first actor is focused, it should emit the PreFocusChange signal
304   DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
305   DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == first);
306   DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
307   DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::Right);
308   preFocusChangeCallback.Reset();
309
310   // Check that the focus is set on the second actor
311   DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
312   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
313   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
314   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == first);
315   DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == second);
316   focusChangedCallback.Reset();
317
318   // Move the focus towards up
319   DALI_TEST_CHECK(manager.MoveFocus(Control::Up) == false);
320
321   // Because no layout control in the stage and no actor is focused, it should emit the PreFocusChange signal
322   DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
323   DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == second);
324   DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
325   DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::Up);
326   preFocusChangeCallback.Reset();
327   DALI_TEST_CHECK(!focusChangedCallback.mSignalVerified);
328
329   END_TEST;
330 }
331
332 int UtcDaliKeyboardFocusManagerClearFocus(void)
333 {
334   ToolkitTestApplication application;
335
336   tet_infoline(" UtcDaliKeyboardFocusManagerClearFocus");
337
338   KeyboardFocusManager manager = KeyboardFocusManager::Get();
339   DALI_TEST_CHECK(manager);
340
341   // Create the first actor and add it to the stage
342   Actor first = Actor::New();
343   first.SetKeyboardFocusable(true);
344   Stage::GetCurrent().Add(first);
345
346   // Create the second actor and add it to the stage
347   Actor second = Actor::New();
348   second.SetKeyboardFocusable(true);
349   Stage::GetCurrent().Add(second);
350
351   // Check that the focus is set on the first actor
352   DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
353   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
354
355   // Check that the focus is set on the second actor
356   DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
357   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
358
359   // Clear the focus
360   manager.ClearFocus();
361
362   // Check that no actor is being focused now.
363   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
364   END_TEST;
365 }
366
367 int UtcDaliKeyboardFocusManagerSetAndGetFocusGroupLoop(void)
368 {
369   ToolkitTestApplication application;
370
371   tet_infoline(" UtcDaliKeyboardFocusManagerSetAndGetFocusGroupLoop");
372
373   KeyboardFocusManager manager = KeyboardFocusManager::Get();
374   DALI_TEST_CHECK(manager);
375
376   // Check that the focus movement is not looped within the same focus group by default
377   DALI_TEST_CHECK(manager.GetFocusGroupLoop() == false);
378
379   // Enable the loop
380   manager.SetFocusGroupLoop(true);
381   DALI_TEST_CHECK(manager.GetFocusGroupLoop() == true);
382   END_TEST;
383 }
384
385 int UtcDaliKeyboardFocusManagerSetAsFocusGroup(void)
386 {
387   ToolkitTestApplication application;
388
389   tet_infoline(" UtcDaliKeyboardFocusManagerSetAsFocusGroup");
390
391   KeyboardFocusManager manager = KeyboardFocusManager::Get();
392   DALI_TEST_CHECK(manager);
393
394   // Create an actor and check that it is not a focus group by default
395   Actor actor = Actor::New();
396   DALI_TEST_CHECK(manager.IsFocusGroup(actor) == false);
397
398   // Set the actor as focus group
399   manager.SetAsFocusGroup(actor, true);
400
401   // flush the queue and render once
402   application.SendNotification();
403   application.Render();
404
405   DALI_TEST_CHECK(manager.IsFocusGroup(actor) == true);
406
407   // Set the actor not as focus group
408   manager.SetAsFocusGroup(actor, false);
409
410   // flush the queue and render once
411   application.SendNotification();
412   application.Render();
413
414   DALI_TEST_CHECK(manager.IsFocusGroup(actor) == false);
415   END_TEST;
416 }
417
418 int UtcDaliKeyboardFocusManagerGetFocusGroup(void)
419 {
420   ToolkitTestApplication application;
421
422   tet_infoline(" UtcDaliKeyboardFocusManagerGetFocusGroup");
423
424   KeyboardFocusManager manager = KeyboardFocusManager::Get();
425   DALI_TEST_CHECK(manager);
426
427   // Create an actor with two child actors and add it to the stage
428   Actor parent = Actor::New();
429   Actor child = Actor::New();
430   parent.Add(child);
431   Stage::GetCurrent().Add(parent);
432
433   // Create three actors and add them as the children of the first child actor
434   Actor grandChild = Actor::New();
435   child.Add(grandChild);
436
437   // Set the parent and the first child actor as focus groups
438   manager.SetAsFocusGroup(parent, true);
439
440   // flush the queue and render once
441   application.SendNotification();
442   application.Render();
443
444   DALI_TEST_CHECK(manager.IsFocusGroup(parent) == true);
445
446   // The current focus group should be the parent, As it is the immediate parent which is also a focus group.
447   DALI_TEST_CHECK(manager.GetFocusGroup(grandChild) == parent);
448
449   manager.SetAsFocusGroup(child, true);
450
451   // flush the queue and render once
452   application.SendNotification();
453   application.Render();
454
455   DALI_TEST_CHECK(manager.IsFocusGroup(child) == true);
456
457   // The focus group should be the child, As it is the immediate parent which is also a focus group.
458   DALI_TEST_CHECK(manager.GetFocusGroup(grandChild) == child);
459
460   manager.SetAsFocusGroup(grandChild, true);
461
462   // flush the queue and render once
463   application.SendNotification();
464   application.Render();
465
466   DALI_TEST_CHECK(manager.IsFocusGroup(grandChild) == true);
467
468   // The current focus group should be itself, As it is also a focus group.
469   DALI_TEST_CHECK(manager.GetFocusGroup(grandChild) == grandChild);
470   END_TEST;
471 }
472
473 int UtcDaliKeyboardFocusManagerSetAndGetFocusIndicator(void)
474 {
475   ToolkitTestApplication application;
476
477   tet_infoline(" UtcDaliKeyboardFocusManagerSetAndGetFocusIndicator");
478
479   KeyboardFocusManager manager = KeyboardFocusManager::Get();
480   DALI_TEST_CHECK(manager);
481
482   Actor defaultFocusIndicatorActor = manager.GetFocusIndicatorActor();
483   DALI_TEST_CHECK(defaultFocusIndicatorActor);
484
485   Actor newFocusIndicatorActor = Actor::New();
486   manager.SetFocusIndicatorActor(newFocusIndicatorActor);
487   DALI_TEST_CHECK(manager.GetFocusIndicatorActor() == newFocusIndicatorActor);
488   END_TEST;
489 }
490
491
492 int UtcDaliKeyboardFocusManagerSignalFocusedActorActivated(void)
493 {
494   ToolkitTestApplication application;
495
496   tet_infoline(" UtcDaliKeyboardFocusManagerSignalFocusedActorActivated");
497
498   KeyboardFocusManager manager = KeyboardFocusManager::Get();
499   DALI_TEST_CHECK(manager);
500
501   bool focusedActorActivatedSignalVerified = false;
502   FocusedActorActivatedCallback focusedActorActivatedCallback(focusedActorActivatedSignalVerified);
503   manager.FocusedActorActivatedSignal().Connect( &focusedActorActivatedCallback, &FocusedActorActivatedCallback::Callback );
504
505   Integration::KeyEvent returnEvent("Return", "", 0, 0, 0, Integration::KeyEvent::Up);
506
507   // Create the first button and add it to the stage
508   PushButton firstPushButton = PushButton::New();
509   firstPushButton.SetKeyboardFocusable(true);
510   Stage::GetCurrent().Add(firstPushButton);
511
512   // Create the second button and add it to the stage
513   PushButton secondPushButton = PushButton::New();
514   secondPushButton.SetKeyboardFocusable(true);
515   Stage::GetCurrent().Add(secondPushButton);
516
517   // Check that the focus is set on the first button
518   DALI_TEST_CHECK(manager.SetCurrentFocusActor(firstPushButton) == true);
519   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == firstPushButton);
520
521   // Send the return event to activate the first button
522   application.ProcessEvent(returnEvent);
523   DALI_TEST_CHECK(focusedActorActivatedCallback.mSignalVerified);
524   DALI_TEST_CHECK(focusedActorActivatedCallback.mActivatedActor == firstPushButton);
525   focusedActorActivatedCallback.Reset();
526
527   // Check that the focus is set on the second button
528   DALI_TEST_CHECK(manager.SetCurrentFocusActor(secondPushButton) == true);
529   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == secondPushButton);
530
531   // Send the return event again to activate the second button
532   application.ProcessEvent(returnEvent);
533   DALI_TEST_CHECK(focusedActorActivatedCallback.mSignalVerified);
534   DALI_TEST_CHECK(focusedActorActivatedCallback.mActivatedActor == secondPushButton);
535   focusedActorActivatedCallback.Reset();
536   END_TEST;
537 }