209 lines
7.7 KiB
C#
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();
|
|
}
|
|
}
|