tilemap-editor 3.3.8__tar.gz → 3.3.10__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.
Files changed (208) hide show
  1. {tilemap_editor-3.3.8/src/tilemap_editor.egg-info → tilemap_editor-3.3.10}/PKG-INFO +1 -1
  2. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/pyproject.toml +1 -1
  3. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/editor.py +14 -5
  4. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/cli.py +11 -1
  5. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/settings.py +35 -1
  6. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10/src/tilemap_editor.egg-info}/PKG-INFO +1 -1
  7. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/tile_grid.py +84 -7
  8. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/node_editor.py +24 -8
  9. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/toolbar.py +15 -12
  10. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/tests/test_project_paths.py +81 -1
  11. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/LICENSE +0 -0
  12. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/MANIFEST.in +0 -0
  13. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/README.md +0 -0
  14. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/fonts/jetbrain-fonts/JetBrainsMono-Bold.ttf +0 -0
  15. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/fonts/jetbrain-fonts/JetBrainsMono-BoldItalic.ttf +0 -0
  16. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/fonts/jetbrain-fonts/JetBrainsMono-Italic.ttf +0 -0
  17. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/fonts/jetbrain-fonts/JetBrainsMono-Regular.ttf +0 -0
  18. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/fonts/noto/NotoSans-Bold.ttf +0 -0
  19. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/fonts/noto/NotoSans-BoldItalic.ttf +0 -0
  20. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/fonts/noto/NotoSans-Italic.ttf +0 -0
  21. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
  22. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/arrow-down.svg +0 -0
  23. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/check.svg +0 -0
  24. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/checked.svg +0 -0
  25. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/close.svg +0 -0
  26. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/duplicate.svg +0 -0
  27. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/error.svg +0 -0
  28. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/file.svg +0 -0
  29. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/filedead.svg +0 -0
  30. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/fit.svg +0 -0
  31. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/folder.svg +0 -0
  32. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/grid.svg +0 -0
  33. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/image.svg +0 -0
  34. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/info.svg +0 -0
  35. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/load.svg +0 -0
  36. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/loop.svg +0 -0
  37. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/onion.svg +0 -0
  38. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/pan.svg +0 -0
  39. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/pause.svg +0 -0
  40. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/pencil.svg +0 -0
  41. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/play.svg +0 -0
  42. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/plus.svg +0 -0
  43. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/radio.svg +0 -0
  44. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/reset.svg +0 -0
  45. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/save.svg +0 -0
  46. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/skip-back.svg +0 -0
  47. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/skip-forward.svg +0 -0
  48. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/stop.svg +0 -0
  49. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/tilemap.svg +0 -0
  50. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/tileset.svg +0 -0
  51. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/unchecked.svg +0 -0
  52. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/warning.svg +0 -0
  53. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/zoomin.svg +0 -0
  54. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/assets/icons/zoomout.svg +0 -0
  55. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/setup.cfg +0 -0
  56. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/configs/themes.py +0 -0
  57. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/constants.py +0 -0
  58. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/event_map.py +0 -0
  59. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/layers.py +0 -0
  60. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/main.py +0 -0
  61. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/node_manager.py +0 -0
  62. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/nodes.py +0 -0
  63. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/__init__.py +0 -0
  64. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/character_collision/__init__.py +0 -0
  65. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/character_collision/editor.py +0 -0
  66. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/character_collision/models.py +0 -0
  67. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/character_collision/protocols.py +0 -0
  68. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/character_collision/shape_editor.py +0 -0
  69. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/character_collision/standalone.py +0 -0
  70. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/object_tileset_collision/__init__.py +0 -0
  71. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/object_tileset_collision/editor.py +0 -0
  72. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/object_tileset_collision/models.py +0 -0
  73. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/object_tileset_collision/protocols.py +0 -0
  74. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/object_tileset_collision/standalone.py +0 -0
  75. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_animation/__init__.py +0 -0
  76. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_animation/__main__.py +0 -0
  77. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_animation/clipboard_util.py +0 -0
  78. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_animation/editor.py +0 -0
  79. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_animation/frame_picker.py +0 -0
  80. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_animation/models.py +0 -0
  81. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_animation/preview.py +0 -0
  82. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_animation/protocols.py +0 -0
  83. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_animation/runtime_load.py +0 -0
  84. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_animation/standalone.py +0 -0
  85. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_animation/timeline.py +0 -0
  86. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_animation/validation.py +0 -0
  87. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_editor/__init__.py +0 -0
  88. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_editor/editor.py +0 -0
  89. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/sprite_editor/standalone.py +0 -0
  90. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/tileset_collision/__init__.py +0 -0
  91. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/tileset_collision/collision_painter.py +0 -0
  92. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/tileset_collision/editor.py +0 -0
  93. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/tileset_collision/models.py +0 -0
  94. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/tileset_collision/protocols.py +0 -0
  95. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/plugins/tileset_collision/standalone.py +0 -0
  96. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/standalone_automap.py +0 -0
  97. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/standalone_error_console.py +0 -0
  98. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/standalone_filemanager.py +0 -0
  99. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/standalone_image_viewer.py +0 -0
  100. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap.py +0 -0
  101. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/__init__.py +0 -0
  102. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/__main__.py +0 -0
  103. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/__init__.py +0 -0
  104. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Bold.ttf +0 -0
  105. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-BoldItalic.ttf +0 -0
  106. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Italic.ttf +0 -0
  107. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Regular.ttf +0 -0
  108. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/fonts/noto/NotoSans-Bold.ttf +0 -0
  109. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/fonts/noto/NotoSans-BoldItalic.ttf +0 -0
  110. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/fonts/noto/NotoSans-Italic.ttf +0 -0
  111. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
  112. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/ToolMove.svg +0 -0
  113. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/arrow-down.svg +0 -0
  114. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/check.svg +0 -0
  115. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/checked.svg +0 -0
  116. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/close.svg +0 -0
  117. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/duplicate.svg +0 -0
  118. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/error.svg +0 -0
  119. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/file.svg +0 -0
  120. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/filedead.svg +0 -0
  121. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/fit.svg +0 -0
  122. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/folder.svg +0 -0
  123. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/grid.svg +0 -0
  124. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/image.svg +0 -0
  125. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/info.svg +0 -0
  126. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/load.svg +0 -0
  127. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/loop.svg +0 -0
  128. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/onion.svg +0 -0
  129. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/pan.svg +0 -0
  130. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/pause.svg +0 -0
  131. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/pencil.svg +0 -0
  132. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/play.svg +0 -0
  133. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/plus.svg +0 -0
  134. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/radio.svg +0 -0
  135. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/reset.svg +0 -0
  136. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/save.svg +0 -0
  137. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/skip-back.svg +0 -0
  138. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/skip-forward.svg +0 -0
  139. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/stop.svg +0 -0
  140. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/tilemap.svg +0 -0
  141. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/tileset.svg +0 -0
  142. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/unchecked.svg +0 -0
  143. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/warning.svg +0 -0
  144. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/zoomin.svg +0 -0
  145. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/assets/icons/zoomout.svg +0 -0
  146. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor/main.py +0 -0
  147. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor.egg-info/SOURCES.txt +0 -0
  148. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor.egg-info/dependency_links.txt +0 -0
  149. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor.egg-info/entry_points.txt +0 -0
  150. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor.egg-info/requires.txt +0 -0
  151. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/tilemap_editor.egg-info/top_level.txt +0 -0
  152. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/ttypes/__init__.py +0 -0
  153. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/ttypes/tilemap.py +0 -0
  154. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/utils/__init__.py +0 -0
  155. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/utils/editor_preference.py +0 -0
  156. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/utils/error_handler.py +0 -0
  157. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/utils/font_manager.py +0 -0
  158. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/utils/history.py +0 -0
  159. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/utils/icon_manager.py +0 -0
  160. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/utils/icons_cache.py +0 -0
  161. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/utils/log_capture.py +0 -0
  162. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/utils/project_paths.py +0 -0
  163. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/utils/serialization.py +0 -0
  164. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/utils/standalone.py +0 -0
  165. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/utils/validation.py +0 -0
  166. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/__init__.py +0 -0
  167. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/automap_models.py +0 -0
  168. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/autotile_template.py +0 -0
  169. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/autotiler.py +0 -0
  170. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/filemanager.py +0 -0
  171. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/input.py +0 -0
  172. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/layer_selector.py +0 -0
  173. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/map_properties.py +0 -0
  174. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/mapsetup.py +0 -0
  175. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/particle_presets.py +0 -0
  176. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/particle_system.py +0 -0
  177. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/regex_automap_designer.py +0 -0
  178. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/spritesheet_grid.py +0 -0
  179. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/tile_selector.py +0 -0
  180. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/checkbox.py +0 -0
  181. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/collision_layer_mask.py +0 -0
  182. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/collision_layer_sidebar.py +0 -0
  183. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/confirm_dialog.py +0 -0
  184. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/draw_utils.py +0 -0
  185. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/fileinput.py +0 -0
  186. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/layer_type_dialog.py +0 -0
  187. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/menubar.py +0 -0
  188. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/mode_indicator.py +0 -0
  189. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/node_selector.py +0 -0
  190. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/notification.py +0 -0
  191. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/particle_config_dialog.py +0 -0
  192. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/property_editor.py +0 -0
  193. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/region_selector.py +0 -0
  194. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/status_bar.py +0 -0
  195. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/theme.py +0 -0
  196. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/tileset_type_dialog.py +0 -0
  197. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/src/widgets/ui/tooltip.py +0 -0
  198. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/tests/test_animation_library_grid_offset.py +0 -0
  199. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/tests/test_collision_layer_mask.py +0 -0
  200. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/tests/test_collision_layer_sidebar.py +0 -0
  201. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/tests/test_editor_pan_mode.py +0 -0
  202. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/tests/test_render_scale.py +0 -0
  203. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/tests/test_sprite_animation_editor_grid.py +0 -0
  204. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/tests/test_tile_grid_selection.py +0 -0
  205. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/tests/test_tile_selector_pick.py +0 -0
  206. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/tests/test_tilemap_save.py +0 -0
  207. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/tests/test_timeline_invalidate_cache.py +0 -0
  208. {tilemap_editor-3.3.8 → tilemap_editor-3.3.10}/tests/test_toolbar_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tilemap-editor
3
- Version: 3.3.8
3
+ Version: 3.3.10
4
4
  Summary: Pygame tilemap editor with SVG icons, professional UI, and sprite animation tools
5
5
  Author: tilemap editor contributors
6
6
  License: Proprietary
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tilemap-editor"
7
- version = "3.3.8"
7
+ version = "3.3.10"
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"
@@ -158,6 +158,7 @@ class Editor:
158
158
  self.eraser_mode = False
159
159
  self.select_mode = False
160
160
  self.node_editing_mode = False
161
+ self.show_nodes = False
161
162
  self._prev_tool = None
162
163
 
163
164
  if isinstance(size, tuple) and len(size) == 2:
@@ -1191,6 +1192,14 @@ class Editor:
1191
1192
  elif event.key == pygame.K_y and (ctrl_held or meta_held):
1192
1193
  self.tilemap.redo()
1193
1194
  continue
1195
+ elif event.key == pygame.K_n and (ctrl_held or meta_held) and shift_held:
1196
+ self.node_editing_mode = not self.node_editing_mode
1197
+ if self.node_editing_mode:
1198
+ self.show_nodes = False
1199
+ self.pan_mode = False
1200
+ self.select_mode = False
1201
+ self.eraser_mode = False
1202
+ continue
1194
1203
  elif event.key == pygame.K_n and (ctrl_held or meta_held):
1195
1204
  self.open_map_setup()
1196
1205
  continue
@@ -1241,16 +1250,16 @@ class Editor:
1241
1250
  self.tilemap.layer_manager.set_active_layer(idx)
1242
1251
  continue
1243
1252
 
1244
- # Priority 5: Toolbar
1245
- if self.toolbar and self.toolbar.handle_event(event):
1246
- continue
1247
-
1248
- # Priority 5.5: Node selector & editor (when node mode active)
1253
+ # Priority 5: Node selector & editor (float on top, check events first)
1249
1254
  if self.node_selector and self.node_selector.handle_event(event):
1250
1255
  continue
1251
1256
  if self.node_editor and self.node_editor.handle_event(event):
1252
1257
  continue
1253
1258
 
1259
+ # Priority 5.5: Toolbar
1260
+ if self.toolbar and self.toolbar.handle_event(event):
1261
+ continue
1262
+
1254
1263
  # Priority 6: Dockable animation panel
1255
1264
  if self.left_panel_visible and self.animation_panel:
1256
1265
  if hasattr(self.animation_panel, "handle_event"):
@@ -5,7 +5,7 @@ import sys
5
5
 
6
6
  from editor import Editor
7
7
  from utils import error_handler, error_context
8
- from .settings import init_settings
8
+ from .settings import init_settings, update_settings
9
9
 
10
10
 
11
11
  def _parse_size(text: str) -> tuple[int, int]:
@@ -29,6 +29,12 @@ def main() -> None:
29
29
  help="Also create src/main.py boilerplate"
30
30
  )
31
31
 
32
+ update_parser = subparsers.add_parser("update", help="Update settings.json base_path for current device")
33
+ update_parser.add_argument(
34
+ "--path", default=None,
35
+ help="Explicit base path (default: resolves cwd to absolute path)"
36
+ )
37
+
32
38
  run_parser = subparsers.add_parser("run", help="Run the tilemap editor")
33
39
  run_parser.add_argument(
34
40
  "--size", default="1500x900", help="Window size as WIDTHxHEIGHT"
@@ -43,6 +49,10 @@ def main() -> None:
43
49
  init_settings(generate_main=args.with_main)
44
50
  return
45
51
 
52
+ if args.command == "update":
53
+ update_settings(path=args.path)
54
+ return
55
+
46
56
  if args.command is None or args.command == "run":
47
57
  _run_editor(args)
48
58
  return
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  import sys
3
3
  from pathlib import Path
4
+ from typing import Optional
4
5
 
5
6
 
6
7
  def init_settings(generate_main: bool = False) -> None:
@@ -71,4 +72,37 @@ if __name__ == "__main__":
71
72
  with open(main_file, "w") as f:
72
73
  f.write(boilerplate)
73
74
 
74
- print(f"Created {main_file}")
75
+ print(f"Created {main_file}")
76
+
77
+
78
+ def update_settings(path: Optional[str] = None) -> None:
79
+ """Update base_path in an existing settings.json to the current device path.
80
+
81
+ If no path is given, resolves the current working directory to an absolute
82
+ path and writes it as base_path. This makes settings.json portable when
83
+ shared across devices — run update on each device to fix the path.
84
+
85
+ Args:
86
+ path: Optional explicit base_path to write (e.g. --path /home/user/project)
87
+ """
88
+ settings_file = Path.cwd() / "settings.json"
89
+
90
+ if not settings_file.exists():
91
+ raise RuntimeError(
92
+ "settings.json not found. Run 'tilemap-editor init' first."
93
+ )
94
+
95
+ with open(settings_file, "r") as f:
96
+ config = json.load(f)
97
+
98
+ if path is not None:
99
+ new_base = str(Path(path).expanduser().resolve())
100
+ else:
101
+ new_base = str(Path.cwd().resolve())
102
+
103
+ config["base_path"] = new_base
104
+
105
+ with open(settings_file, "w") as f:
106
+ json.dump(config, f, indent=4)
107
+
108
+ print(f"Updated base_path to '{new_base}' in {settings_file}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tilemap-editor
3
- Version: 3.3.8
3
+ Version: 3.3.10
4
4
  Summary: Pygame tilemap editor with SVG icons, professional UI, and sprite animation tools
5
5
  Author: tilemap editor contributors
6
6
  License: Proprietary
@@ -181,6 +181,10 @@ class TileGrid:
181
181
  if self.editor.node_editing_mode:
182
182
  return self._handle_node_event(event)
183
183
 
184
+ if self.editor.show_nodes:
185
+ if self._handle_show_node_event(event):
186
+ return True
187
+
184
188
  mouse_pos = pygame.mouse.get_pos()
185
189
  is_hovering = self.rect.collidepoint(mouse_pos)
186
190
  if event.type == pygame.KEYDOWN:
@@ -1502,6 +1506,7 @@ class TileGrid:
1502
1506
  return
1503
1507
 
1504
1508
  editing = self.editor.node_editing_mode
1509
+ showing = self.editor.show_nodes
1505
1510
 
1506
1511
  node_type_colors = {
1507
1512
  "area": (80, 220, 120), # Green / Emerald
@@ -1513,7 +1518,8 @@ class TileGrid:
1513
1518
  "particle_emitter": (240, 140, 200), # Pink / Magenta
1514
1519
  }
1515
1520
 
1516
- active = nm.get_active_node() if editing else None
1521
+ visible = editing or showing
1522
+ active = nm.get_active_node() if visible else None
1517
1523
  for node in nm.nodes.values():
1518
1524
  sx, sy = self._node_to_screen(node.area.x, node.area.y)
1519
1525
  sw, sh = self._node_screen_size(node.area.w, node.area.h)
@@ -1521,8 +1527,13 @@ class TileGrid:
1521
1527
  if not self.rect.colliderect(Rect(sx, sy, sw, sh)):
1522
1528
  continue
1523
1529
 
1524
- is_active = editing and active is not None and active.node_id == node.node_id
1525
- alpha = 180 if is_active else (80 if editing else 40)
1530
+ is_active = visible and active is not None and active.node_id == node.node_id
1531
+ if editing:
1532
+ alpha = 180 if is_active else 80
1533
+ elif showing:
1534
+ alpha = 140 if is_active else 70
1535
+ else:
1536
+ alpha = 40
1526
1537
 
1527
1538
  color = node_type_colors.get(node.node_type, (80, 220, 120))
1528
1539
 
@@ -1533,14 +1544,14 @@ class TileGrid:
1533
1544
  border_color = (*color, alpha)
1534
1545
  pygame.draw.rect(screen, border_color, Rect(sx, sy, sw, sh), max(1, int(2 * self.zoom_level)))
1535
1546
 
1536
- if editing:
1547
+ if visible:
1537
1548
  label = self.font_status.render(node.name, True, (255, 255, 255))
1538
1549
  label_bg = pygame.Surface((label.get_width() + 4, label.get_height() + 2), pygame.SRCALPHA)
1539
1550
  label_bg.fill((0, 0, 0, 160))
1540
1551
  screen.blit(label_bg, (sx, sy - label.get_height() - 2))
1541
1552
  screen.blit(label, (sx + 2, sy - label.get_height() - 1))
1542
1553
 
1543
- if is_active:
1554
+ if is_active and editing:
1544
1555
  self._draw_node_handles(screen, Rect(sx, sy, sw, sh), color)
1545
1556
 
1546
1557
  self._draw_particle_previews(screen)
@@ -1563,8 +1574,8 @@ class TileGrid:
1563
1574
  if active_id not in self._particle_previews:
1564
1575
  self._particle_previews[active_id] = ParticlePreview(dict(active.properties))
1565
1576
  preview = self._particle_previews[active_id]
1566
- preview.config = active.properties
1567
- preview.update(dt, active.area.x, active.area.y, active.area.w, active.area.h)
1577
+ rs = self.editor.tilemap.render_scale
1578
+ preview.update(dt, active.area.x, active.area.y, active.area.w * rs, active.area.h * rs)
1568
1579
  self._last_active_node_id = active_id
1569
1580
  else:
1570
1581
  self._particle_previews.clear()
@@ -1630,6 +1641,72 @@ class TileGrid:
1630
1641
  return name
1631
1642
  return None
1632
1643
 
1644
+ def _handle_show_node_event(self, event) -> bool:
1645
+ nm = getattr(self.editor, "node_manager", None)
1646
+ if not nm or not nm.nodes:
1647
+ return False
1648
+
1649
+ mouse_pos = pygame.mouse.get_pos()
1650
+ is_hover = self.rect.collidepoint(mouse_pos)
1651
+
1652
+ if event.type == pygame.MOUSEBUTTONDOWN:
1653
+ if event.button == 1 and is_hover:
1654
+ wx, wy = self.screen_to_world(mouse_pos)
1655
+ active = nm.get_active_node()
1656
+
1657
+ if active:
1658
+ sw, sh = self._node_screen_size(active.area.w, active.area.h)
1659
+ sx, sy = self._node_to_screen(active.area.x, active.area.y)
1660
+ if Rect(sx, sy, sw, sh).collidepoint(mouse_pos):
1661
+ self._node_drag_state = "moving"
1662
+ self._node_drag_start = (wx, wy)
1663
+ self._node_original_rect = NodeRect(
1664
+ active.area.x, active.area.y,
1665
+ active.area.w, active.area.h,
1666
+ )
1667
+ return True
1668
+
1669
+ for node in nm.nodes.values():
1670
+ if node.node_id == active.node_id:
1671
+ continue
1672
+ nsx, nsy = self._node_to_screen(node.area.x, node.area.y)
1673
+ nsw, nsh = self._node_screen_size(node.area.w, node.area.h)
1674
+ if Rect(nsx, nsy, nsw, nsh).collidepoint(mouse_pos):
1675
+ nm.set_active_node(node.node_id)
1676
+ return True
1677
+ else:
1678
+ for node in nm.nodes.values():
1679
+ nsx, nsy = self._node_to_screen(node.area.x, node.area.y)
1680
+ nsw, nsh = self._node_screen_size(node.area.w, node.area.h)
1681
+ if Rect(nsx, nsy, nsw, nsh).collidepoint(mouse_pos):
1682
+ nm.set_active_node(node.node_id)
1683
+ return True
1684
+
1685
+ nm.set_active_node(None)
1686
+ return False
1687
+
1688
+ elif event.type == pygame.MOUSEBUTTONUP:
1689
+ if event.button == 1 and self._node_drag_state is not None:
1690
+ self._node_drag_state = None
1691
+ self._node_drag_handle = None
1692
+ self._node_original_rect = None
1693
+ return True
1694
+
1695
+ elif event.type == pygame.MOUSEMOTION:
1696
+ if self._node_drag_state is not None and is_hover:
1697
+ active = nm.get_active_node()
1698
+ if active and self._node_original_rect:
1699
+ orig = self._node_original_rect
1700
+ wx, wy = self.screen_to_world(mouse_pos)
1701
+ dx = wx - self._node_drag_start[0]
1702
+ dy = wy - self._node_drag_start[1]
1703
+ if self._node_drag_state == "moving":
1704
+ active.area.x = orig.x + dx
1705
+ active.area.y = orig.y + dy
1706
+ return True
1707
+
1708
+ return False
1709
+
1633
1710
  def _handle_node_event(self, event) -> bool:
1634
1711
  nm = getattr(self.editor, "node_manager", None)
1635
1712
  if not nm:
@@ -56,14 +56,30 @@ class NodeEditor:
56
56
  screen_h = self.editor.screen.get_height()
57
57
  panel_w = self.rect.width
58
58
  panel_h = self.rect.height
59
- px = sx + sw + 8
60
- py = sy + sh + 8
61
- if px + panel_w > screen_w - 10:
62
- px = max(10, sx - panel_w - 8)
63
- if py + panel_h > screen_h - 10:
64
- py = max(10, sy - panel_h - 8)
65
- self.rect.x = max(10, min(px, screen_w - panel_w - 10))
66
- self.rect.y = max(10, min(py, screen_h - panel_h - 10))
59
+ pad = 24
60
+
61
+ node_rect = Rect(sx, sy, sw, sh)
62
+ positions = [
63
+ (sx + sw + pad, sy),
64
+ (sx - panel_w - pad, sy),
65
+ (sx, sy + sh + pad),
66
+ (sx, sy - panel_h - pad),
67
+ ]
68
+ best = None
69
+ for px, py in positions:
70
+ px = max(10, min(px, screen_w - panel_w - 10))
71
+ py = max(10, min(py, screen_h - panel_h - 10))
72
+ pr = Rect(px, py, panel_w, panel_h)
73
+ if not pr.colliderect(node_rect):
74
+ best = (px, py)
75
+ break
76
+ if best is None:
77
+ px = max(10, min(sx + sw + pad, screen_w - panel_w - 10))
78
+ py = max(10, min(sy, screen_h - panel_h - 10))
79
+ self.rect.x = px
80
+ self.rect.y = py
81
+ else:
82
+ self.rect.x, self.rect.y = best
67
83
 
68
84
  @property
69
85
  def editing_field(self) -> bool:
@@ -70,11 +70,9 @@ class Toolbar:
70
70
  elif key == "auto":
71
71
  self.editor.toggle_auto_autotile()
72
72
  elif key == "nodes":
73
- self.editor.node_editing_mode = not self.editor.node_editing_mode
74
- if self.editor.node_editing_mode:
75
- self.editor.pan_mode = False
76
- self.editor.select_mode = False
77
- self.editor.eraser_mode = False
73
+ self.editor.show_nodes = not self.editor.show_nodes
74
+ if self.editor.show_nodes:
75
+ self.editor.node_editing_mode = False
78
76
  elif key == "zoom_in":
79
77
  if self.editor.tile_grid_widget:
80
78
  self.editor.tile_grid_widget.zoom_by(0.1)
@@ -98,6 +96,7 @@ class Toolbar:
98
96
 
99
97
  for key, (r, label) in self.buttons.items():
100
98
  is_active = False
99
+ is_show = False
101
100
  if key == "pan":
102
101
  is_active = self.editor.pan_mode
103
102
  elif key == "select":
@@ -112,14 +111,18 @@ class Toolbar:
112
111
  elif key == "auto":
113
112
  is_active = self.editor.autotile_mode
114
113
  elif key == "nodes":
115
- is_active = self.editor.node_editing_mode
114
+ is_active = self.editor.show_nodes
115
+ is_show = False
116
116
 
117
117
  hover = r.collidepoint(mouse_pos)
118
- bg = (
119
- COLORS.accent_active
120
- if is_active
121
- else (COLORS.hover if hover else COLORS.panel_alt)
122
- )
118
+ if is_active:
119
+ bg = COLORS.accent_active
120
+ elif is_show:
121
+ bg = COLORS.selected
122
+ elif hover:
123
+ bg = COLORS.hover
124
+ else:
125
+ bg = COLORS.panel_alt
123
126
  pygame.draw.rect(screen, bg, r, border_radius=SHAPE.radius_sm)
124
127
  pygame.draw.rect(
125
128
  screen, COLORS.border_soft, r, 1, border_radius=SHAPE.radius_sm
@@ -146,7 +149,7 @@ class Toolbar:
146
149
  elif key == "auto":
147
150
  tip = "Auto-Autotile"
148
151
  elif key == "nodes":
149
- tip = "Node Mode (Ctrl+Shift+N)"
152
+ tip = "Show Nodes (Ctrl+Shift+N for Edit mode)" if not self.editor.show_nodes else "Hide Nodes"
150
153
  elif key == "zoom_in":
151
154
  tip = "Zoom In (Ctrl+Wheel)"
152
155
  elif key == "zoom_out":
@@ -10,7 +10,7 @@ import sys
10
10
  sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
11
11
 
12
12
  from utils.project_paths import to_project_path, resolve_project_path
13
- from tilemap_editor.settings import init_settings
13
+ from tilemap_editor.settings import init_settings, update_settings
14
14
 
15
15
 
16
16
  @pytest.fixture
@@ -143,3 +143,83 @@ class TestInitSettings:
143
143
  assert src_main.exists()
144
144
  finally:
145
145
  os.chdir(str(orig_cwd))
146
+
147
+
148
+ class TestUpdateSettings:
149
+ def test_updates_base_path_to_cwd_when_no_path_given(self):
150
+ with tempfile.TemporaryDirectory() as tmp:
151
+ tmp_path = Path(tmp).resolve()
152
+ orig_cwd = Path.cwd()
153
+ os.chdir(str(tmp_path))
154
+ try:
155
+ settings_file = tmp_path / "settings.json"
156
+ with open(settings_file, "w") as f:
157
+ json.dump({"base_path": "/old/path", "data_path": "data"}, f)
158
+
159
+ update_settings()
160
+
161
+ with open(settings_file) as f:
162
+ cfg = json.load(f)
163
+ assert cfg["base_path"] == str(tmp_path)
164
+ assert cfg["data_path"] == "data"
165
+ finally:
166
+ os.chdir(str(orig_cwd))
167
+
168
+ def test_updates_base_path_to_given_path(self):
169
+ with tempfile.TemporaryDirectory() as tmp:
170
+ tmp_path = Path(tmp).resolve()
171
+ orig_cwd = Path.cwd()
172
+ os.chdir(str(tmp_path))
173
+ try:
174
+ settings_file = tmp_path / "settings.json"
175
+ with open(settings_file, "w") as f:
176
+ json.dump({"base_path": "/old/path", "data_path": "data"}, f)
177
+
178
+ new_path = tmp_path / "some" / "other"
179
+ update_settings(path=str(new_path))
180
+
181
+ with open(settings_file) as f:
182
+ cfg = json.load(f)
183
+ assert cfg["base_path"] == str(new_path.resolve())
184
+ finally:
185
+ os.chdir(str(orig_cwd))
186
+
187
+ def test_raises_when_settings_json_missing(self):
188
+ with tempfile.TemporaryDirectory() as tmp:
189
+ tmp_path = Path(tmp).resolve()
190
+ orig_cwd = Path.cwd()
191
+ os.chdir(str(tmp_path))
192
+ try:
193
+ with pytest.raises(RuntimeError, match="settings.json not found"):
194
+ update_settings()
195
+ finally:
196
+ os.chdir(str(orig_cwd))
197
+
198
+ def test_does_not_touch_other_fields(self):
199
+ with tempfile.TemporaryDirectory() as tmp:
200
+ tmp_path = Path(tmp).resolve()
201
+ orig_cwd = Path.cwd()
202
+ os.chdir(str(tmp_path))
203
+ try:
204
+ original = {
205
+ "base_path": "/old/path",
206
+ "data_path": "data",
207
+ "collision_paths": {"tileset": "collision"},
208
+ "nodes_path": "nodes",
209
+ "error_handler": {"log_path": "errors.log"},
210
+ }
211
+ settings_file = tmp_path / "settings.json"
212
+ with open(settings_file, "w") as f:
213
+ json.dump(original, f)
214
+
215
+ update_settings()
216
+
217
+ with open(settings_file) as f:
218
+ cfg = json.load(f)
219
+ assert cfg["base_path"] == str(tmp_path)
220
+ assert cfg["data_path"] == "data"
221
+ assert cfg["collision_paths"] == {"tileset": "collision"}
222
+ assert cfg["nodes_path"] == "nodes"
223
+ assert cfg["error_handler"] == {"log_path": "errors.log"}
224
+ finally:
225
+ os.chdir(str(orig_cwd))
File without changes