tilemap-editor 3.1.6__tar.gz → 3.1.7__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 (182) hide show
  1. {tilemap_editor-3.1.6/src/tilemap_editor.egg-info → tilemap_editor-3.1.7}/PKG-INFO +1 -1
  2. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/pyproject.toml +1 -1
  3. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/sprite_animation/editor.py +56 -24
  4. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/tileset_collision/editor.py +98 -9
  5. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7/src/tilemap_editor.egg-info}/PKG-INFO +1 -1
  6. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/filemanager.py +8 -2
  7. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/input.py +22 -0
  8. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/LICENSE +0 -0
  9. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/MANIFEST.in +0 -0
  10. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/README.md +0 -0
  11. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/fonts/jetbrain-fonts/JetBrainsMono-Bold.ttf +0 -0
  12. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/fonts/jetbrain-fonts/JetBrainsMono-BoldItalic.ttf +0 -0
  13. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/fonts/jetbrain-fonts/JetBrainsMono-Italic.ttf +0 -0
  14. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/fonts/jetbrain-fonts/JetBrainsMono-Regular.ttf +0 -0
  15. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/fonts/noto/NotoSans-Bold.ttf +0 -0
  16. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/fonts/noto/NotoSans-BoldItalic.ttf +0 -0
  17. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/fonts/noto/NotoSans-Italic.ttf +0 -0
  18. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
  19. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/arrow-down.svg +0 -0
  20. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/check.svg +0 -0
  21. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/checked.svg +0 -0
  22. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/close.svg +0 -0
  23. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/duplicate.svg +0 -0
  24. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/error.svg +0 -0
  25. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/file.svg +0 -0
  26. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/filedead.svg +0 -0
  27. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/fit.svg +0 -0
  28. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/folder.svg +0 -0
  29. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/grid.svg +0 -0
  30. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/image.svg +0 -0
  31. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/info.svg +0 -0
  32. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/load.svg +0 -0
  33. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/loop.svg +0 -0
  34. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/pan.svg +0 -0
  35. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/pause.svg +0 -0
  36. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/pencil.svg +0 -0
  37. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/play.svg +0 -0
  38. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/plus.svg +0 -0
  39. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/radio.svg +0 -0
  40. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/reset.svg +0 -0
  41. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/save.svg +0 -0
  42. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/stop.svg +0 -0
  43. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/tilemap.svg +0 -0
  44. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/tileset.svg +0 -0
  45. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/unchecked.svg +0 -0
  46. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/warning.svg +0 -0
  47. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/zoomin.svg +0 -0
  48. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/assets/icons/zoomout.svg +0 -0
  49. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/setup.cfg +0 -0
  50. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/configs/themes.py +0 -0
  51. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/constants.py +0 -0
  52. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/editor.py +0 -0
  53. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/event_map.py +0 -0
  54. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/layers.py +0 -0
  55. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/main.py +0 -0
  56. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/__init__.py +0 -0
  57. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/character_collision/__init__.py +0 -0
  58. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/character_collision/editor.py +0 -0
  59. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/character_collision/models.py +0 -0
  60. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/character_collision/protocols.py +0 -0
  61. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/character_collision/shape_editor.py +0 -0
  62. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/character_collision/standalone.py +0 -0
  63. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/object_tileset_collision/__init__.py +0 -0
  64. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/object_tileset_collision/editor.py +0 -0
  65. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/object_tileset_collision/models.py +0 -0
  66. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/object_tileset_collision/protocols.py +0 -0
  67. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/object_tileset_collision/standalone.py +0 -0
  68. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/sprite_animation/__init__.py +0 -0
  69. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/sprite_animation/__main__.py +0 -0
  70. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/sprite_animation/clipboard_util.py +0 -0
  71. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/sprite_animation/frame_picker.py +0 -0
  72. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/sprite_animation/models.py +0 -0
  73. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/sprite_animation/preview.py +0 -0
  74. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/sprite_animation/protocols.py +0 -0
  75. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/sprite_animation/runtime_load.py +0 -0
  76. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/sprite_animation/standalone.py +0 -0
  77. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/sprite_animation/timeline.py +0 -0
  78. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/sprite_animation/validation.py +0 -0
  79. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/tileset_collision/__init__.py +0 -0
  80. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/tileset_collision/collision_painter.py +0 -0
  81. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/tileset_collision/models.py +0 -0
  82. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/tileset_collision/protocols.py +0 -0
  83. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/plugins/tileset_collision/standalone.py +0 -0
  84. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/standalone_automap.py +0 -0
  85. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/standalone_error_console.py +0 -0
  86. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/standalone_filemanager.py +0 -0
  87. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/standalone_image_viewer.py +0 -0
  88. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap.py +0 -0
  89. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/__init__.py +0 -0
  90. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/__main__.py +0 -0
  91. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/__init__.py +0 -0
  92. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Bold.ttf +0 -0
  93. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-BoldItalic.ttf +0 -0
  94. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Italic.ttf +0 -0
  95. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Regular.ttf +0 -0
  96. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/fonts/noto/NotoSans-Bold.ttf +0 -0
  97. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/fonts/noto/NotoSans-BoldItalic.ttf +0 -0
  98. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/fonts/noto/NotoSans-Italic.ttf +0 -0
  99. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
  100. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/ToolMove.svg +0 -0
  101. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/arrow-down.svg +0 -0
  102. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/check.svg +0 -0
  103. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/checked.svg +0 -0
  104. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/close.svg +0 -0
  105. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/duplicate.svg +0 -0
  106. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/error.svg +0 -0
  107. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/file.svg +0 -0
  108. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/filedead.svg +0 -0
  109. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/fit.svg +0 -0
  110. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/folder.svg +0 -0
  111. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/grid.svg +0 -0
  112. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/image.svg +0 -0
  113. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/info.svg +0 -0
  114. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/load.svg +0 -0
  115. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/loop.svg +0 -0
  116. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/pan.svg +0 -0
  117. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/pause.svg +0 -0
  118. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/pencil.svg +0 -0
  119. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/play.svg +0 -0
  120. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/plus.svg +0 -0
  121. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/radio.svg +0 -0
  122. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/reset.svg +0 -0
  123. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/save.svg +0 -0
  124. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/stop.svg +0 -0
  125. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/tilemap.svg +0 -0
  126. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/tileset.svg +0 -0
  127. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/unchecked.svg +0 -0
  128. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/warning.svg +0 -0
  129. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/zoomin.svg +0 -0
  130. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/assets/icons/zoomout.svg +0 -0
  131. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/cli.py +0 -0
  132. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/main.py +0 -0
  133. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor/settings.py +0 -0
  134. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor.egg-info/SOURCES.txt +0 -0
  135. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor.egg-info/dependency_links.txt +0 -0
  136. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor.egg-info/entry_points.txt +0 -0
  137. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor.egg-info/requires.txt +0 -0
  138. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/tilemap_editor.egg-info/top_level.txt +0 -0
  139. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/ttypes/__init__.py +0 -0
  140. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/ttypes/tilemap.py +0 -0
  141. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/utils/__init__.py +0 -0
  142. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/utils/editor_preference.py +0 -0
  143. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/utils/error_handler.py +0 -0
  144. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/utils/font_manager.py +0 -0
  145. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/utils/history.py +0 -0
  146. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/utils/icon_manager.py +0 -0
  147. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/utils/icons_cache.py +0 -0
  148. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/utils/log_capture.py +0 -0
  149. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/utils/project_paths.py +0 -0
  150. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/utils/serialization.py +0 -0
  151. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/utils/standalone.py +0 -0
  152. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/utils/validation.py +0 -0
  153. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/__init__.py +0 -0
  154. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/automap_models.py +0 -0
  155. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/autotile_template.py +0 -0
  156. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/autotiler.py +0 -0
  157. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/layer_selector.py +0 -0
  158. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/map_properties.py +0 -0
  159. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/mapsetup.py +0 -0
  160. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/regex_automap_designer.py +0 -0
  161. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/tile_grid.py +0 -0
  162. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/tile_selector.py +0 -0
  163. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/collision_layer_mask.py +0 -0
  164. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/collision_layer_sidebar.py +0 -0
  165. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/draw_utils.py +0 -0
  166. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/fileinput.py +0 -0
  167. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/layer_type_dialog.py +0 -0
  168. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/menubar.py +0 -0
  169. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/mode_indicator.py +0 -0
  170. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/notification.py +0 -0
  171. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/property_editor.py +0 -0
  172. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/region_selector.py +0 -0
  173. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/status_bar.py +0 -0
  174. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/theme.py +0 -0
  175. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/tileset_type_dialog.py +0 -0
  176. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/toolbar.py +0 -0
  177. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/src/widgets/ui/tooltip.py +0 -0
  178. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/tests/test_collision_layer_mask.py +0 -0
  179. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/tests/test_collision_layer_sidebar.py +0 -0
  180. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/tests/test_project_paths.py +0 -0
  181. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/tests/test_render_scale.py +0 -0
  182. {tilemap_editor-3.1.6 → tilemap_editor-3.1.7}/tests/test_tilemap_save.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tilemap-editor
3
- Version: 3.1.6
3
+ Version: 3.1.7
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.1.6"
7
+ version = "3.1.7"
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"
@@ -24,6 +24,7 @@ from utils.font_manager import font_manager, FontWeight, FontStyle
24
24
  from utils.icon_manager import icon_manager
25
25
  from utils.project_paths import resolve_project_path
26
26
  from utils import error_handler
27
+ from widgets.input import InlineTextInput
27
28
  from .clipboard_util import copy_plain_text
28
29
  from .frame_picker import FramePicker
29
30
  from .models import Animation, AnimationLibrary, AnimationMarker
@@ -178,7 +179,7 @@ class SpriteAnimationEditor:
178
179
 
179
180
  # Rename state
180
181
  self._renaming = False
181
- self._rename_text = ""
182
+ self._rename_input = InlineTextInput("anim_rename", "")
182
183
 
183
184
  # Toolbar button rects (calculated in draw)
184
185
  self._btn_new = Rect(0, 0, 0, 0)
@@ -439,16 +440,13 @@ class SpriteAnimationEditor:
439
440
  return True
440
441
  elif event.key == pygame.K_ESCAPE:
441
442
  self._renaming = False
443
+ self._rename_input.is_focused = False
442
444
  return True
443
- elif event.key == pygame.K_BACKSPACE:
444
- self._rename_text = self._rename_text[:-1]
445
- return True
446
- elif event.unicode and len(self._rename_text) < 30:
447
- self._rename_text += event.unicode
445
+ elif self._rename_input.handle_event(event, self._font):
448
446
  return True
449
447
 
450
448
  # Frame width input
451
- if self._editing_frame_width:
449
+ elif self._editing_frame_width:
452
450
  if event.type == pygame.KEYDOWN:
453
451
  mods = pygame.key.get_mods()
454
452
  ctrl_held = mods & (pygame.KMOD_LCTRL | pygame.KMOD_RCTRL)
@@ -486,7 +484,7 @@ class SpriteAnimationEditor:
486
484
  return True
487
485
 
488
486
  # Frame height input
489
- if self._editing_frame_height:
487
+ elif self._editing_frame_height:
490
488
  if event.type == pygame.KEYDOWN:
491
489
  mods = pygame.key.get_mods()
492
490
  ctrl_held = mods & (pygame.KMOD_LCTRL | pygame.KMOD_RCTRL)
@@ -523,7 +521,7 @@ class SpriteAnimationEditor:
523
521
  return True
524
522
 
525
523
  # Offset X input
526
- if self._editing_offset_x:
524
+ elif self._editing_offset_x:
527
525
  if event.type == pygame.KEYDOWN:
528
526
  mods = pygame.key.get_mods()
529
527
  ctrl_held = mods & (pygame.KMOD_LCTRL | pygame.KMOD_RCTRL)
@@ -567,7 +565,7 @@ class SpriteAnimationEditor:
567
565
  return True
568
566
 
569
567
  # Offset Y input
570
- if self._editing_offset_y:
568
+ elif self._editing_offset_y:
571
569
  if event.type == pygame.KEYDOWN:
572
570
  mods = pygame.key.get_mods()
573
571
  ctrl_held = mods & (pygame.KMOD_LCTRL | pygame.KMOD_RCTRL)
@@ -693,6 +691,8 @@ class SpriteAnimationEditor:
693
691
  if self._btn_frame_width.collidepoint(mouse):
694
692
  self._editing_frame_width = True
695
693
  self._editing_frame_height = False
694
+ self._editing_offset_x = False
695
+ self._editing_offset_y = False
696
696
  self._renaming = False
697
697
  return True
698
698
 
@@ -832,10 +832,32 @@ class SpriteAnimationEditor:
832
832
  )
833
833
 
834
834
  if self._renaming:
835
- display_text = self._rename_text + (
836
- "|" if (pygame.time.get_ticks() // 400) % 2 else ""
837
- )
838
- lbl = self._font.render(display_text, True, (255, 220, 100))
835
+ if self._renaming:
836
+ display_name = self._rename_input.text
837
+ cursor_offset = self._rename_input.cursor_pos
838
+
839
+ # Draw selection highlight
840
+ if self._rename_input.selection_start is not None:
841
+ start = min(self._rename_input.selection_start, cursor_offset)
842
+ end = max(self._rename_input.selection_start, cursor_offset)
843
+ if start != end:
844
+ prefix = display_name[:start]
845
+ selected = display_name[start:end]
846
+ prefix_w = self._font.size(prefix)[0]
847
+ select_w = self._font.size(selected)[0]
848
+ sel_rect = Rect(
849
+ self._btn_anim_selector.x + 4 + prefix_w,
850
+ self._btn_anim_selector.y + 5,
851
+ select_w,
852
+ self._btn_anim_selector.height - 10,
853
+ )
854
+ pygame.draw.rect(screen, (60, 100, 160), sel_rect)
855
+
856
+ # Blinking cursor
857
+ if (pygame.time.get_ticks() // 400) % 2:
858
+ display_name = display_name[:cursor_offset] + "|" + display_name[cursor_offset:]
859
+
860
+ lbl = self._font.render(display_name, True, (255, 220, 100))
839
861
  else:
840
862
  display_name = self._active_anim_name or "(none)"
841
863
  if len(display_name) > 16:
@@ -1297,15 +1319,23 @@ class SpriteAnimationEditor:
1297
1319
  def _start_rename(self) -> None:
1298
1320
  if self._active_anim_name:
1299
1321
  self._renaming = True
1300
- self._rename_text = self._active_anim_name
1322
+ self._rename_input.text = self._active_anim_name
1323
+ self._rename_input.cursor_pos = len(self._active_anim_name)
1324
+ self._rename_input.selection_start = None
1325
+ self._rename_input.is_focused = True
1326
+ self._editing_frame_width = False
1327
+ self._editing_frame_height = False
1328
+ self._editing_offset_x = False
1329
+ self._editing_offset_y = False
1301
1330
  self._dropdown_open = False
1302
1331
 
1303
1332
  def _commit_rename(self) -> None:
1304
- new_name = self._rename_text.strip()
1333
+ new_name = self._rename_input.text.strip()
1305
1334
  if new_name and self._active_anim_name and new_name != self._active_anim_name:
1306
1335
  if self.library.rename_animation(self._active_anim_name, new_name):
1307
1336
  self._active_anim_name = new_name
1308
1337
  self._renaming = False
1338
+ self._rename_input.is_focused = False
1309
1339
 
1310
1340
  def _apply_frame_size(self) -> None:
1311
1341
  """Apply the frame size from input fields and update the frame picker."""
@@ -1558,10 +1588,12 @@ class SpriteAnimationEditor:
1558
1588
  if self._btn_meta_key.collidepoint(mouse):
1559
1589
  self._clear_text_editing_focus()
1560
1590
  self._editing_meta_key = True
1591
+ self._editing_meta_value = False
1561
1592
  return True
1562
1593
  if self._btn_meta_value.collidepoint(mouse):
1563
1594
  self._clear_text_editing_focus()
1564
1595
  self._editing_meta_value = True
1596
+ self._editing_meta_key = False
1565
1597
  return True
1566
1598
 
1567
1599
  return True
@@ -1572,6 +1604,8 @@ class SpriteAnimationEditor:
1572
1604
  self._editing_frame_height = False
1573
1605
  self._editing_offset_x = False
1574
1606
  self._editing_offset_y = False
1607
+ self._editing_meta_key = False
1608
+ self._editing_meta_value = False
1575
1609
 
1576
1610
  def _handle_meta_key_keydown(self, event: pygame.event.Event) -> bool:
1577
1611
  if event.key in (pygame.K_RETURN, pygame.K_KP_ENTER, pygame.K_TAB):
@@ -1809,7 +1843,7 @@ class SpriteAnimationEditor:
1809
1843
  print(f"Warning: Could not import FileManager: {e}")
1810
1844
  path = self._default_save_path()
1811
1845
  try:
1812
- self.library.save(path, base_path=self._project_base_path())
1846
+ self.library.save(path, base_path=path.parent)
1813
1847
  self._last_saved_path = path
1814
1848
  print(f"Animations saved to {path}")
1815
1849
  except Exception as e:
@@ -1856,7 +1890,7 @@ class SpriteAnimationEditor:
1856
1890
  try:
1857
1891
  self.library.save(
1858
1892
  self._last_saved_path,
1859
- base_path=self._project_base_path(),
1893
+ base_path=self._last_saved_path.parent,
1860
1894
  )
1861
1895
  print(f"Animations saved to {self._last_saved_path}")
1862
1896
  except Exception as e:
@@ -1914,7 +1948,7 @@ class SpriteAnimationEditor:
1914
1948
  def _on_save_file_selected(self, path: Path) -> None:
1915
1949
  """Callback when user selects a file to save to."""
1916
1950
  try:
1917
- self.library.save(path, base_path=self._project_base_path())
1951
+ self.library.save(path, base_path=path.parent)
1918
1952
  self._last_saved_path = path # Track for quick save
1919
1953
  print(f"Animations saved to {path}")
1920
1954
  except Exception as e:
@@ -2032,14 +2066,12 @@ class SpriteAnimationEditor:
2032
2066
  def _resolve_library_paths(self, json_path: Path) -> None:
2033
2067
  if not self.library.spritesheet_path:
2034
2068
  return
2035
- base_path = self._project_base_path()
2036
- if base_path is None:
2037
- return
2069
+ project_root = self._project_base_path()
2038
2070
  self.library.spritesheet_path = str(
2039
2071
  resolve_project_path(
2040
2072
  self.library.spritesheet_path,
2041
- base_path,
2042
- fallback_roots=[json_path.parent],
2073
+ json_path.parent,
2074
+ fallback_roots=[project_root] if project_root else None,
2043
2075
  must_exist=True,
2044
2076
  )
2045
2077
  )
@@ -65,6 +65,13 @@ class TilesetCollisionEditor:
65
65
  self._tile_size = tile_size
66
66
  self._tileset_name = "No Tileset"
67
67
 
68
+ # Clipboard for copy/paste
69
+ self._clipboard_polygons: List[List[Tuple[float, float]]] = []
70
+ self._clipboard_one_way_flags: List[bool] = []
71
+ self._toast_message: Optional[str] = None
72
+ self._toast_timer: float = 0.0
73
+ self._toast_start: int = 0
74
+
68
75
  # Collision library
69
76
  self.library = TilesetCollisionLibrary(
70
77
  tileset_name=self._tileset_name,
@@ -99,6 +106,7 @@ class TilesetCollisionEditor:
99
106
  # Painted tiles list state
100
107
  self.painted_tiles_scroll = 0
101
108
  self.painted_tiles_hover = -1
109
+ self._painted_tiles_focused = False
102
110
 
103
111
  # Collision painter
104
112
  self.painter = CollisionPainter(
@@ -127,6 +135,8 @@ class TilesetCollisionEditor:
127
135
  buttons_config = [
128
136
  {"label": "Save", "action": self._save_collision},
129
137
  {"label": "Load", "action": self._load_collision},
138
+ {"label": "Copy", "action": self._copy_collision},
139
+ {"label": "Paste", "action": self._paste_collision},
130
140
  {"label": "Clear", "action": self._clear_current},
131
141
  ]
132
142
 
@@ -164,6 +174,29 @@ class TilesetCollisionEditor:
164
174
  """Clear collision for selected tiles via toolbar button"""
165
175
  self.clear_current_selection()
166
176
 
177
+ def _copy_collision(self) -> None:
178
+ """Copy collision shapes from current tile to clipboard"""
179
+ polygons = self.painter.get_polygons()
180
+ one_way_flags = self.painter.get_one_way_flags()
181
+ self._clipboard_polygons = [list(p) for p in polygons]
182
+ self._clipboard_one_way_flags = list(one_way_flags)
183
+ count = len(self._clipboard_polygons)
184
+ self._show_toast(f"Copied {count} shape{'s' if count != 1 else ''}")
185
+
186
+ def _paste_collision(self) -> None:
187
+ """Paste collision shapes from clipboard to selected tiles"""
188
+ if not self._clipboard_polygons:
189
+ self._show_toast("Clipboard is empty")
190
+ return
191
+ self.painter.set_polygons(
192
+ [list(p) for p in self._clipboard_polygons],
193
+ list(self._clipboard_one_way_flags),
194
+ )
195
+ self._save_tile_collision_for_selection()
196
+ tile_count = len(self._selected_tiles)
197
+ shape_count = len(self._clipboard_polygons)
198
+ self._show_toast(f"Pasted {shape_count} shape{'s' if shape_count != 1 else ''} to {tile_count} tile{'s' if tile_count != 1 else ''}")
199
+
167
200
  def _position_toolbar_buttons(self) -> None:
168
201
  """Position toolbar buttons in the toolbar area"""
169
202
  if not hasattr(self, '_toolbar_buttons'):
@@ -332,6 +365,38 @@ class TilesetCollisionEditor:
332
365
  """Callback when polygon is modified"""
333
366
  self._save_tile_collision_for_selection()
334
367
 
368
+ def _show_toast(self, message: str, duration: float = 2.5) -> None:
369
+ """Show a temporary status toast on screen"""
370
+ self._toast_message = message
371
+ self._toast_timer = duration * 1000.0
372
+ self._toast_start = pygame.time.get_ticks()
373
+
374
+ def _draw_toast(self, screen: Surface) -> None:
375
+ """Draw the toast message with fade-out"""
376
+ if self._toast_message is None:
377
+ return
378
+
379
+ elapsed = pygame.time.get_ticks() - self._toast_start
380
+ remaining = self._toast_timer - elapsed
381
+ fade_ms = 500.0
382
+ alpha = 255 if remaining >= fade_ms else max(0, min(255, int((remaining / fade_ms) * 255)))
383
+ label = self._font.render(self._toast_message, True, (255, 255, 255))
384
+ padding = 12
385
+ bg_rect = Rect(
386
+ self.rect.centerx - label.get_width() // 2 - padding,
387
+ self.rect.centery - 60,
388
+ label.get_width() + padding * 2,
389
+ label.get_height() + padding,
390
+ )
391
+
392
+ bg = pygame.Surface((bg_rect.w, bg_rect.h), pygame.SRCALPHA)
393
+ bg.fill((0, 0, 0, min(200, alpha)))
394
+ pygame.draw.rect(bg, (80, 180, 255, alpha), bg.get_rect(), 1)
395
+ screen.blit(bg, bg_rect)
396
+
397
+ label.set_alpha(alpha)
398
+ screen.blit(label, label.get_rect(center=bg_rect.center))
399
+
335
400
  def clear_current_selection(self) -> None:
336
401
  """Clear collision for currently selected tiles"""
337
402
  self.painter.set_polygons([], [])
@@ -446,6 +511,7 @@ class TilesetCollisionEditor:
446
511
  if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1 and not self._space_held:
447
512
  tile_id = self._get_tile_at_mouse(mouse)
448
513
  if tile_id is not None:
514
+ self._painted_tiles_focused = False
449
515
  # Ctrl/Cmd for multi-select
450
516
  mods = pygame.key.get_mods()
451
517
  if mods & (pygame.KMOD_LCTRL | pygame.KMOD_LMETA):
@@ -484,6 +550,7 @@ class TilesetCollisionEditor:
484
550
  # Painted tiles list interaction
485
551
  if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
486
552
  if self.painted_tiles_rect.collidepoint(mouse):
553
+ self._painted_tiles_focused = True
487
554
  painted_tiles = sorted(self.library.tiles.keys())
488
555
  rel_y = mouse[1] - self.painted_tiles_rect.y + self.painted_tiles_scroll
489
556
  tile_height = 64
@@ -503,13 +570,22 @@ class TilesetCollisionEditor:
503
570
 
504
571
  # Keyboard shortcuts
505
572
  if event.type == pygame.KEYDOWN:
573
+ mods = pygame.key.get_mods()
574
+ ctrl = mods & (pygame.KMOD_LCTRL | pygame.KMOD_LMETA)
575
+
576
+ if ctrl:
577
+ if event.key == pygame.K_c:
578
+ self._copy_collision()
579
+ return True
580
+ elif event.key == pygame.K_v:
581
+ self._paste_collision()
582
+ return True
583
+
506
584
  if event.key == pygame.K_DELETE or event.key == pygame.K_BACKSPACE:
507
- if pygame.key.get_mods() & (pygame.KMOD_LSHIFT):
508
- # Shift+Delete: clear current selection
585
+ if mods & (pygame.KMOD_LSHIFT) or self._painted_tiles_focused:
509
586
  self.clear_current_selection()
510
587
  return True
511
588
  elif event.key == pygame.K_h:
512
- # H: Recenter tileset view
513
589
  self._recenter_tileset_view()
514
590
  return True
515
591
 
@@ -577,6 +653,15 @@ class TilesetCollisionEditor:
577
653
  # Draw tileset selector
578
654
  self._draw_tileset_selector(screen)
579
655
 
656
+ # Draw toast overlay
657
+ self._draw_toast(screen)
658
+
659
+ # Update toast timer
660
+ if self._toast_message is not None:
661
+ elapsed = pygame.time.get_ticks() - self._toast_start
662
+ if elapsed >= self._toast_timer:
663
+ self._toast_message = None
664
+
580
665
  def _draw_toolbar(self, screen: Surface) -> None:
581
666
  """Draw the toolbar"""
582
667
  draw_panel(screen, self.toolbar_rect, COLORS.header, COLORS.border)
@@ -590,18 +675,19 @@ class TilesetCollisionEditor:
590
675
  )
591
676
  screen.blit(title, (self.toolbar_rect.x + 10, self.toolbar_rect.y + 10))
592
677
 
593
- # Collision count
678
+ # Draw toolbar buttons
679
+ if hasattr(self, '_toolbar_buttons'):
680
+ self._draw_toolbar_buttons(screen)
681
+
682
+ # Collision count (after buttons to avoid overlap)
594
683
  collision_count = len(self.library.tiles)
595
684
  count_text = self._font_sm.render(
596
685
  f"{collision_count} painted",
597
686
  True,
598
687
  COLORS.text_dim
599
688
  )
600
- screen.blit(count_text, (self.toolbar_rect.right - count_text.get_width() - 10, self.toolbar_rect.y + 12))
601
-
602
- # Draw toolbar buttons
603
- if hasattr(self, '_toolbar_buttons'):
604
- self._draw_toolbar_buttons(screen)
689
+ start_x = self.toolbar_rect.right - (len(self._toolbar_buttons) * 90) - 10
690
+ screen.blit(count_text, (start_x - count_text.get_width() - 15, self.toolbar_rect.y + 12))
605
691
 
606
692
  def _draw_painted_tiles_list(self, screen: Surface) -> None:
607
693
  """Draw the list of tiles with collision"""
@@ -610,6 +696,9 @@ class TilesetCollisionEditor:
610
696
  # Header
611
697
  header_text = self._font_sm.render("Painted Tiles", True, COLORS.text)
612
698
  screen.blit(header_text, (self.painted_tiles_rect.x + 8, self.painted_tiles_rect.y + 8))
699
+ if self._painted_tiles_focused:
700
+ hint = self._font_sm.render("Backspace to clear", True, COLORS.accent)
701
+ screen.blit(hint, (self.painted_tiles_rect.right - hint.get_width() - 8, self.painted_tiles_rect.y + 8))
613
702
 
614
703
  clip = screen.get_clip()
615
704
  screen.set_clip(self.painted_tiles_rect)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tilemap-editor
3
- Version: 3.1.6
3
+ Version: 3.1.7
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
@@ -1381,6 +1381,7 @@ class FileManager:
1381
1381
  if not search_text and not self.is_search_focused:
1382
1382
  search_text = "Search files..."
1383
1383
  search_col = COLORS["text_dim"]
1384
+ txt = self.font_main.render(search_text, True, search_col)
1384
1385
  else:
1385
1386
  search_col = COLORS["text_main"]
1386
1387
  if self.is_search_focused:
@@ -1391,12 +1392,14 @@ class FileManager:
1391
1392
  display_text = prefix + "|" + display_text[cursor_offset:]
1392
1393
  else:
1393
1394
  display_text = prefix + " " + display_text[cursor_offset:]
1394
- txt = self.font_main.render(display_text, True, search_col)
1395
+ txt = self.font_main.render(display_text or " ", True, search_col)
1395
1396
  else:
1396
1397
  txt = self.font_main.render(search_text, True, search_col)
1397
1398
 
1398
- txt = self.font_main.render(search_text, True, search_col)
1399
+ clip = screen.get_clip()
1400
+ screen.set_clip(self.search_rect)
1399
1401
  screen.blit(txt, (self.search_rect.x + 8, self.search_rect.y + 4))
1402
+ screen.set_clip(clip)
1400
1403
 
1401
1404
  file_list_rect = self._get_file_list_rect()
1402
1405
  self._draw_file_list(screen, file_list_rect)
@@ -1657,7 +1660,10 @@ class FileManager:
1657
1660
  else:
1658
1661
  display_name = prefix + " " + display_name[cursor_offset:]
1659
1662
  txt = self.font_main.render(display_name, True, COLORS["text_main"])
1663
+ clip = screen.get_clip()
1664
+ screen.set_clip(self.save_name_rect)
1660
1665
  screen.blit(txt, (self.save_name_rect.x + 6, self.save_name_rect.y + 6))
1666
+ screen.set_clip(clip)
1661
1667
 
1662
1668
  def _draw_icon_arrow_up(self, surface, cx, cy, color):
1663
1669
  points = [(cx, cy - 5), (cx - 5, cy + 2), (cx + 5, cy + 2)]
@@ -269,6 +269,25 @@ class InlineTextInput:
269
269
  self.cursor_pos = 0
270
270
  self.selection_start = None
271
271
 
272
+ def delete_word_left(self) -> None:
273
+ """Delete from cursor to the start of the current or previous word."""
274
+ if self.selection_start is not None:
275
+ start = min(self.selection_start, self.cursor_pos)
276
+ end = max(self.selection_start, self.cursor_pos)
277
+ self.text = self.text[:start] + self.text[end:]
278
+ self.cursor_pos = start
279
+ self.selection_start = None
280
+ return
281
+ if self.cursor_pos == 0:
282
+ return
283
+ idx = self.cursor_pos - 1
284
+ while idx >= 0 and self.text[idx] == ' ':
285
+ idx -= 1
286
+ while idx >= 0 and self.text[idx] != ' ':
287
+ idx -= 1
288
+ self.text = self.text[:idx + 1] + self.text[self.cursor_pos:]
289
+ self.cursor_pos = idx + 1
290
+
272
291
  def handle_event(self, event: pygame.event.Event, font: pygame.font.Font) -> bool:
273
292
  if not self.is_focused:
274
293
  return False
@@ -281,6 +300,9 @@ class InlineTextInput:
281
300
  if ctrl_held and event.key == pygame.K_a:
282
301
  self.select_all()
283
302
  return True
303
+ if ctrl_held and event.key == pygame.K_BACKSPACE:
304
+ self.delete_word_left()
305
+ return True
284
306
 
285
307
  if event.key == pygame.K_LEFT:
286
308
  self.move_cursor(-1)
File without changes
File without changes
File without changes