Browse Source

Fix for stackoverflow in when using DataGridTrees

Lloyd Weehuizen 15 years ago
parent
commit
429e8e4eac
3 changed files with 50 additions and 11 deletions
  1. 6 1
      Source/Core/ElementDocument.cpp
  2. 38 9
      Source/Core/ElementStyle.cpp
  3. 6 1
      Source/Core/ElementStyle.h

+ 6 - 1
Source/Core/ElementDocument.cpp

@@ -299,7 +299,9 @@ void ElementDocument::UpdateLayout()
 		if (lock_layout)
 			return;
 
-		layout_dirty = false;
+		lock_layout = true;
+		
+		GetStyle()->UpdateDefinition();
 
 		Vector2f containing_block(0, 0);
 		if (GetParentNode() != NULL)
@@ -307,6 +309,9 @@ void ElementDocument::UpdateLayout()
 
 		LayoutEngine layout_engine;
 		layout_engine.FormatElement(this, containing_block);
+		
+		layout_dirty = false;
+		lock_layout = false;
 	}
 }
 

+ 38 - 9
Source/Core/ElementStyle.cpp

@@ -51,6 +51,7 @@ ElementStyle::ElementStyle(Element* _element)
 	element = _element;
 
 	definition_dirty = true;
+	child_definition_dirty = true;
 }
 
 ElementStyle::~ElementStyle()
@@ -67,40 +68,60 @@ const ElementDefinition* ElementStyle::GetDefinition()
 {
 	if (definition_dirty)
 	{
-		definition_dirty = false;
+		UpdateDefinition();
+	}
 
+	return definition;
+}
+	
+void ElementStyle::UpdateDefinition()
+{
+	if (definition_dirty)
+	{
+		definition_dirty = false;
+		
 		ElementDefinition* new_definition = NULL;
-
+		
 		const StyleSheet* style_sheet = GetStyleSheet();
 		if (style_sheet != NULL)
 		{
 			new_definition = style_sheet->GetElementDefinition(element);
 		}
-
+		
 		// Switch the property definitions if the definition has changed.
 		if (new_definition != definition || new_definition == NULL)
 		{
 			PropertyNameList properties;
-
+			
 			if (definition != NULL)
 			{
 				definition->GetDefinedProperties(properties, pseudo_classes);
 				definition->RemoveReference();
 			}
-
+			
 			definition = new_definition;
-
+			
 			if (definition != NULL)
 				definition->GetDefinedProperties(properties, pseudo_classes);
-
+			
 			DirtyProperties(properties);
 			element->GetElementDecoration()->ReloadDecorators();
 		}
 		else if (new_definition != NULL)
+		{
 			new_definition->RemoveReference();
+		}
+	}
+	
+	if (child_definition_dirty)
+	{
+		for (int i = 0; i < element->GetNumChildren(true); i++)
+		{
+			element->GetChild(i)->GetStyle()->UpdateDefinition();
+		}
+		
+		child_definition_dirty = false;
 	}
-
-	return definition;
 }
 
 // Sets or removes a pseudo-class on the element.
@@ -408,6 +429,14 @@ void ElementStyle::DirtyDefinition()
 {
 	definition_dirty = true;
 	DirtyChildDefinitions();
+	
+	// Dirty the child definition update the element tree
+	Element* parent = element->GetParentNode();
+	while (parent)
+	{
+		parent->GetStyle()->child_definition_dirty = true;
+		parent = parent->GetParentNode();
+	}
 }
 
 void ElementStyle::DirtyChildDefinitions()

+ 6 - 1
Source/Core/ElementStyle.h

@@ -49,6 +49,9 @@ public:
 
 	/// Returns the element's definition, updating if necessary.
 	const ElementDefinition* GetDefinition();
+	
+	/// Update this definition if required
+	void UpdateDefinition();
 
 	/// Sets or removes a pseudo-class on the element.
 	/// @param[in] pseudo_class The pseudo class to activate or deactivate.
@@ -149,7 +152,9 @@ private:
 	// The definition of this element; if this is NULL one will be fetched from the element's style.
 	ElementDefinition* definition;
 	// Set if a new element definition should be fetched from the style.
-	bool definition_dirty;	
+	bool definition_dirty;
+	// Set if a child element has a dirty style definition
+	bool child_definition_dirty;
 };
 
 }