tilemap-editor 4.3.6__tar.gz → 4.3.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.
- tilemap_editor-4.3.8/CHANGELOG.md +231 -0
- {tilemap_editor-4.3.6/src/tilemap_editor.egg-info → tilemap_editor-4.3.8}/PKG-INFO +3 -1
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/pyproject.toml +36 -7
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/editor.py +27 -78
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/layers.py +8 -1
- tilemap_editor-4.3.8/src/plugins/sprite_editor/camera.py +97 -0
- tilemap_editor-4.3.8/src/plugins/sprite_editor/clipboard.py +74 -0
- tilemap_editor-4.3.8/src/plugins/sprite_editor/commands.py +248 -0
- tilemap_editor-4.3.8/src/plugins/sprite_editor/document.py +352 -0
- tilemap_editor-4.3.8/src/plugins/sprite_editor/editor.py +658 -0
- tilemap_editor-4.3.8/src/plugins/sprite_editor/overlays.py +155 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_editor/region_export.py +3 -3
- tilemap_editor-4.3.8/src/plugins/sprite_editor/selection.py +99 -0
- tilemap_editor-4.3.8/src/plugins/sprite_editor/tools.py +745 -0
- tilemap_editor-4.3.8/src/plugins/sprite_editor/viewport.py +179 -0
- tilemap_editor-4.3.8/src/run.py +3 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap.py +21 -49
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8/src/tilemap_editor.egg-info}/PKG-INFO +3 -1
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor.egg-info/SOURCES.txt +17 -1
- tilemap_editor-4.3.8/src/tilemap_editor.egg-info/requires.txt +4 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/utils/font_manager.py +4 -0
- tilemap_editor-4.3.8/src/utils/natural_sort.py +29 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/filemanager.py +4 -3
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/input.py +31 -6
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/tile_grid.py +91 -76
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/menubar.py +36 -3
- tilemap_editor-4.3.8/src/widgets/ui/resize_map_dialog.py +223 -0
- tilemap_editor-4.3.8/tests/test_map_resize_model.py +50 -0
- tilemap_editor-4.3.8/tests/test_natural_sort.py +80 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_serialization_regression.py +19 -5
- tilemap_editor-4.3.8/tests/test_sprite_editor_commands.py +271 -0
- tilemap_editor-4.3.8/tests/test_sprite_editor_interaction.py +610 -0
- tilemap_editor-4.3.8/tests/test_sprite_editor_models.py +380 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_tile_grid_selection.py +1 -1
- tilemap_editor-4.3.6/src/plugins/sprite_editor/editor.py +0 -631
- tilemap_editor-4.3.6/src/tilemap_editor.egg-info/requires.txt +0 -1
- tilemap_editor-4.3.6/src/widgets/spritesheet_grid.py +0 -707
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/LICENSE +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/MANIFEST.in +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/README.md +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/fonts/jetbrain-fonts/JetBrainsMono-Bold.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/fonts/jetbrain-fonts/JetBrainsMono-BoldItalic.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/fonts/jetbrain-fonts/JetBrainsMono-Italic.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/fonts/jetbrain-fonts/JetBrainsMono-Regular.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/fonts/noto/NotoSans-Bold.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/fonts/noto/NotoSans-BoldItalic.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/fonts/noto/NotoSans-Italic.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/arrow-down.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/check.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/checked.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/close.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/duplicate.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/error.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/file.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/filedead.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/fit.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/folder.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/grid.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/image.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/info.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/load.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/loop.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/onion.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/pan.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/pause.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/pencil.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/play.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/plus.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/radio.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/reset.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/save.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/skip-back.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/skip-forward.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/stop.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/tilemap.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/tileset.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/unchecked.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/warning.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/zoomin.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/assets/icons/zoomout.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/setup.cfg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/constants.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/event_map.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/main.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/node_manager.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/nodes.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/__init__.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/character_collision/__init__.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/character_collision/editor.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/character_collision/models.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/character_collision/protocols.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/character_collision/shape_editor.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/character_collision/standalone.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/object_tileset_collision/__init__.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/object_tileset_collision/editor.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/object_tileset_collision/models.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/object_tileset_collision/protocols.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/object_tileset_collision/standalone.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_animation/__init__.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_animation/__main__.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_animation/clipboard_util.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_animation/editor.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_animation/frame_picker.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_animation/models.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_animation/preview.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_animation/protocols.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_animation/runtime_load.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_animation/standalone.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_animation/timeline.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_animation/validation.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_editor/__init__.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_editor/dialogs.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/sprite_editor/standalone.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/tileset_collision/__init__.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/tileset_collision/collision_painter.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/tileset_collision/editor.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/tileset_collision/models.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/tileset_collision/protocols.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/plugins/tileset_collision/standalone.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/standalone_automap.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/standalone_error_console.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/standalone_filemanager.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/standalone_image_viewer.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/__init__.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/__main__.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/__init__.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Bold.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-BoldItalic.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Italic.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Regular.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/fonts/noto/NotoSans-Bold.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/fonts/noto/NotoSans-BoldItalic.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/fonts/noto/NotoSans-Italic.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/ToolMove.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/arrow-down.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/check.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/checked.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/close.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/duplicate.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/error.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/file.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/filedead.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/fit.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/fold_down_arrow.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/folder.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/gear.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/grid.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/image.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/info.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/load.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/loop.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/miniobj.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/onion.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/pan.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/pause.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/pencil.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/play.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/plus.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/radio.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/reset.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/save.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/skip-back.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/skip-forward.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/stop.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/tilemap.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/tileset.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/unchecked.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/unfold_right_arrow.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/warning.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/zoomin.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/assets/icons/zoomout.svg +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/cli.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/main.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor/settings.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor.egg-info/dependency_links.txt +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor.egg-info/entry_points.txt +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/tilemap_editor.egg-info/top_level.txt +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/ttypes/__init__.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/ttypes/tilemap.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/utils/__init__.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/utils/editor_preference.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/utils/error_handler.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/utils/history.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/utils/icon_manager.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/utils/icons_cache.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/utils/log_capture.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/utils/project_paths.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/utils/property_suggestions.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/utils/serialization.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/utils/standalone.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/utils/validation.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/__init__.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/automap_models.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/autotile_template.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/autotiler.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/layer_selector.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/map_properties.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/mapsetup.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/particle_presets.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/particle_system.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/regex_automap_designer.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/tile_selector.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/button.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/checkbox.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/collision_layer_mask.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/collision_layer_sidebar.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/confirm_dialog.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/dialog_base.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/drag_tracker.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/draw_utils.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/fileinput.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/label.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/layer_type_dialog.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/mode_indicator.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/node_editor.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/node_selector.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/notification.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/particle_config_dialog.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/property_editor.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/region_selector.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/scrollbar.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/sidebar_container.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/splitter.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/status_bar.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/theme.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/tileset_type_dialog.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/toast.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/tool_manager.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/toolbar.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/tooltip.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/ui/tree_widget.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/src/widgets/widget_base.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_animation_library_grid_offset.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_collision_layer_mask.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_collision_layer_sidebar.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_drag_tracker.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_editor_pan_mode.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_gid_collision.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_layers_autotile.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_project_paths.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_render_scale.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_sprite_animation_editor_grid.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_tile_selector_pick.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_tilemap_save.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_timeline_invalidate_cache.py +0 -0
- {tilemap_editor-4.3.6 → tilemap_editor-4.3.8}/tests/test_toolbar_tools.py +0 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
<!-- towncrier release notes start -->
|
|
4
|
+
# tilemap_editor 4.3.8 (2026-08-04)
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
- Sprite editor: two-row grouped toolbar (no more clipped buttons at the default window size), natural filename sorting on multi-sheet loads, and a Stack V/H toggle for vertical or horizontal sheet stacking. (sprite-editor-toolbar-sort)
|
|
9
|
+
- Rewrote the sprite editor around a command stack with single-canvas undo memory: shared clipboard with relative-tile pasting that survives scale/grid changes, drag-move and rubber-band selection that can expand the canvas, object-selection undo restore, and a pure camera with cursor-anchored zoom. (sprite-editor-v2)
|
|
10
|
+
|
|
11
|
+
## Bug Fixes
|
|
12
|
+
|
|
13
|
+
- Fixed sprite editor paste landing in wrong cells after a scale or grid-size change (clipboard now stores relative tile offsets), paste/cut double-clipboard split-brain, paste preview lacking pixel ghost, and moves/pastes past the canvas edge now expanding the canvas. (sprite-editor-paste-fixes)
|
|
14
|
+
- Fixed sprite editor theming and camera gestures: the canvas, header bar, grid lines, and overlays now use theme colors/fonts instead of hardcoded dark values (canvas no longer stays black on light themes), the canvas header no longer covers the sheet's top rows, and mouse wheel zoom/pan work again with the same 30px/1.12x behavior as the old editor. (sprite-editor-theme-wheel)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## [4.3.7] - 2026-07-30
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
- Replaced buggy auto-resize system with explicit offset + size model for widget positioning
|
|
22
|
+
|
|
23
|
+
## [4.3.6] - 2026-07-26
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
- Added tileset properties completion
|
|
28
|
+
- Updated README with credits and Python version info
|
|
29
|
+
|
|
30
|
+
### Bug Fixes
|
|
31
|
+
|
|
32
|
+
- Fixed UX bugs and node prescale problem
|
|
33
|
+
|
|
34
|
+
## [4.3.4] - 2026-07-24
|
|
35
|
+
|
|
36
|
+
### Features
|
|
37
|
+
|
|
38
|
+
- Added y-sort option for tile rendering order
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- Restructured codebase with enhanced UI components and preference persistence
|
|
43
|
+
- Improved shape editor UX with theme integration and viewport centering
|
|
44
|
+
|
|
45
|
+
## [4.3.1] - 2026-07-17
|
|
46
|
+
|
|
47
|
+
### Bug Fixes
|
|
48
|
+
|
|
49
|
+
- Fixed create folder blocker in file manager
|
|
50
|
+
- Adjusted input field inner size
|
|
51
|
+
|
|
52
|
+
## [4.3.0] - 2026-07-16
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- Refactored toolbar and tool system with ToolManager/ToolKind central state
|
|
57
|
+
- Replaced editor boolean flags with centralized ToolManager mutual exclusion
|
|
58
|
+
- CLI `--theme` support
|
|
59
|
+
|
|
60
|
+
### Added
|
|
61
|
+
|
|
62
|
+
- Icon-only compact toolbar (28px) with separator bars and tooltips
|
|
63
|
+
|
|
64
|
+
### Bug Fixes
|
|
65
|
+
|
|
66
|
+
- Fixed node and object render_scale bugs (selection rect, move offset, hit-test)
|
|
67
|
+
|
|
68
|
+
## [4.2.0] - 2026-07-15
|
|
69
|
+
|
|
70
|
+
### Features
|
|
71
|
+
|
|
72
|
+
- Separated autotile group from layer tile data
|
|
73
|
+
- Added global ID system for tiles
|
|
74
|
+
- Re-added autotile early-out optimization
|
|
75
|
+
- Added auto-detect group from variant
|
|
76
|
+
|
|
77
|
+
## [4.1.0] - 2026-07-13
|
|
78
|
+
|
|
79
|
+
### Features
|
|
80
|
+
|
|
81
|
+
- Added .tmx file open/save support with TMX-to-dict converter
|
|
82
|
+
|
|
83
|
+
### Bug Fixes
|
|
84
|
+
|
|
85
|
+
- Fixed alignment of tmx converter with parser fixes (mask, props, gid count)
|
|
86
|
+
|
|
87
|
+
### Misc
|
|
88
|
+
|
|
89
|
+
- Formatted code and applied unsafe fixes with ruff
|
|
90
|
+
|
|
91
|
+
## [4.0.0] - 2026-07-11
|
|
92
|
+
|
|
93
|
+
### Changed
|
|
94
|
+
|
|
95
|
+
- Refactored widget theme system with dynamic COLORS proxy, SHAPE, FONTS, SPACING
|
|
96
|
+
- Applied theme from settings.json with custom theme loading support
|
|
97
|
+
- Added theme-aware WidgetBase with box model (padding, border, content_rect)
|
|
98
|
+
|
|
99
|
+
### Added
|
|
100
|
+
|
|
101
|
+
- CLI `--theme` argument accepting name or path to .json file
|
|
102
|
+
|
|
103
|
+
### Bug Fixes
|
|
104
|
+
|
|
105
|
+
- Fixed tile grid issues and serialization
|
|
106
|
+
- Improved node ui/ux with ctrl/cmd+shift+n toggle for node manager
|
|
107
|
+
- Improved particle rendering
|
|
108
|
+
- Temporarily disabled autotile propagation on collision paint
|
|
109
|
+
|
|
110
|
+
## [3.3.8] - 2026-07-01
|
|
111
|
+
|
|
112
|
+
### Bug Fixes
|
|
113
|
+
|
|
114
|
+
- Replaced smoothscale with scale for broader compatibility
|
|
115
|
+
- Fixed fallback to scale when smoothscale fails on non-32bit surfaces
|
|
116
|
+
- Replaced unicode characters with SVG icons for frame nav and onion skin
|
|
117
|
+
|
|
118
|
+
## [3.3.4] - 2026-06-17
|
|
119
|
+
|
|
120
|
+
### Features
|
|
121
|
+
|
|
122
|
+
- Enhanced sprite editor with cut/copy/paste functionality
|
|
123
|
+
- Added checkbox widget for UI controls
|
|
124
|
+
|
|
125
|
+
### Documentation
|
|
126
|
+
|
|
127
|
+
- Added documentation for tilemap-editor (setup, project structure, architecture, usage)
|
|
128
|
+
|
|
129
|
+
## [3.3.3] - 2026-06-10
|
|
130
|
+
|
|
131
|
+
### Features
|
|
132
|
+
|
|
133
|
+
- Added particle system with 66 presets across 11 categories
|
|
134
|
+
- Added particle system editor integration with config dialog
|
|
135
|
+
- Added particle preview in TileGrid
|
|
136
|
+
|
|
137
|
+
### Bug Fixes
|
|
138
|
+
|
|
139
|
+
- Fixed propagation of negative grid offsets
|
|
140
|
+
- Fixed zero animation frame_stride guard
|
|
141
|
+
- Fixed preset dropdown refresh on node switch
|
|
142
|
+
- Fixed particle preview reset on config save
|
|
143
|
+
|
|
144
|
+
### Misc
|
|
145
|
+
|
|
146
|
+
- Added 'synchronize' type to PR agent workflow triggers
|
|
147
|
+
|
|
148
|
+
## [3.2.10] - 2026-06-07
|
|
149
|
+
|
|
150
|
+
### Bug Fixes
|
|
151
|
+
|
|
152
|
+
- Fixed tab click offset ignoring scroll_x
|
|
153
|
+
|
|
154
|
+
### Added
|
|
155
|
+
|
|
156
|
+
- Hover-only arrow buttons for tab navigation
|
|
157
|
+
|
|
158
|
+
## [3.2.9] - 2026-06-07
|
|
159
|
+
|
|
160
|
+
### Bug Fixes
|
|
161
|
+
|
|
162
|
+
- Fixed stride normalization — removed % stride normalization, auto-compute stride
|
|
163
|
+
- Fixed dialog UI overlap
|
|
164
|
+
|
|
165
|
+
## [3.2.8] - 2026-06-07
|
|
166
|
+
|
|
167
|
+
### Features
|
|
168
|
+
|
|
169
|
+
- Added node system with NodeManager, NodeSelector, NodeEditor, and TileGrid overlay
|
|
170
|
+
- Added lenient tileset loading with warn dialog instead of reject on size mismatch
|
|
171
|
+
|
|
172
|
+
### Bug Fixes
|
|
173
|
+
|
|
174
|
+
- Fixed layer rename text not visible during editing
|
|
175
|
+
- Fixed object layer position offset from render_scale
|
|
176
|
+
- Fixed capsule move icon and animation preview grid_offset
|
|
177
|
+
- Fixed layer rename Cmd+Backspace interaction
|
|
178
|
+
|
|
179
|
+
## [3.2.4] - 2026-06-04
|
|
180
|
+
|
|
181
|
+
### Features
|
|
182
|
+
|
|
183
|
+
- Added copy/paste collision shapes with toast feedback and painted tiles focus mode
|
|
184
|
+
- Added sprite editor integration with flip ghosting fix, tileset zoom, autotiler import fix
|
|
185
|
+
- Added auto-expand spritesheet canvas on paste overflow
|
|
186
|
+
- Added editable name field in character collision editor
|
|
187
|
+
- Added renaming support in character collision
|
|
188
|
+
- Added animation library loading and tool state management
|
|
189
|
+
- Added auto-propagation of collision shapes to auto-tile variant groups on save
|
|
190
|
+
|
|
191
|
+
### Bug Fixes
|
|
192
|
+
|
|
193
|
+
- Fixed animation rename shortcuts, path resolution, file input overflow, and dual-focus metadata fields
|
|
194
|
+
- Fixed sprite editor multi-row paste flattening and missing tile-size arg
|
|
195
|
+
- Fixed dynamic grid span
|
|
196
|
+
- Fixed L shortcut conflict with name input
|
|
197
|
+
|
|
198
|
+
### Misc
|
|
199
|
+
|
|
200
|
+
- Added unit tests
|
|
201
|
+
|
|
202
|
+
## [3.1.6] - 2026-05-21
|
|
203
|
+
|
|
204
|
+
### Bug Fixes
|
|
205
|
+
|
|
206
|
+
- Fixed NameError in save_map
|
|
207
|
+
- Fixed asymmetry in load path resolution
|
|
208
|
+
- Fixed path resolution in init
|
|
209
|
+
|
|
210
|
+
### Added
|
|
211
|
+
|
|
212
|
+
- Added render_scale to map properties with dialog UI and TileGrid support
|
|
213
|
+
- Added auto-creation of data directory on init
|
|
214
|
+
|
|
215
|
+
## [3.1.0] - 2026-05-18
|
|
216
|
+
|
|
217
|
+
### Features
|
|
218
|
+
|
|
219
|
+
- Added Godot-inspired physics layer (radio) + mask (checkbox) bit selector (16 layers)
|
|
220
|
+
- Added collision layer sidebar overlay with toggle/close/dim
|
|
221
|
+
- Added object tileset collision editor with region support
|
|
222
|
+
- Added reusable text input system with cursor, selection, and shortcuts
|
|
223
|
+
- Added project initialization, asset management, and data structure improvements
|
|
224
|
+
- Added theme support
|
|
225
|
+
- Added collision mask support
|
|
226
|
+
- Implemented event priority system and modal overlays in autotiler
|
|
227
|
+
|
|
228
|
+
### Changed
|
|
229
|
+
|
|
230
|
+
- Improved file manager path handling and directory initialization
|
|
231
|
+
- Improved tileset collision help panel and macOS HiDPI support
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tilemap-editor
|
|
3
|
-
Version: 4.3.
|
|
3
|
+
Version: 4.3.8
|
|
4
4
|
Summary: Pygame tilemap editor with collision, animation, sprite & particle tools
|
|
5
5
|
Author: tilemap editor contributors
|
|
6
6
|
License: Proprietary
|
|
@@ -12,6 +12,8 @@ Requires-Python: >=3.11
|
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Dist: pygame-ce>=2.5
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: towncrier; extra == "dev"
|
|
15
17
|
Dynamic: license-file
|
|
16
18
|
|
|
17
19
|
# tilemap-editor
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tilemap-editor"
|
|
7
|
-
version = "4.3.
|
|
7
|
+
version = "4.3.8"
|
|
8
8
|
description = "Pygame tilemap editor with collision, animation, sprite & particle tools"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -24,6 +24,41 @@ classifiers = [
|
|
|
24
24
|
tilemap-editor = "tilemap_editor.cli:main"
|
|
25
25
|
tilemap-anim-editor = "plugins.sprite_animation.standalone:main"
|
|
26
26
|
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
dev = ["towncrier"]
|
|
29
|
+
|
|
30
|
+
[tool.towncrier]
|
|
31
|
+
package = "tilemap_editor"
|
|
32
|
+
directory = "changes"
|
|
33
|
+
filename = "CHANGELOG.md"
|
|
34
|
+
start_string = "<!-- towncrier release notes start -->"
|
|
35
|
+
underlines = ["-", "~", "^"]
|
|
36
|
+
|
|
37
|
+
[[tool.towncrier.type]]
|
|
38
|
+
directory = "feature"
|
|
39
|
+
name = "Features"
|
|
40
|
+
showcontent = true
|
|
41
|
+
|
|
42
|
+
[[tool.towncrier.type]]
|
|
43
|
+
directory = "bugfix"
|
|
44
|
+
name = "Bug Fixes"
|
|
45
|
+
showcontent = true
|
|
46
|
+
|
|
47
|
+
[[tool.towncrier.type]]
|
|
48
|
+
directory = "doc"
|
|
49
|
+
name = "Documentation"
|
|
50
|
+
showcontent = true
|
|
51
|
+
|
|
52
|
+
[[tool.towncrier.type]]
|
|
53
|
+
directory = "removal"
|
|
54
|
+
name = "Deprecations and Removals"
|
|
55
|
+
showcontent = true
|
|
56
|
+
|
|
57
|
+
[[tool.towncrier.type]]
|
|
58
|
+
directory = "misc"
|
|
59
|
+
name = "Misc"
|
|
60
|
+
showcontent = true
|
|
61
|
+
|
|
27
62
|
[tool.setuptools]
|
|
28
63
|
package-dir = {"" = "src"}
|
|
29
64
|
include-package-data = true
|
|
@@ -62,9 +97,3 @@ namespaces = true
|
|
|
62
97
|
|
|
63
98
|
[tool.setuptools.exclude-package-data]
|
|
64
99
|
"*" = ["*.spec", "*.sh"]
|
|
65
|
-
|
|
66
|
-
# Keep data-files for backward compatibility (one release cycle)
|
|
67
|
-
[tool.setuptools.data-files]
|
|
68
|
-
"share/tilemap_editor/assets/icons" = ["assets/icons/*.svg"]
|
|
69
|
-
"share/tilemap_editor/assets/fonts/noto" = ["assets/fonts/noto/*.ttf"]
|
|
70
|
-
"share/tilemap_editor/assets/fonts/jetbrain-fonts" = ["assets/fonts/jetbrain-fonts/*.ttf"]
|
|
@@ -39,6 +39,7 @@ from widgets.ui.node_selector import NodeSelector
|
|
|
39
39
|
from widgets.ui.notification import NotificationManager
|
|
40
40
|
from widgets.ui.particle_config_dialog import ParticleConfigDialog
|
|
41
41
|
from widgets.ui.property_editor import PropertyEditor
|
|
42
|
+
from widgets.ui.resize_map_dialog import ResizeMapDialog
|
|
42
43
|
from widgets.ui.sidebar_container import SidebarContainer, ToolbarAction
|
|
43
44
|
from widgets.ui.theme import COLORS, THEMES, get_theme_manager, set_theme
|
|
44
45
|
from widgets.ui.tileset_type_dialog import TilesetTypeDialog
|
|
@@ -206,8 +207,7 @@ class Editor:
|
|
|
206
207
|
self.tile_grid_widget: TileGrid | None = None
|
|
207
208
|
|
|
208
209
|
self.left_panel_visible = False
|
|
209
|
-
self.
|
|
210
|
-
self._animation_panel_surface: pygame.Surface | None = None
|
|
210
|
+
self.left_panel_w = 300
|
|
211
211
|
|
|
212
212
|
self.autotiler = AutotileRuleDesigner(self, 100, 100)
|
|
213
213
|
self.regex_automap_designer = RegexAutomapDesigner(self, 150, 100)
|
|
@@ -240,6 +240,8 @@ class Editor:
|
|
|
240
240
|
self.tileset_type_dialog = TilesetTypeDialog(editor_rect)
|
|
241
241
|
self.confirm_dialog = ConfirmDialog(editor_rect)
|
|
242
242
|
self.layer_type_dialog = LayerTypeDialog(editor_rect)
|
|
243
|
+
self.resize_map_dialog = ResizeMapDialog(editor_rect)
|
|
244
|
+
self.resize_map_dialog.editor = self
|
|
243
245
|
|
|
244
246
|
self.menubar = MenuBar(self, self.width, 30)
|
|
245
247
|
self.toolbar = Toolbar(self, 0, 30, self.width, 35)
|
|
@@ -622,13 +624,6 @@ class Editor:
|
|
|
622
624
|
|
|
623
625
|
self._update_side_panel_layout()
|
|
624
626
|
|
|
625
|
-
if self.left_panel_visible and self.animation_panel:
|
|
626
|
-
panel_rect = Rect(0, menu_h + toolbar_h, self.left_panel_w, height - (menu_h + toolbar_h))
|
|
627
|
-
if hasattr(self.animation_panel, "rect"):
|
|
628
|
-
self.animation_panel.rect = panel_rect
|
|
629
|
-
if hasattr(self.animation_panel, "_relayout"):
|
|
630
|
-
self.animation_panel._relayout()
|
|
631
|
-
|
|
632
627
|
rect_full = Rect(0, 0, width, height)
|
|
633
628
|
|
|
634
629
|
if hasattr(self, "tileset_type_dialog") and self.tileset_type_dialog:
|
|
@@ -663,6 +658,12 @@ class Editor:
|
|
|
663
658
|
return
|
|
664
659
|
self.map_properties_dialog.open()
|
|
665
660
|
|
|
661
|
+
def open_resize_map_dialog(self):
|
|
662
|
+
if self.resize_map_dialog is None:
|
|
663
|
+
logger.warning({"msg": "resize_map_dialog is not initialized"})
|
|
664
|
+
return
|
|
665
|
+
self.resize_map_dialog.open()
|
|
666
|
+
|
|
666
667
|
def toggle_autotiler(self):
|
|
667
668
|
if self.autotiler.visible:
|
|
668
669
|
self.autotiler.hide()
|
|
@@ -675,47 +676,6 @@ class Editor:
|
|
|
675
676
|
else:
|
|
676
677
|
self.regex_automap_designer.show()
|
|
677
678
|
|
|
678
|
-
def toggle_animation_panel(self):
|
|
679
|
-
"""Toggle the dockable animation panel visibility (Cmd/Ctrl+B)."""
|
|
680
|
-
if not self.left_panel_visible:
|
|
681
|
-
if self.animation_panel is None:
|
|
682
|
-
self._init_animation_panel()
|
|
683
|
-
if self.animation_panel is not None:
|
|
684
|
-
self.left_panel_visible = True
|
|
685
|
-
else:
|
|
686
|
-
self.left_panel_visible = False
|
|
687
|
-
self.handle_resize(self.width, self.height)
|
|
688
|
-
|
|
689
|
-
def _init_animation_panel(self):
|
|
690
|
-
"""Initialize the animation panel without loading any tileset."""
|
|
691
|
-
from plugins.sprite_animation.editor import SpriteAnimationEditor
|
|
692
|
-
|
|
693
|
-
try:
|
|
694
|
-
|
|
695
|
-
class _PanelConsumer:
|
|
696
|
-
editor_instance = self
|
|
697
|
-
|
|
698
|
-
def on_animation_saved(self, name: str, data: dict) -> None:
|
|
699
|
-
self.editor_instance.notifications.notify(f"Animation saved: {name}")
|
|
700
|
-
|
|
701
|
-
def on_animation_deleted(self, name: str) -> None:
|
|
702
|
-
self.editor_instance.notifications.notify(f"Animation deleted: {name}")
|
|
703
|
-
|
|
704
|
-
consumer = _PanelConsumer()
|
|
705
|
-
|
|
706
|
-
panel_rect = Rect(0, 65, self.left_panel_w, self.height - 65)
|
|
707
|
-
|
|
708
|
-
self.animation_panel = SpriteAnimationEditor(
|
|
709
|
-
panel_rect,
|
|
710
|
-
surface=None,
|
|
711
|
-
tile_size=(32, 32),
|
|
712
|
-
consumer=consumer,
|
|
713
|
-
)
|
|
714
|
-
self.animation_panel._data_root = self.data_root
|
|
715
|
-
except Exception as e:
|
|
716
|
-
error_handler.capture(e, context="init_animation_panel")
|
|
717
|
-
self.notifications.notify(f"Failed to init animation panel: {e}")
|
|
718
|
-
|
|
719
679
|
def undo(self):
|
|
720
680
|
self.tilemap.undo()
|
|
721
681
|
if self.tile_grid_widget:
|
|
@@ -730,6 +690,12 @@ class Editor:
|
|
|
730
690
|
if self.tile_grid_widget:
|
|
731
691
|
self.tile_grid_widget.show_grid = not self.tile_grid_widget.show_grid
|
|
732
692
|
|
|
693
|
+
def toggle_map_boundary(self):
|
|
694
|
+
if self.tile_grid_widget:
|
|
695
|
+
self.tile_grid_widget.show_map_boundary = (
|
|
696
|
+
not self.tile_grid_widget.show_map_boundary
|
|
697
|
+
)
|
|
698
|
+
|
|
733
699
|
def cycle_theme(self):
|
|
734
700
|
"""Cycle through available themes."""
|
|
735
701
|
theme_names = list(THEMES.keys())
|
|
@@ -1145,6 +1111,10 @@ class Editor:
|
|
|
1145
1111
|
self.layer_type_dialog.handle_event(event)
|
|
1146
1112
|
continue
|
|
1147
1113
|
|
|
1114
|
+
if self.resize_map_dialog and self.resize_map_dialog.active:
|
|
1115
|
+
self.resize_map_dialog.handle_event(event)
|
|
1116
|
+
continue
|
|
1117
|
+
|
|
1148
1118
|
if self.map_setup_widget and self.map_setup_widget.visible:
|
|
1149
1119
|
if self.map_setup_widget.handle_event(event):
|
|
1150
1120
|
continue
|
|
@@ -1242,7 +1212,7 @@ class Editor:
|
|
|
1242
1212
|
self.cycle_theme()
|
|
1243
1213
|
continue
|
|
1244
1214
|
if event.key == pygame.K_b and (ctrl_held or meta_held):
|
|
1245
|
-
self.
|
|
1215
|
+
self.toggle_map_boundary()
|
|
1246
1216
|
continue
|
|
1247
1217
|
if pygame.K_1 <= event.key <= pygame.K_9:
|
|
1248
1218
|
if not (self.node_editor and self.node_editor.visible and self.node_editor.editing_field):
|
|
@@ -1259,11 +1229,6 @@ class Editor:
|
|
|
1259
1229
|
if self.toolbar and self.toolbar.handle_event(event):
|
|
1260
1230
|
continue
|
|
1261
1231
|
|
|
1262
|
-
if self.left_panel_visible and self.animation_panel:
|
|
1263
|
-
if hasattr(self.animation_panel, "handle_event"):
|
|
1264
|
-
if self.animation_panel.handle_event(event):
|
|
1265
|
-
continue
|
|
1266
|
-
|
|
1267
1232
|
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
|
|
1268
1233
|
mx, my = event.pos
|
|
1269
1234
|
edge_x = self.width - self._effective_selector_w
|
|
@@ -1310,10 +1275,6 @@ class Editor:
|
|
|
1310
1275
|
if self.tile_grid_widget:
|
|
1311
1276
|
self.tile_grid_widget.update()
|
|
1312
1277
|
|
|
1313
|
-
if self.left_panel_visible and self.animation_panel:
|
|
1314
|
-
if hasattr(self.animation_panel, "update"):
|
|
1315
|
-
self.animation_panel.update()
|
|
1316
|
-
|
|
1317
1278
|
self.screen.fill(COLORS.bg)
|
|
1318
1279
|
self.tooltip.hide()
|
|
1319
1280
|
|
|
@@ -1341,20 +1302,6 @@ class Editor:
|
|
|
1341
1302
|
self.screen.blit(overlay, (0, 0))
|
|
1342
1303
|
self.regex_automap_designer.draw(self.screen)
|
|
1343
1304
|
|
|
1344
|
-
if self.left_panel_visible and self.animation_panel:
|
|
1345
|
-
panel_surf = pygame.Surface((self.left_panel_w, self.height), pygame.SRCALPHA)
|
|
1346
|
-
panel_surf.fill((*COLORS.panel_alt, 255))
|
|
1347
|
-
self.screen.blit(panel_surf, (0, 65))
|
|
1348
|
-
|
|
1349
|
-
pygame.draw.rect(
|
|
1350
|
-
self.screen,
|
|
1351
|
-
COLORS.border,
|
|
1352
|
-
Rect(0, 65, self.left_panel_w, self.height - 65),
|
|
1353
|
-
1,
|
|
1354
|
-
)
|
|
1355
|
-
if hasattr(self.animation_panel, "draw"):
|
|
1356
|
-
self.animation_panel.draw(self.screen)
|
|
1357
|
-
|
|
1358
1305
|
self.notifications.draw(self.screen)
|
|
1359
1306
|
|
|
1360
1307
|
if self.map_setup_widget and self.map_setup_widget.visible:
|
|
@@ -1373,16 +1320,18 @@ class Editor:
|
|
|
1373
1320
|
overlay.fill((0, 0, 0, 150))
|
|
1374
1321
|
self.screen.blit(overlay, (0, 0))
|
|
1375
1322
|
self.tileset_type_dialog.draw(self.screen)
|
|
1376
|
-
if self.
|
|
1323
|
+
if self.resize_map_dialog and self.resize_map_dialog.active:
|
|
1324
|
+
self.resize_map_dialog.draw(self.screen)
|
|
1325
|
+
if self.layer_type_dialog.active:
|
|
1377
1326
|
overlay = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
|
|
1378
1327
|
overlay.fill((0, 0, 0, 150))
|
|
1379
1328
|
self.screen.blit(overlay, (0, 0))
|
|
1380
|
-
self.
|
|
1381
|
-
if self.
|
|
1329
|
+
self.layer_type_dialog.draw(self.screen)
|
|
1330
|
+
if self.confirm_dialog.active:
|
|
1382
1331
|
overlay = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
|
|
1383
1332
|
overlay.fill((0, 0, 0, 150))
|
|
1384
1333
|
self.screen.blit(overlay, (0, 0))
|
|
1385
|
-
self.
|
|
1334
|
+
self.confirm_dialog.draw(self.screen)
|
|
1386
1335
|
|
|
1387
1336
|
if self.loading_state["active"]:
|
|
1388
1337
|
overlay = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
|
|
@@ -217,6 +217,7 @@ class Layer:
|
|
|
217
217
|
start_pos: tuple[int, int],
|
|
218
218
|
new_tile_data: TypeTile,
|
|
219
219
|
map_size: tuple[int, int],
|
|
220
|
+
offset: tuple[int, int] = (0, 0),
|
|
220
221
|
) -> None:
|
|
221
222
|
"""Replace contiguous tiles of the same type starting from start_pos."""
|
|
222
223
|
if self.locked or self.layer_type != "tile":
|
|
@@ -238,7 +239,13 @@ class Layer:
|
|
|
238
239
|
while queue:
|
|
239
240
|
curr = queue.pop(0)
|
|
240
241
|
|
|
241
|
-
|
|
242
|
+
ox, oy = offset
|
|
243
|
+
if (
|
|
244
|
+
curr[0] < ox
|
|
245
|
+
or curr[0] >= ox + map_size[0]
|
|
246
|
+
or curr[1] < oy
|
|
247
|
+
or curr[1] >= oy + map_size[1]
|
|
248
|
+
):
|
|
242
249
|
continue
|
|
243
250
|
|
|
244
251
|
curr_tile = self.tiles.get(curr)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Pure camera math — world (document) <-> screen transforms.
|
|
2
|
+
|
|
3
|
+
No pygame imports: this module is fully usable and testable headlessly.
|
|
4
|
+
Holds viewport origin and scroll as plain floats; the viewport provides
|
|
5
|
+
the pygame-side rect/bilt machinery.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
MIN_ZOOM = 0.1
|
|
11
|
+
MAX_ZOOM = 16.0
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _clamp_zoom(value: float) -> float:
|
|
15
|
+
return max(MIN_ZOOM, min(MAX_ZOOM, value))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Camera:
|
|
19
|
+
"""One monotonic linear transform between document and screen space.
|
|
20
|
+
|
|
21
|
+
screen = (local - origin) * zoom + viewport_topleft + scroll
|
|
22
|
+
local = (screen - viewport_topleft - scroll) / zoom + origin
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
viewport_x: float = 0.0,
|
|
28
|
+
viewport_y: float = 0.0,
|
|
29
|
+
zoom: float = 1.0,
|
|
30
|
+
scroll_x: float = 0.0,
|
|
31
|
+
scroll_y: float = 0.0,
|
|
32
|
+
):
|
|
33
|
+
self.viewport_x = float(viewport_x)
|
|
34
|
+
self.viewport_y = float(viewport_y)
|
|
35
|
+
self._zoom = _clamp_zoom(float(zoom))
|
|
36
|
+
self.scroll_x = float(scroll_x)
|
|
37
|
+
self.scroll_y = float(scroll_y)
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def zoom(self) -> float:
|
|
41
|
+
return self._zoom
|
|
42
|
+
|
|
43
|
+
@zoom.setter
|
|
44
|
+
def zoom(self, value: float) -> None:
|
|
45
|
+
self._zoom = _clamp_zoom(float(value))
|
|
46
|
+
|
|
47
|
+
def world_to_screen(self, x: float, y: float) -> tuple[float, float]:
|
|
48
|
+
return (
|
|
49
|
+
self.viewport_x + self.scroll_x + x * self._zoom,
|
|
50
|
+
self.viewport_y + self.scroll_y + y * self._zoom,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def screen_to_world(self, sx: float, sy: float) -> tuple[float, float]:
|
|
54
|
+
if self._zoom <= 0:
|
|
55
|
+
return (0.0, 0.0)
|
|
56
|
+
return (
|
|
57
|
+
(sx - self.viewport_x - self.scroll_x) / self._zoom,
|
|
58
|
+
(sy - self.viewport_y - self.scroll_y) / self._zoom,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def fit(self, world_size: tuple[float, float], viewport_size: tuple[float, float]) -> None:
|
|
62
|
+
"""Zoom so the whole document fits the viewport, centered."""
|
|
63
|
+
ww, wh = world_size
|
|
64
|
+
vw, vh = viewport_size
|
|
65
|
+
if ww <= 0 or wh <= 0 or vw <= 0 or vh <= 0:
|
|
66
|
+
self.reset()
|
|
67
|
+
return
|
|
68
|
+
self._zoom = _clamp_zoom(min(vw / ww, vh / wh))
|
|
69
|
+
self.scroll_x = (vw - ww * self._zoom) / 2.0
|
|
70
|
+
self.scroll_y = (vh - wh * self._zoom) / 2.0
|
|
71
|
+
|
|
72
|
+
def reset(self) -> None:
|
|
73
|
+
"""100% zoom, document origin at the viewport top-left."""
|
|
74
|
+
self._zoom = 1.0
|
|
75
|
+
self.scroll_x = 0.0
|
|
76
|
+
self.scroll_y = 0.0
|
|
77
|
+
|
|
78
|
+
def zoom_at(self, screen_point: tuple[float, float], factor: float) -> None:
|
|
79
|
+
"""Zoom by factor while keeping the world point under the cursor fixed."""
|
|
80
|
+
sx, sy = screen_point
|
|
81
|
+
wx, wy = self.screen_to_world(sx, sy)
|
|
82
|
+
new_zoom = _clamp_zoom(self._zoom * factor)
|
|
83
|
+
if abs(new_zoom - self._zoom) < 1e-9:
|
|
84
|
+
return
|
|
85
|
+
self._zoom = new_zoom
|
|
86
|
+
self.scroll_x = sx - self.viewport_x - wx * self._zoom
|
|
87
|
+
self.scroll_y = sy - self.viewport_y - wy * self._zoom
|
|
88
|
+
|
|
89
|
+
def pan(self, dx: float, dy: float) -> None:
|
|
90
|
+
"""Scroll by a screen-space delta (content follows the cursor)."""
|
|
91
|
+
self.scroll_x += float(dx)
|
|
92
|
+
self.scroll_y += float(dy)
|
|
93
|
+
|
|
94
|
+
def world_to_screen_rect(self, x: float, y: float, w: float, h: float) -> tuple[float, float, float, float]:
|
|
95
|
+
"""Screen-space rect for a world-space rect (floats)."""
|
|
96
|
+
sx, sy = self.world_to_screen(x, y)
|
|
97
|
+
return (sx, sy, w * self._zoom, h * self._zoom)
|