86d0451d99396c21f5715fda244ada617ff5743a
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-unmanaged / 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 #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
24
25 using namespace Dali;
26 using namespace Dali::Toolkit;
27
28 void dali_keyboard_focus_manager_startup(void)
29 {
30   test_return_value = TET_UNDEF;
31 }
32
33 void dali_keyboard_focus_manager_cleanup(void)
34 {
35   test_return_value = TET_PASS;
36 }
37
38
39 namespace
40 {
41
42 // Functors to test whether PreFocusChange signal is emitted when the keyboard focus is about to change
43 class PreFocusChangeCallback : public Dali::ConnectionTracker
44 {
45 public:
46   PreFocusChangeCallback(bool& signalReceived)
47   : mSignalVerified(signalReceived),
48     mCurrentFocusedActor(),
49     mProposedActorToFocus(),
50     mDirection(Control::Left)
51   {
52   }
53
54   Actor Callback(Actor currentFocusedActor, Actor proposedActorToFocus, Control::KeyboardFocusNavigationDirection direction)
55   {
56     tet_infoline("Verifying PreFocusChangeCallback()");
57
58     mSignalVerified = true;
59
60     mCurrentFocusedActor = currentFocusedActor;
61     mProposedActorToFocus = proposedActorToFocus;
62     mDirection = direction;
63
64     return mProposedActorToFocus;
65   }
66
67   void Reset()
68   {
69     mSignalVerified = false;
70     mCurrentFocusedActor = Actor();
71     mProposedActorToFocus = Actor();
72     mDirection = Control::Left;
73   }
74
75   bool& mSignalVerified;
76   Actor mCurrentFocusedActor;
77   Actor mProposedActorToFocus;
78   Control::KeyboardFocusNavigationDirection mDirection;
79 };
80
81 // Functors to test whether focus changed signal is emitted when the keyboard focus is changed
82 class FocusChangedCallback : public Dali::ConnectionTracker
83 {
84 public:
85   FocusChangedCallback(bool& signalReceived)
86   : mSignalVerified(signalReceived),
87     mOriginalFocusedActor(),
88     mCurrentFocusedActor()
89   {
90   }
91
92   void Callback(Actor originalFocusedActor, Actor currentFocusedActor)
93   {
94     tet_infoline("Verifying FocusChangedCallback()");
95
96     if(originalFocusedActor == mCurrentFocusedActor)
97     {
98       mSignalVerified = true;
99     }
100
101     mOriginalFocusedActor = originalFocusedActor;
102     mCurrentFocusedActor = currentFocusedActor;
103   }
104
105   void Reset()
106   {
107     mSignalVerified = false;
108   }
109
110   bool& mSignalVerified;
111   Actor mOriginalFocusedActor;
112   Actor mCurrentFocusedActor;
113 };
114
115 // Functors to test whether focus group changed signal is emitted when the keyboard focus group is changed
116 class FocusGroupChangedCallback : public Dali::ConnectionTracker
117 {
118 public:
119   FocusGroupChangedCallback(bool& signalReceived)
120   : mSignalVerified(signalReceived),
121     mCurrentFocusedActor(),
122     mForward(true)
123   {
124   }
125
126   void Callback(Actor currentFocusedActor, bool forward)
127   {
128     tet_infoline("Verifying FocusGroupChangedCallback()");
129
130     mSignalVerified = true;
131
132     mCurrentFocusedActor = currentFocusedActor;
133     mForward = forward;
134   }
135
136   void Reset()
137   {
138     mSignalVerified = false;
139   }
140
141   bool& mSignalVerified;
142   Actor mCurrentFocusedActor;
143   bool mForward;
144 };
145
146 // Functors to test whether focused actor activated signal is emitted when the focused actor is activated
147 class FocusedActorActivatedCallback : public Dali::ConnectionTracker
148 {
149 public:
150   FocusedActorActivatedCallback(bool& signalReceived)
151   : mSignalVerified(signalReceived),
152     mActivatedActor()
153   {
154   }
155
156   void Callback(Actor activatedActor)
157   {
158     tet_infoline("Verifying FocusedActorActivatedCallback()");
159
160     mSignalVerified = true;
161
162     mActivatedActor = activatedActor;
163   }
164
165   void Reset()
166   {
167     mSignalVerified = false;
168   }
169
170   bool& mSignalVerified;
171   Actor mActivatedActor;
172 };
173
174 } // namespace
175
176
177
178 int UtcDaliKeyboardFocusManagerGet(void)
179 {
180   ToolkitTestApplication application;
181
182   tet_infoline(" UtcDaliKeyboardKeyboardFocusManagerGet");
183
184   // Register Type
185   TypeInfo type;
186   type = TypeRegistry::Get().GetTypeInfo( "KeyboardFocusManager" );
187   DALI_TEST_CHECK( type );
188   BaseHandle handle = type.CreateInstance();
189   DALI_TEST_CHECK( handle );
190
191   KeyboardFocusManager manager;
192
193   manager = KeyboardFocusManager::Get();
194   DALI_TEST_CHECK(manager);
195
196   KeyboardFocusManager newManager = KeyboardFocusManager::Get();
197   DALI_TEST_CHECK(newManager);
198
199   // Check that focus manager is a singleton
200   DALI_TEST_CHECK(manager == newManager);
201   END_TEST;
202 }
203
204
205
206 int UtcDaliKeyboardFocusManagerMoveFocus(void)
207 {
208   ToolkitTestApplication application;
209
210   tet_infoline(" UtcDaliKeyboardFocusManagerMoveFocus");
211
212   // Register Type
213   TypeInfo type;
214   type = TypeRegistry::Get().GetTypeInfo( "KeyboardFocusManager" );
215   DALI_TEST_CHECK( type );
216   BaseHandle handle = type.CreateInstance();
217   DALI_TEST_CHECK( handle );
218
219   KeyboardFocusManager manager = KeyboardFocusManager::Get();
220   DALI_TEST_CHECK(manager);
221
222   bool preFocusChangeSignalVerified = false;
223   PreFocusChangeCallback preFocusChangeCallback(preFocusChangeSignalVerified);
224   manager.PreFocusChangeSignal().Connect( &preFocusChangeCallback, &PreFocusChangeCallback::Callback );
225
226   bool focusChangedSignalVerified = false;
227   FocusChangedCallback focusChangedCallback(focusChangedSignalVerified);
228   manager.FocusChangedSignal().Connect( &focusChangedCallback, &FocusChangedCallback::Callback );
229
230   // Create the first actor and add it to the stage
231   Actor first = Actor::New();
232   first.SetKeyboardFocusable(true);
233   Stage::GetCurrent().Add(first);
234
235   // Create the second actor and add it to the stage
236   Actor second = Actor::New();
237   second.SetKeyboardFocusable(true);
238   Stage::GetCurrent().Add(second);
239
240   // Move the focus to the right
241   DALI_TEST_CHECK(manager.MoveFocus(Control::Right) == false);
242
243   // Because no layout control in the stage and no actor is focused, it should emit the PreFocusChange signal
244   DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
245   DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == Actor());
246   DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
247   DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::Right);
248   preFocusChangeCallback.Reset();
249
250   // Check that the focus is set on the first actor
251   DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
252   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
253   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
254   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == Actor());
255   DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == first);
256   focusChangedCallback.Reset();
257
258   // Move the focus towards right
259   DALI_TEST_CHECK(manager.MoveFocus(Control::Right) == false);
260
261   // Because no layout control in the stage and the first actor is focused, it should emit the PreFocusChange signal
262   DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
263   DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == first);
264   DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
265   DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::Right);
266   preFocusChangeCallback.Reset();
267
268   // Check that the focus is set on the second actor
269   DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
270   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
271   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
272   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == first);
273   DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == second);
274   focusChangedCallback.Reset();
275
276   // Move the focus towards up
277   DALI_TEST_CHECK(manager.MoveFocus(Control::Up) == false);
278
279   // Because no layout control in the stage and no actor is focused, it should emit the PreFocusChange signal
280   DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
281   DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == second);
282   DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
283   DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::Up);
284   preFocusChangeCallback.Reset();
285   DALI_TEST_CHECK(!focusChangedCallback.mSignalVerified);
286
287   // Create a 2x2 table view and try to move focus inside it
288   TableView tableView = TableView::New( 2, 2 );
289   Stage::GetCurrent().Add(tableView);
290
291   // Create the third actor
292   Actor third = Actor::New();
293   third.SetKeyboardFocusable(true);
294
295   // Create the fourth actor
296   Actor fourth = Actor::New();
297   fourth.SetKeyboardFocusable(true);
298
299   // Add the four children to table view
300   tableView.AddChild(first, TableView::CellPosition(0, 0));
301   tableView.AddChild(second, TableView::CellPosition(0, 1));
302   tableView.AddChild(third, TableView::CellPosition(1, 0));
303   tableView.AddChild(fourth, TableView::CellPosition(1, 1));
304
305   // Set the focus to the first actor
306   DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
307   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
308   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
309   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == second);
310   DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == first);
311   focusChangedCallback.Reset();
312
313   // Move the focus towards right
314   DALI_TEST_CHECK(manager.MoveFocus(Control::Right) == true);
315   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
316   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
317   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == first);
318   DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == second);
319   focusChangedCallback.Reset();
320
321   // Move the focus towards down
322   DALI_TEST_CHECK(manager.MoveFocus(Control::Down) == true);
323   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == fourth);
324   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
325   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == second);
326   DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == fourth);
327   focusChangedCallback.Reset();
328
329   // Move the focus towards left
330   DALI_TEST_CHECK(manager.MoveFocus(Control::Left) == true);
331   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == third);
332   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
333   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == fourth);
334   DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == third);
335   focusChangedCallback.Reset();
336
337   // Move the focus towards up
338   DALI_TEST_CHECK(manager.MoveFocus(Control::Up) == true);
339   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
340   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
341   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == third);
342   DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == first);
343   focusChangedCallback.Reset();
344
345   // Move the focus towards left. The focus move will fail as no way to move it upwards
346   DALI_TEST_CHECK(manager.MoveFocus(Control::Left) == false);
347   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
348   DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
349   DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == first);
350   DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
351   DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::Left);
352   preFocusChangeCallback.Reset();
353   DALI_TEST_CHECK(!focusChangedCallback.mSignalVerified);
354
355   // Enable the loop
356   manager.SetFocusGroupLoop(true);
357   DALI_TEST_CHECK(manager.GetFocusGroupLoop() == true);
358
359   // Move the focus towards left again. The focus should move to the fourth actor.
360   DALI_TEST_CHECK(manager.MoveFocus(Control::Left) == true);
361   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == fourth);
362   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
363   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == first);
364   DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == fourth);
365   focusChangedCallback.Reset();
366   END_TEST;
367 }
368
369
370 int UtcDaliKeyboardFocusManagerSignalFocusGroupChanged(void)
371 {
372   ToolkitTestApplication application;
373
374   tet_infoline(" UtcDaliKeyboardFocusManagerSignalFocusGroupChanged");
375
376   // Register Type
377   TypeInfo type;
378   type = TypeRegistry::Get().GetTypeInfo( "KeyboardFocusManager" );
379   DALI_TEST_CHECK( type );
380   BaseHandle handle = type.CreateInstance();
381   DALI_TEST_CHECK( handle );
382
383   KeyboardFocusManager manager = KeyboardFocusManager::Get();
384   DALI_TEST_CHECK(manager);
385
386   bool focusGroupChangedSignalVerified = false;
387   FocusGroupChangedCallback focusGroupChangedCallback(focusGroupChangedSignalVerified);
388   manager.FocusGroupChangedSignal().Connect( &focusGroupChangedCallback, &FocusGroupChangedCallback::Callback );
389
390   Integration::KeyEvent tabEvent("Tab", "", 0, 0, 0, Integration::KeyEvent::Down);
391   Integration::KeyEvent shiftTabEvent("Tab", "", 0, 1, 0, Integration::KeyEvent::Down);
392
393   // Send the tab event to change focus group in the forward direction
394   application.ProcessEvent(tabEvent);
395   DALI_TEST_CHECK(focusGroupChangedCallback.mSignalVerified);
396   DALI_TEST_CHECK(focusGroupChangedCallback.mCurrentFocusedActor == Actor());
397   DALI_TEST_CHECK(focusGroupChangedCallback.mForward == true);
398   focusGroupChangedCallback.Reset();
399
400   // Send the shift tab event to change focus group in the backward direction
401   application.ProcessEvent(shiftTabEvent);
402   DALI_TEST_CHECK(focusGroupChangedCallback.mSignalVerified);
403   DALI_TEST_CHECK(focusGroupChangedCallback.mCurrentFocusedActor == Actor());
404   DALI_TEST_CHECK(focusGroupChangedCallback.mForward == false);
405   focusGroupChangedCallback.Reset();
406   END_TEST;
407 }