Files
HellionChat/ChatTwo/Ui/HellionStyle.cs
T
JonKazama-Hellion 83b9cc62c7 Fix HellionStyle palette byte order (RRGGBBAA, not AARRGGBB)
ChatTwo's ColourUtil.RgbaToAbgr expects the input to be 0xRRGGBBAA
(see Settings.cs Ko-fi buttons, e.g. 0xFF5E5BFF for Ko-fi pink),
not 0xAARRGGBB. The previous palette was bit-shifted by one byte,
which is why the supposedly cyan-teal accents rendered as
half-transparent magenta in-game.
2026-05-01 21:04:54 +02:00

73 lines
3.6 KiB
C#

using ChatTwo.Util;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface.Utility.Raii;
namespace ChatTwo.Ui;
/// <summary>
/// Local ImGui style override applied inside Hellion-owned settings surfaces
/// (Privacy tab, first-run wizard). Industrial HUD palette: deep slate
/// background with cyan-teal accents and sharper geometric framing. Scoped
/// via using-blocks so upstream Chat 2 tabs render in their original style.
/// </summary>
internal static class HellionStyle
{
// Palette — kept central so a future theme switch only edits one file.
// Encoded as 0xRRGGBBAA, matching the convention ChatTwo uses elsewhere
// (see Settings.cs Ko-fi buttons). RgbaToAbgr handles the byte swap.
private const uint AccentRgba = 0x00B8D4FF; // cyan-teal accent
private const uint AccentHoverRgba = 0x26C6DAFF;
private const uint AccentActiveRgba = 0x00838FFF;
private const uint FrameBgRgba = 0x102027FF; // deep slate
private const uint FrameBgHoverRgba = 0x1B2C36FF;
private const uint FrameBgActiveRgba = 0x263A45FF;
private const uint BorderRgba = 0x37474FFF; // steel border
private const uint HeaderRgba = 0x1B2C36FF;
private const uint HeaderHoverRgba = 0x263A45FF;
private const uint HeaderActiveRgba = 0x324A57FF;
private const uint TitleBgActiveRgba = 0x00838FFF;
private const uint CheckMarkRgba = 0x00B8D4FF;
private const uint SliderGrabRgba = 0x00B8D4FF;
private const uint SliderGrabActiveRgba = 0x26C6DAFF;
/// <summary>
/// Push the Hellion color stack. Returns a disposable bundle that pops
/// every color in reverse order on Dispose. Use inside a `using` block.
/// </summary>
internal static IDisposable Push()
{
var stack = new StackHandle();
// Order matters less than count: each PushColor needs a matching pop.
stack.Add(ImRaii.PushColor(ImGuiCol.Button, ColourUtil.RgbaToAbgr(AccentRgba)));
stack.Add(ImRaii.PushColor(ImGuiCol.ButtonHovered, ColourUtil.RgbaToAbgr(AccentHoverRgba)));
stack.Add(ImRaii.PushColor(ImGuiCol.ButtonActive, ColourUtil.RgbaToAbgr(AccentActiveRgba)));
stack.Add(ImRaii.PushColor(ImGuiCol.FrameBg, ColourUtil.RgbaToAbgr(FrameBgRgba)));
stack.Add(ImRaii.PushColor(ImGuiCol.FrameBgHovered, ColourUtil.RgbaToAbgr(FrameBgHoverRgba)));
stack.Add(ImRaii.PushColor(ImGuiCol.FrameBgActive, ColourUtil.RgbaToAbgr(FrameBgActiveRgba)));
stack.Add(ImRaii.PushColor(ImGuiCol.Border, ColourUtil.RgbaToAbgr(BorderRgba)));
stack.Add(ImRaii.PushColor(ImGuiCol.Header, ColourUtil.RgbaToAbgr(HeaderRgba)));
stack.Add(ImRaii.PushColor(ImGuiCol.HeaderHovered, ColourUtil.RgbaToAbgr(HeaderHoverRgba)));
stack.Add(ImRaii.PushColor(ImGuiCol.HeaderActive, ColourUtil.RgbaToAbgr(HeaderActiveRgba)));
stack.Add(ImRaii.PushColor(ImGuiCol.TitleBgActive, ColourUtil.RgbaToAbgr(TitleBgActiveRgba)));
stack.Add(ImRaii.PushColor(ImGuiCol.CheckMark, ColourUtil.RgbaToAbgr(CheckMarkRgba)));
stack.Add(ImRaii.PushColor(ImGuiCol.SliderGrab, ColourUtil.RgbaToAbgr(SliderGrabRgba)));
stack.Add(ImRaii.PushColor(ImGuiCol.SliderGrabActive, ColourUtil.RgbaToAbgr(SliderGrabActiveRgba)));
return stack;
}
private sealed class StackHandle : IDisposable
{
private readonly List<IDisposable> _items = new(16);
internal void Add(IDisposable d) => _items.Add(d);
public void Dispose()
{
// Pop in reverse order so the ImGui stack unwinds cleanly.
for (var i = _items.Count - 1; i >= 0; i--)
_items[i].Dispose();
_items.Clear();
}
}
}