Browse Source

Add border-radius support to gradient decorator

Michael Ragazzon 5 years ago
parent
commit
1908187884

+ 3 - 2
Samples/basic/demo/data/demo.rml

@@ -134,13 +134,14 @@ p.title
 #decorators button.gradient
 {
 	decorator: gradient( vertical #415857 #5990A3 );
-	border: 2px #415857;
+	border: 3px #415857;
+	border-radius: 8px;
 	margin-right: 12px;
 }
 #decorators button.gradient.horizontal
 {
 	decorator: gradient( horizontal #DB6565 #F1B58A );
-	border: 2px #DB6565;
+	border-color: #DB6565;
 }
 #decorators button.gradient:hover
 {

+ 34 - 17
Source/Core/DecoratorGradient.cpp

@@ -28,9 +28,10 @@
 
 #include "DecoratorGradient.h"
 #include "../../Include/RmlUi/Core/Element.h"
+#include "../../Include/RmlUi/Core/ElementUtilities.h"
 #include "../../Include/RmlUi/Core/Geometry.h"
 #include "../../Include/RmlUi/Core/GeometryUtilities.h"
-#include "../../Include/RmlUi/Core/ElementUtilities.h"
+#include "../../Include/RmlUi/Core/Math.h"
 #include "../../Include/RmlUi/Core/PropertyDefinition.h"
 
 /*
@@ -65,10 +66,19 @@ bool DecoratorGradient::Initialise(const Direction &dir_, const Colourb &start_,
 
 DecoratorDataHandle DecoratorGradient::GenerateElementData(Element* element) const
 {
-	auto *data = new Geometry(element);
-	Vector2f padded_size = element->GetBox().GetSize(Box::PADDING);
+	Geometry* geometry = new Geometry(element);
+	const Box& box = element->GetBox();
+
+	const ComputedValues& computed = element->GetComputedValues();
+	const float opacity = computed.opacity;
 
-	const float opacity = element->GetComputedValues().opacity;
+	const Vector4f border_radius{
+		computed.border_top_left_radius,
+		computed.border_top_right_radius,
+		computed.border_bottom_right_radius,
+		computed.border_bottom_left_radius,
+	};
+	GeometryUtilities::GenerateBackgroundBorder(geometry, element->GetBox(), border_radius, Colourb());
 
 	// Apply opacity
 	Colourb colour_start = start;
@@ -76,22 +86,29 @@ DecoratorDataHandle DecoratorGradient::GenerateElementData(Element* element) con
 	Colourb colour_stop = stop;
 	colour_stop.alpha = (byte)(opacity * (float)colour_stop.alpha);
 
-	auto &vertices = data->GetVertices();
-	vertices.resize(4);
+	const Vector2f padding_offset = box.GetPosition(Box::PADDING);
+	const Vector2f padding_size = box.GetSize(Box::PADDING);
 
-	auto &indices = data->GetIndices();
-	indices.resize(6);
+	Vector<Vertex>& vertices = geometry->GetVertices();
 
-	GeometryUtilities::GenerateQuad(&vertices[0], &indices[0], Vector2f(0, 0), padded_size, colour_start, 0);
-
-	if (dir == Direction::Horizontal) {
-		vertices[1].colour = vertices[2].colour = colour_stop;
-	} else if (dir == Direction::Vertical) {
-		vertices[2].colour = vertices[3].colour = colour_stop;
+	if (dir == Direction::Horizontal)
+	{
+		for (int i = 0; i < (int)vertices.size(); i++)
+		{
+			const float t = (vertices[i].position.x - padding_offset.x) / padding_size.x;
+			vertices[i].colour = Math::Lerp(Math::Clamp(t, 0.0f, 1.0f), colour_start, colour_stop);
+		}
+	}
+	else if (dir == Direction::Vertical)
+	{
+		for (int i = 0; i < (int)vertices.size(); i++)
+		{
+			const float t = (vertices[i].position.y - padding_offset.y) / padding_size.y;
+			vertices[i].colour = Math::Lerp(t, colour_start, colour_stop);
+		}
 	}
 
-	data->SetHostElement(element);
-	return reinterpret_cast<DecoratorDataHandle>(data);
+	return reinterpret_cast<DecoratorDataHandle>(geometry);
 }
 
 void DecoratorGradient::ReleaseElementData(DecoratorDataHandle element_data) const
@@ -102,7 +119,7 @@ void DecoratorGradient::ReleaseElementData(DecoratorDataHandle element_data) con
 void DecoratorGradient::RenderElement(Element* element, DecoratorDataHandle element_data) const
 {
 	auto* data = reinterpret_cast<Geometry*>(element_data);
-	data->Render(element->GetAbsoluteOffset(Box::PADDING).Round());
+	data->Render(element->GetAbsoluteOffset(Box::BORDER));
 }
 
 //=======================================================

+ 1 - 0
Tests/Data/VisualTests/border_radius.rml

@@ -19,6 +19,7 @@
 		.thin {
 			border-width: 10px 5px 25px 20px;
 			border-radius: 80px 30px;
+			decorator: gradient( horizontal #ff8400 #ffd34f );
 		}
 		.thick {
 			border-width: 40px 20px;

+ 5 - 1
changelog.md

@@ -72,10 +72,14 @@ Work has started on a complete test suite for RmlUi. The tests have been separat
 
 These changes may result in a differently rendered layout when upgrading to RmlUi 4.0. In particular the first item. If the changes are undesired, set a definite width on the related elements, eg. using the `width` property or the `left`/`right` properties.
 
+### New RCSS properties
+
+- The `border-radius` property is now supported in RmlUi for drawing rounded backgrounds and borders. The gradient decorator also adds support for this property.
+- Implemented the `word-break` RCSS property.
+
 ### Other features and improvements
 
 - Implemented `Element::QuerySelector` and `Element::QuerySelectorAll`.
-- Implemented the `word-break` RCSS property.
 - The `tab-index: auto` property can now be set on the `body` element to enable tabbing back to the document.
 - A custom configuration can now be used by RmlUi. In this way it is possible to replace several types including containers to other STL-compatible containers (such as [EASTL](https://github.com/electronicarts/EASTL)), or to STL containers with custom allocators. See the `CUSTOM_CONFIGURATION` [CMake option](https://mikke89.github.io/RmlUiDoc/pages/cpp_manual/building_with_cmake.html#cmake-options). [#110](https://github.com/mikke89/RmlUi/pull/110) (thanks @rokups).
 - Added ability to change the default base tag in documents [#112](https://github.com/mikke89/RmlUi/pull/112)  (thanks @aquawicket).