57c730fa452af87c7f0a6458d3059ccd2cb09fd3
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Stage.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
20 #include <stdlib.h>
21
22 #include <dali/public-api/dali-core.h>
23 #include <dali/integration-api/context-notifier.h>
24 #include <dali/integration-api/events/key-event-integ.h>
25 #include <dali/integration-api/events/touch-event-integ.h>
26
27 #include <dali-test-suite-utils.h>
28
29 using namespace Dali;
30 using namespace std;
31
32 void stage_test_startup(void)
33 {
34   test_return_value = TET_UNDEF;
35 }
36
37 void stage_test_cleanup(void)
38 {
39   test_return_value = TET_PASS;
40 }
41
42 namespace
43 {
44
45 /**
46  * Functor for EventProcessingFinished signal
47  */
48 struct EventProcessingFinishedFunctor
49 {
50   /**
51    * @param[in] eventProcessingFinished reference to a boolean variable used to check if signal has been called.
52    */
53   EventProcessingFinishedFunctor( bool& eventProcessingFinished )
54   : mEventProcessingFinished( eventProcessingFinished )
55   {}
56
57   void operator()()
58   {
59     mEventProcessingFinished = true;
60   }
61
62   bool& mEventProcessingFinished;
63 };
64
65 // Stores data that is populated in the key-event callback and will be read by the TET cases
66 struct KeyEventSignalData
67 {
68   KeyEventSignalData()
69   : functorCalled(false)
70   {}
71
72   void Reset()
73   {
74     functorCalled = false;
75
76     receivedKeyEvent.keyModifier = 0;
77     receivedKeyEvent.keyPressedName.clear();
78     receivedKeyEvent.keyPressed.clear();
79   }
80
81   bool functorCalled;
82   KeyEvent receivedKeyEvent;
83 };
84
85 // Functor that sets the data when called
86 struct KeyEventReceivedFunctor
87 {
88   KeyEventReceivedFunctor( KeyEventSignalData& data ) : signalData( data ) { }
89
90   bool operator()( const KeyEvent& keyEvent )
91   {
92     signalData.functorCalled = true;
93     signalData.receivedKeyEvent = keyEvent;
94
95     return true;
96   }
97
98   KeyEventSignalData& signalData;
99 };
100
101 // Stores data that is populated in the touched signal callback and will be read by the TET cases
102 struct TouchedSignalData
103 {
104   TouchedSignalData()
105   : functorCalled(false)
106   {}
107
108   void Reset()
109   {
110     functorCalled = false;
111
112     receivedTouchEvent.points.clear();
113     receivedTouchEvent.time = 0;
114   }
115
116   bool functorCalled;
117   TouchEvent receivedTouchEvent;
118 };
119
120 // Functor that sets the data when touched signal is received
121 struct TouchedFunctor
122 {
123   TouchedFunctor( TouchedSignalData& data ) : signalData( data ) { }
124
125   void operator()( const TouchEvent& touch )
126   {
127     signalData.functorCalled = true;
128     signalData.receivedTouchEvent = touch;
129   }
130
131   TouchedSignalData& signalData;
132 };
133
134 bool DummyTouchCallback( Actor actor, const TouchEvent& touch )
135 {
136   return true;
137 }
138
139
140 struct ContextStatusFunctor
141 {
142   ContextStatusFunctor(bool& calledFlag) : mCalledFlag( calledFlag )
143   {
144     mCalledFlag = false;
145   }
146
147   void operator()()
148   {
149     mCalledFlag = true;
150   }
151   void Reset()
152   {
153     mCalledFlag = false;
154   }
155
156   bool& mCalledFlag;
157 };
158
159 } // unnamed namespace
160
161
162 int UtcDaliStageDefaultConstructor(void)
163 {
164   TestApplication application;
165   Stage stage;
166
167   DALI_TEST_CHECK(!stage);
168   END_TEST;
169 }
170
171 int UtcDaliStageDestructor(void)
172 {
173   TestApplication application;
174   Stage* stage = new Stage();
175   delete stage;
176   stage = NULL;
177
178   DALI_TEST_CHECK( true );
179   END_TEST;
180 }
181
182 int UtcDaliStageGetCurrent(void)
183 {
184   TestApplication application;
185   Stage stage = Stage::GetCurrent();
186
187   DALI_TEST_CHECK(stage);
188   END_TEST;
189 }
190
191 int UtcDaliStageIsInstalled(void)
192 {
193   DALI_TEST_CHECK(!Stage::IsInstalled());
194
195   TestApplication application;
196
197   Stage::GetCurrent();
198
199   DALI_TEST_CHECK(Stage::IsInstalled());
200   END_TEST;
201 }
202
203 int UtcDaliStageAdd(void)
204 {
205   TestApplication application;
206
207   Stage stage = Stage::GetCurrent();
208
209   Actor actor = Actor::New();
210   DALI_TEST_CHECK(!actor.OnStage());
211
212   stage.Add(actor);
213   DALI_TEST_CHECK(actor.OnStage());
214   END_TEST;
215 }
216
217 int UtcDaliStageRemove(void)
218 {
219   TestApplication application;
220
221   Stage stage = Stage::GetCurrent();
222
223   Actor actor = Actor::New();
224   DALI_TEST_CHECK(!actor.OnStage());
225
226   stage.Add(actor);
227   DALI_TEST_CHECK(actor.OnStage());
228
229   stage.Remove(actor);
230   DALI_TEST_CHECK(!actor.OnStage());
231   END_TEST;
232 }
233
234 int UtcDaliStageGetSize(void)
235 {
236   TestApplication application;
237
238   Stage stage = Stage::GetCurrent();
239
240   Vector2 size = stage.GetSize();
241
242   DALI_TEST_EQUALS(size.width,  static_cast<float>(TestApplication::DEFAULT_SURFACE_WIDTH),  TEST_LOCATION);
243   DALI_TEST_EQUALS(size.height, static_cast<float>(TestApplication::DEFAULT_SURFACE_HEIGHT), TEST_LOCATION);
244   END_TEST;
245 }
246
247 int UtcDaliStageGetDpi01(void)
248 {
249   TestApplication application; // Initializes core DPI to default values
250
251   Stage stage = Stage::GetCurrent();
252
253   // Test the default DPI.
254   Vector2 dpi = stage.GetDpi();
255   DALI_TEST_EQUALS(dpi.x, static_cast<float>(TestApplication::DEFAULT_HORIZONTAL_DPI), TEST_LOCATION);
256   DALI_TEST_EQUALS(dpi.y, static_cast<float>(TestApplication::DEFAULT_VERTICAL_DPI),   TEST_LOCATION);
257   END_TEST;
258 }
259
260 int UtcDaliStageGetDpi02(void)
261 {
262   TestApplication application; // Initializes core DPI to default values
263
264   // Test that setting core DPI explicitly also sets up the Stage's DPI.
265   application.GetCore().SetDpi(200, 180);
266
267   Stage stage = Stage::GetCurrent();
268   Vector2 dpi = stage.GetDpi();
269   DALI_TEST_EQUALS(dpi.x, 200.0f, TEST_LOCATION);
270   DALI_TEST_EQUALS(dpi.y, 180.0f, TEST_LOCATION);
271   END_TEST;
272 }
273
274
275 int UtcDaliStageGetDpi03(void)
276 {
277   TestApplication application(480, 800, 72.0f, 120.0f); // Initializes core DPI with specific values
278
279   Stage stage = Stage::GetCurrent();
280
281   // Test that setting core DPI explicitly also sets up the Stage's DPI.
282   Vector2 dpi = stage.GetDpi();
283   DALI_TEST_EQUALS(dpi.x, 72.0f, TEST_LOCATION);
284   DALI_TEST_EQUALS(dpi.y, 120.0f, TEST_LOCATION);
285   END_TEST;
286 }
287
288 int UtcDaliStageGetLayerCount(void)
289 {
290   TestApplication application;
291
292   Stage stage = Stage::GetCurrent();
293
294   // Initially we have a default layer
295   DALI_TEST_EQUALS(stage.GetLayerCount(), 1u, TEST_LOCATION);
296
297   Layer layer = Layer::New();
298   stage.Add(layer);
299
300   DALI_TEST_EQUALS(stage.GetLayerCount(), 2u, TEST_LOCATION);
301   END_TEST;
302 }
303
304 int UtcDaliStageGetLayer(void)
305 {
306   TestApplication application;
307
308   Stage stage = Stage::GetCurrent();
309
310   Layer rootLayer = stage.GetLayer(0);
311   DALI_TEST_CHECK(rootLayer);
312
313   Layer layer = Layer::New();
314   stage.Add(layer);
315
316   Layer sameLayer = stage.GetLayer(1);
317   DALI_TEST_CHECK(layer == sameLayer);
318   END_TEST;
319 }
320
321
322 int UtcDaliStageGetRootLayer(void)
323 {
324   TestApplication application;
325
326   Stage stage = Stage::GetCurrent();
327
328   Layer rootLayer = stage.GetLayer(0);
329   DALI_TEST_CHECK( rootLayer );
330
331   Layer layer = Layer::New();
332   stage.Add( layer );
333   layer.LowerToBottom();
334
335   DALI_TEST_CHECK( stage.GetRootLayer() == rootLayer );
336   END_TEST;
337 }
338
339 int UtcDaliStageSetBackgroundColor(void)
340 {
341   TestApplication application;
342
343   Stage stage = Stage::GetCurrent();
344
345   Vector4 testColor(0.1f, 0.2f, 0.3f, 1.0f);
346   stage.SetBackgroundColor(testColor);
347
348   DALI_TEST_EQUALS(testColor, stage.GetBackgroundColor(), TEST_LOCATION);
349   END_TEST;
350 }
351
352 int UtcDaliStageGetBackgroundColor(void)
353 {
354   TestApplication application;
355
356   Stage stage = Stage::GetCurrent();
357
358   DALI_TEST_EQUALS(Stage::DEFAULT_BACKGROUND_COLOR, stage.GetBackgroundColor(), TEST_LOCATION);
359   END_TEST;
360 }
361
362 int UtcDaliStageKeepRendering(void)
363 {
364   TestApplication application;
365
366   Stage stage = Stage::GetCurrent();
367
368   // Run core until it wants to sleep
369   bool keepUpdating( true );
370   while ( keepUpdating )
371   {
372     application.SendNotification();
373     keepUpdating = application.Render(1000.0f /*1 second*/);
374   }
375
376   // Force rendering for the next 5 seconds
377   stage.KeepRendering( 5.0f );
378
379   application.SendNotification();
380
381   // Test that core wants to sleep after 10 seconds
382   keepUpdating = application.Render(1000.0f /*1 second*/);
383   DALI_TEST_CHECK( keepUpdating );
384   keepUpdating = application.Render(1000.0f /*2 seconds*/);
385   DALI_TEST_CHECK( keepUpdating );
386   keepUpdating = application.Render(1000.0f /*3 seconds*/);
387   DALI_TEST_CHECK( keepUpdating );
388   keepUpdating = application.Render(1000.0f /*4 seconds*/);
389   DALI_TEST_CHECK( keepUpdating );
390   keepUpdating = application.Render(1000.0f /*5 seconds*/);
391   DALI_TEST_CHECK( !keepUpdating );
392   END_TEST;
393 }
394
395 int UtcDaliStageEventProcessingFinished(void)
396 {
397   TestApplication application;
398   Stage stage = Stage::GetCurrent();
399
400   bool eventProcessingFinished = false;
401   EventProcessingFinishedFunctor functor( eventProcessingFinished );
402   stage.EventProcessingFinishedSignal().Connect( &application, functor );
403
404   Actor actor( Actor::New() );
405   stage.Add( actor );
406
407   application.SendNotification();
408   application.Render();
409
410   DALI_TEST_CHECK( eventProcessingFinished );
411
412   END_TEST;
413 }
414
415 int UtcDaliStageSignalKeyEvent(void)
416 {
417   TestApplication application;
418   Stage stage = Stage::GetCurrent();
419
420   KeyEventSignalData data;
421   KeyEventReceivedFunctor functor( data );
422   stage.KeyEventSignal().Connect( &application, functor );
423
424   Integration::KeyEvent event( "i","i", 0, 0, 0, Integration::KeyEvent::Down );
425   application.ProcessEvent( event );
426
427   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
428   DALI_TEST_CHECK( event.keyModifier == data.receivedKeyEvent.keyModifier );
429   DALI_TEST_CHECK( event.keyName == data.receivedKeyEvent.keyPressedName );
430   DALI_TEST_CHECK( event.keyString == data.receivedKeyEvent.keyPressed );
431   DALI_TEST_CHECK( event.state == static_cast<Integration::KeyEvent::State>(data.receivedKeyEvent.state) );
432
433   data.Reset();
434
435   Integration::KeyEvent event2( "i","i", 0, 0, 0, Integration::KeyEvent::Up );
436   application.ProcessEvent( event2 );
437
438   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
439   DALI_TEST_CHECK( event2.keyModifier == data.receivedKeyEvent.keyModifier );
440   DALI_TEST_CHECK( event2.keyName == data.receivedKeyEvent.keyPressedName );
441   DALI_TEST_CHECK( event2.keyString == data.receivedKeyEvent.keyPressed );
442   DALI_TEST_CHECK( event2.state == static_cast<Integration::KeyEvent::State>(data.receivedKeyEvent.state) );
443
444   data.Reset();
445
446   Integration::KeyEvent event3( "a","a", 0, 0, 0, Integration::KeyEvent::Down );
447   application.ProcessEvent( event3 );
448
449   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
450   DALI_TEST_CHECK( event3.keyModifier == data.receivedKeyEvent.keyModifier );
451   DALI_TEST_CHECK( event3.keyName == data.receivedKeyEvent.keyPressedName );
452   DALI_TEST_CHECK( event3.keyString == data.receivedKeyEvent.keyPressed );
453   DALI_TEST_CHECK( event3.state == static_cast<Integration::KeyEvent::State>(data.receivedKeyEvent.state) );
454
455   data.Reset();
456
457   Integration::KeyEvent event4( "a","a", 0, 0, 0, Integration::KeyEvent::Up );
458   application.ProcessEvent( event4 );
459
460   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
461   DALI_TEST_CHECK( event4.keyModifier == data.receivedKeyEvent.keyModifier );
462   DALI_TEST_CHECK( event4.keyName == data.receivedKeyEvent.keyPressedName );
463   DALI_TEST_CHECK( event4.keyString == data.receivedKeyEvent.keyPressed );
464   DALI_TEST_CHECK( event4.state == static_cast<Integration::KeyEvent::State>(data.receivedKeyEvent.state) );
465   END_TEST;
466 }
467
468 int UtcDaliStageTouchedSignal(void)
469 {
470   TestApplication application;
471   Stage stage = Stage::GetCurrent();
472
473   TouchedSignalData data;
474   TouchedFunctor functor( data );
475   stage.TouchedSignal().Connect( &application, functor );
476
477   // Render and notify
478   application.SendNotification();
479   application.Render();
480
481   // NO ACTORS, SINGLE TOUCH, DOWN, MOTION THEN UP
482   {
483     Integration::TouchEvent touchEvent;
484     touchEvent.points.push_back( TouchPoint( 0, TouchPoint::Down, 10.0f, 10.0f ) );
485     application.ProcessEvent( touchEvent );
486
487     DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
488     DALI_TEST_CHECK( data.receivedTouchEvent.GetPointCount() != 0 );
489     DALI_TEST_CHECK( !data.receivedTouchEvent.points[0].hitActor );
490     data.Reset();
491
492     touchEvent.points[0].state = TouchPoint::Motion;
493     touchEvent.points[0].screen.x = 12.0f; // Some motion
494     application.ProcessEvent( touchEvent );
495
496     DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
497     data.Reset();
498
499     touchEvent.points[0].state = TouchPoint::Up;
500     application.ProcessEvent( touchEvent );
501
502     DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
503     DALI_TEST_CHECK( data.receivedTouchEvent.GetPointCount() != 0 );
504     DALI_TEST_CHECK( !data.receivedTouchEvent.points[0].hitActor );
505     data.Reset();
506   }
507
508   // Add an actor to the scene
509
510   Actor actor = Actor::New();
511   actor.SetSize( 100.0f, 100.0f );
512   actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
513   actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
514   actor.TouchedSignal().Connect( &DummyTouchCallback );
515   stage.Add( actor );
516
517   // Render and notify
518   application.SendNotification();
519   application.Render();
520
521   // ACTOR ON SCENE, SINGLE TOUCH, DOWN IN ACTOR, MOTION THEN UP OUTSIDE ACTOR
522   {
523     Integration::TouchEvent touchEvent;
524     touchEvent.points.push_back( TouchPoint( 0, TouchPoint::Down, 10.0f, 10.0f ) );
525     application.ProcessEvent( touchEvent );
526
527     DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
528     DALI_TEST_CHECK( data.receivedTouchEvent.GetPointCount() != 0 );
529     DALI_TEST_CHECK( data.receivedTouchEvent.points[0].hitActor == actor );
530     data.Reset();
531
532     touchEvent.points[0].state = TouchPoint::Motion;
533     touchEvent.points[0].screen.x = 150.0f; // Some motion
534     application.ProcessEvent( touchEvent );
535
536     DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
537     data.Reset();
538
539     touchEvent.points[0].state = TouchPoint::Up;
540     application.ProcessEvent( touchEvent );
541
542     DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
543     DALI_TEST_CHECK( data.receivedTouchEvent.GetPointCount() != 0 );
544     DALI_TEST_CHECK( !data.receivedTouchEvent.points[0].hitActor );
545     data.Reset();
546   }
547
548   // INTERRUPTED BEFORE DOWN AND INTERRUPTED AFTER DOWN
549   {
550     Integration::TouchEvent touchEvent;
551     touchEvent.points.push_back( TouchPoint( 0, TouchPoint::Interrupted, 10.0f, 10.0f ) );
552     application.ProcessEvent( touchEvent );
553
554     DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
555     DALI_TEST_CHECK( data.receivedTouchEvent.GetPointCount() != 0 );
556     DALI_TEST_CHECK( !data.receivedTouchEvent.points[0].hitActor );
557     DALI_TEST_CHECK( data.receivedTouchEvent.points[0].state == TouchPoint::Interrupted );
558     data.Reset();
559
560     touchEvent.points[0].state = TouchPoint::Down;
561     application.ProcessEvent( touchEvent );
562
563     DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
564     DALI_TEST_CHECK( data.receivedTouchEvent.GetPointCount() != 0 );
565     DALI_TEST_CHECK( data.receivedTouchEvent.points[0].hitActor == actor );
566     DALI_TEST_CHECK( data.receivedTouchEvent.points[0].state == TouchPoint::Down );
567     data.Reset();
568
569     touchEvent.points[0].state = TouchPoint::Interrupted;
570     application.ProcessEvent( touchEvent );
571
572     DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
573     DALI_TEST_CHECK( data.receivedTouchEvent.GetPointCount() != 0 );
574     DALI_TEST_CHECK( !data.receivedTouchEvent.points[0].hitActor );
575     DALI_TEST_CHECK( data.receivedTouchEvent.points[0].state == TouchPoint::Interrupted );
576     data.Reset();
577   }
578
579   // MULTIPLE TOUCH, SHOULD ONLY RECEIVE TOUCH ON FIRST DOWN AND LAST UP
580   {
581     Integration::TouchEvent touchEvent;
582
583     // 1st point
584     touchEvent.points.push_back( TouchPoint( 0, TouchPoint::Down, 10.0f, 10.0f ) );
585     application.ProcessEvent( touchEvent );
586     DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
587     data.Reset();
588
589     // 2nd point
590     touchEvent.points[0].state = TouchPoint::Stationary;
591     touchEvent.points.push_back( TouchPoint( 1, TouchPoint::Down, 50.0f, 50.0f ) );
592     application.ProcessEvent( touchEvent );
593     DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
594     data.Reset();
595
596     // Primary point is up
597     touchEvent.points[0].state = TouchPoint::Up;
598     touchEvent.points[1].state = TouchPoint::Stationary;
599     application.ProcessEvent( touchEvent );
600     DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
601     data.Reset();
602
603     // Remove 1st point now, 2nd point is now in motion
604     touchEvent.points.erase( touchEvent.points.begin() );
605     touchEvent.points[0].state = TouchPoint::Motion;
606     touchEvent.points[0].screen.x = 150.0f;
607     application.ProcessEvent( touchEvent );
608     DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
609     data.Reset();
610
611     // Final point Up
612     touchEvent.points[0].state = TouchPoint::Up;
613     application.ProcessEvent( touchEvent );
614     DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
615     data.Reset();
616   }
617   END_TEST;
618 }
619
620 int UtcDaliStageContextLostRegainedSignals(void)
621 {
622   TestApplication app;
623   Stage stage = Stage::GetCurrent();
624
625   bool contextLost = false;
626   bool contextRegained = false;
627   ContextStatusFunctor contextLostFunctor( contextLost );
628   ContextStatusFunctor contextRegainedFunctor( contextRegained );
629   stage.ContextLostSignal().Connect(&app, contextLostFunctor );
630   stage.ContextRegainedSignal().Connect(&app, contextRegainedFunctor );
631
632   Integration::Core& core = app.GetCore();
633   Integration::ContextNotifierInterface* notifier = core.GetContextNotifier();
634   notifier->NotifyContextLost();
635   DALI_TEST_EQUALS( contextLost, true, TEST_LOCATION );
636
637   notifier->NotifyContextRegained();
638   DALI_TEST_EQUALS( contextRegained, true, TEST_LOCATION );
639
640   END_TEST;
641 }