config-cli-gui 0.2.7__tar.gz → 0.2.8__tar.gz
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.
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/HISTORY.md +9 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/PKG-INFO +2 -1
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/README.md +1 -1
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/config.yaml +6 -1
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/docs/usage/config.md +6 -5
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/pyproject.toml +1 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/config_cli_gui/_version.py +3 -3
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/config_cli_gui/config.py +8 -78
- config_cli_gui-0.2.8/src/config_cli_gui/configtypes/color.py +43 -0
- config_cli_gui-0.2.8/src/config_cli_gui/configtypes/font.py +74 -0
- config_cli_gui-0.2.8/src/config_cli_gui/configtypes/vector.py +31 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/config_cli_gui/gui.py +108 -4
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/config_cli_gui.egg-info/PKG-INFO +2 -1
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/config_cli_gui.egg-info/SOURCES.txt +4 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/config_cli_gui.egg-info/requires.txt +1 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/example_project/config/config_example.py +9 -2
- config_cli_gui-0.2.8/tests/example_project/gui/__init__.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/test_config_manager.py +9 -2
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/test_docs.py +1 -1
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/uv.lock +40 -1
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.github/FUNDING.yml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.github/actions/setup-environment/action.yml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.github/dependabot.yml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.github/init.sh +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.github/release_message.sh +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.github/update_funding.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.github/workflows/main.yml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.github/workflows/release.yml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.github/workflows/update_readme.yml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.gitignore +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.idea/runConfigurations/config_generate.xml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.idea/runConfigurations/example_project_cli.xml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.idea/runConfigurations/example_project_gui.xml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.pre-commit-config.yaml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.readthedocs.yaml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/LICENSE +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/Makefile +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/docs/.nav.yml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/docs/_static/img/favicon.png +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/docs/_static/img/logo.png +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/docs/css/custom.css +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/docs/develop/contributing.md +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/docs/develop/make_windows.md +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/docs/develop/naming_convention.md +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/docs/funding/funding.md +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/docs/getting-started/install.md +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/docs/getting-started/virtual-environment.md +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/docs/index.md +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/docs/usage/cli.md +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/mkdocs.yml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/scripts/show_filelist.ps1 +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/scripts/show_tree.ps1 +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/scripts/show_tree.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/scripts/update_readme.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/setup.cfg +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/__init__.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/config_cli_gui/__init__.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/config_cli_gui/cli.py +0 -0
- {config_cli_gui-0.2.7/tests → config_cli_gui-0.2.8/src/config_cli_gui/configtypes}/__init__.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/config_cli_gui/docs.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/config_cli_gui.egg-info/dependency_links.txt +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/config_cli_gui.egg-info/entry_points.txt +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/config_cli_gui.egg-info/top_level.txt +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/template.yml.url +0 -0
- {config_cli_gui-0.2.7/tests/example_project → config_cli_gui-0.2.8/tests}/__init__.py +0 -0
- {config_cli_gui-0.2.7/tests/example_project/cli → config_cli_gui-0.2.8/tests/example_project}/__init__.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/example_project/__main__.py +0 -0
- {config_cli_gui-0.2.7/tests/example_project/config → config_cli_gui-0.2.8/tests/example_project/cli}/__init__.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/example_project/cli/__main__.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/example_project/cli/cli_example.py +0 -0
- {config_cli_gui-0.2.7/tests/example_project/core → config_cli_gui-0.2.8/tests/example_project/config}/__init__.py +0 -0
- {config_cli_gui-0.2.7/tests/example_project/gui → config_cli_gui-0.2.8/tests/example_project/core}/__init__.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/example_project/core/base.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/example_project/core/logging.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/example_project/example.gpx +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/example_project/gui/__main__.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/example_project/gui/config.yaml +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/example_project/gui/gui_example.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/test_cli.py +0 -0
- {config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/test_generic_cli.py +0 -0
|
@@ -4,6 +4,15 @@ Changelog
|
|
|
4
4
|
|
|
5
5
|
(unreleased)
|
|
6
6
|
------------
|
|
7
|
+
- Refactoring: get_image_font will look for the actual font path in the
|
|
8
|
+
system. [Paul Magister]
|
|
9
|
+
- Font preview. [Paul Magister]
|
|
10
|
+
- Add font category in config.py. [Paul Magister]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
0.2.7 (2025-11-29)
|
|
14
|
+
------------------
|
|
15
|
+
- Docs: Update HISTORY.md for release 0.2.7. [Paul Magister]
|
|
7
16
|
- Also show required params in gui. [Paul Magister]
|
|
8
17
|
|
|
9
18
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: config-cli-gui
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: Feature-rich Python project template for config-cli-gui.
|
|
5
5
|
Author: pamagister
|
|
6
6
|
Requires-Python: <3.12,>=3.10
|
|
@@ -8,6 +8,7 @@ Description-Content-Type: text/markdown
|
|
|
8
8
|
License-File: LICENSE
|
|
9
9
|
Requires-Dist: pydantic>=2.11.7
|
|
10
10
|
Requires-Dist: pyyaml>=6.0.2
|
|
11
|
+
Requires-Dist: pillow>=12.0.0
|
|
11
12
|
Provides-Extra: dev
|
|
12
13
|
Requires-Dist: pytest>=8.4.0; extra == "dev"
|
|
13
14
|
Requires-Dist: pytest-mock>=3.14.1; extra == "dev"
|
|
@@ -62,11 +62,11 @@ from datetime import datetime
|
|
|
62
62
|
from pathlib import Path
|
|
63
63
|
|
|
64
64
|
from config_cli_gui.config import (
|
|
65
|
-
Color,
|
|
66
65
|
ConfigCategory,
|
|
67
66
|
ConfigManager,
|
|
68
67
|
ConfigParameter,
|
|
69
68
|
)
|
|
69
|
+
from config_cli_gui.configtypes.color import Color
|
|
70
70
|
from config_cli_gui.docs import DocumentationGenerator
|
|
71
71
|
|
|
72
72
|
|
|
@@ -49,4 +49,9 @@ misc:
|
|
|
49
49
|
# Date setting for the application | type=datetime
|
|
50
50
|
some_date: '2025-12-31T10:30:45'
|
|
51
51
|
# Path to the file to use | type=PosixPath
|
|
52
|
-
some_file: some_file.txt
|
|
52
|
+
some_file: some_file.txt
|
|
53
|
+
# Font setting for the application | type=Font
|
|
54
|
+
some_font:
|
|
55
|
+
- DejaVuSans.ttf
|
|
56
|
+
- 12
|
|
57
|
+
- '#0000ff'
|
|
@@ -41,9 +41,10 @@ The parameters in the cli category can be accessed via the command line interfac
|
|
|
41
41
|
|
|
42
42
|
## Category "misc"
|
|
43
43
|
|
|
44
|
-
| Name | Type | Description | Default
|
|
45
|
-
|
|
46
|
-
| some_file | PosixPath | Path to the file to use | PosixPath('some_file.txt')
|
|
47
|
-
| some_color | Color | Color setting for the application | Color(255, 0, 0)
|
|
48
|
-
| some_date | datetime | Date setting for the application | datetime.datetime(2025, 12, 31, 10, 30, 45)
|
|
44
|
+
| Name | Type | Description | Default | Choices |
|
|
45
|
+
|------------|-----------|-----------------------------------|--------------------------------------------------------------|---------|
|
|
46
|
+
| some_file | PosixPath | Path to the file to use | PosixPath('some_file.txt') | - |
|
|
47
|
+
| some_color | Color | Color setting for the application | Color(255, 0, 0) | - |
|
|
48
|
+
| some_date | datetime | Date setting for the application | datetime.datetime(2025, 12, 31, 10, 30, 45) | - |
|
|
49
|
+
| some_font | Font | Font setting for the application | Font(type='DejaVuSans.ttf', size=12, color=Color(0, 0, 255)) | - |
|
|
49
50
|
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.2.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
31
|
+
__version__ = version = '0.2.8'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 2, 8)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g013f3a747'
|
|
@@ -8,83 +8,9 @@ from typing import Any
|
|
|
8
8
|
import yaml
|
|
9
9
|
from pydantic import BaseModel
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def __init__(self, x: int | float, y: int | float, z: int | float | None = None):
|
|
16
|
-
self.x = x
|
|
17
|
-
self.y = y
|
|
18
|
-
self.z = z
|
|
19
|
-
|
|
20
|
-
def to_list(self) -> list[int]:
|
|
21
|
-
return [self.x, self.y, self.z] if self.z is not None else [self.x, self.y]
|
|
22
|
-
|
|
23
|
-
@classmethod
|
|
24
|
-
def from_list(cls, coordinate: list[int | str | float]) -> "Vector":
|
|
25
|
-
if len(coordinate) == 2:
|
|
26
|
-
return cls(float(coordinate[0]), float(coordinate[1]))
|
|
27
|
-
if len(coordinate) >= 3:
|
|
28
|
-
return cls(float(coordinate[0]), float(coordinate[1]), float(coordinate[2]))
|
|
29
|
-
return cls()
|
|
30
|
-
|
|
31
|
-
@classmethod
|
|
32
|
-
def from_str(cls, coordinate: str) -> "Vector":
|
|
33
|
-
return cls.from_list(coordinate.strip("()[]").split(","))
|
|
34
|
-
|
|
35
|
-
def to_str(self) -> str:
|
|
36
|
-
return f"({self.x}, {self.y}, {self.z})" if self.z is not None else f"({self.x}, {self.y})" # type: ignore
|
|
37
|
-
|
|
38
|
-
def __str__(self):
|
|
39
|
-
return self.to_str()
|
|
40
|
-
|
|
41
|
-
def __repr__(self):
|
|
42
|
-
return f"Vector{str(self)}"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class Color:
|
|
46
|
-
"""Simple color class for RGB values."""
|
|
47
|
-
|
|
48
|
-
def __init__(self, r: int = 0, g: int = 0, b: int = 0):
|
|
49
|
-
self.r = max(0, min(255, r))
|
|
50
|
-
self.g = max(0, min(255, g))
|
|
51
|
-
self.b = max(0, min(255, b))
|
|
52
|
-
|
|
53
|
-
def to_list(self) -> list[int]:
|
|
54
|
-
return [self.r, self.g, self.b]
|
|
55
|
-
|
|
56
|
-
def to_rgb(self) -> tuple[float]:
|
|
57
|
-
return (self.r / 255, self.g / 255, self.b / 255)
|
|
58
|
-
|
|
59
|
-
def to_pil(self) -> tuple[int, ...]:
|
|
60
|
-
"""Convert Color object to Pillow-compatible RGB tuple."""
|
|
61
|
-
return tuple(int(c) for c in self.to_list())
|
|
62
|
-
|
|
63
|
-
def to_hex(self) -> str:
|
|
64
|
-
return f"#{self.r:02x}{self.g:02x}{self.b:02x}"
|
|
65
|
-
|
|
66
|
-
@classmethod
|
|
67
|
-
def from_list(cls, rgb_list: list[int | str]) -> "Color":
|
|
68
|
-
if len(rgb_list) >= 3:
|
|
69
|
-
return cls(int(rgb_list[0]), int(rgb_list[1]), int(rgb_list[2]))
|
|
70
|
-
return cls()
|
|
71
|
-
|
|
72
|
-
@classmethod
|
|
73
|
-
def from_hex(cls, hex_color: str) -> "Color":
|
|
74
|
-
hex_color = hex_color.lstrip("#")
|
|
75
|
-
if len(hex_color) == 6:
|
|
76
|
-
return cls(
|
|
77
|
-
int(hex_color[0:2], 16),
|
|
78
|
-
int(hex_color[2:4], 16),
|
|
79
|
-
int(hex_color[4:6], 16),
|
|
80
|
-
)
|
|
81
|
-
return cls()
|
|
82
|
-
|
|
83
|
-
def __str__(self):
|
|
84
|
-
return self.to_hex()
|
|
85
|
-
|
|
86
|
-
def __repr__(self):
|
|
87
|
-
return f"Color({self.r}, {self.g}, {self.b})"
|
|
11
|
+
from config_cli_gui.configtypes.color import Color
|
|
12
|
+
from config_cli_gui.configtypes.font import Font
|
|
13
|
+
from config_cli_gui.configtypes.vector import Vector
|
|
88
14
|
|
|
89
15
|
|
|
90
16
|
@dataclass
|
|
@@ -197,6 +123,8 @@ class ConfigManager:
|
|
|
197
123
|
continue
|
|
198
124
|
|
|
199
125
|
# Type conversions
|
|
126
|
+
if isinstance(param.value, Font) and isinstance(param_value, list):
|
|
127
|
+
param_value = Font.from_list(param_value)
|
|
200
128
|
if isinstance(param.value, Color) and isinstance(param_value, list):
|
|
201
129
|
param_value = Color.from_list(param_value)
|
|
202
130
|
if isinstance(param.value, Color) and isinstance(param_value, str):
|
|
@@ -237,7 +165,9 @@ class ConfigManager:
|
|
|
237
165
|
result[category_name] = {}
|
|
238
166
|
for param in category.get_parameters():
|
|
239
167
|
val = getattr(category, param.name).value
|
|
240
|
-
if isinstance(val,
|
|
168
|
+
if isinstance(val, Font):
|
|
169
|
+
val = val.to_list()
|
|
170
|
+
elif isinstance(val, Color):
|
|
241
171
|
val = val.to_hex()
|
|
242
172
|
elif isinstance(val, Vector):
|
|
243
173
|
val = str(val.to_str())
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
class Color:
|
|
2
|
+
"""Simple color class for RGB values."""
|
|
3
|
+
|
|
4
|
+
def __init__(self, r: int = 0, g: int = 0, b: int = 0):
|
|
5
|
+
self.r = max(0, min(255, r))
|
|
6
|
+
self.g = max(0, min(255, g))
|
|
7
|
+
self.b = max(0, min(255, b))
|
|
8
|
+
|
|
9
|
+
def to_list(self) -> list[int]:
|
|
10
|
+
return [self.r, self.g, self.b]
|
|
11
|
+
|
|
12
|
+
def to_rgb(self) -> tuple[float, float, float]:
|
|
13
|
+
return self.r / 255, self.g / 255, self.b / 255
|
|
14
|
+
|
|
15
|
+
def to_pil(self) -> tuple[int, ...]:
|
|
16
|
+
"""Convert Color object to Pillow-compatible RGB tuple."""
|
|
17
|
+
return tuple(int(c) for c in self.to_list())
|
|
18
|
+
|
|
19
|
+
def to_hex(self) -> str:
|
|
20
|
+
return f"#{self.r:02x}{self.g:02x}{self.b:02x}"
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def from_list(cls, rgb_list: list[int | str]) -> "Color":
|
|
24
|
+
if len(rgb_list) >= 3:
|
|
25
|
+
return cls(int(rgb_list[0]), int(rgb_list[1]), int(rgb_list[2]))
|
|
26
|
+
return cls()
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
def from_hex(cls, hex_color: str) -> "Color":
|
|
30
|
+
hex_color = hex_color.lstrip("#")
|
|
31
|
+
if len(hex_color) == 6:
|
|
32
|
+
return cls(
|
|
33
|
+
int(hex_color[0:2], 16),
|
|
34
|
+
int(hex_color[2:4], 16),
|
|
35
|
+
int(hex_color[4:6], 16),
|
|
36
|
+
)
|
|
37
|
+
return cls()
|
|
38
|
+
|
|
39
|
+
def __str__(self):
|
|
40
|
+
return self.to_hex()
|
|
41
|
+
|
|
42
|
+
def __repr__(self):
|
|
43
|
+
return f"Color({self.r}, {self.g}, {self.b})"
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from PIL import ImageFont
|
|
6
|
+
|
|
7
|
+
from config_cli_gui.configtypes.color import Color
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def list_system_fonts() -> list[str]:
|
|
11
|
+
font_dirs = [
|
|
12
|
+
"/usr/share/fonts",
|
|
13
|
+
"/usr/local/share/fonts",
|
|
14
|
+
str(Path.home() / ".fonts"),
|
|
15
|
+
"/Library/Fonts",
|
|
16
|
+
"/System/Library/Fonts",
|
|
17
|
+
"C:/Windows/Fonts",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
fonts: list[str] = []
|
|
21
|
+
for d in font_dirs:
|
|
22
|
+
if os.path.isdir(d):
|
|
23
|
+
for root, _, files in os.walk(d):
|
|
24
|
+
for f in files:
|
|
25
|
+
if f.lower().endswith((".ttf", ".otf")):
|
|
26
|
+
fonts.append(os.path.join(root, f))
|
|
27
|
+
return fonts
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Font:
|
|
31
|
+
"""Represents a font with type, size and color."""
|
|
32
|
+
|
|
33
|
+
# Klassenattribute nach Klassendefinition setzen
|
|
34
|
+
font_files = list_system_fonts()
|
|
35
|
+
font_names = sorted([os.path.basename(f) for f in font_files])
|
|
36
|
+
font_files_sorted = sorted(font_files, key=os.path.basename)
|
|
37
|
+
|
|
38
|
+
def __init__(self, font_type: str, size: float, color: "Color"):
|
|
39
|
+
self.name = font_type
|
|
40
|
+
self.size = size
|
|
41
|
+
self.color = color
|
|
42
|
+
|
|
43
|
+
def to_list(self) -> list[Any]:
|
|
44
|
+
return [self.name, self.size, self.color.to_hex()]
|
|
45
|
+
|
|
46
|
+
@classmethod
|
|
47
|
+
def from_list(cls, font_data: list[Any]) -> "Font":
|
|
48
|
+
if len(font_data) < 3:
|
|
49
|
+
return cls("Arial", 12, Color(0, 0, 0))
|
|
50
|
+
|
|
51
|
+
font_type, size, color_val = font_data
|
|
52
|
+
color = (
|
|
53
|
+
Color.from_hex(color_val) if isinstance(color_val, str) else Color.from_list(color_val)
|
|
54
|
+
)
|
|
55
|
+
return cls(str(font_type), float(size), color)
|
|
56
|
+
|
|
57
|
+
def get_image_font(self) -> ImageFont.FreeTypeFont:
|
|
58
|
+
"""Return a PIL FreeTypeFont, with fallback to default."""
|
|
59
|
+
try:
|
|
60
|
+
if self.name in self.font_names:
|
|
61
|
+
idx = self.font_names.index(self.name)
|
|
62
|
+
path = self.font_files_sorted[idx]
|
|
63
|
+
return ImageFont.truetype(path, int(self.size))
|
|
64
|
+
except Exception as e:
|
|
65
|
+
print(f"Fehler beim Laden der Schrift '{self.name}': {e}")
|
|
66
|
+
|
|
67
|
+
print("Fallback: Nutze Default-Font.")
|
|
68
|
+
return ImageFont.load_default()
|
|
69
|
+
|
|
70
|
+
def __repr__(self) -> str:
|
|
71
|
+
return f"Font(type='{self.name}', size={self.size}, color={self.color!r})"
|
|
72
|
+
|
|
73
|
+
def __str__(self) -> str:
|
|
74
|
+
return f"{self.name}, {self.size}pt, {self.color}"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class Vector:
|
|
2
|
+
"""Class that represents a vector or point in 2D or 3D"""
|
|
3
|
+
|
|
4
|
+
def __init__(self, x: int | float, y: int | float, z: int | float | None = None):
|
|
5
|
+
self.x = x
|
|
6
|
+
self.y = y
|
|
7
|
+
self.z = z
|
|
8
|
+
|
|
9
|
+
def to_list(self) -> list[int]:
|
|
10
|
+
return [self.x, self.y, self.z] if self.z is not None else [self.x, self.y]
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def from_list(cls, coordinate: list[int | str | float]) -> "Vector":
|
|
14
|
+
if len(coordinate) == 2:
|
|
15
|
+
return cls(float(coordinate[0]), float(coordinate[1]))
|
|
16
|
+
if len(coordinate) >= 3:
|
|
17
|
+
return cls(float(coordinate[0]), float(coordinate[1]), float(coordinate[2]))
|
|
18
|
+
return cls()
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def from_str(cls, coordinate: str) -> "Vector":
|
|
22
|
+
return cls.from_list(coordinate.strip("()[]").split(","))
|
|
23
|
+
|
|
24
|
+
def to_str(self) -> str:
|
|
25
|
+
return f"({self.x}, {self.y}, {self.z})" if self.z is not None else f"({self.x}, {self.y})" # type: ignore
|
|
26
|
+
|
|
27
|
+
def __str__(self):
|
|
28
|
+
return self.to_str()
|
|
29
|
+
|
|
30
|
+
def __repr__(self):
|
|
31
|
+
return f"Vector{str(self)}"
|
|
@@ -2,12 +2,22 @@
|
|
|
2
2
|
"""Generic GUI settings dialog generator for configuration framework."""
|
|
3
3
|
|
|
4
4
|
import calendar
|
|
5
|
+
import os
|
|
5
6
|
import tkinter as tk
|
|
6
7
|
from datetime import datetime
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
from tkinter import colorchooser, filedialog, messagebox, ttk
|
|
9
10
|
|
|
10
|
-
from
|
|
11
|
+
from PIL import Image, ImageDraw, ImageTk
|
|
12
|
+
|
|
13
|
+
from config_cli_gui.config import (
|
|
14
|
+
ConfigCategory,
|
|
15
|
+
ConfigManager,
|
|
16
|
+
ConfigParameter,
|
|
17
|
+
)
|
|
18
|
+
from config_cli_gui.configtypes.color import Color
|
|
19
|
+
from config_cli_gui.configtypes.font import Font
|
|
20
|
+
from config_cli_gui.configtypes.vector import Vector
|
|
11
21
|
|
|
12
22
|
|
|
13
23
|
class ToolTip:
|
|
@@ -318,6 +328,10 @@ class GenericSettingsDialog:
|
|
|
318
328
|
elif isinstance(param.value, Color):
|
|
319
329
|
return self._create_color_widget(parent, param)
|
|
320
330
|
|
|
331
|
+
# Font type - Font picker
|
|
332
|
+
elif isinstance(param.value, Font):
|
|
333
|
+
return self._create_font_widget(parent, param)
|
|
334
|
+
|
|
321
335
|
# Vector type - Vector editor
|
|
322
336
|
elif isinstance(param.value, Vector):
|
|
323
337
|
return self._create_vector_widget(parent, param)
|
|
@@ -428,6 +442,86 @@ class GenericSettingsDialog:
|
|
|
428
442
|
frame.entry_widget = entry
|
|
429
443
|
return frame
|
|
430
444
|
|
|
445
|
+
def _create_font_widget(self, parent, param: ConfigParameter):
|
|
446
|
+
"""Create font picker widget."""
|
|
447
|
+
frame = ttk.Frame(parent)
|
|
448
|
+
font_value = param.value if isinstance(param.value, Font) else Font("Arial", 12, Color())
|
|
449
|
+
|
|
450
|
+
# Font type
|
|
451
|
+
font_type_var = tk.StringVar(value=os.path.basename(font_value.name))
|
|
452
|
+
font_type_combo = ttk.Combobox(
|
|
453
|
+
frame, textvariable=font_type_var, values=Font.font_names, state="readonly", width=25
|
|
454
|
+
)
|
|
455
|
+
font_type_combo.pack(side=tk.LEFT, padx=(0, 5))
|
|
456
|
+
|
|
457
|
+
# Font size
|
|
458
|
+
font_size_var = tk.DoubleVar(value=font_value.size)
|
|
459
|
+
font_size_spinbox = ttk.Spinbox(frame, from_=1, to=100, textvariable=font_size_var, width=5)
|
|
460
|
+
font_size_spinbox.pack(side=tk.LEFT, padx=(0, 5))
|
|
461
|
+
|
|
462
|
+
# Font color
|
|
463
|
+
color_var = tk.StringVar(value=font_value.color.to_hex())
|
|
464
|
+
color_display = tk.Label(frame, width=8, bg=font_value.color.to_hex())
|
|
465
|
+
color_display.pack(side=tk.LEFT, padx=(8, 2))
|
|
466
|
+
|
|
467
|
+
def pick_color():
|
|
468
|
+
color = colorchooser.askcolor(color=color_var.get())
|
|
469
|
+
if color[1]:
|
|
470
|
+
color_var.set(color[1])
|
|
471
|
+
color_display.config(bg=color[1])
|
|
472
|
+
|
|
473
|
+
pick_btn = ttk.Button(frame, text="Pick Color", command=pick_color)
|
|
474
|
+
pick_btn.pack(side=tk.LEFT, padx=(5, 0))
|
|
475
|
+
|
|
476
|
+
def on_color_change(*args):
|
|
477
|
+
try:
|
|
478
|
+
color_display.config(bg=color_var.get())
|
|
479
|
+
except tk.TclError:
|
|
480
|
+
pass
|
|
481
|
+
|
|
482
|
+
color_var.trace("w", on_color_change)
|
|
483
|
+
|
|
484
|
+
def show_preview():
|
|
485
|
+
font_size = int(font_size_var.get())
|
|
486
|
+
img_width = 170 + 3 * font_size
|
|
487
|
+
img_height = 20 + font_size
|
|
488
|
+
|
|
489
|
+
preview_win = tk.Toplevel(self.dialog)
|
|
490
|
+
preview_win.title("Font Preview")
|
|
491
|
+
preview_win.geometry(f"{img_width}x{img_height}")
|
|
492
|
+
preview_win.transient(self.dialog)
|
|
493
|
+
preview_win.grab_set()
|
|
494
|
+
|
|
495
|
+
font_color_hex = color_var.get()
|
|
496
|
+
|
|
497
|
+
font_obj = Font(font_type_var.get(), font_size, Color.from_hex(font_color_hex))
|
|
498
|
+
font = font_obj.get_image_font()
|
|
499
|
+
|
|
500
|
+
img = Image.new("RGB", (img_width, img_height), "white")
|
|
501
|
+
draw = ImageDraw.Draw(img)
|
|
502
|
+
|
|
503
|
+
text = "Sample"
|
|
504
|
+
|
|
505
|
+
draw.text(
|
|
506
|
+
(img_width / 2, img_height / 2), text, fill=font_color_hex, font=font, anchor="mm"
|
|
507
|
+
)
|
|
508
|
+
|
|
509
|
+
photo = ImageTk.PhotoImage(img)
|
|
510
|
+
|
|
511
|
+
img_label = tk.Label(preview_win, image=photo)
|
|
512
|
+
img_label.image = photo
|
|
513
|
+
img_label.pack()
|
|
514
|
+
|
|
515
|
+
preview_btn = ttk.Button(frame, text="Preview", command=show_preview)
|
|
516
|
+
preview_btn.pack(side=tk.LEFT, padx=(5, 0))
|
|
517
|
+
|
|
518
|
+
# Store variables in the frame for later access
|
|
519
|
+
frame.font_type_var = font_type_var
|
|
520
|
+
frame.font_size_var = font_size_var
|
|
521
|
+
frame.color_var = color_var
|
|
522
|
+
frame.entry_widget = font_type_combo
|
|
523
|
+
return frame
|
|
524
|
+
|
|
431
525
|
def _create_vector_widget(self, parent, param: ConfigParameter):
|
|
432
526
|
"""Create vector editor widget."""
|
|
433
527
|
frame = ttk.Frame(parent)
|
|
@@ -512,13 +606,23 @@ class GenericSettingsDialog:
|
|
|
512
606
|
# Update configuration with widget values
|
|
513
607
|
overrides = {}
|
|
514
608
|
for key, widget in self.widgets.items():
|
|
515
|
-
value = widget.var.get()
|
|
516
|
-
|
|
517
|
-
# Parse value based on parameter type
|
|
518
609
|
category_name, param_name = key.split("__", 1)
|
|
519
610
|
category = self.config_manager.get_category(category_name)
|
|
520
611
|
param_value = getattr(category, param_name).value
|
|
521
612
|
|
|
613
|
+
if isinstance(param_value, Font):
|
|
614
|
+
selected_font_name = widget.font_type_var.get()
|
|
615
|
+
font_type = selected_font_name
|
|
616
|
+
if selected_font_name in widget.font_names:
|
|
617
|
+
font_type = widget.font_files[widget.font_names.index(selected_font_name)]
|
|
618
|
+
|
|
619
|
+
font_size = widget.font_size_var.get()
|
|
620
|
+
font_color = Color.from_hex(widget.color_var.get())
|
|
621
|
+
overrides[key] = Font(font_type, font_size, font_color)
|
|
622
|
+
continue
|
|
623
|
+
|
|
624
|
+
value = widget.var.get()
|
|
625
|
+
|
|
522
626
|
# Convert value to appropriate type
|
|
523
627
|
if type(param_value) == bool:
|
|
524
628
|
overrides[key] = value
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: config-cli-gui
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: Feature-rich Python project template for config-cli-gui.
|
|
5
5
|
Author: pamagister
|
|
6
6
|
Requires-Python: <3.12,>=3.10
|
|
@@ -8,6 +8,7 @@ Description-Content-Type: text/markdown
|
|
|
8
8
|
License-File: LICENSE
|
|
9
9
|
Requires-Dist: pydantic>=2.11.7
|
|
10
10
|
Requires-Dist: pyyaml>=6.0.2
|
|
11
|
+
Requires-Dist: pillow>=12.0.0
|
|
11
12
|
Provides-Extra: dev
|
|
12
13
|
Requires-Dist: pytest>=8.4.0; extra == "dev"
|
|
13
14
|
Requires-Dist: pytest-mock>=3.14.1; extra == "dev"
|
|
@@ -55,6 +55,10 @@ src/config_cli_gui.egg-info/dependency_links.txt
|
|
|
55
55
|
src/config_cli_gui.egg-info/entry_points.txt
|
|
56
56
|
src/config_cli_gui.egg-info/requires.txt
|
|
57
57
|
src/config_cli_gui.egg-info/top_level.txt
|
|
58
|
+
src/config_cli_gui/configtypes/__init__.py
|
|
59
|
+
src/config_cli_gui/configtypes/color.py
|
|
60
|
+
src/config_cli_gui/configtypes/font.py
|
|
61
|
+
src/config_cli_gui/configtypes/vector.py
|
|
58
62
|
tests/__init__.py
|
|
59
63
|
tests/test_cli.py
|
|
60
64
|
tests/test_config_manager.py
|
{config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/tests/example_project/config/config_example.py
RENAMED
|
@@ -9,12 +9,13 @@ from datetime import datetime
|
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
|
|
11
11
|
from config_cli_gui.config import (
|
|
12
|
-
Color,
|
|
13
12
|
ConfigCategory,
|
|
14
13
|
ConfigManager,
|
|
15
14
|
ConfigParameter,
|
|
16
|
-
Vector,
|
|
17
15
|
)
|
|
16
|
+
from config_cli_gui.configtypes.color import Color
|
|
17
|
+
from config_cli_gui.configtypes.font import Font
|
|
18
|
+
from config_cli_gui.configtypes.vector import Vector
|
|
18
19
|
from config_cli_gui.docs import DocumentationGenerator
|
|
19
20
|
|
|
20
21
|
|
|
@@ -198,6 +199,12 @@ class MiscConfig(ConfigCategory):
|
|
|
198
199
|
help="Date setting for the application",
|
|
199
200
|
)
|
|
200
201
|
|
|
202
|
+
some_font: ConfigParameter = ConfigParameter(
|
|
203
|
+
name="some_font",
|
|
204
|
+
value=Font("DejaVuSans.ttf", size=12, color=Color(0, 0, 255)),
|
|
205
|
+
help="Font setting for the application",
|
|
206
|
+
)
|
|
207
|
+
|
|
201
208
|
|
|
202
209
|
class ProjectConfigManager(ConfigManager): # Inherit from ConfigManager
|
|
203
210
|
"""Main configuration manager that handles all parameter categories."""
|
|
File without changes
|
|
@@ -6,12 +6,13 @@ from unittest.mock import patch
|
|
|
6
6
|
import pytest
|
|
7
7
|
|
|
8
8
|
from config_cli_gui.config import (
|
|
9
|
-
Color,
|
|
10
9
|
ConfigCategory,
|
|
11
10
|
ConfigManager,
|
|
12
11
|
ConfigParameter,
|
|
13
|
-
Vector,
|
|
14
12
|
)
|
|
13
|
+
from config_cli_gui.configtypes.color import Color
|
|
14
|
+
from config_cli_gui.configtypes.font import Font
|
|
15
|
+
from config_cli_gui.configtypes.vector import Vector
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class ExampleCategory(ConfigCategory):
|
|
@@ -39,6 +40,12 @@ def test_color_basic():
|
|
|
39
40
|
assert str(c) == "#0033ff"
|
|
40
41
|
|
|
41
42
|
|
|
43
|
+
def test_font_basic():
|
|
44
|
+
f = Font("DejaVuSans.ttf", size=12, color=Color(255, 0, 0))
|
|
45
|
+
assert f.to_list() == ["DejaVuSans.ttf", 12, "#ff0000"]
|
|
46
|
+
assert str(f) == "DejaVuSans.ttf, 12pt, #ff0000"
|
|
47
|
+
|
|
48
|
+
|
|
42
49
|
def test_vector_2d():
|
|
43
50
|
v = Vector(1, 2)
|
|
44
51
|
assert v.to_list() == [1, 2]
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
from unittest.mock import patch
|
|
2
2
|
|
|
3
3
|
from config_cli_gui.config import (
|
|
4
|
-
Color,
|
|
5
4
|
ConfigCategory,
|
|
6
5
|
ConfigManager,
|
|
7
6
|
ConfigParameter,
|
|
8
7
|
)
|
|
8
|
+
from config_cli_gui.configtypes.color import Color
|
|
9
9
|
from config_cli_gui.docs import DocumentationGenerator
|
|
10
10
|
|
|
11
11
|
# ---------------------------------------
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
version = 1
|
|
2
|
-
revision =
|
|
2
|
+
revision = 3
|
|
3
3
|
requires-python = ">=3.10, <3.12"
|
|
4
4
|
resolution-markers = [
|
|
5
5
|
"python_full_version >= '3.11'",
|
|
@@ -93,6 +93,7 @@ wheels = [
|
|
|
93
93
|
name = "config-cli-gui"
|
|
94
94
|
source = { editable = "." }
|
|
95
95
|
dependencies = [
|
|
96
|
+
{ name = "pillow" },
|
|
96
97
|
{ name = "pydantic" },
|
|
97
98
|
{ name = "pyyaml" },
|
|
98
99
|
]
|
|
@@ -128,6 +129,7 @@ requires-dist = [
|
|
|
128
129
|
{ name = "mkdocs", marker = "extra == 'docs'", specifier = ">=1.6.1" },
|
|
129
130
|
{ name = "mkdocs-awesome-nav", marker = "extra == 'docs'", specifier = ">=2.6.1" },
|
|
130
131
|
{ name = "mypy", marker = "extra == 'dev'", specifier = ">=1.16.0" },
|
|
132
|
+
{ name = "pillow", specifier = ">=12.0.0" },
|
|
131
133
|
{ name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.2.0" },
|
|
132
134
|
{ name = "pydantic", specifier = ">=2.11.7" },
|
|
133
135
|
{ name = "pygments", marker = "extra == 'docs'", specifier = ">=2.19.1" },
|
|
@@ -481,6 +483,43 @@ wheels = [
|
|
|
481
483
|
{ url = "https://files.pythonhosted.org/packages/55/26/d0ad8b448476d0a1e8d3ea5622dc77b916db84c6aa3cb1e1c0965af948fc/pefile-2023.2.7-py3-none-any.whl", hash = "sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6", size = 71791, upload-time = "2023-02-07T12:28:36.678Z" },
|
|
482
484
|
]
|
|
483
485
|
|
|
486
|
+
[[package]]
|
|
487
|
+
name = "pillow"
|
|
488
|
+
version = "12.0.0"
|
|
489
|
+
source = { registry = "https://pypi.org/simple" }
|
|
490
|
+
sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828, upload-time = "2025-10-15T18:24:14.008Z" }
|
|
491
|
+
wheels = [
|
|
492
|
+
{ url = "https://files.pythonhosted.org/packages/5d/08/26e68b6b5da219c2a2cb7b563af008b53bb8e6b6fcb3fa40715fcdb2523a/pillow-12.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:3adfb466bbc544b926d50fe8f4a4e6abd8c6bffd28a26177594e6e9b2b76572b", size = 5289809, upload-time = "2025-10-15T18:21:27.791Z" },
|
|
493
|
+
{ url = "https://files.pythonhosted.org/packages/cb/e9/4e58fb097fb74c7b4758a680aacd558810a417d1edaa7000142976ef9d2f/pillow-12.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1ac11e8ea4f611c3c0147424eae514028b5e9077dd99ab91e1bd7bc33ff145e1", size = 4650606, upload-time = "2025-10-15T18:21:29.823Z" },
|
|
494
|
+
{ url = "https://files.pythonhosted.org/packages/4b/e0/1fa492aa9f77b3bc6d471c468e62bfea1823056bf7e5e4f1914d7ab2565e/pillow-12.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d49e2314c373f4c2b39446fb1a45ed333c850e09d0c59ac79b72eb3b95397363", size = 6221023, upload-time = "2025-10-15T18:21:31.415Z" },
|
|
495
|
+
{ url = "https://files.pythonhosted.org/packages/c1/09/4de7cd03e33734ccd0c876f0251401f1314e819cbfd89a0fcb6e77927cc6/pillow-12.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c7b2a63fd6d5246349f3d3f37b14430d73ee7e8173154461785e43036ffa96ca", size = 8024937, upload-time = "2025-10-15T18:21:33.453Z" },
|
|
496
|
+
{ url = "https://files.pythonhosted.org/packages/2e/69/0688e7c1390666592876d9d474f5e135abb4acb39dcb583c4dc5490f1aff/pillow-12.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d64317d2587c70324b79861babb9c09f71fbb780bad212018874b2c013d8600e", size = 6334139, upload-time = "2025-10-15T18:21:35.395Z" },
|
|
497
|
+
{ url = "https://files.pythonhosted.org/packages/ed/1c/880921e98f525b9b44ce747ad1ea8f73fd7e992bafe3ca5e5644bf433dea/pillow-12.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d77153e14b709fd8b8af6f66a3afbb9ed6e9fc5ccf0b6b7e1ced7b036a228782", size = 7026074, upload-time = "2025-10-15T18:21:37.219Z" },
|
|
498
|
+
{ url = "https://files.pythonhosted.org/packages/28/03/96f718331b19b355610ef4ebdbbde3557c726513030665071fd025745671/pillow-12.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:32ed80ea8a90ee3e6fa08c21e2e091bba6eda8eccc83dbc34c95169507a91f10", size = 6448852, upload-time = "2025-10-15T18:21:39.168Z" },
|
|
499
|
+
{ url = "https://files.pythonhosted.org/packages/3a/a0/6a193b3f0cc9437b122978d2c5cbce59510ccf9a5b48825096ed7472da2f/pillow-12.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c828a1ae702fc712978bda0320ba1b9893d99be0badf2647f693cc01cf0f04fa", size = 7117058, upload-time = "2025-10-15T18:21:40.997Z" },
|
|
500
|
+
{ url = "https://files.pythonhosted.org/packages/a7/c4/043192375eaa4463254e8e61f0e2ec9a846b983929a8d0a7122e0a6d6fff/pillow-12.0.0-cp310-cp310-win32.whl", hash = "sha256:bd87e140e45399c818fac4247880b9ce719e4783d767e030a883a970be632275", size = 6295431, upload-time = "2025-10-15T18:21:42.518Z" },
|
|
501
|
+
{ url = "https://files.pythonhosted.org/packages/92/c6/c2f2fc7e56301c21827e689bb8b0b465f1b52878b57471a070678c0c33cd/pillow-12.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:455247ac8a4cfb7b9bc45b7e432d10421aea9fc2e74d285ba4072688a74c2e9d", size = 7000412, upload-time = "2025-10-15T18:21:44.404Z" },
|
|
502
|
+
{ url = "https://files.pythonhosted.org/packages/b2/d2/5f675067ba82da7a1c238a73b32e3fd78d67f9d9f80fbadd33a40b9c0481/pillow-12.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:6ace95230bfb7cd79ef66caa064bbe2f2a1e63d93471c3a2e1f1348d9f22d6b7", size = 2435903, upload-time = "2025-10-15T18:21:46.29Z" },
|
|
503
|
+
{ url = "https://files.pythonhosted.org/packages/0e/5a/a2f6773b64edb921a756eb0729068acad9fc5208a53f4a349396e9436721/pillow-12.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0fd00cac9c03256c8b2ff58f162ebcd2587ad3e1f2e397eab718c47e24d231cc", size = 5289798, upload-time = "2025-10-15T18:21:47.763Z" },
|
|
504
|
+
{ url = "https://files.pythonhosted.org/packages/2e/05/069b1f8a2e4b5a37493da6c5868531c3f77b85e716ad7a590ef87d58730d/pillow-12.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3475b96f5908b3b16c47533daaa87380c491357d197564e0ba34ae75c0f3257", size = 4650589, upload-time = "2025-10-15T18:21:49.515Z" },
|
|
505
|
+
{ url = "https://files.pythonhosted.org/packages/61/e3/2c820d6e9a36432503ead175ae294f96861b07600a7156154a086ba7111a/pillow-12.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:110486b79f2d112cf6add83b28b627e369219388f64ef2f960fef9ebaf54c642", size = 6230472, upload-time = "2025-10-15T18:21:51.052Z" },
|
|
506
|
+
{ url = "https://files.pythonhosted.org/packages/4f/89/63427f51c64209c5e23d4d52071c8d0f21024d3a8a487737caaf614a5795/pillow-12.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5269cc1caeedb67e6f7269a42014f381f45e2e7cd42d834ede3c703a1d915fe3", size = 8033887, upload-time = "2025-10-15T18:21:52.604Z" },
|
|
507
|
+
{ url = "https://files.pythonhosted.org/packages/f6/1b/c9711318d4901093c15840f268ad649459cd81984c9ec9887756cca049a5/pillow-12.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa5129de4e174daccbc59d0a3b6d20eaf24417d59851c07ebb37aeb02947987c", size = 6343964, upload-time = "2025-10-15T18:21:54.619Z" },
|
|
508
|
+
{ url = "https://files.pythonhosted.org/packages/41/1e/db9470f2d030b4995083044cd8738cdd1bf773106819f6d8ba12597d5352/pillow-12.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bee2a6db3a7242ea309aa7ee8e2780726fed67ff4e5b40169f2c940e7eb09227", size = 7034756, upload-time = "2025-10-15T18:21:56.151Z" },
|
|
509
|
+
{ url = "https://files.pythonhosted.org/packages/cc/b0/6177a8bdd5ee4ed87cba2de5a3cc1db55ffbbec6176784ce5bb75aa96798/pillow-12.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:90387104ee8400a7b4598253b4c406f8958f59fcf983a6cea2b50d59f7d63d0b", size = 6458075, upload-time = "2025-10-15T18:21:57.759Z" },
|
|
510
|
+
{ url = "https://files.pythonhosted.org/packages/bc/5e/61537aa6fa977922c6a03253a0e727e6e4a72381a80d63ad8eec350684f2/pillow-12.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc91a56697869546d1b8f0a3ff35224557ae7f881050e99f615e0119bf934b4e", size = 7125955, upload-time = "2025-10-15T18:21:59.372Z" },
|
|
511
|
+
{ url = "https://files.pythonhosted.org/packages/1f/3d/d5033539344ee3cbd9a4d69e12e63ca3a44a739eb2d4c8da350a3d38edd7/pillow-12.0.0-cp311-cp311-win32.whl", hash = "sha256:27f95b12453d165099c84f8a8bfdfd46b9e4bda9e0e4b65f0635430027f55739", size = 6298440, upload-time = "2025-10-15T18:22:00.982Z" },
|
|
512
|
+
{ url = "https://files.pythonhosted.org/packages/4d/42/aaca386de5cc8bd8a0254516957c1f265e3521c91515b16e286c662854c4/pillow-12.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:b583dc9070312190192631373c6c8ed277254aa6e6084b74bdd0a6d3b221608e", size = 6999256, upload-time = "2025-10-15T18:22:02.617Z" },
|
|
513
|
+
{ url = "https://files.pythonhosted.org/packages/ba/f1/9197c9c2d5708b785f631a6dfbfa8eb3fb9672837cb92ae9af812c13b4ed/pillow-12.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:759de84a33be3b178a64c8ba28ad5c135900359e85fb662bc6e403ad4407791d", size = 2436025, upload-time = "2025-10-15T18:22:04.598Z" },
|
|
514
|
+
{ url = "https://files.pythonhosted.org/packages/1d/b3/582327e6c9f86d037b63beebe981425d6811104cb443e8193824ef1a2f27/pillow-12.0.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b22bd8c974942477156be55a768f7aa37c46904c175be4e158b6a86e3a6b7ca8", size = 5215068, upload-time = "2025-10-15T18:23:59.594Z" },
|
|
515
|
+
{ url = "https://files.pythonhosted.org/packages/fd/d6/67748211d119f3b6540baf90f92fae73ae51d5217b171b0e8b5f7e5d558f/pillow-12.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:805ebf596939e48dbb2e4922a1d3852cfc25c38160751ce02da93058b48d252a", size = 4614994, upload-time = "2025-10-15T18:24:01.669Z" },
|
|
516
|
+
{ url = "https://files.pythonhosted.org/packages/2d/e1/f8281e5d844c41872b273b9f2c34a4bf64ca08905668c8ae730eedc7c9fa/pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cae81479f77420d217def5f54b5b9d279804d17e982e0f2fa19b1d1e14ab5197", size = 5246639, upload-time = "2025-10-15T18:24:03.403Z" },
|
|
517
|
+
{ url = "https://files.pythonhosted.org/packages/94/5a/0d8ab8ffe8a102ff5df60d0de5af309015163bf710c7bb3e8311dd3b3ad0/pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeaefa96c768fc66818730b952a862235d68825c178f1b3ffd4efd7ad2edcb7c", size = 6986839, upload-time = "2025-10-15T18:24:05.344Z" },
|
|
518
|
+
{ url = "https://files.pythonhosted.org/packages/20/2e/3434380e8110b76cd9eb00a363c484b050f949b4bbe84ba770bb8508a02c/pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f2d0abef9e4e2f349305a4f8cc784a8a6c2f58a8c4892eea13b10a943bd26e", size = 5313505, upload-time = "2025-10-15T18:24:07.137Z" },
|
|
519
|
+
{ url = "https://files.pythonhosted.org/packages/57/ca/5a9d38900d9d74785141d6580950fe705de68af735ff6e727cb911b64740/pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdee52571a343d721fb2eb3b090a82d959ff37fc631e3f70422e0c2e029f3e76", size = 5963654, upload-time = "2025-10-15T18:24:09.579Z" },
|
|
520
|
+
{ url = "https://files.pythonhosted.org/packages/95/7e/f896623c3c635a90537ac093c6a618ebe1a90d87206e42309cb5d98a1b9e/pillow-12.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b290fd8aa38422444d4b50d579de197557f182ef1068b75f5aa8558638b8d0a5", size = 6997850, upload-time = "2025-10-15T18:24:11.495Z" },
|
|
521
|
+
]
|
|
522
|
+
|
|
484
523
|
[[package]]
|
|
485
524
|
name = "platformdirs"
|
|
486
525
|
version = "4.3.8"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.idea/runConfigurations/example_project_cli.xml
RENAMED
|
File without changes
|
{config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/.idea/runConfigurations/example_project_gui.xml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{config_cli_gui-0.2.7/tests → config_cli_gui-0.2.8/src/config_cli_gui/configtypes}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{config_cli_gui-0.2.7 → config_cli_gui-0.2.8}/src/config_cli_gui.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|