Browse Source

Decorators now properly renders (just need to update stylesheets)

Michael Ragazzon 6 years ago
parent
commit
e9a6bfb153

+ 4 - 1
Include/Rocket/Core/PropertySpecification.h

@@ -76,7 +76,7 @@ public:
 			return it->second;
 		return ID::Invalid;
 	}
-	const String& GetName(ID id)
+	const String& GetName(ID id) const
 	{
 		if (static_cast<size_t>(id) < name_map.size())
 			return name_map[static_cast<size_t>(id)];
@@ -204,6 +204,9 @@ public:
 	/// @param dictionary[in] The dictionary to set the default values on.
 	void SetPropertyDefaults(PropertyDictionary& dictionary) const;
 
+	/// Returns the properties of dictionary converted to a string.
+	String PropertiesToString(const PropertyDictionary& dictionary) const;
+
 private:
 	typedef std::vector< PropertyDefinition* > Properties;
 	typedef std::vector< ShorthandDefinition* > Shorthands;

+ 2 - 1
Source/Core/ElementDecoration.cpp

@@ -110,7 +110,8 @@ void ElementDecoration::RenderDecorators()
 	}
 
 	// Render the decorators attached to this element in its current state.
-	for (size_t i = 0; i < decorators.size(); i++)
+	// Render from back to front for correct render order.
+	for (int i = (int)decorators.size() - 1; i >= 0; i--)
 	{
 		DecoratorHandle& decorator = decorators[i];
 		decorator.decorator->RenderElement(element, decorator.decorator_data);

+ 10 - 12
Source/Core/Factory.cpp

@@ -355,32 +355,30 @@ const PropertySpecification* Factory::GetDecoratorPropertySpecification(const St
 // Attempts to instance a decorator from an instancer registered with the factory.
 Decorator* Factory::InstanceDecorator(const String& name, const PropertyDictionary& properties)
 {
+	// TODO: z-index, specificity no longer part of decorator
 	float z_index = 0;
 	int specificity = -1;
 
 	auto iterator = decorator_instancers.find(name);
 	if (iterator == decorator_instancers.end())
-		return NULL;
+		return nullptr;
 
 	DecoratorInstancer* instancer = iterator->second;
 
 	// Turn the generic, un-parsed properties we've got into a properly parsed dictionary.
 	const PropertySpecification& property_specification = instancer->GetPropertySpecification();
 
-	PropertyDictionary parsed_properties;
-	for (PropertyMap::const_iterator i = properties.GetProperties().begin(); i != properties.GetProperties().end(); ++i)
+	// Verify all properties set
+	if((size_t)properties.GetNumProperties() != property_specification.GetRegisteredProperties().size())
 	{
-		specificity = Math::Max(specificity, (*i).second.specificity);
-
-		property_specification.ParsePropertyDeclaration(parsed_properties, (*i).first, (*i).second.value.Get< String >(), (*i).second.source, (*i).second.source_line_number);
+		// If this occurs, call e.g. property_specification.SetPropertyDefaults(properties) before instancing decorator.
+		Log::Message(Log::LT_WARNING, "Some properties were not defined while instancing decorator '%s', make sure non-set properties are set to their default values.", name.c_str());
+		return nullptr;
 	}
 
-	// Set the property defaults for all unset properties.
-	property_specification.SetPropertyDefaults(parsed_properties);
-
-	Decorator* decorator = instancer->InstanceDecorator(name, parsed_properties);
-	if (decorator == NULL)
-		return NULL;
+	Decorator* decorator = instancer->InstanceDecorator(name, properties);
+	if (!decorator)
+		return nullptr;
 
 	decorator->SetZIndex(z_index);
 	decorator->SetSpecificity(specificity);

+ 10 - 0
Source/Core/PropertySpecification.cpp

@@ -361,6 +361,16 @@ void PropertySpecification::SetPropertyDefaults(PropertyDictionary& dictionary)
 	}
 }
 
+String PropertySpecification::PropertiesToString(const PropertyDictionary& dictionary) const
+{
+	String result;
+	for (auto& pair : dictionary.GetProperties())
+	{
+		result += property_map.GetName(pair.first) + ": " + pair.second.ToString() + '\n';
+	}
+	return result;
+}
+
 
 bool PropertySpecification::ParsePropertyValues(StringList& values_list, const String& values, bool split_values) const
 {

+ 3 - 0
Source/Core/StyleSheetParser.cpp

@@ -205,6 +205,9 @@ bool StyleSheetParser::ParseDecoratorBlock(DecoratorSpecificationMap& decorator_
 	if (!ReadProperties(properties, *property_specification))
 		return false;
 
+	// Set non-defined properties to their defaults
+	property_specification->SetPropertyDefaults(properties);
+
 	Decorator* decorator = Factory::InstanceDecorator(decorator_type, properties);
 	if (!decorator)
 	{