protected void UpdateSurroundings(IPanelGroupElement left, IPanelGroupElement top, IPanelGroupElement right, IPanelGroupElement bottom) { surroundings[(int)Direction.Left] = left; surroundings[(int)Direction.Top] = top; surroundings[(int)Direction.Right] = right; surroundings[(int)Direction.Bottom] = bottom; bool horizontal = IsInSameDirection(Direction.Right); for (int i = 0; i < elements.Count; i++) { if (horizontal) { left = i > 0 ? elements[i - 1] : surroundings[(int)Direction.Left]; right = i < elements.Count - 1 ? elements[i + 1] : surroundings[(int)Direction.Right]; } else { bottom = i > 0 ? elements[i - 1] : surroundings[(int)Direction.Bottom]; top = i < elements.Count - 1 ? elements[i + 1] : surroundings[(int)Direction.Top]; } PanelGroup subGroup = elements[i] as PanelGroup; if (subGroup != null) { subGroup.UpdateSurroundings(left, top, right, bottom); } else { ((Panel)elements[i]).Internal.UpdateSurroundings(left, top, right, bottom); } } }
protected virtual void EnsureMinimumSizeOf(IPanelGroupElement element) { float flexibleWidth = element.Size.x - element.MinSize.x; if (flexibleWidth < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, Direction.Right, -flexibleWidth); flexibleWidth = element.Size.x - element.MinSize.x; if (flexibleWidth < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, Direction.Left, -flexibleWidth); } } float flexibleHeight = element.Size.y - element.MinSize.y; if (flexibleHeight < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, Direction.Bottom, -flexibleHeight); flexibleHeight = element.Size.y - element.MinSize.y; if (flexibleHeight < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, Direction.Top, -flexibleHeight); } } PanelGroup subGroup = element as PanelGroup; if (subGroup != null) { subGroup.Internal.EnsureMinimumSize(); } }
private void ResizeAnchoredPanelsRecursively(PanelGroup group, Dictionary <Panel, Vector2> initialSizes) { if (group == null) { return; } int count = group.Count; for (int i = 0; i < count; i++) { Panel panel = group[i] as Panel; if (panel != null) { Vector2 initialSize; if (initialSizes.TryGetValue(panel, out initialSize)) { panel.ResizeTo(initialSize, Direction.Right, Direction.Top); } } else { ResizeAnchoredPanelsRecursively(group[i] as PanelGroup, initialSizes); } } }
private void InitializeRootGroup() { dummyPanel = PanelUtils.Internal.CreatePanel(null, this); dummyPanel.gameObject.name = "DummyPanel"; dummyPanel.CanvasGroup.alpha = 0f; dummyPanel.Internal.SetDummy(minimumFreeSpace); RootPanelGroup = new PanelGroup(this, Direction.Right); RootPanelGroup.AddElement(dummyPanel); }
protected void SetDirty() { isDirty = true; PanelGroup parentGroup = Group; while (parentGroup != null) { parentGroup.isDirty = true; parentGroup = parentGroup.Group; } Canvas.SetDirty(); }
public void AnchorPanel(IPanelGroupElement source, DynamicPanelsCanvas canvas, Direction anchorDirection) { PanelGroup rootGroup = canvas.RootPanelGroup; PanelGroup tempGroup = new PanelGroup(canvas, Direction.Right); for (int i = 0; i < rootGroup.Count; i++) { if (rootGroup[i].Group == rootGroup) { tempGroup.AddElement(rootGroup[i]); } } rootGroup.AddElement(tempGroup); AnchorPanel(source, tempGroup, anchorDirection); }
protected void SetGroupFor(IPanelGroupElement element, PanelGroup group) { Panel panel = element as Panel; if (panel != null) { panel.Internal.Group = group; if (panel.RectTransform.parent != group.Canvas.RectTransform) { panel.RectTransform.SetParent(group.Canvas.RectTransform, false); } } else { ((PanelGroup)element).Group = group; } }
private bool PanelGroupHasAnyOtherPanels(PanelGroup group, Panel panel) { for (int i = 0; i < group.Count; i++) { if (group[i] is Panel) { Panel _panel = (Panel)group[i]; if (_panel != panel && _panel != canvas.dummyPanel) { return(true); } } else if (PanelGroupHasAnyOtherPanels((PanelGroup)group[i], panel)) { return(true); } } return(false); }
protected override void UpdateLayout() { bool wasDirty = isDirty; base.UpdateLayout(); if (wasDirty) { for (int i = elements.Count - 1; i >= 0; i--) { PanelGroup subGroup = elements[i] as PanelGroup; if (subGroup != null) { elements.RemoveAt(i); for (int j = 0; j < subGroup.Count; j++, i++) { elements.Insert(i, subGroup[j]); SetGroupFor(elements[i], this); } } } } }
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); } } }
public InternalSettings(PanelGroup group) { this.group = group; }
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; } }
private static IPanelGroupElement Deserialize(DynamicPanelsCanvas canvas, ISerializedElement element) { if (element == null) { return(null); } if (element is SerializedDummyPanel) { return(canvas.Internal.DummyPanel); } if (element is SerializedPanel) { SerializedPanel serializedPanel = (SerializedPanel)element; Panel panel = null; SerializedPanelTab[] tabs = serializedPanel.tabs; for (int i = 0; i < tabs.Length; i++) { PanelTab tab; if (!PanelNotificationCenter.TryGetTab(tabs[i].id, out tab)) { continue; } if (panel == null) { panel = tab.Detach(); canvas.UnanchoredPanelGroup.AddElement(panel); } else { panel.AddTab(tab); } //if( tab != null ) //{ // tab.MinSize = tabs[i].minSize; // tab.Label = tabs[i].label; //} } if (panel != null) { if (serializedPanel.activeTab < tabs.Length) { int activeTabIndex = panel.GetTabIndex(tabs[serializedPanel.activeTab].id); if (activeTabIndex >= 0) { panel.ActiveTab = activeTabIndex; } } if (serializedPanel is SerializedUnanchoredPanel) { SerializedUnanchoredPanel unanchoredPanel = (SerializedUnanchoredPanel)serializedPanel; panel.RectTransform.anchoredPosition = unanchoredPanel.position; panel.gameObject.SetActive(unanchoredPanel.active); } panel.FloatingSize = serializedPanel.floatingSize; } return(panel); } if (element is SerializedPanelGroup) { SerializedPanelGroup serializedPanelGroup = (SerializedPanelGroup)element; ISerializedElement[] children = serializedPanelGroup.children; if (children == null || children.Length == 0) { return(null); } PanelGroup panelGroup = new PanelGroup(canvas, serializedPanelGroup.horizontal ? Direction.Right : Direction.Top); for (int i = 0; i < children.Length; i++) { if (children[i] == null) { continue; } IPanelGroupElement childElement = Deserialize(canvas, children[i]); if (childElement != null) { panelGroup.AddElement(childElement); sizesHolder.Add(new GroupElementSizeHolder(childElement, children[i].size)); } } if (panelGroup.Count > 0) { return(panelGroup); } } return(null); }
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 }); }
public static void DeserializeCanvasFromArray(DynamicPanelsCanvas canvas, byte[] data) { #if UNITY_EDITOR if (!Application.isPlaying) { Debug.LogError("Can deserialize in Play mode only!"); return; } #endif if (data == null || data.Length == 0) { Debug.LogError("Data is null!"); return; } SerializedCanvas serializedCanvas; BinaryFormatter formatter = new BinaryFormatter(); using (MemoryStream stream = new MemoryStream(data)) { serializedCanvas = formatter.Deserialize(stream) as SerializedCanvas; } if (serializedCanvas == null) { return; } sizesHolder.Clear(); canvas.LeaveFreeSpace = serializedCanvas.useFreeSpace; if (serializedCanvas.rootPanelGroup != null) { PanelGroup rootPanelGroup = canvas.RootPanelGroup; ISerializedElement[] children = serializedCanvas.rootPanelGroup.children; for (int i = children.Length - 1; i >= 0; i--) { IPanelGroupElement element = Deserialize(canvas, children[i]); if (element != null) { if (rootPanelGroup.Count == 0) { rootPanelGroup.AddElement(element); } else { rootPanelGroup.AddElementBefore(rootPanelGroup[0], element); } sizesHolder.Insert(0, new GroupElementSizeHolder(element, children[i].size)); } } } if (sizesHolder.Count > 0) { canvas.ForceRebuildLayoutImmediate(); for (int i = 0; i < sizesHolder.Count; i++) { sizesHolder[i].element.ResizeTo(sizesHolder[i].size, Direction.Right, Direction.Top); } } if (serializedCanvas.unanchoredPanelGroup != null) { ISerializedElement[] children = serializedCanvas.unanchoredPanelGroup.children; for (int i = 0; i < children.Length; i++) { SerializedUnanchoredPanel unanchoredPanel = children[i] as SerializedUnanchoredPanel; if (unanchoredPanel != null) { Panel panel = Deserialize(canvas, unanchoredPanel) as Panel; if (panel != null) { panel.Detach(); canvas.UnanchoredPanelGroup.RestrictPanelToBounds(panel); } } } } for (int i = 0; i < canvas.UnanchoredPanelGroup.Count; i++) { Panel panel = canvas.UnanchoredPanelGroup[i] as Panel; if (panel != null) { panel.RectTransform.SetAsLastSibling(); } } canvas.gameObject.SetActive(serializedCanvas.active); }