Browse Source

Data bindings: Add 'data-attrif' view. See #121.

Michael Ragazzon 5 years ago
parent
commit
5a655abbfa

+ 4 - 3
Samples/basic/databinding/data/databinding.rml

@@ -192,7 +192,7 @@ form h2 {
 	<h1 data-if="invaders.size == 0">It's all safe and sound, sir!</h1>
 </panel>
 <tab>Forms</tab>
-<panel id="controls">
+<panel id="controls" data-model="forms">
 	<h1>Todo</h1>
 	<form onsubmit="submit_form">
 		<h2>Full name</h2>
@@ -213,13 +213,14 @@ form h2 {
 		</div>
 		<h2>Favorite meals</h2>
 		<div>
-			<input type="checkbox" name="meals" value="pizza" checked/> Pizza
+			<input type="checkbox" name="meals" value="pizza" data-attrif-checked="rating > 70" disabled/> Pizza
 			<input type="checkbox" name="meals" value="pasta" checked/> Pasta
 			<input type="checkbox" name="meals" value="lasagne" checked/> Lasagne
+			<p data-visible="rating < 70">You can only have pizza if the rating is satisfactory.</p>
 		</div>
 		<h2>Rating</h2>
 		<div>
-			<input type="range" name="rating" min="0" max="100" step="1" value="50" onchange="rating"/> <span id="rating"/><span id="rating_emoji">&nbsp;</span>
+			<input type="range" name="rating" min="0" max="100" step="1" value="50" onchange="rating" data-value="rating"/> <span id="rating">{{rating}}</span><span id="rating_emoji">&nbsp;</span>
 		</div>
 		<h2>Subject</h2>
 		<div>

+ 28 - 0
Samples/basic/databinding/src/main.cpp

@@ -281,6 +281,32 @@ namespace InvadersExample {
 	}
 }
 
+namespace FormsExample {
+
+	Rml::DataModelHandle model_handle;
+
+	struct MyData {
+		int rating = 50;
+	} my_data;
+
+	bool Initialize(Rml::Context* context)
+	{
+		Rml::DataModelConstructor constructor = context->CreateDataModel("forms");
+		if (!constructor)
+			return false;
+
+		constructor.Bind("rating", &my_data.rating);
+
+		model_handle = constructor.GetModelHandle();
+
+		return true;
+	}
+
+	void Update()
+	{
+		model_handle.Update();
+	}
+}
 
 
 class DemoWindow : public Rml::EventListener
@@ -354,6 +380,7 @@ void GameLoop()
 	BasicExample::Update();
 	EventsExample::Update();
 	InvadersExample::Update(t);
+	FormsExample::Update();
 
 	context->Update();
 
@@ -411,6 +438,7 @@ int main(int RMLUI_UNUSED_PARAMETER(argc), char** RMLUI_UNUSED_PARAMETER(argv))
 		|| !BasicExample::Initialize(context)
 		|| !EventsExample::Initialize(context)
 		|| !InvadersExample::Initialize(context)
+		|| !FormsExample::Initialize(context)
 		)
 	{
 		Rml::Shutdown();

+ 29 - 1
Source/Core/DataViewDefault.cpp

@@ -36,7 +36,7 @@
 
 namespace Rml {
 
-DataViewCommon::DataViewCommon(Element* element, String override_modifier) : DataView(element), modifier(override_modifier)
+DataViewCommon::DataViewCommon(Element* element, String override_modifier) : DataView(element), modifier(std::move(override_modifier))
 {}
 
 bool DataViewCommon::Initialize(DataModel& model, Element* element, const String& expression_str, const String& in_modifier)
@@ -101,6 +101,34 @@ bool DataViewAttribute::Update(DataModel& model)
 }
 
 
+DataViewAttributeIf::DataViewAttributeIf(Element* element) : DataViewCommon(element)
+{}
+
+bool DataViewAttributeIf::Update(DataModel& model)
+{
+	const String& attribute_name = GetModifier();
+	bool result = false;
+	Variant variant;
+	Element* element = GetElement();
+	DataExpressionInterface expr_interface(&model, element);
+
+	if (element && GetExpression().Run(expr_interface, variant))
+	{
+		const bool value = variant.Get<bool>();
+		const bool is_set = static_cast<bool>(element->GetAttribute(attribute_name));
+		if (is_set != value)
+		{
+			if (value)
+				element->SetAttribute(attribute_name, String());
+			else
+				element->RemoveAttribute(attribute_name);
+			result = true;
+		}
+	}
+	return result;
+}
+
+
 DataViewValue::DataViewValue(Element* element) : DataViewAttribute(element, "value")
 {}
 

+ 6 - 1
Source/Core/DataViewDefault.h

@@ -70,13 +70,18 @@ public:
 	bool Update(DataModel& model) override;
 };
 
+class DataViewAttributeIf final : public DataViewCommon {
+public:
+	DataViewAttributeIf(Element* element);
+
+	bool Update(DataModel& model) override;
+};
 
 class DataViewValue final : public DataViewAttribute {
 public:
 	DataViewValue(Element* element);
 };
 
-
 class DataViewStyle final : public DataViewCommon {
 public:
 	DataViewStyle(Element* element);

+ 2 - 0
Source/Core/Factory.cpp

@@ -170,6 +170,7 @@ struct DefaultInstancers {
 
 	// Data binding views
 	DataViewInstancerDefault<DataViewAttribute> data_view_attribute;
+	DataViewInstancerDefault<DataViewAttributeIf> data_view_attribute_if;
 	DataViewInstancerDefault<DataViewClass> data_view_class;
 	DataViewInstancerDefault<DataViewIf> data_view_if;
 	DataViewInstancerDefault<DataViewVisible> data_view_visible;
@@ -259,6 +260,7 @@ bool Factory::Initialise()
 
 	// Data binding views
 	RegisterDataViewInstancer(&default_instancers->data_view_attribute,      "attr",    false);
+	RegisterDataViewInstancer(&default_instancers->data_view_attribute_if,   "attrif",  false);
 	RegisterDataViewInstancer(&default_instancers->data_view_class,          "class",   false);
 	RegisterDataViewInstancer(&default_instancers->data_view_if,             "if",      false);
 	RegisterDataViewInstancer(&default_instancers->data_view_visible,        "visible", false);