Browse Source

Merge pull request #53 from Qfusion/gradient_decorator

Implement gradient decorator
Michael R. P. Ragazzon 6 years ago
parent
commit
b138ec3a13

+ 2 - 0
CMake/FileList.cmake

@@ -13,6 +13,7 @@ set(Core_HDR_FILES
     ${PROJECT_SOURCE_DIR}/Source/Core/ComputeProperty.h
     ${PROJECT_SOURCE_DIR}/Source/Core/ContextInstancerDefault.h
     ${PROJECT_SOURCE_DIR}/Source/Core/DebugFont.h
+    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorGradient.h
     ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorNinePatch.h
     ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiled.h
     ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiledBox.h
@@ -215,6 +216,7 @@ set(Core_SRC_FILES
     ${PROJECT_SOURCE_DIR}/Source/Core/ConvolutionFilter.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/Core.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/Decorator.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorGradient.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorInstancer.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorNinePatch.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiled.cpp

+ 3 - 1
Include/RmlUi/Core/ElementInstancer.h

@@ -111,8 +111,10 @@ class ElementInstancerGeneric : public ElementInstancer
 public:
 	virtual ~ElementInstancerGeneric() {}
 
-	ElementPtr InstanceElement(Element* parent, const String& tag, const XMLAttributes& attributes) override 
+	ElementPtr InstanceElement(Element* RMLUI_UNUSED_PARAMETER(parent), const String& tag, const XMLAttributes& RMLUI_UNUSED_PARAMETER(attributes)) override
 	{
+		RMLUI_UNUSED(parent);
+		RMLUI_UNUSED(attributes);
 		RMLUI_ZoneScopedN("ElementGenericInstance");
 		return ElementPtr(new T(tag));
 	}

+ 134 - 0
Source/Core/DecoratorGradient.cpp

@@ -0,0 +1,134 @@
+/*
+ * This source file is part of RmlUi, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://github.com/mikke89/RmlUi
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ * Copyright (c) 2019 The RmlUi Team, and contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "precompiled.h"
+#include "DecoratorGradient.h"
+#include "../../Include/RmlUi/Core/Element.h"
+#include "../../Include/RmlUi/Core/Geometry.h"
+#include "../../Include/RmlUi/Core/ElementUtilities.h"
+
+/*
+Gradient decorator usage in CSS:
+
+decorator: gradient( direction start-color stop-color );
+
+direction: horizontal|vertical;
+start-color: #ff00ff;
+stop-color: #00ff00;
+*/
+
+namespace Rml {
+namespace Core {
+
+//=======================================================
+
+DecoratorGradient::DecoratorGradient()
+{
+}
+
+DecoratorGradient::~DecoratorGradient()
+{
+}
+
+bool DecoratorGradient::Initialise(const Direction &dir_, const Colourb &start_, const Colourb & stop_)
+{
+	dir = dir_;
+	start = start_;
+	stop = stop_;
+	return true;
+}
+
+DecoratorDataHandle DecoratorGradient::GenerateElementData(Element* element) const
+{
+	auto *data = new Rml::Core::Geometry(element);
+	Vector2f padded_size = element->GetBox().GetSize(Rml::Core::Box::PADDING);
+
+	auto &vertices = data->GetVertices();
+	vertices.resize(4);
+
+	auto &indices = data->GetIndices();
+	indices.resize(6);
+
+	Rml::Core::GeometryUtilities::GenerateQuad(&vertices[0], &indices[0], Vector2f(0, 0), padded_size, start, 0);
+
+	if (dir == Direction::Horizontal) {
+		vertices[1].colour = vertices[2].colour = stop;
+	} else if (dir == Direction::Vertical) {
+		vertices[2].colour = vertices[3].colour = stop;
+	}
+
+	data->SetHostElement(element);
+	return reinterpret_cast<DecoratorDataHandle>(data);
+}
+
+void DecoratorGradient::ReleaseElementData(DecoratorDataHandle element_data) const
+{
+	delete reinterpret_cast<Rml::Core::Geometry*>(element_data);
+}
+
+void DecoratorGradient::RenderElement(Element* element, DecoratorDataHandle element_data) const
+{
+	auto* data = reinterpret_cast<Rml::Core::Geometry*>(element_data);
+	data->Render(element->GetAbsoluteOffset(Rml::Core::Box::PADDING).Round());
+}
+
+//=======================================================
+
+DecoratorGradientInstancer::DecoratorGradientInstancer()
+{
+	// register properties for the decorator
+	ids.direction = RegisterProperty("direction", "horizontal").AddParser("keyword", "horizontal, vertical").GetId();
+	ids.start = RegisterProperty("start-color", "#ffffff").AddParser("color").GetId();
+	ids.stop = RegisterProperty("stop-color", "#ffffff").AddParser("color").GetId();
+	RegisterShorthand("decorator", "direction, start-color, stop-color", Rml::Core::ShorthandType::FallThrough);
+}
+
+DecoratorGradientInstancer::~DecoratorGradientInstancer()
+{
+}
+
+std::shared_ptr<Rml::Core::Decorator> DecoratorGradientInstancer::InstanceDecorator(const String & RMLUI_UNUSED_PARAMETER(name), const PropertyDictionary& properties_,
+	const Rml::Core::DecoratorInstancerInterface& RMLUI_UNUSED_PARAMETER(interface_))
+{
+	RMLUI_UNUSED(name);
+	RMLUI_UNUSED(interface_);
+
+	DecoratorGradient::Direction dir = (DecoratorGradient::Direction)properties_.GetProperty(ids.direction)->Get< int >();
+	Colourb start = properties_.GetProperty(ids.start)->Get<Colourb>();
+	Colourb stop = properties_.GetProperty(ids.stop)->Get<Colourb>();
+
+	auto decorator = std::make_shared<DecoratorGradient>();
+	if (decorator->Initialise(dir, start, stop)) {
+		return decorator;
+	}
+
+	return nullptr;
+}
+
+}
+}

+ 80 - 0
Source/Core/DecoratorGradient.h

@@ -0,0 +1,80 @@
+/*
+ * This source file is part of RmlUi, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://github.com/mikke89/RmlUi
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ * Copyright (c) 2019 The RmlUi Team, and contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef RMLUICOREDECORATORGRADIENT_H
+#define RMLUICOREDECORATORGRADIENT_H
+
+#include "../../Include/RmlUi/Core/Decorator.h"
+#include "../../Include/RmlUi/Core/DecoratorInstancer.h"
+#include "../../Include/RmlUi/Core/Property.h"
+
+namespace Rml {
+namespace Core {
+
+class DecoratorGradient : public Decorator
+{
+public:
+	enum class Direction { Horizontal = 0, Vertical = 1 };
+
+	DecoratorGradient();
+	virtual ~DecoratorGradient();
+
+	bool Initialise(const Direction &dir_, const Colourb &start_, const Colourb & stop_);
+
+	DecoratorDataHandle GenerateElementData(Element* element) const override;
+	void ReleaseElementData(DecoratorDataHandle element_data) const override;
+
+	void RenderElement(Element* element, DecoratorDataHandle element_data) const override;
+
+private:
+	Direction dir;
+	Colourb start, stop;
+};
+
+
+
+class DecoratorGradientInstancer : public DecoratorInstancer
+{
+public:
+	DecoratorGradientInstancer();
+	~DecoratorGradientInstancer();
+
+	SharedPtr<Decorator> InstanceDecorator(const String& name, const PropertyDictionary& properties, const DecoratorInstancerInterface& interface) override;
+
+private:
+	struct GradientPropertyIds {
+		Rml::Core::PropertyId direction, start, stop;
+	};
+	GradientPropertyIds ids;
+
+};
+
+}
+}
+
+#endif

+ 3 - 0
Source/Core/Factory.cpp

@@ -35,6 +35,7 @@
 #include "DecoratorTiledImageInstancer.h"
 #include "DecoratorTiledVerticalInstancer.h"
 #include "DecoratorNinePatch.h"
+#include "DecoratorGradient.h"
 #include "ElementHandle.h"
 #include "ElementImage.h"
 #include "ElementTextDefault.h"
@@ -95,6 +96,7 @@ struct DefaultInstancers {
 	Ptr<DecoratorInstancer> decorator_tiled_box = std::make_unique<DecoratorTiledBoxInstancer>();
 	Ptr<DecoratorInstancer> decorator_image = std::make_unique<DecoratorTiledImageInstancer>();
 	Ptr<DecoratorInstancer> decorator_ninepatch = std::make_unique<DecoratorNinePatchInstancer>();
+	Ptr<DecoratorInstancer> decorator_gradient = std::make_unique<DecoratorGradientInstancer>();
 
 	Ptr<FontEffectInstancer> font_effect_shadow = std::make_unique<FontEffectShadowInstancer>();
 	Ptr<FontEffectInstancer> font_effect_outline = std::make_unique<FontEffectOutlineInstancer>();
@@ -147,6 +149,7 @@ bool Factory::Initialise()
 	RegisterDecoratorInstancer("tiled-box", default_instancers->decorator_tiled_box.get());
 	RegisterDecoratorInstancer("image", default_instancers->decorator_image.get());
 	RegisterDecoratorInstancer("ninepatch", default_instancers->decorator_ninepatch.get());
+	RegisterDecoratorInstancer("gradient", default_instancers->decorator_gradient.get());
 
 	RegisterFontEffectInstancer("shadow", default_instancers->font_effect_shadow.get());
 	RegisterFontEffectInstancer("outline", default_instancers->font_effect_outline.get());