molde 0.1.12__py3-none-any.whl → 0.1.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- molde/__init__.py +12 -12
- molde/__main__.py +81 -81
- molde/actors/__init__.py +5 -5
- molde/actors/common_symbols_actor.py +148 -148
- molde/actors/ghost_actor.py +12 -12
- molde/actors/lines_actor.py +31 -31
- molde/actors/round_points_actor.py +7 -7
- molde/actors/square_points_actor.py +32 -32
- molde/colors/__init__.py +1 -1
- molde/colors/color.py +273 -150
- molde/colors/color_names.py +124 -124
- molde/interactor_styles/__init__.py +2 -2
- molde/interactor_styles/arcball_camera_style.py +288 -288
- molde/interactor_styles/box_selection_style.py +87 -87
- molde/main_window.ui +864 -864
- molde/pickers/__init__.py +2 -2
- molde/pickers/cell_area_picker.py +61 -61
- molde/pickers/cell_property_area_picker.py +84 -84
- molde/poly_data/__init__.py +13 -13
- molde/poly_data/lines_data.py +23 -23
- molde/poly_data/vertices_data.py +24 -24
- molde/render_widgets/__init__.py +2 -2
- molde/render_widgets/animated_render_widget.py +164 -164
- molde/render_widgets/common_render_widget.py +429 -429
- molde/stylesheets/__init__.py +122 -122
- molde/stylesheets/common.qss +15 -15
- molde/stylesheets/create_color_page.py +61 -61
- molde/stylesheets/mainwindow.ui +646 -646
- molde/stylesheets/qcheckbox.qss +23 -23
- molde/stylesheets/qinputs.qss +81 -81
- molde/stylesheets/qlayouts.qss +23 -23
- molde/stylesheets/qmenubar.qss +12 -12
- molde/stylesheets/qprogressbar.qss +11 -11
- molde/stylesheets/qpushbutton.qss +89 -89
- molde/stylesheets/qradiobutton.qss +30 -30
- molde/stylesheets/qscrollbar.qss +29 -29
- molde/stylesheets/qslider.qss +61 -61
- molde/stylesheets/qtablewidget.qss +27 -27
- molde/stylesheets/qtabwidget.qss +28 -28
- molde/stylesheets/qtoolbar.qss +63 -63
- molde/stylesheets/qtoolbuttons.qss +14 -14
- molde/stylesheets/qtreewidget.qss +25 -25
- molde/ui_files/messages/new_loading_window.ui +73 -73
- molde/utils/__init__.py +8 -8
- molde/utils/format_sequences.py +44 -44
- molde/utils/poly_data_utils.py +66 -66
- molde/utils/tree_info.py +52 -52
- molde/windows/loading_window.py +189 -189
- {molde-0.1.12.dist-info → molde-0.1.14.dist-info}/METADATA +1 -1
- molde-0.1.14.dist-info/RECORD +68 -0
- {molde-0.1.12.dist-info → molde-0.1.14.dist-info}/WHEEL +1 -1
- molde-0.1.12.dist-info/RECORD +0 -68
molde/colors/__init__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
from .color import Color
|
1
|
+
from .color import Color
|
2
2
|
from .color_names import *
|
molde/colors/color.py
CHANGED
@@ -1,150 +1,273 @@
|
|
1
|
-
import typing
|
2
|
-
from qtpy.QtGui import QColor
|
3
|
-
import numpy as np
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
elif len(args) == 1 and isinstance(args[0],
|
65
|
-
|
66
|
-
|
67
|
-
elif len(args)
|
68
|
-
|
69
|
-
|
70
|
-
elif len(args)
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
def
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
1
|
+
import typing
|
2
|
+
from qtpy.QtGui import QColor
|
3
|
+
import numpy as np
|
4
|
+
from dataclasses import dataclass
|
5
|
+
|
6
|
+
|
7
|
+
@dataclass(frozen=True, init=False)
|
8
|
+
class Color:
|
9
|
+
r: int
|
10
|
+
g: int
|
11
|
+
b: int
|
12
|
+
a: int
|
13
|
+
|
14
|
+
@typing.overload
|
15
|
+
def __new__(self, r: int, g: int, b: int, a: int = 255):
|
16
|
+
"""
|
17
|
+
Initialize Colors with RGB or RGBA integer values ranging from 0 to 255.
|
18
|
+
"""
|
19
|
+
|
20
|
+
@typing.overload
|
21
|
+
def __new__(self, r: float, g: float, b: float, a: float = 1.0):
|
22
|
+
"""
|
23
|
+
Initialize Colors with RGB or RGBA floating values ranging from 0.0 to 1.0.
|
24
|
+
"""
|
25
|
+
|
26
|
+
@typing.overload
|
27
|
+
def __new__(self, hexa: str):
|
28
|
+
"""
|
29
|
+
Initialize colors from hex values.
|
30
|
+
The valid formats incluce RGB (#FF0000 for example)
|
31
|
+
and RGBA (#FF0000FF for example)
|
32
|
+
"""
|
33
|
+
|
34
|
+
@typing.overload
|
35
|
+
def __new__(self, qcolor: QColor):
|
36
|
+
"""
|
37
|
+
Initialize the color class with an instance of QColor
|
38
|
+
"""
|
39
|
+
|
40
|
+
@typing.overload
|
41
|
+
def __new__(self, color: "Color"):
|
42
|
+
"""
|
43
|
+
Initialize the color class with an instance it's own class
|
44
|
+
"""
|
45
|
+
|
46
|
+
@typing.overload
|
47
|
+
def __new__(self):
|
48
|
+
"""
|
49
|
+
Initialize an empty black color
|
50
|
+
"""
|
51
|
+
|
52
|
+
def __new__(cls, *args):
|
53
|
+
"""
|
54
|
+
Calls the appropriate constructor for the class according to the
|
55
|
+
number of arguments and their types.
|
56
|
+
"""
|
57
|
+
|
58
|
+
all_int = all([isinstance(i, int) for i in args])
|
59
|
+
all_float = all([isinstance(i, float) for i in args])
|
60
|
+
|
61
|
+
if len(args) == 0:
|
62
|
+
return cls.from_rgba(0, 0, 0, 255)
|
63
|
+
|
64
|
+
elif len(args) == 1 and isinstance(args[0], str):
|
65
|
+
return cls.from_hex(*args)
|
66
|
+
|
67
|
+
elif len(args) == 1 and isinstance(args[0], QColor):
|
68
|
+
return cls.from_qcolor(*args)
|
69
|
+
|
70
|
+
elif len(args) == 1 and isinstance(args[0], Color):
|
71
|
+
return cls.from_color(*args)
|
72
|
+
|
73
|
+
elif len(args) in [3, 4] and all_int:
|
74
|
+
return cls.from_rgba(*args)
|
75
|
+
|
76
|
+
elif len(args) in [3, 4] and all_float:
|
77
|
+
return cls.from_rgba_f(*args)
|
78
|
+
|
79
|
+
else:
|
80
|
+
raise ValueError("Invalid input values")
|
81
|
+
|
82
|
+
@classmethod
|
83
|
+
def from_rgba(cls, r: int, g: int, b: int, a: int = 255) -> "Color":
|
84
|
+
"""
|
85
|
+
This is the default constructor for the class.
|
86
|
+
All other constructors call this one.
|
87
|
+
|
88
|
+
Since "Color" should be imutable, we use "object.__setattr__" to bypass
|
89
|
+
the imutability just in the constructor.
|
90
|
+
"""
|
91
|
+
|
92
|
+
obj = super().__new__(cls)
|
93
|
+
object.__setattr__(obj, "r", round(np.clip(r, 0, 255)))
|
94
|
+
object.__setattr__(obj, "g", round(np.clip(g, 0, 255)))
|
95
|
+
object.__setattr__(obj, "b", round(np.clip(b, 0, 255)))
|
96
|
+
object.__setattr__(obj, "a", round(np.clip(a, 0, 255)))
|
97
|
+
return obj
|
98
|
+
|
99
|
+
@classmethod
|
100
|
+
def from_rgb(self, r: int, g: int, b: int) -> "Color":
|
101
|
+
return self.from_rgba(r, g, b)
|
102
|
+
|
103
|
+
@classmethod
|
104
|
+
def from_rgb_f(self, r: float, g: float, b: float) -> "Color":
|
105
|
+
return self.from_rgba_f(r, g, b)
|
106
|
+
|
107
|
+
@classmethod
|
108
|
+
def from_rgba_f(self, r: float, g: float, b: float, a: float = 1) -> "Color":
|
109
|
+
return self.from_rgba(
|
110
|
+
round(r * 255),
|
111
|
+
round(g * 255),
|
112
|
+
round(b * 255),
|
113
|
+
round(a * 255),
|
114
|
+
)
|
115
|
+
|
116
|
+
@classmethod
|
117
|
+
def from_hex(self, color: str) -> "Color":
|
118
|
+
color = color.lstrip("#")
|
119
|
+
if len(color) == 6:
|
120
|
+
r, g, b = int(color[0:2], 16), int(color[2:4], 16), int(color[4:6], 16)
|
121
|
+
return self.from_rgb(r, g, b)
|
122
|
+
elif len(color) == 8:
|
123
|
+
r, g, b, a = int(color[0:2], 16), int(color[2:4], 16), int(color[4:6], 16), int(color[6:8], 16)
|
124
|
+
return self.from_rgba(r, g, b, a)
|
125
|
+
raise ValueError("Invalid hex color format")
|
126
|
+
|
127
|
+
@classmethod
|
128
|
+
def from_hsv(self, hue: float, saturation: float, value: float):
|
129
|
+
v = value / 100
|
130
|
+
s = saturation / 100
|
131
|
+
|
132
|
+
c = v * s
|
133
|
+
h = hue / 60
|
134
|
+
x = c * (1 - abs(h % 2 - 1))
|
135
|
+
|
136
|
+
if 0 <= h < 1:
|
137
|
+
r, g, b = c, x, 0
|
138
|
+
elif 1 <= h < 2:
|
139
|
+
r, g, b = x, c, 0
|
140
|
+
elif 2 <= h < 3:
|
141
|
+
r, g, b = 0, c, x
|
142
|
+
elif 3 <= h < 4:
|
143
|
+
r, g, b = 0, x, c
|
144
|
+
elif 4 <= h < 5:
|
145
|
+
r, g, b = x, 0, c
|
146
|
+
elif 5 <= h < 6:
|
147
|
+
r, g, b = c, 0, x
|
148
|
+
else:
|
149
|
+
r, g, b = 0, 0, 0
|
150
|
+
|
151
|
+
return self.from_rgb_f(
|
152
|
+
(r + v - c),
|
153
|
+
(g + v - c),
|
154
|
+
(b + v - c),
|
155
|
+
)
|
156
|
+
|
157
|
+
@classmethod
|
158
|
+
def from_qcolor(self, color: QColor) -> "Color":
|
159
|
+
return self.from_rgba(color.red(), color.green(), color.blue(), color.alpha())
|
160
|
+
|
161
|
+
@classmethod
|
162
|
+
def from_color(self, color: "Color"):
|
163
|
+
self.r = color.r
|
164
|
+
self.g = color.g
|
165
|
+
self.b = color.b
|
166
|
+
self.a = color.a
|
167
|
+
return self
|
168
|
+
|
169
|
+
def to_rgb(self) -> tuple[int, int, int]:
|
170
|
+
return (self.r, self.g, self.b)
|
171
|
+
|
172
|
+
def to_rgba(self) -> tuple[int, int, int, int]:
|
173
|
+
return (self.r, self.g, self.b, self.a)
|
174
|
+
|
175
|
+
def to_rgb_f(self) -> tuple[float, float, float]:
|
176
|
+
return ((self.r / 255), (self.g / 255), (self.b / 255))
|
177
|
+
|
178
|
+
def to_rgba_f(self) -> tuple[float, float, float, float]:
|
179
|
+
return ((self.r / 255), (self.g / 255), (self.b / 255), (self.a / 255))
|
180
|
+
|
181
|
+
def to_hex(self) -> str:
|
182
|
+
return f"#{self.r:02X}{self.g:02X}{self.b:02X}"
|
183
|
+
|
184
|
+
def to_hexa(self) -> str:
|
185
|
+
return f"#{self.r:02X}{self.g:02X}{self.b:02X}{self.a:02X}"
|
186
|
+
|
187
|
+
def to_hsv(self) -> tuple[int, int, int]:
|
188
|
+
r, g, b = self.to_rgb_f()
|
189
|
+
min_, mid_, max_ = sorted((r, g, b))
|
190
|
+
delta = max_ - min_
|
191
|
+
|
192
|
+
if delta == 0:
|
193
|
+
hue = 0
|
194
|
+
elif max_ == r:
|
195
|
+
hue = (g - b) / delta
|
196
|
+
elif max_ == g:
|
197
|
+
hue = (b - r) / delta + 2
|
198
|
+
elif max_ == b:
|
199
|
+
hue = (r - g) / delta + 4
|
200
|
+
else:
|
201
|
+
hue = 0
|
202
|
+
|
203
|
+
hue = round(60 * hue)
|
204
|
+
value = round(100 * max_)
|
205
|
+
saturation = round(100 * delta / max_) if (max_ != 0) else 0
|
206
|
+
|
207
|
+
return (
|
208
|
+
np.clip(0, 360, hue),
|
209
|
+
np.clip(0, 100, saturation),
|
210
|
+
np.clip(0, 100, value),
|
211
|
+
)
|
212
|
+
|
213
|
+
def to_qt(self) -> QColor:
|
214
|
+
return QColor(self.r, self.g, self.b, self.a)
|
215
|
+
|
216
|
+
def copy(self) -> "Color":
|
217
|
+
return Color(self.r, self.g, self.b, self.a)
|
218
|
+
|
219
|
+
def apply_factor(self, factor: float | int) -> "Color":
|
220
|
+
new_color = self.copy()
|
221
|
+
new_color.r = round(np.clip(self.r * factor, 0, 255))
|
222
|
+
new_color.g = round(np.clip(self.g * factor, 0, 255))
|
223
|
+
new_color.b = round(np.clip(self.b * factor, 0, 255))
|
224
|
+
|
225
|
+
return new_color
|
226
|
+
|
227
|
+
def with_brightness(self, brightness: int) -> "Color":
|
228
|
+
"""
|
229
|
+
Percentage of brightness of the new color.
|
230
|
+
"""
|
231
|
+
h, s, _ = self.to_hsv()
|
232
|
+
return self.from_hsv(h, s, brightness)
|
233
|
+
|
234
|
+
def with_saturation(self, saturation: int) -> "Color":
|
235
|
+
"""
|
236
|
+
Percentage of brightness of the new color.
|
237
|
+
"""
|
238
|
+
h, _, v = self.to_hsv()
|
239
|
+
return self.from_hsv(h, saturation, v)
|
240
|
+
|
241
|
+
def with_rgba(
|
242
|
+
self,
|
243
|
+
r: int | None = None,
|
244
|
+
g: int | None = None,
|
245
|
+
b: int | None = None,
|
246
|
+
a: int | None = None,
|
247
|
+
) -> "Color":
|
248
|
+
return self.from_rgba(
|
249
|
+
r if (r is not None) else self.r,
|
250
|
+
g if (g is not None) else self.g,
|
251
|
+
b if (b is not None) else self.b,
|
252
|
+
a if (a is not None) else self.a,
|
253
|
+
)
|
254
|
+
|
255
|
+
def with_rgba_f(
|
256
|
+
self,
|
257
|
+
r: int | None = None,
|
258
|
+
g: int | None = None,
|
259
|
+
b: int | None = None,
|
260
|
+
a: int | None = None,
|
261
|
+
) -> "Color":
|
262
|
+
return self.from_rgba_f(
|
263
|
+
r if (r is not None) else self.r,
|
264
|
+
g if (g is not None) else self.g,
|
265
|
+
b if (b is not None) else self.b,
|
266
|
+
a if (a is not None) else self.a,
|
267
|
+
)
|
268
|
+
|
269
|
+
def __repr__(self):
|
270
|
+
return f"Color(r={self.r}, g={self.g}, b={self.b}, a={self.a})"
|
271
|
+
|
272
|
+
def __eq__(self, other: "Color"):
|
273
|
+
return self.r == other.r and self.g == other.g and self.b == other.b and self.a == other.a
|