diff --git a/src/Artemis.UI.Shared/Controls/Flyouts/MaterialIconPickerFlyout.cs b/src/Artemis.UI.Shared/Controls/Flyouts/MaterialIconPickerFlyout.cs
index cf220336d..99321b5e0 100644
--- a/src/Artemis.UI.Shared/Controls/Flyouts/MaterialIconPickerFlyout.cs
+++ b/src/Artemis.UI.Shared/Controls/Flyouts/MaterialIconPickerFlyout.cs
@@ -19,7 +19,20 @@ public sealed class MaterialIconPickerFlyout : Flyout
protected override Control CreatePresenter()
{
_picker ??= new MaterialIconPicker.MaterialIconPicker();
- PickerFlyoutPresenter presenter = new() {Content = MaterialIconPicker};
+ _picker.Flyout = this;
+ FlyoutPresenter presenter = new() {Content = MaterialIconPicker};
return presenter;
}
+
+ #region Overrides of FlyoutBase
+
+ ///
+ protected override void OnClosed()
+ {
+ if (_picker != null)
+ _picker.Flyout = null;
+ base.OnClosed();
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Controls/MaterialIconPicker/MaterialIconPicker.cs b/src/Artemis.UI.Shared/Controls/MaterialIconPicker/MaterialIconPicker.cs
index e1e65c9fa..5777b21de 100644
--- a/src/Artemis.UI.Shared/Controls/MaterialIconPicker/MaterialIconPicker.cs
+++ b/src/Artemis.UI.Shared/Controls/MaterialIconPicker/MaterialIconPicker.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Reactive.Linq;
using System.Text.RegularExpressions;
using System.Windows.Input;
+using Artemis.UI.Shared.Flyouts;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
@@ -28,16 +29,35 @@ public partial class MaterialIconPicker : TemplatedControl
public static readonly StyledProperty ValueProperty =
AvaloniaProperty.Register(nameof(Value), defaultBindingMode: BindingMode.TwoWay);
+ ///
+ /// Gets the command to execute when deleting stops.
+ ///
+ public static readonly DirectProperty SelectIconProperty =
+ AvaloniaProperty.RegisterDirect(nameof(SelectIcon), g => g.SelectIcon);
+
+ private readonly ICommand _selectIcon;
+ private ItemsRepeater? _iconsContainer;
+
private SourceList? _iconsSource;
private TextBox? _searchBox;
private IDisposable? _sub;
- private ItemsRepeater? _iconsContainer;
- private readonly ICommand _selectIcon;
+ private readonly Dictionary _enumNames;
///
public MaterialIconPicker()
{
- _selectIcon = ReactiveCommand.Create(i => Value = i);
+ _selectIcon = ReactiveCommand.Create(i =>
+ {
+ Value = i;
+ Flyout?.Hide();
+ });
+
+ // Build a list of enum names and values, this is required because a value may have more than one name
+ _enumNames = new Dictionary();
+ MaterialIconKind[] values = Enum.GetValues();
+ string[] names = Enum.GetNames();
+ for (int index = 0; index < names.Length; index++)
+ _enumNames[names[index]] = values[index];
}
///
@@ -49,12 +69,6 @@ public partial class MaterialIconPicker : TemplatedControl
set => SetValue(ValueProperty, value);
}
- ///
- /// Gets the command to execute when deleting stops.
- ///
- public static readonly DirectProperty SelectIconProperty =
- AvaloniaProperty.RegisterDirect(nameof(SelectIcon), g => g.SelectIcon);
-
///
/// Gets the command to execute when deleting stops.
///
@@ -64,16 +78,14 @@ public partial class MaterialIconPicker : TemplatedControl
private init => SetAndRaise(SelectIconProperty, ref _selectIcon, value);
}
- #region Overrides of TemplatedControl
+ internal MaterialIconPickerFlyout? Flyout { get; set; }
- ///
- protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ private void Setup()
{
- _searchBox = e.NameScope.Find("SearchBox");
- _iconsContainer = e.NameScope.Find("IconsContainer");
- if (_iconsContainer == null)
+ if (_searchBox == null || _iconsContainer == null)
return;
+ // Build a list of values, they are not unique because a value with multiple names occurs once per name
_iconsSource = new SourceList();
_iconsSource.AddRange(Enum.GetValues().Distinct());
_sub = _iconsSource.Connect()
@@ -84,6 +96,25 @@ public partial class MaterialIconPicker : TemplatedControl
_iconsContainer.ItemsSource = icons;
}
+ #region Overrides of TemplatedControl
+
+ ///
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ _searchBox = e.NameScope.Find("SearchBox");
+ _iconsContainer = e.NameScope.Find("IconsContainer");
+
+ Setup();
+ base.OnApplyTemplate(e);
+ }
+
+ ///
+ protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
+ {
+ Setup();
+ base.OnAttachedToLogicalTree(e);
+ }
+
///
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
{
@@ -91,6 +122,9 @@ public partial class MaterialIconPicker : TemplatedControl
_iconsSource = null;
_sub?.Dispose();
_sub = null;
+
+ if (_searchBox != null)
+ _searchBox.Text = "";
base.OnDetachedFromLogicalTree(e);
}
@@ -99,8 +133,11 @@ public partial class MaterialIconPicker : TemplatedControl
if (string.IsNullOrWhiteSpace(text))
return _ => true;
+ // Strip out whitespace and find all matching enum values
text = StripWhiteSpaceRegex().Replace(text, "");
- return data => data.ToString().Contains(text, StringComparison.InvariantCultureIgnoreCase);
+ HashSet values = _enumNames.Where(n => n.Key.Contains(text, StringComparison.OrdinalIgnoreCase)).Select(n => n.Value).ToHashSet();
+ // Only show those that matched
+ return data => values.Contains(data);
}
[GeneratedRegex("\\s+")]
diff --git a/src/Artemis.UI.Shared/Controls/MaterialIconPicker/MaterialIconPickerButton.cs b/src/Artemis.UI.Shared/Controls/MaterialIconPicker/MaterialIconPickerButton.cs
index c05b7d74d..53c751ac3 100644
--- a/src/Artemis.UI.Shared/Controls/MaterialIconPicker/MaterialIconPickerButton.cs
+++ b/src/Artemis.UI.Shared/Controls/MaterialIconPicker/MaterialIconPickerButton.cs
@@ -31,7 +31,7 @@ public class MaterialIconPickerButton : TemplatedControl
/// Gets or sets the desired flyout placement.
///
public static readonly StyledProperty PlacementProperty =
- AvaloniaProperty.Register(nameof(Placement));
+ AvaloniaProperty.Register(nameof(Placement), PlacementMode.BottomEdgeAlignedLeft);
private Button? _button;
private MaterialIconPickerFlyout? _flyout;
@@ -79,14 +79,21 @@ public class MaterialIconPickerButton : TemplatedControl
if (_flyout == null)
return;
- // Logic here is taken from Fluent Avalonia's ColorPicker which also reuses the same control since it's large
- _flyout.MaterialIconPicker.Value = Value;
-
- _flyout.Placement = Placement;
- _flyout.ShowAt(_button != null ? _button : this);
- _flyoutActive = true;
-
+ MaterialIconPickerFlyout flyout = new();
+ flyout.FlyoutPresenterClasses.Add("material-icon-picker-presenter");
+ flyout.MaterialIconPicker.Value = Value;
+ flyout.Placement = Placement;
+
+ flyout.Closed += FlyoutOnClosed;
+ flyout.ShowAt(this);
FlyoutOpened?.Invoke(this, EventArgs.Empty);
+
+ void FlyoutOnClosed(object? closedSender, EventArgs closedEventArgs)
+ {
+ Value = flyout.MaterialIconPicker.Value;
+ flyout.Closed -= FlyoutOnClosed;
+ FlyoutClosed?.Invoke(this, EventArgs.Empty);
+ }
}
#region Overrides of TemplatedControl
diff --git a/src/Artemis.UI.Shared/Styles/Controls/GradientPickerButton.axaml b/src/Artemis.UI.Shared/Styles/Controls/GradientPickerButton.axaml
index 13f5ae0a5..75aafc057 100644
--- a/src/Artemis.UI.Shared/Styles/Controls/GradientPickerButton.axaml
+++ b/src/Artemis.UI.Shared/Styles/Controls/GradientPickerButton.axaml
@@ -28,7 +28,6 @@
-