mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Show task bar progress bar for loading progress
Using the new API in SDL 3.4.0
This commit is contained in:
@@ -601,6 +601,11 @@ namespace Robust.Client.Graphics.Clyde
|
||||
_clyde._windowing!.TextInputStop(Reg);
|
||||
}
|
||||
|
||||
public void SetWindowProgress(WindowProgressState state, float value)
|
||||
{
|
||||
_clyde._windowing!.WindowSetProgress(Reg, state, value);
|
||||
}
|
||||
|
||||
public nint? WindowsHWnd => _clyde._windowing!.WindowGetWin32Window(Reg);
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,8 @@ namespace Robust.Client.Graphics.Clyde
|
||||
private bool _earlyGLInit;
|
||||
private bool _threadWindowApi;
|
||||
|
||||
public bool IsInitialized { get; private set; }
|
||||
|
||||
public Clyde()
|
||||
{
|
||||
_currentBoundRenderTarget = default!;
|
||||
@@ -183,6 +185,8 @@ namespace Robust.Client.Graphics.Clyde
|
||||
if (!InitMainWindowAndRenderer())
|
||||
return false;
|
||||
|
||||
IsInitialized = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace Robust.Client.Graphics.Clyde
|
||||
internal sealed class ClydeHeadless : IClydeInternal
|
||||
{
|
||||
// Would it make sense to report a fake resolution like 720p here so code doesn't break? idk.
|
||||
public bool IsInitialized { get; private set; }
|
||||
public IClydeWindow MainWindow { get; }
|
||||
public Vector2i ScreenSize => (1280, 720);
|
||||
public IEnumerable<IClydeWindow> AllWindows => _windows;
|
||||
@@ -172,6 +173,7 @@ namespace Robust.Client.Graphics.Clyde
|
||||
|
||||
public bool InitializePostWindowing()
|
||||
{
|
||||
IsInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -583,6 +585,11 @@ namespace Robust.Client.Graphics.Clyde
|
||||
public event Action<WindowDestroyedEventArgs>? Destroyed;
|
||||
public event Action<WindowResizedEventArgs>? Resized { add { } remove { } }
|
||||
|
||||
public void SetWindowProgress(WindowProgressState state, float value)
|
||||
{
|
||||
// Nop.
|
||||
}
|
||||
|
||||
public void TextInputSetRect(UIBox2i rect, int cursor)
|
||||
{
|
||||
// Nop.
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace Robust.Client.Graphics.Clyde
|
||||
void WindowSetSize(WindowReg window, Vector2i size);
|
||||
void WindowSetVisible(WindowReg window, bool visible);
|
||||
void WindowRequestAttention(WindowReg window);
|
||||
void WindowSetProgress(WindowReg reg, WindowProgressState state, float value);
|
||||
void WindowSwapBuffers(WindowReg window);
|
||||
uint? WindowGetX11Id(WindowReg window);
|
||||
nint? WindowGetX11Display(WindowReg window);
|
||||
|
||||
@@ -21,6 +21,7 @@ internal partial class Clyde
|
||||
private sealed partial class Sdl3WindowingImpl
|
||||
{
|
||||
private int _nextWindowId = 1;
|
||||
private bool _progressUnavailable;
|
||||
|
||||
public (WindowReg?, string? error) WindowCreate(
|
||||
GLContextSpec? spec,
|
||||
@@ -461,6 +462,42 @@ internal partial class Clyde
|
||||
_sawmill.Error("Failed to flash window: {error}", SDL.SDL_GetError());
|
||||
}
|
||||
|
||||
public void WindowSetProgress(WindowReg window, WindowProgressState state, float value)
|
||||
{
|
||||
SendCmd(new CmdWinSetProgress
|
||||
{
|
||||
Window = WinPtr(window),
|
||||
State = (SDL.SDL_ProgressState)state,
|
||||
Value = value
|
||||
});
|
||||
}
|
||||
|
||||
private void WinThreadWinSetProgress(CmdWinSetProgress cmd)
|
||||
{
|
||||
if (_progressUnavailable)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var res = SDL.SDL_SetWindowProgressState(cmd.Window, cmd.State);
|
||||
if (!res)
|
||||
{
|
||||
_sawmill.Error("Failed to set window progress state: {error}", SDL.SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
res = SDL.SDL_SetWindowProgressValue(cmd.Window, cmd.Value);
|
||||
if (!res)
|
||||
_sawmill.Error("Failed to set window progress value: {error}", SDL.SDL_GetError());
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
// Allowing it to fail means I don't have to update the launcher immediately :)
|
||||
_progressUnavailable = true;
|
||||
_sawmill.Debug("SDL3 progress APIs unavailable");
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void WindowSwapBuffers(WindowReg window)
|
||||
{
|
||||
var reg = (Sdl3WindowReg)window;
|
||||
|
||||
@@ -93,6 +93,10 @@ internal partial class Clyde
|
||||
WinThreadWinRequestAttention(cmd);
|
||||
break;
|
||||
|
||||
case CmdWinSetProgress cmd:
|
||||
WinThreadWinSetProgress(cmd);
|
||||
break;
|
||||
|
||||
case CmdWinSetSize cmd:
|
||||
WinThreadWinSetSize(cmd);
|
||||
break;
|
||||
@@ -261,6 +265,13 @@ internal partial class Clyde
|
||||
public nint Window;
|
||||
}
|
||||
|
||||
private sealed class CmdWinSetProgress : CmdBase
|
||||
{
|
||||
public nint Window;
|
||||
public SDL.SDL_ProgressState State;
|
||||
public float Value;
|
||||
}
|
||||
|
||||
private sealed class CmdWinSetSize : CmdBase
|
||||
{
|
||||
public nint Window;
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace Robust.Client.Graphics
|
||||
[NotContentImplementable]
|
||||
public interface IClyde
|
||||
{
|
||||
internal bool IsInitialized { get; }
|
||||
|
||||
IClydeWindow MainWindow { get; }
|
||||
IRenderTarget MainWindowRenderTarget => MainWindow.RenderTarget;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Numerics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using SDL3;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
@@ -43,6 +44,8 @@ namespace Robust.Client.Graphics
|
||||
/// </summary>
|
||||
event Action<WindowResizedEventArgs> Resized;
|
||||
|
||||
internal void SetWindowProgress(WindowProgressState state, float value);
|
||||
|
||||
/// <summary>
|
||||
/// Set the active text input area in window pixel coordinates.
|
||||
/// </summary>
|
||||
@@ -68,6 +71,15 @@ namespace Robust.Client.Graphics
|
||||
void TextInputStop();
|
||||
}
|
||||
|
||||
internal enum WindowProgressState : byte
|
||||
{
|
||||
None = SDL.SDL_ProgressState.SDL_PROGRESS_STATE_NONE,
|
||||
Indeterminate = SDL.SDL_ProgressState.SDL_PROGRESS_STATE_INDETERMINATE,
|
||||
Normal = SDL.SDL_ProgressState.SDL_PROGRESS_STATE_NORMAL,
|
||||
Paused = SDL.SDL_ProgressState.SDL_PROGRESS_STATE_PAUSED,
|
||||
Error = SDL.SDL_ProgressState.SDL_PROGRESS_STATE_ERROR
|
||||
}
|
||||
|
||||
[NotContentImplementable]
|
||||
internal interface IClydeWindowInternal : IClydeWindow
|
||||
{
|
||||
|
||||
@@ -118,6 +118,13 @@ internal sealed class LoadingScreenManager : ILoadingScreenManager
|
||||
|
||||
_currentSectionName = sectionName;
|
||||
|
||||
if (_clyde.IsInitialized)
|
||||
{
|
||||
_clyde.MainWindow.SetWindowProgress(
|
||||
WindowProgressState.Normal,
|
||||
_currentSection / (float)_numberOfLoadingSections);
|
||||
}
|
||||
|
||||
if (!dontRender)
|
||||
{
|
||||
// This ensures that if the screen was resized or something the new size is properly updated to clyde.
|
||||
@@ -176,6 +183,8 @@ internal sealed class LoadingScreenManager : ILoadingScreenManager
|
||||
if (_currentSection != _numberOfLoadingSections)
|
||||
_sawmill.Error($"The number of seen loading sections isn't equal to the total number of loading sections! Seen: {_currentSection}, Total: {_numberOfLoadingSections}");
|
||||
|
||||
_clyde.MainWindow.SetWindowProgress(WindowProgressState.None, 1);
|
||||
|
||||
_finished = true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user