using System; using Robust.Client.Utility; using Robust.Shared.ViewVariables; namespace Robust.Client.UserInterface.Controls { /// /// Base class for a generic UI button. /// /// /// /// [ControlWrap("BaseButton")] public abstract class BaseButton : Control { private bool _attemptingPress; private bool _beingHovered; private bool _disabled; private bool _pressed; protected BaseButton() { } protected BaseButton(string name) : base(name) { } /// /// Controls mode of operation in relation to press/release events. /// [ViewVariables] public ActionMode Mode { get; set; } = ActionMode.Release; /// /// Whether the button is disabled. /// If a button is disabled, it appears greyed out and cannot be interacted with. /// [ViewVariables] public bool Disabled { get => _disabled; set { var old = _disabled; _disabled = value; if (old != value) { DrawModeChanged(); } } } /// /// Whether the button is currently toggled down. Only applies when is true. /// [ViewVariables] public bool Pressed { get => _pressed; set { if (_pressed == value) { return; } _pressed = value; DrawModeChanged(); } } /// /// If true, this button functions as a toggle, not as a regular push button. /// [ViewVariables] public bool ToggleMode { get; set; } /// /// If true, this button is currently being hovered over by the mouse. /// [ViewVariables] public bool IsHovered => _beingHovered; /// /// Draw mode used for styling of buttons. /// [ViewVariables] public DrawModeEnum DrawMode { get { if (Disabled) { return DrawModeEnum.Disabled; } if (Pressed || _attemptingPress) { return DrawModeEnum.Pressed; } if (IsHovered) { return DrawModeEnum.Hover; } return DrawModeEnum.Normal; } } /// /// Fired when the button is pushed down by the mouse. /// public event Action OnButtonDown; /// /// Fired when the button is released by the mouse. /// public event Action OnButtonUp; /// /// Fired when the button is "pressed". When this happens depends on . /// public event Action OnPressed; /// /// If is set, fired when the button is toggled up or down. /// public event Action OnToggled; protected virtual void DrawModeChanged() { } protected internal override void MouseDown(GUIMouseButtonEventArgs args) { base.MouseDown(args); if (Disabled) { return; } var buttonEventArgs = new ButtonEventArgs(this); OnButtonDown?.Invoke(buttonEventArgs); var drawMode = DrawMode; if (Mode == ActionMode.Release) { _attemptingPress = true; } else { if (ToggleMode) { _pressed = !_pressed; OnPressed?.Invoke(buttonEventArgs); OnToggled?.Invoke(new ButtonToggledEventArgs(Pressed, this)); } else { _attemptingPress = true; OnPressed?.Invoke(buttonEventArgs); } } if (drawMode != DrawMode) { DrawModeChanged(); } } protected internal override void MouseUp(GUIMouseButtonEventArgs args) { base.MouseUp(args); if (Disabled) { return; } var buttonEventArgs = new ButtonEventArgs(this); OnButtonUp?.Invoke(buttonEventArgs); var drawMode = DrawMode; if (Mode == ActionMode.Release && _attemptingPress) { if (ToggleMode) { _pressed = !_pressed; } OnPressed?.Invoke(buttonEventArgs); if (ToggleMode) { OnToggled?.Invoke(new ButtonToggledEventArgs(Pressed, this)); } } _attemptingPress = false; if (drawMode != DrawMode) { DrawModeChanged(); } } protected internal override void MouseEntered() { base.MouseEntered(); var drawMode = DrawMode; _beingHovered = true; if (drawMode != DrawMode) { DrawModeChanged(); } } protected internal override void MouseExited() { base.MouseExited(); var drawMode = DrawMode; _beingHovered = false; if (drawMode != DrawMode) { DrawModeChanged(); } } public enum DrawModeEnum { Normal = 0, Pressed = 1, Hover = 2, Disabled = 3, } public class ButtonEventArgs : EventArgs { /// /// The button this event originated from. /// public BaseButton Button { get; } public ButtonEventArgs(BaseButton button) { Button = button; } } /// /// Fired when a is toggled. /// public class ButtonToggledEventArgs : ButtonEventArgs { /// /// The new pressed state of the button. /// public bool Pressed { get; } public ButtonToggledEventArgs(bool pressed, BaseButton button) : base(button) { Pressed = pressed; } } private protected override void SetGodotProperty(string property, object value, GodotAssetScene context) { base.SetGodotProperty(property, value, context); switch (property) { case "toggle_mode": ToggleMode = (bool) value; break; case "disabled": Disabled = (bool) value; break; } } /// /// For use with . /// public enum ActionMode { /// /// fires when the mouse button causing them is pressed down. /// Press = 0, /// /// fires when the mouse button causing them is released. /// This is the default and most intuitive method. /// Release = 1, } } }