diff --git a/Source/Editor/Modules/SimulationModule.cs b/Source/Editor/Modules/SimulationModule.cs index 6f54ab10d..bb9df0950 100644 --- a/Source/Editor/Modules/SimulationModule.cs +++ b/Source/Editor/Modules/SimulationModule.cs @@ -2,6 +2,7 @@ using System; using System.Threading; +using FlaxEditor.GUI.Docking; using FlaxEditor.States; using FlaxEditor.Windows; using FlaxEngine; @@ -20,6 +21,7 @@ namespace FlaxEditor.Modules private bool _updateOrFixedUpdateWasCalled; private long _breakpointHangFlag; private EditorWindow _enterPlayFocusedWindow; + private DockWindow _previousWindow; private Guid[] _scenesToReload; internal SimulationModule(Editor editor) @@ -272,23 +274,43 @@ namespace FlaxEditor.Modules // Show Game widow if hidden if (gameWin != null) { - if (gameWin.FocusOnPlay) + switch (gameWin.FocusOnPlayOption) + { + case Options.InterfaceOptions.PlayModeFocus.None: break; + + case Options.InterfaceOptions.PlayModeFocus.GameWindow: gameWin.FocusGameViewport(); + break; + + case Options.InterfaceOptions.PlayModeFocus.GameWindowThenRestore: + _previousWindow = gameWin.ParentDockPanel.SelectedTab; + gameWin.FocusGameViewport(); + break; + } + gameWin.SetWindowMode(Editor.Options.Options.Interface.DefaultGameWindowMode); } - Editor.Log("[PlayMode] Enter"); } /// public override void OnPlayEnd() { - // Restore focused window before play mode - if (_enterPlayFocusedWindow != null) + var gameWin = Editor.Windows.GameWin; + + switch (gameWin.FocusOnPlayOption) { - _enterPlayFocusedWindow.FocusOrShow(); - _enterPlayFocusedWindow = null; + case Options.InterfaceOptions.PlayModeFocus.None: break; + case Options.InterfaceOptions.PlayModeFocus.GameWindow: break; + case Options.InterfaceOptions.PlayModeFocus.GameWindowThenRestore: + if (_previousWindow != null && !_previousWindow.IsDisposing) + { + if (!Editor.Windows.GameWin.ParentDockPanel.ContainsTab(_previousWindow)) + break; + _previousWindow.Focus(); + } + break; } Editor.UI.UncheckPauseButton(); diff --git a/Source/Editor/Options/InterfaceOptions.cs b/Source/Editor/Options/InterfaceOptions.cs index 30cb64aa8..ec46ccdd9 100644 --- a/Source/Editor/Options/InterfaceOptions.cs +++ b/Source/Editor/Options/InterfaceOptions.cs @@ -1,8 +1,8 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. +using System; using System.ComponentModel; using FlaxEditor.GUI.Docking; -using FlaxEditor.Utilities; using FlaxEngine; using FlaxEngine.GUI; @@ -139,6 +139,27 @@ namespace FlaxEditor.Options AutoUnit, } + /// + /// Options focus Game Window behaviour when play mode is entered. + /// + public enum PlayModeFocus + { + /// + /// Don't change focus. + /// + None, + + /// + /// Focus the Game Window. + /// + GameWindow, + + /// + /// Focus the Game Window. On play mode end restore focus to the previous window. + /// + GameWindowThenRestore, + } + /// /// Gets or sets the Editor User Interface scale. Applied to all UI elements, windows and text. Can be used to scale the interface up on a bigger display. Editor restart required. /// @@ -339,6 +360,18 @@ namespace FlaxEditor.Options [EditorDisplay("Output Log", "Text Shadow Offset"), EditorOrder(445), Tooltip("The output log text shadow offset. Set to 0 to disable this feature.")] public Float2 OutputLogTextShadowOffset { get; set; } = new Float2(1); + // [Deprecated in v1.10] + [Serialize, Obsolete, NoUndo] + private bool FocusGameWinOnPlay + { + get => throw new Exception(); + set + { + // Upgrade value + FocusOnPlayMode = value ? PlayModeFocus.GameWindow : PlayModeFocus.None; + } + } + /// /// Gets or sets a value indicating whether auto-focus output log window on code compilation error. /// @@ -361,11 +394,11 @@ namespace FlaxEditor.Options public bool OutputLogScrollToBottom { get; set; } = true; /// - /// Gets or sets a value indicating whether auto-focus game window on play mode start. + /// Gets or sets a value indicating what panel should be focused when play mode start. /// - [DefaultValue(true)] - [EditorDisplay("Play In-Editor", "Focus Game Window On Play"), EditorOrder(500), Tooltip("Determines whether auto-focus game window on play mode start.")] - public bool FocusGameWinOnPlay { get; set; } = true; + [DefaultValue(PlayModeFocus.GameWindow)] + [EditorDisplay("Play In-Editor", "Focus On Play"), EditorOrder(500), Tooltip("Set what panel to focus on play mode start.")] + public PlayModeFocus FocusOnPlayMode { get; set; } = PlayModeFocus.GameWindow; /// /// Gets or sets a value indicating what action should be taken upon pressing the play button. diff --git a/Source/Editor/Windows/GameWindow.cs b/Source/Editor/Windows/GameWindow.cs index 56e4c4380..0366cef8f 100644 --- a/Source/Editor/Windows/GameWindow.cs +++ b/Source/Editor/Windows/GameWindow.cs @@ -39,6 +39,28 @@ namespace FlaxEditor.Windows private bool _useAspect = false; private bool _freeAspect = true; + private List _focusOptions = new List() + { + new PlayModeFocusOptions + { + Name = "None", + Tooltip = "Don't change focus.", + FocusOption = InterfaceOptions.PlayModeFocus.None, + }, + new PlayModeFocusOptions + { + Name = "Game Window", + Tooltip = "Focus the Game Window.", + FocusOption = InterfaceOptions.PlayModeFocus.GameWindow, + }, + new PlayModeFocusOptions + { + Name = "Game Window Then Restore", + Tooltip = "Focus the Game Window. On play mode end restore focus to the previous window.", + FocusOption = InterfaceOptions.PlayModeFocus.GameWindowThenRestore, + }, + }; + /// /// Gets the viewport. /// @@ -162,9 +184,9 @@ namespace FlaxEditor.Windows public bool CenterMouseOnFocus { get; set; } /// - /// Gets or sets a value indicating whether auto-focus game window on play mode start. + /// Gets or sets a value indicating what panel should be focused when play mode start. /// - public bool FocusOnPlay { get; set; } + public InterfaceOptions.PlayModeFocus FocusOnPlayOption { get; set; } private enum ViewportScaleType { @@ -195,6 +217,29 @@ namespace FlaxEditor.Windows public bool Active; } + private class PlayModeFocusOptions + { + /// + /// The name. + /// + public string Name; + + /// + /// The tooltip. + /// + public string Tooltip; + + /// + /// The type of focus. + /// + public InterfaceOptions.PlayModeFocus FocusOption; + + /// + /// If the option is active. + /// + public bool Active; + } + /// /// Root control for game UI preview in Editor. Supports basic UI editing via . /// @@ -430,7 +475,7 @@ namespace FlaxEditor.Windows private void OnOptionsChanged(EditorOptions options) { CenterMouseOnFocus = options.Interface.CenterMouseOnGameWinFocus; - FocusOnPlay = options.Interface.FocusGameWinOnPlay; + FocusOnPlayOption = options.Interface.FocusOnPlayMode; } private void PlayingStateOnSceneDuplicating() @@ -495,10 +540,15 @@ namespace FlaxEditor.Windows // Focus on play { - var focus = menu.AddButton("Start Focused"); - focus.CloseMenuOnClick = false; - var checkbox = new CheckBox(140, 2, FocusOnPlay) { Parent = focus }; - checkbox.StateChanged += state => FocusOnPlay = state.Checked; + var pfMenu = menu.AddChildMenu("Focus On Play Override").ContextMenu; + + GenerateFocusOptionsContextMenu(pfMenu); + + pfMenu.AddSeparator(); + + var button = pfMenu.AddButton("Remove override"); + button.TooltipText = "Reset the override to the value set in the editor options."; + button.Clicked += () => FocusOnPlayOption = Editor.Instance.Options.Options.Interface.FocusOnPlayMode; } menu.AddSeparator(); @@ -600,6 +650,40 @@ namespace FlaxEditor.Windows menu.AddSeparator(); } + private void GenerateFocusOptionsContextMenu(ContextMenu pfMenu) + { + foreach (PlayModeFocusOptions f in _focusOptions) + { + f.Active = f.FocusOption == FocusOnPlayOption; + + var button = pfMenu.AddButton(f.Name); + button.CloseMenuOnClick = false; + button.Tag = f; + button.TooltipText = f.Tooltip; + button.Icon = f.Active ? Style.Current.CheckBoxTick : SpriteHandle.Invalid; + button.Clicked += () => + { + foreach (var child in pfMenu.Items) + { + if (child is ContextMenuButton cmb && cmb.Tag is PlayModeFocusOptions p) + { + if (cmb == button) + { + p.Active = true; + button.Icon = Style.Current.CheckBoxTick; + FocusOnPlayOption = p.FocusOption; + } + else if (p.Active) + { + cmb.Icon = SpriteHandle.Invalid; + p.Active = false; + } + } + } + }; + } + } + private void CreateViewportSizingContextMenu(ContextMenu vsMenu) { // Add default viewport sizing options diff --git a/Source/Engine/Content/Assets/Animation.cpp b/Source/Engine/Content/Assets/Animation.cpp index 261394441..6f8b23ec7 100644 --- a/Source/Engine/Content/Assets/Animation.cpp +++ b/Source/Engine/Content/Assets/Animation.cpp @@ -504,7 +504,7 @@ void Animation::GetReferences(Array& assets, Array& files) const writer.StartObject(); k.Value.Instance->Serialize(writer, nullptr); writer.EndObject(); - JsonAssetBase::GetReferences(StringAnsiView((char*)buffer.GetString(), buffer.GetSize()), assets); + JsonAssetBase::GetReferences(StringAnsiView((const char*)buffer.GetString(), (int32)buffer.GetSize()), assets); } } } diff --git a/Source/Engine/Core/LogContext.cpp b/Source/Engine/Core/LogContext.cpp index 6916fd7de..c7ed7ea2e 100644 --- a/Source/Engine/Core/LogContext.cpp +++ b/Source/Engine/Core/LogContext.cpp @@ -57,7 +57,7 @@ void LogContext::Print(LogType verbosity) LogContextData& context = stack.Ptr[index]; // Skip duplicates - if (index < stack.Count - 1 && stack.Ptr[stack.Count - 1] == context) + if (index < (int32)stack.Count - 1 && stack.Ptr[stack.Count - 1] == context) continue; // Build call hierarchy via indentation