2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <dali/integration-api/scene.h>
22 #include <dali/integration-api/events/key-event-integ.h>
23 #include <dali/public-api/events/key-event.h>
24 #include <dali/integration-api/events/touch-event-integ.h>
25 #include <dali/integration-api/events/wheel-event-integ.h>
27 #include <dali-test-suite-utils.h>
29 // Internal headers are allowed here
34 const std::string DEFAULT_DEVICE_NAME("hwKeyboard");
36 // Functor for EventProcessingFinished signal
37 struct EventProcessingFinishedFunctor
40 * @param[in] eventProcessingFinished reference to a boolean variable used to check if signal has been called.
42 EventProcessingFinishedFunctor( bool& eventProcessingFinished )
43 : mEventProcessingFinished( eventProcessingFinished )
48 mEventProcessingFinished = true;
51 bool& mEventProcessingFinished;
54 // Stores data that is populated in the key-event callback and will be read by the TET cases
55 struct KeyEventSignalData
58 : functorCalled(false)
63 functorCalled = false;
65 receivedKeyEvent.keyModifier = 0;
66 receivedKeyEvent.keyPressedName.clear();
67 receivedKeyEvent.keyPressed.clear();
71 KeyEvent receivedKeyEvent;
74 // Functor that sets the data when called
75 struct KeyEventReceivedFunctor
77 KeyEventReceivedFunctor( KeyEventSignalData& data ) : signalData( data ) { }
79 bool operator()( const KeyEvent& keyEvent )
81 signalData.functorCalled = true;
82 signalData.receivedKeyEvent = keyEvent;
87 KeyEventSignalData& signalData;
90 // Stores data that is populated in the touched signal callback and will be read by the TET cases
91 struct TouchedSignalData
94 : functorCalled(false)
99 functorCalled = false;
101 receivedTouchEvent.points.clear();
102 receivedTouchEvent.time = 0;
104 receivedTouchData.Reset();
108 TouchEvent receivedTouchEvent;
109 TouchData receivedTouchData;
112 // Functor that sets the data when touched signal is received
113 struct TouchedFunctor
115 TouchedFunctor( TouchedSignalData& data ) : signalData( data ) { }
117 void operator()( const TouchEvent& touch )
119 signalData.functorCalled = true;
120 signalData.receivedTouchEvent = touch;
123 TouchedSignalData& signalData;
126 // Functor that sets the data when touched signal is received
129 TouchFunctor( TouchedSignalData& data ) : signalData( data ) { }
131 void operator()( const TouchData& touch )
133 signalData.functorCalled = true;
134 signalData.receivedTouchData = touch;
139 signalData.functorCalled = true;
142 TouchedSignalData& signalData;
145 // Stores data that is populated in the wheel-event callback and will be read by the TET cases
146 struct WheelEventSignalData
148 WheelEventSignalData()
149 : functorCalled(false)
154 functorCalled = false;
158 WheelEvent receivedWheelEvent;
161 // Functor that sets the data when wheel-event signal is received
162 struct WheelEventReceivedFunctor
164 WheelEventReceivedFunctor( WheelEventSignalData& data ) : signalData( data ) { }
166 bool operator()( const WheelEvent& wheelEvent )
168 signalData.functorCalled = true;
169 signalData.receivedWheelEvent = wheelEvent;
174 WheelEventSignalData& signalData;
177 void GenerateTouch( TestApplication& application, PointState::Type state, const Vector2& screenPosition )
179 Integration::TouchEvent touchEvent;
180 Integration::Point point;
181 point.SetState( state );
182 point.SetScreenPosition( screenPosition );
183 touchEvent.points.push_back( point );
184 application.ProcessEvent( touchEvent );
187 bool DummyTouchCallback( Actor actor, const TouchEvent& touch )
192 } // unnamed namespace
194 int UtcDaliSceneAdd(void)
196 TestApplication application;
197 tet_infoline("Testing Dali::Integration::Scene::Add");
199 Dali::Integration::Scene scene = application.GetScene();
201 Actor actor = Actor::New();
202 DALI_TEST_CHECK( !actor.OnStage() );
205 DALI_TEST_CHECK( actor.OnStage() );
210 int UtcDaliSceneRemove(void)
212 TestApplication application;
213 tet_infoline("Testing Dali::Integration::Scene::Remove");
215 Dali::Integration::Scene scene = application.GetScene();
217 Actor actor = Actor::New();
218 DALI_TEST_CHECK( !actor.OnStage() );
221 DALI_TEST_CHECK( actor.OnStage() );
224 DALI_TEST_CHECK( !actor.OnStage() );
229 int UtcDaliSceneGetSize(void)
231 TestApplication application;
232 tet_infoline("Testing Dali::Integration::Scene::GetSize");
234 Dali::Integration::Scene scene = application.GetScene();
235 Size size = scene.GetSize();
236 DALI_TEST_EQUALS( TestApplication::DEFAULT_SURFACE_WIDTH, size.width, TEST_LOCATION );
237 DALI_TEST_EQUALS( TestApplication::DEFAULT_SURFACE_HEIGHT, size.height, TEST_LOCATION );
242 int UtcDaliSceneGetDpi(void)
244 TestApplication application; // Initializes core DPI to default values
246 // Test that setting core DPI explicitly also sets up the scene's DPI.
247 Dali::Integration::Scene scene = application.GetScene();
248 scene.SetDpi( Vector2(200.0f, 180.0f) );
249 Vector2 dpi = scene.GetDpi();
250 DALI_TEST_EQUALS( dpi.x, 200.0f, TEST_LOCATION );
251 DALI_TEST_EQUALS( dpi.y, 180.0f, TEST_LOCATION );
255 int UtcDaliSceneGetRenderTaskList(void)
257 TestApplication application;
258 tet_infoline("Testing Dali::Integration::Scene::GetRenderTaskList");
260 Dali::Integration::Scene scene = application.GetScene();
262 // Check we get a valid instance.
263 const RenderTaskList& tasks = scene.GetRenderTaskList();
265 // There should be 1 task by default.
266 DALI_TEST_EQUALS( tasks.GetTaskCount(), 1u, TEST_LOCATION );
268 // RenderTaskList has it's own UTC tests.
269 // But we can confirm that GetRenderTaskList in Stage retrieves the same RenderTaskList each time.
270 RenderTask newTask = scene.GetRenderTaskList().CreateTask();
272 DALI_TEST_EQUALS( scene.GetRenderTaskList().GetTask( 1 ), newTask, TEST_LOCATION );
277 int UtcDaliSceneGetRootLayer(void)
279 TestApplication application;
280 tet_infoline("Testing Dali::Integration::Scene::GetRootLayer");
282 Dali::Integration::Scene scene = application.GetScene();
283 Layer layer = scene.GetLayer( 0 );
284 DALI_TEST_CHECK( layer );
286 // Check that GetRootLayer() correctly retreived layer 0.
287 DALI_TEST_CHECK( scene.GetRootLayer() == layer );
292 int UtcDaliSceneGetLayerCount(void)
294 TestApplication application;
295 tet_infoline("Testing Dali::Integration::Scene::GetLayerCount");
297 Dali::Integration::Scene scene = application.GetScene();
298 // Initially we have a default layer
299 DALI_TEST_EQUALS( scene.GetLayerCount(), 1u, TEST_LOCATION );
301 Layer layer = Layer::New();
304 DALI_TEST_EQUALS( scene.GetLayerCount(), 2u, TEST_LOCATION );
308 int UtcDaliSceneGetLayer(void)
310 TestApplication application;
311 tet_infoline("Testing Dali::Integration::Scene::GetLayer");
313 Dali::Integration::Scene scene = application.GetScene();
315 Layer rootLayer = scene.GetLayer( 0 );
316 DALI_TEST_CHECK( rootLayer );
318 Layer layer = Layer::New();
321 Layer sameLayer = scene.GetLayer( 1 );
322 DALI_TEST_CHECK( layer == sameLayer );
327 int UtcDaliSceneGet(void)
329 TestApplication application;
330 tet_infoline("Testing Dali::Integration::Scene::Get");
332 Dali::Integration::Scene scene = application.GetScene();
334 Actor actor = Actor::New();
335 DALI_TEST_CHECK( Dali::Integration::Scene() == Dali::Integration::Scene::Get( actor ) );
339 DALI_TEST_CHECK( scene == Dali::Integration::Scene::Get( actor ) );
344 int UtcDaliSceneEventProcessingFinishedP(void)
346 TestApplication application;
347 Dali::Integration::Scene scene = application.GetScene();
349 bool eventProcessingFinished = false;
350 EventProcessingFinishedFunctor functor( eventProcessingFinished );
351 scene.EventProcessingFinishedSignal().Connect( &application, functor );
353 Actor actor( Actor::New() );
356 application.SendNotification();
357 application.Render();
359 DALI_TEST_CHECK( eventProcessingFinished );
364 int UtcDaliSceneEventProcessingFinishedN(void)
366 TestApplication application;
367 Dali::Integration::Scene scene = application.GetScene();
369 bool eventProcessingFinished = false;
370 EventProcessingFinishedFunctor functor( eventProcessingFinished );
371 scene.EventProcessingFinishedSignal().Connect( &application, functor );
373 Actor actor( Actor::New() );
376 // Do not complete event processing and confirm the signal has not been emitted.
377 DALI_TEST_CHECK( !eventProcessingFinished );
382 int UtcDaliSceneSignalKeyEventP(void)
384 TestApplication application;
385 Dali::Integration::Scene scene = application.GetScene();
387 KeyEventSignalData data;
388 KeyEventReceivedFunctor functor( data );
389 scene.KeyEventSignal().Connect( &application, functor );
391 Integration::KeyEvent event( "i", "", "i", 0, 0, 0, Integration::KeyEvent::Down, "i", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE );
392 application.ProcessEvent( event );
394 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
395 DALI_TEST_CHECK( event.keyModifier == data.receivedKeyEvent.keyModifier );
396 DALI_TEST_CHECK( event.keyName == data.receivedKeyEvent.keyPressedName );
397 DALI_TEST_CHECK( event.keyString == data.receivedKeyEvent.keyPressed );
398 DALI_TEST_CHECK( event.state == static_cast<Integration::KeyEvent::State>( data.receivedKeyEvent.state ) );
402 Integration::KeyEvent event2( "i", "", "i", 0, 0, 0, Integration::KeyEvent::Up, "i", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE );
403 application.ProcessEvent( event2 );
405 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
406 DALI_TEST_CHECK( event2.keyModifier == data.receivedKeyEvent.keyModifier );
407 DALI_TEST_CHECK( event2.keyName == data.receivedKeyEvent.keyPressedName );
408 DALI_TEST_CHECK( event2.keyString == data.receivedKeyEvent.keyPressed );
409 DALI_TEST_CHECK( event2.state == static_cast<Integration::KeyEvent::State>( data.receivedKeyEvent.state ) );
413 Integration::KeyEvent event3( "a", "", "a", 0, 0, 0, Integration::KeyEvent::Down, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE );
414 application.ProcessEvent( event3 );
416 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
417 DALI_TEST_CHECK( event3.keyModifier == data.receivedKeyEvent.keyModifier );
418 DALI_TEST_CHECK( event3.keyName == data.receivedKeyEvent.keyPressedName );
419 DALI_TEST_CHECK( event3.keyString == data.receivedKeyEvent.keyPressed );
420 DALI_TEST_CHECK( event3.state == static_cast<Integration::KeyEvent::State>( data.receivedKeyEvent.state ) );
424 Integration::KeyEvent event4( "a", "", "a", 0, 0, 0, Integration::KeyEvent::Up, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE );
425 application.ProcessEvent( event4 );
427 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
428 DALI_TEST_CHECK( event4.keyModifier == data.receivedKeyEvent.keyModifier );
429 DALI_TEST_CHECK( event4.keyName == data.receivedKeyEvent.keyPressedName );
430 DALI_TEST_CHECK( event4.keyString == data.receivedKeyEvent.keyPressed );
431 DALI_TEST_CHECK( event4.state == static_cast<Integration::KeyEvent::State>( data.receivedKeyEvent.state ) );
435 int UtcDaliSceneSignalKeyEventN(void)
437 TestApplication application;
438 Dali::Integration::Scene scene = application.GetScene();
440 KeyEventSignalData data;
441 KeyEventReceivedFunctor functor( data );
442 scene.KeyEventSignal().Connect( &application, functor );
444 // Check that a non-pressed key events data is not modified.
445 DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
450 int UtcDaliSceneTouchSignalP(void)
452 TestApplication application;
453 Dali::Integration::Scene scene = application.GetScene();
455 TouchedSignalData data;
456 TouchFunctor functor( data );
457 scene.TouchSignal().Connect( &application, functor );
459 // Render and notify.
460 application.SendNotification();
461 application.Render();
463 // Basic test: No actors, single touch (down then up).
465 GenerateTouch( application, PointState::DOWN, Vector2( 10.0f, 10.0f ) );
467 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
468 DALI_TEST_CHECK( data.receivedTouchData.GetPointCount() != 0u );
469 DALI_TEST_CHECK( !data.receivedTouchData.GetHitActor(0) );
472 GenerateTouch( application, PointState::UP, Vector2( 10.0f, 10.0f ) );
474 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
475 DALI_TEST_CHECK( data.receivedTouchData.GetPointCount() != 0u );
476 DALI_TEST_CHECK( !data.receivedTouchData.GetHitActor(0) );
480 // Add an actor to the scene.
481 Actor actor = Actor::New();
482 actor.SetSize( 100.0f, 100.0f );
483 actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
484 actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
485 actor.TouchedSignal().Connect( &DummyTouchCallback );
488 // Render and notify.
489 application.SendNotification();
490 application.Render();
492 // Actor on scene, single touch, down in actor, motion, then up outside actor.
494 GenerateTouch( application, PointState::DOWN, Vector2( 10.0f, 10.0f ) );
496 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
497 DALI_TEST_CHECK( data.receivedTouchData.GetPointCount() != 0u );
498 DALI_TEST_CHECK( data.receivedTouchData.GetHitActor(0) == actor );
501 GenerateTouch( application, PointState::MOTION, Vector2( 150.0f, 10.0f ) ); // Some motion
503 DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
506 GenerateTouch( application, PointState::UP, Vector2( 150.0f, 10.0f ) ); // Some motion
508 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
509 DALI_TEST_CHECK( data.receivedTouchData.GetPointCount() != 0u );
510 DALI_TEST_CHECK( !data.receivedTouchData.GetHitActor(0) );
514 // Multiple touch. Should only receive a touch on first down and last up.
516 Integration::TouchEvent touchEvent;
517 Integration::Point point;
520 point.SetState( PointState::DOWN );
521 point.SetScreenPosition( Vector2( 10.0f, 10.0f ) );
522 touchEvent.points.push_back( point );
523 application.ProcessEvent( touchEvent );
524 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
525 DALI_TEST_EQUALS( data.receivedTouchData.GetPointCount(), 1u, TEST_LOCATION );
529 touchEvent.points[0].SetState( PointState::STATIONARY );
530 point.SetDeviceId( 1 );
531 point.SetScreenPosition( Vector2( 50.0f, 50.0f ) );
532 touchEvent.points.push_back( point );
533 application.ProcessEvent( touchEvent );
534 DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
537 // Primary point is up
538 touchEvent.points[0].SetState( PointState::UP );
539 touchEvent.points[1].SetState( PointState::STATIONARY );
540 application.ProcessEvent( touchEvent );
541 DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
544 // Remove 1st point now, 2nd point is now in motion
545 touchEvent.points.erase( touchEvent.points.begin() );
546 touchEvent.points[0].SetState( PointState::MOTION );
547 touchEvent.points[0].SetScreenPosition( Vector2( 150.0f, 50.0f ) );
548 application.ProcessEvent( touchEvent );
549 DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
553 touchEvent.points[0].SetState( PointState::UP );
554 application.ProcessEvent( touchEvent );
555 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
556 DALI_TEST_EQUALS( data.receivedTouchData.GetPointCount(), 1u, TEST_LOCATION );
562 int UtcDaliSceneTouchSignalN(void)
564 TestApplication application;
565 Dali::Integration::Scene scene = application.GetScene();
567 TouchedSignalData data;
568 TouchFunctor functor( data );
569 scene.TouchSignal().Connect( &application, functor );
571 // Render and notify.
572 application.SendNotification();
573 application.Render();
575 // Confirm functor not called before there has been any touch event.
576 DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
578 // No actors, single touch, down, motion then up.
580 GenerateTouch( application, PointState::DOWN, Vector2( 10.0f, 10.0f ) );
582 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
583 DALI_TEST_CHECK( data.receivedTouchData.GetPointCount() != 0u );
584 DALI_TEST_CHECK( !data.receivedTouchData.GetHitActor(0));
588 // Confirm there is no signal when the touchpoint is only moved.
589 GenerateTouch( application, PointState::MOTION, Vector2( 1200.0f, 10.0f ) ); // Some motion
591 DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
594 // Confirm a following up event generates a signal.
595 GenerateTouch( application, PointState::UP, Vector2( 1200.0f, 10.0f ) );
597 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
598 DALI_TEST_CHECK( data.receivedTouchData.GetPointCount() != 0u );
599 DALI_TEST_CHECK( !data.receivedTouchData.GetHitActor(0));
603 // Add an actor to the scene.
604 Actor actor = Actor::New();
605 actor.SetSize( 100.0f, 100.0f );
606 actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
607 actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
608 actor.TouchedSignal().Connect( &DummyTouchCallback );
611 // Render and notify.
612 application.SendNotification();
613 application.Render();
615 // Actor on scene. Interrupted before down and interrupted after down.
617 GenerateTouch( application, PointState::INTERRUPTED, Vector2( 10.0f, 10.0f ) );
619 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
620 DALI_TEST_CHECK( data.receivedTouchData.GetPointCount() != 0u );
621 DALI_TEST_CHECK( !data.receivedTouchData.GetHitActor(0) );
622 DALI_TEST_CHECK( data.receivedTouchData.GetState(0) == PointState::INTERRUPTED );
625 GenerateTouch( application, PointState::DOWN, Vector2( 10.0f, 10.0f ) );
627 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
628 DALI_TEST_CHECK( data.receivedTouchData.GetPointCount() != 0u );
629 DALI_TEST_CHECK( data.receivedTouchData.GetHitActor(0) == actor );
630 DALI_TEST_CHECK( data.receivedTouchData.GetState(0) == PointState::DOWN );
633 GenerateTouch( application, PointState::INTERRUPTED, Vector2( 10.0f, 10.0f ) );
635 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
636 DALI_TEST_CHECK( data.receivedTouchData.GetPointCount() != 0u );
637 DALI_TEST_CHECK( !data.receivedTouchData.GetHitActor(0) );
638 DALI_TEST_CHECK( data.receivedTouchData.GetState(0) == PointState::INTERRUPTED );
640 DALI_TEST_EQUALS( data.receivedTouchData.GetPointCount(), 1u, TEST_LOCATION );
642 // Check that getting info about a non-existent point returns an empty handle
643 Actor actor = data.receivedTouchData.GetHitActor( 1 );
644 DALI_TEST_CHECK( !actor );
652 int UtcDaliSceneSignalWheelEventP(void)
654 TestApplication application;
655 Dali::Integration::Scene scene = application.GetScene();
657 WheelEventSignalData data;
658 WheelEventReceivedFunctor functor( data );
659 scene.WheelEventSignal().Connect( &application, functor );
661 Integration::WheelEvent event( Integration::WheelEvent::CUSTOM_WHEEL, 0, 0u, Vector2( 0.0f, 0.0f ), 1, 1000u );
662 application.ProcessEvent( event );
664 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
665 DALI_TEST_CHECK( static_cast< WheelEvent::Type >(event.type) == data.receivedWheelEvent.type );
666 DALI_TEST_CHECK( event.direction == data.receivedWheelEvent.direction );
667 DALI_TEST_CHECK( event.modifiers == data.receivedWheelEvent.modifiers );
668 DALI_TEST_CHECK( event.point == data.receivedWheelEvent.point );
669 DALI_TEST_CHECK( event.z == data.receivedWheelEvent.z );
670 DALI_TEST_CHECK( event.timeStamp == data.receivedWheelEvent.timeStamp );
674 Integration::WheelEvent event2( Integration::WheelEvent::CUSTOM_WHEEL, 0, 0u, Vector2( 0.0f, 0.0f ), -1, 1000u );
675 application.ProcessEvent( event2 );
677 DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
678 DALI_TEST_CHECK( static_cast< WheelEvent::Type >(event2.type) == data.receivedWheelEvent.type );
679 DALI_TEST_CHECK( event2.direction == data.receivedWheelEvent.direction );
680 DALI_TEST_CHECK( event2.modifiers == data.receivedWheelEvent.modifiers );
681 DALI_TEST_CHECK( event2.point == data.receivedWheelEvent.point );
682 DALI_TEST_CHECK( event2.z == data.receivedWheelEvent.z );
683 DALI_TEST_CHECK( event2.timeStamp == data.receivedWheelEvent.timeStamp );