diff --git a/ILSpy/Assets/Icons/Literal.svg b/ILSpy/Assets/Icons/Literal.svg
new file mode 100644
index 000000000..45c0171e7
--- /dev/null
+++ b/ILSpy/Assets/Icons/Literal.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/ILSpy/Images.cs b/ILSpy/Images.cs
index 4a5d7439d..d9969966f 100644
--- a/ILSpy/Images.cs
+++ b/ILSpy/Images.cs
@@ -107,6 +107,7 @@ namespace ILSpy.Images
public static readonly IImage Field = LoadSvg(nameof(Field));
public static readonly IImage Property = LoadSvg(nameof(Property));
public static readonly IImage Event = LoadSvg(nameof(Event));
+ public static readonly IImage Literal = LoadSvg(nameof(Literal));
// Reference overlays (small badge layered onto a base icon for TypeRef/MemberRef nodes).
internal static readonly IImage ReferenceOverlay = LoadSvg(nameof(ReferenceOverlay));
diff --git a/ILSpy/Search/SearchPane.axaml b/ILSpy/Search/SearchPane.axaml
index 08af2edeb..2ebb4bca9 100644
--- a/ILSpy/Search/SearchPane.axaml
+++ b/ILSpy/Search/SearchPane.axaml
@@ -9,15 +9,39 @@
+ PlaceholderText="Search for t:TypeName, m:Member or c:Constant; use exact match (=term), 'should not contain' (-term) or 'must contain' (+term); use /reg(ular)?Ex(pressions)?/ or both - t:/Type(Name)?/..."
+ ToolTip.Tip="Search"
+ Text="{Binding SearchTerm, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
+
+
+
+
+
+ MinWidth="180">
-
+
+
+
+
+
diff --git a/ILSpy/Search/SearchPane.axaml.cs b/ILSpy/Search/SearchPane.axaml.cs
index 08e48bcb2..6b2dbba83 100644
--- a/ILSpy/Search/SearchPane.axaml.cs
+++ b/ILSpy/Search/SearchPane.axaml.cs
@@ -20,6 +20,7 @@ using System;
using Avalonia.Controls;
using Avalonia.Input;
+using Avalonia.Interactivity;
using Avalonia.Threading;
using ICSharpCode.ILSpyX.Search;
@@ -37,6 +38,17 @@ namespace ILSpy.Search
SearchResults.KeyDown += OnResultKeyDown;
}
+ void OnClearSearchClicked(object? sender, RoutedEventArgs e)
+ {
+ // Empty the query and return focus to the input so the user can start typing
+ // straight away. Setting SearchTerm = "" triggers the same cancel-and-restart
+ // path as deleting the text by hand.
+ if (DataContext is SearchPaneModel vm)
+ vm.SearchTerm = string.Empty;
+ SearchInput.Focus();
+ e.Handled = true;
+ }
+
protected override void OnDataContextChanged(EventArgs e)
{
base.OnDataContextChanged(e);
diff --git a/ILSpy/Search/SearchPaneModel.cs b/ILSpy/Search/SearchPaneModel.cs
index 82d16c624..8eed545f5 100644
--- a/ILSpy/Search/SearchPaneModel.cs
+++ b/ILSpy/Search/SearchPaneModel.cs
@@ -20,6 +20,8 @@ using System;
using System.Collections.ObjectModel;
using System.Composition;
+using Avalonia.Media;
+
using CommunityToolkit.Mvvm.ComponentModel;
using ICSharpCode.ILSpyX;
@@ -36,12 +38,14 @@ namespace ILSpy.Search
///
/// One entry in the search-mode picker. The determines which
/// ICSharpCode.ILSpyX.Search strategy runs when the user types a query;
- /// is the label rendered in the ComboBox.
+ /// is the label rendered in the ComboBox and
+ /// is the icon shown alongside it (both in the dropdown and in the closed selector).
///
public sealed class SearchModeEntry
{
public required SearchMode Mode { get; init; }
public required string Name { get; init; }
+ public required IImage Image { get; init; }
}
[Export]
@@ -71,18 +75,18 @@ namespace ILSpy.Search
/// strings so users moving between builds see the same labels.
///
public SearchModeEntry[] SearchModes { get; } = new[] {
- new SearchModeEntry { Mode = SearchMode.TypeAndMember, Name = "Types and Members" },
- new SearchModeEntry { Mode = SearchMode.Type, Name = "Type" },
- new SearchModeEntry { Mode = SearchMode.Member, Name = "Member" },
- new SearchModeEntry { Mode = SearchMode.Method, Name = "Method" },
- new SearchModeEntry { Mode = SearchMode.Field, Name = "Field" },
- new SearchModeEntry { Mode = SearchMode.Property, Name = "Property" },
- new SearchModeEntry { Mode = SearchMode.Event, Name = "Event" },
- new SearchModeEntry { Mode = SearchMode.Literal, Name = "Constant" },
- new SearchModeEntry { Mode = SearchMode.Token, Name = "Metadata Token" },
- new SearchModeEntry { Mode = SearchMode.Resource, Name = "Resource" },
- new SearchModeEntry { Mode = SearchMode.Assembly, Name = "Assembly" },
- new SearchModeEntry { Mode = SearchMode.Namespace, Name = "Namespace" },
+ new SearchModeEntry { Mode = SearchMode.TypeAndMember, Name = "Types and Members", Image = Images.Images.Library },
+ new SearchModeEntry { Mode = SearchMode.Type, Name = "Type", Image = Images.Images.Class },
+ new SearchModeEntry { Mode = SearchMode.Member, Name = "Member", Image = Images.Images.Property },
+ new SearchModeEntry { Mode = SearchMode.Method, Name = "Method", Image = Images.Images.Method },
+ new SearchModeEntry { Mode = SearchMode.Field, Name = "Field", Image = Images.Images.Field },
+ new SearchModeEntry { Mode = SearchMode.Property, Name = "Property", Image = Images.Images.Property },
+ new SearchModeEntry { Mode = SearchMode.Event, Name = "Event", Image = Images.Images.Event },
+ new SearchModeEntry { Mode = SearchMode.Literal, Name = "Constant", Image = Images.Images.Literal },
+ new SearchModeEntry { Mode = SearchMode.Token, Name = "Metadata Token", Image = Images.Images.Library },
+ new SearchModeEntry { Mode = SearchMode.Resource, Name = "Resource", Image = Images.Images.Resource },
+ new SearchModeEntry { Mode = SearchMode.Assembly, Name = "Assembly", Image = Images.Images.Assembly },
+ new SearchModeEntry { Mode = SearchMode.Namespace, Name = "Namespace", Image = Images.Images.Namespace },
};
///