mirror of
https://github.com/foo-dogsquared/nixos-config.git
synced 2025-02-24 18:19:01 +00:00
bahaghari/lib: update and refactor colors.rgb
Now the RGB colorspace object doesn't have the methods built into the set as that basically screws a lot of things when exporting it to the output. Also, the alpha component should be handled nicely now.
This commit is contained in:
parent
3825c8568c
commit
35873462f3
@ -5,8 +5,13 @@
|
|||||||
{ pkgs, lib, self }:
|
{ pkgs, lib, self }:
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
/* Generates an RGB colorspace object to be generated with its method for
|
# A bunch of metadata for this implementation. Might be useful if you want to
|
||||||
convenience.
|
# create functions from this subset.
|
||||||
|
valueMin = 0.0;
|
||||||
|
valueMax = 255.0;
|
||||||
|
|
||||||
|
/* Generates an RGB colorspace object. The point is to provide some
|
||||||
|
typechecking if the values passed are correct.
|
||||||
|
|
||||||
Type: RGB :: Attrs -> Attrs
|
Type: RGB :: Attrs -> Attrs
|
||||||
|
|
||||||
@ -14,23 +19,13 @@ rec {
|
|||||||
RGB { r = 242.0; g = 12; b = 23; }
|
RGB { r = 242.0; g = 12; b = 23; }
|
||||||
=> {
|
=> {
|
||||||
# The individual red, green, and blue components.
|
# The individual red, green, and blue components.
|
||||||
|
|
||||||
# And several methods.
|
|
||||||
__functor = {
|
|
||||||
toHex = <function>;
|
|
||||||
lighten = <function>;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
RGB = { r, g, b }@color:
|
RGB = { r, g, b, ... }@color:
|
||||||
assert lib.assertMsg (isRgb color)
|
assert lib.assertMsg (isRgb color)
|
||||||
"bahaghariLib.colors.rgb.RGB: given color does not have valid RGB value";
|
"bahaghariLib.colors.rgb.RGB: Given object has invalid values (only 0-255 are allowed)";
|
||||||
{
|
lib.optionalAttrs (color ? a) { inherit (color) a; } // {
|
||||||
inherit r g b;
|
inherit r g b;
|
||||||
__functor = {
|
|
||||||
toHex = self: toHex color;
|
|
||||||
lighten = self: lighten color;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Returns a boolean to check if it's a valid RGB Nix object or not.
|
/* Returns a boolean to check if it's a valid RGB Nix object or not.
|
||||||
@ -49,12 +44,12 @@ rec {
|
|||||||
isRgb { r = 123; g = 123; b = 123; }
|
isRgb { r = 123; g = 123; b = 123; }
|
||||||
=> true
|
=> true
|
||||||
*/
|
*/
|
||||||
isRgb = { r, g, b }@color:
|
isRgb = { r, g, b, ... }@color:
|
||||||
let
|
let
|
||||||
isWithinRGBRange = v: self.math.isWithinRange 0 255 v;
|
isWithinRGBRange = v: self.math.isWithinRange valueMin valueMax v;
|
||||||
isValidRGB = v: self.isNumber v && isWithinRGBRange v;
|
isValidRGB = v: self.isNumber v && isWithinRGBRange v;
|
||||||
in
|
colors = [ r g b ] ++ lib.optionals (color ? a) [ color.a ];
|
||||||
lib.lists.all (v: isValidRGB v) (lib.attrValues color);
|
in lib.lists.all (v: isValidRGB v) colors;
|
||||||
|
|
||||||
/* Converts the color to a 6-digit hex string. Unfortunately, it cannot
|
/* Converts the color to a 6-digit hex string. Unfortunately, it cannot
|
||||||
handle floats very well so we'll have to round these up.
|
handle floats very well so we'll have to round these up.
|
||||||
@ -67,13 +62,30 @@ rec {
|
|||||||
*/
|
*/
|
||||||
toHex = { r, g, b, ... }:
|
toHex = { r, g, b, ... }:
|
||||||
let
|
let
|
||||||
r' = self.math.round r;
|
components = builtins.map (c:
|
||||||
g' = self.math.round g;
|
let c' = self.math.round c;
|
||||||
b' = self.math.round b;
|
in self.hex.pad 2 (self.hex.fromDec c')) [ r g b ];
|
||||||
rH = self.hex.pad 2 (self.hex.fromDec r');
|
in lib.concatStringsSep "" components;
|
||||||
gH = self.hex.pad 2 (self.hex.fromDec g');
|
|
||||||
bH = self.hex.pad 2 (self.hex.fromDec b');
|
/* Converts the color to a 8-digit hex string (RGBA). If no `a` component, it
|
||||||
in "${rH}${gH}${bH}";
|
will be assumed to be at maximum value. Unfortunately, it cannot handle
|
||||||
|
floats very well so we'll have to round these up.
|
||||||
|
|
||||||
|
Type: toHex :: RGB -> String
|
||||||
|
|
||||||
|
Example:
|
||||||
|
toHex' { r = 231; g = 12; b = 21; }
|
||||||
|
=> "E70C15FF"
|
||||||
|
|
||||||
|
toHex' { r = 231; g = 12; b = 21; a = 0; }
|
||||||
|
=> "E70C1500"
|
||||||
|
*/
|
||||||
|
toHex' = { r, g, b, a ? valueMax, ... }:
|
||||||
|
let
|
||||||
|
components = builtins.map (c:
|
||||||
|
let c' = self.math.round c;
|
||||||
|
in self.hex.pad 2 (self.hex.fromDec c')) [ r g b a ];
|
||||||
|
in lib.concatStringsSep "" components;
|
||||||
|
|
||||||
/* Converts a valid hex string into an RGB object.
|
/* Converts a valid hex string into an RGB object.
|
||||||
|
|
||||||
@ -85,6 +97,12 @@ rec {
|
|||||||
|
|
||||||
fromHex "FFF"
|
fromHex "FFF"
|
||||||
=> { r = 255; g = 255; b = 255; }
|
=> { r = 255; g = 255; b = 255; }
|
||||||
|
|
||||||
|
fromHex "FFFF"
|
||||||
|
=> { r = 255; g = 255; b = 255; a = 255; }
|
||||||
|
|
||||||
|
fromHex "FFFFFFFF"
|
||||||
|
=> { r = 255; g = 255; b = 255; a = 255; }
|
||||||
*/
|
*/
|
||||||
fromHex = hex:
|
fromHex = hex:
|
||||||
let
|
let
|
||||||
@ -92,8 +110,15 @@ rec {
|
|||||||
r = lib.lists.elemAt hex' 0;
|
r = lib.lists.elemAt hex' 0;
|
||||||
g = lib.lists.elemAt hex' 1;
|
g = lib.lists.elemAt hex' 1;
|
||||||
b = lib.lists.elemAt hex' 2;
|
b = lib.lists.elemAt hex' 2;
|
||||||
in
|
a =
|
||||||
RGB { inherit r g b; };
|
if lib.lists.length hex' == 4 then
|
||||||
|
lib.lists.elemAt hex' 3
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
in RGB {
|
||||||
|
inherit r g b;
|
||||||
|
${self.optionalNull (a != null) "a"} = a;
|
||||||
|
};
|
||||||
|
|
||||||
/* Given a percentage, uniformly lighten the given RGB color.
|
/* Given a percentage, uniformly lighten the given RGB color.
|
||||||
|
|
||||||
@ -105,11 +130,10 @@ rec {
|
|||||||
in
|
in
|
||||||
lighten color 50
|
lighten color 50
|
||||||
*/
|
*/
|
||||||
lighten = { r, g, b, ... }: percentage:
|
lighten = { r, g, b, ... }:
|
||||||
let
|
percentage:
|
||||||
grow' = c: self.math.grow' 0 255 percentage;
|
let grow' = c: self.math.grow' valueMin valueMax percentage;
|
||||||
in
|
in RGB {
|
||||||
RGB {
|
|
||||||
r = grow' r;
|
r = grow' r;
|
||||||
g = grow' g;
|
g = grow' g;
|
||||||
b = grow' b;
|
b = grow' b;
|
||||||
@ -134,9 +158,10 @@ rec {
|
|||||||
hexMatch = hex:
|
hexMatch = hex:
|
||||||
let
|
let
|
||||||
length = lib.stringLength hex;
|
length = lib.stringLength hex;
|
||||||
genMatch = r: n: lib.concatStringsSep "" (lib.genList (_: "([[:xdigit:]]{${builtins.toString n}})") r);
|
generateRegex = r: n:
|
||||||
nonAlphaGenMatch = genMatch 3;
|
lib.strings.replicate r "([[:xdigit:]]{${builtins.toString n}})";
|
||||||
withAlphaGenMatch = genMatch 4;
|
nonAlphaGenMatch = generateRegex 3;
|
||||||
|
withAlphaGenMatch = generateRegex 4;
|
||||||
|
|
||||||
regex =
|
regex =
|
||||||
if (length == 6) then
|
if (length == 6) then
|
||||||
@ -153,8 +178,8 @@ rec {
|
|||||||
scale = self.trivial.scale {
|
scale = self.trivial.scale {
|
||||||
inMin = 0;
|
inMin = 0;
|
||||||
inMax = 15;
|
inMax = 15;
|
||||||
outMin = 0;
|
outMin = valueMin;
|
||||||
outMax = 255;
|
outMax = valueMax;
|
||||||
};
|
};
|
||||||
|
|
||||||
match = lib.strings.match regex hex;
|
match = lib.strings.match regex hex;
|
||||||
|
@ -5,7 +5,7 @@ let
|
|||||||
# actual results. Also, it will mess up the result comparison since comparing
|
# actual results. Also, it will mess up the result comparison since comparing
|
||||||
# functions is reference-based so it will always fail.
|
# functions is reference-based so it will always fail.
|
||||||
normalizeData = colors:
|
normalizeData = colors:
|
||||||
lib.attrsets.removeAttrs colors [ "__functor" ];
|
lib.attrsets.removeAttrs colors [ "__functor" "methods" ];
|
||||||
|
|
||||||
rgbSample = self.colors.rgb.RGB {
|
rgbSample = self.colors.rgb.RGB {
|
||||||
r = 255;
|
r = 255;
|
||||||
@ -15,8 +15,7 @@ let
|
|||||||
|
|
||||||
# A modified version of RGB that normalizes data out-of-the-boxly.
|
# A modified version of RGB that normalizes data out-of-the-boxly.
|
||||||
RGB = colors: normalizeData (self.colors.rgb.RGB colors);
|
RGB = colors: normalizeData (self.colors.rgb.RGB colors);
|
||||||
in
|
in lib.runTests {
|
||||||
lib.runTests {
|
|
||||||
testsBasicRgb = {
|
testsBasicRgb = {
|
||||||
expr = RGB {
|
expr = RGB {
|
||||||
r = 34;
|
r = 34;
|
||||||
@ -30,6 +29,21 @@ lib.runTests {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
testsBasicRgb2 = {
|
||||||
|
expr = RGB {
|
||||||
|
r = 23;
|
||||||
|
g = 65;
|
||||||
|
b = 241;
|
||||||
|
a = 255;
|
||||||
|
};
|
||||||
|
expected = {
|
||||||
|
r = 23;
|
||||||
|
g = 65;
|
||||||
|
b = 241;
|
||||||
|
a = 255;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
testsFromHex = {
|
testsFromHex = {
|
||||||
expr = normalizeData (self.colors.rgb.fromHex "FFFFFF");
|
expr = normalizeData (self.colors.rgb.fromHex "FFFFFF");
|
||||||
expected = normalizeData (self.colors.rgb.RGB {
|
expected = normalizeData (self.colors.rgb.RGB {
|
||||||
@ -54,6 +68,7 @@ lib.runTests {
|
|||||||
r = 255;
|
r = 255;
|
||||||
g = 255;
|
g = 255;
|
||||||
b = 255;
|
b = 255;
|
||||||
|
a = 255;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,6 +78,7 @@ lib.runTests {
|
|||||||
r = 255;
|
r = 255;
|
||||||
g = 255;
|
g = 255;
|
||||||
b = 255;
|
b = 255;
|
||||||
|
a = 255;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,6 +96,25 @@ lib.runTests {
|
|||||||
expected = "173A69";
|
expected = "173A69";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
testsToHexVariant = {
|
||||||
|
expr = self.colors.rgb.toHex' (RGB {
|
||||||
|
r = 255;
|
||||||
|
g = 56;
|
||||||
|
b = 105;
|
||||||
|
});
|
||||||
|
expected = "FF3869FF";
|
||||||
|
};
|
||||||
|
|
||||||
|
testsToHexVariant2 = {
|
||||||
|
expr = self.colors.rgb.toHex' (RGB {
|
||||||
|
r = 255;
|
||||||
|
g = 56;
|
||||||
|
b = 105;
|
||||||
|
a = 34;
|
||||||
|
});
|
||||||
|
expected = "FF386922";
|
||||||
|
};
|
||||||
|
|
||||||
testsHexMatch = {
|
testsHexMatch = {
|
||||||
expr = self.colors.rgb.hexMatch "FFF";
|
expr = self.colors.rgb.hexMatch "FFF";
|
||||||
expected = [ 255 255 255 ];
|
expected = [ 255 255 255 ];
|
||||||
|
Loading…
Reference in New Issue
Block a user