protected virtual void EnsureMinimumSizeOf(IPanelGroupElement element) { float flexibleWidth = element.Size.x - element.MinSize.x; if (flexibleWidth < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, PanelDirection.Right, -flexibleWidth); flexibleWidth = element.Size.x - element.MinSize.x; if (flexibleWidth < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, PanelDirection.Left, -flexibleWidth); } } float flexibleHeight = element.Size.y - element.MinSize.y; if (flexibleHeight < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, PanelDirection.Bottom, -flexibleHeight); flexibleHeight = element.Size.y - element.MinSize.y; if (flexibleHeight < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, PanelDirection.Top, -flexibleHeight); } } if (element is PanelGroup subGroup) { subGroup.Internal.EnsureMinimumSize(); } }
protected void ReplaceElement(IPanelGroupElement beforeElement, IPanelGroupElement afterElement) { if (beforeElement == afterElement) { return; } if (beforeElement.IsNull() || afterElement.IsNull()) { Debug.LogError("Invalid argument!"); return; } int index = elements.IndexOf(beforeElement); if (index < 0) { Debug.LogError("Invalid index!"); return; } if (beforeElement.Group == this) { Canvas.UnanchoredPanelGroup.AddElement(beforeElement); } AddElementAt(index, afterElement); }
protected void TryChangeSizeOf(IPanelGroupElement element, PanelDirection direction, float deltaSize) { if (element.IsNull() || deltaSize <= MIN_SIZE_TOLERANCE || element.GetSurroundingElement(direction).IsNull()) { return; } resizePropsIndex = 0; IPanelGroupElement surroundingElement = element.GetSurroundingElement(direction); element = surroundingElement.GetSurroundingElement(direction.Opposite()); AddResizeProperty(element); float deltaMovement = TryChangeSizeOfInternal(surroundingElement, direction, deltaSize); if (resizePropsIndex > 1) { ResizeElementHelper(0, direction, deltaMovement); for (int i = 0; i < resizePropsIndex; i++) { ElementDirtyProperties properties = resizeProperties[i]; Vector2 position = properties.element.Position + new Vector2(properties.posX, properties.posY); Vector2 size = properties.element.Size + new Vector2(properties.sizeX, properties.sizeY); UpdateBoundsOf(properties.element, position, size); } } }
protected void UpdateSurroundings(IPanelGroupElement left, IPanelGroupElement top, IPanelGroupElement right, IPanelGroupElement bottom) { surroundings[(int)PanelDirection.Left] = left; surroundings[(int)PanelDirection.Top] = top; surroundings[(int)PanelDirection.Right] = right; surroundings[(int)PanelDirection.Bottom] = bottom; bool horizontal = IsInSameDirection(PanelDirection.Right); for (int i = 0; i < elements.Count; i++) { if (horizontal) { left = i > 0 ? elements[i - 1] : surroundings[(int)PanelDirection.Left]; right = i < elements.Count - 1 ? elements[i + 1] : surroundings[(int)PanelDirection.Right]; } else { bottom = i > 0 ? elements[i - 1] : surroundings[(int)PanelDirection.Bottom]; top = i < elements.Count - 1 ? elements[i + 1] : surroundings[(int)PanelDirection.Top]; } if (elements[i] is PanelGroup subGroup) { subGroup.UpdateSurroundings(left, top, right, bottom); } else { ((Panel)elements[i]).Internal.UpdateSurroundings(left, top, right, bottom); } } }
protected void ResizeElementTo(IPanelGroupElement element, Vector2 newSize, Direction horizontalDir, Direction verticalDir) { if (horizontalDir != Direction.Left && horizontalDir != Direction.Right) { horizontalDir = Direction.Right; } if (verticalDir != Direction.Bottom && verticalDir != Direction.Top) { verticalDir = Direction.Bottom; } Direction horizontalOpposite = horizontalDir.Opposite(); Direction verticalOpposite = verticalDir.Opposite(); float flexibleWidth = newSize.x - element.Size.x; if (flexibleWidth > MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, horizontalDir, flexibleWidth); flexibleWidth = newSize.x - element.Size.x; if (flexibleWidth > MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, horizontalOpposite, flexibleWidth); } } else if (flexibleWidth < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element.GetSurroundingElement(horizontalDir), horizontalOpposite, -flexibleWidth); flexibleWidth = newSize.x - element.Size.x; if (flexibleWidth < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element.GetSurroundingElement(horizontalOpposite), horizontalDir, -flexibleWidth); } } float flexibleHeight = newSize.y - element.Size.y; if (flexibleHeight > MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, verticalDir, flexibleHeight); flexibleHeight = newSize.y - element.Size.y; if (flexibleHeight > MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, verticalOpposite, flexibleHeight); } } else if (flexibleHeight < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element.GetSurroundingElement(verticalDir), verticalOpposite, -flexibleHeight); flexibleHeight = newSize.y - element.Size.y; if (flexibleHeight < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element.GetSurroundingElement(verticalOpposite), verticalDir, -flexibleHeight); } } }
protected void AddElementAt(int index, IPanelGroupElement element) { if (element.IsNull()) { Debug.LogError("Invalid argument!"); return; } if (index < 0 || index > elements.Count) { Debug.LogError("Invalid index!"); return; } int elementIndex = elements.IndexOf(element); if (elementIndex >= 0 && element.Group != this) { if (index > elementIndex) { index--; } elements.RemoveAt(elementIndex); elementIndex = -1; } if (elementIndex == index) { return; } if (element.Group != null) { element.Group.SetDirty(); } if (elementIndex < 0) { // Element not present in this group, add it elements.Insert(index, element); SetGroupFor(element, this); } else if (elementIndex != index) { // Element already present in this group, just change its index if (elementIndex > index) { elementIndex++; } elements.Insert(index, element); elements.RemoveAt(elementIndex); } SetDirty(); }
public void UpdateSurroundings(IPanelGroupElement left, IPanelGroupElement top, IPanelGroupElement right, IPanelGroupElement bottom) { panel.surroundings[(int)Direction.Left] = left; panel.surroundings[(int)Direction.Top] = top; panel.surroundings[(int)Direction.Right] = right; panel.surroundings[(int)Direction.Bottom] = bottom; ValidateTabs(); }
protected void UpdateBoundsOf(IPanelGroupElement element, Vector2 position, Vector2 size) { if (element is Panel panel) { panel.Internal.UpdateBounds(position, size); } else { ((PanelGroup)element).UpdateBounds(position, size); } }
protected void ResizeElementTo(IPanelGroupElement element, Vector2 newSize) { float flexibleWidth = newSize.x - element.Size.x; if (flexibleWidth > MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, Direction.Right, flexibleWidth); flexibleWidth = newSize.x - element.Size.x; if (flexibleWidth > MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, Direction.Left, flexibleWidth); } } else if (flexibleWidth < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element.GetSurroundingElement(Direction.Right), Direction.Left, -flexibleWidth); flexibleWidth = newSize.x - element.Size.x; if (flexibleWidth < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element.GetSurroundingElement(Direction.Left), Direction.Right, -flexibleWidth); } } float flexibleHeight = newSize.y - element.Size.y; if (flexibleHeight > MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, Direction.Bottom, flexibleHeight); flexibleHeight = newSize.y - element.Size.y; if (flexibleHeight > MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element, Direction.Top, flexibleHeight); } } else if (flexibleHeight < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element.GetSurroundingElement(Direction.Bottom), Direction.Top, -flexibleHeight); flexibleHeight = newSize.y - element.Size.y; if (flexibleHeight < -MIN_SIZE_TOLERANCE) { TryChangeSizeOf(element.GetSurroundingElement(Direction.Top), Direction.Bottom, -flexibleHeight); } } }
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; } }
protected override void EnsureMinimumSizeOf(IPanelGroupElement element) { Panel panel = element as Panel; if (!panel) { return; } Vector2 position = panel.Position; Vector2 size = panel.Size; Vector2 minSize = panel.MinSize; bool hasChanged = false; float flexibleWidth = size.x - minSize.x; if (flexibleWidth < -MIN_SIZE_TOLERANCE) { size.x -= flexibleWidth; position.x += flexibleWidth * 0.5f; hasChanged = true; } float flexibleHeight = size.y - minSize.y; if (flexibleHeight < -MIN_SIZE_TOLERANCE) { size.y -= flexibleHeight; position.y += flexibleHeight * 0.5f; hasChanged = true; } if (hasChanged) { panel.Internal.UpdateBounds(position, size); RestrictPanelToBounds(panel); } }
private void AddResizeProperty(IPanelGroupElement element) { if (resizeProperties == null) { resizeProperties = new List <ElementDirtyProperties>() { new ElementDirtyProperties(element), new ElementDirtyProperties() }; } else if (resizePropsIndex == resizeProperties.Count) { resizeProperties.Add(new ElementDirtyProperties(element)); } else { resizeProperties[resizePropsIndex].Reset(element); } resizePropsIndex++; }
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 void DockToPanel(IPanelGroupElement anchor, Direction direction) { PanelManager.Instance.AnchorPanel(this, anchor, direction); }
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 void Reset(IPanelGroupElement element) { this.element = element; posX = posY = sizeX = sizeY = 0f; }
public GroupElementSizeHolder(IPanelGroupElement element, Vector2 size) { this.element = element; this.size = size; }
public void AddElementAfter(IPanelGroupElement pivot, IPanelGroupElement element) { AddElementAt(elements.IndexOf(pivot) + 1, element); }
protected float TryChangeSizeOfInternal(IPanelGroupElement element, PanelDirection direction, float deltaSize) { int currResizePropsIndex = resizePropsIndex; AddResizeProperty(element); float thisFlexibleSize; if (direction == PanelDirection.Left || direction == PanelDirection.Right) { thisFlexibleSize = element.Size.x - element.MinSize.x; } else { thisFlexibleSize = element.Size.y - element.MinSize.y; } if (thisFlexibleSize > MIN_SIZE_TOLERANCE) { if (thisFlexibleSize >= deltaSize) { thisFlexibleSize = deltaSize; deltaSize = 0f; } else { deltaSize -= thisFlexibleSize; } ResizeElementHelper(currResizePropsIndex, direction.Opposite(), -thisFlexibleSize); } else { thisFlexibleSize = 0f; } if (deltaSize > MIN_SIZE_TOLERANCE) { IPanelGroupElement surrounding = element.GetSurroundingElement(direction); if (!surrounding.IsNull()) { if (surrounding.Group != element.Group) { AddResizeProperty(surrounding.GetSurroundingElement(direction.Opposite())); } float deltaMovement = TryChangeSizeOfInternal(surrounding, direction, deltaSize); if (deltaMovement > MIN_SIZE_TOLERANCE) { if (surrounding.Group == element.Group) { if (direction == PanelDirection.Left) { resizeProperties[currResizePropsIndex].posX -= deltaMovement; } else if (direction == PanelDirection.Top) { resizeProperties[currResizePropsIndex].posY += deltaMovement; } else if (direction == PanelDirection.Right) { resizeProperties[currResizePropsIndex].posX += deltaMovement; } else { resizeProperties[currResizePropsIndex].posY -= deltaMovement; } thisFlexibleSize += deltaMovement; } else { ResizeElementHelper(currResizePropsIndex + 1, direction, deltaMovement); } } else { resizePropsIndex = currResizePropsIndex + (thisFlexibleSize == 0 ? 0 : 1); } } else if (thisFlexibleSize == 0f) { resizePropsIndex = currResizePropsIndex; } } return(thisFlexibleSize); }
public ElementDirtyProperties(IPanelGroupElement element) { this.element = element; }
public void AddElementBefore(IPanelGroupElement pivot, IPanelGroupElement element) { AddElementAt(elements.IndexOf(pivot), element); }
public void AddElement(IPanelGroupElement element) { AddElementAt(elements.Count, element); }
public void TryChangeSizeOf(IPanelGroupElement element, PanelDirection direction, float deltaSize) { group.TryChangeSizeOf(element, direction, deltaSize); }
public void ResizeElementTo(IPanelGroupElement element, Vector2 newSize, PanelDirection horizontalDir, PanelDirection verticalDir) { group.ResizeElementTo(element, newSize, horizontalDir, verticalDir); }
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); }
public void UpdateSurroundings(IPanelGroupElement left, IPanelGroupElement top, IPanelGroupElement right, IPanelGroupElement bottom) { group.UpdateSurroundings(left, top, right, bottom); }
private void OnResize(Direction direction, Vector2 screenPoint) { Vector2 localPoint; RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, screenPoint, Canvas.Internal.worldCamera, out localPoint); Vector2 sizeDelta = RectTransform.sizeDelta; if (!IsDocked) { Vector2 anchoredPosition = RectTransform.anchoredPosition; if (direction == Direction.Left) { float width = sizeDelta.x - localPoint.x; if (width < m_minSize.x) { width = m_minSize.x; } anchoredPosition.x += sizeDelta.x - width; sizeDelta.x = width; } else if (direction == Direction.Top) { float height = localPoint.y; if (height < m_minSize.y) { height = m_minSize.y; } sizeDelta.y = height; } else if (direction == Direction.Right) { float width = localPoint.x; if (width < m_minSize.x) { width = m_minSize.x; } sizeDelta.x = width; } else { float height = sizeDelta.y - localPoint.y; if (height < m_minSize.y) { height = m_minSize.y; } anchoredPosition.y += sizeDelta.y - height; sizeDelta.y = height; } RectTransform.sizeDelta = sizeDelta; RectTransform.anchoredPosition = anchoredPosition; } else { float deltaSize; if (direction == Direction.Left) { deltaSize = -localPoint.x; } else if (direction == Direction.Top) { deltaSize = localPoint.y - sizeDelta.y; } else if (direction == Direction.Right) { deltaSize = localPoint.x - sizeDelta.x; } else { deltaSize = -localPoint.y; } if (deltaSize >= 0f) { Group.Internal.TryChangeSizeOf(this, direction, deltaSize); } else { IPanelGroupElement surrounding = surroundings[(int)direction]; if (surrounding != null) { surrounding.Group.Internal.TryChangeSizeOf(surrounding, direction.Opposite(), -deltaSize); } } } }
public void ReplaceElement(IPanelGroupElement beforeElement, IPanelGroupElement afterElement) { group.ReplaceElement(beforeElement, afterElement); }