// Copyright (c) Wojciech Figat. All rights reserved. using System; using FlaxEngine; using FlaxEngine.GUI; namespace FlaxEditor.GUI { /// /// Tool strip button control. /// /// [HideInEditor] public class ToolStripButton : Control { /// /// The default margin for button parts (icon, text, etc.). /// public const int DefaultMargin = 2; private SpriteHandle _icon; private string _text; private bool _primaryMouseDown; private bool _secondaryMouseDown; /// /// Event fired when user clicks the button. /// public Action Clicked; /// /// Event fired when user clicks the button. /// public Action SecondaryClicked; /// /// The checked state. /// public bool Checked; /// /// The automatic check mode. /// public bool AutoCheck; /// /// Gets or sets the button text. /// public string Text { get => _text; set { _text = value; PerformLayout(); } } /// /// The icon. /// public SpriteHandle Icon { get => _icon; set { _icon = value; PerformLayout(); } } /// /// A reference to a context menu to raise when the secondary mouse button is pressed. /// public ContextMenu.ContextMenu ContextMenu; /// /// Initializes a new instance of the class. /// /// The height. /// The icon. public ToolStripButton(float height, ref SpriteHandle icon) : base(0, 0, height, height) { _icon = icon; } /// /// Sets the automatic check mode. /// /// True if use auto check, otherwise false. /// This button. public ToolStripButton SetAutoCheck(bool value) { AutoCheck = value; return this; } /// /// Sets the checked state. /// /// True if check it, otherwise false. /// This button. public ToolStripButton SetChecked(bool value) { Checked = value; return this; } /// /// Links the tooltip with input binding info. /// /// The text. /// The input key binding. /// This tooltip. public ToolStripButton LinkTooltip(string text, ref Options.InputBinding inputBinding) { var input = inputBinding.ToString(); if (input.Length != 0) text = $"{text} ({input})"; LinkTooltip(text); return this; } private void OnClicked() { if (AutoCheck) Checked = !Checked; Clicked?.Invoke(); (Parent as ToolStrip)?.OnButtonClicked(this); } /// public override void Draw() { base.Draw(); // Cache data var style = Style.Current; float iconSize = Height - DefaultMargin; var clientRect = new Rectangle(Float2.Zero, Size); var iconRect = new Rectangle(DefaultMargin, DefaultMargin, iconSize, iconSize); var textRect = new Rectangle(DefaultMargin, 0, 0, Height); bool enabled = EnabledInHierarchy; bool mouseButtonDown = _primaryMouseDown || _secondaryMouseDown; // Draw background if (enabled && (IsMouseOver || IsNavFocused || Checked)) Render2D.FillRectangle(clientRect, Checked ? style.BackgroundSelected : mouseButtonDown ? style.BackgroundHighlighted : (style.LightBackground * 1.3f)); // Draw icon if (_icon.IsValid) { Render2D.DrawSprite(_icon, iconRect, enabled ? style.Foreground : style.ForegroundDisabled); textRect.Location.X += iconSize + DefaultMargin; } // Draw text if (!string.IsNullOrEmpty(_text)) { textRect.Size.X = Width - DefaultMargin - textRect.Left; Render2D.DrawText(style.FontMedium, _text, textRect, enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Near, TextAlignment.Center); } } /// public override void PerformLayout(bool force = false) { var style = Style.Current; float iconSize = Height - DefaultMargin; bool hasSprite = _icon.IsValid; float width = DefaultMargin * 2; if (hasSprite) width += iconSize; if (!string.IsNullOrEmpty(_text) && style.FontMedium) width += style.FontMedium.MeasureText(_text).X + (hasSprite ? DefaultMargin : 0); Width = width; } /// public override bool OnMouseDown(Float2 location, MouseButton button) { if (button == MouseButton.Left) { _primaryMouseDown = true; Focus(); return true; } if (button == MouseButton.Right) { _secondaryMouseDown = true; Focus(); return true; } return base.OnMouseDown(location, button); } /// public override bool OnMouseUp(Float2 location, MouseButton button) { if (button == MouseButton.Left && _primaryMouseDown) { _primaryMouseDown = false; OnClicked(); return true; } if (button == MouseButton.Right && _secondaryMouseDown) { _secondaryMouseDown = false; SecondaryClicked?.Invoke(); (Parent as ToolStrip)?.OnSecondaryButtonClicked(this); ContextMenu?.Show(this, new Float2(0, Height)); return true; } return base.OnMouseUp(location, button); } /// public override bool OnMouseDoubleClick(Float2 location, MouseButton button) { if (button == MouseButton.Left) { OnClicked(); return true; } return false; } /// public override void OnMouseLeave() { _primaryMouseDown = false; _secondaryMouseDown = false; base.OnMouseLeave(); } /// public override void OnLostFocus() { _primaryMouseDown = false; _secondaryMouseDown = false; base.OnLostFocus(); } } }