From bd6ce4ae2588b9725b2c6a6e7ee0b8bda2c95ba8 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Sun, 17 Sep 2023 02:03:01 -0400 Subject: [PATCH 01/24] Very basic grip snap working. Need to add configuration. --- Source/Editor/Surface/VisjectSurface.Input.cs | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Surface/VisjectSurface.Input.cs b/Source/Editor/Surface/VisjectSurface.Input.cs index 7264321c3..27c8e2a02 100644 --- a/Source/Editor/Surface/VisjectSurface.Input.cs +++ b/Source/Editor/Surface/VisjectSurface.Input.cs @@ -1,5 +1,6 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. +using System; using System.Collections.Generic; using System.Linq; using FlaxEditor.Options; @@ -223,16 +224,46 @@ namespace FlaxEditor.Surface // Moving else if (_isMovingSelection) { + bool testOption = true; + float testGridSize = 15f; // Calculate delta (apply view offset) var viewDelta = _rootControl.Location - _movingSelectionViewPos; _movingSelectionViewPos = _rootControl.Location; var delta = location - _leftMouseDownPos - viewDelta; - if (delta.LengthSquared > 0.01f) + var deltaLengthSquared = delta.LengthSquared; + + delta /= _targetScale; + if ((!testOption || Math.Abs(delta.X) >= testGridSize || (Math.Abs(delta.Y) >= testGridSize)) + && deltaLengthSquared > 0.01f) { // Move selected nodes - delta /= _targetScale; + Debug.Log("test " + delta.ToString() + ", " + testGridSize.ToString() + ", " + _targetScale.ToString()); + + + if (testOption) + { + // Round delta to ensure grid snapping. + + Float2 unroundedDelta = delta; + unroundedDelta.X = (float) Math.CopySign(Math.Floor(Math.Abs((double)unroundedDelta.X) / testGridSize) * testGridSize, unroundedDelta.X); + unroundedDelta.Y = (float)Math.CopySign(Math.Floor(Math.Abs((double)unroundedDelta.Y) / testGridSize) * testGridSize, unroundedDelta.Y); + delta = unroundedDelta; + } + foreach (var node in _movingNodes) + { + if (testOption) + { + // Ensure location is snapped if grid snap is on. + + Float2 unroundedLocation = node.Location; + unroundedLocation.X = (float)Math.CopySign(Math.Round(Math.Abs((double)unroundedLocation.X) / testGridSize) * testGridSize, unroundedLocation.X); + unroundedLocation.Y = (float)Math.CopySign(Math.Round(Math.Abs((double)unroundedLocation.Y) / testGridSize) * testGridSize, unroundedLocation.Y); + node.Location = unroundedLocation; + } node.Location += delta; + } + _leftMouseDownPos = location; _movingNodesDelta += delta; Cursor = CursorType.SizeAll; From 976faee8a33fb4d189a7998471c0169be69de8ce Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Sun, 17 Sep 2023 12:46:57 -0400 Subject: [PATCH 02/24] Extract options from testing area and handle extra mouse deltas that were not processed during the previous movement frame. --- Source/Editor/Surface/VisjectSurface.Input.cs | 51 ++++++++++++------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/Source/Editor/Surface/VisjectSurface.Input.cs b/Source/Editor/Surface/VisjectSurface.Input.cs index 27c8e2a02..5ba070200 100644 --- a/Source/Editor/Surface/VisjectSurface.Input.cs +++ b/Source/Editor/Surface/VisjectSurface.Input.cs @@ -18,10 +18,18 @@ namespace FlaxEditor.Surface /// public readonly InputActionsContainer InputActions; + /// + /// Should grid snapping be enabled for these nodes? + /// + public bool GridSnappingEnabled = false; + private string _currentInputText = string.Empty; private Float2 _movingNodesDelta; + private Float2 _gridRoundingDelta; private HashSet _movingNodes; private readonly Stack _inputBrackets = new Stack(); + private readonly float _gridSize = 15f; + private class InputBracket { @@ -177,6 +185,15 @@ namespace FlaxEditor.Surface } } + private Float2 RoundToGrid(Float2 point) + { + Float2 pointToRound = point; + pointToRound.X = (float)Math.CopySign(Math.Floor(Math.Abs((double)pointToRound.X) / _gridSize) * _gridSize, pointToRound.X); + pointToRound.Y = (float)Math.CopySign(Math.Floor(Math.Abs((double)pointToRound.Y) / _gridSize) * _gridSize, pointToRound.Y); + + return pointToRound; + } + /// public override void OnMouseEnter(Float2 location) { @@ -224,48 +241,44 @@ namespace FlaxEditor.Surface // Moving else if (_isMovingSelection) { - bool testOption = true; - float testGridSize = 15f; + if (!GridSnappingEnabled) + _gridRoundingDelta = Float2.Zero; // Reset in case user toggled option between frames. + // Calculate delta (apply view offset) var viewDelta = _rootControl.Location - _movingSelectionViewPos; _movingSelectionViewPos = _rootControl.Location; - var delta = location - _leftMouseDownPos - viewDelta; + var delta = location - _leftMouseDownPos - viewDelta + _gridRoundingDelta; var deltaLengthSquared = delta.LengthSquared; delta /= _targetScale; - if ((!testOption || Math.Abs(delta.X) >= testGridSize || (Math.Abs(delta.Y) >= testGridSize)) + if ((!GridSnappingEnabled || Math.Abs(delta.X) >= _gridSize || (Math.Abs(delta.Y) >= _gridSize)) && deltaLengthSquared > 0.01f) { // Move selected nodes - Debug.Log("test " + delta.ToString() + ", " + testGridSize.ToString() + ", " + _targetScale.ToString()); + Debug.Log("test " + delta.ToString() + ", " + _gridSize.ToString() + ", " + _targetScale.ToString()); - - if (testOption) + // The change that occurred by rounding. Used to retain specific delta values if it doesn't snap on one axis but does on another. + if (GridSnappingEnabled) { - // Round delta to ensure grid snapping. - Float2 unroundedDelta = delta; - unroundedDelta.X = (float) Math.CopySign(Math.Floor(Math.Abs((double)unroundedDelta.X) / testGridSize) * testGridSize, unroundedDelta.X); - unroundedDelta.Y = (float)Math.CopySign(Math.Floor(Math.Abs((double)unroundedDelta.Y) / testGridSize) * testGridSize, unroundedDelta.Y); - delta = unroundedDelta; + + delta = RoundToGrid(unroundedDelta); + _gridRoundingDelta = (unroundedDelta - delta) * _targetScale; // Standardize unit of the rounding delta, in case user zooms between node movements. } foreach (var node in _movingNodes) { - if (testOption) + if (GridSnappingEnabled) { - // Ensure location is snapped if grid snap is on. - Float2 unroundedLocation = node.Location; - unroundedLocation.X = (float)Math.CopySign(Math.Round(Math.Abs((double)unroundedLocation.X) / testGridSize) * testGridSize, unroundedLocation.X); - unroundedLocation.Y = (float)Math.CopySign(Math.Round(Math.Abs((double)unroundedLocation.Y) / testGridSize) * testGridSize, unroundedLocation.Y); - node.Location = unroundedLocation; + node.Location = RoundToGrid(unroundedLocation); } + node.Location += delta; } _leftMouseDownPos = location; - _movingNodesDelta += delta; + _movingNodesDelta += delta; // TODO: Figure out how to handle undo for differing values of _gridRoundingDelta between selected nodes. For now it will be a small error in undo. Cursor = CursorType.SizeAll; MarkAsEdited(false); } From e38da7eb95020e0235cdb19c6cb62b6e7b70959e Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Sun, 17 Sep 2023 16:48:41 -0400 Subject: [PATCH 03/24] Factor Toolstrip setup out from the various Visject Windows. I made this it's own commit in case you don't like these changes, but if you want to undo you will have to add the new button I added to all three windows. --- Source/Editor/Surface/SurfaceUtils.cs | 21 +++++++++++++++++++ Source/Editor/Surface/VisjectSurfaceWindow.cs | 15 ++----------- .../Assets/VisjectFunctionSurfaceWindow.cs | 14 ++----------- .../Windows/Assets/VisualScriptWindow.cs | 12 ++--------- 4 files changed, 27 insertions(+), 35 deletions(-) diff --git a/Source/Editor/Surface/SurfaceUtils.cs b/Source/Editor/Surface/SurfaceUtils.cs index 08b9c6d63..563d00df0 100644 --- a/Source/Editor/Surface/SurfaceUtils.cs +++ b/Source/Editor/Surface/SurfaceUtils.cs @@ -12,6 +12,8 @@ using FlaxEditor.Scripting; using FlaxEditor.Utilities; using FlaxEngine.Utilities; using FlaxEngine; +using FlaxEditor.GUI; +using FlaxEditor.Options; namespace FlaxEditor.Surface { @@ -532,5 +534,24 @@ namespace FlaxEditor.Surface value = new Double4(i); return value; } + + public static void VisjectCommonToolstripSetup(Editor editor, ToolStrip toolStrip, FlaxEditor.Undo undo, + Action save, Action showWholeGraph, InputActionsContainer actionsContainer, + out ToolStripButton saveButton, out ToolStripButton undoButton, out ToolStripButton redoButton) + { + // Toolstrip + saveButton = (ToolStripButton)toolStrip.AddButton(editor.Icons.Save64, save).LinkTooltip("Save"); + toolStrip.AddSeparator(); + undoButton = (ToolStripButton)toolStrip.AddButton(editor.Icons.Undo64, undo.PerformUndo).LinkTooltip("Undo (Ctrl+Z)"); + redoButton = (ToolStripButton)toolStrip.AddButton(editor.Icons.Redo64, undo.PerformRedo).LinkTooltip("Redo (Ctrl+Y)"); + toolStrip.AddSeparator(); + toolStrip.AddButton(editor.Icons.Search64, editor.ContentFinding.ShowSearch).LinkTooltip("Open content search tool (Ctrl+F)"); + toolStrip.AddButton(editor.Icons.CenterView64, showWholeGraph).LinkTooltip("Show whole graph"); + + // Setup input actions + actionsContainer.Add(options => options.Undo, undo.PerformUndo); + actionsContainer.Add(options => options.Redo, undo.PerformRedo); + actionsContainer.Add(options => options.Search, editor.ContentFinding.ShowSearch); + } } } diff --git a/Source/Editor/Surface/VisjectSurfaceWindow.cs b/Source/Editor/Surface/VisjectSurfaceWindow.cs index 305121e11..8362cbd44 100644 --- a/Source/Editor/Surface/VisjectSurfaceWindow.cs +++ b/Source/Editor/Surface/VisjectSurfaceWindow.cs @@ -772,19 +772,8 @@ namespace FlaxEditor.Surface } _propertiesEditor.Modified += OnPropertyEdited; - // Toolstrip - _saveButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Save64, Save).LinkTooltip("Save"); - _toolstrip.AddSeparator(); - _undoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Undo64, _undo.PerformUndo).LinkTooltip("Undo (Ctrl+Z)"); - _redoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Redo64, _undo.PerformRedo).LinkTooltip("Redo (Ctrl+Y)"); - _toolstrip.AddSeparator(); - _toolstrip.AddButton(Editor.Icons.Search64, Editor.ContentFinding.ShowSearch).LinkTooltip("Open content search tool (Ctrl+F)"); - _toolstrip.AddButton(editor.Icons.CenterView64, ShowWholeGraph).LinkTooltip("Show whole graph"); - - // Setup input actions - InputActions.Add(options => options.Undo, _undo.PerformUndo); - InputActions.Add(options => options.Redo, _undo.PerformRedo); - InputActions.Add(options => options.Search, Editor.ContentFinding.ShowSearch); + SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, Save, ShowWholeGraph, InputActions, + out _saveButton, out _undoButton, out _redoButton); } private void OnUndoRedo(IUndoAction action) diff --git a/Source/Editor/Windows/Assets/VisjectFunctionSurfaceWindow.cs b/Source/Editor/Windows/Assets/VisjectFunctionSurfaceWindow.cs index 7ae6ae8be..69a1ae6ad 100644 --- a/Source/Editor/Windows/Assets/VisjectFunctionSurfaceWindow.cs +++ b/Source/Editor/Windows/Assets/VisjectFunctionSurfaceWindow.cs @@ -68,13 +68,8 @@ namespace FlaxEditor.Windows.Assets _undo.ActionDone += OnUndoRedo; // Toolstrip - _saveButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Save64, Save).LinkTooltip("Save"); - _toolstrip.AddSeparator(); - _undoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Undo64, _undo.PerformUndo).LinkTooltip("Undo (Ctrl+Z)"); - _redoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Redo64, _undo.PerformRedo).LinkTooltip("Redo (Ctrl+Y)"); - _toolstrip.AddSeparator(); - _toolstrip.AddButton(Editor.Icons.Search64, Editor.ContentFinding.ShowSearch).LinkTooltip("Open content search tool (Ctrl+F)"); - _toolstrip.AddButton(editor.Icons.CenterView64, ShowWholeGraph).LinkTooltip("Show whole graph"); + SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, Save, ShowWholeGraph, InputActions, + out _saveButton, out _undoButton, out _redoButton); // Panel _panel = new Panel(ScrollBars.None) @@ -83,11 +78,6 @@ namespace FlaxEditor.Windows.Assets Offsets = new Margin(0, 0, _toolstrip.Bottom, 0), Parent = this }; - - // Setup input actions - InputActions.Add(options => options.Undo, _undo.PerformUndo); - InputActions.Add(options => options.Redo, _undo.PerformRedo); - InputActions.Add(options => options.Search, Editor.ContentFinding.ShowSearch); } private void OnUndoRedo(IUndoAction action) diff --git a/Source/Editor/Windows/Assets/VisualScriptWindow.cs b/Source/Editor/Windows/Assets/VisualScriptWindow.cs index ed20b591e..cd5455a5b 100644 --- a/Source/Editor/Windows/Assets/VisualScriptWindow.cs +++ b/Source/Editor/Windows/Assets/VisualScriptWindow.cs @@ -596,13 +596,8 @@ namespace FlaxEditor.Windows.Assets _propertiesEditor.Select(_properties); // Toolstrip - _saveButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Save64, Save).LinkTooltip("Save"); - _toolstrip.AddSeparator(); - _undoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Undo64, _undo.PerformUndo).LinkTooltip("Undo (Ctrl+Z)"); - _redoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Redo64, _undo.PerformRedo).LinkTooltip("Redo (Ctrl+Y)"); - _toolstrip.AddSeparator(); - _toolstrip.AddButton(Editor.Icons.Search64, Editor.ContentFinding.ShowSearch).LinkTooltip("Open content search tool (Ctrl+F)"); - _toolstrip.AddButton(editor.Icons.CenterView64, ShowWholeGraph).LinkTooltip("Show whole graph"); + SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, Save, ShowWholeGraph, InputActions, + out _saveButton, out _undoButton, out _redoButton); _toolstrip.AddSeparator(); _toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/scripting/visual/index.html")).LinkTooltip("See documentation to learn more"); _debugToolstripControls = new[] @@ -642,9 +637,6 @@ namespace FlaxEditor.Windows.Assets debugObjectPickerContainer.Parent = _toolstrip; // Setup input actions - InputActions.Add(options => options.Undo, _undo.PerformUndo); - InputActions.Add(options => options.Redo, _undo.PerformRedo); - InputActions.Add(options => options.Search, Editor.ContentFinding.ShowSearch); InputActions.Add(options => options.DebuggerContinue, OnDebuggerContinue); InputActions.Add(options => options.DebuggerStepOver, OnDebuggerStepOver); InputActions.Add(options => options.DebuggerStepOut, OnDebuggerStepOut); From 5571430e1bed9aed28fc3124be38db640c9b715e Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Sun, 17 Sep 2023 16:50:02 -0400 Subject: [PATCH 04/24] Move options out of VisjectSurface.Input to a different place. --- Source/Editor/Surface/VisjectSurface.Input.cs | 11 ----------- Source/Editor/Surface/VisjectSurface.cs | 6 ++++++ 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Source/Editor/Surface/VisjectSurface.Input.cs b/Source/Editor/Surface/VisjectSurface.Input.cs index 5ba070200..462abe54e 100644 --- a/Source/Editor/Surface/VisjectSurface.Input.cs +++ b/Source/Editor/Surface/VisjectSurface.Input.cs @@ -18,18 +18,11 @@ namespace FlaxEditor.Surface /// public readonly InputActionsContainer InputActions; - /// - /// Should grid snapping be enabled for these nodes? - /// - public bool GridSnappingEnabled = false; - private string _currentInputText = string.Empty; private Float2 _movingNodesDelta; private Float2 _gridRoundingDelta; private HashSet _movingNodes; private readonly Stack _inputBrackets = new Stack(); - private readonly float _gridSize = 15f; - private class InputBracket { @@ -254,10 +247,6 @@ namespace FlaxEditor.Surface if ((!GridSnappingEnabled || Math.Abs(delta.X) >= _gridSize || (Math.Abs(delta.Y) >= _gridSize)) && deltaLengthSquared > 0.01f) { - // Move selected nodes - Debug.Log("test " + delta.ToString() + ", " + _gridSize.ToString() + ", " + _targetScale.ToString()); - - // The change that occurred by rounding. Used to retain specific delta values if it doesn't snap on one axis but does on another. if (GridSnappingEnabled) { Float2 unroundedDelta = delta; diff --git a/Source/Editor/Surface/VisjectSurface.cs b/Source/Editor/Surface/VisjectSurface.cs index 22aba4855..7cfcecbfc 100644 --- a/Source/Editor/Surface/VisjectSurface.cs +++ b/Source/Editor/Surface/VisjectSurface.cs @@ -30,6 +30,12 @@ namespace FlaxEditor.Surface /// protected SurfaceRootControl _rootControl; + /// + /// Is grid snapping enabled for this surface? + /// + public bool GridSnappingEnabled = false; + + private readonly float _gridSize = 15f; private float _targetScale = 1.0f; private float _moveViewWithMouseDragSpeed = 1.0f; private bool _canEdit = true; From 02d68bc057d9d4a1f4fadaf1ac09a703033f8b60 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Sun, 17 Sep 2023 18:20:50 -0400 Subject: [PATCH 05/24] Add toggle button for grid snapping. --- Source/Editor/Surface/SurfaceUtils.cs | 21 +++++++++++++++++-- Source/Editor/Surface/VisjectSurfaceWindow.cs | 11 ++++++++-- .../Assets/VisjectFunctionSurfaceWindow.cs | 11 ++++++++-- .../Windows/Assets/VisualScriptWindow.cs | 13 ++++++++++-- 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/Source/Editor/Surface/SurfaceUtils.cs b/Source/Editor/Surface/SurfaceUtils.cs index 563d00df0..f5ca394fb 100644 --- a/Source/Editor/Surface/SurfaceUtils.cs +++ b/Source/Editor/Surface/SurfaceUtils.cs @@ -14,6 +14,7 @@ using FlaxEngine.Utilities; using FlaxEngine; using FlaxEditor.GUI; using FlaxEditor.Options; +using FlaxEngine.GUI; namespace FlaxEditor.Surface { @@ -535,9 +536,10 @@ namespace FlaxEditor.Surface return value; } + // This might not be the greatest place to put this but I couldn't find anything better yet. public static void VisjectCommonToolstripSetup(Editor editor, ToolStrip toolStrip, FlaxEditor.Undo undo, - Action save, Action showWholeGraph, InputActionsContainer actionsContainer, - out ToolStripButton saveButton, out ToolStripButton undoButton, out ToolStripButton redoButton) + Action save, Action showWholeGraph, Action toggleGridSnap, InputActionsContainer actionsContainer, + out ToolStripButton saveButton, out ToolStripButton undoButton, out ToolStripButton redoButton, out ToolStripButton gridSnapButton) { // Toolstrip saveButton = (ToolStripButton)toolStrip.AddButton(editor.Icons.Save64, save).LinkTooltip("Save"); @@ -547,11 +549,26 @@ namespace FlaxEditor.Surface toolStrip.AddSeparator(); toolStrip.AddButton(editor.Icons.Search64, editor.ContentFinding.ShowSearch).LinkTooltip("Open content search tool (Ctrl+F)"); toolStrip.AddButton(editor.Icons.CenterView64, showWholeGraph).LinkTooltip("Show whole graph"); + gridSnapButton = (ToolStripButton)toolStrip.AddButton(editor.Icons.Stop64, toggleGridSnap).LinkTooltip("Toggle grid snapping for nodes."); + gridSnapButton.BackgroundColor = Style.Current.Background; // Default color for grid snap button. // Setup input actions actionsContainer.Add(options => options.Undo, undo.PerformUndo); actionsContainer.Add(options => options.Redo, undo.PerformRedo); actionsContainer.Add(options => options.Search, editor.ContentFinding.ShowSearch); } + + public static void ToggleSurfaceGridSnap(VisjectSurface surface, ToolStripButton gridSnapButton) + { + surface.GridSnappingEnabled = !surface.GridSnappingEnabled; + if (surface.GridSnappingEnabled) + { + gridSnapButton.BackgroundColor = Style.Current.BackgroundSelected; + } + else + { + gridSnapButton.BackgroundColor = Style.Current.Background; + } + } } } diff --git a/Source/Editor/Surface/VisjectSurfaceWindow.cs b/Source/Editor/Surface/VisjectSurfaceWindow.cs index 8362cbd44..eff8ec8a3 100644 --- a/Source/Editor/Surface/VisjectSurfaceWindow.cs +++ b/Source/Editor/Surface/VisjectSurfaceWindow.cs @@ -669,6 +669,7 @@ namespace FlaxEditor.Surface private readonly ToolStripButton _saveButton; private readonly ToolStripButton _undoButton; private readonly ToolStripButton _redoButton; + private readonly ToolStripButton _gridSnapButton; private bool _showWholeGraphOnLoad = true; /// @@ -772,8 +773,9 @@ namespace FlaxEditor.Surface } _propertiesEditor.Modified += OnPropertyEdited; - SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, Save, ShowWholeGraph, InputActions, - out _saveButton, out _undoButton, out _redoButton); + SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, + Save, ShowWholeGraph, ToggleGridSnap, InputActions, + out _saveButton, out _undoButton, out _redoButton, out _gridSnapButton); } private void OnUndoRedo(IUndoAction action) @@ -812,6 +814,11 @@ namespace FlaxEditor.Surface _surface.ShowWholeGraph(); } + private void ToggleGridSnap() + { + SurfaceUtils.ToggleSurfaceGridSnap(_surface, _gridSnapButton); + } + /// /// Refreshes temporary asset to see changes live when editing the surface. /// diff --git a/Source/Editor/Windows/Assets/VisjectFunctionSurfaceWindow.cs b/Source/Editor/Windows/Assets/VisjectFunctionSurfaceWindow.cs index 69a1ae6ad..9750fa3e6 100644 --- a/Source/Editor/Windows/Assets/VisjectFunctionSurfaceWindow.cs +++ b/Source/Editor/Windows/Assets/VisjectFunctionSurfaceWindow.cs @@ -30,6 +30,7 @@ namespace FlaxEditor.Windows.Assets private readonly ToolStripButton _saveButton; private readonly ToolStripButton _undoButton; private readonly ToolStripButton _redoButton; + private readonly ToolStripButton _gridSnapButton; private bool _showWholeGraphOnLoad = true; /// @@ -68,8 +69,9 @@ namespace FlaxEditor.Windows.Assets _undo.ActionDone += OnUndoRedo; // Toolstrip - SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, Save, ShowWholeGraph, InputActions, - out _saveButton, out _undoButton, out _redoButton); + SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, + Save, ShowWholeGraph, ToggleGridSnap, InputActions, + out _saveButton, out _undoButton, out _redoButton, out _gridSnapButton); // Panel _panel = new Panel(ScrollBars.None) @@ -94,6 +96,11 @@ namespace FlaxEditor.Windows.Assets _surface.ShowWholeGraph(); } + private void ToggleGridSnap() + { + SurfaceUtils.ToggleSurfaceGridSnap(_surface, _gridSnapButton); + } + /// /// Refreshes temporary asset to see changes live when editing the surface. /// diff --git a/Source/Editor/Windows/Assets/VisualScriptWindow.cs b/Source/Editor/Windows/Assets/VisualScriptWindow.cs index cd5455a5b..3b6480063 100644 --- a/Source/Editor/Windows/Assets/VisualScriptWindow.cs +++ b/Source/Editor/Windows/Assets/VisualScriptWindow.cs @@ -533,6 +533,7 @@ namespace FlaxEditor.Windows.Assets private readonly ToolStripButton _saveButton; private readonly ToolStripButton _undoButton; private readonly ToolStripButton _redoButton; + private readonly ToolStripButton _gridSnapButton; private Control[] _debugToolstripControls; private bool _showWholeGraphOnLoad = true; private bool _tmpAssetIsDirty; @@ -596,8 +597,11 @@ namespace FlaxEditor.Windows.Assets _propertiesEditor.Select(_properties); // Toolstrip - SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, Save, ShowWholeGraph, InputActions, - out _saveButton, out _undoButton, out _redoButton); + SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, + Save, ShowWholeGraph, ToggleGridSnap, InputActions, + out _saveButton, out _undoButton, out _redoButton, out _gridSnapButton); + + // The rest of the toolstrip _toolstrip.AddSeparator(); _toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/scripting/visual/index.html")).LinkTooltip("See documentation to learn more"); _debugToolstripControls = new[] @@ -678,6 +682,11 @@ namespace FlaxEditor.Windows.Assets _surface.ShowWholeGraph(); } + private void ToggleGridSnap() + { + SurfaceUtils.ToggleSurfaceGridSnap(_surface, _gridSnapButton); + } + /// /// Refreshes temporary asset to see changes live when editing the surface. /// From 83bf68a64f21d964f0ca8498522f25d6c7270cae Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Sun, 17 Sep 2023 18:31:49 -0400 Subject: [PATCH 06/24] Make GridSize public. --- Source/Editor/Surface/VisjectSurface.Input.cs | 6 +++--- Source/Editor/Surface/VisjectSurface.cs | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Source/Editor/Surface/VisjectSurface.Input.cs b/Source/Editor/Surface/VisjectSurface.Input.cs index 462abe54e..d61f9bd0d 100644 --- a/Source/Editor/Surface/VisjectSurface.Input.cs +++ b/Source/Editor/Surface/VisjectSurface.Input.cs @@ -181,8 +181,8 @@ namespace FlaxEditor.Surface private Float2 RoundToGrid(Float2 point) { Float2 pointToRound = point; - pointToRound.X = (float)Math.CopySign(Math.Floor(Math.Abs((double)pointToRound.X) / _gridSize) * _gridSize, pointToRound.X); - pointToRound.Y = (float)Math.CopySign(Math.Floor(Math.Abs((double)pointToRound.Y) / _gridSize) * _gridSize, pointToRound.Y); + pointToRound.X = (float)Math.CopySign(Math.Floor(Math.Abs((double)pointToRound.X) / GridSize) * GridSize, pointToRound.X); + pointToRound.Y = (float)Math.CopySign(Math.Floor(Math.Abs((double)pointToRound.Y) / GridSize) * GridSize, pointToRound.Y); return pointToRound; } @@ -244,7 +244,7 @@ namespace FlaxEditor.Surface var deltaLengthSquared = delta.LengthSquared; delta /= _targetScale; - if ((!GridSnappingEnabled || Math.Abs(delta.X) >= _gridSize || (Math.Abs(delta.Y) >= _gridSize)) + if ((!GridSnappingEnabled || Math.Abs(delta.X) >= GridSize || (Math.Abs(delta.Y) >= GridSize)) && deltaLengthSquared > 0.01f) { if (GridSnappingEnabled) diff --git a/Source/Editor/Surface/VisjectSurface.cs b/Source/Editor/Surface/VisjectSurface.cs index 7cfcecbfc..fc0995100 100644 --- a/Source/Editor/Surface/VisjectSurface.cs +++ b/Source/Editor/Surface/VisjectSurface.cs @@ -35,7 +35,11 @@ namespace FlaxEditor.Surface /// public bool GridSnappingEnabled = false; - private readonly float _gridSize = 15f; + /// + /// The size of the snapping grid. + /// + public static readonly float GridSize = 15f; + private float _targetScale = 1.0f; private float _moveViewWithMouseDragSpeed = 1.0f; private bool _canEdit = true; From b202573920699216965a7394446522fc3106671f Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Mon, 18 Sep 2023 10:37:23 -0400 Subject: [PATCH 07/24] Scale node size to the next highest grid-aligned size. --- Source/Editor/Surface/NodeArchetype.cs | 14 ++++++++++++- Source/Editor/Surface/VisjectSurface.Input.cs | 20 ++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs index 6dc923ce2..cdcf1211b 100644 --- a/Source/Editor/Surface/NodeArchetype.cs +++ b/Source/Editor/Surface/NodeArchetype.cs @@ -99,10 +99,22 @@ namespace FlaxEditor.Surface /// public CreateCustomNodeFunc Create; + private Float2 _size; + /// /// Default initial size of the node. /// - public Float2 Size; + public Float2 Size { + get + { + return _size; + } + set + { + _size = VisjectSurface.RoundToGrid(value, true); + Debug.Log(_size.ToString()); + } + } /// /// Custom set of flags. diff --git a/Source/Editor/Surface/VisjectSurface.Input.cs b/Source/Editor/Surface/VisjectSurface.Input.cs index d61f9bd0d..be64019b6 100644 --- a/Source/Editor/Surface/VisjectSurface.Input.cs +++ b/Source/Editor/Surface/VisjectSurface.Input.cs @@ -178,11 +178,25 @@ namespace FlaxEditor.Surface } } - private Float2 RoundToGrid(Float2 point) + /// + /// Round a visject coordinate point to the grid. + /// + /// The point to be rounded. + /// Round to ceiling instead? + /// + public static Float2 RoundToGrid(Float2 point, bool ceil = false) { + Func round = x => + { + double pointGridUnits = Math.Abs((double)x) / GridSize; + pointGridUnits = ceil ? Math.Ceiling(pointGridUnits) : Math.Floor(pointGridUnits); + + return (float)Math.CopySign(pointGridUnits * GridSize, x); + }; + Float2 pointToRound = point; - pointToRound.X = (float)Math.CopySign(Math.Floor(Math.Abs((double)pointToRound.X) / GridSize) * GridSize, pointToRound.X); - pointToRound.Y = (float)Math.CopySign(Math.Floor(Math.Abs((double)pointToRound.Y) / GridSize) * GridSize, pointToRound.Y); + pointToRound.X = round(pointToRound.X); + pointToRound.Y = round(pointToRound.Y); return pointToRound; } From d83d510002c827c26efb71b2b62981fbedd4f5c6 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Tue, 19 Sep 2023 22:59:38 -0400 Subject: [PATCH 08/24] Update material size node to fit text.. --- 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 1a797c67d..a68132587 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -281,7 +281,7 @@ namespace FlaxEditor.Surface.Archetypes Title = "Material", Description = "Main material node", Flags = NodeFlags.MaterialGraph | NodeFlags.NoRemove | NodeFlags.NoSpawnViaGUI | NodeFlags.NoSpawnViaPaste | NodeFlags.NoCloseButton, - Size = new Float2(150, 300), + Size = new Float2(180, 300), Elements = new[] { NodeElementArchetype.Factory.Input(0, "", true, typeof(void), 0), From a7d56c29b505e6a258a1a6a8c5e6070f1b57bd01 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Tue, 19 Sep 2023 23:00:17 -0400 Subject: [PATCH 09/24] Update scaling setters. --- Source/Editor/Surface/NodeArchetype.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs index cdcf1211b..b1a36ba0a 100644 --- a/Source/Editor/Surface/NodeArchetype.cs +++ b/Source/Editor/Surface/NodeArchetype.cs @@ -100,11 +100,11 @@ namespace FlaxEditor.Surface public CreateCustomNodeFunc Create; private Float2 _size; - /// /// Default initial size of the node. /// - public Float2 Size { + public Float2 Size + { get { return _size; @@ -112,7 +112,6 @@ namespace FlaxEditor.Surface set { _size = VisjectSurface.RoundToGrid(value, true); - Debug.Log(_size.ToString()); } } From 0fe1acdabccbe274eb21ea0dc43815c84386ae45 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Tue, 19 Sep 2023 23:00:55 -0400 Subject: [PATCH 10/24] Update grid size to fit the Node Box positioning. --- 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 fc0995100..50c112418 100644 --- a/Source/Editor/Surface/VisjectSurface.cs +++ b/Source/Editor/Surface/VisjectSurface.cs @@ -38,7 +38,7 @@ namespace FlaxEditor.Surface /// /// The size of the snapping grid. /// - public static readonly float GridSize = 15f; + public static readonly float GridSize = 20f; private float _targetScale = 1.0f; private float _moveViewWithMouseDragSpeed = 1.0f; From b4d95a68f140978841640694d400f3d0b3a7e89d Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Tue, 19 Sep 2023 23:08:57 -0400 Subject: [PATCH 11/24] Apply patch from DutchDave on discord to make nodes selectable from any point on the node. --- Source/Editor/Surface/SurfaceNode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index c24c47fbd..047e22476 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -878,7 +878,7 @@ namespace FlaxEditor.Surface /// public override bool CanSelect(ref Float2 location) { - return _headerRect.MakeOffsetted(Location).Contains(ref location); + return _headerRect.MakeOffsetted(Location).Contains(ref location) || new Rectangle(Float2.Zero, Size).MakeOffsetted(Location).Contains(ref location); } /// From 67653cc0e88407dbdbd5628613c90ee8b68d5542 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Wed, 20 Sep 2023 01:45:49 -0400 Subject: [PATCH 12/24] Increase the size of the bitwise node to accomodate for the "Result" text. --- Source/Editor/Surface/Archetypes/Bitwise.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Bitwise.cs b/Source/Editor/Surface/Archetypes/Bitwise.cs index 06f719adc..058159d48 100644 --- a/Source/Editor/Surface/Archetypes/Bitwise.cs +++ b/Source/Editor/Surface/Archetypes/Bitwise.cs @@ -19,7 +19,7 @@ namespace FlaxEditor.Surface.Archetypes Description = desc, AlternativeTitles = altTitles, Flags = NodeFlags.AllGraphs, - Size = new Float2(140, 20), + Size = new Float2(160, 20), Elements = new[] { NodeElementArchetype.Factory.Input(0, "A", true, typeof(int), 0), @@ -37,7 +37,7 @@ namespace FlaxEditor.Surface.Archetypes Description = desc, AlternativeTitles = altTitles, Flags = NodeFlags.AllGraphs, - Size = new Float2(140, 40), + Size = new Float2(160, 40), DefaultValues = new object[] { 0, From 2696bc3704c35d2b9d4f7ca787b1dde3485f176b Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Fri, 22 Sep 2023 12:26:11 -0400 Subject: [PATCH 13/24] Add debug view for collision boxes. --- Source/Editor/Surface/NodeArchetype.cs | 45 ++++- Source/Editor/Surface/NodeElementArchetype.cs | 4 +- Source/Editor/Surface/SurfaceNode.cs | 180 ++++++++++++++++-- 3 files changed, 205 insertions(+), 24 deletions(-) diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs index b1a36ba0a..4582aa054 100644 --- a/Source/Editor/Surface/NodeArchetype.cs +++ b/Source/Editor/Surface/NodeArchetype.cs @@ -1,8 +1,11 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using System; +using System.Collections.Generic; +using System.Linq; using FlaxEditor.Scripting; using FlaxEngine; +using FlaxEngine.GUI; namespace FlaxEditor.Surface { @@ -178,10 +181,50 @@ namespace FlaxEditor.Surface /// public Func DependentBoxFilter; + private NodeElementArchetype[] _elements; /// /// Array with default elements descriptions. /// - public NodeElementArchetype[] Elements; + public NodeElementArchetype[] Elements + { + get + { + return _elements; + } + set + { + _elements = value; + + /*Float2 topLeft = Float2.Zero; + Float2 bottomRight = Float2.Zero; + List textRectangles = new List(); + + foreach (NodeElementArchetype nodeElementType in _elements) + { + bool isInputElement = nodeElementType.Type == NodeElementType.Input; + bool isOutputElement = nodeElementType.Type == NodeElementType.Output; + if (isInputElement) + { + // Text will be to the right + } + + // In case of negatives.. most likely not needed. + topLeft.X = Math.Min(topLeft.X, nodeElementType.Position.X); + topLeft.Y = Math.Min(topLeft.Y, nodeElementType.Position.Y); + + bottomRight.X = Math.Max(bottomRight.X, nodeElementType.Position.X + nodeElementType.Size.X); + bottomRight.Y = Math.Max(bottomRight.Y, nodeElementType.Position.Y + nodeElementType.Size.Y); + } + + float paddingConst = 15; + + float sizeXElements = bottomRight.X - topLeft.X + paddingConst; + float sizeYElements = bottomRight.Y - topLeft.Y + paddingConst; + float titleSize = Style.Current.FontLarge.MeasureText(Title).X + paddingConst; + + Size = new Float2(Math.Max(sizeXElements, titleSize), sizeYElements);*/ + } + } /// /// Tries to parse some text and extract the data from it. diff --git a/Source/Editor/Surface/NodeElementArchetype.cs b/Source/Editor/Surface/NodeElementArchetype.cs index be8b67378..298127c3a 100644 --- a/Source/Editor/Surface/NodeElementArchetype.cs +++ b/Source/Editor/Surface/NodeElementArchetype.cs @@ -132,8 +132,8 @@ namespace FlaxEditor.Surface { Type = NodeElementType.Input, Position = new Float2( - Constants.NodeMarginX - Constants.BoxOffsetX, - Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY), + Constants.NodeMarginX - Constants.BoxOffsetX, + Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY), Text = text, Single = single, ValueIndex = valueIndex, diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 047e22476..8d0ed43b9 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -165,7 +165,7 @@ namespace FlaxEditor.Surface { if (Surface == null) return; - Size = CalculateNodeSize(width, height); + Size = CalculateNodeSize(width, height); // Update boxes on width change //if (!Mathf.NearEqual(prevSize.X, Size.X)) @@ -180,6 +180,109 @@ namespace FlaxEditor.Surface } } + private Float2 GetBoxControlWidthHeight(Control control, Font boxLabelFont) + { + float boxWidth = 0; + float boxHeight = 0; + + if (control is InputBox inputBox) + { + boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 20; + if (inputBox.DefaultValueEditor != null) + boxWidth += inputBox.DefaultValueEditor.Width + 4; + boxHeight = inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f; + } + else if (control is OutputBox outputBox) + { + boxWidth = boxLabelFont.MeasureText(outputBox.Text).X + 20; + boxHeight = outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f; + } + else if (control is Control defaultControl) + { + if (defaultControl.AnchorPreset == AnchorPresets.TopLeft) + { + boxWidth = defaultControl.Right + 4 - Constants.NodeMarginX; + boxHeight = defaultControl.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize; + } + else + { + boxWidth = defaultControl.Width + 4; + boxHeight = defaultControl.Height + 4; + } + } + + return new Float2(boxWidth, boxHeight); + } + + public ContainerControl HACK = null; + + private Float2 CompareAndGetNewCollisionSize(Rectangle rect1, Rectangle rect2, float collisionWidth, float collisionHeight) + { + Rectangle sharedArea; + Rectangle.Shared(ref rect1, ref rect2, out sharedArea); + + Color colliderColor = Color.Chocolate; + colliderColor.A = 0.1f; + Panel colliderPanel = new Panel + { + BackgroundColor = colliderColor, + Location = sharedArea.Location, + Size = sharedArea.Size, + Parent = HACK + }; + + return new Float2(Mathf.Max(collisionWidth, sharedArea.Width + 4), Mathf.Max(collisionHeight, sharedArea.Height + 4)); + } + + private Float2 CalculateCollisionSize(List controls, Font boxLabelFont) + { + List colliderRectangles = new List(); + int controlsCount = controls.Count; + for (int i = 0; i < controlsCount; i++) + { + var control = controls[i]; + if (!control.Visible || control is Panel panel) + continue; + + Float2 boxSize = GetBoxControlWidthHeight(control, boxLabelFont); + + Rectangle controlRect = new Rectangle(control.X, control.Y, boxSize.X, boxSize.Y); + colliderRectangles.Add(controlRect); + + Color colliderColor = Style.Current.BackgroundSelected; + colliderColor.A = 0.25f; + Panel colliderPanel = new Panel + { + BackgroundColor = colliderColor, + Location = controlRect.Location, + Size = controlRect.Size, + Parent = HACK + }; + } + + float collisionWidth = 0; + float collisionHeight = 0; + for (int i = 0; i < colliderRectangles.Count; i++) + { + for (int j = 0; j < colliderRectangles.Count; j++) + { + if (i == j) + { + continue; + } + + Rectangle rect1 = colliderRectangles[i]; + Rectangle rect2 = colliderRectangles[j]; + Float2 newCollisionSize = CompareAndGetNewCollisionSize(rect1, rect2, collisionWidth, collisionHeight); + + collisionWidth = newCollisionSize.X; + collisionHeight = newCollisionSize.Y; + } + } + + return new Float2(collisionWidth, collisionHeight); + } + /// /// Automatically resizes the node to match the title size and all the elements for best fit of the node dimensions. /// @@ -187,6 +290,7 @@ namespace FlaxEditor.Surface { if (Surface == null) return; + HACK = this; var width = 0.0f; var height = 0.0f; var leftHeight = 0.0f; @@ -195,44 +299,75 @@ namespace FlaxEditor.Surface var rightWidth = 40.0f; var boxLabelFont = Style.Current.FontSmall; var titleLabelFont = Style.Current.FontLarge; - for (int i = 0; i < Children.Count; i++) + int childrenCount = Children.Count; + for (int i = 0; i < childrenCount; i++) { var child = Children[i]; + if (child is Panel panel) + { + panel.Visible = false; + } if (!child.Visible) continue; + + Float2 boxSize = GetBoxControlWidthHeight(child, boxLabelFont); if (child is InputBox inputBox) { - var boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 20; - if (inputBox.DefaultValueEditor != null) - boxWidth += inputBox.DefaultValueEditor.Width + 4; - leftWidth = Mathf.Max(leftWidth, boxWidth); - leftHeight = Mathf.Max(leftHeight, inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f); + leftWidth = Mathf.Max(leftWidth, boxSize.X); + leftHeight = Mathf.Max(leftHeight, boxSize.Y); } else if (child is OutputBox outputBox) { - rightWidth = Mathf.Max(rightWidth, boxLabelFont.MeasureText(outputBox.Text).X + 20); - rightHeight = Mathf.Max(rightHeight, outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f); + rightWidth = Mathf.Max(rightWidth, boxSize.X); + rightHeight = Mathf.Max(rightHeight, boxSize.Y); } - else if (child is Control control) + else { - if (control.AnchorPreset == AnchorPresets.TopLeft) - { - width = Mathf.Max(width, control.Right + 4 - Constants.NodeMarginX); - height = Mathf.Max(height, control.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize); - } - else - { - width = Mathf.Max(width, control.Width + 4); - height = Mathf.Max(height, control.Height + 4); - } + width = Mathf.Max(width, boxSize.X); + height = Mathf.Max(height, boxSize.Y); } } + Debug.Log(Title); + Float2 collisionSize = CalculateCollisionSize(Children, boxLabelFont); + Debug.Log(collisionSize.ToString()); + //width += collisionSize.X; + //height += collisionSize.Y; + width = Mathf.Max(width, leftWidth + rightWidth + 10); width = Mathf.Max(width, titleLabelFont.MeasureText(Title).X + 30); height = Mathf.Max(height, Mathf.Max(leftHeight, rightHeight)); - Resize(width, height); + + Float2 roundedSize = VisjectSurface.RoundToGrid(new Float2(width, height), true); + Resize(roundedSize.X, roundedSize.Y); } + /* if (child is InputBox inputBox) +{ + var boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 20; + if (inputBox.DefaultValueEditor != null) + boxWidth += inputBox.DefaultValueEditor.Width + 4; + leftWidth = Mathf.Max(leftWidth, boxWidth); + leftHeight = Mathf.Max(leftHeight, inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f); +} +else if (child is OutputBox outputBox) +{ + rightWidth = Mathf.Max(rightWidth, boxLabelFont.MeasureText(outputBox.Text).X + 20); + rightHeight = Mathf.Max(rightHeight, outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f); +} +else if (child is Control control) +{ + if (control.AnchorPreset == AnchorPresets.TopLeft) + { + width = Mathf.Max(width, control.Right + 4 - Constants.NodeMarginX); + height = Mathf.Max(height, control.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize); + } + else + { + width = Mathf.Max(width, control.Width + 4); + height = Mathf.Max(height, control.Height + 4); + } +}*/ + /// /// Creates an element from the archetype and adds the element to the node. /// @@ -310,6 +445,9 @@ namespace FlaxEditor.Surface Elements.Add(element); if (element is Control control) AddChild(control); + + if (!(element is Panel panel)) + ResizeAuto(); } /// From 081ef1fd81fd32a9aaa3fd97b86cde9e6a9692e8 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Mon, 25 Sep 2023 14:20:35 -0400 Subject: [PATCH 14/24] More debug draws. It seems to be showing some weird issues with leftWidth/rightWidth size. --- Source/Editor/Surface/SurfaceNode.cs | 135 +++++++++++++++++++++++++-- Source/Engine/Core/Config.Gen.h | 3 + 2 files changed, 129 insertions(+), 9 deletions(-) diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 8d0ed43b9..d6275e439 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -223,19 +223,21 @@ namespace FlaxEditor.Surface Color colliderColor = Color.Chocolate; colliderColor.A = 0.1f; - Panel colliderPanel = new Panel + /*Panel colliderPanel = new Panel { BackgroundColor = colliderColor, Location = sharedArea.Location, Size = sharedArea.Size, Parent = HACK - }; + };*/ return new Float2(Mathf.Max(collisionWidth, sharedArea.Width + 4), Mathf.Max(collisionHeight, sharedArea.Height + 4)); } private Float2 CalculateCollisionSize(List controls, Font boxLabelFont) { + Debug.Log(string.Format("{0}:", Title)); + List colliderRectangles = new List(); int controlsCount = controls.Count; for (int i = 0; i < controlsCount; i++) @@ -244,20 +246,98 @@ namespace FlaxEditor.Surface if (!control.Visible || control is Panel panel) continue; - Float2 boxSize = GetBoxControlWidthHeight(control, boxLabelFont); + Debug.Log(string.Format("\t{0}:", control.GetType().ToString())); + Debug.Log(string.Format("\t\tControl Bounds: {0}", control.Bounds)); + /*Color colliderColor2 = Color.Crimson; + colliderColor2.A = 0.25f; + new Panel + { + BackgroundColor = colliderColor2, + Location = control.Bounds.Location, + Size = control.Bounds.Size, + Parent = HACK + }; - Rectangle controlRect = new Rectangle(control.X, control.Y, boxSize.X, boxSize.Y); + if (control is InputBox inputBox2) + { + Rectangle textRect; + textRect.Size = boxLabelFont.MeasureText(inputBox2.Text); + textRect.Location = new Float2(control.Bounds.Location.X + 24, control.Bounds.Location.Y); + Debug.Log(string.Format("\t\tText Rectangle: {0}", textRect)); + + Color colliderColor3 = Color.ForestGreen; + colliderColor3.A = 0.25f; + new Panel + { + BackgroundColor = colliderColor3, + Location = textRect.Location, + Size = textRect.Size, + Parent = HACK + }; + } + + if (control is OutputBox outputBox2) + { + Rectangle textRect; + textRect.Size = boxLabelFont.MeasureText(outputBox2.Text); + textRect.Location = new Float2(control.Bounds.Location.X - textRect.Size.X - 2, control.Bounds.Location.Y); + Debug.Log(string.Format("\t\tText Rectangle: {0}", textRect)); + + Color colliderColor3 = Color.ForestGreen; + colliderColor3.A = 0.25f; + new Panel + { + BackgroundColor = colliderColor3, + Location = textRect.Location, + Size = textRect.Size, + Parent = HACK + }; + }*/ + + + + + + Float2 boxSize = GetBoxControlWidthHeight(control, boxLabelFont); + Float2 boxPosition = control.Location; + + // Special condition handling that is different than `GetBoxControlWidthHeight` + if (control is OutputBox outputBox) + { + boxPosition.X -= boxLabelFont.MeasureText(outputBox.Text).X; + boxSize.X = boxLabelFont.MeasureText(outputBox.Text).X + 20; + boxSize.Y = Mathf.Max(boxLabelFont.MeasureText(outputBox.Text).Y, outputBox.Height) + 4; + } else if (control is InputBox inputBox) + { + boxSize.X = boxLabelFont.MeasureText(inputBox.Text).X + 20; + boxSize.Y = Mathf.Max(boxLabelFont.MeasureText(inputBox.Text).Y, inputBox.Height) + 4; + } else + { + if (control.AnchorPreset == AnchorPresets.TopLeft) + { + boxSize.X = control.Right + 4 - Constants.NodeMarginX; + boxSize.Y = control.Bottom - control.Top + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize; + boxPosition.Y = control.Top; + } + else + { + boxSize.X = control.Width + 4; + boxSize.Y = control.Height + 4; + } + } + + Rectangle controlRect = new Rectangle(boxPosition.X, boxPosition.Y, boxSize.X, boxSize.Y); colliderRectangles.Add(controlRect); Color colliderColor = Style.Current.BackgroundSelected; colliderColor.A = 0.25f; - Panel colliderPanel = new Panel + /*Panel colliderPanel = new Panel { BackgroundColor = colliderColor, Location = controlRect.Location, Size = controlRect.Size, Parent = HACK - }; + };*/ } float collisionWidth = 0; @@ -283,6 +363,13 @@ namespace FlaxEditor.Surface return new Float2(collisionWidth, collisionHeight); } + //HACK + private Color alphainator(Color color, float alpha) + { + color.A = alpha; + return color; + } + /// /// Automatically resizes the node to match the title size and all the elements for best fit of the node dimensions. /// @@ -336,9 +423,39 @@ namespace FlaxEditor.Surface width = Mathf.Max(width, leftWidth + rightWidth + 10); width = Mathf.Max(width, titleLabelFont.MeasureText(Title).X + 30); height = Mathf.Max(height, Mathf.Max(leftHeight, rightHeight)); - - Float2 roundedSize = VisjectSurface.RoundToGrid(new Float2(width, height), true); - Resize(roundedSize.X, roundedSize.Y); + + new Panel + { + BackgroundColor = alphainator(Color.Azure, 0.25f), + Size = new Float2(leftWidth, height), + AnchorPreset = AnchorPresets.TopLeft, + Location = new Float2(4f, Constants.NodeHeaderSize + 4), + Parent = HACK + }; + + new Panel + { + BackgroundColor = alphainator(Color.Crimson, 0.25f), + Size = new Float2(rightWidth, height), + AnchorPreset = AnchorPresets.TopRight, + Location = new Float2(-4-rightWidth, Constants.NodeHeaderSize + 4), + Parent = HACK + }; + + /*Rectangle testRect = Rectangle.Default; + testRect.Width = width; + testRect.Height = height; + testRect.Y += 10; // ra + new Panel + { + BackgroundColor = colliderColor, + Location = testRect.Location, + Size = testRect.Size, + Parent = HACK + };*/ + + Float2 roundedSize = VisjectSurface.RoundToGrid(new Float2(width, height), ceil: true); + //Resize(roundedSize.X, roundedSize.Y); } /* if (child is InputBox inputBox) diff --git a/Source/Engine/Core/Config.Gen.h b/Source/Engine/Core/Config.Gen.h index 6f70f09be..81c149108 100644 --- a/Source/Engine/Core/Config.Gen.h +++ b/Source/Engine/Core/Config.Gen.h @@ -1 +1,4 @@ #pragma once + +#define COMPILE_WITH_DEV_ENV 0 +#define OFFICIAL_BUILD 1 From d9f3fe186d03716ac3fc7a3d73036a27ae3851dc Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Mon, 2 Oct 2023 00:13:29 -0400 Subject: [PATCH 15/24] Implement function to properly get the size of the value editor for an InputBox. --- Source/Editor/Surface/Elements/InputBox.cs | 30 ++++++ Source/Editor/Surface/SurfaceNode.cs | 113 +++++++-------------- 2 files changed, 64 insertions(+), 79 deletions(-) diff --git a/Source/Editor/Surface/Elements/InputBox.cs b/Source/Editor/Surface/Elements/InputBox.cs index 4eac03105..5b0a43ca9 100644 --- a/Source/Editor/Surface/Elements/InputBox.cs +++ b/Source/Editor/Surface/Elements/InputBox.cs @@ -1652,5 +1652,35 @@ namespace FlaxEditor.Surface.Elements } } } + + /// + /// Get the size of the value editor for this box. + /// + /// The size of the value editor for this box. + public Float2 GetValueEditorSize() + { + if (!HasValue) + return Float2.Zero; + + if (_defaultValueEditor != null) + return _defaultValueEditor.Bounds.Size; + + for (int i = 0; i < DefaultValueEditors.Count; i++) + { + if (DefaultValueEditors[i].CanUse(this, ref _currentType)) + { + var bounds = new Rectangle(X + Width + 8 + Style.Current.FontSmall.MeasureText(Text).X, Y, 90, Height); + _editor = DefaultValueEditors[i]; + + // TODO: Find a better way to evaluate the size than using existing create code to resolve the size for each editor type. + var tempEditor = _editor.Create(this, ref bounds); + Float2 editorSize = tempEditor.Size; + tempEditor.Dispose(); + return editorSize; + } + } + + return Float2.Zero; + } } } diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index d6275e439..c18698890 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -180,40 +180,6 @@ namespace FlaxEditor.Surface } } - private Float2 GetBoxControlWidthHeight(Control control, Font boxLabelFont) - { - float boxWidth = 0; - float boxHeight = 0; - - if (control is InputBox inputBox) - { - boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 20; - if (inputBox.DefaultValueEditor != null) - boxWidth += inputBox.DefaultValueEditor.Width + 4; - boxHeight = inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f; - } - else if (control is OutputBox outputBox) - { - boxWidth = boxLabelFont.MeasureText(outputBox.Text).X + 20; - boxHeight = outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f; - } - else if (control is Control defaultControl) - { - if (defaultControl.AnchorPreset == AnchorPresets.TopLeft) - { - boxWidth = defaultControl.Right + 4 - Constants.NodeMarginX; - boxHeight = defaultControl.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize; - } - else - { - boxWidth = defaultControl.Width + 4; - boxHeight = defaultControl.Height + 4; - } - } - - return new Float2(boxWidth, boxHeight); - } - public ContainerControl HACK = null; private Float2 CompareAndGetNewCollisionSize(Rectangle rect1, Rectangle rect2, float collisionWidth, float collisionHeight) @@ -370,6 +336,39 @@ namespace FlaxEditor.Surface return color; } + private Float2 GetBoxControlWidthHeight(Control control, Font boxLabelFont) + { + float boxWidth = 0; + float boxHeight = 0; + + if (control is InputBox inputBox) + { + boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 24; + boxWidth += inputBox.GetValueEditorSize().X + 8; + boxHeight = inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f; + } + else if (control is OutputBox outputBox) + { + boxWidth = boxLabelFont.MeasureText(outputBox.Text).X + 24; + boxHeight = outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f; + } + else if (control is Control defaultControl) + { + if (defaultControl.AnchorPreset == AnchorPresets.TopLeft) + { + boxWidth = defaultControl.Right + 4 - Constants.NodeMarginX; + boxHeight = defaultControl.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize; + } + else + { + boxWidth = defaultControl.Width + 4; + boxHeight = defaultControl.Height + 4; + } + } + + return new Float2(boxWidth, boxHeight); + } + /// /// Automatically resizes the node to match the title size and all the elements for best fit of the node dimensions. /// @@ -414,11 +413,6 @@ namespace FlaxEditor.Surface height = Mathf.Max(height, boxSize.Y); } } - Debug.Log(Title); - Float2 collisionSize = CalculateCollisionSize(Children, boxLabelFont); - Debug.Log(collisionSize.ToString()); - //width += collisionSize.X; - //height += collisionSize.Y; width = Mathf.Max(width, leftWidth + rightWidth + 10); width = Mathf.Max(width, titleLabelFont.MeasureText(Title).X + 30); @@ -442,49 +436,10 @@ namespace FlaxEditor.Surface Parent = HACK }; - /*Rectangle testRect = Rectangle.Default; - testRect.Width = width; - testRect.Height = height; - testRect.Y += 10; // ra - new Panel - { - BackgroundColor = colliderColor, - Location = testRect.Location, - Size = testRect.Size, - Parent = HACK - };*/ - Float2 roundedSize = VisjectSurface.RoundToGrid(new Float2(width, height), ceil: true); - //Resize(roundedSize.X, roundedSize.Y); + Resize(roundedSize.X, roundedSize.Y); } - /* if (child is InputBox inputBox) -{ - var boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 20; - if (inputBox.DefaultValueEditor != null) - boxWidth += inputBox.DefaultValueEditor.Width + 4; - leftWidth = Mathf.Max(leftWidth, boxWidth); - leftHeight = Mathf.Max(leftHeight, inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f); -} -else if (child is OutputBox outputBox) -{ - rightWidth = Mathf.Max(rightWidth, boxLabelFont.MeasureText(outputBox.Text).X + 20); - rightHeight = Mathf.Max(rightHeight, outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f); -} -else if (child is Control control) -{ - if (control.AnchorPreset == AnchorPresets.TopLeft) - { - width = Mathf.Max(width, control.Right + 4 - Constants.NodeMarginX); - height = Mathf.Max(height, control.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize); - } - else - { - width = Mathf.Max(width, control.Width + 4); - height = Mathf.Max(height, control.Height + 4); - } -}*/ - /// /// Creates an element from the archetype and adds the element to the node. /// From 8ba1878657ad161aec5f9c80db6c25ac7efdf8b0 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Mon, 2 Oct 2023 00:18:16 -0400 Subject: [PATCH 16/24] Cleanup Logs. --- Source/Editor/Surface/SurfaceNode.cs | 176 --------------------------- 1 file changed, 176 deletions(-) diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index c18698890..763f82fdb 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -180,162 +180,6 @@ namespace FlaxEditor.Surface } } - public ContainerControl HACK = null; - - private Float2 CompareAndGetNewCollisionSize(Rectangle rect1, Rectangle rect2, float collisionWidth, float collisionHeight) - { - Rectangle sharedArea; - Rectangle.Shared(ref rect1, ref rect2, out sharedArea); - - Color colliderColor = Color.Chocolate; - colliderColor.A = 0.1f; - /*Panel colliderPanel = new Panel - { - BackgroundColor = colliderColor, - Location = sharedArea.Location, - Size = sharedArea.Size, - Parent = HACK - };*/ - - return new Float2(Mathf.Max(collisionWidth, sharedArea.Width + 4), Mathf.Max(collisionHeight, sharedArea.Height + 4)); - } - - private Float2 CalculateCollisionSize(List controls, Font boxLabelFont) - { - Debug.Log(string.Format("{0}:", Title)); - - List colliderRectangles = new List(); - int controlsCount = controls.Count; - for (int i = 0; i < controlsCount; i++) - { - var control = controls[i]; - if (!control.Visible || control is Panel panel) - continue; - - Debug.Log(string.Format("\t{0}:", control.GetType().ToString())); - Debug.Log(string.Format("\t\tControl Bounds: {0}", control.Bounds)); - /*Color colliderColor2 = Color.Crimson; - colliderColor2.A = 0.25f; - new Panel - { - BackgroundColor = colliderColor2, - Location = control.Bounds.Location, - Size = control.Bounds.Size, - Parent = HACK - }; - - if (control is InputBox inputBox2) - { - Rectangle textRect; - textRect.Size = boxLabelFont.MeasureText(inputBox2.Text); - textRect.Location = new Float2(control.Bounds.Location.X + 24, control.Bounds.Location.Y); - Debug.Log(string.Format("\t\tText Rectangle: {0}", textRect)); - - Color colliderColor3 = Color.ForestGreen; - colliderColor3.A = 0.25f; - new Panel - { - BackgroundColor = colliderColor3, - Location = textRect.Location, - Size = textRect.Size, - Parent = HACK - }; - } - - if (control is OutputBox outputBox2) - { - Rectangle textRect; - textRect.Size = boxLabelFont.MeasureText(outputBox2.Text); - textRect.Location = new Float2(control.Bounds.Location.X - textRect.Size.X - 2, control.Bounds.Location.Y); - Debug.Log(string.Format("\t\tText Rectangle: {0}", textRect)); - - Color colliderColor3 = Color.ForestGreen; - colliderColor3.A = 0.25f; - new Panel - { - BackgroundColor = colliderColor3, - Location = textRect.Location, - Size = textRect.Size, - Parent = HACK - }; - }*/ - - - - - - Float2 boxSize = GetBoxControlWidthHeight(control, boxLabelFont); - Float2 boxPosition = control.Location; - - // Special condition handling that is different than `GetBoxControlWidthHeight` - if (control is OutputBox outputBox) - { - boxPosition.X -= boxLabelFont.MeasureText(outputBox.Text).X; - boxSize.X = boxLabelFont.MeasureText(outputBox.Text).X + 20; - boxSize.Y = Mathf.Max(boxLabelFont.MeasureText(outputBox.Text).Y, outputBox.Height) + 4; - } else if (control is InputBox inputBox) - { - boxSize.X = boxLabelFont.MeasureText(inputBox.Text).X + 20; - boxSize.Y = Mathf.Max(boxLabelFont.MeasureText(inputBox.Text).Y, inputBox.Height) + 4; - } else - { - if (control.AnchorPreset == AnchorPresets.TopLeft) - { - boxSize.X = control.Right + 4 - Constants.NodeMarginX; - boxSize.Y = control.Bottom - control.Top + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize; - boxPosition.Y = control.Top; - } - else - { - boxSize.X = control.Width + 4; - boxSize.Y = control.Height + 4; - } - } - - Rectangle controlRect = new Rectangle(boxPosition.X, boxPosition.Y, boxSize.X, boxSize.Y); - colliderRectangles.Add(controlRect); - - Color colliderColor = Style.Current.BackgroundSelected; - colliderColor.A = 0.25f; - /*Panel colliderPanel = new Panel - { - BackgroundColor = colliderColor, - Location = controlRect.Location, - Size = controlRect.Size, - Parent = HACK - };*/ - } - - float collisionWidth = 0; - float collisionHeight = 0; - for (int i = 0; i < colliderRectangles.Count; i++) - { - for (int j = 0; j < colliderRectangles.Count; j++) - { - if (i == j) - { - continue; - } - - Rectangle rect1 = colliderRectangles[i]; - Rectangle rect2 = colliderRectangles[j]; - Float2 newCollisionSize = CompareAndGetNewCollisionSize(rect1, rect2, collisionWidth, collisionHeight); - - collisionWidth = newCollisionSize.X; - collisionHeight = newCollisionSize.Y; - } - } - - return new Float2(collisionWidth, collisionHeight); - } - - //HACK - private Color alphainator(Color color, float alpha) - { - color.A = alpha; - return color; - } - private Float2 GetBoxControlWidthHeight(Control control, Font boxLabelFont) { float boxWidth = 0; @@ -376,7 +220,6 @@ namespace FlaxEditor.Surface { if (Surface == null) return; - HACK = this; var width = 0.0f; var height = 0.0f; var leftHeight = 0.0f; @@ -417,25 +260,6 @@ namespace FlaxEditor.Surface width = Mathf.Max(width, leftWidth + rightWidth + 10); width = Mathf.Max(width, titleLabelFont.MeasureText(Title).X + 30); height = Mathf.Max(height, Mathf.Max(leftHeight, rightHeight)); - - new Panel - { - BackgroundColor = alphainator(Color.Azure, 0.25f), - Size = new Float2(leftWidth, height), - AnchorPreset = AnchorPresets.TopLeft, - Location = new Float2(4f, Constants.NodeHeaderSize + 4), - Parent = HACK - }; - - new Panel - { - BackgroundColor = alphainator(Color.Crimson, 0.25f), - Size = new Float2(rightWidth, height), - AnchorPreset = AnchorPresets.TopRight, - Location = new Float2(-4-rightWidth, Constants.NodeHeaderSize + 4), - Parent = HACK - }; - Float2 roundedSize = VisjectSurface.RoundToGrid(new Float2(width, height), ceil: true); Resize(roundedSize.X, roundedSize.Y); } From 8cf6134f8ba8f6d8fbad87959fb6ce9fd21d28b6 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Mon, 2 Oct 2023 00:34:14 -0400 Subject: [PATCH 17/24] Cleanup. --- Source/Editor/Surface/NodeArchetype.cs | 45 +------------------ Source/Editor/Surface/NodeElementArchetype.cs | 4 +- Source/Editor/Surface/SurfaceNode.cs | 8 ++-- Source/Editor/Surface/SurfaceUtils.cs | 4 +- Source/Editor/Surface/VisjectSurface.Input.cs | 2 +- .../Windows/Assets/VisualScriptWindow.cs | 2 +- 6 files changed, 10 insertions(+), 55 deletions(-) diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs index 4582aa054..b1a36ba0a 100644 --- a/Source/Editor/Surface/NodeArchetype.cs +++ b/Source/Editor/Surface/NodeArchetype.cs @@ -1,11 +1,8 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using System; -using System.Collections.Generic; -using System.Linq; using FlaxEditor.Scripting; using FlaxEngine; -using FlaxEngine.GUI; namespace FlaxEditor.Surface { @@ -181,50 +178,10 @@ namespace FlaxEditor.Surface /// public Func DependentBoxFilter; - private NodeElementArchetype[] _elements; /// /// Array with default elements descriptions. /// - public NodeElementArchetype[] Elements - { - get - { - return _elements; - } - set - { - _elements = value; - - /*Float2 topLeft = Float2.Zero; - Float2 bottomRight = Float2.Zero; - List textRectangles = new List(); - - foreach (NodeElementArchetype nodeElementType in _elements) - { - bool isInputElement = nodeElementType.Type == NodeElementType.Input; - bool isOutputElement = nodeElementType.Type == NodeElementType.Output; - if (isInputElement) - { - // Text will be to the right - } - - // In case of negatives.. most likely not needed. - topLeft.X = Math.Min(topLeft.X, nodeElementType.Position.X); - topLeft.Y = Math.Min(topLeft.Y, nodeElementType.Position.Y); - - bottomRight.X = Math.Max(bottomRight.X, nodeElementType.Position.X + nodeElementType.Size.X); - bottomRight.Y = Math.Max(bottomRight.Y, nodeElementType.Position.Y + nodeElementType.Size.Y); - } - - float paddingConst = 15; - - float sizeXElements = bottomRight.X - topLeft.X + paddingConst; - float sizeYElements = bottomRight.Y - topLeft.Y + paddingConst; - float titleSize = Style.Current.FontLarge.MeasureText(Title).X + paddingConst; - - Size = new Float2(Math.Max(sizeXElements, titleSize), sizeYElements);*/ - } - } + public NodeElementArchetype[] Elements; /// /// Tries to parse some text and extract the data from it. diff --git a/Source/Editor/Surface/NodeElementArchetype.cs b/Source/Editor/Surface/NodeElementArchetype.cs index 298127c3a..be8b67378 100644 --- a/Source/Editor/Surface/NodeElementArchetype.cs +++ b/Source/Editor/Surface/NodeElementArchetype.cs @@ -132,8 +132,8 @@ namespace FlaxEditor.Surface { Type = NodeElementType.Input, Position = new Float2( - Constants.NodeMarginX - Constants.BoxOffsetX, - Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY), + Constants.NodeMarginX - Constants.BoxOffsetX, + Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY), Text = text, Single = single, ValueIndex = valueIndex, diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 763f82fdb..67fd7a308 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -165,7 +165,7 @@ namespace FlaxEditor.Surface { if (Surface == null) return; - Size = CalculateNodeSize(width, height); + Size = CalculateNodeSize(width, height); // Update boxes on width change //if (!Mathf.NearEqual(prevSize.X, Size.X)) @@ -228,8 +228,7 @@ namespace FlaxEditor.Surface var rightWidth = 40.0f; var boxLabelFont = Style.Current.FontSmall; var titleLabelFont = Style.Current.FontLarge; - int childrenCount = Children.Count; - for (int i = 0; i < childrenCount; i++) + for (int i = 0; i < Children.Count; i++) { var child = Children[i]; if (child is Panel panel) @@ -342,8 +341,7 @@ namespace FlaxEditor.Surface if (element is Control control) AddChild(control); - if (!(element is Panel panel)) - ResizeAuto(); + ResizeAuto(); // Resize when an element is added to avoid hardcoded sizes. } /// diff --git a/Source/Editor/Surface/SurfaceUtils.cs b/Source/Editor/Surface/SurfaceUtils.cs index f5ca394fb..b8563220d 100644 --- a/Source/Editor/Surface/SurfaceUtils.cs +++ b/Source/Editor/Surface/SurfaceUtils.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. + // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using System; using System.Collections.Generic; @@ -13,8 +13,8 @@ using FlaxEditor.Utilities; using FlaxEngine.Utilities; using FlaxEngine; using FlaxEditor.GUI; -using FlaxEditor.Options; using FlaxEngine.GUI; +using FlaxEditor.Options; namespace FlaxEditor.Surface { diff --git a/Source/Editor/Surface/VisjectSurface.Input.cs b/Source/Editor/Surface/VisjectSurface.Input.cs index 0b664768d..a250d4df7 100644 --- a/Source/Editor/Surface/VisjectSurface.Input.cs +++ b/Source/Editor/Surface/VisjectSurface.Input.cs @@ -197,7 +197,7 @@ namespace FlaxEditor.Surface Float2 pointToRound = point; pointToRound.X = round(pointToRound.X); pointToRound.Y = round(pointToRound.Y); - + return pointToRound; } diff --git a/Source/Editor/Windows/Assets/VisualScriptWindow.cs b/Source/Editor/Windows/Assets/VisualScriptWindow.cs index 3b6480063..075c127d4 100644 --- a/Source/Editor/Windows/Assets/VisualScriptWindow.cs +++ b/Source/Editor/Windows/Assets/VisualScriptWindow.cs @@ -597,7 +597,7 @@ namespace FlaxEditor.Windows.Assets _propertiesEditor.Select(_properties); // Toolstrip - SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, + SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, Save, ShowWholeGraph, ToggleGridSnap, InputActions, out _saveButton, out _undoButton, out _redoButton, out _gridSnapButton); From 1b12ccd1801f49346db0078e05e1d08cca371b7c Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Mon, 2 Oct 2023 00:36:07 -0400 Subject: [PATCH 18/24] Remove extra spacing on copyright notice. --- Source/Editor/Surface/SurfaceUtils.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Surface/SurfaceUtils.cs b/Source/Editor/Surface/SurfaceUtils.cs index b8563220d..408baca57 100644 --- a/Source/Editor/Surface/SurfaceUtils.cs +++ b/Source/Editor/Surface/SurfaceUtils.cs @@ -1,4 +1,4 @@ - // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. +// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using System; using System.Collections.Generic; From 075da663442b940e1477ea47629a2080d657790d Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Tue, 10 Oct 2023 12:46:49 -0400 Subject: [PATCH 19/24] I am not a C# compiler. --- Source/Editor/Surface/SurfaceNode.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 4ed6078f7..f2d1a9b1c 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -248,12 +248,12 @@ namespace FlaxEditor.Surface } else { - if (control.AnchorPreset == AnchorPresets.TopLeft) + if (child.AnchorPreset == AnchorPresets.TopLeft) { width = Mathf.Max(width, boxSize.X); height = Mathf.Max(height, boxSize.Y); } - else if (!_headerRect.Intersects(control.Bounds)) + else if (!_headerRect.Intersects(child.Bounds)) { width = Mathf.Max(width, boxSize.X); height = Mathf.Max(height, boxSize.Y); From 6af9df79b2b98d2b84cbdc477d6d4f2d35061ab4 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Tue, 10 Oct 2023 19:11:45 -0400 Subject: [PATCH 20/24] Debug testing.. --- Source/Editor/Surface/SurfaceNode.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index f2d1a9b1c..4e27baf0e 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -187,11 +187,13 @@ namespace FlaxEditor.Surface boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 24; boxWidth += inputBox.GetValueEditorSize().X + 8; boxHeight = inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f; + Debug.Log($"InputBox {control.GetType().Name}: {boxWidth}, {boxHeight}"); } else if (control is OutputBox outputBox) { boxWidth = boxLabelFont.MeasureText(outputBox.Text).X + 24; boxHeight = outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f; + Debug.Log($"OutputBox {control.GetType().Name}: {boxWidth}, {boxHeight}"); } else if (control is Control defaultControl) { @@ -205,6 +207,10 @@ namespace FlaxEditor.Surface boxWidth = defaultControl.Width + 4; boxHeight = defaultControl.Height + 4; } + Debug.Log($"Control {control.GetType().Name}: {boxWidth}, {boxHeight}"); + } else + { + Debug.Log($"Control (filtered) {control.GetType().Name}: {boxWidth}, {boxHeight}"); } return new Float2(boxWidth, boxHeight); @@ -343,6 +349,7 @@ namespace FlaxEditor.Surface public void AddElement(ISurfaceNodeElement element) { Elements.Add(element); + Debug.Log($"Element: {element.Archetype.Type}"); if (element is Control control) AddChild(control); From 46e26e63efdf8f622c48ece1223bdf2deca76c1a Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Thu, 12 Oct 2023 13:54:03 -0400 Subject: [PATCH 21/24] Revert auto-resize feature to put in a different branch. --- Source/Editor/Surface/Archetypes/Bitwise.cs | 4 +- Source/Editor/Surface/Archetypes/Material.cs | 2 +- Source/Editor/Surface/SurfaceNode.cs | 79 ++++---------------- 3 files changed, 19 insertions(+), 66 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Bitwise.cs b/Source/Editor/Surface/Archetypes/Bitwise.cs index 058159d48..06f719adc 100644 --- a/Source/Editor/Surface/Archetypes/Bitwise.cs +++ b/Source/Editor/Surface/Archetypes/Bitwise.cs @@ -19,7 +19,7 @@ namespace FlaxEditor.Surface.Archetypes Description = desc, AlternativeTitles = altTitles, Flags = NodeFlags.AllGraphs, - Size = new Float2(160, 20), + Size = new Float2(140, 20), Elements = new[] { NodeElementArchetype.Factory.Input(0, "A", true, typeof(int), 0), @@ -37,7 +37,7 @@ namespace FlaxEditor.Surface.Archetypes Description = desc, AlternativeTitles = altTitles, Flags = NodeFlags.AllGraphs, - Size = new Float2(160, 40), + Size = new Float2(140, 40), DefaultValues = new object[] { 0, diff --git a/Source/Editor/Surface/Archetypes/Material.cs b/Source/Editor/Surface/Archetypes/Material.cs index 72a780858..b85d1c9d4 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -281,7 +281,7 @@ namespace FlaxEditor.Surface.Archetypes Title = "Material", Description = "Main material node", Flags = NodeFlags.MaterialGraph | NodeFlags.NoRemove | NodeFlags.NoSpawnViaGUI | NodeFlags.NoSpawnViaPaste | NodeFlags.NoCloseButton, - Size = new Float2(180, 300), + Size = new Float2(150, 300), Elements = new[] { NodeElementArchetype.Factory.Input(0, "", true, typeof(void), 0), diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 4e27baf0e..780ef81f0 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -177,45 +177,6 @@ namespace FlaxEditor.Surface Size = CalculateNodeSize(width, height); } - private Float2 GetBoxControlWidthHeight(Control control, Font boxLabelFont) - { - float boxWidth = 0; - float boxHeight = 0; - - if (control is InputBox inputBox) - { - boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 24; - boxWidth += inputBox.GetValueEditorSize().X + 8; - boxHeight = inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f; - Debug.Log($"InputBox {control.GetType().Name}: {boxWidth}, {boxHeight}"); - } - else if (control is OutputBox outputBox) - { - boxWidth = boxLabelFont.MeasureText(outputBox.Text).X + 24; - boxHeight = outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f; - Debug.Log($"OutputBox {control.GetType().Name}: {boxWidth}, {boxHeight}"); - } - else if (control is Control defaultControl) - { - if (defaultControl.AnchorPreset == AnchorPresets.TopLeft) - { - boxWidth = defaultControl.Right + 4 - Constants.NodeMarginX; - boxHeight = defaultControl.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize; - } - else - { - boxWidth = defaultControl.Width + 4; - boxHeight = defaultControl.Height + 4; - } - Debug.Log($"Control {control.GetType().Name}: {boxWidth}, {boxHeight}"); - } else - { - Debug.Log($"Control (filtered) {control.GetType().Name}: {boxWidth}, {boxHeight}"); - } - - return new Float2(boxWidth, boxHeight); - } - /// /// Automatically resizes the node to match the title size and all the elements for best fit of the node dimensions. /// @@ -234,44 +195,39 @@ namespace FlaxEditor.Surface for (int i = 0; i < Children.Count; i++) { var child = Children[i]; - if (child is Panel panel) - { - panel.Visible = false; - } if (!child.Visible) continue; - - Float2 boxSize = GetBoxControlWidthHeight(child, boxLabelFont); if (child is InputBox inputBox) { - leftWidth = Mathf.Max(leftWidth, boxSize.X); - leftHeight = Mathf.Max(leftHeight, boxSize.Y); + var boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 20; + if (inputBox.DefaultValueEditor != null) + boxWidth += inputBox.DefaultValueEditor.Width + 4; + leftWidth = Mathf.Max(leftWidth, boxWidth); + leftHeight = Mathf.Max(leftHeight, inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f); } else if (child is OutputBox outputBox) { - rightWidth = Mathf.Max(rightWidth, boxSize.X); - rightHeight = Mathf.Max(rightHeight, boxSize.Y); + rightWidth = Mathf.Max(rightWidth, boxLabelFont.MeasureText(outputBox.Text).X + 20); + rightHeight = Mathf.Max(rightHeight, outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f); } - else + else if (child is Control control) { - if (child.AnchorPreset == AnchorPresets.TopLeft) + if (control.AnchorPreset == AnchorPresets.TopLeft) { - width = Mathf.Max(width, boxSize.X); - height = Mathf.Max(height, boxSize.Y); + width = Mathf.Max(width, control.Right + 4 - Constants.NodeMarginX); + height = Mathf.Max(height, control.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize); } - else if (!_headerRect.Intersects(child.Bounds)) + else if (!_headerRect.Intersects(control.Bounds)) { - width = Mathf.Max(width, boxSize.X); - height = Mathf.Max(height, boxSize.Y); + width = Mathf.Max(width, control.Width + 4); + height = Mathf.Max(height, control.Height + 4); } } } - width = Mathf.Max(width, leftWidth + rightWidth + 10); width = Mathf.Max(width, titleLabelFont.MeasureText(Title).X + 30); height = Mathf.Max(height, Mathf.Max(leftHeight, rightHeight)); - Float2 roundedSize = VisjectSurface.RoundToGrid(new Float2(width, height), ceil: true); - Resize(roundedSize.X, roundedSize.Y); + Resize(width, height); } /// @@ -349,11 +305,8 @@ namespace FlaxEditor.Surface public void AddElement(ISurfaceNodeElement element) { Elements.Add(element); - Debug.Log($"Element: {element.Archetype.Type}"); if (element is Control control) AddChild(control); - - ResizeAuto(); // Resize when an element is added to avoid hardcoded sizes. } /// @@ -935,7 +888,7 @@ namespace FlaxEditor.Surface /// public override bool CanSelect(ref Float2 location) { - return _headerRect.MakeOffsetted(Location).Contains(ref location) || new Rectangle(Float2.Zero, Size).MakeOffsetted(Location).Contains(ref location); + return _headerRect.MakeOffsetted(Location).Contains(ref location); } /// From c9d7498bed0647e35ec5b50656baf7200942b7de Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Thu, 12 Oct 2023 13:57:38 -0400 Subject: [PATCH 22/24] Remove unneeded changes. --- Source/Editor/Surface/Elements/InputBox.cs | 30 ---------------------- 1 file changed, 30 deletions(-) diff --git a/Source/Editor/Surface/Elements/InputBox.cs b/Source/Editor/Surface/Elements/InputBox.cs index 5a9f33704..2047bcd1a 100644 --- a/Source/Editor/Surface/Elements/InputBox.cs +++ b/Source/Editor/Surface/Elements/InputBox.cs @@ -1652,35 +1652,5 @@ namespace FlaxEditor.Surface.Elements } } } - - /// - /// Get the size of the value editor for this box. - /// - /// The size of the value editor for this box. - public Float2 GetValueEditorSize() - { - if (!HasValue) - return Float2.Zero; - - if (_defaultValueEditor != null) - return _defaultValueEditor.Bounds.Size; - - for (int i = 0; i < DefaultValueEditors.Count; i++) - { - if (DefaultValueEditors[i].CanUse(this, ref _currentType)) - { - var bounds = new Rectangle(X + Width + 8 + Style.Current.FontSmall.MeasureText(Text).X, Y, 90, Height); - _editor = DefaultValueEditors[i]; - - // TODO: Find a better way to evaluate the size than using existing create code to resolve the size for each editor type. - var tempEditor = _editor.Create(this, ref bounds); - Float2 editorSize = tempEditor.Size; - tempEditor.Dispose(); - return editorSize; - } - } - - return Float2.Zero; - } } } From 96ba3832d6d75c801f046c9902f9724076b0e805 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Fri, 10 Nov 2023 10:53:14 -0500 Subject: [PATCH 23/24] Re-add change allowing you to drag anywhere on the node. --- Source/Editor/Surface/SurfaceNode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 780ef81f0..30ed4b1f3 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -888,7 +888,7 @@ namespace FlaxEditor.Surface /// public override bool CanSelect(ref Float2 location) { - return _headerRect.MakeOffsetted(Location).Contains(ref location); + return _headerRect.MakeOffsetted(Location).Contains(ref location) || new Rectangle(Float2.Zero, Size).MakeOffsetted(Location).Contains(ref location); ; } /// From c26a806a351324623e5b8d3311b1115f421b6767 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 11 Sep 2024 19:57:57 +0200 Subject: [PATCH 24/24] Code cleanup #1456 --- Source/Editor/Options/InterfaceOptions.cs | 14 ++++++ Source/Editor/Surface/NodeArchetype.cs | 13 +----- Source/Editor/Surface/SurfaceUtils.cs | 43 +++++++------------ Source/Editor/Surface/VisjectSurface.Input.cs | 40 +++++++---------- Source/Editor/Surface/VisjectSurface.cs | 19 ++++++-- Source/Editor/Surface/VisjectSurfaceWindow.cs | 30 ++++++------- .../Windows/Assets/AnimationGraphWindow.cs | 1 + .../Windows/Assets/BehaviorTreeWindow.cs | 12 +----- .../Editor/Windows/Assets/MaterialWindow.cs | 3 +- .../Windows/Assets/ParticleEmitterWindow.cs | 3 +- .../Assets/VisjectFunctionSurfaceWindow.cs | 10 +---- .../Windows/Assets/VisualScriptWindow.cs | 12 +----- Source/Engine/Core/Math/Float2.cs | 10 +++++ 13 files changed, 95 insertions(+), 115 deletions(-) diff --git a/Source/Editor/Options/InterfaceOptions.cs b/Source/Editor/Options/InterfaceOptions.cs index 8f786362d..f7cc7107a 100644 --- a/Source/Editor/Options/InterfaceOptions.cs +++ b/Source/Editor/Options/InterfaceOptions.cs @@ -382,6 +382,20 @@ namespace FlaxEditor.Options [EditorDisplay("Visject"), EditorOrder(550), Tooltip("Shows/hides the description panel in the visual scripting context menu.")] public bool VisualScriptingDescriptionPanel { get; set; } = true; + /// + /// Gets or sets the surface grid snapping option. + /// + [DefaultValue(false)] + [EditorDisplay("Visject", "Grid Snapping"), EditorOrder(551), Tooltip("Toggles grid snapping when moving nodes.")] + public bool SurfaceGridSnapping { get; set; } = false; + + /// + /// Gets or sets the surface grid snapping option. + /// + [DefaultValue(20.0f)] + [EditorDisplay("Visject", "Grid Snapping Size"), EditorOrder(551), Tooltip("Defines the size of the grid for nodes snapping."), VisibleIf(nameof(SurfaceGridSnapping))] + public float SurfaceGridSnappingSize { get; set; } = 20.0f; + private static FontAsset DefaultFont => FlaxEngine.Content.LoadAsyncInternal(EditorAssets.PrimaryFont); private static FontAsset ConsoleFont => FlaxEngine.Content.LoadAsyncInternal(EditorAssets.InconsolataRegularFont); diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs index 32d75c71c..609b7b5f7 100644 --- a/Source/Editor/Surface/NodeArchetype.cs +++ b/Source/Editor/Surface/NodeArchetype.cs @@ -109,7 +109,6 @@ namespace FlaxEditor.Surface /// public CreateCustomNodeFunc Create; - private Float2 _size; /// /// Function for asynchronously loaded nodes to check if input ports are compatible, for filtering. /// @@ -123,17 +122,7 @@ namespace FlaxEditor.Surface /// /// Default initial size of the node. /// - public Float2 Size - { - get - { - return _size; - } - set - { - _size = VisjectSurface.RoundToGrid(value, true); - } - } + public Float2 Size; /// /// Custom set of flags. diff --git a/Source/Editor/Surface/SurfaceUtils.cs b/Source/Editor/Surface/SurfaceUtils.cs index a6fc82d55..c1f966812 100644 --- a/Source/Editor/Surface/SurfaceUtils.cs +++ b/Source/Editor/Surface/SurfaceUtils.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Reflection; using System.Text; @@ -10,12 +9,9 @@ using FlaxEditor.CustomEditors; using FlaxEditor.CustomEditors.Elements; using FlaxEditor.Options; using FlaxEditor.Scripting; -using FlaxEditor.Utilities; using FlaxEngine.Utilities; using FlaxEngine; using FlaxEditor.GUI; -using FlaxEngine.GUI; -using FlaxEditor.Options; namespace FlaxEditor.Surface { @@ -560,41 +556,32 @@ namespace FlaxEditor.Surface return AreScriptTypesEqualInner(left, right) || AreScriptTypesEqualInner(right, left); } - // This might not be the greatest place to put this but I couldn't find anything better yet. - public static void VisjectCommonToolstripSetup(Editor editor, ToolStrip toolStrip, FlaxEditor.Undo undo, - Action save, Action showWholeGraph, Action toggleGridSnap, InputActionsContainer actionsContainer, - out ToolStripButton saveButton, out ToolStripButton undoButton, out ToolStripButton redoButton, out ToolStripButton gridSnapButton) + internal static void PerformCommonSetup(Windows.Assets.AssetEditorWindow window, ToolStrip toolStrip, VisjectSurface surface, + out ToolStripButton saveButton, out ToolStripButton undoButton, out ToolStripButton redoButton) { + var editor = window.Editor; + var interfaceOptions = editor.Options.Options.Interface; var inputOptions = editor.Options.Options.Input; + var undo = surface.Undo; // Toolstrip - saveButton = (ToolStripButton)toolStrip.AddButton(editor.Icons.Save64, save).LinkTooltip("Save"); + saveButton = (ToolStripButton)toolStrip.AddButton(editor.Icons.Save64, window.Save).LinkTooltip("Save"); toolStrip.AddSeparator(); undoButton = (ToolStripButton)toolStrip.AddButton(editor.Icons.Undo64, undo.PerformUndo).LinkTooltip($"Undo ({inputOptions.Undo})"); redoButton = (ToolStripButton)toolStrip.AddButton(editor.Icons.Redo64, undo.PerformRedo).LinkTooltip($"Redo ({inputOptions.Redo})"); toolStrip.AddSeparator(); toolStrip.AddButton(editor.Icons.Search64, editor.ContentFinding.ShowSearch).LinkTooltip($"Open content search tool ({inputOptions.Search})"); - toolStrip.AddButton(editor.Icons.CenterView64, showWholeGraph).LinkTooltip("Show whole graph"); - gridSnapButton = (ToolStripButton)toolStrip.AddButton(editor.Icons.Stop64, toggleGridSnap).LinkTooltip("Toggle grid snapping for nodes."); - gridSnapButton.BackgroundColor = Style.Current.Background; // Default color for grid snap button. + toolStrip.AddButton(editor.Icons.CenterView64, surface.ShowWholeGraph).LinkTooltip("Show whole graph"); + var gridSnapButton = toolStrip.AddButton(editor.Icons.Grid32, surface.ToggleGridSnapping); + gridSnapButton.LinkTooltip("Toggle grid snapping for nodes."); + gridSnapButton.AutoCheck = true; + gridSnapButton.Checked = surface.GridSnappingEnabled = interfaceOptions.SurfaceGridSnapping; + surface.GridSnappingSize = interfaceOptions.SurfaceGridSnappingSize; // Setup input actions - actionsContainer.Add(options => options.Undo, undo.PerformUndo); - actionsContainer.Add(options => options.Redo, undo.PerformRedo); - actionsContainer.Add(options => options.Search, editor.ContentFinding.ShowSearch); - } - - public static void ToggleSurfaceGridSnap(VisjectSurface surface, ToolStripButton gridSnapButton) - { - surface.GridSnappingEnabled = !surface.GridSnappingEnabled; - if (surface.GridSnappingEnabled) - { - gridSnapButton.BackgroundColor = Style.Current.BackgroundSelected; - } - else - { - gridSnapButton.BackgroundColor = Style.Current.Background; - } + window.InputActions.Add(options => options.Undo, undo.PerformUndo); + window.InputActions.Add(options => options.Redo, undo.PerformRedo); + window.InputActions.Add(options => options.Search, editor.ContentFinding.ShowSearch); } } } diff --git a/Source/Editor/Surface/VisjectSurface.Input.cs b/Source/Editor/Surface/VisjectSurface.Input.cs index c540a2bd1..416f0152e 100644 --- a/Source/Editor/Surface/VisjectSurface.Input.cs +++ b/Source/Editor/Surface/VisjectSurface.Input.cs @@ -192,26 +192,19 @@ namespace FlaxEditor.Surface } /// - /// Round a visject coordinate point to the grid. + /// Snaps a coordinate point to the grid. /// /// The point to be rounded. /// Round to ceiling instead? - /// - public static Float2 RoundToGrid(Float2 point, bool ceil = false) + /// Rounded coordinate. + public Float2 SnapToGrid(Float2 point, bool ceil = false) { - Func round = x => - { - double pointGridUnits = Math.Abs((double)x) / GridSize; - pointGridUnits = ceil ? Math.Ceiling(pointGridUnits) : Math.Floor(pointGridUnits); - - return (float)Math.CopySign(pointGridUnits * GridSize, x); - }; - - Float2 pointToRound = point; - pointToRound.X = round(pointToRound.X); - pointToRound.Y = round(pointToRound.Y); - - return pointToRound; + float gridSize = GridSnappingSize; + Float2 snapped = point.Absolute / gridSize; + snapped = ceil ? Float2.Ceil(snapped) : Float2.Floor(snapped); + snapped.X = (float)Math.CopySign(snapped.X * gridSize, point.X); + snapped.Y = (float)Math.CopySign(snapped.Y * gridSize, point.Y); + return snapped; } /// @@ -281,7 +274,8 @@ namespace FlaxEditor.Surface // Moving else if (_isMovingSelection) { - if (!GridSnappingEnabled) + var gridSnap = GridSnappingEnabled; + if (!gridSnap) _gridRoundingDelta = Float2.Zero; // Reset in case user toggled option between frames. // Calculate delta (apply view offset) @@ -291,25 +285,23 @@ namespace FlaxEditor.Surface var deltaLengthSquared = delta.LengthSquared; delta /= _targetScale; - if ((!GridSnappingEnabled || Math.Abs(delta.X) >= GridSize || (Math.Abs(delta.Y) >= GridSize)) + if ((!gridSnap || Mathf.Abs(delta.X) >= GridSnappingSize || (Mathf.Abs(delta.Y) >= GridSnappingSize)) && deltaLengthSquared > 0.01f) { - if (GridSnappingEnabled) + if (gridSnap) { Float2 unroundedDelta = delta; - - delta = RoundToGrid(unroundedDelta); + delta = SnapToGrid(unroundedDelta); _gridRoundingDelta = (unroundedDelta - delta) * _targetScale; // Standardize unit of the rounding delta, in case user zooms between node movements. } foreach (var node in _movingNodes) { - if (GridSnappingEnabled) + if (gridSnap) { Float2 unroundedLocation = node.Location; - node.Location = RoundToGrid(unroundedLocation); + node.Location = SnapToGrid(unroundedLocation); } - node.Location += delta; } diff --git a/Source/Editor/Surface/VisjectSurface.cs b/Source/Editor/Surface/VisjectSurface.cs index e4eb3269b..28ec17d53 100644 --- a/Source/Editor/Surface/VisjectSurface.cs +++ b/Source/Editor/Surface/VisjectSurface.cs @@ -34,18 +34,26 @@ namespace FlaxEditor.Surface /// /// Is grid snapping enabled for this surface? /// - public bool GridSnappingEnabled = false; + public bool GridSnappingEnabled + { + get => _gridSnappingEnabled; + set + { + _gridSnappingEnabled = value; + _gridRoundingDelta = Float2.Zero; + } + } /// /// The size of the snapping grid. /// - public static readonly float GridSize = 20f; + public float GridSnappingSize = 20f; private float _targetScale = 1.0f; private float _moveViewWithMouseDragSpeed = 1.0f; private bool _canEdit = true; private readonly bool _supportsDebugging; - private bool _isReleasing; + private bool _isReleasing, _gridSnappingEnabled; private VisjectCM _activeVisjectCM; private GroupArchetype _customNodesGroup; private List _customNodes; @@ -642,6 +650,11 @@ namespace FlaxEditor.Surface SelectionChanged?.Invoke(); } + internal void ToggleGridSnapping() + { + GridSnappingEnabled = !GridSnappingEnabled; + } + /// /// Selects all the nodes. /// diff --git a/Source/Editor/Surface/VisjectSurfaceWindow.cs b/Source/Editor/Surface/VisjectSurfaceWindow.cs index ec3db7a9d..16e4f303b 100644 --- a/Source/Editor/Surface/VisjectSurfaceWindow.cs +++ b/Source/Editor/Surface/VisjectSurfaceWindow.cs @@ -891,10 +891,21 @@ namespace FlaxEditor.Surface /// protected Tabs _tabs; - private readonly ToolStripButton _saveButton; - private readonly ToolStripButton _undoButton; - private readonly ToolStripButton _redoButton; - private readonly ToolStripButton _gridSnapButton; + /// + /// Save button on a toolstrip. + /// + protected ToolStripButton _saveButton; + + /// + /// Undo button on a toolstrip. + /// + protected ToolStripButton _undoButton; + + /// + /// Redo button on a toolstrip. + /// + protected ToolStripButton _redoButton; + private bool _showWholeGraphOnLoad = true; /// @@ -951,8 +962,6 @@ namespace FlaxEditor.Surface protected VisjectSurfaceWindow(Editor editor, AssetItem item, bool useTabs = false) : base(editor, item) { - var inputOptions = Editor.Options.Options.Input; - // Undo _undo = new FlaxEditor.Undo(); _undo.UndoDone += OnUndoRedo; @@ -999,10 +1008,6 @@ namespace FlaxEditor.Surface _propertiesEditor.Panel.Parent = _split2.Panel2; } _propertiesEditor.Modified += OnPropertyEdited; - - SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, - Save, ShowWholeGraph, ToggleGridSnap, InputActions, - out _saveButton, out _undoButton, out _redoButton, out _gridSnapButton); } private void OnUndoRedo(IUndoAction action) @@ -1041,11 +1046,6 @@ namespace FlaxEditor.Surface _surface.ShowWholeGraph(); } - private void ToggleGridSnap() - { - SurfaceUtils.ToggleSurfaceGridSnap(_surface, _gridSnapButton); - } - /// /// Refreshes temporary asset to see changes live when editing the surface. /// diff --git a/Source/Editor/Windows/Assets/AnimationGraphWindow.cs b/Source/Editor/Windows/Assets/AnimationGraphWindow.cs index e75becf72..1cf03f062 100644 --- a/Source/Editor/Windows/Assets/AnimationGraphWindow.cs +++ b/Source/Editor/Windows/Assets/AnimationGraphWindow.cs @@ -206,6 +206,7 @@ namespace FlaxEditor.Windows.Assets _surface.ContextChanged += OnSurfaceContextChanged; // Toolstrip + SurfaceUtils.PerformCommonSetup(this, _toolstrip, _surface, out _saveButton, out _undoButton, out _redoButton); _showNodesButton = (ToolStripButton)_toolstrip.AddButton(editor.Icons.Bone64, () => _preview.ShowNodes = !_preview.ShowNodes).LinkTooltip("Show animated model nodes debug view"); _toolstrip.AddSeparator(); _toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/animation/anim-graph/index.html")).LinkTooltip("See documentation to learn more"); diff --git a/Source/Editor/Windows/Assets/BehaviorTreeWindow.cs b/Source/Editor/Windows/Assets/BehaviorTreeWindow.cs index 47d6f2840..f4e7a4f6a 100644 --- a/Source/Editor/Windows/Assets/BehaviorTreeWindow.cs +++ b/Source/Editor/Windows/Assets/BehaviorTreeWindow.cs @@ -172,13 +172,8 @@ namespace FlaxEditor.Windows.Assets _knowledgePropertiesEditor.Panel.Parent = _split2.Panel2; // Toolstrip - _saveButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Save64, Save).LinkTooltip("Save"); + SurfaceUtils.PerformCommonSetup(this, _toolstrip, _surface, out _saveButton, out _undoButton, out _redoButton); _toolstrip.AddSeparator(); - _undoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Undo64, _undo.PerformUndo).LinkTooltip($"Undo ({inputOptions.Undo})"); - _redoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Redo64, _undo.PerformRedo).LinkTooltip($"Redo ({inputOptions.Redo})"); - _toolstrip.AddSeparator(); - _toolstrip.AddButton(Editor.Icons.Search64, Editor.ContentFinding.ShowSearch).LinkTooltip($"Open content search tool ({inputOptions.Search})"); - _toolstrip.AddButton(editor.Icons.CenterView64, _surface.ShowWholeGraph).LinkTooltip("Show whole graph"); _toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/scripting/ai/behavior-trees/index.html")).LinkTooltip("See documentation to learn more"); // Debug behavior picker @@ -206,11 +201,6 @@ namespace FlaxEditor.Windows.Assets _behaviorPicker.CheckValid = OnBehaviorPickerCheckValid; _behaviorPicker.ValueChanged += OnBehaviorPickerValueChanged; - // Setup input actions - InputActions.Add(options => options.Undo, _undo.PerformUndo); - InputActions.Add(options => options.Redo, _undo.PerformRedo); - InputActions.Add(options => options.Search, Editor.ContentFinding.ShowSearch); - SetCanEdit(!Editor.IsPlayMode); ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin; } diff --git a/Source/Editor/Windows/Assets/MaterialWindow.cs b/Source/Editor/Windows/Assets/MaterialWindow.cs index ef37fbe67..ad72c92d9 100644 --- a/Source/Editor/Windows/Assets/MaterialWindow.cs +++ b/Source/Editor/Windows/Assets/MaterialWindow.cs @@ -257,8 +257,9 @@ namespace FlaxEditor.Windows.Assets }; // Toolstrip - _toolstrip.AddSeparator(); + SurfaceUtils.PerformCommonSetup(this, _toolstrip, _surface, out _saveButton, out _undoButton, out _redoButton); _toolstrip.AddButton(editor.Icons.Code64, ShowSourceCode).LinkTooltip("Show generated shader source code"); + _toolstrip.AddSeparator(); _toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/graphics/materials/index.html")).LinkTooltip("See documentation to learn more"); } diff --git a/Source/Editor/Windows/Assets/ParticleEmitterWindow.cs b/Source/Editor/Windows/Assets/ParticleEmitterWindow.cs index 93dce7034..c373b4cdc 100644 --- a/Source/Editor/Windows/Assets/ParticleEmitterWindow.cs +++ b/Source/Editor/Windows/Assets/ParticleEmitterWindow.cs @@ -141,8 +141,9 @@ namespace FlaxEditor.Windows.Assets }; // Toolstrip - _toolstrip.AddSeparator(); + SurfaceUtils.PerformCommonSetup(this, _toolstrip, _surface, out _saveButton, out _undoButton, out _redoButton); _toolstrip.AddButton(editor.Icons.Code64, ShowSourceCode).LinkTooltip("Show generated shader source code"); + _toolstrip.AddSeparator(); _toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/particles/index.html")).LinkTooltip("See documentation to learn more"); } diff --git a/Source/Editor/Windows/Assets/VisjectFunctionSurfaceWindow.cs b/Source/Editor/Windows/Assets/VisjectFunctionSurfaceWindow.cs index 1cdd07611..24b3e3f9b 100644 --- a/Source/Editor/Windows/Assets/VisjectFunctionSurfaceWindow.cs +++ b/Source/Editor/Windows/Assets/VisjectFunctionSurfaceWindow.cs @@ -30,7 +30,6 @@ namespace FlaxEditor.Windows.Assets private readonly ToolStripButton _saveButton; private readonly ToolStripButton _undoButton; private readonly ToolStripButton _redoButton; - private readonly ToolStripButton _gridSnapButton; private bool _showWholeGraphOnLoad = true; /// @@ -71,9 +70,7 @@ namespace FlaxEditor.Windows.Assets _undo.ActionDone += OnUndoRedo; // Toolstrip - SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, - Save, ShowWholeGraph, ToggleGridSnap, InputActions, - out _saveButton, out _undoButton, out _redoButton, out _gridSnapButton); + SurfaceUtils.PerformCommonSetup(this, _toolstrip, _surface, out _saveButton, out _undoButton, out _redoButton); // Panel _panel = new Panel(ScrollBars.None) @@ -98,11 +95,6 @@ namespace FlaxEditor.Windows.Assets _surface.ShowWholeGraph(); } - private void ToggleGridSnap() - { - SurfaceUtils.ToggleSurfaceGridSnap(_surface, _gridSnapButton); - } - /// /// Refreshes temporary asset to see changes live when editing the surface. /// diff --git a/Source/Editor/Windows/Assets/VisualScriptWindow.cs b/Source/Editor/Windows/Assets/VisualScriptWindow.cs index 3f742e09d..b424ecffc 100644 --- a/Source/Editor/Windows/Assets/VisualScriptWindow.cs +++ b/Source/Editor/Windows/Assets/VisualScriptWindow.cs @@ -533,7 +533,6 @@ namespace FlaxEditor.Windows.Assets private readonly ToolStripButton _saveButton; private readonly ToolStripButton _undoButton; private readonly ToolStripButton _redoButton; - private readonly ToolStripButton _gridSnapButton; private Control[] _debugToolstripControls; private bool _showWholeGraphOnLoad = true; private bool _tmpAssetIsDirty; @@ -598,11 +597,7 @@ namespace FlaxEditor.Windows.Assets _propertiesEditor.Select(_properties); // Toolstrip - SurfaceUtils.VisjectCommonToolstripSetup(editor, _toolstrip, _undo, - Save, ShowWholeGraph, ToggleGridSnap, InputActions, - out _saveButton, out _undoButton, out _redoButton, out _gridSnapButton); - - // The rest of the toolstrip + SurfaceUtils.PerformCommonSetup(this, _toolstrip, _surface, out _saveButton, out _undoButton, out _redoButton); _toolstrip.AddSeparator(); _toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/scripting/visual/index.html")).LinkTooltip("See documentation to learn more"); _debugToolstripControls = new[] @@ -683,11 +678,6 @@ namespace FlaxEditor.Windows.Assets _surface.ShowWholeGraph(); } - private void ToggleGridSnap() - { - SurfaceUtils.ToggleSurfaceGridSnap(_surface, _gridSnapButton); - } - /// /// Refreshes temporary asset to see changes live when editing the surface. /// diff --git a/Source/Engine/Core/Math/Float2.cs b/Source/Engine/Core/Math/Float2.cs index adbe61508..92247d865 100644 --- a/Source/Engine/Core/Math/Float2.cs +++ b/Source/Engine/Core/Math/Float2.cs @@ -865,6 +865,16 @@ namespace FlaxEngine return new Float2(Mathf.Ceil(v.X), Mathf.Ceil(v.Y)); } + /// + /// Returns the vector with components containing the smallest integer smaller to or equal to the original value. + /// + /// The value. + /// The result. + public static Float2 Floor(Float2 v) + { + return new Float2(Mathf.Floor(v.X), Mathf.Floor(v.Y)); + } + /// /// Breaks the components of the vector into an integral and a fractional part. Returns vector made of fractional parts. ///