protected virtual void UpdateLayout() { if (isDirty) { elements.RemoveAll((element) => element.IsNull() || element.Group != this); for (int i = elements.Count - 1; i >= 0; i--) { PanelGroup subGroup = elements[i] as PanelGroup; if (subGroup != null) { subGroup.UpdateLayout(); int count = subGroup.Count; if (count == 0) { elements.RemoveAt(i); } else if (count == 1) { elements[i] = subGroup.elements[0]; SetGroupFor(elements[i], this); i++; } else if (subGroup.IsInSameDirection(direction)) { elements.RemoveAt(i); elements.InsertRange(i, subGroup.elements); for (int j = 0; j < count; j++, i++) { SetGroupFor(elements[i], this); } } } } Vector2 size = Vector2.zero; Vector2 minSize = Vector2.zero; bool horizontal = IsInSameDirection(Direction.Right); int dummyPanelIndex = -1; for (int i = 0; i < elements.Count; i++) { Vector2 elementSize = elements[i].Size; Vector2 elementMinSize = elements[i].MinSize; // Rescue elements whose sizes are stuck at 0 bool rescueElement = false; if (elementSize.x == 0f && elementMinSize.x > 0f) { elementSize.x = Mathf.Min(1f, elementMinSize.x); rescueElement = true; } if (elementSize.y == 0f && elementMinSize.y > 0f) { elementSize.y = Mathf.Min(1f, elementMinSize.y); rescueElement = true; } if (rescueElement) { UpdateBoundsOf(elements[i], elements[i].Position, elementSize); } if (i == 0) { size = elementSize; minSize = elementMinSize; } else { if (horizontal) { size.x += elementSize.x; minSize.x += elementMinSize.x; if (elementSize.y < size.y) { size.y = elementSize.y; } if (elementMinSize.y > minSize.y) { minSize.y = elementMinSize.y; } } else { size.y += elementSize.y; minSize.y += elementMinSize.y; if (elementSize.x < size.x) { size.x = elementSize.x; } if (elementMinSize.x > minSize.x) { minSize.x = elementMinSize.x; } } } if (elements[i] is Panel && ((Panel)elements[i]).Internal.IsDummy) { dummyPanelIndex = i; } } if (dummyPanelIndex >= 0) { Vector2 flexibleSpace = Vector2.zero; if (size.x < Size.x) { flexibleSpace.x = Size.x - size.x; size.x = Size.x; } if (size.y < Size.y) { flexibleSpace.y = Size.y - size.y; size.y = Size.y; } ((Panel)elements[dummyPanelIndex]).RectTransform.sizeDelta += flexibleSpace; } Size = size; MinSize = minSize; isDirty = false; } }
public void AnchorPanel(IPanelGroupElement source, IPanelGroupElement anchor, Direction anchorDirection) { PanelGroup group = anchor.Group; if (group is UnanchoredPanelGroup) { Debug.LogError("Can not anchor to an unanchored panel!"); return; } Vector2 size; Panel panel = source as Panel; if (panel != null) { size = panel.IsDocked ? panel.FloatingSize : panel.Size; } else { ((PanelGroup)source).Internal.UpdateLayout(); size = source.Size; } // Fill the whole anchored area in order not to break other elements' sizes on layout update if (anchorDirection == Direction.Left || anchorDirection == Direction.Right) { if (anchor.Size.y > 0f) { size.y = anchor.Size.y; } } else { if (anchor.Size.x > 0f) { size.x = anchor.Size.x; } } if (panel != null) { panel.RectTransform.sizeDelta = size; } else { ((PanelGroup)source).Internal.UpdateBounds(source.Position, size); } bool addElementAfter = anchorDirection == Direction.Right || anchorDirection == Direction.Top; if (group.IsInSameDirection(anchorDirection)) { if (addElementAfter) { group.AddElementAfter(anchor, source); } else { group.AddElementBefore(anchor, source); } } else { IPanelGroupElement element1, element2; if (addElementAfter) { element1 = anchor; element2 = source; } else { element1 = source; element2 = anchor; } PanelGroup newGroup = new PanelGroup(anchor.Canvas, anchorDirection); newGroup.AddElement(element1); newGroup.AddElement(element2); group.Internal.ReplaceElement(anchor, newGroup); } if (panel != null) { if (draggedPanel == panel) { draggedPanel = null; } panel.RectTransform.SetAsFirstSibling(); if (panel.Internal.ContentScrollRect != null) { panel.Internal.ContentScrollRect.OnDrag(nullPointerEventData); } } }
private static ISerializedElement Serialize(IPanelGroupElement element) { if (element == null) { return(null); } if (element is Panel) { Panel panel = (Panel)element; if (panel.Internal.IsDummy) { return new SerializedDummyPanel() { size = panel.Size } } ; tabsTemp.Clear(); for (int i = 0; i < panel.NumberOfTabs; i++) { PanelTab tab = panel[i]; tabsTemp.Add(new SerializedPanelTab() { id = tab.ID, //minSize = tab.MinSize, //label = tab.Label }); } if (tabsTemp.Count == 0) { return(null); } if (panel.IsDocked) { return(new SerializedPanel() { activeTab = panel.ActiveTab, tabs = tabsTemp.ToArray(), size = panel.Size, floatingSize = panel.FloatingSize }); } else { return(new SerializedUnanchoredPanel() { active = panel.gameObject.activeSelf, activeTab = panel.ActiveTab, tabs = tabsTemp.ToArray(), position = panel.Position, size = panel.Size, floatingSize = panel.Size }); } } PanelGroup panelGroup = (PanelGroup)element; ISerializedElement[] children = new ISerializedElement[panelGroup.Count]; for (int i = 0; i < panelGroup.Count; i++) { children[i] = Serialize(panelGroup[i]); } return(new SerializedPanelGroup() { horizontal = panelGroup.IsInSameDirection(Direction.Right), children = children, size = panelGroup.Size }); }