${internal_src_dir}/layouting/layout-group-data-impl.cpp\r
${internal_src_dir}/layouting/layout-controller-impl.cpp\r
${internal_src_dir}/layouting/layout-controller-debug.cpp\r
+ ${internal_src_dir}/layouting/layout-transition-data-impl.cpp\r
${internal_src_dir}/visuals/animated-image/animated-image-visual.cpp\r
${internal_src_dir}/visuals/animated-image/image-cache.cpp\r
${internal_src_dir}/visuals/animated-image/fixed-image-cache.cpp\r
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
--- /dev/null
+/*
+ * 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 <iostream>
+
+#include <stdlib.h>
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/internal/layouting/size-negotiation-mapper.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/devel-api/layouting/linear-layout.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+
+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
Vector<FontDescriptionRun> fontDescriptions11;
fontDescriptions11.PushBack( fontDescription1101 );
+ FontRun fontRun1201 =
+ {
+ {
+ 0u,
+ 6u
+ },
+ 8u
+ };
+ FontRun fontRun1202 =
+ {
+ {
+ 6u,
+ 1u
+ },
+ 9u
+ };
+ FontRun fontRun1203 =
+ {
+ {
+ 7u,
+ 5u
+ },
+ 8u
+ };
+ Vector<FontRun> fontRuns12;
+ fontRuns12.PushBack( fontRun1201 );
+ fontRuns12.PushBack( fontRun1202 );
+ fontRuns12.PushBack( fontRun1203 );
+
+ FontDescriptionRun fontDescription1201 =
+ {
+ {
+ 0u,
+ 6u
+ },
+ const_cast<char*>( "TizenSans" ),
+ 9u,
+ TextAbstraction::FontWeight::NORMAL,
+ TextAbstraction::FontWidth::NORMAL,
+ TextAbstraction::FontSlant::NORMAL,
+ 0u,
+ true,
+ false,
+ false,
+ false,
+ false
+ };
+ FontDescriptionRun fontDescription1202 =
+ {
+ {
+ 6u,
+ 1u
+ },
+ const_cast<char*>( "TizenSans" ),
+ 9u,
+ TextAbstraction::FontWeight::NORMAL,
+ TextAbstraction::FontWidth::NORMAL,
+ TextAbstraction::FontSlant::NORMAL,
+ 0u,
+ true,
+ false,
+ false,
+ false,
+ false
+ };
+ FontDescriptionRun fontDescription1203 =
+ {
+ {
+ 7u,
+ 5u
+ },
+ const_cast<char*>( "TizenSans" ),
+ 9u,
+ TextAbstraction::FontWeight::NORMAL,
+ TextAbstraction::FontWidth::NORMAL,
+ TextAbstraction::FontSlant::NORMAL,
+ 0u,
+ true,
+ false,
+ false,
+ false,
+ false
+ };
+ Vector<FontDescriptionRun> fontDescriptions12;
+ fontDescriptions12.PushBack( fontDescription1201 );
+ fontDescriptions12.PushBack( fontDescription1202 );
+ fontDescriptions12.PushBack( fontDescription1203 );
+
const ValidateFontsData data[] =
{
{
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 )
{
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
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
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
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)
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])) )
{
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])<epsilon);
}
const float* m2 = matrix2.AsFloat();
bool identical = true;
- int i;
+ int32_t i;
for (i=0;i<16;++i)
{
if(m1[i] != m2[i])
const float* m2 = matrix2.AsFloat();
bool equivalent = true;
- for (int i=0;i<16;++i)
+ for (int32_t i=0;i<16;++i)
{
equivalent &= (fabsf(m1[i] - m2[i])<epsilon);
}
}
}
-BufferImage CreateBufferImage(int width, int height, const Vector4& color)
+BufferImage CreateBufferImage(int32_t width, int32_t height, const Vector4& color)
{
BufferImage image = BufferImage::New(width, height, Pixel::RGBA8888);
return CreateBufferImage(4, 4, Color::WHITE);
}
-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 )
{
TestPlatformAbstraction& platform = application.GetPlatform();
platform.SetClosestImageSize(Vector2( imageWidth, imageHeight));
Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_RETAIN );
Integration::PixelBuffer* pixbuffer = bitmap->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);
#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)
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.
// 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
/*
- * 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.
{
-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!
mCore->ProcessEvents();
}
-void TestApplication::SetSurfaceWidth( unsigned int width, unsigned height )
+void TestApplication::SetSurfaceWidth( uint32_t width, uint32_t height )
{
mSurfaceWidth = width;
mSurfaceHeight = 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 &&
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<float>( intervalMilliseconds ) * 0.001f;
mCore->Update( elapsedSeconds, mLastVSyncTime, nextVSyncTime, mStatus, false, false );
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 );
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();
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);
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();
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;
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;
};
*/
TraceCallStack& TestGlSyncAbstraction::GetTrace() { return mTrace; }
-int TestGlSyncAbstraction::GetNumberOfSyncObjects()
+int32_t TestGlSyncAbstraction::GetNumberOfSyncObjects()
{
- return mSyncObjects.size();
+ return static_cast<int32_t>( mSyncObjects.size() );
}
*
* @return the number of sync objects
*/
- int GetNumberOfSyncObjects();
+ int32_t GetNumberOfSyncObjects();
private:
namespace TestHarness
{
-typedef std::map<int, TestCase> RunningTestCases;
+typedef std::map<int32_t, TestCase> RunningTestCases;
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
}
-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 )
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 )
{
}
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");
}
else if(WIFSIGNALED(status) )
{
- int signal = WTERMSIG(status);
+ int32_t signal = WTERMSIG(status);
testResult = EXIT_STATUS_TESTCASE_ABORTED;
if( signal == SIGABRT )
{
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 )
}
}
-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++;
}
// 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<int> failedTestCases;
+ std::vector<int32_t> 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);
// 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");
{
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);
if( reRunFailed )
{
- for( unsigned int i=0; i<failedTestCases.size(); i++)
+ for( uint32_t i=0; i<failedTestCases.size(); i++)
{
char* testCaseStrapline;
- int numChars = asprintf(&testCaseStrapline, "Test case %s", tc_array[failedTestCases[i]].name );
+ int32_t numChars = asprintf(&testCaseStrapline, "Test case %s", tc_array[failedTestCases[i]].name );
printf("\n%s\n", testCaseStrapline);
- for(int j=0; j<numChars; j++)
+ for(int32_t j=0; j<numChars; j++)
{
printf("=");
}
-int FindAndRunTestCase(::testcase tc_array[], const char* testCaseName)
+int32_t FindAndRunTestCase(::testcase tc_array[], const char* testCaseName)
{
- int result = EXIT_STATUS_TESTCASE_NOT_FOUND;
+ int32_t result = EXIT_STATUS_TESTCASE_NOT_FOUND;
- for( int i = 0; tc_array[i].name; i++ )
+ for( int32_t i = 0; tc_array[i].name; i++ )
{
if( !strcmp(testCaseName, tc_array[i].name) )
{
#define TEST_HARNESS_H
/*
- * Copyright (c) 2014 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.
#include <stdio.h>
#include <testcase.h>
+#include <cstdint>
namespace TestHarness
{
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()
{
}
- TestCase(int tc, const char* name)
+ TestCase(int32_t tc, const char* name)
: testCase(tc),
testCaseName(name)
{
* 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
* @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
* @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
* @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
/*
- * 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.
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();
}
-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)
{
}
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;
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;
};
SamplingMode::Type samplingMode,
bool orientationCorrection )
{
- ImageDimensions closestSize = ImageDimensions( mClosestSize.x, mClosestSize.y );
+ ImageDimensions closestSize = ImageDimensions( mClosestSize );
mTrace.PushCall("GetClosestImageSize", "");
return closestSize;
}
SamplingMode::Type samplingMode,
bool orientationCorrection )
{
- ImageDimensions closestSize = ImageDimensions( mClosestSize.x, mClosestSize.y );
+ ImageDimensions closestSize = ImageDimensions( mClosestSize );
mTrace.PushCall("GetClosestImageSize", "");
return closestSize;
}
mDecodedBitmap.Reset();
}
-void TestPlatformAbstraction::SetClosestImageSize(const Vector2& size)
+void TestPlatformAbstraction::SetClosestImageSize( const Vector2& size )
{
- mClosestSize = size;
+ mClosestSize = ImageDimensions( static_cast<uint32_t>( size.x ), static_cast<uint32_t>( size.y ) );
}
void TestPlatformAbstraction::SetLoadFileResult( bool result, Dali::Vector< unsigned char >& buffer )
* @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.
mutable TraceCallStack mTrace;
bool mIsLoadingResult;
- Vector2 mClosestSize;
+ ImageDimensions mClosestSize;
LoadFileResult mLoadFileResult;
bool mSaveFileResult;
* @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<int32_t>( i );
break;
}
}
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) )
}
if( match == true )
{
- index = i;
+ index = static_cast<int32_t>( i );
break;
}
}
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;
class DisplayConnection;
class ThreadSynchronizationInterface;
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+class GraphicsInterface;
+
+} // namespace Adaptor
+
+} // namespace Internal
+
namespace Integration
{
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 ) {}
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() {}
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 );
--- /dev/null
+/*
+ * 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 <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <toolkit-event-thread-callback.h>
+
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/layouting/absolute-layout.h>
+#include <dali-toolkit/devel-api/layouting/bin-layout.h>
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+#include <dali-toolkit/devel-api/layouting/linear-layout.h>
+
+#include <../custom-layout.h>
+
+#include <layout-utils.h>
+
+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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( 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<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( 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<Vector3>( 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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( 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<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( 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<Vector3>( 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<Vector3>( Actor::Property::POSITION ), Vector3( 50.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 50.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( 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<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( 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<Vector3>( 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<Vector3>( 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<Vector3>( 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<Vector3>( Actor::Property::SIZE ), hbox.GetProperty<Vector3>( 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<Vector3>( 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<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( 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<Vector3>( Actor::Property::SIZE ), hbox.GetProperty<Vector3>( 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<Vector3>( Actor::Property::SIZE ), Vector3( 380.0f, 810.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ END_TEST;
+}
\ No newline at end of file
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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
- DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 40.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
-
- DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
- DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
-
- END_TEST;
-}
-
int UtcDaliLayouting_LayoutChildren01(void)
{
ToolkitTestApplication application;
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();
END_TEST;
}
-int UtcDaliLayouting_LayoutChildren03(void)
+int UtcDaliLayouting_LayoutChildren02(void)
{
ToolkitTestApplication application;
tet_infoline(" UtcDaliLayouting_LayoutChildren02");
}
-int UtcDaliLayouting_LayoutChildren04(void)
+int UtcDaliLayouting_LayoutChildren03(void)
{
ToolkitTestApplication application;
tet_infoline(" UtcDaliLayouting_LayoutChildren03");
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;
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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( child.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); // Not re-laid out
+ DALI_TEST_EQUALS( child.GetProperty<Vector3>( 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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( child.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); // Stage Size
+ DALI_TEST_EQUALS( child.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 180.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * 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 <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <toolkit-event-thread-callback.h>
+
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/layouting/absolute-layout.h>
+#include <dali-toolkit/devel-api/layouting/grid.h>
+#include <dali-toolkit/devel-api/layouting/linear-layout.h>
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+
+#include <../custom-layout.h>
+
+#include <layout-utils.h>
+
+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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( 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<unsigned int>( 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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 300.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( 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<unsigned int>( 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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( 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<unsigned int>( 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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( 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<unsigned int>( 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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( 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<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( 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<Vector3>( 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<unsigned int>( 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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( 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<unsigned int>( 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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( 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<unsigned int>( 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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( 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<unsigned int>( 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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ finishCheck.CheckSignalReceived();
+
+ END_TEST;
+}
+
--- /dev/null
+/*
+ * 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 <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <toolkit-event-thread-callback.h>
+
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/layouting/absolute-layout.h>
+#include <dali-toolkit/devel-api/layouting/linear-layout.h>
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+#include <dali/devel-api/actors/actor-devel.h>
+
+
+#include <layout-utils.h>
+
+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<Vector3>( 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<Vector3>( Actor::Property::POSITION ), Vector3( 40.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ END_TEST;
+}
\ No newline at end of file
*
* @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 );
*
* @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 );
$(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 \
$(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
--- /dev/null
+/*
+ * 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 <dali-toolkit/devel-api/layouting/bin-layout.h>
+
+//INTERNAL HEADERS
+#include <dali-toolkit/internal/layouting/bin-layout-impl.h>
+
+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
--- /dev/null
+#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 <dali/public-api/common/dali-common.h>
+#include <dali/public-api/object/base-handle.h>
+#include <dali-toolkit/devel-api/layouting/layout-group.h>
+#include <dali-toolkit/devel-api/layouting/layout-size.h>
+#include <dali-toolkit/public-api/toolkit-property-index-ranges.h>
+
+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
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 )
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
// 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 );
}
}
}
+
+ RequestLayout( Dali::Toolkit::LayoutTransitionData::LayoutTransitionType::ON_OWNER_SET );
}
}
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 );
if( childLayout )
{
Remove( *childLayout.Get() );
+ RequestLayout( Dali::Toolkit::LayoutTransitionData::LayoutTransitionType::ON_CHILD_REMOVE );
}
}
}
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.
void ChildAddedToOwner( Actor child );
/**
+ * Implementation of ChildAddedToOwner
+ */
+ void ChildAddedToOwnerImpl( Actor child );
+
+ /**
* Callback when child is removed from owner
*/
void ChildRemovedFromOwner( Actor child );
#include <dali/public-api/animation/animation.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <dali-toolkit/public-api/controls/control.h>
+#include <dali/devel-api/object/handle-devel.h>
#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+#include <dali-toolkit/internal/layouting/layout-transition-data-impl.h>
#include <dali-toolkit/internal/layouting/layout-item-data-impl.h>
+#include <dali/devel-api/scripting/enum-helper.h>
+
namespace
{
const char* WIDTH_SPECIFICATION_NAME( "widthSpecification" );
const char* HEIGHT_SPECIFICATION_NAME( "heightSpecification" );
-const float DEFAULT_TRANSITION_DURATION( 0.5f );
}
namespace Dali
mImpl->mOwner = &(owner.GetBaseObject());
RegisterChildProperties( containerType );
OnInitialize(); // Ensure direct deriving class gets initialized
- RequestLayout();
}
Handle LayoutItem::GetOwner() const
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();
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
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 );
}
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
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;
#include <dali/public-api/common/intrusive-ptr.h>
#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/object/property-map.h>
#include <dali/public-api/object/type-registry.h>
#include <dali/public-api/actors/actor-enumerations.h>
+#include <dali/public-api/animation/animation.h>
#include <dali-toolkit/devel-api/layouting/child-layout-data.h>
#include <dali-toolkit/devel-api/layouting/layout-item.h>
#include <dali-toolkit/devel-api/layouting/layout-child-impl.h>
namespace Internal
{
+struct LayoutData;
+
class LayoutItem;
using LayoutItemPtr = IntrusivePtr<LayoutItem>;
+class LayoutTransitionData;
+using LayoutTransitionDataPtr = IntrusivePtr<LayoutTransitionData>;
/**
* Base class for layouts.
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.
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
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
public:
class Impl; // Class declaration is public so we can add devel API's in the future
-
private:
std::unique_ptr<Impl> mImpl; ///< Implementation class holds all the data
SlotDelegate<LayoutItem> mSlotDelegate;
#include <dali-toolkit/devel-api/layouting/layout-item.h>
#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-transition-data.h>
+#include <dali-toolkit/internal/layouting/layout-transition-data-impl.h>
namespace Dali
{
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
#include <cstdint>
#include <dali-toolkit/public-api/dali-toolkit-common.h>
#include <dali/public-api/actors/actor-enumerations.h>
+#include <dali/public-api/animation/animation.h>
#include <dali/public-api/object/base-handle.h>
#include <dali/public-api/object/property-index-ranges.h>
+#include <dali/public-api/object/property-map.h>
#include <dali-toolkit/devel-api/layouting/child-layout-data.h>
#include <dali-toolkit/devel-api/layouting/measure-spec.h>
+#include <dali-toolkit/devel-api/layouting/layout-transition-data.h>
#include <dali-toolkit/public-api/dali-toolkit-common.h>
namespace Dali
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.
*/
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
/**
--- /dev/null
+/*
+ * 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 <dali-toolkit/devel-api/layouting/layout-transition-data.h>
+#include <dali-toolkit/internal/layouting/layout-transition-data-impl.h>
+
+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<Internal::LayoutTransitionData*>(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
--- /dev/null
+#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 <memory>
+#include <cstdint>
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/actors/actor-enumerations.h>
+#include <dali/public-api/animation/animation.h>
+#include <dali/public-api/object/base-handle.h>
+#include <dali/public-api/object/property-index-ranges.h>
+#include <dali/public-api/object/property-map.h>
+#include <dali-toolkit/public-api/dali-toolkit-common.h>
+
+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
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);
}
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/controls/control-wrapper-impl.h>
+#include <dali-toolkit/devel-api/layouting/bin-layout.h>
#include <dali-toolkit/devel-api/layouting/layout-item.h>
#include <dali-toolkit/internal/styling/style-manager-impl.h>
#include <dali-toolkit/internal/visuals/visual-string-constants.h>
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 )
$(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 \
AbsoluteLayout( const AbsoluteLayout& other ) = delete;
AbsoluteLayout& operator=( const AbsoluteLayout& other ) = delete;
- void ForceUniformHeight( int count, MeasureSpec widthMeasureSpec );
-
};
} // namespace Internal
--- /dev/null
+/*
+ * 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 <dali-toolkit/internal/layouting/bin-layout-impl.h>
+
+//INTERNAL HEADERS
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/common/extents.h>
+#include <dali/public-api/actors/actor.h>
+#include <dali-toolkit/devel-api/layouting/layout-item.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/layouting/size-negotiation-mapper.h>
+
+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:"<<widthMeasureSpec<<", height:"<<heightMeasureSpec );
+
+ auto widthMode = widthMeasureSpec.GetMode();
+ auto heightMode = heightMeasureSpec.GetMode();
+ LayoutLength widthSpecSize = widthMeasureSpec.GetSize();
+ LayoutLength heightSpecSize = heightMeasureSpec.GetSize();
+
+ bool exactWidth ( false );
+ bool exactHeight ( false );
+
+ // Layouting behaviour
+ // EXACT, width and height as provided.
+ // 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.
+
+ LayoutLength layoutWidth( 0 );
+ LayoutLength layoutHeight( 0 );
+
+ // If BinLayout has children then measure children to get max dimensions
+ if ( childCount > 0 )
+ {
+ for( unsigned int i=0; i<childCount; ++i )
+ {
+ auto childLayout = GetChildAt( i );
+ if( childLayout )
+ {
+ auto childControl = Toolkit::Control::DownCast(childLayout->GetOwner());
+
+ // 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<float>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
+ LayoutLength desiredHeight = childControl.GetProperty<float>( 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
--- /dev/null
+#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 <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+#include <dali-toolkit/devel-api/layouting/bin-layout.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+class BinLayout;
+using BinLayoutPtr = IntrusivePtr<BinLayout>;
+
+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<Internal::BinLayout&>( 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<const Internal::BinLayout&>( object );
+}
+
+} // namespace Toolkit
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_BIN_LAYOUT_H
#include <dali/public-api/common/stage.h>
#include <dali/public-api/actors/layer.h>
#include <dali-toolkit/internal/layouting/layout-controller-impl.h>
+#include <dali-toolkit/internal/layouting/layout-item-data-impl.h>
#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
#include <dali-toolkit/public-api/controls/control.h>
#include <dali-toolkit/public-api/controls/control-impl.h>
{
LayoutController::LayoutController()
-: mLayoutRequested(false)
+: mLayoutRequested( false ),
+ mSlotDelegate( this )
{
}
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 );
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;
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() );
}
}
if( layout )
{
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayout on layout\n" );
layout->Layout( left, top, right, bottom );
}
}
}
}
+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
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+#include <list>
#include <dali/public-api/object/base-object.h>
#include <dali/integration-api/core.h>
#include <dali-toolkit/public-api/controls/control.h>
#include <dali-toolkit/devel-api/layouting/layout-controller.h>
#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+#include <dali-toolkit/internal/layouting/layout-transition-data-impl.h>
namespace Dali
{
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.
*/
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
/**
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<LayoutController> mSlotDelegate;
};
} // namespace Internal
namespace Internal
{
-bool LayoutItem::Impl::sUseZeroUnspecifiedMeasureSpec = false;
+class LayoutData;
+bool LayoutItem::Impl::sUseZeroUnspecifiedMeasureSpec = false;
+LayoutData* LayoutItem::Impl::sLayoutData = nullptr;
LayoutItem::Impl::Impl()
: mOwner( nullptr ),
#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
#include <dali-toolkit/devel-api/layouting/layout-controller.h>
#include <dali-toolkit/devel-api/layouting/layout-size.h>
+#include <dali-toolkit/internal/layouting/layout-transition-data-impl.h>
namespace Dali
{
{
namespace Internal
{
-class LayoutParent;
-
class LayoutItem::Impl
{
static bool sUseZeroUnspecifiedMeasureSpec;
+ LayoutTransitionDataPtr mOnChildAddTransitionData;
+ LayoutTransitionDataPtr mOnChildRemoveTransitionData;
+ LayoutTransitionDataPtr mOnOwnerSetTransitionData;
+ LayoutTransitionDataPtr mDefaultTransitionData;
+
+ // To pass layout data during perform layout
+ static LayoutData* sLayoutData;
};
} // namespace Internal
--- /dev/null
+/*
+ * 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 <dali/integration-api/debug.h>
+
+#include <dali/public-api/animation/animation.h>
+#include <dali/public-api/object/base-handle.h>
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali/devel-api/object/handle-devel.h>
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+#include <dali-toolkit/internal/layouting/layout-transition-data-impl.h>
+#include <dali-toolkit/internal/layouting/layout-item-data-impl.h>
+
+#include <dali/devel-api/scripting/enum-helper.h>
+
+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<float>();
+ }
+ 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<Vector4>();
+ 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<std::string>();
+
+ 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<std::string>();
+ }
+ }
+ else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::TYPE )
+ {
+ if( value.GetType() == Property::STRING )
+ {
+ std::string animatorType = value.Get<std::string>();
+ 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<Property::Map>();
+ 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<float>();
+ }
+ else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::DURATION )
+ {
+ layoutDataAnimator.timePeriod.durationSeconds = pair.second.Get<float>();
+ }
+ }
+ }
+ }
+
+ 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<std::string>() ) );
+ }
+ else
+ {
+ layoutDataElement.propertyIndex = value.Get<int>();
+ }
+ 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<std::string>();
+ 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<Dali::Toolkit::LayoutTransitionData::LayoutTransitionType>(layoutTransitionType), handle );
+ }
+}
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
--- /dev/null
+#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 <memory>
+
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/object/property-map.h>
+#include <dali/public-api/object/type-registry.h>
+#include <dali/public-api/actors/actor-enumerations.h>
+#include <dali/public-api/animation/animation.h>
+
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-transition-data.h>
+
+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>;
+
+/**
+ * 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
// 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 );
}
}
* @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 );
Vector<ScriptRun>::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.
// 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,
// 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
// Whether the current character is a new paragraph character.
isNewParagraphCharacter = TextAbstraction::IsNewParagraph( character );
- previousFontId = currentFontId;
isPreviousEmojiScript = isEmojiScript;
} // end traverse characters.
}
// Retrieves the glyph's color.
- const ColorIndex colorIndex = *( colorIndexBuffer + glyphIndex );
+ const ColorIndex colorIndex = useDefaultColor ? 0u : *( colorIndexBuffer + glyphIndex );
Vector4 color;
if ( style == Typesetter::STYLE_SHADOW )
// 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()
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
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