From 642766d9cc1bcf1395549b0434c9f64c4863847d Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 26 Aug 2023 12:19:37 +0300 Subject: [PATCH 01/13] Add Editor input options for Play Current Scenes and running cooked game --- Source/Editor/GUI/ContextMenu/ContextMenu.cs | 19 +++++++++ Source/Editor/Modules/UIModule.cs | 44 ++++++++++++-------- Source/Editor/Options/InputOptions.cs | 18 ++++++-- Source/Editor/Windows/SceneEditorWindow.cs | 3 ++ 4 files changed, 63 insertions(+), 21 deletions(-) diff --git a/Source/Editor/GUI/ContextMenu/ContextMenu.cs b/Source/Editor/GUI/ContextMenu/ContextMenu.cs index f2e5d30e3..25f45a1f8 100644 --- a/Source/Editor/GUI/ContextMenu/ContextMenu.cs +++ b/Source/Editor/GUI/ContextMenu/ContextMenu.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; +using FlaxEditor.Options; using FlaxEngine; using FlaxEngine.GUI; @@ -269,6 +270,24 @@ namespace FlaxEditor.GUI.ContextMenu return item; } + /// + /// Adds the button. + /// + /// The text. + /// The input binding. + /// On button clicked event. + /// Created context menu item control. + public ContextMenuButton AddButton(string text, InputBinding binding, Action clicked) + { + var item = new ContextMenuButton(this, text, binding.ToString()) + { + Parent = _panel + }; + item.Clicked += clicked; + SortButtons(); + return item; + } + /// /// Gets the child menu (with that name). /// diff --git a/Source/Editor/Modules/UIModule.cs b/Source/Editor/Modules/UIModule.cs index 08ec09de8..9130797bf 100644 --- a/Source/Editor/Modules/UIModule.cs +++ b/Source/Editor/Modules/UIModule.cs @@ -62,6 +62,8 @@ namespace FlaxEditor.Modules private ContextMenuButton _menuGamePlayCurrentScenes; private ContextMenuButton _menuGameStop; private ContextMenuButton _menuGamePause; + private ContextMenuButton _menuGameCookAndRun; + private ContextMenuButton _menuGameRunCookedGame; private ContextMenuButton _menuToolsBuildScenes; private ContextMenuButton _menuToolsBakeLightmaps; private ContextMenuButton _menuToolsClearLightmaps; @@ -510,7 +512,7 @@ namespace FlaxEditor.Modules MenuFile = MainMenu.AddButton("File"); var cm = MenuFile.ContextMenu; cm.VisibleChanged += OnMenuFileShowHide; - _menuSaveAll = cm.AddButton("Save All", inputOptions.Save.ToString(), Editor.SaveAll); + _menuSaveAll = cm.AddButton("Save All", inputOptions.Save, Editor.SaveAll); _menuFileSaveScenes = cm.AddButton("Save scenes", Editor.Scene.SaveScenes); _menuFileCloseScenes = cm.AddButton("Close scenes", Editor.Scene.CloseAllScenes); cm.AddSeparator(); @@ -526,18 +528,18 @@ namespace FlaxEditor.Modules MenuEdit = MainMenu.AddButton("Edit"); cm = MenuEdit.ContextMenu; cm.VisibleChanged += OnMenuEditShowHide; - _menuEditUndo = cm.AddButton(string.Empty, inputOptions.Undo.ToString(), Editor.PerformUndo); - _menuEditRedo = cm.AddButton(string.Empty, inputOptions.Redo.ToString(), Editor.PerformRedo); + _menuEditUndo = cm.AddButton(string.Empty, inputOptions.Undo, Editor.PerformUndo); + _menuEditRedo = cm.AddButton(string.Empty, inputOptions.Redo, Editor.PerformRedo); cm.AddSeparator(); - _menuEditCut = cm.AddButton("Cut", inputOptions.Cut.ToString(), Editor.SceneEditing.Cut); - _menuEditCopy = cm.AddButton("Copy", inputOptions.Copy.ToString(), Editor.SceneEditing.Copy); - _menuEditPaste = cm.AddButton("Paste", inputOptions.Paste.ToString(), Editor.SceneEditing.Paste); + _menuEditCut = cm.AddButton("Cut", inputOptions.Cut, Editor.SceneEditing.Cut); + _menuEditCopy = cm.AddButton("Copy", inputOptions.Copy, Editor.SceneEditing.Copy); + _menuEditPaste = cm.AddButton("Paste", inputOptions.Paste, Editor.SceneEditing.Paste); cm.AddSeparator(); - _menuEditDelete = cm.AddButton("Delete", inputOptions.Delete.ToString(), Editor.SceneEditing.Delete); - _menuEditDuplicate = cm.AddButton("Duplicate", inputOptions.Duplicate.ToString(), Editor.SceneEditing.Duplicate); + _menuEditDelete = cm.AddButton("Delete", inputOptions.Delete, Editor.SceneEditing.Delete); + _menuEditDuplicate = cm.AddButton("Duplicate", inputOptions.Duplicate, Editor.SceneEditing.Duplicate); cm.AddSeparator(); - _menuEditSelectAll = cm.AddButton("Select all", inputOptions.SelectAll.ToString(), Editor.SceneEditing.SelectAllScenes); - _menuEditFind = cm.AddButton("Find", inputOptions.Search.ToString(), Editor.Windows.SceneWin.Search); + _menuEditSelectAll = cm.AddButton("Select all", inputOptions.SelectAll, Editor.SceneEditing.SelectAllScenes); + _menuEditFind = cm.AddButton("Find", inputOptions.Search, Editor.Windows.SceneWin.Search); // Scene MenuScene = MainMenu.AddButton("Scene"); @@ -555,18 +557,20 @@ namespace FlaxEditor.Modules cm = MenuGame.ContextMenu; cm.VisibleChanged += OnMenuGameShowHide; - _menuGamePlayGame = cm.AddButton("Play Game", Editor.Simulation.RequestPlayGameOrStopPlay); - _menuGamePlayCurrentScenes = cm.AddButton("Play Current Scenes", Editor.Simulation.RequestPlayScenesOrStopPlay); - _menuGameStop = cm.AddButton("Stop Game", Editor.Simulation.RequestStopPlay); - _menuGamePause = cm.AddButton("Pause", inputOptions.Pause.ToString(), Editor.Simulation.RequestPausePlay); + _menuGamePlayGame = cm.AddButton("Play Game", inputOptions.Play, Editor.Simulation.RequestPlayGameOrStopPlay); + _menuGamePlayCurrentScenes = cm.AddButton("Play Current Scenes", inputOptions.PlayCurrentScenes, Editor.Simulation.RequestPlayScenesOrStopPlay); + _menuGameStop = cm.AddButton("Stop Game", inputOptions.Play, Editor.Simulation.RequestStopPlay); + _menuGamePause = cm.AddButton("Pause", inputOptions.Pause, Editor.Simulation.RequestPausePlay); cm.AddSeparator(); var numberOfClientsMenu = cm.AddChildMenu("Number of game clients"); _numberOfClientsGroup.AddItemsToContextMenu(numberOfClientsMenu.ContextMenu); cm.AddSeparator(); - cm.AddButton("Cook & Run", Editor.Windows.GameCookerWin.BuildAndRun).LinkTooltip("Runs Game Cooker to build the game for this platform and runs the game after."); - cm.AddButton("Run cooked game", Editor.Windows.GameCookerWin.RunCooked).LinkTooltip("Runs the game build from the last cooking output. Use Cook&Play or Game Cooker first."); + _menuGameCookAndRun = cm.AddButton("Cook & Run", inputOptions.CookAndRun, Editor.Windows.GameCookerWin.BuildAndRun); + _menuGameCookAndRun.LinkTooltip("Runs Game Cooker to build the game for this platform and runs the game after."); + _menuGameRunCookedGame = cm.AddButton("Run cooked game", inputOptions.RunCookedGame, Editor.Windows.GameCookerWin.RunCooked); + _menuGameRunCookedGame.LinkTooltip("Runs the game build from the last cooking output. Use 'Cook & Run' or Game Cooker first."); // Tools MenuTools = MainMenu.AddButton("Tools"); @@ -642,8 +646,12 @@ namespace FlaxEditor.Modules _menuEditDuplicate.ShortKeys = inputOptions.Duplicate.ToString(); _menuEditSelectAll.ShortKeys = inputOptions.SelectAll.ToString(); _menuEditFind.ShortKeys = inputOptions.Search.ToString(); - _menuGamePlayCurrentScenes.ShortKeys = inputOptions.Play.ToString(); + _menuGamePlayGame.ShortKeys = inputOptions.Play.ToString(); + _menuGamePlayCurrentScenes.ShortKeys = inputOptions.PlayCurrentScenes.ToString(); _menuGamePause.ShortKeys = inputOptions.Pause.ToString(); + _menuGameStop.ShortKeys = inputOptions.Play.ToString(); + _menuGameCookAndRun.ShortKeys = inputOptions.CookAndRun.ToString(); + _menuGameRunCookedGame.ShortKeys = inputOptions.RunCookedGame.ToString(); MainMenuShortcutKeysUpdated?.Invoke(); } @@ -692,7 +700,7 @@ namespace FlaxEditor.Modules playActionGroup.SelectedChanged = SetPlayAction; Editor.Options.OptionsChanged += options => { playActionGroup.Selected = options.Interface.PlayButtonAction; }; - _toolStripPause = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Pause64, Editor.Simulation.RequestResumeOrPause).LinkTooltip($"Pause/Resume game({inputOptions.Pause})"); + _toolStripPause = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Pause64, Editor.Simulation.RequestResumeOrPause).LinkTooltip($"Pause/Resume game ({inputOptions.Pause})"); _toolStripStep = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Skip64, Editor.Simulation.RequestPlayOneFrame).LinkTooltip("Step one frame in game"); UpdateToolstrip(); diff --git a/Source/Editor/Options/InputOptions.cs b/Source/Editor/Options/InputOptions.cs index e0a51622b..9285532a1 100644 --- a/Source/Editor/Options/InputOptions.cs +++ b/Source/Editor/Options/InputOptions.cs @@ -85,17 +85,29 @@ namespace FlaxEditor.Options public InputBinding SnapToGround = new InputBinding(KeyboardKeys.End); [DefaultValue(typeof(InputBinding), "F5")] - [EditorDisplay("Scene"), EditorOrder(510)] + [EditorDisplay("Scene", "Play/Stop"), EditorOrder(510)] public InputBinding Play = new InputBinding(KeyboardKeys.F5); + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Scene", "Play Current Scenes/Stop"), EditorOrder(520)] + public InputBinding PlayCurrentScenes = new InputBinding(KeyboardKeys.None); + [DefaultValue(typeof(InputBinding), "F6")] - [EditorDisplay("Scene"), EditorOrder(520)] + [EditorDisplay("Scene"), EditorOrder(530)] public InputBinding Pause = new InputBinding(KeyboardKeys.F6); [DefaultValue(typeof(InputBinding), "F11")] - [EditorDisplay("Scene"), EditorOrder(530)] + [EditorDisplay("Scene"), EditorOrder(540)] public InputBinding StepFrame = new InputBinding(KeyboardKeys.F11); + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Scene", "Cook & Run"), EditorOrder(550)] + public InputBinding CookAndRun = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Scene", "Run cooked game"), EditorOrder(560)] + public InputBinding RunCookedGame = new InputBinding(KeyboardKeys.None); + #endregion #region Debugger diff --git a/Source/Editor/Windows/SceneEditorWindow.cs b/Source/Editor/Windows/SceneEditorWindow.cs index 72ff3be33..290f02089 100644 --- a/Source/Editor/Windows/SceneEditorWindow.cs +++ b/Source/Editor/Windows/SceneEditorWindow.cs @@ -39,8 +39,11 @@ namespace FlaxEditor.Windows InputActions.Add(options => options.Delete, Editor.SceneEditing.Delete); InputActions.Add(options => options.Search, () => Editor.Windows.SceneWin.Search()); InputActions.Add(options => options.Play, Editor.Simulation.DelegatePlayOrStopPlayInEditor); + InputActions.Add(options => options.PlayCurrentScenes, Editor.Simulation.RequestPlayScenesOrStopPlay); InputActions.Add(options => options.Pause, Editor.Simulation.RequestResumeOrPause); InputActions.Add(options => options.StepFrame, Editor.Simulation.RequestPlayOneFrame); + InputActions.Add(options => options.CookAndRun, () => Editor.Windows.GameCookerWin.BuildAndRun()); + InputActions.Add(options => options.RunCookedGame, () => Editor.Windows.GameCookerWin.RunCooked()); } } } From 61b4738b6ab0bea024dcaf6f35b0cc8f0b11b188 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 26 Aug 2023 13:05:00 +0300 Subject: [PATCH 02/13] Fix Editor bindings with no modifiers triggering with modifiers pressed --- Source/Editor/Options/InputBinding.cs | 81 ++++++++++++++++++--------- 1 file changed, 55 insertions(+), 26 deletions(-) diff --git a/Source/Editor/Options/InputBinding.cs b/Source/Editor/Options/InputBinding.cs index 2e18dab9e..2ee64275e 100644 --- a/Source/Editor/Options/InputBinding.cs +++ b/Source/Editor/Options/InputBinding.cs @@ -134,6 +134,57 @@ namespace FlaxEditor.Options return false; } + private bool ProcessModifiers(Control control) + { + var root = control.Root; + bool ctrlPressed = root.GetKey(KeyboardKeys.Control); + bool shiftPressed = root.GetKey(KeyboardKeys.Shift); + bool altPressed = root.GetKey(KeyboardKeys.Alt); + + bool mod1 = false; + if (Modifier1 == KeyboardKeys.None) + mod1 = true; + else if (Modifier1 == KeyboardKeys.Control) + { + mod1 = ctrlPressed; + ctrlPressed = false; + } + else if (Modifier1 == KeyboardKeys.Shift) + { + mod1 = shiftPressed; + shiftPressed = false; + } + else if (Modifier1 == KeyboardKeys.Alt) + { + mod1 = altPressed; + altPressed = false; + } + + bool mod2 = false; + if (Modifier2 == KeyboardKeys.None) + mod2 = true; + else if (Modifier2 == KeyboardKeys.Control) + { + mod2 = ctrlPressed; + ctrlPressed = false; + } + else if (Modifier2 == KeyboardKeys.Shift) + { + mod2 = shiftPressed; + shiftPressed = false; + } + else if (Modifier2 == KeyboardKeys.Alt) + { + mod2 = altPressed; + altPressed = false; + } + + // Check if any unhandled modifiers are not pressed + if (mod1 && mod2) + return !ctrlPressed && !shiftPressed && !altPressed; + return false; + } + /// /// Processes this input binding to check if state matches. /// @@ -142,19 +193,7 @@ namespace FlaxEditor.Options public bool Process(Control control) { var root = control.Root; - - if (root.GetKey(Key)) - { - if (Modifier1 == KeyboardKeys.None || root.GetKey(Modifier1)) - { - if (Modifier2 == KeyboardKeys.None || root.GetKey(Modifier2)) - { - return true; - } - } - } - - return false; + return root.GetKey(Key) && ProcessModifiers(control); } /// @@ -165,20 +204,10 @@ namespace FlaxEditor.Options /// True if input has been processed, otherwise false. public bool Process(Control control, KeyboardKeys key) { - var root = control.Root; + if (key != Key) + return false; - if (key == Key) - { - if (Modifier1 == KeyboardKeys.None || root.GetKey(Modifier1)) - { - if (Modifier2 == KeyboardKeys.None || root.GetKey(Modifier2)) - { - return true; - } - } - } - - return false; + return ProcessModifiers(control); } /// From 17e1afb04a9dd7f7d2e93e9ec337c0bce71fca9e Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Thu, 14 Sep 2023 19:48:27 +0300 Subject: [PATCH 03/13] Add Editor input option for toggling gizmo transform space --- Source/Editor/Options/InputOptions.cs | 4 ++++ Source/Editor/Viewport/MainEditorGizmoViewport.cs | 1 + Source/Editor/Viewport/PrefabWindowViewport.cs | 1 + 3 files changed, 6 insertions(+) diff --git a/Source/Editor/Options/InputOptions.cs b/Source/Editor/Options/InputOptions.cs index 9285532a1..a294fbf50 100644 --- a/Source/Editor/Options/InputOptions.cs +++ b/Source/Editor/Options/InputOptions.cs @@ -144,6 +144,10 @@ namespace FlaxEditor.Options [EditorDisplay("Gizmo"), EditorOrder(1020)] public InputBinding ScaleMode = new InputBinding(KeyboardKeys.Alpha3); + [DefaultValue(typeof(InputBinding), "Alpha4")] + [EditorDisplay("Gizmo"), EditorOrder(1030)] + public InputBinding ToggleTransformSpace = new InputBinding(KeyboardKeys.Alpha4); + #endregion #region Viewport diff --git a/Source/Editor/Viewport/MainEditorGizmoViewport.cs b/Source/Editor/Viewport/MainEditorGizmoViewport.cs index 9cbfce562..2c8ec8504 100644 --- a/Source/Editor/Viewport/MainEditorGizmoViewport.cs +++ b/Source/Editor/Viewport/MainEditorGizmoViewport.cs @@ -390,6 +390,7 @@ namespace FlaxEditor.Viewport InputActions.Add(options => options.TranslateMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Translate); InputActions.Add(options => options.RotateMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Rotate); InputActions.Add(options => options.ScaleMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale); + InputActions.Add(options => options.ToggleTransformSpace, () => { OnTransformSpaceToggle(transformSpaceToggle); transformSpaceToggle.Checked = !transformSpaceToggle.Checked; }); InputActions.Add(options => options.LockFocusSelection, LockFocusSelection); InputActions.Add(options => options.FocusSelection, FocusSelection); InputActions.Add(options => options.RotateSelection, RotateSelection); diff --git a/Source/Editor/Viewport/PrefabWindowViewport.cs b/Source/Editor/Viewport/PrefabWindowViewport.cs index ec6a983ce..a9fe4766f 100644 --- a/Source/Editor/Viewport/PrefabWindowViewport.cs +++ b/Source/Editor/Viewport/PrefabWindowViewport.cs @@ -233,6 +233,7 @@ namespace FlaxEditor.Viewport InputActions.Add(options => options.TranslateMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Translate); InputActions.Add(options => options.RotateMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Rotate); InputActions.Add(options => options.ScaleMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale); + InputActions.Add(options => options.ToggleTransformSpace, () => { OnTransformSpaceToggle(transformSpaceToggle); transformSpaceToggle.Checked = !transformSpaceToggle.Checked; }); InputActions.Add(options => options.FocusSelection, ShowSelectedActors); SetUpdate(ref _update, OnUpdate); From 964913013db6fd85fe9ce936f72499b201a9a2ad Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Thu, 14 Sep 2023 19:48:55 +0300 Subject: [PATCH 04/13] Add shortcut key to gizmo buttons --- Source/Editor/Viewport/MainEditorGizmoViewport.cs | 9 +++++---- Source/Editor/Viewport/PrefabWindowViewport.cs | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Source/Editor/Viewport/MainEditorGizmoViewport.cs b/Source/Editor/Viewport/MainEditorGizmoViewport.cs index 2c8ec8504..6c52ce46b 100644 --- a/Source/Editor/Viewport/MainEditorGizmoViewport.cs +++ b/Source/Editor/Viewport/MainEditorGizmoViewport.cs @@ -194,6 +194,7 @@ namespace FlaxEditor.Viewport { _editor = editor; _dragAssets = new DragAssets(ValidateDragItem); + var inputOptions = editor.Options.Options.Input; // Prepare rendering task Task.ActorsSource = ActorsSources.Scenes; @@ -250,7 +251,7 @@ namespace FlaxEditor.Viewport var transformSpaceToggle = new ViewportWidgetButton(string.Empty, editor.Icons.Globe32, null, true) { Checked = TransformGizmo.ActiveTransformSpace == TransformGizmoBase.TransformSpace.World, - TooltipText = "Gizmo transform space (world or local)", + TooltipText = $"Gizmo transform space (world or local) ({inputOptions.ToggleTransformSpace})", Parent = transformSpaceWidget }; transformSpaceToggle.Toggled += OnTransformSpaceToggle; @@ -347,7 +348,7 @@ namespace FlaxEditor.Viewport _gizmoModeTranslate = new ViewportWidgetButton(string.Empty, editor.Icons.Translate32, null, true) { Tag = TransformGizmoBase.Mode.Translate, - TooltipText = "Translate gizmo mode", + TooltipText = $"Translate gizmo mode ({inputOptions.TranslateMode})", Checked = true, Parent = gizmoMode }; @@ -355,14 +356,14 @@ namespace FlaxEditor.Viewport _gizmoModeRotate = new ViewportWidgetButton(string.Empty, editor.Icons.Rotate32, null, true) { Tag = TransformGizmoBase.Mode.Rotate, - TooltipText = "Rotate gizmo mode", + TooltipText = $"Rotate gizmo mode ({inputOptions.RotateMode})", Parent = gizmoMode }; _gizmoModeRotate.Toggled += OnGizmoModeToggle; _gizmoModeScale = new ViewportWidgetButton(string.Empty, editor.Icons.Scale32, null, true) { Tag = TransformGizmoBase.Mode.Scale, - TooltipText = "Scale gizmo mode", + TooltipText = $"Scale gizmo mode ({inputOptions.ScaleMode})", Parent = gizmoMode }; _gizmoModeScale.Toggled += OnGizmoModeToggle; diff --git a/Source/Editor/Viewport/PrefabWindowViewport.cs b/Source/Editor/Viewport/PrefabWindowViewport.cs index a9fe4766f..c02d6b6e8 100644 --- a/Source/Editor/Viewport/PrefabWindowViewport.cs +++ b/Source/Editor/Viewport/PrefabWindowViewport.cs @@ -84,6 +84,7 @@ namespace FlaxEditor.Viewport _dragAssets = new DragAssets(ValidateDragItem); ShowDebugDraw = true; ShowEditorPrimitives = true; + var inputOptions = window.Editor.Options.Options.Input; // Prepare rendering task Task.ActorsSource = ActorsSources.CustomActors; @@ -113,7 +114,7 @@ namespace FlaxEditor.Viewport var transformSpaceToggle = new ViewportWidgetButton(string.Empty, window.Editor.Icons.Globe32, null, true) { Checked = TransformGizmo.ActiveTransformSpace == TransformGizmoBase.TransformSpace.World, - TooltipText = "Gizmo transform space (world or local)", + TooltipText = $"Gizmo transform space (world or local) ({inputOptions.ToggleTransformSpace})", Parent = transformSpaceWidget }; transformSpaceToggle.Toggled += OnTransformSpaceToggle; @@ -205,7 +206,7 @@ namespace FlaxEditor.Viewport _gizmoModeTranslate = new ViewportWidgetButton(string.Empty, window.Editor.Icons.Translate32, null, true) { Tag = TransformGizmoBase.Mode.Translate, - TooltipText = "Translate gizmo mode", + TooltipText = $"Translate gizmo mode ({inputOptions.TranslateMode})", Checked = true, Parent = gizmoMode }; @@ -213,14 +214,14 @@ namespace FlaxEditor.Viewport _gizmoModeRotate = new ViewportWidgetButton(string.Empty, window.Editor.Icons.Rotate32, null, true) { Tag = TransformGizmoBase.Mode.Rotate, - TooltipText = "Rotate gizmo mode", + TooltipText = $"Rotate gizmo mode ({inputOptions.RotateMode})", Parent = gizmoMode }; _gizmoModeRotate.Toggled += OnGizmoModeToggle; _gizmoModeScale = new ViewportWidgetButton(string.Empty, window.Editor.Icons.Scale32, null, true) { Tag = TransformGizmoBase.Mode.Scale, - TooltipText = "Scale gizmo mode", + TooltipText = $"Scale gizmo mode ({inputOptions.ScaleMode})", Parent = gizmoMode }; _gizmoModeScale.Toggled += OnGizmoModeToggle; From 69ce189c5d8f71c0cd563bb97b068541e8bb48ea Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 16 Sep 2023 19:52:58 +0300 Subject: [PATCH 05/13] Add input bindings for Scene viewport related actions and Pilot Actor --- Source/Editor/Modules/UIModule.cs | 8 ++++---- Source/Editor/Options/InputOptions.cs | 16 ++++++++++++++++ .../Windows/SceneTreeWindow.ContextMenu.cs | 15 ++++++++------- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Source/Editor/Modules/UIModule.cs b/Source/Editor/Modules/UIModule.cs index 9130797bf..d54012cc3 100644 --- a/Source/Editor/Modules/UIModule.cs +++ b/Source/Editor/Modules/UIModule.cs @@ -545,10 +545,10 @@ namespace FlaxEditor.Modules MenuScene = MainMenu.AddButton("Scene"); cm = MenuScene.ContextMenu; cm.VisibleChanged += OnMenuSceneShowHide; - _menuSceneMoveActorToViewport = cm.AddButton("Move actor to viewport", MoveActorToViewport); - _menuSceneAlignActorWithViewport = cm.AddButton("Align actor with viewport", AlignActorWithViewport); - _menuSceneAlignViewportWithActor = cm.AddButton("Align viewport with actor", AlignViewportWithActor); - _menuScenePilotActor = cm.AddButton("Pilot actor", PilotActor); + _menuSceneMoveActorToViewport = cm.AddButton("Move actor to viewport", inputOptions.MoveActorToViewport, MoveActorToViewport); + _menuSceneAlignActorWithViewport = cm.AddButton("Align actor with viewport", inputOptions.AlignActorWithViewport, AlignActorWithViewport); + _menuSceneAlignViewportWithActor = cm.AddButton("Align viewport with actor", inputOptions.AlignViewportWithActor, AlignViewportWithActor); + _menuScenePilotActor = cm.AddButton("Pilot actor", inputOptions.PilotActor, PilotActor); cm.AddSeparator(); _menuSceneCreateTerrain = cm.AddButton("Create terrain", CreateTerrain); diff --git a/Source/Editor/Options/InputOptions.cs b/Source/Editor/Options/InputOptions.cs index a294fbf50..9559e9142 100644 --- a/Source/Editor/Options/InputOptions.cs +++ b/Source/Editor/Options/InputOptions.cs @@ -108,6 +108,22 @@ namespace FlaxEditor.Options [EditorDisplay("Scene", "Run cooked game"), EditorOrder(560)] public InputBinding RunCookedGame = new InputBinding(KeyboardKeys.None); + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Scene", "Move actor to viewport"), EditorOrder(570)] + public InputBinding MoveActorToViewport = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Scene", "Align actor with viewport"), EditorOrder(571)] + public InputBinding AlignActorWithViewport = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Scene", "Align viewport with actor"), EditorOrder(572)] + public InputBinding AlignViewportWithActor = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Scene"), EditorOrder(573)] + public InputBinding PilotActor = new InputBinding(KeyboardKeys.None); + #endregion #region Debugger diff --git a/Source/Editor/Windows/SceneTreeWindow.ContextMenu.cs b/Source/Editor/Windows/SceneTreeWindow.ContextMenu.cs index e48e59f80..63d110368 100644 --- a/Source/Editor/Windows/SceneTreeWindow.ContextMenu.cs +++ b/Source/Editor/Windows/SceneTreeWindow.ContextMenu.cs @@ -26,6 +26,7 @@ namespace FlaxEditor.Windows bool hasSthSelected = Editor.SceneEditing.HasSthSelected; bool isSingleActorSelected = Editor.SceneEditing.SelectionCount == 1 && Editor.SceneEditing.Selection[0] is ActorNode; bool canEditScene = Editor.StateMachine.CurrentState.CanEditScene && Level.IsAnySceneLoaded; + var inputOptions = Editor.Options.Options.Input; // Create popup @@ -44,17 +45,17 @@ namespace FlaxEditor.Windows if (hasSthSelected) { - contextMenu.AddButton(Editor.Windows.EditWin.IsPilotActorActive ? "Stop piloting actor" : "Pilot actor", Editor.UI.PilotActor); + contextMenu.AddButton(Editor.Windows.EditWin.IsPilotActorActive ? "Stop piloting actor" : "Pilot actor", inputOptions.PilotActor, Editor.UI.PilotActor); } contextMenu.AddSeparator(); // Basic editing options - b = contextMenu.AddButton("Rename", Rename); + b = contextMenu.AddButton("Rename", inputOptions.Rename, Rename); b.Enabled = isSingleActorSelected; - b = contextMenu.AddButton("Duplicate", Editor.SceneEditing.Duplicate); + b = contextMenu.AddButton("Duplicate", inputOptions.Duplicate, Editor.SceneEditing.Duplicate); b.Enabled = hasSthSelected; if (isSingleActorSelected) @@ -116,17 +117,17 @@ namespace FlaxEditor.Windows } } } - b = contextMenu.AddButton("Delete", Editor.SceneEditing.Delete); + b = contextMenu.AddButton("Delete", inputOptions.Delete, Editor.SceneEditing.Delete); b.Enabled = hasSthSelected; contextMenu.AddSeparator(); - b = contextMenu.AddButton("Copy", Editor.SceneEditing.Copy); + b = contextMenu.AddButton("Copy", inputOptions.Copy, Editor.SceneEditing.Copy); b.Enabled = hasSthSelected; - contextMenu.AddButton("Paste", Editor.SceneEditing.Paste); + contextMenu.AddButton("Paste", inputOptions.Paste, Editor.SceneEditing.Paste); - b = contextMenu.AddButton("Cut", Editor.SceneEditing.Cut); + b = contextMenu.AddButton("Cut", inputOptions.Cut, Editor.SceneEditing.Cut); b.Enabled = canEditScene; // Prefab options From 0122a9f699c50787906e1b706088ec1aed3982f6 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 16 Sep 2023 22:39:04 +0300 Subject: [PATCH 06/13] Implement viewport camera rotation toggle for trackpad users --- Source/Editor/Options/InputBinding.cs | 27 +++++++++++++++++--- Source/Editor/Options/InputOptions.cs | 4 +++ Source/Editor/Viewport/EditorViewport.cs | 32 ++++++++++++++++-------- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/Source/Editor/Options/InputBinding.cs b/Source/Editor/Options/InputBinding.cs index 2ee64275e..eb61c0f68 100644 --- a/Source/Editor/Options/InputBinding.cs +++ b/Source/Editor/Options/InputBinding.cs @@ -136,10 +136,19 @@ namespace FlaxEditor.Options private bool ProcessModifiers(Control control) { - var root = control.Root; - bool ctrlPressed = root.GetKey(KeyboardKeys.Control); - bool shiftPressed = root.GetKey(KeyboardKeys.Shift); - bool altPressed = root.GetKey(KeyboardKeys.Alt); + return ProcessModifiers(control.Root.GetKey); + } + + private bool ProcessModifiers(Window window) + { + return ProcessModifiers(window.GetKey); + } + + private bool ProcessModifiers(Func getKeyFunc) + { + bool ctrlPressed = getKeyFunc(KeyboardKeys.Control); + bool shiftPressed = getKeyFunc(KeyboardKeys.Shift); + bool altPressed = getKeyFunc(KeyboardKeys.Alt); bool mod1 = false; if (Modifier1 == KeyboardKeys.None) @@ -210,6 +219,16 @@ namespace FlaxEditor.Options return ProcessModifiers(control); } + /// + /// Processes this input binding to check if state matches. + /// + /// The input providing window. + /// True if input has been processed, otherwise false. + public bool Process(Window window) + { + return window.GetKey(Key) && ProcessModifiers(window); + } + /// public override string ToString() { diff --git a/Source/Editor/Options/InputOptions.cs b/Source/Editor/Options/InputOptions.cs index 9559e9142..1ad7907cd 100644 --- a/Source/Editor/Options/InputOptions.cs +++ b/Source/Editor/Options/InputOptions.cs @@ -192,6 +192,10 @@ namespace FlaxEditor.Options [EditorDisplay("Viewport"), EditorOrder(1550)] public InputBinding Down = new InputBinding(KeyboardKeys.Q); + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Viewport", "Toggle Camera Rotation"), EditorOrder(1560)] + public InputBinding CameraToggleRotation = new InputBinding(KeyboardKeys.None); + [DefaultValue(typeof(InputBinding), "Numpad0")] [EditorDisplay("Viewport"), EditorOrder(1600)] public InputBinding ViewpointFront = new InputBinding(KeyboardKeys.Numpad0); diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index ad7e06ba5..928922108 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -137,7 +137,7 @@ namespace FlaxEditor.Viewport // Input - private bool _isControllingMouse, _isViewportControllingMouse; + private bool _isControllingMouse, _isViewportControllingMouse, _wasVirtualMouseRightDown, _isVirtualMouseRightDown; private int _deltaFilteringStep; private Float2 _startPos; private Float2 _mouseDeltaLast; @@ -685,6 +685,7 @@ namespace FlaxEditor.Viewport InputActions.Add(options => options.ViewpointBack, () => OrientViewport(Quaternion.Euler(EditorViewportCameraViewpointValues.First(vp => vp.Name == "Back").Orientation))); InputActions.Add(options => options.ViewpointRight, () => OrientViewport(Quaternion.Euler(EditorViewportCameraViewpointValues.First(vp => vp.Name == "Right").Orientation))); InputActions.Add(options => options.ViewpointLeft, () => OrientViewport(Quaternion.Euler(EditorViewportCameraViewpointValues.First(vp => vp.Name == "Left").Orientation))); + InputActions.Add(options => options.CameraToggleRotation, () => _isVirtualMouseRightDown = !_isVirtualMouseRightDown); // Link for task event task.Begin += OnRenderBegin; @@ -1048,6 +1049,15 @@ namespace FlaxEditor.Viewport // Track controlling mouse state change bool wasControllingMouse = _prevInput.IsControllingMouse; _isControllingMouse = _input.IsControllingMouse; + + // Simulate holding mouse right down for trackpad users + if (_prevInput.IsMouseRightDown && !_input.IsMouseRightDown) + _isVirtualMouseRightDown = false; + if (_wasVirtualMouseRightDown) + wasControllingMouse = true; + if (_isVirtualMouseRightDown) + _isControllingMouse = _isVirtualMouseRightDown; + if (wasControllingMouse != _isControllingMouse) { if (_isControllingMouse) @@ -1061,16 +1071,18 @@ namespace FlaxEditor.Viewport OnLeftMouseButtonDown(); else if (_prevInput.IsMouseLeftDown && !_input.IsMouseLeftDown) OnLeftMouseButtonUp(); - // - if (!_prevInput.IsMouseRightDown && _input.IsMouseRightDown) + + if ((!_prevInput.IsMouseRightDown && _input.IsMouseRightDown) || (!_wasVirtualMouseRightDown && _isVirtualMouseRightDown)) OnRightMouseButtonDown(); - else if (_prevInput.IsMouseRightDown && !_input.IsMouseRightDown) + else if ((_prevInput.IsMouseRightDown && !_input.IsMouseRightDown) || (_wasVirtualMouseRightDown && !_isVirtualMouseRightDown)) OnRightMouseButtonUp(); - // + if (!_prevInput.IsMouseMiddleDown && _input.IsMouseMiddleDown) OnMiddleMouseButtonDown(); else if (_prevInput.IsMouseMiddleDown && !_input.IsMouseMiddleDown) OnMiddleMouseButtonUp(); + + _wasVirtualMouseRightDown = _isVirtualMouseRightDown; } // Get clamped delta time (more stable during lags) @@ -1088,7 +1100,7 @@ namespace FlaxEditor.Viewport bool isAltDown = _input.IsAltDown; bool lbDown = _input.IsMouseLeftDown; bool mbDown = _input.IsMouseMiddleDown; - bool rbDown = _input.IsMouseRightDown; + bool rbDown = _input.IsMouseRightDown || _isVirtualMouseRightDown; bool wheelInUse = Math.Abs(_input.MouseWheelDelta) > Mathf.Epsilon; _input.IsPanning = !isAltDown && mbDown && !rbDown; @@ -1098,7 +1110,7 @@ namespace FlaxEditor.Viewport _input.IsOrbiting = isAltDown && lbDown && !mbDown && !rbDown; // Control move speed with RMB+Wheel - rmbWheel = useMovementSpeed && _input.IsMouseRightDown && wheelInUse; + rmbWheel = useMovementSpeed && (_input.IsMouseRightDown || _isVirtualMouseRightDown) && wheelInUse; if (rmbWheel) { float step = 4.0f; @@ -1165,7 +1177,7 @@ namespace FlaxEditor.Viewport // Calculate smooth mouse delta not dependant on viewport size var offset = _viewMousePos - _startPos; - if (_input.IsZooming && !_input.IsMouseRightDown && !_input.IsMouseLeftDown && !_input.IsMouseMiddleDown && !_isOrtho && !rmbWheel) + if (_input.IsZooming && !_input.IsMouseRightDown && !_input.IsMouseLeftDown && !_input.IsMouseMiddleDown && !_isOrtho && !rmbWheel && !_isVirtualMouseRightDown) { offset = Float2.Zero; } @@ -1213,7 +1225,7 @@ namespace FlaxEditor.Viewport UpdateView(dt, ref moveDelta, ref mouseDelta, out var centerMouse); // Move mouse back to the root position - if (centerMouse && (_input.IsMouseRightDown || _input.IsMouseLeftDown || _input.IsMouseMiddleDown)) + if (centerMouse && (_input.IsMouseRightDown || _input.IsMouseLeftDown || _input.IsMouseMiddleDown || _isVirtualMouseRightDown)) { var center = PointToWindow(_startPos); win.MousePosition = center; @@ -1229,7 +1241,7 @@ namespace FlaxEditor.Viewport } else { - if (_input.IsMouseLeftDown || _input.IsMouseRightDown) + if (_input.IsMouseLeftDown || _input.IsMouseRightDown || _isVirtualMouseRightDown) { // Calculate smooth mouse delta not dependant on viewport size var offset = _viewMousePos - _startPos; From 2023aa8c94db72848f77095be90c5f3b317acc53 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 16 Sep 2023 23:16:17 +0300 Subject: [PATCH 07/13] Add viewport camera movement speed adjustment input bindings --- Source/Editor/Options/InputOptions.cs | 20 ++++++--- Source/Editor/Viewport/EditorViewport.cs | 52 +++++++++++++++--------- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/Source/Editor/Options/InputOptions.cs b/Source/Editor/Options/InputOptions.cs index 1ad7907cd..27faf48a2 100644 --- a/Source/Editor/Options/InputOptions.cs +++ b/Source/Editor/Options/InputOptions.cs @@ -196,28 +196,36 @@ namespace FlaxEditor.Options [EditorDisplay("Viewport", "Toggle Camera Rotation"), EditorOrder(1560)] public InputBinding CameraToggleRotation = new InputBinding(KeyboardKeys.None); + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Viewport", "Increase Camera Move Speed"), EditorOrder(1570)] + public InputBinding CameraIncreaseMoveSpeed = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Viewport", "Decrease Camera Move Speed"), EditorOrder(1571)] + public InputBinding CameraDecreaseMoveSpeed = new InputBinding(KeyboardKeys.None); + [DefaultValue(typeof(InputBinding), "Numpad0")] - [EditorDisplay("Viewport"), EditorOrder(1600)] + [EditorDisplay("Viewport"), EditorOrder(1700)] public InputBinding ViewpointFront = new InputBinding(KeyboardKeys.Numpad0); [DefaultValue(typeof(InputBinding), "Numpad5")] - [EditorDisplay("Viewport"), EditorOrder(1610)] + [EditorDisplay("Viewport"), EditorOrder(1710)] public InputBinding ViewpointBack = new InputBinding(KeyboardKeys.Numpad5); [DefaultValue(typeof(InputBinding), "Numpad4")] - [EditorDisplay("Viewport"), EditorOrder(1620)] + [EditorDisplay("Viewport"), EditorOrder(1720)] public InputBinding ViewpointLeft = new InputBinding(KeyboardKeys.Numpad4); [DefaultValue(typeof(InputBinding), "Numpad6")] - [EditorDisplay("Viewport"), EditorOrder(1630)] + [EditorDisplay("Viewport"), EditorOrder(1730)] public InputBinding ViewpointRight = new InputBinding(KeyboardKeys.Numpad6); [DefaultValue(typeof(InputBinding), "Numpad8")] - [EditorDisplay("Viewport"), EditorOrder(1640)] + [EditorDisplay("Viewport"), EditorOrder(1740)] public InputBinding ViewpointTop = new InputBinding(KeyboardKeys.Numpad8); [DefaultValue(typeof(InputBinding), "Numpad2")] - [EditorDisplay("Viewport"), EditorOrder(1650)] + [EditorDisplay("Viewport"), EditorOrder(1750)] public InputBinding ViewpointBottom = new InputBinding(KeyboardKeys.Numpad2); #endregion diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index 928922108..9ecd7107b 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -686,6 +686,8 @@ namespace FlaxEditor.Viewport InputActions.Add(options => options.ViewpointRight, () => OrientViewport(Quaternion.Euler(EditorViewportCameraViewpointValues.First(vp => vp.Name == "Right").Orientation))); InputActions.Add(options => options.ViewpointLeft, () => OrientViewport(Quaternion.Euler(EditorViewportCameraViewpointValues.First(vp => vp.Name == "Left").Orientation))); InputActions.Add(options => options.CameraToggleRotation, () => _isVirtualMouseRightDown = !_isVirtualMouseRightDown); + InputActions.Add(options => options.CameraIncreaseMoveSpeed, () => AdjustCameraMoveSpeed(1)); + InputActions.Add(options => options.CameraDecreaseMoveSpeed, () => AdjustCameraMoveSpeed(-1)); // Link for task event task.Begin += OnRenderBegin; @@ -723,6 +725,30 @@ namespace FlaxEditor.Viewport } } + /// + /// Increases or decreases the camera movement speed. + /// + /// The stepping direction for speed adjustment. + protected void AdjustCameraMoveSpeed(int step) + { + int camValueIndex = -1; + for (int i = 0; i < EditorViewportCameraSpeedValues.Length; i++) + { + if (Mathf.NearEqual(EditorViewportCameraSpeedValues[i], _movementSpeed)) + { + camValueIndex = i; + break; + } + } + if (camValueIndex == -1) + return; + + if (step > 0) + MovementSpeed = EditorViewportCameraSpeedValues[Mathf.Min(camValueIndex + 1, EditorViewportCameraSpeedValues.Length - 1)]; + else if (step < 0) + MovementSpeed = EditorViewportCameraSpeedValues[Mathf.Max(camValueIndex - 1, 0)]; + } + private void OnEditorOptionsChanged(EditorOptions options) { _mouseSensitivity = options.Viewport.MouseSensitivity; @@ -1113,29 +1139,17 @@ namespace FlaxEditor.Viewport rmbWheel = useMovementSpeed && (_input.IsMouseRightDown || _isVirtualMouseRightDown) && wheelInUse; if (rmbWheel) { - float step = 4.0f; + const float step = 4.0f; _wheelMovementChangeDeltaSum += _input.MouseWheelDelta * options.Viewport.MouseWheelSensitivity; - int camValueIndex = -1; - for (int i = 0; i < EditorViewportCameraSpeedValues.Length; i++) + if (_wheelMovementChangeDeltaSum >= step) { - if (Mathf.NearEqual(EditorViewportCameraSpeedValues[i], _movementSpeed)) - { - camValueIndex = i; - break; - } + _wheelMovementChangeDeltaSum -= step; + AdjustCameraMoveSpeed(1); } - if (camValueIndex != -1) + else if (_wheelMovementChangeDeltaSum <= -step) { - if (_wheelMovementChangeDeltaSum >= step) - { - _wheelMovementChangeDeltaSum -= step; - MovementSpeed = EditorViewportCameraSpeedValues[Mathf.Min(camValueIndex + 1, EditorViewportCameraSpeedValues.Length - 1)]; - } - else if (_wheelMovementChangeDeltaSum <= -step) - { - _wheelMovementChangeDeltaSum += step; - MovementSpeed = EditorViewportCameraSpeedValues[Mathf.Max(camValueIndex - 1, 0)]; - } + _wheelMovementChangeDeltaSum += step; + AdjustCameraMoveSpeed(-1); } } } From efbc757369cc6f5e7029b0db58ffda628a6a6073 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 16 Sep 2023 23:23:50 +0300 Subject: [PATCH 08/13] Cancel camera rotation toggle when entering playmode or hitting escape --- Source/Editor/Viewport/EditorViewport.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index 9ecd7107b..34dbe561c 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -1077,8 +1077,8 @@ namespace FlaxEditor.Viewport _isControllingMouse = _input.IsControllingMouse; // Simulate holding mouse right down for trackpad users - if (_prevInput.IsMouseRightDown && !_input.IsMouseRightDown) - _isVirtualMouseRightDown = false; + if ((_prevInput.IsMouseRightDown && !_input.IsMouseRightDown) || win.GetKeyDown(KeyboardKeys.Escape)) + _isVirtualMouseRightDown = false; // Cancel when mouse right or escape is pressed if (_wasVirtualMouseRightDown) wasControllingMouse = true; if (_isVirtualMouseRightDown) @@ -1385,6 +1385,7 @@ namespace FlaxEditor.Viewport { OnControlMouseEnd(RootWindow.Window); _isControllingMouse = false; + _isVirtualMouseRightDown = false; } } From 8ed57863b88761022d38b6354e59ac507d56c17d Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sun, 17 Sep 2023 00:14:18 +0300 Subject: [PATCH 09/13] Add Editor input bindings for Tools menu items --- Source/Editor/Editor.cs | 65 +++++++++++++++++ Source/Editor/Modules/UIModule.cs | 84 ++++++---------------- Source/Editor/Options/InputOptions.cs | 44 ++++++++++-- Source/Editor/Windows/SceneEditorWindow.cs | 8 +++ 4 files changed, 134 insertions(+), 67 deletions(-) diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs index 7f0359331..06a6f0979 100644 --- a/Source/Editor/Editor.cs +++ b/Source/Editor/Editor.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; @@ -13,6 +14,7 @@ using FlaxEditor.Content.Thumbnails; using FlaxEditor.Modules; using FlaxEditor.Modules.SourceCodeEditing; using FlaxEditor.Options; +using FlaxEditor.SceneGraph.Actors; using FlaxEditor.States; using FlaxEditor.Windows; using FlaxEditor.Windows.Assets; @@ -1274,6 +1276,69 @@ namespace FlaxEditor Scene.MarkSceneEdited(scenes); } + /// + /// Bakes all environmental probes in the scene. + /// + public void BakeAllEnvProbes() + { + Scene.ExecuteOnGraph(node => + { + if (node is EnvironmentProbeNode envProbeNode && envProbeNode.IsActive) + { + ((EnvironmentProbe)envProbeNode.Actor).Bake(); + node.ParentScene.IsEdited = true; + } + else if (node is SkyLightNode skyLightNode && skyLightNode.IsActive && skyLightNode.Actor is SkyLight skyLight && skyLight.Mode == SkyLight.Modes.CaptureScene) + { + skyLight.Bake(); + node.ParentScene.IsEdited = true; + } + + return node.IsActive; + }); + } + + /// + /// Builds CSG for all open scenes. + /// + public void BuildCSG() + { + var scenes = Level.Scenes; + scenes.ToList().ForEach(x => x.BuildCSG(0)); + Scene.MarkSceneEdited(scenes); + } + + /// + /// Builds Nav mesh for all open scenes. + /// + public void BuildNavMesh() + { + var scenes = Level.Scenes; + scenes.ToList().ForEach(x => Navigation.BuildNavMesh(x, 0)); + Scene.MarkSceneEdited(scenes); + } + + /// + /// Builds SDF for all static models in the scene. + /// + public void BuildAllMeshesSDF() + { + // TODO: async maybe with progress reporting? + Scene.ExecuteOnGraph(node => + { + if (node is StaticModelNode staticModelNode && staticModelNode.Actor is StaticModel staticModel) + { + if (staticModel.DrawModes.HasFlag(DrawPass.GlobalSDF) && staticModel.Model != null && !staticModel.Model.IsVirtual && staticModel.Model.SDF.Texture == null) + { + Log("Generating SDF for " + staticModel.Model); + if (!staticModel.Model.GenerateSDF()) + staticModel.Model.Save(); + } + } + return true; + }); + } + #endregion #region Internal Calls diff --git a/Source/Editor/Modules/UIModule.cs b/Source/Editor/Modules/UIModule.cs index d54012cc3..bde2e610a 100644 --- a/Source/Editor/Modules/UIModule.cs +++ b/Source/Editor/Modules/UIModule.cs @@ -70,9 +70,10 @@ namespace FlaxEditor.Modules private ContextMenuButton _menuToolsBakeAllEnvProbes; private ContextMenuButton _menuToolsBuildCSGMesh; private ContextMenuButton _menuToolsBuildNavMesh; - private ContextMenuButton _menuToolsBuildAllMesgesSDF; + private ContextMenuButton _menuToolsBuildAllMeshesSDF; private ContextMenuButton _menuToolsCancelBuilding; private ContextMenuButton _menuToolsSetTheCurrentSceneViewAsDefault; + private ContextMenuButton _menuToolsTakeScreenshot; private ContextMenuChildMenu _menuWindowApplyWindowLayout; private ToolStripButton _toolStripSaveAll; @@ -576,14 +577,14 @@ namespace FlaxEditor.Modules MenuTools = MainMenu.AddButton("Tools"); cm = MenuTools.ContextMenu; cm.VisibleChanged += OnMenuToolsShowHide; - _menuToolsBuildScenes = cm.AddButton("Build scenes data", "Ctrl+F10", Editor.BuildScenesOrCancel); + _menuToolsBuildScenes = cm.AddButton("Build scenes data", inputOptions.BuildScenesData, Editor.BuildScenesOrCancel); cm.AddSeparator(); - _menuToolsBakeLightmaps = cm.AddButton("Bake lightmaps", Editor.BakeLightmapsOrCancel); - _menuToolsClearLightmaps = cm.AddButton("Clear lightmaps data", Editor.ClearLightmaps); - _menuToolsBakeAllEnvProbes = cm.AddButton("Bake all env probes", BakeAllEnvProbes); - _menuToolsBuildCSGMesh = cm.AddButton("Build CSG mesh", BuildCSG); - _menuToolsBuildNavMesh = cm.AddButton("Build Nav Mesh", BuildNavMesh); - _menuToolsBuildAllMesgesSDF = cm.AddButton("Build all meshes SDF", BuildAllMeshesSDF); + _menuToolsBakeLightmaps = cm.AddButton("Bake lightmaps", inputOptions.BakeLightmaps, Editor.BakeLightmapsOrCancel); + _menuToolsClearLightmaps = cm.AddButton("Clear lightmaps data", inputOptions.ClearLightmaps, Editor.ClearLightmaps); + _menuToolsBakeAllEnvProbes = cm.AddButton("Bake all env probes", inputOptions.BakeEnvProbes, Editor.BakeAllEnvProbes); + _menuToolsBuildCSGMesh = cm.AddButton("Build CSG mesh", inputOptions.BuildCSG, Editor.BuildCSG); + _menuToolsBuildNavMesh = cm.AddButton("Build Nav Mesh", inputOptions.BuildNav, Editor.BuildNavMesh); + _menuToolsBuildAllMeshesSDF = cm.AddButton("Build all meshes SDF", inputOptions.BuildSDF, Editor.BuildAllMeshesSDF); cm.AddSeparator(); cm.AddButton("Game Cooker", Editor.Windows.GameCookerWin.FocusOrShow); _menuToolsCancelBuilding = cm.AddButton("Cancel building game", () => GameCooker.Cancel()); @@ -591,7 +592,7 @@ namespace FlaxEditor.Modules cm.AddButton("Profiler", Editor.Windows.ProfilerWin.FocusOrShow); cm.AddSeparator(); _menuToolsSetTheCurrentSceneViewAsDefault = cm.AddButton("Set current scene view as project default", SetTheCurrentSceneViewAsDefault); - cm.AddButton("Take screenshot", "F12", Editor.Windows.TakeScreenshot); + _menuToolsTakeScreenshot = cm.AddButton("Take screenshot", inputOptions.TakeScreenshot, Editor.Windows.TakeScreenshot); cm.AddSeparator(); cm.AddButton("Plugins", () => Editor.Windows.PluginsWin.Show()); cm.AddButton("Options", () => Editor.Windows.EditorOptionsWin.Show()); @@ -652,6 +653,14 @@ namespace FlaxEditor.Modules _menuGameStop.ShortKeys = inputOptions.Play.ToString(); _menuGameCookAndRun.ShortKeys = inputOptions.CookAndRun.ToString(); _menuGameRunCookedGame.ShortKeys = inputOptions.RunCookedGame.ToString(); + _menuToolsBuildScenes.ShortKeys = inputOptions.BuildScenesData.ToString(); + _menuToolsBakeLightmaps.ShortKeys = inputOptions.BakeLightmaps.ToString(); + _menuToolsClearLightmaps.ShortKeys = inputOptions.ClearLightmaps.ToString(); + _menuToolsBakeAllEnvProbes.ShortKeys = inputOptions.BakeEnvProbes.ToString(); + _menuToolsBuildCSGMesh.ShortKeys = inputOptions.BuildCSG.ToString(); + _menuToolsBuildNavMesh.ShortKeys = inputOptions.BuildNav.ToString(); + _menuToolsBuildAllMeshesSDF.ShortKeys = inputOptions.BuildSDF.ToString(); + _menuToolsTakeScreenshot.ShortKeys = inputOptions.TakeScreenshot.ToString(); MainMenuShortcutKeysUpdated?.Invoke(); } @@ -676,10 +685,10 @@ namespace FlaxEditor.Modules ToolStrip.AddSeparator(); // Cook scenes - _toolStripBuildScenes = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Build64, Editor.BuildScenesOrCancel).LinkTooltip("Build scenes data - CSG, navmesh, static lighting, env probes - configurable via Build Actions in editor options (Ctrl+F10)"); + _toolStripBuildScenes = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Build64, Editor.BuildScenesOrCancel).LinkTooltip($"Build scenes data - CSG, navmesh, static lighting, env probes - configurable via Build Actions in editor options ({inputOptions.BuildScenesData})"); // Cook and run - _toolStripCook = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.ShipIt64, Editor.Windows.GameCookerWin.BuildAndRun).LinkTooltip("Cook & Run - build game for the current platform and run it locally"); + _toolStripCook = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.ShipIt64, Editor.Windows.GameCookerWin.BuildAndRun).LinkTooltip($"Cook & Run - build game for the current platform and run it locally ({inputOptions.Play})"); _toolStripCook.ContextMenu = new ContextMenu(); _toolStripCook.ContextMenu.AddButton("Run cooked game", Editor.Windows.GameCookerWin.RunCooked); _toolStripCook.ContextMenu.AddSeparator(); @@ -880,7 +889,7 @@ namespace FlaxEditor.Modules _menuToolsBakeLightmaps.Text = isBakingLightmaps ? "Cancel baking lightmaps" : "Bake lightmaps"; _menuToolsClearLightmaps.Enabled = canEdit; _menuToolsBakeAllEnvProbes.Enabled = canEdit; - _menuToolsBuildAllMesgesSDF.Enabled = canEdit && !isBakingLightmaps; + _menuToolsBuildAllMeshesSDF.Enabled = canEdit && !isBakingLightmaps; _menuToolsBuildCSGMesh.Enabled = canEdit; _menuToolsBuildNavMesh.Enabled = canEdit; _menuToolsCancelBuilding.Enabled = GameCooker.IsRunning; @@ -980,57 +989,6 @@ namespace FlaxEditor.Modules new Tools.Terrain.CreateTerrainDialog().Show(Editor.Windows.MainWindow); } - private void BakeAllEnvProbes() - { - Editor.Scene.ExecuteOnGraph(node => - { - if (node is EnvironmentProbeNode envProbeNode && envProbeNode.IsActive) - { - ((EnvironmentProbe)envProbeNode.Actor).Bake(); - node.ParentScene.IsEdited = true; - } - else if (node is SkyLightNode skyLightNode && skyLightNode.IsActive && skyLightNode.Actor is SkyLight skyLight && skyLight.Mode == SkyLight.Modes.CaptureScene) - { - skyLight.Bake(); - node.ParentScene.IsEdited = true; - } - - return node.IsActive; - }); - } - - private void BuildCSG() - { - var scenes = Level.Scenes; - scenes.ToList().ForEach(x => x.BuildCSG(0)); - Editor.Scene.MarkSceneEdited(scenes); - } - - private void BuildNavMesh() - { - var scenes = Level.Scenes; - scenes.ToList().ForEach(x => Navigation.BuildNavMesh(x, 0)); - Editor.Scene.MarkSceneEdited(scenes); - } - - private void BuildAllMeshesSDF() - { - // TODO: async maybe with progress reporting? - Editor.Scene.ExecuteOnGraph(node => - { - if (node is StaticModelNode staticModelNode && staticModelNode.Actor is StaticModel staticModel) - { - if (staticModel.DrawModes.HasFlag(DrawPass.GlobalSDF) && staticModel.Model != null && !staticModel.Model.IsVirtual && staticModel.Model.SDF.Texture == null) - { - Editor.Log("Generating SDF for " + staticModel.Model); - if (!staticModel.Model.GenerateSDF()) - staticModel.Model.Save(); - } - } - return true; - }); - } - private void SetTheCurrentSceneViewAsDefault() { var projectInfo = Editor.GameProject; diff --git a/Source/Editor/Options/InputOptions.cs b/Source/Editor/Options/InputOptions.cs index 27faf48a2..52d7343dd 100644 --- a/Source/Editor/Options/InputOptions.cs +++ b/Source/Editor/Options/InputOptions.cs @@ -126,22 +126,58 @@ namespace FlaxEditor.Options #endregion + #region Tools + + [DefaultValue(typeof(InputBinding), "Ctrl+F10")] + [EditorDisplay("Tools", "Build scenes data"), EditorOrder(600)] + public InputBinding BuildScenesData = new InputBinding(KeyboardKeys.F10, KeyboardKeys.Control); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Tools", "Bake lightmaps"), EditorOrder(601)] + public InputBinding BakeLightmaps = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Tools", "Clear lightmaps data"), EditorOrder(602)] + public InputBinding ClearLightmaps = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Tools", "Bake all env probes"), EditorOrder(603)] + public InputBinding BakeEnvProbes = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Tools", "Build CSG mesh"), EditorOrder(604)] + public InputBinding BuildCSG = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Tools", "Build Nav Mesh"), EditorOrder(605)] + public InputBinding BuildNav = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Tools", "Build all meshes SDF"), EditorOrder(606)] + public InputBinding BuildSDF = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "F12")] + [EditorDisplay("Tools", "Take screenshot"), EditorOrder(607)] + public InputBinding TakeScreenshot = new InputBinding(KeyboardKeys.F12); + + #endregion + #region Debugger [DefaultValue(typeof(InputBinding), "F5")] - [EditorDisplay("Debugger", "Continue"), EditorOrder(610)] + [EditorDisplay("Debugger", "Continue"), EditorOrder(810)] public InputBinding DebuggerContinue = new InputBinding(KeyboardKeys.F5); [DefaultValue(typeof(InputBinding), "F10")] - [EditorDisplay("Debugger", "Step Over"), EditorOrder(620)] + [EditorDisplay("Debugger", "Step Over"), EditorOrder(820)] public InputBinding DebuggerStepOver = new InputBinding(KeyboardKeys.F10); [DefaultValue(typeof(InputBinding), "F11")] - [EditorDisplay("Debugger", "Step Into"), EditorOrder(630)] + [EditorDisplay("Debugger", "Step Into"), EditorOrder(830)] public InputBinding DebuggerStepInto = new InputBinding(KeyboardKeys.F11); [DefaultValue(typeof(InputBinding), "Shift+F11")] - [EditorDisplay("Debugger", "Step Out"), EditorOrder(640)] + [EditorDisplay("Debugger", "Step Out"), EditorOrder(840)] public InputBinding DebuggerStepOut = new InputBinding(KeyboardKeys.F11, KeyboardKeys.Shift); #endregion diff --git a/Source/Editor/Windows/SceneEditorWindow.cs b/Source/Editor/Windows/SceneEditorWindow.cs index 290f02089..529eb5ebc 100644 --- a/Source/Editor/Windows/SceneEditorWindow.cs +++ b/Source/Editor/Windows/SceneEditorWindow.cs @@ -44,6 +44,14 @@ namespace FlaxEditor.Windows InputActions.Add(options => options.StepFrame, Editor.Simulation.RequestPlayOneFrame); InputActions.Add(options => options.CookAndRun, () => Editor.Windows.GameCookerWin.BuildAndRun()); InputActions.Add(options => options.RunCookedGame, () => Editor.Windows.GameCookerWin.RunCooked()); + InputActions.Add(options => options.BuildScenesData, Editor.BuildScenesOrCancel); + InputActions.Add(options => options.BakeLightmaps, Editor.BakeLightmapsOrCancel); + InputActions.Add(options => options.ClearLightmaps, Editor.ClearLightmaps); + InputActions.Add(options => options.BakeEnvProbes, Editor.BakeAllEnvProbes); + InputActions.Add(options => options.BuildCSG, Editor.BuildCSG); + InputActions.Add(options => options.BuildNav, Editor.BuildNavMesh); + InputActions.Add(options => options.BuildSDF, Editor.BuildAllMeshesSDF); + InputActions.Add(options => options.TakeScreenshot, Editor.Windows.TakeScreenshot); } } } From a1cbaba743c0b9311051898e01f51e32fd5c7669 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sun, 17 Sep 2023 00:15:26 +0300 Subject: [PATCH 10/13] Add Editor input bindings for Profiler window and Profiler actions --- Source/Editor/Modules/UIModule.cs | 6 ++++-- Source/Editor/Options/InputOptions.cs | 16 ++++++++++++++++ Source/Editor/Windows/GameWindow.cs | 3 +++ Source/Editor/Windows/Profiler/ProfilerWindow.cs | 4 ++++ Source/Editor/Windows/SceneEditorWindow.cs | 3 +++ 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Modules/UIModule.cs b/Source/Editor/Modules/UIModule.cs index bde2e610a..e675b4fe0 100644 --- a/Source/Editor/Modules/UIModule.cs +++ b/Source/Editor/Modules/UIModule.cs @@ -72,6 +72,7 @@ namespace FlaxEditor.Modules private ContextMenuButton _menuToolsBuildNavMesh; private ContextMenuButton _menuToolsBuildAllMeshesSDF; private ContextMenuButton _menuToolsCancelBuilding; + private ContextMenuButton _menuToolsProfilerWindow; private ContextMenuButton _menuToolsSetTheCurrentSceneViewAsDefault; private ContextMenuButton _menuToolsTakeScreenshot; private ContextMenuChildMenu _menuWindowApplyWindowLayout; @@ -589,7 +590,7 @@ namespace FlaxEditor.Modules cm.AddButton("Game Cooker", Editor.Windows.GameCookerWin.FocusOrShow); _menuToolsCancelBuilding = cm.AddButton("Cancel building game", () => GameCooker.Cancel()); cm.AddSeparator(); - cm.AddButton("Profiler", Editor.Windows.ProfilerWin.FocusOrShow); + _menuToolsProfilerWindow = cm.AddButton("Profiler", inputOptions.ProfilerWindow, () => Editor.Windows.ProfilerWin.FocusOrShow()); cm.AddSeparator(); _menuToolsSetTheCurrentSceneViewAsDefault = cm.AddButton("Set current scene view as project default", SetTheCurrentSceneViewAsDefault); _menuToolsTakeScreenshot = cm.AddButton("Take screenshot", inputOptions.TakeScreenshot, Editor.Windows.TakeScreenshot); @@ -611,7 +612,7 @@ namespace FlaxEditor.Modules cm.AddButton("Output Log", Editor.Windows.OutputLogWin.FocusOrShow); cm.AddButton("Graphics Quality", Editor.Windows.GraphicsQualityWin.FocusOrShow); cm.AddButton("Game Cooker", Editor.Windows.GameCookerWin.FocusOrShow); - cm.AddButton("Profiler", Editor.Windows.ProfilerWin.FocusOrShow); + cm.AddButton("Profiler", inputOptions.ProfilerWindow, Editor.Windows.ProfilerWin.FocusOrShow); cm.AddButton("Content Search", Editor.ContentFinding.ShowSearch); cm.AddButton("Visual Script Debugger", Editor.Windows.VisualScriptDebuggerWin.FocusOrShow); cm.AddSeparator(); @@ -660,6 +661,7 @@ namespace FlaxEditor.Modules _menuToolsBuildCSGMesh.ShortKeys = inputOptions.BuildCSG.ToString(); _menuToolsBuildNavMesh.ShortKeys = inputOptions.BuildNav.ToString(); _menuToolsBuildAllMeshesSDF.ShortKeys = inputOptions.BuildSDF.ToString(); + _menuToolsProfilerWindow.ShortKeys = inputOptions.ProfilerWindow.ToString(); _menuToolsTakeScreenshot.ShortKeys = inputOptions.TakeScreenshot.ToString(); MainMenuShortcutKeysUpdated?.Invoke(); diff --git a/Source/Editor/Options/InputOptions.cs b/Source/Editor/Options/InputOptions.cs index 52d7343dd..b19a46596 100644 --- a/Source/Editor/Options/InputOptions.cs +++ b/Source/Editor/Options/InputOptions.cs @@ -162,6 +162,22 @@ namespace FlaxEditor.Options #endregion + #region Profiler + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Profiler", "Open Profiler Window"), EditorOrder(630)] + public InputBinding ProfilerWindow = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Profiler", "Start/Stop Profiler"), EditorOrder(631)] + public InputBinding ProfilerStartStop = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Profiler", "Clear Profiler data"), EditorOrder(632)] + public InputBinding ProfilerClear = new InputBinding(KeyboardKeys.None); + + #endregion + #region Debugger [DefaultValue(typeof(InputBinding), "F5")] diff --git a/Source/Editor/Windows/GameWindow.cs b/Source/Editor/Windows/GameWindow.cs index 513542fdc..ed1799827 100644 --- a/Source/Editor/Windows/GameWindow.cs +++ b/Source/Editor/Windows/GameWindow.cs @@ -306,6 +306,9 @@ namespace FlaxEditor.Windows InputActions.Add(options => options.Play, Editor.Simulation.DelegatePlayOrStopPlayInEditor); InputActions.Add(options => options.Pause, Editor.Simulation.RequestResumeOrPause); InputActions.Add(options => options.StepFrame, Editor.Simulation.RequestPlayOneFrame); + InputActions.Add(options => options.ProfilerWindow, () => Editor.Windows.ProfilerWin.FocusOrShow()); + InputActions.Add(options => options.ProfilerStartStop, () => { Editor.Windows.ProfilerWin.LiveRecording = !Editor.Windows.ProfilerWin.LiveRecording; Editor.UI.AddStatusMessage($"Profiling {(Editor.Windows.ProfilerWin.LiveRecording ? "started" : "stopped")}."); }); + InputActions.Add(options => options.ProfilerClear, () => { Editor.Windows.ProfilerWin.Clear(); Editor.UI.AddStatusMessage($"Profiling results cleared."); }); } private void ChangeViewportRatio(ViewportScaleOptions v) diff --git a/Source/Editor/Windows/Profiler/ProfilerWindow.cs b/Source/Editor/Windows/Profiler/ProfilerWindow.cs index f5a5c6f86..e4ad5d64a 100644 --- a/Source/Editor/Windows/Profiler/ProfilerWindow.cs +++ b/Source/Editor/Windows/Profiler/ProfilerWindow.cs @@ -116,6 +116,10 @@ namespace FlaxEditor.Windows.Profiler Parent = this }; _tabs.SelectedTabChanged += OnSelectedTabChanged; + + InputActions.Add(options => options.ProfilerWindow, Hide); + InputActions.Add(options => options.ProfilerStartStop, () => LiveRecording = !LiveRecording); + InputActions.Add(options => options.ProfilerClear, Clear); } /// diff --git a/Source/Editor/Windows/SceneEditorWindow.cs b/Source/Editor/Windows/SceneEditorWindow.cs index 529eb5ebc..0241207ac 100644 --- a/Source/Editor/Windows/SceneEditorWindow.cs +++ b/Source/Editor/Windows/SceneEditorWindow.cs @@ -52,6 +52,9 @@ namespace FlaxEditor.Windows InputActions.Add(options => options.BuildNav, Editor.BuildNavMesh); InputActions.Add(options => options.BuildSDF, Editor.BuildAllMeshesSDF); InputActions.Add(options => options.TakeScreenshot, Editor.Windows.TakeScreenshot); + InputActions.Add(options => options.ProfilerWindow, () => Editor.Windows.ProfilerWin.FocusOrShow()); + InputActions.Add(options => options.ProfilerStartStop, () => { Editor.Windows.ProfilerWin.LiveRecording = !Editor.Windows.ProfilerWin.LiveRecording; Editor.UI.AddStatusMessage($"Profiling {(Editor.Windows.ProfilerWin.LiveRecording ? "started" : "stopped")}."); }); + InputActions.Add(options => options.ProfilerClear, () => { Editor.Windows.ProfilerWin.Clear(); Editor.UI.AddStatusMessage($"Profiling results cleared."); }); } } } From 52cf4df641eff1b65ce6c1af8e912700b9c72556 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 23 Sep 2023 15:21:33 +0300 Subject: [PATCH 11/13] Add input bindings for File menu actions --- Source/Editor/Modules/UIModule.cs | 23 ++++++---- Source/Editor/Options/InputOptions.cs | 24 ++++++++++ Source/Editor/Utilities/Utils.cs | 53 +++++++++++++++++++++- Source/Editor/Windows/SceneEditorWindow.cs | 37 +-------------- 4 files changed, 92 insertions(+), 45 deletions(-) diff --git a/Source/Editor/Modules/UIModule.cs b/Source/Editor/Modules/UIModule.cs index e675b4fe0..6b3c705cc 100644 --- a/Source/Editor/Modules/UIModule.cs +++ b/Source/Editor/Modules/UIModule.cs @@ -42,8 +42,10 @@ namespace FlaxEditor.Modules private ContextMenuButton _menuFileSaveScenes; private ContextMenuButton _menuFileCloseScenes; + private ContextMenuButton _menuFileOpenScriptsProject; private ContextMenuButton _menuFileGenerateScriptsProjectFiles; - private ContextMenuButton _menuSaveAll; + private ContextMenuButton _menuFileRecompileScripts; + private ContextMenuButton _menuFileSaveAll; private ContextMenuButton _menuEditUndo; private ContextMenuButton _menuEditRedo; private ContextMenuButton _menuEditCut; @@ -514,13 +516,13 @@ namespace FlaxEditor.Modules MenuFile = MainMenu.AddButton("File"); var cm = MenuFile.ContextMenu; cm.VisibleChanged += OnMenuFileShowHide; - _menuSaveAll = cm.AddButton("Save All", inputOptions.Save, Editor.SaveAll); - _menuFileSaveScenes = cm.AddButton("Save scenes", Editor.Scene.SaveScenes); - _menuFileCloseScenes = cm.AddButton("Close scenes", Editor.Scene.CloseAllScenes); + _menuFileSaveAll = cm.AddButton("Save All", inputOptions.Save, Editor.SaveAll); + _menuFileSaveScenes = cm.AddButton("Save scenes", inputOptions.SaveScenes, Editor.Scene.SaveScenes); + _menuFileCloseScenes = cm.AddButton("Close scenes", inputOptions.CloseScenes, Editor.Scene.CloseAllScenes); cm.AddSeparator(); - cm.AddButton("Open scripts project", Editor.CodeEditing.OpenSolution); - _menuFileGenerateScriptsProjectFiles = cm.AddButton("Generate scripts project files", Editor.ProgressReporting.GenerateScriptsProjectFiles.RunAsync); - cm.AddButton("Recompile scripts", ScriptsBuilder.Compile); + _menuFileOpenScriptsProject = cm.AddButton("Open scripts project", inputOptions.OpenScriptsProject, Editor.CodeEditing.OpenSolution); + _menuFileGenerateScriptsProjectFiles = cm.AddButton("Generate scripts project files", inputOptions.GenerateScriptsProject, Editor.ProgressReporting.GenerateScriptsProjectFiles.RunAsync); + _menuFileRecompileScripts = cm.AddButton("Recompile scripts", inputOptions.RecompileScripts, ScriptsBuilder.Compile); cm.AddSeparator(); cm.AddButton("Open project...", OpenProject); cm.AddSeparator(); @@ -639,7 +641,12 @@ namespace FlaxEditor.Modules { var inputOptions = options.Input; - _menuSaveAll.ShortKeys = inputOptions.Save.ToString(); + _menuFileSaveAll.ShortKeys = inputOptions.Save.ToString(); + _menuFileSaveScenes.ShortKeys = inputOptions.SaveScenes.ToString(); + _menuFileCloseScenes.ShortKeys = inputOptions.CloseScenes.ToString(); + _menuFileOpenScriptsProject.ShortKeys = inputOptions.OpenScriptsProject.ToString(); + _menuFileGenerateScriptsProjectFiles.ShortKeys = inputOptions.GenerateScriptsProject.ToString(); + _menuFileRecompileScripts.ShortKeys = inputOptions.RecompileScripts.ToString(); _menuEditUndo.ShortKeys = inputOptions.Undo.ToString(); _menuEditRedo.ShortKeys = inputOptions.Redo.ToString(); _menuEditCut.ShortKeys = inputOptions.Cut.ToString(); diff --git a/Source/Editor/Options/InputOptions.cs b/Source/Editor/Options/InputOptions.cs index b19a46596..90d098bb6 100644 --- a/Source/Editor/Options/InputOptions.cs +++ b/Source/Editor/Options/InputOptions.cs @@ -78,6 +78,30 @@ namespace FlaxEditor.Options #endregion + #region File + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("File"), EditorOrder(300)] + public InputBinding SaveScenes = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("File"), EditorOrder(310)] + public InputBinding CloseScenes = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("File"), EditorOrder(320)] + public InputBinding OpenScriptsProject = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("File"), EditorOrder(330)] + public InputBinding GenerateScriptsProject = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("File"), EditorOrder(340)] + public InputBinding RecompileScripts = new InputBinding(KeyboardKeys.None); + + #endregion + #region Scene [DefaultValue(typeof(InputBinding), "End")] diff --git a/Source/Editor/Utilities/Utils.cs b/Source/Editor/Utilities/Utils.cs index fe801bbaf..134f9cae4 100644 --- a/Source/Editor/Utilities/Utils.cs +++ b/Source/Editor/Utilities/Utils.cs @@ -18,10 +18,10 @@ using FlaxEditor.GUI.ContextMenu; using FlaxEditor.GUI.Input; using FlaxEditor.GUI.Tree; using FlaxEditor.SceneGraph; -using FlaxEditor.Scripting; using FlaxEngine; using FlaxEngine.GUI; using FlaxEngine.Utilities; +using FlaxEditor.Windows; namespace FlaxEngine { @@ -1235,5 +1235,56 @@ namespace FlaxEditor.Utilities } return s; } + + /// + /// Binds global input actions for the window. + /// + /// The editor window. + public static void SetupCommonInputActions(EditorWindow window) + { + var inputActions = window.InputActions; + + // Setup input actions + inputActions.Add(options => options.Save, Editor.Instance.SaveAll); + inputActions.Add(options => options.Undo, () => + { + Editor.Instance.PerformUndo(); + window.Focus(); + }); + inputActions.Add(options => options.Redo, () => + { + Editor.Instance.PerformRedo(); + window.Focus(); + }); + inputActions.Add(options => options.Cut, Editor.Instance.SceneEditing.Cut); + inputActions.Add(options => options.Copy, Editor.Instance.SceneEditing.Copy); + inputActions.Add(options => options.Paste, Editor.Instance.SceneEditing.Paste); + inputActions.Add(options => options.Duplicate, Editor.Instance.SceneEditing.Duplicate); + inputActions.Add(options => options.SelectAll, Editor.Instance.SceneEditing.SelectAllScenes); + inputActions.Add(options => options.Delete, Editor.Instance.SceneEditing.Delete); + inputActions.Add(options => options.Search, () => Editor.Instance.Windows.SceneWin.Search()); + inputActions.Add(options => options.Play, Editor.Instance.Simulation.DelegatePlayOrStopPlayInEditor); + inputActions.Add(options => options.PlayCurrentScenes, Editor.Instance.Simulation.RequestPlayScenesOrStopPlay); + inputActions.Add(options => options.Pause, Editor.Instance.Simulation.RequestResumeOrPause); + inputActions.Add(options => options.StepFrame, Editor.Instance.Simulation.RequestPlayOneFrame); + inputActions.Add(options => options.CookAndRun, () => Editor.Instance.Windows.GameCookerWin.BuildAndRun()); + inputActions.Add(options => options.RunCookedGame, () => Editor.Instance.Windows.GameCookerWin.RunCooked()); + inputActions.Add(options => options.BuildScenesData, Editor.Instance.BuildScenesOrCancel); + inputActions.Add(options => options.BakeLightmaps, Editor.Instance.BakeLightmapsOrCancel); + inputActions.Add(options => options.ClearLightmaps, Editor.Instance.ClearLightmaps); + inputActions.Add(options => options.BakeEnvProbes, Editor.Instance.BakeAllEnvProbes); + inputActions.Add(options => options.BuildCSG, Editor.Instance.BuildCSG); + inputActions.Add(options => options.BuildNav, Editor.Instance.BuildNavMesh); + inputActions.Add(options => options.BuildSDF, Editor.Instance.BuildAllMeshesSDF); + inputActions.Add(options => options.TakeScreenshot, Editor.Instance.Windows.TakeScreenshot); + inputActions.Add(options => options.ProfilerWindow, () => Editor.Instance.Windows.ProfilerWin.FocusOrShow()); + inputActions.Add(options => options.ProfilerStartStop, () => { Editor.Instance.Windows.ProfilerWin.LiveRecording = !Editor.Instance.Windows.ProfilerWin.LiveRecording; Editor.Instance.UI.AddStatusMessage($"Profiling {(Editor.Instance.Windows.ProfilerWin.LiveRecording ? "started" : "stopped")}."); }); + inputActions.Add(options => options.ProfilerClear, () => { Editor.Instance.Windows.ProfilerWin.Clear(); Editor.Instance.UI.AddStatusMessage($"Profiling results cleared."); }); + inputActions.Add(options => options.SaveScenes, () => Editor.Instance.Scene.SaveScenes()); + inputActions.Add(options => options.CloseScenes, () => Editor.Instance.Scene.CloseAllScenes()); + inputActions.Add(options => options.OpenScriptsProject, () => Editor.Instance.CodeEditing.OpenSolution()); + inputActions.Add(options => options.GenerateScriptsProject, () => Editor.Instance.ProgressReporting.GenerateScriptsProjectFiles.RunAsync()); + inputActions.Add(options => options.RecompileScripts, ScriptsBuilder.Compile); + } } } diff --git a/Source/Editor/Windows/SceneEditorWindow.cs b/Source/Editor/Windows/SceneEditorWindow.cs index 0241207ac..04cce47e8 100644 --- a/Source/Editor/Windows/SceneEditorWindow.cs +++ b/Source/Editor/Windows/SceneEditorWindow.cs @@ -19,42 +19,7 @@ namespace FlaxEditor.Windows protected SceneEditorWindow(Editor editor, bool hideOnClose, ScrollBars scrollBars) : base(editor, hideOnClose, scrollBars) { - // Setup input actions - InputActions.Add(options => options.Save, Editor.SaveAll); - InputActions.Add(options => options.Undo, () => - { - Editor.PerformUndo(); - Focus(); - }); - InputActions.Add(options => options.Redo, () => - { - Editor.PerformRedo(); - Focus(); - }); - InputActions.Add(options => options.Cut, Editor.SceneEditing.Cut); - InputActions.Add(options => options.Copy, Editor.SceneEditing.Copy); - InputActions.Add(options => options.Paste, Editor.SceneEditing.Paste); - InputActions.Add(options => options.Duplicate, Editor.SceneEditing.Duplicate); - InputActions.Add(options => options.SelectAll, Editor.SceneEditing.SelectAllScenes); - InputActions.Add(options => options.Delete, Editor.SceneEditing.Delete); - InputActions.Add(options => options.Search, () => Editor.Windows.SceneWin.Search()); - InputActions.Add(options => options.Play, Editor.Simulation.DelegatePlayOrStopPlayInEditor); - InputActions.Add(options => options.PlayCurrentScenes, Editor.Simulation.RequestPlayScenesOrStopPlay); - InputActions.Add(options => options.Pause, Editor.Simulation.RequestResumeOrPause); - InputActions.Add(options => options.StepFrame, Editor.Simulation.RequestPlayOneFrame); - InputActions.Add(options => options.CookAndRun, () => Editor.Windows.GameCookerWin.BuildAndRun()); - InputActions.Add(options => options.RunCookedGame, () => Editor.Windows.GameCookerWin.RunCooked()); - InputActions.Add(options => options.BuildScenesData, Editor.BuildScenesOrCancel); - InputActions.Add(options => options.BakeLightmaps, Editor.BakeLightmapsOrCancel); - InputActions.Add(options => options.ClearLightmaps, Editor.ClearLightmaps); - InputActions.Add(options => options.BakeEnvProbes, Editor.BakeAllEnvProbes); - InputActions.Add(options => options.BuildCSG, Editor.BuildCSG); - InputActions.Add(options => options.BuildNav, Editor.BuildNavMesh); - InputActions.Add(options => options.BuildSDF, Editor.BuildAllMeshesSDF); - InputActions.Add(options => options.TakeScreenshot, Editor.Windows.TakeScreenshot); - InputActions.Add(options => options.ProfilerWindow, () => Editor.Windows.ProfilerWin.FocusOrShow()); - InputActions.Add(options => options.ProfilerStartStop, () => { Editor.Windows.ProfilerWin.LiveRecording = !Editor.Windows.ProfilerWin.LiveRecording; Editor.UI.AddStatusMessage($"Profiling {(Editor.Windows.ProfilerWin.LiveRecording ? "started" : "stopped")}."); }); - InputActions.Add(options => options.ProfilerClear, () => { Editor.Windows.ProfilerWin.Clear(); Editor.UI.AddStatusMessage($"Profiling results cleared."); }); + FlaxEditor.Utilities.Utils.SetupCommonInputActions(this); } } } From 385c3541c97e6cc26b292e0a6f5364c631ebef14 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 23 Sep 2023 15:21:57 +0300 Subject: [PATCH 12/13] Apply global editor bindings in most windows --- Source/Editor/Windows/ContentWindow.cs | 2 ++ Source/Editor/Windows/DebugLogWindow.cs | 1 + Source/Editor/Windows/GameWindow.cs | 9 ++------- Source/Editor/Windows/OutputLogWindow.cs | 1 + Source/Editor/Windows/Profiler/ProfilerWindow.cs | 4 ++-- Source/Editor/Windows/ToolboxWindow.cs | 2 ++ 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Source/Editor/Windows/ContentWindow.cs b/Source/Editor/Windows/ContentWindow.cs index 285302d03..6c538f6b8 100644 --- a/Source/Editor/Windows/ContentWindow.cs +++ b/Source/Editor/Windows/ContentWindow.cs @@ -129,6 +129,8 @@ namespace FlaxEditor.Windows Title = "Content"; Icon = editor.Icons.Folder32; + FlaxEditor.Utilities.Utils.SetupCommonInputActions(this); + // Content database events editor.ContentDatabase.WorkspaceModified += () => _isWorkspaceDirty = true; editor.ContentDatabase.ItemRemoved += OnContentDatabaseItemRemoved; diff --git a/Source/Editor/Windows/DebugLogWindow.cs b/Source/Editor/Windows/DebugLogWindow.cs index 24e38d9af..ab0c07ec5 100644 --- a/Source/Editor/Windows/DebugLogWindow.cs +++ b/Source/Editor/Windows/DebugLogWindow.cs @@ -317,6 +317,7 @@ namespace FlaxEditor.Windows Title = "Debug Log"; Icon = IconInfo; OnEditorOptionsChanged(Editor.Options.Options); + FlaxEditor.Utilities.Utils.SetupCommonInputActions(this); // Toolstrip var toolstrip = new ToolStrip(22.0f) diff --git a/Source/Editor/Windows/GameWindow.cs b/Source/Editor/Windows/GameWindow.cs index ed1799827..bbdf763fb 100644 --- a/Source/Editor/Windows/GameWindow.cs +++ b/Source/Editor/Windows/GameWindow.cs @@ -271,6 +271,8 @@ namespace FlaxEditor.Windows Title = "Game"; AutoFocus = true; + FlaxEditor.Utilities.Utils.SetupCommonInputActions(this); + var task = MainRenderTask.Instance; // Setup viewport @@ -302,13 +304,6 @@ namespace FlaxEditor.Windows // Link editor options Editor.Options.OptionsChanged += OnOptionsChanged; OnOptionsChanged(Editor.Options.Options); - - InputActions.Add(options => options.Play, Editor.Simulation.DelegatePlayOrStopPlayInEditor); - InputActions.Add(options => options.Pause, Editor.Simulation.RequestResumeOrPause); - InputActions.Add(options => options.StepFrame, Editor.Simulation.RequestPlayOneFrame); - InputActions.Add(options => options.ProfilerWindow, () => Editor.Windows.ProfilerWin.FocusOrShow()); - InputActions.Add(options => options.ProfilerStartStop, () => { Editor.Windows.ProfilerWin.LiveRecording = !Editor.Windows.ProfilerWin.LiveRecording; Editor.UI.AddStatusMessage($"Profiling {(Editor.Windows.ProfilerWin.LiveRecording ? "started" : "stopped")}."); }); - InputActions.Add(options => options.ProfilerClear, () => { Editor.Windows.ProfilerWin.Clear(); Editor.UI.AddStatusMessage($"Profiling results cleared."); }); } private void ChangeViewportRatio(ViewportScaleOptions v) diff --git a/Source/Editor/Windows/OutputLogWindow.cs b/Source/Editor/Windows/OutputLogWindow.cs index 0b2249a33..4ea31b35e 100644 --- a/Source/Editor/Windows/OutputLogWindow.cs +++ b/Source/Editor/Windows/OutputLogWindow.cs @@ -150,6 +150,7 @@ namespace FlaxEditor.Windows { Title = "Output Log"; ClipChildren = false; + FlaxEditor.Utilities.Utils.SetupCommonInputActions(this); // Setup UI _viewDropdown = new Button(2, 2, 40.0f, TextBoxBase.DefaultHeight) diff --git a/Source/Editor/Windows/Profiler/ProfilerWindow.cs b/Source/Editor/Windows/Profiler/ProfilerWindow.cs index e4ad5d64a..ee8a7e83e 100644 --- a/Source/Editor/Windows/Profiler/ProfilerWindow.cs +++ b/Source/Editor/Windows/Profiler/ProfilerWindow.cs @@ -117,9 +117,9 @@ namespace FlaxEditor.Windows.Profiler }; _tabs.SelectedTabChanged += OnSelectedTabChanged; + FlaxEditor.Utilities.Utils.SetupCommonInputActions(this); + InputActions.Bindings.RemoveAll(x => x.Callback == this.FocusOrShow); InputActions.Add(options => options.ProfilerWindow, Hide); - InputActions.Add(options => options.ProfilerStartStop, () => LiveRecording = !LiveRecording); - InputActions.Add(options => options.ProfilerClear, Clear); } /// diff --git a/Source/Editor/Windows/ToolboxWindow.cs b/Source/Editor/Windows/ToolboxWindow.cs index 3df4d3527..b747149c5 100644 --- a/Source/Editor/Windows/ToolboxWindow.cs +++ b/Source/Editor/Windows/ToolboxWindow.cs @@ -353,6 +353,8 @@ namespace FlaxEditor.Windows : base(editor, true, ScrollBars.None) { Title = "Toolbox"; + + FlaxEditor.Utilities.Utils.SetupCommonInputActions(this); } /// From 080091c27181196996bb0ef512e9243ec0b77b2b Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 23 Sep 2023 15:35:45 +0300 Subject: [PATCH 13/13] Fix missing bindings for Actor related actions --- Source/Editor/Modules/UIModule.cs | 6 +++--- Source/Editor/Utilities/Utils.cs | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Modules/UIModule.cs b/Source/Editor/Modules/UIModule.cs index 6b3c705cc..1bb40469b 100644 --- a/Source/Editor/Modules/UIModule.cs +++ b/Source/Editor/Modules/UIModule.cs @@ -937,7 +937,7 @@ namespace FlaxEditor.Modules Editor.Windows.LoadLayout((string)button.Tag); } - private void AlignViewportWithActor() + internal void AlignViewportWithActor() { var selection = Editor.SceneEditing; if (selection.HasSthSelected && selection.Selection[0] is ActorNode node) @@ -948,7 +948,7 @@ namespace FlaxEditor.Modules } } - private void MoveActorToViewport() + internal void MoveActorToViewport() { var selection = Editor.SceneEditing; if (selection.HasSthSelected && selection.Selection[0] is ActorNode node) @@ -962,7 +962,7 @@ namespace FlaxEditor.Modules } } - private void AlignActorWithViewport() + internal void AlignActorWithViewport() { var selection = Editor.SceneEditing; if (selection.HasSthSelected && selection.Selection[0] is ActorNode node) diff --git a/Source/Editor/Utilities/Utils.cs b/Source/Editor/Utilities/Utils.cs index 134f9cae4..863bdbedb 100644 --- a/Source/Editor/Utilities/Utils.cs +++ b/Source/Editor/Utilities/Utils.cs @@ -1263,6 +1263,10 @@ namespace FlaxEditor.Utilities inputActions.Add(options => options.SelectAll, Editor.Instance.SceneEditing.SelectAllScenes); inputActions.Add(options => options.Delete, Editor.Instance.SceneEditing.Delete); inputActions.Add(options => options.Search, () => Editor.Instance.Windows.SceneWin.Search()); + inputActions.Add(options => options.MoveActorToViewport, Editor.Instance.UI.MoveActorToViewport); + inputActions.Add(options => options.AlignActorWithViewport, Editor.Instance.UI.AlignActorWithViewport); + inputActions.Add(options => options.AlignViewportWithActor, Editor.Instance.UI.AlignViewportWithActor); + inputActions.Add(options => options.PilotActor, Editor.Instance.UI.PilotActor); inputActions.Add(options => options.Play, Editor.Instance.Simulation.DelegatePlayOrStopPlayInEditor); inputActions.Add(options => options.PlayCurrentScenes, Editor.Instance.Simulation.RequestPlayScenesOrStopPlay); inputActions.Add(options => options.Pause, Editor.Instance.Simulation.RequestResumeOrPause);