Files
FlaxEngine/Source/Editor/GUI/ToolStripButton.cs
envision3d 39f4c00135 add play button actions, number of players
- add context menu support for toolstrip buttons
- add "Play Game" vs. "Play Scenes"
- add context menu for choosing play button action to toolstrip button
- add number of game client selection for cook & run
- add context menu for cook & run to toolstrip button
- add menu items for the above
- add editor option entries for saving user preferences for the above
2023-06-28 02:02:10 -05:00

245 lines
7.2 KiB
C#

// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System;
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.GUI
{
/// <summary>
/// Tool strip button control.
/// </summary>
/// <seealso cref="FlaxEngine.GUI.Control" />
[HideInEditor]
public partial class ToolStripButton : Control
{
// TODO: abstracted for potential future in-editor input configuration (ex. for left handed mouse users)
private const MouseButton PRIMARY_MOUSE_BUTTON = MouseButton.Left;
private const MouseButton SECONDARY_MOUSE_BUTTON = MouseButton.Right;
/// <summary>
/// The default margin for button parts (icon, text, etc.).
/// </summary>
public const int DefaultMargin = 2;
private SpriteHandle _icon;
private string _text;
private bool _primaryMouseDown;
private bool _secondaryMouseDown;
/// <summary>
/// Event fired when user clicks the button.
/// </summary>
public Action PrimaryClicked;
/// <summary>
/// Event fired when user clicks the button.
/// </summary>
public Action SecondaryClicked;
/// <summary>
/// The checked state.
/// </summary>
public bool Checked;
/// <summary>
/// The automatic check mode.
/// </summary>
public bool AutoCheck;
/// <summary>
/// Gets or sets the button text.
/// </summary>
public string Text
{
get => _text;
set
{
_text = value;
PerformLayout();
}
}
/// <summary>
/// The icon.
/// </summary>
public SpriteHandle Icon
{
get => _icon;
set
{
_icon = value;
PerformLayout();
}
}
/// <summary>
/// A reference to a context menu to raise when the secondary mouse button is pressed.
/// </summary>
public ContextMenu.ContextMenu ContextMenu;
/// <summary>
/// Initializes a new instance of the <see cref="ToolStripButton"/> class.
/// </summary>
/// <param name="height">The height.</param>
/// <param name="icon">The icon.</param>
public ToolStripButton(float height, ref SpriteHandle icon)
: base(0, 0, height, height)
{
_icon = icon;
}
/// <summary>
/// Sets the automatic check mode.
/// </summary>
/// <param name="value">True if use auto check, otherwise false.</param>
/// <returns>This button.</returns>
public ToolStripButton SetAutoCheck(bool value)
{
AutoCheck = value;
return this;
}
/// <summary>
/// Sets the checked state.
/// </summary>
/// <param name="value">True if check it, otherwise false.</param>
/// <returns>This button.</returns>
public ToolStripButton SetChecked(bool value)
{
Checked = value;
return this;
}
/// <inheritdoc />
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);
}
}
/// <inheritdoc />
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;
}
/// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button)
{
if (button == PRIMARY_MOUSE_BUTTON)
{
// Set flag
_primaryMouseDown = true;
Focus();
return true;
}
else if (button == SECONDARY_MOUSE_BUTTON)
{
// Set flag
_secondaryMouseDown = true;
Focus();
return true;
}
return base.OnMouseDown(location, button);
}
/// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button)
{
if (button == PRIMARY_MOUSE_BUTTON && _primaryMouseDown)
{
// Clear flag
_primaryMouseDown = false;
// Fire events
if (AutoCheck)
Checked = !Checked;
PrimaryClicked?.Invoke();
(Parent as ToolStrip)?.OnButtonPrimaryClicked(this);
return true;
}
else if (button == SECONDARY_MOUSE_BUTTON && _secondaryMouseDown)
{
// Clear flag
_secondaryMouseDown = false;
SecondaryClicked?.Invoke();
(Parent as ToolStrip)?.OnButtonSecondaryClicked(this);
ContextMenu?.Show(this, new Float2(0, Height));
return true;
}
return base.OnMouseUp(location, button);
}
/// <inheritdoc />
public override void OnMouseLeave()
{
// Clear flag
_primaryMouseDown = false;
_secondaryMouseDown = false;
base.OnMouseLeave();
}
/// <inheritdoc />
public override void OnLostFocus()
{
// Clear flag
_primaryMouseDown = false;
_secondaryMouseDown = false;
base.OnLostFocus();
}
}
}