Added color options for header

This commit is contained in:
cake
2025-12-26 22:26:29 +01:00
parent f792bc1954
commit 1ab4e2f94b
3 changed files with 68 additions and 26 deletions

View File

@@ -2803,8 +2803,13 @@ public class SettingsUi : WindowMediatorSubscriberBase
("LightlessYellow", "Warning Yellow", "Warning colors"), ("LightlessYellow", "Warning Yellow", "Warning colors"),
("LightlessOrange", "Performance Orange", "Performance notifications and warnings"), ("LightlessOrange", "Performance Orange", "Performance notifications and warnings"),
("PairBlue", "Syncshell Blue", "Syncshell headers, toggle highlights, and moderator actions"), ("PairBlue", "Syncshell Blue", "Syncshell headers, toggle highlights, and moderator actions"),
("DimRed", "Error Red", "Error and offline colors") ("DimRed", "Error Red", "Error and offline colors"),
("HeaderGradientTop", "Header Gradient (Top)", "Top color of the animated header background"),
("HeaderGradientBottom", "Header Gradient (Bottom)", "Bottom color of the animated header background"),
("HeaderStaticStar", "Header Stars", "Tint color for the static background stars in the header"),
("HeaderShootingStar", "Header Shooting Star", "Tint color for the shooting star effect"),
}; };
if (ImGui.BeginTable("##ColorTable", 3, if (ImGui.BeginTable("##ColorTable", 3,
ImGuiTableFlags.Borders | ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit)) ImGuiTableFlags.Borders | ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit))
{ {

View File

@@ -43,8 +43,19 @@ public class AnimatedHeader
private const float _extendedParticleHeight = 40f; private const float _extendedParticleHeight = 40f;
public float Height { get; set; } = 150f; public float Height { get; set; } = 150f;
// Color keys for theming
public string? TopColorKey { get; set; } = "HeaderGradientTop";
public string? BottomColorKey { get; set; } = "HeaderGradientBottom";
public string? StaticStarColorKey { get; set; } = "HeaderStaticStar";
public string? ShootingStarColorKey { get; set; } = "HeaderShootingStar";
// Fallbacks if the color keys are not found
public Vector4 TopColor { get; set; } = new(0.08f, 0.05f, 0.15f, 1.0f); public Vector4 TopColor { get; set; } = new(0.08f, 0.05f, 0.15f, 1.0f);
public Vector4 BottomColor { get; set; } = new(0.12f, 0.08f, 0.20f, 1.0f); public Vector4 BottomColor { get; set; } = new(0.12f, 0.08f, 0.20f, 1.0f);
public Vector4 StaticStarColor { get; set; } = new(1f, 1f, 1f, 1f);
public Vector4 ShootingStarColor { get; set; } = new(0.4f, 0.8f, 1.0f, 1.0f);
public bool EnableParticles { get; set; } = true; public bool EnableParticles { get; set; } = true;
public bool EnableBottomGradient { get; set; } = true; public bool EnableBottomGradient { get; set; } = true;
@@ -148,16 +159,21 @@ public class AnimatedHeader
{ {
var drawList = ImGui.GetWindowDrawList(); var drawList = ImGui.GetWindowDrawList();
var top = ResolveColor(TopColorKey, TopColor);
var bottom = ResolveColor(BottomColorKey, BottomColor);
drawList.AddRectFilledMultiColor( drawList.AddRectFilledMultiColor(
headerStart, headerStart,
headerEnd, headerEnd,
ImGui.GetColorU32(TopColor), ImGui.GetColorU32(top),
ImGui.GetColorU32(TopColor), ImGui.GetColorU32(top),
ImGui.GetColorU32(BottomColor), ImGui.GetColorU32(bottom),
ImGui.GetColorU32(BottomColor) ImGui.GetColorU32(bottom)
); );
// Draw static background stars // Draw static background stars
var starBase = ResolveColor(StaticStarColorKey, StaticStarColor);
var random = new Random(42); var random = new Random(42);
for (int i = 0; i < 50; i++) for (int i = 0; i < 50; i++)
{ {
@@ -166,7 +182,9 @@ public class AnimatedHeader
(float)random.NextDouble() * (headerEnd.Y - headerStart.Y) (float)random.NextDouble() * (headerEnd.Y - headerStart.Y)
); );
var brightness = 0.3f + (float)random.NextDouble() * 0.4f; var brightness = 0.3f + (float)random.NextDouble() * 0.4f;
drawList.AddCircleFilled(starPos, 1f, ImGui.GetColorU32(new Vector4(1f, 1f, 1f, brightness))); var starColor = starBase with { W = starBase.W * brightness };
drawList.AddCircleFilled(starPos, 1f, ImGui.GetColorU32(starColor));
} }
} }
@@ -174,15 +192,18 @@ public class AnimatedHeader
{ {
var drawList = ImGui.GetWindowDrawList(); var drawList = ImGui.GetWindowDrawList();
var gradientHeight = GradientHeight; var gradientHeight = GradientHeight;
var bottom = ResolveColor(BottomColorKey, BottomColor);
for (int i = 0; i < gradientHeight; i++) for (int i = 0; i < gradientHeight; i++)
{ {
var progress = i / gradientHeight; var progress = i / gradientHeight;
var smoothProgress = progress * progress; var smoothProgress = progress * progress;
var r = BottomColor.X + (0.0f - BottomColor.X) * smoothProgress;
var g = BottomColor.Y + (0.0f - BottomColor.Y) * smoothProgress; var r = bottom.X + (0.0f - bottom.X) * smoothProgress;
var b = BottomColor.Z + (0.0f - BottomColor.Z) * smoothProgress; var g = bottom.Y + (0.0f - bottom.Y) * smoothProgress;
var b = bottom.Z + (0.0f - bottom.Z) * smoothProgress;
var alpha = 1f - smoothProgress; var alpha = 1f - smoothProgress;
var gradientColor = new Vector4(r, g, b, alpha); var gradientColor = new Vector4(r, g, b, alpha);
drawList.AddLine( drawList.AddLine(
new Vector2(headerStart.X, headerEnd.Y + i), new Vector2(headerStart.X, headerEnd.Y + i),
@@ -310,9 +331,11 @@ public class AnimatedHeader
? baseAlpha * (0.6f + 0.4f * MathF.Sin(particle.Twinkle)) ? baseAlpha * (0.6f + 0.4f * MathF.Sin(particle.Twinkle))
: baseAlpha; : baseAlpha;
var shootingBase = ResolveColor(ShootingStarColorKey, ShootingStarColor);
if (particle.Type == ParticleType.ShootingStar && particle.Trail != null && particle.Trail.Count > 1) if (particle.Type == ParticleType.ShootingStar && particle.Trail != null && particle.Trail.Count > 1)
{ {
var cyanColor = new Vector4(0.4f, 0.8f, 1.0f, 1.0f); var baseColor = shootingBase;
for (int t = 1; t < particle.Trail.Count; t++) for (int t = 1; t < particle.Trail.Count; t++)
{ {
@@ -321,17 +344,18 @@ public class AnimatedHeader
var trailWidth = (1f - trailProgress) * 3f + 1f; var trailWidth = (1f - trailProgress) * 3f + 1f;
var glowAlpha = trailAlpha * 0.4f; var glowAlpha = trailAlpha * 0.4f;
drawList.AddLine( drawList.AddLine(
bannerStart + particle.Trail[t - 1], bannerStart + particle.Trail[t - 1],
bannerStart + particle.Trail[t], bannerStart + particle.Trail[t],
ImGui.GetColorU32(cyanColor with { W = glowAlpha }), ImGui.GetColorU32(baseColor with { W = glowAlpha }),
trailWidth + 4f trailWidth + 4f
); );
drawList.AddLine( drawList.AddLine(
bannerStart + particle.Trail[t - 1], bannerStart + particle.Trail[t - 1],
bannerStart + particle.Trail[t], bannerStart + particle.Trail[t],
ImGui.GetColorU32(cyanColor with { W = trailAlpha }), ImGui.GetColorU32(baseColor with { W = trailAlpha }),
trailWidth trailWidth
); );
} }
@@ -450,6 +474,13 @@ public class AnimatedHeader
Hue = 270f Hue = 270f
}); });
} }
private static Vector4 ResolveColor(string? key, Vector4 fallback)
{
if (string.IsNullOrWhiteSpace(key))
return fallback;
return UIColors.Get(key);
}
/// <summary> /// <summary>
/// Clears all active particles. Useful when closing or hiding a window with an animated header. /// Clears all active particles. Useful when closing or hiding a window with an animated header.

View File

@@ -6,7 +6,7 @@ namespace LightlessSync.UI
{ {
internal static class UIColors internal static class UIColors
{ {
private static readonly Dictionary<string, string> DefaultHexColors = new(StringComparer.OrdinalIgnoreCase) private static readonly Dictionary<string, string> _defaultHexColors = new(StringComparer.OrdinalIgnoreCase)
{ {
{ "LightlessPurple", "#ad8af5" }, { "LightlessPurple", "#ad8af5" },
{ "LightlessPurpleActive", "#be9eff" }, { "LightlessPurpleActive", "#be9eff" },
@@ -31,6 +31,12 @@ namespace LightlessSync.UI
{ "ProfileBodyGradientTop", "#2f283fff" }, { "ProfileBodyGradientTop", "#2f283fff" },
{ "ProfileBodyGradientBottom", "#372d4d00" }, { "ProfileBodyGradientBottom", "#372d4d00" },
{ "HeaderGradientTop", "#140D26FF" },
{ "HeaderGradientBottom", "#1F1433FF" },
{ "HeaderStaticStar", "#FFFFFFFF" },
{ "HeaderShootingStar", "#66CCFFFF" },
}; };
private static LightlessConfigService? _configService; private static LightlessConfigService? _configService;
@@ -45,7 +51,7 @@ namespace LightlessSync.UI
if (_configService?.Current.CustomUIColors.TryGetValue(name, out var customColorHex) == true) if (_configService?.Current.CustomUIColors.TryGetValue(name, out var customColorHex) == true)
return HexToRgba(customColorHex); return HexToRgba(customColorHex);
if (!DefaultHexColors.TryGetValue(name, out var hex)) if (!_defaultHexColors.TryGetValue(name, out var hex))
throw new ArgumentException($"Color '{name}' not found in UIColors.", nameof(name)); throw new ArgumentException($"Color '{name}' not found in UIColors.", nameof(name));
return HexToRgba(hex); return HexToRgba(hex);
@@ -53,7 +59,7 @@ namespace LightlessSync.UI
public static void Set(string name, Vector4 color) public static void Set(string name, Vector4 color)
{ {
if (!DefaultHexColors.ContainsKey(name)) if (!_defaultHexColors.ContainsKey(name))
throw new ArgumentException($"Color '{name}' not found in UIColors.", nameof(name)); throw new ArgumentException($"Color '{name}' not found in UIColors.", nameof(name));
if (_configService != null) if (_configService != null)
@@ -83,7 +89,7 @@ namespace LightlessSync.UI
public static Vector4 GetDefault(string name) public static Vector4 GetDefault(string name)
{ {
if (!DefaultHexColors.TryGetValue(name, out var hex)) if (!_defaultHexColors.TryGetValue(name, out var hex))
throw new ArgumentException($"Color '{name}' not found in UIColors.", nameof(name)); throw new ArgumentException($"Color '{name}' not found in UIColors.", nameof(name));
return HexToRgba(hex); return HexToRgba(hex);
@@ -96,7 +102,7 @@ namespace LightlessSync.UI
public static IEnumerable<string> GetColorNames() public static IEnumerable<string> GetColorNames()
{ {
return DefaultHexColors.Keys; return _defaultHexColors.Keys;
} }
public static Vector4 HexToRgba(string hexColor) public static Vector4 HexToRgba(string hexColor)