// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using System; using FlaxEditor.GUI.ContextMenu; using FlaxEngine; using FlaxEngine.GUI; namespace FlaxEditor.Viewport.Widgets { /// /// Viewport Widget Button class. /// /// [HideInEditor] public class ViewportWidgetButton : Control { private string _text; private SpriteHandle _icon; private ContextMenu _cm; private bool _checked; private bool _autoCheck; private bool _isMosueDown; /// /// Event fired when user toggles checked state. /// public event Action Toggled; /// /// Event fired when user click the button. /// public event Action Clicked; /// /// Gets or sets the text. /// public string Text { get => _text; set { _text = value; PerformLayout(); } } /// /// Gets or sets a value indicating whether this is checked. /// public bool Checked { get => _checked; set => _checked = value; } /// /// Initializes a new instance of the class. /// /// The text. /// The icon. /// The context menu. /// if set to true will be automatic checked on mouse click. public ViewportWidgetButton(string text, SpriteHandle icon, ContextMenu contextMenu = null, bool autoCheck = false) : base(0, 0, CalculateButtonWidth(0, icon.IsValid), ViewportWidgetsContainer.WidgetsHeight) { _text = text; _icon = icon; _cm = contextMenu; _autoCheck = autoCheck; if (_cm != null) _cm.VisibleChanged += CmOnVisibleChanged; } private void CmOnVisibleChanged(Control control) { if (_cm != null && !_cm.IsOpened) { if (HasParent && Parent.HasParent) { // Focus viewport Parent.Parent.Focus(); } } } private static float CalculateButtonWidth(float textWidth, bool hasIcon) { return (hasIcon ? ViewportWidgetsContainer.WidgetsIconSize : 0) + (textWidth > 0 ? textWidth + 8 : 0); } /// public override void Draw() { // Cache data var style = Style.Current; const float iconSize = ViewportWidgetsContainer.WidgetsIconSize; var iconRect = new Rectangle(0, (Height - iconSize) / 2, iconSize, iconSize); var textRect = new Rectangle(0, 0, Width + 1, Height + 1); // Check if is checked or mouse is over and auto check feature is enabled if (_checked) Render2D.FillRectangle(textRect, style.BackgroundSelected * (IsMouseOver ? 0.9f : 0.6f)); else if (_autoCheck && IsMouseOver) Render2D.FillRectangle(textRect, style.BackgroundHighlighted); // Check if has icon if (_icon.IsValid) { // Draw icon Render2D.DrawSprite(_icon, iconRect, style.Foreground); // Update text rectangle textRect.Location.X += iconSize; textRect.Size.X -= iconSize; } // Draw text Render2D.DrawText(style.FontMedium, _text, textRect, style.Foreground * (IsMouseOver ? 1.0f : 0.9f), TextAlignment.Center, TextAlignment.Center); } /// public override bool OnMouseDown(Vector2 location, MouseButton button) { if (button == MouseButton.Left) { _isMosueDown = true; } if (_autoCheck) { // Toggle Checked = !_checked; Toggled?.Invoke(this); } _cm?.Show(this, new Vector2(-1, Height + 2)); return base.OnMouseDown(location, button); } /// public override bool OnMouseUp(Vector2 location, MouseButton button) { if (button == MouseButton.Left && _isMosueDown) { _isMosueDown = false; Clicked?.Invoke(this); } return base.OnMouseUp(location, button); } /// public override void PerformLayout(bool force = false) { var style = Style.Current; if (style != null && style.FontMedium) Width = CalculateButtonWidth(style.FontMedium.MeasureText(_text).X, _icon.IsValid); } } }