tilemap-editor 4.1.0__tar.gz → 4.3.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-4.1.0/src/tilemap_editor.egg-info → tilemap_editor-4.3.0}/PKG-INFO +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/pyproject.toml +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/editor.py +23 -23
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/layers.py +45 -39
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap.py +32 -6
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/ToolMove.svg +1 -1
- tilemap_editor-4.3.0/src/tilemap_editor/assets/icons/checked.svg +1 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/duplicate.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/error.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/file.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/filedead.svg +1 -1
- tilemap_editor-4.3.0/src/tilemap_editor/assets/icons/fit.svg +1 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/folder.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/grid.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/image.svg +1 -1
- tilemap_editor-4.3.0/src/tilemap_editor/assets/icons/info.svg +1 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/load.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/loop.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/pan.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/pause.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/pencil.svg +2 -2
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/play.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/plus.svg +1 -1
- tilemap_editor-4.3.0/src/tilemap_editor/assets/icons/radio.svg +1 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/reset.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/save.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/stop.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/tilemap.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/tileset.svg +1 -1
- tilemap_editor-4.3.0/src/tilemap_editor/assets/icons/unchecked.svg +1 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/warning.svg +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/zoomin.svg +5 -5
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/zoomout.svg +5 -5
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/cli.py +6 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0/src/tilemap_editor.egg-info}/PKG-INFO +1 -1
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor.egg-info/SOURCES.txt +5 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/ttypes/tilemap.py +6 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/utils/icon_manager.py +51 -4
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/autotiler.py +13 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/tile_grid.py +275 -220
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/button.py +27 -3
- tilemap_editor-4.3.0/src/widgets/ui/drag_tracker.py +62 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/theme.py +57 -8
- tilemap_editor-4.3.0/src/widgets/ui/tool_manager.py +50 -0
- tilemap_editor-4.3.0/src/widgets/ui/toolbar.py +146 -0
- tilemap_editor-4.3.0/tests/test_drag_tracker.py +77 -0
- tilemap_editor-4.3.0/tests/test_gid_collision.py +43 -0
- tilemap_editor-4.3.0/tests/test_layers_autotile.py +1021 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/tests/test_toolbar_tools.py +50 -46
- tilemap_editor-4.1.0/src/tilemap_editor/assets/icons/checked.svg +0 -1
- tilemap_editor-4.1.0/src/tilemap_editor/assets/icons/fit.svg +0 -1
- tilemap_editor-4.1.0/src/tilemap_editor/assets/icons/info.svg +0 -1
- tilemap_editor-4.1.0/src/tilemap_editor/assets/icons/radio.svg +0 -1
- tilemap_editor-4.1.0/src/tilemap_editor/assets/icons/unchecked.svg +0 -1
- tilemap_editor-4.1.0/src/widgets/ui/toolbar.py +0 -164
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/LICENSE +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/MANIFEST.in +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/README.md +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/fonts/jetbrain-fonts/JetBrainsMono-Bold.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/fonts/jetbrain-fonts/JetBrainsMono-BoldItalic.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/fonts/jetbrain-fonts/JetBrainsMono-Italic.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/fonts/jetbrain-fonts/JetBrainsMono-Regular.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/fonts/noto/NotoSans-Bold.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/fonts/noto/NotoSans-BoldItalic.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/fonts/noto/NotoSans-Italic.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/arrow-down.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/check.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/checked.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/close.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/duplicate.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/error.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/file.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/filedead.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/fit.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/folder.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/grid.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/image.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/info.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/load.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/loop.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/onion.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/pan.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/pause.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/pencil.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/play.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/plus.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/radio.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/reset.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/save.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/skip-back.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/skip-forward.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/stop.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/tilemap.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/tileset.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/unchecked.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/warning.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/zoomin.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/assets/icons/zoomout.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/setup.cfg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/configs/themes.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/constants.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/event_map.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/main.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/node_manager.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/nodes.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/__init__.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/character_collision/__init__.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/character_collision/editor.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/character_collision/models.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/character_collision/protocols.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/character_collision/shape_editor.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/character_collision/standalone.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/object_tileset_collision/__init__.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/object_tileset_collision/editor.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/object_tileset_collision/models.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/object_tileset_collision/protocols.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/object_tileset_collision/standalone.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_animation/__init__.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_animation/__main__.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_animation/clipboard_util.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_animation/editor.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_animation/frame_picker.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_animation/models.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_animation/preview.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_animation/protocols.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_animation/runtime_load.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_animation/standalone.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_animation/timeline.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_animation/validation.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_editor/__init__.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_editor/editor.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/sprite_editor/standalone.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/tileset_collision/__init__.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/tileset_collision/collision_painter.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/tileset_collision/editor.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/tileset_collision/models.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/tileset_collision/protocols.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/plugins/tileset_collision/standalone.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/standalone_automap.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/standalone_error_console.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/standalone_filemanager.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/standalone_image_viewer.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/__init__.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/__main__.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/__init__.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Bold.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-BoldItalic.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Italic.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Regular.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/fonts/noto/NotoSans-Bold.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/fonts/noto/NotoSans-BoldItalic.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/fonts/noto/NotoSans-Italic.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/arrow-down.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/check.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/close.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/onion.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/skip-back.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/assets/icons/skip-forward.svg +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/main.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor/settings.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor.egg-info/dependency_links.txt +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor.egg-info/entry_points.txt +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor.egg-info/requires.txt +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/tilemap_editor.egg-info/top_level.txt +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/ttypes/__init__.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/utils/__init__.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/utils/editor_preference.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/utils/error_handler.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/utils/font_manager.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/utils/history.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/utils/icons_cache.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/utils/log_capture.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/utils/project_paths.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/utils/serialization.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/utils/standalone.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/utils/validation.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/__init__.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/automap_models.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/autotile_template.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/filemanager.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/input.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/layer_selector.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/map_properties.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/mapsetup.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/particle_presets.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/particle_system.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/regex_automap_designer.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/spritesheet_grid.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/tile_selector.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/checkbox.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/collision_layer_mask.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/collision_layer_sidebar.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/confirm_dialog.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/dialog_base.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/draw_utils.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/fileinput.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/label.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/layer_type_dialog.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/menubar.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/mode_indicator.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/node_editor.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/node_selector.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/notification.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/particle_config_dialog.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/property_editor.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/region_selector.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/scrollbar.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/sidebar_container.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/status_bar.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/tileset_type_dialog.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/ui/tooltip.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/src/widgets/widget_base.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/tests/test_animation_library_grid_offset.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/tests/test_collision_layer_mask.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/tests/test_collision_layer_sidebar.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/tests/test_editor_pan_mode.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/tests/test_project_paths.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/tests/test_render_scale.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/tests/test_serialization_regression.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/tests/test_sprite_animation_editor_grid.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/tests/test_tile_grid_selection.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/tests/test_tile_selector_pick.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/tests/test_tilemap_save.py +0 -0
- {tilemap_editor-4.1.0 → tilemap_editor-4.3.0}/tests/test_timeline_invalidate_cache.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tilemap-editor"
|
|
7
|
-
version = "4.
|
|
7
|
+
version = "4.3.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"
|
|
@@ -40,6 +40,7 @@ from widgets.ui.particle_config_dialog import ParticleConfigDialog
|
|
|
40
40
|
from widgets.ui.property_editor import PropertyEditor
|
|
41
41
|
from widgets.ui.sidebar_container import SidebarContainer, ToolbarAction
|
|
42
42
|
from widgets.ui.theme import COLORS, THEMES, get_theme_manager, set_theme
|
|
43
|
+
from widgets.ui.tool_manager import ToolKind, ToolManager
|
|
43
44
|
from widgets.ui.tileset_type_dialog import TilesetTypeDialog
|
|
44
45
|
from widgets.ui.toolbar import Toolbar
|
|
45
46
|
from widgets.ui.tooltip import TooltipManager
|
|
@@ -138,27 +139,31 @@ _launch_standalone_module = launch_standalone
|
|
|
138
139
|
|
|
139
140
|
|
|
140
141
|
class Editor:
|
|
141
|
-
def __init__(
|
|
142
|
+
def __init__(
|
|
143
|
+
self,
|
|
144
|
+
size: Optional[Tuple[int, int]] = None,
|
|
145
|
+
fps=60,
|
|
146
|
+
theme: Optional[str] = None,
|
|
147
|
+
):
|
|
142
148
|
self.base_path, self.data_root, self.config = _load_project_config()
|
|
143
149
|
logger.info(f"Project base_path: {self.base_path}")
|
|
144
150
|
logger.info(f"Data root: {self.data_root}")
|
|
145
151
|
|
|
146
|
-
theme_name = self.config.get("theme", "dark")
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
logger.
|
|
152
|
+
theme_name = theme or self.config.get("theme", "dark")
|
|
153
|
+
tm = get_theme_manager()
|
|
154
|
+
if not tm.set_theme(theme_name):
|
|
155
|
+
logger.warning(f"Theme '{theme_name}' not found, falling back to dark")
|
|
156
|
+
tm.set_theme("dark")
|
|
150
157
|
|
|
151
158
|
pygame.init()
|
|
152
159
|
pygame.display.set_caption("Pure Pygame Editor")
|
|
153
160
|
|
|
154
161
|
self.fps = fps
|
|
155
162
|
self.running = False
|
|
156
|
-
self.pan_mode = False
|
|
157
163
|
self.autotile_mode = False
|
|
158
|
-
self.eraser_mode = False
|
|
159
|
-
self.select_mode = False
|
|
160
164
|
self.node_editing_mode = False
|
|
161
165
|
self.show_nodes = False
|
|
166
|
+
self.tool_manager = ToolManager()
|
|
162
167
|
self._prev_tool = None
|
|
163
168
|
|
|
164
169
|
if isinstance(size, tuple) and len(size) == 2:
|
|
@@ -712,6 +717,8 @@ class Editor:
|
|
|
712
717
|
next_idx = (current_idx + 1) % len(theme_names)
|
|
713
718
|
new_theme = theme_names[next_idx]
|
|
714
719
|
set_theme(new_theme)
|
|
720
|
+
from utils.icon_manager import icon_manager
|
|
721
|
+
icon_manager.clear_cache()
|
|
715
722
|
self.notifications.notify(f"Theme: {new_theme}")
|
|
716
723
|
|
|
717
724
|
settings_file = Path.cwd() / "settings.json"
|
|
@@ -1199,9 +1206,7 @@ class Editor:
|
|
|
1199
1206
|
self.node_editing_mode = not self.node_editing_mode
|
|
1200
1207
|
if self.node_editing_mode:
|
|
1201
1208
|
self.show_nodes = False
|
|
1202
|
-
self.
|
|
1203
|
-
self.select_mode = False
|
|
1204
|
-
self.eraser_mode = False
|
|
1209
|
+
self.tool_manager.deactivate()
|
|
1205
1210
|
continue
|
|
1206
1211
|
elif event.key == pygame.K_n and (ctrl_held or meta_held):
|
|
1207
1212
|
self.open_map_setup()
|
|
@@ -1210,27 +1215,22 @@ class Editor:
|
|
|
1210
1215
|
self.perform_load()
|
|
1211
1216
|
continue
|
|
1212
1217
|
elif event.key == pygame.K_SPACE and (ctrl_held or meta_held):
|
|
1213
|
-
if self.
|
|
1214
|
-
|
|
1215
|
-
if
|
|
1216
|
-
self.select_mode = True
|
|
1217
|
-
elif getattr(self, "_prev_tool", None) == "eraser":
|
|
1218
|
-
self.eraser_mode = True
|
|
1219
|
-
elif getattr(self, "_prev_tool", None) == "nodes":
|
|
1218
|
+
if self.tool_manager.is_active(ToolKind.PAN):
|
|
1219
|
+
restored = self.tool_manager.restore_previous()
|
|
1220
|
+
if restored is None and self._prev_tool == "nodes":
|
|
1220
1221
|
self.node_editing_mode = True
|
|
1222
|
+
self._prev_tool = None
|
|
1221
1223
|
else:
|
|
1222
|
-
if self.
|
|
1224
|
+
if self.tool_manager.is_active(ToolKind.SELECT):
|
|
1223
1225
|
self._prev_tool = "select"
|
|
1224
|
-
elif self.
|
|
1226
|
+
elif self.tool_manager.is_active(ToolKind.ERASER):
|
|
1225
1227
|
self._prev_tool = "eraser"
|
|
1226
1228
|
elif self.node_editing_mode:
|
|
1227
1229
|
self._prev_tool = "nodes"
|
|
1228
1230
|
else:
|
|
1229
1231
|
self._prev_tool = None
|
|
1230
|
-
self.pan_mode = True
|
|
1231
|
-
self.select_mode = False
|
|
1232
|
-
self.eraser_mode = False
|
|
1233
1232
|
self.node_editing_mode = False
|
|
1233
|
+
self.tool_manager.activate(ToolKind.PAN)
|
|
1234
1234
|
continue
|
|
1235
1235
|
elif event.key == pygame.K_g and (ctrl_held or meta_held):
|
|
1236
1236
|
self.toggle_grid()
|
|
@@ -4,8 +4,9 @@ Supports multiple layers with independent tile and object data.
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
import random
|
|
7
|
-
from typing import TYPE_CHECKING, Dict, List, Optional,
|
|
8
|
-
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple
|
|
8
|
+
|
|
9
|
+
from ttypes.tilemap import TypeObject, TypeTile
|
|
9
10
|
|
|
10
11
|
if TYPE_CHECKING:
|
|
11
12
|
from widgets.autotiler import AutotileRule
|
|
@@ -78,11 +79,16 @@ class Layer:
|
|
|
78
79
|
existing_positions = [p for p in positions if p in self.tiles]
|
|
79
80
|
return self._autotile_tiles(rules, existing_positions)
|
|
80
81
|
|
|
81
|
-
def _autotile_tiles(
|
|
82
|
-
self, rules: List["AutotileRule"], positions: List[Tuple[int, int]]
|
|
83
|
-
) -> int:
|
|
82
|
+
def _autotile_tiles(self, rules: List["AutotileRule"], positions: List[Tuple[int, int]]) -> int:
|
|
84
83
|
"""
|
|
85
84
|
Internal helper to update specific tiles according to autotile rules.
|
|
85
|
+
|
|
86
|
+
Group membership is determined by:
|
|
87
|
+
1. The tile's ``autotile_group`` field (if present)
|
|
88
|
+
2. Legacy fallback: (tileset_index, variant_id) lookup in variant_to_group
|
|
89
|
+
|
|
90
|
+
When a rule matches, the tile's variant is re-rolled from the rule's
|
|
91
|
+
variant_ids (removing the early-out that prevented re-autotile).
|
|
86
92
|
"""
|
|
87
93
|
if self.locked or self.layer_type != "tile":
|
|
88
94
|
return 0
|
|
@@ -90,17 +96,12 @@ class Layer:
|
|
|
90
96
|
if not rules or not positions:
|
|
91
97
|
return 0
|
|
92
98
|
|
|
93
|
-
rules_hash = hash(
|
|
94
|
-
tuple(
|
|
95
|
-
(r.group_id, r.tileset_index, tuple(sorted(r.variant_ids)))
|
|
96
|
-
for r in rules
|
|
97
|
-
)
|
|
98
|
-
)
|
|
99
|
+
rules_hash = hash(tuple((r.group_id, r.tileset_index, tuple(sorted(r.variant_ids))) for r in rules))
|
|
99
100
|
|
|
100
101
|
if self._autotile_cache["rules_hash"] != rules_hash:
|
|
101
|
-
variant_to_group = {}
|
|
102
|
+
variant_to_group: Dict[Tuple[int, int], str] = {}
|
|
102
103
|
rules_by_group: Dict[str, List["AutotileRule"]] = {}
|
|
103
|
-
significant_offsets = set()
|
|
104
|
+
significant_offsets: Set[Tuple[int, int]] = set()
|
|
104
105
|
|
|
105
106
|
for rule in rules:
|
|
106
107
|
gid = rule.group_id
|
|
@@ -132,6 +133,13 @@ class Layer:
|
|
|
132
133
|
|
|
133
134
|
changes_count = 0
|
|
134
135
|
|
|
136
|
+
def _get_group(t: dict) -> Optional[str]:
|
|
137
|
+
"""Get group_id for a tile: autotile_group field > legacy variant lookup."""
|
|
138
|
+
ag = t.get("autotile_group")
|
|
139
|
+
if ag is not None:
|
|
140
|
+
return ag
|
|
141
|
+
return variant_to_group.get((t["ttype"], t["variant"]))
|
|
142
|
+
|
|
135
143
|
for pos in positions:
|
|
136
144
|
if pos not in self.tiles:
|
|
137
145
|
continue
|
|
@@ -140,10 +148,14 @@ class Layer:
|
|
|
140
148
|
ttype = tile["ttype"]
|
|
141
149
|
current_variant = tile["variant"]
|
|
142
150
|
|
|
143
|
-
target_group_id =
|
|
151
|
+
target_group_id = _get_group(tile)
|
|
144
152
|
if not target_group_id:
|
|
145
153
|
continue
|
|
146
154
|
|
|
155
|
+
group_rules = rules_by_group.get(target_group_id)
|
|
156
|
+
if not group_rules:
|
|
157
|
+
continue
|
|
158
|
+
|
|
147
159
|
actual_neighbors = []
|
|
148
160
|
for dx, dy in [
|
|
149
161
|
(-1, -1),
|
|
@@ -158,33 +170,34 @@ class Layer:
|
|
|
158
170
|
npos = (pos[0] + dx, pos[1] + dy)
|
|
159
171
|
if npos in self.tiles:
|
|
160
172
|
n_tile = self.tiles[npos]
|
|
161
|
-
n_group =
|
|
162
|
-
|
|
173
|
+
n_group = _get_group(n_tile)
|
|
163
174
|
if n_group == target_group_id:
|
|
164
175
|
actual_neighbors.append((dx, dy))
|
|
165
176
|
|
|
166
|
-
neighbor_offsets_set = {
|
|
167
|
-
n for n in actual_neighbors if n in significant_offsets
|
|
168
|
-
}
|
|
177
|
+
neighbor_offsets_set = {n for n in actual_neighbors if n in significant_offsets}
|
|
169
178
|
|
|
170
179
|
matched_rule: Optional["AutotileRule"] = None
|
|
171
|
-
|
|
172
|
-
|
|
180
|
+
new_variant: Optional[int] = None
|
|
173
181
|
for rule in group_rules:
|
|
174
|
-
if
|
|
175
|
-
rule.neighbors == neighbor_offsets_set
|
|
176
|
-
and rule.tileset_index == ttype
|
|
177
|
-
):
|
|
182
|
+
if rule.neighbors == neighbor_offsets_set and rule.tileset_index == ttype:
|
|
178
183
|
matched_rule = rule
|
|
179
184
|
break
|
|
180
185
|
|
|
181
186
|
if matched_rule and matched_rule.variant_ids:
|
|
182
|
-
if
|
|
183
|
-
|
|
187
|
+
# only reroll if current variant isnt already
|
|
188
|
+
# in the matched rule's set to prevents re-randomization
|
|
189
|
+
# of neighbors whose pattern hasnt actually changed.
|
|
190
|
+
if current_variant not in matched_rule.variant_ids:
|
|
191
|
+
new_variant = random.choice(matched_rule.variant_ids)
|
|
192
|
+
else:
|
|
193
|
+
new_variant = current_variant
|
|
194
|
+
|
|
195
|
+
if new_variant != current_variant:
|
|
196
|
+
tile["variant"] = new_variant
|
|
197
|
+
changes_count += 1
|
|
184
198
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
changes_count += 1
|
|
199
|
+
if "autotile_group" not in tile:
|
|
200
|
+
tile["autotile_group"] = matched_rule.group_id
|
|
188
201
|
|
|
189
202
|
return changes_count
|
|
190
203
|
|
|
@@ -221,12 +234,7 @@ class Layer:
|
|
|
221
234
|
while queue:
|
|
222
235
|
curr = queue.pop(0)
|
|
223
236
|
|
|
224
|
-
if
|
|
225
|
-
curr[0] < 0
|
|
226
|
-
or curr[0] >= map_size[0]
|
|
227
|
-
or curr[1] < 0
|
|
228
|
-
or curr[1] >= map_size[1]
|
|
229
|
-
):
|
|
237
|
+
if curr[0] < 0 or curr[0] >= map_size[0] or curr[1] < 0 or curr[1] >= map_size[1]:
|
|
230
238
|
continue
|
|
231
239
|
|
|
232
240
|
curr_tile = self.tiles.get(curr)
|
|
@@ -459,9 +467,7 @@ class LayerManager:
|
|
|
459
467
|
if not manager.layers:
|
|
460
468
|
manager.create_layer("Default")
|
|
461
469
|
|
|
462
|
-
if manager.active_layer_idx < 0 or manager.active_layer_idx >= len(
|
|
463
|
-
manager.layers
|
|
464
|
-
):
|
|
470
|
+
if manager.active_layer_idx < 0 or manager.active_layer_idx >= len(manager.layers):
|
|
465
471
|
manager.active_layer_idx = 0
|
|
466
472
|
|
|
467
473
|
return manager
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from json import dump as JSONDump
|
|
2
2
|
from json import load as JSONLoad
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Union
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
|
|
5
5
|
|
|
6
6
|
from pygame import Rect
|
|
7
7
|
|
|
@@ -271,11 +271,22 @@ class Tilemap:
|
|
|
271
271
|
},
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
+
ttype_to_firstgid: List[int] = []
|
|
274
275
|
if hasattr(self.editor, "tileset_widget") and self.editor.tileset_widget:
|
|
276
|
+
firstgid = 0
|
|
277
|
+
tile_w, tile_h = self.tile_size
|
|
275
278
|
for ts in self.editor.tileset_widget.tilesets:
|
|
276
279
|
path_str = to_project_path(ts.path, map_dir)
|
|
277
280
|
|
|
278
|
-
|
|
281
|
+
ts_surf = ts.surface
|
|
282
|
+
tile_count = (ts_surf.get_width() // tile_w) * (ts_surf.get_height() // tile_h)
|
|
283
|
+
|
|
284
|
+
ttype_to_firstgid.append(firstgid)
|
|
285
|
+
|
|
286
|
+
ts_data: Dict[str, Any] = {
|
|
287
|
+
"path": path_str, "type": ts.tileset_type,
|
|
288
|
+
"tile_count": tile_count, "firstgid": firstgid,
|
|
289
|
+
}
|
|
279
290
|
if ts.properties:
|
|
280
291
|
ts_data["properties"] = ts.properties
|
|
281
292
|
if ts.tile_properties:
|
|
@@ -284,6 +295,7 @@ class Tilemap:
|
|
|
284
295
|
ts_data["animation"] = ts.animation
|
|
285
296
|
|
|
286
297
|
save_data["resources"]["tilesets"].append(ts_data)
|
|
298
|
+
firstgid += tile_count
|
|
287
299
|
|
|
288
300
|
if hasattr(self.editor, "autotiler") and self.editor.autotiler:
|
|
289
301
|
if "groups" not in save_data["project_state"]:
|
|
@@ -324,11 +336,17 @@ class Tilemap:
|
|
|
324
336
|
|
|
325
337
|
for loc, tile in layer.tiles.items():
|
|
326
338
|
key = serialize_point(loc)
|
|
339
|
+
ttype = tile["ttype"]
|
|
340
|
+
variant = tile["variant"]
|
|
327
341
|
tile_data: Dict[str, Any] = {
|
|
328
342
|
"pos": serialize_point(tile["pos"]),
|
|
329
|
-
"ttype":
|
|
330
|
-
"variant":
|
|
343
|
+
"ttype": ttype,
|
|
344
|
+
"variant": variant,
|
|
331
345
|
}
|
|
346
|
+
if "autotile_group" in tile:
|
|
347
|
+
tile_data["autotile_group"] = tile["autotile_group"]
|
|
348
|
+
if ttype_to_firstgid:
|
|
349
|
+
tile_data["gid"] = ttype_to_firstgid[ttype] + variant
|
|
332
350
|
if "properties" in tile:
|
|
333
351
|
tile_data["properties"] = tile["properties"]
|
|
334
352
|
layer_data["tiles"][key] = tile_data
|
|
@@ -355,11 +373,17 @@ class Tilemap:
|
|
|
355
373
|
if first_layer:
|
|
356
374
|
for loc, tile in first_layer.tiles.items():
|
|
357
375
|
key = serialize_point(loc)
|
|
376
|
+
ttype = tile["ttype"]
|
|
377
|
+
variant = tile["variant"]
|
|
358
378
|
tile_data: Dict[str, Any] = {
|
|
359
379
|
"pos": serialize_point(tile["pos"]),
|
|
360
|
-
"ttype":
|
|
361
|
-
"variant":
|
|
380
|
+
"ttype": ttype,
|
|
381
|
+
"variant": variant,
|
|
362
382
|
}
|
|
383
|
+
if "autotile_group" in tile:
|
|
384
|
+
tile_data["autotile_group"] = tile["autotile_group"]
|
|
385
|
+
if ttype_to_firstgid:
|
|
386
|
+
tile_data["gid"] = ttype_to_firstgid[ttype] + variant
|
|
363
387
|
save_data["data"]["ongrid"][key] = tile_data
|
|
364
388
|
|
|
365
389
|
with open(target_path, "w") as f:
|
|
@@ -659,6 +683,8 @@ class Tilemap:
|
|
|
659
683
|
tile_copy["pos"] = pos
|
|
660
684
|
if "properties" in tile_data:
|
|
661
685
|
tile_copy["properties"] = tile_data["properties"]
|
|
686
|
+
if "autotile_group" in tile_data:
|
|
687
|
+
tile_copy["autotile_group"] = tile_data["autotile_group"]
|
|
662
688
|
self._normalize_ttype(tile_copy)
|
|
663
689
|
layer.tiles[pos] = tile_copy
|
|
664
690
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><g fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><g fill="#ffffff"><circle cx="8" cy="8" r="2"/><path d="M8 1a1 1 0 0 0-.691.291l-2 2 1.414 1.414 1.293-1.293 1.293 1.293 1.414-1.414-2-2A1 1 0 0 0 8 1zM3.309 5.291l-2 2a1 1 0 0 0 0 1.414l2 2 1.414-1.414L3.43 7.998l1.293-1.293-1.414-1.414zm9.414 0-1.414 1.414 1.293 1.293-1.293 1.293 1.414 1.414 2-2a1 1 0 0 0 0-1.414l-2-2zm-6 6-1.414 1.414 2 2a1 1 0 0 0 1.414 0l2-2-1.414-1.414-1.293 1.293-1.293-1.293z"/></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><rect width="14" height="14" x="1" y="1" fill="#ffffff" rx="2.33"/><path fill="#ffffff" d="M11.5 3.734 5.89 9.346 4.185 7.665l-1.5 1.499 3.204 3.18L13 5.235z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="m5 1v11h9v-6h-5v-5zm5 0v4h4zm-8 3v11h2 8v-2h-8v-9z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><circle cx="8" cy="8" r="4" fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><circle cx="8" cy="8" r="4" fill="#ffffff"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="m2 1v14h12v-9h-5v-5zm8 0v4h4z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M2 1v14h12V6H9V1zm8 0v4h4zM5 7.793l.646-.646a.353.353 0 0 1 .707.707l-.646.646.646.646a.353.353 0 0 1-.707.707L5 9.207l-.646.646a.353.353 0 0 1-.707-.706l.646-.647-.646-.646a.353.353 0 0 1 .707-.707zm6 0 .646-.646a.353.353 0 0 1 .707.707l-.646.646.646.646a.353.353 0 0 1-.706.707L11 9.207l-.646.646a.353.353 0 0 1-.707-.706l.646-.647-.646-.646a.353.353 0 0 1 .706-.707zM3.5 11h9a.5.5 0 0 1 0 1H8a2 2 0 0 1-4 0h-.5a.5.5 0 0 1 0-1zM5 12a1 1 0 0 0 2 0z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><circle cx="8" cy="8" r="8" fill-opacity=".4"/><path fill="#ffffff" d="M8 1a7 7 0 0 0 0 14A7 7 0 0 0 8 1zm0 3.166A1 1 0 0 1 9.526 5v7h-2V6.87l-1.445.962-1-1.6z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M2 2a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-4a1 1 0 0 1-1-1V3a1 1 0 0 0-1-1z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M3 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 2h2v2H3zm4 0h2v2H7zm4 0h2v2h-2zM3 7h2v2H3zm4 0h2v2H7zm4 0h2v2h-2zm-8 4h2v2H3zm4 0h2v2H7zm4 0h2v2h-2z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="m2 1a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-12a1 1 0 0 0 -1-1zm1 2h10v8h-10zm6 2-1.5 2.5-.70117 1.168-.099609-.16797-.89844-1.5-.90039 1.5-.90039 1.5h1.8008.19922 1.5996 1.4004 3l-1.5-2.5-1.5-2.5z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M8 1a7 7 0 0 0 0 14A7 7 0 0 0 8 1zM7 4h2v2H7zm0 3h2v5H7z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M3 2a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9c1.105 0 1.818-.91 2-2l1-6a1 1 0 0 0-1-1H6c-.552 0-.909.455-1 1l-1 6c-.091.545-.448 1-1 1a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1 1 1 0 0 0 1 1h5a1 1 0 0 0-1-1H7a2 2 0 0 0-2-2H3z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M8 1v2H6a5 5 0 0 0-4 8l1.414-1.414A3 3 0 0 1 6 5h2v2l4-3-4-3zm6 4-1.414 1.414A3 3 0 0 1 10 11H8V9l-4 3 4 3v-2h2a5 5 0 0 0 4-8z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M11 2a1 1 0 0 0-2 0v6H8V3a1 1 0 0 0-2 0v8.05l-2.5-1.8A1 1 0 0 0 1.875 11L6 15h6a2 2 0 0 0 2-2V4a1 1 0 0 0-2 0v4h-1z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M4 3a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1zm6 0a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1z"/></svg>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
2
|
-
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="m3.99 16.854-1.314 3.504a.75.75 0 0 0 .966.965l3.503-1.314a3 3 0 0 0 1.068-.687L18.36 9.175s-.354-1.061-1.414-2.122c-1.06-1.06-2.122-1.414-2.122-1.414L4.677 15.786a3 3 0 0 0-.687 1.068zm12.249-12.63 1.383-1.383c.248-.248.579-.406.925-.348.487.08 1.232.322 1.934 1.025.703.703.945 1.447 1.025 1.934.058.346-.1.677-.348.925L19.774 7.76s-.353-1.06-1.414-2.12c-1.06-1.062-2.121-1.415-2.121-1.415z" fill="#
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
2
|
+
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="m3.99 16.854-1.314 3.504a.75.75 0 0 0 .966.965l3.503-1.314a3 3 0 0 0 1.068-.687L18.36 9.175s-.354-1.061-1.414-2.122c-1.06-1.06-2.122-1.414-2.122-1.414L4.677 15.786a3 3 0 0 0-.687 1.068zm12.249-12.63 1.383-1.383c.248-.248.579-.406.925-.348.487.08 1.232.322 1.934 1.025.703.703.945 1.447 1.025 1.934.058.346-.1.677-.348.925L19.774 7.76s-.353-1.06-1.414-2.12c-1.06-1.062-2.121-1.415-2.121-1.415z" fill="#ffffff"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M4 12a1 1 0 0 0 1.555.832l6-4a1 1 0 0 0 0-1.664l-6-4A1 1 0 0 0 4 4z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="m7 1v6h-6v2h6v6h2v-6h6v-2h-6v-6z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><circle cx="8" cy="8" r="7" fill="#ffffff"/><circle cx="8" cy="8" r="4" fill="#ffffff"/></svg>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
2
|
-
<svg fill="#
|
|
2
|
+
<svg fill="#ffffff" width="800px" height="800px" viewBox="0 0 512 512" data-name="Layer 1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"><path d="M64,256H34A222,222,0,0,1,430,118.15V85h30V190H355V160h67.27A192.21,192.21,0,0,0,256,64C150.13,64,64,150.13,64,256Zm384,0c0,105.87-86.13,192-192,192A192.21,192.21,0,0,1,89.73,352H157V322H52V427H82V393.85A222,222,0,0,0,478,256Z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M3 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4l-3-3h-1v6H3zm1 0v5h3V1zm4 8a1 1 0 0 1 0 4 1 1 0 0 1 0-4z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><rect width="10" height="10" x="3" y="3" fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><rect width="10" height="10" x="3" y="3" fill="#ffffff" rx="1"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M1 1v2h2V1zm3 0v2h2V1zm3 0v2h2V1zm3 0v2h2V1zm3 0v2h2V1zM1 4v2h2V4zm3 0v2h2V4zm3 0v2h2V4zm3 0v2h2V4zm3 0v2h2V4zM1 7v2h2V7zm3 0v2h2V7zm3 0v2h2V7zm3 0v2h2V7zm3 0v2h2V7zM1 10v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zM1 13v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M1 1v2h2V1zm3 0v2h2V1zm3 0v2h2V1zm3 0v2h2V1zm3 0v2h2V1zM1 4v2h2V4zm3 0v2h2V4zm3 0v2h2V4zm3 0v2h2V4zm3 0v2h2V4zM1 7v2h2V7zm3 0v2h2V7zm5 1v7h5a1 1 0 0 0 1-1V9a1 1 0 0 0-1-1v4l-1-1-1 1V8zm-8 2v2h2v-2zm3 0v2h2v-2zm-3 3v2h2v-2zm3 0v2h2v-2z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><rect width="14" height="14" x="1" y="1" fill="#ffffff" rx="2.33"/><path fill="#ffffff" d="M11.5 3.734 5.89 9.346 4.185 7.665l-1.5 1.499 3.204 3.18L13 5.235z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M8 1a7 7 0 0 0 0 14A7 7 0 0 0 8 1zM7 3h2v7H7zm0 8h2v2H7z"/></svg>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
-
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
-
<svg fill="#
|
|
4
|
-
<title>zoomin</title>
|
|
5
|
-
<path d="M16.906 20.188l5.5 5.5-2.25 2.281-5.75-5.781c-1.406 0.781-3.031 1.219-4.719 1.219-5.344 0-9.688-4.344-9.688-9.688s4.344-9.688 9.688-9.688 9.719 4.344 9.719 9.688c0 2.5-0.969 4.781-2.5 6.469zM2.688 13.719c0 3.875 3.125 6.969 7 6.969 3.844 0 7-3.094 7-6.969s-3.156-6.969-7-6.969c-3.875 0-7 3.094-7 6.969zM10.813 12.625h3.875v2.219h-3.875v3.844h-2.219v-3.844h-3.844v-2.219h3.844v-3.875h2.219v3.875z"></path>
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg fill="#ffffff" width="800px" height="800px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
4
|
+
<title>zoomin</title>
|
|
5
|
+
<path d="M16.906 20.188l5.5 5.5-2.25 2.281-5.75-5.781c-1.406 0.781-3.031 1.219-4.719 1.219-5.344 0-9.688-4.344-9.688-9.688s4.344-9.688 9.688-9.688 9.719 4.344 9.719 9.688c0 2.5-0.969 4.781-2.5 6.469zM2.688 13.719c0 3.875 3.125 6.969 7 6.969 3.844 0 7-3.094 7-6.969s-3.156-6.969-7-6.969c-3.875 0-7 3.094-7 6.969zM10.813 12.625h3.875v2.219h-3.875v3.844h-2.219v-3.844h-3.844v-2.219h3.844v-3.875h2.219v3.875z"></path>
|
|
6
6
|
</svg>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
-
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
-
<svg fill="#
|
|
4
|
-
<title>zoomout</title>
|
|
5
|
-
<path d="M16.906 20.188l5.5 5.5-2.25 2.281-5.75-5.781c-1.406 0.781-3.031 1.219-4.719 1.219-5.344 0-9.688-4.344-9.688-9.688s4.344-9.688 9.688-9.688 9.719 4.344 9.719 9.688c0 2.5-0.969 4.781-2.5 6.469zM2.688 13.719c0 3.875 3.125 6.969 7 6.969 3.844 0 7-3.094 7-6.969s-3.156-6.969-7-6.969c-3.875 0-7 3.094-7 6.969zM4.438 12.625h10.531v2.219h-10.531v-2.219z"></path>
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg fill="#ffffff" width="800px" height="800px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
4
|
+
<title>zoomout</title>
|
|
5
|
+
<path d="M16.906 20.188l5.5 5.5-2.25 2.281-5.75-5.781c-1.406 0.781-3.031 1.219-4.719 1.219-5.344 0-9.688-4.344-9.688-9.688s4.344-9.688 9.688-9.688 9.719 4.344 9.719 9.688c0 2.5-0.969 4.781-2.5 6.469zM2.688 13.719c0 3.875 3.125 6.969 7 6.969 3.844 0 7-3.094 7-6.969s-3.156-6.969-7-6.969c-3.875 0-7 3.094-7 6.969zM4.438 12.625h10.531v2.219h-10.531v-2.219z"></path>
|
|
6
6
|
</svg>
|
|
@@ -43,6 +43,11 @@ def main() -> None:
|
|
|
43
43
|
"--size", default="1500x900", help="Window size as WIDTHxHEIGHT"
|
|
44
44
|
)
|
|
45
45
|
run_parser.add_argument("--fps", type=int, default=60, help="Editor FPS")
|
|
46
|
+
run_parser.add_argument(
|
|
47
|
+
"--theme",
|
|
48
|
+
default=None,
|
|
49
|
+
help='Theme name or path to .json theme file (e.g. "molokai", "path/to/custom.json")',
|
|
50
|
+
)
|
|
46
51
|
|
|
47
52
|
args = parser.parse_args()
|
|
48
53
|
|
|
@@ -74,7 +79,7 @@ def _run_editor(args) -> None:
|
|
|
74
79
|
try:
|
|
75
80
|
with error_context("cli_main"):
|
|
76
81
|
size = _parse_size(args.size)
|
|
77
|
-
editor = Editor(size=size, fps=max(1, args.fps))
|
|
82
|
+
editor = Editor(size=size, fps=max(1, args.fps), theme=args.theme)
|
|
78
83
|
editor.run()
|
|
79
84
|
except KeyboardInterrupt:
|
|
80
85
|
print("\nEditor interrupted by user")
|
|
@@ -179,6 +179,7 @@ src/widgets/ui/collision_layer_mask.py
|
|
|
179
179
|
src/widgets/ui/collision_layer_sidebar.py
|
|
180
180
|
src/widgets/ui/confirm_dialog.py
|
|
181
181
|
src/widgets/ui/dialog_base.py
|
|
182
|
+
src/widgets/ui/drag_tracker.py
|
|
182
183
|
src/widgets/ui/draw_utils.py
|
|
183
184
|
src/widgets/ui/fileinput.py
|
|
184
185
|
src/widgets/ui/label.py
|
|
@@ -196,12 +197,16 @@ src/widgets/ui/sidebar_container.py
|
|
|
196
197
|
src/widgets/ui/status_bar.py
|
|
197
198
|
src/widgets/ui/theme.py
|
|
198
199
|
src/widgets/ui/tileset_type_dialog.py
|
|
200
|
+
src/widgets/ui/tool_manager.py
|
|
199
201
|
src/widgets/ui/toolbar.py
|
|
200
202
|
src/widgets/ui/tooltip.py
|
|
201
203
|
tests/test_animation_library_grid_offset.py
|
|
202
204
|
tests/test_collision_layer_mask.py
|
|
203
205
|
tests/test_collision_layer_sidebar.py
|
|
206
|
+
tests/test_drag_tracker.py
|
|
204
207
|
tests/test_editor_pan_mode.py
|
|
208
|
+
tests/test_gid_collision.py
|
|
209
|
+
tests/test_layers_autotile.py
|
|
205
210
|
tests/test_project_paths.py
|
|
206
211
|
tests/test_render_scale.py
|
|
207
212
|
tests/test_serialization_regression.py
|
|
@@ -5,6 +5,8 @@ class TypeTile(TypedDict, total=True):
|
|
|
5
5
|
pos: Tuple[int, int]
|
|
6
6
|
ttype: int
|
|
7
7
|
variant: int
|
|
8
|
+
autotile_group: NotRequired[str]
|
|
9
|
+
gid: NotRequired[int]
|
|
8
10
|
properties: NotRequired[Dict[str, Any]]
|
|
9
11
|
|
|
10
12
|
|
|
@@ -35,6 +37,8 @@ class TypeTileSerealized(TypedDict, total=True):
|
|
|
35
37
|
pos: str
|
|
36
38
|
ttype: str
|
|
37
39
|
variant: int
|
|
40
|
+
autotile_group: NotRequired[str]
|
|
41
|
+
gid: NotRequired[int]
|
|
38
42
|
properties: NotRequired[Dict[str, Any]]
|
|
39
43
|
|
|
40
44
|
|
|
@@ -62,6 +66,8 @@ class TypeLayerSerialized(TypedDict, total=True):
|
|
|
62
66
|
class TypeTilesetSerialized(TypedDict, total=True):
|
|
63
67
|
path: str
|
|
64
68
|
type: str
|
|
69
|
+
tile_count: NotRequired[int]
|
|
70
|
+
firstgid: NotRequired[int]
|
|
65
71
|
properties: NotRequired[Dict[str, Any]]
|
|
66
72
|
tile_properties: NotRequired[Dict[str, Dict[str, Any]]]
|
|
67
73
|
animation: NotRequired[dict]
|