From 1b2ebcb1e8e84a8f2a39cfe3f408ed902c2d3759 Mon Sep 17 00:00:00 2001 From: Matt Parker <61717342+MattParkerDev@users.noreply.github.com> Date: Fri, 12 Sep 2025 18:04:20 +1000 Subject: [PATCH] add reactive binding --- .../BottomPanel/BottomPanelManager.cs | 16 +- .../Features/Problems/ProblemEntry.cs | 8 + .../Features/Problems/ProblemEntry.cs.uid | 1 + .../Features/Problems/ProblemsPanel.cs | 30 ++ .../Features/Problems/ProblemsPanel.cs.uid | 1 + .../Features/Problems/ProblemsPanel.tscn | 25 +- .../Problems/ProblemsPanelProjectEntry.cs | 14 + .../Problems/ProblemsPanelProjectEntry.cs.uid | 1 + .../Problems/ProblemsPanelProjectEntry.tscn | 12 + src/SharpIDE.Godot/IdeRoot.cs | 4 + src/SharpIDE.Godot/IdeRoot.tscn | 1 + src/SharpIDE.Godot/NodeExtensions.cs | 32 ++- src/SharpIDE.Godot/SharpIDE.Godot.csproj | 4 + .../R3.Godot/FrameProviderDispatcher.cs | 33 +++ .../R3.Godot/FrameProviderDispatcher.cs.uid | 1 + .../addons/R3.Godot/GodotFrameProvider.cs | 80 ++++++ .../addons/R3.Godot/GodotFrameProvider.cs.uid | 1 + .../addons/R3.Godot/GodotNodeExtensions.cs | 32 +++ .../R3.Godot/GodotNodeExtensions.cs.uid | 1 + .../R3.Godot/GodotObservableExtensions.cs | 78 ++++++ .../R3.Godot/GodotObservableExtensions.cs.uid | 1 + .../R3.Godot/GodotProviderInitializer.cs | 21 ++ .../R3.Godot/GodotProviderInitializer.cs.uid | 1 + .../addons/R3.Godot/GodotR3Plugin.cs | 32 +++ .../addons/R3.Godot/GodotR3Plugin.cs.uid | 1 + .../addons/R3.Godot/GodotSignalMapper.cs | 261 ++++++++++++++++++ .../addons/R3.Godot/GodotSignalMapper.cs.uid | 1 + .../addons/R3.Godot/GodotTimeProvider.cs | 196 +++++++++++++ .../addons/R3.Godot/GodotTimeProvider.cs.uid | 1 + .../addons/R3.Godot/GodotUINodeExtensions.cs | 82 ++++++ .../R3.Godot/GodotUINodeExtensions.cs.uid | 1 + .../ObservableTrackerDebuggerPlugin.cs | 150 ++++++++++ .../ObservableTrackerDebuggerPlugin.cs.uid | 1 + .../R3.Godot/ObservableTrackerRuntimeHook.cs | 58 ++++ .../ObservableTrackerRuntimeHook.cs.uid | 1 + .../addons/R3.Godot/ObservableTrackerTab.cs | 146 ++++++++++ .../R3.Godot/ObservableTrackerTab.cs.uid | 1 + .../addons/R3.Godot/ObservableTrackerTree.cs | 67 +++++ .../R3.Godot/ObservableTrackerTree.cs.uid | 1 + src/SharpIDE.Godot/addons/R3.Godot/plugin.cfg | 8 + src/SharpIDE.Godot/project.godot | 9 + 41 files changed, 1411 insertions(+), 4 deletions(-) create mode 100644 src/SharpIDE.Godot/Features/Problems/ProblemEntry.cs create mode 100644 src/SharpIDE.Godot/Features/Problems/ProblemEntry.cs.uid create mode 100644 src/SharpIDE.Godot/Features/Problems/ProblemsPanel.cs create mode 100644 src/SharpIDE.Godot/Features/Problems/ProblemsPanel.cs.uid create mode 100644 src/SharpIDE.Godot/Features/Problems/ProblemsPanelProjectEntry.cs create mode 100644 src/SharpIDE.Godot/Features/Problems/ProblemsPanelProjectEntry.cs.uid create mode 100644 src/SharpIDE.Godot/Features/Problems/ProblemsPanelProjectEntry.tscn create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/FrameProviderDispatcher.cs create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/FrameProviderDispatcher.cs.uid create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotFrameProvider.cs create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotFrameProvider.cs.uid create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotNodeExtensions.cs create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotNodeExtensions.cs.uid create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotObservableExtensions.cs create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotObservableExtensions.cs.uid create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotProviderInitializer.cs create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotProviderInitializer.cs.uid create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotR3Plugin.cs create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotR3Plugin.cs.uid create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotSignalMapper.cs create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotSignalMapper.cs.uid create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotTimeProvider.cs create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotTimeProvider.cs.uid create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotUINodeExtensions.cs create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/GodotUINodeExtensions.cs.uid create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/ObservableTrackerDebuggerPlugin.cs create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/ObservableTrackerDebuggerPlugin.cs.uid create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/ObservableTrackerRuntimeHook.cs create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/ObservableTrackerRuntimeHook.cs.uid create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/ObservableTrackerTab.cs create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/ObservableTrackerTab.cs.uid create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/ObservableTrackerTree.cs create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/ObservableTrackerTree.cs.uid create mode 100644 src/SharpIDE.Godot/addons/R3.Godot/plugin.cfg diff --git a/src/SharpIDE.Godot/Features/BottomPanel/BottomPanelManager.cs b/src/SharpIDE.Godot/Features/BottomPanel/BottomPanelManager.cs index d6fe54c..7d56e39 100644 --- a/src/SharpIDE.Godot/Features/BottomPanel/BottomPanelManager.cs +++ b/src/SharpIDE.Godot/Features/BottomPanel/BottomPanelManager.cs @@ -1,13 +1,25 @@ using Godot; +using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence; +using SharpIDE.Godot.Features.Problems; namespace SharpIDE.Godot.Features.BottomPanel; public partial class BottomPanelManager : Panel { + public SharpIdeSolutionModel? Solution + { + get; + set + { + field = value; + _problemsPanel.Solution = value; + } + } + private Control _runPanel = null!; private Control _debugPanel = null!; private Control _buildPanel = null!; - private Control _problemsPanel = null!; + private ProblemsPanel _problemsPanel = null!; private Dictionary _panelTypeMap = []; @@ -16,7 +28,7 @@ public partial class BottomPanelManager : Panel _runPanel = GetNode("%RunPanel"); _debugPanel = GetNode("%DebugPanel"); _buildPanel = GetNode("%BuildPanel"); - _problemsPanel = GetNode("%ProblemsPanel"); + _problemsPanel = GetNode("%ProblemsPanel"); _panelTypeMap = new Dictionary { diff --git a/src/SharpIDE.Godot/Features/Problems/ProblemEntry.cs b/src/SharpIDE.Godot/Features/Problems/ProblemEntry.cs new file mode 100644 index 0000000..5fedc43 --- /dev/null +++ b/src/SharpIDE.Godot/Features/Problems/ProblemEntry.cs @@ -0,0 +1,8 @@ +using Godot; + +namespace SharpIDE.Godot.Features.Problems; + +public partial class ProblemEntry : Control +{ + +} \ No newline at end of file diff --git a/src/SharpIDE.Godot/Features/Problems/ProblemEntry.cs.uid b/src/SharpIDE.Godot/Features/Problems/ProblemEntry.cs.uid new file mode 100644 index 0000000..8119a60 --- /dev/null +++ b/src/SharpIDE.Godot/Features/Problems/ProblemEntry.cs.uid @@ -0,0 +1 @@ +uid://dkgiknux4rqit diff --git a/src/SharpIDE.Godot/Features/Problems/ProblemsPanel.cs b/src/SharpIDE.Godot/Features/Problems/ProblemsPanel.cs new file mode 100644 index 0000000..41c3d12 --- /dev/null +++ b/src/SharpIDE.Godot/Features/Problems/ProblemsPanel.cs @@ -0,0 +1,30 @@ +using System.Collections.Specialized; +using Godot; +using ObservableCollections; +using R3; +using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence; + +namespace SharpIDE.Godot.Features.Problems; + +public partial class ProblemsPanel : Control +{ + private PackedScene _problemsPanelProjectEntryScene = GD.Load("uid://do72lghjvfdp3"); + private VBoxContainer _vBoxContainer = null!; + // TODO: Use observable collections in the solution model and downwards + public SharpIdeSolutionModel? Solution { get; set; } + private readonly ObservableHashSet _projects = []; + + public override void _Ready() + { + Observable.EveryValueChanged(this, manager => manager.Solution) + .Where(s => s is not null) + .Subscribe(s => + { + GD.Print($"ProblemsPanel: Solution changed to {s?.Name ?? "null"}"); + _projects.Clear(); + _projects.AddRange(s!.AllProjects); + }); + _vBoxContainer = GetNode("ScrollContainer/VBoxContainer"); + _vBoxContainer.BindChildren(_projects, _problemsPanelProjectEntryScene); + } +} \ No newline at end of file diff --git a/src/SharpIDE.Godot/Features/Problems/ProblemsPanel.cs.uid b/src/SharpIDE.Godot/Features/Problems/ProblemsPanel.cs.uid new file mode 100644 index 0000000..76ad7ea --- /dev/null +++ b/src/SharpIDE.Godot/Features/Problems/ProblemsPanel.cs.uid @@ -0,0 +1 @@ +uid://b1r3no4u3khik diff --git a/src/SharpIDE.Godot/Features/Problems/ProblemsPanel.tscn b/src/SharpIDE.Godot/Features/Problems/ProblemsPanel.tscn index 1c30411..ff60dc8 100644 --- a/src/SharpIDE.Godot/Features/Problems/ProblemsPanel.tscn +++ b/src/SharpIDE.Godot/Features/Problems/ProblemsPanel.tscn @@ -1,4 +1,7 @@ -[gd_scene format=3 uid="uid://tqpmww430cor"] +[gd_scene load_steps=3 format=3 uid="uid://tqpmww430cor"] + +[ext_resource type="Script" uid="uid://b1r3no4u3khik" path="res://Features/Problems/ProblemsPanel.cs" id="1_bnenc"] +[ext_resource type="PackedScene" uid="uid://do72lghjvfdp3" path="res://Features/Problems/ProblemsPanelProjectEntry.tscn" id="2_xj8le"] [node name="ProblemsPanel" type="Control"] layout_mode = 3 @@ -7,3 +10,23 @@ anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 +script = ExtResource("1_bnenc") + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="ProblemsPanelProjectEntry" parent="ScrollContainer/VBoxContainer" instance=ExtResource("2_xj8le")] +layout_mode = 2 + +[node name="ProblemsPanelProjectEntry2" parent="ScrollContainer/VBoxContainer" instance=ExtResource("2_xj8le")] +layout_mode = 2 diff --git a/src/SharpIDE.Godot/Features/Problems/ProblemsPanelProjectEntry.cs b/src/SharpIDE.Godot/Features/Problems/ProblemsPanelProjectEntry.cs new file mode 100644 index 0000000..60d0235 --- /dev/null +++ b/src/SharpIDE.Godot/Features/Problems/ProblemsPanelProjectEntry.cs @@ -0,0 +1,14 @@ +using Godot; +using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence; + +namespace SharpIDE.Godot.Features.Problems; + +public partial class ProblemsPanelProjectEntry : MarginContainer +{ + public SharpIdeProjectModel Project { get; set; } = null!; + + public override void _Ready() + { + GetNode