diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1c82d06..30a2257 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,7 +16,9 @@ Jump to version:
## 7.0.1 (In Development)
-No code changes
+### MLEM
+Additions
+- Added ColorExtensions.ToHsl and ColorHelper.FromHsl
## 7.0.0
diff --git a/MLEM/Graphics/ColorExtensions.cs b/MLEM/Graphics/ColorExtensions.cs
index 7c4faca..897fbb8 100644
--- a/MLEM/Graphics/ColorExtensions.cs
+++ b/MLEM/Graphics/ColorExtensions.cs
@@ -58,6 +58,39 @@ namespace MLEM.Graphics {
return $"{(hash ? "#" : string.Empty)}{color.R:X2}{color.G:X2}{color.B:X2}";
}
+ ///
+ /// Converts the given into HSL representation and returns the result as a value tuple with values between 0 and 1.
+ ///
+ /// This code is adapted from https://gist.github.com/mjackson/5311256.
+ /// The color to convert.
+ /// The resulting HSL color as a value tuple containing H, S and L, each between 0 and 1.
+ public static (float H, float S, float L) ToHsl(this Color color) {
+ var r = color.R / 255F;
+ var g = color.G / 255F;
+ var b = color.B / 255F;
+
+ var max = Math.Max(Math.Max(r, g), b);
+ var min = Math.Min(Math.Min(r, g), b);
+ float h, s, l = (max + min) / 2;
+
+ if (max == min) {
+ h = s = 0; // achromatic
+ } else {
+ var d = max - min;
+ s = l > 0.5F ? d / (2 - max - min) : d / (max + min);
+ if (r == max) {
+ h = (g - b) / d + (g < b ? 6 : 0);
+ } else if (g == max) {
+ h = (b - r) / d + 2;
+ } else {
+ h = (r - g) / d + 4;
+ }
+ h /= 6;
+ }
+
+ return (h, s, l);
+ }
+
}
///
@@ -116,5 +149,54 @@ namespace MLEM.Graphics {
return false;
}
+ ///
+ ///Converts the given HSL color to an RGB and returns the result.
+ ///
+ /// This code is adapted from https://gist.github.com/mjackson/5311256.
+ /// The HSL color to convert, as a value tuple that contains H, S and L values, each between 0 and 1.
+ /// The resulting RGB color.
+ public static Color FromHsl((float H, float S, float L) color) {
+ return ColorHelper.FromHsl(color.H, color.S, color.L);
+ }
+
+ ///
+ ///Converts the given HSL values to an RGB and returns the result.
+ ///
+ /// This code is adapted from https://gist.github.com/mjackson/5311256.
+ /// The H component of the HSL color, between 0 and 1.
+ /// The S component of the HSL color, between 0 and 1.
+ /// The L component of the HSL color, between 0 and 1.
+ /// The resulting RGB color.
+ public static Color FromHsl(float h, float s, float l) {
+ float r, g, b;
+
+ if (s == 0) {
+ r = g = b = l; // achromatic
+ } else {
+ var q = l < 0.5F ? l * (1 + s) : l + s - l * s;
+ var p = 2 * l - q;
+
+ r = ColorHelper.HueToRgb(p, q, h + 1 / 3F);
+ g = ColorHelper.HueToRgb(p, q, h);
+ b = ColorHelper.HueToRgb(p, q, h - 1 / 3F);
+ }
+
+ return new Color(r, g, b);
+ }
+
+ private static float HueToRgb(float p, float q, float t) {
+ if (t < 0)
+ t += 1;
+ if (t > 1)
+ t -= 1;
+ if (t < 1 / 6F)
+ return p + (q - p) * 6 * t;
+ if (t < 1 / 2F)
+ return q;
+ if (t < 2 / 3F)
+ return p + (q - p) * (2 / 3F - t) * 6;
+ return p;
+ }
+
}
}
diff --git a/Sandbox/GameImpl.cs b/Sandbox/GameImpl.cs
index dff401b..3a2711f 100644
--- a/Sandbox/GameImpl.cs
+++ b/Sandbox/GameImpl.cs
@@ -19,6 +19,7 @@ using MLEM.Textures;
using MLEM.Ui;
using MLEM.Ui.Elements;
using MLEM.Ui.Style;
+using Group = MLEM.Ui.Elements.Group;
namespace Sandbox;
@@ -87,6 +88,7 @@ public class GameImpl : MlemGame {
this.SpriteBatch.End();
};*/
+ /*
var panel = new Panel(Anchor.Center, new Vector2(0, 100), Vector2.Zero) {SetWidthBasedOnChildren = true};
panel.AddChild(new Button(Anchor.AutoLeft, new Vector2(100, 10)));
panel.AddChild(new Button(Anchor.AutoCenter, new Vector2(80, 10)));
@@ -112,17 +114,21 @@ public class GameImpl : MlemGame {
var dir = vec.ToDirection();
Console.WriteLine(vec + " -> " + dir);
}
+ */
+ /*
var writer = new StringWriter();
- this.Content.GetJsonSerializer().Serialize(writer, obj);
+ this.Content.GetJsonSerializer().Serialize(writer, obj);*/
//Console.WriteLine(writer.ToString());
// {"Vec":"10 20","Point":"20 30","Rectangle":"1 2 3 4","RectangleF":"4 5 6 7"}
// Also:
//this.Content.AddJsonConverter(new CustomConverter());
+ /*
var res = this.Content.LoadJson("Test");
Console.WriteLine("The res is " + res);
+ */
//var gradient = this.SpriteBatch.GenerateGradientTexture(Color.Green, Color.Red, Color.Blue, Color.Yellow);
/*this.OnDraw += (game, time) => {
@@ -139,6 +145,7 @@ public class GameImpl : MlemGame {
this.SpriteBatch.End();
};*/
+ /*
var sc = 2;
var formatter = new TextFormatter();
formatter.AddImage("Test", new TextureRegion(tex, 0, 8, 24, 24));
@@ -185,6 +192,7 @@ public class GameImpl : MlemGame {
}
this.tokenized.Update(time);
};
+ */
/*var testPanel = new Panel(Anchor.Center, new Vector2(0.5F, 100), Vector2.Zero);
testPanel.AddChild(new Button(Anchor.AutoLeft, new Vector2(0.25F, -1)));
@@ -225,6 +233,7 @@ public class GameImpl : MlemGame {
par.OnDrawn = (e, time, batch, a) => batch.DrawRectangle(e.DisplayArea.ToExtended(), Color.Red);
this.UiSystem.Add("Load", loadGroup);*/
+ /*
var spillPanel = new Panel(Anchor.Center, new Vector2(100), Vector2.Zero);
var squishingGroup = spillPanel.AddChild(new SquishingGroup(Anchor.TopLeft, Vector2.One));
squishingGroup.AddChild(new Button(Anchor.TopLeft, new Vector2(30), "TL") {
@@ -293,6 +302,7 @@ public class GameImpl : MlemGame {
}
this.SpriteBatch.End();
};
+ */
/*var viewport = new BoxingViewportAdapter(this.Window, this.GraphicsDevice, 1280, 720);
var newPanel = new Panel(Anchor.TopLeft, new Vector2(200, 100), new Vector2(10, 10));
@@ -387,6 +397,28 @@ public class GameImpl : MlemGame {
Console.WriteLine("MouseButtons: " + string.Join(", ", GenericInput.AllMouseButtons));
Console.WriteLine("Buttons: " + string.Join(", ", GenericInput.AllButtons));
Console.WriteLine("Inputs: " + string.Join(", ", GenericInput.AllInputs));*/
+
+ var hsl = new Panel(Anchor.Center, new Vector2(100), true);
+ var color = Color.Pink.ToHsl();
+ hsl.AddChild(new Paragraph(Anchor.AutoLeft, 1, "H"));
+ hsl.AddChild(new Slider(Anchor.AutoLeft, new Vector2(1, 10), 5, 1) {
+ CurrentValue = color.H,
+ OnValueChanged = (_, v) => color.H = v
+ });
+ hsl.AddChild(new Paragraph(Anchor.AutoLeft, 1, "S"));
+ hsl.AddChild(new Slider(Anchor.AutoLeft, new Vector2(1, 10), 5, 1) {
+ CurrentValue = color.S,
+ OnValueChanged = (_, v) => color.S = v
+ });
+ hsl.AddChild(new Paragraph(Anchor.AutoLeft, 1, "L"));
+ hsl.AddChild(new Slider(Anchor.AutoLeft, new Vector2(1, 10), 5, 1) {
+ CurrentValue = color.L,
+ OnValueChanged = (_, v) => color.L = v
+ });
+ hsl.AddChild(new Group(Anchor.AutoLeft, new Vector2(1, 40), false) {
+ OnDrawn = (e, _, batch, _, _) => batch.Draw(batch.GetBlankTexture(), e.DisplayArea, ColorHelper.FromHsl(color))
+ });
+ this.UiSystem.Add("HSL", hsl);
}
protected override void DoUpdate(GameTime gameTime) {