diff --git a/OpenDreamClient/Interface/Descriptors/MenuDescriptors.cs b/OpenDreamClient/Interface/Descriptors/MenuDescriptors.cs index 555b3c638d..c908df301a 100644 --- a/OpenDreamClient/Interface/Descriptors/MenuDescriptors.cs +++ b/OpenDreamClient/Interface/Descriptors/MenuDescriptors.cs @@ -48,6 +48,14 @@ public string? Category { [DataField("can-check")] public bool CanCheck { get; private set; } + [DataField("is-checked")] + public bool IsChecked { get; set; } + + [DataField("group")] + public string? Group { get; private set; } + [DataField("index")] + public int Index { get; private set; } + public MenuElementDescriptor WithCategory(ISerializationManager serialization, string category) { var copy = serialization.CreateCopy(this, notNullableOverride: true); diff --git a/OpenDreamClient/Interface/InterfaceMenu.cs b/OpenDreamClient/Interface/InterfaceMenu.cs index cd98515bad..f1edfcb19e 100644 --- a/OpenDreamClient/Interface/InterfaceMenu.cs +++ b/OpenDreamClient/Interface/InterfaceMenu.cs @@ -23,6 +23,17 @@ public InterfaceMenu(MenuDescriptor descriptor) : base(descriptor) { CreateMenu(); } + public void SetGroupChecked(string group, string id) { + foreach (MenuElement menuElement in MenuElements.Values) { + if (menuElement.ElementDescriptor is not MenuElementDescriptor menuElementDescriptor) + continue; + + if (menuElementDescriptor.Group == group) { + menuElementDescriptor.IsChecked = menuElementDescriptor.Id == id; + } + } + } + public override void AddChild(ElementDescriptor descriptor) { if (descriptor is not MenuElementDescriptor elementDescriptor) throw new ArgumentException($"Attempted to add a {descriptor} to a menu", nameof(descriptor)); @@ -80,7 +91,6 @@ public sealed class MenuElement : InterfaceElement { private MenuElementDescriptor MenuElementDescriptor => (MenuElementDescriptor) ElementDescriptor; public string? Category => MenuElementDescriptor.Category; public string Command => MenuElementDescriptor.Command; - private readonly InterfaceMenu _menu; public MenuElement(MenuElementDescriptor data, InterfaceMenu menu) : base(data) { @@ -106,16 +116,53 @@ public MenuBar.MenuEntry CreateMenuEntry() { if (String.IsNullOrEmpty(text)) return new MenuBar.MenuSeparator(); + if(MenuElementDescriptor.CanCheck) + if(MenuElementDescriptor.IsChecked) + text = text + " ☑"; + MenuBar.MenuButton menuButton = new() { Text = text }; - //result.IsCheckable = MenuElementDescriptor.CanCheck; - if (!String.IsNullOrEmpty(Command)) - menuButton.OnPressed += () => { EntitySystem.Get().RunCommand(Command); }; + + menuButton.OnPressed += () => { + if(MenuElementDescriptor.CanCheck) + if(!String.IsNullOrEmpty(MenuElementDescriptor.Group)) + _menu.SetGroupChecked(MenuElementDescriptor.Group, MenuElementDescriptor.Id); + else + MenuElementDescriptor.IsChecked = !MenuElementDescriptor.IsChecked; + _menu.CreateMenu(); + if(!string.IsNullOrEmpty(MenuElementDescriptor.Command)) + EntitySystem.Get().RunCommand(Command); + }; return menuButton; } + public override bool TryGetProperty(string property, out string value) { + switch (property) { + case "command": + value = Command; + return true; + case "category": + value = Category ?? ""; + return true; + case "can-check": + value = MenuElementDescriptor.CanCheck.ToString(); + return true; + case "is-checked": + value = MenuElementDescriptor.IsChecked.ToString(); + return true; + case "group": + value = MenuElementDescriptor.Group ?? ""; + return true; + case "index": + value = MenuElementDescriptor.Index.ToString(); + return true; + default: + return base.TryGetProperty(property, out value); + } + } + public override void AddChild(ElementDescriptor descriptor) { // Set the child's category to this element // TODO: The "parent" and "category" attributes seem to be treated differently in BYOND; not the same thing.