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