|
1
|
|
|
# Copyright Pincer 2021-Present |
|
|
|
|
|
|
2
|
|
|
# Full MIT License can be found in `LICENSE` at the project root. |
|
3
|
|
|
|
|
4
|
|
|
import string |
|
5
|
|
|
from typing import Union |
|
6
|
|
|
|
|
7
|
|
|
|
|
8
|
|
|
class Color: |
|
9
|
|
|
""" |
|
10
|
|
|
A color in RGB. |
|
11
|
|
|
|
|
12
|
|
|
Parameters |
|
13
|
|
|
--------- |
|
14
|
|
|
c : Union[:class:`str`,:class:`int`] |
|
15
|
|
|
The hex color can be a string that optionally starts with an ``#`` or |
|
16
|
|
|
an int with the RGB values. |
|
17
|
|
|
Attributes |
|
18
|
|
|
--------- |
|
19
|
|
|
r : :class:`int` |
|
20
|
|
|
The red value for this color. |
|
21
|
|
|
g : :class:`int` |
|
22
|
|
|
The green value for this color. |
|
23
|
|
|
b : :class:`int` |
|
24
|
|
|
The blue value for this color. |
|
25
|
|
|
""" |
|
26
|
|
|
|
|
27
|
|
|
_MIN_VALUE = 0 |
|
28
|
|
|
_MAX_VALUE = 1 << 24 |
|
29
|
|
|
|
|
30
|
|
|
def __init__(self, c: Union[str, int]) -> None: |
|
31
|
|
|
if isinstance(c, int): |
|
32
|
|
|
if c < self._MIN_VALUE or c >= self._MAX_VALUE: |
|
33
|
|
|
raise ValueError("The color must be between 0 and 16777215") |
|
34
|
|
|
|
|
35
|
|
|
self.r = c >> 16 & 255 |
|
36
|
|
|
self.g = c >> 8 & 255 |
|
37
|
|
|
self.b = c & 255 |
|
38
|
|
|
return |
|
39
|
|
|
|
|
40
|
|
|
# Conversion modified from this answer |
|
41
|
|
|
# https://stackoverflow.com/a/29643643 |
|
42
|
|
|
if c.startswith("#"): |
|
43
|
|
|
c = c[1:] |
|
44
|
|
|
|
|
45
|
|
|
if len(c) != 6: |
|
46
|
|
|
raise ValueError("Hex value must be 6 characters.") |
|
47
|
|
|
|
|
48
|
|
|
if any(digit not in string.hexdigits for digit in c): |
|
49
|
|
|
raise ValueError("Illegal hex digit character.") |
|
50
|
|
|
|
|
51
|
|
|
self.r, self.g, self.b = (int(c[n : n + 2], 16) for n in (0, 2, 4)) |
|
|
|
|
|
|
52
|
|
|
|
|
53
|
|
|
def __eq__(self, other): |
|
54
|
|
|
return self.r == other.r and self.g == other.g and self.b == other.b |
|
55
|
|
|
|
|
56
|
|
|
def __repr__(self): |
|
57
|
|
|
return f"Color(r={self.r}, g={self.g}, b={self.b})" |
|
58
|
|
|
|
|
59
|
|
|
def __str__(self) -> str: |
|
60
|
|
|
return f"#{self.hex}" |
|
61
|
|
|
|
|
62
|
|
|
@property |
|
63
|
|
|
def rbg(self): |
|
64
|
|
|
""" |
|
65
|
|
|
Returns |
|
66
|
|
|
------- |
|
67
|
|
|
Tuple[:class:`int`, :class:`int` :class:`int`] |
|
68
|
|
|
Tuple value for rgb. |
|
69
|
|
|
""" |
|
70
|
|
|
return self.r, self.g, self.b |
|
71
|
|
|
|
|
72
|
|
|
@property |
|
73
|
|
|
def hex(self): |
|
74
|
|
|
""" |
|
75
|
|
|
Returns |
|
76
|
|
|
--------- |
|
77
|
|
|
str |
|
78
|
|
|
Str value for hex. |
|
79
|
|
|
""" |
|
80
|
|
|
return f"{self.r:02x}{self.g:02x}{self.b:02x}" |
|
81
|
|
|
|