|
1 | 1 | import sys
|
2 | 2 | import os
|
| 3 | +import colorsys |
3 | 4 | from math import modf
|
4 | 5 | from enum import IntEnum, IntFlag
|
5 | 6 | from typing import Tuple, List, Union, Sequence, AnyStr, Optional, Iterator, Type
|
@@ -1729,21 +1730,31 @@ def __str__(self) -> str:
|
1729 | 1730 | )
|
1730 | 1731 |
|
1731 | 1732 |
|
1732 |
| -class Color(Structure): |
| 1733 | +class _Color(Structure): |
1733 | 1734 | _fields_ = [
|
1734 | 1735 | ('r', c_ubyte),
|
1735 | 1736 | ('g', c_ubyte),
|
1736 | 1737 | ('b', c_ubyte),
|
1737 | 1738 | ('a', c_ubyte),
|
1738 | 1739 | ]
|
1739 | 1740 |
|
| 1741 | + |
| 1742 | +class Color(_Color): |
| 1743 | + |
1740 | 1744 | @classmethod
|
1741 | 1745 | def zero(cls) -> 'Color':
|
1742 |
| - return cls(0., 0., 0., 1.) |
| 1746 | + return cls(0, 0, 0, 255) |
1743 | 1747 |
|
1744 | 1748 | @classmethod
|
1745 | 1749 | def one(cls) -> 'Color':
|
1746 |
| - return cls(1., 1., 1., 1.) |
| 1750 | + return cls(255, 255, 255, 255) |
| 1751 | + |
| 1752 | + def __init__(self, *args) -> None: |
| 1753 | + """Constructor.""" |
| 1754 | + result = _flatten((int, float), *args, map_to=int) |
| 1755 | + if len(result) != 4: |
| 1756 | + raise ValueError("Too many or too few initializers ({} instead of 2).".format(len(result))) |
| 1757 | + super(Color, self).__init__(*result) |
1747 | 1758 |
|
1748 | 1759 | def __str__(self) -> str:
|
1749 | 1760 | return "({}, {}, {}, {})".format(self.r, self.g, self.b, self.a)
|
@@ -1784,6 +1795,63 @@ def __getitem__(self, key: str) -> 'Color':
|
1784 | 1795 | 4: Vector4(*values),
|
1785 | 1796 | }[len(values)]
|
1786 | 1797 |
|
| 1798 | + @property |
| 1799 | + def normalized(self) -> 'Vector4': |
| 1800 | + """Gets or sets a normalized Vector4 color.""" |
| 1801 | + return Vector4( |
| 1802 | + self.r / 255.0, |
| 1803 | + self.g / 255.0, |
| 1804 | + self.b / 255.0, |
| 1805 | + self.a / 255.0 |
| 1806 | + ) |
| 1807 | + |
| 1808 | + @normalized.setter |
| 1809 | + def normalized(self, value: Union[Seq, Vector4, Vector3]) -> None: |
| 1810 | + value = _flatten((int, float), *value, map_to=float) |
| 1811 | + if len(result) not in (3, 4): |
| 1812 | + raise ValueError("Too many or too few values (expected 3 or 4, not {})".format(len(result))) |
| 1813 | + self.r = int(value[0] * 255.0) |
| 1814 | + self.g = int(value[1] * 255.0) |
| 1815 | + self.b = int(value[2] * 255.0) |
| 1816 | + if len(value) == 4: |
| 1817 | + self.a = int(value[3] * 255.0) |
| 1818 | + |
| 1819 | + @property |
| 1820 | + def hsv(self) -> 'Vector4': |
| 1821 | + """Gets a normalized color in HSV colorspace.""" |
| 1822 | + return Vector4(*colorsys.rgb_to_hsv(*self.normalized[:3]), self.a / 255.) |
| 1823 | + |
| 1824 | + @hsv.setter |
| 1825 | + def hsv(self, value: Union[Seq, Vector4, Vector3]) -> None: |
| 1826 | + result = _flatten((int, float), *value, map_to=float) |
| 1827 | + if len(result) not in (3, 4): |
| 1828 | + raise ValueError("Too many or too few values (expected 3 or 4, not {})".format(len(result))) |
| 1829 | + self.normalized = colorsys.hsv_to_rgb(result[:3]) |
| 1830 | + |
| 1831 | + @property |
| 1832 | + def hls(self) -> 'Vector4': |
| 1833 | + """Gets a normalized color in HLS colorspace.""" |
| 1834 | + return Vector4(*colorsys.rgb_to_hls(*self.normalized[:3]), self.a / 255.) |
| 1835 | + |
| 1836 | + @hls.setter |
| 1837 | + def hls(self, value: Union[Seq, Vector4, Vector3]) -> None: |
| 1838 | + result = _flatten((int, float), *value, map_to=float) |
| 1839 | + if len(result) not in (3, 4): |
| 1840 | + raise ValueError("Too many or too few values (expected 3 or 4, not {})".format(len(result))) |
| 1841 | + self.normalized = colorsys.hls_to_rgb(result[:3]) |
| 1842 | + |
| 1843 | + @property |
| 1844 | + def yiq(self) -> 'Vector4': |
| 1845 | + """Gets or sets a normalized color in YIQ colorspace.""" |
| 1846 | + return Vector4(*colorsys.rgb_to_yiq(*self.normalized[:3]), self.a / 255.) |
| 1847 | + |
| 1848 | + @yiq.setter |
| 1849 | + def yiq(self, value: Union[Seq, Vector4, Vector3]) -> None: |
| 1850 | + result = _flatten((int, float), *value, map_to=float) |
| 1851 | + if len(result) not in (3, 4): |
| 1852 | + raise ValueError("Too many or too few values (expected 3 or 4, not {})".format(len(result))) |
| 1853 | + self.normalized = colorsys.yiq_to_rgb(result[:3]) |
| 1854 | + |
1787 | 1855 |
|
1788 | 1856 | ColorPtr = POINTER(Color)
|
1789 | 1857 |
|
|
0 commit comments