From 425008d4537adaff1e7e90adc62711355bd5d572 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 10 May 2026 08:07:22 +0200 Subject: [PATCH] Plain-click mutex chip = single-select, Shift+click = add MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Default click on a value chip in a flags-filter mutex group now collapses the selection to {value} — the file-manager / Excel intuition. Shift+click keeps the existing additive multi-toggle behaviour. Plain click on the chip clears the filter for the group. Assisted-by: Claude:claude-opus-4-7:Claude Code --- ILSpy/Controls/FlagsFilterPopup.cs | 11 +++++++++++ ILSpy/Controls/MutexChipGroup.cs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/ILSpy/Controls/FlagsFilterPopup.cs b/ILSpy/Controls/FlagsFilterPopup.cs index 4cb8df4b5..f93b41a8a 100644 --- a/ILSpy/Controls/FlagsFilterPopup.cs +++ b/ILSpy/Controls/FlagsFilterPopup.cs @@ -65,6 +65,17 @@ namespace ILSpy.Views.Filters stack.Children.Add(independentGroup); } + // Hint text in the same style as the live filter summary below — just a quiet + // italic line explaining the chip click semantics so users don't have to guess. + var chipHint = new TextBlock { + Text = "Click a chip to select only that value · Shift+Click to add to / remove from the selection · Click to clear", + FontStyle = FontStyle.Italic, + Foreground = Brushes.Gray, + TextWrapping = TextWrapping.Wrap, + Margin = new Thickness(0, 6, 0, 0), + }; + stack.Children.Add(chipHint); + summary = new TextBlock { FontStyle = FontStyle.Italic, Foreground = Brushes.Gray, diff --git a/ILSpy/Controls/MutexChipGroup.cs b/ILSpy/Controls/MutexChipGroup.cs index d65286c22..457aaa31f 100644 --- a/ILSpy/Controls/MutexChipGroup.cs +++ b/ILSpy/Controls/MutexChipGroup.cs @@ -24,6 +24,8 @@ using System.Linq; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; +using Avalonia.Input; +using Avalonia.Interactivity; using Avalonia.Layout; using Avalonia.Media; @@ -67,6 +69,16 @@ namespace ILSpy.Views.Filters // the synthetic zero entry "(none)" so its purpose stays obvious. var chip = MakeChip(v.Label); chip.IsCheckedChanged += (_, _) => OnValueToggled(v.Value); + // Plain click → "select only this" (single-select). Shift+Click falls through + // to the ToggleButton's default toggle, which feeds OnValueToggled and lets + // the user build / trim an additive multi-select set. + var capturedValue = v.Value; + chip.AddHandler(InputElement.PointerPressedEvent, (_, e) => { + if ((e.KeyModifiers & KeyModifiers.Shift) != 0) + return; // additive: keep ToggleButton's default toggle behaviour + SelectOnly(capturedValue); + e.Handled = true; + }, RoutingStrategies.Tunnel); valueChips[v.Value] = chip; wrap.Children.Add(chip); } @@ -122,6 +134,24 @@ namespace ILSpy.Views.Filters state.SetMutexSelection(group.Name, selection); } + void SelectOnly(uint value) + { + // Single-chip selection — collapse the group to {value}. We bypass the + // "all checked == any" / "none checked == any" collapse rules in + // OnValueToggled because Ctrl/Shift+click is an explicit narrow-down + // gesture; the user picked exactly one chip and wants exactly one. + suppress = true; + try + { + anyChip.IsChecked = false; + foreach (var (v, chip) in valueChips) + chip.IsChecked = v == value; + } + finally + { suppress = false; } + state.SetMutexSelection(group.Name, ImmutableHashSet.Create(value)); + } + void ResetToAny() { suppress = true;