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.
///