Merge branch '1.12.2' into pair-notifs-ui
# Conflicts: # LightlessSync/UI/SettingsUi.cs
This commit is contained in:
@@ -18,6 +18,7 @@ using LightlessSync.PlayerData.Pairs;
|
||||
using LightlessSync.Services;
|
||||
using LightlessSync.Services.Mediator;
|
||||
using LightlessSync.Services.ServerConfiguration;
|
||||
using LightlessSync.UI.Style;
|
||||
using LightlessSync.Utils;
|
||||
using LightlessSync.UtilsEnum.Enum;
|
||||
using LightlessSync.WebAPI;
|
||||
@@ -44,10 +45,8 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
private readonly ApiController _apiController;
|
||||
private readonly CacheMonitor _cacheMonitor;
|
||||
private readonly LightlessConfigService _configService;
|
||||
|
||||
private readonly ConcurrentDictionary<GameObjectHandler, Dictionary<string, FileDownloadStatus>> _currentDownloads =
|
||||
new();
|
||||
|
||||
private readonly UiThemeConfigService _themeConfigService;
|
||||
private readonly ConcurrentDictionary<GameObjectHandler, Dictionary<string, FileDownloadStatus>> _currentDownloads = new();
|
||||
private readonly DalamudUtilService _dalamudUtilService;
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly FileCacheManager _fileCacheManager;
|
||||
@@ -77,6 +76,9 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
private string _lightfinderIconInput = string.Empty;
|
||||
private bool _lightfinderIconInputInitialized = false;
|
||||
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[]
|
||||
{
|
||||
@@ -92,7 +94,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
private bool _wasOpen = false;
|
||||
|
||||
public SettingsUi(ILogger<SettingsUi> logger,
|
||||
UiSharedService uiShared, LightlessConfigService configService,
|
||||
UiSharedService uiShared, LightlessConfigService configService, UiThemeConfigService themeConfigService,
|
||||
PairManager pairManager,
|
||||
ServerConfigurationManager serverConfigurationManager,
|
||||
PlayerPerformanceConfigService playerPerformanceConfigService,
|
||||
@@ -110,6 +112,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
performanceCollector)
|
||||
{
|
||||
_configService = configService;
|
||||
_themeConfigService = themeConfigService;
|
||||
_pairManager = pairManager;
|
||||
_serverConfigurationManager = serverConfigurationManager;
|
||||
_playerPerformanceConfigService = playerPerformanceConfigService;
|
||||
@@ -138,6 +141,12 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
};
|
||||
|
||||
Mediator.Subscribe<OpenSettingsUiMessage>(this, (_) => Toggle());
|
||||
Mediator.Subscribe<OpenLightfinderSettingsMessage>(this, (_) =>
|
||||
{
|
||||
IsOpen = true;
|
||||
_selectGeneralTabOnNextDraw = true;
|
||||
_openLightfinderSectionOnNextDraw = true;
|
||||
});
|
||||
Mediator.Subscribe<SwitchToIntroUiMessage>(this, (_) => IsOpen = false);
|
||||
Mediator.Subscribe<CutsceneStartMessage>(this, (_) => UiSharedService_GposeStart());
|
||||
Mediator.Subscribe<CutsceneEndMessage>(this, (_) => UiSharedService_GposeEnd());
|
||||
@@ -177,39 +186,360 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
|
||||
DrawSettingsContent();
|
||||
}
|
||||
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)
|
||||
{
|
||||
var innerSpacing = ImGui.GetStyle().ItemInnerSpacing.X;
|
||||
var foregroundColor = PackedColorToVector3(colors.Foreground);
|
||||
var glowColor = PackedColorToVector3(colors.Glow);
|
||||
|
||||
const ImGuiColorEditFlags colorFlags = ImGuiColorEditFlags.NoInputs | ImGuiColorEditFlags.NoLabel;
|
||||
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);
|
||||
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<DtrEntry.Colors> 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 foregroundColor = ConvertColor(colors.Foreground);
|
||||
var glowColor = ConvertColor(colors.Glow);
|
||||
|
||||
var ret = ImGui.ColorEdit3("###foreground", ref foregroundColor,
|
||||
ImGuiColorEditFlags.NoInputs | ImGuiColorEditFlags.NoLabel | ImGuiColorEditFlags.Uint8);
|
||||
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,
|
||||
ImGuiColorEditFlags.NoInputs | ImGuiColorEditFlags.NoLabel | ImGuiColorEditFlags.Uint8);
|
||||
if (ImGui.IsItemHovered())
|
||||
ImGui.SetTooltip("Glow Color - Set to pure black (#000000) to use the default color");
|
||||
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)
|
||||
=> unchecked(new((byte)color / 255.0f, (byte)(color >> 8) / 255.0f, (byte)(color >> 16) / 255.0f));
|
||||
private static DtrEntry.Colors SwapColorChannels(DtrEntry.Colors colors)
|
||||
=> new(SwapColorChannels(colors.Foreground), SwapColorChannels(colors.Glow));
|
||||
|
||||
static uint ConvertBackColor(Vector3 color)
|
||||
=> byte.CreateSaturating(color.X * 255.0f) | ((uint)byte.CreateSaturating(color.Y * 255.0f) << 8) |
|
||||
((uint)byte.CreateSaturating(color.Z * 255.0f) << 16);
|
||||
private static uint SwapColorChannels(uint color)
|
||||
{
|
||||
if (color == 0)
|
||||
return 0;
|
||||
|
||||
return ((color & 0xFFu) << 16) | (color & 0xFF00u) | ((color >> 16) & 0xFFu);
|
||||
}
|
||||
|
||||
private static Vector4 PackedThemeColorToVector4(uint packed)
|
||||
=> new(
|
||||
(packed & 0xFF) / 255f,
|
||||
((packed >> 8) & 0xFF) / 255f,
|
||||
((packed >> 16) & 0xFF) / 255f,
|
||||
((packed >> 24) & 0xFF) / 255f);
|
||||
|
||||
private static uint ThemeVector4ToPackedColor(Vector4 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);
|
||||
var a = ToByte(color.W);
|
||||
return (uint)(r | (g << 8) | (b << 16) | (a << 24));
|
||||
}
|
||||
|
||||
private void UpdateStyleOverride(string key, Action<UiStyleOverride> updater)
|
||||
{
|
||||
var overrides = _themeConfigService.Current.StyleOverrides;
|
||||
|
||||
if (!overrides.TryGetValue(key, out var entry))
|
||||
entry = new UiStyleOverride();
|
||||
|
||||
updater(entry);
|
||||
|
||||
if (entry.IsEmpty)
|
||||
overrides.Remove(key);
|
||||
else
|
||||
overrides[key] = entry;
|
||||
|
||||
_themeConfigService.Save();
|
||||
}
|
||||
|
||||
private void DrawThemeOverridesSection()
|
||||
{
|
||||
ImGui.TextUnformatted("Lightless Theme Overrides");
|
||||
_uiShared.DrawHelpText("Adjust the Lightless redesign theme. Overrides only apply when the redesign is enabled.");
|
||||
|
||||
if (!_configService.Current.UseLightlessRedesign)
|
||||
UiSharedService.ColorTextWrapped("The Lightless redesign is currently disabled. Enable it to see these changes take effect.", UIColors.Get("DimRed"));
|
||||
|
||||
const ImGuiTableFlags flags = ImGuiTableFlags.Borders | ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingStretchProp;
|
||||
if (!ImGui.BeginTable("##ThemeOverridesTable", 3, flags))
|
||||
return;
|
||||
|
||||
ImGui.TableSetupColumn("Element", ImGuiTableColumnFlags.WidthFixed, 325f);
|
||||
ImGui.TableSetupColumn("Value", ImGuiTableColumnFlags.WidthStretch);
|
||||
ImGui.TableSetupColumn("Reset", ImGuiTableColumnFlags.WidthFixed, 70f);
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
DrawThemeCategoryRow("Colors");
|
||||
foreach (var option in MainStyle.ColorOptions)
|
||||
DrawThemeColorRow(option);
|
||||
|
||||
DrawThemeCategoryRow("Spacing & Padding");
|
||||
foreach (var option in MainStyle.Vector2Options)
|
||||
DrawThemeVectorRow(option);
|
||||
|
||||
DrawThemeCategoryRow("Rounding & Sizes");
|
||||
foreach (var option in MainStyle.FloatOptions)
|
||||
DrawThemeFloatRow(option);
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
private static void DrawThemeCategoryRow(string label)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableSetColumnIndex(0);
|
||||
ImGui.TextColored(UIColors.Get("LightlessPurple"), label);
|
||||
ImGui.TableSetColumnIndex(1);
|
||||
ImGui.TableSetColumnIndex(2);
|
||||
}
|
||||
|
||||
private void DrawThemeColorRow(MainStyle.StyleColorOption option)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableSetColumnIndex(0);
|
||||
ImGui.TextUnformatted(option.Label);
|
||||
bool showTooltip = ImGui.IsItemHovered();
|
||||
|
||||
var tooltip = string.Empty;
|
||||
if (!string.IsNullOrEmpty(option.Description))
|
||||
tooltip = option.Description;
|
||||
|
||||
var overrides = _themeConfigService.Current.StyleOverrides;
|
||||
overrides.TryGetValue(option.Key, out var existing);
|
||||
|
||||
if (!string.IsNullOrEmpty(option.UiColorKey))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(tooltip))
|
||||
tooltip += "\n";
|
||||
tooltip += $"Default uses UIColors[\"{option.UiColorKey}\"]";
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.TextDisabled($"(UIColors.{option.UiColorKey})");
|
||||
if (ImGui.IsItemHovered())
|
||||
showTooltip = true;
|
||||
}
|
||||
|
||||
ImGui.TableSetColumnIndex(2);
|
||||
if (DrawStyleResetButton(option.Key, existing?.Color is not null))
|
||||
{
|
||||
UpdateStyleOverride(option.Key, entry =>
|
||||
{
|
||||
entry.Color = null;
|
||||
entry.Float = null;
|
||||
entry.Vector2 = null;
|
||||
});
|
||||
|
||||
existing = null;
|
||||
}
|
||||
|
||||
if (showTooltip && !string.IsNullOrEmpty(tooltip))
|
||||
ImGui.SetTooltip(tooltip);
|
||||
|
||||
var defaultColor = MainStyle.NormalizeColorVector(option.DefaultValue());
|
||||
var current = existing?.Color is { } packed ? PackedThemeColorToVector4(packed) : defaultColor;
|
||||
var edit = current;
|
||||
|
||||
ImGui.TableSetColumnIndex(1);
|
||||
if (ImGui.ColorEdit4($"##theme-color-{option.Key}", ref edit, ImGuiColorEditFlags.AlphaPreviewHalf))
|
||||
{
|
||||
UpdateStyleOverride(option.Key, entry =>
|
||||
{
|
||||
entry.Color = ThemeVector4ToPackedColor(edit);
|
||||
entry.Float = null;
|
||||
entry.Vector2 = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawThemeVectorRow(MainStyle.StyleVector2Option option)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableSetColumnIndex(0);
|
||||
ImGui.TextUnformatted(option.Label);
|
||||
if (!string.IsNullOrEmpty(option.Description) && ImGui.IsItemHovered())
|
||||
ImGui.SetTooltip(option.Description);
|
||||
|
||||
var overrides = _themeConfigService.Current.StyleOverrides;
|
||||
overrides.TryGetValue(option.Key, out var existing);
|
||||
|
||||
ImGui.TableSetColumnIndex(2);
|
||||
if (DrawStyleResetButton(option.Key, existing?.Vector2 is not null))
|
||||
{
|
||||
UpdateStyleOverride(option.Key, entry =>
|
||||
{
|
||||
entry.Vector2 = null;
|
||||
entry.Color = null;
|
||||
entry.Float = null;
|
||||
});
|
||||
existing = null;
|
||||
}
|
||||
|
||||
var defaultValue = option.DefaultValue();
|
||||
var current = existing?.Vector2 is { } vectorOverride ? (Vector2)vectorOverride : defaultValue;
|
||||
var edit = current;
|
||||
|
||||
ImGui.TableSetColumnIndex(1);
|
||||
if (ImGui.DragFloat2($"##theme-vector-{option.Key}", ref edit, option.Speed))
|
||||
{
|
||||
if (option.Min is { } min)
|
||||
edit = Vector2.Max(edit, min);
|
||||
if (option.Max is { } max)
|
||||
edit = Vector2.Min(edit, max);
|
||||
|
||||
UpdateStyleOverride(option.Key, entry =>
|
||||
{
|
||||
entry.Vector2 = new Vector2Config(edit.X, edit.Y);
|
||||
entry.Color = null;
|
||||
entry.Float = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawThemeFloatRow(MainStyle.StyleFloatOption option)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableSetColumnIndex(0);
|
||||
ImGui.TextUnformatted(option.Label);
|
||||
if (!string.IsNullOrEmpty(option.Description) && ImGui.IsItemHovered())
|
||||
ImGui.SetTooltip(option.Description);
|
||||
|
||||
var overrides = _themeConfigService.Current.StyleOverrides;
|
||||
overrides.TryGetValue(option.Key, out var existing);
|
||||
|
||||
ImGui.TableSetColumnIndex(2);
|
||||
if (DrawStyleResetButton(option.Key, existing?.Float is not null))
|
||||
{
|
||||
UpdateStyleOverride(option.Key, entry =>
|
||||
{
|
||||
entry.Float = null;
|
||||
entry.Color = null;
|
||||
entry.Vector2 = null;
|
||||
});
|
||||
existing = null;
|
||||
}
|
||||
|
||||
var current = existing?.Float ?? option.DefaultValue;
|
||||
var edit = current;
|
||||
|
||||
var min = option.Min ?? float.MinValue;
|
||||
var max = option.Max ?? float.MaxValue;
|
||||
|
||||
ImGui.TableSetColumnIndex(1);
|
||||
if (ImGui.DragFloat($"##theme-float-{option.Key}", ref edit, option.Speed, min, max, "%.2f"))
|
||||
{
|
||||
if (option.Min.HasValue)
|
||||
edit = MathF.Max(option.Min.Value, edit);
|
||||
if (option.Max.HasValue)
|
||||
edit = MathF.Min(option.Max.Value, edit);
|
||||
|
||||
UpdateStyleOverride(option.Key, entry =>
|
||||
{
|
||||
entry.Float = edit;
|
||||
entry.Color = null;
|
||||
entry.Vector2 = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private bool DrawStyleResetButton(string key, bool hasOverride, string? tooltipOverride = null)
|
||||
{
|
||||
using var id = ImRaii.PushId($"reset-{key}");
|
||||
using var disabled = ImRaii.Disabled(!hasOverride);
|
||||
var availableWidth = ImGui.GetContentRegionAvail().X;
|
||||
bool pressed = false;
|
||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||
{
|
||||
if (ImGui.Button(FontAwesomeIcon.Undo.ToIconString(), new Vector2(availableWidth, 0)))
|
||||
pressed = true;
|
||||
}
|
||||
|
||||
var tooltip = tooltipOverride ?? (hasOverride
|
||||
? "Reset this style override to its default value."
|
||||
: "Value already matches the default.");
|
||||
UiSharedService.AttachToolTip(tooltip);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
private void DrawBlockedTransfers()
|
||||
@@ -1187,12 +1517,193 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
var forceOpenLightfinder = _openLightfinderSectionOnNextDraw;
|
||||
if (_openLightfinderSectionOnNextDraw)
|
||||
{
|
||||
ImGui.SetNextItemOpen(true, ImGuiCond.Always);
|
||||
}
|
||||
|
||||
if (_uiShared.MediumTreeNode("Lightfinder", UIColors.Get("LightlessPurple")))
|
||||
{
|
||||
if (forceOpenLightfinder)
|
||||
{
|
||||
ImGui.SetScrollHereY();
|
||||
}
|
||||
|
||||
_openLightfinderSectionOnNextDraw = false;
|
||||
|
||||
bool autoEnable = _configService.Current.LightfinderAutoEnableOnConnect;
|
||||
var autoAlign = _configService.Current.LightfinderAutoAlign;
|
||||
var offsetX = (int)_configService.Current.LightfinderLabelOffsetX;
|
||||
var offsetY = (int)_configService.Current.LightfinderLabelOffsetY;
|
||||
var labelScale = _configService.Current.LightfinderLabelScale;
|
||||
bool showLightfinderInDtr = _configService.Current.ShowLightfinderInDtr;
|
||||
var dtrLightfinderEnabled = SwapColorChannels(_configService.Current.DtrColorsLightfinderEnabled);
|
||||
var dtrLightfinderDisabled = SwapColorChannels(_configService.Current.DtrColorsLightfinderDisabled);
|
||||
var dtrLightfinderCooldown = SwapColorChannels(_configService.Current.DtrColorsLightfinderCooldown);
|
||||
var dtrLightfinderUnavailable = SwapColorChannels(_configService.Current.DtrColorsLightfinderUnavailable);
|
||||
|
||||
ImGui.TextUnformatted("Connection");
|
||||
if (ImGui.Checkbox("Auto-enable Lightfinder on server connection", ref autoEnable))
|
||||
{
|
||||
_configService.Current.LightfinderAutoEnableOnConnect = autoEnable;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("When enabled, Lightfinder will automatically turn on after reconnecting to the Lightless server.");
|
||||
|
||||
_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))
|
||||
{
|
||||
_configService.Current.ShowLightfinderInDtr = showLightfinderInDtr;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Adds a Lightfinder status to the Server info bar. Left click toggles Lightfinder when visible.");
|
||||
|
||||
var lightfinderDisplayMode = _configService.Current.LightfinderDtrDisplayMode;
|
||||
var lightfinderDisplayLabel = lightfinderDisplayMode switch
|
||||
{
|
||||
LightfinderDtrDisplayMode.PendingPairRequests => "Pending pair requests",
|
||||
_ => "Nearby Lightfinder users",
|
||||
};
|
||||
|
||||
ImGui.BeginDisabled(!showLightfinderInDtr);
|
||||
if (ImGui.BeginCombo("Info display", lightfinderDisplayLabel))
|
||||
{
|
||||
foreach (var option in Enum.GetValues<LightfinderDtrDisplayMode>())
|
||||
{
|
||||
var optionLabel = option switch
|
||||
{
|
||||
LightfinderDtrDisplayMode.PendingPairRequests => "Pending pair requests",
|
||||
_ => "Nearby Lightfinder users",
|
||||
};
|
||||
|
||||
var selected = option == lightfinderDisplayMode;
|
||||
if (ImGui.Selectable(optionLabel, selected))
|
||||
{
|
||||
_configService.Current.LightfinderDtrDisplayMode = option;
|
||||
_configService.Save();
|
||||
}
|
||||
|
||||
if (selected)
|
||||
ImGui.SetItemDefaultFocus();
|
||||
}
|
||||
|
||||
ImGui.EndCombo();
|
||||
}
|
||||
ImGui.EndDisabled();
|
||||
_uiShared.DrawHelpText("Choose what the Lightfinder info bar displays while Lightfinder is active.");
|
||||
|
||||
bool useLightfinderColors = _configService.Current.UseLightfinderColorsInDtr;
|
||||
if (ImGui.Checkbox("Color-code the Lightfinder info bar according to status", ref useLightfinderColors))
|
||||
{
|
||||
_configService.Current.UseLightfinderColorsInDtr = useLightfinderColors;
|
||||
_configService.Save();
|
||||
}
|
||||
|
||||
ImGui.BeginDisabled(!showLightfinderInDtr || !useLightfinderColors);
|
||||
const ImGuiTableFlags lightfinderInfoTableFlags = ImGuiTableFlags.Borders | ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit;
|
||||
if (ImGui.BeginTable("##LightfinderInfoBarColorTable", 3, lightfinderInfoTableFlags))
|
||||
{
|
||||
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();
|
||||
|
||||
_uiShared.ColoredSeparator(UIColors.Get("LightlessPurpleDefault"), 1.5f);
|
||||
|
||||
ImGui.TextUnformatted("Alignment");
|
||||
ImGui.BeginDisabled(autoAlign);
|
||||
@@ -1344,6 +1855,17 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
|
||||
_uiShared.DrawHelpText("Toggles paired player(s) Lightfinder label.");
|
||||
|
||||
var showHidden = _configService.Current.LightfinderLabelShowHidden;
|
||||
if (ImGui.Checkbox("Show Lightfinder label when no nameplate(s) is visible", ref showHidden))
|
||||
{
|
||||
_configService.Current.LightfinderLabelShowHidden = showHidden;
|
||||
_configService.Save();
|
||||
_nameplateHandler.ClearNameplateCaches();
|
||||
_nameplateHandler.FlagRefresh();
|
||||
_nameplateService.RequestRedraw();
|
||||
}
|
||||
_uiShared.DrawHelpText("Toggles Lightfinder label when no nameplate(s) is visible.");
|
||||
|
||||
_uiShared.ColoredSeparator(UIColors.Get("LightlessPurpleDefault"), 1.5f);
|
||||
|
||||
ImGui.TextUnformatted("Label");
|
||||
@@ -1389,7 +1911,8 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
var selected = i == _lightfinderIconPresetIndex;
|
||||
if (ImGui.Selectable(preview, selected))
|
||||
{
|
||||
ApplyLightfinderIcon(optionGlyph, i);
|
||||
_lightfinderIconInput = NameplateHandler.ToIconEditorString(optionGlyph);
|
||||
_lightfinderIconPresetIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1550,29 +2073,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();
|
||||
|
||||
@@ -1649,6 +2185,8 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
|
||||
_uiShared.DrawHelpText("This changes the vanity colored UID's in pair list.");
|
||||
|
||||
DrawThemeOverridesSection();
|
||||
|
||||
_uiShared.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f);
|
||||
ImGui.TreePop();
|
||||
}
|
||||
@@ -2872,14 +3410,21 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Lightless Sync Discord"))
|
||||
{
|
||||
Util.OpenLink("https://discord.gg/mpNdkrTRjW");
|
||||
Util.OpenLink("https://discord.gg/Lightless");
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
if (ImGui.BeginTabBar("mainTabBar"))
|
||||
{
|
||||
if (ImGui.BeginTabItem("General"))
|
||||
var generalTabFlags = ImGuiTabItemFlags.None;
|
||||
if (_selectGeneralTabOnNextDraw)
|
||||
{
|
||||
generalTabFlags |= ImGuiTabItemFlags.SetSelected;
|
||||
}
|
||||
|
||||
if (ImGui.BeginTabItem("General", generalTabFlags))
|
||||
{
|
||||
_selectGeneralTabOnNextDraw = false;
|
||||
DrawGeneral();
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user