// Copyright (c) 2012-2023 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;
}
///
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;
if (AutoCheck)
Checked = !Checked;
Clicked?.Invoke();
(Parent as ToolStrip)?.OnButtonClicked(this);
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 void OnMouseLeave()
{
_primaryMouseDown = false;
_secondaryMouseDown = false;
base.OnMouseLeave();
}
///
public override void OnLostFocus()
{
_primaryMouseDown = false;
_secondaryMouseDown = false;
base.OnLostFocus();
}
}
}