// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using System; namespace FlaxEngine.GUI { /// /// The checkbox control states. /// public enum CheckBoxState { /// /// The default state. /// Default, /// /// The checked state. /// Checked, /// /// The intermediate state. /// Intermediate, } /// /// Check box control. /// /// public class CheckBox : Control { /// /// The mouse is down. /// protected bool _mouseDown; /// /// The current state. /// protected CheckBoxState _state; /// /// The mouse over box state. /// protected bool _mouseOverBox; /// /// The box size. /// protected float _boxSize; /// /// The box rectangle. /// protected Rectangle _box; /// /// Gets or sets the state of the checkbox. /// [EditorOrder(10)] public CheckBoxState State { get => _state; set { if (_state != value) { _state = value; StateChanged?.Invoke(this); } } } /// /// Gets or sets a value indicating whether this is checked. /// [NoSerialize, HideInEditor] public bool Checked { get => _state == CheckBoxState.Checked; set => State = value ? CheckBoxState.Checked : CheckBoxState.Default; } /// /// Gets or sets a value indicating whether this is in the intermediate state. /// [NoSerialize, HideInEditor] public bool Intermediate { get => _state == CheckBoxState.Intermediate; set => State = value ? CheckBoxState.Intermediate : CheckBoxState.Default; } /// /// Gets or sets the size of the box. /// public float BoxSize { get => _boxSize; set { _boxSize = value; CacheBox(); } } /// /// Gets or sets the color of the checkbox icon. /// [EditorDisplay("Style"), EditorOrder(2000)] public Color ImageColor { get; set; } /// /// Gets or sets the color of the border. /// [EditorDisplay("Style"), EditorOrder(2000)] public Color BorderColor { get; set; } /// /// Gets or sets the border color when checkbox is hovered. /// [EditorDisplay("Style"), EditorOrder(2000)] public Color BorderColorHighlighted { get; set; } /// /// Gets or sets the image used to render checkbox checked state. /// [EditorDisplay("Style"), EditorOrder(2000), Tooltip("The image used to render checkbox checked state.")] public IBrush CheckedImage { get; set; } /// /// Gets or sets the image used to render checkbox intermediate state. /// [EditorDisplay("Style"), EditorOrder(2000), Tooltip("The image used to render checkbox intermediate state.")] public IBrush IntermediateImage { get; set; } /// /// Event fired when 'checked' state gets changed. /// public event Action StateChanged; /// /// Initializes a new instance of the class. /// public CheckBox() : this(0, 0) { } /// /// Initializes a new instance of the class. /// /// The x. /// The y. /// if set to true set checked on start. /// The checkbox size. public CheckBox(float x, float y, bool isChecked = false, float size = 18) : base(x, y, size, size) { _state = isChecked ? CheckBoxState.Checked : CheckBoxState.Default; _boxSize = Mathf.Min(16.0f, size); var style = Style.Current; ImageColor = style.BorderSelected * 1.2f; BorderColor = style.BorderNormal; BorderColorHighlighted = style.BorderSelected; CheckedImage = new SpriteBrush(style.CheckBoxTick); IntermediateImage = new SpriteBrush(style.CheckBoxIntermediate); CacheBox(); } /// /// Toggles the checked state. /// public void Toggle() { Checked = !Checked; } private void CacheBox() { _box = new Rectangle(0, (Height - _boxSize) * 0.5f, _boxSize, _boxSize); } /// public override void Draw() { base.Draw(); bool enabled = EnabledInHierarchy; // Border Color borderColor = BorderColor; if (!enabled) borderColor *= 0.5f; else if (_mouseDown || _mouseOverBox) borderColor = BorderColorHighlighted; Render2D.DrawRectangle(_box.MakeExpanded(-2.0f), borderColor); // Icon if (_state != CheckBoxState.Default) { var color = ImageColor; if (!enabled) color *= 0.6f; if (_state == CheckBoxState.Checked) CheckedImage?.Draw(_box, color); else IntermediateImage?.Draw(_box, color); } } /// public override void OnMouseMove(Vector2 location) { base.OnMouseMove(location); _mouseOverBox = _box.Contains(ref location); } /// public override bool OnMouseDown(Vector2 location, MouseButton button) { if (button == MouseButton.Left) { // Set flag _mouseDown = true; Focus(); return true; } return base.OnMouseDown(location, button); } /// public override bool OnMouseUp(Vector2 location, MouseButton button) { if (button == MouseButton.Left && _mouseDown) { // Clear flag _mouseDown = false; // Check if mouse is still over the box if (_mouseOverBox) { Toggle(); Focus(); return true; } } return base.OnMouseUp(location, button); } /// public override void OnMouseLeave() { base.OnMouseLeave(); // Clear flags _mouseOverBox = false; _mouseDown = false; } /// protected override void OnSizeChanged() { base.OnSizeChanged(); CacheBox(); } } }