From b714668f4cd39c30f37695bde603ff1ff8fa7a0f Mon Sep 17 00:00:00 2001 From: Saas Date: Wed, 17 Dec 2025 18:54:37 +0100 Subject: [PATCH 01/35] improve visject graph readability - Separate size for boxes (the circle thingie to connect to) and box rows - Smaller boxes (circle thingie) - Smaller footer - Smaller and color header - Left align header text - Replace background with solid color - Adjust node `ArchetypeColor`s (former `FooterColor`) to keep header title readable over colored header --- .../Editor/Surface/Archetypes/BehaviorTree.cs | 6 ++--- Source/Editor/Surface/Archetypes/Function.cs | 2 +- Source/Editor/Surface/Archetypes/Textures.cs | 2 +- Source/Editor/Surface/Archetypes/Tools.cs | 2 +- Source/Editor/Surface/Constants.cs | 15 +++++++++---- Source/Editor/Surface/Elements/Box.cs | 2 +- Source/Editor/Surface/NodeElementArchetype.cs | 4 ++-- Source/Editor/Surface/NodeFactory.cs | 22 +++++++++---------- Source/Editor/Surface/SurfaceNode.cs | 16 +++++++++----- Source/Editor/Surface/SurfaceStyle.cs | 8 ++++++- Source/Editor/Surface/VisjectSurface.Draw.cs | 8 ++++++- 11 files changed, 56 insertions(+), 31 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/BehaviorTree.cs b/Source/Editor/Surface/Archetypes/BehaviorTree.cs index 0b4b3f713..9c9325177 100644 --- a/Source/Editor/Surface/Archetypes/BehaviorTree.cs +++ b/Source/Editor/Surface/Archetypes/BehaviorTree.cs @@ -415,8 +415,8 @@ namespace FlaxEditor.Surface.Archetypes // Setup boxes _input = (InputBox)GetBox(0); _output = (OutputBox)GetBox(1); - _input.ConnectionOffset = new Float2(0, FlaxEditor.Surface.Constants.BoxSize * -0.5f); - _output.ConnectionOffset = new Float2(0, FlaxEditor.Surface.Constants.BoxSize * 0.5f); + _input.ConnectionOffset = new Float2(0, FlaxEditor.Surface.Constants.BoxRowHeight * -0.5f); + _output.ConnectionOffset = new Float2(0, FlaxEditor.Surface.Constants.BoxRowHeight * 0.5f); // Setup node type and data var flagsRoot = NodeFlags.NoRemove | NodeFlags.NoCloseButton | NodeFlags.NoSpawnViaPaste; @@ -667,7 +667,7 @@ namespace FlaxEditor.Surface.Archetypes } } - protected override Color FooterColor => Color.Transparent; + protected override Color ArchetypeColor => Color.Transparent; protected override Float2 CalculateNodeSize(float width, float height) { diff --git a/Source/Editor/Surface/Archetypes/Function.cs b/Source/Editor/Surface/Archetypes/Function.cs index 79d3948bf..6410b51e7 100644 --- a/Source/Editor/Surface/Archetypes/Function.cs +++ b/Source/Editor/Surface/Archetypes/Function.cs @@ -631,7 +631,7 @@ namespace FlaxEditor.Surface.Archetypes } /// - protected override Color FooterColor => new Color(200, 11, 112); + protected override Color ArchetypeColor => new Color(200, 11, 112); /// public override void OnLoaded(SurfaceNodeActions action) diff --git a/Source/Editor/Surface/Archetypes/Textures.cs b/Source/Editor/Surface/Archetypes/Textures.cs index 56f8154d7..c1132e947 100644 --- a/Source/Editor/Surface/Archetypes/Textures.cs +++ b/Source/Editor/Surface/Archetypes/Textures.cs @@ -204,7 +204,7 @@ namespace FlaxEditor.Surface.Archetypes NodeElementArchetype.Factory.Input(3, "Max Steps", true, typeof(float), 3, 2), NodeElementArchetype.Factory.Input(4, "Heightmap Texture", true, typeof(FlaxEngine.Object), 4), NodeElementArchetype.Factory.Output(0, "Parallax UVs", typeof(Float2), 5), - NodeElementArchetype.Factory.Text(Surface.Constants.BoxSize + 4, 5 * Surface.Constants.LayoutOffsetY, "Channel"), + NodeElementArchetype.Factory.Text(Surface.Constants.BoxRowHeight + 4, 5 * Surface.Constants.LayoutOffsetY, "Channel"), NodeElementArchetype.Factory.ComboBox(70, 5 * Surface.Constants.LayoutOffsetY, 50, 3, new[] { "R", diff --git a/Source/Editor/Surface/Archetypes/Tools.cs b/Source/Editor/Surface/Archetypes/Tools.cs index aacebd189..3d0a8cd0c 100644 --- a/Source/Editor/Surface/Archetypes/Tools.cs +++ b/Source/Editor/Surface/Archetypes/Tools.cs @@ -1058,7 +1058,7 @@ namespace FlaxEditor.Surface.Archetypes internal class RerouteNode : SurfaceNode, IConnectionInstigator { - internal static readonly Float2 DefaultSize = new Float2(FlaxEditor.Surface.Constants.BoxSize); + internal static readonly Float2 DefaultSize = new Float2(FlaxEditor.Surface.Constants.BoxRowHeight); private Rectangle _localBounds; private InputBox _input; private OutputBox _output; diff --git a/Source/Editor/Surface/Constants.cs b/Source/Editor/Surface/Constants.cs index 0f3dca783..3310351bf 100644 --- a/Source/Editor/Surface/Constants.cs +++ b/Source/Editor/Surface/Constants.cs @@ -23,12 +23,14 @@ namespace FlaxEditor.Surface /// /// The node header height. /// - public const float NodeHeaderSize = 28.0f; + public const float NodeHeaderSize = 20.0f; + + public const float NodeHeaderTextScale = 0.65f; /// /// The node footer height. /// - public const float NodeFooterSize = 4.0f; + public const float NodeFooterSize = 2.0f; /// /// The node left margin. @@ -45,14 +47,19 @@ namespace FlaxEditor.Surface /// public const float BoxOffsetX = 2.0f; + /// + /// The width of the row that is started by a box. + /// + public const float BoxRowHeight = 18.0f; + /// /// The box size (with and height). /// - public const float BoxSize = 20.0f; + public const float BoxSize = 12.0f; /// /// The node layout offset on the y axis (height of the boxes rows, etc.). It's used to make the design more consistent. /// - public const float LayoutOffsetY = 20.0f; + public const float LayoutOffsetY = 22.0f; } } diff --git a/Source/Editor/Surface/Elements/Box.cs b/Source/Editor/Surface/Elements/Box.cs index 964b3cc69..08023ac93 100644 --- a/Source/Editor/Surface/Elements/Box.cs +++ b/Source/Editor/Surface/Elements/Box.cs @@ -196,7 +196,7 @@ namespace FlaxEditor.Surface.Elements /// protected Box(SurfaceNode parentNode, NodeElementArchetype archetype, Float2 location) - : base(parentNode, archetype, location, new Float2(Constants.BoxSize), false) + : base(parentNode, archetype, location, new Float2(Constants.BoxRowHeight), false) { _currentType = DefaultType; _isSingle = Archetype.Single; diff --git a/Source/Editor/Surface/NodeElementArchetype.cs b/Source/Editor/Surface/NodeElementArchetype.cs index f5a23d411..1a9d4ae74 100644 --- a/Source/Editor/Surface/NodeElementArchetype.cs +++ b/Source/Editor/Surface/NodeElementArchetype.cs @@ -157,7 +157,7 @@ namespace FlaxEditor.Surface { Type = NodeElementType.Output, Position = new Float2( - Constants.NodeMarginX - Constants.BoxSize + Constants.BoxOffsetX, + Constants.NodeMarginX - Constants.BoxRowHeight + Constants.BoxOffsetX, Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY), Text = text, Single = single, @@ -182,7 +182,7 @@ namespace FlaxEditor.Surface { Type = NodeElementType.Output, Position = new Float2( - Constants.NodeMarginX - Constants.BoxSize + Constants.BoxOffsetX, + Constants.NodeMarginX - Constants.BoxRowHeight + Constants.BoxOffsetX, Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY), Text = text, Single = single, diff --git a/Source/Editor/Surface/NodeFactory.cs b/Source/Editor/Surface/NodeFactory.cs index 7c85cb449..8448c37a3 100644 --- a/Source/Editor/Surface/NodeFactory.cs +++ b/Source/Editor/Surface/NodeFactory.cs @@ -60,56 +60,56 @@ namespace FlaxEditor.Surface { GroupID = 1, Name = "Material", - Color = new Color(231, 76, 60), + Color = new Color(181, 89, 49), Archetypes = Archetypes.Material.Nodes }, new GroupArchetype { GroupID = 2, Name = "Constants", - Color = new Color(243, 156, 18), + Color = new Color(163, 106, 21), Archetypes = Archetypes.Constants.Nodes }, new GroupArchetype { GroupID = 3, Name = "Math", - Color = new Color(52, 152, 219), + Color = new Color(45, 126, 181), Archetypes = Archetypes.Math.Nodes }, new GroupArchetype { GroupID = 4, Name = "Packing", - Color = new Color(155, 89, 182), + Color = new Color(124, 66, 143), Archetypes = Archetypes.Packing.Nodes }, new GroupArchetype { GroupID = 5, Name = "Textures", - Color = new Color(46, 204, 113), + Color = new Color(43, 130, 83), Archetypes = Archetypes.Textures.Nodes }, new GroupArchetype { GroupID = 6, Name = "Parameters", - Color = new Color(52, 73, 94), + Color = new Color(55, 78, 99), Archetypes = Archetypes.Parameters.Nodes }, new GroupArchetype { GroupID = 7, Name = "Tools", - Color = new Color(149, 165, 166), + Color = new Color(88, 96, 97), Archetypes = Archetypes.Tools.Nodes }, new GroupArchetype { GroupID = 8, Name = "Layers", - Color = new Color(249, 105, 116), + Color = new Color(189, 75, 81), Archetypes = Archetypes.Layers.Nodes }, new GroupArchetype @@ -123,21 +123,21 @@ namespace FlaxEditor.Surface { GroupID = 10, Name = "Boolean", - Color = new Color(237, 28, 36), + Color = new Color(166, 27, 32), Archetypes = Archetypes.Boolean.Nodes }, new GroupArchetype { GroupID = 11, Name = "Bitwise", - Color = new Color(181, 230, 29), + Color = new Color(96, 125, 34), Archetypes = Archetypes.Bitwise.Nodes }, new GroupArchetype { GroupID = 12, Name = "Comparisons", - Color = new Color(148, 30, 34), + Color = new Color(166, 33, 57), Archetypes = Archetypes.Comparisons.Nodes }, // GroupID = 13 -> Custom Nodes provided externally diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 6312bd68d..4b918de08 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -55,6 +55,11 @@ namespace FlaxEditor.Surface /// protected Rectangle _headerRect; + /// + /// The header text rectangle (local space). + /// + protected Rectangle _headerTextRect; + /// /// The close button rectangle (local space). /// @@ -132,7 +137,7 @@ namespace FlaxEditor.Surface AutoFocus = false; TooltipText = GetTooltip(); CullChildren = false; - BackgroundColor = Style.Current.BackgroundNormal; + BackgroundColor = Color.Lerp(Style.Current.Background, Style.Current.BackgroundHighlighted, 0.55f); if (Archetype.DefaultValues != null) { @@ -149,7 +154,7 @@ namespace FlaxEditor.Surface /// /// Gets the color of the footer of the node. /// - protected virtual Color FooterColor => GroupArchetype.Color; + protected virtual Color ArchetypeColor => GroupArchetype.Color; private Float2 mouseDownMousePosition; @@ -1032,6 +1037,7 @@ namespace FlaxEditor.Surface const float closeButtonMargin = Constants.NodeCloseButtonMargin; const float closeButtonSize = Constants.NodeCloseButtonSize; _headerRect = new Rectangle(0, 0, Width, headerSize); + _headerTextRect = _headerRect with { Width = _headerRect.Width - 5f, X = _headerRect.X + 5f }; _closeButtonRect = new Rectangle(Width - closeButtonSize - closeButtonMargin, closeButtonMargin, closeButtonSize, closeButtonSize); _footerRect = new Rectangle(0, Height - footerSize, Width, footerSize); } @@ -1058,8 +1064,8 @@ namespace FlaxEditor.Surface var headerColor = style.BackgroundHighlighted; if (_headerRect.Contains(ref _mousePosition) && !Surface.IsConnecting && !Surface.IsSelecting) headerColor *= 1.07f; - Render2D.FillRectangle(_headerRect, headerColor); - Render2D.DrawText(style.FontLarge, Title, _headerRect, style.Foreground, TextAlignment.Center, TextAlignment.Center); + Render2D.FillRectangle(_headerRect, ArchetypeColor); + Render2D.DrawText(style.FontLarge, Title, _headerTextRect, style.Foreground, TextAlignment.Near, TextAlignment.Center, TextWrapping.NoWrap, 1f, Constants.NodeHeaderTextScale); // Close button if ((Archetype.Flags & NodeFlags.NoCloseButton) == 0 && Surface.CanEdit) @@ -1069,7 +1075,7 @@ namespace FlaxEditor.Surface } // Footer - Render2D.FillRectangle(_footerRect, FooterColor); + Render2D.FillRectangle(_footerRect, ArchetypeColor); DrawChildren(); diff --git a/Source/Editor/Surface/SurfaceStyle.cs b/Source/Editor/Surface/SurfaceStyle.cs index be09f51be..654cf7abf 100644 --- a/Source/Editor/Surface/SurfaceStyle.cs +++ b/Source/Editor/Surface/SurfaceStyle.cs @@ -140,6 +140,11 @@ namespace FlaxEditor.Surface /// public Texture Background; + /// + /// The color used as a surface background. + /// + public Color BackgroundColor; + /// /// Boxes drawing callback. /// @@ -216,7 +221,7 @@ namespace FlaxEditor.Surface private static void DefaultDrawBox(Elements.Box box) { - var rect = new Rectangle(Float2.Zero, box.Size); + var rect = new Rectangle(0.0f, box.Height * 0.5f - Constants.BoxSize * 0.5f, new Float2(Constants.BoxSize)); // Size culling const float minBoxSize = 5.0f; @@ -293,6 +298,7 @@ namespace FlaxEditor.Surface ArrowClose = editor.Icons.VisjectArrowClosed32, }, Background = editor.UI.VisjectSurfaceBackground, + BackgroundColor = new Color(31, 31, 31), }; } diff --git a/Source/Editor/Surface/VisjectSurface.Draw.cs b/Source/Editor/Surface/VisjectSurface.Draw.cs index af5893907..0138bce8d 100644 --- a/Source/Editor/Surface/VisjectSurface.Draw.cs +++ b/Source/Editor/Surface/VisjectSurface.Draw.cs @@ -65,7 +65,7 @@ namespace FlaxEditor.Surface /// protected virtual void DrawBackground() { - DrawBackgroundDefault(Style.Background, Width, Height); + DrawBackgroundSolidColor(Style.BackgroundColor, Width, Height); } internal static void DrawBackgroundDefault(Texture background, float width, float height) @@ -95,6 +95,12 @@ namespace FlaxEditor.Surface } } + internal static void DrawBackgroundSolidColor(Color color, float width, float height) + { + Rectangle backgroundRect = new Rectangle(0f, 0f, width, height); + Render2D.FillRectangle(backgroundRect, color); + } + /// /// Draws the selection background. /// From e27287080366984ad2534f380dfdecf1bc6a44ef Mon Sep 17 00:00:00 2001 From: Saas Date: Thu, 18 Dec 2025 19:51:17 +0100 Subject: [PATCH 02/35] increase max zoom --- Source/Editor/Surface/VisjectSurface.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Surface/VisjectSurface.cs b/Source/Editor/Surface/VisjectSurface.cs index e3bb94bcc..dfc8ea7a2 100644 --- a/Source/Editor/Surface/VisjectSurface.cs +++ b/Source/Editor/Surface/VisjectSurface.cs @@ -217,7 +217,7 @@ namespace FlaxEditor.Surface set { // Clamp - value = Mathf.Clamp(value, 0.05f, 1.6f); + value = Mathf.Clamp(value, 0.05f, 1.85f); // Check if value will change if (Mathf.Abs(value - _targetScale) > 0.0001f) From d3d67fddcc807308b79076fc4b446253d2728160 Mon Sep 17 00:00:00 2001 From: Saas Date: Thu, 18 Dec 2025 19:54:31 +0100 Subject: [PATCH 03/35] add node shadow - rectangular shadow (can be disabled...) - ... for example for nodes with more complex shapes like reroute --- Source/Editor/Surface/Archetypes/Tools.cs | 6 ++++++ Source/Editor/Surface/SurfaceNode.cs | 18 +++++++++++++++++- Source/Engine/Core/Math/Rectangle.cs | 10 ++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Surface/Archetypes/Tools.cs b/Source/Editor/Surface/Archetypes/Tools.cs index 3d0a8cd0c..555f7ad55 100644 --- a/Source/Editor/Surface/Archetypes/Tools.cs +++ b/Source/Editor/Surface/Archetypes/Tools.cs @@ -1059,6 +1059,7 @@ namespace FlaxEditor.Surface.Archetypes internal class RerouteNode : SurfaceNode, IConnectionInstigator { internal static readonly Float2 DefaultSize = new Float2(FlaxEditor.Surface.Constants.BoxRowHeight); + internal override bool DrawBasicShadow => false; private Rectangle _localBounds; private InputBox _input; private OutputBox _output; @@ -1187,6 +1188,11 @@ namespace FlaxEditor.Surface.Archetypes icon = type.IsVoid ? style.Icons.ArrowClose : style.Icons.BoxClose; else icon = type.IsVoid ? style.Icons.ArrowOpen : style.Icons.BoxOpen; + + // Shadow + var shadowRect = _localBounds.MakeOffsetted(ShadowOffset); + Render2D.DrawSprite(icon, shadowRect, Color.Black.AlphaMultiplied(0.125f)); + Render2D.DrawSprite(icon, _localBounds, connectionColor); base.Draw(); diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 4b918de08..89471eaf4 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -40,6 +40,13 @@ namespace FlaxEditor.Surface [HideInEditor] public class SurfaceNode : SurfaceControl { + internal const float ShadowOffset = 2.25f; + + /// + /// If true, draws a basic rectangle shadow behind the node. Disable to hide shadow or if the node is drawing a custom shadow. + /// + internal virtual bool DrawBasicShadow => true; + /// /// The box to draw a highlight around. Drawing will be skipped if null. /// @@ -1047,8 +1054,16 @@ namespace FlaxEditor.Surface { var style = Style.Current; - // Background var backgroundRect = new Rectangle(Float2.Zero, Size); + + // Shadow + if (DrawBasicShadow) + { + var shadowRect = backgroundRect.MakeOffsetted(ShadowOffset); + Render2D.FillRectangle(shadowRect, Color.Black.AlphaMultiplied(0.125f)); + } + + // Background Render2D.FillRectangle(backgroundRect, BackgroundColor); // Breakpoint hit @@ -1085,6 +1100,7 @@ namespace FlaxEditor.Surface var colorTop = Color.Orange; var colorBottom = Color.OrangeRed; Render2D.DrawRectangle(backgroundRect, colorTop, colorTop, colorBottom, colorBottom); + Render2D.DrawRectangle(backgroundRect, colorTop, colorTop, colorBottom, colorBottom, 2.5f); } // Breakpoint dot diff --git a/Source/Engine/Core/Math/Rectangle.cs b/Source/Engine/Core/Math/Rectangle.cs index 81c689d48..c2339d9d5 100644 --- a/Source/Engine/Core/Math/Rectangle.cs +++ b/Source/Engine/Core/Math/Rectangle.cs @@ -253,6 +253,16 @@ namespace FlaxEngine return new Rectangle(Location + new Float2(x, y), Size); } + /// + /// Make offseted rectangle + /// + /// Offset (will be applied to X- and Y- axis). + /// Offseted rectangle. + public Rectangle MakeOffsetted(float offset) + { + return new Rectangle(Location + new Float2(offset, offset), Size); + } + /// /// Make offseted rectangle /// From 31b1ceb9f03a3cd2e32e32a46624e1384efa418a Mon Sep 17 00:00:00 2001 From: Saas Date: Thu, 18 Dec 2025 19:57:58 +0100 Subject: [PATCH 04/35] increase selection outline width --- Source/Editor/Surface/SurfaceNode.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 89471eaf4..ad74f58ae 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -1099,7 +1099,6 @@ namespace FlaxEditor.Surface { var colorTop = Color.Orange; var colorBottom = Color.OrangeRed; - Render2D.DrawRectangle(backgroundRect, colorTop, colorTop, colorBottom, colorBottom); Render2D.DrawRectangle(backgroundRect, colorTop, colorTop, colorBottom, colorBottom, 2.5f); } From cfda18ea9d7b7074a63988bf958d18b846ee0eef Mon Sep 17 00:00:00 2001 From: Saas Date: Thu, 18 Dec 2025 22:41:55 +0100 Subject: [PATCH 05/35] propagate disabled node boxes across reroute nodes --- Source/Editor/Surface/Archetypes/Tools.cs | 10 ++++++++++ Source/Editor/Surface/Elements/Box.cs | 11 +++++++++++ Source/Editor/Surface/Elements/OutputBox.cs | 4 ++-- Source/Editor/Surface/SurfaceStyle.cs | 2 +- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Tools.cs b/Source/Editor/Surface/Archetypes/Tools.cs index 555f7ad55..685068986 100644 --- a/Source/Editor/Surface/Archetypes/Tools.cs +++ b/Source/Editor/Surface/Archetypes/Tools.cs @@ -1059,7 +1059,10 @@ namespace FlaxEditor.Surface.Archetypes internal class RerouteNode : SurfaceNode, IConnectionInstigator { internal static readonly Float2 DefaultSize = new Float2(FlaxEditor.Surface.Constants.BoxRowHeight); + + internal bool DrawDisabled => _input.AllConnectionsDisabled || _output.AllConnectionsDisabled; internal override bool DrawBasicShadow => false; + private Rectangle _localBounds; private InputBox _input; private OutputBox _output; @@ -1165,6 +1168,9 @@ namespace FlaxEditor.Surface.Archetypes /// public override void Draw() { + // Update active state of input + _input.IsActive = !_output.AllConnectionsDisabled; + var style = Surface.Style; var connectionColor = style.Colors.Default; var type = ScriptType.Null; @@ -1178,6 +1184,10 @@ namespace FlaxEditor.Surface.Archetypes Surface.Style.GetConnectionColor(type, hints, out connectionColor); } + // Draw the box as disabled if needed + if (DrawDisabled) + connectionColor = connectionColor * 0.6f; + if (!_input.HasAnyConnection) Render2D.FillRectangle(new Rectangle(-barHorizontalOffset - barHeight * 2, (DefaultSize.Y - barHeight) / 2, barHeight * 2, barHeight), connectionColor); if (!_output.HasAnyConnection) diff --git a/Source/Editor/Surface/Elements/Box.cs b/Source/Editor/Surface/Elements/Box.cs index 08023ac93..4c86af041 100644 --- a/Source/Editor/Surface/Elements/Box.cs +++ b/Source/Editor/Surface/Elements/Box.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Linq; using FlaxEditor.Scripting; using FlaxEditor.Surface.Undo; using FlaxEngine; @@ -194,6 +195,16 @@ namespace FlaxEditor.Surface.Elements set => _isActive = value; } + /// + /// Gets if the box is disabled (user can still connect, but connections will be ignored). + /// + public bool IsDisabled => !(Enabled && IsActive); + + /// + /// Gets a value indicating whether all connections are disabled. + /// + public bool AllConnectionsDisabled => Connections.All(c => c.IsDisabled); + /// protected Box(SurfaceNode parentNode, NodeElementArchetype archetype, Float2 location) : base(parentNode, archetype, location, new Float2(Constants.BoxRowHeight), false) diff --git a/Source/Editor/Surface/Elements/OutputBox.cs b/Source/Editor/Surface/Elements/OutputBox.cs index 7e271fef0..0673f694b 100644 --- a/Source/Editor/Surface/Elements/OutputBox.cs +++ b/Source/Editor/Surface/Elements/OutputBox.cs @@ -190,7 +190,7 @@ namespace FlaxEditor.Surface.Elements Box targetBox = Connections[i]; var endPos = targetBox.ConnectionOrigin; var highlight = DefaultConnectionThickness + Mathf.Max(startHighlight, targetBox.ConnectionsHighlightIntensity); - var alpha = targetBox.Enabled && targetBox.IsActive ? 1.0f : 0.6f; + var alpha = targetBox.IsDisabled ? 0.6f : 1.0f; // We have to calculate an offset here to preserve the original color for when the default connection thickness is larger than 1 var highlightOffset = (highlight - (DefaultConnectionThickness - 1)); @@ -216,7 +216,7 @@ namespace FlaxEditor.Surface.Elements // Draw all the connections var startPos = ConnectionOrigin; var endPos = targetBox.ConnectionOrigin; - var alpha = targetBox.Enabled && targetBox.IsActive ? 1.0f : 0.6f; + var alpha = targetBox.IsDisabled ? 0.6f : 1.0f; var color = _currentTypeColor * alpha; DrawConnection(Surface.Style, ref startPos, ref endPos, ref color, SelectedConnectionThickness); } diff --git a/Source/Editor/Surface/SurfaceStyle.cs b/Source/Editor/Surface/SurfaceStyle.cs index 654cf7abf..86707efd3 100644 --- a/Source/Editor/Surface/SurfaceStyle.cs +++ b/Source/Editor/Surface/SurfaceStyle.cs @@ -233,7 +233,7 @@ namespace FlaxEditor.Surface // Draw icon bool hasConnections = box.HasAnyConnection; - float alpha = box.Enabled && box.IsActive ? 1.0f : 0.6f; + float alpha = box.IsDisabled ? 0.6f : 1.0f; Color color = box.CurrentTypeColor * alpha; var style = box.Surface.Style; SpriteHandle icon; From 21d46dad070d02af73f2b470ebc93237537f7ec2 Mon Sep 17 00:00:00 2001 From: Saas Date: Thu, 18 Dec 2025 22:55:56 +0100 Subject: [PATCH 06/35] change how connected boxes are drawn --- Source/Editor/Surface/Constants.cs | 2 +- Source/Editor/Surface/SurfaceStyle.cs | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Surface/Constants.cs b/Source/Editor/Surface/Constants.cs index 3310351bf..80aecd3ec 100644 --- a/Source/Editor/Surface/Constants.cs +++ b/Source/Editor/Surface/Constants.cs @@ -55,7 +55,7 @@ namespace FlaxEditor.Surface /// /// The box size (with and height). /// - public const float BoxSize = 12.0f; + public const float BoxSize = 13.0f; /// /// The node layout offset on the y axis (height of the boxes rows, etc.). It's used to make the design more consistent. diff --git a/Source/Editor/Surface/SurfaceStyle.cs b/Source/Editor/Surface/SurfaceStyle.cs index 86707efd3..8d547c14e 100644 --- a/Source/Editor/Surface/SurfaceStyle.cs +++ b/Source/Editor/Surface/SurfaceStyle.cs @@ -2,6 +2,7 @@ using System; using FlaxEditor.Scripting; +using FlaxEditor.Surface.Elements; using FlaxEngine; using FlaxEngine.Utilities; @@ -228,8 +229,9 @@ namespace FlaxEditor.Surface if (rect.Size.LengthSquared < minBoxSize * minBoxSize) return; - // Debugging boxes size + // Debugging boxes size and bounds //Render2D.DrawRectangle(rect, Color.Orange); return; + //Render2D.DrawRectangle(box.Bounds, Color.Green); // Draw icon bool hasConnections = box.HasAnyConnection; @@ -244,13 +246,23 @@ namespace FlaxEditor.Surface color *= box.ConnectionsHighlightIntensity + 1; Render2D.DrawSprite(icon, rect, color); + // Draw connected hint with color from connected output box + if (hasConnections && box.Connections[0] is OutputBox connectedOutputBox) + { + bool connectedSameColor = connectedOutputBox.CurrentTypeColor == box.CurrentTypeColor; + Color innerColor = connectedSameColor ? color.RGBMultiplied(0.4f) : connectedOutputBox.CurrentTypeColor; + innerColor = innerColor * alpha; + Render2D.DrawSprite(icon, rect.MakeExpanded(-5.0f), innerColor); + } + // Draw selection hint if (box.IsSelected) { float outlineAlpha = Mathf.Sin(Time.TimeSinceStartup * 4.0f) * 0.5f + 0.5f; float outlineWidth = Mathf.Lerp(1.5f, 4.0f, outlineAlpha); var outlineRect = new Rectangle(rect.X - outlineWidth, rect.Y - outlineWidth, rect.Width + outlineWidth * 2, rect.Height + outlineWidth * 2); - Render2D.DrawSprite(icon, outlineRect, FlaxEngine.GUI.Style.Current.BorderSelected.RGBMultiplied(1.0f + outlineAlpha * 0.4f)); + Color selectionColor = FlaxEngine.GUI.Style.Current.BorderSelected.RGBMultiplied(1.0f + outlineAlpha * 0.4f); + Render2D.DrawSprite(icon, outlineRect, selectionColor.AlphaMultiplied(0.4f)); } } From a98a76f6e5d2bce1a5b6390f882ad35ca665e1ec Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 20 Dec 2025 00:02:11 +0100 Subject: [PATCH 07/35] fix box spacing and (auto calculate) node height - Work in progress but enough progress to commit because it basically works, it's just a bit ugly - Node height is now recalculated every time a new element is added to the node - Introduced `Archetype.UseFixedSize` for special nodes like *Color Gradient* or *Curve* that must rely on hardcoded size for now because the auto sizing does not take elements like the gradient editor or curve editor into account (ideally in the future it will) - Fixed input and output box spacing (still some 1px offsets that I'm unsure where they are from, could be placebo though) --- .../Archetypes/Animation.StateMachine.cs | 2 +- Source/Editor/Surface/Archetypes/Animation.cs | 4 +-- .../Editor/Surface/Archetypes/BehaviorTree.cs | 6 ++--- Source/Editor/Surface/Archetypes/Constants.cs | 6 ++--- Source/Editor/Surface/Archetypes/Material.cs | 2 +- .../Surface/Archetypes/ParticleModules.cs | 2 +- Source/Editor/Surface/Archetypes/Particles.cs | 4 +-- Source/Editor/Surface/Archetypes/Textures.cs | 2 +- Source/Editor/Surface/Archetypes/Tools.cs | 11 +++++--- Source/Editor/Surface/Constants.cs | 16 +++++++++--- Source/Editor/Surface/Elements/InputBox.cs | 2 +- Source/Editor/Surface/Elements/OutputBox.cs | 2 +- Source/Editor/Surface/NodeArchetype.cs | 2 ++ Source/Editor/Surface/NodeElementArchetype.cs | 26 +++++++++---------- .../Editor/Surface/ParticleEmitterSurface.cs | 4 +-- Source/Editor/Surface/SurfaceComment.cs | 4 +-- Source/Editor/Surface/SurfaceNode.cs | 21 ++++++++++----- 17 files changed, 69 insertions(+), 47 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Animation.StateMachine.cs b/Source/Editor/Surface/Archetypes/Animation.StateMachine.cs index e66f38398..b4afff091 100644 --- a/Source/Editor/Surface/Archetypes/Animation.StateMachine.cs +++ b/Source/Editor/Surface/Archetypes/Animation.StateMachine.cs @@ -79,7 +79,7 @@ namespace FlaxEditor.Surface.Archetypes : base(id, context, nodeArch, groupArch) { var marginX = FlaxEditor.Surface.Constants.NodeMarginX; - var uiStartPosY = FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize; + var uiStartPosY = FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight; var editButton = new Button(marginX, uiStartPosY, 246, 20) { diff --git a/Source/Editor/Surface/Archetypes/Animation.cs b/Source/Editor/Surface/Archetypes/Animation.cs index 9f3112905..ad5e45611 100644 --- a/Source/Editor/Surface/Archetypes/Animation.cs +++ b/Source/Editor/Surface/Archetypes/Animation.cs @@ -244,7 +244,7 @@ namespace FlaxEditor.Surface.Archetypes Type = NodeElementType.Input, Position = new Float2( FlaxEditor.Surface.Constants.NodeMarginX - FlaxEditor.Surface.Constants.BoxOffsetX, - FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize + ylevel * FlaxEditor.Surface.Constants.LayoutOffsetY), + FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight + ylevel * FlaxEditor.Surface.Constants.LayoutOffsetY), Text = "Pose " + _blendPoses.Count, Single = true, ValueIndex = -1, @@ -263,7 +263,7 @@ namespace FlaxEditor.Surface.Archetypes private void UpdateHeight() { float nodeHeight = 10 + (Mathf.Max(_blendPoses.Count, 1) + 3) * FlaxEditor.Surface.Constants.LayoutOffsetY; - Height = nodeHeight + FlaxEditor.Surface.Constants.NodeMarginY * 2 + FlaxEditor.Surface.Constants.NodeHeaderSize + FlaxEditor.Surface.Constants.NodeFooterSize; + Height = nodeHeight + FlaxEditor.Surface.Constants.NodeMarginY * 2 + FlaxEditor.Surface.Constants.NodeHeaderHeight + FlaxEditor.Surface.Constants.NodeFooterSize; } /// diff --git a/Source/Editor/Surface/Archetypes/BehaviorTree.cs b/Source/Editor/Surface/Archetypes/BehaviorTree.cs index 9c9325177..63f6f5c2d 100644 --- a/Source/Editor/Surface/Archetypes/BehaviorTree.cs +++ b/Source/Editor/Surface/Archetypes/BehaviorTree.cs @@ -515,7 +515,7 @@ namespace FlaxEditor.Surface.Archetypes height += decorator.Height + DecoratorsMarginY; width = Mathf.Max(width, decorator.Width - FlaxEditor.Surface.Constants.NodeCloseButtonSize - 2 * DecoratorsMarginX); } - Size = new Float2(width + FlaxEditor.Surface.Constants.NodeMarginX * 2 + FlaxEditor.Surface.Constants.NodeCloseButtonSize, height + FlaxEditor.Surface.Constants.NodeHeaderSize + FlaxEditor.Surface.Constants.NodeFooterSize); + Size = new Float2(width + FlaxEditor.Surface.Constants.NodeMarginX * 2 + FlaxEditor.Surface.Constants.NodeCloseButtonSize, height + FlaxEditor.Surface.Constants.NodeHeaderHeight + FlaxEditor.Surface.Constants.NodeFooterSize); UpdateRectangles(); } @@ -537,7 +537,7 @@ namespace FlaxEditor.Surface.Archetypes decorator.IndexInParent = indexInParent + 1; // Push elements above the node } const float footerSize = FlaxEditor.Surface.Constants.NodeFooterSize; - const float headerSize = FlaxEditor.Surface.Constants.NodeHeaderSize; + const float headerSize = FlaxEditor.Surface.Constants.NodeHeaderHeight; const float closeButtonMargin = FlaxEditor.Surface.Constants.NodeCloseButtonMargin; const float closeButtonSize = FlaxEditor.Surface.Constants.NodeCloseButtonSize; _headerRect = new Rectangle(0, bounds.Y - Y, bounds.Width, headerSize); @@ -676,7 +676,7 @@ namespace FlaxEditor.Surface.Archetypes width = Mathf.Max(width, _debugInfoSize.X + 8.0f); height += _debugInfoSize.Y + 8.0f; } - return new Float2(width + FlaxEditor.Surface.Constants.NodeCloseButtonSize * 2 + DecoratorsMarginX * 2, height + FlaxEditor.Surface.Constants.NodeHeaderSize); + return new Float2(width + FlaxEditor.Surface.Constants.NodeCloseButtonSize * 2 + DecoratorsMarginX * 2, height + FlaxEditor.Surface.Constants.NodeHeaderHeight); } protected override void UpdateRectangles() diff --git a/Source/Editor/Surface/Archetypes/Constants.cs b/Source/Editor/Surface/Archetypes/Constants.cs index ad88fa56a..680cc512d 100644 --- a/Source/Editor/Surface/Archetypes/Constants.cs +++ b/Source/Editor/Surface/Archetypes/Constants.cs @@ -166,7 +166,7 @@ namespace FlaxEditor.Surface.Archetypes _picker = new EnumComboBox(type) { EnumTypeValue = Values[0], - Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 160, 16), + Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 160, 16), Parent = this, }; _picker.ValueChanged += () => SetValue(0, _picker.EnumTypeValue); @@ -218,7 +218,7 @@ namespace FlaxEditor.Surface.Archetypes _output = (OutputBox)Elements[0]; _typePicker = new TypePickerControl { - Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 160, 16), + Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 160, 16), Parent = this, }; _typePicker.ValueChanged += () => Set(3); @@ -362,7 +362,7 @@ namespace FlaxEditor.Surface.Archetypes _output = (OutputBox)Elements[0]; _keyTypePicker = new TypePickerControl { - Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 160, 16), + Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 160, 16), Parent = this, }; _keyTypePicker.ValueChanged += OnKeyTypeChanged; diff --git a/Source/Editor/Surface/Archetypes/Material.cs b/Source/Editor/Surface/Archetypes/Material.cs index e46038639..f707e4c2b 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -323,7 +323,7 @@ namespace FlaxEditor.Surface.Archetypes public CustomCodeNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch) : base(id, context, nodeArch, groupArch) { - Float2 pos = new Float2(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize), size; + Float2 pos = new Float2(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight), size; if (nodeArch.TypeID == 8) { pos += new Float2(60, 0); diff --git a/Source/Editor/Surface/Archetypes/ParticleModules.cs b/Source/Editor/Surface/Archetypes/ParticleModules.cs index 4a68c31e0..debc88d59 100644 --- a/Source/Editor/Surface/Archetypes/ParticleModules.cs +++ b/Source/Editor/Surface/Archetypes/ParticleModules.cs @@ -461,7 +461,7 @@ namespace FlaxEditor.Surface.Archetypes /// /// The particle module node elements offset applied to controls to reduce default surface node header thickness. /// - private const float NodeElementsOffset = 16.0f - Surface.Constants.NodeHeaderSize; + private const float NodeElementsOffset = 16.0f - Surface.Constants.NodeHeaderHeight; private const NodeFlags DefaultModuleFlags = NodeFlags.ParticleEmitterGraph | NodeFlags.NoSpawnViaGUI | NodeFlags.NoMove; diff --git a/Source/Editor/Surface/Archetypes/Particles.cs b/Source/Editor/Surface/Archetypes/Particles.cs index 5b8c05381..d5319b875 100644 --- a/Source/Editor/Surface/Archetypes/Particles.cs +++ b/Source/Editor/Surface/Archetypes/Particles.cs @@ -74,7 +74,7 @@ namespace FlaxEditor.Surface.Archetypes /// /// The header height. /// - public const float HeaderHeight = FlaxEditor.Surface.Constants.NodeHeaderSize; + public const float HeaderHeight = FlaxEditor.Surface.Constants.NodeHeaderHeight; /// /// Gets the type of the module. @@ -199,7 +199,7 @@ namespace FlaxEditor.Surface.Archetypes DrawChildren(); // Options border - var optionsAreaStart = FlaxEditor.Surface.Constants.NodeHeaderSize + 3.0f; + var optionsAreaStart = FlaxEditor.Surface.Constants.NodeHeaderHeight + 3.0f; var optionsAreaHeight = 7 * FlaxEditor.Surface.Constants.LayoutOffsetY + 6.0f; Render2D.DrawRectangle(new Rectangle(1, optionsAreaStart, Width - 2, optionsAreaHeight), style.BackgroundSelected); diff --git a/Source/Editor/Surface/Archetypes/Textures.cs b/Source/Editor/Surface/Archetypes/Textures.cs index c1132e947..4a5bff299 100644 --- a/Source/Editor/Surface/Archetypes/Textures.cs +++ b/Source/Editor/Surface/Archetypes/Textures.cs @@ -54,7 +54,7 @@ namespace FlaxEditor.Surface.Archetypes { _textureGroupPicker = new ComboBox { - Location = new Float2(FlaxEditor.Surface.Constants.NodeMarginX + 50, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize + FlaxEditor.Surface.Constants.LayoutOffsetY * 5), + Location = new Float2(FlaxEditor.Surface.Constants.NodeMarginX + 50, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight + FlaxEditor.Surface.Constants.LayoutOffsetY * 5), Width = 100, Parent = this, }; diff --git a/Source/Editor/Surface/Archetypes/Tools.cs b/Source/Editor/Surface/Archetypes/Tools.cs index 685068986..13691a05b 100644 --- a/Source/Editor/Surface/Archetypes/Tools.cs +++ b/Source/Editor/Surface/Archetypes/Tools.cs @@ -467,6 +467,7 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new CurveNode(id, context, arch, groupArch), Description = "An animation spline represented by a set of keyframes, each representing an endpoint of a Bezier curve.", Flags = NodeFlags.AllGraphs, + UseFixedSize = true, Size = new Float2(400, 180.0f), DefaultValues = new object[] { @@ -828,7 +829,7 @@ namespace FlaxEditor.Surface.Archetypes _picker = new TypePickerControl { Type = ScriptType.FlaxObject, - Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX + 20, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 160, 16), + Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX + 20, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 160, 16), Parent = this, }; _picker.ValueChanged += () => SetValue(0, _picker.ValueTypeName); @@ -897,7 +898,7 @@ namespace FlaxEditor.Surface.Archetypes _picker = new TypePickerControl { Type = ScriptType.Object, - Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 140, 16), + Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 140, 16), Parent = this, }; _picker.ValueChanged += () => SetValue(0, _picker.ValueTypeName); @@ -948,7 +949,7 @@ namespace FlaxEditor.Surface.Archetypes _picker = new TypePickerControl { Type = ScriptType.FlaxObject, - Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX + 20, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 160, 16), + Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX + 20, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 160, 16), Parent = this, }; _picker.ValueChanged += () => SetValue(0, _picker.ValueTypeName); @@ -999,7 +1000,7 @@ namespace FlaxEditor.Surface.Archetypes _picker = new TypePickerControl { Type = type, - Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX + 20, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 160, 16), + Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX + 20, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 160, 16), Parent = this, }; _picker.ValueChanged += () => SetValue(0, _picker.ValueTypeName); @@ -1510,6 +1511,7 @@ namespace FlaxEditor.Surface.Archetypes Description = "Linear color gradient sampler", Flags = NodeFlags.AllGraphs, Size = new Float2(400, 150.0f), + UseFixedSize = true, DefaultValues = new object[] { // Stops count @@ -1829,6 +1831,7 @@ namespace FlaxEditor.Surface.Archetypes Description = "Reroute a connection.", Flags = NodeFlags.NoCloseButton | NodeFlags.NoSpawnViaGUI | NodeFlags.AllGraphs, Size = RerouteNode.DefaultSize, + UseFixedSize = true, ConnectionsHints = ConnectionsHint.All, IndependentBoxes = new int[] { 0 }, DependentBoxes = new int[] { 1 }, diff --git a/Source/Editor/Surface/Constants.cs b/Source/Editor/Surface/Constants.cs index 80aecd3ec..58dee6084 100644 --- a/Source/Editor/Surface/Constants.cs +++ b/Source/Editor/Surface/Constants.cs @@ -23,7 +23,7 @@ namespace FlaxEditor.Surface /// /// The node header height. /// - public const float NodeHeaderSize = 20.0f; + public const float NodeHeaderHeight = 20.0f; public const float NodeHeaderTextScale = 0.65f; @@ -35,7 +35,7 @@ namespace FlaxEditor.Surface /// /// The node left margin. /// - public const float NodeMarginX = 5.0f; + public const float NodeMarginX = 8.0f; /// /// The node right margin. @@ -45,7 +45,7 @@ namespace FlaxEditor.Surface /// /// The box position offset on the x axis. /// - public const float BoxOffsetX = 2.0f; + public const float BoxOffsetX = 0.0f; /// /// The width of the row that is started by a box. @@ -61,5 +61,15 @@ namespace FlaxEditor.Surface /// The node layout offset on the y axis (height of the boxes rows, etc.). It's used to make the design more consistent. /// public const float LayoutOffsetY = 22.0f; + + /// + /// The offset between the box text and the box + /// + public const float BoxTextOffset = 4.0f; + + /// + /// The width of the rectangle used to draw the box text. + /// + public const float BoxTextRectWidth = 1410.0f; } } diff --git a/Source/Editor/Surface/Elements/InputBox.cs b/Source/Editor/Surface/Elements/InputBox.cs index 9861ebacd..113da6c68 100644 --- a/Source/Editor/Surface/Elements/InputBox.cs +++ b/Source/Editor/Surface/Elements/InputBox.cs @@ -1442,7 +1442,7 @@ namespace FlaxEditor.Surface.Elements // Draw text var style = Style.Current; - var rect = new Rectangle(Width + 4, 0, 1410, Height); + var rect = new Rectangle(Width + Constants.BoxTextOffset, 0, Constants.BoxTextRectWidth, Height); Render2D.DrawText(style.FontSmall, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Near, TextAlignment.Center); } diff --git a/Source/Editor/Surface/Elements/OutputBox.cs b/Source/Editor/Surface/Elements/OutputBox.cs index 0673f694b..025b16f4b 100644 --- a/Source/Editor/Surface/Elements/OutputBox.cs +++ b/Source/Editor/Surface/Elements/OutputBox.cs @@ -234,7 +234,7 @@ namespace FlaxEditor.Surface.Elements // Draw text var style = Style.Current; - var rect = new Rectangle(-100, 0, 100 - 2, Height); + var rect = new Rectangle(-Constants.BoxTextRectWidth - Constants.BoxTextOffset, 0, Constants.BoxTextRectWidth, Height); Render2D.DrawText(style.FontSmall, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Far, TextAlignment.Center); } } diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs index b29dd0956..18e6ac8c9 100644 --- a/Source/Editor/Surface/NodeArchetype.cs +++ b/Source/Editor/Surface/NodeArchetype.cs @@ -129,6 +129,8 @@ namespace FlaxEditor.Surface /// public NodeFlags Flags; + public bool UseFixedSize = false; + /// /// Title text. /// diff --git a/Source/Editor/Surface/NodeElementArchetype.cs b/Source/Editor/Surface/NodeElementArchetype.cs index 1a9d4ae74..d8008f53f 100644 --- a/Source/Editor/Surface/NodeElementArchetype.cs +++ b/Source/Editor/Surface/NodeElementArchetype.cs @@ -78,12 +78,12 @@ namespace FlaxEditor.Surface /// /// Gets the actual element position on the y axis. /// - public float ActualPositionY => Position.Y + Constants.NodeMarginY + Constants.NodeHeaderSize; + public float ActualPositionY => Position.Y + Constants.NodeMarginY + Constants.NodeHeaderHeight; /// /// Gets the actual element position. /// - public Float2 ActualPosition => new Float2(Position.X + Constants.NodeMarginX, Position.Y + Constants.NodeMarginY + Constants.NodeHeaderSize); + public Float2 ActualPosition => new Float2(Position.X + Constants.NodeMarginX, Position.Y + Constants.NodeMarginY + Constants.NodeHeaderHeight); /// /// Node element archetypes factory object. Helps to build surface nodes archetypes. @@ -107,7 +107,7 @@ namespace FlaxEditor.Surface Type = NodeElementType.Input, Position = new Float2( Constants.NodeMarginX - Constants.BoxOffsetX, - Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY), + Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY), Text = text, Single = single, ValueIndex = valueIndex, @@ -133,7 +133,7 @@ namespace FlaxEditor.Surface Type = NodeElementType.Input, Position = new Float2( Constants.NodeMarginX - Constants.BoxOffsetX, - Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY), + Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY), Text = text, Single = single, ValueIndex = valueIndex, @@ -158,7 +158,7 @@ namespace FlaxEditor.Surface Type = NodeElementType.Output, Position = new Float2( Constants.NodeMarginX - Constants.BoxRowHeight + Constants.BoxOffsetX, - Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY), + Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY), Text = text, Single = single, ValueIndex = -1, @@ -182,8 +182,8 @@ namespace FlaxEditor.Surface { Type = NodeElementType.Output, Position = new Float2( - Constants.NodeMarginX - Constants.BoxRowHeight + Constants.BoxOffsetX, - Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY), + Constants.NodeMarginX - Constants.BoxSize + Constants.BoxOffsetX, + Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY), Text = text, Single = single, ValueIndex = -1, @@ -228,7 +228,7 @@ namespace FlaxEditor.Surface return new NodeElementArchetype { Type = NodeElementType.IntegerValue, - Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderSize + y), + Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y), Text = null, Single = false, ValueIndex = valueIndex, @@ -254,7 +254,7 @@ namespace FlaxEditor.Surface return new NodeElementArchetype { Type = NodeElementType.UnsignedIntegerValue, - Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderSize + y), + Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y), Text = null, Single = false, ValueIndex = valueIndex, @@ -280,7 +280,7 @@ namespace FlaxEditor.Surface return new NodeElementArchetype { Type = NodeElementType.FloatValue, - Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderSize + y), + Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y), Text = null, Single = false, ValueIndex = valueIndex, @@ -359,7 +359,7 @@ namespace FlaxEditor.Surface return new NodeElementArchetype { Type = NodeElementType.ColorValue, - Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderSize + y), + Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y), Text = null, Single = false, ValueIndex = valueIndex, @@ -530,7 +530,7 @@ namespace FlaxEditor.Surface return new NodeElementArchetype { Type = NodeElementType.TextBox, - Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderSize + y), + Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y), Size = new Float2(width, height), Single = false, ValueIndex = valueIndex, @@ -595,7 +595,7 @@ namespace FlaxEditor.Surface return new NodeElementArchetype { Type = NodeElementType.BoxValue, - Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderSize + y), + Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y), Text = null, Single = false, ValueIndex = valueIndex, diff --git a/Source/Editor/Surface/ParticleEmitterSurface.cs b/Source/Editor/Surface/ParticleEmitterSurface.cs index f332471fb..c61d4365d 100644 --- a/Source/Editor/Surface/ParticleEmitterSurface.cs +++ b/Source/Editor/Surface/ParticleEmitterSurface.cs @@ -59,7 +59,7 @@ namespace FlaxEditor.Surface var width = _rootNode.Width; var rootPos = _rootNode.Location; var pos = rootPos; - pos.Y += Constants.NodeHeaderSize + 1.0f + 7 * Constants.LayoutOffsetY + 6.0f + 4.0f; + pos.Y += Constants.NodeHeaderHeight + 1.0f + 7 * Constants.LayoutOffsetY + 6.0f + 4.0f; for (int i = 0; i < _rootNode.Headers.Length; i++) { @@ -67,7 +67,7 @@ namespace FlaxEditor.Surface var modulesStart = pos - rootPos; var modules = modulesGroups.FirstOrDefault(x => x.Key == header.ModuleType); - pos.Y += Constants.NodeHeaderSize + 2.0f; + pos.Y += Constants.NodeHeaderHeight + 2.0f; if (modules != null) { foreach (var module in modules) diff --git a/Source/Editor/Surface/SurfaceComment.cs b/Source/Editor/Surface/SurfaceComment.cs index 10e9fc776..3c04cb736 100644 --- a/Source/Editor/Surface/SurfaceComment.cs +++ b/Source/Editor/Surface/SurfaceComment.cs @@ -70,7 +70,7 @@ namespace FlaxEditor.Surface { _renameTextBox = new TextBox(false, 0, 0, Width) { - Height = Constants.NodeHeaderSize, + Height = Constants.NodeHeaderHeight, Visible = false, Parent = this, EndEditOnClick = false, // We have to handle this ourselves, otherwise the textbox instantly loses focus when double-clicking the header @@ -158,7 +158,7 @@ namespace FlaxEditor.Surface /// protected override void UpdateRectangles() { - const float headerSize = Constants.NodeHeaderSize; + const float headerSize = Constants.NodeHeaderHeight; const float buttonMargin = Constants.NodeCloseButtonMargin; const float buttonSize = Constants.NodeCloseButtonSize; _headerRect = new Rectangle(0, 0, Width, headerSize); diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index ad74f58ae..56c327f49 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -135,7 +135,7 @@ namespace FlaxEditor.Surface /// The node archetype. /// The group archetype. public SurfaceNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch) - : base(context, nodeArch.Size.X + Constants.NodeMarginX * 2, nodeArch.Size.Y + Constants.NodeMarginY * 2 + Constants.NodeHeaderSize + Constants.NodeFooterSize) + : base(context, nodeArch.Size.X + Constants.NodeMarginX * 2, nodeArch.Size.Y + Constants.NodeMarginY * 2 + Constants.NodeHeaderHeight + Constants.NodeFooterSize) { Title = nodeArch.Title; ID = id; @@ -173,7 +173,7 @@ namespace FlaxEditor.Surface /// The node control total size. protected virtual Float2 CalculateNodeSize(float width, float height) { - return new Float2(width + Constants.NodeMarginX * 2, height + Constants.NodeMarginY * 2 + Constants.NodeHeaderSize + Constants.NodeFooterSize); + return new Float2(width + Constants.NodeMarginX * 2, height + Constants.NodeMarginY * 2 + Constants.NodeHeaderHeight + Constants.NodeFooterSize); } /// @@ -227,25 +227,28 @@ namespace FlaxEditor.Surface var child = Children[i]; if (!child.Visible) continue; + // Input boxes 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); + leftHeight = Mathf.Max(leftHeight, inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderHeight + 20.0f); } + // Output boxes 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); + rightHeight = Mathf.Max(rightHeight, outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderHeight + 20.0f); } + // Other controls in the node 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); + height = Mathf.Max(height, control.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderHeight); } else if (!_headerRect.Intersects(control.Bounds)) { @@ -337,6 +340,10 @@ namespace FlaxEditor.Surface Elements.Add(element); if (element is Control control) AddChild(control); + + // TODO: Perform this at a better time instead of every time an element gets added. + if (!Archetype.UseFixedSize) + ResizeAuto(); } /// @@ -377,7 +384,7 @@ namespace FlaxEditor.Surface // Sync properties for exiting box box.Text = text; box.CurrentType = type; - box.Y = Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY; + box.Y = Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY; } // Update box @@ -1040,7 +1047,7 @@ namespace FlaxEditor.Surface protected override void UpdateRectangles() { const float footerSize = Constants.NodeFooterSize; - const float headerSize = Constants.NodeHeaderSize; + const float headerSize = Constants.NodeHeaderHeight; const float closeButtonMargin = Constants.NodeCloseButtonMargin; const float closeButtonSize = Constants.NodeCloseButtonSize; _headerRect = new Rectangle(0, 0, Width, headerSize); From a92d2b6ca2353d862c60086e77507a2e0a0955a7 Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 20 Dec 2025 16:58:35 +0100 Subject: [PATCH 08/35] add slight background grid --- Source/Editor/Surface/VisjectSurface.Draw.cs | 47 +++++++++++++++++--- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/Source/Editor/Surface/VisjectSurface.Draw.cs b/Source/Editor/Surface/VisjectSurface.Draw.cs index 0138bce8d..0b7f6eaae 100644 --- a/Source/Editor/Surface/VisjectSurface.Draw.cs +++ b/Source/Editor/Surface/VisjectSurface.Draw.cs @@ -66,6 +66,47 @@ namespace FlaxEditor.Surface protected virtual void DrawBackground() { DrawBackgroundSolidColor(Style.BackgroundColor, Width, Height); + DrawGridBackground(Width, Height); + } + + // TODO: Rename (and get rid of old texture based draw background?) + internal static void DrawBackgroundSolidColor(Color color, float width, float height) + { + Rectangle backgroundRect = new Rectangle(0f, 0f, width, height); + Render2D.FillRectangle(backgroundRect, color); + } + + internal void DrawGridBackground(float width, float height) + { + var viewRect = GetClientArea(); + var upperLeft = _rootControl.PointFromParent(viewRect.Location); + var bottomRight = _rootControl.PointFromParent(viewRect.Size); + var min = Float2.Min(upperLeft, bottomRight); + var max = Float2.Max(upperLeft, bottomRight); + var pixelRange = (max - min) * ViewScale * 2.75f; + Render2D.PushClip(ref viewRect); + DrawAxis(Float2.UnitX, viewRect, min.X, max.X, pixelRange.X); + DrawAxis(Float2.UnitY, viewRect, min.Y, max.Y, pixelRange.Y); + Render2D.PopClip(); + } + + private void DrawAxis(Float2 axis, Rectangle viewRect, float min, float max, float pixelRange) + { + var linesColor = Style.BackgroundColor.RGBMultiplied(1.2f); + float[] _gridTickStrengths = { 0f }; + Utilities.Utils.DrawCurveTicks((decimal tick, double step, float strength) => + { + var p = _rootControl.PointToParent(axis * (float)tick); ; + + // Draw line + var lineRect = new Rectangle + ( + viewRect.Location + (p - 0.5f) * axis, + Float2.Lerp(viewRect.Size, Float2.One, axis) + ); + Render2D.FillRectangle(lineRect, linesColor.AlphaMultiplied(strength)); + + }, Utilities.Utils.CurveTickSteps, ref _gridTickStrengths, min, max, pixelRange); } internal static void DrawBackgroundDefault(Texture background, float width, float height) @@ -95,12 +136,6 @@ namespace FlaxEditor.Surface } } - internal static void DrawBackgroundSolidColor(Color color, float width, float height) - { - Rectangle backgroundRect = new Rectangle(0f, 0f, width, height); - Render2D.FillRectangle(backgroundRect, color); - } - /// /// Draws the selection background. /// From 3279016067f4ef1ead1c6f2fb8b3c04b25cd92f4 Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 20 Dec 2025 20:32:40 +0100 Subject: [PATCH 09/35] tweak some node spacing --- Source/Editor/Surface/Constants.cs | 22 ++++++++++++++------- Source/Editor/Surface/Elements/InputBox.cs | 2 +- Source/Editor/Surface/Elements/OutputBox.cs | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Source/Editor/Surface/Constants.cs b/Source/Editor/Surface/Constants.cs index 58dee6084..bec0b5183 100644 --- a/Source/Editor/Surface/Constants.cs +++ b/Source/Editor/Surface/Constants.cs @@ -13,7 +13,7 @@ namespace FlaxEditor.Surface /// /// The node close button size. /// - public const float NodeCloseButtonSize = 12.0f; + public const float NodeCloseButtonSize = 16.0f; /// /// The node close button margin from the edges. @@ -25,6 +25,9 @@ namespace FlaxEditor.Surface /// public const float NodeHeaderHeight = 20.0f; + /// + /// The scale of the header text. + /// public const float NodeHeaderTextScale = 0.65f; /// @@ -33,14 +36,14 @@ namespace FlaxEditor.Surface public const float NodeFooterSize = 2.0f; /// - /// The node left margin. + /// The horizontal node margin. /// public const float NodeMarginX = 8.0f; /// - /// The node right margin. + /// The vertical node right margin. /// - public const float NodeMarginY = 5.0f; + public const float NodeMarginY = 7.0f; /// /// The box position offset on the x axis. @@ -50,7 +53,7 @@ namespace FlaxEditor.Surface /// /// The width of the row that is started by a box. /// - public const float BoxRowHeight = 18.0f; + public const float BoxRowHeight = 19.0f; /// /// The box size (with and height). @@ -60,7 +63,7 @@ namespace FlaxEditor.Surface /// /// The node layout offset on the y axis (height of the boxes rows, etc.). It's used to make the design more consistent. /// - public const float LayoutOffsetY = 22.0f; + public const float LayoutOffsetY = 24.0f; /// /// The offset between the box text and the box @@ -70,6 +73,11 @@ namespace FlaxEditor.Surface /// /// The width of the rectangle used to draw the box text. /// - public const float BoxTextRectWidth = 1410.0f; + public const float BoxTextRectWidth = 500.0f; + + /// + /// The scale of text of boxes. + /// + public const float BoxTextScale = 1.175f; } } diff --git a/Source/Editor/Surface/Elements/InputBox.cs b/Source/Editor/Surface/Elements/InputBox.cs index 113da6c68..5a4bfc31c 100644 --- a/Source/Editor/Surface/Elements/InputBox.cs +++ b/Source/Editor/Surface/Elements/InputBox.cs @@ -1443,7 +1443,7 @@ namespace FlaxEditor.Surface.Elements // Draw text var style = Style.Current; var rect = new Rectangle(Width + Constants.BoxTextOffset, 0, Constants.BoxTextRectWidth, Height); - Render2D.DrawText(style.FontSmall, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Near, TextAlignment.Center); + Render2D.DrawText(style.FontMedium, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Near, TextAlignment.Center, TextWrapping.NoWrap, 1f, Constants.BoxTextScale); } /// diff --git a/Source/Editor/Surface/Elements/OutputBox.cs b/Source/Editor/Surface/Elements/OutputBox.cs index 025b16f4b..3e473d7ac 100644 --- a/Source/Editor/Surface/Elements/OutputBox.cs +++ b/Source/Editor/Surface/Elements/OutputBox.cs @@ -235,7 +235,7 @@ namespace FlaxEditor.Surface.Elements // Draw text var style = Style.Current; var rect = new Rectangle(-Constants.BoxTextRectWidth - Constants.BoxTextOffset, 0, Constants.BoxTextRectWidth, Height); - Render2D.DrawText(style.FontSmall, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Far, TextAlignment.Center); + Render2D.DrawText(style.FontMedium, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Far, TextAlignment.Center, TextWrapping.NoWrap, 1f, Constants.BoxTextScale); } } } From 2c98d805063d0f113975a6e859964dda2dded291 Mon Sep 17 00:00:00 2001 From: Saas Date: Wed, 4 Mar 2026 23:15:09 +0100 Subject: [PATCH 10/35] fix node auto resizing --- Source/Editor/Surface/Archetypes/Comparisons.cs | 10 +++++----- Source/Editor/Surface/Archetypes/Material.cs | 5 +++-- Source/Editor/Surface/Archetypes/Textures.cs | 7 ++++--- Source/Editor/Surface/Constants.cs | 14 +++++++------- Source/Editor/Surface/ResizableSurfaceNode.cs | 6 ++++++ Source/Editor/Surface/SurfaceComment.cs | 2 +- Source/Editor/Surface/SurfaceNode.cs | 11 +++++++++++ 7 files changed, 37 insertions(+), 18 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Comparisons.cs b/Source/Editor/Surface/Archetypes/Comparisons.cs index bcf0159d2..da81ba21d 100644 --- a/Source/Editor/Surface/Archetypes/Comparisons.cs +++ b/Source/Editor/Surface/Archetypes/Comparisons.cs @@ -39,7 +39,7 @@ namespace FlaxEditor.Surface.Archetypes { NodeElementArchetype.Factory.Input(0, string.Empty, true, null, 0, 0), NodeElementArchetype.Factory.Input(1, string.Empty, true, null, 1, 1), - NodeElementArchetype.Factory.Output(0, title, typeof(bool), 2) + NodeElementArchetype.Factory.Output(0, "Result", typeof(bool), 2) } }; } @@ -173,10 +173,10 @@ namespace FlaxEditor.Surface.Archetypes { Op(1, "==", "Determines whether two values are equal", new[] { "equals" }), Op(2, "!=", "Determines whether two values are not equal", new[] { "not equals" }), - Op(3, ">", "Determines whether the first value is greater than the other", new[] { "greater than", "larger than", "bigger than" }), - Op(4, "<", "Determines whether the first value is less than the other", new[] { "less than", "smaller than" }), - Op(5, "<=", "Determines whether the first value is less or equal to the other", new[] { "less equals than", "smaller equals than" }), - Op(6, ">=", "Determines whether the first value is greater or equal to the other", new[] { "greater equals than", "larger equals than", "bigger equals than" }), + Op(3, ">", "Determines whether the first value is greater than the other", new[] { "greater than", "larger than", "bigger than", "more than" }), + Op(4, "<", "Determines whether the first value is less than the other", new[] { "less than", "smaller than", "tinier than" }), + Op(5, "<=", "Determines whether the first value is less or equal to the other", new[] { "less equals than", "smaller equals than", "tinier equals than" }), + Op(6, ">=", "Determines whether the first value is greater or equal to the other", new[] { "greater equals than", "larger equals than", "bigger equals than", "more equals than" }), new NodeArchetype { TypeID = 7, diff --git a/Source/Editor/Surface/Archetypes/Material.cs b/Source/Editor/Surface/Archetypes/Material.cs index 59138c29e..2a9a3ca0d 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -312,11 +312,12 @@ namespace FlaxEditor.Surface.Archetypes : base(id, context, nodeArch, groupArch) { _sizeValueIndex = Archetype.TypeID == 8 ? 1 : 3; // Index of the Size stored in Values array - Float2 pos = new Float2(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight), size; + //Float2 pos = new Float2(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight), size; + Float2 pos = new Float2(FlaxEditor.Surface.Constants.NodeMarginX + 25f, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight), size; if (nodeArch.TypeID == 8) { pos += new Float2(60, 0); - size = new Float2(172, 200); + size = new Float2(125, 200); } else { diff --git a/Source/Editor/Surface/Archetypes/Textures.cs b/Source/Editor/Surface/Archetypes/Textures.cs index bf43014c0..fe7f3ec39 100644 --- a/Source/Editor/Surface/Archetypes/Textures.cs +++ b/Source/Editor/Surface/Archetypes/Textures.cs @@ -57,7 +57,7 @@ namespace FlaxEditor.Surface.Archetypes { _textureGroupPicker = new ComboBox { - Location = new Float2(FlaxEditor.Surface.Constants.NodeMarginX + 50, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize + FlaxEditor.Surface.Constants.LayoutOffsetY * _level), + Location = new Float2(FlaxEditor.Surface.Constants.NodeMarginX + 50, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight + FlaxEditor.Surface.Constants.LayoutOffsetY * _level), Width = 100, Parent = this, }; @@ -134,7 +134,8 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new Constants.ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Texture))), Description = "Two dimensional texture object", Flags = NodeFlags.MaterialGraph, - Size = new Float2(140, 120), + UseFixedSize = true, + Size = new Float2(140, 140), DefaultValues = new object[] { Guid.Empty @@ -493,7 +494,7 @@ namespace FlaxEditor.Surface.Archetypes { TypeID = 18, Title = "Lightmap UV", - AlternativeTitles = new string[] { "Lightmap TexCoord" }, + AlternativeTitles = new string[] { "Lightmap TexCoord" }, Description = "Lightmap UVs", Flags = NodeFlags.MaterialGraph, Size = new Float2(110, 20), diff --git a/Source/Editor/Surface/Constants.cs b/Source/Editor/Surface/Constants.cs index bec0b5183..7ca322116 100644 --- a/Source/Editor/Surface/Constants.cs +++ b/Source/Editor/Surface/Constants.cs @@ -23,12 +23,12 @@ namespace FlaxEditor.Surface /// /// The node header height. /// - public const float NodeHeaderHeight = 20.0f; + public const float NodeHeaderHeight = 23.0f; /// /// The scale of the header text. /// - public const float NodeHeaderTextScale = 0.65f; + public const float NodeHeaderTextScale = 0.8f; /// /// The node footer height. @@ -38,12 +38,12 @@ namespace FlaxEditor.Surface /// /// The horizontal node margin. /// - public const float NodeMarginX = 8.0f; + public const float NodeMarginX = 6.0f; /// /// The vertical node right margin. /// - public const float NodeMarginY = 7.0f; + public const float NodeMarginY = 8.0f; /// /// The box position offset on the x axis. @@ -58,7 +58,7 @@ namespace FlaxEditor.Surface /// /// The box size (with and height). /// - public const float BoxSize = 13.0f; + public const float BoxSize = 15.0f; /// /// The node layout offset on the y axis (height of the boxes rows, etc.). It's used to make the design more consistent. @@ -68,7 +68,7 @@ namespace FlaxEditor.Surface /// /// The offset between the box text and the box /// - public const float BoxTextOffset = 4.0f; + public const float BoxTextOffset = 2.0f; /// /// The width of the rectangle used to draw the box text. @@ -78,6 +78,6 @@ namespace FlaxEditor.Surface /// /// The scale of text of boxes. /// - public const float BoxTextScale = 1.175f; + public const float BoxTextScale = 1f;//1.175f; } } diff --git a/Source/Editor/Surface/ResizableSurfaceNode.cs b/Source/Editor/Surface/ResizableSurfaceNode.cs index 259c29836..ee6560a84 100644 --- a/Source/Editor/Surface/ResizableSurfaceNode.cs +++ b/Source/Editor/Surface/ResizableSurfaceNode.cs @@ -74,6 +74,12 @@ namespace FlaxEditor.Surface Resize(size.X, size.Y); } + /// + public override void ResizeAuto() + { + // Do nothing, we want to put full control of node size into the users hands + } + /// public override void Draw() { diff --git a/Source/Editor/Surface/SurfaceComment.cs b/Source/Editor/Surface/SurfaceComment.cs index dea81de15..fb0dd8371 100644 --- a/Source/Editor/Surface/SurfaceComment.cs +++ b/Source/Editor/Surface/SurfaceComment.cs @@ -56,7 +56,7 @@ namespace FlaxEditor.Surface : base(id, context, nodeArch, groupArch) { _sizeValueIndex = 2; // Index of the Size stored in Values array - _sizeMin = new Float2(140.0f, Constants.NodeHeaderSize); + _sizeMin = new Float2(140.0f, Constants.NodeHeaderHeight); _renameTextBox = new TextBox(false, 0, 0, Width) { Height = Constants.NodeHeaderHeight, diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 56c327f49..1c0728d13 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -938,6 +938,9 @@ namespace FlaxEditor.Surface if (Elements[i] is Box box) box.OnConnectionsChanged(); } + + if (!Archetype.UseFixedSize) + ResizeAuto(); } /// @@ -975,6 +978,9 @@ namespace FlaxEditor.Surface Surface.AddBatchedUndoAction(new EditNodeValuesAction(this, before, graphEdited)); _isDuringValuesEditing = false; + + if (!Archetype.UseFixedSize) + ResizeAuto(); } /// @@ -1009,6 +1015,9 @@ namespace FlaxEditor.Surface } _isDuringValuesEditing = false; + + if (!Archetype.UseFixedSize) + ResizeAuto(); } internal void SetIsDuringValuesEditing(bool value) @@ -1041,6 +1050,8 @@ namespace FlaxEditor.Surface public virtual void ConnectionTick(Box box) { UpdateBoxesTypes(); + if (!Archetype.UseFixedSize) + ResizeAuto(); } /// From 23c3edcab979a875f9cc1f26e045c2f3dd7d5193 Mon Sep 17 00:00:00 2001 From: Saas Date: Wed, 4 Mar 2026 23:37:33 +0100 Subject: [PATCH 11/35] small cleanup --- Source/Editor/Surface/Archetypes/Comparisons.cs | 2 +- Source/Editor/Surface/Archetypes/Material.cs | 1 - Source/Editor/Surface/Constants.cs | 2 +- Source/Editor/Surface/SurfaceNode.cs | 1 - Source/Editor/Surface/VisjectSurface.Draw.cs | 1 - 5 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Comparisons.cs b/Source/Editor/Surface/Archetypes/Comparisons.cs index da81ba21d..32baadc1c 100644 --- a/Source/Editor/Surface/Archetypes/Comparisons.cs +++ b/Source/Editor/Surface/Archetypes/Comparisons.cs @@ -39,7 +39,7 @@ namespace FlaxEditor.Surface.Archetypes { NodeElementArchetype.Factory.Input(0, string.Empty, true, null, 0, 0), NodeElementArchetype.Factory.Input(1, string.Empty, true, null, 1, 1), - NodeElementArchetype.Factory.Output(0, "Result", typeof(bool), 2) + NodeElementArchetype.Factory.Output(0, title, typeof(bool), 2) } }; } diff --git a/Source/Editor/Surface/Archetypes/Material.cs b/Source/Editor/Surface/Archetypes/Material.cs index 2a9a3ca0d..241f857b5 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -312,7 +312,6 @@ namespace FlaxEditor.Surface.Archetypes : base(id, context, nodeArch, groupArch) { _sizeValueIndex = Archetype.TypeID == 8 ? 1 : 3; // Index of the Size stored in Values array - //Float2 pos = new Float2(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight), size; Float2 pos = new Float2(FlaxEditor.Surface.Constants.NodeMarginX + 25f, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight), size; if (nodeArch.TypeID == 8) { diff --git a/Source/Editor/Surface/Constants.cs b/Source/Editor/Surface/Constants.cs index 7ca322116..2945a85e9 100644 --- a/Source/Editor/Surface/Constants.cs +++ b/Source/Editor/Surface/Constants.cs @@ -78,6 +78,6 @@ namespace FlaxEditor.Surface /// /// The scale of text of boxes. /// - public const float BoxTextScale = 1f;//1.175f; + public const float BoxTextScale = 1f; } } diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 1c0728d13..deca508b1 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -341,7 +341,6 @@ namespace FlaxEditor.Surface if (element is Control control) AddChild(control); - // TODO: Perform this at a better time instead of every time an element gets added. if (!Archetype.UseFixedSize) ResizeAuto(); } diff --git a/Source/Editor/Surface/VisjectSurface.Draw.cs b/Source/Editor/Surface/VisjectSurface.Draw.cs index 0b7f6eaae..0665a8ebb 100644 --- a/Source/Editor/Surface/VisjectSurface.Draw.cs +++ b/Source/Editor/Surface/VisjectSurface.Draw.cs @@ -69,7 +69,6 @@ namespace FlaxEditor.Surface DrawGridBackground(Width, Height); } - // TODO: Rename (and get rid of old texture based draw background?) internal static void DrawBackgroundSolidColor(Color color, float width, float height) { Rectangle backgroundRect = new Rectangle(0f, 0f, width, height); From a9c510c29622aa40baecab50b45e0dbdd5a4adcd Mon Sep 17 00:00:00 2001 From: Saas Date: Thu, 5 Mar 2026 19:49:29 +0100 Subject: [PATCH 12/35] tweak some group archetype colors --- Source/Editor/Surface/NodeFactory.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Surface/NodeFactory.cs b/Source/Editor/Surface/NodeFactory.cs index 8448c37a3..30e3628fd 100644 --- a/Source/Editor/Surface/NodeFactory.cs +++ b/Source/Editor/Surface/NodeFactory.cs @@ -116,7 +116,7 @@ namespace FlaxEditor.Surface { GroupID = 9, Name = "Animations", - Color = new Color(105, 179, 160), + Color = new Color(72, 125, 107), Archetypes = Archetypes.Animation.Nodes }, new GroupArchetype @@ -145,7 +145,7 @@ namespace FlaxEditor.Surface { GroupID = 14, Name = "Particles", - Color = new Color(121, 210, 176), + Color = new Color(72, 125, 107), Archetypes = Archetypes.Particles.Nodes }, new GroupArchetype From d3891688f0c6359b4bd61a9552f99bd08354c62f Mon Sep 17 00:00:00 2001 From: Saas Date: Fri, 13 Mar 2026 21:59:53 +0100 Subject: [PATCH 13/35] fix boxes positioning and remove unused constants --- Source/Editor/Surface/Archetypes/Animation.cs | 2 +- Source/Editor/Surface/Constants.cs | 14 ++------------ Source/Editor/Surface/Elements/InputBox.cs | 2 +- Source/Editor/Surface/Elements/OutputBox.cs | 4 ++-- Source/Editor/Surface/NodeElementArchetype.cs | 8 ++++---- Source/Editor/Surface/SurfaceNode.cs | 2 +- Source/Editor/Surface/SurfaceStyle.cs | 2 +- 7 files changed, 12 insertions(+), 22 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Animation.cs b/Source/Editor/Surface/Archetypes/Animation.cs index ad5e45611..48a54a56f 100644 --- a/Source/Editor/Surface/Archetypes/Animation.cs +++ b/Source/Editor/Surface/Archetypes/Animation.cs @@ -243,7 +243,7 @@ namespace FlaxEditor.Surface.Archetypes { Type = NodeElementType.Input, Position = new Float2( - FlaxEditor.Surface.Constants.NodeMarginX - FlaxEditor.Surface.Constants.BoxOffsetX, + FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight + ylevel * FlaxEditor.Surface.Constants.LayoutOffsetY), Text = "Pose " + _blendPoses.Count, Single = true, diff --git a/Source/Editor/Surface/Constants.cs b/Source/Editor/Surface/Constants.cs index 2945a85e9..9b857805e 100644 --- a/Source/Editor/Surface/Constants.cs +++ b/Source/Editor/Surface/Constants.cs @@ -23,7 +23,7 @@ namespace FlaxEditor.Surface /// /// The node header height. /// - public const float NodeHeaderHeight = 23.0f; + public const float NodeHeaderHeight = 25.0f; /// /// The scale of the header text. @@ -45,11 +45,6 @@ namespace FlaxEditor.Surface /// public const float NodeMarginY = 8.0f; - /// - /// The box position offset on the x axis. - /// - public const float BoxOffsetX = 0.0f; - /// /// The width of the row that is started by a box. /// @@ -68,16 +63,11 @@ namespace FlaxEditor.Surface /// /// The offset between the box text and the box /// - public const float BoxTextOffset = 2.0f; + public const float BoxTextOffset = 1.65f; /// /// The width of the rectangle used to draw the box text. /// public const float BoxTextRectWidth = 500.0f; - - /// - /// The scale of text of boxes. - /// - public const float BoxTextScale = 1f; } } diff --git a/Source/Editor/Surface/Elements/InputBox.cs b/Source/Editor/Surface/Elements/InputBox.cs index 5a4bfc31c..3e2bb4d5c 100644 --- a/Source/Editor/Surface/Elements/InputBox.cs +++ b/Source/Editor/Surface/Elements/InputBox.cs @@ -1443,7 +1443,7 @@ namespace FlaxEditor.Surface.Elements // Draw text var style = Style.Current; var rect = new Rectangle(Width + Constants.BoxTextOffset, 0, Constants.BoxTextRectWidth, Height); - Render2D.DrawText(style.FontMedium, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Near, TextAlignment.Center, TextWrapping.NoWrap, 1f, Constants.BoxTextScale); + Render2D.DrawText(style.FontMedium, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Near, TextAlignment.Center); } /// diff --git a/Source/Editor/Surface/Elements/OutputBox.cs b/Source/Editor/Surface/Elements/OutputBox.cs index 3e473d7ac..fa9d15c22 100644 --- a/Source/Editor/Surface/Elements/OutputBox.cs +++ b/Source/Editor/Surface/Elements/OutputBox.cs @@ -234,8 +234,8 @@ namespace FlaxEditor.Surface.Elements // Draw text var style = Style.Current; - var rect = new Rectangle(-Constants.BoxTextRectWidth - Constants.BoxTextOffset, 0, Constants.BoxTextRectWidth, Height); - Render2D.DrawText(style.FontMedium, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Far, TextAlignment.Center, TextWrapping.NoWrap, 1f, Constants.BoxTextScale); + var rect = new Rectangle(-Constants.BoxTextRectWidth - Constants.BoxTextOffset * 2f, 0f, Constants.BoxTextRectWidth, Height); + Render2D.DrawText(style.FontMedium, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Far, TextAlignment.Center); } } } diff --git a/Source/Editor/Surface/NodeElementArchetype.cs b/Source/Editor/Surface/NodeElementArchetype.cs index d8008f53f..55c8a43a7 100644 --- a/Source/Editor/Surface/NodeElementArchetype.cs +++ b/Source/Editor/Surface/NodeElementArchetype.cs @@ -106,7 +106,7 @@ namespace FlaxEditor.Surface { Type = NodeElementType.Input, Position = new Float2( - Constants.NodeMarginX - Constants.BoxOffsetX, + Constants.NodeMarginX, Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY), Text = text, Single = single, @@ -132,7 +132,7 @@ namespace FlaxEditor.Surface { Type = NodeElementType.Input, Position = new Float2( - Constants.NodeMarginX - Constants.BoxOffsetX, + Constants.NodeMarginX, Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY), Text = text, Single = single, @@ -157,7 +157,7 @@ namespace FlaxEditor.Surface { Type = NodeElementType.Output, Position = new Float2( - Constants.NodeMarginX - Constants.BoxRowHeight + Constants.BoxOffsetX, + -Constants.NodeMarginX, Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY), Text = text, Single = single, @@ -182,7 +182,7 @@ namespace FlaxEditor.Surface { Type = NodeElementType.Output, Position = new Float2( - Constants.NodeMarginX - Constants.BoxSize + Constants.BoxOffsetX, + -Constants.NodeMarginX, Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY), Text = text, Single = single, diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index deca508b1..a775d446c 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -199,7 +199,7 @@ namespace FlaxEditor.Surface { if (Elements[i] is OutputBox box) { - box.Location = box.Archetype.Position + new Float2(width, 0); + box.Location = box.Archetype.Position + new Float2(width - Constants.NodeMarginX, 0); } } diff --git a/Source/Editor/Surface/SurfaceStyle.cs b/Source/Editor/Surface/SurfaceStyle.cs index 8d547c14e..94d9b04df 100644 --- a/Source/Editor/Surface/SurfaceStyle.cs +++ b/Source/Editor/Surface/SurfaceStyle.cs @@ -222,7 +222,7 @@ namespace FlaxEditor.Surface private static void DefaultDrawBox(Elements.Box box) { - var rect = new Rectangle(0.0f, box.Height * 0.5f - Constants.BoxSize * 0.5f, new Float2(Constants.BoxSize)); + var rect = new Rectangle(box.Width * 0.5f - Constants.BoxSize * 0.5f, box.Height * 0.5f - Constants.BoxSize * 0.5f, new Float2(Constants.BoxSize)); // Size culling const float minBoxSize = 5.0f; From e008c7e2b4d689bee4e7534628d52e9c2a81718c Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 14 Mar 2026 14:20:00 +0100 Subject: [PATCH 14/35] fix behavior tree nodes --- .../Editor/Surface/Archetypes/BehaviorTree.cs | 78 ++++++++++++++++--- Source/Editor/Surface/SurfaceNode.cs | 4 +- 2 files changed, 69 insertions(+), 13 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/BehaviorTree.cs b/Source/Editor/Surface/Archetypes/BehaviorTree.cs index 63f6f5c2d..69a6e8f7e 100644 --- a/Source/Editor/Surface/Archetypes/BehaviorTree.cs +++ b/Source/Editor/Surface/Archetypes/BehaviorTree.cs @@ -189,21 +189,74 @@ namespace FlaxEditor.Surface.Archetypes public override void Draw() { - base.Draw(); + var style = Style.Current; + + var backgroundRect = new Rectangle(Float2.Zero, Size); + + // Shadow + if (DrawBasicShadow) + { + var shadowRect = backgroundRect.MakeOffsetted(ShadowOffset); + Render2D.FillRectangle(shadowRect, Color.Black.AlphaMultiplied(0.125f)); + } + + // Background + Render2D.FillRectangle(backgroundRect, ArchetypeColor); + + // Breakpoint hit + if (Breakpoint.Hit) + { + var colorTop = Color.OrangeRed; + var colorBottom = Color.Red; + var time = DateTime.Now - Engine.StartupTime; + Render2D.DrawRectangle(backgroundRect.MakeExpanded(Mathf.Lerp(3.0f, 12.0f, Mathf.Sin((float)time.TotalSeconds * 10.0f) * 0.5f + 0.5f)), colorTop, colorTop, colorBottom, colorBottom, 2.0f); + } + + // Header + var headerColor = style.BackgroundHighlighted; + if (_headerRect.Contains(ref _mousePosition) && !Surface.IsConnecting && !Surface.IsSelecting) + headerColor *= 1.07f; + Render2D.FillRectangle(_headerRect, style.BackgroundHighlighted); + Render2D.DrawText(style.FontLarge, Title, _headerTextRect, style.Foreground, TextAlignment.Near, TextAlignment.Center, TextWrapping.NoWrap, 1f, FlaxEditor.Surface.Constants.NodeHeaderTextScale); + + // Close button + if ((Archetype.Flags & NodeFlags.NoCloseButton) == 0 && Surface.CanEdit) + { + bool highlightClose = _closeButtonRect.Contains(_mousePosition) && !Surface.IsConnecting && !Surface.IsSelecting; + Render2D.DrawSprite(style.Cross, _closeButtonRect, highlightClose ? style.Foreground : style.ForegroundGrey); + } + + DrawChildren(); + + // Selection outline + if (_isSelected) + { + var colorTop = Color.Orange; + var colorBottom = Color.OrangeRed; + Render2D.DrawRectangle(backgroundRect, colorTop, colorTop, colorBottom, colorBottom, 2.5f); + } + + // Breakpoint dot + if (Breakpoint.Set) + { + var icon = Breakpoint.Enabled ? Surface.Style.Icons.BoxClose : Surface.Style.Icons.BoxOpen; + Render2D.DrawSprite(icon, new Rectangle(-7, -7, 16, 16), new Color(0.9f, 0.9f, 0.9f)); + Render2D.DrawSprite(icon, new Rectangle(-6, -6, 14, 14), new Color(0.894117647f, 0.0784313725f, 0.0f)); + } + + if (highlightBox != null) + Render2D.DrawRectangle(highlightBox.Bounds, style.BorderHighlighted, 2f); // Debug Info if (!string.IsNullOrEmpty(_debugInfo)) - { - var style = Style.Current; Render2D.DrawText(style.FontSmall, _debugInfo, new Rectangle(4, _headerRect.Bottom + 4, _debugInfoSize), style.Foreground); - } // Debug relevancy outline if (_debugRelevant) { var colorTop = Color.LightYellow; var colorBottom = Color.Yellow; - var backgroundRect = new Rectangle(Float2.One, Size - new Float2(2.0f)); + backgroundRect = new Rectangle(Float2.One, Size - new Float2(2.0f)); Render2D.DrawRectangle(backgroundRect, colorTop, colorTop, colorBottom, colorBottom); } } @@ -515,7 +568,7 @@ namespace FlaxEditor.Surface.Archetypes height += decorator.Height + DecoratorsMarginY; width = Mathf.Max(width, decorator.Width - FlaxEditor.Surface.Constants.NodeCloseButtonSize - 2 * DecoratorsMarginX); } - Size = new Float2(width + FlaxEditor.Surface.Constants.NodeMarginX * 2 + FlaxEditor.Surface.Constants.NodeCloseButtonSize, height + FlaxEditor.Surface.Constants.NodeHeaderHeight + FlaxEditor.Surface.Constants.NodeFooterSize); + Size = new Float2(width + FlaxEditor.Surface.Constants.NodeMarginX * 2 + FlaxEditor.Surface.Constants.NodeCloseButtonSize, height + FlaxEditor.Surface.Constants.NodeHeaderHeight); UpdateRectangles(); } @@ -536,13 +589,13 @@ namespace FlaxEditor.Surface.Archetypes if (decorator.IndexInParent < indexInParent) decorator.IndexInParent = indexInParent + 1; // Push elements above the node } - const float footerSize = FlaxEditor.Surface.Constants.NodeFooterSize; - const float headerSize = FlaxEditor.Surface.Constants.NodeHeaderHeight; + + const float headerHeight = FlaxEditor.Surface.Constants.NodeHeaderHeight; const float closeButtonMargin = FlaxEditor.Surface.Constants.NodeCloseButtonMargin; - const float closeButtonSize = FlaxEditor.Surface.Constants.NodeCloseButtonSize; - _headerRect = new Rectangle(0, bounds.Y - Y, bounds.Width, headerSize); + float closeButtonSize = FlaxEditor.Surface.Constants.NodeCloseButtonSize * 0.65f; + _headerRect = new Rectangle(0, bounds.Y - Y, bounds.Width, headerHeight); + _headerTextRect = _headerRect with { X = 5f, Width = Width - closeButtonSize - closeButtonMargin * 4f }; _closeButtonRect = new Rectangle(bounds.Width - closeButtonSize - closeButtonMargin, _headerRect.Y + closeButtonMargin, closeButtonSize, closeButtonSize); - _footerRect = new Rectangle(0, bounds.Height - footerSize, bounds.Width, footerSize); if (_output != null && _output.Visible) { _footerRect.Y -= ConnectionAreaHeight; @@ -684,6 +737,9 @@ namespace FlaxEditor.Surface.Archetypes base.UpdateRectangles(); _footerRect = Rectangle.Empty; + const float closeButtonMargin = FlaxEditor.Surface.Constants.NodeCloseButtonMargin; + float closeButtonSize = FlaxEditor.Surface.Constants.NodeCloseButtonSize * 0.65f; + _closeButtonRect = new Rectangle(Bounds.Width - closeButtonSize - closeButtonMargin, _headerRect.Y + closeButtonMargin, closeButtonSize, closeButtonSize); if (_dragIcon != null) _dragIcon.Bounds = new Rectangle(_closeButtonRect.X - _closeButtonRect.Width, _closeButtonRect.Y, _closeButtonRect.Size); } diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index a775d446c..0ee35e23e 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -159,7 +159,7 @@ namespace FlaxEditor.Surface public virtual string ContentSearchText => null; /// - /// Gets the color of the footer of the node. + /// Gets the color of the header of the node. /// protected virtual Color ArchetypeColor => GroupArchetype.Color; @@ -1061,7 +1061,7 @@ namespace FlaxEditor.Surface const float closeButtonMargin = Constants.NodeCloseButtonMargin; const float closeButtonSize = Constants.NodeCloseButtonSize; _headerRect = new Rectangle(0, 0, Width, headerSize); - _headerTextRect = _headerRect with { Width = _headerRect.Width - 5f, X = _headerRect.X + 5f }; + _headerTextRect = _headerRect with { X = 5f, Width = Width - closeButtonSize - closeButtonMargin * 4f }; _closeButtonRect = new Rectangle(Width - closeButtonSize - closeButtonMargin, closeButtonMargin, closeButtonSize, closeButtonSize); _footerRect = new Rectangle(0, Height - footerSize, Width, footerSize); } From fcdd05dede36087ec603e386b5d0b71dfc108937 Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 14 Mar 2026 14:20:30 +0100 Subject: [PATCH 15/35] fix straight connection sprite rotation offset at some angles --- Source/Editor/Surface/SurfaceStyle.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Source/Editor/Surface/SurfaceStyle.cs b/Source/Editor/Surface/SurfaceStyle.cs index 94d9b04df..d5bbdaf62 100644 --- a/Source/Editor/Surface/SurfaceStyle.cs +++ b/Source/Editor/Surface/SurfaceStyle.cs @@ -329,13 +329,11 @@ namespace FlaxEditor.Surface { var dir = sub / length; var arrowRect = new Rectangle(0, 0, 16.0f, 16.0f); - float rotation = Float2.Dot(dir, Float2.UnitY); - if (endPos.X < startPos.X) - rotation = 2 - rotation; + float rotation = Mathf.Atan2(dir.Y, dir.X); var sprite = Editor.Instance.Icons.VisjectArrowClosed32; var arrowTransform = Matrix3x3.Translation2D(-6.5f, -8) * - Matrix3x3.RotationZ(rotation * Mathf.PiOverTwo) * + Matrix3x3.RotationZ(rotation) * Matrix3x3.Translation2D(endPos - dir * 8); Render2D.PushTransform(ref arrowTransform); From 0cec65f35f309ddd194783291e02d3f41c047873 Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 14 Mar 2026 14:46:10 +0100 Subject: [PATCH 16/35] disable vertex snapping while drawing box to fix snapping artefacts when zooming surface --- Source/Editor/Surface/SurfaceStyle.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/Editor/Surface/SurfaceStyle.cs b/Source/Editor/Surface/SurfaceStyle.cs index d5bbdaf62..0bfdd641e 100644 --- a/Source/Editor/Surface/SurfaceStyle.cs +++ b/Source/Editor/Surface/SurfaceStyle.cs @@ -244,6 +244,10 @@ namespace FlaxEditor.Surface else icon = hasConnections ? style.Icons.BoxClose : style.Icons.BoxOpen; color *= box.ConnectionsHighlightIntensity + 1; + + var features = Render2D.Features; + Render2D.Features = features & ~Render2D.RenderingFeatures.VertexSnapping; + Render2D.DrawSprite(icon, rect, color); // Draw connected hint with color from connected output box @@ -264,6 +268,8 @@ namespace FlaxEditor.Surface Color selectionColor = FlaxEngine.GUI.Style.Current.BorderSelected.RGBMultiplied(1.0f + outlineAlpha * 0.4f); Render2D.DrawSprite(icon, outlineRect, selectionColor.AlphaMultiplied(0.4f)); } + + Render2D.Features = features; } /// From 2fbeac60774bf87ae97b87f2eff22d37f2b64bfc Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 14 Mar 2026 16:29:43 +0100 Subject: [PATCH 17/35] disable decorator node shadows --- Source/Editor/Surface/Archetypes/BehaviorTree.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Editor/Surface/Archetypes/BehaviorTree.cs b/Source/Editor/Surface/Archetypes/BehaviorTree.cs index 69a6e8f7e..7eb9df286 100644 --- a/Source/Editor/Surface/Archetypes/BehaviorTree.cs +++ b/Source/Editor/Surface/Archetypes/BehaviorTree.cs @@ -701,6 +701,8 @@ namespace FlaxEditor.Surface.Archetypes private DragDecorator _dragDecorator; private float _dragLocation = -1; + internal override bool DrawBasicShadow => false; + internal Decorator(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch) : base(id, context, nodeArch, groupArch) { From 60076d48c761e4b661015d1c2067177acd8caaff Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 14 Mar 2026 16:38:56 +0100 Subject: [PATCH 18/35] fix box alignment for nodes with fixed size and adjust some node sizes --- Source/Editor/Surface/Archetypes/Constants.cs | 18 ++++++++++++------ Source/Editor/Surface/Archetypes/Textures.cs | 3 ++- Source/Editor/Surface/NodeArchetype.cs | 3 +++ Source/Editor/Surface/SurfaceNode.cs | 10 ++++++++++ 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Constants.cs b/Source/Editor/Surface/Archetypes/Constants.cs index 680cc512d..562cd98e0 100644 --- a/Source/Editor/Surface/Archetypes/Constants.cs +++ b/Source/Editor/Surface/Archetypes/Constants.cs @@ -482,7 +482,8 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(bool))), Description = "Constant boolean value", Flags = NodeFlags.AllGraphs, - Size = new Float2(110, 20), + UseFixedSize = true, + Size = new Float2(90, 20), DefaultValues = new object[] { false @@ -515,7 +516,8 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(int))), Description = "Constant integer value", Flags = NodeFlags.AllGraphs, - Size = new Float2(110, 20), + UseFixedSize = true, + Size = new Float2(120, 20), DefaultValues = new object[] { 0 @@ -543,7 +545,8 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(float))), Description = "Constant floating point", Flags = NodeFlags.AllGraphs, - Size = new Float2(110, 20), + UseFixedSize = true, + Size = new Float2(120, 20), DefaultValues = new object[] { 0.0f @@ -750,7 +753,8 @@ namespace FlaxEditor.Surface.Archetypes Title = "PI", Description = "A value specifying the approximation of π which is 180 degrees", Flags = NodeFlags.AllGraphs, - Size = new Float2(50, 20), + UseFixedSize = true, + Size = new Float2(45, 20), Elements = new[] { NodeElementArchetype.Factory.Output(0, "π", typeof(float), 0), @@ -782,7 +786,8 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(uint))), Description = "Constant unsigned integer value", Flags = NodeFlags.AllGraphs, - Size = new Float2(170, 20), + UseFixedSize = true, + Size = new Float2(130, 20), DefaultValues = new object[] { 0u @@ -824,7 +829,8 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(double))), Description = "Constant floating point", Flags = NodeFlags.AllGraphs, - Size = new Float2(110, 20), + UseFixedSize = true, + Size = new Float2(120, 20), DefaultValues = new object[] { 0.0d diff --git a/Source/Editor/Surface/Archetypes/Textures.cs b/Source/Editor/Surface/Archetypes/Textures.cs index fe7f3ec39..c7d0d3b5b 100644 --- a/Source/Editor/Surface/Archetypes/Textures.cs +++ b/Source/Editor/Surface/Archetypes/Textures.cs @@ -159,7 +159,8 @@ namespace FlaxEditor.Surface.Archetypes AlternativeTitles = new string[] { "UV", "UVs" }, Description = "Texture coordinates", Flags = NodeFlags.MaterialGraph, - Size = new Float2(150, 30), + UseFixedSize = true, + Size = new Float2(160, 20), DefaultValues = new object[] { 0u diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs index 18e6ac8c9..006bd2fb6 100644 --- a/Source/Editor/Surface/NodeArchetype.cs +++ b/Source/Editor/Surface/NodeArchetype.cs @@ -129,6 +129,9 @@ namespace FlaxEditor.Surface /// public NodeFlags Flags; + /// + /// If the node should use the as node size. If false, the node will auto resize based on its elements. + /// public bool UseFixedSize = false; /// diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 0ee35e23e..9a1fd2ef4 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -343,6 +343,8 @@ namespace FlaxEditor.Surface if (!Archetype.UseFixedSize) ResizeAuto(); + else + Resize(Archetype.Size.X, Archetype.Size.Y); } /// @@ -940,6 +942,8 @@ namespace FlaxEditor.Surface if (!Archetype.UseFixedSize) ResizeAuto(); + else + Resize(Archetype.Size.X, Archetype.Size.Y); } /// @@ -980,6 +984,8 @@ namespace FlaxEditor.Surface if (!Archetype.UseFixedSize) ResizeAuto(); + else + Resize(Archetype.Size.X, Archetype.Size.Y); } /// @@ -1017,6 +1023,8 @@ namespace FlaxEditor.Surface if (!Archetype.UseFixedSize) ResizeAuto(); + else + Resize(Archetype.Size.X, Archetype.Size.Y); } internal void SetIsDuringValuesEditing(bool value) @@ -1051,6 +1059,8 @@ namespace FlaxEditor.Surface UpdateBoxesTypes(); if (!Archetype.UseFixedSize) ResizeAuto(); + else + Resize(Archetype.Size.X, Archetype.Size.Y); } /// From 44ecac7ffc34d0102f142eccc3ad49c074d64fad Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 14 Mar 2026 16:52:56 +0100 Subject: [PATCH 19/35] make debug text more legible --- Source/Editor/Surface/Archetypes/BehaviorTree.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Surface/Archetypes/BehaviorTree.cs b/Source/Editor/Surface/Archetypes/BehaviorTree.cs index 7eb9df286..30b05ed78 100644 --- a/Source/Editor/Surface/Archetypes/BehaviorTree.cs +++ b/Source/Editor/Surface/Archetypes/BehaviorTree.cs @@ -249,7 +249,11 @@ namespace FlaxEditor.Surface.Archetypes // Debug Info if (!string.IsNullOrEmpty(_debugInfo)) - Render2D.DrawText(style.FontSmall, _debugInfo, new Rectangle(4, _headerRect.Bottom + 4, _debugInfoSize), style.Foreground); + { + // Draw an extra background to cover the archetype color colored node background and make text more legible + Render2D.FillRectangle(new Rectangle(0, _headerRect.Bottom + 4, Width, Height - _headerRect.Bottom - 4), style.BackgroundHighlighted); + Render2D.DrawText(style.FontSmall, _debugInfo, new Rectangle(4, _headerRect.Bottom + 7, _debugInfoSize), style.Foreground, scale: 0.8f); + } // Debug relevancy outline if (_debugRelevant) From f2a13b64d489830b5c426e0d12a899dc54920b5c Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 14 Mar 2026 19:00:12 +0100 Subject: [PATCH 20/35] fix reroute node output box moving on connection change --- Source/Editor/Surface/Archetypes/Tools.cs | 6 ++++++ Source/Editor/Surface/SurfaceNode.cs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Surface/Archetypes/Tools.cs b/Source/Editor/Surface/Archetypes/Tools.cs index cc6820020..bd5818693 100644 --- a/Source/Editor/Surface/Archetypes/Tools.cs +++ b/Source/Editor/Surface/Archetypes/Tools.cs @@ -1179,6 +1179,12 @@ namespace FlaxEditor.Surface.Archetypes _footerRect = Rectangle.Empty; } + /// + public override void Resize(float width, float height) + { + // Do nothing so the input and output boxes do not change position + } + /// public override void Draw() { diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 9a1fd2ef4..9fb6dfbbd 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -181,7 +181,7 @@ namespace FlaxEditor.Surface /// /// The width. /// The height. - public void Resize(float width, float height) + public virtual void Resize(float width, float height) { if (Surface == null) return; From 5ec018b904989bcfae6d2ec8cc51a4b38f9798ab Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 14 Mar 2026 19:05:35 +0100 Subject: [PATCH 21/35] fix particle module changing size after certain user actions --- Source/Editor/Surface/Archetypes/ParticleModules.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/Editor/Surface/Archetypes/ParticleModules.cs b/Source/Editor/Surface/Archetypes/ParticleModules.cs index debc88d59..f65c54646 100644 --- a/Source/Editor/Surface/Archetypes/ParticleModules.cs +++ b/Source/Editor/Surface/Archetypes/ParticleModules.cs @@ -138,6 +138,12 @@ namespace FlaxEditor.Surface.Archetypes } } + /// + public override void Resize(float width, float height) + { + // Do nothing so module does not change size + } + private bool ArrangeAreaCheck(out int index, out Rectangle rect) { var barSidesExtend = 20.0f; From 0237235dcbdd42347f240e96ed23e9852ed886bb Mon Sep 17 00:00:00 2001 From: Saas Date: Sun, 15 Mar 2026 14:29:31 +0100 Subject: [PATCH 22/35] draw close button using Render2D to make it look good even when zoomed in a lot --- .../Editor/Surface/Archetypes/BehaviorTree.cs | 11 ++++++---- .../Surface/Archetypes/ParticleModules.cs | 6 ++--- Source/Editor/Surface/Constants.cs | 4 ++-- Source/Editor/Surface/SurfaceComment.cs | 4 ++-- Source/Editor/Surface/SurfaceNode.cs | 22 +++++++++++++++++-- Source/Editor/Surface/SurfaceStyle.cs | 3 ++- 6 files changed, 36 insertions(+), 14 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/BehaviorTree.cs b/Source/Editor/Surface/Archetypes/BehaviorTree.cs index 30b05ed78..c112bcf27 100644 --- a/Source/Editor/Surface/Archetypes/BehaviorTree.cs +++ b/Source/Editor/Surface/Archetypes/BehaviorTree.cs @@ -223,7 +223,7 @@ namespace FlaxEditor.Surface.Archetypes if ((Archetype.Flags & NodeFlags.NoCloseButton) == 0 && Surface.CanEdit) { bool highlightClose = _closeButtonRect.Contains(_mousePosition) && !Surface.IsConnecting && !Surface.IsSelecting; - Render2D.DrawSprite(style.Cross, _closeButtonRect, highlightClose ? style.Foreground : style.ForegroundGrey); + DrawCloseButton(_closeButtonRect, highlightClose ? style.Foreground : style.ForegroundGrey); } DrawChildren(); @@ -596,7 +596,7 @@ namespace FlaxEditor.Surface.Archetypes const float headerHeight = FlaxEditor.Surface.Constants.NodeHeaderHeight; const float closeButtonMargin = FlaxEditor.Surface.Constants.NodeCloseButtonMargin; - float closeButtonSize = FlaxEditor.Surface.Constants.NodeCloseButtonSize * 0.65f; + float closeButtonSize = FlaxEditor.Surface.Constants.NodeCloseButtonSize * 0.75f; _headerRect = new Rectangle(0, bounds.Y - Y, bounds.Width, headerHeight); _headerTextRect = _headerRect with { X = 5f, Width = Width - closeButtonSize - closeButtonMargin * 4f }; _closeButtonRect = new Rectangle(bounds.Width - closeButtonSize - closeButtonMargin, _headerRect.Y + closeButtonMargin, closeButtonSize, closeButtonSize); @@ -744,10 +744,13 @@ namespace FlaxEditor.Surface.Archetypes _footerRect = Rectangle.Empty; const float closeButtonMargin = FlaxEditor.Surface.Constants.NodeCloseButtonMargin; - float closeButtonSize = FlaxEditor.Surface.Constants.NodeCloseButtonSize * 0.65f; + float closeButtonSize = FlaxEditor.Surface.Constants.NodeCloseButtonSize * 0.75f; _closeButtonRect = new Rectangle(Bounds.Width - closeButtonSize - closeButtonMargin, _headerRect.Y + closeButtonMargin, closeButtonSize, closeButtonSize); if (_dragIcon != null) - _dragIcon.Bounds = new Rectangle(_closeButtonRect.X - _closeButtonRect.Width, _closeButtonRect.Y, _closeButtonRect.Size); + { + var dragIconRect = _closeButtonRect.MakeExpanded(5f); + _dragIcon.Bounds = new Rectangle(dragIconRect.X - dragIconRect.Width, dragIconRect.Y, dragIconRect.Size); + } } protected override void UpdateTitle() diff --git a/Source/Editor/Surface/Archetypes/ParticleModules.cs b/Source/Editor/Surface/Archetypes/ParticleModules.cs index f65c54646..e85c87898 100644 --- a/Source/Editor/Surface/Archetypes/ParticleModules.cs +++ b/Source/Editor/Surface/Archetypes/ParticleModules.cs @@ -121,7 +121,7 @@ namespace FlaxEditor.Surface.Archetypes Render2D.DrawRectangle(new Rectangle(1, 0, Width - 2, Height - 1), Colors[idx]); // Close button - Render2D.DrawSprite(style.Cross, _closeButtonRect, _closeButtonRect.Contains(_mousePosition) ? style.Foreground : style.ForegroundGrey); + DrawCloseButton(_closeButtonRect, _closeButtonRect.Contains(_mousePosition) ? style.Foreground : style.ForegroundGrey); // Arrange button var dragBarColor = _arrangeButtonRect.Contains(_mousePosition) ? style.Foreground : style.ForegroundGrey; @@ -267,9 +267,9 @@ namespace FlaxEditor.Surface.Archetypes const float closeButtonMargin = FlaxEditor.Surface.Constants.NodeCloseButtonMargin; const float closeButtonSize = FlaxEditor.Surface.Constants.NodeCloseButtonSize; _headerRect = new Rectangle(0, 0, Width, headerSize); - _closeButtonRect = new Rectangle(Width - closeButtonSize - closeButtonMargin, closeButtonMargin, closeButtonSize, closeButtonSize); + _closeButtonRect = new Rectangle(Width - closeButtonSize * 0.75f - closeButtonMargin, closeButtonMargin + 0.25f, closeButtonSize * 0.75f, closeButtonSize * 0.75f); _footerRect = Rectangle.Empty; - _enabled.Location = new Float2(_closeButtonRect.X - _enabled.Width - 2, _closeButtonRect.Y); + _enabled.Location = new Float2(_closeButtonRect.X - _enabled.Width - 2, _closeButtonRect.Y - 0.25f); _arrangeButtonRect = new Rectangle(_enabled.X - closeButtonSize - closeButtonMargin, closeButtonMargin, closeButtonSize, closeButtonSize); } diff --git a/Source/Editor/Surface/Constants.cs b/Source/Editor/Surface/Constants.cs index 9b857805e..474d3979b 100644 --- a/Source/Editor/Surface/Constants.cs +++ b/Source/Editor/Surface/Constants.cs @@ -13,12 +13,12 @@ namespace FlaxEditor.Surface /// /// The node close button size. /// - public const float NodeCloseButtonSize = 16.0f; + public const float NodeCloseButtonSize = 10.0f; /// /// The node close button margin from the edges. /// - public const float NodeCloseButtonMargin = 2.0f; + public const float NodeCloseButtonMargin = 5.0f; /// /// The node header height. diff --git a/Source/Editor/Surface/SurfaceComment.cs b/Source/Editor/Surface/SurfaceComment.cs index fb0dd8371..79a285bd8 100644 --- a/Source/Editor/Surface/SurfaceComment.cs +++ b/Source/Editor/Surface/SurfaceComment.cs @@ -128,7 +128,7 @@ namespace FlaxEditor.Surface const float buttonMargin = Constants.NodeCloseButtonMargin; const float buttonSize = Constants.NodeCloseButtonSize; _headerRect = new Rectangle(0, 0, Width, headerSize); - _closeButtonRect = new Rectangle(Width - buttonSize - buttonMargin, buttonMargin, buttonSize, buttonSize); + _closeButtonRect = new Rectangle(Width - buttonSize * 0.75f - buttonMargin, buttonMargin, buttonSize * 0.75f, buttonSize * 0.75f); _colorButtonRect = new Rectangle(_closeButtonRect.Left - buttonSize - buttonMargin, buttonMargin, buttonSize, buttonSize); _resizeButtonRect = new Rectangle(_closeButtonRect.Left, Height - buttonSize - buttonMargin, buttonSize, buttonSize); _renameTextBox.Width = Width; @@ -183,7 +183,7 @@ namespace FlaxEditor.Surface if (Surface.CanEdit) { // Close button - Render2D.DrawSprite(style.Cross, _closeButtonRect, _closeButtonRect.Contains(_mousePosition) && Surface.CanEdit ? style.Foreground : style.ForegroundGrey); + DrawCloseButton(_closeButtonRect, _closeButtonRect.Contains(_mousePosition) && Surface.CanEdit ? style.Foreground : style.ForegroundGrey); // Color button Render2D.DrawSprite(style.Settings, _colorButtonRect, _colorButtonRect.Contains(_mousePosition) && Surface.CanEdit ? style.Foreground : style.ForegroundGrey); diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 9fb6dfbbd..2b053b315 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -454,7 +454,7 @@ namespace FlaxEditor.Surface private static readonly List UpdateStack = new List(); /// - /// Updates dependant/independent boxes types. + /// Updates dependent/independent boxes types. /// public void UpdateBoxesTypes() { @@ -796,6 +796,24 @@ namespace FlaxEditor.Surface return output; } + /// + /// Draws the close button inside of the . + /// + /// The rectangle to draw the close button in. + /// The color of the close button. + public void DrawCloseButton(Rectangle rect, Color color) + { + // Disable vertex snapping to reduce artefacts at the line ends + var features = Render2D.Features; + Render2D.Features = features & ~Render2D.RenderingFeatures.VertexSnapping; + + rect.Expand(-2f); // Don't overshoot the rectangle because of the thickness + Render2D.DrawLine(rect.TopLeft, rect.BottomRight, color, 2f); + Render2D.DrawLine(rect.BottomLeft, rect.TopRight, color, 2f); + + Render2D.Features = features; + } + /// /// Draws all the connections between surface objects related to this node. /// @@ -1113,7 +1131,7 @@ namespace FlaxEditor.Surface if ((Archetype.Flags & NodeFlags.NoCloseButton) == 0 && Surface.CanEdit) { bool highlightClose = _closeButtonRect.Contains(_mousePosition) && !Surface.IsConnecting && !Surface.IsSelecting; - Render2D.DrawSprite(style.Cross, _closeButtonRect, highlightClose ? style.Foreground : style.ForegroundGrey); + DrawCloseButton(_closeButtonRect, highlightClose ? style.Foreground : style.ForegroundGrey); } // Footer diff --git a/Source/Editor/Surface/SurfaceStyle.cs b/Source/Editor/Surface/SurfaceStyle.cs index 0bfdd641e..4fc656823 100644 --- a/Source/Editor/Surface/SurfaceStyle.cs +++ b/Source/Editor/Surface/SurfaceStyle.cs @@ -245,6 +245,7 @@ namespace FlaxEditor.Surface icon = hasConnections ? style.Icons.BoxClose : style.Icons.BoxOpen; color *= box.ConnectionsHighlightIntensity + 1; + // Disable vertex snapping to prevent position jitter/ snapping artefacts for the boxes when zooming the surface var features = Render2D.Features; Render2D.Features = features & ~Render2D.RenderingFeatures.VertexSnapping; @@ -273,7 +274,7 @@ namespace FlaxEditor.Surface } /// - /// Function used to create style for the given surface type. Can be overriden to provide some customization via user plugin. + /// Function used to create style for the given surface type. Can be overridden to provide some customization via user plugin. /// public static Func CreateStyleHandler = CreateDefault; From 5655cc8f422c58de7234e4aa715d294f606475e5 Mon Sep 17 00:00:00 2001 From: Saas Date: Sun, 15 Mar 2026 16:59:09 +0100 Subject: [PATCH 23/35] account for surface node elements when auto resizing --- Source/Editor/Surface/Archetypes/Constants.cs | 6 ------ Source/Editor/Surface/Archetypes/Textures.cs | 2 -- Source/Editor/Surface/NodeElementArchetype.cs | 9 ++++++++- Source/Editor/Surface/SurfaceNode.cs | 11 +++++++++++ 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Constants.cs b/Source/Editor/Surface/Archetypes/Constants.cs index 562cd98e0..a11213f93 100644 --- a/Source/Editor/Surface/Archetypes/Constants.cs +++ b/Source/Editor/Surface/Archetypes/Constants.cs @@ -482,7 +482,6 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(bool))), Description = "Constant boolean value", Flags = NodeFlags.AllGraphs, - UseFixedSize = true, Size = new Float2(90, 20), DefaultValues = new object[] { @@ -516,7 +515,6 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(int))), Description = "Constant integer value", Flags = NodeFlags.AllGraphs, - UseFixedSize = true, Size = new Float2(120, 20), DefaultValues = new object[] { @@ -545,7 +543,6 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(float))), Description = "Constant floating point", Flags = NodeFlags.AllGraphs, - UseFixedSize = true, Size = new Float2(120, 20), DefaultValues = new object[] { @@ -753,7 +750,6 @@ namespace FlaxEditor.Surface.Archetypes Title = "PI", Description = "A value specifying the approximation of π which is 180 degrees", Flags = NodeFlags.AllGraphs, - UseFixedSize = true, Size = new Float2(45, 20), Elements = new[] { @@ -786,7 +782,6 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(uint))), Description = "Constant unsigned integer value", Flags = NodeFlags.AllGraphs, - UseFixedSize = true, Size = new Float2(130, 20), DefaultValues = new object[] { @@ -829,7 +824,6 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(double))), Description = "Constant floating point", Flags = NodeFlags.AllGraphs, - UseFixedSize = true, Size = new Float2(120, 20), DefaultValues = new object[] { diff --git a/Source/Editor/Surface/Archetypes/Textures.cs b/Source/Editor/Surface/Archetypes/Textures.cs index c7d0d3b5b..2cc56c8a4 100644 --- a/Source/Editor/Surface/Archetypes/Textures.cs +++ b/Source/Editor/Surface/Archetypes/Textures.cs @@ -134,7 +134,6 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new Constants.ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Texture))), Description = "Two dimensional texture object", Flags = NodeFlags.MaterialGraph, - UseFixedSize = true, Size = new Float2(140, 140), DefaultValues = new object[] { @@ -159,7 +158,6 @@ namespace FlaxEditor.Surface.Archetypes AlternativeTitles = new string[] { "UV", "UVs" }, Description = "Texture coordinates", Flags = NodeFlags.MaterialGraph, - UseFixedSize = true, Size = new Float2(160, 20), DefaultValues = new object[] { diff --git a/Source/Editor/Surface/NodeElementArchetype.cs b/Source/Editor/Surface/NodeElementArchetype.cs index 55c8a43a7..0e3c504ff 100644 --- a/Source/Editor/Surface/NodeElementArchetype.cs +++ b/Source/Editor/Surface/NodeElementArchetype.cs @@ -3,8 +3,9 @@ using System; using System.Collections.Generic; using System.Reflection; -using FlaxEditor.CustomEditors; +using FlaxEditor.GUI.Input; using FlaxEditor.Scripting; +using FlaxEditor.Surface.Elements; using FlaxEngine; namespace FlaxEditor.Surface @@ -205,6 +206,7 @@ namespace FlaxEditor.Surface { Type = NodeElementType.BoolValue, Position = new Float2(x, y), + Size = new Float2(16f), Text = null, Single = false, ValueIndex = valueIndex, @@ -229,6 +231,7 @@ namespace FlaxEditor.Surface { Type = NodeElementType.IntegerValue, Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y), + Size = new Float2(50f, IntegerValue.DefaultHeight), Text = null, Single = false, ValueIndex = valueIndex, @@ -255,6 +258,7 @@ namespace FlaxEditor.Surface { Type = NodeElementType.UnsignedIntegerValue, Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y), + Size = new Float2(50f, UnsignedIntegerValue.DefaultHeight), Text = null, Single = false, ValueIndex = valueIndex, @@ -281,6 +285,7 @@ namespace FlaxEditor.Surface { Type = NodeElementType.FloatValue, Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y), + Size = new Float2(50f, FloatValueBox.DefaultHeight), Text = null, Single = false, ValueIndex = valueIndex, @@ -360,6 +365,7 @@ namespace FlaxEditor.Surface { Type = NodeElementType.ColorValue, Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y), + Size = new Float2(32, 18), Text = null, Single = false, ValueIndex = valueIndex, @@ -382,6 +388,7 @@ namespace FlaxEditor.Surface { Type = NodeElementType.Asset, Position = new Float2(x, y), + Size = new Float2(78f, 90f), Text = type.FullName, Single = false, ValueIndex = valueIndex, diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 2b053b315..af62c8318 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -242,6 +242,17 @@ namespace FlaxEditor.Surface rightWidth = Mathf.Max(rightWidth, boxLabelFont.MeasureText(outputBox.Text).X + 20); rightHeight = Mathf.Max(rightHeight, outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderHeight + 20.0f); } + // Elements (Float-, int-, uint- value boxes, asset pickers, etc.) + else if (child is ISurfaceNodeElement surfaceElement) + { + leftWidth = Mathf.Max(leftWidth, surfaceElement.Archetype.Size.X + 8f); + leftHeight = Mathf.Max(leftHeight, surfaceElement.Archetype.Size.Y + 8f); + } + else if (child is SurfaceNodeElementControl elementControl) + { + leftWidth = Mathf.Max(leftWidth, elementControl.Width + 8f); + leftHeight = Mathf.Max(leftHeight, elementControl.Height + 8f); + } // Other controls in the node else if (child is Control control) { From 5b2b1930d26019fcb6f7d35cb24bbd5adf4f9bc0 Mon Sep 17 00:00:00 2001 From: Saas Date: Sun, 15 Mar 2026 17:03:01 +0100 Subject: [PATCH 24/35] fix Particle Emitter node to not auto resize --- Source/Editor/Surface/Archetypes/Particles.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Editor/Surface/Archetypes/Particles.cs b/Source/Editor/Surface/Archetypes/Particles.cs index 5346972e9..d5848a8e4 100644 --- a/Source/Editor/Surface/Archetypes/Particles.cs +++ b/Source/Editor/Surface/Archetypes/Particles.cs @@ -341,6 +341,7 @@ namespace FlaxEditor.Surface.Archetypes Title = "Particle Emitter", Description = "Main particle emitter node. Contains a set of modules per emitter context. Modules are executed in order from top to bottom of the stack.", Flags = NodeFlags.ParticleEmitterGraph | NodeFlags.NoRemove | NodeFlags.NoSpawnViaGUI | NodeFlags.NoSpawnViaPaste | NodeFlags.NoCloseButton, + UseFixedSize = true, Size = new Float2(300, 600), DefaultValues = new object[] { From d5d10aa3293b8c5138c1af2c3ec4ee89debc40d9 Mon Sep 17 00:00:00 2001 From: Saas Date: Sun, 15 Mar 2026 19:53:09 +0100 Subject: [PATCH 25/35] fix handling controls during resizing --- Source/Editor/Surface/Archetypes/Tools.cs | 1 + Source/Editor/Surface/SurfaceNode.cs | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Tools.cs b/Source/Editor/Surface/Archetypes/Tools.cs index bd5818693..5fa66a3ea 100644 --- a/Source/Editor/Surface/Archetypes/Tools.cs +++ b/Source/Editor/Surface/Archetypes/Tools.cs @@ -1727,6 +1727,7 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new AsNode(id, context, arch, groupArch), Description = "Casts the object to a different type. Returns null if cast fails.", Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph, + //UseFixedSize = true, Size = new Float2(200, 20), DefaultValues = new object[] { diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index af62c8318..a88260629 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -243,6 +243,7 @@ namespace FlaxEditor.Surface rightHeight = Mathf.Max(rightHeight, outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderHeight + 20.0f); } // Elements (Float-, int-, uint- value boxes, asset pickers, etc.) + // These will only ever be on the left side of the node, so we only adjust left width and height else if (child is ISurfaceNodeElement surfaceElement) { leftWidth = Mathf.Max(leftWidth, surfaceElement.Archetype.Size.X + 8f); @@ -258,12 +259,12 @@ namespace FlaxEditor.Surface { if (control.AnchorPreset == AnchorPresets.TopLeft) { - width = Mathf.Max(width, control.Right + 4 - Constants.NodeMarginX); + width = Mathf.Max(width, control.Right + 15 + Constants.NodeMarginX); height = Mathf.Max(height, control.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderHeight); } else if (!_headerRect.Intersects(control.Bounds)) { - width = Mathf.Max(width, control.Width + 4); + width = Mathf.Max(width, control.Width + 15 + Constants.NodeMarginX); height = Mathf.Max(height, control.Height + 4); } } From a1af870874f5d3f35477e0eebb9c1daec3ddeec4 Mon Sep 17 00:00:00 2001 From: Saas Date: Fri, 20 Mar 2026 19:01:52 +0100 Subject: [PATCH 26/35] fix surface elements resizing the node --- Source/Editor/Surface/SurfaceNode.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index a88260629..b37d85d3c 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -244,11 +244,6 @@ namespace FlaxEditor.Surface } // Elements (Float-, int-, uint- value boxes, asset pickers, etc.) // These will only ever be on the left side of the node, so we only adjust left width and height - else if (child is ISurfaceNodeElement surfaceElement) - { - leftWidth = Mathf.Max(leftWidth, surfaceElement.Archetype.Size.X + 8f); - leftHeight = Mathf.Max(leftHeight, surfaceElement.Archetype.Size.Y + 8f); - } else if (child is SurfaceNodeElementControl elementControl) { leftWidth = Mathf.Max(leftWidth, elementControl.Width + 8f); From 4594a8475345cc1c63c1289dabfa8435c125efbf Mon Sep 17 00:00:00 2001 From: Saas Date: Fri, 20 Mar 2026 19:07:11 +0100 Subject: [PATCH 27/35] disable vertex snapping for Blend Points of Animation Blend 1D and 2D --- Source/Editor/Surface/Archetypes/Animation.MultiBlend.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/Editor/Surface/Archetypes/Animation.MultiBlend.cs b/Source/Editor/Surface/Archetypes/Animation.MultiBlend.cs index 450960af7..1d842a7c3 100644 --- a/Source/Editor/Surface/Archetypes/Animation.MultiBlend.cs +++ b/Source/Editor/Surface/Archetypes/Animation.MultiBlend.cs @@ -102,8 +102,14 @@ namespace FlaxEditor.Surface.Archetypes outline = style.BorderHighlighted; else if (_editor._node.SelectedAnimationIndex == _index) outline = style.BackgroundSelected; + + var features = Render2D.Features; + Render2D.Features = features & ~Render2D.RenderingFeatures.VertexSnapping; + Render2D.DrawSprite(icon, rect.MakeExpanded(4.0f), outline); Render2D.DrawSprite(icon, rect, style.Foreground); + + Render2D.Features = features; } /// From 1bd86ca28b4b002c6b14ca6de382621f86b72d58 Mon Sep 17 00:00:00 2001 From: Saas Date: Fri, 20 Mar 2026 20:17:10 +0100 Subject: [PATCH 28/35] temporary fix for "Copy Node" node size --- Source/Editor/Surface/Archetypes/Animation.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Editor/Surface/Archetypes/Animation.cs b/Source/Editor/Surface/Archetypes/Animation.cs index 48a54a56f..a3fc66b82 100644 --- a/Source/Editor/Surface/Archetypes/Animation.cs +++ b/Source/Editor/Surface/Archetypes/Animation.cs @@ -932,6 +932,7 @@ namespace FlaxEditor.Surface.Archetypes Title = "Copy Node", Description = "Copies the skeleton node transformation data (in local space)", Flags = NodeFlags.AnimGraph, + UseFixedSize = true, Size = new Float2(260, 140), DefaultValues = new object[] { From c673e9f52db3d767ef46d85370b2c212f5190896 Mon Sep 17 00:00:00 2001 From: Saas Date: Fri, 20 Mar 2026 20:18:12 +0100 Subject: [PATCH 29/35] minor fixes --- Source/Editor/Surface/Archetypes/Tools.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Editor/Surface/Archetypes/Tools.cs b/Source/Editor/Surface/Archetypes/Tools.cs index 5fa66a3ea..bd5818693 100644 --- a/Source/Editor/Surface/Archetypes/Tools.cs +++ b/Source/Editor/Surface/Archetypes/Tools.cs @@ -1727,7 +1727,6 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new AsNode(id, context, arch, groupArch), Description = "Casts the object to a different type. Returns null if cast fails.", Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph, - //UseFixedSize = true, Size = new Float2(200, 20), DefaultValues = new object[] { From a346e258d3c75ae714cadacc4b0e37b63faa8cf5 Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 21 Mar 2026 12:53:10 +0100 Subject: [PATCH 30/35] make "Flow" group archetype color more legible --- Source/Editor/Surface/NodeFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Surface/NodeFactory.cs b/Source/Editor/Surface/NodeFactory.cs index 30e3628fd..f787899dc 100644 --- a/Source/Editor/Surface/NodeFactory.cs +++ b/Source/Editor/Surface/NodeFactory.cs @@ -166,7 +166,7 @@ namespace FlaxEditor.Surface { GroupID = 17, Name = "Flow", - Color = new Color(237, 136, 64), + Color = new Color(181, 91, 33), Archetypes = Archetypes.Flow.Nodes }, new GroupArchetype From f26dbf530c60e2a245ea15c692cb9032aae9689f Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 28 Mar 2026 13:46:38 +0100 Subject: [PATCH 31/35] fix skeleton blend mask node to resize when asset reference is (dis-) connected --- Source/Editor/Surface/Archetypes/Animation.cs | 3 +++ Source/Editor/Surface/SurfaceNode.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Surface/Archetypes/Animation.cs b/Source/Editor/Surface/Archetypes/Animation.cs index a3fc66b82..c8d45cc5f 100644 --- a/Source/Editor/Surface/Archetypes/Animation.cs +++ b/Source/Editor/Surface/Archetypes/Animation.cs @@ -70,6 +70,9 @@ namespace FlaxEditor.Surface.Archetypes if (box.ID != _assetBox.ID) return; _assetSelect.Visible = !box.HasAnyConnection; + + if (!Archetype.UseFixedSize) + ResizeAuto(); } } diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index b37d85d3c..2d440160f 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -1058,7 +1058,7 @@ namespace FlaxEditor.Surface } /// - /// Sets teh node values from the given pasted source. Can be overriden to perform validation or custom values processing. + /// Sets teh node values from the given pasted source. Can be overridden to perform validation or custom values processing. /// /// The input values array. public virtual void SetValuesPaste(object[] values) From 9fa9e75e0801fa9a3242d96fa1021c8cce27ad1b Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 28 Mar 2026 21:28:09 +0100 Subject: [PATCH 32/35] fix decorator size when surface is loaded --- Source/Editor/Surface/Archetypes/BehaviorTree.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/Editor/Surface/Archetypes/BehaviorTree.cs b/Source/Editor/Surface/Archetypes/BehaviorTree.cs index c112bcf27..d99fedaee 100644 --- a/Source/Editor/Surface/Archetypes/BehaviorTree.cs +++ b/Source/Editor/Surface/Archetypes/BehaviorTree.cs @@ -829,6 +829,11 @@ namespace FlaxEditor.Surface.Archetypes node.ResizeAuto(); } } + else + { + // Correctly size decorators when surface is loaded + Node.ResizeAuto(); + } } /// From b78ff57f6ab4ac10382adf6f35c78c0a14d650b2 Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 28 Mar 2026 22:04:41 +0100 Subject: [PATCH 33/35] fix custom code nodes --- Source/Editor/Surface/Archetypes/Material.cs | 17 +++++++++-------- Source/Editor/Surface/Archetypes/Tools.cs | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Material.cs b/Source/Editor/Surface/Archetypes/Material.cs index a5c7b1da7..719553651 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -312,16 +312,16 @@ namespace FlaxEditor.Surface.Archetypes : base(id, context, nodeArch, groupArch) { _sizeValueIndex = Archetype.TypeID == 8 ? 1 : 3; // Index of the Size stored in Values array - Float2 pos = new Float2(FlaxEditor.Surface.Constants.NodeMarginX + 25f, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight), size; + Float2 pos = new Float2(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight), size; if (nodeArch.TypeID == 8) { - pos += new Float2(60, 0); - size = new Float2(125, 200); + pos += new Float2(65, 0); + size = new Float2(160, 185); } else { - pos += new Float2(0, 40); - size = new Float2(300, 200); + pos += new Float2(0, 40 + FlaxEditor.Utilities.Constants.UIMargin * 2f); + size = new Float2(300, 180); } _textBox = new CustomCodeTextBox { @@ -506,8 +506,8 @@ namespace FlaxEditor.Surface.Archetypes Size = new Float2(300, 200), DefaultValues = new object[] { - "// Here you can add HLSL code\nOutput0 = Input0;", - new Float2(300, 200), + "// You can add HLSL code here\nOutput0 = Input0;", + new Float2(350, 200), }, Elements = new[] { @@ -969,10 +969,11 @@ namespace FlaxEditor.Surface.Archetypes Title = "Custom Global Code", Description = "Custom global HLSL shader code expression (placed before material shader code). Can contain includes to shader utilities or declare functions to reuse later.", Flags = NodeFlags.MaterialGraph, + UseFixedSize = true, Size = new Float2(300, 240), DefaultValues = new object[] { - "// Here you can add HLSL code\nfloat4 GetCustomColor()\n{\n\treturn float4(1, 0, 0, 1);\n}", + "// You can add HLSL code here\nfloat4 GetCustomColor()\n{\n\treturn float4(1, 0, 0, 1);\n}", true, (int)MaterialTemplateInputsMapping.Utilities, new Float2(300, 240), diff --git a/Source/Editor/Surface/Archetypes/Tools.cs b/Source/Editor/Surface/Archetypes/Tools.cs index bd5818693..757c9f5c9 100644 --- a/Source/Editor/Surface/Archetypes/Tools.cs +++ b/Source/Editor/Surface/Archetypes/Tools.cs @@ -486,7 +486,7 @@ namespace FlaxEditor.Surface.Archetypes zero, // Tangent In zero, // Tangent Out - // Empty keys zero-6 + // Empty keys 0-6 0.0f, zero, zero, zero, 0.0f, zero, zero, zero, 0.0f, zero, zero, zero, From ec756fe6266b805aa9dcbfd984de5f8a55f3f7a8 Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 28 Mar 2026 22:16:31 +0100 Subject: [PATCH 34/35] fix custom code node size --- Source/Editor/Surface/Archetypes/Material.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Surface/Archetypes/Material.cs b/Source/Editor/Surface/Archetypes/Material.cs index 719553651..d9890f031 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -317,6 +317,7 @@ namespace FlaxEditor.Surface.Archetypes { pos += new Float2(65, 0); size = new Float2(160, 185); + _sizeMin = new Float2(240, 185); } else { @@ -969,7 +970,6 @@ namespace FlaxEditor.Surface.Archetypes Title = "Custom Global Code", Description = "Custom global HLSL shader code expression (placed before material shader code). Can contain includes to shader utilities or declare functions to reuse later.", Flags = NodeFlags.MaterialGraph, - UseFixedSize = true, Size = new Float2(300, 240), DefaultValues = new object[] { From bda0dee371248803657ebc815b114988a46f6520 Mon Sep 17 00:00:00 2001 From: Saas Date: Sat, 28 Mar 2026 22:32:55 +0100 Subject: [PATCH 35/35] fix curve node --- Source/Editor/Surface/Archetypes/Tools.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Tools.cs b/Source/Editor/Surface/Archetypes/Tools.cs index 757c9f5c9..ee335d01d 100644 --- a/Source/Editor/Surface/Archetypes/Tools.cs +++ b/Source/Editor/Surface/Archetypes/Tools.cs @@ -467,7 +467,6 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new CurveNode(id, context, arch, groupArch), Description = "An animation spline represented by a set of keyframes, each representing an endpoint of a Bezier curve.", Flags = NodeFlags.AllGraphs, - UseFixedSize = true, Size = new Float2(400, 180.0f), DefaultValues = new object[] { @@ -516,13 +515,12 @@ namespace FlaxEditor.Surface.Archetypes base.OnLoaded(action); // Create curve editor - var upperLeft = GetBox(0).BottomLeft; - var upperRight = GetBox(1).BottomRight; - float curveMargin = 20.0f; + var upperLeft = GetBox(0).BottomRight; + var upperRight = GetBox(1).BottomLeft; _curve = new BezierCurveEditor { MaxKeyframes = 7, - Bounds = new Rectangle(upperLeft + new Float2(curveMargin, 10.0f), upperRight.X - upperLeft.X - curveMargin * 2.0f, 140.0f), + Bounds = new Rectangle(upperLeft + new Float2(0f, 10.0f), upperRight.X - upperLeft.X - 8.0f, 135.0f), Parent = this, AnchorMax = Float2.One, };