6
StarHorizon_Public/Content.Client/_NF/Research/UI/FancyResearchConsoleItem.xaml.cs
2026-01-13 18:31:02 +02:00

209 lines
7.7 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 - now using centralized color scheme
public static readonly Color DefaultColor = ResearchColorScheme.UIColors.DefaultTechBackground;
public static readonly Color DefaultBorderColor = ResearchColorScheme.UIColors.DefaultTechBorder;
public static readonly Color DefaultHoveredColor = ResearchColorScheme.UIColors.DefaultTechHover;
public Color BackgroundColor = DefaultColor;
public Color SecondaryBackgroundColor = DefaultColor;
public Color BorderColor = DefaultBorderColor;
public Color HoveredColor = DefaultHoveredColor;
public Color SecondaryHoveredColor = DefaultHoveredColor;
public Color SelectedColor = DefaultHoveredColor;
public Color SecondarySelectedColor = 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 primary discipline for background color
var primaryDiscipline = _prototype.Index<TechDisciplinePrototype>(proto.Discipline);
var primaryColor = primaryDiscipline.Color;
// Check if there's a secondary discipline
TechDisciplinePrototype? secondaryDiscipline = null;
Color? secondaryColor = null;
if (proto.SecondaryDiscipline.HasValue)
{
secondaryDiscipline = _prototype.Index<TechDisciplinePrototype>(proto.SecondaryDiscipline.Value);
secondaryColor = secondaryDiscipline.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
BorderColor = ResearchColorScheme.GetTechBorderColor(availability);
// Calculate background colors based on availability using centralized factors
var darkenFactor = ResearchColorScheme.GetBackgroundInterpolationFactor(availability);
BackgroundColor = Color.InterpolateBetween(primaryColor, Color.Black, darkenFactor);
if (secondaryColor.HasValue)
SecondaryBackgroundColor = Color.InterpolateBetween(secondaryColor.Value, Color.Black, darkenFactor);
// Create brighter versions of the discipline colors for hover by interpolating with white
var hoverFactor = ResearchColorScheme.GetHoverMixingFactor();
HoveredColor = Color.InterpolateBetween(primaryColor, Color.White, hoverFactor);
if (secondaryColor.HasValue)
SecondaryHoveredColor = Color.InterpolateBetween(secondaryColor.Value, Color.White, hoverFactor);
// Create even brighter versions for selection (persistent bright highlight)
var selectionFactor = ResearchColorScheme.GetSelectionMixingFactor();
SelectedColor = Color.InterpolateBetween(primaryColor, Color.White, selectionFactor);
if (secondaryColor.HasValue)
SecondarySelectedColor = Color.InterpolateBetween(secondaryColor.Value, Color.White, selectionFactor);
// Create appropriate style box based on whether we have dual disciplines
if (secondaryDiscipline != null)
{
// Create dual-color rounded style box with diagonal split
var dualColorStyle = new RoundedDualColorStyleBoxFlat
{
PrimaryColor = BackgroundColor,
SecondaryColor = SecondaryBackgroundColor,
BorderColor = BorderColor,
BorderThickness = new Thickness(2.5f),
CornerRadius = 8f
};
Panel.PanelOverride = dualColorStyle;
}
else
{
// Create regular single-color rounded style box
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 RoundedDualColorStyleBoxFlat dualColorPanel)
{
// Priority: Selected > Hovered > Normal
if (IsSelected)
{
dualColorPanel.PrimaryColor = SelectedColor;
dualColorPanel.SecondaryColor = SecondarySelectedColor;
}
else if (Button.IsHovered)
{
dualColorPanel.PrimaryColor = HoveredColor;
dualColorPanel.SecondaryColor = SecondaryHoveredColor;
}
else
{
dualColorPanel.PrimaryColor = BackgroundColor;
dualColorPanel.SecondaryColor = SecondaryBackgroundColor;
}
dualColorPanel.BorderColor = BorderColor;
}
else if (Panel.PanelOverride is RoundedStyleBoxFlat singleColorPanel)
{
// Priority: Selected > Hovered > Normal
if (IsSelected)
singleColorPanel.BackgroundColor = SelectedColor;
else if (Button.IsHovered)
singleColorPanel.BackgroundColor = HoveredColor;
else
singleColorPanel.BackgroundColor = BackgroundColor;
singleColorPanel.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();
}
}