Updating ProjectBrowser

This commit is contained in:
2026-02-04 19:08:18 +09:00
parent 59991f47d5
commit eadd13931f
30 changed files with 382 additions and 139 deletions

View File

@@ -0,0 +1,95 @@
using Ghost.Editor.Core.Utilities;
using Microsoft.UI.Xaml.Controls;
using System.Reflection;
using System.Runtime.InteropServices;
namespace Ghost.Editor.Core.Controls;
public sealed partial class ContextFlyout : MenuFlyout
{
private bool _isPopulated;
public string Tag
{
get; set;
} = string.Empty;
public ContextFlyout()
{
Opening += ContextFlyout_Opening;
}
private void PopulateContextMenu()
{
var methods = TypeCache.GetMethodsWithAttribute<ContextMenuItemAttribute>();
if (methods == null)
{
return;
}
var list = new List<(ContextMenuItemAttribute attr, MethodInfo method)>();
foreach (var method in methods)
{
var attributes = method.GetCustomAttributes(typeof(ContextMenuItemAttribute), false);
var attribute = (ContextMenuItemAttribute)attributes[0];
if (!string.Equals(attribute.Tag, Tag, StringComparison.OrdinalIgnoreCase))
{
continue;
}
list.Add((attribute, method));
}
var span = CollectionsMarshal.AsSpan(list);
span.Sort((a, b) =>
{
var result = a.attr.Group.CompareTo(b.attr.Group);
if (result == 0)
{
result = string.CompareOrdinal(a.attr.Name, b.attr.Name);
}
return result;
});
// itemContainer may be a main thread only collection (for example, ObservableCollection), we run it on the UI thread
var i = 0;
var group = 0;
while (i < list.Count)
{
var (attr, method) = list[i];
if (attr.Group != group)
{
Items.Add(new MenuFlyoutSeparator());
group = attr.Group;
}
// TODO: Group items with / in the name into submenus
var menuItem = new MenuFlyoutItem
{
Text = attr.Name
};
menuItem.Click += (_, _) =>
{
method.Invoke(null, null);
};
Items.Add(menuItem);
i++;
}
}
private async void ContextFlyout_Opening(object? sender, object e)
{
if (_isPopulated)
{
return;
}
PopulateContextMenu();
_isPopulated = true;
}
}