Implement more UX and cards for other distros

This commit is contained in:
2026-07-06 15:37:12 +02:00
parent 8b6c6235c2
commit 68dc13c60d
31 changed files with 759 additions and 16 deletions
@@ -167,6 +167,7 @@ namespace KernelPanic.UI
Label description = new(string.IsNullOrWhiteSpace(unit.Description) ? "--" : unit.Description);
description.AddToClassList("collection-detail-description");
detail.Add(description);
AddPassiveDetails(detail, unit);
VisualElement readout = new();
readout.AddToClassList("collection-detail-readout");
@@ -183,7 +184,6 @@ namespace KernelPanic.UI
details.AddToClassList("collection-detail-values");
details.Add(BuildDetailLine("lang", DistroPresentation.FormatLanguages(unit)));
details.Add(BuildDetailLine("passive", string.IsNullOrWhiteSpace(unit.PassiveName) ? "--" : unit.PassiveName));
details.Add(BuildDetailLine("uptime", unit.BaseUptime.ToString()));
details.Add(BuildDetailLine("ram", unit.BaseRam.ToString()));
details.Add(BuildDetailLine("cycles", unit.BaseCyclesPerTurn.ToString()));
@@ -204,6 +204,12 @@ namespace KernelPanic.UI
Label description = new(card == null || string.IsNullOrWhiteSpace(card.Description) ? "--" : card.Description);
description.AddToClassList("collection-detail-description");
detail.Add(description);
if (card != null && !string.IsNullOrWhiteSpace(card.FlavorText))
{
Label flavor = new(card.FlavorText);
flavor.AddToClassList("flavor-text");
detail.Add(flavor);
}
detail.Add(BuildDetailLine("owner", DistroPresentation.DisplayName(entry.Owner)));
detail.Add(BuildDetailLine("lang", card == null ? "--" : card.Language.ToString()));
@@ -227,6 +233,29 @@ namespace KernelPanic.UI
return row;
}
private static void AddPassiveDetails(VisualElement target, DistroDefinition unit)
{
if (unit.Passive == null)
{
return;
}
Label passiveTitle = new(unit.Passive.Name);
passiveTitle.AddToClassList("detail-section-title");
target.Add(passiveTitle);
Label passiveRules = new(unit.Passive.RulesText);
passiveRules.AddToClassList("collection-detail-description");
target.Add(passiveRules);
if (!string.IsNullOrWhiteSpace(unit.Passive.FlavorText))
{
Label passiveFlavor = new(unit.Passive.FlavorText);
passiveFlavor.AddToClassList("flavor-text");
target.Add(passiveFlavor);
}
}
private static IReadOnlyList<CardEntry> BuildCardEntries(DistroDefinition featuredUnit)
{
List<CardEntry> entries = new();
+1 -1
View File
@@ -130,7 +130,7 @@ namespace KernelPanic.UI
asciiFitter.SetArt(DistroArtPresenter.Render(asciiLabel, asciiPlaceholder, unit));
unitNameLabel.text = DistroPresentation.DisplayName(unit);
languagesLabel.text = DistroPresentation.FormatLanguages(unit);
passiveLabel.text = string.IsNullOrWhiteSpace(unit.PassiveName) ? "--" : unit.PassiveName;
passiveLabel.text = unit.Passive == null || string.IsNullOrWhiteSpace(unit.Passive.Name) ? "--" : unit.Passive.Name;
bestWaveLabel.text = "--"; // TODO: Bind best-wave stats from SaveService when stats exist.
SetAccent(ColorUtility.ToHtmlStringRGB(unit.AccentColor));
}
+60 -5
View File
@@ -206,16 +206,28 @@ namespace KernelPanic.UI
{
root.RegisterCallback<KeyDownEvent>(HandleKeyDown);
root.RegisterCallback<PointerDownEvent>(HandlePointerDown);
collectionUnitsButton.clicked += ShowCollectionUnits;
collectionCardsButton.clicked += ShowCollectionCards;
collectionUnitsButton.RegisterCallback<ClickEvent>(HandleCollectionUnitsTabClicked);
collectionCardsButton.RegisterCallback<ClickEvent>(HandleCollectionCardsTabClicked);
}
private void UnregisterCallbacks()
{
root.UnregisterCallback<KeyDownEvent>(HandleKeyDown);
root.UnregisterCallback<PointerDownEvent>(HandlePointerDown);
collectionUnitsButton.clicked -= ShowCollectionUnits;
collectionCardsButton.clicked -= ShowCollectionCards;
collectionUnitsButton.UnregisterCallback<ClickEvent>(HandleCollectionUnitsTabClicked);
collectionCardsButton.UnregisterCallback<ClickEvent>(HandleCollectionCardsTabClicked);
}
private void HandleCollectionUnitsTabClicked(ClickEvent evt)
{
ShowCollectionUnits();
evt.StopPropagation();
}
private void HandleCollectionCardsTabClicked(ClickEvent evt)
{
ShowCollectionCards();
evt.StopPropagation();
}
private void LoadMetaState()
@@ -599,7 +611,8 @@ namespace KernelPanic.UI
summary.Add(meta);
row.Add(summary);
row.Add(new Label(string.IsNullOrWhiteSpace(unit.PassiveName) ? "passive: --" : $"passive: {unit.PassiveName}")
string passiveTitle = unit.Passive == null || string.IsNullOrWhiteSpace(unit.Passive.Name) ? "--" : unit.Passive.Name;
row.Add(new Label($"passive: {passiveTitle}")
{
name = $"RunSetupDescription{index}"
});
@@ -724,10 +737,46 @@ namespace KernelPanic.UI
stats.AddToClassList("collection-detail-muted");
copy.Add(stats);
AddDistroTeachingDetails(copy, unit);
readout.Add(copy);
return readout;
}
private static void AddDistroTeachingDetails(VisualElement target, DistroDefinition unit)
{
if (unit.Passive != null)
{
Label passiveTitle = new(unit.Passive.Name);
passiveTitle.AddToClassList("detail-section-title");
target.Add(passiveTitle);
Label passiveRules = new(unit.Passive.RulesText);
passiveRules.AddToClassList("collection-detail-description");
target.Add(passiveRules);
if (!string.IsNullOrWhiteSpace(unit.Passive.FlavorText))
{
Label passiveFlavor = new(unit.Passive.FlavorText);
passiveFlavor.AddToClassList("flavor-text");
target.Add(passiveFlavor);
}
}
if (!string.IsNullOrWhiteSpace(unit.PlaystyleSummary))
{
Label playstyle = new(unit.PlaystyleSummary);
playstyle.AddToClassList("collection-detail-description");
target.Add(playstyle);
}
for (int i = 0; i < unit.LanguageBlurbs.Count; i++)
{
DistroDefinition.LanguageBlurb blurb = unit.LanguageBlurbs[i];
target.Add(BuildDetailLine(blurb.Lang.ToString(), blurb.Blurb));
}
}
private static VisualElement BuildDetailLine(string key, string value)
{
VisualElement row = new();
@@ -767,6 +816,12 @@ namespace KernelPanic.UI
row.ElementAt(1).AddToClassList("package-description");
}
if (!string.IsNullOrWhiteSpace(card.FlavorText))
{
row.Add(new Label(card.FlavorText) { name = "RunSetupCardFlavor" });
row.ElementAt(row.childCount - 1).AddToClassList("package-flavor");
}
return row;
}
@@ -0,0 +1,47 @@
using System;
using UnityEngine.UIElements;
namespace KernelPanic.UI
{
/// <summary>
/// Binds shared command-style chrome used by terminal sub-screens.
/// </summary>
public sealed class ScreenFrameController
{
private Label titleLabel;
private Label hintLabel;
public void Bind(VisualElement panel, string title, string hint, Action onBack)
{
titleLabel = panel.Q<Label>(className: "screen-frame-title");
hintLabel = panel.Q<Label>(className: "screen-frame-hint");
if (titleLabel != null)
{
titleLabel.text = title;
}
if (hintLabel != null)
{
hintLabel.text = hint;
hintLabel.RegisterCallback<ClickEvent>(_ => onBack?.Invoke());
}
}
public void SetHint(string hint)
{
if (hintLabel != null)
{
hintLabel.text = hint;
}
}
public void SetTitle(string title)
{
if (titleLabel != null)
{
titleLabel.text = title;
}
}
}
}