END_TEST;
}
+
+int UtcDaliGradientAnimateTest(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliGradientAnimateTest");
+
+ Control control = Control::New();
+ control[Actor::Property::SIZE] = Vector2(200.f, 200.f);
+
+ // Linear Gradient
+ Dali::Property::Map map;
+ map.Insert(Toolkit::Visual::Property::TYPE, Visual::GRADIENT);
+ Property::Array stopOffsets;
+ stopOffsets.PushBack(0.0f);
+ stopOffsets.PushBack(0.5f);
+ stopOffsets.PushBack(1.0f);
+ map.Insert(GradientVisual::Property::STOP_OFFSET, stopOffsets);
+ Property::Array stopColors;
+ stopColors.PushBack(Vector4(1.0f, 0.0f, 0.0f, 1.0f));
+ stopColors.PushBack(Vector4(0.8f, 1.0f, 0.0f, 1.0f));
+ stopColors.PushBack(Vector4(0.0f, 0.0f, 1.0f, 1.0f));
+ map.Insert(GradientVisual::Property::STOP_COLOR, stopColors);
+ map.Insert(GradientVisual::Property::SPREAD_METHOD, GradientVisual::SpreadMethod::REPEAT);
+ map.Insert(GradientVisual::Property::START_POSITION, Vector2(-100.f, -100.f));
+ map.Insert(GradientVisual::Property::END_POSITION, Vector2(100.f, 100.f));
+ map.Insert(GradientVisual::Property::START_OFFSET, 0.5f);
+
+ control[Dali::Toolkit::Control::Property::BACKGROUND] = map;
+
+ Dali::Property property1 = DevelControl::GetVisualProperty(control, Control::Property::BACKGROUND, GradientVisual::Property::START_OFFSET);
+ DALI_TEST_EQUALS(property1.object.GetProperty(property1.propertyIndex).Get<float>(), 0.5f, TEST_LOCATION);
+
+ Animation animation = Animation::New(1.0f);
+ animation.AnimateTo(DevelControl::GetVisualProperty(control, Control::Property::BACKGROUND, GradientVisual::Property::START_OFFSET), 1.0f);
+ animation.Play();
+
+ application.SendNotification();
+ application.Render(0); // Ensure animation starts
+ application.Render(1001u); // A Cycle
+
+ Dali::Property property2 = DevelControl::GetVisualProperty(control, Control::Property::BACKGROUND, GradientVisual::Property::START_OFFSET);
+ DALI_TEST_EQUALS(property2.object.GetProperty(property2.propertyIndex).Get<float>(), 1.0f, TEST_LOCATION);
+
+ END_TEST;
+}
\ No newline at end of file
{
// scale factor to fit start and end position of gradient.
UNIFORM highp float uTextureCoordinateScaleFactor;
+ UNIFORM highp float uGradientOffset;
UNIFORM lowp vec4 uColor;
#ifdef IS_REQUIRED_BORDERLINE
{
#ifdef RADIAL
mediump float radialTexCoord = ((length(vTexCoord) - 0.5) * uTextureCoordinateScaleFactor) + 0.5;
- lowp vec4 textureColor = TEXTURE(sTexture, vec2(radialTexCoord, 0.5)) * uColor;
+ lowp vec4 textureColor = TEXTURE(sTexture, vec2(radialTexCoord + uGradientOffset, 0.5)) * uColor;
#else
- lowp vec4 textureColor = TEXTURE(sTexture, vec2(vTexCoord.y, 0.5)) * uColor;
+ lowp vec4 textureColor = TEXTURE(sTexture, vec2(vTexCoord.y + uGradientOffset, 0.5)) * uColor;
#endif
#if defined(IS_REQUIRED_ROUNDED_CORNER) || defined(IS_REQUIRED_BORDERLINE)
// uniform names
static constexpr std::string_view UNIFORM_ALIGNMENT_MATRIX_NAME("uAlignmentMatrix");
static constexpr std::string_view UNIFORM_TEXTURE_COORDINATE_SCALE_FACTOR_NAME("uTextureCoordinateScaleFactor");
+static constexpr std::string_view UNIFORM_START_OFFSET_NAME("uGradientOffset");
// default offset value
static constexpr float DEFAULT_OFFSET_MINIMUM = 0.0f;
float textureSize = static_cast<float>(lookupTexture.GetWidth());
mImpl->mRenderer.RegisterUniqueProperty(UNIFORM_TEXTURE_COORDINATE_SCALE_FACTOR_NAME, (textureSize - 1.0f) / textureSize);
+ float startOffset = mGradient->GetStartOffset();
+ mStartOffsetIndex = mImpl->mRenderer.RegisterUniqueProperty(Toolkit::GradientVisual::Property::START_OFFSET, UNIFORM_START_OFFSET_NAME, startOffset);
+
// Register transform properties
mImpl->SetTransformUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
}
}
}
+ Property::Value* startOffset = propertyMap.Find(Toolkit::GradientVisual::Property::START_OFFSET, START_OFFSET_NAME);
+ float startOffsetValue;
+ if(startOffset && startOffset->Get(startOffsetValue))
+ {
+ mGradient->SetStartOffset(startOffsetValue);
+ }
+
return true;
}
Matrix3 mGradientTransform;
IntrusivePtr<Gradient> mGradient;
Type mGradientType;
+ Dali::Property::Index mStartOffsetIndex;
bool mIsOpaque; ///< Set to false if any of the stop colors are not opaque
};
namespace
{
// The maximum width of the lookup texture ( it is a 1-dimension texture with the height as 1 )
-const unsigned int MAXIMUM_TEXTURE_RESOLUTION(128u);
+const uint32_t MAXIMUM_TEXTURE_RESOLUTION(512u);
} // namespace
namespace Dali
{
Gradient::Gradient()
: mGradientUnits(Toolkit::GradientVisual::Units::OBJECT_BOUNDING_BOX),
- mSpreadMethod(Toolkit::GradientVisual::SpreadMethod::PAD)
+ mSpreadMethod(Toolkit::GradientVisual::SpreadMethod::PAD),
+ mStartOffset(0.f)
{
}
unsigned int Gradient::EstimateTextureResolution()
{
- float minInterval = 1.0;
- const uint32_t numStops = mGradientStops.Count();
- DALI_ASSERT_ALWAYS(numStops > 0u && "The number of gradient stop should not be zero!");
- for(uint32_t i = 0; i < numStops - 1u; i++)
- {
- float interval = mGradientStops[i + 1].mOffset - mGradientStops[i].mOffset;
- minInterval = interval > minInterval ? minInterval : interval;
- }
- // Use at least three pixels for each segment between two stops
- unsigned int resolution = static_cast<int>(3.f / (minInterval + Math::MACHINE_EPSILON_100) + 0.5f);
- // Clamp the resolution to handle the overlapping stops
- if(resolution > MAXIMUM_TEXTURE_RESOLUTION)
- {
- return MAXIMUM_TEXTURE_RESOLUTION;
- }
+ return MAXIMUM_TEXTURE_RESOLUTION;
+}
- return resolution;
+void Gradient::SetStartOffset(float startOffset)
+{
+ mStartOffset = startOffset;
+}
+
+float Gradient::GetStartOffset() const
+{
+ return mStartOffset;
}
} // namespace Internal
*/
Dali::Texture GenerateLookupTexture();
+ /**
+ * Sets the gradient's start position offset.
+ * @param[in] startOffset The start offset.
+ * @note 0.0 is start position of gradient, 1.0 is end position of gradient.
+ * It is possible to set the startOffset outside the [0, 1] range.
+ * For example, you can animate it from 0.5 to 1.5.
+ */
+ void SetStartOffset(float startOffset);
+
+ /**
+ * Retrieves the gradient's start position offset.
+ * @return The start offset
+ */
+ float GetStartOffset() const;
+
private:
/**
* Estimate the resolution of the lookup texture.
Matrix3 mAlignmentTransform;
Toolkit::GradientVisual::Units::Type mGradientUnits;
Toolkit::GradientVisual::SpreadMethod::Type mSpreadMethod;
+ float mStartOffset;
};
} // namespace Internal
const char* const STOP_COLOR_NAME("stopColor"); // Property::Array VECTOR4
const char* const UNITS_NAME("units"); // Property::String "userSpaceOnUse | objectBoundingBox"
const char* const SPREAD_METHOD_NAME("spreadMethod"); // Property::String "pad | reflect | repeat"
+const char* const START_OFFSET_NAME("startOffset"); // Property::FLOAT
//mesh visual
const char* const OBJECT_URL_NAME("objectUrl");
extern const char* const STOP_COLOR_NAME; // Property::Array VECTOR4
extern const char* const UNITS_NAME; // Property::String "userSpaceOnUse | objectBoundingBox"
extern const char* const SPREAD_METHOD_NAME; // Property::String "pad | reflect | repeat"
+extern const char* const START_OFFSET_NAME; // Property::FLOAT
//mesh visual
extern const char* const OBJECT_URL_NAME;
* @note Optional. If not supplied, default is SpreadMethod::PAD.
* @see SpreadMethod::Type
*/
- SPREAD_METHOD
+ SPREAD_METHOD,
+
+ /**
+ * @brief The offset value that shifts the starting position of the gradient.
+ * @details Name "startOffset", type Property::FLOAT.
+ * @SINCE_2_4.17
+ * @note Optional. If not supplied, default is 0.
+ */
+ START_OFFSET
};
} // namespace Property