From: greynaga Date: Fri, 26 Oct 2018 11:24:53 +0000 (+0100) Subject: [dali_1.3.47] Merge branch 'devel/master' X-Git-Tag: dali_1.9.8~5^2~74 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=46378e74ac2f46a4ca7c6a038de9c42639d60faa;hp=a6df5a1084f5784b49e20b4bb3298ca0a953bc35 [dali_1.3.47] Merge branch 'devel/master' Change-Id: I43fd5e71b3188a077b10b22365c4b653327dc8b4 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 931b3e6..9114e20 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,6 +104,7 @@ SET( SOURCES ${SOURCES} ${internal_src_dir}/layouting/layout-group-data-impl.cpp ${internal_src_dir}/layouting/layout-controller-impl.cpp ${internal_src_dir}/layouting/layout-controller-debug.cpp + ${internal_src_dir}/layouting/layout-transition-data-impl.cpp ${internal_src_dir}/visuals/animated-image/animated-image-visual.cpp ${internal_src_dir}/visuals/animated-image/image-cache.cpp ${internal_src_dir}/visuals/animated-image/fixed-image-cache.cpp diff --git a/automated-tests/src/dali-toolkit-internal/CMakeLists.txt b/automated-tests/src/dali-toolkit-internal/CMakeLists.txt index 037fd71..df591a7 100755 --- a/automated-tests/src/dali-toolkit-internal/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit-internal/CMakeLists.txt @@ -14,6 +14,7 @@ SET(TC_SOURCES utc-Dali-ItemView-internal.cpp utc-Dali-LogicalModel.cpp utc-Dali-PropertyHelper.cpp + utc-Dali-SizeNegotiationMapper.cpp utc-Dali-Text-CharacterSetConversion.cpp utc-Dali-Text-Controller.cpp utc-Dali-Text-Cursor.cpp diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-SizeNegotiationMapper.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-SizeNegotiationMapper.cpp new file mode 100644 index 0000000..692cef7 --- /dev/null +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-SizeNegotiationMapper.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include + +#include +#include +#include +#include +#include + +using namespace Dali; +using namespace Toolkit; + +int UtcDaliLayoutingSizeNegotiationMapper_01(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliLayoutingSizeNegotiationMapper_01 - Test mapping Dimension::ALL_DIMENSIONS"); + + auto control = Control::New(); + control.SetName( "fitToChildrenControl" ); + DevelControl::SetLayoutingRequired( control, true ); + control.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS ); + + Toolkit::Internal::Control& controlImpl = Toolkit::Internal::GetImplementation( control ); + Toolkit::Internal::Control::Impl& controlDataImpl = Toolkit::Internal::Control::Impl::Get( controlImpl ); + Toolkit::Internal::LayoutItemPtr layout = controlDataImpl.GetLayout(); + // Set defaults which should be overriden by mapper + control.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + control.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + + // Set ALL_DIMENSIONS specifications using mapper + Toolkit::Internal::SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( control, layout, Dimension::ALL_DIMENSIONS ); + + // Test WIDTH and HEIGHT updated + DALI_TEST_EQUALS( control.GetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION ), Property::Value( ChildLayoutData::WRAP_CONTENT ), TEST_LOCATION ); + DALI_TEST_EQUALS( control.GetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION ), Property::Value( ChildLayoutData::WRAP_CONTENT ), TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLayoutingSizeNegotiationMapper_02(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliLayoutingSizeNegotiationMapper_02 - Test mapping for Dimension::WIDTH only"); + + auto control = Control::New(); + control.SetName( "fitToChildrenControl" ); + DevelControl::SetLayoutingRequired( control, true ); + control.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS ); + + Toolkit::Internal::Control& controlImpl = Toolkit::Internal::GetImplementation( control ); + Toolkit::Internal::Control::Impl& controlDataImpl = Toolkit::Internal::Control::Impl::Get( controlImpl ); + Toolkit::Internal::LayoutItemPtr layout = controlDataImpl.GetLayout(); + + // Set defaults which should be overriden by mapper + control.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + control.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + + // Set WIDTH specifications using mapper + Toolkit::Internal::SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( control, layout, Dimension::WIDTH ); + + // Test WIDTH only updated. + DALI_TEST_EQUALS( control.GetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION ), Property::Value( ChildLayoutData::WRAP_CONTENT ), TEST_LOCATION ); + DALI_TEST_EQUALS( control.GetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION ), Property::Value( ChildLayoutData::MATCH_PARENT ), TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLayoutingSizeNegotiationMapper_03(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliLayoutingSizeNegotiationMapper_03 - Test mapping for Dimension::HEIGHT only"); + + auto control = Control::New(); + control.SetName( "fitToChildrenControl" ); + DevelControl::SetLayoutingRequired( control, true ); + control.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS ); + + Toolkit::Internal::Control& controlImpl = Toolkit::Internal::GetImplementation( control ); + Toolkit::Internal::Control::Impl& controlDataImpl = Toolkit::Internal::Control::Impl::Get( controlImpl ); + Toolkit::Internal::LayoutItemPtr layout = controlDataImpl.GetLayout(); + + // Set defaults which should be overriden by mapper + control.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + control.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + + // Set HEIGHT specifications using mapper + Toolkit::Internal::SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( control, layout, Dimension::HEIGHT ); + + // Test HEIGHT only updated. + DALI_TEST_EQUALS( control.GetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION ), Property::Value( ChildLayoutData::MATCH_PARENT ), TEST_LOCATION ); + DALI_TEST_EQUALS( control.GetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION ), Property::Value( ChildLayoutData::WRAP_CONTENT), TEST_LOCATION ); + + END_TEST; +} \ No newline at end of file diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp old mode 100644 new mode 100755 index 94bb485..559e34e --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp @@ -1649,6 +1649,94 @@ int UtcDaliTextMultiLanguageValidateFonts01(void) Vector fontDescriptions11; fontDescriptions11.PushBack( fontDescription1101 ); + FontRun fontRun1201 = + { + { + 0u, + 6u + }, + 8u + }; + FontRun fontRun1202 = + { + { + 6u, + 1u + }, + 9u + }; + FontRun fontRun1203 = + { + { + 7u, + 5u + }, + 8u + }; + Vector fontRuns12; + fontRuns12.PushBack( fontRun1201 ); + fontRuns12.PushBack( fontRun1202 ); + fontRuns12.PushBack( fontRun1203 ); + + FontDescriptionRun fontDescription1201 = + { + { + 0u, + 6u + }, + const_cast( "TizenSans" ), + 9u, + TextAbstraction::FontWeight::NORMAL, + TextAbstraction::FontWidth::NORMAL, + TextAbstraction::FontSlant::NORMAL, + 0u, + true, + false, + false, + false, + false + }; + FontDescriptionRun fontDescription1202 = + { + { + 6u, + 1u + }, + const_cast( "TizenSans" ), + 9u, + TextAbstraction::FontWeight::NORMAL, + TextAbstraction::FontWidth::NORMAL, + TextAbstraction::FontSlant::NORMAL, + 0u, + true, + false, + false, + false, + false + }; + FontDescriptionRun fontDescription1203 = + { + { + 7u, + 5u + }, + const_cast( "TizenSans" ), + 9u, + TextAbstraction::FontWeight::NORMAL, + TextAbstraction::FontWidth::NORMAL, + TextAbstraction::FontSlant::NORMAL, + 0u, + true, + false, + false, + false, + false + }; + Vector fontDescriptions12; + fontDescriptions12.PushBack( fontDescription1201 ); + fontDescriptions12.PushBack( fontDescription1202 ); + fontDescriptions12.PushBack( fontDescription1203 ); + const ValidateFontsData data[] = { { @@ -1761,8 +1849,18 @@ int UtcDaliTextMultiLanguageValidateFonts01(void) fontDescriptions11, fontRuns11 }, + { + "Common script.", + "Hello \tworld", + "/tizen/TizenSansRegular.ttf", + TextAbstraction::FontClient::DEFAULT_POINT_SIZE, + 0u, + 12u, + fontDescriptions12, + fontRuns12 + }, }; - const unsigned int numberOfTests = 11u; + const unsigned int numberOfTests = 12u; for( unsigned int index = 0u; index < numberOfTests; ++index ) { diff --git a/automated-tests/src/dali-toolkit/CMakeLists.txt b/automated-tests/src/dali-toolkit/CMakeLists.txt index 7ad18b7..fe9102e 100755 --- a/automated-tests/src/dali-toolkit/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit/CMakeLists.txt @@ -10,6 +10,7 @@ SET(TC_SOURCES utc-Dali-AbsoluteLayout.cpp utc-Dali-Alignment.cpp utc-Dali-AnimatedImageVisual.cpp + utc-Dali-BinLayout.cpp utc-Dali-BloomView.cpp utc-Dali-BubbleEmitter.cpp utc-Dali-Builder.cpp @@ -26,8 +27,10 @@ SET(TC_SOURCES utc-Dali-JsonParser.cpp utc-Dali-KeyInputFocusManager.cpp utc-Dali-Layouting.cpp - utc-Dali-LayoutingResizePolicy.cpp + utc-Dali-LayoutingAnimation.cpp utc-Dali-LayoutingNesting.cpp + utc-Dali-LayoutingResizePolicy.cpp + utc-Dali-LayoutingSettingAndRemoval.cpp utc-Dali-PageTurnView.cpp utc-Dali-Scene3dView.cpp utc-Dali-Script.cpp diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.cpp index cf97813..b9c8245 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.cpp @@ -26,9 +26,9 @@ using namespace Dali; -int test_return_value = TET_UNDEF; +int32_t test_return_value = TET_UNDEF; -void tet_result(int value) +void tet_result(int32_t value) { // First TET_PASS should set to zero // first TET_FAIL should prevent any further TET_PASS from setting back to zero @@ -81,14 +81,14 @@ void DALI_TEST_EQUALS( const BaseHandle& baseHandle1, const BaseHandle& baseHand DALI_TEST_EQUALS< const BaseHandle& >( baseHandle1, baseHandle2, location ); } -void DALI_TEST_EQUALS( const size_t value1, const unsigned int value2, const char* location ) +void DALI_TEST_EQUALS( const size_t value1, const uint32_t value2, const char* location ) { - DALI_TEST_EQUALS< unsigned int>( ( unsigned int )( value1 ), value2, location ); + DALI_TEST_EQUALS< uint32_t >( ( uint32_t )( value1 ), value2, location ); } -void DALI_TEST_EQUALS( const unsigned int value1, const size_t value2, const char* location ) +void DALI_TEST_EQUALS( const uint32_t value1, const size_t value2, const char* location ) { - DALI_TEST_EQUALS< unsigned int >( value1, ( unsigned int )( value2 ), location ); + DALI_TEST_EQUALS< uint32_t >( value1, ( uint32_t )( value2 ), location ); } void DALI_TEST_EQUALS( const Matrix3& matrix1, const Matrix3& matrix2, const char* location) @@ -97,7 +97,7 @@ void DALI_TEST_EQUALS( const Matrix3& matrix1, const Matrix3& matrix2, const cha const float* m2 = matrix2.AsFloat(); bool equivalent = true; - for (int i=0;i<9;++i) + for (int32_t i=0;i<9;++i) { if( ! (fabsf(m1[i] - m2[i])< GetRangedEpsilon(m1[i], m2[i])) ) { @@ -132,7 +132,7 @@ void DALI_TEST_EQUALS( const Matrix3& matrix1, const Matrix3& matrix2, float eps const float* m2 = matrix2.AsFloat(); bool equivalent = true; - for (int i=0;i<9;++i) + for (int32_t i=0;i<9;++i) { equivalent &= (fabsf(m1[i] - m2[i])GetPackedPixelsProfile()->ReserveBuffer( pixelFormat, imageWidth, imageHeight, imageWidth, imageHeight ); - unsigned int bytesPerPixel = GetBytesPerPixel( pixelFormat ); - unsigned int initialColor = 0xFF; + uint32_t bytesPerPixel = GetBytesPerPixel( pixelFormat ); + uint32_t initialColor = 0xFF; memset( pixbuffer, initialColor, imageHeight*imageWidth*bytesPerPixel); Integration::ResourcePointer resourcePtr(bitmap); diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.h index 4f71920..ed1a65f 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.h @@ -64,9 +64,9 @@ constexpr int32_t basenameIndex( const char * const path, const int32_t index = #define TET_FAIL 1 #define TET_PASS 0 -extern int test_return_value; +extern int32_t test_return_value; -void tet_result(int value); +void tet_result(int32_t value); #define END_TEST \ return ((test_return_value>0)?1:0) @@ -199,20 +199,20 @@ inline void DALI_TEST_EQUALS( TimePeriod value1, TimePeriod value2, void DALI_TEST_EQUALS( const BaseHandle& baseHandle1, const BaseHandle& baseHandle2, const char* location ); /** - * Test whether a size_t value and an unsigned int are equal. + * Test whether a size_t value and an uint32_t are equal. * @param[in] value1 The first value * @param[in] value2 The second value * @param[in] location The TEST_LOCATION macro should be used here */ -void DALI_TEST_EQUALS( const size_t value1, const unsigned int value2, const char* location ); +void DALI_TEST_EQUALS( const size_t value1, const uint32_t value2, const char* location ); /** - * Test whether an unsigned int and a size_t value and are equal. + * Test whether an uint32_t and a size_t value and are equal. * @param[in] value1 The first value * @param[in] value2 The second value * @param[in] location The TEST_LOCATION macro should be used here */ -void DALI_TEST_EQUALS( const unsigned int value1, const size_t value2, const char* location ); +void DALI_TEST_EQUALS( const uint32_t value1, const size_t value2, const char* location ); /** * Test whether two Matrix3 objects are equal. @@ -374,11 +374,11 @@ struct DefaultFunctionCoverage // Helper to Create buffer image BufferImage CreateBufferImage(); -BufferImage CreateBufferImage(int width, int height, const Vector4& color); +BufferImage CreateBufferImage(int32_t width, int32_t height, const Vector4& color); // Prepare a resource image to be loaded. Should be called before creating the ResourceImage -void PrepareResourceImage( TestApplication& application, unsigned int imageWidth, unsigned int imageHeight, Pixel::Format pixelFormat ); +void PrepareResourceImage( TestApplication& application, uint32_t imageWidth, uint32_t imageHeight, Pixel::Format pixelFormat ); // Test namespace to prevent pollution of Dali namespace, add Test helper functions here namespace Test diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.cpp index 8bb7176..a20ef6d 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,42 +21,22 @@ namespace Dali { -TestApplication::TestApplication( size_t surfaceWidth, - size_t surfaceHeight, - float horizontalDpi, - float verticalDpi, +TestApplication::TestApplication( uint32_t surfaceWidth, + uint32_t surfaceHeight, + uint32_t horizontalDpi, + uint32_t verticalDpi, ResourcePolicy::DataRetention policy) : mCore( NULL ), mSurfaceWidth( surfaceWidth ), mSurfaceHeight( surfaceHeight ), mFrame( 0u ), - mDpi( horizontalDpi, verticalDpi ), + mDpi{ horizontalDpi, verticalDpi }, mLastVSyncTime(0u), mDataRetentionPolicy( policy ) { Initialize(); } -TestApplication::TestApplication( bool initialize, - size_t surfaceWidth, - size_t surfaceHeight, - float horizontalDpi, - float verticalDpi, - ResourcePolicy::DataRetention policy) -: mCore( NULL ), - mSurfaceWidth( surfaceWidth ), - mSurfaceHeight( surfaceHeight ), - mFrame( 0u ), - mDpi( horizontalDpi, verticalDpi ), - mLastVSyncTime(0u), - mDataRetentionPolicy( policy ) -{ - if ( initialize ) - { - Initialize(); - } -} - void TestApplication::Initialize() { // We always need the first update! @@ -165,7 +145,7 @@ void TestApplication::SendNotification() mCore->ProcessEvents(); } -void TestApplication::SetSurfaceWidth( unsigned int width, unsigned height ) +void TestApplication::SetSurfaceWidth( uint32_t width, uint32_t height ) { mSurfaceWidth = width; mSurfaceHeight = height; @@ -173,12 +153,12 @@ void TestApplication::SetSurfaceWidth( unsigned int width, unsigned height ) mCore->SurfaceResized( mSurfaceWidth, mSurfaceHeight ); } -void TestApplication::SetTopMargin( unsigned int margin ) +void TestApplication::SetTopMargin( uint32_t margin ) { mCore->SetTopMargin( margin ); } -void TestApplication::DoUpdate( unsigned int intervalMilliseconds, const char* location ) +void TestApplication::DoUpdate( uint32_t intervalMilliseconds, const char* location ) { if( GetUpdateStatus() == 0 && mRenderStatus.NeedsUpdate() == false && @@ -187,8 +167,8 @@ void TestApplication::DoUpdate( unsigned int intervalMilliseconds, const char* l fprintf(stderr, "WARNING - Update not required :%s\n", location==NULL?"NULL":location); } - unsigned int nextVSyncTime = mLastVSyncTime + intervalMilliseconds; - float elapsedSeconds = intervalMilliseconds / 1e3f; + uint32_t nextVSyncTime = mLastVSyncTime + intervalMilliseconds; + float elapsedSeconds = static_cast( intervalMilliseconds ) * 0.001f; mCore->Update( elapsedSeconds, mLastVSyncTime, nextVSyncTime, mStatus, false, false ); @@ -197,7 +177,7 @@ void TestApplication::DoUpdate( unsigned int intervalMilliseconds, const char* l mLastVSyncTime = nextVSyncTime; } -bool TestApplication::Render( unsigned int intervalMilliseconds, const char* location ) +bool TestApplication::Render( uint32_t intervalMilliseconds, const char* location ) { DoUpdate( intervalMilliseconds, location ); mCore->Render( mRenderStatus, false ); @@ -207,12 +187,12 @@ bool TestApplication::Render( unsigned int intervalMilliseconds, const char* loc return mStatus.KeepUpdating() || mRenderStatus.NeedsUpdate(); } -unsigned int TestApplication::GetUpdateStatus() +uint32_t TestApplication::GetUpdateStatus() { return mStatus.KeepUpdating(); } -bool TestApplication::UpdateOnly( unsigned int intervalMilliseconds ) +bool TestApplication::UpdateOnly( uint32_t intervalMilliseconds ) { DoUpdate( intervalMilliseconds ); return mStatus.KeepUpdating(); @@ -240,11 +220,11 @@ void TestApplication::ResetContext() mCore->ContextCreated(); } -unsigned int TestApplication::Wait( unsigned int durationToWait ) +uint32_t TestApplication::Wait( uint32_t durationToWait ) { int time = 0; - for(unsigned int i = 0; i <= ( durationToWait / RENDER_FRAME_INTERVAL); i++) + for(uint32_t i = 0; i <= ( durationToWait / RENDER_FRAME_INTERVAL); i++) { SendNotification(); Render(RENDER_FRAME_INTERVAL); diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.h index 6b8b236..49f2b3c 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.h @@ -36,32 +36,25 @@ class DALI_CORE_API TestApplication : public ConnectionTracker public: // Default values derived from H2 device. - static const unsigned int DEFAULT_SURFACE_WIDTH = 480; - static const unsigned int DEFAULT_SURFACE_HEIGHT = 800; + static const uint32_t DEFAULT_SURFACE_WIDTH = 480; + static const uint32_t DEFAULT_SURFACE_HEIGHT = 800; #ifdef _CPP11 - static constexpr float DEFAULT_HORIZONTAL_DPI = 220.0f; - static constexpr float DEFAULT_VERTICAL_DPI = 217.0f; + static constexpr uint32_t DEFAULT_HORIZONTAL_DPI = 220; + static constexpr uint32_t DEFAULT_VERTICAL_DPI = 217; #else - static const float DEFAULT_HORIZONTAL_DPI = 220.0f; - static const float DEFAULT_VERTICAL_DPI = 217.0f; + static const uint32_t DEFAULT_HORIZONTAL_DPI = 220; + static const uint32_t DEFAULT_VERTICAL_DPI = 217; #endif - static const unsigned int DEFAULT_RENDER_INTERVAL = 1; + static const uint32_t DEFAULT_RENDER_INTERVAL = 1; - static const unsigned int RENDER_FRAME_INTERVAL = 16; + static const uint32_t RENDER_FRAME_INTERVAL = 16; - TestApplication( size_t surfaceWidth = DEFAULT_SURFACE_WIDTH, - size_t surfaceHeight = DEFAULT_SURFACE_HEIGHT, - float horizontalDpi = DEFAULT_HORIZONTAL_DPI, - float verticalDpi = DEFAULT_VERTICAL_DPI, - ResourcePolicy::DataRetention policy = ResourcePolicy::DALI_DISCARDS_ALL_DATA); - - TestApplication( bool initialize, - size_t surfaceWidth = DEFAULT_SURFACE_WIDTH, - size_t surfaceHeight = DEFAULT_SURFACE_HEIGHT, - float horizontalDpi = DEFAULT_HORIZONTAL_DPI, - float verticalDpi = DEFAULT_VERTICAL_DPI, + TestApplication( uint32_t surfaceWidth = DEFAULT_SURFACE_WIDTH, + uint32_t surfaceHeight = DEFAULT_SURFACE_HEIGHT, + uint32_t horizontalDpi = DEFAULT_HORIZONTAL_DPI, + uint32_t verticalDpi = DEFAULT_VERTICAL_DPI, ResourcePolicy::DataRetention policy = ResourcePolicy::DALI_DISCARDS_ALL_DATA); void Initialize(); @@ -76,18 +69,18 @@ public: TestGestureManager& GetGestureManager(); void ProcessEvent(const Integration::Event& event); void SendNotification(); - void SetSurfaceWidth( unsigned int width, unsigned height ); - void SetTopMargin( unsigned int margin ); - bool Render( unsigned int intervalMilliseconds = DEFAULT_RENDER_INTERVAL, const char* location=NULL ); - unsigned int GetUpdateStatus(); - bool UpdateOnly( unsigned int intervalMilliseconds = DEFAULT_RENDER_INTERVAL ); + void SetSurfaceWidth( uint32_t width, unsigned height ); + void SetTopMargin( uint32_t margin ); + bool Render( uint32_t intervalMilliseconds = DEFAULT_RENDER_INTERVAL, const char* location=NULL ); + uint32_t GetUpdateStatus(); + bool UpdateOnly( uint32_t intervalMilliseconds = DEFAULT_RENDER_INTERVAL ); bool RenderOnly( ); void ResetContext(); bool GetRenderNeedsUpdate(); - unsigned int Wait( unsigned int durationToWait ); + uint32_t Wait( uint32_t durationToWait ); private: - void DoUpdate( unsigned int intervalMilliseconds, const char* location=NULL ); + void DoUpdate( uint32_t intervalMilliseconds, const char* location=NULL ); protected: TestPlatformAbstraction mPlatformAbstraction; @@ -101,12 +94,12 @@ protected: Integration::Core* mCore; - unsigned int mSurfaceWidth; - unsigned int mSurfaceHeight; - unsigned int mFrame; + uint32_t mSurfaceWidth; + uint32_t mSurfaceHeight; + uint32_t mFrame; - Vector2 mDpi; - unsigned int mLastVSyncTime; + struct { uint32_t x; uint32_t y; } mDpi; + uint32_t mLastVSyncTime; ResourcePolicy::DataRetention mDataRetentionPolicy; }; diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.cpp index 65a884e..858e930 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.cpp @@ -132,9 +132,9 @@ void TestGlSyncAbstraction::ResetTrace() { mTrace.Reset(); } */ TraceCallStack& TestGlSyncAbstraction::GetTrace() { return mTrace; } -int TestGlSyncAbstraction::GetNumberOfSyncObjects() +int32_t TestGlSyncAbstraction::GetNumberOfSyncObjects() { - return mSyncObjects.size(); + return static_cast( mSyncObjects.size() ); } diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.h index 979987b..c2db8d2 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.h @@ -105,7 +105,7 @@ public: // TEST FUNCTIONS * * @return the number of sync objects */ - int GetNumberOfSyncObjects(); + int32_t GetNumberOfSyncObjects(); private: diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-harness.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-harness.cpp index 645d74b..c4a27d1 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-harness.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-harness.cpp @@ -27,7 +27,7 @@ namespace TestHarness { -typedef std::map RunningTestCases; +typedef std::map RunningTestCases; const char* basename(const char* path) { @@ -41,9 +41,9 @@ const char* basename(const char* path) return slash; } -int RunTestCase( struct ::testcase_s& testCase ) +int32_t RunTestCase( struct ::testcase_s& testCase ) { - int result = EXIT_STATUS_TESTCASE_FAILED; + int32_t result = EXIT_STATUS_TESTCASE_FAILED; // dont want to catch exception as we want to be able to get // gdb stack trace from the first error @@ -69,11 +69,11 @@ int RunTestCase( struct ::testcase_s& testCase ) } -int RunTestCaseInChildProcess( struct ::testcase_s& testCase, bool suppressOutput ) +int32_t RunTestCaseInChildProcess( struct ::testcase_s& testCase, bool suppressOutput ) { - int testResult = EXIT_STATUS_TESTCASE_FAILED; + int32_t testResult = EXIT_STATUS_TESTCASE_FAILED; - int pid = fork(); + int32_t pid = fork(); if( pid == 0 ) // Child process { if( suppressOutput ) @@ -84,12 +84,12 @@ int RunTestCaseInChildProcess( struct ::testcase_s& testCase, bool suppressOutpu else { printf("\n"); - for(int i=0; i<80; ++i) printf("#"); + for(int32_t i=0; i<80; ++i) printf("#"); printf("\nTC: %s\n", testCase.name); fflush(stdout); } - int status = RunTestCase( testCase ); + int32_t status = RunTestCase( testCase ); if( ! suppressOutput ) { @@ -107,8 +107,8 @@ int RunTestCaseInChildProcess( struct ::testcase_s& testCase, bool suppressOutpu } else // Parent process { - int status = 0; - int childPid = waitpid(pid, &status, 0); + int32_t status = 0; + int32_t childPid = waitpid(pid, &status, 0); if( childPid == -1 ) { perror("waitpid"); @@ -127,7 +127,7 @@ int RunTestCaseInChildProcess( struct ::testcase_s& testCase, bool suppressOutpu } else if(WIFSIGNALED(status) ) { - int signal = WTERMSIG(status); + int32_t signal = WTERMSIG(status); testResult = EXIT_STATUS_TESTCASE_ABORTED; if( signal == SIGABRT ) { @@ -148,7 +148,7 @@ int RunTestCaseInChildProcess( struct ::testcase_s& testCase, bool suppressOutpu return testResult; } -void OutputStatistics( const char* processName, int numPasses, int numFailures ) +void OutputStatistics( const char* processName, int32_t numPasses, int32_t numFailures ) { FILE* fp=fopen("summary.xml", "a"); if( fp != NULL ) @@ -175,15 +175,15 @@ void OutputStatistics( const char* processName, int numPasses, int numFailures ) } } -int RunAll( const char* processName, ::testcase tc_array[] ) +int32_t RunAll( const char* processName, ::testcase tc_array[] ) { - int numFailures = 0; - int numPasses = 0; + int32_t numFailures = 0; + int32_t numPasses = 0; // Run test cases in child process( to kill output/handle signals ), but run serially. - for( unsigned int i=0; tc_array[i].name; i++) + for( uint32_t i=0; tc_array[i].name; i++) { - int result = RunTestCaseInChildProcess( tc_array[i], false ); + int32_t result = RunTestCaseInChildProcess( tc_array[i], false ); if( result == 0 ) { numPasses++; @@ -200,26 +200,26 @@ int RunAll( const char* processName, ::testcase tc_array[] ) } // Constantly runs up to MAX_NUM_CHILDREN processes -int RunAllInParallel( const char* processName, ::testcase tc_array[], bool reRunFailed) +int32_t RunAllInParallel( const char* processName, ::testcase tc_array[], bool reRunFailed) { - int numFailures = 0; - int numPasses = 0; + int32_t numFailures = 0; + int32_t numPasses = 0; RunningTestCases children; - std::vector failedTestCases; + std::vector failedTestCases; // Fork up to MAX_NUM_CHILDREN processes, then // wait. As soon as a proc completes, fork the next. - int nextTestCase = 0; - int numRunningChildren = 0; + int32_t nextTestCase = 0; + int32_t numRunningChildren = 0; while( tc_array[nextTestCase].name || numRunningChildren > 0) { // Create more children (up to the max number or til the end of the array) while( numRunningChildren < MAX_NUM_CHILDREN && tc_array[nextTestCase].name ) { - int pid = fork(); + int32_t pid = fork(); if( pid == 0 ) // Child process { close(STDOUT_FILENO); @@ -242,8 +242,8 @@ int RunAllInParallel( const char* processName, ::testcase tc_array[], bool reRu // Wait for the next child to finish - int status=0; - int childPid = waitpid(-1, &status, 0); + int32_t status=0; + int32_t childPid = waitpid(-1, &status, 0); if( childPid == -1 ) { perror("waitpid"); @@ -254,7 +254,7 @@ int RunAllInParallel( const char* processName, ::testcase tc_array[], bool reRu { if( childPid > 0 ) { - int testResult = WEXITSTATUS(status); + int32_t testResult = WEXITSTATUS(status); if( testResult ) { printf("Test case %s failed: %d\n", children[childPid].testCaseName, testResult); @@ -296,12 +296,12 @@ int RunAllInParallel( const char* processName, ::testcase tc_array[], bool reRu if( reRunFailed ) { - for( unsigned int i=0; i #include +#include namespace TestHarness { @@ -34,11 +35,11 @@ enum ExitStatus EXIT_STATUS_TESTCASE_NOT_FOUND // 6 }; -const int MAX_NUM_CHILDREN(16); +const int32_t MAX_NUM_CHILDREN(16); struct TestCase { - int testCase; + int32_t testCase; const char* testCaseName; TestCase() @@ -47,7 +48,7 @@ struct TestCase { } - TestCase(int tc, const char* name) + TestCase(int32_t tc, const char* name) : testCase(tc), testCaseName(name) { @@ -70,7 +71,7 @@ struct TestCase * Run a test case * @param[in] testCase The Testkit-lite test case to run */ -int RunTestCase( struct testcase_s& testCase ); +int32_t RunTestCase( struct testcase_s& testCase ); /** * Run all test cases in parallel @@ -79,7 +80,7 @@ int RunTestCase( struct testcase_s& testCase ); * @param[in] reRunFailed True if failed test cases should be re-run * @return 0 on success */ -int RunAllInParallel(const char* processName, testcase tc_array[], bool reRunFailed); +int32_t RunAllInParallel(const char* processName, testcase tc_array[], bool reRunFailed); /** * Run all test cases in serial @@ -87,7 +88,7 @@ int RunAllInParallel(const char* processName, testcase tc_array[], bool reRunFai * @param[in] tc_array The array of auto-generated testkit-lite test cases * @return 0 on success */ -int RunAll( const char* processName, testcase tc_array[] ); +int32_t RunAll( const char* processName, testcase tc_array[] ); /** * Find the named test case in the given array, and run it @@ -95,7 +96,7 @@ int RunAll( const char* processName, testcase tc_array[] ); * @param[in] testCaseName the name of the test case to run * @return 0 on success */ -int FindAndRunTestCase(::testcase tc_array[], const char* testCaseName); +int32_t FindAndRunTestCase(::testcase tc_array[], const char* testCaseName); /** * Display usage instructions for this program diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-native-image.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-native-image.cpp index da4e7e8..ee6c17a 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-native-image.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-native-image.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,12 +23,12 @@ namespace Dali { -TestNativeImagePointer TestNativeImage::New(int width, int height) +TestNativeImagePointer TestNativeImage::New(uint32_t width, uint32_t height) { return new TestNativeImage(width, height); } -TestNativeImage::TestNativeImage(int width, int height) +TestNativeImage::TestNativeImage(uint32_t width, uint32_t height) : mWidth(width), mHeight(height), mExtensionCreateCalls(0), mExtensionDestroyCalls(0), mTargetTextureCalls(0),createResult(true) { mExtension = new TestNativeImageExtension(); @@ -39,12 +39,12 @@ TestNativeImage::~TestNativeImage() } -TestNativeImageNoExtPointer TestNativeImageNoExt::New(int width, int height) +TestNativeImageNoExtPointer TestNativeImageNoExt::New(uint32_t width, uint32_t height) { return new TestNativeImageNoExt(width, height); } -TestNativeImageNoExt::TestNativeImageNoExt(int width, int height) +TestNativeImageNoExt::TestNativeImageNoExt(uint32_t width, uint32_t height) : mWidth(width), mHeight(height), mExtensionCreateCalls(0), mExtensionDestroyCalls(0), mTargetTextureCalls(0),createResult(true) { } diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-native-image.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-native-image.h index 5cb4b27..a664107 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-native-image.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-native-image.h @@ -36,35 +36,35 @@ public: inline const char* GetCustomFragmentPreFix(){return "#extension GL_OES_EGL_image_external:require\n";} inline const char* GetCustomSamplerTypename(){return "samplerExternalOES";} - inline int GetEglImageTextureTarget(){return GL_TEXTURE_EXTERNAL_OES;} + inline int32_t GetEglImageTextureTarget(){return GL_TEXTURE_EXTERNAL_OES;} }; class DALI_CORE_API TestNativeImage : public Dali::NativeImageInterface { public: - static TestNativeImagePointer New(int width, int height); + static TestNativeImagePointer New(uint32_t width, uint32_t height); inline void SetGlExtensionCreateResult(bool result){ createResult = result;} inline virtual bool GlExtensionCreate() { ++mExtensionCreateCalls; return createResult;}; inline virtual void GlExtensionDestroy() { ++mExtensionDestroyCalls; }; inline virtual GLenum TargetTexture() { ++mTargetTextureCalls; return 0;}; inline virtual void PrepareTexture() {}; - inline virtual unsigned int GetWidth() const {return mWidth;}; - inline virtual unsigned int GetHeight() const {return mHeight;}; + inline virtual uint32_t GetWidth() const {return mWidth;}; + inline virtual uint32_t GetHeight() const {return mHeight;}; inline virtual bool RequiresBlending() const {return true;}; inline virtual Dali::NativeImageInterface::Extension* GetExtension() {return mExtension;} private: - TestNativeImage(int width, int height); + TestNativeImage(uint32_t width, uint32_t height); virtual ~TestNativeImage(); - int mWidth; - int mHeight; + uint32_t mWidth; + uint32_t mHeight; public: - int mExtensionCreateCalls; - int mExtensionDestroyCalls; - int mTargetTextureCalls; + int32_t mExtensionCreateCalls; + int32_t mExtensionDestroyCalls; + int32_t mTargetTextureCalls; bool createResult; TestNativeImageExtension* mExtension; @@ -74,27 +74,27 @@ public: class DALI_CORE_API TestNativeImageNoExt : public Dali::NativeImageInterface { public: - static TestNativeImageNoExtPointer New(int width, int height); + static TestNativeImageNoExtPointer New(uint32_t width, uint32_t height); inline void SetGlExtensionCreateResult(bool result){ createResult = result;} inline virtual bool GlExtensionCreate() { ++mExtensionCreateCalls; return createResult;}; inline virtual void GlExtensionDestroy() { ++mExtensionDestroyCalls; }; inline virtual GLenum TargetTexture() { ++mTargetTextureCalls; return 1;}; inline virtual void PrepareTexture() {}; - inline virtual unsigned int GetWidth() const {return mWidth;}; - inline virtual unsigned int GetHeight() const {return mHeight;}; + inline virtual uint32_t GetWidth() const {return mWidth;}; + inline virtual uint32_t GetHeight() const {return mHeight;}; inline virtual bool RequiresBlending() const {return true;}; private: - TestNativeImageNoExt(int width, int height); + TestNativeImageNoExt(uint32_t width, uint32_t height); virtual ~TestNativeImageNoExt(); - int mWidth; - int mHeight; + uint32_t mWidth; + uint32_t mHeight; public: - int mExtensionCreateCalls; - int mExtensionDestroyCalls; - int mTargetTextureCalls; + int32_t mExtensionCreateCalls; + int32_t mExtensionDestroyCalls; + int32_t mTargetTextureCalls; bool createResult; }; diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.cpp index cb0b39c..190aa63 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.cpp @@ -43,7 +43,7 @@ ImageDimensions TestPlatformAbstraction::GetClosestImageSize( const std::string& SamplingMode::Type samplingMode, bool orientationCorrection ) { - ImageDimensions closestSize = ImageDimensions( mClosestSize.x, mClosestSize.y ); + ImageDimensions closestSize = ImageDimensions( mClosestSize ); mTrace.PushCall("GetClosestImageSize", ""); return closestSize; } @@ -54,7 +54,7 @@ ImageDimensions TestPlatformAbstraction::GetClosestImageSize( Integration::Resou SamplingMode::Type samplingMode, bool orientationCorrection ) { - ImageDimensions closestSize = ImageDimensions( mClosestSize.x, mClosestSize.y ); + ImageDimensions closestSize = ImageDimensions( mClosestSize ); mTrace.PushCall("GetClosestImageSize", ""); return closestSize; } @@ -115,9 +115,9 @@ void TestPlatformAbstraction::ClearReadyResources() mDecodedBitmap.Reset(); } -void TestPlatformAbstraction::SetClosestImageSize(const Vector2& size) +void TestPlatformAbstraction::SetClosestImageSize( const Vector2& size ) { - mClosestSize = size; + mClosestSize = ImageDimensions( static_cast( size.x ), static_cast( size.y ) ); } void TestPlatformAbstraction::SetLoadFileResult( bool result, Dali::Vector< unsigned char >& buffer ) diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.h index f31561e..dfa4d6c 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.h @@ -129,7 +129,7 @@ public: // TEST FUNCTIONS * @brief Sets the value returned by GetClosestImageSize. * @param[in] size The size that should be returned. */ - void SetClosestImageSize(const Vector2& size); + void SetClosestImageSize( const Vector2& size ); /** * @brief Sets the result return by LoadFile. @@ -177,7 +177,7 @@ private: mutable TraceCallStack mTrace; bool mIsLoadingResult; - Vector2 mClosestSize; + ImageDimensions mClosestSize; LoadFileResult mLoadFileResult; bool mSaveFileResult; diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-trace-call-stack.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-trace-call-stack.cpp index f57dc50..f894389 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-trace-call-stack.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-trace-call-stack.cpp @@ -164,14 +164,14 @@ bool TraceCallStack::FindMethodAndParamsFromStartIndex( std::string method, std: * @param[in] params A comma separated list of parameter values * @return index in the stack where the method was found or -1 otherwise */ -int TraceCallStack::FindIndexFromMethodAndParams(std::string method, std::string params) const +int32_t TraceCallStack::FindIndexFromMethodAndParams(std::string method, std::string params) const { - int index = -1; + int32_t index = -1; for( size_t i=0; i < mCallStack.size(); i++ ) { if( 0 == mCallStack[i].method.compare(method) && 0 == mCallStack[i].paramList.compare(params) ) { - index = i; + index = static_cast( i ); break; } } @@ -180,7 +180,7 @@ int TraceCallStack::FindIndexFromMethodAndParams(std::string method, std::string int TraceCallStack::FindIndexFromMethodAndParams(std::string method, const TraceCallStack::NamedParams& params) const { - int index = -1; + int32_t index = -1; for( size_t i=0; i < mCallStack.size(); i++ ) { if( 0 == mCallStack[i].method.compare(method) ) @@ -198,7 +198,7 @@ int TraceCallStack::FindIndexFromMethodAndParams(std::string method, const Trace } if( match == true ) { - index = i; + index = static_cast( i ); break; } } diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-trace-call-stack.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-trace-call-stack.h index d32f619..d569cba 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-trace-call-stack.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-trace-call-stack.h @@ -165,8 +165,8 @@ public: std::string GetTraceString() { std::stringstream traceStream; - int functionCount = mCallStack.size(); - for( int i = 0; i < functionCount; ++i ) + std::size_t functionCount = mCallStack.size(); + for( std::size_t i = 0; i < functionCount; ++i ) { Dali::TraceCallStack::FunctionCall functionCall = mCallStack[ i ]; traceStream << "StackTrace: Index:" << i << ", Function:" << functionCall.method << ", ParamList:" << functionCall.paramList << std::endl; diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h index e5d4a70..ee60af1 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h @@ -26,6 +26,18 @@ class EglInterface; class DisplayConnection; class ThreadSynchronizationInterface; +namespace Internal +{ + +namespace Adaptor +{ + +class GraphicsInterface; + +} // namespace Adaptor + +} // namespace Internal + namespace Integration { @@ -40,13 +52,13 @@ public: virtual void GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) { dpiHorizontal = dpiVertical = 96; } - virtual void InitializeEgl( EglInterface& egl ) {} + virtual void InitializeGraphics( Dali::Internal::Adaptor::GraphicsInterface& graphics, Dali::DisplayConnection& displayConnection ) {}; - virtual void CreateEglSurface( EglInterface& egl ) {} + virtual void CreateSurface() {} - virtual void DestroyEglSurface( EglInterface& egl ) {} + virtual void DestroySurface() {} - virtual bool ReplaceEGLSurface( EglInterface& egl ) { return false; } + virtual bool ReplaceGraphicsSurface() { return false; } virtual void MoveResize( Dali::PositionSize positionSize ) {} @@ -54,9 +66,9 @@ public: virtual void StartRender() {} - virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface ) { return false; } + virtual bool PreRender( bool resizingSurface ) { return false; } - virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ) {} + virtual void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface ) {} virtual void StopRender() {} diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-test-application.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-test-application.h index 1301b8f..2b1db83 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-test-application.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-test-application.h @@ -39,9 +39,8 @@ public: size_t surfaceHeight = DEFAULT_SURFACE_HEIGHT, float horizontalDpi = DEFAULT_HORIZONTAL_DPI, float verticalDpi = DEFAULT_VERTICAL_DPI ) - : TestApplication( false, surfaceWidth, surfaceHeight, horizontalDpi, verticalDpi ) + : TestApplication( surfaceWidth, surfaceHeight, horizontalDpi, verticalDpi ) { - Initialize(); auto singletonService = SingletonService::Get(); Test::SetApplication( singletonService, *this ); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-BinLayout.cpp b/automated-tests/src/dali-toolkit/utc-Dali-BinLayout.cpp new file mode 100644 index 0000000..3122c71 --- /dev/null +++ b/automated-tests/src/dali-toolkit/utc-Dali-BinLayout.cpp @@ -0,0 +1,495 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include <../custom-layout.h> + +#include + +using namespace Dali; +using namespace Toolkit; + +namespace +{ +// Turns the given control into a Root layout control and adds it to the stage. +void SetupRootLayoutControl( Control& rootControl ) +{ + rootControl = Control::New(); + auto absoluteLayout = AbsoluteLayout::New(); + DevelControl::SetLayout( rootControl, absoluteLayout ); + rootControl.SetName( "RootAbsoluteLayout" ); + Stage stage = Stage::GetCurrent(); + stage.Add( rootControl ); +} + +void CreateDefaultBinContainer( Control& binContainer ) +{ + binContainer = Control::New(); + binContainer.SetName( "binContainer" ); + DevelControl::SetLayout( binContainer, BinLayout::New() ); + binContainer.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + binContainer.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); +} + +} // namespace + +void utc_dali_toolkit_bin_layouting_startup(void) +{ + test_return_value = TET_UNDEF; +} + +void utc_dali_toolkit_bin_layouting_cleanup(void) +{ + test_return_value = TET_PASS; +} + +int UtcDaliLayouting_BinLayoutDownCast(void) +{ + TestApplication application; + tet_infoline(" UtcDaliLayouting_BinLayoutDownCast - Testing Downcast"); + + BinLayout binLayout = BinLayout::New(); + + LayoutGroup layoutGroup( binLayout ); + + BinLayout binLayoutCandidate = BinLayout::DownCast( layoutGroup ); + DALI_TEST_CHECK( binLayoutCandidate ); + + END_TEST; +} + +int UtcDaliLayouting_BinLayoutAssignment(void) +{ + TestApplication application; + tet_infoline(" UtcDaliLayouting_BinLayoutAssignment - Testing operator="); + + BinLayout binLayout = BinLayout::New(); + BinLayout binLayout2; + + binLayout2 = binLayout; + + DALI_TEST_EQUALS( binLayout2, binLayout, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLayouting_BinLayoutCopyConstructor(void) +{ + TestApplication application; + tet_infoline(" UtcDaliLayouting_BinLayoutCopyConstructor - Testing copy constructor"); + + BinLayout binLayout1 = BinLayout::New(); + BinLayout binLayout2( binLayout1 ); + + DALI_TEST_EQUALS( binLayout1, binLayout2, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliLayouting_BinLayout01(void) +{ + const auto NUMBER_OF_ITEMS = 4; + + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_BinLayout01 BinLayout WRAP_CONTENT"); + + Stage stage = Stage::GetCurrent(); + + auto rootControl = Control::New(); + auto absoluteLayout = AbsoluteLayout::New(); + DevelControl::SetLayout( rootControl, absoluteLayout ); + rootControl.SetName( "AbsoluteLayout" ); + stage.Add( rootControl ); + + auto binContainer = Control::New(); + auto binLayout = BinLayout::New(); + binContainer.SetName( "BinLayout"); + DevelControl::SetLayout( binContainer, binLayout ); + binContainer.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + binContainer.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + + std::vector< Control > controls; + for( auto i=0; i < NUMBER_OF_ITEMS; i++ ) + { + controls.push_back( CreateLeafControl( 100, 100 ) ); + } + + for( auto&& iter : controls ) + { + binContainer.Add( iter ); + } + + rootControl.Add( binContainer ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + // Items will be laid out at the same position + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + // Item sizes will not be changed + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + // BinLayout size to be that of greatest child dimensions + DALI_TEST_EQUALS( binContainer.GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLayouting_BinLayout02(void) +{ + const auto NUMBER_OF_ITEMS = 4; + + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_BinLayout02 BinLayout MATCH_PARENT"); + + Stage stage = Stage::GetCurrent(); + + auto rootControl = Control::New(); + auto absoluteLayout = AbsoluteLayout::New(); + DevelControl::SetLayout( rootControl, absoluteLayout ); + rootControl.SetName( "AbsoluteLayout" ); + stage.Add( rootControl ); + + auto binContainer = Control::New(); + auto binLayout = BinLayout::New(); + binContainer.SetName( "BinLayout"); + DevelControl::SetLayout( binContainer, binLayout ); + binContainer.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + binContainer.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + + std::vector< Control > controls; + for( auto i=0; i < NUMBER_OF_ITEMS; i++ ) + { + controls.push_back( CreateLeafControl( 100, 100 ) ); + } + + for( auto&& iter : controls ) + { + binContainer.Add( iter ); + } + + rootControl.Add( binContainer ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + // Items will be laid out at the same position + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + // Item sizes will not be changed + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + // BinLayout size to be that of greatest child dimensions + DALI_TEST_EQUALS( binContainer.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLayouting_BinLayout03(void) +{ + const auto NUMBER_OF_ITEMS = 4; + + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_BinLayout03 Explicit child Positioning when Bin layout MATCH_PARENT"); + + Stage stage = Stage::GetCurrent(); + + auto rootControl = Control::New(); + auto absoluteLayout = AbsoluteLayout::New(); + DevelControl::SetLayout( rootControl, absoluteLayout ); + rootControl.SetName( "AbsoluteLayout" ); + stage.Add( rootControl ); + + auto binContainer = Control::New(); + auto binLayout = BinLayout::New(); + binContainer.SetName( "BinLayout"); + DevelControl::SetLayout( binContainer, binLayout ); + binContainer.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + binContainer.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + + std::vector< Control > controls; + for( auto i=0; i < NUMBER_OF_ITEMS; i++ ) + { + controls.push_back( CreateLeafControl( 100, 100 ) ); + } + + for( auto&& iter : controls ) + { + binContainer.Add( iter ); + } + + tet_infoline("Position child explicitly from top left"); + controls[0].SetProperty(Actor::Property::POSITION_X, 50.0f ); + + tet_infoline("Position child explicitly from top left"); + controls[2].SetProperty(Actor::Property::POSITION_Y, 50.0f ); + + rootControl.Add( binContainer ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + // Items will be laid out at the same position + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 50.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 50.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + // Item sizes will not be changed + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + // BinLayout size to be that of parent + DALI_TEST_EQUALS( binContainer.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLayoutingBinLayoutResizePolicy_01(void) +{ + /* + Root + | + Control (LinearLayout Horizontal) + | + Control (BinLayout) + | + Control (ResizePolicy::FILL_TO_PARENT) + | + LeafControl + */ + + ToolkitTestApplication application; + tet_infoline("UtcDaliLayoutingBinLayoutResizePolicy_01 - Test ResizePolicy mapping with FILL_TO_PARENT on BinLayout child"); + + Stage stage = Stage::GetCurrent(); + + auto rootControl = Control::New(); + SetupRootLayoutControl( rootControl ); + + auto hbox = Control::New(); + auto hboxLayout = LinearLayout::New(); + hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); + DevelControl::SetLayout( hbox, hboxLayout ); + hbox.SetName( "hBox" ); + hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + + auto binContainer = Control::New(); + CreateDefaultBinContainer( binContainer ); + hbox.Add( binContainer ); + + auto control = Control::New(); + control.SetName( "fillToParentControl" ); + DevelControl::SetLayoutingRequired( control, true ); + control.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); + binContainer.Add( control ); + + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 40, 40 ) ); + + for( auto&& iter : controls ) + { + control.Add( iter ); + } + + rootControl.Add( hbox ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + tet_infoline("Testing child of BinLayout is size of parent"); + DALI_TEST_EQUALS( control.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + tet_infoline("Testing BinLayout's child control has not altered it's children's sizes "); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + tet_infoline("Testing BinLayout is size of parent"); + DALI_TEST_EQUALS( binContainer.GetProperty( Actor::Property::SIZE ), hbox.GetProperty( Actor::Property::SIZE ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLayoutingBinLayoutResizePolicy_02(void) +{ + /* + Root + | + Control (LinearLayout Horizontal) + | + Control (BinLayout) + | + Control (ResizePolicy::SIZE_RELATIVE_TO_PARENT) + | + LeafControl + */ + + ToolkitTestApplication application; + tet_infoline("UtcDaliLayoutingBinLayoutResizePolicy_02 - Set ResizePolicy SIZE_RELATIVE_TO_PARENT on BinLayout child"); + + const auto NUMBER_OF_ITEMS = 4; + + Stage stage = Stage::GetCurrent(); + + auto rootControl = Control::New(); + SetupRootLayoutControl( rootControl ); + + auto hbox = Control::New(); + auto hboxLayout = LinearLayout::New(); + hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); + DevelControl::SetLayout( hbox, hboxLayout ); + hbox.SetName( "hBox" ); + hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + + auto binContainer = Control::New(); + CreateDefaultBinContainer( binContainer ); + hbox.Add( binContainer ); + + auto control = Control::New(); + control.SetName( "fitToChildrenControl" ); + DevelControl::SetLayoutingRequired( control, true ); + control.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS ); + control.SetSizeModeFactor( Vector3( 0.50f, 1.0f, 1.0f ) ); + binContainer.Add( control ); + + std::vector< Control > controls; + for( auto i=0; i < NUMBER_OF_ITEMS; i++ ) + { + controls.push_back( CreateLeafControl( 40, 40 ) ); + } + + for( auto&& iter : controls ) + { + control.Add( iter ); + } + + rootControl.Add( hbox ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + tet_infoline("Testing child of BinLayout is the defined relative size of parent"); + DALI_TEST_EQUALS( control.GetProperty( Actor::Property::SIZE ), Vector3( 240.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + tet_infoline("Testing BinLayout's child control has not altered it's children's sizes "); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + tet_infoline("Testing BinLayout is size of parent"); + DALI_TEST_EQUALS( binContainer.GetProperty( Actor::Property::SIZE ), hbox.GetProperty( Actor::Property::SIZE ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliBinLayoutResizePolicy_03(void) +{ + /* + Root + | + Control (LinearLayout Horizontal) + | + Control (LayoutingRequired) + | + Control (ResizePolicy::SIZE_RELATIVE_TO_PARENT) + | + LeafControl + */ + + ToolkitTestApplication application; + tet_infoline("UtcDaliBinLayoutResizePolicy_03 - Set ResizePolicy SIZE_FIXED_OFFSET_FROM_PARENT on BinLayout child"); + + Stage stage = Stage::GetCurrent(); + + auto rootControl = Control::New(); + SetupRootLayoutControl( rootControl ); + + auto hbox = Control::New(); + auto hboxLayout = LinearLayout::New(); + hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); + DevelControl::SetLayout( hbox, hboxLayout ); + hbox.SetName( "hBox" ); + hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + + auto binContainer = Control::New(); + CreateDefaultBinContainer( binContainer ); + hbox.Add( binContainer ); + + hbox.Add( binContainer ); + + auto control = Control::New(); + control.SetName( "fitToChildrenControl" ); + DevelControl::SetLayoutingRequired( control, true ); + control.SetResizePolicy( ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS ); + control.SetSizeModeFactor( Vector3( -100.0f, 10.0f, 0.0f ) ); + binContainer.Add( control ); + + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 40, 40 ) ); + + for( auto&& iter : controls ) + { + control.Add( iter ); + } + + rootControl.Add( hbox ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( DevelControl::IsLayoutingRequired( control ), true , 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( control.GetProperty( Actor::Property::SIZE ), Vector3( 380.0f, 810.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} \ No newline at end of file diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp index 49da596..23cc93a 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp @@ -2692,60 +2692,6 @@ int UtcDaliLayouting_HboxLayout_TargetSize(void) END_TEST; } -int UtcDaliLayouting_RemoveLayout01(void) -{ - ToolkitTestApplication application; - tet_infoline(" UtcDaliLayouting_RemoveLayout"); - - Stage stage = Stage::GetCurrent(); - - auto rootControl = Control::New(); - auto absoluteLayout = AbsoluteLayout::New(); - DevelControl::SetLayout( rootControl, absoluteLayout ); - rootControl.SetName( "AbsoluteLayout" ); - stage.Add( rootControl ); - - auto hbox = Control::New(); - auto hboxLayout = LinearLayout::New(); - hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); - DevelControl::SetLayout( hbox, hboxLayout ); - hbox.SetName( "HBox" ); - - std::vector< Control > controls; - controls.push_back( CreateLeafControl( 40, 40 ) ); - controls.push_back( CreateLeafControl( 60, 40 ) ); - - for( auto&& iter : controls ) - { - hbox.Add( iter ); - } - hbox.SetParentOrigin( ParentOrigin::CENTER ); - hbox.SetAnchorPoint( AnchorPoint::CENTER ); - rootControl.Add( hbox ); - - tet_infoline("Layout as normal"); - application.SendNotification(); - application.Render(); - - tet_infoline("Set an empty layout on hbox container"); - LinearLayout emptyLayout; - DevelControl::SetLayout( hbox, emptyLayout ); - - tet_infoline("Run another layout"); - application.SendNotification(); - application.Render(); - - tet_infoline("Check leaf controls haven't moved"); - - DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); - DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 40.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); - - DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION ); - DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 60.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION ); - - END_TEST; -} - int UtcDaliLayouting_LayoutChildren01(void) { ToolkitTestApplication application; @@ -2765,41 +2711,6 @@ int UtcDaliLayouting_LayoutChildren01(void) DALI_TEST_EQUALS( absoluteLayout.GetChildCount(), 1, TEST_LOCATION ); - tet_infoline("Test removal by setting empty layout to child container" ); - DevelControl::SetLayout( hbox, LayoutItem{} ); - - DALI_TEST_EQUALS( absoluteLayout.GetChildCount(), 0, TEST_LOCATION ); - - auto& hboxImpl = GetImplementation( hboxLayout ); - Handle empty; - DALI_TEST_EQUALS( hboxLayout.GetOwner(), empty, TEST_LOCATION ); - DALI_TEST_EQUALS( (void*)hboxImpl.GetParent(), (void*)nullptr, TEST_LOCATION ); - - // For coverage - hboxImpl.SetLayoutRequested(); - - END_TEST; -} - -int UtcDaliLayouting_LayoutChildren02(void) -{ - ToolkitTestApplication application; - tet_infoline(" UtcDaliLayouting_LayoutChildren02"); - - Stage stage = Stage::GetCurrent(); - - auto rootControl = Control::New(); - auto absoluteLayout = AbsoluteLayout::New(); - DevelControl::SetLayout( rootControl, absoluteLayout ); - stage.Add( rootControl ); - - auto hbox = Control::New(); - auto hboxLayout = LinearLayout::New(); - DevelControl::SetLayout( hbox, hboxLayout ); - rootControl.Add( hbox ); - - DALI_TEST_EQUALS( absoluteLayout.GetChildCount(), 1, TEST_LOCATION ); - tet_infoline("Test removal by removing child actor from parent container" ); hbox.Unparent(); @@ -2815,7 +2726,7 @@ int UtcDaliLayouting_LayoutChildren02(void) END_TEST; } -int UtcDaliLayouting_LayoutChildren03(void) +int UtcDaliLayouting_LayoutChildren02(void) { ToolkitTestApplication application; tet_infoline(" UtcDaliLayouting_LayoutChildren02"); @@ -2852,7 +2763,7 @@ int UtcDaliLayouting_LayoutChildren03(void) } -int UtcDaliLayouting_LayoutChildren04(void) +int UtcDaliLayouting_LayoutChildren03(void) { ToolkitTestApplication application; tet_infoline(" UtcDaliLayouting_LayoutChildren03"); @@ -2985,34 +2896,51 @@ int UtcDaliLayouting_SetLayoutOrder02(void) tet_infoline("SetLayout"); auto vboxLayout = LinearLayout::New(); - DevelControl::SetLayout( controls[0], vboxLayout ); + DevelControl::SetLayout( controls[0], vboxLayout ); // 1 2 0(vbox) TestLayoutItemOrder( controls, hboxLayout ); tet_infoline("Raise"); - controls[0].Raise(); // 1 2 0 + controls[0].Raise(); // 1 2 0(vbox) TestLayoutItemOrder( controls, hboxLayout ); tet_infoline("Lower"); - controls[2].Lower(); // 2 1 0 + controls[2].Lower(); // 2 1 0(vbox) TestLayoutItemOrder( controls, hboxLayout ); tet_infoline("SetLayout again"); auto vboxLayout1 = LinearLayout::New(); - DevelControl::SetLayout( controls[2], vboxLayout1 ); + DevelControl::SetLayout( controls[2], vboxLayout1 ); // 2 1(vbox1) 0(vbox) + + TestLayoutItemOrder( controls, hboxLayout ); + + tet_infoline("SetLayout with empty handle"); + + DevelControl::SetLayout( controls[0], LayoutItem{} ); // 2 1(vbox1) 0 TestLayoutItemOrder( controls, hboxLayout ); - DevelControl::SetLayout( controls[2], vboxLayout ); + tet_infoline("SetLayout to another control"); + + DevelControl::SetLayout( controls[2], vboxLayout1 ); // 2(vbox1) 1 0 + + TestLayoutItemOrder( controls, hboxLayout ); + + tet_infoline("SetLayout to change layout"); + + DevelControl::SetLayout( controls[2], vboxLayout1 ); // 2(vbox) 1 0 + + TestLayoutItemOrder( controls, hboxLayout ); END_TEST; } + int UtcDaliLayouting_LayoutGroup01(void) { ToolkitTestApplication application; @@ -3412,3 +3340,53 @@ int UtcDaliLayouting_SetLayout(void) END_TEST; } + +int UtcDaliLayouting_StageAdd(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_StageAdd"); + + Stage stage = Stage::GetCurrent(); + + AbsoluteLayout absoluteLayout = AbsoluteLayout::New(); + Control container = Control::New(); + container.SetName( "Container" ); + DevelControl::SetLayout( container, absoluteLayout ); + container.SetAnchorPoint( Dali::AnchorPoint::CENTER ); + container.SetParentOrigin( Dali::ParentOrigin::CENTER ); + + Control child = Control::New(); + child.SetAnchorPoint( Dali::AnchorPoint::TOP_LEFT ); + child.SetPosition( 0.0f, 0.0f ); + child.SetSize( 480.0f, 180.0f ); + child.SetName( "Child Control" ); + container.Add( child ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( child.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::SIZE ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); // Not re-laid out + DALI_TEST_EQUALS( child.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 180.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render(); + + // Add container to stage here + // Should call RequestLayout() to measure and layout + stage.Add( container ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( child.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); // Stage Size + DALI_TEST_EQUALS( child.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 180.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-LayoutingAnimation.cpp b/automated-tests/src/dali-toolkit/utc-Dali-LayoutingAnimation.cpp new file mode 100644 index 0000000..ead839d --- /dev/null +++ b/automated-tests/src/dali-toolkit/utc-Dali-LayoutingAnimation.cpp @@ -0,0 +1,1211 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include <../custom-layout.h> + +#include + +using namespace Dali; +using namespace Toolkit; + +void utc_dali_toolkit_layouting_animation_startup(void) +{ + test_return_value = TET_UNDEF; +} + +void utc_dali_toolkit_layouting_animation_cleanup(void) +{ + test_return_value = TET_PASS; +} + +namespace +{ + +// Functor to test whether a Finish signal is emitted +struct LayoutTransitionFinishCheck +{ + LayoutTransitionFinishCheck( bool& signalReceived ) + : mSignalReceived( signalReceived ) + { + } + + void operator()( LayoutTransitionData::LayoutTransitionType type, LayoutTransitionData& layoutTransitionData ) + { + mSignalReceived = true; + } + + void Reset() + { + mSignalReceived = false; + } + + void CheckSignalReceived() + { + if (!mSignalReceived) + { + tet_printf("Expected Finish signal was not received\n"); + tet_result(TET_FAIL); + } + else + { + tet_result(TET_PASS); + } + } + + void CheckSignalNotReceived() + { + if (mSignalReceived) + { + tet_printf("Unexpected Finish signal was received\n"); + tet_result(TET_FAIL); + } + else + { + tet_result(TET_PASS); + } + } + + bool& mSignalReceived; // owned by individual tests +}; + +} // anon namespace + +int UtcDaliLayouting_LayoutTransitionDataConstructorP(void) +{ + TestApplication application; + + LayoutTransitionData layoutTransitionData; + + DALI_TEST_CHECK( !layoutTransitionData ); + END_TEST; +} + +int UtcDaliLayouting_LayoutTransitionDataNewP(void) +{ + TestApplication application; + + LayoutTransitionData layoutTransitionData = LayoutTransitionData::New(); + + DALI_TEST_CHECK(layoutTransitionData); + END_TEST; +} + +int UtcDaliLayouting_LayoutTransitionDataDownCastP(void) +{ + TestApplication application; + + LayoutTransitionData layoutTransitionData = LayoutTransitionData::New(); + BaseHandle object(layoutTransitionData); + + LayoutTransitionData layoutTransitionData2 = LayoutTransitionData::DownCast(object); + DALI_TEST_CHECK(layoutTransitionData2); + + LayoutTransitionData layoutTransitionData3 = DownCast< LayoutTransitionData >(object); + DALI_TEST_CHECK(layoutTransitionData2); + END_TEST; +} + +int UtcDaliLayouting_LayoutTransitionDataDownCastN(void) +{ + TestApplication application; + + BaseHandle unInitializedObject; + + LayoutTransitionData layoutTransitionData1 = LayoutTransitionData::DownCast( unInitializedObject ); + DALI_TEST_CHECK( !layoutTransitionData1 ); + + LayoutTransitionData layoutTransitionData2 = DownCast< LayoutTransitionData >( unInitializedObject ); + DALI_TEST_CHECK( !layoutTransitionData2 ); + END_TEST; +} + +int UtcDaliLayouting_LayoutTransitionDataSetGetTransition(void) +{ + TestApplication application; + + auto layout = LinearLayout::New(); + auto layoutTransitionData = LayoutTransitionData::New(); + + layout.SetTransitionData( LayoutTransitionData::ON_OWNER_SET, layoutTransitionData ); + DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_OWNER_SET ) == layoutTransitionData ); + DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_ADD ) == LayoutTransitionData() ); + DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE ) == LayoutTransitionData() ); + + layout.SetTransitionData( LayoutTransitionData::ON_OWNER_SET, LayoutTransitionData() ); + layout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, layoutTransitionData ); + DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_OWNER_SET ) == LayoutTransitionData() ); + DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_ADD ) == layoutTransitionData ); + DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE ) == LayoutTransitionData() ); + + layout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, LayoutTransitionData() ); + layout.SetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE, layoutTransitionData ); + DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_OWNER_SET ) == LayoutTransitionData() ); + DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_ADD ) == LayoutTransitionData() ); + DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE ) == layoutTransitionData ); + + END_TEST; +} + +int UtcDaliLayouting_SetLayoutTransition01(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_SetLayoutTransition01"); + + Stage stage = Stage::GetCurrent(); + auto container = Control::New(); + auto horizontalLayout = LinearLayout::New(); + horizontalLayout.SetAnimateLayout( true ); + horizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); + + auto verticalLayout = LinearLayout::New(); + verticalLayout.SetAnimateLayout( true ); + verticalLayout.SetOrientation( LinearLayout::Orientation::VERTICAL ); + + DevelControl::SetLayout( container, horizontalLayout ); + container.SetName( "Container"); + + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 100, 100 ) ); + controls.push_back( CreateLeafControl( 100, 100 ) ); + for( auto&& iter : controls ) + { + container.Add( iter ); + } + + container.SetParentOrigin( ParentOrigin::CENTER ); + container.SetAnchorPoint( AnchorPoint::CENTER ); + stage.Add( container ); + + auto layoutTransitionData = LayoutTransitionData::New(); + { + // Instant resize for parent + Property::Map map; + map["property"] = "size"; + map["targetValue"] = Property::Value(); // capture from layout update + map["animator"] = Property::Map() + .Add("alphaFunction", "LINEAR") + .Add("timePeriod", Property::Map() + .Add("delay", 0.0f) + .Add("duration", 0.0f)); + layoutTransitionData.AddPropertyAnimator( container, map ); + } + { + Property::Map map; + map["property"] = "opacity"; + map["initialValue"] = 0.0f; + map["targetValue"] = 1.0f; + map["animator"] = Property::Map() + .Add("alphaFunction", "LINEAR") + .Add("timePeriod", Property::Map() + .Add("delay", 0.0f) + .Add("duration", 0.5f)); + layoutTransitionData.AddPropertyAnimator( container, map ); + } + { + // Instant position for children + Property::Map map; + map["property"] = "position"; + map["animator"] = Property::Map() + .Add("alphaFunction", "LINEAR") + .Add("timePeriod", Property::Map() + .Add("delay", 0.0f) + .Add("duration", 0.0f)); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { + // Grow children from (0,0) size to full size (captured) + Property::Map map; + map["property"] = "size"; + map["initialValue"] = Vector3( 0.0f, 0.0f, 0 ); + map["animator"] = Property::Map() + .Add("alphaFunction", "LINEAR") + .Add("timePeriod", Property::Map() + .Add("delay", 0.0f) + .Add("duration", 0.5f)); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); + } + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + // First round, no animation + // TODO: container size (0, 0) after it is added to the stage should be fixed with HQ patch soon + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::SIZE ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + bool signalReceived(false); + LayoutTransitionFinishCheck finishCheck(signalReceived); + layoutTransitionData.FinishedSignal().Connect(&application, finishCheck); + + // Change a layout, start transition + verticalLayout.SetTransitionData( LayoutTransitionData::ON_OWNER_SET, layoutTransitionData ); + DevelControl::SetLayout( container, verticalLayout ); + + application.SendNotification(); + application.Render( 1u /*just very beginning of the animation*/ ); + + finishCheck.CheckSignalNotReceived(); + // Second round, animation just started + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( container.GetCurrentOpacity(), 0.0f, 0.1f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 300.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetCurrentPosition(), Vector3( 0.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 0.0f, 0.0f, 0.0f ), 1.0f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetCurrentSize(), Vector3( 0.0f, 0.0f, 0.0f ), 1.0f, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast( 0.5f * 1000.0f ) + 1u /*just after the end of the animation*/ ); + + // Third round, animation just finished + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( container.GetCurrentOpacity(), 1.0f, 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 300.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetCurrentPosition(), Vector3( 0.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render( 10u /* wait a bit more for a signal */ ); + + finishCheck.CheckSignalReceived(); + + // Now sizes and positions are finally set + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 300.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + // Transition back now with default transition + DevelControl::SetLayout( container, horizontalLayout ); + + application.SendNotification(); + application.Render( 1u /*just very beginning of the animation*/ ); + + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( container.GetCurrentOpacity(), 1.0f, 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 300.0f, 0.0f ), 1.0f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetCurrentPosition(), Vector3( 0.0f, 400.0f, 0.0f ), 1.0f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast( 0.5f * 1000.0f ) + 1u /*just after the end of the animation*/ ); + + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( container.GetCurrentOpacity(), 1.0f, 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetCurrentPosition(), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render( 10u /* wait a bit more for complete default animation */ ); + + // Now sizes and positions are finally set + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLayouting_AddChildLayoutTransition01(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_AddChildLayoutTransition01"); + + Stage stage = Stage::GetCurrent(); + auto container = Control::New(); + auto horizontalLayout = LinearLayout::New(); + horizontalLayout.SetAnimateLayout( true ); + horizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); + + DevelControl::SetLayout( container, horizontalLayout ); + container.SetName( "Container"); + + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 100, 100 ) ); + container.SetParentOrigin( ParentOrigin::CENTER ); + container.SetAnchorPoint( AnchorPoint::CENTER ); + stage.Add( container ); + + auto layoutTransitionData = LayoutTransitionData::New(); + { + // Instant resize for parent + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = "size"; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR" ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( container, map ); + } + { + // Instant position for a child + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = "position"; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { + // Grow a child from (0,0) size to full size (captured) + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = "size"; + map[ LayoutTransitionData::AnimatorKey::INITIAL_VALUE ] = Vector3( 0.0f, 0.0f, 0 ); + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f)); + layoutTransitionData.AddPropertyAnimator( controls[0], map ); + } + + horizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, layoutTransitionData ); + container.Add( controls[0] ); + + bool signalReceived(false); + LayoutTransitionFinishCheck finishCheck(signalReceived); + layoutTransitionData.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render( 1u /*just very beginning of the animation*/ ); + + finishCheck.CheckSignalNotReceived(); + // The animation just started + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast( 0.5f * 1000.0f ) + 1u /*just after the end of the animation*/ ); + + // The animation just finished + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render( 10u /* wait a bit more for a signal */ ); + + // Now sizes and positions are finally set + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + finishCheck.CheckSignalReceived(); + + END_TEST; +} + +int UtcDaliLayouting_RemoveChildLayoutTransition01(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_RemoveChildLayoutTransition01"); + + Stage stage = Stage::GetCurrent(); + auto container = Control::New(); + auto horizontalLayout = LinearLayout::New(); + horizontalLayout.SetAnimateLayout( true ); + horizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); + + DevelControl::SetLayout( container, horizontalLayout ); + container.SetName( "Container"); + + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 100, 100 ) ); + controls.push_back( CreateLeafControl( 100, 100 ) ); + container.SetParentOrigin( ParentOrigin::CENTER ); + container.SetAnchorPoint( AnchorPoint::CENTER ); + stage.Add( container ); + container.Add( controls[0] ); + container.Add( controls[1] ); + + // Initial rendering done + application.SendNotification(); + application.Render(); + + auto layoutTransitionData = LayoutTransitionData::New(); + { + // Instant resize for parent width + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE_WIDTH; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TYPE, "ANIMATE_TO" ) + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR" ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( container, map ); + } + { + // Instant resize for parent height + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE_HEIGHT; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TYPE, "ANIMATE_TO" ) + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR" ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( container, map ); + } + { + // Instant position for parent X position + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION_X; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TYPE, "ANIMATE_TO" ) + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR" ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( container, map ); + } + { + // Instant position for parent Y position + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION_Y; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TYPE, "ANIMATE_TO" ) + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR" ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( container, map ); + } + { + // Shrink the children + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE_WIDTH; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = 0.0f; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TYPE, "ANIMATE_TO" ) + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f)); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); + } + { + // Shrink the children + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE_HEIGHT; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = 0.0f; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TYPE, "ANIMATE_TO" ) + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f)); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); + } + { + // Instant position for a child + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION_X; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TYPE, "ANIMATE_TO" ) + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { + // Instant position for a child + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION_Y; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TYPE, "ANIMATE_TO" ) + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + + horizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE, layoutTransitionData ); + container.Remove( controls[1] ); + + bool signalReceived(false); + LayoutTransitionFinishCheck finishCheck(signalReceived); + layoutTransitionData.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render( 1u /*just very beginning of the animation*/ ); + + finishCheck.CheckSignalNotReceived(); + // Animation just started + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetCurrentPosition(), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 0.0f, 0.0f, 0.0f ), 1.0f, TEST_LOCATION ); + // this control is already removed from the tree. + DALI_TEST_EQUALS( controls[1].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast( 0.5f * 1000.0f ) + 1u /*just after the end of the animation*/ ); + + // Animation just finished + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + // this control is already removed from the tree. + DALI_TEST_EQUALS( controls[1].GetCurrentPosition(), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 0.0f, 0.0f, 0.0f ), 1.0f, TEST_LOCATION ); + // this control is already removed from the tree. + DALI_TEST_EQUALS( controls[1].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render( 10u /* wait a bit more for a signal */ ); + + // Now sizes and positions are finally set + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + // this control is already removed from the tree. + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + // this control is already removed from the tree. + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + finishCheck.CheckSignalReceived(); + + END_TEST; +} + +int UtcDaliLayouting_AddChildLayoutTransition02_KeyFrames(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_AddChildLayoutTransition02_KeyFrames"); + + Stage stage = Stage::GetCurrent(); + auto container = Control::New(); + auto horizontalLayout = LinearLayout::New(); + horizontalLayout.SetAnimateLayout( true ); + horizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); + + DevelControl::SetLayout( container, horizontalLayout ); + container.SetName( "Container"); + + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 100, 100 ) ); + container.SetParentOrigin( ParentOrigin::CENTER ); + container.SetAnchorPoint( AnchorPoint::CENTER ); + stage.Add( container ); + + auto layoutTransitionData = LayoutTransitionData::New(); + { + // Instant resize for parent + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR" ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( container, map ); + } + { + // Instant position for a child + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { + // Grow a child from (0,0) size to full size with key frames + KeyFrames keyFrames = KeyFrames::New(); + keyFrames.Add( 0.0f, Vector3( 0.0f, 0.0f, 0 ) ); + keyFrames.Add( 0.5f, Vector3( 100.0f, 100.0f, 0 ) ); + + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TYPE, "ANIMATE_BETWEEN") + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f)); + layoutTransitionData.AddPropertyAnimator( controls[0], map, keyFrames, Animation::Interpolation::Linear ); + } + + horizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, layoutTransitionData ); + container.Add( controls[0] ); + + bool signalReceived(false); + LayoutTransitionFinishCheck finishCheck(signalReceived); + layoutTransitionData.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render( 1u /*just very beginning of the animation*/ ); + + finishCheck.CheckSignalNotReceived(); + // The animation just started + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast( 0.5f * 1000.0f ) + 1u /*just after the end of the animation*/ ); + + // The animation just finished + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render( 10u /* wait a bit more for a signal */ ); + + // Now sizes and positions are finally set + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + finishCheck.CheckSignalReceived(); + + END_TEST; +} + +int UtcDaliLayouting_AddChildLayoutTransition03_Path(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_AddChildLayoutTransition03_Path"); + + Stage stage = Stage::GetCurrent(); + auto container = Control::New(); + auto horizontalLayout = LinearLayout::New(); + horizontalLayout.SetAnimateLayout( true ); + horizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); + + DevelControl::SetLayout( container, horizontalLayout ); + container.SetName( "Container"); + + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 100, 100 ) ); + container.SetParentOrigin( ParentOrigin::CENTER ); + container.SetAnchorPoint( AnchorPoint::CENTER ); + stage.Add( container ); + + auto layoutTransitionData = LayoutTransitionData::New(); + { + // Instant resize for parent + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR" ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( container, map ); + } + + Dali::Path path = Dali::Path::New(); + { + // Curve position for a child + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TYPE, "ANIMATE_PATH") + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) ); + + // Build the path + Vector3 position0( 30.0, 80.0, 0.0 ); + Vector3 position1( 70.0, 120.0, 0.0 ); + Vector3 position2( 0.0, 350.0, 0.0 ); + + //Dali::Path path = Dali::Path::New(); + path.AddPoint( position0 ); + path.AddPoint( position1 ); + path.AddPoint( position2 ); + + // Control points for first segment + path.AddControlPoint( Vector3( 39.0, 90.0, 0.0 ) ); + path.AddControlPoint( Vector3( 56.0, 119.0, 0.0 ) ); + + // Control points for second segment + path.AddControlPoint( Vector3( 78.0, 120.0, 0.0 ) ); + path.AddControlPoint( Vector3( 93.0, 104.0, 0.0 ) ); + + layoutTransitionData.AddPropertyAnimator( controls[0], map, path, Vector3::XAXIS ); + } + { + // Grow a child from (0,0) size to full size (captured) + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = "size"; + map[ LayoutTransitionData::AnimatorKey::INITIAL_VALUE ] = Vector3( 0.0f, 0.0f, 0 ); + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f)); + layoutTransitionData.AddPropertyAnimator( controls[0], map ); + } + + horizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, layoutTransitionData ); + container.Add( controls[0] ); + + bool signalReceived(false); + LayoutTransitionFinishCheck finishCheck(signalReceived); + layoutTransitionData.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render( 0 ); + + finishCheck.CheckSignalNotReceived(); + // The animation just started + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + Vector3 position, tangent; + Quaternion rotation; + path.Sample( 0.0f, position, tangent ); + rotation = Quaternion( Vector3::XAXIS, tangent ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), position, 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentOrientation(), rotation, 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast( 0.5f * 1000.0f ) + 1u /*just after the end of the animation*/ ); + + path.Sample( 1.0f, position, tangent ); + rotation = Quaternion( Vector3::XAXIS, tangent ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), position, 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentOrientation(), rotation, 0.0001f, TEST_LOCATION ); + + // The animation just finished + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render( 10u /* wait a bit more for a signal */ ); + + // Now sizes and positions are finally set + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + finishCheck.CheckSignalReceived(); + + END_TEST; +} + +int UtcDaliLayouting_AddChildLayoutTransition04_AnimateBy(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_AddChildLayoutTransition04_AnimateBy"); + + Stage stage = Stage::GetCurrent(); + auto container = Control::New(); + auto horizontalLayout = LinearLayout::New(); + horizontalLayout.SetAnimateLayout( true ); + horizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); + + DevelControl::SetLayout( container, horizontalLayout ); + container.SetName( "Container"); + + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 100, 100 ) ); + container.SetParentOrigin( ParentOrigin::CENTER ); + container.SetAnchorPoint( AnchorPoint::CENTER ); + stage.Add( container ); + + auto layoutTransitionData = LayoutTransitionData::New(); + { + // Instant resize for parent + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR" ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( container, map ); + } + { + // Instant position for a child + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 0.0f, 350.0f, 0 ); + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TYPE, "ANIMATE_BY") + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f)); + layoutTransitionData.AddPropertyAnimator( controls[0], map ); + } + + horizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, layoutTransitionData ); + container.Add( controls[0] ); + + bool signalReceived(false); + LayoutTransitionFinishCheck finishCheck(signalReceived); + layoutTransitionData.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render( 1u /*just very beginning of the animation*/ ); + + finishCheck.CheckSignalNotReceived(); + // The animation just started + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render( static_cast( 0.5f * 1000.0f ) + 1u /*just after the end of the animation*/ ); + + // The animation just finished + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render( 10u /* wait a bit more for a signal */ ); + + // Now sizes and positions are finally set + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + finishCheck.CheckSignalReceived(); + + END_TEST; +} + +int UtcDaliLayouting_AddChildLayoutTransition05(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_AddChildLayoutTransition05"); + + Stage stage = Stage::GetCurrent(); + auto container = Control::New(); + auto horizontalLayout = LinearLayout::New(); + horizontalLayout.SetAnimateLayout( true ); + horizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); + + DevelControl::SetLayout( container, horizontalLayout ); + container.SetName( "Container"); + + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 100, 100 ) ); + container.SetParentOrigin( ParentOrigin::CENTER ); + container.SetAnchorPoint( AnchorPoint::CENTER ); + stage.Add( container ); + + auto layoutTransitionData = LayoutTransitionData::New(); + { + // Instant resize for parent + Property::Map map; + map[ "property" ] = Actor::Property::SIZE; + map[ "targetValue" ] = Property::Value(); // capture from layout update + map[ "animator" ] = Property::Map() + .Add( "name", "InstantAnimator" ) + .Add( "type", "ANIMATE_TO") + .Add( "alphaFunction", "LINEAR" ) + .Add( "timePeriod", Property::Map() + .Add( "delay", 0.0f ) + .Add( "duration", 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( container, map ); + } + { + // Instant position for a child + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::COLOR_ALPHA; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = "InstantAnimator"; + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { + // Grow a child from (0,0) size to full size (captured) + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; + map[ LayoutTransitionData::AnimatorKey::INITIAL_VALUE ] = Vector3( 0.0f, 0.0f, 0 ); + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = std::string(); + layoutTransitionData.AddPropertyAnimator( controls[0], map ); + } + { + // Instant opacity for a child, for testing + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = "InstantAnimator"; + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + + // Just throw all other alpha functions in + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "WRONG" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "REVERSE" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "EASE_IN_SQUARE" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "EASE_OUT_SQUARE" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "EASE_IN" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "EASE_IN" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "EASE_OUT" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "EASE_IN_OUT" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "EASE_IN_OUT_SINE" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "EASE_IN_SINE" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "EASE_OUT_SINE" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "BOUNCE" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "SIN" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "EASE_OUT_BACK" ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, Vector4( 0.0f, 1.0f, 2.0f, 3.0f ) ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + // valid + Property::Array array; + array.Reserve( 4 ); + array.PushBack( 0.0f ); + array.PushBack( 1.0f ); + array.PushBack( 2.0f ); + array.PushBack( 3.0f ); + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, array ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + // invalid + Property::Array array; + array.Reserve( 3 ); + array.PushBack( 0.0f ); + array.PushBack( 1.0f ); + array.PushBack( 2.0f ); + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, array ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + // invalid + Property::Array array; + array.Reserve( 4 ); + array.PushBack( 0.0f ); + array.PushBack( 10 ); + array.PushBack( 2.0f ); + array.PushBack( 3.0f ); + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, array ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + { // no property, not going to be used, but going to be parsed + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = 0; // invalid + layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent + } + + horizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, layoutTransitionData ); + container.Add( controls[0] ); + + bool signalReceived(false); + LayoutTransitionFinishCheck finishCheck(signalReceived); + layoutTransitionData.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render( 1u /*just very beginning of the animation*/ ); + + finishCheck.CheckSignalNotReceived(); + // The animation just started + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 1.0f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 0.0f, 0.0f, 0.0f ), 1.0f, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast( 0.5f * 1000.0f ) + 1u /*just after the end of the animation*/ ); + + // The animation just finished + DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + application.SendNotification(); + application.Render( 10u /* wait a bit more for a signal */ ); + + // Now sizes and positions are finally set + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( container.GetProperty( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + finishCheck.CheckSignalReceived(); + + END_TEST; +} + diff --git a/automated-tests/src/dali-toolkit/utc-Dali-LayoutingSettingAndRemoval.cpp b/automated-tests/src/dali-toolkit/utc-Dali-LayoutingSettingAndRemoval.cpp new file mode 100644 index 0000000..b55afd6 --- /dev/null +++ b/automated-tests/src/dali-toolkit/utc-Dali-LayoutingSettingAndRemoval.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +#include + +using namespace Dali; +using namespace Toolkit; + +namespace +{ + +// Turns the given control into a Root layout control and adds it to the stage. +void SetupRootLayoutControl( Control& rootControl ) +{ + rootControl = Control::New(); + auto absoluteLayout = AbsoluteLayout::New(); + DevelControl::SetLayout( rootControl, absoluteLayout ); + rootControl.SetName( "RootAbsoluteLayout" ); + Stage stage = Stage::GetCurrent(); + stage.Add( rootControl ); +} + +} // unnamed namespace + +void utc_dali_toolkit_layouting_setting_and_removal_startup(void) +{ + test_return_value = TET_UNDEF; +} + +void utc_dali_toolkit_layouting_setting_and_removal_cleanup(void) +{ + test_return_value = TET_PASS; +} + +int UtcDaliLayoutingSettingAndRemoval_RemoveLayout(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliLayoutingSettingAndRemoval_RemoveLayout - Remove a layout from a control"); + + Stage stage = Stage::GetCurrent(); + + auto rootControl = Control::New(); + SetupRootLayoutControl( rootControl ); + + auto hbox = Control::New(); + auto hboxLayout = LinearLayout::New(); + DevelControl::SetLayout( hbox, hboxLayout ); + hbox.SetName( "HBox"); + rootControl.Add( hbox ); + + // Add child controls + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 100, 100 ) ); // 0 + controls.push_back( CreateLeafControl( 100, 100 ) ); // 1 + controls.push_back( CreateLeafControl( 100, 100 ) ); // 2 + + for( auto&& iter : controls ) + { + hbox.Add( iter ); + } + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + tet_infoline("Get number of child in the rootControl layout"); + DALI_TEST_EQUALS( ( LayoutGroup::DownCast( DevelControl::GetLayout( rootControl ) ) ).GetChildCount(), 1 , TEST_LOCATION ); + + tet_infoline("SetLayout with empty Layout handle"); + + DevelControl::SetLayout( hbox, LayoutItem{} ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + tet_infoline("Get number of children in the rootControl layout"); + DALI_TEST_EQUALS( ( LayoutGroup::DownCast( DevelControl::GetLayout( rootControl ) ) ).GetChildCount(), 1 , TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLayoutingSettingAndRemoval_RemoveLayoutFromChild(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliLayoutingSettingAndRemoval_RemoveLayoutFromChild - Remove a layout from a child of another layout"); + + /* + + Hbox + | | | + control0 control1 control2 + (vbox) (leaf) (leaf) + + Test removes layout from control0 but does not remove the control. + + */ + + Stage stage = Stage::GetCurrent(); + + auto rootControl = Control::New(); + SetupRootLayoutControl( rootControl ); + + auto hbox = Control::New(); + auto hboxLayout = LinearLayout::New(); + DevelControl::SetLayout( hbox, hboxLayout ); + hbox.SetName( "HBox"); + rootControl.Add( hbox ); + + // Add child controls + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 100, 100 ) ); // 0 + controls.push_back( CreateLeafControl( 100, 100 ) ); // 1 + controls.push_back( CreateLeafControl( 100, 100 ) ); // 2 + + for( auto&& iter : controls ) + { + hbox.Add( iter ); + } + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + tet_infoline("Set LinearLayout to child control 0"); + + auto vboxLayout = LinearLayout::New(); + DevelControl::SetLayout( controls[0], vboxLayout ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + tet_infoline("Get number of children in the hbox layout"); + DALI_TEST_EQUALS( ( LayoutGroup::DownCast( DevelControl::GetLayout( hbox ) ) ).GetChildCount(), 3 , TEST_LOCATION ); + + tet_infoline("SetLayout with empty Layout handle"); + + DevelControl::SetLayout( controls[0], LayoutItem{} ); + + // If vbox control has no children then should get a LayoutItem. + // but if still has children then should be a LayoutGroup/BinContainer. + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + tet_infoline("Get number of child in the hbox layout"); + DALI_TEST_EQUALS( ( LayoutGroup::DownCast( DevelControl::GetLayout( hbox ) ) ).GetChildCount(), 3 , TEST_LOCATION ); + // Test should fail as the setting of an empty layout reduces the child count by 1 + + END_TEST; +} + +int UtcDaliLayoutingSettingAndRemoval_RemoveLayoutFromHbox(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayoutingSettingAndRemoval_RemoveLayoutFromHbox"); + + Stage stage = Stage::GetCurrent(); + + auto rootControl = Control::New(); + auto absoluteLayout = AbsoluteLayout::New(); + DevelControl::SetLayout( rootControl, absoluteLayout ); + rootControl.SetName( "AbsoluteLayout" ); + stage.Add( rootControl ); + + auto hbox = Control::New(); + auto hboxLayout = LinearLayout::New(); + hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); + DevelControl::SetLayout( hbox, hboxLayout ); + hbox.SetName( "Container" ); + + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 40, 40 ) ); + controls.push_back( CreateLeafControl( 60, 40 ) ); + + for( auto&& iter : controls ) + { + hbox.Add( iter ); + } + hbox.SetParentOrigin( ParentOrigin::CENTER ); + hbox.SetAnchorPoint( AnchorPoint::CENTER ); + rootControl.Add( hbox ); + + tet_infoline("Layout as normal"); + application.SendNotification(); + application.Render(); + + tet_infoline("Set an empty layout on hbox container"); + LinearLayout emptyLayout; + DevelControl::SetLayout( hbox, emptyLayout ); + + tet_infoline("Run another layout"); + application.SendNotification(); + application.Render(); + + tet_infoline("Check leaf controls size and position"); + + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + tet_infoline("Child keeps position from last layout"); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 40.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 60.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} \ No newline at end of file diff --git a/dali-toolkit/devel-api/controls/control-devel.h b/dali-toolkit/devel-api/controls/control-devel.h index e2fcc86..52a0d4a 100755 --- a/dali-toolkit/devel-api/controls/control-devel.h +++ b/dali-toolkit/devel-api/controls/control-devel.h @@ -289,6 +289,8 @@ DALI_TOOLKIT_API Toolkit::LayoutItem GetLayout( Control control ); * * @param[in] control The internal Control to set the layout on * @param[in] layout Pointer to the layout + * @note Providing an empty layout will remove the current layout and + * replace it with a BinLayout. */ DALI_TOOLKIT_API void SetLayout( Internal::Control& control, Toolkit::LayoutItem layout ); @@ -297,6 +299,8 @@ DALI_TOOLKIT_API void SetLayout( Internal::Control& control, Toolkit::LayoutItem * * @param[in] control The Control to set the layout on * @param[in] layout Pointer to the layout + * @note Providing an empty layout will remove the current layout and + * replace it with a BinLayout. */ DALI_TOOLKIT_API void SetLayout( Control control, Toolkit::LayoutItem layout ); diff --git a/dali-toolkit/devel-api/file.list b/dali-toolkit/devel-api/file.list index 3627396..1cad2f5 100755 --- a/dali-toolkit/devel-api/file.list +++ b/dali-toolkit/devel-api/file.list @@ -34,15 +34,17 @@ devel_api_src_files = \ $(devel_api_src_dir)/image-loader/atlas-upload-observer.cpp \ $(devel_api_src_dir)/image-loader/image-atlas.cpp \ $(devel_api_src_dir)/image-loader/texture-manager.cpp \ - $(devel_api_src_dir)/layouting/flex-layout.cpp \ $(devel_api_src_dir)/layouting/absolute-layout.cpp \ - $(devel_api_src_dir)/layouting/linear-layout.cpp \ + $(devel_api_src_dir)/layouting/bin-layout.cpp \ + $(devel_api_src_dir)/layouting/flex-layout.cpp \ $(devel_api_src_dir)/layouting/grid.cpp \ $(devel_api_src_dir)/layouting/layout-item.cpp \ $(devel_api_src_dir)/layouting/layout-item-impl.cpp \ $(devel_api_src_dir)/layouting/layout-controller.cpp \ $(devel_api_src_dir)/layouting/layout-group.cpp \ $(devel_api_src_dir)/layouting/layout-group-impl.cpp \ + $(devel_api_src_dir)/layouting/linear-layout.cpp \ + $(devel_api_src_dir)/layouting/layout-transition-data.cpp \ $(devel_api_src_dir)/scripting/script.cpp \ $(devel_api_src_dir)/styling/style-manager-devel.cpp \ $(devel_api_src_dir)/transition-effects/cube-transition-cross-effect.cpp \ @@ -100,6 +102,7 @@ devel_api_layouting_header_files = \ $(devel_api_src_dir)/layouting/layout-length.h \ $(devel_api_src_dir)/layouting/layout-parent-impl.h \ $(devel_api_src_dir)/layouting/layout-size.h \ + $(devel_api_src_dir)/layouting/layout-transition-data.h \ $(devel_api_src_dir)/layouting/measured-size.h \ $(devel_api_src_dir)/layouting/measure-spec.h diff --git a/dali-toolkit/devel-api/layouting/bin-layout.cpp b/dali-toolkit/devel-api/layouting/bin-layout.cpp new file mode 100644 index 0000000..59d0b19 --- /dev/null +++ b/dali-toolkit/devel-api/layouting/bin-layout.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//CLASS HEADER +#include + +//INTERNAL HEADERS +#include + +namespace Dali +{ +namespace Toolkit +{ + +BinLayout::BinLayout() +{ +} + +BinLayout BinLayout::New() +{ + Internal::BinLayoutPtr internal = Internal::BinLayout::New(); + return BinLayout( internal.Get() ); +} + +BinLayout BinLayout::DownCast( BaseHandle handle ) +{ + return BinLayout( dynamic_cast< Dali::Toolkit::Internal::BinLayout*>( handle.GetObjectPtr() ) ); +} + +BinLayout::BinLayout( const BinLayout& other ) +: LayoutGroup( other ) +{ +} + +BinLayout& BinLayout::operator=( const BinLayout& other ) +{ + if( &other != this ) + { + LayoutGroup::operator=( other ); + } + return *this; +} + +BinLayout::BinLayout( Dali::Toolkit::Internal::BinLayout* object ) +: LayoutGroup( object ) +{ +} + +} // namespace Toolkit +} // namespace Dali diff --git a/dali-toolkit/devel-api/layouting/bin-layout.h b/dali-toolkit/devel-api/layouting/bin-layout.h new file mode 100644 index 0000000..b61245c --- /dev/null +++ b/dali-toolkit/devel-api/layouting/bin-layout.h @@ -0,0 +1,104 @@ +#ifndef DALI_TOOLKIT_LAYOUTING_BIN_LAYOUT_H +#define DALI_TOOLKIT_LAYOUTING_BIN_LAYOUT_H + +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +namespace Dali +{ +namespace Toolkit +{ + +namespace Internal DALI_INTERNAL +{ +class BinLayout; +} + +/** + * This class implements a bin layout, providing a simple layout to accept + * children and perform ResizePolicy mapping. + * + * Children will be positioned with their AnchorPoint and position if provided. + * If multiple children are added then they could overlap. + */ +class DALI_TOOLKIT_API BinLayout : public LayoutGroup +{ +public: + + /** + * @brief Creates an uninitialized BinLayout handle. + * + * Initialize it using BinLayout::New(). + * Calling member functions with an uninitialized handle is not allowed. + */ + BinLayout(); + + /** + * @brief Creates a BinLayout object. + */ + static BinLayout New(); + + /** + * @brief Downcasts a handle to a BinLayout handle. + * + * If handle points to a BinLayout, the downcast produces a valid handle. + * If not, the returned handle is left uninitialized. + + * @param[in] handle to an object + * @return Handle to a BinLayout or an uninitialized handle + */ + static BinLayout DownCast( BaseHandle handle ); + + /** + * @brief Copy constructor + */ + BinLayout( const BinLayout& other ); + + /** + * @brief Assignment operator + */ + BinLayout& operator=( const BinLayout& other ); + + /** + * @brief Default destructor. + * + * This is non-virtual, since derived Handle types must not contain data or virtual methods + */ + ~BinLayout()=default; + + +public: // Not intended for application developers + + /// @cond internal + /** + * @brief This constructor is used by BinLayout::New() methods. + * + * @param[in] actor A pointer to a newly allocated Dali resource + */ + explicit DALI_INTERNAL BinLayout( Internal::BinLayout* body ); + /// @endcond +}; + +} // namespace Toolkit +} // namespace Dali + +#endif // DALI_TOOLKIT_LAYOUTING_BIN_LAYOUT_H diff --git a/dali-toolkit/devel-api/layouting/layout-controller.cpp b/dali-toolkit/devel-api/layouting/layout-controller.cpp index 645fe48..ba87af2 100644 --- a/dali-toolkit/devel-api/layouting/layout-controller.cpp +++ b/dali-toolkit/devel-api/layouting/layout-controller.cpp @@ -68,7 +68,12 @@ LayoutController LayoutController::Get() void LayoutController::RequestLayout( LayoutItem layout ) { - GetImpl(*this).RequestLayout( GetImplementation( layout ) ); + GetImpl( *this ).RequestLayout( GetImplementation( layout ), -1 ); +} + +void LayoutController::RequestLayout( LayoutItem layout, Dali::Toolkit::LayoutTransitionData::LayoutTransitionType layoutTransitionType ) +{ + GetImpl( *this ).RequestLayout( GetImplementation( layout ), layoutTransitionType ); } LayoutController::LayoutController( Internal::LayoutController *impl ) diff --git a/dali-toolkit/devel-api/layouting/layout-controller.h b/dali-toolkit/devel-api/layouting/layout-controller.h index 2741829..062793d 100755 --- a/dali-toolkit/devel-api/layouting/layout-controller.h +++ b/dali-toolkit/devel-api/layouting/layout-controller.h @@ -62,10 +62,19 @@ public: static LayoutController Get(); /** - * @brief Request for a particular layout (wrapping a control or a visual) to be measured and laid out. + * @brief Request for a particular layout (wrapping a control or a visual) to be measured and laid out. A specified layout transition + * will be triggered during the layout. + * @param[in] layout The layout to measure & relayout. + */ + void RequestLayout( LayoutItem layout ); + + /** + * @brief Request for a particular layout (wrapping a control or a visual) to be measured and laid out. A specified layout transition + * will be triggered during the layout. * @param[in] layout The layout to measure & relayout. + * @param[in] layoutTransitionType The layout transition type. */ - void RequestLayout( LayoutItem layout ); + void RequestLayout( LayoutItem layout, Dali::Toolkit::LayoutTransitionData::LayoutTransitionType layoutTransitionType ); public: /// @cond internal diff --git a/dali-toolkit/devel-api/layouting/layout-group-impl.cpp b/dali-toolkit/devel-api/layouting/layout-group-impl.cpp index cab70c3..06305bd 100644 --- a/dali-toolkit/devel-api/layouting/layout-group-impl.cpp +++ b/dali-toolkit/devel-api/layouting/layout-group-impl.cpp @@ -507,7 +507,7 @@ void LayoutGroup::OnInitialize() // Take ownership of existing children for( unsigned int childIndex = 0 ; childIndex < control.GetChildCount(); ++childIndex ) { - ChildAddedToOwner( control.GetChildAt( childIndex ) ); + ChildAddedToOwnerImpl( control.GetChildAt( childIndex ) ); } DevelActor::ChildAddedSignal( control ).Connect( mSlotDelegate, &LayoutGroup::ChildAddedToOwner ); @@ -551,6 +551,8 @@ void LayoutGroup::OnInitialize() } } } + + RequestLayout( Dali::Toolkit::LayoutTransitionData::LayoutTransitionType::ON_OWNER_SET ); } } @@ -582,6 +584,12 @@ void LayoutGroup::RemoveChild( LayoutItem& item ) void LayoutGroup::ChildAddedToOwner( Actor child ) { + ChildAddedToOwnerImpl( child ); + RequestLayout( Dali::Toolkit::LayoutTransitionData::LayoutTransitionType::ON_CHILD_ADD ); +} + +void LayoutGroup::ChildAddedToOwnerImpl( Actor child ) +{ LayoutItemPtr childLayout; Toolkit::Control control = Toolkit::Control::DownCast( child ); @@ -662,6 +670,7 @@ void LayoutGroup::ChildRemovedFromOwner( Actor child ) if( childLayout ) { Remove( *childLayout.Get() ); + RequestLayout( Dali::Toolkit::LayoutTransitionData::LayoutTransitionType::ON_CHILD_REMOVE ); } } } @@ -750,10 +759,9 @@ void LayoutGroup::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMea bool exactWidth ( false ); bool exactHeight ( false ); - // Default Layouting behaviour if not overridden + // Layouting behaviour // EXACT, width and height as provided. - // MATCH_PARENT, width and hewidthSpecSizeight that of parent - + // MATCH_PARENT, width and height that of parent // WRAP_CONTENT, take width of widest child and height size of longest child (within given limit) // UNSPECIFIED, take width of widest child and height size of longest child. diff --git a/dali-toolkit/devel-api/layouting/layout-group-impl.h b/dali-toolkit/devel-api/layouting/layout-group-impl.h index ee73c88..37aa90f 100644 --- a/dali-toolkit/devel-api/layouting/layout-group-impl.h +++ b/dali-toolkit/devel-api/layouting/layout-group-impl.h @@ -294,6 +294,11 @@ private: void ChildAddedToOwner( Actor child ); /** + * Implementation of ChildAddedToOwner + */ + void ChildAddedToOwnerImpl( Actor child ); + + /** * Callback when child is removed from owner */ void ChildRemovedFromOwner( Actor child ); diff --git a/dali-toolkit/devel-api/layouting/layout-item-impl.cpp b/dali-toolkit/devel-api/layouting/layout-item-impl.cpp index f70a5f1..cd4cf40 100644 --- a/dali-toolkit/devel-api/layouting/layout-item-impl.cpp +++ b/dali-toolkit/devel-api/layouting/layout-item-impl.cpp @@ -19,10 +19,14 @@ #include #include #include +#include #include #include +#include #include +#include + namespace { @@ -33,7 +37,6 @@ Debug::Filter* gLayoutFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG const char* WIDTH_SPECIFICATION_NAME( "widthSpecification" ); const char* HEIGHT_SPECIFICATION_NAME( "heightSpecification" ); -const float DEFAULT_TRANSITION_DURATION( 0.5f ); } namespace Dali @@ -66,7 +69,6 @@ void LayoutItem::Initialize( Handle& owner, const std::string& containerType ) mImpl->mOwner = &(owner.GetBaseObject()); RegisterChildProperties( containerType ); OnInitialize(); // Ensure direct deriving class gets initialized - RequestLayout(); } Handle LayoutItem::GetOwner() const @@ -93,6 +95,35 @@ void LayoutItem::Unparent() mImpl->mOwner = NULL; } +LayoutTransitionDataPtr LayoutItem::GetDefaultTransition() +{ + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::GetDefaultTransition\n" ); + if ( !mImpl->mDefaultTransitionData.Get() ) + { + auto owner = GetOwner(); + auto actor = Actor::DownCast( owner ); + + mImpl->mDefaultTransitionData = LayoutTransitionData::New(); + { + Property::Map map; + map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION; + map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update + map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR ] = std::string(); // default animator with default duration + // Capture calculated position after layout, apply default linear animation + mImpl->mDefaultTransitionData->AddPropertyAnimator( actor, map ); + } + { + Property::Map map; + map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; + map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update + map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR ] = std::string(); // default animator with default duration + // Capture calculated size after layout, apply default linear animation + mImpl->mDefaultTransitionData->AddPropertyAnimator( actor, map ); + } + } + return mImpl->mDefaultTransitionData; +} + void LayoutItem::SetAnimateLayout( bool animateLayout ) { auto owner = GetOwner(); @@ -111,6 +142,39 @@ bool LayoutItem::IsLayoutAnimated() const return mImpl->mAnimated; } +void LayoutItem::SetTransitionData( int layoutTransitionType, Internal::LayoutTransitionDataPtr layoutTransitionDataPtr ) +{ + switch ( layoutTransitionType ) + { + case Dali::Toolkit::LayoutTransitionData::ON_CHILD_ADD: + mImpl->mOnChildAddTransitionData = layoutTransitionDataPtr; + break; + case Dali::Toolkit::LayoutTransitionData::ON_CHILD_REMOVE: + mImpl->mOnChildRemoveTransitionData = layoutTransitionDataPtr; + break; + case Dali::Toolkit::LayoutTransitionData::ON_OWNER_SET: + mImpl->mOnOwnerSetTransitionData = layoutTransitionDataPtr; + break; + default: + break; + } +} + +Internal::LayoutTransitionDataPtr LayoutItem::GetTransitionData( int layoutTransitionType ) const +{ + switch ( layoutTransitionType ) + { + case Dali::Toolkit::LayoutTransitionData::ON_CHILD_ADD: + return mImpl->mOnChildAddTransitionData.Get(); + case Dali::Toolkit::LayoutTransitionData::ON_CHILD_REMOVE: + return mImpl->mOnChildRemoveTransitionData.Get(); + case Dali::Toolkit::LayoutTransitionData::ON_OWNER_SET: + return mImpl->mOnOwnerSetTransitionData.Get(); + default: + return LayoutTransitionDataPtr(); + } +} + void LayoutItem::RegisterChildProperties( const std::string& containerType ) { // Call on derived types @@ -198,14 +262,23 @@ void LayoutItem::Layout( LayoutLength l, LayoutLength t, LayoutLength r, LayoutL mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_MEASURE_NEEDED_BEFORE_LAYOUT ); } + LayoutData& layoutData = *mImpl->sLayoutData; + size_t size = layoutData.childrenPropertyAnimators.size(); + bool changed = SetFrame( l, t, r, b ); if( changed || mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_LAYOUT_REQUIRED ) ) { + OnLayout( changed, l, t, r, b ); mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_LAYOUT_REQUIRED ); } + if ( size != layoutData.childrenPropertyAnimators.size() ) + { + layoutData.childrenPropertyAnimators.resize( size ); + } + mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT ); mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_IS_LAID_OUT ); } @@ -333,14 +406,29 @@ LayoutParent* LayoutItem::GetParent() void LayoutItem::RequestLayout() { Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner ); + if( control ) + { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout control(%s)\n", + control.GetName().c_str() ); + } + // @todo Enforce failure if called in Measure/Layout passes. + mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT ); + Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get(); + layoutController.RequestLayout( Toolkit::LayoutItem( this ) ); +} + +void LayoutItem::RequestLayout( Dali::Toolkit::LayoutTransitionData::LayoutTransitionType layoutAnimationType ) +{ + Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner ); if ( control ) { - DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout %s\n", control.GetName().c_str()); + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout control(%s) layoutTranstionType(%d)\n", + control.GetName().c_str(), (int)layoutAnimationType ); } // @todo Enforce failure if called in Measure/Layout passes. mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT ); Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get(); - layoutController.RequestLayout( Toolkit::LayoutItem(this) ); + layoutController.RequestLayout( Toolkit::LayoutItem(this), layoutAnimationType ); } bool LayoutItem::IsLayoutRequested() const @@ -469,56 +557,65 @@ bool LayoutItem::SetFrame( LayoutLength left, LayoutLength top, LayoutLength rig if( mImpl->mLeft != left || mImpl->mRight != right || mImpl->mTop != top || mImpl->mBottom != bottom || mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_SET_FRAME ) ) { changed = true; - - LayoutLength oldWidth = mImpl->mRight - mImpl->mLeft; - LayoutLength oldHeight = mImpl->mBottom - mImpl->mTop; - LayoutLength newWidth = right - left; - LayoutLength newHeight = bottom - top; - bool sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight); - - mImpl->mLeft = left; - mImpl->mTop = top; - mImpl->mRight = right; - mImpl->mBottom = bottom; - mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_FORCE_SET_FRAME ); + } + LayoutLength oldWidth = mImpl->mRight - mImpl->mLeft; + LayoutLength oldHeight = mImpl->mBottom - mImpl->mTop; + LayoutLength newWidth = right - left; + LayoutLength newHeight = bottom - top; + bool sizeChanged = ( newWidth != oldWidth ) || ( newHeight != oldHeight ); - // Reflect up to parent control - auto owner = GetOwner(); - auto actor = Actor::DownCast(owner); - if( actor ) - { - DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame owner(" << left << ", " << top << ", " << right << ", " << bottom << ")\n" ); + mImpl->mLeft = left; + mImpl->mTop = top; + mImpl->mRight = right; + mImpl->mBottom = bottom; - if( mImpl->mAnimated ) - { - auto animation = Animation::New( 0.5f ); - animation.AnimateTo( Property( actor, Actor::Property::POSITION_X ), left.AsInteger() ); - animation.AnimateTo( Property( actor, Actor::Property::POSITION_Y ), top.AsInteger() ); + // Reflect up to parent control + auto owner = GetOwner(); + auto actor = Actor::DownCast( owner ); + LayoutData& layoutData = *mImpl->sLayoutData; + if( actor ) + { + if( mImpl->mAnimated && !layoutData.speculativeLayout ) + { - animation.AnimateTo( Property( actor, Actor::Property::SIZE_WIDTH ), newWidth.AsInteger() ); - animation.AnimateTo( Property( actor, Actor::Property::SIZE_HEIGHT ), newHeight.AsInteger() ); + LayoutItem* transitionOwner = layoutData.layoutTransition.layoutItem.Get(); + LayoutTransitionDataPtr layoutTransitionDataPtr = GetTransitionData( layoutData.layoutTransition.layoutTransitionType ); - animation.FinishedSignal().Connect( mSlotDelegate, &LayoutItem::OnLayoutAnimationFinished ); - animation.Play(); + // Found transition owner + if( transitionOwner == this && layoutTransitionDataPtr.Get() ) + { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame apply transition to (%s), transition type (%d)\n", actor.GetName().c_str(), layoutData.layoutTransition.layoutTransitionType ); + layoutData.layoutPositionDataArray.push_back( LayoutPositionData( actor, left.AsDecimal(), top.AsDecimal(), right.AsDecimal(), bottom.AsDecimal(), true ) ); + layoutTransitionDataPtr->ConvertToLayoutDataElements( actor, layoutData ); + changed = true; } else { - // @todo Collate into list of Property & Property::Value pairs. - actor.SetX( left.AsInteger() ); - actor.SetY( top.AsInteger() ); - actor.SetProperty( Actor::Property::SIZE_WIDTH, newWidth.AsInteger() ); - actor.SetProperty( Actor::Property::SIZE_HEIGHT, newHeight.AsInteger() ); + if( changed ) + { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame apply default transition to (%s), transition type (%d)\n", actor.GetName().c_str(), layoutData.layoutTransition.layoutTransitionType ); + layoutData.layoutPositionDataArray.push_back( LayoutPositionData( actor, left.AsDecimal(), top.AsDecimal(), right.AsDecimal(), bottom.AsDecimal(), true ) ); + GetDefaultTransition()->ConvertToLayoutDataElements( actor, layoutData ); + } } } - - if( sizeChanged ) + else { - SizeChange( LayoutSize( newWidth, newHeight ), LayoutSize( oldWidth, oldHeight ) ); + if( changed ) + { + layoutData.layoutPositionDataArray.push_back( LayoutPositionData( actor, left.AsDecimal(), top.AsDecimal(), right.AsDecimal(), bottom.AsDecimal(), false ) ); + } } } + // TODO: do we need it + if( sizeChanged ) + { + SizeChange( LayoutSize( newWidth, newHeight ), LayoutSize( oldWidth, oldHeight ) ); + } + DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame exit(" << left << ", " << top << ", " << right << ", " << bottom << ")\n" ); return changed; diff --git a/dali-toolkit/devel-api/layouting/layout-item-impl.h b/dali-toolkit/devel-api/layouting/layout-item-impl.h index 3850e5f..19b61d5 100644 --- a/dali-toolkit/devel-api/layouting/layout-item-impl.h +++ b/dali-toolkit/devel-api/layouting/layout-item-impl.h @@ -20,8 +20,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -37,9 +39,13 @@ namespace Toolkit namespace Internal { +struct LayoutData; + class LayoutItem; using LayoutItemPtr = IntrusivePtr; +class LayoutTransitionData; +using LayoutTransitionDataPtr = IntrusivePtr; /** * Base class for layouts. @@ -114,6 +120,28 @@ public: bool IsLayoutAnimated() const; /** + * @brief Get the default transition + * + * @return The default transition + */ + LayoutTransitionDataPtr GetDefaultTransition(); + + /** + * @brief Set the layout transition data + * @param[in] layoutTransitionType The type of the transition + * @param[in] layoutTransitionDataPtr The transition data pointer + */ + void SetTransitionData( int layoutTransitionType, LayoutTransitionDataPtr layoutTransitionDataPtr ); + + /** + * @brief Get the transition data + * @param[in] layoutTransitionType The type of the transition + * + * @return The transition + */ + LayoutTransitionDataPtr GetTransitionData( int layoutTransitionType ) const; + + /** * @brief This is called to find out how big a layout should be. * * The parent supplies constraint information in the width and height parameters. @@ -176,6 +204,14 @@ public: void RequestLayout(); /** + * @brief Request that this layout is re-laid out with particular transition. + * @param[in] layoutTranstionType The transition type + * + * This will make this layout and all it's parent layouts dirty and set the transition queued. + */ + void RequestLayout( Dali::Toolkit::LayoutTransitionData::LayoutTransitionType layoutTranstionType ); + + /** * @brief Predicate to determine if this layout has been requested to re-layout * * @return True if a layout request has occured on this layout @@ -408,10 +444,9 @@ protected: MeasuredSize::State childMeasuredState ); /** - * @brief Sets the frame (the size and position) of the layout onto it's owner + * @brief Sets the frame (the size and position) of the layout onto it's owner. + * Collect all properties to animate after the layout update. * - * @todo Consider instead, collating properties into LayoutCollector in order to set/animate them all - * in one block. * @param[in] left The horizontal position of the left edge of this frame within the parent layout * @param[in] top The vertical position of the top edge of this frame within the parent layout * @param[in] right The horizontal position of the right edge of this frame within the parent layout @@ -466,7 +501,6 @@ private: public: class Impl; // Class declaration is public so we can add devel API's in the future - private: std::unique_ptr mImpl; ///< Implementation class holds all the data SlotDelegate mSlotDelegate; diff --git a/dali-toolkit/devel-api/layouting/layout-item.cpp b/dali-toolkit/devel-api/layouting/layout-item.cpp index 153c134..a84b45d 100644 --- a/dali-toolkit/devel-api/layouting/layout-item.cpp +++ b/dali-toolkit/devel-api/layouting/layout-item.cpp @@ -16,6 +16,8 @@ #include #include +#include +#include namespace Dali { @@ -53,6 +55,21 @@ bool LayoutItem::IsLayoutAnimated() const return GetImplementation( *this ).IsLayoutAnimated(); } +void LayoutItem::SetTransitionData( LayoutTransitionData::LayoutTransitionType layoutTransitionType, LayoutTransitionData layoutTransitionData ) +{ + Toolkit::Internal::LayoutTransitionDataPtr layoutTransitionDataPtr = Toolkit::Internal::LayoutTransitionDataPtr(); + if ( layoutTransitionData ) + { + layoutTransitionDataPtr = Toolkit::Internal::LayoutTransitionDataPtr( &Toolkit::GetImplementation( layoutTransitionData ) ); + } + GetImplementation( *this ).SetTransitionData( layoutTransitionType, layoutTransitionDataPtr ); +} + +LayoutTransitionData LayoutItem::GetTransitionData( LayoutTransitionData::LayoutTransitionType layoutTransitionType ) const +{ + return LayoutTransitionData( GetImplementation( *this ).GetTransitionData( layoutTransitionType ).Get() ); +} + } // namespace Toolkit } // namespace Dali diff --git a/dali-toolkit/devel-api/layouting/layout-item.h b/dali-toolkit/devel-api/layouting/layout-item.h index fc69e6d..1ad32ed 100755 --- a/dali-toolkit/devel-api/layouting/layout-item.h +++ b/dali-toolkit/devel-api/layouting/layout-item.h @@ -20,10 +20,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include namespace Dali @@ -38,7 +41,6 @@ class LayoutItem; using LayoutId = unsigned int; - /** * Base class for layouts. It is used to layout a control (or visual). * It can be laid out by a LayoutGroup. @@ -115,6 +117,23 @@ public: */ bool IsLayoutAnimated() const; + /** + * @brief Set the layout transition data + * + * @param[in] layoutTransitionType The type of the layout transition + * @param[in] layoutTransitionData The layout transition data + */ + void SetTransitionData( LayoutTransitionData::LayoutTransitionType layoutTransitionType, LayoutTransitionData layoutTransitionData ); + + /** + * @brief Get the layout transition data + * + * @param[in] layoutTransitionType The type of the layout transition + * + * @return The layout transition data + */ + LayoutTransitionData GetTransitionData( LayoutTransitionData::LayoutTransitionType layoutTransitionType ) const; + public: /// @cond internal /** diff --git a/dali-toolkit/devel-api/layouting/layout-transition-data.cpp b/dali-toolkit/devel-api/layouting/layout-transition-data.cpp new file mode 100644 index 0000000..c01b2dd --- /dev/null +++ b/dali-toolkit/devel-api/layouting/layout-transition-data.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +namespace Dali +{ +namespace Toolkit +{ + +LayoutTransitionData::LayoutTransitionData() +: BaseHandle() +{ +} + +LayoutTransitionData::LayoutTransitionData( Internal::LayoutTransitionData* layoutAnimationData ) +: BaseHandle( layoutAnimationData ) +{ +} + +LayoutTransitionData LayoutTransitionData::New() +{ + Internal::LayoutTransitionDataPtr layoutAnimationData = Internal::LayoutTransitionData::New(); + return LayoutTransitionData( layoutAnimationData.Get() ); +} + +LayoutTransitionData LayoutTransitionData::DownCast( BaseHandle handle ) +{ + return LayoutTransitionData( dynamic_cast(handle.GetObjectPtr()) ); +} + +void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map ) +{ + GetImplementation( *this ).AddPropertyAnimator( actor, map ); +} + +void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation ) +{ + GetImplementation( *this ).AddPropertyAnimator( actor, map, keyFrames, interpolation ); +} + +void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward ) +{ + GetImplementation( *this ).AddPropertyAnimator( actor, map, path, forward ); +} + +LayoutTransitionData::LayoutTransitionSignalType& LayoutTransitionData::FinishedSignal() +{ + return GetImplementation(*this ).FinishedSignal(); +} + +} // namespace Toolkit +} // namespace Dali diff --git a/dali-toolkit/devel-api/layouting/layout-transition-data.h b/dali-toolkit/devel-api/layouting/layout-transition-data.h new file mode 100644 index 0000000..5bd509a --- /dev/null +++ b/dali-toolkit/devel-api/layouting/layout-transition-data.h @@ -0,0 +1,151 @@ +#ifndef DALI_TOOLKIT_LAYOUTING_LAYOUT_TRANSITION_DATA_H +#define DALI_TOOLKIT_LAYOUTING_LAYOUT_TRANSITION_DATA_H +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Dali +{ +namespace Toolkit +{ + +namespace Internal +{ +class LayoutTransitionData; +} + +class DALI_TOOLKIT_API LayoutTransitionData final : public BaseHandle +{ +public: + + /** + * @brief Enumeration for property animator keys belonging to the LayoutTransitionData class. + */ + struct AnimatorKey + { + enum Type + { + PROPERTY, ///< A property to animate + INITIAL_VALUE, ///< Initial value of an animated property + TARGET_VALUE, ///< Target value of an animated property + ANIMATOR, ///< Animator for an animated property + TYPE, ///< Type of an animator + NAME, ///< Name of an animator + TIME_PERIOD, ///< Time period of an property animation + DURATION, ///< Duration of an property animation + DELAY, ///< Delay of an property animation + ALPHA_FUNCTION, ///< Alpha function of a property animation + }; + }; + + enum LayoutTransitionType + { + ON_CHILD_ADD, + ON_CHILD_REMOVE, + ON_OWNER_SET + }; + + typedef Signal< void (LayoutTransitionData::LayoutTransitionType, LayoutTransitionData&) > LayoutTransitionSignalType; ///< Transition finished signal + + /** + * Create an uninitialized handle + * + * @SINCE_1_2.12 + */ + LayoutTransitionData(); + + /** + * Destructor - non virtual + * + * @SINCE_1_2.12 + */ + ~LayoutTransitionData() = default; + + /** + * Create an initialized LayoutTransitionData + */ + static LayoutTransitionData New(); + + /** + * @brief Downcasts a handle to LayoutTransitionData handle. + * + * If handle points to an LayoutTransitionData object, the downcast produces valid handle. + * If not, the returned handle is left uninitialized. + * + * @param[in] handle Handle to an object + * @return Handle to an LayoutTransitionData object or an uninitialized handle + */ + static LayoutTransitionData DownCast( BaseHandle handle ); + + /** + * @brief Add a property animator for an actor + * + * @param[in] actor An owner of the animated property + * @param[in] map The animated property map including animator map + */ + void AddPropertyAnimator( Actor actor, Property::Map map ); + + /** + * @brief Add a property animator for an actor + * + * @param[in] actor An owner of the animated property + * @param[in] map The properties map + * @param[in] keyFrames key frames + * @param[in] interpolation An interpolation + */ + void AddPropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation ); + + /** + * @brief Add a property animator for an actor + * + * @param[in] actor An owner of the animated property + * @param[in] map A properties map + * @param[in] path An animation path + * @param[in] forward A forward vector for the path + */ + void AddPropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward ); + + /** + * @brief Connects to this signal to be notified when a transition animation have finished. + * + * @return A signal object to connect with + */ + LayoutTransitionSignalType& FinishedSignal(); + +public: + /// @cond internal + /** + * @brief This constructor is used by LayoutTransitionData::New() method. + * + * @param[in] layoutTransitonData A pointer to a newly allocated transition data resource + */ + DALI_INTERNAL explicit LayoutTransitionData( Internal::LayoutTransitionData* layoutTransitonData ); + /// @endcond +}; + +}//namespace Toolkit +}//namespace Dali + +#endif // DALI_TOOLKIT_LAYOUTING_LAYOUT_TRANSITION_DATA_H diff --git a/dali-toolkit/internal/builder/builder-filesystem.h b/dali-toolkit/internal/builder/builder-filesystem.h old mode 100644 new mode 100755 index bbb77d7..d7118dd --- a/dali-toolkit/internal/builder/builder-filesystem.h +++ b/dali-toolkit/internal/builder/builder-filesystem.h @@ -46,7 +46,9 @@ inline std::string ExpandPath(const std::string &name) inline std::string ExePath(void) { char buf[256]; - readlink("/proc/self/exe", buf, sizeof(buf)); + ssize_t len = readlink("/proc/self/exe", buf, sizeof(buf) - 1); + len = len > 0 ? len : 0; + buf[len] = '\0'; return std::string(buf); } diff --git a/dali-toolkit/internal/controls/control/control-data-impl.cpp b/dali-toolkit/internal/controls/control/control-data-impl.cpp index 6468ad5..c5af35e 100755 --- a/dali-toolkit/internal/controls/control/control-data-impl.cpp +++ b/dali-toolkit/internal/controls/control/control-data-impl.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -1457,11 +1458,11 @@ void Control::Impl::SetLayout( Toolkit::Internal::LayoutItem& layout ) void Control::Impl::RemoveLayout() { - if( mLayout ) - { - mLayout->Unparent(); - mLayout.Reset(); - } + DALI_LOG_INFO( gLogFilterLayout, Debug::Verbose, "Control::Impl::RemoveLayout\n"); + + Toolkit::BinLayout binLayout = Toolkit::BinLayout::New(); + + mControlImpl.mImpl->SetLayout( GetImplementation( binLayout ) ) ; } void Control::Impl::SetLayoutingRequired( bool layoutingRequired ) diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 11faf72..8fab9fd 100755 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -11,15 +11,17 @@ toolkit_src_files = \ $(toolkit_src_dir)/builder/style.cpp \ $(toolkit_src_dir)/builder/tree-node-manipulator.cpp \ $(toolkit_src_dir)/builder/replacement.cpp \ - $(toolkit_src_dir)/layouting/flex-layout-impl.cpp \ $(toolkit_src_dir)/layouting/absolute-layout-impl.cpp \ - $(toolkit_src_dir)/layouting/linear-layout-impl.cpp \ + $(toolkit_src_dir)/layouting/bin-layout-impl.cpp \ + $(toolkit_src_dir)/layouting/flex-layout-impl.cpp \ $(toolkit_src_dir)/layouting/grid-locations.cpp \ $(toolkit_src_dir)/layouting/grid-impl.cpp \ $(toolkit_src_dir)/layouting/layout-item-data-impl.cpp \ $(toolkit_src_dir)/layouting/layout-group-data-impl.cpp \ $(toolkit_src_dir)/layouting/layout-controller-debug.cpp \ $(toolkit_src_dir)/layouting/layout-controller-impl.cpp \ + $(toolkit_src_dir)/layouting/linear-layout-impl.cpp \ + $(toolkit_src_dir)/layouting/layout-transition-data-impl.cpp \ $(toolkit_src_dir)/layouting/size-negotiation-mapper.cpp \ $(toolkit_src_dir)/visuals/animated-image/animated-image-visual.cpp \ $(toolkit_src_dir)/visuals/animated-image/image-cache.cpp \ diff --git a/dali-toolkit/internal/layouting/absolute-layout-impl.h b/dali-toolkit/internal/layouting/absolute-layout-impl.h index 99fb3c8..7b2d62b 100644 --- a/dali-toolkit/internal/layouting/absolute-layout-impl.h +++ b/dali-toolkit/internal/layouting/absolute-layout-impl.h @@ -63,8 +63,6 @@ private: AbsoluteLayout( const AbsoluteLayout& other ) = delete; AbsoluteLayout& operator=( const AbsoluteLayout& other ) = delete; - void ForceUniformHeight( int count, MeasureSpec widthMeasureSpec ); - }; } // namespace Internal diff --git a/dali-toolkit/internal/layouting/bin-layout-impl.cpp b/dali-toolkit/internal/layouting/bin-layout-impl.cpp new file mode 100644 index 0000000..567fc39 --- /dev/null +++ b/dali-toolkit/internal/layouting/bin-layout-impl.cpp @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//CLASS HEADER +#include + +//INTERNAL HEADERS +#include +#include +#include +#include +#include +#include +#include + +namespace +{ +#if defined(DEBUG_ENABLED) +static Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_LAYOUT" ); +#endif +} + +namespace Dali +{ +namespace Toolkit +{ +namespace Internal +{ + +BinLayoutPtr BinLayout::New() +{ + BinLayoutPtr layout( new BinLayout() ); + return layout; +} + +BinLayout::BinLayout() +: LayoutGroup() +{ +} + +BinLayout::~BinLayout() +{ +} + +void BinLayout::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec ) +{ +#if defined(DEBUG_ENABLED) + auto actor = Actor::DownCast(GetOwner()); + + std::ostringstream oss; + oss << "BinLayout::OnMeasure "; + if( actor ) + { + oss << "Actor Id:" << actor.GetId() << " Name:" << actor.GetName() << " "; + } + oss << "widthMeasureSpec:" << widthMeasureSpec << " heightMeasureSpec:" << heightMeasureSpec << std::endl; + DALI_LOG_INFO( gLogFilter, Debug::Concise, oss.str().c_str() ); +#endif + + auto childCount = GetChildCount(); + + DALI_LOG_STREAM( gLogFilter, Debug::Verbose, + "BinLayout::OnMeasure Actor Id:" << Actor::DownCast(GetOwner()).GetId() << + " Owner:" << Actor::DownCast(GetOwner()).GetName() << + " Child Count:" << childCount << + " MeasureSpecs( width:"< 0 ) + { + for( unsigned int i=0; iGetOwner()); + + // If child control has children check if a ResizePolicy is set on it. A LayoutItem could be a legacy container. + // A legacy container would need it's ResizePolicy to be applied as a MeasureSpec. + + // Check below will be true for legacy containers and for controls with the layout flag required set. + // Other layouts will have their own OnMeasure (a requirement) hence not execute BinLayout::OnMeasure. + // Controls which have set the layout required flag will not be legacy controls hence should not have a ResizePolicy set. + if( childControl.GetChildCount() > 0 ) + { + // First pass, Static mappings that are not dependant on parent + SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( childControl, childLayout, Dimension::WIDTH ); + SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( childControl, childLayout, Dimension::HEIGHT ); + } + + // Second pass, if any mappings were not possible due to parent size dependencies then calculate an exact desired size for child + if( true == childLayout->IsResizePolicyRequired() ) // No need to test child count as this flag would only be set if control had children. + { + // Get last stored width and height specifications for the child + LayoutLength desiredWidth = childControl.GetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION ); + LayoutLength desiredHeight = childControl.GetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION ); + + DALI_LOG_INFO( gLogFilter, Debug::General, "BinLayout::MeasureChild Initial desired size pre ResizePolicy(%f,%f)\n", desiredWidth.AsInteger(), desiredHeight.AsInteger() ); + + childLayout->SetResizePolicyRequired( false ); // clear flag incase in case of changes before next Measure + SizeNegotiationMapper::GetSizeofChildForParentDependentResizePolicy( childControl, widthMeasureSpec, heightMeasureSpec, desiredWidth, desiredHeight ); + + // Parent dependant ResizePolicies become exact sizes so are now set on the child before it's measured. + childControl.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, desiredWidth.AsInteger() ); + childControl.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, desiredHeight.AsInteger() ); + + DALI_LOG_INFO( gLogFilter, Debug::General, " BinLayout::OnMeasure ResizePolicy Required resulting size(%f,%f)\n", desiredWidth.AsInteger(), desiredHeight.AsInteger() ); + } + + // Get size of child + MeasureChild( childLayout, widthMeasureSpec, heightMeasureSpec ); + LayoutLength childWidth = childLayout->GetMeasuredWidth(); + LayoutLength childHeight = childLayout->GetMeasuredHeight(); + + Extents childMargin = childLayout->GetMargin(); + + // BinLayout width is that of it's widest child and it's height of the tallest child. + // MeasureSpec::Mode::UNSPECIFIED will use these sizes + layoutWidth = std::max( layoutWidth, childWidth + childMargin.start + childMargin.end ); + layoutHeight = std::max( layoutHeight, childHeight + childMargin.top + childMargin.bottom ); + DALI_LOG_STREAM( gLogFilter, Debug::Verbose, "BinLayout::OnMeasure calculated current BinLayout width[" << layoutWidth << "] height[" << layoutHeight << "]\n" ); + } + else + { + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "BinLayout::OnMeasure Not a layout\n" ); + } + } + + Extents padding = GetPadding(); + layoutWidth += padding.start + padding.end; + layoutHeight += padding.top + padding.bottom; + } + else + { + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "BinLayout::OnMeasure Getting default size as a leaf\n" ); + // BinLayout does not contain any children so must be a leaf + layoutWidth = GetDefaultSize( GetSuggestedMinimumWidth(), widthMeasureSpec ); + layoutHeight = GetDefaultSize( GetSuggestedMinimumHeight(), heightMeasureSpec ); + } + + // Can't exceed specified width + if( widthMode == MeasureSpec::Mode::EXACTLY ) + { + exactWidth = true; + } + else if ( widthMode == MeasureSpec::Mode::AT_MOST ) + { + layoutWidth = std::min( layoutWidth, widthSpecSize ); + } + + // Can't exceed specified height + if( heightMode == MeasureSpec::Mode::EXACTLY ) + { + exactHeight = true; + } + else if ( heightMode == MeasureSpec::Mode::AT_MOST ) + { + layoutHeight = std::min( layoutHeight, heightSpecSize ); + } + + layoutWidth = std::max( layoutWidth, GetSuggestedMinimumWidth() ); + layoutHeight = std::max( layoutHeight, GetSuggestedMinimumHeight() ); + + if( exactWidth ) + { + layoutWidth = widthSpecSize; + } + + if( exactHeight ) + { + layoutHeight = heightSpecSize; + } + + DALI_LOG_STREAM( gLogFilter, Debug::General, "BinLayout::OnMeasure Measured size(" << layoutWidth << "," << layoutHeight << ") for : " << Actor::DownCast(GetOwner()).GetName() << " \n" ); + SetMeasuredDimensions( MeasuredSize( layoutWidth ), MeasuredSize( layoutHeight ) ); + +} + +void BinLayout::OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom ) +{ + auto count = GetChildCount(); + + DALI_LOG_STREAM( gLogFilter, Debug::Verbose, "BinLayout OnLayout owner:" << ( ( Toolkit::Control::DownCast(GetOwner())) ? Toolkit::Control::DownCast(GetOwner()).GetName() : "invalid" ) << " childCount:" << count ); + + for( unsigned int childIndex = 0; childIndex < count; childIndex++) + { + LayoutItemPtr childLayout = GetChildAt( childIndex ); + if( childLayout != nullptr ) + { + + auto childOwner = childLayout->GetOwner(); + LayoutLength childWidth = childLayout->GetMeasuredWidth(); + LayoutLength childHeight = childLayout->GetMeasuredHeight(); + Extents childMargin = childLayout->GetMargin(); + auto control = Toolkit::Control::DownCast( childOwner ); + Extents padding = GetPadding(); + + auto childPosition = control.GetProperty< Vector3 >( Actor::Property::POSITION ); + auto anchorPoint = control.GetProperty< Vector3 >( Actor::Property::ANCHOR_POINT ); + + DALI_LOG_STREAM( gLogFilter, Debug::General, "BinLayout::OnLayout child[" << control.GetName() << + "] position(" << childPosition << ") child width[" << childWidth << "] height[" << childHeight << "]\n" ); + + // Margin and Padding only supported when child anchor point is TOP_LEFT. + int paddingAndMarginOffsetX = ( AnchorPoint::TOP_LEFT == anchorPoint ) ? ( padding.top + childMargin.top ) : 0; + int paddingAndMarginOffsetY = ( AnchorPoint::TOP_LEFT == anchorPoint ) ? ( padding.start + childMargin.start ) : 0; + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "BinLayout::OnLayout paddingMargin offset(%d,%d)\n", paddingAndMarginOffsetX, paddingAndMarginOffsetY ); + + LayoutLength childLeft = childPosition.x + paddingAndMarginOffsetX; + LayoutLength childTop = childPosition.y + paddingAndMarginOffsetY; + + childLayout->Layout( childLeft, childTop, childLeft + childWidth, childTop + childHeight ); + } + } +} + +} // namespace Internal +} // namespace Toolkit +} // namespace Dali diff --git a/dali-toolkit/internal/layouting/bin-layout-impl.h b/dali-toolkit/internal/layouting/bin-layout-impl.h new file mode 100644 index 0000000..d20ea64 --- /dev/null +++ b/dali-toolkit/internal/layouting/bin-layout-impl.h @@ -0,0 +1,87 @@ +#ifndef DALI_TOOLKIT_INTERNAL_BIN_LAYOUT_H +#define DALI_TOOLKIT_INTERNAL_BIN_LAYOUT_H + +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Internal +{ + +class BinLayout; +using BinLayoutPtr = IntrusivePtr; + +class BinLayout final : public LayoutGroup +{ +public: + static BinLayoutPtr New(); + +protected: + + /** + * Constructor + */ + BinLayout(); + + /** + * Destructor + */ + virtual ~BinLayout(); + + /** + * @copydoc LayoutItem::OnMeasure + */ + virtual void OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec ) override; + + /** + * @copydoc LayoutItem::OnLayout + */ + virtual void OnLayout( bool changed, LayoutLength l, LayoutLength t, LayoutLength r, LayoutLength b ) override; + +private: + BinLayout( const BinLayout& other ) = delete; + BinLayout& operator=( const BinLayout& other ) = delete; + +}; + +} // namespace Internal + +inline Internal::BinLayout& GetImplementation( Dali::Toolkit::BinLayout& handle ) +{ + DALI_ASSERT_ALWAYS( handle && "BinLayout handle is empty" ); + BaseObject& object = handle.GetBaseObject(); + return static_cast( object ); +} + +inline const Internal::BinLayout& GetImplementation( const Dali::Toolkit::BinLayout& handle ) +{ + DALI_ASSERT_ALWAYS( handle && "BinLayout handle is empty" ); + const BaseObject& object = handle.GetBaseObject(); + return static_cast( object ); +} + +} // namespace Toolkit +} // namespace Dali + +#endif // DALI_TOOLKIT_INTERNAL_BIN_LAYOUT_H diff --git a/dali-toolkit/internal/layouting/layout-controller-impl.cpp b/dali-toolkit/internal/layouting/layout-controller-impl.cpp index f912810..17a75a6 100644 --- a/dali-toolkit/internal/layouting/layout-controller-impl.cpp +++ b/dali-toolkit/internal/layouting/layout-controller-impl.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -42,7 +43,8 @@ namespace Internal { LayoutController::LayoutController() -: mLayoutRequested(false) +: mLayoutRequested( false ), + mSlotDelegate( this ) { } @@ -52,15 +54,33 @@ LayoutController::~LayoutController() void LayoutController::Initialize() { + mAnimation = Animation::New( 0.0f ); } -void LayoutController::RequestLayout( LayoutItem& LayoutItem ) +void LayoutController::RequestLayout( LayoutItem& layoutItem, int layoutTransitionType ) { - DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout\n" ); + auto actor = Actor::DownCast( layoutItem.GetOwner() ); + if ( actor ) + { + DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout owner[%s] layoutItem[%p] layoutAnimationType(%d)\n", actor.GetName().c_str(), &layoutItem, layoutTransitionType ); + } + else + { + DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout layoutItem[%p] layoutAnimationType(%d)\n", &layoutItem, layoutTransitionType ); + } + mLayoutRequested = true; + if( layoutTransitionType != -1 ) + { + LayoutTransition layoutTransition = LayoutTransition( layoutItem, layoutTransitionType ); + if( std::find( mLayoutTransitions.begin(), mLayoutTransitions.end(), layoutTransition ) == mLayoutTransitions.end() && layoutItem.GetTransitionData( layoutTransitionType ).Get() ) + { + mLayoutTransitions.push_back( layoutTransition ); + } + } // Go up the tree and mark all parents to relayout - LayoutParent* layoutParent = LayoutItem.GetParent(); + LayoutParent* layoutParent = layoutItem.GetParent(); if( layoutParent ) { LayoutGroup& layoutGroup = static_cast< LayoutGroup& >( *layoutParent ); @@ -74,11 +94,10 @@ void LayoutController::RequestLayout( LayoutItem& LayoutItem ) void LayoutController::Process() { // Perform the full process. + DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::Process\n" ); if( mLayoutRequested ) { - mLayoutRequested = false; - // If window size has changed, expect stage to have already been updated Stage stage = Stage::GetCurrent(); auto stageWidth = stage.GetSize().width; @@ -91,8 +110,34 @@ void LayoutController::Process() MeasureHierarchy( stage.GetRootLayer(), widthSpec, heightSpec ); LAYOUT_DEBUG_MEASURE_STATES( stage.GetRootLayer() ); + + LayoutTransition layoutTransition; + LayoutPositionDataArray layoutPositionDataArray; + LayoutDataArray layoutDataArray; + LayoutAnimatorArray layoutAnimatorArray; + layoutAnimatorArray.push_back( LayoutDataAnimator() ); + PropertyAnimatorArray childrenPropertiesAnimators; + + if ( mLayoutTransitions.size() ) + { + layoutTransition = mLayoutTransitions.front(); + mLayoutTransitions.pop_front(); + mLayoutRequested = ( mLayoutTransitions.size() != 0 ); + } + else + { + mLayoutRequested = false; + } + + LayoutData layoutData( layoutTransition, layoutPositionDataArray, layoutDataArray, layoutAnimatorArray, childrenPropertiesAnimators ); + LayoutItem::Impl::sLayoutData = &layoutData; PerformLayout( stage.GetRootLayer(), 0, 0, stageWidth, stageHeight ); + PerformLayoutPositioning( layoutPositionDataArray, false ); + + PerformLayoutAnimation( layoutTransition, layoutPositionDataArray, layoutDataArray, layoutAnimatorArray ); + LayoutItem::Impl::sLayoutData = nullptr; + LAYOUT_DEBUG_AFTER_LAYOUT( stage.GetRootLayer() ); } } @@ -145,7 +190,6 @@ void LayoutController::PerformLayout( Actor root, int left, int top, int right, if( layout ) { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayout on layout\n" ); layout->Layout( left, top, right, bottom ); } } @@ -161,6 +205,142 @@ void LayoutController::PerformLayout( Actor root, int left, int top, int right, } } +void LayoutController::PerformLayoutPositioning( LayoutPositionDataArray& layoutPositionDataArray, bool all ) const +{ + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayoutPositioning %d\n", (int)all ); + + for( auto layoutPositionData : layoutPositionDataArray ) + { + Actor actor = Actor::DownCast( layoutPositionData.handle ); + if( actor && ( !layoutPositionData.animated || all ) ) + { + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayoutPositioning %s\n", actor.GetName().c_str() ); + actor.SetPosition( layoutPositionData.left, layoutPositionData.top ); + actor.SetSize( layoutPositionData.right - layoutPositionData.left, layoutPositionData.bottom - layoutPositionData.top ); + } + } +} + +void LayoutController::PerformLayoutAnimation( LayoutTransition& layoutTransition, LayoutPositionDataArray& layoutPositionDataArray, LayoutDataArray& layoutDataArray, LayoutAnimatorArray& layoutAnimatorArray ) +{ + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayoutAnimation\n" ); + Animation animation = Animation::New( 0 ); + bool isAnimatorAdded = false; + + for( auto layoutDataElement : layoutDataArray ) + { + if ( layoutDataElement.animatorIndex >= 0 ) + { + Actor actor = Actor::DownCast( layoutDataElement.handle ); + if ( actor ) + { + LayoutDataAnimator animator = layoutAnimatorArray[ layoutDataElement.animatorIndex ]; + TimePeriod timePeriod = TimePeriod( 0, animation.GetDuration() ); + if (animator.timePeriod.durationSeconds >= 0) + { + timePeriod = animator.timePeriod; + } + + Property::Value value = layoutDataElement.targetValue; + // Capture calculated position and size values after layout if target values are not set. + // Other values are set to current actor ones. + if( value.GetType() == Property::NONE ) + { + if ( layoutDataElement.positionDataIndex < 0) + { + auto result = std::find_if( layoutPositionDataArray.begin(), layoutPositionDataArray.end(), [&actor](const LayoutPositionData& iter) + { return iter.handle == actor; } ); + if( result == layoutPositionDataArray.end() ) + { + continue; + } + layoutDataElement.positionDataIndex = std::distance(layoutPositionDataArray.begin(), result); + } + + LayoutPositionData& positionData = layoutPositionDataArray[ layoutDataElement.positionDataIndex ]; + + switch ( layoutDataElement.propertyIndex ) + { + case Actor::Property::POSITION: + value = Vector3( positionData.left, positionData.top, 0.0f ); + break; + case Actor::Property::POSITION_X: + value = positionData.left; + break; + case Actor::Property::POSITION_Y: + value = positionData.top; + break; + case Actor::Property::SIZE: + value = Vector3( positionData.right - positionData.left, positionData.bottom - positionData.top, 0.0f ); + break; + case Actor::Property::SIZE_WIDTH: + value = positionData.right - positionData.left; + break; + case Actor::Property::SIZE_HEIGHT: + value = positionData.bottom - positionData.top; + break; + default: + value = actor.GetProperty( layoutDataElement.propertyIndex ); + } + } + + // Failed to get target value, just move the next one + if( value.GetType() == Property::NONE ) + { + continue; + } + + // Set initial value + Property::Value initialValue = layoutDataElement.initialValue; + if( initialValue.GetType() != Property::NONE ) + { + actor.SetProperty( layoutDataElement.propertyIndex, initialValue ); + } + + // Create an animator for the property + switch (animator.animatorType) + { + case LayoutDataAnimator::AnimatorType::ANIMATE_TO: + { + animation.AnimateTo( Property( actor, layoutDataElement.propertyIndex ), value, animator.alphaFunction, timePeriod ); + break; + } + case LayoutDataAnimator::AnimatorType::ANIMATE_BY: + { + animation.AnimateBy( Property( actor, layoutDataElement.propertyIndex ), value, animator.alphaFunction, timePeriod ); + break; + } + case LayoutDataAnimator::AnimatorType::ANIMATE_BETWEEN: + { + animation.AnimateBetween( Property( actor, layoutDataElement.propertyIndex ), animator.keyFrames, animator.alphaFunction, animator.interpolation ); + break; + } + case LayoutDataAnimator::AnimatorType::ANIMATE_PATH: + animation.Animate( actor, animator.path, animator.forward, animator.alphaFunction, timePeriod ); + break; + } + } + isAnimatorAdded = true; + } + } + + if( isAnimatorAdded ) + { + if( mAnimation.GetState() == Animation::PLAYING ) + { + mAnimation.Clear(); + if( mAnimationFinishedFunctors.size() != 0 ) + { + mAnimationFinishedFunctors.front()( mAnimation ); + } + } + + mAnimation = animation; + mAnimationFinishedFunctors.push_back( AnimationFinishedFunctor( *this, layoutTransition, layoutPositionDataArray ) ); + mAnimation.FinishedSignal().Connect( mSlotDelegate.GetConnectionTracker(), mAnimationFinishedFunctors.back() ); + mAnimation.Play(); + } +} } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/layouting/layout-controller-impl.h b/dali-toolkit/internal/layouting/layout-controller-impl.h index 08db259..1c3130d 100644 --- a/dali-toolkit/internal/layouting/layout-controller-impl.h +++ b/dali-toolkit/internal/layouting/layout-controller-impl.h @@ -16,13 +16,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#include #include #include #include #include #include #include +#include namespace Dali { @@ -54,9 +55,9 @@ public: void Initialize(); /** - * This marks the given layout and all its parents as dirty. + * This marks the given layout and all its parents as dirty and triggers a transition if set. */ - void RequestLayout( LayoutItem& layout ); + void RequestLayout( LayoutItem& layout, int layoutTransitionType ); /** * Measures next level of layouts in the actor hierarchy. @@ -68,6 +69,16 @@ public: */ void PerformLayout( Actor root, int left, int top, int right, int bottom ); + /** + * Perform positioning of actors after layout update + */ + void PerformLayoutPositioning( LayoutPositionDataArray& layoutPositionDataArray, bool all ) const; + + /** + * Perform animation of actors properties after layout update + */ + void PerformLayoutAnimation( LayoutTransition& layoutTransition, LayoutPositionDataArray& layoutPositionDataArray, LayoutDataArray& layoutDataArray, LayoutAnimatorArray& layoutAnimatorArray ); + protected: // Implementation of Processor /** @@ -76,7 +87,40 @@ protected: // Implementation of Processor virtual void Process(); private: + std::list< LayoutTransition > mLayoutTransitions; + struct AnimationFinishedFunctor + { + AnimationFinishedFunctor( LayoutController& layoutController, LayoutTransition& layoutTransition, LayoutPositionDataArray& array ) + : layoutController( layoutController ), + layoutDataPositionArray(), + layoutItem( layoutTransition.layoutItem ), + layoutTransitionType( layoutTransition.layoutTransitionType ) + { + layoutDataPositionArray.swap( array ); + } + + void operator()( Animation& animation ) + { + layoutController.PerformLayoutPositioning( layoutDataPositionArray, true ); + layoutController.mAnimationFinishedFunctors.pop_front(); + if (layoutTransitionType != -1) + { + LayoutTransitionDataPtr layoutTransitionDataPtr = layoutItem->GetTransitionData( layoutTransitionType ); + layoutTransitionDataPtr->EmitSignalFinish( layoutTransitionType ); + } + } + + LayoutController& layoutController; + LayoutPositionDataArray layoutDataPositionArray; + LayoutItemPtr layoutItem; + int layoutTransitionType; + }; + bool mLayoutRequested; + Animation mAnimation; + std::list< AnimationFinishedFunctor > mAnimationFinishedFunctors; + + SlotDelegate mSlotDelegate; }; } // namespace Internal diff --git a/dali-toolkit/internal/layouting/layout-item-data-impl.cpp b/dali-toolkit/internal/layouting/layout-item-data-impl.cpp index 0833b3b..c97a8df 100644 --- a/dali-toolkit/internal/layouting/layout-item-data-impl.cpp +++ b/dali-toolkit/internal/layouting/layout-item-data-impl.cpp @@ -24,8 +24,10 @@ namespace Toolkit namespace Internal { -bool LayoutItem::Impl::sUseZeroUnspecifiedMeasureSpec = false; +class LayoutData; +bool LayoutItem::Impl::sUseZeroUnspecifiedMeasureSpec = false; +LayoutData* LayoutItem::Impl::sLayoutData = nullptr; LayoutItem::Impl::Impl() : mOwner( nullptr ), diff --git a/dali-toolkit/internal/layouting/layout-item-data-impl.h b/dali-toolkit/internal/layouting/layout-item-data-impl.h index 2347d28..0e68977 100644 --- a/dali-toolkit/internal/layouting/layout-item-data-impl.h +++ b/dali-toolkit/internal/layouting/layout-item-data-impl.h @@ -20,6 +20,7 @@ #include #include #include +#include namespace Dali { @@ -27,8 +28,6 @@ namespace Toolkit { namespace Internal { -class LayoutParent; - class LayoutItem::Impl { @@ -81,6 +80,13 @@ public: static bool sUseZeroUnspecifiedMeasureSpec; + LayoutTransitionDataPtr mOnChildAddTransitionData; + LayoutTransitionDataPtr mOnChildRemoveTransitionData; + LayoutTransitionDataPtr mOnOwnerSetTransitionData; + LayoutTransitionDataPtr mDefaultTransitionData; + + // To pass layout data during perform layout + static LayoutData* sLayoutData; }; } // namespace Internal diff --git a/dali-toolkit/internal/layouting/layout-transition-data-impl.cpp b/dali-toolkit/internal/layouting/layout-transition-data-impl.cpp new file mode 100644 index 0000000..f43ee79 --- /dev/null +++ b/dali-toolkit/internal/layouting/layout-transition-data-impl.cpp @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace +{ +// Key tokens +const char* TOKEN_PROPERTY("property"); +const char* TOKEN_INITIAL_VALUE("initialValue"); +const char* TOKEN_TARGET_VALUE("targetValue"); +const char* TOKEN_ANIMATOR("animator"); +const char* TOKEN_TYPE("type"); +const char* TOKEN_NAME("name"); +const char* TOKEN_TIME_PERIOD("timePeriod"); +const char* TOKEN_DURATION("duration"); +const char* TOKEN_DELAY("delay"); +const char* TOKEN_ALPHA_FUNCTION("alphaFunction"); + +DALI_ENUM_TO_STRING_TABLE_BEGIN( ALPHA_FUNCTION_BUILTIN ) +DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, LINEAR) +DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, REVERSE) +DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN) +DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_OUT) +DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN_OUT) +DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN_SQUARE) +DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_OUT_SQUARE) +DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN_SINE) +DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_OUT_SINE) +DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN_OUT_SINE) +DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_OUT_BACK) +DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, BOUNCE) +DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, SIN) +DALI_ENUM_TO_STRING_TABLE_END( ALPHA_FUNCTION_BUILTIN ) + +} + +namespace Dali +{ +namespace Toolkit +{ +namespace Internal +{ + +LayoutTransitionData::LayoutTransitionData() +{ +} + +LayoutTransitionData::~LayoutTransitionData() +{ +} + +LayoutTransitionDataPtr LayoutTransitionData::New() +{ + LayoutTransitionDataPtr layoutAnimationData( new LayoutTransitionData() ); + return layoutAnimationData; +} + +LayoutTransitionData::PropertyAnimator::PropertyAnimator( ) + : handle( Actor( ) ) + , map() + , interpolation( Animation::Linear ) +{ +} + +LayoutTransitionData::PropertyAnimator::PropertyAnimator( Actor actor, Property::Map map ) + : handle( actor ) + , map( map ) + , interpolation( Animation::Linear ) +{ +} + +LayoutTransitionData::PropertyAnimator::PropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward ) + : handle( actor ) + , map( map ) + , interpolation( Animation::Linear ) + , path( path ) + , forward( forward ) +{ +} + +LayoutTransitionData::PropertyAnimator::PropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation ) + : handle( actor ) + , map( map ) + , keyFrames( keyFrames ) + , interpolation( interpolation ) +{ +} + +void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map ) +{ + mPropertyAnimators.push_back( PropertyAnimator( actor, map ) ); +} + +void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation ) +{ + mPropertyAnimators.push_back( PropertyAnimator( actor, map, keyFrames, interpolation ) ); +} + +void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward ) +{ + mPropertyAnimators.push_back( PropertyAnimator( actor, map, path, forward ) ); +} + +bool LayoutTransitionData::ConvertToLayoutAnimator( const Property::Map& animatorMap, const PropertyAnimator& propertyAnimator, LayoutDataAnimator& layoutDataAnimator ) +{ + bool valid = true; + + for ( size_t animatorMapIdx = 0; animatorMapIdx < animatorMap.Count(); ++animatorMapIdx ) + { + const KeyValuePair pair( animatorMap.GetKeyValue( animatorMapIdx ) ); + + Property::Index indexKey = Property::INVALID_INDEX; + if ( pair.first.type == Property::Key::STRING ) + { + const std::string& key(pair.first.stringKey); + if( key == TOKEN_TYPE ) + { + indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::TYPE; + } + else if( key == TOKEN_NAME ) + { + indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::NAME; + } + else if( key == TOKEN_TIME_PERIOD ) + { + indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::TIME_PERIOD; + } + else if( key == TOKEN_ALPHA_FUNCTION ) + { + indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION; + } + } + else + { + indexKey = pair.first.indexKey; + } + + const Property::Value& value( pair.second ); + + if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION ) + { + if ( value.GetType() == Property::ARRAY ) + { + valid = true; + Vector4 controlPoints; + Property::Array *array = value.GetArray(); + if ( array && array->Count() >= 4 ) + { + for ( size_t vecIdx = 0; vecIdx < 4; ++vecIdx ) + { + Property::Value& v = array->GetElementAt( vecIdx ); + if ( v.GetType() == Property::FLOAT ) + { + controlPoints[vecIdx] = v.Get(); + } + else + { + valid = false; + break; + } + } + } + else + { + valid = false; + } + + if ( valid ) + { + Vector2 controlPoint1( controlPoints.x, controlPoints.y ); + Vector2 controlPoint2( controlPoints.z, controlPoints.w ); + layoutDataAnimator.alphaFunction = AlphaFunction( controlPoint1, controlPoint2 ); + } + else + { + valid = false; + } + } + else if ( value.GetType() == Property::VECTOR4 ) + { + Vector4 controlPoints = value.Get(); + Vector2 controlPoint1( controlPoints.x, controlPoints.y ); + Vector2 controlPoint2( controlPoints.z, controlPoints.w ); + layoutDataAnimator.alphaFunction = AlphaFunction( controlPoint1, controlPoint2 ); + } + else if ( value.GetType() == Property::STRING ) + { + std::string alphaFunctionValue = value.Get(); + + if ( alphaFunctionValue == "LINEAR" ) + { + layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::LINEAR ); + } + else if ( !alphaFunctionValue.compare( 0, 5, "EASE_" ) ) + { + if ( alphaFunctionValue == "EASE_IN" ) + { + layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN ); + } + else if ( alphaFunctionValue == "EASE_OUT" ) + { + layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT ); + } + else if ( !alphaFunctionValue.compare( 5, 3, "IN_" ) ) + { + if ( !alphaFunctionValue.compare( 8, -1, "SQUARE" ) ) + { + layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_SQUARE ); + } + else if ( !alphaFunctionValue.compare( 8, -1, "OUT" ) ) + { + layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_OUT ); + } + else if ( !alphaFunctionValue.compare( 8, -1, "OUT_SINE" ) ) + { + layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_OUT_SINE ); + } + else if ( !alphaFunctionValue.compare( 8, -1, "SINE" ) ) + { + layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_SINE ); + } + } + else if ( !alphaFunctionValue.compare( 5, 4, "OUT_" ) ) + { + if ( !alphaFunctionValue.compare( 9, -1, "SQUARE" ) ) + { + layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT_SQUARE ); + } + else if ( !alphaFunctionValue.compare( 9, -1, "SINE" ) ) + { + layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT_SINE ); + } + else if ( !alphaFunctionValue.compare( 9, -1, "BACK" ) ) + { + layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT_BACK ); + } + } + } + else if ( alphaFunctionValue == "REVERSE" ) + { + layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::REVERSE ); + } + else if ( alphaFunctionValue == "BOUNCE" ) + { + layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::BOUNCE ); + } + else if ( alphaFunctionValue == "SIN" ) + { + layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::SIN ); + } + else + { + valid = false; + } + } + else + { + valid = false; + } + } + else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::NAME ) + { + if( value.GetType() == Property::STRING ) + { + layoutDataAnimator.name = value.Get(); + } + } + else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::TYPE ) + { + if( value.GetType() == Property::STRING ) + { + std::string animatorType = value.Get(); + if( animatorType == "ANIMATE_TO" ) + { + layoutDataAnimator.animatorType = LayoutDataAnimator::AnimatorType::ANIMATE_TO; + } + else if( animatorType == "ANIMATE_BY" ) + { + layoutDataAnimator.animatorType = LayoutDataAnimator::AnimatorType::ANIMATE_BY; + } + else if( animatorType == "ANIMATE_BETWEEN" ) + { + layoutDataAnimator.animatorType = LayoutDataAnimator::AnimatorType::ANIMATE_BETWEEN; + layoutDataAnimator.keyFrames = propertyAnimator.keyFrames; + } + else if( animatorType == "ANIMATE_PATH" ) + { + layoutDataAnimator.animatorType = LayoutDataAnimator::AnimatorType::ANIMATE_PATH; + layoutDataAnimator.path = propertyAnimator.path; + layoutDataAnimator.forward = propertyAnimator.forward; + } + } + } + else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::TIME_PERIOD ) + { + Property::Map timeMap = value.Get(); + for ( size_t timeMapIdx = 0; timeMapIdx < timeMap.Count(); ++timeMapIdx ) + { + const KeyValuePair pair( timeMap.GetKeyValue( timeMapIdx ) ); + indexKey = Property::INVALID_INDEX; + + if ( pair.first.type == Property::Key::STRING) + { + const std::string& key( pair.first.stringKey ); + if( key == TOKEN_DURATION ) + { + indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::DURATION; + } + else if( key == TOKEN_DELAY ) + { + indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::DELAY; + } + } + else + { + indexKey = pair.first.indexKey; + } + + if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::DELAY ) + { + layoutDataAnimator.timePeriod.delaySeconds = pair.second.Get(); + } + else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::DURATION ) + { + layoutDataAnimator.timePeriod.durationSeconds = pair.second.Get(); + } + } + } + } + + return valid; +} + +bool LayoutTransitionData::ConvertToLayoutDataElement( const PropertyAnimator& propertyAnimator, LayoutDataElement& layoutDataElement, LayoutData& layoutData ) +{ + const Property::Map& map = propertyAnimator.map; + bool propertyFound = false; + + for( unsigned int mapIdx = 0; mapIdx < map.Count(); ++mapIdx ) + { + const KeyValuePair pair( map.GetKeyValue( mapIdx ) ); + const Property::Value& value( pair.second ); + Property::Index indexKey = Property::INVALID_INDEX; + + if ( pair.first.type == Property::Key::STRING ) + { + const std::string& key( pair.first.stringKey ); + if ( key == TOKEN_PROPERTY ) + { + indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY; + } + else if( key == TOKEN_INITIAL_VALUE ) + { + indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::INITIAL_VALUE; + } + else if( key == TOKEN_TARGET_VALUE ) + { + indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE; + } + else if( key == TOKEN_ANIMATOR ) + { + indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR; + } + } + else + { + indexKey = pair.first.indexKey; + } + + if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY ) + { + if( value.GetType() == Property::STRING ) + { + Actor actor = Actor::DownCast( layoutDataElement.handle ); + layoutDataElement.propertyIndex = DevelHandle::GetPropertyIndex( actor, Property::Key( value.Get() ) ); + } + else + { + layoutDataElement.propertyIndex = value.Get(); + } + propertyFound = true; + } + else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::INITIAL_VALUE ) + { + layoutDataElement.initialValue = value; + } + else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE ) + { + layoutDataElement.targetValue = value; + } + else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR ) + { + if( value.GetType() == Property::STRING ) + { + std::string animatorName = value.Get(); + if ( animatorName.empty() ) + { + layoutDataElement.animatorIndex = 0; + } + else + { + auto animator = std::find_if( layoutData.layoutAnimatorArray.begin(), layoutData.layoutAnimatorArray.end(), [&animatorName](const LayoutDataAnimator& iter) { + return (iter.name == animatorName); } ); + if( animator != layoutData.layoutAnimatorArray.end() ) + { + layoutDataElement.animatorIndex = std::distance( layoutData.layoutAnimatorArray.begin(), animator ); + } + } + } + else if ( value.GetType() == Property::MAP ) + { + Property::Map animatorMap = value.Get< Property::Map >(); + LayoutDataAnimator layoutDataAnimator; + if( ConvertToLayoutAnimator( animatorMap, propertyAnimator, layoutDataAnimator ) ) + { + layoutData.layoutAnimatorArray.push_back( layoutDataAnimator ); + layoutDataElement.animatorIndex = layoutData.layoutAnimatorArray.size()-1; + } + } + } + } + + return propertyFound; +} + +void LayoutTransitionData::ConvertToLayoutDataElements( Actor owner, LayoutData& layoutData ) +{ + LayoutDataArray& layoutDataArray = layoutData.layoutDataArray; + // Add the children animators + for( const PropertyAnimator& iter : layoutData.childrenPropertyAnimators ) + { + LayoutDataElement layoutDataElement; + layoutDataElement.handle = owner; + layoutDataElement.positionDataIndex = layoutData.layoutPositionDataArray.size() - 1; + + if( ConvertToLayoutDataElement( iter, layoutDataElement, layoutData ) ) + { + layoutDataArray.push_back( layoutDataElement ); + } + } + + // Add the transition animators + for( const PropertyAnimator& iter : mPropertyAnimators ) + { + if( iter.handle == nullptr ) + { + layoutData.childrenPropertyAnimators.push_back( iter ); + continue; + } + + LayoutDataElement layoutDataElement; + layoutDataElement.handle = iter.handle; + if( ConvertToLayoutDataElement( iter, layoutDataElement, layoutData ) ) + { + layoutDataArray.push_back( layoutDataElement ); + } + } +} + +Dali::Toolkit::LayoutTransitionData::LayoutTransitionSignalType& LayoutTransitionData::FinishedSignal() +{ + return mFinishedSignal; +} + +void LayoutTransitionData::EmitSignalFinish( int layoutTransitionType ) +{ + if ( !mFinishedSignal.Empty() ) + { + Dali::Toolkit::LayoutTransitionData handle( this ); + mFinishedSignal.Emit( static_cast(layoutTransitionType), handle ); + } +} + +} // namespace Internal +} // namespace Toolkit +} // namespace Dali diff --git a/dali-toolkit/internal/layouting/layout-transition-data-impl.h b/dali-toolkit/internal/layouting/layout-transition-data-impl.h new file mode 100644 index 0000000..eb9e9d9 --- /dev/null +++ b/dali-toolkit/internal/layouting/layout-transition-data-impl.h @@ -0,0 +1,246 @@ +#ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_TRANSITION_DATA_IMPL_H +#define DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_TRANSITION_DATA_IMPL_H +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Internal +{ + +struct LayoutTransition +{ + LayoutTransition( LayoutItem& layoutItem, int layoutTransitionType ) + : layoutItem( &layoutItem ) + , layoutTransitionType( layoutTransitionType ) + { + } + + LayoutTransition() + : layoutTransitionType( -1 ) + { + } + + bool operator==( const LayoutTransition& rhs ) + { + return ( ( layoutItem.Get() == rhs.layoutItem.Get() ) && layoutTransitionType == rhs.layoutTransitionType ); + } + + LayoutItemPtr layoutItem; + int layoutTransitionType; +}; + +const float DEFAULT_TRANSITION_DURATION( 0.5f ); + +struct LayoutDataAnimator +{ + enum class AnimatorType + { + ANIMATE_TO, + ANIMATE_BY, + ANIMATE_BETWEEN, + ANIMATE_PATH + }; + + LayoutDataAnimator() + : animatorType( AnimatorType::ANIMATE_TO ), + alphaFunction( AlphaFunction::LINEAR ), + timePeriod( 0.0f, DEFAULT_TRANSITION_DURATION ), + interpolation( Animation::Linear ) + { + } + + std::string name; + AnimatorType animatorType; + AlphaFunction alphaFunction; + TimePeriod timePeriod; + + KeyFrames keyFrames; + Animation::Interpolation interpolation; + + Path path; + Vector3 forward; +}; + +using LayoutAnimatorArray = std::vector< LayoutDataAnimator >; + +struct LayoutPositionData +{ + LayoutPositionData( Handle handle, float left, float top, float right, float bottom, bool animated ) : + handle( handle ), left( left ), top( top ), right( right ), bottom( bottom ), animated( animated ) + { + }; + + BaseHandle handle; + float left; + float top; + float right; + float bottom; + bool animated; +}; + +using LayoutPositionDataArray = std::vector< LayoutPositionData >; + +struct LayoutDataElement +{ + LayoutDataElement() + : propertyIndex( Property::INVALID_KEY ), animatorIndex( -1 ), positionDataIndex(-1 ) + { + }; + + LayoutDataElement( Actor actor, Property::Index propertyIndex, Property::Value value ) + : handle( actor ), + propertyIndex( propertyIndex ), + targetValue( value ), + animatorIndex( -1 ), + positionDataIndex( -1 ) + { + }; + + BaseHandle handle; + Property::Index propertyIndex; + Property::Value initialValue; + Property::Value targetValue; + int animatorIndex; + int positionDataIndex; +}; + +class LayoutTransitionData; +using LayoutTransitionDataPtr = IntrusivePtr; + +/** + * LayoutTransitionData implementation class. + */ +class DALI_TOOLKIT_API LayoutTransitionData : public BaseObject +{ +public: + struct PropertyAnimator + { + PropertyAnimator(); + PropertyAnimator( Actor actor, Property::Map map ); + PropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward ); + PropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation ); + + BaseHandle handle; + + Property::Map map; + + KeyFrames keyFrames; + Animation::Interpolation interpolation; + + Path path; + Vector3 forward; + }; + + using PropertyAnimatorArray = std::vector< PropertyAnimator >; + + static LayoutTransitionDataPtr New(); + + LayoutTransitionData( const LayoutTransitionData& ) = delete; + LayoutTransitionData& operator=( const LayoutTransitionData& ) = delete; + + void AddPropertyAnimator( Actor actor, Property::Map map ); + void AddPropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation ); + void AddPropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward ); + + void ConvertToLayoutDataElements( Actor, LayoutData& layoutData ); + + /** + * @copydoc Dali::Animation::FinishedSignal() + */ + Dali::Toolkit::LayoutTransitionData::LayoutTransitionSignalType& FinishedSignal(); + + void EmitSignalFinish( int layoutTransitionType ); + +private: + bool ConvertToLayoutAnimator( const Property::Map& animatorData, const PropertyAnimator& propertyAnimator, LayoutDataAnimator& layoutAnimator ); + bool ConvertToLayoutDataElement( const PropertyAnimator& propertyAnimator, LayoutDataElement& layoutDataElement, LayoutData& layoutData ); + + PropertyAnimatorArray mPropertyAnimators; + + /** + * Ref counted object - Only allow construction via New(). + */ + LayoutTransitionData(); + +protected: + /** + * A ref counted object may only be deleted by calling Unreference + */ + virtual ~LayoutTransitionData(); + + Dali::Toolkit::LayoutTransitionData::LayoutTransitionSignalType mFinishedSignal; +}; + +using PropertyAnimatorArray = std::vector< LayoutTransitionData::PropertyAnimator >; +using LayoutTransitionDataArray = std::vector< LayoutTransitionDataPtr >; +using LayoutDataArray = std::vector< LayoutDataElement >; + +struct LayoutData +{ + LayoutData( LayoutTransition& layoutTransition, LayoutPositionDataArray& layoutPositionDataArray, LayoutDataArray& layoutDataArray, + LayoutAnimatorArray& layoutAnimatorArray, PropertyAnimatorArray& childrenPropertyAnimators ) + : speculativeLayout( false ), + layoutTransition( layoutTransition ), + layoutPositionDataArray( layoutPositionDataArray ), + layoutDataArray( layoutDataArray), + layoutAnimatorArray( layoutAnimatorArray ), + childrenPropertyAnimators( childrenPropertyAnimators ) + { + }; + + bool speculativeLayout; + LayoutTransition& layoutTransition; + LayoutPositionDataArray& layoutPositionDataArray; + LayoutDataArray& layoutDataArray; + LayoutAnimatorArray& layoutAnimatorArray; + PropertyAnimatorArray& childrenPropertyAnimators; +}; + +} //namespace Internal + +inline Internal::LayoutTransitionData& GetImplementation( Dali::Toolkit::LayoutTransitionData& handle ) +{ + DALI_ASSERT_ALWAYS( handle && "LayoutTransitionData handle is empty" ); + BaseObject& object = handle.GetBaseObject(); + return static_cast< Internal::LayoutTransitionData& >( object ); +} + +inline const Internal::LayoutTransitionData& GetImplementation( const Dali::Toolkit::LayoutTransitionData& handle ) +{ + DALI_ASSERT_ALWAYS( handle && "LayoutTransitionData handle is empty" ); + const BaseObject& object = handle.GetBaseObject(); + return static_cast< const Internal::LayoutTransitionData& >( object ); +} + +} //namespace Toolkit +} //namespace Dali + +#endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_TRANSITION_DATA_IMPL_H diff --git a/dali-toolkit/internal/layouting/size-negotiation-mapper.cpp b/dali-toolkit/internal/layouting/size-negotiation-mapper.cpp index a0f052a..2a1c7a3 100644 --- a/dali-toolkit/internal/layouting/size-negotiation-mapper.cpp +++ b/dali-toolkit/internal/layouting/size-negotiation-mapper.cpp @@ -150,17 +150,13 @@ void SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( Toolkit::Contr // matchedLayoutParamHeight should not be used. if( matchFound ) { - if( dimension == Dimension::WIDTH ) + if( dimension & Dimension::WIDTH ) { SetWidthLayoutParams( control, matchedLayoutParamWidth ); } - else if( dimension == Dimension::HEIGHT ) - { - SetHeightLayoutParams( control, matchedLayoutParamHeight ); - } - else if( Dimension::ALL_DIMENSIONS ) + + if( dimension & Dimension::HEIGHT ) { - SetWidthLayoutParams( control, matchedLayoutParamWidth ); SetHeightLayoutParams( control, matchedLayoutParamHeight ); } } diff --git a/dali-toolkit/internal/layouting/size-negotiation-mapper.h b/dali-toolkit/internal/layouting/size-negotiation-mapper.h index d89996c..082da33 100644 --- a/dali-toolkit/internal/layouting/size-negotiation-mapper.h +++ b/dali-toolkit/internal/layouting/size-negotiation-mapper.h @@ -40,17 +40,19 @@ namespace SizeNegotiationMapper * @param[out] control the control to set the layout params on * @param[out] layout the layout for the given control * @param[in] dimension the dimension or dimensions the resize policy applies to. + * @note If Dimension::ALL_DIMENSIONS is provided as the dimension parameter then Dimension::WIDTH is used for + * both height and width mapping. */ void SetLayoutParametersUsingResizePolicy( Toolkit::Control control, Toolkit::Internal::LayoutItemPtr layout, const Dimension::Type dimension ); /** * @brief Sets the child layout parameters on the control using the a ResizePolicy that is dependant on it's parent - * @note This method should be used after a child has been parented and a parent measure spec is available. * @param[out] control the control to set the layout params on * @param[in] parentWidthSpecification the parent's width measure specification * @param[in] parentHeightSpecification the parent's height measure specification * @param[out] childWidth the resulting child width * @param[out] childHeight the resulting child height + * @note This method should be used after a child has been parented and a parent measure spec is available. */ void GetSizeofChildForParentDependentResizePolicy( Toolkit::Control control, const MeasureSpec parentWidthSpecification, const MeasureSpec parentHeightSpecification, LayoutLength& childWidth, LayoutLength& childHeight ); diff --git a/dali-toolkit/internal/text/multi-language-support-impl.cpp b/dali-toolkit/internal/text/multi-language-support-impl.cpp old mode 100644 new mode 100755 index 6ca96ad..4b6eee2 --- a/dali-toolkit/internal/text/multi-language-support-impl.cpp +++ b/dali-toolkit/internal/text/multi-language-support-impl.cpp @@ -436,8 +436,6 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, Vector::ConstIterator scriptRunEndIt = scripts.End(); bool isNewParagraphCharacter = false; - FontId currentFontId = 0u; - FontId previousFontId = 0u; bool isPreviousEmojiScript = false; // Description of fallback font which is selected at current iteration. @@ -465,7 +463,6 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, // Get the font for the current character. FontId fontId = fontClient.GetFontId( currentFontDescription, currentFontPointSize ); - currentFontId = fontId; // Get the script for the current character. Script script = GetScript( index, @@ -553,133 +550,107 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, // supports the 'white space'. However, that font may not support the DEVANAGARI script. isCommonScript = TextAbstraction::IsCommonScript( character ); - if( isCommonScript ) + // Check in the valid fonts cache. + ValidateFontsPerScript* validateFontsPerScript = *( validFontsPerScriptCacheBuffer + script ); + + if( NULL != validateFontsPerScript ) { - if( isValidCachedDefaultFont && - ( isDefaultFont || ( currentFontId == previousFontId ) ) && - !isEmojiScript ) + // This cache stores valid fonts set by the user. + isValidFont = validateFontsPerScript->IsValidFont( fontId ); + + // It may happen that a validated font for a script doesn't have all the glyphs for that script. + // i.e a font validated for the CJK script may contain glyphs for the chinese language but not for the Japanese. + if( isValidFont ) { - // At this point the character common for all scripts has no font assigned. - // If there is a valid previously cached default font for it, use that one. - fontId = cachedDefaultFontId; + // Checks if the current character is supported by the font is needed. + isValidFont = fontClient.IsCharacterSupportedByFont( fontId, character ); } } - else + + if( !isValidFont ) // (2) { - // Check in the valid fonts cache. - ValidateFontsPerScript* validateFontsPerScript = *( validFontsPerScriptCacheBuffer + script ); + // The selected font is not stored in any cache. + + // Checks if the current character is supported by the selected font. + isValidFont = fontClient.IsCharacterSupportedByFont( fontId, character ); - if( NULL != validateFontsPerScript ) + // Emojis are present in many monochrome fonts; prefer color by default. + if( isValidFont && + isEmojiScript ) { - // This cache stores valid fonts set by the user. - isValidFont = validateFontsPerScript->IsValidFont( fontId ); + const GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character ); - // It may happen that a validated font for a script doesn't have all the glyphs for that script. - // i.e a font validated for the CJK script may contain glyphs for the chinese language but not for the Japanese. - if( isValidFont ) + // For color emojis, the font is valid if the glyph is a color glyph (the bitmap is RGBA). + isValidFont = fontClient.IsColorGlyph( fontId, glyphIndex ); + } + + // If there is a valid font, cache it. + if( isValidFont && !isCommonScript ) + { + if( NULL == validateFontsPerScript ) { - // Checks if the current character is supported by the font is needed. - isValidFont = fontClient.IsCharacterSupportedByFont( fontId, character ); + validateFontsPerScript = new ValidateFontsPerScript(); + + *( validFontsPerScriptCacheBuffer + script ) = validateFontsPerScript; } + + validateFontsPerScript->mValidFonts.PushBack( fontId ); } - if( !isValidFont ) // (2) + if( !isValidFont && ( fontId != cachedDefaultFontId ) && ( !TextAbstraction::IsNewParagraph( character ) )) // (3) { - // The selected font is not stored in any cache. - - // Checks if the current character is supported by the selected font. - isValidFont = fontClient.IsCharacterSupportedByFont( fontId, character ); + // The selected font by the user or the platform's default font has failed to validate the character. - // Emojis are present in many monochrome fonts; prefer color by default. - if( isValidFont && - isEmojiScript ) + // Checks if the previously discarted cached default font supports the character. + bool isValidCachedFont = false; + if( isValidCachedDefaultFont ) { - const GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character ); - - // For color emojis, the font is valid if the glyph is a color glyph (the bitmap is RGBA). - isValidFont = fontClient.IsColorGlyph( fontId, glyphIndex ); + isValidCachedFont = fontClient.IsCharacterSupportedByFont( cachedDefaultFontId, character ); } - // If there is a valid font, cache it. - if( isValidFont ) + if( isValidCachedFont ) { - if( NULL == validateFontsPerScript ) - { - validateFontsPerScript = new ValidateFontsPerScript(); + // Use the cached default font for the script if there is one. + fontId = cachedDefaultFontId; + } + else + { + // There is no valid cached default font for the script. - *( validFontsPerScriptCacheBuffer + script ) = validateFontsPerScript; - } + DefaultFonts* defaultFontsPerScript = NULL; - validateFontsPerScript->mValidFonts.PushBack( fontId ); - } + // Emojis are present in many monochrome fonts; prefer color by default. + const bool preferColor = ( TextAbstraction::EMOJI == script ); - if( !isValidFont && ( fontId != cachedDefaultFontId ) ) // (3) - { - // The selected font by the user or the platform's default font has failed to validate the character. + // Find a fallback-font. + fontId = fontClient.FindFallbackFont( character, + currentFontDescription, + currentFontPointSize, + preferColor ); - // Checks if the previously discarted cached default font supports the character. - bool isValidCachedFont = false; - if( isValidCachedDefaultFont ) + if( 0u == fontId ) { - isValidCachedFont = fontClient.IsCharacterSupportedByFont( cachedDefaultFontId, character ); + fontId = fontClient.FindDefaultFont( UTF32_A, currentFontPointSize ); } - if( isValidCachedFont ) - { - // Use the cached default font for the script if there is one. - fontId = cachedDefaultFontId; - } - else + if ( !isCommonScript && (script != TextAbstraction::UNKNOWN) ) { - // There is no valid cached default font for the script. - - DefaultFonts* defaultFontsPerScript = NULL; - - // Emojis are present in many monochrome fonts; prefer color by default. - const bool preferColor = ( TextAbstraction::EMOJI == script ); - - // Find a fallback-font. - fontId = fontClient.FindFallbackFont( character, - currentFontDescription, - currentFontPointSize, - preferColor ); - - if( 0u == fontId ) + // Cache the font if it is not an unknown script + if( NULL == defaultFontsPerScript ) { - // If the system does not support a suitable font, fallback to Latin - defaultFontsPerScript = *( defaultFontPerScriptCacheBuffer + TextAbstraction::LATIN ); - if( NULL != defaultFontsPerScript ) - { - fontId = defaultFontsPerScript->FindFont( fontClient, - currentFontDescription, - currentFontPointSize ); - } - } - - if( 0u == fontId ) - { - fontId = fontClient.FindDefaultFont( UTF32_A, currentFontPointSize ); - } + defaultFontsPerScript = *( defaultFontPerScriptCacheBuffer + script ); - if ( script != TextAbstraction::UNKNOWN ) - { - // Cache the font if it is not an unknown script if( NULL == defaultFontsPerScript ) { - defaultFontsPerScript = *( defaultFontPerScriptCacheBuffer + script ); - - if( NULL == defaultFontsPerScript ) - { - defaultFontsPerScript = new DefaultFonts(); - *( defaultFontPerScriptCacheBuffer + script ) = defaultFontsPerScript; - } + defaultFontsPerScript = new DefaultFonts(); + *( defaultFontPerScriptCacheBuffer + script ) = defaultFontsPerScript; } - defaultFontsPerScript->Cache( currentFontDescription, fontId ); } + defaultFontsPerScript->Cache( currentFontDescription, fontId ); } - } // !isValidFont (3) - } // !isValidFont (2) - } // !isCommonScript + } + } // !isValidFont (3) + } // !isValidFont (2) } // !isValidFont (1) #ifdef DEBUG_ENABLED @@ -734,7 +705,6 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, // Whether the current character is a new paragraph character. isNewParagraphCharacter = TextAbstraction::IsNewParagraph( character ); - previousFontId = currentFontId; isPreviousEmojiScript = isEmojiScript; } // end traverse characters. diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.cpp b/dali-toolkit/internal/text/rendering/text-typesetter.cpp index 0e149d7..8018054 100755 --- a/dali-toolkit/internal/text/rendering/text-typesetter.cpp +++ b/dali-toolkit/internal/text/rendering/text-typesetter.cpp @@ -637,7 +637,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth } // Retrieves the glyph's color. - const ColorIndex colorIndex = *( colorIndexBuffer + glyphIndex ); + const ColorIndex colorIndex = useDefaultColor ? 0u : *( colorIndexBuffer + glyphIndex ); Vector4 color; if ( style == Typesetter::STYLE_SHADOW ) diff --git a/dali-toolkit/public-api/controls/control-impl.cpp b/dali-toolkit/public-api/controls/control-impl.cpp index 8f862f5..1804809 100755 --- a/dali-toolkit/public-api/controls/control-impl.cpp +++ b/dali-toolkit/public-api/controls/control-impl.cpp @@ -573,6 +573,9 @@ void Control::OnStageConnection( int depth ) // The clipping renderer is only created if required. CreateClippingRenderer( *this ); + + // Request to be laid out when the control is connected to the Stage. + Toolkit::DevelControl::RequestLayout( *this ); } void Control::OnStageDisconnection() diff --git a/dali-toolkit/public-api/dali-toolkit-version.cpp b/dali-toolkit/public-api/dali-toolkit-version.cpp index 8d8d1a9..932fe48 100644 --- a/dali-toolkit/public-api/dali-toolkit-version.cpp +++ b/dali-toolkit/public-api/dali-toolkit-version.cpp @@ -31,7 +31,7 @@ namespace Toolkit const unsigned int TOOLKIT_MAJOR_VERSION = 1; const unsigned int TOOLKIT_MINOR_VERSION = 3; -const unsigned int TOOLKIT_MICRO_VERSION = 46; +const unsigned int TOOLKIT_MICRO_VERSION = 47; const char * const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/packaging/dali-toolkit.spec b/packaging/dali-toolkit.spec index 32a4005..4c72035 100644 --- a/packaging/dali-toolkit.spec +++ b/packaging/dali-toolkit.spec @@ -1,6 +1,6 @@ Name: dali-toolkit Summary: Dali 3D engine Toolkit -Version: 1.3.46 +Version: 1.3.47 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT