From 07c1dfc61329a92fe8a52420da539bdcf9b20d5b Mon Sep 17 00:00:00 2001 From: Saas Date: Fri, 19 Sep 2025 20:23:47 +0200 Subject: [PATCH 1/3] add focus selected visject controls functionality --- Source/Editor/Options/InputOptions.cs | 4 +++ Source/Editor/Surface/VisjectSurface.Input.cs | 4 ++- Source/Editor/Surface/VisjectSurface.cs | 30 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Options/InputOptions.cs b/Source/Editor/Options/InputOptions.cs index af919c1f3..624daf890 100644 --- a/Source/Editor/Options/InputOptions.cs +++ b/Source/Editor/Options/InputOptions.cs @@ -694,6 +694,10 @@ namespace FlaxEditor.Options [EditorDisplay("Node Editors"), EditorOrder(4580)] public InputBinding NodesDistributeVertical = new InputBinding(KeyboardKeys.A, KeyboardKeys.Alt); + [DefaultValue(typeof(InputBinding), "Shift+F")] + [EditorDisplay("Node Editors"), EditorOrder(4590)] + public InputBinding FocusSelectedNodes = new InputBinding(KeyboardKeys.F, KeyboardKeys.Shift); + #endregion } } diff --git a/Source/Editor/Surface/VisjectSurface.Input.cs b/Source/Editor/Surface/VisjectSurface.Input.cs index 09df195eb..72594eb5f 100644 --- a/Source/Editor/Surface/VisjectSurface.Input.cs +++ b/Source/Editor/Surface/VisjectSurface.Input.cs @@ -29,6 +29,7 @@ namespace FlaxEditor.Surface private HashSet _movingNodes; private HashSet _temporarySelectedNodes; private readonly Stack _inputBrackets = new Stack(); + private InputBinding _focusSelectedNodeBinding; private class InputBracket { @@ -844,7 +845,8 @@ namespace FlaxEditor.Surface private void CurrentInputTextChanged(string currentInputText) { - if (string.IsNullOrEmpty(currentInputText)) + // Check if focus selected nodes binding is being pressed to prevent it triggering primary menu + if (string.IsNullOrEmpty(currentInputText) || _focusSelectedNodeBinding.Process(RootWindow)) return; if (IsPrimaryMenuOpened || !CanEdit) { diff --git a/Source/Editor/Surface/VisjectSurface.cs b/Source/Editor/Surface/VisjectSurface.cs index 8cbcb4a21..fb0d1f576 100644 --- a/Source/Editor/Surface/VisjectSurface.cs +++ b/Source/Editor/Surface/VisjectSurface.cs @@ -425,6 +425,7 @@ namespace FlaxEditor.Surface new InputActionsContainer.Binding(options => options.NodesAlignRight, () => { AlignNodes(SelectedNodes, NodeAlignmentType.Right); }), new InputActionsContainer.Binding(options => options.NodesDistributeHorizontal, () => { DistributeNodes(SelectedNodes, false); }), new InputActionsContainer.Binding(options => options.NodesDistributeVertical, () => { DistributeNodes(SelectedNodes, true); }), + new InputActionsContainer.Binding(options => options.FocusSelectedNodes, () => { ShowSelection(); }), }); Context.ControlSpawned += OnSurfaceControlSpawned; @@ -436,7 +437,10 @@ namespace FlaxEditor.Surface DragHandlers.Add(_dragAssets = new DragAssets(ValidateDragItem)); DragHandlers.Add(_dragParameters = new DragNames(SurfaceParameter.DragPrefix, ValidateDragParameter)); + OnEditorOptionsChanged(Editor.Instance.Options.Options); + ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin; + Editor.Instance.Options.OptionsChanged += OnEditorOptionsChanged; } private void OnScriptsReloadBegin() @@ -446,6 +450,11 @@ namespace FlaxEditor.Surface _cmPrimaryMenu = null; } + private void OnEditorOptionsChanged(EditorOptions options) + { + _focusSelectedNodeBinding = options.Input.FocusSelectedNodes; + } + /// /// Gets the display name of the connection type used in the surface. /// @@ -643,6 +652,26 @@ namespace FlaxEditor.Surface ViewCenterPosition = areaRect.Center; } + /// + /// Shows the selected controls by changing the view scale and the position. + /// + public void ShowSelection() + { + var selection = SelectedControls; + if (selection.Count == 0) + return; + + // Calculate the bounds of all selected controls + Rectangle bounds = selection[0].Bounds; + for (int i = 1; i < selection.Count; i++) + bounds = Rectangle.Union(bounds, selection[i].Bounds); + + // Add margin + bounds = bounds.MakeExpanded(250.0f); + + ShowArea(bounds); + } + /// /// Shows the given surface node by changing the view scale and the position and focuses the node. /// @@ -1066,6 +1095,7 @@ namespace FlaxEditor.Surface _cmPrimaryMenu?.Dispose(); ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin; + Editor.Instance.Options.OptionsChanged += OnEditorOptionsChanged; base.OnDestroy(); } From 1dd96ae9cbc219749f445ab551414150fbed25a7 Mon Sep 17 00:00:00 2001 From: Saas Date: Fri, 19 Sep 2025 23:04:43 +0200 Subject: [PATCH 2/3] add undo to MoveSelectedNodes (do TODO) --- Source/Editor/Surface/SurfaceUtils.cs | 10 +++++----- Source/Editor/Surface/VisjectSurface.Input.cs | 10 +++++++++- Source/Editor/Windows/Assets/AssetEditorWindow.cs | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Source/Editor/Surface/SurfaceUtils.cs b/Source/Editor/Surface/SurfaceUtils.cs index d75efb5a0..bf70ca2e9 100644 --- a/Source/Editor/Surface/SurfaceUtils.cs +++ b/Source/Editor/Surface/SurfaceUtils.cs @@ -573,13 +573,13 @@ namespace FlaxEditor.Surface var showSearch = () => editor.ContentFinding.ShowSearch(window); // Toolstrip - saveButton = toolStrip.AddButton(editor.Icons.Save64, window.Save).LinkTooltip("Save", ref inputOptions.Save); + saveButton = toolStrip.AddButton(editor.Icons.Save64, window.Save).LinkTooltip("Save.", ref inputOptions.Save); toolStrip.AddSeparator(); - undoButton = toolStrip.AddButton(editor.Icons.Undo64, undo.PerformUndo).LinkTooltip("Undo", ref inputOptions.Undo); - redoButton = toolStrip.AddButton(editor.Icons.Redo64, undo.PerformRedo).LinkTooltip("Redo", ref inputOptions.Redo); + undoButton = toolStrip.AddButton(editor.Icons.Undo64, undo.PerformUndo).LinkTooltip("Undo.", ref inputOptions.Undo); + redoButton = toolStrip.AddButton(editor.Icons.Redo64, undo.PerformRedo).LinkTooltip("Redo.", ref inputOptions.Redo); toolStrip.AddSeparator(); - toolStrip.AddButton(editor.Icons.Search64, showSearch).LinkTooltip("Open content search tool", ref inputOptions.Search); - toolStrip.AddButton(editor.Icons.CenterView64, surface.ShowWholeGraph).LinkTooltip("Show whole graph"); + toolStrip.AddButton(editor.Icons.Search64, showSearch).LinkTooltip("Open content search tool.", ref inputOptions.Search); + 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; diff --git a/Source/Editor/Surface/VisjectSurface.Input.cs b/Source/Editor/Surface/VisjectSurface.Input.cs index 72594eb5f..1ebd4fdee 100644 --- a/Source/Editor/Surface/VisjectSurface.Input.cs +++ b/Source/Editor/Surface/VisjectSurface.Input.cs @@ -702,13 +702,21 @@ namespace FlaxEditor.Surface private void MoveSelectedNodes(Float2 delta) { - // TODO: undo + List undoActions = new List(); + delta /= _targetScale; OnGetNodesToMove(); foreach (var node in _movingNodes) + { node.Location += delta; + if (Undo != null) + undoActions.Add(new MoveNodesAction(Context, new[] { node.ID }, delta)); + } _isMovingSelection = false; MarkAsEdited(false); + + if (undoActions.Count > 0) + Undo?.AddAction(new MultiUndoAction(undoActions, "Moved ")); } /// diff --git a/Source/Editor/Windows/Assets/AssetEditorWindow.cs b/Source/Editor/Windows/Assets/AssetEditorWindow.cs index 646112441..eeac84b60 100644 --- a/Source/Editor/Windows/Assets/AssetEditorWindow.cs +++ b/Source/Editor/Windows/Assets/AssetEditorWindow.cs @@ -53,7 +53,7 @@ namespace FlaxEditor.Windows.Assets { Parent = this }; - _toolstrip.AddButton(editor.Icons.Search64, () => Editor.Windows.ContentWin.Select(_item)).LinkTooltip("Show and select in Content Window"); + _toolstrip.AddButton(editor.Icons.Search64, () => Editor.Windows.ContentWin.Select(_item)).LinkTooltip("Show and select in Content Window."); InputActions.Add(options => options.Save, Save); From 2a21141dd48aa219d3f32949ccb857dd71b6c785 Mon Sep 17 00:00:00 2001 From: Saas Date: Mon, 9 Feb 2026 15:56:37 +0100 Subject: [PATCH 3/3] focus whole graph if no selection --- Source/Editor/Surface/VisjectSurface.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Surface/VisjectSurface.cs b/Source/Editor/Surface/VisjectSurface.cs index bb082aefe..a11f6710a 100644 --- a/Source/Editor/Surface/VisjectSurface.cs +++ b/Source/Editor/Surface/VisjectSurface.cs @@ -423,9 +423,9 @@ namespace FlaxEditor.Surface new InputActionsContainer.Binding(options => options.NodesAlignLeft, () => { AlignNodes(SelectedNodes, NodeAlignmentType.Left); }), new InputActionsContainer.Binding(options => options.NodesAlignCenter, () => { AlignNodes(SelectedNodes, NodeAlignmentType.Center); }), new InputActionsContainer.Binding(options => options.NodesAlignRight, () => { AlignNodes(SelectedNodes, NodeAlignmentType.Right); }), - new InputActionsContainer.Binding(options => options.NodesDistributeHorizontal, () => { DistributeNodes(SelectedNodes, false); }), - new InputActionsContainer.Binding(options => options.NodesDistributeVertical, () => { DistributeNodes(SelectedNodes, true); }), - new InputActionsContainer.Binding(options => options.FocusSelectedNodes, () => { ShowSelection(); }), + new InputActionsContainer.Binding(options => options.NodesDistributeHorizontal, () => { DistributeNodes(SelectedNodes, false); }), + new InputActionsContainer.Binding(options => options.NodesDistributeVertical, () => { DistributeNodes(SelectedNodes, true); }), + new InputActionsContainer.Binding(options => options.FocusSelectedNodes, () => { FocusSelectionOrWholeGraph(); }), }); Context.ControlSpawned += OnSurfaceControlSpawned; @@ -652,6 +652,17 @@ namespace FlaxEditor.Surface ViewCenterPosition = areaRect.Center; } + /// + /// Adjusts the view to focus on the currently selected nodes, or the entire graph if no nodes are selected. + /// + public void FocusSelectionOrWholeGraph() + { + if (SelectedNodes.Count > 0) + ShowSelection(); + else + ShowWholeGraph(); + } + /// /// Shows the selected controls by changing the view scale and the position. ///