drawlib 0.1.1__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.
Potentially problematic release.
This version of drawlib might be problematic. Click here for more details.
- drawlib/.pylintrc +2 -0
- drawlib/__init__.py +33 -0
- drawlib/__main__.py +21 -0
- drawlib/apis.py +22 -0
- drawlib/assets/__init__.py +8 -0
- drawlib/assets/v0_1/__init__.py +8 -0
- drawlib/assets/v0_1/fonticons/__init__.py +8 -0
- drawlib/assets/v0_1/fonts/__init__.py +8 -0
- drawlib/v0_1/__init__.py +31 -0
- drawlib/v0_1/__main__.py +20 -0
- drawlib/v0_1/apis.py +127 -0
- drawlib/v0_1/private/__init__.py +20 -0
- drawlib/v0_1/private/arg_validator.py +163 -0
- drawlib/v0_1/private/command.py +204 -0
- drawlib/v0_1/private/core/__init__.py +15 -0
- drawlib/v0_1/private/core/colors.py +285 -0
- drawlib/v0_1/private/core/dimage.py +510 -0
- drawlib/v0_1/private/core/fonts.py +324 -0
- drawlib/v0_1/private/core/model.py +1082 -0
- drawlib/v0_1/private/core/model_validator.py +175 -0
- drawlib/v0_1/private/core/theme.py +1042 -0
- drawlib/v0_1/private/core/util.py +809 -0
- drawlib/v0_1/private/core_canvas/__init__.py +15 -0
- drawlib/v0_1/private/core_canvas/base.py +653 -0
- drawlib/v0_1/private/core_canvas/canvas.py +88 -0
- drawlib/v0_1/private/core_canvas/image.py +154 -0
- drawlib/v0_1/private/core_canvas/line.py +263 -0
- drawlib/v0_1/private/core_canvas/original_arrow.py +139 -0
- drawlib/v0_1/private/core_canvas/original_polygon.py +584 -0
- drawlib/v0_1/private/core_canvas/patches.py +547 -0
- drawlib/v0_1/private/core_canvas/text.py +136 -0
- drawlib/v0_1/private/download.py +58 -0
- drawlib/v0_1/private/dutil.py +28 -0
- drawlib/v0_1/private/icons/__init__.py +15 -0
- drawlib/v0_1/private/icons/phosphor.py +35275 -0
- drawlib/v0_1/private/icons/util.py +82 -0
- drawlib/v0_1/private/logging.py +38 -0
- drawlib/v0_1/private/settings.py +233 -0
- drawlib/v0_1/private/smartarts/__init__.py +15 -0
- drawlib/v0_1/private/smartarts/cycle.py +11 -0
- drawlib/v0_1/private/smartarts/dsart.py +17 -0
- drawlib/v0_1/private/smartarts/groups.py +20 -0
- drawlib/v0_1/private/smartarts/pyramid.py +18 -0
- drawlib/v0_1/private/smartarts/sourcecode.py +216 -0
- drawlib/v0_1/private/smartarts/table.py +11 -0
- drawlib/v0_1/private/smartarts/tree.py +18 -0
- drawlib/v0_1/private/tools.py +161 -0
- drawlib/v0_1/private/util.py +353 -0
- drawlib-0.1.1.dist-info/LICENSE.txt +202 -0
- drawlib-0.1.1.dist-info/METADATA +36 -0
- drawlib-0.1.1.dist-info/RECORD +52 -0
- drawlib-0.1.1.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,1042 @@
|
|
|
1
|
+
# Copyright (c) 2024 Yuichi Ito (yuichi@yuichi.com)
|
|
2
|
+
#
|
|
3
|
+
# This software is licensed under the Apache License, Version 2.0.
|
|
4
|
+
# For more information, please visit: https://github.com/yuichi110/drawlib
|
|
5
|
+
#
|
|
6
|
+
# This software is provided "as is", without warranty of any kind,
|
|
7
|
+
# express or implied, including but not limited to the warranties of
|
|
8
|
+
# merchantability, fitness for a particular purpose and noninfringement.
|
|
9
|
+
|
|
10
|
+
"""Drawlib style theme
|
|
11
|
+
|
|
12
|
+
Define style theme at class ``Theme``.
|
|
13
|
+
Default or choosed theme is applied if style is not provided.
|
|
14
|
+
Instance ``dtheme`` is provided to user to control theme.
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import dataclasses
|
|
19
|
+
from typing import Optional, Dict, Tuple, Union, Literal, List
|
|
20
|
+
from copy import deepcopy
|
|
21
|
+
|
|
22
|
+
from drawlib.v0_1.private.util import error_handler
|
|
23
|
+
from drawlib.v0_1.private.core.model import (
|
|
24
|
+
IconStyle,
|
|
25
|
+
ImageStyle,
|
|
26
|
+
LineStyle,
|
|
27
|
+
LineArrowStyle,
|
|
28
|
+
ShapeStyle,
|
|
29
|
+
ShapeTextStyle,
|
|
30
|
+
TextStyle,
|
|
31
|
+
)
|
|
32
|
+
from drawlib.v0_1.private.core.fonts import (
|
|
33
|
+
FontBase,
|
|
34
|
+
Font,
|
|
35
|
+
FontSourceCode,
|
|
36
|
+
)
|
|
37
|
+
from drawlib.v0_1.private.arg_validator import ArgValidator
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclasses.dataclass
|
|
41
|
+
class _ThemeStyle:
|
|
42
|
+
"""Helper dataclass for defining theme styles"""
|
|
43
|
+
|
|
44
|
+
# icon
|
|
45
|
+
icon_style: Literal["thin", "light", "regular", "bold", "fill"]
|
|
46
|
+
icon_color: Union[
|
|
47
|
+
Tuple[float, float, float],
|
|
48
|
+
Tuple[float, float, float, float],
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
# line
|
|
52
|
+
line_style: Literal["solid", "dashed", "dotted", "dashdot"]
|
|
53
|
+
line_width: float
|
|
54
|
+
line_color: Union[
|
|
55
|
+
Tuple[float, float, float],
|
|
56
|
+
Tuple[float, float, float, float],
|
|
57
|
+
]
|
|
58
|
+
arrowhead_style: Literal[
|
|
59
|
+
"->",
|
|
60
|
+
"<-",
|
|
61
|
+
"<->",
|
|
62
|
+
"-|>",
|
|
63
|
+
"<|-",
|
|
64
|
+
"<|-|>",
|
|
65
|
+
]
|
|
66
|
+
arrowhead_scale: int
|
|
67
|
+
|
|
68
|
+
# shape
|
|
69
|
+
shape_line_style: Literal["solid", "dashed", "dotted", "dashdot"]
|
|
70
|
+
shape_line_width: float
|
|
71
|
+
shape_color: Union[
|
|
72
|
+
Tuple[float, float, float],
|
|
73
|
+
Tuple[float, float, float, float],
|
|
74
|
+
None,
|
|
75
|
+
]
|
|
76
|
+
shape_line_color: Union[
|
|
77
|
+
Tuple[float, float, float],
|
|
78
|
+
Tuple[float, float, float, float],
|
|
79
|
+
None,
|
|
80
|
+
]
|
|
81
|
+
shape_fill_color: Union[
|
|
82
|
+
Tuple[float, float, float],
|
|
83
|
+
Tuple[float, float, float, float],
|
|
84
|
+
None,
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
# shapetext
|
|
88
|
+
shapetext_font: FontBase
|
|
89
|
+
shapetext_size: int
|
|
90
|
+
shapetext_color: Union[
|
|
91
|
+
Tuple[float, float, float],
|
|
92
|
+
Tuple[float, float, float, float],
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
# text
|
|
96
|
+
text_font: FontBase
|
|
97
|
+
text_size: int
|
|
98
|
+
text_color: Union[
|
|
99
|
+
Tuple[float, float, float],
|
|
100
|
+
Tuple[float, float, float, float],
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class Theme:
|
|
105
|
+
"""Drawlib Thema control class.
|
|
106
|
+
|
|
107
|
+
* define theme here
|
|
108
|
+
* provide theme access methods
|
|
109
|
+
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
@error_handler
|
|
113
|
+
def __init__(self):
|
|
114
|
+
self.theme_default()
|
|
115
|
+
|
|
116
|
+
#############
|
|
117
|
+
### Thema ###
|
|
118
|
+
#############
|
|
119
|
+
|
|
120
|
+
@error_handler
|
|
121
|
+
def theme_initialize(self) -> None:
|
|
122
|
+
"""Initialize theme.
|
|
123
|
+
|
|
124
|
+
This method need to be called before setting manual theme.
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
None
|
|
128
|
+
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
self._background: Tuple[float, float, float, float] = (255, 255, 255, 1)
|
|
132
|
+
self._sourcecode_font: FontSourceCode = FontSourceCode.SOURCECODEPRO
|
|
133
|
+
|
|
134
|
+
# icon
|
|
135
|
+
self._iconstyles: Dict[str, IconStyle] = {}
|
|
136
|
+
|
|
137
|
+
# image
|
|
138
|
+
self._imagestyles: Dict[str, ImageStyle] = {}
|
|
139
|
+
|
|
140
|
+
# line
|
|
141
|
+
self._linestyles: Dict[str, LineStyle] = {}
|
|
142
|
+
self._linearrowstyles: Dict[str, LineArrowStyle] = {}
|
|
143
|
+
|
|
144
|
+
# shape
|
|
145
|
+
self._shapestyles: Dict[str, ShapeStyle] = {}
|
|
146
|
+
self._shapestyles_arc: Dict[str, ShapeStyle] = {}
|
|
147
|
+
self._shapestyles_arrow: Dict[str, ShapeStyle] = {}
|
|
148
|
+
self._shapestyles_circle: Dict[str, ShapeStyle] = {}
|
|
149
|
+
self._shapestyles_ellipse: Dict[str, ShapeStyle] = {}
|
|
150
|
+
self._shapestyles_polygon: Dict[str, ShapeStyle] = {}
|
|
151
|
+
self._shapestyles_rectangle: Dict[str, ShapeStyle] = {}
|
|
152
|
+
self._shapestyles_regularpolygon: Dict[str, ShapeStyle] = {}
|
|
153
|
+
self._shapestyles_wedge: Dict[str, ShapeStyle] = {}
|
|
154
|
+
self._shapetextstyles: Dict[str, ShapeTextStyle] = {}
|
|
155
|
+
|
|
156
|
+
# text
|
|
157
|
+
self._textstyles: Dict[str, TextStyle] = {}
|
|
158
|
+
|
|
159
|
+
@error_handler
|
|
160
|
+
def theme_default(self) -> None:
|
|
161
|
+
"""Change theme to default.
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
None
|
|
165
|
+
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
# https://coolors.co/6d7cc5-70c2bf-e4dfda-d4b483-c1666b
|
|
169
|
+
|
|
170
|
+
# primary color
|
|
171
|
+
blue_light = _get_rgba_from_hex("#6D7CC5")
|
|
172
|
+
blue_dark = _get_rgba_from_hex("#12152B")
|
|
173
|
+
|
|
174
|
+
# secondary color
|
|
175
|
+
green_light = _get_rgba_from_hex("#70C2BF")
|
|
176
|
+
green_dark = _get_rgba_from_hex("#0C1D1C")
|
|
177
|
+
|
|
178
|
+
# third color
|
|
179
|
+
pink_light = _get_rgba_from_hex("#C1666B")
|
|
180
|
+
pink_dark = _get_rgba_from_hex("#1D0C0D")
|
|
181
|
+
|
|
182
|
+
tstyle1 = _ThemeStyle(
|
|
183
|
+
icon_style="thin",
|
|
184
|
+
icon_color=blue_dark,
|
|
185
|
+
line_style="solid",
|
|
186
|
+
line_width=2,
|
|
187
|
+
line_color=blue_dark,
|
|
188
|
+
arrowhead_style="->",
|
|
189
|
+
arrowhead_scale=20,
|
|
190
|
+
shape_line_style="solid",
|
|
191
|
+
shape_line_width=1,
|
|
192
|
+
shape_line_color=blue_dark,
|
|
193
|
+
shape_fill_color=blue_light,
|
|
194
|
+
shape_color=None,
|
|
195
|
+
shapetext_font=Font.SANSSERIF_REGULAR,
|
|
196
|
+
shapetext_size=16,
|
|
197
|
+
shapetext_color=blue_dark,
|
|
198
|
+
text_font=Font.SANSSERIF_REGULAR,
|
|
199
|
+
text_size=16,
|
|
200
|
+
text_color=blue_dark,
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
tstyle2 = deepcopy(tstyle1)
|
|
204
|
+
tstyle2.line_color = green_dark
|
|
205
|
+
tstyle2.shape_line_color = green_dark
|
|
206
|
+
tstyle2.shape_fill_color = green_light
|
|
207
|
+
tstyle2.shapetext_color = green_dark
|
|
208
|
+
tstyle2.text_color = green_dark
|
|
209
|
+
|
|
210
|
+
tstyle3 = deepcopy(tstyle1)
|
|
211
|
+
tstyle3.line_color = pink_dark
|
|
212
|
+
tstyle3.shape_line_color = pink_dark
|
|
213
|
+
tstyle3.shape_fill_color = pink_light
|
|
214
|
+
tstyle3.shapetext_color = pink_dark
|
|
215
|
+
tstyle3.text_color = pink_dark
|
|
216
|
+
|
|
217
|
+
self._apply_thema_styles(
|
|
218
|
+
background=(255, 255, 255, 1), # white
|
|
219
|
+
sourcecode_font=FontSourceCode.SOURCECODEPRO,
|
|
220
|
+
tstyle1=tstyle1,
|
|
221
|
+
tstyle2=tstyle2,
|
|
222
|
+
tstyle3=tstyle3,
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
@error_handler
|
|
226
|
+
def theme_gray(self) -> None:
|
|
227
|
+
"""Change theme to gray.
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
None
|
|
231
|
+
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
# https://coolors.co/palette/f8f9fa-e9ecef-dee2e6-ced4da-adb5bd-6c757d-495057-343a40-212529
|
|
235
|
+
|
|
236
|
+
# primary color
|
|
237
|
+
gray1 = _get_rgba_from_hex("#ADB5BD")
|
|
238
|
+
gray_dark = _get_rgba_from_hex("#212529")
|
|
239
|
+
|
|
240
|
+
# secondary color
|
|
241
|
+
gray2 = _get_rgba_from_hex("#CED4DA")
|
|
242
|
+
|
|
243
|
+
# third color
|
|
244
|
+
gray3 = _get_rgba_from_hex("#DEE2E6")
|
|
245
|
+
|
|
246
|
+
tstyle1 = _ThemeStyle(
|
|
247
|
+
icon_style="thin",
|
|
248
|
+
icon_color=gray_dark,
|
|
249
|
+
line_style="solid",
|
|
250
|
+
line_width=2,
|
|
251
|
+
line_color=gray_dark,
|
|
252
|
+
arrowhead_style="->",
|
|
253
|
+
arrowhead_scale=20,
|
|
254
|
+
shape_line_style="solid",
|
|
255
|
+
shape_line_width=1,
|
|
256
|
+
shape_line_color=gray_dark,
|
|
257
|
+
shape_fill_color=gray1,
|
|
258
|
+
shape_color=None,
|
|
259
|
+
shapetext_font=Font.SANSSERIF_REGULAR,
|
|
260
|
+
shapetext_size=16,
|
|
261
|
+
shapetext_color=gray_dark,
|
|
262
|
+
text_font=Font.SANSSERIF_REGULAR,
|
|
263
|
+
text_size=16,
|
|
264
|
+
text_color=gray_dark,
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
tstyle2 = deepcopy(tstyle1)
|
|
268
|
+
tstyle2.shape_fill_color = gray2
|
|
269
|
+
|
|
270
|
+
tstyle3 = deepcopy(tstyle1)
|
|
271
|
+
tstyle3.shape_fill_color = gray3
|
|
272
|
+
|
|
273
|
+
self._apply_thema_styles(
|
|
274
|
+
background=(255, 255, 255, 1), # white
|
|
275
|
+
sourcecode_font=FontSourceCode.SOURCECODEPRO,
|
|
276
|
+
tstyle1=tstyle1,
|
|
277
|
+
tstyle2=tstyle2,
|
|
278
|
+
tstyle3=tstyle3,
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
##################
|
|
282
|
+
### Background ###
|
|
283
|
+
##################
|
|
284
|
+
|
|
285
|
+
@error_handler
|
|
286
|
+
def background_color_get(self) -> Tuple[int, int, int]:
|
|
287
|
+
"""Get theme background color.
|
|
288
|
+
|
|
289
|
+
Returns:
|
|
290
|
+
color
|
|
291
|
+
|
|
292
|
+
"""
|
|
293
|
+
|
|
294
|
+
# has no alpha
|
|
295
|
+
if len(self._background) == 3:
|
|
296
|
+
return self._background
|
|
297
|
+
|
|
298
|
+
# has alpha
|
|
299
|
+
b = self._background
|
|
300
|
+
return (b[0], b[1], b[2])
|
|
301
|
+
|
|
302
|
+
@error_handler
|
|
303
|
+
def background_color_set(
|
|
304
|
+
self,
|
|
305
|
+
color: Union[
|
|
306
|
+
Tuple[int, int, int],
|
|
307
|
+
Tuple[int, int, int, float],
|
|
308
|
+
],
|
|
309
|
+
) -> None:
|
|
310
|
+
"""Set theme background color.
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
color: background color. (R, G, B)
|
|
314
|
+
|
|
315
|
+
Returns:
|
|
316
|
+
None
|
|
317
|
+
|
|
318
|
+
"""
|
|
319
|
+
|
|
320
|
+
ArgValidator.validate_color("color", color)
|
|
321
|
+
self._background = color
|
|
322
|
+
|
|
323
|
+
@error_handler
|
|
324
|
+
def background_alpha_get(self) -> float:
|
|
325
|
+
"""Get theme background alpha.
|
|
326
|
+
|
|
327
|
+
Returns:
|
|
328
|
+
float: 0 ~ 1.0
|
|
329
|
+
|
|
330
|
+
"""
|
|
331
|
+
|
|
332
|
+
# has no alpha
|
|
333
|
+
if len(self._background) == 3:
|
|
334
|
+
return 1.0
|
|
335
|
+
|
|
336
|
+
# has alpha
|
|
337
|
+
return self._background[3]
|
|
338
|
+
|
|
339
|
+
@error_handler
|
|
340
|
+
def background_alpha_set(self, alpha: float) -> None:
|
|
341
|
+
"""Set theme background alpha.
|
|
342
|
+
|
|
343
|
+
Args:
|
|
344
|
+
alpha: float. 0.0 ~ 1.0
|
|
345
|
+
|
|
346
|
+
Returns:
|
|
347
|
+
None
|
|
348
|
+
|
|
349
|
+
"""
|
|
350
|
+
|
|
351
|
+
ArgValidator.validate_alpha("alpha", alpha)
|
|
352
|
+
|
|
353
|
+
if len(self._background) == 3:
|
|
354
|
+
# tuple + tuple makes concat tuple
|
|
355
|
+
self._background = self._background + (alpha,)
|
|
356
|
+
return
|
|
357
|
+
|
|
358
|
+
self._background = self._background[:-1] + (alpha,)
|
|
359
|
+
|
|
360
|
+
############
|
|
361
|
+
### Icon ###
|
|
362
|
+
############
|
|
363
|
+
|
|
364
|
+
@error_handler
|
|
365
|
+
def iconstyle_get(self, name: str = "1") -> IconStyle:
|
|
366
|
+
"""Get theme IconStyle.
|
|
367
|
+
|
|
368
|
+
Args:
|
|
369
|
+
name(option): key
|
|
370
|
+
|
|
371
|
+
Returns:
|
|
372
|
+
IconStyle
|
|
373
|
+
|
|
374
|
+
"""
|
|
375
|
+
|
|
376
|
+
return deepcopy(self._iconstyles[name])
|
|
377
|
+
|
|
378
|
+
@error_handler
|
|
379
|
+
def iconstyle_set(self, style: IconStyle, name: str = "1") -> None:
|
|
380
|
+
"""Set theme IconStyle.
|
|
381
|
+
|
|
382
|
+
Args:
|
|
383
|
+
style: theme IconStyle
|
|
384
|
+
name(optional): key
|
|
385
|
+
|
|
386
|
+
Returns:
|
|
387
|
+
None
|
|
388
|
+
|
|
389
|
+
"""
|
|
390
|
+
|
|
391
|
+
ArgValidator.validate_iconstyle("style", style)
|
|
392
|
+
ArgValidator.validate_str("name", name)
|
|
393
|
+
self._iconstyles[name] = deepcopy(style)
|
|
394
|
+
|
|
395
|
+
############
|
|
396
|
+
### Image ###
|
|
397
|
+
############
|
|
398
|
+
|
|
399
|
+
@error_handler
|
|
400
|
+
def imagestyle_get(self, name: str = "1") -> ImageStyle:
|
|
401
|
+
"""Get theme ImageStyle.
|
|
402
|
+
|
|
403
|
+
Args:
|
|
404
|
+
name(option): key
|
|
405
|
+
|
|
406
|
+
Returns:
|
|
407
|
+
ImageStyle
|
|
408
|
+
|
|
409
|
+
"""
|
|
410
|
+
|
|
411
|
+
return deepcopy(self._imagestyles[name])
|
|
412
|
+
|
|
413
|
+
@error_handler
|
|
414
|
+
def imagestyle_set(self, style: ImageStyle, name: str = "1") -> None:
|
|
415
|
+
"""Set theme ImageStyle.
|
|
416
|
+
|
|
417
|
+
Args:
|
|
418
|
+
style: theme ImageStyle
|
|
419
|
+
name(optional): key
|
|
420
|
+
|
|
421
|
+
Returns:
|
|
422
|
+
None
|
|
423
|
+
|
|
424
|
+
"""
|
|
425
|
+
|
|
426
|
+
ArgValidator.validate_imagestyle("style", style)
|
|
427
|
+
ArgValidator.validate_str("name", name)
|
|
428
|
+
self._imagestyles[name] = deepcopy(style)
|
|
429
|
+
|
|
430
|
+
############
|
|
431
|
+
### Line ###
|
|
432
|
+
############
|
|
433
|
+
|
|
434
|
+
@error_handler
|
|
435
|
+
def linestyle_get(self, name: str = "1") -> LineStyle:
|
|
436
|
+
"""Get theme LineStyle.
|
|
437
|
+
|
|
438
|
+
Args:
|
|
439
|
+
name(option): key
|
|
440
|
+
|
|
441
|
+
Returns:
|
|
442
|
+
LineStyle
|
|
443
|
+
|
|
444
|
+
"""
|
|
445
|
+
|
|
446
|
+
return deepcopy(self._linestyles[name])
|
|
447
|
+
|
|
448
|
+
@error_handler
|
|
449
|
+
def linestyle_set(self, style: LineStyle, name: str = "1") -> None:
|
|
450
|
+
"""Set theme LineStyle.
|
|
451
|
+
|
|
452
|
+
Args:
|
|
453
|
+
style: theme LineStyle
|
|
454
|
+
name(optional): key
|
|
455
|
+
|
|
456
|
+
Returns:
|
|
457
|
+
None
|
|
458
|
+
|
|
459
|
+
"""
|
|
460
|
+
|
|
461
|
+
ArgValidator.validate_linestyle("style", style)
|
|
462
|
+
ArgValidator.validate_str("name", name)
|
|
463
|
+
self._linestyles[name] = deepcopy(style)
|
|
464
|
+
|
|
465
|
+
@error_handler
|
|
466
|
+
def linearrowstyle_get(self, name: str = "1") -> LineArrowStyle:
|
|
467
|
+
"""Get theme LineArrowStyle.
|
|
468
|
+
|
|
469
|
+
Args:
|
|
470
|
+
name(optional): key
|
|
471
|
+
|
|
472
|
+
Returns:
|
|
473
|
+
LineArrowStyle
|
|
474
|
+
|
|
475
|
+
"""
|
|
476
|
+
|
|
477
|
+
return deepcopy(self._linearrowstyles[name])
|
|
478
|
+
|
|
479
|
+
@error_handler
|
|
480
|
+
def linearrowstyle_set(self, style: LineArrowStyle, name: str = "1") -> None:
|
|
481
|
+
"""Set theme LineArrowStyle.
|
|
482
|
+
|
|
483
|
+
Args:
|
|
484
|
+
style: theme LineArrowStyle
|
|
485
|
+
name(optional): key
|
|
486
|
+
|
|
487
|
+
Returns:
|
|
488
|
+
None
|
|
489
|
+
|
|
490
|
+
"""
|
|
491
|
+
|
|
492
|
+
ArgValidator.validate_linearrowstyle("style", style)
|
|
493
|
+
ArgValidator.validate_str("name", name)
|
|
494
|
+
self._linearrowstyles[name] = deepcopy(style)
|
|
495
|
+
|
|
496
|
+
############
|
|
497
|
+
### Text ###
|
|
498
|
+
############
|
|
499
|
+
|
|
500
|
+
@error_handler
|
|
501
|
+
def textstyle_get(self, name: str = "1") -> TextStyle:
|
|
502
|
+
"""Get theme TextStyle.
|
|
503
|
+
|
|
504
|
+
Args:
|
|
505
|
+
name(optional): key
|
|
506
|
+
|
|
507
|
+
Returns:
|
|
508
|
+
TextStyle
|
|
509
|
+
|
|
510
|
+
"""
|
|
511
|
+
|
|
512
|
+
return deepcopy(self._textstyles[name])
|
|
513
|
+
|
|
514
|
+
@error_handler
|
|
515
|
+
def textstyle_set(self, style: TextStyle, name: str = "1") -> None:
|
|
516
|
+
"""Set theme TextStyle.
|
|
517
|
+
|
|
518
|
+
Args:
|
|
519
|
+
style: theme TextStyle
|
|
520
|
+
name(optional): key
|
|
521
|
+
|
|
522
|
+
Returns:
|
|
523
|
+
None
|
|
524
|
+
|
|
525
|
+
"""
|
|
526
|
+
|
|
527
|
+
ArgValidator.validate_textstyle("style", style)
|
|
528
|
+
ArgValidator.validate_str("name", name)
|
|
529
|
+
self._textstyles[name] = deepcopy(style)
|
|
530
|
+
|
|
531
|
+
@error_handler
|
|
532
|
+
def sourcecodefont_get(self) -> FontSourceCode:
|
|
533
|
+
"""Get theme FontSourceCode.
|
|
534
|
+
|
|
535
|
+
Returns:
|
|
536
|
+
FontSourceCode
|
|
537
|
+
|
|
538
|
+
"""
|
|
539
|
+
return self._sourcecode_font
|
|
540
|
+
|
|
541
|
+
@error_handler
|
|
542
|
+
def sourcecodefont_set(self, font: FontSourceCode) -> None:
|
|
543
|
+
"""Set theme FontSourceCode.
|
|
544
|
+
|
|
545
|
+
Args:
|
|
546
|
+
font: FontSourceCode
|
|
547
|
+
|
|
548
|
+
Returns:
|
|
549
|
+
None
|
|
550
|
+
|
|
551
|
+
"""
|
|
552
|
+
ArgValidator.validate_fontsourcecode(font)
|
|
553
|
+
self._sourcecode_font = font
|
|
554
|
+
|
|
555
|
+
#############
|
|
556
|
+
### Shape ###
|
|
557
|
+
#############
|
|
558
|
+
|
|
559
|
+
@error_handler
|
|
560
|
+
def shapestyle_get(self, name: str = "1") -> ShapeStyle:
|
|
561
|
+
"""Get theme ShapeStyle.
|
|
562
|
+
|
|
563
|
+
Args:
|
|
564
|
+
name(optional): key
|
|
565
|
+
|
|
566
|
+
Returns:
|
|
567
|
+
ShapeStyle
|
|
568
|
+
|
|
569
|
+
"""
|
|
570
|
+
|
|
571
|
+
return deepcopy(self._shapestyles[name])
|
|
572
|
+
|
|
573
|
+
@error_handler
|
|
574
|
+
def shapestyle_set(self, style: ShapeStyle, name: str = "1") -> None:
|
|
575
|
+
"""Set theme ShapeStyle.
|
|
576
|
+
|
|
577
|
+
Args:
|
|
578
|
+
style: theme ShapeStyle
|
|
579
|
+
name(optional): key
|
|
580
|
+
|
|
581
|
+
Returns:
|
|
582
|
+
None
|
|
583
|
+
|
|
584
|
+
"""
|
|
585
|
+
|
|
586
|
+
ArgValidator.validate_shapestyle("style", style)
|
|
587
|
+
ArgValidator.validate_str("name", name)
|
|
588
|
+
self._shapestyles[name] = deepcopy(style)
|
|
589
|
+
|
|
590
|
+
@error_handler
|
|
591
|
+
def shapetextstyle_get(self, name: str = "1") -> ShapeTextStyle:
|
|
592
|
+
"""Get theme ShapeTextStyle.
|
|
593
|
+
|
|
594
|
+
Args:
|
|
595
|
+
name(optional): key
|
|
596
|
+
|
|
597
|
+
Returns:
|
|
598
|
+
ShapeTextStyle
|
|
599
|
+
|
|
600
|
+
"""
|
|
601
|
+
|
|
602
|
+
return deepcopy(self._shapetextstyles[name])
|
|
603
|
+
|
|
604
|
+
@error_handler
|
|
605
|
+
def shapetextstyle_set(self, style: ShapeTextStyle, name: str = "1") -> None:
|
|
606
|
+
"""Set theme ShapeTextStyle.
|
|
607
|
+
|
|
608
|
+
Args:
|
|
609
|
+
style: theme ShapeTextStyle
|
|
610
|
+
name(optional): key
|
|
611
|
+
|
|
612
|
+
Returns:
|
|
613
|
+
None
|
|
614
|
+
|
|
615
|
+
"""
|
|
616
|
+
|
|
617
|
+
ArgValidator.validate_shapetextstyle("style", style)
|
|
618
|
+
ArgValidator.validate_str("name", name)
|
|
619
|
+
self._shapetextstyles[name] = deepcopy(style)
|
|
620
|
+
|
|
621
|
+
@error_handler
|
|
622
|
+
def shapestyle_arc_get(self, name: str = "1") -> ShapeStyle:
|
|
623
|
+
"""Get theme ShapeStyle for arc.
|
|
624
|
+
|
|
625
|
+
If ShapeStyle is not set for arc, get general ShapeStyle.
|
|
626
|
+
|
|
627
|
+
Args:
|
|
628
|
+
name(optional): key
|
|
629
|
+
|
|
630
|
+
Returns:
|
|
631
|
+
ShapeStyle
|
|
632
|
+
|
|
633
|
+
"""
|
|
634
|
+
|
|
635
|
+
if name in self._shapestyles_arc:
|
|
636
|
+
return deepcopy(self._shapestyles_arc[name])
|
|
637
|
+
style = deepcopy(self._shapestyles[name])
|
|
638
|
+
style.fcolor = None # arc default style doesn't have fill color
|
|
639
|
+
return style
|
|
640
|
+
|
|
641
|
+
@error_handler
|
|
642
|
+
def shapestyle_arc_set(self, style: ShapeStyle, name: str = "1") -> None:
|
|
643
|
+
"""Set theme ShapeStyle for arc.
|
|
644
|
+
|
|
645
|
+
Args:
|
|
646
|
+
style: theme ShapeStyle for arc
|
|
647
|
+
name(optional): key
|
|
648
|
+
|
|
649
|
+
Returns:
|
|
650
|
+
None
|
|
651
|
+
|
|
652
|
+
"""
|
|
653
|
+
|
|
654
|
+
ArgValidator.validate_shapestyle("style", style)
|
|
655
|
+
ArgValidator.validate_str("name", name)
|
|
656
|
+
self._shapestyles_arc[name] = deepcopy(style)
|
|
657
|
+
|
|
658
|
+
@error_handler
|
|
659
|
+
def shapestyle_arrow_get(self, name: str = "1") -> ShapeStyle:
|
|
660
|
+
"""Get theme ShapeStyle for arrow.
|
|
661
|
+
|
|
662
|
+
If ShapeStyle is not set for arrow, get general ShapeStyle.
|
|
663
|
+
|
|
664
|
+
Args:
|
|
665
|
+
name(optional): key
|
|
666
|
+
|
|
667
|
+
Returns:
|
|
668
|
+
ShapeStyle
|
|
669
|
+
|
|
670
|
+
"""
|
|
671
|
+
|
|
672
|
+
if name in self._shapestyles_arrow:
|
|
673
|
+
return deepcopy(self._shapestyles_arrow[name])
|
|
674
|
+
return deepcopy(self._shapestyles[name])
|
|
675
|
+
|
|
676
|
+
@error_handler
|
|
677
|
+
def shapestyle_arrow_set(self, style: ShapeStyle, name: str = "1") -> None:
|
|
678
|
+
"""Set theme ShapeStyle for arrow.
|
|
679
|
+
|
|
680
|
+
Args:
|
|
681
|
+
style: theme ShapeStyle for arrow
|
|
682
|
+
name(optional): key
|
|
683
|
+
|
|
684
|
+
Returns:
|
|
685
|
+
None
|
|
686
|
+
|
|
687
|
+
"""
|
|
688
|
+
|
|
689
|
+
ArgValidator.validate_shapestyle("style", style)
|
|
690
|
+
ArgValidator.validate_str("name", name)
|
|
691
|
+
self._shapestyles_arrow[name] = deepcopy(style)
|
|
692
|
+
|
|
693
|
+
@error_handler
|
|
694
|
+
def shapestyle_circle_get(self, name: str = "1") -> ShapeStyle:
|
|
695
|
+
"""Get theme ShapeStyle for circle.
|
|
696
|
+
|
|
697
|
+
If ShapeStyle is not set for circle, get general ShapeStyle.
|
|
698
|
+
|
|
699
|
+
Args:
|
|
700
|
+
name(optional): key
|
|
701
|
+
|
|
702
|
+
Returns:
|
|
703
|
+
ShapeStyle
|
|
704
|
+
|
|
705
|
+
"""
|
|
706
|
+
|
|
707
|
+
if name in self._shapestyles_circle:
|
|
708
|
+
return deepcopy(self._shapestyles_circle[name])
|
|
709
|
+
return deepcopy(self._shapestyles[name])
|
|
710
|
+
|
|
711
|
+
@error_handler
|
|
712
|
+
def shapestyle_circle_set(self, style: ShapeStyle, name: str = "1") -> None:
|
|
713
|
+
"""Set theme ShapeStyle for circle.
|
|
714
|
+
|
|
715
|
+
Args:
|
|
716
|
+
style: theme ShapeStyle for circle
|
|
717
|
+
name(optional): key
|
|
718
|
+
|
|
719
|
+
Returns:
|
|
720
|
+
None
|
|
721
|
+
|
|
722
|
+
"""
|
|
723
|
+
ArgValidator.validate_shapestyle("style", style)
|
|
724
|
+
ArgValidator.validate_str("name", name)
|
|
725
|
+
self._shapestyles_circle[name] = deepcopy(style)
|
|
726
|
+
|
|
727
|
+
@error_handler
|
|
728
|
+
def shapestyle_ellipse_get(self, name: str = "1") -> ShapeStyle:
|
|
729
|
+
"""Get theme ShapeStyle for ellipse.
|
|
730
|
+
|
|
731
|
+
If ShapeStyle is not set for ellipse, get general ShapeStyle.
|
|
732
|
+
|
|
733
|
+
Args:
|
|
734
|
+
name(optional): key
|
|
735
|
+
|
|
736
|
+
Returns:
|
|
737
|
+
ShapeStyle
|
|
738
|
+
|
|
739
|
+
"""
|
|
740
|
+
|
|
741
|
+
if name in self._shapestyles_ellipse:
|
|
742
|
+
return deepcopy(self._shapestyles_ellipse[name])
|
|
743
|
+
return deepcopy(self._shapestyles[name])
|
|
744
|
+
|
|
745
|
+
@error_handler
|
|
746
|
+
def shapestyle_ellipse_set(self, style: ShapeStyle, name: str = "1") -> None:
|
|
747
|
+
"""Set theme ShapeStyle for ellipse.
|
|
748
|
+
|
|
749
|
+
Args:
|
|
750
|
+
style: theme ShapeStyle for ellipse
|
|
751
|
+
name(optional): key
|
|
752
|
+
|
|
753
|
+
Returns:
|
|
754
|
+
None
|
|
755
|
+
|
|
756
|
+
"""
|
|
757
|
+
|
|
758
|
+
ArgValidator.validate_shapestyle("style", style)
|
|
759
|
+
ArgValidator.validate_str("name", name)
|
|
760
|
+
self._shapestyles_ellipse[name] = deepcopy(style)
|
|
761
|
+
|
|
762
|
+
@error_handler
|
|
763
|
+
def shapestyle_polygon_get(self, name: str = "1") -> ShapeStyle:
|
|
764
|
+
"""Get theme ShapeStyle for polygon.
|
|
765
|
+
|
|
766
|
+
If ShapeStyle is not set for polygon, get general ShapeStyle.
|
|
767
|
+
|
|
768
|
+
Args:
|
|
769
|
+
name(optional): key
|
|
770
|
+
|
|
771
|
+
Returns:
|
|
772
|
+
ShapeStyle
|
|
773
|
+
|
|
774
|
+
"""
|
|
775
|
+
|
|
776
|
+
if name in self._shapestyles_polygon:
|
|
777
|
+
return deepcopy(self._shapestyles_polygon[name])
|
|
778
|
+
return deepcopy(self._shapestyles[name])
|
|
779
|
+
|
|
780
|
+
@error_handler
|
|
781
|
+
def shapestyle_polygon_set(self, style: ShapeStyle, name: str = "1") -> None:
|
|
782
|
+
"""Set theme ShapeStyle for polygon.
|
|
783
|
+
|
|
784
|
+
Args:
|
|
785
|
+
style: theme ShapeStyle for polygon
|
|
786
|
+
name(optional): key
|
|
787
|
+
|
|
788
|
+
Returns:
|
|
789
|
+
None
|
|
790
|
+
|
|
791
|
+
"""
|
|
792
|
+
|
|
793
|
+
ArgValidator.validate_shapestyle("style", style)
|
|
794
|
+
ArgValidator.validate_str("name", name)
|
|
795
|
+
self._shapestyles_polygon[name] = deepcopy(style)
|
|
796
|
+
|
|
797
|
+
@error_handler
|
|
798
|
+
def shapestyle_rectangle_get(self, name: str = "1") -> ShapeStyle:
|
|
799
|
+
"""Get theme ShapeStyle for rectangle.
|
|
800
|
+
|
|
801
|
+
If ShapeStyle is not set for rectangle, get general ShapeStyle.
|
|
802
|
+
|
|
803
|
+
Args:
|
|
804
|
+
name(optional): key
|
|
805
|
+
|
|
806
|
+
Returns:
|
|
807
|
+
ShapeStyle
|
|
808
|
+
|
|
809
|
+
"""
|
|
810
|
+
|
|
811
|
+
if name in self._shapestyles_rectangle:
|
|
812
|
+
return deepcopy(self._shapestyles_rectangle[name])
|
|
813
|
+
return deepcopy(self._shapestyles[name])
|
|
814
|
+
|
|
815
|
+
@error_handler
|
|
816
|
+
def shapestyle_rectangle_set(self, style: ShapeStyle, name: str = "1") -> None:
|
|
817
|
+
"""Set theme ShapeStyle for rectangle.
|
|
818
|
+
|
|
819
|
+
Args:
|
|
820
|
+
style: theme ShapeStyle for rectangle
|
|
821
|
+
name(optional): key
|
|
822
|
+
|
|
823
|
+
Returns:
|
|
824
|
+
None
|
|
825
|
+
|
|
826
|
+
"""
|
|
827
|
+
|
|
828
|
+
ArgValidator.validate_shapestyle("style", style)
|
|
829
|
+
ArgValidator.validate_str("name", name)
|
|
830
|
+
self._shapestyles_rectangle[name] = deepcopy(style)
|
|
831
|
+
|
|
832
|
+
@error_handler
|
|
833
|
+
def shapestyle_regularpolygon_get(self, name: str = "1") -> ShapeStyle:
|
|
834
|
+
"""Get theme ShapeStyle for regularpolygon.
|
|
835
|
+
|
|
836
|
+
If ShapeStyle is not set for regularpolygon, get general ShapeStyle.
|
|
837
|
+
|
|
838
|
+
Args:
|
|
839
|
+
name(optional): key
|
|
840
|
+
|
|
841
|
+
Returns:
|
|
842
|
+
ShapeStyle
|
|
843
|
+
|
|
844
|
+
"""
|
|
845
|
+
|
|
846
|
+
if name in self._shapestyles_regularpolygon:
|
|
847
|
+
return deepcopy(self._shapestyles_regularpolygon[name])
|
|
848
|
+
return deepcopy(self._shapestyles[name])
|
|
849
|
+
|
|
850
|
+
@error_handler
|
|
851
|
+
def shapestyle_regularpolygon_set(self, style: ShapeStyle, name: str = "1") -> None:
|
|
852
|
+
"""Set theme ShapeStyle for regularpolygon.
|
|
853
|
+
|
|
854
|
+
Args:
|
|
855
|
+
style: theme ShapeStyle for regularpolygon
|
|
856
|
+
name(optional): key
|
|
857
|
+
|
|
858
|
+
Returns:
|
|
859
|
+
None
|
|
860
|
+
|
|
861
|
+
"""
|
|
862
|
+
|
|
863
|
+
ArgValidator.validate_shapestyle("style", style)
|
|
864
|
+
ArgValidator.validate_str("name", name)
|
|
865
|
+
self._shapestyles_regularpolygon[name] = deepcopy(style)
|
|
866
|
+
|
|
867
|
+
@error_handler
|
|
868
|
+
def shapestyle_wedge_get(self, name: str = "1") -> ShapeStyle:
|
|
869
|
+
"""Get theme ShapeStyle for wedge.
|
|
870
|
+
|
|
871
|
+
If ShapeStyle is not set for wedge, get general ShapeStyle.
|
|
872
|
+
|
|
873
|
+
Args:
|
|
874
|
+
name(optional): key
|
|
875
|
+
|
|
876
|
+
Returns:
|
|
877
|
+
ShapeStyle
|
|
878
|
+
|
|
879
|
+
"""
|
|
880
|
+
|
|
881
|
+
if name in self._shapestyles_wedge:
|
|
882
|
+
return deepcopy(self._shapestyles_wedge[name])
|
|
883
|
+
return deepcopy(self._shapestyles[name])
|
|
884
|
+
|
|
885
|
+
@error_handler
|
|
886
|
+
def shapestyle_wedge_set(self, style: ShapeStyle, name: str = "1") -> None:
|
|
887
|
+
"""Set theme ShapeStyle for wedge.
|
|
888
|
+
|
|
889
|
+
Args:
|
|
890
|
+
style: theme ShapeStyle for wedge
|
|
891
|
+
name(optional): key
|
|
892
|
+
|
|
893
|
+
Returns:
|
|
894
|
+
None
|
|
895
|
+
|
|
896
|
+
"""
|
|
897
|
+
|
|
898
|
+
ArgValidator.validate_shapestyle("style", style)
|
|
899
|
+
ArgValidator.validate_str("name", name)
|
|
900
|
+
self._shapestyles_wedge[name] = deepcopy(style)
|
|
901
|
+
|
|
902
|
+
###############
|
|
903
|
+
### Private ###
|
|
904
|
+
###############
|
|
905
|
+
|
|
906
|
+
def _apply_thema_styles(
|
|
907
|
+
self,
|
|
908
|
+
background: Union[Tuple[int, int, int], Tuple[int, int, int, float]],
|
|
909
|
+
sourcecode_font: FontSourceCode,
|
|
910
|
+
tstyle1: _ThemeStyle,
|
|
911
|
+
tstyle2: Optional[_ThemeStyle] = None,
|
|
912
|
+
tstyle3: Optional[_ThemeStyle] = None,
|
|
913
|
+
tstyle4: Optional[_ThemeStyle] = None,
|
|
914
|
+
tstyle5: Optional[_ThemeStyle] = None,
|
|
915
|
+
) -> None:
|
|
916
|
+
|
|
917
|
+
self.theme_initialize()
|
|
918
|
+
self._background = background
|
|
919
|
+
self._sourcecode_font = sourcecode_font
|
|
920
|
+
|
|
921
|
+
tstyles: List[_ThemeStyle] = [
|
|
922
|
+
tstyle1,
|
|
923
|
+
tstyle2,
|
|
924
|
+
tstyle3,
|
|
925
|
+
tstyle4,
|
|
926
|
+
tstyle5,
|
|
927
|
+
]
|
|
928
|
+
for i, tstyle in enumerate(tstyles, start=1):
|
|
929
|
+
name = str(i)
|
|
930
|
+
if tstyle is None:
|
|
931
|
+
if name == "1":
|
|
932
|
+
raise ValueError('default thema style "1" must be configured.')
|
|
933
|
+
continue
|
|
934
|
+
|
|
935
|
+
self.iconstyle_set(
|
|
936
|
+
style=IconStyle(
|
|
937
|
+
style=tstyle.icon_style,
|
|
938
|
+
color=tstyle.icon_color,
|
|
939
|
+
),
|
|
940
|
+
name=name,
|
|
941
|
+
)
|
|
942
|
+
self.imagestyle_set(
|
|
943
|
+
style=ImageStyle(
|
|
944
|
+
lstyle=tstyle.shape_line_style,
|
|
945
|
+
lcolor=tstyle.shape_line_color,
|
|
946
|
+
),
|
|
947
|
+
name=name,
|
|
948
|
+
)
|
|
949
|
+
self.linestyle_set(
|
|
950
|
+
style=LineStyle(
|
|
951
|
+
style=tstyle.line_style,
|
|
952
|
+
width=tstyle.line_width,
|
|
953
|
+
color=tstyle.line_color,
|
|
954
|
+
),
|
|
955
|
+
name=name,
|
|
956
|
+
)
|
|
957
|
+
|
|
958
|
+
self.linearrowstyle_set(
|
|
959
|
+
style=LineArrowStyle(
|
|
960
|
+
lstyle=tstyle.line_style,
|
|
961
|
+
lwidth=tstyle.line_width,
|
|
962
|
+
hstyle=tstyle.arrowhead_style,
|
|
963
|
+
hscale=tstyle.arrowhead_scale,
|
|
964
|
+
color=tstyle.line_color,
|
|
965
|
+
),
|
|
966
|
+
name=name,
|
|
967
|
+
)
|
|
968
|
+
|
|
969
|
+
self.textstyle_set(
|
|
970
|
+
style=TextStyle(
|
|
971
|
+
font=tstyle.text_font,
|
|
972
|
+
size=tstyle.text_size,
|
|
973
|
+
color=tstyle.text_color,
|
|
974
|
+
halign=None, # depends on situation. keep None.
|
|
975
|
+
valign=None, # depends on situation. keep None.
|
|
976
|
+
),
|
|
977
|
+
name=name,
|
|
978
|
+
)
|
|
979
|
+
|
|
980
|
+
self.shapestyle_set(
|
|
981
|
+
style=ShapeStyle(
|
|
982
|
+
lwidth=tstyle.shape_line_width,
|
|
983
|
+
lstyle=tstyle.shape_line_style,
|
|
984
|
+
lcolor=tstyle.shape_line_color,
|
|
985
|
+
fcolor=tstyle.shape_fill_color,
|
|
986
|
+
halign=None, # depends on situation. keep None.
|
|
987
|
+
valign=None, # depends on situation. keep None.
|
|
988
|
+
),
|
|
989
|
+
name=name,
|
|
990
|
+
)
|
|
991
|
+
|
|
992
|
+
self.shapetextstyle_set(
|
|
993
|
+
style=ShapeTextStyle(
|
|
994
|
+
font=tstyle.text_font,
|
|
995
|
+
size=tstyle.text_size,
|
|
996
|
+
color=tstyle.text_color,
|
|
997
|
+
halign=None, # depends on situation. keep None.
|
|
998
|
+
valign=None, # depends on situation. keep None.
|
|
999
|
+
),
|
|
1000
|
+
name=name,
|
|
1001
|
+
)
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
def _get_rgba_from_hex(hex_color: str) -> Tuple[int, int, int, float]:
|
|
1005
|
+
"""
|
|
1006
|
+
Convert a hexadecimal color code to RGBA values.
|
|
1007
|
+
|
|
1008
|
+
Args:
|
|
1009
|
+
hex_color (str): The hexadecimal color code (e.g., "#FF5733" or "#FFF").
|
|
1010
|
+
|
|
1011
|
+
Returns:
|
|
1012
|
+
tuple[int, int, int, float]: A tuple containing the RGBA values (0-255 for R, G, B and 0.0-1.0 for A).
|
|
1013
|
+
"""
|
|
1014
|
+
|
|
1015
|
+
# Remove the '#' prefix if present
|
|
1016
|
+
hex_color = hex_color.lstrip("#")
|
|
1017
|
+
|
|
1018
|
+
# Determine the length of the hex color code
|
|
1019
|
+
hex_length = len(hex_color)
|
|
1020
|
+
|
|
1021
|
+
# Convert the hex code to RGB values
|
|
1022
|
+
if hex_length == 3: # Short hex format (#RGB)
|
|
1023
|
+
r = int(hex_color[0] * 2, 16)
|
|
1024
|
+
g = int(hex_color[1] * 2, 16)
|
|
1025
|
+
b = int(hex_color[2] * 2, 16)
|
|
1026
|
+
a = 1.0
|
|
1027
|
+
elif hex_length in (6, 8): # Full hex format (#RRGGBB)
|
|
1028
|
+
r = int(hex_color[0:2], 16)
|
|
1029
|
+
g = int(hex_color[2:4], 16)
|
|
1030
|
+
b = int(hex_color[4:6], 16)
|
|
1031
|
+
if hex_length == 8: # With alpha
|
|
1032
|
+
a = int(hex_color[6:8], 16)
|
|
1033
|
+
else:
|
|
1034
|
+
a = 1.0
|
|
1035
|
+
else:
|
|
1036
|
+
raise ValueError("Invalid hex color code format")
|
|
1037
|
+
|
|
1038
|
+
return (r, g, b, a)
|
|
1039
|
+
|
|
1040
|
+
|
|
1041
|
+
dtheme = Theme()
|
|
1042
|
+
"""Singleton instance of class ``Theme``."""
|