using Content.Shared._NF.Research; using Content.Shared.Research.Prototypes; using Robust.Client.AutoGenerated; using Robust.Client.GameObjects; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.XAML; using Robust.Shared.Prototypes; namespace Content.Client._NF.Research.UI; [GenerateTypedNameReferences] public sealed partial class FancyResearchConsoleItem : LayoutContainer { [Dependency] private readonly IPrototypeManager _prototype = default!; // Public fields public TechnologyPrototype Prototype; public Action? SelectAction; public ResearchAvailability Availability; // Some visuals public static readonly Color DefaultColor = Color.FromHex("#141F2F"); public static readonly Color DefaultBorderColor = Color.FromHex("#4972A1"); public static readonly Color DefaultHoveredColor = Color.FromHex("#4972A1"); public Color BackgroundColor = DefaultColor; public Color BorderColor = DefaultBorderColor; public Color HoveredColor = DefaultHoveredColor; public Color SelectedColor = DefaultHoveredColor; // Selection state private bool _isSelected = false; public bool IsSelected { get => _isSelected; set { if (_isSelected == value) return; _isSelected = value; UpdateColor(); } } public FancyResearchConsoleItem(TechnologyPrototype proto, SpriteSystem sprite, ResearchAvailability availability) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); Availability = availability; Prototype = proto; // Get the discipline for background color var discipline = _prototype.Index(proto.Discipline); var disciplineColor = discipline.Color; // Handle technology icon - prioritize EntityIcon for full sprite layers if (proto.EntityIcon.HasValue) { // Use EntityPrototypeView to show all sprite layers ResearchDisplay.SetPrototype(proto.EntityIcon.Value); } else if (proto.Icon != null) { // For legacy Icon support, we need to handle this differently since EntityPrototypeView // expects entity prototypes. For now, we'll need a fallback approach. // TODO: Consider deprecating the Icon field in favor of EntityIcon // We cannot directly set a SpriteSpecifier on EntityPrototypeView // This is a limitation of the new approach - EntityIcon should be preferred // For now, this will show no icon for legacy Icon-only technologies ResearchDisplay.SetPrototype(null); } else { // No icon specified ResearchDisplay.SetPrototype(null); } Button.OnPressed += Selected; Button.OnDrawModeChanged += UpdateColor; // Set colors - border & background color varies by availability state switch (availability) { case ResearchAvailability.Researched: BackgroundColor = Color.InterpolateBetween(disciplineColor, Color.Black, 0.2f); // slightly darker, to emphasise available techs BorderColor = Color.LimeGreen; break; case ResearchAvailability.Available: BackgroundColor = disciplineColor; BorderColor = Color.FromHex("#e8fa25"); break; case ResearchAvailability.PrereqsMet: BackgroundColor = disciplineColor; BorderColor = Color.FromHex("#cca031"); break; case ResearchAvailability.Unavailable: BackgroundColor = Color.InterpolateBetween(disciplineColor, Color.Black, 0.5f); // much darker, to emphasise available & researched techs BorderColor = Color.Crimson; break; default: BackgroundColor = Color.InterpolateBetween(disciplineColor, Color.Black, 0.5f); // much darker, to emphasise available & researched techs BorderColor = Color.Crimson; break; } // Create a brighter version of the discipline color for hover by interpolating with white HoveredColor = Color.InterpolateBetween(disciplineColor, Color.White, 0.3f); // Create an even brighter version for selection (persistent bright highlight) SelectedColor = Color.InterpolateBetween(disciplineColor, Color.White, 0.5f); // Create rounded style box with 8px corner radius and thick border var roundedStyle = new RoundedStyleBoxFlat { BackgroundColor = BackgroundColor, BorderColor = BorderColor, BorderThickness = new Thickness(2.5f), CornerRadius = 8f }; Panel.PanelOverride = roundedStyle; UpdateColor(); } private void UpdateColor() { if (Panel.PanelOverride is RoundedStyleBoxFlat panel) { // Priority: Selected > Hovered > Normal if (IsSelected) panel.BackgroundColor = SelectedColor; else if (Button.IsHovered) panel.BackgroundColor = HoveredColor; else panel.BackgroundColor = BackgroundColor; panel.BorderColor = BorderColor; } } protected override void ExitedTree() { base.ExitedTree(); Button.OnPressed -= Selected; } private void Selected(BaseButton.ButtonEventArgs args) { SelectAction?.Invoke(Prototype, Availability); } } public sealed class DrawButton : Button { public event Action? OnDrawModeChanged; public DrawButton() { } protected override void DrawModeChanged() { OnDrawModeChanged?.Invoke(); } }