using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Automation;
using static PKHeX.WinForms.Properties.Resources;
namespace PKHeX.WinForms.Controls;
public partial class GenderToggle : UserControl, IGenderToggle
{
public bool AllowClick { get; set; } = true;
private int Value = -1; // Initial load will trigger gender to appear (-1 => 0)
private string? InitialAccessible;
public static int FocusBorderDeflate { get; set; }
public byte Gender
{
get => (byte)Value;
set => Value = SetGender(value);
}
public GenderToggle() => InitializeComponent();
protected override void OnMouseDown(MouseEventArgs e)
{
Focus();
base.OnMouseDown(e);
}
protected override void OnEnter(EventArgs e)
{
Invalidate();
base.OnEnter(e);
AccessibilityObject.RaiseAutomationNotification(AutomationNotificationKind.Other,
AutomationNotificationProcessing.All, AccessibleDescription ?? AccessibleName ?? "");
}
protected override void OnLeave(EventArgs e)
{
Invalidate();
base.OnLeave(e);
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
if (!Focused)
return;
var rc = ClientRectangle;
rc.Inflate(-FocusBorderDeflate, -FocusBorderDeflate);
ControlPaint.DrawFocusRectangle(pe.Graphics, rc);
}
private static readonly Image[] GenderImages =
[
gender_0,
gender_1,
gender_2,
];
private int SetGender(int value)
{
if ((uint)value > 2)
value = 2;
if (Value == value)
return value;
BackgroundImage = GenderImages[value];
AccessibleName = (InitialAccessible ??= AccessibleName) + $" ({value})";
AccessibleDescription = (InitialAccessible ??= AccessibleName) + $" ({value})";
return value;
}
private void GenderToggle_Click(object sender, EventArgs e)
{
if (!AllowClick)
return;
TryToggle();
}
private void GenderToggle_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode is not (Keys.Enter or Keys.Space))
return;
TryToggle();
}
private void TryToggle()
{
if (AllowClick && ToggleGender().CanToggle)
{
AccessibilityObject.RaiseAutomationNotification(AutomationNotificationKind.Other,
AutomationNotificationProcessing.All, $"Gender changed to {Gender}.");
return;
}
AccessibilityObject.RaiseAutomationNotification(AutomationNotificationKind.Other,
AutomationNotificationProcessing.All, $"Cannot change gender. Current value is {Gender}.");
}
public (bool CanToggle, int Value) ToggleGender()
{
if (CanToggle())
return (true, Gender ^= 1);
return (false, Gender);
}
public bool CanToggle() => (uint)Gender < 2;
}
public interface IGenderToggle
{
///
/// Enables use of the built-in click action.
///
bool AllowClick { get; set; }
///
/// Get or set the value the control displays.
///
byte Gender { get; set; }
///
/// Manually flips the gender state if possible.
///
/// True if the gender was toggled, and the current Gender value after the operation.
(bool CanToggle, int Value) ToggleGender();
}