Skip to content

Commit

Permalink
Merge pull request #124 from ahmetsait/flags-editor-dark-mode
Browse files Browse the repository at this point in the history
Fix `FlagsEditorControl` unreadable text on Visual Studio dark theme
  • Loading branch information
desjarlais authored May 13, 2024
2 parents 0a18503 + 21df4eb commit 816f3cb
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 4 deletions.
97 changes: 97 additions & 0 deletions Scintilla.NET/ColorSpace.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using System;
using System.Drawing;

namespace ScintillaNET;

internal class ColorSpace
{
public static float SrgbToLinearSrgb(float x) =>
x >= 0.04045 ? (float)Math.Pow((x + 0.055f) / (1 + 0.055f), 2.4f) : x / 12.92f;

public static float LinearSrgbToSrgb(float x) =>
x >= 0.0031308 ? 1.055f * (float)Math.Pow(x, 1.0 / 2.4) - 0.055f : 12.92f * x;
}

/// <summary>
/// OkLab color.
/// </summary>
/// <param name="L">Luminance (perceived lightness) in range [0.0, 1.0].</param>
/// <param name="a">How green/red the color is in range [-0.233887, +0.276216].</param>
/// <param name="b">How blue/yellow the color is in range [-0.311528, +0.198570].</param>
internal struct OkLab(float L, float a, float b)
{
public float L = L;
public float a = a;
public float b = b;

public readonly Srgb ToLinearSrgb()
{
float l_ = this.L + 0.3963377774f * this.a + 0.2158037573f * this.b;
float m_ = this.L - 0.1055613458f * this.a - 0.0638541728f * this.b;
float s_ = this.L - 0.0894841775f * this.a - 1.2914855480f * this.b;

float l = l_ * l_ * l_;
float m = m_ * m_ * m_;
float s = s_ * s_ * s_;

return new Srgb(
Helpers.Clamp(+4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s, 0, 1),
Helpers.Clamp(-1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s, 0, 1),
Helpers.Clamp(-0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s, 0, 1)
);
}

public override readonly string ToString()
{
return FormattableString.Invariant($"(L:{L}, a:{a}, b:{b})");
}
}

/// <summary>
/// sRGB color.
/// </summary>
/// <param name="R">Red component.</param>
/// <param name="G">Green component.</param>
/// <param name="B">Blue component.</param>
internal struct Srgb(float R, float G, float B)
{
public float R = R;
public float G = G;
public float B = B;

public readonly OkLab ToOkLab()
{
float l = 0.4122214708f * this.R + 0.5363325363f * this.G + 0.0514459929f * this.B;
float m = 0.2119034982f * this.R + 0.6806995451f * this.G + 0.1073969566f * this.B;
float s = 0.0883024619f * this.R + 0.2817188376f * this.G + 0.6299787005f * this.B;

float l_ = (float)Math.Pow(l, 1.0 / 3.0);
float m_ = (float)Math.Pow(m, 1.0 / 3.0);
float s_ = (float)Math.Pow(s, 1.0 / 3.0);

return new OkLab(
0.2104542553f * l_ + 0.7936177850f * m_ - 0.0040720468f * s_,
1.9779984951f * l_ - 2.4285922050f * m_ + 0.4505937099f * s_,
0.0259040371f * l_ + 0.7827717662f * m_ - 0.8086757660f * s_
);
}

public static Srgb FromColor(Color c) => new(c.R / 255.0f, c.G / 255.0f, c.B / 255.0f);

public readonly Color ToColor() => Color.FromArgb((byte)(this.R * 255), (byte)(this.G * 255), (byte)(this.B * 255));

public readonly Srgb ToLinearSrgb() =>
new(Helpers.Clamp(ColorSpace.SrgbToLinearSrgb(R), 0f, 1f),
Helpers.Clamp(ColorSpace.SrgbToLinearSrgb(G), 0f, 1f),
Helpers.Clamp(ColorSpace.SrgbToLinearSrgb(B), 0f, 1f));

public readonly Srgb ToSrgb() =>
new(Helpers.Clamp(ColorSpace.LinearSrgbToSrgb(R), 0f, 1f),
Helpers.Clamp(ColorSpace.LinearSrgbToSrgb(G), 0f, 1f),
Helpers.Clamp(ColorSpace.LinearSrgbToSrgb(B), 0f, 1f));

public override readonly string ToString()
{
return FormattableString.Invariant($"(R:{R}, G:{G}, B:{B})");
}
}
4 changes: 2 additions & 2 deletions Scintilla.NET/FlagsEditorControl.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 13 additions & 2 deletions Scintilla.NET/FlagsEditorControl.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.Design;
Expand Down Expand Up @@ -51,7 +52,6 @@ public FlagsEditorControl(IWindowsFormsEditorService editorService, Enum value)
Tag = item,
Margin = new Padding(3, 0, 3, 0),
Padding = Padding.Empty,
UseVisualStyleBackColor = true,
};
checkBox.CheckStateChanged += checkBox_CheckStateChanged;
this.flowLayoutPanel_CheckBoxList.Controls.Add(checkBox);
Expand All @@ -67,7 +67,6 @@ public FlagsEditorControl(IWindowsFormsEditorService editorService, Enum value)
Tag = (Enum)Enum.ToObject(this.enumType, allBits),
Margin = new Padding(3, 0, 3, 0),
Padding = Padding.Empty,
UseVisualStyleBackColor = true,
};
checkBox.CheckStateChanged += checkBox_CheckStateChanged;
this.flowLayoutPanel_CheckBoxList.Controls.Add(checkBox);
Expand All @@ -81,6 +80,18 @@ public FlagsEditorControl(IWindowsFormsEditorService editorService, Enum value)
}
}

protected override void OnBackColorChanged(EventArgs e)
{
base.OnBackColorChanged(e);
Helpers.ApplyToControlTree(this, c => {
OkLab backColor = Srgb.FromColor(c.BackColor).ToLinearSrgb().ToOkLab();
if (backColor.L < 0.5f)
c.ForeColor = Color.White;
else
c.ForeColor = Color.Black;
});
}

private static ulong CalculateEnumAllValue(Type enumType)
{
ulong all = 0;
Expand Down
14 changes: 14 additions & 0 deletions Scintilla.NET/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ public static unsafe byte[] CharToByteStyles(byte[] styles, byte* text, int leng
return result;
}

public static float Clamp(float f, float min, float max)
{
return f < min ? min : f > max ? max : f;
}

public static int Clamp(int value, int min, int max)
{
if (value < min)
Expand Down Expand Up @@ -1260,6 +1265,15 @@ public static int MaxIndex<TSource>(this IEnumerable<TSource> source, Func<TSour
return maxIndex;
}

public static void ApplyToControlTree(Control control, Action<Control> action)
{
foreach (Control child in control.Controls)
{
ApplyToControlTree(child, action);
}
action(control);
}

#endregion Methods

#region Types
Expand Down

0 comments on commit 816f3cb

Please sign in to comment.