using Godot; using System; using System.Collections.Generic; using Chessistics.Engine.Model; using Chessistics.Scripts.Pieces; namespace Chessistics.Scripts.UI; public partial class PieceStockPanel : VBoxContainer { [Signal] public delegate void PieceSelectedEventHandler(int kindIndex); private readonly Dictionary _entries = new(); private PieceKind? _selectedKind; public PieceKind? SelectedKind => _selectedKind; private static readonly Color NormalBg = new("#2A2A2E"); private static readonly Color SelectedBg = new("#3D6B8E"); private static readonly Color HoverBg = new("#353538"); private static readonly Color DisabledBg = new("#1E1E20"); private static readonly Color BorderNormal = new("#444448"); private static readonly Color BorderSelected = new("#5A9ECC"); public void Setup(IReadOnlyList stock) { foreach (var child in GetChildren()) child.QueueFree(); _entries.Clear(); _selectedKind = null; var title = new Label { Text = "PIECES" }; title.AddThemeFontSizeOverride("font_size", 16); title.AddThemeColorOverride("font_color", new Color("#B8942A")); AddChild(title); AddChild(new HSeparator()); foreach (var entry in stock) { var hbox = new HBoxContainer(); hbox.AddThemeConstantOverride("separation", 8); // Color dot matching piece color var dot = new ColorRect { CustomMinimumSize = new Vector2(10, 10), Size = new Vector2(10, 10), Color = PieceView.GetPieceColor(entry.Kind), MouseFilter = Control.MouseFilterEnum.Ignore }; var dotCenter = new CenterContainer { CustomMinimumSize = new Vector2(14, 32) }; dotCenter.AddChild(dot); hbox.AddChild(dotCenter); var button = new Button { Text = GetPieceName(entry.Kind), CustomMinimumSize = new Vector2(120, 32), ToggleMode = false, // We manage selection state ourselves FocusMode = FocusModeEnum.None // Prevent spacebar from activating buttons }; ApplyButtonStyle(button, false); var countLabel = new Label { Text = $"x{entry.Count}" }; countLabel.AddThemeFontSizeOverride("font_size", 13); countLabel.AddThemeColorOverride("font_color", new Color("#999999")); var kind = entry.Kind; button.Pressed += () => OnPieceButtonPressed(kind); hbox.AddChild(button); hbox.AddChild(countLabel); AddChild(hbox); _entries[entry.Kind] = (button, countLabel, entry.Count); } } private void OnPieceButtonPressed(PieceKind kind) { if (_selectedKind == kind) { _selectedKind = null; UpdateButtonStates(); return; } _selectedKind = kind; UpdateButtonStates(); EmitSignal(SignalName.PieceSelected, (int)kind); } private void UpdateButtonStates() { foreach (var (k, (button, _, remaining)) in _entries) { bool selected = k == _selectedKind; button.Disabled = remaining <= 0; ApplyButtonStyle(button, selected); } } private static void ApplyButtonStyle(Button button, bool selected) { var bg = selected ? SelectedBg : NormalBg; var border = selected ? BorderSelected : BorderNormal; var normal = MakeStyle(bg, border); var hover = MakeStyle(selected ? SelectedBg.Lightened(0.1f) : HoverBg, border); var disabled = MakeStyle(DisabledBg, new Color("#2A2A2E")); button.AddThemeStyleboxOverride("normal", normal); button.AddThemeStyleboxOverride("hover", hover); button.AddThemeStyleboxOverride("pressed", MakeStyle(bg.Darkened(0.15f), border)); button.AddThemeStyleboxOverride("disabled", disabled); button.AddThemeFontSizeOverride("font_size", 12); button.AddThemeColorOverride("font_color", selected ? Colors.White : new Color("#CCCCCC")); button.AddThemeColorOverride("font_disabled_color", new Color("#555555")); } private static StyleBoxFlat MakeStyle(Color bg, Color border) { return new StyleBoxFlat { BgColor = bg, BorderColor = border, BorderWidthBottom = 1, BorderWidthTop = 1, BorderWidthLeft = 1, BorderWidthRight = 1, CornerRadiusTopLeft = 4, CornerRadiusTopRight = 4, CornerRadiusBottomLeft = 4, CornerRadiusBottomRight = 4, ContentMarginLeft = 8, ContentMarginRight = 8, ContentMarginTop = 4, ContentMarginBottom = 4 }; } public void UpdateCount(PieceKind kind, int remaining) { if (!_entries.TryGetValue(kind, out var entry)) return; _entries[kind] = (entry.button, entry.countLabel, remaining); entry.countLabel.Text = $"x{remaining}"; entry.button.Disabled = remaining <= 0; } public void ClearSelection() { _selectedKind = null; UpdateButtonStates(); } private static string GetPieceName(PieceKind kind) => kind switch { PieceKind.Pawn => "Pion", PieceKind.Rook => "Tour II", PieceKind.Bishop => "Fou II", PieceKind.Knight => "Cavalier", PieceKind.Queen => "Dame", _ => kind.ToString() }; }