6
StarHorizon_Public/Content.Client/_NF/Research/UI/FancyResearchConsoleItem.xaml.cs
2025-08-13 15:03:01 +03:00

172 lines
5.8 KiB
C#

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<TechnologyPrototype, ResearchAvailability>? 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<TechDisciplinePrototype>(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();
}
}