diff options
Diffstat (limited to 'thcolor/_color.py')
-rwxr-xr-x | thcolor/_color.py | 174 |
1 files changed, 138 insertions, 36 deletions
diff --git a/thcolor/_color.py b/thcolor/_color.py index 55795d2..d273071 100755 --- a/thcolor/_color.py +++ b/thcolor/_color.py @@ -103,23 +103,36 @@ def _hue(name, value): # Color class definition. # --- -class _ColorType(_Enum): - """ The color type. """ +class Color: + """ Class representing a color within thcolor. Its constructor depends + on the first given argument, which represents the color type as one + of the :class:`Color.Type` constants. - """ Invalid color. """ - INVALID = 0 + .. function:: Color(Color.Type.RGB, red, green, blue, alpha = 1.0) - """ RGB/A color. """ - RGB = 1 + Create a color using its red, green and blue components. Each is + expressed as a byte value, from 0 (dark) to 255 (light). - """ HSL/A color. """ - HSL = 2 + An alpha value going from 0.0 (invisible) to 1.0 (opaque) can be + appended to the base components. - """ HWB/A color. """ - HWB = 3 + .. function:: Color(Color.Type.HSL, hue, saturation, lightness, alpha = 1.0) -class Color: - """ Represent a color with all of its available formats. """ + Create a color using its hue, saturation and lightness components. + The hue is represented by an :class:`Angle` object, and the + saturation and lightness are values going from 0.0 to 1.0. + + An alpha value going from 0.0 (invisible) to 1.0 (opaque) can be + appended to the base components. + + .. function:: Color(Color.Type.HWB, hue, whiteness, blackness, alpha = 1.0) + + Create a color using its hue, whiteness and blackness components. + The hue is represented by an :class:`Angle` object, and the + whiteness and light,ess are values going from 0.0 to 1.0. + + An alpha value going from 0.0 (invisible) to 1.0 (opaque) can be + appended to the base components. """ # Properties to work with: # @@ -130,26 +143,56 @@ class Color: # `_sat`, `_lgt`: saturation and light for HSL. # `_wht`, `_blk`: whiteness and blackness for HWB. - Type = _ColorType + class Type(_Enum): + """ Class representing the type of a color, or how it is expressed. + The following types are available: + + .. data:: INVALID + + An invalid color, for internal processing. + + .. data:: RGB + + A color expressed through its sRGB components: red, green + and blue. + + .. data:: HSL + + A color expressed through its HSL components: hue, saturation + and lightness. + + .. data:: HWB + + A color expressed through its HWB components: hue, whiteness + and blackness. + + An alpha component can be added to every single one of these + types, so it is not included in the type names. """ + + INVALID = 0 + RGB = 1 + HSL = 2 + HWB = 3 def __init__(self, *args, **kwargs): self._type = Color.Type.INVALID self.set(*args, **kwargs) def __repr__(self): - args = (('type', self._type),) + args = (('type', f'{self.__class__.__name__}.{str(self._type)}'),) if self._type == Color.Type.RGB: - args += (('red', self._r), ('green', self._g), ('blue', self._b)) + args += (('red', repr(self._r)), ('green', repr(self._g)), + ('blue', repr(self._b))) elif self._type == Color.Type.HSL: - args += (('hue', self._hue), ('saturation', self._sat), - ('lightness', self._lgt)) + args += (('hue', repr(self._hue)), ('saturation', repr(self._sat)), + ('lightness', repr(self._lgt))) elif self._type == Color.Type.HWB: - args += (('hue', self._hue), ('whiteness', self._wht), - ('blackness', self._blk)) + args += (('hue', repr(self._hue)), ('whiteness', repr(self._wht)), + ('blackness', repr(self._blk))) args += (('alpha', self._alpha),) - argtext = ', '.join(f'{key}: {repr(value)}' for key, value in args) + argtext = ', '.join(f'{key} = {value}' for key, value in args) return f"{self.__class__.__name__}({argtext})" # --- @@ -157,7 +200,8 @@ class Color: # --- def set(self, *args, **kwargs): - """ Set the color. """ + """ Set the color using its constructor arguments and keyword + arguments. """ args = list(args) @@ -260,7 +304,8 @@ class Color: @property def type(self): - """ Get the type. """ + """ The read-only angle type as one of the :class:`Color.Type` + constants. """ return self._type @@ -392,7 +437,14 @@ class Color: # --- def rgb(self): - """ Get the (red, green, blue) components of the color. """ + """ Get the sRGB (red, green, blue) components of the color. + For example: + + >>> Color.from_text("#876543").rgb() + ... (135, 101, 67) + + If the color is not represented as sRGB internally, it will be + converted. """ if self._type == Color.Type.RGB: return (self._r, self._g, self._b) @@ -404,7 +456,14 @@ class Color: raise ValueError(f"color type {self._type} doesn't translate to rgb") def hsl(self): - """ Get the (hue, saturation, lightness) components of the color. """ + """ Get the HSL (hue, saturation, lightness) components of the color. + For example: + + >>> Color.from_text("hsl(90turn 0% 5%)").hls() + ... (Angle(type = Angle.Type.TURN, value = 90.0), 0.05, 0.0) + + If the color is not represented as HSL internally, it will be + converted. """ if self._type == Color.Type.RGB: return _rgb_to_hls(self._r, self._g, self._b) @@ -416,7 +475,14 @@ class Color: raise ValueError(f"color type {self._type} doesn't translate to hsl") def hwb(self): - """ Get the (hue, whiteness, blackness) components of the color. """ + """ Get the HWB (hue, whiteness, blackness) components of the color. + For example: + + >>> Color.from_text("hwb(.7 turn / 5% 10%)").hwb() + ... (Angle(type = Angle.Type.TURN, value = 0.7), 0.05, 0.1) + + If the color is not represented as HSL internally, it will be + converted. """ if self._type == Color.Type.RGB: return _rgb_to_hwb(self._r, self._g, self._b) @@ -426,7 +492,14 @@ class Color: return (self._hue, self._wht, self._blk) def rgba(self): - """ Get the (red, green, blue, alpha) components of the color. """ + """ Get the sRGB (red, green, blue) and alpha components of the color. + For example: + + >>> Color.from_text("#87654321").rgb() + ... (135, 101, 67, 0.1294) + + If the color is not represented as sRGB internally, it will be + converted. """ r, g, b = self.rgb() alpha = self._alpha @@ -434,7 +507,14 @@ class Color: return (r, g, b, alpha) def hsla(self): - """ Get the (hue, saturation, lightness) components of the color. """ + """ Get the HSL (hue, saturation, lightness) and alpha components of + the color. For example: + + >>> Color.from_text("hsl(90turn 0% 5% .8)").hlsa() + ... (Angle(type = Angle.Type.TURN, value = 90.0), 0.05, 0.0, 0.8) + + If the color is not represented as HSL internally, it will be + converted. """ h, s, l = self.hsl() alpha = self._alpha @@ -442,28 +522,41 @@ class Color: return (h, s, l, alpha) def hls(self): - """ Get the (hue, lightness, saturation) components of the color. """ + """ Alias for :meth:`hsl` but reverses the lightness and + saturation for commodity. """ h, s, l = self.hsl() return (h, l, s) def hlsa(self): - """ Get the (hue, lightness, saturation, alpha) components of - the color. """ + """ Alias for :meth:`hsla` but reverses the lightness and + saturation for commodity. """ h, s, l, a = self.hsla() return (h, l, s, a) def hwba(self): - """ Get the (hue, whiteness, blackness, alpha) components of - the color. """ + """ Get the HWB (hue, whiteness, blackness) and alpha components of + the color. For example: + + >>> Color.from_text("hwb(.7 turn / 5% 10% .2)").hwba() + ... (Angle(type = Angle.Type.TURN, value = 0.7), 0.05, 0.1, 0.2) + + If the color is not represented as HSL internally, it will be + converted. """ h, w, b = self.hwb() a = self._alpha return (h, w, b, a) def css(self): - """ Get the CSS declarations (with compatibility management). """ + """ Get the CSS color descriptions, with older CSS specifications + compatibility, as a list of strings. + + For example: + + >>> Color(Color.Type.RGB, 18, 52, 86, 0.82).css() + ... ["#123456", "rgba(18, 52, 86, 82%)"] """ def _percent(prop): per = round(prop, 4) * 100 @@ -516,17 +609,26 @@ class Color: # --- def from_str(*args, **kwargs): - """ Alias for `from_text()`. """ + """ Alias for :meth:`from_text()`. """ return Color.from_text(value) def from_string(*args, **kwargs): - """ Alias for `from_text()`. """ + """ Alias for :meth:`from_text()`. """ return Color.from_text(value) def from_text(expr, ref = None): - """ Get a color from a string. """ + """ Create a color from a string using a :class:`Reference` object. + If the ``ref`` argument is ``None``, then the default reference + is loaded. + + An example: + + >>> Color.from_text("#123456") + ... Color(type = Color.Type.RGB, red = 18, green = 52, blue = 86, alpha = 1.0) + + TODO: describe the text format here. """ if ref is None: ref = _Reference.default() |