From 2696bc3704c35d2b9d4f7ca787b1dde3485f176b Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Fri, 22 Sep 2023 12:26:11 -0400 Subject: [PATCH] Add debug view for collision boxes. --- Source/Editor/Surface/NodeArchetype.cs | 45 ++++- Source/Editor/Surface/NodeElementArchetype.cs | 4 +- Source/Editor/Surface/SurfaceNode.cs | 180 ++++++++++++++++-- 3 files changed, 205 insertions(+), 24 deletions(-) diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs index b1a36ba0a..4582aa054 100644 --- a/Source/Editor/Surface/NodeArchetype.cs +++ b/Source/Editor/Surface/NodeArchetype.cs @@ -1,8 +1,11 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using System; +using System.Collections.Generic; +using System.Linq; using FlaxEditor.Scripting; using FlaxEngine; +using FlaxEngine.GUI; namespace FlaxEditor.Surface { @@ -178,10 +181,50 @@ namespace FlaxEditor.Surface /// public Func DependentBoxFilter; + private NodeElementArchetype[] _elements; /// /// Array with default elements descriptions. /// - public NodeElementArchetype[] Elements; + public NodeElementArchetype[] Elements + { + get + { + return _elements; + } + set + { + _elements = value; + + /*Float2 topLeft = Float2.Zero; + Float2 bottomRight = Float2.Zero; + List textRectangles = new List(); + + foreach (NodeElementArchetype nodeElementType in _elements) + { + bool isInputElement = nodeElementType.Type == NodeElementType.Input; + bool isOutputElement = nodeElementType.Type == NodeElementType.Output; + if (isInputElement) + { + // Text will be to the right + } + + // In case of negatives.. most likely not needed. + topLeft.X = Math.Min(topLeft.X, nodeElementType.Position.X); + topLeft.Y = Math.Min(topLeft.Y, nodeElementType.Position.Y); + + bottomRight.X = Math.Max(bottomRight.X, nodeElementType.Position.X + nodeElementType.Size.X); + bottomRight.Y = Math.Max(bottomRight.Y, nodeElementType.Position.Y + nodeElementType.Size.Y); + } + + float paddingConst = 15; + + float sizeXElements = bottomRight.X - topLeft.X + paddingConst; + float sizeYElements = bottomRight.Y - topLeft.Y + paddingConst; + float titleSize = Style.Current.FontLarge.MeasureText(Title).X + paddingConst; + + Size = new Float2(Math.Max(sizeXElements, titleSize), sizeYElements);*/ + } + } /// /// Tries to parse some text and extract the data from it. diff --git a/Source/Editor/Surface/NodeElementArchetype.cs b/Source/Editor/Surface/NodeElementArchetype.cs index be8b67378..298127c3a 100644 --- a/Source/Editor/Surface/NodeElementArchetype.cs +++ b/Source/Editor/Surface/NodeElementArchetype.cs @@ -132,8 +132,8 @@ namespace FlaxEditor.Surface { Type = NodeElementType.Input, Position = new Float2( - Constants.NodeMarginX - Constants.BoxOffsetX, - Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY), + Constants.NodeMarginX - Constants.BoxOffsetX, + Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY), Text = text, Single = single, ValueIndex = valueIndex, diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 047e22476..8d0ed43b9 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -165,7 +165,7 @@ namespace FlaxEditor.Surface { if (Surface == null) return; - Size = CalculateNodeSize(width, height); + Size = CalculateNodeSize(width, height); // Update boxes on width change //if (!Mathf.NearEqual(prevSize.X, Size.X)) @@ -180,6 +180,109 @@ namespace FlaxEditor.Surface } } + private Float2 GetBoxControlWidthHeight(Control control, Font boxLabelFont) + { + float boxWidth = 0; + float boxHeight = 0; + + if (control is InputBox inputBox) + { + boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 20; + if (inputBox.DefaultValueEditor != null) + boxWidth += inputBox.DefaultValueEditor.Width + 4; + boxHeight = inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f; + } + else if (control is OutputBox outputBox) + { + boxWidth = boxLabelFont.MeasureText(outputBox.Text).X + 20; + boxHeight = outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f; + } + else if (control is Control defaultControl) + { + if (defaultControl.AnchorPreset == AnchorPresets.TopLeft) + { + boxWidth = defaultControl.Right + 4 - Constants.NodeMarginX; + boxHeight = defaultControl.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize; + } + else + { + boxWidth = defaultControl.Width + 4; + boxHeight = defaultControl.Height + 4; + } + } + + return new Float2(boxWidth, boxHeight); + } + + public ContainerControl HACK = null; + + private Float2 CompareAndGetNewCollisionSize(Rectangle rect1, Rectangle rect2, float collisionWidth, float collisionHeight) + { + Rectangle sharedArea; + Rectangle.Shared(ref rect1, ref rect2, out sharedArea); + + Color colliderColor = Color.Chocolate; + colliderColor.A = 0.1f; + Panel colliderPanel = new Panel + { + BackgroundColor = colliderColor, + Location = sharedArea.Location, + Size = sharedArea.Size, + Parent = HACK + }; + + return new Float2(Mathf.Max(collisionWidth, sharedArea.Width + 4), Mathf.Max(collisionHeight, sharedArea.Height + 4)); + } + + private Float2 CalculateCollisionSize(List controls, Font boxLabelFont) + { + List colliderRectangles = new List(); + int controlsCount = controls.Count; + for (int i = 0; i < controlsCount; i++) + { + var control = controls[i]; + if (!control.Visible || control is Panel panel) + continue; + + Float2 boxSize = GetBoxControlWidthHeight(control, boxLabelFont); + + Rectangle controlRect = new Rectangle(control.X, control.Y, boxSize.X, boxSize.Y); + colliderRectangles.Add(controlRect); + + Color colliderColor = Style.Current.BackgroundSelected; + colliderColor.A = 0.25f; + Panel colliderPanel = new Panel + { + BackgroundColor = colliderColor, + Location = controlRect.Location, + Size = controlRect.Size, + Parent = HACK + }; + } + + float collisionWidth = 0; + float collisionHeight = 0; + for (int i = 0; i < colliderRectangles.Count; i++) + { + for (int j = 0; j < colliderRectangles.Count; j++) + { + if (i == j) + { + continue; + } + + Rectangle rect1 = colliderRectangles[i]; + Rectangle rect2 = colliderRectangles[j]; + Float2 newCollisionSize = CompareAndGetNewCollisionSize(rect1, rect2, collisionWidth, collisionHeight); + + collisionWidth = newCollisionSize.X; + collisionHeight = newCollisionSize.Y; + } + } + + return new Float2(collisionWidth, collisionHeight); + } + /// /// Automatically resizes the node to match the title size and all the elements for best fit of the node dimensions. /// @@ -187,6 +290,7 @@ namespace FlaxEditor.Surface { if (Surface == null) return; + HACK = this; var width = 0.0f; var height = 0.0f; var leftHeight = 0.0f; @@ -195,44 +299,75 @@ namespace FlaxEditor.Surface var rightWidth = 40.0f; var boxLabelFont = Style.Current.FontSmall; var titleLabelFont = Style.Current.FontLarge; - for (int i = 0; i < Children.Count; i++) + int childrenCount = Children.Count; + for (int i = 0; i < childrenCount; i++) { var child = Children[i]; + if (child is Panel panel) + { + panel.Visible = false; + } if (!child.Visible) continue; + + Float2 boxSize = GetBoxControlWidthHeight(child, boxLabelFont); if (child is InputBox inputBox) { - var boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 20; - if (inputBox.DefaultValueEditor != null) - boxWidth += inputBox.DefaultValueEditor.Width + 4; - leftWidth = Mathf.Max(leftWidth, boxWidth); - leftHeight = Mathf.Max(leftHeight, inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f); + leftWidth = Mathf.Max(leftWidth, boxSize.X); + leftHeight = Mathf.Max(leftHeight, boxSize.Y); } else if (child is OutputBox outputBox) { - rightWidth = Mathf.Max(rightWidth, boxLabelFont.MeasureText(outputBox.Text).X + 20); - rightHeight = Mathf.Max(rightHeight, outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f); + rightWidth = Mathf.Max(rightWidth, boxSize.X); + rightHeight = Mathf.Max(rightHeight, boxSize.Y); } - else if (child is Control control) + else { - if (control.AnchorPreset == AnchorPresets.TopLeft) - { - width = Mathf.Max(width, control.Right + 4 - Constants.NodeMarginX); - height = Mathf.Max(height, control.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize); - } - else - { - width = Mathf.Max(width, control.Width + 4); - height = Mathf.Max(height, control.Height + 4); - } + width = Mathf.Max(width, boxSize.X); + height = Mathf.Max(height, boxSize.Y); } } + Debug.Log(Title); + Float2 collisionSize = CalculateCollisionSize(Children, boxLabelFont); + Debug.Log(collisionSize.ToString()); + //width += collisionSize.X; + //height += collisionSize.Y; + width = Mathf.Max(width, leftWidth + rightWidth + 10); width = Mathf.Max(width, titleLabelFont.MeasureText(Title).X + 30); height = Mathf.Max(height, Mathf.Max(leftHeight, rightHeight)); - Resize(width, height); + + Float2 roundedSize = VisjectSurface.RoundToGrid(new Float2(width, height), true); + Resize(roundedSize.X, roundedSize.Y); } + /* if (child is InputBox inputBox) +{ + var boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 20; + if (inputBox.DefaultValueEditor != null) + boxWidth += inputBox.DefaultValueEditor.Width + 4; + leftWidth = Mathf.Max(leftWidth, boxWidth); + leftHeight = Mathf.Max(leftHeight, inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f); +} +else if (child is OutputBox outputBox) +{ + rightWidth = Mathf.Max(rightWidth, boxLabelFont.MeasureText(outputBox.Text).X + 20); + rightHeight = Mathf.Max(rightHeight, outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f); +} +else if (child is Control control) +{ + if (control.AnchorPreset == AnchorPresets.TopLeft) + { + width = Mathf.Max(width, control.Right + 4 - Constants.NodeMarginX); + height = Mathf.Max(height, control.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize); + } + else + { + width = Mathf.Max(width, control.Width + 4); + height = Mathf.Max(height, control.Height + 4); + } +}*/ + /// /// Creates an element from the archetype and adds the element to the node. /// @@ -310,6 +445,9 @@ namespace FlaxEditor.Surface Elements.Add(element); if (element is Control control) AddChild(control); + + if (!(element is Panel panel)) + ResizeAuto(); } ///