bind problems to tree view instead

This commit is contained in:
Matt Parker
2025-09-12 18:29:00 +10:00
parent 296dd306b4
commit b968443968
8 changed files with 96 additions and 69 deletions

View File

@@ -8,14 +8,18 @@ namespace SharpIDE.Godot.Features.Problems;
public partial class ProblemsPanel : Control
{
private PackedScene _problemsPanelProjectEntryScene = GD.Load<PackedScene>("uid://do72lghjvfdp3");
private VBoxContainer _vBoxContainer = null!;
// TODO: Use observable collections in the solution model and downwards
public SharpIdeSolutionModel? Solution { get; set; }
private Tree _tree = null!;
private TreeItem _rootItem = null!;
// TODO: Use observable collections in the solution model and downwards
private readonly ObservableHashSet<SharpIdeProjectModel> _projects = [];
public override void _Ready()
{
_tree = GetNode<Tree>("ScrollContainer/Tree");
_rootItem = _tree.CreateItem();
_rootItem.SetText(0, "Problems");
Observable.EveryValueChanged(this, manager => manager.Solution)
.Where(s => s is not null)
.Subscribe(s =>
@@ -24,8 +28,27 @@ public partial class ProblemsPanel : Control
_projects.Clear();
_projects.AddRange(s!.AllProjects);
});
_vBoxContainer = GetNode<VBoxContainer>("ScrollContainer/VBoxContainer");
_vBoxContainer.GetChildren().ToList().ForEach(c => c.QueueFree());
_vBoxContainer.BindChildren(_projects, _problemsPanelProjectEntryScene);
BindToTree(_projects);
}
public void BindToTree(ObservableHashSet<SharpIdeProjectModel> list)
{
var view = list.CreateView(x =>
{
var treeItem = _tree.CreateItem(_rootItem);
treeItem.SetText(0, x.Name);
Observable.EveryValueChanged(x, s => s.Diagnostics.Count)
.Subscribe(s => treeItem.Visible = s is not 0);
return treeItem;
});
view.ViewChanged += OnViewChanged;
}
private static void OnViewChanged(in SynchronizedViewChangedEventArgs<SharpIdeProjectModel, TreeItem> eventArgs)
{
GD.Print("View changed: " + eventArgs.Action);
if (eventArgs.Action == NotifyCollectionChangedAction.Remove)
{
eventArgs.OldItem.View.Free();
}
}
}

View File

@@ -1,7 +1,6 @@
[gd_scene load_steps=3 format=3 uid="uid://tqpmww430cor"]
[gd_scene load_steps=2 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
@@ -20,13 +19,8 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer"]
[node name="Tree" type="Tree" 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
hide_root = true

View File

@@ -1,19 +0,0 @@
using Godot;
using R3;
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<Label>("Label").Text = Project?.Name ?? "NULL";
if (Project is null) return;
Observable.EveryValueChanged(this, s => s.Project.Diagnostics.Count)
.Subscribe(s => Visible = s is not 0);
}
}

View File

@@ -1 +0,0 @@
uid://bx5v8rr87343o

View File

@@ -1,12 +0,0 @@
[gd_scene load_steps=2 format=3 uid="uid://do72lghjvfdp3"]
[ext_resource type="Script" uid="uid://bx5v8rr87343o" path="res://Features/Problems/ProblemsPanelProjectEntry.cs" id="1_2yh8u"]
[node name="ProblemsPanelProjectEntry" type="MarginContainer"]
offset_right = 40.0
offset_bottom = 40.0
script = ExtResource("1_2yh8u")
[node name="Label" type="Label" parent="."]
layout_mode = 2
text = "Project"

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" class="mud-icon-root mud-svg-icon mud-warning-text mud-icon-size-medium" focusable="false" viewBox="0 0 24 24" aria-hidden="true" role="img" style="fill: rgb(255, 168, 0);">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>
</svg>

After

Width:  |  Height:  |  Size: 364 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://pd3h5qfjn8pb"
path="res://.godot/imported/Warning.svg-95fb43666a11f922fb0317f6e4f8ece8.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Features/Problems/Resources/Warning.svg"
dest_files=["res://.godot/imported/Warning.svg-95fb43666a11f922fb0317f6e4f8ece8.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -8,28 +8,28 @@ namespace SharpIDE.Godot;
public static class ControlExtensions
{
extension(Control control)
{
public void BindChildren(ObservableHashSet<SharpIdeProjectModel> list, PackedScene scene)
{
var view = list.CreateView(x =>
{
var node = scene.Instantiate<ProblemsPanelProjectEntry>();
node.Project = x;
Callable.From(() => control.AddChild(node)).CallDeferred();
return node;
});
view.ViewChanged += OnViewChanged;
}
private static void OnViewChanged(in SynchronizedViewChangedEventArgs<SharpIdeProjectModel, ProblemsPanelProjectEntry> eventArgs)
{
GD.Print("View changed: " + eventArgs.Action);
if (eventArgs.Action == NotifyCollectionChangedAction.Remove)
{
eventArgs.OldItem.View.QueueFree();
}
}
}
// extension(Control control)
// {
// public void BindChildren(ObservableHashSet<SharpIdeProjectModel> list, PackedScene scene)
// {
// var view = list.CreateView(x =>
// {
// var node = scene.Instantiate<ProblemsPanelProjectEntry>();
// node.Project = x;
// Callable.From(() => control.AddChild(node)).CallDeferred();
// return node;
// });
// view.ViewChanged += OnViewChanged;
// }
// private static void OnViewChanged(in SynchronizedViewChangedEventArgs<SharpIdeProjectModel, ProblemsPanelProjectEntry> eventArgs)
// {
// GD.Print("View changed: " + eventArgs.Action);
// if (eventArgs.Action == NotifyCollectionChangedAction.Remove)
// {
// eventArgs.OldItem.View.QueueFree();
// }
// }
// }
}
public static class NodeExtensions