Browse Source

Add a virtual method on elements for responding to recompilation of style sheets. Eg. new style sheets may change sprites, such as in decorators and img elements.

Michael Ragazzon 4 years ago
parent
commit
742894e123

+ 6 - 4
Include/RmlUi/Core/Element.h

@@ -416,7 +416,7 @@ public:
 	/// Gets this element's parent node.
 	/// @return This element's parent.
 	Element* GetParentNode() const;
-	/// Recursively search for a ancestor of this node matching the given selector.
+	/// Recursively search for the first ancestor of this node matching the given selector.
 	/// @param[in] selectors The selector or comma-separated selectors to match against.
 	/// @return The ancestor if found, or nullptr if no ancestor could be matched.
 	/// @performance Prefer GetElementById/TagName/ClassName whenever possible.
@@ -607,6 +607,8 @@ protected:
 	virtual void OnLayout();
 	/// Called when the 'dp'-ratio has been changed.
 	virtual void OnDpRatioChange();
+	/// Called when the current document's compiled style sheet has been changed. This may result in changed sprites.
+	virtual void OnStyleSheetChange();
 
 	/// Called when attributes on the element are changed.
 	/// @param[in] changed_attributes Dictionary of attributes changed on the element. Attribute value will be empty if it was unset.
@@ -644,9 +646,9 @@ protected:
 
 	void SetOwnerDocument(ElementDocument* document);
 
-	void Release() override;
+	void OnStyleSheetChangeRecursive();
 
-	void DirtyDecoratorsRecursive();
+	void Release() override;
 
 private:
 	void SetParent(Element* parent);
@@ -668,7 +670,7 @@ private:
 	void DirtyTransformState(bool perspective_dirty, bool transform_dirty);
 	void UpdateTransformState();
 
-	void DirtyDpRatio();
+	void OnDpRatioChangeRecursive();
 
 	/// Start an animation, replacing any existing animations of the same property name. If start_value is null, the element's current value is used.
 	ElementAnimationList::iterator StartAnimation(PropertyId property_id, const Property * start_value, int num_iterations, bool alternate_direction, float delay, bool initiated_by_animation_property);

+ 1 - 1
Include/RmlUi/Core/ElementDocument.h

@@ -160,7 +160,7 @@ private:
 	/// Returns true if the document has been marked as needing a re-layout.
 	bool IsLayoutDirty() override;
 
-	/// Notify the document that media query related properties have changed and that stylesheets need to be re-evaluated.
+	/// Notify the document that media query related properties have changed and that style sheets need to be re-evaluated.
 	void DirtyMediaQueries();
 
 	/// Updates all sizes defined by the 'vw' and the 'vh' units.

+ 1 - 1
Source/Core/Context.cpp

@@ -153,7 +153,7 @@ void Context::SetDensityIndependentPixelRatio(float _density_independent_pixel_r
 			if (document)
 			{
 				document->DirtyMediaQueries();
-				document->DirtyDpRatio();
+				document->OnDpRatioChangeRecursive();
 			}
 		}
 	}

+ 14 - 8
Source/Core/Element.cpp

@@ -1649,6 +1649,10 @@ void Element::OnDpRatioChange()
 {
 }
 
+void Element::OnStyleSheetChange()
+{
+}
+
 // Called when attributes on the element are changed.
 void Element::OnAttributeChange(const ElementAttributes& changed_attributes)
 {
@@ -2799,27 +2803,29 @@ void Element::UpdateTransformState()
 	}
 }
 
-void Element::DirtyDpRatio()
+void Element::OnStyleSheetChangeRecursive()
 {
 	GetElementDecoration()->DirtyDecorators();
-	GetStyle()->DirtyPropertiesWithUnits(Property::DP);
 
-	OnDpRatioChange();
+	OnStyleSheetChange();
 
-	// Now dirty all of our descendant's properties that use the unit.
+	// Now dirty all of our descendants.
 	const int num_children = GetNumChildren(true);
 	for (int i = 0; i < num_children; ++i)
-		GetChild(i)->DirtyDpRatio();
+		GetChild(i)->OnStyleSheetChangeRecursive();
 }
 
-void Element::DirtyDecoratorsRecursive()
+void Element::OnDpRatioChangeRecursive()
 {
 	GetElementDecoration()->DirtyDecorators();
+	GetStyle()->DirtyPropertiesWithUnits(Property::DP);
+
+	OnDpRatioChange();
 
-	// Now dirty all of our descendant decorators as well.
+	// Now dirty all of our descendants.
 	const int num_children = GetNumChildren(true);
 	for (int i = 0; i < num_children; ++i)
-		GetChild(i)->DirtyDecoratorsRecursive();
+		GetChild(i)->OnDpRatioChangeRecursive();
 }
 
 } // namespace Rml

+ 1 - 1
Source/Core/ElementDocument.cpp

@@ -240,7 +240,7 @@ void ElementDocument::DirtyMediaQueries()
 		if (changed_style_sheet)
 		{
 			GetStyle()->DirtyDefinition();
-			DirtyDecoratorsRecursive();
+			OnStyleSheetChangeRecursive();
 		}
 	}
 }

+ 9 - 0
Source/Core/Elements/ElementImage.cpp

@@ -163,6 +163,15 @@ void ElementImage::OnDpRatioChange()
 	DirtyLayout();
 }
 
+void ElementImage::OnStyleSheetChange()
+{
+	if (HasAttribute("sprite"))
+	{
+		texture_dirty = true;
+		DirtyLayout();
+	}
+}
+
 void ElementImage::GenerateGeometry()
 {
 	// Release the old geometry before specifying the new vertices.

+ 3 - 0
Source/Core/Elements/ElementImage.h

@@ -85,6 +85,9 @@ protected:
 	/// Our intrinsic dimensions may change with the dp-ratio.
 	void OnDpRatioChange() override;
 
+	/// The sprite may have changed when the style sheet is recompiled.
+	void OnStyleSheetChange() override;
+
 	/// Checks for changes to the image's source or dimensions.
 	/// @param[in] changed_attributes A list of attributes changed on the element.
 	void OnAttributeChange(const ElementAttributes& changed_attributes) override;