namespace UIWidgets.Menu { using System.ComponentModel; using System.Runtime.CompilerServices; using UIWidgets.l10n; using UnityEngine; #if ENABLE_INPUT_SYSTEM using UnityEngine.InputSystem; #endif /// /// Menu item. /// public class MenuItem : IObservable, INotifyPropertyChanged { string name; /// /// Name. /// public string Name { get { return name; } set { if (name != value) { name = value; NotifyPropertyChanged("Name"); } } } string template; /// /// Template. /// public string Template { get { return template; } set { if (template != value) { template = value; NotifyPropertyChanged("Template"); } } } bool isChecked; /// /// Checked. /// public bool Checked { get { return isChecked; } set { if (isChecked != value) { isChecked = value; NotifyPropertyChanged("Checked"); } } } Sprite icon; /// /// Icon. /// public Sprite Icon { get { return icon; } set { if (icon != value) { icon = value; NotifyPropertyChanged("Icon"); } } } HotKey hotKey; /// /// Hot Key. /// public HotKey HotKey { get { return hotKey; } set { if (hotKey != value) { DestroyInputAction(); hotKey = value; CreateHotKeyAction(); NotifyPropertyChanged("HotKey"); } } } bool visible = true; /// /// Is item visible? /// public bool Visible { get { return visible; } set { if (visible != value) { visible = value; NotifyPropertyChanged("Visible"); } } } bool interactable = true; /// /// Is item interactable? /// public bool Interactable { get { return interactable; } set { if (interactable != value) { interactable = value; NotifyPropertyChanged("Interactable"); } } } object tag; /// /// Icon. /// public object Tag { get { return tag; } set { if (tag != value) { tag = value; NotifyPropertyChanged("Tag"); } } } ObservableList items; /// /// Nested items. /// public ObservableList Items { get { return items; } set { if (items == value) { return; } if (items != null) { items.OnCollectionChange -= ItemsChanged; } items = value; if (items != null) { items.OnCollectionChange += ItemsChanged; } NotifyPropertyChanged("Items"); } } MenuItemAction action = new MenuItemAction(); /// /// Action. /// public MenuItemAction Action { get { return action; } set { if (action != value) { action = value; NotifyPropertyChanged("Action"); } } } /// /// Has visible items? /// public bool HasVisibleItems { get { if (Items == null) { return false; } for (int i = 0; i < Items.Count; i++) { if (Items[i].Visible) { return true; } } return false; } } /// /// Property changed event. /// public event OnChange OnChange; /// /// Property changed event. /// public event PropertyChangedEventHandler PropertyChanged; /// /// Initializes a new instance of the class. /// public MenuItem() { Items = new ObservableList(); } /// /// Items changed. /// protected void ItemsChanged() { NotifyPropertyChanged("Items"); } /// /// Property changed. /// /// Property name. protected void NotifyPropertyChanged(string propertyName) { var c_handlers = OnChange; if (c_handlers != null) { c_handlers(); } var handlers = PropertyChanged; if (handlers != null) { handlers(this, new PropertyChangedEventArgs(propertyName)); } } #if ENABLE_INPUT_SYSTEM /// /// HotKey action. /// protected InputAction HotKeyAction; #endif /// /// Is hot key enabled. /// Supported for the InputSystem only. /// public bool IsEnabledHotKey { get { #if ENABLE_INPUT_SYSTEM if (HotKeyAction == null) { return false; } return HotKeyAction.enabled; #else return false; #endif } } /// /// Enable hot key. /// Supported for the InputSystem only. /// public void EnableHotKey() { #if ENABLE_INPUT_SYSTEM if (HotKeyAction == null) { CreateHotKeyAction(); } if (HotKeyAction != null) { HotKeyAction.Enable(); } #endif } /// /// Disable hot key. /// Supported for the InputSystem only. /// public void DisableHotKey() { #if ENABLE_INPUT_SYSTEM if (HotKeyAction == null) { return; } HotKeyAction.Disable(); #endif } /// /// Destroy current HotKey action. /// protected virtual void DestroyInputAction() { #if ENABLE_INPUT_SYSTEM if (HotKeyAction != null) { HotKeyAction.Disable(); HotKeyAction.Dispose(); HotKeyAction = null; } #endif } /// /// Create HotKey action. /// protected virtual void CreateHotKeyAction() { #if ENABLE_INPUT_SYSTEM if (!hotKey.Valid) { return; } HotKeyAction = new InputAction(Name); var group = CompatibilityInput.KeysGroup(hotKey.Key); if (hotKey.Modifiers > 0) { InputActionSetupExtensions.CompositeSyntax composite; if (hotKey.Modifiers == 3) { composite = HotKeyAction.AddCompositeBinding("CustomButtonWithThreeModifiers"); composite = composite.With("Modifier1", "/Ctrl"); composite = composite.With("Modifier2", "/Alt"); composite = composite.With("Modifier3", "/Shift"); } else if (hotKey.Modifiers == 2) { composite = HotKeyAction.AddCompositeBinding("ButtonWithTwoModifiers"); var index = 1; if (hotKey.Ctrl) { composite = composite.With(string.Format("Modifier{0}", index.ToString()), "/Ctrl"); index += 1; } if (hotKey.Alt) { composite = composite.With(string.Format("Modifier{0}", index.ToString()), "/Alt"); index += 1; } if (hotKey.Shift) { composite = composite.With(string.Format("Modifier{0}", index.ToString()), "/Shift"); index += 1; } } else { composite = HotKeyAction.AddCompositeBinding("ButtonWithOneModifier"); if (hotKey.Ctrl) { composite = composite.With("Modifier", "/Ctrl"); } else if (hotKey.Alt) { composite = composite.With("Modifier", "/Alt"); } else if (hotKey.Shift) { composite = composite.With("Modifier", "/Shift"); } } for (int i = 0; i < group.Keys.Length; i++) { composite = composite.With("Button", string.Format("/{0}", Key2String(group.Keys[i]))); } } else { for (int i = 0; i < group.Keys.Length; i++) { HotKeyAction.AddBinding(string.Format("/{0}", Key2String(group.Keys[i]))); } } HotKeyAction.performed += InvokeAction; #endif } #if ENABLE_INPUT_SYSTEM /// /// InputSystem key to string. /// /// Key. /// String. protected virtual string Key2String(Key key) { switch (key) { case Key.Digit0: return "0"; case Key.Digit1: return "1"; case Key.Digit2: return "2"; case Key.Digit3: return "3"; case Key.Digit4: return "4"; case Key.Digit5: return "5"; case Key.Digit6: return "6"; case Key.Digit7: return "7"; case Key.Digit8: return "8"; case Key.Digit9: return "9"; } return EnumHelper.ToString(key); } /// /// Invoke action. /// /// Context. protected virtual void InvokeAction(InputAction.CallbackContext context) { if (Visible && Interactable) { Action.Invoke(this); } } #endif } }