Add the ability to quickly change window modes for the game window.

This commit is contained in:
MineBill
2023-12-21 19:49:48 +02:00
parent 4e34524a08
commit 87addf8197
4 changed files with 137 additions and 8 deletions

View File

@@ -264,11 +264,14 @@ namespace FlaxEditor.Modules
_enterPlayFocusedWindow = gameWin;
// Show Game widow if hidden
if (gameWin != null && gameWin.FocusOnPlay)
if (gameWin != null)
{
gameWin.FocusGameViewport();
if (gameWin.FocusOnPlay)
gameWin.FocusGameViewport();
gameWin.SetWindowMode(Editor.Options.Options.Interface.DefaultGameWindowMode);
}
Editor.Log("[PlayMode] Enter");
}

View File

@@ -737,6 +737,17 @@ namespace FlaxEditor.Modules
playActionGroup.SelectedChanged = SetPlayAction;
Editor.Options.OptionsChanged += options => { playActionGroup.Selected = options.Interface.PlayButtonAction; };
var windowModesGroup = new ContextMenuSingleSelectGroup<InterfaceOptions.GameWindowMode>();
var windowTypeMenu = _toolStripPlay.ContextMenu.AddChildMenu("Game window mode");
windowModesGroup.AddItem("Docked", InterfaceOptions.GameWindowMode.Docked, null, "Shows the game window docked, inside the editor");
windowModesGroup.AddItem("Popup", InterfaceOptions.GameWindowMode.PopupWindow, null, "Shows the game window as a popup");
windowModesGroup.AddItem("Maximized", InterfaceOptions.GameWindowMode.MaximizedWindow, null, "Shows the game window maximized (Same as pressing F11)");
windowModesGroup.AddItem("Borderless", InterfaceOptions.GameWindowMode.BorderlessWindow, null, "Shows the game window borderless");
windowModesGroup.AddItemsToContextMenu(windowTypeMenu.ContextMenu);
windowModesGroup.Selected = Editor.Options.Options.Interface.DefaultGameWindowMode;
windowModesGroup.SelectedChanged = SetGameWindowMode;
Editor.Options.OptionsChanged += options => { windowModesGroup.Selected = options.Interface.DefaultGameWindowMode; };
_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");
@@ -1033,6 +1044,13 @@ namespace FlaxEditor.Modules
Editor.Options.Apply(options);
}
private void SetGameWindowMode(InterfaceOptions.GameWindowMode newGameWindowMode)
{
var options = Editor.Options.Options;
options.Interface.DefaultGameWindowMode = newGameWindowMode;
Editor.Options.Apply(options);
}
private void OnMainWindowClosing()
{
// Clear UI references (GUI cannot be used after window closing)

View File

@@ -90,6 +90,32 @@ namespace FlaxEditor.Options
PlayScenes,
}
/// <summary>
/// Available window modes for the game window.
/// </summary>
public enum GameWindowMode
{
/// <summary>
/// Shows the game window docked, inside the editor.
/// </summary>
Docked,
/// <summary>
/// Shows the game window as a popup.
/// </summary>
PopupWindow,
/// <summary>
/// Shows the game window maximized. (Same as pressing F11)
/// </summary>
MaximizedWindow,
/// <summary>
/// Shows the game window borderless.
/// </summary>
BorderlessWindow,
}
/// <summary>
/// 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.
/// </summary>
@@ -229,6 +255,13 @@ namespace FlaxEditor.Options
[EditorDisplay("Play In-Editor", "Play Button Action"), EditorOrder(410)]
public PlayAction PlayButtonAction { get; set; } = PlayAction.PlayScenes;
/// <summary>
/// Gets or sets a value indicating how the game window should be displayed when the game is launched.
/// </summary>
[DefaultValue(GameWindowMode.Docked)]
[EditorDisplay("Play In-Editor", "Game Window Mode"), EditorOrder(420), Tooltip("Determines how the game window is displayed when the game is launched.")]
public GameWindowMode DefaultGameWindowMode { get; set; } = GameWindowMode.Docked;
/// <summary>
/// Gets or sets a value indicating the number of game clients to launch when building and/or running cooked game.
/// </summary>

View File

@@ -23,6 +23,7 @@ namespace FlaxEditor.Windows
private bool _showGUI = true;
private bool _showDebugDraw = false;
private bool _isMaximized = false, _isUnlockingMouse = false;
private bool _isFloating = false, _isBorderless = false;
private bool _cursorVisible = true;
private float _gameStartTime;
private GUI.Docking.DockState _maximizeRestoreDockState;
@@ -68,7 +69,7 @@ namespace FlaxEditor.Windows
}
/// <summary>
/// Gets or sets a value indicating whether game window is maximized (only in play mode).
/// Gets or sets a value indicating whether the game window is maximized (only in play mode).
/// </summary>
private bool IsMaximized
{
@@ -78,20 +79,42 @@ namespace FlaxEditor.Windows
if (_isMaximized == value)
return;
_isMaximized = value;
if (value)
{
IsFloating = true;
var rootWindow = RootWindow;
rootWindow.Maximize();
}
else
{
IsFloating = false;
}
}
}
/// <summary>
/// Gets or sets a value indicating whether the game window is floating (popup, only in play mode).
/// </summary>
private bool IsFloating
{
get => _isFloating;
set
{
if (_isFloating == value)
return;
_isFloating = value;
var rootWindow = RootWindow;
if (value)
{
// Maximize
_maximizeRestoreDockTo = _dockedTo;
_maximizeRestoreDockState = _dockedTo.TryGetDockState(out _);
if (_maximizeRestoreDockState != GUI.Docking.DockState.Float)
{
var monitorBounds = Platform.GetMonitorBounds(PointToScreen(Size * 0.5f));
ShowFloating(monitorBounds.Location + new Float2(200, 200), Float2.Zero, WindowStartPosition.Manual);
rootWindow = RootWindow;
var size = DefaultSize;
var location = monitorBounds.Location + monitorBounds.Size * 0.5f - size * 0.5f;
ShowFloating(location, size, WindowStartPosition.Manual);
}
if (rootWindow != null && !rootWindow.IsMaximized)
rootWindow.Maximize();
}
else
{
@@ -105,6 +128,33 @@ namespace FlaxEditor.Windows
}
}
/// <summary>
/// Gets or sets a value indicating whether the game window is borderless (only in play mode).
/// </summary>
private bool IsBorderless
{
get => _isBorderless;
set
{
if (_isBorderless == value)
return;
_isBorderless = value;
if (value)
{
IsFloating = true;
var rootWindow = RootWindow;
var monitorBounds = Platform.GetMonitorBounds(rootWindow.RootWindow.Window.ClientPosition);
rootWindow.Window.Position = monitorBounds.Location;
rootWindow.Window.SetBorderless(true);
rootWindow.Window.ClientSize = monitorBounds.Size;
}
else
{
IsFloating = false;
}
}
}
/// <summary>
/// Gets or sets a value indicating whether center mouse position on window focus in play mode. Helps when working with games that lock mouse cursor.
/// </summary>
@@ -464,7 +514,9 @@ namespace FlaxEditor.Windows
/// <inheritdoc />
public override void OnPlayEnd()
{
IsFloating = false;
IsMaximized = false;
IsBorderless = false;
Cursor = CursorType.Default;
}
@@ -930,6 +982,29 @@ namespace FlaxEditor.Windows
Focus();
}
/// <summary>
/// Apply the selected window mode to the game window.
/// </summary>
/// <param name="mode"></param>
public void SetWindowMode(InterfaceOptions.GameWindowMode mode)
{
switch (mode)
{
case InterfaceOptions.GameWindowMode.Docked:
break;
case InterfaceOptions.GameWindowMode.PopupWindow:
IsFloating = true;
break;
case InterfaceOptions.GameWindowMode.MaximizedWindow:
IsMaximized = true;
break;
case InterfaceOptions.GameWindowMode.BorderlessWindow:
IsBorderless = true;
break;
default: throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
}
}
/// <summary>
/// Takes the screenshot of the current viewport.
/// </summary>