tilemap-editor 2.0.11__tar.gz → 3.0.0__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.
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/PKG-INFO +14 -1
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/README.md +13 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/pyproject.toml +14 -1
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/editor.py +10 -17
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/character_collision/standalone.py +4 -1
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/object_tileset_collision/editor.py +62 -16
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/object_tileset_collision/standalone.py +5 -2
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/sprite_animation/editor.py +45 -23
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/sprite_animation/models.py +10 -4
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/sprite_animation/runtime_load.py +10 -11
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/sprite_animation/standalone.py +9 -2
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/tileset_collision/collision_painter.py +3 -2
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/tileset_collision/standalone.py +4 -1
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/standalone_filemanager.py +19 -4
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/tilemap.py +78 -36
- tilemap_editor-3.0.0/src/tilemap_editor/assets/__init__.py +7 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Bold.ttf +0 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-BoldItalic.ttf +0 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Italic.ttf +0 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Regular.ttf +0 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/fonts/noto/NotoSans-Bold.ttf +0 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/fonts/noto/NotoSans-BoldItalic.ttf +0 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/fonts/noto/NotoSans-Italic.ttf +0 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/arrow-down.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/check.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/checked.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/close.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/duplicate.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/error.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/file.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/filedead.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/fit.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/folder.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/grid.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/image.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/info.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/load.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/loop.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/pan.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/pause.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/pencil.svg +2 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/play.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/plus.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/radio.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/reset.svg +2 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/save.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/stop.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/tilemap.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/tileset.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/unchecked.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/warning.svg +1 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/zoomin.svg +6 -0
- tilemap_editor-3.0.0/src/tilemap_editor/assets/icons/zoomout.svg +6 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/tilemap_editor.egg-info/PKG-INFO +14 -1
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/tilemap_editor.egg-info/SOURCES.txt +40 -0
- tilemap_editor-3.0.0/src/utils/__init__.py +11 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/utils/icon_manager.py +49 -1
- tilemap_editor-3.0.0/src/utils/project_paths.py +56 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/utils/standalone.py +7 -7
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/autotiler.py +8 -4
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/filemanager.py +274 -5
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/tile_selector.py +139 -1
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/ui/layer_type_dialog.py +2 -1
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/ui/status_bar.py +76 -23
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/ui/tileset_type_dialog.py +48 -14
- tilemap_editor-2.0.11/src/utils/__init__.py +0 -4
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/LICENSE +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/MANIFEST.in +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/fonts/jetbrain-fonts/JetBrainsMono-Bold.ttf +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/fonts/jetbrain-fonts/JetBrainsMono-BoldItalic.ttf +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/fonts/jetbrain-fonts/JetBrainsMono-Italic.ttf +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/fonts/jetbrain-fonts/JetBrainsMono-Regular.ttf +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/fonts/noto/NotoSans-Bold.ttf +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/fonts/noto/NotoSans-BoldItalic.ttf +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/fonts/noto/NotoSans-Italic.ttf +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/arrow-down.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/check.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/checked.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/close.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/duplicate.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/error.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/file.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/filedead.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/fit.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/folder.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/grid.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/image.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/info.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/load.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/loop.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/pan.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/pause.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/pencil.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/play.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/plus.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/radio.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/reset.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/save.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/stop.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/tilemap.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/tileset.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/unchecked.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/warning.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/zoomin.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/assets/icons/zoomout.svg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/setup.cfg +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/configs/themes.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/constants.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/event_map.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/layers.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/main.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/__init__.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/character_collision/__init__.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/character_collision/editor.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/character_collision/models.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/character_collision/protocols.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/character_collision/shape_editor.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/object_tileset_collision/__init__.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/object_tileset_collision/models.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/object_tileset_collision/protocols.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/sprite_animation/__init__.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/sprite_animation/__main__.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/sprite_animation/clipboard_util.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/sprite_animation/frame_picker.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/sprite_animation/preview.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/sprite_animation/protocols.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/sprite_animation/timeline.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/sprite_animation/validation.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/tileset_collision/__init__.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/tileset_collision/editor.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/tileset_collision/models.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/tileset_collision/protocols.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/standalone_automap.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/standalone_error_console.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/standalone_image_viewer.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/tilemap_editor/__init__.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/tilemap_editor/__main__.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/tilemap_editor/cli.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/tilemap_editor/main.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/tilemap_editor/settings.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/tilemap_editor.egg-info/dependency_links.txt +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/tilemap_editor.egg-info/entry_points.txt +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/tilemap_editor.egg-info/requires.txt +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/tilemap_editor.egg-info/top_level.txt +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/ttypes/__init__.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/ttypes/tilemap.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/utils/editor_preference.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/utils/error_handler.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/utils/font_manager.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/utils/history.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/utils/icons_cache.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/utils/log_capture.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/utils/serialization.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/utils/validation.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/__init__.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/automap_models.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/autotile_template.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/input.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/layer_selector.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/mapsetup.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/regex_automap_designer.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/tile_grid.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/ui/draw_utils.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/ui/fileinput.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/ui/menubar.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/ui/mode_indicator.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/ui/notification.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/ui/property_editor.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/ui/region_selector.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/ui/theme.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/ui/toolbar.py +0 -0
- {tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/widgets/ui/tooltip.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tilemap-editor
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.0
|
|
4
4
|
Summary: Pygame tilemap editor with SVG icons, professional UI, and sprite animation tools
|
|
5
5
|
Author: tilemap editor contributors
|
|
6
6
|
License: Proprietary
|
|
@@ -30,6 +30,19 @@ Dynamic: license-file
|
|
|
30
30
|
|
|
31
31
|
### Quick Start
|
|
32
32
|
|
|
33
|
+
If used for the first time do run the following commands. Afterward you can simply run wherever you want.
|
|
34
|
+
|
|
35
|
+
It is required because it initialize project settings on `settings.json`
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
tilemap-editor init
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
tilemap-editor run
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
|
|
33
46
|
```python
|
|
34
47
|
from editor import Editor
|
|
35
48
|
|
|
@@ -14,6 +14,19 @@
|
|
|
14
14
|
|
|
15
15
|
### Quick Start
|
|
16
16
|
|
|
17
|
+
If used for the first time do run the following commands. Afterward you can simply run wherever you want.
|
|
18
|
+
|
|
19
|
+
It is required because it initialize project settings on `settings.json`
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
tilemap-editor init
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
tilemap-editor run
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
|
|
17
30
|
```python
|
|
18
31
|
from editor import Editor
|
|
19
32
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tilemap-editor"
|
|
7
|
-
version = "
|
|
7
|
+
version = "3.0.0"
|
|
8
8
|
description = "Pygame tilemap editor with SVG icons, professional UI, and sprite animation tools"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -52,5 +52,18 @@ include = [
|
|
|
52
52
|
]
|
|
53
53
|
namespaces = true
|
|
54
54
|
|
|
55
|
+
[tool.setuptools.package-data]
|
|
56
|
+
"tilemap_editor.assets" = [
|
|
57
|
+
"icons/*.svg",
|
|
58
|
+
"fonts/noto/*.ttf",
|
|
59
|
+
"fonts/jetbrain-fonts/*.ttf"
|
|
60
|
+
]
|
|
61
|
+
|
|
55
62
|
[tool.setuptools.exclude-package-data]
|
|
56
63
|
"*" = ["*.spec", "*.sh"]
|
|
64
|
+
|
|
65
|
+
# Keep data-files for backward compatibility (one release cycle)
|
|
66
|
+
[tool.setuptools.data-files]
|
|
67
|
+
"share/tilemap_editor/assets/icons" = ["assets/icons/*.svg"]
|
|
68
|
+
"share/tilemap_editor/assets/fonts/noto" = ["assets/fonts/noto/*.ttf"]
|
|
69
|
+
"share/tilemap_editor/assets/fonts/jetbrain-fonts" = ["assets/fonts/jetbrain-fonts/*.ttf"]
|
|
@@ -253,13 +253,10 @@ class Editor:
|
|
|
253
253
|
]
|
|
254
254
|
|
|
255
255
|
if initial_dir:
|
|
256
|
-
|
|
257
|
-
rel_path = initial_dir.relative_to(self.base_path)
|
|
258
|
-
args.extend(["--initial-dir", str(rel_path)])
|
|
259
|
-
except ValueError:
|
|
260
|
-
args.extend(["--initial-dir", str(initial_dir)])
|
|
256
|
+
args.extend(["--initial-dir", str(initial_dir.resolve())])
|
|
261
257
|
else:
|
|
262
|
-
args.extend(["--initial-dir", str(self.
|
|
258
|
+
args.extend(["--initial-dir", str(self.data_root.resolve())])
|
|
259
|
+
args.extend(["--data-root", str(self.data_root.resolve())])
|
|
263
260
|
|
|
264
261
|
# Add allowed extensions
|
|
265
262
|
if allowed_exts:
|
|
@@ -392,7 +389,7 @@ class Editor:
|
|
|
392
389
|
if self.tilemap.active_project_path:
|
|
393
390
|
default_name = self.tilemap.active_project_path.name
|
|
394
391
|
self.open_file_manager(
|
|
395
|
-
initial_dir=self.
|
|
392
|
+
initial_dir=self.data_root,
|
|
396
393
|
allowed_exts=[".json"],
|
|
397
394
|
mode="save",
|
|
398
395
|
default_name=default_name,
|
|
@@ -414,7 +411,7 @@ class Editor:
|
|
|
414
411
|
def perform_load(self):
|
|
415
412
|
self.open_file_manager(
|
|
416
413
|
on_select=self.on_map_file_selected,
|
|
417
|
-
initial_dir=self.
|
|
414
|
+
initial_dir=self.data_root,
|
|
418
415
|
allowed_exts=[".json"],
|
|
419
416
|
)
|
|
420
417
|
|
|
@@ -595,6 +592,7 @@ class Editor:
|
|
|
595
592
|
tile_size=(32, 32), # Default tile size
|
|
596
593
|
consumer=consumer,
|
|
597
594
|
)
|
|
595
|
+
self.animation_panel._data_root = self.data_root
|
|
598
596
|
except Exception as e:
|
|
599
597
|
error_handler.capture(e, context="init_animation_panel")
|
|
600
598
|
self.notifications.notify(f"Failed to init animation panel: {e}")
|
|
@@ -650,17 +648,12 @@ class Editor:
|
|
|
650
648
|
def launch_animation_editor(self):
|
|
651
649
|
"""Launch the sprite animation editor in a new window.
|
|
652
650
|
|
|
653
|
-
|
|
654
|
-
|
|
651
|
+
Always asks for a spritesheet instead of assuming the active tileset is
|
|
652
|
+
the animation source.
|
|
655
653
|
"""
|
|
656
|
-
sheet = self._active_tileset_image_path()
|
|
657
|
-
if sheet is not None:
|
|
658
|
-
self._launch_animation_editor_with_image(sheet)
|
|
659
|
-
return
|
|
660
|
-
|
|
661
654
|
self.open_file_manager(
|
|
662
655
|
on_select=self._launch_animation_editor_with_image,
|
|
663
|
-
initial_dir=self.
|
|
656
|
+
initial_dir=self.data_root,
|
|
664
657
|
allowed_exts=[".png", ".jpg", ".jpeg"],
|
|
665
658
|
mode="open",
|
|
666
659
|
)
|
|
@@ -773,7 +766,7 @@ class Editor:
|
|
|
773
766
|
"""
|
|
774
767
|
self.open_file_manager(
|
|
775
768
|
on_select=self._launch_character_collision_editor_with_image,
|
|
776
|
-
initial_dir=self.
|
|
769
|
+
initial_dir=self.data_root,
|
|
777
770
|
allowed_exts=[".png", ".jpg", ".jpeg"],
|
|
778
771
|
mode="open",
|
|
779
772
|
)
|
{tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/character_collision/standalone.py
RENAMED
|
@@ -21,7 +21,10 @@ if str(_src_dir) not in sys.path:
|
|
|
21
21
|
|
|
22
22
|
import pygame
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
try:
|
|
25
|
+
from .editor import CharacterCollisionEditor
|
|
26
|
+
except ImportError:
|
|
27
|
+
from plugins.character_collision.editor import CharacterCollisionEditor
|
|
25
28
|
from utils import error_handler, error_context
|
|
26
29
|
|
|
27
30
|
|
{tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/object_tileset_collision/editor.py
RENAMED
|
@@ -6,8 +6,8 @@ Layout:
|
|
|
6
6
|
| [Save] [Load] | Define Regions | Paint Collision | [?] |
|
|
7
7
|
+---------------+--------------------------------+-------------+
|
|
8
8
|
| Regions List | Collision Painter (Region) | StatusBar |
|
|
9
|
-
| - Tree (
|
|
10
|
-
| - Rock (
|
|
9
|
+
| - Tree (ok) | | |
|
|
10
|
+
| - Rock (warn) | [Region image, zoomed] | 3 shapes |
|
|
11
11
|
| - Player (?)| | Complete |
|
|
12
12
|
+---------------+--------------------------------+-------------+
|
|
13
13
|
| Object Tileset (Region Selector) |
|
|
@@ -59,6 +59,36 @@ class RegionStatus:
|
|
|
59
59
|
is_valid: bool = True
|
|
60
60
|
|
|
61
61
|
|
|
62
|
+
def _render_fit_text(
|
|
63
|
+
font: pygame.font.Font,
|
|
64
|
+
text: str,
|
|
65
|
+
color: Tuple[int, int, int],
|
|
66
|
+
max_width: int,
|
|
67
|
+
) -> Surface:
|
|
68
|
+
"""Render text constrained to max_width with an ellipsis."""
|
|
69
|
+
if max_width <= 0:
|
|
70
|
+
return font.render("", True, color)
|
|
71
|
+
|
|
72
|
+
surf = font.render(text, True, color)
|
|
73
|
+
if surf.get_width() <= max_width:
|
|
74
|
+
return surf
|
|
75
|
+
|
|
76
|
+
ellipsis = "..."
|
|
77
|
+
if font.size(ellipsis)[0] > max_width:
|
|
78
|
+
return font.render("", True, color)
|
|
79
|
+
|
|
80
|
+
low, high = 0, len(text)
|
|
81
|
+
while low < high:
|
|
82
|
+
mid = (low + high + 1) // 2
|
|
83
|
+
candidate = text[:mid].rstrip() + ellipsis
|
|
84
|
+
if font.size(candidate)[0] <= max_width:
|
|
85
|
+
low = mid
|
|
86
|
+
else:
|
|
87
|
+
high = mid - 1
|
|
88
|
+
|
|
89
|
+
return font.render(text[:low].rstrip() + ellipsis, True, color)
|
|
90
|
+
|
|
91
|
+
|
|
62
92
|
class ObjectTilesetCollisionEditor:
|
|
63
93
|
"""
|
|
64
94
|
Main editor for object tileset collision shapes.
|
|
@@ -610,8 +640,8 @@ class ObjectTilesetCollisionEditor:
|
|
|
610
640
|
# Close button
|
|
611
641
|
close_btn = Rect(panel_rect.right - 35, panel_y + 10, 25, 25)
|
|
612
642
|
pygame.draw.rect(screen, COLORS.danger, close_btn, border_radius=SHAPE.radius_sm)
|
|
613
|
-
|
|
614
|
-
screen.blit(
|
|
643
|
+
close_icon = icon_manager.get_icon("close", 15, COLORS.text)
|
|
644
|
+
screen.blit(close_icon, close_icon.get_rect(center=close_btn.center))
|
|
615
645
|
|
|
616
646
|
# Content
|
|
617
647
|
help_text = [
|
|
@@ -642,8 +672,8 @@ class ObjectTilesetCollisionEditor:
|
|
|
642
672
|
(" • Middle mouse drag: Pan (always works)", False),
|
|
643
673
|
("", False),
|
|
644
674
|
("Status Icons:", True),
|
|
645
|
-
("
|
|
646
|
-
("
|
|
675
|
+
(" Check icon = Has collision shapes", False),
|
|
676
|
+
(" Warning icon = No collision defined yet", False),
|
|
647
677
|
(" ? = Unnamed region", False),
|
|
648
678
|
("", False),
|
|
649
679
|
("Shortcuts:", True),
|
|
@@ -900,11 +930,6 @@ class ObjectTilesetCollisionEditor:
|
|
|
900
930
|
load_label = self._font.render("Load", True, COLORS.text)
|
|
901
931
|
draw_button(screen, load_btn_rect, load_label, hover=load_hover)
|
|
902
932
|
|
|
903
|
-
# Title (centered, after mode indicator)
|
|
904
|
-
title = self._font.render(f"— {self._tileset_name}", True, COLORS.text_dim)
|
|
905
|
-
title_x = self.mode_indicator.rect.right + 20
|
|
906
|
-
screen.blit(title, (title_x, self.toolbar_rect.centery - title.get_height() // 2))
|
|
907
|
-
|
|
908
933
|
# Help button (info icon)
|
|
909
934
|
help_btn_rect = Rect(self.toolbar_rect.right - 38, self.toolbar_rect.y + 8, 28, 28)
|
|
910
935
|
help_hover = help_btn_rect.collidepoint(mouse)
|
|
@@ -913,6 +938,17 @@ class ObjectTilesetCollisionEditor:
|
|
|
913
938
|
pygame.draw.rect(screen, COLORS.border_soft, help_btn_rect, 1, border_radius=SHAPE.radius_sm)
|
|
914
939
|
screen.blit(help_icon, (help_btn_rect.centerx - 10, help_btn_rect.centery - 10))
|
|
915
940
|
|
|
941
|
+
# Title after mode indicator, clipped before the help button.
|
|
942
|
+
title_x = self.mode_indicator.rect.right + 20
|
|
943
|
+
title_max_w = help_btn_rect.x - title_x - 10
|
|
944
|
+
title = _render_fit_text(
|
|
945
|
+
self._font,
|
|
946
|
+
f"- {self._tileset_name}",
|
|
947
|
+
COLORS.text_dim,
|
|
948
|
+
title_max_w,
|
|
949
|
+
)
|
|
950
|
+
screen.blit(title, (title_x, self.toolbar_rect.centery - title.get_height() // 2))
|
|
951
|
+
|
|
916
952
|
def _draw_regions_list(self, screen: Surface) -> None:
|
|
917
953
|
"""Draw the regions list panel"""
|
|
918
954
|
draw_panel(screen, self.regions_list_rect, COLORS.panel, COLORS.border)
|
|
@@ -950,9 +986,9 @@ class ObjectTilesetCollisionEditor:
|
|
|
950
986
|
icon_y = item_rect.centery - 6
|
|
951
987
|
|
|
952
988
|
if status.has_collision:
|
|
953
|
-
icon =
|
|
989
|
+
icon = icon_manager.get_icon("check", 12, COLORS.success)
|
|
954
990
|
elif region.name and not region.name.startswith("Region "):
|
|
955
|
-
icon =
|
|
991
|
+
icon = icon_manager.get_icon("warning", 12, COLORS.warning)
|
|
956
992
|
else:
|
|
957
993
|
icon = self._font_sm.render("?", True, COLORS.text_dim)
|
|
958
994
|
|
|
@@ -974,10 +1010,20 @@ class ObjectTilesetCollisionEditor:
|
|
|
974
1010
|
pygame.draw.rect(screen, (100, 120, 140),
|
|
975
1011
|
Rect(name_x, item_rect.y + 5, item_rect.width - 30, 20), border_radius=2)
|
|
976
1012
|
|
|
977
|
-
name_surf =
|
|
1013
|
+
name_surf = _render_fit_text(
|
|
1014
|
+
self._font,
|
|
1015
|
+
display_name,
|
|
1016
|
+
COLORS.text,
|
|
1017
|
+
item_rect.right - name_x - 8,
|
|
1018
|
+
)
|
|
978
1019
|
else:
|
|
979
1020
|
name = region.name or "Unnamed"
|
|
980
|
-
name_surf =
|
|
1021
|
+
name_surf = _render_fit_text(
|
|
1022
|
+
self._font,
|
|
1023
|
+
name,
|
|
1024
|
+
COLORS.text,
|
|
1025
|
+
item_rect.right - name_x - 8,
|
|
1026
|
+
)
|
|
981
1027
|
|
|
982
1028
|
screen.blit(name_surf, (name_x, item_rect.y + 8))
|
|
983
1029
|
|
|
@@ -1080,4 +1126,4 @@ class ObjectTilesetCollisionEditor:
|
|
|
1080
1126
|
screen.fill((20, 20, 20))
|
|
1081
1127
|
self.draw(screen)
|
|
1082
1128
|
pygame.display.flip()
|
|
1083
|
-
clock.tick(60)
|
|
1129
|
+
clock.tick(60)
|
{tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/object_tileset_collision/standalone.py
RENAMED
|
@@ -22,7 +22,10 @@ if sys.platform == "darwin":
|
|
|
22
22
|
|
|
23
23
|
import pygame
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
try:
|
|
26
|
+
from .editor import ObjectTilesetCollisionEditor
|
|
27
|
+
except ImportError:
|
|
28
|
+
from plugins.object_tileset_collision.editor import ObjectTilesetCollisionEditor
|
|
26
29
|
from utils import error_handler, error_context
|
|
27
30
|
|
|
28
31
|
|
|
@@ -94,4 +97,4 @@ def main(argv: list[str] | None = None) -> None:
|
|
|
94
97
|
|
|
95
98
|
|
|
96
99
|
if __name__ == "__main__":
|
|
97
|
-
main()
|
|
100
|
+
main()
|
|
@@ -22,6 +22,7 @@ import pygame
|
|
|
22
22
|
from pygame import Rect, Surface, Color
|
|
23
23
|
from utils.font_manager import font_manager, FontWeight, FontStyle
|
|
24
24
|
from utils.icon_manager import icon_manager
|
|
25
|
+
from utils.project_paths import resolve_project_path
|
|
25
26
|
from utils import error_handler
|
|
26
27
|
from .clipboard_util import copy_plain_text
|
|
27
28
|
from .frame_picker import FramePicker
|
|
@@ -103,7 +104,7 @@ class SpriteAnimationEditor:
|
|
|
103
104
|
Layout::
|
|
104
105
|
|
|
105
106
|
+----------------------------------------------------+
|
|
106
|
-
| Toolbar: [idle
|
|
107
|
+
| Toolbar: [idle] [+] [X] | [Save] [Load] |
|
|
107
108
|
+---------------+------------------------------------+
|
|
108
109
|
| Preview | Spritesheet Frame Picker |
|
|
109
110
|
| (220px w) | (pan/zoom, click to add) |
|
|
@@ -242,6 +243,7 @@ class SpriteAnimationEditor:
|
|
|
242
243
|
|
|
243
244
|
# Track the last saved path for quick save (Ctrl+S)
|
|
244
245
|
self._last_saved_path: Optional[Path] = None
|
|
246
|
+
self._data_root: Optional[Path] = Path.cwd() / "data"
|
|
245
247
|
|
|
246
248
|
# Sync sub-widgets
|
|
247
249
|
self._sync_active_animation()
|
|
@@ -867,7 +869,7 @@ class SpriteAnimationEditor:
|
|
|
867
869
|
self._draw_toolbar_btn(screen, self._btn_new, "+", mouse)
|
|
868
870
|
x += 32
|
|
869
871
|
|
|
870
|
-
#
|
|
872
|
+
# Delete
|
|
871
873
|
self._btn_del = Rect(x, cy, 28, bh)
|
|
872
874
|
# Close/X icon for delete
|
|
873
875
|
close_icon = icon_manager.get_icon("close", 14, _COLORS["btn_danger_hover"])
|
|
@@ -1174,7 +1176,7 @@ class SpriteAnimationEditor:
|
|
|
1174
1176
|
if self._info_tooltip_pinned:
|
|
1175
1177
|
lines.append("Esc or click outside card to close")
|
|
1176
1178
|
else:
|
|
1177
|
-
lines.append("Click
|
|
1179
|
+
lines.append("Click info to pin this panel")
|
|
1178
1180
|
|
|
1179
1181
|
padding = 8
|
|
1180
1182
|
line_height = 16
|
|
@@ -1674,8 +1676,8 @@ class SpriteAnimationEditor:
|
|
|
1674
1676
|
|
|
1675
1677
|
pygame.draw.rect(screen, _COLORS["btn_danger"], del_rect, border_radius=3)
|
|
1676
1678
|
pygame.draw.rect(screen, _COLORS["border"], del_rect, 1, border_radius=3)
|
|
1677
|
-
|
|
1678
|
-
screen.blit(
|
|
1679
|
+
close_icon = icon_manager.get_icon("close", 12, _COLORS["text"])
|
|
1680
|
+
screen.blit(close_icon, close_icon.get_rect(center=del_rect.center))
|
|
1679
1681
|
|
|
1680
1682
|
row_y += META_ROW_H
|
|
1681
1683
|
|
|
@@ -1802,13 +1804,12 @@ class SpriteAnimationEditor:
|
|
|
1802
1804
|
# Import FileManager
|
|
1803
1805
|
try:
|
|
1804
1806
|
from widgets.filemanager import FileManager
|
|
1805
|
-
from constants import BASE_PATH
|
|
1806
1807
|
except ImportError as e:
|
|
1807
1808
|
# Fallback to old behavior if FileManager not available
|
|
1808
1809
|
print(f"Warning: Could not import FileManager: {e}")
|
|
1809
1810
|
path = self._default_save_path()
|
|
1810
1811
|
try:
|
|
1811
|
-
self.library.save(path)
|
|
1812
|
+
self.library.save(path, base_path=self._project_base_path())
|
|
1812
1813
|
self._last_saved_path = path
|
|
1813
1814
|
print(f"Animations saved to {path}")
|
|
1814
1815
|
except Exception as e:
|
|
@@ -1821,12 +1822,12 @@ class SpriteAnimationEditor:
|
|
|
1821
1822
|
initial_dir = self._last_saved_path.parent
|
|
1822
1823
|
default_name = self._last_saved_path.name
|
|
1823
1824
|
elif self.library.spritesheet_path:
|
|
1824
|
-
|
|
1825
|
-
initial_dir = Path(self.library.spritesheet_path).parent
|
|
1825
|
+
initial_dir = self._data_root / "animations"
|
|
1826
1826
|
default_name = Path(self.library.spritesheet_path).stem + ".anim.json"
|
|
1827
1827
|
else:
|
|
1828
1828
|
initial_dir = self._data_root / "animations"
|
|
1829
1829
|
default_name = "animations.anim.json"
|
|
1830
|
+
initial_dir.mkdir(parents=True, exist_ok=True)
|
|
1830
1831
|
|
|
1831
1832
|
# Create file manager for save
|
|
1832
1833
|
screen = pygame.display.get_surface()
|
|
@@ -1842,6 +1843,7 @@ class SpriteAnimationEditor:
|
|
|
1842
1843
|
mode="save",
|
|
1843
1844
|
default_name=default_name,
|
|
1844
1845
|
on_cancel=self._close_file_manager,
|
|
1846
|
+
data_root=self._data_root,
|
|
1845
1847
|
)
|
|
1846
1848
|
|
|
1847
1849
|
def _quick_save(self) -> None:
|
|
@@ -1852,7 +1854,10 @@ class SpriteAnimationEditor:
|
|
|
1852
1854
|
if self._last_saved_path:
|
|
1853
1855
|
# Save to existing path
|
|
1854
1856
|
try:
|
|
1855
|
-
self.library.save(
|
|
1857
|
+
self.library.save(
|
|
1858
|
+
self._last_saved_path,
|
|
1859
|
+
base_path=self._project_base_path(),
|
|
1860
|
+
)
|
|
1856
1861
|
print(f"Animations saved to {self._last_saved_path}")
|
|
1857
1862
|
except Exception as e:
|
|
1858
1863
|
error_handler.capture(e, context="save_animations_quick")
|
|
@@ -1867,13 +1872,13 @@ class SpriteAnimationEditor:
|
|
|
1867
1872
|
# Import FileManager
|
|
1868
1873
|
try:
|
|
1869
1874
|
from widgets.filemanager import FileManager
|
|
1870
|
-
from constants import BASE_PATH
|
|
1871
1875
|
except ImportError:
|
|
1872
1876
|
# Fallback to old behavior if FileManager not available
|
|
1873
1877
|
path = self._default_save_path()
|
|
1874
1878
|
if path.exists():
|
|
1875
1879
|
try:
|
|
1876
1880
|
self.library = AnimationLibrary.load(path)
|
|
1881
|
+
self._resolve_library_paths(path)
|
|
1877
1882
|
names = self.library.animation_names()
|
|
1878
1883
|
self._active_anim_name = names[0] if names else None
|
|
1879
1884
|
if not names:
|
|
@@ -1886,11 +1891,9 @@ class SpriteAnimationEditor:
|
|
|
1886
1891
|
print(f"No animation file found at {path}")
|
|
1887
1892
|
return
|
|
1888
1893
|
|
|
1889
|
-
#
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
else:
|
|
1893
|
-
initial_dir = self._data_root / "animations"
|
|
1894
|
+
# Load project animation files from the configured data folder.
|
|
1895
|
+
initial_dir = self._data_root / "animations"
|
|
1896
|
+
initial_dir.mkdir(parents=True, exist_ok=True)
|
|
1894
1897
|
|
|
1895
1898
|
# Create file manager for load
|
|
1896
1899
|
screen = pygame.display.get_surface()
|
|
@@ -1905,12 +1908,13 @@ class SpriteAnimationEditor:
|
|
|
1905
1908
|
on_select=self._on_load_file_selected,
|
|
1906
1909
|
mode="open",
|
|
1907
1910
|
on_cancel=self._close_file_manager,
|
|
1911
|
+
data_root=self._data_root,
|
|
1908
1912
|
)
|
|
1909
1913
|
|
|
1910
1914
|
def _on_save_file_selected(self, path: Path) -> None:
|
|
1911
1915
|
"""Callback when user selects a file to save to."""
|
|
1912
1916
|
try:
|
|
1913
|
-
self.library.save(path)
|
|
1917
|
+
self.library.save(path, base_path=self._project_base_path())
|
|
1914
1918
|
self._last_saved_path = path # Track for quick save
|
|
1915
1919
|
print(f"Animations saved to {path}")
|
|
1916
1920
|
except Exception as e:
|
|
@@ -1928,6 +1932,7 @@ class SpriteAnimationEditor:
|
|
|
1928
1932
|
if path.exists():
|
|
1929
1933
|
try:
|
|
1930
1934
|
self.library = AnimationLibrary.load(path)
|
|
1935
|
+
self._resolve_library_paths(path)
|
|
1931
1936
|
self._last_saved_path = path # Track loaded file as save location
|
|
1932
1937
|
names = self.library.animation_names()
|
|
1933
1938
|
self._active_anim_name = names[0] if names else None
|
|
@@ -1952,16 +1957,12 @@ class SpriteAnimationEditor:
|
|
|
1952
1957
|
# Import FileManager
|
|
1953
1958
|
try:
|
|
1954
1959
|
from widgets.filemanager import FileManager
|
|
1955
|
-
from constants import BASE_PATH
|
|
1956
1960
|
except ImportError as e:
|
|
1957
1961
|
print(f"Warning: Could not import FileManager: {e}")
|
|
1958
1962
|
return
|
|
1959
1963
|
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
initial_dir = Path(self.library.spritesheet_path).parent
|
|
1963
|
-
else:
|
|
1964
|
-
initial_dir = self._data_root / "animations"
|
|
1964
|
+
initial_dir = self._data_root
|
|
1965
|
+
initial_dir.mkdir(parents=True, exist_ok=True)
|
|
1965
1966
|
|
|
1966
1967
|
# Create file manager for loading spritesheet
|
|
1967
1968
|
screen = cast(Surface, pygame.display.get_surface())
|
|
@@ -1976,6 +1977,7 @@ class SpriteAnimationEditor:
|
|
|
1976
1977
|
on_select=self._on_spritesheet_selected,
|
|
1977
1978
|
mode="open",
|
|
1978
1979
|
on_cancel=self._close_file_manager,
|
|
1980
|
+
data_root=self._data_root,
|
|
1979
1981
|
)
|
|
1980
1982
|
|
|
1981
1983
|
def _on_spritesheet_selected(self, path: Union[Path, List[Path]]) -> None:
|
|
@@ -2022,6 +2024,26 @@ class SpriteAnimationEditor:
|
|
|
2022
2024
|
return Path(self.library.spritesheet_path).parent / f"{base}.anim.json"
|
|
2023
2025
|
return Path.cwd() / "animations.anim.json"
|
|
2024
2026
|
|
|
2027
|
+
def _project_base_path(self) -> Optional[Path]:
|
|
2028
|
+
if self._data_root is None:
|
|
2029
|
+
return None
|
|
2030
|
+
return Path(self._data_root).parent
|
|
2031
|
+
|
|
2032
|
+
def _resolve_library_paths(self, json_path: Path) -> None:
|
|
2033
|
+
if not self.library.spritesheet_path:
|
|
2034
|
+
return
|
|
2035
|
+
base_path = self._project_base_path()
|
|
2036
|
+
if base_path is None:
|
|
2037
|
+
return
|
|
2038
|
+
self.library.spritesheet_path = str(
|
|
2039
|
+
resolve_project_path(
|
|
2040
|
+
self.library.spritesheet_path,
|
|
2041
|
+
base_path,
|
|
2042
|
+
fallback_roots=[json_path.parent],
|
|
2043
|
+
must_exist=True,
|
|
2044
|
+
)
|
|
2045
|
+
)
|
|
2046
|
+
|
|
2025
2047
|
# ------------------------------------------------------------------
|
|
2026
2048
|
# Integration helpers
|
|
2027
2049
|
# ------------------------------------------------------------------
|
|
@@ -12,6 +12,8 @@ from dataclasses import dataclass, field
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from typing import Any, Dict, List, Optional, Tuple
|
|
14
14
|
|
|
15
|
+
from utils.project_paths import to_project_path
|
|
16
|
+
|
|
15
17
|
|
|
16
18
|
@dataclass
|
|
17
19
|
class AnimationMarker:
|
|
@@ -189,9 +191,13 @@ class AnimationLibrary:
|
|
|
189
191
|
def animation_names(self) -> List[str]:
|
|
190
192
|
return list(self.animations.keys())
|
|
191
193
|
|
|
192
|
-
def to_dict(self) -> dict:
|
|
194
|
+
def to_dict(self, *, base_path: Optional[Path] = None) -> dict:
|
|
195
|
+
spritesheet_path = self.spritesheet_path
|
|
196
|
+
if spritesheet_path and base_path is not None:
|
|
197
|
+
spritesheet_path = to_project_path(spritesheet_path, base_path)
|
|
198
|
+
|
|
193
199
|
return {
|
|
194
|
-
"spritesheet_path":
|
|
200
|
+
"spritesheet_path": spritesheet_path,
|
|
195
201
|
"tile_size": list(self.tile_size),
|
|
196
202
|
"animations": {
|
|
197
203
|
name: anim.to_dict() for name, anim in self.animations.items()
|
|
@@ -208,10 +214,10 @@ class AnimationLibrary:
|
|
|
208
214
|
lib.animations[name] = Animation.from_dict(anim_data)
|
|
209
215
|
return lib
|
|
210
216
|
|
|
211
|
-
def save(self, path: Path) -> None:
|
|
217
|
+
def save(self, path: Path, *, base_path: Optional[Path] = None) -> None:
|
|
212
218
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
213
219
|
with open(path, "w", encoding="utf-8") as f:
|
|
214
|
-
json.dump(self.to_dict(), f, indent=2)
|
|
220
|
+
json.dump(self.to_dict(base_path=base_path), f, indent=2)
|
|
215
221
|
|
|
216
222
|
@staticmethod
|
|
217
223
|
def load(path: Path) -> AnimationLibrary:
|
|
@@ -198,17 +198,16 @@ class SpriteAnimRuntime:
|
|
|
198
198
|
|
|
199
199
|
img_path = Path(sheet_ref)
|
|
200
200
|
if not img_path.is_absolute():
|
|
201
|
-
|
|
202
|
-
if
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
img_path =
|
|
210
|
-
|
|
211
|
-
img_path = cand
|
|
201
|
+
candidates = [(p.parent / img_path).resolve()]
|
|
202
|
+
if extra_search_base is not None:
|
|
203
|
+
candidates.append((Path(extra_search_base) / sheet_ref).resolve())
|
|
204
|
+
candidates.extend((parent / img_path).resolve() for parent in p.parents)
|
|
205
|
+
|
|
206
|
+
img_path = candidates[0]
|
|
207
|
+
for candidate in candidates:
|
|
208
|
+
if candidate.is_file():
|
|
209
|
+
img_path = candidate
|
|
210
|
+
break
|
|
212
211
|
|
|
213
212
|
if not img_path.is_file():
|
|
214
213
|
raise AnimationParseError(f"Spritesheet not found: {sheet_ref!r} (tried {img_path})")
|
|
@@ -22,7 +22,10 @@ if str(_src_dir) not in sys.path:
|
|
|
22
22
|
|
|
23
23
|
import pygame
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
try:
|
|
26
|
+
from .editor import SpriteAnimationEditor
|
|
27
|
+
except ImportError:
|
|
28
|
+
from plugins.sprite_animation.editor import SpriteAnimationEditor
|
|
26
29
|
from utils import error_handler, error_context
|
|
27
30
|
|
|
28
31
|
|
|
@@ -106,10 +109,14 @@ def main(argv: list[str] | None = None) -> None:
|
|
|
106
109
|
)
|
|
107
110
|
|
|
108
111
|
if args.load and args.load.exists():
|
|
109
|
-
|
|
112
|
+
try:
|
|
113
|
+
from .models import AnimationLibrary
|
|
114
|
+
except ImportError:
|
|
115
|
+
from plugins.sprite_animation.models import AnimationLibrary
|
|
110
116
|
|
|
111
117
|
lib = AnimationLibrary.load(args.load)
|
|
112
118
|
editor.load_animation_data(lib.to_dict())
|
|
119
|
+
editor._resolve_library_paths(args.load)
|
|
113
120
|
print(f"Loaded animations from {args.load}")
|
|
114
121
|
|
|
115
122
|
editor.run()
|
{tilemap_editor-2.0.11 → tilemap_editor-3.0.0}/src/plugins/tileset_collision/collision_painter.py
RENAMED
|
@@ -20,6 +20,7 @@ from enum import Enum
|
|
|
20
20
|
import pygame
|
|
21
21
|
from pygame import Rect
|
|
22
22
|
from utils.font_manager import font_manager, FontWeight
|
|
23
|
+
from utils.icon_manager import icon_manager
|
|
23
24
|
from utils.error_handler import error_handler, error_context
|
|
24
25
|
|
|
25
26
|
|
|
@@ -718,8 +719,8 @@ class CollisionPainter:
|
|
|
718
719
|
close_bg = _COLORS["polygon_stroke"] if close_hover else _COLORS["bg"]
|
|
719
720
|
pygame.draw.rect(screen, close_bg, close_btn)
|
|
720
721
|
pygame.draw.rect(screen, _COLORS["border"], close_btn, 1)
|
|
721
|
-
|
|
722
|
-
screen.blit(
|
|
722
|
+
close_icon = icon_manager.get_icon("close", 14, _COLORS["text"])
|
|
723
|
+
screen.blit(close_icon, close_icon.get_rect(center=close_btn.center))
|
|
723
724
|
|
|
724
725
|
# Divider
|
|
725
726
|
pygame.draw.line(
|
|
@@ -26,7 +26,10 @@ if sys.platform == "darwin":
|
|
|
26
26
|
|
|
27
27
|
import pygame
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
try:
|
|
30
|
+
from .editor import TilesetCollisionEditor
|
|
31
|
+
except ImportError:
|
|
32
|
+
from plugins.tileset_collision.editor import TilesetCollisionEditor
|
|
30
33
|
from utils import error_handler, error_context
|
|
31
34
|
|
|
32
35
|
|