Files
SharpIDE/src/SharpIDE.Godot/IdeWindow.cs
2025-10-01 19:53:40 +10:00

103 lines
3.6 KiB
C#

using Godot;
using Microsoft.Build.Locator;
using Microsoft.Extensions.Hosting;
using SharpIDE.Application.Features.Events;
using SharpIDE.Godot.Features.IdeSettings;
using SharpIDE.Godot.Features.SlnPicker;
namespace SharpIDE.Godot;
/// <summary>
/// Used to hold either the main IDE scene or the solution picker scene
/// </summary>
public partial class IdeWindow : Control
{
private const string SlnPickerScenePath = "res://Features/SlnPicker/SlnPicker.tscn";
private const string IdeRootScenePath = "res://IdeRoot.tscn";
private PackedScene? _solutionPickerScene;
private PackedScene? _ideRootScene;
private IdeRoot? _ideRoot;
private SlnPicker? _slnPicker;
public override void _Ready()
{
ResourceLoader.LoadThreadedRequest(SlnPickerScenePath);
ResourceLoader.LoadThreadedRequest(IdeRootScenePath);
MSBuildLocator.RegisterDefaults();
GodotServiceDefaults.AddServiceDefaults();
Singletons.AppState = AppStateLoader.LoadAppStateFromConfigFile();
//GetWindow().SetMinSize(new Vector2I(1152, 648));
Callable.From(() => PickSolution(true)).CallDeferred();
}
public override void _ExitTree()
{
AppStateLoader.SaveAppStateToConfigFile(Singletons.AppState);
// GodotGlobalEvents.Instance = null!;
// GlobalEvents.Instance = null!;
// GC.Collect();
// GC.WaitForPendingFinalizers();
// GC.Collect();
// PrintOrphanNodes();
}
public void PickSolution(bool fullscreen = false)
{
if (_slnPicker is not null) throw new InvalidOperationException("Solution picker is already active");
_solutionPickerScene ??= (PackedScene)ResourceLoader.LoadThreadedGet(SlnPickerScenePath);
_slnPicker = _solutionPickerScene.Instantiate<SlnPicker>();
if (fullscreen)
{
AddChild(_slnPicker);
}
else
{
var popupWindow = GetNode<Window>("Window");
var windowSize = GetWindow().GetSize();
popupWindow.Size = windowSize with { X = windowSize.X / 2, Y = windowSize.Y / 2 };
popupWindow.Title = "Open Solution";
popupWindow.AddChild(_slnPicker);
popupWindow.Popup();
popupWindow.CloseRequested += () =>
{
popupWindow.Hide();
};
}
_ = Task.GodotRun(async () =>
{
var slnPathTask = _slnPicker.GetSelectedSolutionPath();
_ideRootScene ??= (PackedScene)ResourceLoader.LoadThreadedGet(IdeRootScenePath);
var ideRoot = _ideRootScene.Instantiate<IdeRoot>();
ideRoot.IdeWindow = this;
var slnPath = await slnPathTask;
if (slnPath is null)
{
ideRoot.QueueFree();
_slnPicker.QueueFree();
_slnPicker = null;
return;
}
ideRoot.SetSlnFilePath(slnPath);
Singletons.AppState.PreviouslyOpenedSolutions.Add(new PreviouslyOpenedSln { FilePath = slnPath, Name = Path.GetFileName(slnPath) });
await this.InvokeAsync(() =>
{
_slnPicker.GetParent().RemoveChild(_slnPicker);
_slnPicker.QueueFree();
_slnPicker = null;
if (_ideRoot is not null)
{
RemoveChild(_ideRoot);
_ideRoot.QueueFree();
}
else
{
GetWindow().Mode = Window.ModeEnum.Maximized;
}
_ideRoot = ideRoot;
AddChild(ideRoot);
});
});
}
}