using ChatTwo.Util; using Dalamud.Bindings.ImGui; using Dalamud.Interface.Utility.Raii; namespace ChatTwo.Ui; /// /// 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. /// internal static class HellionStyle { // Palette — kept central so a future theme switch only edits one file. private const uint AccentRgba = 0xFF00B8D4; // cyan-teal accent private const uint AccentHoverRgba = 0xFF26C6DA; private const uint AccentActiveRgba = 0xFF00838F; private const uint FrameBgRgba = 0xFF102027; // deep slate private const uint FrameBgHoverRgba = 0xFF1B2C36; private const uint FrameBgActiveRgba = 0xFF263A45; private const uint BorderRgba = 0xFF37474F; // steel border private const uint HeaderRgba = 0xFF1B2C36; private const uint HeaderHoverRgba = 0xFF263A45; private const uint HeaderActiveRgba = 0xFF324A57; private const uint TitleBgActiveRgba = 0xFF00838F; private const uint CheckMarkRgba = 0xFF00B8D4; private const uint SliderGrabRgba = 0xFF00B8D4; private const uint SliderGrabActiveRgba = 0xFF26C6DA; /// /// Push the Hellion color stack. Returns a disposable bundle that pops /// every color in reverse order on Dispose. Use inside a `using` block. /// 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 _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(); } } }