This repository has been archived on 2023-07-11. You can view files and clone it, but cannot push or open issues or pull requests.
gwen-dotnet/Gwen/Control/Button.cs

319 lines
8.7 KiB
C#
Raw Normal View History

using System;
using Gwen.Input;
namespace Gwen.Control
{
/// <summary>
/// Button control.
/// </summary>
public class Button : Label
{
private bool m_Depressed;
private bool m_Toggle;
private bool m_ToggleStatus;
private bool m_CenterImage;
private ImagePanel m_Image;
/// <summary>
/// Invoked when the button is released.
/// </summary>
public event GwenEventHandler Clicked;
/// <summary>
/// Invoked when the button is pressed.
/// </summary>
public event GwenEventHandler Pressed;
/// <summary>
/// Invoked when the button is released.
/// </summary>
public event GwenEventHandler Released;
/// <summary>
/// Invoked when the button's toggle state has changed.
/// </summary>
public event GwenEventHandler Toggled;
/// <summary>
/// Invoked when the button's toggle state has changed to On.
/// </summary>
public event GwenEventHandler ToggledOn;
/// <summary>
/// Invoked when the button's toggle state has changed to Off.
/// </summary>
public event GwenEventHandler ToggledOff;
/// <summary>
/// Invoked when the button has been double clicked.
/// </summary>
public event GwenEventHandler DoubleClickedLeft;
/// <summary>
/// Indicates whether the button is depressed.
/// </summary>
public bool IsDepressed
{
get { return m_Depressed; }
set
{
if (m_Depressed == value)
return;
m_Depressed = value;
Redraw();
}
}
/// <summary>
/// Indicates whether the button is toggleable.
/// </summary>
public bool IsToggle { get { return m_Toggle; } set { m_Toggle = value; } }
/// <summary>
/// Determines the button's toggle state.
/// </summary>
public bool ToggleState
{
get { return m_ToggleStatus; }
set
{
if (!m_Toggle) return;
if (m_ToggleStatus == value) return;
m_ToggleStatus = value;
if (Toggled != null)
Toggled.Invoke(this);
if (m_ToggleStatus)
{
if (ToggledOn != null)
ToggledOn.Invoke(this);
}
else
{
if (ToggledOff != null)
ToggledOff.Invoke(this);
}
Redraw();
}
}
/// <summary>
/// Control constructor.
/// </summary>
/// <param name="parent">Parent control.</param>
public Button(Base parent)
: base(parent)
{
SetSize(100, 20);
MouseInputEnabled = true;
Alignment = Pos.Center;
TextPadding = new Padding(3, 3, 3, 3);
}
/// <summary>
/// Toggles the button.
/// </summary>
public virtual void Toggle()
{
ToggleState = !ToggleState;
}
/// <summary>
/// "Clicks" the button.
/// </summary>
public virtual void Press(Base control = null)
{
OnClicked();
}
/// <summary>
/// Renders the control using specified skin.
/// </summary>
/// <param name="skin">Skin to use.</param>
protected override void Render(Skin.Base skin)
{
base.Render(skin);
if (ShouldDrawBackground)
{
bool drawDepressed = IsDepressed && IsHovered;
if (IsToggle)
drawDepressed = drawDepressed || ToggleState;
bool bDrawHovered = IsHovered && ShouldDrawHover;
skin.DrawButton(this, drawDepressed, bDrawHovered, IsDisabled);
}
}
/// <summary>
/// Handler invoked on mouse click (left) event.
/// </summary>
/// <param name="x">X coordinate.</param>
/// <param name="y">Y coordinate.</param>
/// <param name="down">If set to <c>true</c> mouse button is down.</param>
protected override void OnMouseClickedLeft(int x, int y, bool down)
{
//base.OnMouseClickedLeft(x, y, down);
if (down)
{
IsDepressed = true;
InputHandler.MouseFocus = this;
if (Pressed != null)
Pressed.Invoke(this);
}
else
{
if (IsHovered && m_Depressed)
{
OnClicked();
}
IsDepressed = false;
InputHandler.MouseFocus = null;
if (Released != null)
Released.Invoke(this);
}
Redraw();
}
/// <summary>
/// Internal OnPressed implementation.
/// </summary>
protected virtual void OnClicked()
{
if (IsToggle)
{
Toggle();
}
if (Clicked != null)
Clicked.Invoke(this);
}
/// <summary>
/// Sets the button's image.
/// </summary>
/// <param name="textureName">Texture name. Null to remove.</param>
/// <param name="center">Determines whether the image should be centered.</param>
public virtual void SetImage(String textureName, bool center = false)
{
if (String.IsNullOrEmpty(textureName))
{
if (m_Image != null)
m_Image.Dispose();
m_Image = null;
return;
}
if (m_Image == null)
{
m_Image = new ImagePanel(this);
}
m_Image.ImageName = textureName;
m_Image.SizeToContents( );
m_Image.SetPosition(Math.Max(Padding.Left, 2), 2);
m_CenterImage = center;
TextPadding = new Padding(m_Image.Right + 2, TextPadding.Top, TextPadding.Right, TextPadding.Bottom);
}
/// <summary>
/// Sizes to contents.
/// </summary>
public override void SizeToContents()
{
base.SizeToContents();
if (m_Image != null)
{
int height = m_Image.Height + 4;
if (Height < height)
{
Height = height;
}
}
}
/// <summary>
/// Handler for Space keyboard event.
/// </summary>
/// <param name="down">Indicates whether the key was pressed or released.</param>
/// <returns>
/// True if handled.
/// </returns>
protected override bool OnKeySpace(bool down)
{
if (down)
OnClicked();
return true;
}
/// <summary>
/// Default accelerator handler.
/// </summary>
protected override void OnAccelerator()
{
OnClicked();
}
/// <summary>
/// Lays out the control's interior according to alignment, padding, dock etc.
/// </summary>
/// <param name="skin">Skin to use.</param>
protected override void Layout(Skin.Base skin)
{
base.Layout(skin);
if (m_Image != null)
{
Align.CenterVertically(m_Image);
if (m_CenterImage)
Align.CenterHorizontally(m_Image);
}
}
/// <summary>
/// Updates control colors.
/// </summary>
public override void UpdateColors()
{
if (IsDisabled)
{
TextColor = Skin.Colors.Button.Disabled;
return;
}
if (IsDepressed || ToggleState)
{
TextColor = Skin.Colors.Button.Down;
return;
}
if (IsHovered)
{
TextColor = Skin.Colors.Button.Hover;
return;
}
TextColor = Skin.Colors.Button.Normal;
}
/// <summary>
/// Handler invoked on mouse double click (left) event.
/// </summary>
/// <param name="x">X coordinate.</param>
/// <param name="y">Y coordinate.</param>
protected override void OnMouseDoubleClickedLeft(int x, int y)
{
OnMouseClickedLeft(x, y, true);
if (DoubleClickedLeft != null)
DoubleClickedLeft.Invoke(this);
}
}
}