naps2/NAPS2.Lib/EtoForms/MenuProvider.cs
2023-12-06 20:17:50 -08:00

107 lines
2.6 KiB
C#

using Eto.Forms;
namespace NAPS2.EtoForms;
public class MenuProvider
{
private readonly List<Item> _items = [];
public MenuProvider Dynamic(ListProvider<Command> commandListProvider)
{
_items.Add(new DynamicItem
{
CommandListProvider = commandListProvider ?? throw new ArgumentNullException(nameof(commandListProvider))
});
commandListProvider.OnChanged += () => ContentsChanged?.Invoke();
return this;
}
public MenuProvider Append(Command? command)
{
if (command == null)
{
return this;
}
_items.Add(new CommandItem
{
Command = command
});
return this;
}
public MenuProvider Separator()
{
_items.Add(new SeparatorItem());
return this;
}
public MenuProvider SubMenu(Command command, MenuProvider subMenu)
{
_items.Add(new SubMenuItem
{
Command = command ?? throw new ArgumentNullException(nameof(command)),
MenuProvider = subMenu
});
return this;
}
private event Action? ContentsChanged;
public class Item
{
}
private class DynamicItem : Item
{
public ListProvider<Command> CommandListProvider { get; init; } = null!;
}
public class CommandItem : Item
{
public Command Command { get; init; } = null!;
}
public class SubMenuItem : Item
{
public Command Command { get; init; } = null!;
public MenuProvider MenuProvider { get; init; } = null!;
}
public class SeparatorItem : Item
{
}
private List<Item> GetSubItems()
{
var actualItems = new List<Item>();
Item? lastItem = null;
foreach (var item in _items)
{
if (item is DynamicItem dynamicItem)
{
var dynamicItemValues =
dynamicItem.CommandListProvider.Value.Select(x => new CommandItem
{
Command = x
}).ToList();
if (dynamicItemValues.Any())
{
actualItems.AddRange(dynamicItemValues);
lastItem = item;
}
}
else if (item is not SeparatorItem || (lastItem != null && lastItem is not SeparatorItem))
{
actualItems.Add(item);
lastItem = item;
}
}
return actualItems;
}
public void Handle(Action<List<Item>> subItemsHandler)
{
subItemsHandler(GetSubItems());
ContentsChanged += () => subItemsHandler(GetSubItems());
}
}