2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
25 #include <dali/public-api/dali-core.h>
27 #include <dali-toolkit/public-api/controls/page-turn-view/page-turn-view.h>
28 #include <dali-toolkit/public-api/controls/page-turn-view/page-factory.h>
29 #include <dali-toolkit/public-api/controls/page-turn-view/page-turn-portrait-view.h>
30 #include <dali-toolkit/public-api/controls/page-turn-view/page-turn-landscape-view.h>
32 #include <dali-toolkit-test-suite-utils.h>
35 using namespace Dali::Toolkit;
39 const int RENDER_FRAME_INTERVAL = 16; ///< Duration of each frame in ms. (at approx 60FPS)
40 const unsigned int TOTAL_PAGE_NUMBER = 20;
41 const Vector2 PAGE_SIZE( 300.f,400.f );
42 const unsigned int IMAGE_WIDTH = 30;
43 const unsigned int IMAGE_HEIGHT = 30;
44 const Vector2 IMAGE_SIZE( static_cast<float>( IMAGE_WIDTH ), static_cast<float>(IMAGE_HEIGHT) );
45 const Vector2 SPINE_SHADOW_PARAMETER( 60.0f, 30.0f );
47 static bool gObjectCreatedCallBackCalled;
48 static void TestCallback(BaseHandle handle)
50 gObjectCreatedCallBackCalled = true;
54 * Simulate time passed by.
56 * @note this will always process at least 1 frame (1/60 sec)
58 * @param application Test application instance
59 * @param duration Time to pass in milliseconds.
60 * @return The actual time passed in milliseconds
62 int Wait(ToolkitTestApplication& application, int duration = 0)
66 for(int i = 0; i <= ( duration / RENDER_FRAME_INTERVAL); i++)
68 application.SendNotification();
69 application.Render(RENDER_FRAME_INTERVAL);
70 time += RENDER_FRAME_INTERVAL;
76 // Generate a PanGestureEvent to send to Core
77 Integration::PanGestureEvent GeneratePan(
79 const Vector2& previousPosition,
80 const Vector2& currentPosition,
81 unsigned long timeDelta,
82 unsigned int numberOfTouches = 1)
84 Integration::PanGestureEvent pan(state);
86 pan.previousPosition = previousPosition;
87 pan.currentPosition = currentPosition;
88 pan.timeDelta = timeDelta;
89 pan.numberOfTouches = numberOfTouches;
95 * Helper to generate PanGestureEvent
97 * @param[in] application Application instance
98 * @param[in] state The Gesture State
99 * @param[in] pos The current position of touch.
101 static void SendPan(ToolkitTestApplication& application, Gesture::State state, const Vector2& pos)
105 if( (state == Gesture::Started) ||
106 (state == Gesture::Possible) )
112 application.ProcessEvent(GeneratePan(state, last, pos, RENDER_FRAME_INTERVAL));
118 static Vector2 PerformGestureDiagonalSwipe(ToolkitTestApplication& application, Vector2 start, Vector2 direction, int frames, bool toStart = true, bool toFinish = true)
120 // Now do a pan starting from (start) and heading (direction)
125 SendPan(application, Gesture::Possible, pos);
127 SendPan(application, Gesture::Started, pos);
131 for(int i = 0;i<frames;i++)
133 pos += direction; // Move in this direction
134 SendPan(application, Gesture::Continuing, pos);
140 pos += direction; // Move in this direction
141 SendPan(application, Gesture::Finished, pos);
148 ImageActor CreateSolidColorImageActor( ToolkitTestApplication& application, const Vector4& color, unsigned int width, unsigned int height )
150 BitmapImage imageData = BitmapImage::New( width, height, Pixel::RGBA8888 );
151 ImageActor imageActor = ImageActor::New( imageData );
152 Stage::GetCurrent().Add( imageActor );
155 PixelBuffer* pixbuf = imageData.GetBuffer();
156 unsigned int size = width * height;
158 for( size_t i = 0; i < size; i++ )
160 pixbuf[i*4+0] = 0xFF * color.r;
161 pixbuf[i*4+1] = 0xFF * color.g;
162 pixbuf[i*4+2] = 0xFF * color.b;
163 pixbuf[i*4+3] = 0xFF * color.a;
167 application.GetGlAbstraction().SetCheckFramebufferStatusResult(GL_FRAMEBUFFER_COMPLETE );
168 application.SendNotification();
169 application.Render(RENDER_FRAME_INTERVAL);
170 application.Render(RENDER_FRAME_INTERVAL);
171 application.SendNotification();
176 //Functor to test whether PageTurnSignal / PagePanSignal is emitted
177 class PageSignalCallback : public Dali::ConnectionTracker
181 PageSignalCallback( bool& signalReceived, PageTurnView& view, unsigned int& pageIndex, bool& isForwards )
182 : mSignalVerified( signalReceived ),
184 mPageIndex( pageIndex ),
185 mIsTurningForwards( isForwards )
189 // callback to be connected to PageTurnSignal
190 void PageTurnSignalCallback( PageTurnView view, unsigned int pageIndex, bool isTurningForward )
192 tet_infoline( "Verifying PageTurnedSignal" );
194 if( mView == view && mPageIndex == pageIndex && mIsTurningForwards == isTurningForward )
196 mSignalVerified = true;
200 // callback to be connected to PagePanSignal
201 void PagePanSignalCallback( PageTurnView view )
203 tet_infoline( "Verifying PagePannedSignal" );
207 mSignalVerified = true;
213 mSignalVerified = false;
216 bool& mSignalVerified;
218 unsigned int& mPageIndex;
219 bool& mIsTurningForwards;
225 static void Startup();
226 static void Cleanup();
229 void (*tet_startup)() = Startup;
230 void (*tet_cleanup)() = Cleanup;
234 POSITIVE_TC_IDX = 0x01,
238 #define MAX_NUMBER_OF_TESTS 10000
240 struct tet_testlist tet_testlist[MAX_NUMBER_OF_TESTS];
243 // Add test functionality for all APIs in the class (Positive and Negative)
244 TEST_FUNCTION( UtcDaliPageTurnPortraitViewNew, POSITIVE_TC_IDX );
245 TEST_FUNCTION( UtcDaliPageTurnLandscapeViewNew, POSITIVE_TC_IDX );
246 TEST_FUNCTION( UtcDaliPageTurnViewSetAndGetSpineShadowParameter, POSITIVE_TC_IDX );
247 TEST_FUNCTION( UtcDaliPageTurnViewGoToPageAndGetCurrentPage, POSITIVE_TC_IDX );
248 TEST_FUNCTION( UtcDaliPageTurnViewEnterLeaveEditMode, POSITIVE_TC_IDX );
249 TEST_FUNCTION( UtcDaliPageTurnViewGetHitActor, POSITIVE_TC_IDX );
250 TEST_FUNCTION( UtcDaliPageTurnViewRefresh, POSITIVE_TC_IDX );
251 TEST_FUNCTION( UtcDaliPageTurnViewSignals, POSITIVE_TC_IDX );
253 // Called only once before first test is run.
254 static void Startup()
258 // Called only once after last test is run
259 static void Cleanup()
263 //Implementation of PageFactory for providing page actors to PageTurnView
264 class TestPageFactory : public PageFactory
268 TestPageFactory(ToolkitTestApplication& application)
269 : mApplication( application )
271 mSourceActors.resize(TOTAL_PAGE_NUMBER);
272 mTotalPageNumber = TOTAL_PAGE_NUMBER;
276 * Query the number of pages available from the factory.
277 * The maximum available page has an ID of GetNumberOfPages()-1.
279 virtual unsigned int GetNumberOfPages()
281 return mTotalPageNumber;
285 * Create an image actor to represent a page.
286 * @param[in] pageId The ID of the page to create.
287 * @return An image actor, or an uninitialized pointer if the ID is out of range.
289 virtual Actor NewPage( unsigned int pageId )
291 if(!mSourceActors[pageId])
293 Actor actor = CreateSolidColorImageActor(mApplication, Color::BLUE,IMAGE_WIDTH,IMAGE_HEIGHT);
294 actor.SetName( static_cast<std::ostringstream*>( &(std::ostringstream() << pageId) )->str() );
296 actor.SetParentOrigin( ParentOrigin::CENTER );
297 actor.SetAnchorPoint( AnchorPoint::CENTER );
299 SetActorHittability( actor, true );
301 mSourceActors[pageId] = actor;
304 return mSourceActors[pageId];
307 void DeletePage( unsigned int pageId )
309 mSourceActors.erase( mSourceActors.begin() + pageId );
314 ToolkitTestApplication& mApplication;
315 std::vector<Actor> mSourceActors;
316 unsigned int mTotalPageNumber;
320 static void UtcDaliPageTurnPortraitViewNew()
322 ToolkitTestApplication application;
324 tet_infoline(" UtcDaliPageTurnViewNew ");
326 // Test default constructor
327 PageTurnView portraitView;
328 DALI_TEST_CHECK( !portraitView );
330 // Test object creation
331 TestPageFactory factory(application);
332 portraitView = PageTurnPortraitView::New( factory, PAGE_SIZE );
333 DALI_TEST_CHECK( portraitView );
335 //Additional check to ensure object is created by checking if it's registered
336 ObjectRegistry registry = Stage::GetCurrent().GetObjectRegistry();
337 DALI_TEST_CHECK( registry );
339 gObjectCreatedCallBackCalled = false;
340 registry.ObjectCreatedSignal().Connect( &TestCallback );
342 TestPageFactory factory(application);
343 PageTurnView PortraitView = PageTurnPortraitView::New( factory, PAGE_SIZE );
345 DALI_TEST_CHECK( gObjectCreatedCallBackCalled );
347 // Test copy constructor
348 PageTurnView viewCopy( portraitView );
349 DALI_TEST_CHECK( viewCopy );
353 handleView = portraitView;
354 PageTurnView downCastView = PageTurnView::DownCast( handleView );
355 DALI_TEST_CHECK( downCastView );
358 static void UtcDaliPageTurnLandscapeViewNew()
360 ToolkitTestApplication application;
362 tet_infoline(" UtcDaliPageTurnViewNew ");
364 //Test default constructor
365 PageTurnView landscapeView;
366 DALI_TEST_CHECK( !landscapeView );
368 // Test object creation
369 TestPageFactory factory(application);
370 landscapeView = PageTurnLandscapeView::New( factory, PAGE_SIZE );
371 DALI_TEST_CHECK( landscapeView );
373 //Additional check to ensure object is created by checking if it's registered
374 ObjectRegistry registry = Stage::GetCurrent().GetObjectRegistry();
375 DALI_TEST_CHECK( registry );
377 gObjectCreatedCallBackCalled = false;
378 registry.ObjectCreatedSignal().Connect( &TestCallback );
380 TestPageFactory factory(application);
381 PageTurnView landscapeView = PageTurnLandscapeView::New( factory, PAGE_SIZE );
383 DALI_TEST_CHECK( gObjectCreatedCallBackCalled );
385 // Test copy constructor
386 PageTurnView viewCopy( landscapeView );
387 DALI_TEST_CHECK( viewCopy );
391 handleView = landscapeView;
392 PageTurnView downCastView = PageTurnView::DownCast( handleView );
393 DALI_TEST_CHECK( downCastView );
397 static void UtcDaliPageTurnViewSetAndGetSpineShadowParameter()
399 ToolkitTestApplication application;
401 tet_infoline(" UtcDaliPageTurnViewSetAndGetSpineShadowParameter ");
403 TestPageFactory factory(application);
404 PageTurnView landscapeView = PageTurnLandscapeView::New( factory, PAGE_SIZE );
405 DALI_TEST_CHECK( landscapeView.GetSpineShadowParameter() != SPINE_SHADOW_PARAMETER);
406 landscapeView.SetSpineShadowParameter(SPINE_SHADOW_PARAMETER);
407 DALI_TEST_CHECK( landscapeView.GetSpineShadowParameter() == SPINE_SHADOW_PARAMETER);
410 static void UtcDaliPageTurnViewGoToPageAndGetCurrentPage()
412 ToolkitTestApplication application;
414 tet_infoline(" UtcDaliPageTurnViewGoToPageAndGetCurrentPage ");
416 TestPageFactory factory(application);
417 PageTurnView portraitView = PageTurnPortraitView::New( factory, PAGE_SIZE );
418 DALI_TEST_CHECK( portraitView.GetCurrentPage() == 0 );
420 portraitView.GoToPage( 10 );
421 DALI_TEST_CHECK( portraitView.GetCurrentPage() == 10 );
423 portraitView.GoToPage( 5 );
424 DALI_TEST_CHECK( portraitView.GetCurrentPage() == 5 );
427 static void UtcDaliPageTurnViewEnterLeaveEditMode()
429 ToolkitTestApplication application;
431 tet_infoline( " UtcDaliPageTurnViewEnterLeaveEditMode " );
433 TestPageFactory factory(application);
434 factory.EnableOffscreenRendering( );
436 PageTurnView pageTurnView = PageTurnLandscapeView::New( factory, PAGE_SIZE );
437 pageTurnView.SetPositionInheritanceMode( USE_PARENT_POSITION );
438 Stage::GetCurrent().Add( pageTurnView );
440 Vector2 size = Stage::GetCurrent().GetSize();
442 pageTurnView.GoToPage(5);
445 application.SendNotification();
446 application.Render(RENDER_FRAME_INTERVAL);
448 Actor actor = pageTurnView.EnterEditMode();
449 // Test that when entering edit mode, current page source actor is returned.
451 std::istringstream( actor.GetName() ) >> pageId;
452 DALI_TEST_CHECK( pageId == 5 );
455 PageTurnView currentView;
456 unsigned int pageIndex;
457 bool isTurningForwards;
458 PageSignalCallback callbackPanStarted( signalVerified, currentView, pageIndex, isTurningForwards );
459 pageTurnView.PagePanStartedSignal().Connect( &callbackPanStarted, &PageSignalCallback::PagePanSignalCallback );
461 currentView = pageTurnView;
463 DALI_TEST_CHECK( !callbackPanStarted.mSignalVerified );
465 // Test that the control does not receive pan gesture in edit-mode
466 PerformGestureDiagonalSwipe( application, Vector2(size*0.75f), Vector2(size*0.01f), 10, true, true);
467 DALI_TEST_CHECK( !callbackPanStarted.mSignalVerified );
469 pageTurnView.LeaveEditMode();
470 // Test that the control receives pan gesture after leaving edit-mode
471 PerformGestureDiagonalSwipe( application, Vector2(size*0.75f), Vector2(size*0.01f), 10, true, true);
472 DALI_TEST_CHECK( callbackPanStarted.mSignalVerified );
475 static void UtcDaliPageTurnViewGetHitActor()
477 ToolkitTestApplication application;
479 tet_infoline(" UtcDaliPageTurnViewGetHitActor ");
481 TestPageFactory factory(application);
482 factory.EnableOffscreenRendering( );
484 PageTurnView pageTurnView = PageTurnPortraitView::New( factory, PAGE_SIZE );
485 pageTurnView.SetParentOrigin( ParentOrigin::TOP_LEFT );
486 pageTurnView.SetAnchorPoint( AnchorPoint::TOP_LEFT );
487 Stage::GetCurrent().Add( pageTurnView );
490 application.SendNotification();
491 application.Render(RENDER_FRAME_INTERVAL);
493 pageTurnView.GoToPage(3);
495 Vector2 localCoordinate = Vector2();
496 Vector2 screenCoordinate = PAGE_SIZE*0.5f+Vector2(7.f,8.f);
497 Actor hitActor = pageTurnView.GetHitActor( screenCoordinate, localCoordinate );
498 DALI_TEST_CHECK( hitActor );
500 std::istringstream( hitActor.GetName() ) >> pageId;
501 DALI_TEST_CHECK( pageId == 3 );
502 DALI_TEST_EQUALS( localCoordinate, IMAGE_SIZE*0.5f+Vector2(7.f,8.f), 0.1f, TEST_LOCATION );
504 screenCoordinate = PAGE_SIZE*0.5f+IMAGE_SIZE;
505 hitActor = pageTurnView.GetHitActor( screenCoordinate, localCoordinate );
506 DALI_TEST_CHECK( !hitActor );
509 static void UtcDaliPageTurnViewRefresh()
511 ToolkitTestApplication application;
513 tet_infoline(" UtcDaliPageTurnViewRefresh ");
515 TestPageFactory factory(application);
516 factory.EnableOffscreenRendering( );
517 PageTurnView pageTurnView = PageTurnPortraitView::New( factory, PAGE_SIZE );
518 pageTurnView.SetParentOrigin( ParentOrigin::TOP_LEFT );
519 pageTurnView.SetAnchorPoint( AnchorPoint::TOP_LEFT );
520 Stage::GetCurrent().Add( pageTurnView );
523 application.SendNotification();
524 application.Render(RENDER_FRAME_INTERVAL);
525 application.Render(RENDER_FRAME_INTERVAL);
526 application.SendNotification();
528 factory.DeletePage( 0 );
530 pageTurnView.RefreshCurrentPage();
531 // simply calls the certain off screen render task to refresh
532 Vector2 localCoordinate = Vector2();
533 Vector2 screenCoordinate = PAGE_SIZE*0.5f;
534 Actor hitActor = pageTurnView.GetHitActor( screenCoordinate, localCoordinate );
536 std::istringstream( hitActor.GetName() ) >> pageId;
537 DALI_TEST_CHECK( pageId == 0 );
539 pageTurnView.RefreshAll();
540 // re-parent all the source actors and refresh
541 hitActor = pageTurnView.GetHitActor( screenCoordinate, localCoordinate );
542 std::istringstream( hitActor.GetName() ) >> pageId;
543 DALI_TEST_CHECK( pageId == 1 );
546 static void UtcDaliPageTurnViewSignals()
548 ToolkitTestApplication application;
550 tet_infoline(" UtcDaliPageTurnViewSignals ");
552 TestPageFactory factory(application);
553 Vector2 size = Stage::GetCurrent().GetSize();
554 PageTurnView portraitView = PageTurnPortraitView::New( factory, size );
555 portraitView.SetPositionInheritanceMode( USE_PARENT_POSITION );
556 Stage::GetCurrent().Add( portraitView );
559 application.SendNotification();
560 application.Render(RENDER_FRAME_INTERVAL);
562 // [0]: testing PageTurnStartedSignal; [1]: testing PageTurnFinishedSignal
563 // [2]: testing PagePanStartedSignal; [3]: testing PagePanFinishedSignal
564 bool signalVerified[4];
565 PageTurnView currentView;
566 unsigned int pageIndex;
567 bool isTurningForwards;
569 PageSignalCallback callbackTurnStarted( signalVerified[0], currentView, pageIndex, isTurningForwards );
570 portraitView.PageTurnStartedSignal().Connect( &callbackTurnStarted, &PageSignalCallback::PageTurnSignalCallback );
572 PageSignalCallback callbackTurnFinished( signalVerified[1], currentView, pageIndex, isTurningForwards );
573 portraitView.PageTurnFinishedSignal().Connect( &callbackTurnFinished, &PageSignalCallback::PageTurnSignalCallback );
575 PageSignalCallback callbackPanStarted( signalVerified[2], currentView, pageIndex, isTurningForwards );
576 portraitView.PagePanStartedSignal().Connect( &callbackPanStarted, &PageSignalCallback::PagePanSignalCallback );
578 PageSignalCallback callbackPanFinished( signalVerified[3], currentView, pageIndex, isTurningForwards );
579 portraitView.PagePanFinishedSignal().Connect( &callbackPanFinished, &PageSignalCallback::PagePanSignalCallback );
581 DALI_TEST_CHECK( !callbackTurnStarted.mSignalVerified );
582 DALI_TEST_CHECK( !callbackTurnFinished.mSignalVerified );
583 DALI_TEST_CHECK( !callbackPanStarted.mSignalVerified );
584 DALI_TEST_CHECK( !callbackPanFinished.mSignalVerified );
586 currentView = portraitView;
588 //-----Test 1: pan 10 frames from position(size * 0.75f) to position(size * 0.25f), page 0 will be turned forward----
590 isTurningForwards = true;
591 // Do a pan moving up diagonally.
592 Vector2 start = size * 0.75f;
593 Vector2 direction = -size*0.05f; //-size*0.5f/10.f;
595 DALI_TEST_CHECK( portraitView.GetCurrentPage() == 0);
596 PerformGestureDiagonalSwipe( application, start, direction, 5, true, false);
597 DALI_TEST_CHECK( callbackTurnStarted.mSignalVerified );
598 DALI_TEST_CHECK( !callbackTurnFinished.mSignalVerified );
599 DALI_TEST_CHECK( callbackPanStarted.mSignalVerified );
600 DALI_TEST_CHECK( !callbackPanFinished.mSignalVerified );
602 PerformGestureDiagonalSwipe( application, start+direction*5.f, direction, 5, false, true);
603 DALI_TEST_CHECK( !callbackTurnFinished.mSignalVerified );
604 DALI_TEST_CHECK( callbackPanFinished.mSignalVerified );
606 Wait(application, 1000);
607 DALI_TEST_CHECK( callbackTurnFinished.mSignalVerified );
608 DALI_TEST_CHECK( portraitView.GetCurrentPage() == pageIndex+1); // the page is turn over
610 //---Test 2: pan from position( size*0.5f ) to position( size.width, size.height*0.5f ) to position( size * 0.75f ), page 1 will bent then slid back---
611 callbackTurnStarted.Reset();
612 callbackTurnFinished.Reset();
613 callbackPanStarted.Reset();
614 callbackPanFinished.Reset();
615 portraitView.GoToPage(5);
617 isTurningForwards = true;
619 //pan 10 frames from position( size.width, size.height*0.5f ) to position( size * 0.75f )
620 start = Vector2( size.width, size.height*0.5f );
621 direction = Vector2(-size.width*0.025f, size.height*0.025f);
622 PerformGestureDiagonalSwipe( application, start, direction, 5, true, false);
623 DALI_TEST_CHECK( callbackPanStarted.mSignalVerified );
624 DALI_TEST_CHECK( callbackTurnStarted.mSignalVerified );
625 DALI_TEST_CHECK( !callbackTurnFinished.mSignalVerified );
626 DALI_TEST_CHECK( !callbackPanFinished.mSignalVerified );
628 signalVerified[0] = false;
629 isTurningForwards = false;
630 PerformGestureDiagonalSwipe( application, start + direction*2 , direction, 5, false, true);
631 DALI_TEST_CHECK( !callbackTurnFinished.mSignalVerified );
632 DALI_TEST_CHECK( callbackPanFinished.mSignalVerified );
633 DALI_TEST_CHECK( callbackTurnStarted.mSignalVerified ); // start the sliding back
635 Wait(application, 1000);
636 DALI_TEST_CHECK( callbackTurnFinished.mSignalVerified );
637 DALI_TEST_CHECK( portraitView.GetCurrentPage() == pageIndex); // the page is not turned over
639 // ----Test 3: pan 10 frames from position( size*0.25f ) to position( size.width*0.75f, size.height*0.25f ), the previous page will be turned backwards---
640 callbackTurnStarted.Reset();
641 callbackTurnFinished.Reset();
642 callbackPanStarted.Reset();
643 callbackPanFinished.Reset();
644 portraitView.GoToPage(10);
645 pageIndex = 9; // will turn the previous page back
646 isTurningForwards = false;
648 direction = Vector2(size.x*0.05f, 0.f);
649 PerformGestureDiagonalSwipe( application, start, direction, 5, true, false);
650 DALI_TEST_CHECK( callbackPanStarted.mSignalVerified );
651 DALI_TEST_CHECK( !callbackTurnStarted.mSignalVerified );
652 DALI_TEST_CHECK( !callbackTurnFinished.mSignalVerified );
653 DALI_TEST_CHECK( !callbackPanFinished.mSignalVerified );
655 PerformGestureDiagonalSwipe( application, start+direction*5.f, direction, 5, false, true);
656 DALI_TEST_CHECK( callbackTurnStarted.mSignalVerified );
657 DALI_TEST_CHECK( callbackPanFinished.mSignalVerified );
658 DALI_TEST_CHECK( !callbackTurnFinished.mSignalVerified );
660 Wait( application, 1000 );
662 DALI_TEST_CHECK( callbackTurnFinished.mSignalVerified );
663 DALI_TEST_CHECK( portraitView.GetCurrentPage() == 9);