Refactor HUD color management to utilize HudTheme constants.

- Replace hardcoded color values with HudTheme references across files
- Update ActivityProse, Chronicle, ChronicleHud, and others for consistency
- Increment version to 0.28.25 in mod.json
This commit is contained in:
DazedAnon 2026-07-17 18:06:43 -05:00
parent 1ab58e9d9e
commit ef561b87d8
9 changed files with 109 additions and 58 deletions

View file

@ -7,10 +7,9 @@ namespace IdleSpectator;
public static class ActivityProse
{
/// <summary>
/// Bright lemon for person names - must read clearly on dark dossier chrome and
/// against orange reason text (<c>#F2B861</c>).
/// Vanilla tip name-value purple - reads on dark dossier chrome and orange reason text.
/// </summary>
public const string NameColorHex = "#FFE566";
public const string NameColorHex = HudTheme.NameColorHex;
public static string ColorName(string name)
{
@ -23,7 +22,7 @@ public static class ActivityProse
}
/// <summary>
/// Wrap known person names in gold for orange reason beats (rest inherits ReasonColor).
/// Wrap known person names in purple for orange reason beats (rest inherits ReasonColor).
/// Longer names first so partial overlaps do not corrupt replacements.
/// </summary>
public static string ColorizePersonNames(string plain, params string[] names)

View file

@ -115,8 +115,7 @@ public sealed class ChronicleEntry
return body ?? "";
}
const string color = "#A8B4C8";
string stamped = "<color=" + color + ">[" + DateLabel + "]</color>";
string stamped = "<color=" + HudTheme.DateColorHex + ">[" + DateLabel + "]</color>";
if (string.IsNullOrEmpty(body))
{
return stamped;

View file

@ -248,7 +248,7 @@ public static class ChronicleHud
Image bg = _root.GetComponent<Image>();
bg.raycastTarget = true;
HudCanvas.StylePanel(bg, _root.transform, new Color(0.07f, 0.08f, 0.1f, 0.92f));
HudCanvas.StylePanel(bg, _root.transform);
CanvasGroup group = _root.GetComponent<CanvasGroup>();
group.blocksRaycasts = true;
@ -262,7 +262,7 @@ public static class ChronicleHud
hotRt.sizeDelta = new Vector2(16f, 12f);
hotRt.anchoredPosition = new Vector2(-6f, -5f);
_hotkeyText.alignment = TextAnchor.MiddleRight;
_hotkeyText.color = new Color(0.5f, 0.53f, 0.58f, 0.95f);
_hotkeyText.color = HudTheme.Muted;
_hotkeyText.raycastTarget = false;
_titleIcon = HudCanvas.MakeIcon(_root.transform, "TitleIcon", TitleIconSize);
@ -281,7 +281,7 @@ public static class ChronicleHud
titleRt.offsetMin = new Vector2(24f, -TitleBandH);
titleRt.offsetMax = new Vector2(-22f, -2f);
_titleText.alignment = TextAnchor.MiddleLeft;
_titleText.color = new Color(0.9f, 0.91f, 0.93f, 1f);
_titleText.color = HudTheme.Name;
_titleText.fontStyle = FontStyle.Bold;
_titleText.raycastTarget = false;
_titleText.horizontalOverflow = HorizontalWrapMode.Overflow;
@ -297,7 +297,7 @@ public static class ChronicleHud
_deleteGraveLabel = _deleteGraveBtn.transform.Find("Label")?.GetComponent<Text>();
if (_deleteGraveLabel != null)
{
_deleteGraveLabel.color = new Color(0.92f, 0.62f, 0.58f, 1f);
_deleteGraveLabel.color = HudTheme.Danger;
}
PlaceTitleTool(_deleteGraveBtn, -22f, 34f);
@ -338,7 +338,7 @@ public static class ChronicleHud
GameObject go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(Button));
go.transform.SetParent(parent, false);
Image bg = go.GetComponent<Image>();
bg.color = new Color(0.1f, 0.11f, 0.13f, 0.35f);
bg.color = HudTheme.TabIdleFill;
bg.raycastTarget = true;
Button button = go.GetComponent<Button>();
button.targetGraphic = bg;
@ -346,7 +346,7 @@ public static class ChronicleHud
Text text = HudCanvas.MakeText(go.transform, "Label", label, 8);
StretchFull(text.GetComponent<RectTransform>(), 1f);
text.alignment = TextAnchor.MiddleCenter;
text.color = new Color(0.7f, 0.72f, 0.76f, 1f);
text.color = HudTheme.Label;
text.raycastTarget = false;
// Active underline accent (toggled in StyleTab).
@ -359,7 +359,7 @@ public static class ChronicleHud
uRt.sizeDelta = new Vector2(0f, 2f);
uRt.anchoredPosition = Vector2.zero;
Image uImg = underline.GetComponent<Image>();
uImg.color = new Color(0.55f, 0.72f, 0.95f, 0f);
uImg.color = new Color(HudTheme.StatusBlue.r, HudTheme.StatusBlue.g, HudTheme.StatusBlue.b, 0f);
uImg.raycastTarget = false;
return go;
}
@ -412,19 +412,19 @@ public static class ChronicleHud
searchRt.offsetMin = Vector2.zero;
searchRt.offsetMax = new Vector2(-40f, 0f);
Image searchBg = searchGo.GetComponent<Image>();
searchBg.color = new Color(0.05f, 0.06f, 0.08f, 0.95f);
searchBg.color = HudTheme.SearchFill;
searchBg.raycastTarget = true;
Text placeholder = HudCanvas.MakeText(searchGo.transform, "Placeholder", "Search name…", 8);
StretchFull(placeholder.GetComponent<RectTransform>(), 4f);
placeholder.alignment = TextAnchor.MiddleLeft;
placeholder.color = new Color(0.5f, 0.52f, 0.56f, 0.9f);
placeholder.color = HudTheme.Muted;
placeholder.raycastTarget = false;
Text searchText = HudCanvas.MakeText(searchGo.transform, "Text", "", 8);
StretchFull(searchText.GetComponent<RectTransform>(), 4f);
searchText.alignment = TextAnchor.MiddleLeft;
searchText.color = new Color(0.9f, 0.9f, 0.92f, 1f);
searchText.color = HudTheme.Name;
searchText.supportRichText = false;
searchText.raycastTarget = false;
@ -513,7 +513,7 @@ public static class ChronicleHud
GameObject go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(Button));
go.transform.SetParent(parent, false);
Image bg = go.GetComponent<Image>();
bg.color = new Color(0.12f, 0.13f, 0.16f, 0.95f);
bg.color = HudTheme.ToolFill;
bg.raycastTarget = true;
Button button = go.GetComponent<Button>();
button.targetGraphic = bg;
@ -521,7 +521,7 @@ public static class ChronicleHud
Text text = HudCanvas.MakeText(go.transform, "Label", label, 10);
StretchFull(text.GetComponent<RectTransform>(), 0f);
text.alignment = TextAnchor.MiddleCenter;
text.color = new Color(0.78f, 0.8f, 0.84f, 1f);
text.color = HudTheme.Body;
text.raycastTarget = false;
return button;
}
@ -531,7 +531,7 @@ public static class ChronicleHud
GameObject go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(Button));
go.transform.SetParent(parent, false);
Image bg = go.GetComponent<Image>();
bg.color = new Color(0.12f, 0.13f, 0.16f, 0.95f);
bg.color = HudTheme.ToolFill;
bg.raycastTarget = true;
Button button = go.GetComponent<Button>();
button.targetGraphic = bg;
@ -989,8 +989,8 @@ public static class ChronicleHud
if (bg != null)
{
bg.color = kept
? new Color(0.45f, 0.36f, 0.12f, 0.95f)
: new Color(0.12f, 0.13f, 0.16f, 0.95f);
? new Color(HudTheme.AccentGold.r * 0.55f, HudTheme.AccentGold.g * 0.45f, HudTheme.AccentGold.b * 0.2f, 0.95f)
: HudTheme.ToolFill;
}
}
@ -1389,16 +1389,16 @@ public static class ChronicleHud
if (bg != null)
{
bg.color = active
? new Color(0.16f, 0.18f, 0.22f, 0.55f)
: new Color(0.08f, 0.09f, 0.1f, 0.15f);
? HudTheme.TabActiveFill
: HudTheme.TabIdleFill;
}
Text label = tab.transform.Find("Label")?.GetComponent<Text>();
if (label != null)
{
label.color = active
? new Color(0.95f, 0.96f, 0.98f, 1f)
: new Color(0.62f, 0.65f, 0.7f, 1f);
? HudTheme.Name
: HudTheme.Label;
label.fontStyle = active ? FontStyle.Bold : FontStyle.Normal;
}
@ -1406,8 +1406,8 @@ public static class ChronicleHud
if (underline != null)
{
underline.color = active
? new Color(0.55f, 0.72f, 0.95f, 0.95f)
: new Color(0.55f, 0.72f, 0.95f, 0f);
? new Color(HudTheme.StatusBlue.r, HudTheme.StatusBlue.g, HudTheme.StatusBlue.b, 0.95f)
: new Color(HudTheme.StatusBlue.r, HudTheme.StatusBlue.g, HudTheme.StatusBlue.b, 0f);
}
}
@ -1420,8 +1420,8 @@ public static class ChronicleHud
HudIcons.Apply(_favFilterIcon, HudIcons.Favorite());
_favFilterIcon.color = _favoritesOnly
? new Color(1f, 0.85f, 0.25f, 1f)
: new Color(0.55f, 0.58f, 0.62f, 1f);
? HudTheme.FavoriteOn
: HudTheme.FavoriteOff;
}
private static void RefreshStaleVisual()
@ -1434,12 +1434,12 @@ public static class ChronicleHud
bool stale = CastListStale;
_refreshBg.color = stale
? new Color(0.28f, 0.34f, 0.22f, 0.98f)
: new Color(0.12f, 0.13f, 0.16f, 0.95f);
: HudTheme.ToolFill;
if (_refreshLabel != null)
{
_refreshLabel.color = stale
? new Color(0.85f, 0.95f, 0.55f, 1f)
: new Color(0.78f, 0.8f, 0.84f, 1f);
: HudTheme.Body;
}
}
@ -1858,7 +1858,7 @@ public static class ChronicleHud
labelRt.offsetMin = new Vector2(18f, 2f);
labelRt.offsetMax = new Vector2(-4f, -2f);
label.alignment = TextAnchor.UpperLeft;
label.color = new Color(0.88f, 0.9f, 0.78f, 1f);
label.color = HudTheme.Body;
label.supportRichText = true;
label.resizeTextForBestFit = false;
label.horizontalOverflow = HorizontalWrapMode.Wrap;
@ -2078,7 +2078,7 @@ public static class ChronicleHud
Text label = HudCanvas.MakeText(go.transform, "Text", title, 8);
StretchFull(label.GetComponent<RectTransform>(), 2f);
label.alignment = TextAnchor.MiddleLeft;
label.color = new Color(0.7f, 0.74f, 0.82f, 1f);
label.color = HudTheme.Label;
label.fontStyle = FontStyle.Bold;
label.raycastTarget = false;
go.transform.SetParent(_content, false);
@ -2112,7 +2112,7 @@ public static class ChronicleHud
Text label = HudCanvas.MakeText(go.transform, "Text", "— " + title + " —", 8);
StretchFull(label.GetComponent<RectTransform>(), 2f);
label.alignment = TextAnchor.MiddleCenter;
label.color = new Color(0.7f, 0.74f, 0.82f, 1f);
label.color = HudTheme.Label;
label.fontStyle = FontStyle.Bold;
label.raycastTarget = false;
return go;
@ -2130,7 +2130,7 @@ public static class ChronicleHud
Text label = HudCanvas.MakeText(go.transform, "Text", text, 8);
StretchFull(label.GetComponent<RectTransform>(), 3f);
label.alignment = TextAnchor.MiddleLeft;
label.color = new Color(0.65f, 0.68f, 0.72f, 0.95f);
label.color = HudTheme.Muted;
label.resizeTextForBestFit = false;
label.horizontalOverflow = HorizontalWrapMode.Wrap;
label.verticalOverflow = VerticalWrapMode.Overflow;
@ -2195,7 +2195,7 @@ public static class ChronicleHud
labelRt.offsetMax = new Vector2(-4f, -1f);
label.alignment = TextAnchor.MiddleLeft;
label.color = summary.IsAlive
? new Color(0.9f, 0.9f, 0.92f, 1f)
? HudTheme.Name
: ColorForDeathManner(summary.DeathManner, listRow: false);
label.horizontalOverflow = HorizontalWrapMode.Overflow;
label.raycastTarget = false;

View file

@ -256,7 +256,7 @@ public static class DossierAvatar
{
_fallbackBg.gameObject.SetActive(true);
_fallbackBg.sprite = null;
_fallbackBg.color = new Color(0.04f, 0.045f, 0.055f, 0.95f);
_fallbackBg.color = HudTheme.InsetFill;
_fallbackBg.type = Image.Type.Simple;
}
@ -408,7 +408,7 @@ public static class DossierAvatar
bgRt.anchorMax = Vector2.one;
bgRt.offsetMin = Vector2.zero;
bgRt.offsetMax = Vector2.zero;
_fallbackBg.color = new Color(0.04f, 0.045f, 0.055f, 0.95f);
_fallbackBg.color = HudTheme.InsetFill;
_fallbackBg.raycastTarget = false;
_fallbackSprite = HudCanvas.MakeIcon(_host, "FallbackLive", size);

View file

@ -68,7 +68,7 @@ public static class GraveCountBadges
RectTransform rt = go.GetComponent<RectTransform>();
rt.sizeDelta = new Vector2(14f, 10f);
Image img = go.GetComponent<Image>();
img.color = new Color(0.08f, 0.09f, 0.11f, 0.85f);
img.color = HudTheme.ToolFill;
img.raycastTarget = false;
Text label = HudCanvas.MakeText(go.transform, "N", "2", 8);
RectTransform lrt = label.GetComponent<RectTransform>();
@ -77,7 +77,7 @@ public static class GraveCountBadges
lrt.offsetMin = Vector2.zero;
lrt.offsetMax = Vector2.zero;
label.alignment = TextAnchor.MiddleCenter;
label.color = new Color(0.95f, 0.85f, 0.55f, 1f);
label.color = HudTheme.AccentGold;
label.raycastTarget = false;
go.SetActive(false);
Pool.Add(new Badge { Go = go, Rt = rt, Label = label });

View file

@ -65,7 +65,7 @@ public static class HudCanvas
return image;
}
/// <summary>Dark fill + lighter 1px edge so panels read as WorldBox chrome.</summary>
/// <summary>Vanilla-tooltip fill + slate 1px edge (<see cref="HudTheme"/>).</summary>
public static void StylePanel(Image fill, Transform root, Color fillColor)
{
if (fill != null)
@ -87,7 +87,13 @@ public static class HudCanvas
edgeRt.offsetMin = new Vector2(-1f, -1f);
edgeRt.offsetMax = new Vector2(1f, 1f);
Image edgeImg = edge.GetComponent<Image>();
edgeImg.color = new Color(0.42f, 0.45f, 0.5f, 0.55f);
edgeImg.color = HudTheme.PanelEdge;
edgeImg.raycastTarget = false;
}
/// <summary>Default panel chrome using <see cref="HudTheme.PanelFill"/>.</summary>
public static void StylePanel(Image fill, Transform root)
{
StylePanel(fill, root, HudTheme.PanelFill);
}
}

47
IdleSpectator/HudTheme.cs Normal file
View file

@ -0,0 +1,47 @@
using UnityEngine;
namespace IdleSpectator;
/// <summary>
/// Shared HUD chrome matched to vanilla WorldBox unit tooltip colors
/// (near-black panel, slate capsules, orange values, purple name-values, muted greens).
/// </summary>
public static class HudTheme
{
// Panel chrome - sampled from vanilla unit tip outer fill.
public static readonly Color PanelFill = new Color(18f / 255f, 20f / 255f, 24f / 255f, 1f);
public static readonly Color PanelEdge = new Color(44f / 255f, 48f / 255f, 56f / 255f, 0.75f);
// Nested capsules / activity inset (vanilla age/HP chip slate).
public static readonly Color CapsuleFill = new Color(34f / 255f, 48f / 255f, 64f / 255f, 0.92f);
public static readonly Color InsetFill = new Color(21f / 255f, 23f / 255f, 26f / 255f, 0.94f);
public static readonly Color Separator = new Color(70f / 255f, 78f / 255f, 90f / 255f, 0.55f);
// Text
public static readonly Color Name = new Color(246f / 255f, 248f / 255f, 243f / 255f, 1f);
public static readonly Color Label = new Color(149f / 255f, 150f / 255f, 150f / 255f, 1f);
public static readonly Color Body = new Color(210f / 255f, 212f / 255f, 214f / 255f, 1f);
public static readonly Color Muted = new Color(128f / 255f, 132f / 255f, 140f / 255f, 0.95f);
// Accents from vanilla tip values / bars.
public static readonly Color ValueOrange = new Color(236f / 255f, 156f / 255f, 56f / 255f, 1f);
public static readonly Color NamePurple = new Color(167f / 255f, 96f / 255f, 228f / 255f, 1f);
public static readonly Color TaskGreen = new Color(38f / 255f, 158f / 255f, 4f / 255f, 1f);
public static readonly Color StatusBlue = new Color(100f / 255f, 168f / 255f, 210f / 255f, 1f);
public static readonly Color AccentGold = new Color(212f / 255f, 194f / 255f, 56f / 255f, 1f);
public static readonly Color Danger = new Color(235f / 255f, 115f / 255f, 105f / 255f, 1f);
// Controls
public static readonly Color ToolFill = new Color(28f / 255f, 32f / 255f, 40f / 255f, 0.95f);
public static readonly Color TabActiveFill = new Color(40f / 255f, 52f / 255f, 68f / 255f, 0.9f);
public static readonly Color TabIdleFill = new Color(18f / 255f, 20f / 255f, 24f / 255f, 0.25f);
public static readonly Color SearchFill = new Color(14f / 255f, 16f / 255f, 20f / 255f, 0.96f);
public static readonly Color FavoriteOn = AccentGold;
public static readonly Color FavoriteOff = Label;
/// <summary>Rich-text hex for person names (vanilla tip name-value purple).</summary>
public const string NameColorHex = "#A760E4";
/// <summary>Rich-text hex for date stamps on lore lines.</summary>
public const string DateColorHex = "#959696";
}

View file

@ -47,14 +47,14 @@ public static class WatchCaption
private static float _panelWidth = LiveMax + PadX * 2f;
private static readonly Color NameColor = new Color(0.95f, 0.93f, 0.88f, 1f);
private static readonly Color StatValueColor = new Color(1f, 0.62f, 0.28f, 1f);
private static readonly Color TaskColor = new Color(0.26f, 1f, 0.26f, 1f);
private static readonly Color ReasonColor = new Color(0.95f, 0.72f, 0.38f, 1f);
private static readonly Color TraitNameColor = new Color(0.78f, 0.8f, 0.84f, 1f);
private static readonly Color StatusNameColor = new Color(0.62f, 0.82f, 0.92f, 1f);
private static readonly Color HistoryTextColor = new Color(0.82f, 0.84f, 0.86f, 1f);
private static readonly Color StatusBannerColor = new Color(1f, 0.55f, 0.18f, 1f);
private static readonly Color NameColor = HudTheme.Name;
private static readonly Color StatValueColor = HudTheme.ValueOrange;
private static readonly Color TaskColor = HudTheme.TaskGreen;
private static readonly Color ReasonColor = HudTheme.ValueOrange;
private static readonly Color TraitNameColor = HudTheme.Body;
private static readonly Color StatusNameColor = HudTheme.StatusBlue;
private static readonly Color HistoryTextColor = HudTheme.Body;
private static readonly Color StatusBannerColor = HudTheme.ValueOrange;
private static GameObject _root;
private static RectTransform _rootRt;
@ -1904,7 +1904,7 @@ public static class WatchCaption
slot.Label.horizontalOverflow = HorizontalWrapMode.Wrap;
slot.Label.verticalOverflow = VerticalWrapMode.Overflow;
slot.Label.color = row.isActivity
? new Color(0.88f, 0.9f, 0.78f, 1f)
? HudTheme.Body
: HistoryTextColor;
slot.Label.text = row.rich ?? row.plain ?? "";
RectTransform lrt = slot.Label.GetComponent<RectTransform>();
@ -2466,8 +2466,8 @@ public static class WatchCaption
HudIcons.Apply(_favoriteIcon, HudIcons.Favorite());
_favoriteIcon.color = fav
? new Color(1f, 0.85f, 0.25f, 1f)
: new Color(0.55f, 0.58f, 0.62f, 1f);
? HudTheme.FavoriteOn
: HudTheme.FavoriteOff;
}
private static void PlaceLeftChip(RectTransform rt, float x, float yFromTop, float width, float height)
@ -3032,7 +3032,7 @@ public static class WatchCaption
Image bg = _root.GetComponent<Image>();
bg.raycastTarget = false;
HudCanvas.StylePanel(bg, _root.transform, new Color(0.07f, 0.08f, 0.1f, 0.9f));
HudCanvas.StylePanel(bg, _root.transform);
CanvasGroup group = _root.GetComponent<CanvasGroup>();
// Buttons need raycasts; panel chrome still ignores hits via raycastTarget=false on bg/text.
@ -3048,7 +3048,7 @@ public static class WatchCaption
GameObject boxGo = new GameObject("ActivityBox", typeof(RectTransform), typeof(Image));
boxGo.transform.SetParent(_historyCol.transform, false);
_activityBoxBg = boxGo.GetComponent<Image>();
_activityBoxBg.color = new Color(0.14f, 0.16f, 0.14f, 0.55f);
_activityBoxBg.color = HudTheme.InsetFill;
_activityBoxBg.raycastTarget = false;
boxGo.SetActive(false);
@ -3056,7 +3056,7 @@ public static class WatchCaption
sepGo.transform.SetParent(_historyCol.transform, false);
_lifeSep = sepGo.GetComponent<RectTransform>();
Image sepImg = sepGo.GetComponent<Image>();
sepImg.color = new Color(0.55f, 0.58f, 0.62f, 0.55f);
sepImg.color = HudTheme.Separator;
sepImg.raycastTarget = false;
sepGo.SetActive(false);
@ -3197,7 +3197,7 @@ public static class WatchCaption
rt.sizeDelta = new Vector2(BtnSize, BtnSize);
Image bg = go.GetComponent<Image>();
bg.color = new Color(0.12f, 0.13f, 0.16f, 0.85f);
bg.color = HudTheme.ToolFill;
bg.raycastTarget = true;
Image iconImg = HudCanvas.MakeIcon(go.transform, "Icon", BtnSize - 4f);

View file

@ -1,7 +1,7 @@
{
"name": "IdleSpectator",
"author": "dazed",
"version": "0.28.24",
"version": "0.28.25",
"description": "AFK Idle Spectator (I) + Lore (L). Killer button retargets dossier to the killer.",
"GUID": "com.dazed.idlespectator"
}