private void UpdateSubTree(VisualElement root) { Rect yogaRect = new Rect(root.yogaNode.LayoutX, root.yogaNode.LayoutY, root.yogaNode.LayoutWidth, root.yogaNode.LayoutHeight); Rect lastRect = root.renderData.lastLayout; bool rectChanged = lastRect != yogaRect; // If the last layout rect is different than the current one we must dirty transform on children if (rectChanged) { if (yogaRect.position != lastRect.position) { root.IncrementVersion(VersionChangeType.Transform); } root.IncrementVersion(VersionChangeType.Clip); root.renderData.lastLayout = yogaRect; } // ignore clean sub trees bool hasNewLayout = root.yogaNode.HasNewLayout; if (hasNewLayout) { for (int i = 0; i < root.shadow.childCount; ++i) { UpdateSubTree(root.shadow[i]); } } if (rectChanged) { using (var evt = GeometryChangedEvent.GetPooled(lastRect, yogaRect)) { evt.target = root; root.SendEvent(evt); } } if (hasNewLayout) { root.yogaNode.MarkLayoutSeen(); // Layout change require a repaint root.IncrementVersion(VersionChangeType.Repaint); } }
public void Insert(int index, VisualElement child) { if (child == null) { throw new ArgumentException("Cannot insert null child"); } if (index > childCount) { throw new IndexOutOfRangeException("Index out of range: " + index); } if (child == m_Owner) { throw new ArgumentException("Cannot insert element as its own child"); } child.RemoveFromHierarchy(); child.shadow.SetParent(m_Owner); if (m_Owner.m_Children == null) { //TODO: Trigger a release on finalizer or something, this means we'll need to make the pool thread-safe as well m_Owner.m_Children = VisualElementListPool.Get(); } if (m_Owner.yogaNode.IsMeasureDefined) { m_Owner.yogaNode.SetMeasureFunction(null); } PutChildAtIndex(child, index); child.SetEnabledFromHierarchy(m_Owner.enabledInHierarchy); child.IncrementVersion(VersionChangeType.Hierarchy); m_Owner.IncrementVersion(VersionChangeType.Hierarchy); }