From 9e852e5e879084155aadf5a7d8f41bc227be1a26 Mon Sep 17 00:00:00 2001 From: Matt Parker <61717342+MattParkerDev@users.noreply.github.com> Date: Tue, 27 Jan 2026 22:39:22 +1000 Subject: [PATCH] Fix rendering error underlines --- .../Features/CodeEditor/SharpIdeCodeEdit.cs | 10 +++- .../Features/CodeEditor/SharpIdeCodeEdit.tscn | 6 +++ src/SharpIDE.Godot/NodeExtensions.cs | 47 +++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.cs b/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.cs index c7307d0..8c36bac 100644 --- a/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.cs +++ b/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.cs @@ -35,6 +35,8 @@ public partial class SharpIdeCodeEdit : CodeEdit private CustomHighlighter _syntaxHighlighter = new(); private PopupMenu _popupMenu = null!; + private CanvasItem _aboveCanvasItem = null!; + private Rid? _aboveCanvasItemRid = null!; private ImmutableArray _fileDiagnostics = []; private ImmutableArray _fileAnalyzerDiagnostics = []; @@ -63,6 +65,9 @@ public partial class SharpIdeCodeEdit : CodeEdit { SyntaxHighlighter = _syntaxHighlighter; _popupMenu = GetNode("CodeFixesMenu"); + _aboveCanvasItem = GetNode("%AboveCanvasItem"); + _aboveCanvasItemRid = _aboveCanvasItem.GetCanvasItem(); + RenderingServer.Singleton.CanvasItemSetParent(_aboveCanvasItemRid.Value, GetCanvasItem()); _popupMenu.IdPressed += OnCodeFixSelected; CustomCodeCompletionRequested.Subscribe(OnCodeCompletionRequested); CodeFixesRequested += OnCodeFixesRequested; @@ -363,8 +368,9 @@ public partial class SharpIdeCodeEdit : CodeEdit { endPos.X += 10; } - DrawDashedLine(startPos, endPos, color, thickness); - //DrawLine(startPos, endPos, color, thickness); + + RenderingServer.Singleton.CanvasItemClear(_aboveCanvasItemRid!.Value); + RenderingServer.Singleton.DrawDashedLine(_aboveCanvasItemRid!.Value, startPos, endPos, color, thickness); } public override void _Draw() { diff --git a/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.tscn b/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.tscn index 07bb8ea..f6ea40c 100644 --- a/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.tscn +++ b/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.tscn @@ -43,3 +43,9 @@ size = Vector2i(217, 100) item_count = 1 item_0/text = "Getting Context Actions..." item_0/id = 0 + +[node name="AboveCanvasItem" type="Control" parent="." unique_id=650087366] +unique_name_in_owner = true +anchors_preset = 0 +offset_right = 40.0 +offset_bottom = 40.0 diff --git a/src/SharpIDE.Godot/NodeExtensions.cs b/src/SharpIDE.Godot/NodeExtensions.cs index 6482871..94d721a 100644 --- a/src/SharpIDE.Godot/NodeExtensions.cs +++ b/src/SharpIDE.Godot/NodeExtensions.cs @@ -40,6 +40,53 @@ public class RequiresGodotUiThreadAttribute : Attribute public static class NodeExtensions { + extension(RenderingServerInstance renderingServerInstance) + { + // https://github.com/godotengine/godot/blob/a4bbad2ba8a8ecd4e756e49de5c83666f12a9bd5/scene/main/canvas_item.cpp#L717 + public void DrawDashedLine(Rid canvasItemRid, Vector2 from, Vector2 to, Color color, float width = -1.0f, float dash = 2.0f, bool aligned = true, bool antialiased = false) + { + if (dash <= 0.0f) + { + GD.PushError("draw_dashed_line: dash length must be greater than 0"); + return; + } + + var length = (to - from).Length(); + var step = dash * (to - from).Normalized(); + + if (length < dash || step == Vector2.Zero) + { + renderingServerInstance.CanvasItemAddLine(canvasItemRid, from, to, color, width, antialiased); + return; + } + + int steps = aligned ? Mathf.CeilToInt(length / dash) : Mathf.FloorToInt(length / dash); + if (steps % 2 == 0) + { + steps--; + } + + var off = from; + if (aligned) + { + off += (to - from).Normalized() * (length - steps * dash) / 2.0f; + } + + //Span points = steps <= 128 ? stackalloc Vector2[steps + 1] : new Vector2[steps + 1]; + Span points = stackalloc Vector2[steps + 1]; + for (var i = 0; i < steps; i += 2) + { + points[i] = (i == 0) ? from : off; + points[i + 1] = (aligned && i == steps - 1) ? to : (off + step); + off += step * 2; + } + + ReadOnlySpan colors = stackalloc Color[1] { color }; + + renderingServerInstance.CanvasItemAddMultiline(canvasItemRid, points, colors, width, antialiased); + } + } + extension(TreeItem treeItem) { public T? GetTypedMetadata(int column) where T : RefCounted?