From f66b1b2c5cd1e134deb19df9d3f77c546aa26e86 Mon Sep 17 00:00:00 2001 From: Eunki Hong Date: Mon, 25 Sep 2017 15:41:41 +0900 Subject: [PATCH] [4.0] Animated Gradient Visual in devel-api Animated gradient visual. Can be used for Control's background. At Internal::AnimatedGradientVisual : - Use only one shader codes to draw effects. *NOTE : We change shader string at AnimatedGradientVisual::CreateShader() - When DoSetProperties occured --> Set non-animated properties (for make Renderer) --> Set animated properties (for make Animations) - When DoSetOnStage occured --> Make Renderer --> Make Animations --> Play Animations - When DoSetOffStage occured --> Stop Animations At AnimatedGradientVisual::Property : - 3 non-animated properties. - GRADIENT_TYPE = LINEAR / RADIAL - UNIT_TYPE = OBJECT_BOUNDING_BOX / USER_SPACE (See GradientVisual::units) - SPREAD_TYPE = REFLECT / REPEAT / CLAMP (See GradientVisual::spreadMethod) - 7 animated properties. - START_POSITION ( Vector2 ) - START_COLOR ( Vector4 ) - END_POSITION ( Vector2 ) - END_COLOR ( Vector4 ) - ROTATE_CENTER ( Vector2 ) - ROTATE_AMOUNT ( Float ) - OFFSET ( Float ) - Every animate properties have there each values - START, TARGET, DIRECTION, DURATION, DELAY, REPEAT, REPEAT_DELAY, MOTION_TYPE, and EASING_TYPE. - animated by Dali::Animation::AnimateTo() - Setup properties by Property::Map Change-Id: If85c08d4500d132b6d8de6ed016bf985770c846c Signed-off-by: Eunki Hong --- .../src/dali-toolkit/utc-Dali-Visual.cpp | 1103 ++++++++++++++++++++ dali-toolkit/devel-api/file.list | 8 +- .../animated-gradient-visual-properties-devel.h | 347 ++++++ .../devel-api/visuals/visual-properties-devel.h | 59 ++ dali-toolkit/internal/file.list | 1 + .../animated-gradient/animated-gradient-visual.cpp | 807 ++++++++++++++ .../animated-gradient/animated-gradient-visual.h | 281 +++++ .../internal/visuals/visual-factory-cache.h | 12 + .../internal/visuals/visual-factory-impl.cpp | 12 +- .../internal/visuals/visual-string-constants.cpp | 2 + 10 files changed, 2627 insertions(+), 5 deletions(-) create mode 100755 dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h create mode 100644 dali-toolkit/devel-api/visuals/visual-properties-devel.h create mode 100755 dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.cpp create mode 100755 dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp index 121d5f4..af56d92 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include "dummy-control.h" @@ -280,6 +282,15 @@ int UtcDaliVisualSize(void) gradientVisual.GetNaturalSize(naturalSize); DALI_TEST_EQUALS( naturalSize, Vector2::ZERO,TEST_LOCATION ); + // animated gradient visual + Vector2 animated_gradient_visual_size(10.f, 10.f); + propertyMap.Clear(); + propertyMap.Insert( Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT ); + Visual::Base animatedGradientVisual = factory.CreateVisual( propertyMap ); + animatedGradientVisual.GetNaturalSize(naturalSize); + animatedGradientVisual.SetTransformAndSize(DefaultTransform(), controlSize ); + DALI_TEST_EQUALS( naturalSize, Vector2::ZERO, TEST_LOCATION ); + // svg visual Visual::Base svgVisual = factory.CreateVisual( TEST_SVG_FILE_NAME, ImageDimensions() ); svgVisual.SetTransformAndSize(DefaultTransform(), controlSize ); @@ -1102,6 +1113,490 @@ int UtcDaliVisualGetPropertyMap10(void) END_TEST; } +int UtcDaliVisualGetPropertyMap11(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualGetPropertyMap11: AnimatedGradientVisual" ); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK( factory ); + + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT); + + Vector2 start(-0.5f, 0.5f); + Vector2 end (0.5f, -0.0f); + Vector4 start_color(1.0f, 0.7f, 0.5f, 1.0f); + Vector4 end_color (0.7f, 0.5f, 1.0f, 1.0f); + Vector2 rotate_center(0.0f, 0.4f); + float rotate_amount = 1.57f; + float offset = 100.f; + + propertyMap.Insert(DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, DevelAnimatedGradientVisual::GradientType::RADIAL); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::UNIT_TYPE, DevelAnimatedGradientVisual::UnitType::USER_SPACE); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::SPREAD_TYPE, DevelAnimatedGradientVisual::SpreadType::CLAMP); + + propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_POSITION, start); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_POSITION, end); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_COLOR, start_color); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_COLOR, end_color); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_CENTER, rotate_center); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, rotate_amount); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::OFFSET, offset); + + Visual::Base animatedGradientVisual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK( animatedGradientVisual ); + + Property::Map resultMap; + animatedGradientVisual.CreatePropertyMap( resultMap ); + + // check the property values from the returned map from visual + Property::Value* value = resultMap.Find( Toolkit::Visual::Property::TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelVisual::ANIMATED_GRADIENT ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelAnimatedGradientVisual::GradientType::RADIAL ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::UNIT_TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelAnimatedGradientVisual::UnitType::USER_SPACE ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::SPREAD_TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelAnimatedGradientVisual::SpreadType::CLAMP ); + + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::START_POSITION, Property::VECTOR2 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), start , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::END_POSITION, Property::VECTOR2 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), end , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::START_COLOR, Property::VECTOR4 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), start_color , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::END_COLOR, Property::VECTOR4 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), end_color , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Property::VECTOR2 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), rotate_center , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, Property::FLOAT ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), rotate_amount , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::OFFSET, Property::FLOAT ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), offset , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliVisualGetPropertyMap12(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualGetPropertyMap12: AnimatedGradientVisual with animation param" ); + + // Case 1 : Set values by index + { + tet_printf( " - Set Values by Index\n" ); + // NOTE : PropertyMap doesn't optimized even delay < -loop_count * (duration + repeat_delay) so this animation will not run + // _delay = -10.0f is this case. It will progress (10.0f / 1.5f) amount. and 10.0f / 1.5f > 5. + for(float _delay = -10.0f; _delay <= 5.0f; _delay += 5.0f) + { + tet_printf( "test with delay [%f]\n", _delay ); + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK( factory ); + + Property::Map propertyMap; + Property::Map animationMap; + propertyMap.Insert(Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT); + + float duration = 1.1f; + float delay = _delay; + float repeat_delay = 0.4f; + + int direction = DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD; + int loop_count = 5; + int motion = DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR; + int easing = DevelAnimatedGradientVisual::AnimationParameter::EasingType::OUT; + + auto buildAnimatedMap = [&animationMap, &direction, &duration, &delay, &loop_count, &repeat_delay, &motion, &easing](const Property::Value &start, const Property::Value &target)->Property::Map& + { + animationMap.Clear(); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::START, start); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET, target); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, direction); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION, duration); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY, delay); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT, loop_count); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, repeat_delay); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, motion); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, easing); + + return animationMap; + }; + + Vector2 start1(-0.5f, 0.5f); + Vector2 end1 (0.5f, -0.5f); + Vector4 start_color1(1.0f, 0.7f, 0.5f, 1.0f); + Vector4 end_color1 (0.7f, 0.5f, 1.0f, 1.0f); + Vector2 rotate_center1(0.0f, 0.4f); + float rotate_amount1 = 0.0f; + float offset1 = 0.f; + + Vector2 start2(-0.5f, -0.5f); + Vector2 end2 (0.5f, 0.5f); + Vector4 start_color2(0.0f, 0.1f, 0.8f, 1.0f); + Vector4 end_color2 (0.3f, 1.0f, 0.1f, 0.0f); + Vector2 rotate_center2(0.0f, -0.4f); + float rotate_amount2 = 6.2832f; + float offset2 = 2.f; + + propertyMap.Insert(DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, DevelAnimatedGradientVisual::GradientType::LINEAR); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::UNIT_TYPE, DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::SPREAD_TYPE, DevelAnimatedGradientVisual::SpreadType::REPEAT); + + propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_POSITION, buildAnimatedMap(start1 , start2 )); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_POSITION, buildAnimatedMap(end1 , end2 )); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_COLOR, buildAnimatedMap(start_color1 , start_color2 )); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_COLOR, buildAnimatedMap(end_color1 , end_color2 )); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_CENTER, buildAnimatedMap(rotate_center1, rotate_center2)); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, buildAnimatedMap(rotate_amount1, rotate_amount2)); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::OFFSET, buildAnimatedMap(offset1 , offset2 )); + + Visual::Base animatedGradientVisual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK( animatedGradientVisual ); + + Property::Map resultMap; + animatedGradientVisual.CreatePropertyMap( resultMap ); + + // check the property values from the returned map from visual + Property::Value* value = resultMap.Find( Toolkit::Visual::Property::TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelVisual::ANIMATED_GRADIENT ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelAnimatedGradientVisual::GradientType::LINEAR ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::UNIT_TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::SPREAD_TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelAnimatedGradientVisual::SpreadType::REPEAT ); + + auto checkAnimatedMap = [&value, &resultMap, &direction, &duration, &delay, &loop_count, &repeat_delay, &motion, &easing](const Property::Index &index, const Property::Value &start, const Property::Value &target, int line_num)->void + { + tet_printf("Check value at %d\n", line_num); + value = resultMap.Find( index, Property::MAP ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->GetType() == Property::MAP ); + Property::Map *temp_map = value->GetMap(); + DALI_TEST_CHECK( temp_map ); + + auto checkMapValue = [&temp_map](const Property::Index index)->Property::Value + { + Property::Value *res = temp_map->Find( index ); + DALI_TEST_CHECK( res ); + return *res; + }; + + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::START) , start, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET) , target, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION) , Property::Value( direction ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION) , Property::Value( duration ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY) , Property::Value( delay ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT) , Property::Value( loop_count ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY), Property::Value( repeat_delay ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE) , Property::Value( motion ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE) , Property::Value( easing ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + }; + + // check the animation map data is good + checkAnimatedMap(DevelAnimatedGradientVisual::Property::START_POSITION, start1 , start2 , __LINE__); + checkAnimatedMap(DevelAnimatedGradientVisual::Property::END_POSITION , end1 , end2 , __LINE__); + checkAnimatedMap(DevelAnimatedGradientVisual::Property::START_COLOR , start_color1 , start_color2 , __LINE__); + checkAnimatedMap(DevelAnimatedGradientVisual::Property::END_COLOR , end_color1 , end_color2 , __LINE__); + checkAnimatedMap(DevelAnimatedGradientVisual::Property::ROTATE_CENTER , rotate_center1, rotate_center2, __LINE__); + checkAnimatedMap(DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT , rotate_amount1, rotate_amount2, __LINE__); + checkAnimatedMap(DevelAnimatedGradientVisual::Property::OFFSET , offset1 , offset2 , __LINE__); + } + } + + // Case 2 : Set values by string + { + tet_printf( " - Set Values by String\n" ); + // NOTE : PropertyMap doesn't optimized even delay < -loop_count * (duration + repeat_delay) so this animation will not run + // _delay = -10.0f is this case. It will progress (10.0f / 1.5f) amount. and 10.0f / 1.5f > 5. + for(float _delay = -10.0f; _delay <= 5.0f; _delay += 5.0f) + { + tet_printf( "test with delay [%f]\n", _delay ); + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK( factory ); + + Property::Map propertyMap; + Property::Map animationMap; + propertyMap.Insert("visualType", "ANIMATED_GRADIENT"); + + float duration = 1.1f; + float delay = _delay; + float repeat_delay = 0.4f; + + int direction = DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD; + int loop_count = 5; + int motion = DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR; + int easing = DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN_OUT; + + auto buildAnimatedMap = [&animationMap, &duration, &delay, &loop_count, &repeat_delay](const Property::Value &start, const Property::Value &target)->Property::Map& + { + animationMap.Clear(); + animationMap.Insert("startValue" , start); + animationMap.Insert("targetValue" , target); + animationMap.Insert("directionType", "BACKWARD"); + animationMap.Insert("duration" , duration); + animationMap.Insert("delay" , delay); + animationMap.Insert("repeat" , loop_count); + animationMap.Insert("repeatDelay" , repeat_delay); + animationMap.Insert("motionType" , "MIRROR"); + animationMap.Insert("easingType" , "IN_OUT"); + + return animationMap; + }; + + Vector2 start1(-0.5f, 0.5f); + Vector2 end1 (0.5f, -0.5f); + Vector4 start_color1(1.0f, 0.7f, 0.5f, 1.0f); + Vector4 end_color1 (0.7f, 0.5f, 1.0f, 1.0f); + Vector2 rotate_center1(0.0f, 0.4f); + float rotate_amount1 = 0.0f; + float offset1 = 0.f; + + Vector2 start2(-0.5f, -0.5f); + Vector2 end2 (0.5f, 0.5f); + Vector4 start_color2(0.0f, 0.1f, 0.8f, 1.0f); + Vector4 end_color2 (0.3f, 1.0f, 0.1f, 0.0f); + Vector2 rotate_center2(0.0f, -0.4f); + float rotate_amount2 = 6.2832f; + float offset2 = 2.f; + + // For test mix the type string/index key and string/index value works well. + propertyMap.Insert(DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, "RADIAL"); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::UNIT_TYPE, DevelAnimatedGradientVisual::UnitType::USER_SPACE); + propertyMap.Insert("spreadType" , DevelAnimatedGradientVisual::SpreadType::REFLECT); + + propertyMap.Insert("startPosition", buildAnimatedMap(start1 , start2 )); + propertyMap.Insert("endPosition" , buildAnimatedMap(end1 , end2 )); + propertyMap.Insert("startColor" , buildAnimatedMap(start_color1 , start_color2 )); + propertyMap.Insert("endColor" , buildAnimatedMap(end_color1 , end_color2 )); + propertyMap.Insert("rotateCenter" , buildAnimatedMap(rotate_center1, rotate_center2)); + propertyMap.Insert("rotateAmount" , buildAnimatedMap(rotate_amount1, rotate_amount2)); + propertyMap.Insert("offset" , buildAnimatedMap(offset1 , offset2 )); + + Visual::Base animatedGradientVisual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK( animatedGradientVisual ); + + Property::Map resultMap; + animatedGradientVisual.CreatePropertyMap( resultMap ); + + // check the property values from the returned map from visual + // Note : resultMap from CreatePropertyMap only contain indexKey + Property::Value* value = resultMap.Find( Toolkit::Visual::Property::TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelVisual::ANIMATED_GRADIENT ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelAnimatedGradientVisual::GradientType::RADIAL ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::UNIT_TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelAnimatedGradientVisual::UnitType::USER_SPACE ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::SPREAD_TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelAnimatedGradientVisual::SpreadType::REFLECT ); + + auto checkAnimatedMap = [&value, &resultMap, &direction, &duration, &delay, &loop_count, &repeat_delay, &motion, &easing](const Property::Index &index, const Property::Value &start, const Property::Value &target, int line_num)->void + { + tet_printf("Check value at %d\n", line_num); + value = resultMap.Find( index, Property::MAP ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->GetType() == Property::MAP ); + Property::Map *temp_map = value->GetMap(); + DALI_TEST_CHECK( temp_map ); + + auto checkMapValue = [&temp_map](const Property::Index index)->Property::Value + { + Property::Value *res = temp_map->Find( index ); + DALI_TEST_CHECK( res ); + return *res; + }; + + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::START) , start, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET) , target, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION) , Property::Value( direction ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION) , Property::Value( duration ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY) , Property::Value( delay ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT) , Property::Value( loop_count ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY), Property::Value( repeat_delay ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE) , Property::Value( motion ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE) , Property::Value( easing ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + }; + + // check the animation map data is good + checkAnimatedMap(DevelAnimatedGradientVisual::Property::START_POSITION, start1 , start2 , __LINE__); + checkAnimatedMap(DevelAnimatedGradientVisual::Property::END_POSITION , end1 , end2 , __LINE__); + checkAnimatedMap(DevelAnimatedGradientVisual::Property::START_COLOR , start_color1 , start_color2 , __LINE__); + checkAnimatedMap(DevelAnimatedGradientVisual::Property::END_COLOR , end_color1 , end_color2 , __LINE__); + checkAnimatedMap(DevelAnimatedGradientVisual::Property::ROTATE_CENTER , rotate_center1, rotate_center2, __LINE__); + checkAnimatedMap(DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT , rotate_amount1, rotate_amount2, __LINE__); + checkAnimatedMap(DevelAnimatedGradientVisual::Property::OFFSET , offset1 , offset2 , __LINE__); + } + } + + END_TEST; +} +int UtcDaliVisualGetPropertyMap13(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualGetPropertyMap13: AnimatedGradientVisual when repeat = 0" ); + + for(int _direction = 0; _direction <= 1; ++_direction) + { + for(float _delay = -10.0f; _delay <= 10.0f; _delay += 10.0f) + { + tet_printf( ((_direction == 0) ? "Forward test with delay [%f]\n" : "Backward test with delay [%f]\n") , _delay ); + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK( factory ); + + Property::Map propertyMap; + Property::Map animationMap; + propertyMap.Insert(Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT); + + float duration = 1.0f; + float delay = _delay; + float repeat_delay = 0.5f; + + int direction = _direction; + int loop_count = 0; // When loop_count is 0, Animation will not be created. + int motion = DevelAnimatedGradientVisual::AnimationParameter::MotionType::LOOP; + int easing = DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN; + + auto buildAnimatedMap = [&animationMap, &direction, &duration, &delay, &loop_count, &repeat_delay, &motion, &easing](const Property::Value &start, const Property::Value &target)->Property::Map& + { + animationMap.Clear(); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::START, start); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET, target); + if(direction == 0)animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD); + else animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, direction); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION, duration); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY, delay); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT, loop_count); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, repeat_delay); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, motion); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, easing); + + return animationMap; + }; + + Vector2 start1(-0.5f, 0.5f); + Vector2 end1 (0.5f, -0.5f); + Vector4 start_color1(1.0f, 0.7f, 0.5f, 1.0f); + Vector4 end_color1 (0.7f, 0.5f, 1.0f, 1.0f); + Vector2 rotate_center1(1.0f, 0.4f); + float rotate_amount1 = 2.0f; + float offset1 = 1.f; + + Vector2 start2(-0.5f, -0.5f); + Vector2 end2 (0.5f, 0.5f); + Vector4 start_color2(0.0f, 0.1f, 0.8f, 1.0f); + Vector4 end_color2 (0.3f, 1.0f, 0.1f, 0.0f); + Vector2 rotate_center2(1.0f, -0.4f); + float rotate_amount2 = 1.0f; + float offset2 = 3.f; + + propertyMap.Insert(DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, DevelAnimatedGradientVisual::GradientType::LINEAR); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::UNIT_TYPE, DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::SPREAD_TYPE, DevelAnimatedGradientVisual::SpreadType::REFLECT); + + propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_POSITION, buildAnimatedMap(start1 , start2 )); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_POSITION, buildAnimatedMap(end1 , end2 )); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_COLOR, buildAnimatedMap(start_color1 , start_color2 )); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_COLOR, buildAnimatedMap(end_color1 , end_color2 )); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_CENTER, buildAnimatedMap(rotate_center1, rotate_center2)); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, buildAnimatedMap(rotate_amount1, rotate_amount2)); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::OFFSET, buildAnimatedMap(offset1 , offset2 )); + + Visual::Base animatedGradientVisual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK( animatedGradientVisual ); + + Property::Map resultMap; + animatedGradientVisual.CreatePropertyMap( resultMap ); + + // check the property values from the returned map from visual + Property::Value* value = resultMap.Find( Toolkit::Visual::Property::TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelVisual::ANIMATED_GRADIENT ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelAnimatedGradientVisual::GradientType::LINEAR ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::UNIT_TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::SPREAD_TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == DevelAnimatedGradientVisual::SpreadType::REFLECT ); + + // If loop_count = 0, Animation doesn't created. + // Optimized resultMap only have one value, which is target value + // Note: target value will be changed by direction option. + value = resultMap.Find( DevelAnimatedGradientVisual::Property::START_POSITION, Property::VECTOR2 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), direction ? start1 : start2 , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::END_POSITION, Property::VECTOR2 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), direction ? end1 : end2 , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::START_COLOR, Property::VECTOR4 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), direction ? start_color1 : start_color2 , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::END_COLOR, Property::VECTOR4 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), direction ? end_color1 : end_color2 , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Property::VECTOR2 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), direction ? rotate_center1 : rotate_center2 , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, Property::FLOAT ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), direction ? rotate_amount1 : rotate_amount2 , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( DevelAnimatedGradientVisual::Property::OFFSET, Property::FLOAT ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), direction ? offset1 : offset2 , Math::MACHINE_EPSILON_100, TEST_LOCATION ); + } + } + + END_TEST; +} + int UtcDaliVisualAnimateBorderVisual01(void) { ToolkitTestApplication application; @@ -1356,6 +1851,614 @@ int UtcDaliVisualAnimatePrimitiveVisual(void) END_TEST; } +int UtcDaliVisualAnimatedGradientVisual01(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliAnimatedGradientVisual with default" ); + + { + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT); + Visual::Base visual = factory.CreateVisual( propertyMap ); + + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual ); + actor.SetSize(2000, 2000); + actor.SetParentOrigin(ParentOrigin::CENTER); + actor.SetColor(Color::BLACK); + Stage::GetCurrent().Add(actor); + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + + DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION); + + for(int step_iter = 0; step_iter < 3; step_iter++) + { + application.SendNotification(); + application.Render(0); + application.Render(750u); // step i/4 + application.SendNotification(); + + DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue( "start_point" , Vector2( -0.5f, 0.0f ) ), true, TEST_LOCATION ); + DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue( "end_point" , Vector2( 0.5f, 0.0f ) ), true, TEST_LOCATION ); + DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue( "start_color" , Vector4( 143.0f, 170.0f, 220.0f, 255.0f ) / 255.0f ), true, TEST_LOCATION ); + DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue( "end_color" , Vector4( 255.0f, 163.0f, 163.0f, 255.0f ) / 255.0f ), true, TEST_LOCATION ); + DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue( "rotate_center", Vector2( 0.0f, 0.0f ) ), true, TEST_LOCATION ); + DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue( "rotate_angle" , 0.0f ), true, TEST_LOCATION ); + DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue( "gradient_offset", 0.5f * step_iter + 0.5f ), true, TEST_LOCATION ); + } + + //Not check here. cause gradient_offset value can be 2.0f or 0.0f + application.Render(750u); // go to end + application.SendNotification(); + + application.Render(10u); // finish + application.SendNotification(); + + actor.Unparent(); + application.SendNotification(); + application.Render(0u); + application.SendNotification(); + } + + END_TEST; +} + +int UtcDaliVisualAnimatedGradientVisual02(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliAnimatedGradientVisual with full-option" ); + + { + float _delay[4] = {0.0f, -1.35f, 0.15f, -0.4f}; // fract(_delay) must NOT be 1/4, 2/4, 3/4. cause we don't know progress is 1.0f or 0.0f + int _direction[2] = {0, 1}; + int _loop_count[3] = {-1, 0, 1}; + int _motion[2] = {0, 1}; + int _easing[4] = {0, 1, 2, 3}; + + int test_case_max = 4 * 2 * 3 * 2 * 4; + int test_case = 0; + int test_case_d = 7; // 7 is the number of animated properties. + + float _duration = 0.4f; + float _repeat_delay = _duration * 0.25f; // < _duration. cause real_duration = _duration - _repeat_delay; + float noise_maker = 0.0f; + // total testing time = ceil((4*2*3*2*4) / 7) * (_duration(=0.4) * 2 + 0.01) = 22.68 seconds + for( test_case = 0; test_case < test_case_max + test_case_d; test_case += test_case_d ) + { + tet_printf( "test [%d ~ %d / %d]\n" , test_case, test_case + test_case_d - 1, test_case_max); + + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + Property::Map animationMap; + propertyMap.Insert(Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT); + + int gradient_type = DevelAnimatedGradientVisual::GradientType::LINEAR; + int unit_type = DevelAnimatedGradientVisual::UnitType::USER_SPACE; + int spread_type = DevelAnimatedGradientVisual::SpreadType::REPEAT; + + auto buildAnimatedMap = [&animationMap, &_direction, &_duration, &_delay, &_loop_count, &_repeat_delay, &_motion, &_easing, &test_case](const Property::Value &start, const Property::Value &target, int tc_offset)->Property::Map& + { + int tc = (test_case + tc_offset); + int idx_easing = tc % 4; tc /= 4; + int idx_motion = tc % 2; tc /= 2; + int idx_loop_count = tc % 3; tc /= 3; + int idx_direction = tc % 2; tc /= 2; + int idx_delay = tc % 4; tc /= 4; + + float duration = _duration - _repeat_delay; + float repeat_delay = _repeat_delay; + float delay = _delay[idx_delay] * _duration; + int direction = _direction[idx_direction]; + int loop_count = _loop_count[idx_loop_count]; + int motion = _motion[idx_motion]; + int easing = _easing[idx_easing]; + + animationMap.Clear(); + animationMap.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::START, start ); + animationMap.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET, target ); + if( direction == 0 ) + { + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD); + } + else + { + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD); + } + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION, duration); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY, delay); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT, loop_count); + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, repeat_delay); + if( motion == 0 ) + { + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, DevelAnimatedGradientVisual::AnimationParameter::MotionType::LOOP); + } + else + { + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR); + } + if( easing == 0 ) + { + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR); + } + else if( easing == 1 ) + { + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN); + } + else if( easing == 2 ) + { + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::OUT); + } + else + { + animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN_OUT); + } + + return animationMap; + }; + + // Give different values for debuging + noise_maker += 1.0f; + Vector2 start1(-0.5f + noise_maker * 0.1f, 0.5f + noise_maker * 0.1f); + Vector2 end1 (0.5f + noise_maker * 0.1f, -0.5f + noise_maker * 0.1f); + Vector4 start_color1(1.0f, 0.7f, 0.5f, 1.0f); + Vector4 end_color1 (0.7f, 0.5f, 1.0f, 1.0f); + Vector2 rotate_center1(0.0f + noise_maker * 0.1f, 0.4f + noise_maker * 0.1f); + float rotate_amount1 = 0.0f + noise_maker * 0.1f; + float offset1 = 0.f + noise_maker * 0.1f; + + Vector2 start2(0.2f + noise_maker * 0.1f, -0.7f + noise_maker * 0.1f); + Vector2 end2 (0.5f + noise_maker * 0.1f, 0.5f + noise_maker * 0.1f); + Vector4 start_color2(0.0f, 0.1f, 0.8f, 1.0f); + Vector4 end_color2 (0.3f, 1.0f, 0.1f, 0.0f); + Vector2 rotate_center2(0.0f + noise_maker * 0.1f, -0.4f + noise_maker * 0.1f); + float rotate_amount2 = 7.0f + noise_maker * 0.1f; + float offset2 = 2.f + noise_maker * 0.1f; + + propertyMap.Insert(DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, gradient_type); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::UNIT_TYPE, unit_type); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::SPREAD_TYPE, spread_type); + + propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_POSITION, buildAnimatedMap(start1 , start2 ,0)); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_POSITION, buildAnimatedMap(end1 , end2 ,1)); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_COLOR, buildAnimatedMap(start_color1 , start_color2 ,2)); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_COLOR, buildAnimatedMap(end_color1 , end_color2 ,3)); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_CENTER, buildAnimatedMap(rotate_center1, rotate_center2,4)); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, buildAnimatedMap(rotate_amount1, rotate_amount2,5)); + propertyMap.Insert(DevelAnimatedGradientVisual::Property::OFFSET, buildAnimatedMap(offset1 , offset2 ,6)); + + Visual::Base visual = factory.CreateVisual( propertyMap ); + + DummyControl actor = DummyControl::New( true ); + Impl::DummyControl& dummyImpl = static_cast( actor.GetImplementation() ); + dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual ); + actor.SetSize( 2000, 2000 ); + actor.SetParentOrigin(ParentOrigin::CENTER); + actor.SetColor(Color::BLACK); + Stage::GetCurrent().Add(actor); + + application.SendNotification(); + application.Render( 0 ); + application.SendNotification(); + + DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION); + + application.SendNotification(); + + //Compare between CPU calculated value and Shader Visual calculated value + auto testProperty = [&application, &_direction, &_duration, &_delay, &_loop_count, &_repeat_delay, &_motion, &_easing, &test_case](const char* name, const Property::Value& start, const Property::Value& target, int tc_offset, int value_type, float progress)->void + { + int tc = (test_case + tc_offset); + int idx_easing = tc % 4; tc /= 4; + int idx_motion = tc % 2; tc /= 2; + int idx_loop_count = tc % 3; tc /= 3; + int idx_direction = tc % 2; tc /= 2; + int idx_delay = tc % 4; tc /= 4; + + float duration = _duration - _repeat_delay; + float repeat_delay = _repeat_delay; + float delay = _delay[idx_delay] * _duration; + int direction = _direction[idx_direction]; + int loop_count = _loop_count[idx_loop_count]; + int motion = _motion[idx_motion]; + int easing = _easing[idx_easing]; + + progress -= delay / _duration; + + Property::Value s = start; + Property::Value t = target; + if( direction == 1 ) + { + s = target; + t = start; + } + float x; ///< Animator progress value + if( loop_count == 0 ) + { + x = 1.0f; + } + else if( loop_count > 0 && progress + 0.01f > loop_count ) + { + x = ( motion == 0 ) ? 1.0f : 0.0f; + } + else + { + if( progress < 0.0f ) + { + progress = 0.0f; + } + progress = fmodf( progress, 1.0f ); + progress = Dali::Clamp( (progress * (duration + repeat_delay) - repeat_delay) / duration, 0.0f, 1.0f ); + + x = progress; + if( motion == 1 ) + { + x = progress * 2.0f; + if( x > 1.0f ) + { + x = 2.0f - x; + } + } + + if( easing == 1 ) // EASE_IN + { + x = x*x; + } + else if( easing == 2 ) // EASE_OUT + { + x = 2.0f*x - x*x; + } + else if( easing == 3 ) // EASE_IN_OUT + { + x = x * x * (3.0f - 2.0f * x); + } + } + if( value_type == 0 ) // result type is Float + { + float res; + float cur; + res = s.Get() * (1.0f - x) + t.Get() * (x); + DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue(name, cur), true, TEST_LOCATION ); + DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + } + else if( value_type == 1 ) // result type is Vector2 + { + Vector2 res; + Vector2 cur; + res = s.Get() * (1.0f - x) + t.Get() * (x); + DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue(name, cur), true, TEST_LOCATION ); + DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + } + else if( value_type == 2 ) // result type is Vector3 + { + Vector3 res; + Vector3 cur; + res = s.Get() * (1.0f - x) + t.Get() * (x); + DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue(name, cur), true, TEST_LOCATION ); + DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + } + else // result type is Vector4 + { + Vector4 res; + Vector4 cur; + res = s.Get() * (1.0f - x) + t.Get() * (x); + DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue(name, cur), true, TEST_LOCATION ); + DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + } + }; + + float step = 0.0f; + for( int iter = 0; iter < 2; iter++ ) // test 2*duration seconds + { + for( int step_iter = 0; step_iter < 3; step_iter++ ) + { + application.SendNotification(); + application.Render( _duration * 250.f ); // step i/4 + application.SendNotification(); + step += 0.25f; + + testProperty( "start_point" , Property::Value( start1 ) , Property::Value( start2 ) , 0, 1, step ); + testProperty( "end_point" , Property::Value( end1 ) , Property::Value( end2 ) , 1, 1, step ); + testProperty( "start_color" , Property::Value( start_color1 ) , Property::Value( start_color2 ) , 2, 3, step ); + testProperty( "end_color" , Property::Value( end_color1 ) , Property::Value( end_color2 ) , 3, 3, step ); + testProperty( "rotate_center" , Property::Value( rotate_center1 ), Property::Value( rotate_center2 ), 4, 1, step ); + testProperty( "rotate_angle" , Property::Value( rotate_amount1 ), Property::Value( rotate_amount2 ), 5, 0, step ); + testProperty( "gradient_offset", Property::Value( offset1 ) , Property::Value( offset2 ) , 6, 0, step ); + } + application.SendNotification(); + application.Render(_duration * 250.f); // step 4/4 will not test + application.SendNotification(); + step += 0.25f; + } + + application.SendNotification(); + actor.Unparent(); + application.SendNotification(); + application.Render(10.f); // tempral time + application.SendNotification(); + } + } + + END_TEST; +} + +int UtcDaliVisualAnimatedGradientVisual03(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliAnimatedGradientVisual with full-option use string key" ); + + { + float _delay[4] = {0.0f, -1.35f, 0.15f, -0.4f}; // fract(_delay) must NOT be 1/4, 2/4, 3/4. cause we don't know progress is 1.0f or 0.0f + int _direction[2] = {0, 1}; + int _loop_count[3] = {-1, 0, 1}; + int _motion[2] = {0, 1}; + int _easing[4] = {0, 1, 2, 3}; + + int test_case_max = 4 * 2 * 3 * 2 * 4; + int test_case = 0; + int test_case_d = 7; // 7 is the number of animated properties. + + float _duration = 0.4f; + float _repeat_delay = _duration * 0.25f; // < _duration. cause real_duration = _duration - _repeat_delay; + float noise_maker = 0.2f; + // total testing time = ceil((4*2*3*2*4) / 7) * (_duration(=0.4) * 2 + 0.01) = 22.68 seconds + for( test_case = 0; test_case < test_case_max + test_case_d; test_case += test_case_d ) + { + tet_printf( "test [%d ~ %d / %d]\n" , test_case, test_case + test_case_d - 1, test_case_max); + + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + Property::Map animationMap; + propertyMap.Insert(Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT); + + auto buildAnimatedMap = [&animationMap, &_direction, &_duration, &_delay, &_loop_count, &_repeat_delay, &_motion, &_easing, &test_case](const Property::Value &start, const Property::Value &target, int tc_offset)->Property::Map& + { + int tc = (test_case + tc_offset); + int idx_easing = tc % 4; tc /= 4; + int idx_motion = tc % 2; tc /= 2; + int idx_loop_count = tc % 3; tc /= 3; + int idx_direction = tc % 2; tc /= 2; + int idx_delay = tc % 4; tc /= 4; + + float duration = _duration - _repeat_delay; + float repeat_delay = _repeat_delay; + float delay = _delay[idx_delay] * _duration; + int direction = _direction[idx_direction]; + int loop_count = _loop_count[idx_loop_count]; + int motion = _motion[idx_motion]; + int easing = _easing[idx_easing]; + + animationMap.Clear(); + animationMap.Insert( "startValue", start ); + animationMap.Insert( "targetValue", target ); + if( direction == 0 ) + { + animationMap.Insert("directionType", "FORWARD"); + } + else + { + animationMap.Insert("directionType", "BACKWARD"); + } + animationMap.Insert("duration", duration); + animationMap.Insert("delay", delay); + animationMap.Insert("repeat", loop_count); + animationMap.Insert("repeatDelay", repeat_delay); + if( motion == 0 ) + { + animationMap.Insert("motionType", "LOOP"); + } + else + { + animationMap.Insert("motionType", "MIRROR"); + } + if( easing == 0 ) + { + animationMap.Insert("easingType", "LINEAR"); + } + else if( easing == 1 ) + { + animationMap.Insert("easingType", "IN"); + } + else if( easing == 2 ) + { + animationMap.Insert("easingType", "OUT"); + } + else + { + animationMap.Insert("easingType", "IN_OUT"); + } + + return animationMap; + }; + + // Give different values for debuging + noise_maker += 0.8f; + Vector2 start1(-0.5f + noise_maker * 0.1f, 0.5f + noise_maker * 0.1f); + Vector2 end1 (0.5f + noise_maker * 0.1f, -0.5f + noise_maker * 0.1f); + Vector4 start_color1(1.0f, 0.7f, 0.5f, 1.0f); + Vector4 end_color1 (0.7f, 0.5f, 1.0f, 1.0f); + Vector2 rotate_center1(0.0f + noise_maker * 0.1f, 0.4f + noise_maker * 0.1f); + float rotate_amount1 = 0.0f + noise_maker * 0.1f; + float offset1 = 0.f + noise_maker * 0.1f; + + Vector2 start2(0.2f + noise_maker * 0.1f, -0.7f + noise_maker * 0.1f); + Vector2 end2 (0.5f + noise_maker * 0.1f, 0.5f + noise_maker * 0.1f); + Vector4 start_color2(0.0f, 0.1f, 0.8f, 1.0f); + Vector4 end_color2 (0.3f, 1.0f, 0.1f, 0.0f); + Vector2 rotate_center2(0.0f + noise_maker * 0.1f, -0.4f + noise_maker * 0.1f); + float rotate_amount2 = 7.0f + noise_maker * 0.1f; + float offset2 = 2.f + noise_maker * 0.1f; + + propertyMap.Insert("gradientType", "LINEAR"); + propertyMap.Insert("unitType", "USER_SPACE"); + propertyMap.Insert("spreadType", "CLAMP"); + + propertyMap.Insert("startPosition", buildAnimatedMap(start1 , start2 ,0)); + propertyMap.Insert("endPosition", buildAnimatedMap(end1 , end2 ,1)); + propertyMap.Insert("startColor", buildAnimatedMap(start_color1 , start_color2 ,2)); + propertyMap.Insert("endColor", buildAnimatedMap(end_color1 , end_color2 ,3)); + propertyMap.Insert("rotateCenter", buildAnimatedMap(rotate_center1, rotate_center2,4)); + propertyMap.Insert("rotateAmount", buildAnimatedMap(rotate_amount1, rotate_amount2,5)); + propertyMap.Insert("offset", buildAnimatedMap(offset1 , offset2 ,6)); + + Visual::Base visual = factory.CreateVisual( propertyMap ); + + DummyControl actor = DummyControl::New( true ); + Impl::DummyControl& dummyImpl = static_cast( actor.GetImplementation() ); + dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual ); + actor.SetSize( 2000, 2000 ); + actor.SetParentOrigin(ParentOrigin::CENTER); + actor.SetColor(Color::BLACK); + Stage::GetCurrent().Add(actor); + + application.SendNotification(); + application.Render( 0 ); + application.SendNotification(); + + DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION); + + application.SendNotification(); + + //Compare between CPU calculated value and Shader Visual calculated value + auto testProperty = [&application, &_direction, &_duration, &_delay, &_loop_count, &_repeat_delay, &_motion, &_easing, &test_case](const char* name, const Property::Value& start, const Property::Value& target, int tc_offset, int value_type, float progress)->void + { + int tc = (test_case + tc_offset); + int idx_easing = tc % 4; tc /= 4; + int idx_motion = tc % 2; tc /= 2; + int idx_loop_count = tc % 3; tc /= 3; + int idx_direction = tc % 2; tc /= 2; + int idx_delay = tc % 4; tc /= 4; + + float duration = _duration - _repeat_delay; + float repeat_delay = _repeat_delay; + float delay = _delay[idx_delay] * _duration; + int direction = _direction[idx_direction]; + int loop_count = _loop_count[idx_loop_count]; + int motion = _motion[idx_motion]; + int easing = _easing[idx_easing]; + + progress -= delay / _duration; + + Property::Value s = start; + Property::Value t = target; + if( direction == 1 ) + { + s = target; + t = start; + } + float x; ///< Animator progress value + if( loop_count == 0 ) + { + x = 1.0f; + } + else if( loop_count > 0 && progress + 0.01f > loop_count ) + { + x = ( motion == 0 ) ? 1.0f : 0.0f; + } + else + { + if( progress < 0.0f ) + { + progress = 0.0f; + } + progress = fmodf( progress, 1.0f ); + progress = Dali::Clamp( (progress * (duration + repeat_delay) - repeat_delay) / duration, 0.0f, 1.0f ); + + x = progress; + if( motion == 1 ) + { + x = progress * 2.0f; + if( x > 1.0f ) + { + x = 2.0f - x; + } + } + + if( easing == 1 ) // EASE_IN + { + x = x*x; + } + else if( easing == 2 ) // EASE_OUT + { + x = 2.0f*x - x*x; + } + else if( easing == 3 ) // EASE_IN_OUT + { + x = x * x * (3.0f - 2.0f * x); + } + } + if( value_type == 0 ) // result type is Float + { + float res; + float cur; + res = s.Get() * (1.0f - x) + t.Get() * (x); + DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue(name, cur), true, TEST_LOCATION ); + DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + } + else if( value_type == 1 ) // result type is Vector2 + { + Vector2 res; + Vector2 cur; + res = s.Get() * (1.0f - x) + t.Get() * (x); + DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue(name, cur), true, TEST_LOCATION ); + DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + } + else if( value_type == 2 ) // result type is Vector3 + { + Vector3 res; + Vector3 cur; + res = s.Get() * (1.0f - x) + t.Get() * (x); + DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue(name, cur), true, TEST_LOCATION ); + DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + } + else // result type is Vector4 + { + Vector4 res; + Vector4 cur; + res = s.Get() * (1.0f - x) + t.Get() * (x); + DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue(name, cur), true, TEST_LOCATION ); + DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + } + }; + + float step = 0.0f; + for( int iter = 0; iter < 2; iter++ ) // test 2*duration seconds + { + for( int step_iter = 0; step_iter < 3; step_iter++ ) + { + application.SendNotification(); + application.Render( _duration * 250.f ); // step i/4 + application.SendNotification(); + step += 0.25f; + + testProperty( "start_point" , Property::Value( start1 ) , Property::Value( start2 ) , 0, 1, step ); + testProperty( "end_point" , Property::Value( end1 ) , Property::Value( end2 ) , 1, 1, step ); + testProperty( "start_color" , Property::Value( start_color1 ) , Property::Value( start_color2 ) , 2, 3, step ); + testProperty( "end_color" , Property::Value( end_color1 ) , Property::Value( end_color2 ) , 3, 3, step ); + testProperty( "rotate_center" , Property::Value( rotate_center1 ), Property::Value( rotate_center2 ), 4, 1, step ); + testProperty( "rotate_angle" , Property::Value( rotate_amount1 ), Property::Value( rotate_amount2 ), 5, 0, step ); + testProperty( "gradient_offset", Property::Value( offset1 ) , Property::Value( offset2 ) , 6, 0, step ); + } + application.SendNotification(); + application.Render(_duration * 250.f); // step 4/4 will not test + application.SendNotification(); + step += 0.25f; + } + + application.SendNotification(); + actor.Unparent(); + application.SendNotification(); + application.Render(10.f); // tempral time + application.SendNotification(); + } + } + + END_TEST; +} int UtcDaliVisualWireframeVisual(void) { diff --git a/dali-toolkit/devel-api/file.list b/dali-toolkit/devel-api/file.list index 4964c98..cf27ec2 100644 --- a/dali-toolkit/devel-api/file.list +++ b/dali-toolkit/devel-api/file.list @@ -46,9 +46,6 @@ devel_api_src_files = \ devel_api_header_files = \ $(devel_api_src_dir)/direction-enums.h -devel_api_visuals_header_files = \ - $(devel_api_src_dir)/visuals/image-visual-properties-devel.h - devel_api_controls_header_files = \ $(devel_api_src_dir)/controls/control-depth-index-ranges.h \ $(devel_api_src_dir)/controls/control-devel.h \ @@ -94,6 +91,11 @@ devel_api_visual_factory_header_files = \ $(devel_api_src_dir)/visual-factory/visual-factory.h \ $(devel_api_src_dir)/visual-factory/visual-base.h +devel_api_visuals_header_files = \ + $(devel_api_src_dir)/visuals/image-visual-properties-devel.h \ + $(devel_api_src_dir)/visuals/animated-gradient-visual-properties-devel.h \ + $(devel_api_src_dir)/visuals/visual-properties-devel.h + devel_api_shadow_view_header_files = \ $(devel_api_src_dir)/controls/shadow-view/shadow-view.h diff --git a/dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h b/dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h new file mode 100755 index 0000000..41b3f31 --- /dev/null +++ b/dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h @@ -0,0 +1,347 @@ +#ifndef DALI_TOOLKIT_DEVEL_ANIMATED_GRADIENT_VISUAL_PROPERTIES_H +#define DALI_TOOLKIT_DEVEL_ANIMATED_GRADIENT_VISUAL_PROPERTIES_H + +/* + * Copyright (c) 2017 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. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +/** + * + */ + +/** + * @brief AnimatedGradientVisual is to render a smooth transition of colors to the control's quad with animation. + */ +namespace DevelAnimatedGradientVisual +{ + +/** + * @brief AnimatedGradientVisual Property + */ +namespace Property +{ + +/** + * @brief AnimatedGradientVisual Property + */ +enum +{ + /** + * @brief The form of gradient. + * @details Name "gradientType", type GradientType::Type (Property::INTEGER) or Property::STRING. + * @note If not supplied, default is GradientType::LINEAR. + * @see GradientType::Type + */ + GRADIENT_TYPE = VISUAL_PROPERTY_START_INDEX, + + /** + * @brief The coordinate system inside of control's quad. + * @details Name "unitType", type UnitType::Type (Property::INTEGER) or Property::STRING. + * @note If not supplied, default is UnitType::OBJECT_BOUNDING_BOX. + * @see UnitType::Type + */ + UNIT_TYPE, + + /** + * @brief The policy of color when gradient coordinate is not between 0 and 1. + * @details Name "spreadType", type SpreadType::Type (Property::INTEGER) or Property::STRING. + * @note If not supplied, default is SpreadType::REFLECT. + * @see SpreadType::Type + */ + SPREAD_TYPE, + + /** + * @brief The position of a gradient coordinate is 0. If GRADIENT_TYPE is RADIAL, than it will be center of circle. + * @details Name "startPosition", type Property::Vector2 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property + * @note If not supplied, default is Vector2( -0.5f, 0.0f ). + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property + */ + START_POSITION, + + /** + * @brief The color of a gradient coordinate is 0. + * @details Name "startColor", type Property::Vector4 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + * @note If not supplied, default is Vector4( 143.0f, 170.0f, 220.0f, 255.0f ) / 255.0f. + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + */ + START_COLOR, + + /** + * @brief The position of a gradient coordinate is 1. + * @details Name "endPosition", type Property::Vector2 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + * @note If not supplied, default is Vector2( 0.5f, 0.0f ). + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + */ + END_POSITION, + + /** + * @brief The color of a gradient coordinate is 1. + * @details Name "endColor", type Property::Vector4 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + * @note If not supplied, default is Vector4( 255.0f, 163.0f, 163.0f, 255.0f ) / 255.0f. + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property + */ + END_COLOR, + + /** + * @brief The center of rotate START_POSITION and END_POSITION. + * @details Name "rotateCenter", type Property::Vector2 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + * @note If not supplied, default is Vector2( 0.0f, 0.0f ). + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property + */ + ROTATE_CENTER, + + /** + * @brief The amount of rotate START_POSITION and END_POSITION in radian. + * @details Name "rotateAmount", type Property::FLOAT or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + * @note If not supplied, default is 0.0f. + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property + */ + ROTATE_AMOUNT, + + /** + * @brief The offset of gradient coordinate. The point will have a color where (gradient coordinate + offset). + * @details Name "offset", type Property::FLOAT or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + * @note If not supplied, default is Animation from 0.0f to 2.0f, with duration 3.0f seconds. + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + */ + OFFSET +}; + +} // namespace Property + +/** + * @brief The type of gradient form. It decide the method of calculate gradient coordinate. + * - If GradientType::Type is LINEAR, gradient coordinate is dot product with the line which contain START_POSITION and END_POSITION. + * - If GradientType::Type is RADIAL, gradient coordinate is euclidean distance from START_POSITION. + */ +namespace GradientType +{ + +/** + * @brief The type of gradient form. It decide the method of calculate gradient coordinate. + * - If GradientType::Type is LINEAR, gradient coordinate is dot product with the line which contain START_POSITION and END_POSITION. + * - If GradientType::Type is RADIAL, gradient coordinate is euclidean distance from START_POSITION. + */ +enum Type +{ + LINEAR, ///< Draw gradient linear form. + RADIAL ///< Draw gradient radial form. +}; + +} // namespace GradientType + +/** + * @brief The type of coordinate system for certain attributes of the points in a gradients. + * This applies to the START_POSITION, END_POSITION, and ROTATE_CENTER. + */ +namespace UnitType +{ + +/** + * @brief The type of coordinate system for certain attributes of the points in a gradients. + * This applies to the START_POSITION, END_POSITION, and ROTATE_CENTER. + */ +enum Type +{ + OBJECT_BOUNDING_BOX, ///< Use positions coordinate in bottom-left(-0.5,-0.5) ~ top-right(0.5,0.5). + USER_SPACE, ///< Use positions coordinate in bottom-left(-ActorSize.xy * 0.5) ~ top-right(ActorSize.xy * 0.5). +}; + +} // namespace UnitType + +/** + * @brief The policies that define what happens if the gradient coordinate is not between 0 and 1. + */ +namespace SpreadType +{ + +/** + * @brief The policies that define what happens if the gradient coordinate is not between 0 and 1. + */ +enum Type +{ + REFLECT, ///< Reflect the gradient pattern start-to-end, end-to-start, start-to-end etc. + REPEAT, ///< Repeat the gradient pattern start-to-end, start-to-end, start-to-end etc. + CLAMP, ///< Use the terminal colors of gradient. +}; + +} // namespace SpreadType + +/** + * @brief AnimatedGradientVisual::AnimationParameter is information of each properties animation. + * Value animate from start to target during duration seconds. + * Each start/target value type for AnimatedGradientVisual Property is : + * - START_POSITION, END_POSITION, ROTATE_CENTER is Property::Vector2 + * - START_COLOR, END_COLOR is Property::Vector4 + * - ROTATE_AMOUNT, OFFSET is Property::FLOAT + * You can set the animation information to AnimatedGradientVisual Property by using Property::MAP. + */ +namespace AnimationParameter +{ + +/** + * @brief AnimatedGradientVisual::AnimationParameter Property + */ +enum Property +{ + + /** + * @brief The start value of this animation. + * @details Name "startValue", type depends on AnimatedGradientVisual Property. + * @note If not supplied, default is Property::Value( 0.0f ). + */ + START = DevelAnimatedGradientVisual::Property::OFFSET + 1, + + /** + * @brief The target value of this animation. + * @details Name "targetValue", type depends on AnimatedGradientVisual Property. + * @note If not supplied, default is Property::Value( 0.0f ). + */ + TARGET, + + /** + * @brief The direction of this animation. + * @details Name "directionType", type DirectionType::Type (Property::INTEGER) or Property::STRING. + * @note If not supplied, default is DirectionType::FORWARD. + * @see DirectionType::Type + */ + DIRECTION, + + /** + * @brief The duration of this animation in seconds. + * @details Name "duration", type Property::FLOAT. + * @note If not supplied, default is 3.0f. + */ + DURATION, + + /** + * @brief The delay of this animation in seconds. + * If delay is positive, wait the animation 'delay' seconds. + * If delay is negative, skip the animation '-delay' seconds. + * @details Name "delay", type Property::FLOAT. + * @note If not supplied, default is 0.0f. + */ + DELAY, + + /** + * @brief The repeat count of this animation. + * If repeat is negative, animate unlimited loop. + * If repeat is zero, animation will no run. + * If repeat is positive, animate 'repeat' times. + * @details Name "repeat", type Property::INTEGER. + * @note If not supplied, default is 0. + */ + REPEAT, + + /** + * @brief The delay before each loop of this animation in seconds. + * @details Name "repeatDelay", type Property::FLOAT. + * @note If not supplied, default is 0.0f. + */ + REPEAT_DELAY, + + /** + * @brief The motion of this animation. + * @details Name "motionType", type MotionType::Type (Property::INTEGER) or Property::STRING. + * @note If not supplied, default is MotionType::LOOP. + * @see MotionType::Type + */ + MOTION_TYPE, + + /** + * @brief The easing option of this animation. + * @details Name "easingType", type EasingType::Type (Property::INTEGER) or Property::STRING. + * @note If not supplied, default is EasingType::LINEAR. + * @see EasingType::Type + */ + EASING_TYPE +}; + +/** + * @brief The type of animation direction + */ +namespace DirectionType +{ + +/** + * @brief The type of animation direction + */ +enum Type +{ + FORWARD, ///< Animate value from START to TARGET + BACKWARD, ///< Animate value frome TARGET to START +}; + +} // namespace DirectionType + +/** + * @brief The type of animation motion + */ +namespace MotionType +{ + +/** + * @brief The type of animation motion + */ +enum Type +{ + LOOP, ///< Animate loopingmode restart + MIRROR, ///< Animate loopingmode auto_reverse +}; + +} // namespace MotionType + +/** + * @brief The type of animation easing + */ +namespace EasingType +{ + +/** + * @brief The type of animation easing + */ +enum Type +{ + LINEAR, ///< Easing animation linear + IN, ///< Ease-in animation (slow start -> fast finish) + OUT, ///< Ease-out animation (fast start -> slow finish) + IN_OUT, ///< Ease-in and Ease-out animation (slow start -> slow finish) +}; + +} // namespace EasingType + +} // namespace AnimationParameter + +} // namespace DevelAnimatedGradientVisual + +/** + * + */ + +} // namespace Toolkit + +} // namespace Dali + +#endif diff --git a/dali-toolkit/devel-api/visuals/visual-properties-devel.h b/dali-toolkit/devel-api/visuals/visual-properties-devel.h new file mode 100644 index 0000000..019b632 --- /dev/null +++ b/dali-toolkit/devel-api/visuals/visual-properties-devel.h @@ -0,0 +1,59 @@ +#ifndef DALI_TOOLKIT_DEVEL_API_VISUALS_VISUAL_PROPERTIES_DEVEL_H +#define DALI_TOOLKIT_DEVEL_API_VISUALS_VISUAL_PROPERTIES_DEVEL_H + +/* + * Copyright (c) 2017 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. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace DevelVisual +{ + +/** + * @brief All the visual types. + */ +enum Type +{ + BORDER = Dali::Toolkit::Visual::BORDER, + COLOR = Dali::Toolkit::Visual::COLOR, + GRADIENT = Dali::Toolkit::Visual::GRADIENT, + IMAGE = Dali::Toolkit::Visual::IMAGE, + MESH = Dali::Toolkit::Visual::MESH, + PRIMITIVE = Dali::Toolkit::Visual::PRIMITIVE, + WIREFRAME = Dali::Toolkit::Visual::WIREFRAME, + TEXT = Dali::Toolkit::Visual::TEXT, + N_PATCH = Dali::Toolkit::Visual::N_PATCH, + SVG = Dali::Toolkit::Visual::SVG, + ANIMATED_IMAGE = Dali::Toolkit::Visual::ANIMATED_IMAGE, + + ANIMATED_GRADIENT = ANIMATED_IMAGE + 1, ///< Renders an animated gradient. +}; + +} // namespace DevelVisual + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_DEVEL_API_VISUALS_VISUAL_PROPERTIES_DEVEL_H diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index f559778..c3d0a0e 100755 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -21,6 +21,7 @@ toolkit_src_files = \ $(toolkit_src_dir)/visuals/gradient/gradient.cpp \ $(toolkit_src_dir)/visuals/gradient/linear-gradient.cpp \ $(toolkit_src_dir)/visuals/gradient/radial-gradient.cpp \ + $(toolkit_src_dir)/visuals/animated-gradient/animated-gradient-visual.cpp \ $(toolkit_src_dir)/visuals/image-atlas-manager.cpp \ $(toolkit_src_dir)/visuals/image/image-visual.cpp \ $(toolkit_src_dir)/visuals/mesh/mesh-visual.cpp \ diff --git a/dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.cpp b/dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.cpp new file mode 100755 index 0000000..f20286c --- /dev/null +++ b/dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.cpp @@ -0,0 +1,807 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +//CLASS HEADER +#include + +//INTERNAL INCLUDES +#include +#include +#include +#include +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +namespace +{ +// non-animated property +const char* const GRADIENT_TYPE_NAME("gradientType"); +const char* const UNIT_TYPE_NAME("unitType"); +const char* const SPREAD_TYPE_NAME("spreadType"); +// animated property +const char* const START_POSITION_NAME("startPosition"); +const char* const START_COLOR_NAME("startColor"); +const char* const END_POSITION_NAME("endPosition"); +const char* const END_COLOR_NAME("endColor"); +const char* const ROTATE_CENTER_NAME("rotateCenter"); +const char* const ROTATE_AMOUNT_NAME("rotateAmount"); +const char* const OFFSET_NAME("offset"); +// animation parameter property +const char* const START_VALUE_NAME("startValue"); +const char* const TARGET_VALUE_NAME("targetValue"); +const char* const DIRECTION_TYPE_NAME("directionType"); +const char* const DURATION_NAME("duration"); +const char* const DELAY_NAME("delay"); +const char* const REPEAT_NAME("repeat"); +const char* const REPEAT_DELAY_NAME("repeatDelay"); +const char* const MOTION_TYPE_NAME("motionType"); +const char* const EASING_TYPE_NAME("easingType"); +// common shader property +const char* const UNIFORM_START_POINT_NAME("start_point"); +const char* const UNIFORM_START_COLOR_NAME("start_color"); +const char* const UNIFORM_END_POINT_NAME("end_point"); +const char* const UNIFORM_END_COLOR_NAME("end_color"); +const char* const UNIFORM_ROTATE_CENTER_NAME("rotate_center"); +const char* const UNIFORM_ROTATE_ANGLE_NAME("rotate_angle"); +const char* const UNIFORM_OFFSET_NAME("gradient_offset"); + +DALI_ENUM_TO_STRING_TABLE_BEGIN( GRADIENT_TYPE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::GradientType, LINEAR ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::GradientType, RADIAL ) +DALI_ENUM_TO_STRING_TABLE_END( GRADIENT_TYPE ) + +DALI_ENUM_TO_STRING_TABLE_BEGIN( UNIT_TYPE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::UnitType, OBJECT_BOUNDING_BOX ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::UnitType, USER_SPACE ) +DALI_ENUM_TO_STRING_TABLE_END( UNIT_TYPE ) + +DALI_ENUM_TO_STRING_TABLE_BEGIN( SPREAD_TYPE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::SpreadType, REFLECT ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::SpreadType, REPEAT ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::SpreadType, CLAMP ) +DALI_ENUM_TO_STRING_TABLE_END( SPREAD_TYPE ) + +DALI_ENUM_TO_STRING_TABLE_BEGIN( DIRECTION_TYPE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType, FORWARD ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType, BACKWARD ) +DALI_ENUM_TO_STRING_TABLE_END( DIRECTION_TYPE ) + +DALI_ENUM_TO_STRING_TABLE_BEGIN( MOTION_TYPE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType, LOOP ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType, MIRROR ) +DALI_ENUM_TO_STRING_TABLE_END( MOTION_TYPE ) + +DALI_ENUM_TO_STRING_TABLE_BEGIN( EASING_TYPE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType, LINEAR ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType, IN ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType, OUT ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType, IN_OUT ) +DALI_ENUM_TO_STRING_TABLE_END( EASING_TYPE ) + +// Default values of each properties +const Toolkit::DevelAnimatedGradientVisual::GradientType::Type DEFAULT_GRADIENT_TYPE = Toolkit::DevelAnimatedGradientVisual::GradientType::LINEAR; +const Toolkit::DevelAnimatedGradientVisual::UnitType::Type DEFAULT_UNIT_TYPE = Toolkit::DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX; +const Toolkit::DevelAnimatedGradientVisual::SpreadType::Type DEFAULT_SPREAD_TYPE = Toolkit::DevelAnimatedGradientVisual::SpreadType::REFLECT; + +const float DEFAULT_START_POSITION[] = { -0.5f, 0.0f }; +const float DEFAULT_START_COLOR[] = { 143.0f/255.0f, 170.0f/255.0f, 220.0f/255.0f, 255.0f/255.0f }; +const float DEFAULT_END_POSITION[] = { 0.5f, 0.0f }; +const float DEFAULT_END_COLOR[] = { 255.0f/255.0f, 163.0f/255.0f, 163.0f/255.0f, 255.0f/255.0f }; +const float DEFAULT_ROTATE_CENTER[] = { 0.0f, 0.0f }; +const float DEFAULT_ROTATE_AMOUNT = 0.0f; + +const float DEFAULT_ANIMATION_START_VALUE = 0.0f; +const float DEFAULT_ANIMATION_TARGET_VALUE = 0.0f; +const float DEFAULT_ANIMATION_DURATION = 3.0f; +const float DEFAULT_ANIMATION_DELAY = 0.0f; +const int DEFAULT_ANIMATION_REPEAT = 0; +const float DEFAULT_ANIMATION_REPEAT_DELAY = 0.0f; + +const Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::Type DEFAULT_ANIMATION_DIRECTION_TYPE = Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD; +const Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::Type DEFAULT_ANIMATION_MOTION_TYPE = Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::LOOP; +const Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::Type DEFAULT_ANIMATION_EASING_TYPE = Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR; + +const char* const BASIC_VERTEX_SHADER = DALI_COMPOSE_SHADER( + attribute mediump vec2 aPosition; + uniform mediump mat4 uMvpMatrix; + uniform mediump vec3 uSize; + + uniform mediump vec2 start_point; + uniform mediump vec2 end_point; + uniform mediump vec2 rotate_center; + uniform mediump float rotate_angle; + + varying mediump vec2 vTexCoord; + varying mediump vec2 vStart; + varying mediump vec2 vEnd; + + vec2 rotate(vec2 x, vec2 c, float a) + { + vec2 d = x - c; + vec2 r = vec2(d.x * cos(a) - d.y * sin(a), d.x * sin(a) + d.y * cos(a)); + +\n #ifdef UNIT_TYPE_BOUNDING_BOX \n return r + c; \n #endif \n /* UnitType::OBJECT_BOUNDING_BOX */ +\n #ifdef UNIT_TYPE_USER \n return (r + c) / uSize.x; \n #endif \n /* UnitType::USER_SPACE */ + } + + //Visual size and offset + uniform mediump vec2 offset; + uniform mediump vec2 size; + uniform mediump vec4 offsetSizeMode; + uniform mediump vec2 origin; + uniform mediump vec2 anchorPoint; + + vec4 ComputeVertexPosition() + { + vec2 visualSize = mix( uSize.xy*size, size, offsetSizeMode.zw ); + vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy ); + return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 ); + } + + void main() + { + vStart = rotate( start_point, rotate_center, rotate_angle ); + vEnd = rotate( end_point, rotate_center, rotate_angle ); + gl_Position = uMvpMatrix * ComputeVertexPosition(); + +\n #ifdef UNIT_TYPE_BOUNDING_BOX \n vTexCoord = vec2(aPosition.x, -aPosition.y); \n #endif \n /* UnitType::OBJECT_BOUNDING_BOX */ +\n #ifdef UNIT_TYPE_USER \n vTexCoord = vec2(aPosition.x, -aPosition.y * uSize.y / uSize.x); \n #endif \n /* UnitType::USER_SPACE */ + } +); + +const char* const BASIC_FRAGMENT_SHADER = DALI_COMPOSE_SHADER( + precision mediump float; + + uniform mediump vec4 start_color; + uniform mediump vec4 end_color; + uniform mediump float gradient_offset; + + varying mediump vec2 vTexCoord; + varying mediump vec2 vStart; + varying mediump vec2 vEnd; + + float get_position(vec2 x, vec2 s, vec2 e) + { + vec2 df = e - s; + vec2 dx = x - s; + +\n #ifdef GRADIENT_TYPE_LINEAR \n return dot(dx,df)/dot(df,df); \n #endif \n /* GradientType::LINEAR */ +\n #ifdef GRADIENT_TYPE_RADIAL \n return sqrt(dot(dx,dx)/dot(df,df)); \n #endif \n /* GradientType::RADIAL */ + } + float recalculate(float r) + { +\n #ifdef SPREAD_TYPE_REFLECT \n return 1.0 - abs(mod(r, 2.0) - 1.0); \n #endif \n /* SpreadType::REFLECT */ +\n #ifdef SPREAD_TYPE_REPEAT \n return fract(r); \n #endif \n /* SpreadType::REPEAT */ +\n #ifdef SPREAD_TYPE_CLAMP \n return clamp(r, 0.0, 1.0); \n #endif \n /* SpreadType::CLAMP */ + } + + void main() + { + float r = get_position( vTexCoord, vStart, vEnd ); + r = recalculate( r + gradient_offset ); + vec4 color = mix( start_color, end_color, r ); + gl_FragColor = color; + } +); + +Property::Value GetStartValue( const Property::Map& map, Property::Index index, const char* const name ) +{ + // Get start value of animation parameter + Property::Value* res = map.Find( index, name ); + if( res ) + { + Property::Map* s_map = res->GetMap(); + if( s_map ) + { + res = s_map->Find( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::START, START_VALUE_NAME ); + DALI_ASSERT_ALWAYS( res && "Start value is not setup in Property::Map" ); + } + } + else + { + DALI_ASSERT_ALWAYS( !"Start value is not setup even default" ); + } + return *res; +} + +VisualFactoryCache::ShaderType GetShaderType( Toolkit::DevelAnimatedGradientVisual::GradientType::Type grad, Toolkit::DevelAnimatedGradientVisual::UnitType::Type unit, Toolkit::DevelAnimatedGradientVisual::SpreadType::Type spread ) +{ + return static_cast( + VisualFactoryCache::ANIMATED_GRADIENT_SHADER_LINEAR_BOUNDING_REFLECT + + static_cast( grad ) * 6 + // 6 is the number of UnitType * SpreadType + static_cast( unit ) * 3 + // 3 is the number of SpreadType. + static_cast( spread ) + ); +} + +} // unnamed namespace + +AnimatedGradientVisualPtr AnimatedGradientVisual::New( VisualFactoryCache& factoryCache, const Property::Map& properties ) +{ + AnimatedGradientVisualPtr animatedGradientVisualPtr( new AnimatedGradientVisual( factoryCache ) ); + animatedGradientVisualPtr->SetProperties( properties ); + return animatedGradientVisualPtr; +} + +AnimatedGradientVisual::AnimatedGradientVisual( VisualFactoryCache& factoryCache ) : Visual::Base( factoryCache ) +{ + SetupDefaultValue(); +} + +AnimatedGradientVisual::~AnimatedGradientVisual() +{ + +} + +void AnimatedGradientVisual::SetupDefaultValue() +{ + mGradientType = DEFAULT_GRADIENT_TYPE; + mUnitType = DEFAULT_UNIT_TYPE; + mSpreadType = DEFAULT_SPREAD_TYPE; + + mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION] = Vector2( DEFAULT_START_POSITION ); + mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = Vector4( DEFAULT_START_COLOR ); + mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION] = Vector2( DEFAULT_END_POSITION ); + mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = Vector4( DEFAULT_END_COLOR ); + mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER] = Vector2( DEFAULT_ROTATE_CENTER ); + mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT] = DEFAULT_ROTATE_AMOUNT; + // Default Offset value is very special. unlimited animation from 0.0f to 2.0f + { + Property::Map map; + map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::START, 0.0f ); + map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET, 2.0f ); + map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT, -1 ); + + mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET] = map; + } +} + +void AnimatedGradientVisual::DoSetProperties( const Property::Map& propertyMap ) +{ + //GRADIENT_TYPE + Property::Value* gradientTypeValue = propertyMap.Find( Toolkit::DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, GRADIENT_TYPE_NAME ); + Toolkit::DevelAnimatedGradientVisual::GradientType::Type gradientType = mGradientType; + if( gradientTypeValue ) + { + Scripting::GetEnumerationProperty( *gradientTypeValue, GRADIENT_TYPE_TABLE, GRADIENT_TYPE_TABLE_COUNT, gradientType ); + } + + //UNIT_TYPE + Property::Value* unitTypeValue = propertyMap.Find( Toolkit::DevelAnimatedGradientVisual::Property::UNIT_TYPE, UNIT_TYPE_NAME ); + Toolkit::DevelAnimatedGradientVisual::UnitType::Type unitType = mUnitType; + if( unitTypeValue ) + { + Scripting::GetEnumerationProperty( *unitTypeValue, UNIT_TYPE_TABLE, UNIT_TYPE_TABLE_COUNT, unitType ); + } + + //SPREAD_TYPE + Property::Value* spreadTypeValue = propertyMap.Find( Toolkit::DevelAnimatedGradientVisual::Property::SPREAD_TYPE, SPREAD_TYPE_NAME ); + Toolkit::DevelAnimatedGradientVisual::SpreadType::Type spreadType = mSpreadType; + if( spreadTypeValue ) + { + Scripting::GetEnumerationProperty( *spreadTypeValue, SPREAD_TYPE_TABLE, SPREAD_TYPE_TABLE_COUNT, spreadType ); + } + + mGradientType = gradientType; + mUnitType = unitType; + mSpreadType = spreadType; + + SetupGradientAnimationData(propertyMap); +} + +void AnimatedGradientVisual::SetupGradientAnimationData( const Property::Map& propertyMap ) +{ + mGradientAnimationDataList.Clear(); // Clear Transition Information. All animation will deleted safely + + static Property::Map propertyNameMap; + static Property::Map propertyUniformNameMap; + if( propertyNameMap.Empty() ) + { + propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION] = START_POSITION_NAME; + propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR ] = START_COLOR_NAME; + propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION ] = END_POSITION_NAME; + propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR ] = END_COLOR_NAME; + propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER ] = ROTATE_CENTER_NAME; + propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT ] = ROTATE_AMOUNT_NAME; + propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET ] = OFFSET_NAME; + } + if( propertyUniformNameMap.Empty() ) + { + propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION] = UNIFORM_START_POINT_NAME; + propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR ] = UNIFORM_START_COLOR_NAME; + propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION ] = UNIFORM_END_POINT_NAME; + propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR ] = UNIFORM_END_COLOR_NAME; + propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER ] = UNIFORM_ROTATE_CENTER_NAME; + propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT ] = UNIFORM_ROTATE_ANGLE_NAME; + propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET ] = UNIFORM_OFFSET_NAME; + } + + Property::Map::SizeType map_index_end = propertyNameMap.Count(); + for( Property::Map::SizeType map_index = 0; map_index < map_index_end; map_index++ ) + { + KeyValuePair property_pair = propertyNameMap.GetKeyValue( map_index ); + KeyValuePair uniform_pair = propertyUniformNameMap.GetKeyValue( map_index ); + Property::Index index = property_pair.first.indexKey; + const std::string property_name = property_pair.second.Get< std::string >(); + const std::string uniform_name = uniform_pair.second.Get< std::string >(); + + Property::Map map; + Property::Value default_value = mValueMap[index]; + + map["target"] = "background"; + map["property"] = uniform_name; + + Property::Value *value = propertyMap.Find( index, property_name ); + if( !value ) + { + value = &default_value; + } + else + { + // Update value list + mValueMap[index] = (*value); + } + + int loop_count = 0; + float delay = 0.0f; + bool forward = true; + bool auto_mirror = false; + std::string ease_str = "LINEAR"; + Property::Map *map_value = value->GetMap(); + if( map_value ) + { + auto getValueFromMap = [ &map_value ]( const Property::Index& index, const std::string& name, Property::Value& res ) -> void + { + Property::Value *sub_value = map_value->Find( index, name ); + if( sub_value ) + { + res = *sub_value; + } + }; + + Property::Value value_start = DEFAULT_ANIMATION_START_VALUE; + Property::Value value_target = DEFAULT_ANIMATION_TARGET_VALUE; + Property::Value value_duration = DEFAULT_ANIMATION_DURATION; + Property::Value value_delay = DEFAULT_ANIMATION_DELAY; + Property::Value value_repeat = DEFAULT_ANIMATION_REPEAT; + Property::Value value_repeat_delay = DEFAULT_ANIMATION_REPEAT_DELAY; + + getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::START , START_VALUE_NAME , value_start ); + getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET , TARGET_VALUE_NAME , value_target ); + getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION , DURATION_NAME , value_duration ); + getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY , DELAY_NAME , value_delay ); + getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT , REPEAT_NAME , value_repeat ); + getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, REPEAT_DELAY_NAME , value_repeat_delay ); + + Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::Type direction_type = DEFAULT_ANIMATION_DIRECTION_TYPE; + Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::Type motion_type = DEFAULT_ANIMATION_MOTION_TYPE; + Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::Type easing_type = DEFAULT_ANIMATION_EASING_TYPE; + + Property::Value *direction_sub_value = map_value->Find( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DIRECTION_TYPE_NAME ); + if( direction_sub_value ) + { + Scripting::GetEnumerationProperty( *direction_sub_value, DIRECTION_TYPE_TABLE, DIRECTION_TYPE_TABLE_COUNT, direction_type ); + } + Property::Value *motion_sub_value = map_value->Find( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, MOTION_TYPE_NAME ); + if( motion_sub_value ) + { + Scripting::GetEnumerationProperty( *motion_sub_value , MOTION_TYPE_TABLE , MOTION_TYPE_TABLE_COUNT , motion_type ); + } + Property::Value *easing_sub_value = map_value->Find( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, EASING_TYPE_NAME ); + if( easing_sub_value ) + { + Scripting::GetEnumerationProperty( *easing_sub_value , EASING_TYPE_TABLE , EASING_TYPE_TABLE_COUNT , easing_type ); + } + + forward = ( direction_type == Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD ); + delay = value_delay.Get< float >(); + loop_count = value_repeat.Get< int >(); + auto_mirror = ( motion_type == Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR ); + + switch( easing_type ) + { + case Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR: + { + ease_str = "LINEAR"; + break; + } + case Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN: + { + ease_str = "EASE_IN_SQUARE"; + break; + } + case Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::OUT: + { + ease_str = "EASE_OUT_SQUARE"; + break; + } + case Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN_OUT: + { + ease_str = "EASE_IN_OUT"; + break; + } + } + + map["initialValue"] = forward ? value_start : value_target; + map["targetValue"] = forward ? value_target : value_start; + if( loop_count != 0 ) + { + map["animator"] = Property::Map() + .Add( "alphaFunction", ease_str ) + .Add( "timePeriod", Property::Map() + .Add( "delay", value_repeat_delay.Get< float >() ) + .Add( "duration", value_duration.Get< float >() ) ); + } + } + else + { + map["initialValue"] = *value; + map["targetValue"] = *value; + } + + AnimatedGradientVisual::GradientAnimationData *animData = new AnimatedGradientVisual::GradientAnimationData(); + animData->transition = Toolkit::TransitionData::New( map ); + animData->index = index; + animData->loop_count = loop_count; + animData->delay = delay; + animData->forward = forward; + animData->auto_mirror = auto_mirror; + mGradientAnimationDataList.PushBack( animData ); + } +} + +void AnimatedGradientVisual::SetupAnimation() +{ + for( auto&& elem : mGradientAnimationDataList ) + { + Toolkit::TransitionData& transition = elem->transition; + Animation& animation = elem->animation; + int loop_count = elem->loop_count; + bool auto_mirror = elem->auto_mirror; + bool without_animation = ( loop_count == 0 ); + + const Internal::TransitionData& transitionData = Toolkit::GetImplementation( transition ); + for( auto iter = transitionData.Begin(); iter != transitionData.End(); iter++ ) + { + TransitionData::Animator *animator = (*iter); + AnimateProperty( animation, *animator ); + } + if( animation && !without_animation ) + { + if( loop_count < 0 ) + { + animation.SetLooping( true ); + } + else if( loop_count > 0 ) + { + animation.SetLoopCount( loop_count ); + } + if( auto_mirror ) + { + animation.SetLoopingMode( Animation::LoopingMode::AUTO_REVERSE ); + } + } + } +} + +void AnimatedGradientVisual::PlayAnimation() +{ + for( auto&& elem : mGradientAnimationDataList ) + { + Animation& animation = elem->animation; + if( animation ) + { + float delay = elem->delay; + if( delay > 0.0f ) + { + animation.PlayAfter( delay ); + } + else if( delay < 0.0f ) + { + float progress = -delay / animation.GetDuration(); // (duration + repeat_duration) + if(progress >= 1.0f) + { + int cur_loop = animation.GetLoopCount(); + int decrease_loop = floor( progress ) + 1; + while( decrease_loop > progress ) + { + decrease_loop--; + } + progress -= decrease_loop; + if( cur_loop == 0 ) + { + animation.PlayFrom( progress ); + } + else + { + cur_loop -= decrease_loop; + if( cur_loop > 0 ) + { + animation.SetLoopCount( cur_loop ); + animation.PlayFrom( progress ); + } + else + { + // animation done. make this animation finished safely. + animation.SetLoopCount( 1 ); + animation.PlayFrom( 1.0f ); + } + } + } + else + { + animation.PlayFrom( progress ); + } + } + else + { + animation.Play(); + } + } + } +} + +void AnimatedGradientVisual::StopAnimation() +{ + for( auto&& elem : mGradientAnimationDataList ) + { + Animation& animation = elem->animation; + if( animation ) + { + animation.Stop(); + } + } +} + +void AnimatedGradientVisual::OnSetTransform() +{ + if( mImpl->mRenderer ) + { + mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT ); + } +} + +void AnimatedGradientVisual::DoSetOnStage( Actor& actor ) +{ + InitializeRenderer(); + actor.AddRenderer( mImpl->mRenderer ); + SetupAnimation(); + PlayAnimation(); + + ResourceReady( Toolkit::Visual::ResourceStatus::READY ); +} + +void AnimatedGradientVisual::DoSetOffStage( Actor& actor ) +{ + DALI_ASSERT_DEBUG( (bool)mImpl->mRenderer && "There should always be a renderer whilst on stage"); + + StopAnimation(); + actor.RemoveRenderer( mImpl->mRenderer ); + mImpl->mRenderer.Reset(); +} + +void AnimatedGradientVisual::DoCreatePropertyMap( Property::Map& map ) const +{ + map.Clear(); + map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::ANIMATED_GRADIENT ); + + //Create non-animated properties + map.Insert( Toolkit::DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, static_cast(mGradientType) ); + map.Insert( Toolkit::DevelAnimatedGradientVisual::Property::UNIT_TYPE , static_cast(mUnitType) ); + map.Insert( Toolkit::DevelAnimatedGradientVisual::Property::SPREAD_TYPE , static_cast(mSpreadType) ); + + //Create animated properties. Get from transition for more realistic test. Not from animation cause Animation may not setuped + for( auto&& elem : mGradientAnimationDataList ) + { + Toolkit::TransitionData& transition = elem->transition; + Property::Index index = elem->index; + int loop_count = elem->loop_count; + float delay = elem->delay; + bool forward = elem->forward; + bool auto_mirror = elem->auto_mirror; + + const Internal::TransitionData& transitionData = Toolkit::GetImplementation( transition ); + for( auto iter = transitionData.Begin(); iter != transitionData.End(); iter++ ) + { + TransitionData::Animator *animator = (*iter); + if( animator->animate ) + { + //with animation + Property::Map animation_map; + Property::Value value_start = forward ? animator->initialValue : animator->targetValue; + Property::Value value_target = forward ? animator->targetValue : animator->initialValue; + Property::Value value_direction; + Property::Value value_duration = Property::Value( animator->timePeriodDuration ); + Property::Value value_delay = Property::Value( delay ); + Property::Value value_repeat = Property::Value( loop_count ); + Property::Value value_repeat_delay = Property::Value( animator->timePeriodDelay ); + Property::Value value_motion_type; + Property::Value value_easing_type; + + if( forward ) + { + value_direction = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD ); + } + else + { + value_direction = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD ); + } + if( auto_mirror ) + { + value_motion_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR ); + } + else + { + value_motion_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::LOOP ); + } + switch( animator->alphaFunction.GetBuiltinFunction() ) + { + case Dali::AlphaFunction::LINEAR: + { + value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR ); + break; + } + case Dali::AlphaFunction::EASE_IN_SQUARE: + { + value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN ); + break; + } + case Dali::AlphaFunction::EASE_OUT_SQUARE: + { + value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::OUT ); + break; + } + case Dali::AlphaFunction::EASE_IN_OUT: + { + value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN_OUT ); + break; + } + default: + { + value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR ); + } + } + + animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::START , value_start ); + animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET , value_target ); + animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION , value_direction ); + animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION , value_duration ); + animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY , value_delay ); + animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT , value_repeat ); + animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, value_repeat_delay ); + animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE , value_motion_type ); + animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE , value_easing_type ); + + map.Insert( index, animation_map ); + } + else + { + //without animation + map.Insert( index, animator->targetValue ); + } + } + } +} + +void AnimatedGradientVisual::DoCreateInstancePropertyMap( Property::Map& map ) const +{ + +} + +Shader AnimatedGradientVisual::CreateShader() +{ + Shader shader; + + std::string tagUnit; + std::string tagGrad; + std::string tagSpread; + switch( mUnitType ) + { + case Toolkit::DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX: + { + tagUnit = "UNIT_TYPE_BOUNDING_BOX"; + break; + } + case Toolkit::DevelAnimatedGradientVisual::UnitType::USER_SPACE: + { + tagUnit = "UNIT_TYPE_USER"; + break; + } + } + switch( mGradientType ) + { + case Toolkit::DevelAnimatedGradientVisual::GradientType::LINEAR: + { + tagGrad = "GRADIENT_TYPE_LINEAR"; + break; + } + case Toolkit::DevelAnimatedGradientVisual::GradientType::RADIAL: + { + tagGrad = "GRADIENT_TYPE_RADIAL"; + break; + } + } + switch( mSpreadType ) + { + case Toolkit::DevelAnimatedGradientVisual::SpreadType::REFLECT: + { + tagSpread = "SPREAD_TYPE_REFLECT"; + break; + } + case Toolkit::DevelAnimatedGradientVisual::SpreadType::REPEAT: + { + tagSpread = "SPREAD_TYPE_REPEAT"; + break; + } + case Toolkit::DevelAnimatedGradientVisual::SpreadType::CLAMP: + { + tagSpread = "SPREAD_TYPE_CLAMP"; + break; + } + } + + std::string vert; + std::string frag; + + vert = "#define " + tagUnit + "\n" + + BASIC_VERTEX_SHADER; + frag = "#define " + tagGrad + "\n" + + "#define " + tagSpread + "\n" + + BASIC_FRAGMENT_SHADER; + + shader = Shader::New( vert, frag ); + return shader; +} + +void AnimatedGradientVisual::InitializeRenderer() +{ + Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY ); + VisualFactoryCache::ShaderType shaderType = GetShaderType( mGradientType, mUnitType, mSpreadType ); + Shader shader = mFactoryCache.GetShader( shaderType ); + if( !shader ) + { + shader = CreateShader(); + mFactoryCache.SaveShader( shaderType, shader ); + } + + mImpl->mRenderer = Renderer::New( geometry, shader ); + + mImpl->mRenderer.RegisterProperty( UNIFORM_START_POINT_NAME , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, START_POSITION_NAME ) ); + mImpl->mRenderer.RegisterProperty( UNIFORM_START_COLOR_NAME , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR , START_COLOR_NAME ) ); + mImpl->mRenderer.RegisterProperty( UNIFORM_END_POINT_NAME , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION , END_POSITION_NAME ) ); + mImpl->mRenderer.RegisterProperty( UNIFORM_END_COLOR_NAME , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR , END_COLOR_NAME ) ); + mImpl->mRenderer.RegisterProperty( UNIFORM_ROTATE_CENTER_NAME, GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER , ROTATE_CENTER_NAME ) ); + mImpl->mRenderer.RegisterProperty( UNIFORM_ROTATE_ANGLE_NAME , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT , ROTATE_AMOUNT_NAME ) ); + mImpl->mRenderer.RegisterProperty( UNIFORM_OFFSET_NAME , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::OFFSET , OFFSET_NAME ) ); + + //Register transform properties + mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT ); +} + +}//namespace Internal + +}//namespace Toolkit + +}//namespace Dali diff --git a/dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h b/dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h new file mode 100755 index 0000000..ab480d9 --- /dev/null +++ b/dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h @@ -0,0 +1,281 @@ +#ifndef DALI_TOOLKIT_INTERNAL_ANIMATED_GRADIENT_VISUAL_H +#define DALI_TOOLKIT_INTERNAL_ANIMATED_GRADIENT_VISUAL_H + +/* + * Copyright (c) 2017 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. + * + */ + +//EXTERNAL INCLUDES +#include +#include +#include +#include + +//INTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ +class AnimatedGradientVisual; +typedef IntrusivePtr< AnimatedGradientVisual > AnimatedGradientVisualPtr; + +/** + * This visual which renders smooth transition of colors to the control's quad. + * There are two types of properties: non-animated property and animated property + * + * The following properties are non-animated property. + * + * | %Property Name | Type | Default | + * |----------------|--------------|---------------------------| + * | gradientType | GradientType | Linear | + * | unitType | UnitType | Object bounding box | + * | spreadType | SpreadType | Reflect | + * + * The following properties are animated property. + * + * | %Property Name | Type | Default | + * |----------------|------------------------------------------|---------------------------------| + * | startPosition | Vector2 or AnimationParameter< Vector2 > | (-0.5, 0) | + * | startColor | Vector4 or AnimationParameter< Vector4 > | (143., 170., 220., 255.) / 255. | + * | endPosition | Vector2 or AnimationParameter< Vector2 > | (0.5, 0) | + * | endColor | Vector4 or AnimationParameter< Vector4 > | (255., 163., 163., 255.) / 255. | + * | rotateCenter | Vector2 or AnimationParameter< Vector2 > | (0.0, 0.0) | + * | rotateAmount | Float or AnimationParameter< Float > | 0.0 | + * | offset | Float or AnimationParameter< Float > | (explain details below) | + * + * Each animated property can contain follow AnimationParameter + * + * | %AnimationParameter::Propery Name | Type | Default | + * |--------------------------------------|---------------|----------| + * | start | T | Zero | + * | target | T | Zero | + * | direction | DirectionType | Forward | + * | duration | Float | 3.0 | + * | delay | Float | 0.0 | + * | repeat | Integer | 0 | + * | repeat_delay | Float | 0.0 | + * | motion_type | MotionType | Loop | + * | easing_type | EasingType | Linear | + * + * T is animated property value's type. If property type is AnimationParameter< Vector2 >, start and target type is Vector2. + * + * + * gradientType decide the form of gradient + * unitType decide the coordinate of all positions + * spreadType decide how to make color where gradient_point is not 0 ~ 1 + * visualSize decide this visual's size hardly. only use when unitType is SCREEN + * + * startPoint and startColor decide position and color where gradient_point = 0. if gradientType is RADIAL, here is center of circle. + * endPoint and endColor decide position and color where gradient_point = 1. + * rotateCenter and rotateAmount are same job as its name + * rotateAmount is radian value + * + * offset is main feature of this visual. + * Image the points which has same gradient_point values. If gradientType is LINEAR, this form is line. If gradientTYPE IS RADIAL, this form is circle. + * without think about offset value, gradient_point = t color will be like this + * + * color(t) = startColor * (1-t) + endColor * t (0 <= t <= 1) + * + * so color be smooth changed when gradient_point change smooth. + * offset value change the color of gradient_point = t like this + * + * realColor(t) = color(t + offset) + * + * so If offset value increas (or decrease) gradient looks like "Flowing" effect + * default offset value is an unlimited simple loop animation from 0 to 2. duration is 3.0 second + * + * GradientType has two types : LINEAR / RADIAL + * LINEAR draw gradient linear form + * RADIAL draw gradietn circle form + * UnitType has two types : OBJECT_BOUNDING_BOX / USER_SPACE + * OBJECT_BOUNDING_BOX use normalized coordinate, relate by Actor bounding box. bottom-left ~ top-right : (-0.5,-0.5) ~ (0.5, 0.5) + * USER_SPACE use coordinate, relate by Actor Size. bottom-left ~ top-right : (ActorSize * -0.5) ~ (ActorSize * 0.5) + * SpreadType has three types : REFLECT / REPEAT / CLAMP + * REFLECT use mirror warping + * REPEAT use repeat warping + * CLAMP use clamp warping + * + * DirectionType has two types : FORWARD / BACKWARD + * FORWARD animate value from start to target + * BACKWARD animate value from target to start + * MotionType has two types : LOOP / MIRROR + * LOOP animate loopingmode restart + * MIRROR animate loopingmode auto_reverse + * EasingType has four types : LINEAR / IN / OUT / IN_OUT + * LINEAR easing animation linear + * IN easing in (slow start -> fast finish) + * OUT easing out (fast start -> slow finish) + * IN_OUT easing in and out (slow start -> slow finish) + */ +class AnimatedGradientVisual : public Visual::Base +{ +public: + + /** + * Animation informations what this visual using + */ + struct GradientAnimationData + { + GradientAnimationData() + : index( Property::INVALID_INDEX ), + loop_count( 0 ), + delay( 0.0f ), + forward( false ), + auto_mirror( false ) + { + } + + Toolkit::TransitionData transition; + Animation animation; + Property::Index index; + int loop_count; ///< if < 0, loop unlimited. else, loop loop_count times. + float delay; ///< delay time. if > 0, wait 'delay' seconds. else, play animation at '-delay' seconds. + bool forward; ///< True if AnimationParameter::DirectionType::Type is FORWARD + bool auto_mirror; ///< True if AnimationParameter::LoopType::Type is MIRROR + }; + + using GradientAnimationDataList = Dali::OwnerContainer< GradientAnimationData* >; + +public: + + /** + * @brief Create a new animated gradient visual. + * + * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + * @param[in] properties A Property::Map containing settings for this visual + * @return A smart-pointer to the newly allocated visual + */ + static AnimatedGradientVisualPtr New( VisualFactoryCache& factoryCache, const Property::Map& properties ); + +private: //from Visual + + /** + * @copydoc Visual::Base::CreatePropertyMap + */ + virtual void DoCreatePropertyMap( Property::Map& map ) const; + + /** + * @copydoc Visual::Base::CreateInstancePropertyMap + */ + virtual void DoCreateInstancePropertyMap( Property::Map& map ) const; + +protected: + + /** + * @brief Constructor. + * + * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + */ + AnimatedGradientVisual( VisualFactoryCache& factoryCache ); + + /** + * @brief A reference counted object may only be deleted by calling Unrefecence() + */ + virtual ~AnimatedGradientVisual(); + +protected: //from Visual + + /** + * @copydoc Visual::Base::DoSetProperties + */ + virtual void DoSetProperties( const Property::Map& propertyMap ); + + /** + * @copydoc Visual::Base::OnSetTransform + */ + virtual void OnSetTransform(); + + /** + * @copydoc Visual::Base::DoSetOnStage + */ + virtual void DoSetOnStage( Actor& actor ); + + /** + * @copydoc Visual::Base::DoSetOffStage + */ + virtual void DoSetOffStage( Actor& actor ); + +private: + + /** + * @brief Initialize the default value of properies. + */ + void SetupDefaultValue(); + + /** + * @brief Initialize the rendere with the geometry from the cache, and shader which made by CreateShader() + */ + void InitializeRenderer(); + + /** + * @brief Make animations with GradientAnimationData + */ + void SetupAnimation(); + + /** + * @brief Play animations + */ + void PlayAnimation(); + + /** + * @brief Stop animations + */ + void StopAnimation(); + + /** + * @brief Clear all previous GradientAnimationData and Setup new GradientAnimationData information which made by animated properties + * + * param[in] propertyMap A Property::Map come from DoSetProperties + */ + void SetupGradientAnimationData( const Property::Map& propertyMap ); + + /** + * @brief Create new shader + * + * return A Shader which made by non-animated properties + */ + Shader CreateShader(); + + // Undefined + AnimatedGradientVisual( const AnimatedGradientVisual& gradientRenderer ); + + // Undefined + AnimatedGradientVisual& operator=( const AnimatedGradientVisual& gradientRenderer ); + +private: + GradientAnimationDataList mGradientAnimationDataList; + Property::Map mValueMap; + + Dali::Toolkit::DevelAnimatedGradientVisual::GradientType::Type mGradientType; + Dali::Toolkit::DevelAnimatedGradientVisual::UnitType::Type mUnitType; + Dali::Toolkit::DevelAnimatedGradientVisual::SpreadType::Type mSpreadType; +}; + +}//namespace Internal + +}//namespace Toolkit + +}//namespace Dali + +#endif diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.h b/dali-toolkit/internal/visuals/visual-factory-cache.h index 75c949e..7f13da6 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.h +++ b/dali-toolkit/internal/visuals/visual-factory-cache.h @@ -74,6 +74,18 @@ public: TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE, TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI, TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI, + ANIMATED_GRADIENT_SHADER_LINEAR_BOUNDING_REFLECT, + ANIMATED_GRADIENT_SHADER_LINEAR_BOUNDING_REPEAT, + ANIMATED_GRADIENT_SHADER_LINEAR_BOUNDING_CLAMP, + ANIMATED_GRADIENT_SHADER_LINEAR_USER_REFLECT, + ANIMATED_GRADIENT_SHADER_LINEAR_USER_REPEAT, + ANIMATED_GRADIENT_SHADER_LINEAR_USER_CLAMP, + ANIMATED_GRADIENT_SHADER_RADIAL_BOUNDING_REFLECT, + ANIMATED_GRADIENT_SHADER_RADIAL_BOUNDING_REPEAT, + ANIMATED_GRADIENT_SHADER_RADIAL_BOUNDING_CLAMP, + ANIMATED_GRADIENT_SHADER_RADIAL_USER_REFLECT, + ANIMATED_GRADIENT_SHADER_RADIAL_USER_REPEAT, + ANIMATED_GRADIENT_SHADER_RADIAL_USER_CLAMP, WIREFRAME_SHADER, SHADER_TYPE_MAX = WIREFRAME_SHADER }; diff --git a/dali-toolkit/internal/visuals/visual-factory-impl.cpp b/dali-toolkit/internal/visuals/visual-factory-impl.cpp index 826de69..c368580 100644 --- a/dali-toolkit/internal/visuals/visual-factory-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-impl.cpp @@ -26,12 +26,14 @@ #include // INTERNAL INCLUDES +#include #include #include #include #include #include #include +#include #include #include #include @@ -88,7 +90,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property Visual::BasePtr visualPtr; Property::Value* typeValue = propertyMap.Find( Toolkit::Visual::Property::TYPE, VISUAL_TYPE ); - Toolkit::Visual::Type visualType = Toolkit::Visual::IMAGE; // Default to IMAGE type. + Toolkit::DevelVisual::Type visualType = Toolkit::DevelVisual::IMAGE; // Default to IMAGE type. if( typeValue ) { Scripting::GetEnumerationProperty( *typeValue, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT, visualType ); @@ -230,6 +232,12 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property } break; } + + case Toolkit::DevelVisual::ANIMATED_GRADIENT: + { + visualPtr = AnimatedGradientVisual::New( *( mFactoryCache.Get() ), propertyMap ); + break; + } } if( !visualPtr ) @@ -237,7 +245,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property DALI_LOG_ERROR( "Renderer type unknown\n" ); } - if( mDebugEnabled && visualType != Toolkit::Visual::WIREFRAME ) + if( mDebugEnabled && visualType != Toolkit::DevelVisual::WIREFRAME ) { //Create a WireframeVisual if we have debug enabled visualPtr = WireframeVisual::New( *( mFactoryCache.Get() ), visualPtr, propertyMap ); diff --git a/dali-toolkit/internal/visuals/visual-string-constants.cpp b/dali-toolkit/internal/visuals/visual-string-constants.cpp index e28a910..661e251 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.cpp +++ b/dali-toolkit/internal/visuals/visual-string-constants.cpp @@ -20,6 +20,7 @@ // INTERNAL INCLUDES #include +#include namespace Dali { @@ -42,6 +43,7 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, N_PATCH ) DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, SVG ) DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, ANIMATED_IMAGE ) DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, WIREFRAME ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelVisual, ANIMATED_GRADIENT ) DALI_ENUM_TO_STRING_TABLE_END( VISUAL_TYPE ) // Visual Type -- 2.7.4