add sln picker
This commit is contained in:
@@ -45,6 +45,11 @@ public partial class BottomPanelManager : Panel
|
||||
GodotGlobalEvents.BottomPanelTabSelected += OnBottomPanelTabSelected;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
GodotGlobalEvents.BottomPanelTabSelected -= OnBottomPanelTabSelected;
|
||||
}
|
||||
|
||||
private async Task OnBottomPanelTabSelected(BottomPanelType? type)
|
||||
{
|
||||
await this.InvokeAsync(() =>
|
||||
|
||||
26
src/SharpIDE.Godot/Features/SlnPicker/SlnPicker.cs
Normal file
26
src/SharpIDE.Godot/Features/SlnPicker/SlnPicker.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Godot;
|
||||
|
||||
namespace SharpIDE.Godot.Features.SlnPicker;
|
||||
|
||||
public partial class SlnPicker : Control
|
||||
{
|
||||
private FileDialog _fileDialog = null!;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_fileDialog = GetNode<FileDialog>("%FileDialog");
|
||||
}
|
||||
public async Task<string?> GetSelectedSolutionPath()
|
||||
{
|
||||
var tcs = new TaskCompletionSource<string?>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
await this.InvokeAsync(() =>
|
||||
{
|
||||
_fileDialog.FileSelected += path => tcs.SetResult(path);
|
||||
_fileDialog.Canceled += () => tcs.SetResult(null);
|
||||
_fileDialog.PopupCentered();
|
||||
});
|
||||
|
||||
var selectedPath = await tcs.Task;
|
||||
return selectedPath;
|
||||
}
|
||||
}
|
||||
1
src/SharpIDE.Godot/Features/SlnPicker/SlnPicker.cs.uid
Normal file
1
src/SharpIDE.Godot/Features/SlnPicker/SlnPicker.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bjvwb6jg6jpsi
|
||||
21
src/SharpIDE.Godot/Features/SlnPicker/SlnPicker.tscn
Normal file
21
src/SharpIDE.Godot/Features/SlnPicker/SlnPicker.tscn
Normal file
@@ -0,0 +1,21 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://cwvhbsd1mdl2x"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bjvwb6jg6jpsi" path="res://Features/SlnPicker/SlnPicker.cs" id="1_ciq0g"]
|
||||
|
||||
[node name="SlnPicker" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_ciq0g")
|
||||
|
||||
[node name="FileDialog" type="FileDialog" parent="."]
|
||||
unique_name_in_owner = true
|
||||
oversampling_override = 1.0
|
||||
title = "Open a File"
|
||||
file_mode = 0
|
||||
access = 2
|
||||
filters = PackedStringArray("*.sln,*.slnx;Solution Files")
|
||||
use_native_dialog = true
|
||||
@@ -15,6 +15,7 @@ namespace SharpIDE.Godot;
|
||||
|
||||
public partial class IdeRoot : Control
|
||||
{
|
||||
public IdeWindow IdeWindow { get; set; } = null!;
|
||||
private Button _openSlnButton = null!;
|
||||
private Button _buildSlnButton = null!;
|
||||
private FileDialog _fileDialog = null!;
|
||||
@@ -28,11 +29,9 @@ public partial class IdeRoot : Control
|
||||
private BottomPanelManager _bottomPanelManager = null!;
|
||||
|
||||
private readonly PackedScene _runMenuItemScene = ResourceLoader.Load<PackedScene>("res://Features/Run/RunMenuItem.tscn");
|
||||
private TaskCompletionSource _nodeReadyTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
public override void _Ready()
|
||||
{
|
||||
MSBuildLocator.RegisterDefaults();
|
||||
GodotServiceDefaults.AddServiceDefaults();
|
||||
|
||||
_openSlnButton = GetNode<Button>("%OpenSlnButton");
|
||||
_buildSlnButton = GetNode<Button>("%BuildSlnButton");
|
||||
_runMenuPopup = GetNode<Popup>("%RunMenuPopup");
|
||||
@@ -47,11 +46,12 @@ public partial class IdeRoot : Control
|
||||
|
||||
_runMenuButton.Pressed += OnRunMenuButtonPressed;
|
||||
GodotGlobalEvents.FileSelected += OnSolutionExplorerPanelOnFileSelected;
|
||||
_fileDialog.FileSelected += OnSlnFileSelected;
|
||||
_openSlnButton.Pressed += () => _fileDialog.Visible = true;
|
||||
_fileDialog.FileSelected += SetSlnFilePath;
|
||||
_openSlnButton.Pressed += IdeWindow.PickSolution;
|
||||
_buildSlnButton.Pressed += OnBuildSlnButtonPressed;
|
||||
GodotGlobalEvents.BottomPanelVisibilityChangeRequested += async show => await this.InvokeAsync(() => _invertedVSplitContainer.InvertedSetCollapsed(!show));
|
||||
OnSlnFileSelected(@"C:\Users\Matthew\Documents\Git\BlazorCodeBreaker\BlazorCodeBreaker.slnx");
|
||||
_nodeReadyTcs.SetResult();
|
||||
//OnSlnFileSelected(@"C:\Users\Matthew\Documents\Git\BlazorCodeBreaker\BlazorCodeBreaker.slnx");
|
||||
}
|
||||
|
||||
private void OnRunMenuButtonPressed()
|
||||
@@ -73,18 +73,23 @@ public partial class IdeRoot : Control
|
||||
await _codeEditorPanel.SetSharpIdeFile(file, fileLinePosition);
|
||||
}
|
||||
|
||||
private void OnSlnFileSelected(string path)
|
||||
public void SetSlnFilePath(string path)
|
||||
{
|
||||
_ = Task.GodotRun(async () =>
|
||||
{
|
||||
GD.Print($"Selected: {path}");
|
||||
var solutionModel = await VsPersistenceMapper.GetSolutionModel(path);
|
||||
await _nodeReadyTcs.Task;
|
||||
_solutionExplorerPanel.SolutionModel = solutionModel;
|
||||
_codeEditorPanel.Solution = solutionModel;
|
||||
_bottomPanelManager.Solution = solutionModel;
|
||||
_searchWindow.Solution = solutionModel;
|
||||
Callable.From(_solutionExplorerPanel.RepopulateTree).CallDeferred();
|
||||
RoslynAnalysis.StartSolutionAnalysis(solutionModel);
|
||||
|
||||
var infraProject = solutionModel.AllProjects.SingleOrDefault(s => s.Name == "WebUi");
|
||||
var diFile = infraProject?.Folders.Single(s => s.Name == "Pages").Files.Single(s => s.Name == "TestPage.razor");
|
||||
if (diFile != null) await this.InvokeDeferredAsync(() => GodotGlobalEvents.InvokeFileExternallySelected(diFile));
|
||||
|
||||
var tasks = solutionModel.AllProjects.Select(p => p.MsBuildEvaluationProjectTask).ToList();
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
@@ -100,13 +105,6 @@ public partial class IdeRoot : Control
|
||||
}
|
||||
_runMenuButton.Disabled = false;
|
||||
});
|
||||
|
||||
var infraProject = solutionModel.AllProjects.Single(s => s.Name == "WebUi");
|
||||
var diFile = infraProject.Folders.Single(s => s.Name == "Pages").Files.Single(s => s.Name == "TestPage.razor");
|
||||
await this.InvokeDeferredAsync(() => GodotGlobalEvents.InvokeFileExternallySelected(diFile));
|
||||
|
||||
//var runnableProject = solutionModel.AllProjects.First(s => s.IsRunnable);
|
||||
//await this.InvokeAsync(() => _runPanel.NewRunStarted(runnableProject));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
63
src/SharpIDE.Godot/IdeWindow.cs
Normal file
63
src/SharpIDE.Godot/IdeWindow.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using Ardalis.GuardClauses;
|
||||
using Godot;
|
||||
using Microsoft.Build.Locator;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
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 readonly PackedScene _solutionPickerScene = ResourceLoader.Load<PackedScene>("res://Features/SlnPicker/SlnPicker.tscn");
|
||||
private readonly PackedScene _ideRootScene = ResourceLoader.Load<PackedScene>("res://IdeRoot.tscn");
|
||||
|
||||
private IdeRoot? _ideRoot;
|
||||
private SlnPicker? _slnPicker;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
MSBuildLocator.RegisterDefaults();
|
||||
GodotServiceDefaults.AddServiceDefaults();
|
||||
|
||||
PickSolution();
|
||||
}
|
||||
|
||||
public void PickSolution()
|
||||
{
|
||||
if (_slnPicker is not null) throw new InvalidOperationException("Solution picker is already active");
|
||||
_slnPicker = _solutionPickerScene.Instantiate<SlnPicker>();
|
||||
AddChild(_slnPicker);
|
||||
_ = Task.GodotRun(async () =>
|
||||
{
|
||||
var slnPathTask = _slnPicker.GetSelectedSolutionPath();
|
||||
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);
|
||||
|
||||
await this.InvokeAsync(() =>
|
||||
{
|
||||
RemoveChild(_slnPicker);
|
||||
_slnPicker.QueueFree();
|
||||
_slnPicker = null;
|
||||
if (_ideRoot is not null)
|
||||
{
|
||||
RemoveChild(_ideRoot);
|
||||
_ideRoot.QueueFree();
|
||||
}
|
||||
_ideRoot = ideRoot;
|
||||
AddChild(ideRoot);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
1
src/SharpIDE.Godot/IdeWindow.cs.uid
Normal file
1
src/SharpIDE.Godot/IdeWindow.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bul4kkrg1yhqx
|
||||
12
src/SharpIDE.Godot/IdeWindow.tscn
Normal file
12
src/SharpIDE.Godot/IdeWindow.tscn
Normal file
@@ -0,0 +1,12 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://b70jhun5a4las"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bul4kkrg1yhqx" path="res://IdeWindow.cs" id="1_3do1e"]
|
||||
|
||||
[node name="IdeWindow" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_3do1e")
|
||||
@@ -36,6 +36,13 @@ public static class NodeExtensions
|
||||
{
|
||||
extension(Node node)
|
||||
{
|
||||
public void ClearChildren()
|
||||
{
|
||||
foreach (var child in node.GetChildren())
|
||||
{
|
||||
child.QueueFree();
|
||||
}
|
||||
}
|
||||
public Task<T> InvokeAsync<T>(Func<T> workItem)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<T>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
@@ -11,7 +11,7 @@ config_version=5
|
||||
[application]
|
||||
|
||||
config/name="SharpIDE.Godot"
|
||||
run/main_scene="uid://b2oniigcp5ew5"
|
||||
run/main_scene="uid://b70jhun5a4las"
|
||||
config/features=PackedStringArray("4.5", "C#", "Forward Plus")
|
||||
run/max_fps=157
|
||||
run/low_processor_mode=true
|
||||
|
||||
Reference in New Issue
Block a user