Vibe search feature

This commit is contained in:
2026-09-29 18:21:21 +00:00
committed by JonathanMcCaffrey
parent 4e7fc73ebb
commit 3bcdd359a9
6 changed files with 115 additions and 61663 deletions
@@ -4,7 +4,7 @@ sessionId: session-260928-112553-atgt
# Delivery Steps
### * Step 1: Implementation
### ✓ Step 1: Implementation
<plan_session_history>
History processor: During the current session, you have worked on the following `<previous_issue>`.
The `<issue_description>` usually continues or extends your previous work. Consider all `<previous_issue>` and `<issue_description>` together.
@@ -59,6 +59,18 @@ System.TypeLoadException: Method 'get_HasExplicitSafeAreaEdges' in type 'Microso
tool name: submit
tool parameters:
</previous_issue_solution>
<previous_issue>
## Orchestrated Plan Task
implement according to the plan
</previous_issue>
<previous_issue>
## Plan Task
Add a search feature to the editor that will highlight matching nodes in the ZeroSpace.MapEditor
</previous_issue>
<previous_issue_solution>
tool name: submit
tool parameters:
</previous_issue_solution>
</plan_session_history>
<plan_task>
-61660
View File
File diff suppressed because one or more lines are too long
@@ -27,4 +27,6 @@ public sealed class MapNode
}
public bool IsSelected { get; set; }
public bool IsHighlighted { get; set; }
}
@@ -58,11 +58,18 @@ public sealed class MapDrawable : IDrawable
canvas.FillColor = ColorForKind(node.Doc.Kind);
canvas.FillCircle(center, radius);
if (node.IsHighlighted)
{
canvas.StrokeColor = Color.FromArgb("#FFD700");
canvas.StrokeSize = 3;
canvas.DrawCircle(center, radius + 4);
}
if (node.IsSelected)
{
canvas.StrokeColor = Colors.White;
canvas.StrokeSize = 3;
canvas.DrawCircle(center, radius + 6);
canvas.DrawCircle(center, node.IsHighlighted ? radius + 8 : radius + 6);
}
}
}
@@ -10,6 +10,11 @@
<Button Text="+" WidthRequest="44" Clicked="OnZoomInClicked" />
<Button Text="−" WidthRequest="44" Clicked="OnZoomOutClicked" />
<Button Text="Reset View" Clicked="OnResetViewClicked" />
<SearchBar x:Name="SearchControl"
Placeholder="Search systems..."
WidthRequest="220"
TextChanged="OnSearchTextChanged"
SearchButtonPressed="OnSearchButtonPressed" />
<Label x:Name="StatusLabel"
Text="No folder loaded."
VerticalOptions="Center"
@@ -82,6 +82,84 @@ public partial class MapEditorPage : ContentPage
FitView();
}
private void CenterOnNode(MapNode node)
{
var width = MapView.Width;
var height = MapView.Height;
if (width > 0 && height > 0)
{
_drawable.OffsetX = width / 2 - node.X * _drawable.Scale;
_drawable.OffsetY = height / 2 - node.Y * _drawable.Scale;
MapView.Invalidate();
}
}
// ----- search -----
private void OnSearchTextChanged(object? sender, TextChangedEventArgs e) => ApplySearch(e.NewTextValue);
private void OnSearchButtonPressed(object? sender, EventArgs e)
{
ApplySearch(SearchControl.Text);
FocusFirstMatch();
}
private void ApplySearch(string? query)
{
var trimmed = query?.Trim();
if (string.IsNullOrEmpty(trimmed))
{
foreach (var node in _nodes)
{
node.IsHighlighted = false;
}
if (_folder is not null)
{
StatusLabel.Text = $"{_nodes.Count} systems loaded from {_folder}.";
}
else
{
StatusLabel.Text = "No folder loaded.";
}
MapView.Invalidate();
return;
}
var matchCount = 0;
foreach (var node in _nodes)
{
var isMatch = node.Doc.Name.Contains(trimmed, StringComparison.OrdinalIgnoreCase);
node.IsHighlighted = isMatch;
if (isMatch)
{
matchCount++;
}
}
if (matchCount == 0)
{
StatusLabel.Text = $"No systems matching '{trimmed}'.";
}
else
{
StatusLabel.Text = $"Found {matchCount} matching system{(matchCount == 1 ? string.Empty : "s")}.";
}
MapView.Invalidate();
}
private void FocusFirstMatch()
{
var match = _nodes.FirstOrDefault(static n => n.IsHighlighted);
if (match is not null)
{
Select(match);
CenterOnNode(match);
}
}
// ----- pointer interaction -----
private MapNode? HitTest(Point screen)
@@ -321,7 +399,15 @@ public partial class MapEditorPage : ContentPage
FitView();
Preferences.Set("MapEditorFolder", folder);
UpdateDirtyState();
StatusLabel.Text = $"{_nodes.Count} systems loaded from {folder}.";
if (!string.IsNullOrWhiteSpace(SearchControl.Text))
{
ApplySearch(SearchControl.Text);
}
else
{
StatusLabel.Text = $"{_nodes.Count} systems loaded from {folder}.";
}
}
private async void OnOpenFolderClicked(object? sender, EventArgs e)