From 6a0f8c507cd44d2f7889802d3bb9af87a4167a38 Mon Sep 17 00:00:00 2001 From: azyges <229218900+azyges@users.noreply.github.com> Date: Sat, 11 Oct 2025 07:52:52 +0900 Subject: [PATCH] add seperate colors for labels and update color inputs --- LightlessSync/Services/NameplateHandler.cs | 4 +- LightlessSync/UI/SettingsUi.cs | 278 ++++++++++++++++----- LightlessSync/UI/UIColors.cs | 3 + 3 files changed, 215 insertions(+), 70 deletions(-) diff --git a/LightlessSync/Services/NameplateHandler.cs b/LightlessSync/Services/NameplateHandler.cs index 74edabc..0731d0e 100644 --- a/LightlessSync/Services/NameplateHandler.cs +++ b/LightlessSync/Services/NameplateHandler.cs @@ -259,8 +259,8 @@ public unsafe class NameplateHandler : IMediatorSubscriber continue; } - var labelColor = UIColors.Get("LightlessPurple"); - var edgeColor = UIColors.Get("FullBlack"); + var labelColor = UIColors.Get("Lightfinder"); + var edgeColor = UIColors.Get("LightfinderEdge"); var config = _configService.Current; var scaleMultiplier = System.Math.Clamp(config.LightfinderLabelScale, 0.5f, 2.0f); diff --git a/LightlessSync/UI/SettingsUi.cs b/LightlessSync/UI/SettingsUi.cs index de20fb6..6bb69a2 100644 --- a/LightlessSync/UI/SettingsUi.cs +++ b/LightlessSync/UI/SettingsUi.cs @@ -77,6 +77,7 @@ public class SettingsUi : WindowMediatorSubscriberBase private int _lightfinderIconPresetIndex = -1; private bool _selectGeneralTabOnNextDraw = false; private bool _openLightfinderSectionOnNextDraw = false; + private static readonly LightlessConfig DefaultConfig = new(); private static readonly (string Label, SeIconChar Icon)[] LightfinderIconPresets = new[] { ("Link Marker", SeIconChar.LinkMarker), @@ -185,52 +186,102 @@ public class SettingsUi : WindowMediatorSubscriberBase DrawSettingsContent(); } - private static bool InputDtrColors(string label, ref DtrEntry.Colors colors) + private static Vector3 PackedColorToVector3(uint color) + => new( + (color & 0xFF) / 255f, + ((color >> 8) & 0xFF) / 255f, + ((color >> 16) & 0xFF) / 255f); + + private static uint Vector3ToPackedColor(Vector3 color) + { + static byte ToByte(float channel) + { + var scaled = MathF.Round(Math.Clamp(channel, 0f, 1f) * 255.0f); + return (byte)Math.Clamp((int)scaled, 0, 255); + } + + var r = ToByte(color.X); + var g = ToByte(color.Y); + var b = ToByte(color.Z); + return (uint)(r | (g << 8) | (b << 16)); + } + + private static bool DrawDtrColorEditors(ref DtrEntry.Colors colors) { - using var id = ImRaii.PushId(label); var innerSpacing = ImGui.GetStyle().ItemInnerSpacing.X; - var foregroundColor = ConvertColor(colors.Foreground); - var glowColor = ConvertColor(colors.Glow); + var foregroundColor = PackedColorToVector3(colors.Foreground); + var glowColor = PackedColorToVector3(colors.Glow); const ImGuiColorEditFlags colorFlags = ImGuiColorEditFlags.NoInputs | ImGuiColorEditFlags.NoLabel; - var ret = ImGui.ColorEdit3("###foreground", ref foregroundColor, colorFlags); + var changed = ImGui.ColorEdit3("###foreground", ref foregroundColor, colorFlags); if (ImGui.IsItemHovered()) ImGui.SetTooltip("Foreground Color - Set to pure black (#000000) to use the default color"); ImGui.SameLine(0.0f, innerSpacing); - ret |= ImGui.ColorEdit3("###glow", ref glowColor, colorFlags); + changed |= ImGui.ColorEdit3("###glow", ref glowColor, colorFlags); if (ImGui.IsItemHovered()) ImGui.SetTooltip("Glow Color - Set to pure black (#000000) to use the default color"); + if (changed) + colors = new(Vector3ToPackedColor(foregroundColor), Vector3ToPackedColor(glowColor)); + + return changed; + } + + private void DrawDtrColorRow(string id, string label, string description, ref DtrEntry.Colors colors, DtrEntry.Colors defaultDisplay, Action applyConfig) + { + ImGui.TableNextRow(); + + ImGui.TableSetColumnIndex(0); + using (ImRaii.PushId(id)) + { + var edited = DrawDtrColorEditors(ref colors); + ImGui.SameLine(0.0f, ImGui.GetStyle().ItemInnerSpacing.X); + ImGui.AlignTextToFramePadding(); + ImGui.TextUnformatted(label); + + if (edited) + { + applyConfig(colors); + _configService.Save(); + } + } + + ImGui.TableSetColumnIndex(1); + ImGui.AlignTextToFramePadding(); + ImGui.TextUnformatted(description); + + ImGui.TableSetColumnIndex(2); + using var resetId = ImRaii.PushId($"reset-{id}"); + var availableWidth = ImGui.GetContentRegionAvail().X; + var isDefault = colors == defaultDisplay; + + using (ImRaii.Disabled(isDefault)) + { + using (ImRaii.PushFont(UiBuilder.IconFont)) + { + if (ImGui.Button(FontAwesomeIcon.Undo.ToIconString(), new Vector2(availableWidth, 0))) + { + colors = defaultDisplay; + applyConfig(defaultDisplay); + _configService.Save(); + } + } + } + + UiSharedService.AttachToolTip(isDefault ? "Colors already match the default value." : "Reset these colors to their default values."); + } + + private static bool InputDtrColors(string label, ref DtrEntry.Colors colors) + { + using var id = ImRaii.PushId(label); + var innerSpacing = ImGui.GetStyle().ItemInnerSpacing.X; + var ret = DrawDtrColorEditors(ref colors); + ImGui.SameLine(0.0f, innerSpacing); ImGui.TextUnformatted(label); - if (ret) - colors = new(ConvertBackColor(foregroundColor), ConvertBackColor(glowColor)); - return ret; - - static Vector3 ConvertColor(uint color) - { - var r = (color & 0xFF) / 255.0f; - var g = ((color >> 8) & 0xFF) / 255.0f; - var b = ((color >> 16) & 0xFF) / 255.0f; - return new(r, g, b); - } - - static uint ConvertBackColor(Vector3 color) - { - static byte ToByte(float channel) - { - var scaled = MathF.Round(Math.Clamp(channel, 0f, 1f) * 255.0f); - return (byte)Math.Clamp((int)scaled, 0, 255); - } - - var r = ToByte(color.X); - var g = ToByte(color.Y); - var b = ToByte(color.Z); - return (uint)(r | (g << 8) | (b << 16)); - } } private static DtrEntry.Colors SwapColorChannels(DtrEntry.Colors colors) @@ -1386,6 +1437,62 @@ public class SettingsUi : WindowMediatorSubscriberBase _uiShared.ColoredSeparator(UIColors.Get("LightlessPurpleDefault"), 1.5f); + ImGui.TextUnformatted("Lightfinder Nameplate Colors"); + if (ImGui.BeginTable("##LightfinderColorTable", 3, ImGuiTableFlags.Borders | ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit)) + { + ImGui.TableSetupColumn("Color", ImGuiTableColumnFlags.WidthFixed); + ImGui.TableSetupColumn("Description", ImGuiTableColumnFlags.WidthStretch); + ImGui.TableSetupColumn("Reset", ImGuiTableColumnFlags.WidthFixed, 40f); + ImGui.TableHeadersRow(); + + var lightfinderColors = new (string Key, string Label, string Description)[] + { + ("Lightfinder", "Nameplate Text", "Color used for Lightfinder nameplate text."), + ("LightfinderEdge", "Nameplate Outline", "Outline color applied around Lightfinder nameplate text.") + }; + + foreach (var (key, label, description) in lightfinderColors) + { + ImGui.TableNextRow(); + + ImGui.TableSetColumnIndex(0); + var colorValue = UIColors.Get(key); + if (ImGui.ColorEdit4($"##color_{key}", ref colorValue, ImGuiColorEditFlags.NoInputs | ImGuiColorEditFlags.AlphaPreviewHalf)) + { + UIColors.Set(key, colorValue); + } + ImGui.SameLine(); + ImGui.AlignTextToFramePadding(); + ImGui.TextUnformatted(label); + + ImGui.TableSetColumnIndex(1); + ImGui.AlignTextToFramePadding(); + ImGui.TextUnformatted(description); + + ImGui.TableSetColumnIndex(2); + using var resetId = ImRaii.PushId($"Reset_{key}"); + var availableWidth = ImGui.GetContentRegionAvail().X; + var isCustom = UIColors.IsCustom(key); + using (ImRaii.Disabled(!isCustom)) + { + using (ImRaii.PushFont(UiBuilder.IconFont)) + { + if (ImGui.Button(FontAwesomeIcon.Undo.ToIconString(), new Vector2(availableWidth, 0))) + { + UIColors.Reset(key); + } + } + } + UiSharedService.AttachToolTip(isCustom ? "Reset this color to default" : "Color is already at default value"); + } + + ImGui.EndTable(); + } + + ImGui.Spacing(); + + _uiShared.ColoredSeparator(UIColors.Get("LightlessPurpleDefault"), 1.5f); + ImGui.TextUnformatted("Lightfinder Info Bar"); if (ImGui.Checkbox("Show Lightfinder status in Server info bar", ref showLightfinderInDtr)) { @@ -1436,25 +1543,47 @@ public class SettingsUi : WindowMediatorSubscriberBase } ImGui.BeginDisabled(!showLightfinderInDtr || !useLightfinderColors); - if (InputDtrColors("Enabled", ref dtrLightfinderEnabled)) + const ImGuiTableFlags lightfinderInfoTableFlags = ImGuiTableFlags.Borders | ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit; + if (ImGui.BeginTable("##LightfinderInfoBarColorTable", 3, lightfinderInfoTableFlags)) { - _configService.Current.DtrColorsLightfinderEnabled = SwapColorChannels(dtrLightfinderEnabled); - _configService.Save(); - } - if (InputDtrColors("Disabled", ref dtrLightfinderDisabled)) - { - _configService.Current.DtrColorsLightfinderDisabled = SwapColorChannels(dtrLightfinderDisabled); - _configService.Save(); - } - if (InputDtrColors("Cooldown", ref dtrLightfinderCooldown)) - { - _configService.Current.DtrColorsLightfinderCooldown = SwapColorChannels(dtrLightfinderCooldown); - _configService.Save(); - } - if (InputDtrColors("Unavailable", ref dtrLightfinderUnavailable)) - { - _configService.Current.DtrColorsLightfinderUnavailable = SwapColorChannels(dtrLightfinderUnavailable); - _configService.Save(); + ImGui.TableSetupColumn("Status", ImGuiTableColumnFlags.WidthFixed, 220f); + ImGui.TableSetupColumn("Description", ImGuiTableColumnFlags.WidthStretch); + ImGui.TableSetupColumn("Reset", ImGuiTableColumnFlags.WidthFixed, 40f); + ImGui.TableHeadersRow(); + + DrawDtrColorRow( + "enabled", + "Enabled", + "Displayed when Lightfinder is active.", + ref dtrLightfinderEnabled, + SwapColorChannels(DefaultConfig.DtrColorsLightfinderEnabled), + value => _configService.Current.DtrColorsLightfinderEnabled = SwapColorChannels(value)); + + DrawDtrColorRow( + "disabled", + "Disabled", + "Shown when Lightfinder is turned off.", + ref dtrLightfinderDisabled, + SwapColorChannels(DefaultConfig.DtrColorsLightfinderDisabled), + value => _configService.Current.DtrColorsLightfinderDisabled = SwapColorChannels(value)); + + DrawDtrColorRow( + "cooldown", + "Cooldown", + "Displayed while Lightfinder is on cooldown.", + ref dtrLightfinderCooldown, + SwapColorChannels(DefaultConfig.DtrColorsLightfinderCooldown), + value => _configService.Current.DtrColorsLightfinderCooldown = SwapColorChannels(value)); + + DrawDtrColorRow( + "unavailable", + "Unavailable", + "Used when Lightfinder is not available on the current server.", + ref dtrLightfinderUnavailable, + SwapColorChannels(DefaultConfig.DtrColorsLightfinderUnavailable), + value => _configService.Current.DtrColorsLightfinderUnavailable = SwapColorChannels(value)); + + ImGui.EndTable(); } ImGui.EndDisabled(); @@ -1798,29 +1927,42 @@ public class SettingsUi : WindowMediatorSubscriberBase } _uiShared.DrawHelpText("This will color the Server Info Bar entry based on connection status and visible pairs."); - using (ImRaii.Disabled(!useColorsInDtr)) + ImGui.BeginDisabled(!useColorsInDtr); + const ImGuiTableFlags serverInfoTableFlags = ImGuiTableFlags.Borders | ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit; + if (ImGui.BeginTable("##ServerInfoBarColorTable", 3, serverInfoTableFlags)) { - using var indent = ImRaii.PushIndent(); - if (InputDtrColors("Default", ref dtrColorsDefault)) - { - _configService.Current.DtrColorsDefault = dtrColorsDefault; - _configService.Save(); - } + ImGui.TableSetupColumn("Status", ImGuiTableColumnFlags.WidthFixed, 220f); + ImGui.TableSetupColumn("Description", ImGuiTableColumnFlags.WidthStretch); + ImGui.TableSetupColumn("Reset", ImGuiTableColumnFlags.WidthFixed, 40f); + ImGui.TableHeadersRow(); - ImGui.SameLine(); - if (InputDtrColors("Not Connected", ref dtrColorsNotConnected)) - { - _configService.Current.DtrColorsNotConnected = dtrColorsNotConnected; - _configService.Save(); - } + DrawDtrColorRow( + "server-default", + "Default", + "Displayed when connected without any special status.", + ref dtrColorsDefault, + DefaultConfig.DtrColorsDefault, + value => _configService.Current.DtrColorsDefault = value); - ImGui.SameLine(); - if (InputDtrColors("Pairs in Range", ref dtrColorsPairsInRange)) - { - _configService.Current.DtrColorsPairsInRange = dtrColorsPairsInRange; - _configService.Save(); - } + DrawDtrColorRow( + "server-not-connected", + "Not Connected", + "Shown while disconnected from the Lightless server.", + ref dtrColorsNotConnected, + DefaultConfig.DtrColorsNotConnected, + value => _configService.Current.DtrColorsNotConnected = value); + + DrawDtrColorRow( + "server-pairs", + "Pairs in Range", + "Used when nearby paired players are detected.", + ref dtrColorsPairsInRange, + DefaultConfig.DtrColorsPairsInRange, + value => _configService.Current.DtrColorsPairsInRange = value); + + ImGui.EndTable(); } + ImGui.EndDisabled(); ImGui.Spacing(); diff --git a/LightlessSync/UI/UIColors.cs b/LightlessSync/UI/UIColors.cs index 3bd288f..993573d 100644 --- a/LightlessSync/UI/UIColors.cs +++ b/LightlessSync/UI/UIColors.cs @@ -26,6 +26,9 @@ namespace LightlessSync.UI { "LightlessAdminGlow", "#b09343" }, { "LightlessModeratorText", "#94ffda" }, { "LightlessModeratorGlow", "#599c84" }, + + { "Lightfinder", "#ad8af5" }, + { "LightfinderEdge", "#000000" }, }; private static LightlessConfigService? _configService;