namespace Sandbox.UI; public partial class Panel { int? LastOrder; internal void UpdateOrder() { if ( ComputedStyle.Order == LastOrder ) return; LastOrder = ComputedStyle.Order; Parent?.DirtyChildrenOrder(); } bool NeedsOrderSort; internal void DirtyChildrenOrder() { NeedsOrderSort = true; } internal void SortChildrenOrder() { if ( !NeedsOrderSort ) return; NeedsOrderSort = false; if ( _children == null ) return; foreach ( var child in _children.OrderBy( x => x.LastOrder ?? 0 ).ThenBy( x => x.SiblingIndex ) ) { if ( child.YogaNode is null ) continue; YogaNode.RemoveChild( child.YogaNode ); YogaNode.AddChild( child.YogaNode ); } } /// /// Move this panel to be after the given sibling. /// public void MoveAfterSibling( Panel previousSibling ) { if ( Parent == null ) throw new ArgumentException( "Can't move after sibling if we have no parent" ); if ( previousSibling.Parent != this.Parent ) throw new ArgumentException( "previousSibling doesn't share a parent with us" ); if ( Parent.IndexesDirty ) Parent.UpdateChildrenIndexes(); // already okay if ( previousSibling.SiblingIndex == SiblingIndex - 1 ) return; Parent.SetChildIndex( this, previousSibling.SiblingIndex ); } /// /// Move given child panel to be given index, where 0 is the first child. /// public void SetChildIndex( Panel child, int newIndex ) { if ( child.Parent != this ) throw new ArgumentException( "Can't set child index - it's not our child!" ); if ( child.SiblingIndex == newIndex && newIndex < _children.Count && _children[newIndex] == child ) return; newIndex = Math.Clamp( newIndex, 0, _children.Count - 1 ); if ( child.YogaNode != null ) { YogaNode?.RemoveChild( child.YogaNode ); YogaNode?.AddChild( newIndex, child.YogaNode ); } // Log.Info( $"{child.ElementName} Set Index To {newIndex} [si:{child.SiblingIndex}] [i:{_children.IndexOf( child )}]" ); _children.Remove( child ); _children.Insert( newIndex, child ); child.UpdateSiblingIndex( newIndex, _children.Count ); IndexesDirty = true; Assert.Equals( child.SiblingIndex, newIndex ); } }