meltygui 0.1.0__py3-none-any.whl

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 (372) hide show
  1. meltygui/__init__.py +107 -0
  2. meltygui/accounts/__init__.py +0 -0
  3. meltygui/accounts/internet_accounts.py +1355 -0
  4. meltygui/chat/__init__.py +91 -0
  5. meltygui/chat/activity.py +75 -0
  6. meltygui/chat/backends.py +36 -0
  7. meltygui/chat/chat_interface.py +732 -0
  8. meltygui/chat/chat_proxy.py +352 -0
  9. meltygui/chat/codex_proxy.py +592 -0
  10. meltygui/chat/codex_settings.py +100 -0
  11. meltygui/chat/codex_transport.py +60 -0
  12. meltygui/chat/command_parser.py +204 -0
  13. meltygui/chat/images.py +227 -0
  14. meltygui/chat/messages.py +417 -0
  15. meltygui/chat/metadata.py +139 -0
  16. meltygui/chat/writer_locks.py +64 -0
  17. meltygui/code/__init__.py +0 -0
  18. meltygui/code/basic_converters.py +533 -0
  19. meltygui/code/chain_converters.py +2111 -0
  20. meltygui/code/code_checks.py +2209 -0
  21. meltygui/code/core_syntax.py +1430 -0
  22. meltygui/code/file_converters.py +1933 -0
  23. meltygui/code/fileref.py +702 -0
  24. meltygui/code/hotswap_guard.py +144 -0
  25. meltygui/code/libcst_conversion.py +9724 -0
  26. meltygui/code/live_instrument.py +392 -0
  27. meltygui/code/live_view.py +2490 -0
  28. meltygui/code/melty_scan.py +2684 -0
  29. meltygui/code/new_codecs.py +1255 -0
  30. meltygui/code/new_converters.py +3017 -0
  31. meltygui/code/project_code.py +278 -0
  32. meltygui/code/source_context.py +63 -0
  33. meltygui/code/symbol_roster.py +1588 -0
  34. meltygui/code/syntax_check.py +34 -0
  35. meltygui/code/syntax_check_worker.py +114 -0
  36. meltygui/completion/__init__.py +0 -0
  37. meltygui/completion/fim.py +1232 -0
  38. meltygui/completion/fim_context.py +481 -0
  39. meltygui/completion/providers/__init__.py +0 -0
  40. meltygui/completion/providers/anthropic_oauth.py +446 -0
  41. meltygui/completion/providers/anthropic_requests.py +69 -0
  42. meltygui/completion/providers/claude.py +203 -0
  43. meltygui/completion/providers/claude_usage.py +499 -0
  44. meltygui/completion/providers/codex_accounts.py +180 -0
  45. meltygui/completion/providers/copilot.py +617 -0
  46. meltygui/completion/providers/oauth_popup.py +220 -0
  47. meltygui/completion/providers/ollama.py +320 -0
  48. meltygui/completion/providers/profiles.py +23 -0
  49. meltygui/core/README.md +88 -0
  50. meltygui/core/__init__.py +1 -0
  51. meltygui/core/automation/__init__.py +1 -0
  52. meltygui/core/automation/action_core.py +153 -0
  53. meltygui/core/automation/collection_action.py +45 -0
  54. meltygui/core/automation/mcp_eval.py +167 -0
  55. meltygui/core/automation/mcp_hotswap.py +107 -0
  56. meltygui/core/automation/mcp_query.py +552 -0
  57. meltygui/core/automation/mcp_server.py +657 -0
  58. meltygui/core/automation/orchestration_core.py +2636 -0
  59. meltygui/core/automation/query_core.py +124 -0
  60. meltygui/core/automation/search_core.py +26 -0
  61. meltygui/core/automation/selector_core.py +340 -0
  62. meltygui/core/automation/value_core.py +1752 -0
  63. meltygui/core/cache/__init__.py +1 -0
  64. meltygui/core/cache/cache_diagnostics.py +0 -0
  65. meltygui/core/cache/invalidation_decoration.py +153 -0
  66. meltygui/core/cache/invalidation_tracker.py +43 -0
  67. meltygui/core/cache/tile_cache.py +5968 -0
  68. meltygui/core/conversion/__init__.py +1 -0
  69. meltygui/core/conversion/bubbling.py +599 -0
  70. meltygui/core/conversion/cache_tree.py +188 -0
  71. meltygui/core/conversion/chain.py +113 -0
  72. meltygui/core/conversion/converter_register.py +145 -0
  73. meltygui/core/conversion/data_decoration.py +67 -0
  74. meltygui/core/conversion/dict_conversion.py +1815 -0
  75. meltygui/core/conversion/dict_conversion_util.py +177 -0
  76. meltygui/core/conversion/dynamic_obj.py +89 -0
  77. meltygui/core/conversion/graph_compare.py +183 -0
  78. meltygui/core/conversion/load_save_v2.py +1032 -0
  79. meltygui/core/conversion/missing_saved_class.py +39 -0
  80. meltygui/core/conversion/path_finder.py +606 -0
  81. meltygui/core/conversion/render_host.py +1083 -0
  82. meltygui/core/core_render.py +6537 -0
  83. meltygui/core/definition_hotswap.py +231 -0
  84. meltygui/core/diagnostics/__init__.py +1 -0
  85. meltygui/core/diagnostics/attribute_churn.py +38 -0
  86. meltygui/core/diagnostics/fps_counter.py +39 -0
  87. meltygui/core/diagnostics/gpu_frame_timer.py +103 -0
  88. meltygui/core/diagnostics/inspection_core.py +169 -0
  89. meltygui/core/diagnostics/monitor_core.py +105 -0
  90. meltygui/core/diagnostics/notifications.py +706 -0
  91. meltygui/core/diagnostics/perf_trace.py +281 -0
  92. meltygui/core/diagnostics/profile_decoration.py +88 -0
  93. meltygui/core/diagnostics/resize_trace.py +62 -0
  94. meltygui/core/diagnostics/screenshot_core.py +247 -0
  95. meltygui/core/diagnostics/session_status.py +98 -0
  96. meltygui/core/diagnostics/trace_core.py +445 -0
  97. meltygui/core/files/__init__.py +1 -0
  98. meltygui/core/files/file_core.py +208 -0
  99. meltygui/core/files/file_explorer_core.py +104 -0
  100. meltygui/core/files/file_tree_core.py +198 -0
  101. meltygui/core/files/file_watch_core.py +43 -0
  102. meltygui/core/files/import_graph_core.py +43 -0
  103. meltygui/core/files/metadata_core.py +51 -0
  104. meltygui/core/graphics/__init__.py +1 -0
  105. meltygui/core/graphics/cuda_context_core.py +166 -0
  106. meltygui/core/graphics/cuda_interop_core.py +136 -0
  107. meltygui/core/graphics/cuda_kernel_core.py +91 -0
  108. meltygui/core/graphics/framebuffer_recorder.py +337 -0
  109. meltygui/core/graphics/gl_state.py +658 -0
  110. meltygui/core/graphics/lut_core.py +52 -0
  111. meltygui/core/graphics/overlay_renderer.py +984 -0
  112. meltygui/core/graphics/scene_target.py +180 -0
  113. meltygui/core/graphics/screenshot.py +439 -0
  114. meltygui/core/graphics/shader_func.py +478 -0
  115. meltygui/core/graphics/tensor_core.py +45 -0
  116. meltygui/core/graphics/text_texture.py +329 -0
  117. meltygui/core/graphics/wayland_color.py +635 -0
  118. meltygui/core/input/__init__.py +1 -0
  119. meltygui/core/input/collision.py +165 -0
  120. meltygui/core/input/drag_drop_core.py +1525 -0
  121. meltygui/core/input/hypr_left_drag.py +323 -0
  122. meltygui/core/input/input_core.py +245 -0
  123. meltygui/core/input/input_handler.py +1101 -0
  124. meltygui/core/input/mouse_cursor.py +355 -0
  125. meltygui/core/input/pynput_backend.py +1054 -0
  126. meltygui/core/input/space_mouse.py +338 -0
  127. meltygui/core/input/touchpad_backend.py +393 -0
  128. meltygui/core/input/view_selection.py +177 -0
  129. meltygui/core/layout/__init__.py +1 -0
  130. meltygui/core/layout/column_core.py +2153 -0
  131. meltygui/core/layout/cursor_core.py +161 -0
  132. meltygui/core/layout/dropdown_core.py +278 -0
  133. meltygui/core/layout/edge_constraints.py +155 -0
  134. meltygui/core/layout/grid_core.py +117 -0
  135. meltygui/core/layout/header_core.py +23 -0
  136. meltygui/core/layout/header_runtime.py +67 -0
  137. meltygui/core/layout/layout_core.py +87 -0
  138. meltygui/core/layout/tile_manager_core.py +591 -0
  139. meltygui/core/melty.py +6726 -0
  140. meltygui/core/module_map.json +896 -0
  141. meltygui/core/module_names.py +19 -0
  142. meltygui/core/rendering/__init__.py +1 -0
  143. meltygui/core/rendering/core_decoration.py +431 -0
  144. meltygui/core/rendering/core_render_helpers.py +328 -0
  145. meltygui/core/rendering/func_metadata.py +398 -0
  146. meltygui/core/rendering/mode.py +818 -0
  147. meltygui/core/rendering/mode_defaults.py +41 -0
  148. meltygui/core/rendering/modes.py +136 -0
  149. meltygui/core/rendering/parameter_core.py +1665 -0
  150. meltygui/core/rendering/render_dispatch.py +1891 -0
  151. meltygui/core/rendering/render_funcs.py +273 -0
  152. meltygui/core/rendering/shaped.py +312 -0
  153. meltygui/core/rendering/window_decoration.py +25 -0
  154. meltygui/core/runtime/__init__.py +1 -0
  155. meltygui/core/runtime/app.py +735 -0
  156. meltygui/core/runtime/app_session.py +140 -0
  157. meltygui/core/runtime/background.py +564 -0
  158. meltygui/core/runtime/extensions.py +53 -0
  159. meltygui/core/runtime/gc_manager.py +1163 -0
  160. meltygui/core/runtime/lifecycle.py +21 -0
  161. meltygui/core/runtime/paths.py +27 -0
  162. meltygui/core/runtime/settings.py +14 -0
  163. meltygui/core/runtime/singleton.py +16 -0
  164. meltygui/core/runtime/thread_safe_bool.py +24 -0
  165. meltygui/core/runtime/thread_signal.py +30 -0
  166. meltygui/core/runtime/toggles.py +3115 -0
  167. meltygui/core/services/__init__.py +1 -0
  168. meltygui/core/services/account_core.py +10 -0
  169. meltygui/core/services/chat_core.py +19 -0
  170. meltygui/core/services/claude_terminal_core.py +346 -0
  171. meltygui/core/services/terminal_core.py +458 -0
  172. meltygui/core/services/terminal_runtime.py +78 -0
  173. meltygui/core/styling/__init__.py +1 -0
  174. meltygui/core/styling/color_core.py +46 -0
  175. meltygui/core/styling/fonts.py +639 -0
  176. meltygui/core/styling/global_style.py +338 -0
  177. meltygui/core/styling/style.py +198 -0
  178. meltygui/core/styling/style_core.py +522 -0
  179. meltygui/core/styling/warm_start.py +149 -0
  180. meltygui/core/windowing/__init__.py +1 -0
  181. meltygui/core/windowing/backends/PYIMGUI_LICENSE +28 -0
  182. meltygui/core/windowing/backends/__init__.py +1 -0
  183. meltygui/core/windowing/backends/imgui_renderer.py +138 -0
  184. meltygui/core/windowing/backends/native_wayland.py +850 -0
  185. meltygui/core/windowing/backends/protocols/xdg-decoration-unstable-v1.xml +156 -0
  186. meltygui/core/windowing/backends/protocols/xdg-shell.xml +1420 -0
  187. meltygui/core/windowing/backends/wayland_protocol.py +101 -0
  188. meltygui/core/windowing/dock_core.py +182 -0
  189. meltygui/core/windowing/frame_geometry.py +42 -0
  190. meltygui/core/windowing/geometry_feed.py +864 -0
  191. meltygui/core/windowing/glfw_utils.py +1343 -0
  192. meltygui/core/windowing/os_frame.py +1552 -0
  193. meltygui/core/windowing/surface.py +643 -0
  194. meltygui/core/windowing/titlebar.py +1560 -0
  195. meltygui/core/windowing/titlebar_buttons.py +281 -0
  196. meltygui/core/windowing/wayland_move.py +932 -0
  197. meltygui/core/windowing/window_api.py +62 -0
  198. meltygui/core/windowing/window_constants.py +339 -0
  199. meltygui/core/windowing/window_visibility.py +162 -0
  200. meltygui/debug/__init__.py +0 -0
  201. meltygui/debug/app_view_utils.py +9 -0
  202. meltygui/editor/__init__.py +0 -0
  203. meltygui/editor/bash_syntax.py +30 -0
  204. meltygui/editor/code_line_fast.py +152 -0
  205. meltygui/editor/diff.py +139 -0
  206. meltygui/editor/external_changes.py +159 -0
  207. meltygui/editor/file_header.py +41 -0
  208. meltygui/editor/live_usage.py +169 -0
  209. meltygui/editor/live_view_views.py +1803 -0
  210. meltygui/editor/pending_save.py +1351 -0
  211. meltygui/editor/roster_tints.py +547 -0
  212. meltygui/editor/source_preview.py +16 -0
  213. meltygui/editor/source_tools.py +10 -0
  214. meltygui/editor/source_ui.py +70 -0
  215. meltygui/editor/spell_check.py +77 -0
  216. meltygui/editor/text_editor.py +9076 -0
  217. meltygui/editor/usage_picker.py +538 -0
  218. meltygui/events/__init__.py +0 -0
  219. meltygui/events/example.py +118 -0
  220. meltygui/examples/__init__.py +0 -0
  221. meltygui/examples/columns_demo.py +33 -0
  222. meltygui/examples/columns_window_demo.py +60 -0
  223. meltygui/examples/context_menu_demo.py +24 -0
  224. meltygui/examples/context_menu_window_demo.py +49 -0
  225. meltygui/examples/gui_playground.py +127 -0
  226. meltygui/examples/live_view_playground.py +256 -0
  227. meltygui/examples/lora.py +43 -0
  228. meltygui/examples/lora_data.py +59 -0
  229. meltygui/examples/lora_policies.py +67 -0
  230. meltygui/examples/mode_demo.py +49 -0
  231. meltygui/examples/modifies_demo.py +119 -0
  232. meltygui/examples/scalar_policies.py +60 -0
  233. meltygui/examples/style_layouts.py +149 -0
  234. meltygui/examples/tile_manager_demo.py +74 -0
  235. meltygui/examples/tint_demo.py +160 -0
  236. meltygui/examples/tint_functions.py +56 -0
  237. meltygui/examples/trace_demo.py +88 -0
  238. meltygui/examples/two_windows.py +36 -0
  239. meltygui/files/__init__.py +0 -0
  240. meltygui/files/fast_file_explorer.py +439 -0
  241. meltygui/gnome_extension/lsd-window-geometry@latent-descent/extension.js +237 -0
  242. meltygui/gnome_extension/lsd-window-geometry@latent-descent/lsd-window-geometry@latent-descent.iml +9 -0
  243. meltygui/gnome_extension/lsd-window-geometry@latent-descent/metadata.json +7 -0
  244. meltygui/graphics/__init__.py +6 -0
  245. meltygui/graphics/base.py +85 -0
  246. meltygui/graphics/examples.py +507 -0
  247. meltygui/graphics/executor.py +520 -0
  248. meltygui/graphics/filter.py +667 -0
  249. meltygui/graphics/filter.pyi +856 -0
  250. meltygui/graphics/generate_stubs.py +22 -0
  251. meltygui/graphics/registry.py +203 -0
  252. meltygui/graphics/shader_compiler.py +155 -0
  253. meltygui/graphics/shaders.py +1302 -0
  254. meltygui/graphics/stub_generator.py +250 -0
  255. meltygui/graphics/texture_manager.py +170 -0
  256. meltygui/graphics/texture_min_max.py +295 -0
  257. meltygui/hdr_color.py +757 -0
  258. meltygui/image_load.py +308 -0
  259. meltygui/model/__init__.py +1 -0
  260. meltygui/model/account_model.py +142 -0
  261. meltygui/model/camera_model.py +159 -0
  262. meltygui/model/chat_model.py +86 -0
  263. meltygui/model/code_model.py +62 -0
  264. meltygui/model/code_proxy_model.py +876 -0
  265. meltygui/model/collection_model.py +41 -0
  266. meltygui/model/color_model.py +127 -0
  267. meltygui/model/cuda_tensor_model.py +36 -0
  268. meltygui/model/cuda_texture_model.py +149 -0
  269. meltygui/model/dropdown_model.py +137 -0
  270. meltygui/model/file_metadata_model.py +73 -0
  271. meltygui/model/file_model.py +289 -0
  272. meltygui/model/format_model.py +390 -0
  273. meltygui/model/graph_model.py +98 -0
  274. meltygui/model/icon_model.py +1024 -0
  275. meltygui/model/import_graph_model.py +468 -0
  276. meltygui/model/layout_model.py +15 -0
  277. meltygui/model/lut_model.py +266 -0
  278. meltygui/model/search_model.py +173 -0
  279. meltygui/model/tensor_model.py +402 -0
  280. meltygui/model/terminal_model.py +329 -0
  281. meltygui/model/texture_model.py +146 -0
  282. meltygui/model/tile_model.py +24 -0
  283. meltygui/model/trace_model.py +198 -0
  284. meltygui/model/trace_report_model.py +146 -0
  285. meltygui/models/__init__.py +0 -0
  286. meltygui/models/file_meta.py +613 -0
  287. meltygui/models/function_console.py +184 -0
  288. meltygui/models/orchestration.py +48 -0
  289. meltygui/pbr.py +1576 -0
  290. meltygui/png_unfilter.c +49 -0
  291. meltygui/resources/JetBrainsMono-Regular.ttf +0 -0
  292. meltygui/resources/THIRD_PARTY_NOTICES.md +21 -0
  293. meltygui/resources/dejavu/DejaVuSans-Bold.ttf +0 -0
  294. meltygui/resources/dejavu/DejaVuSans-ExtraLight.ttf +0 -0
  295. meltygui/resources/dejavu/DejaVuSans.ttf +0 -0
  296. meltygui/resources/dejavu/LICENSE.txt +78 -0
  297. meltygui/resources/fontawesome-LICENSE.txt +121 -0
  298. meltygui/resources/fontawesome-webfont.ttf +0 -0
  299. meltygui/resources/hdri/studio_small_09_1k.hdr +0 -0
  300. meltygui/resources/jetbrains-weights/JetBrainsMono-Bold.ttf +0 -0
  301. meltygui/resources/jetbrains-weights/JetBrainsMono-ExtraBold.ttf +0 -0
  302. meltygui/resources/jetbrains-weights/JetBrainsMono-ExtraLight.ttf +0 -0
  303. meltygui/resources/jetbrains-weights/JetBrainsMono-Light.ttf +0 -0
  304. meltygui/resources/jetbrains-weights/JetBrainsMono-Medium.ttf +0 -0
  305. meltygui/resources/jetbrains-weights/JetBrainsMono-SemiBold.ttf +0 -0
  306. meltygui/resources/jetbrains-weights/JetBrainsMono-Thin.ttf +0 -0
  307. meltygui/resources/jetbrains-weights/OFL.txt +93 -0
  308. meltygui/resources/jetbrains-weights/README.md +2 -0
  309. meltygui/state/__init__.py +0 -0
  310. meltygui/state/account_state.py +22 -0
  311. meltygui/state/animation_state.py +97 -0
  312. meltygui/state/annotation_state.py +22 -0
  313. meltygui/state/chat_state.py +36 -0
  314. meltygui/state/code_state.py +10 -0
  315. meltygui/state/core_enums.py +59 -0
  316. meltygui/state/core_markers.py +115 -0
  317. meltygui/state/core_undo.py +1075 -0
  318. meltygui/state/file_state.py +75 -0
  319. meltygui/state/graph_state.py +26 -0
  320. meltygui/state/inspection_state.py +47 -0
  321. meltygui/state/menu_state.py +10 -0
  322. meltygui/state/model_enums.py +11 -0
  323. meltygui/state/new_core_model.py +2394 -0
  324. meltygui/state/orchestration_state.py +14 -0
  325. meltygui/state/query_state.py +24 -0
  326. meltygui/state/tensor_state.py +10 -0
  327. meltygui/state/terminal_state.py +23 -0
  328. meltygui/state/trace_state.py +32 -0
  329. meltygui/state/voxel_state.py +12 -0
  330. meltygui/text_index.py +816 -0
  331. meltygui/utils/__init__.py +0 -0
  332. meltygui/utils/jump_to_code.py +344 -0
  333. meltygui/utils/pkl_inspect.py +90 -0
  334. meltygui/utils/render_utils.py +1419 -0
  335. meltygui/view/__init__.py +1 -0
  336. meltygui/view/account_view.py +524 -0
  337. meltygui/view/action_view.py +73 -0
  338. meltygui/view/chat_decoration_view.py +112 -0
  339. meltygui/view/chat_view.py +1703 -0
  340. meltygui/view/code_view.py +2677 -0
  341. meltygui/view/collection_view.py +1185 -0
  342. meltygui/view/color_view.py +824 -0
  343. meltygui/view/control_view.py +559 -0
  344. meltygui/view/decoration_view.py +439 -0
  345. meltygui/view/diagnostic_view.py +177 -0
  346. meltygui/view/dropdown_view.py +1082 -0
  347. meltygui/view/file_view.py +1599 -0
  348. meltygui/view/graph_cuda_view.py +105 -0
  349. meltygui/view/graph_view.py +882 -0
  350. meltygui/view/header_view.py +848 -0
  351. meltygui/view/input_view.py +238 -0
  352. meltygui/view/inspection_view.py +1783 -0
  353. meltygui/view/layout_view.py +596 -0
  354. meltygui/view/lut_view.py +45 -0
  355. meltygui/view/menu_view.py +212 -0
  356. meltygui/view/orchestration_view.py +658 -0
  357. meltygui/view/query_view.py +118 -0
  358. meltygui/view/search_view.py +342 -0
  359. meltygui/view/tab_view.py +258 -0
  360. meltygui/view/tensor_view.py +430 -0
  361. meltygui/view/terminal_view.py +355 -0
  362. meltygui/view/text_view.py +8031 -0
  363. meltygui/view/texture_view.py +480 -0
  364. meltygui/view/tile_view.py +38 -0
  365. meltygui/view/trace_view.py +923 -0
  366. meltygui/view/voxel_cuda_view.py +824 -0
  367. meltygui/view/voxel_view.py +1860 -0
  368. meltygui/view/window_view.py +111 -0
  369. meltygui-0.1.0.dist-info/METADATA +143 -0
  370. meltygui-0.1.0.dist-info/RECORD +372 -0
  371. meltygui-0.1.0.dist-info/WHEEL +4 -0
  372. meltygui-0.1.0.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,439 @@
1
+ """Decoration view functions and supporting definitions."""
2
+ from math import sqrt
3
+ from meltygui.hdr_color import pack_color
4
+ from meltygui.core.core_render import render_func
5
+ from meltygui.core.rendering.core_decoration import Core
6
+ from meltygui.core.rendering.window_decoration import window
7
+ from meltygui.core.runtime.toggles import mix
8
+ import meltygui_imgui as imgui
9
+
10
+
11
+ @render_func(use_cache=False)
12
+ def draw_drag_drop_target(input_value, draw_state, on_drag, do_flow, depth,
13
+ collection, key, meltygui, y_offset, enable_flow, min_width,
14
+ unique, tag, style_manager, offset=0, indent_size=10):
15
+ from meltygui.core.styling.global_style import GlobalStyle
16
+
17
+ if Core.melty.active_layer == Core.melty.drag_layer:
18
+ return False, 0.0
19
+
20
+ cursor_y_screen = imgui.get_cursor_screen_pos()[1]
21
+
22
+ if collection == input_value or not Core.melty.is_window_enabled():
23
+ return False, 0.0
24
+
25
+ if meltygui.initial_drag_offset is None:
26
+ return False, 0.0
27
+
28
+ if key is None:
29
+ pass
30
+ # ----------------- top spacing -----------
31
+ falloff = 25.0 # Higher is gentler
32
+ if enable_flow:
33
+ drop_gap = 6.0
34
+ else:
35
+ drop_gap = 0.0
36
+
37
+ drag_delta_curve = 1.0 - max(0.0, min(1.0, 1.0 - abs(meltygui.drag_delta[1] / 15.0)))
38
+
39
+ mouse_pos = imgui.get_mouse_pos()
40
+ cursor_top = imgui.get_cursor_screen_pos()[1]
41
+ cursor_left = imgui.get_cursor_screen_pos()[0]
42
+ static_offset = drop_gap
43
+ distance_to_mouse = abs(mouse_pos[1] - cursor_y_screen -
44
+ meltygui.initial_drag_offset[1] - drop_gap + static_offset)
45
+ bell_curve = max(0.0, min(1.0, 1.0 - (distance_to_mouse / falloff)))
46
+
47
+ window_size = imgui.get_window_size()
48
+ window_pos = imgui.get_window_position()
49
+ window_rect = (window_pos[0], window_pos[1],
50
+ window_pos[0] + window_size[0],
51
+ window_pos[1] + window_size[1])
52
+ mouse_over_window = imgui.is_mouse_hovering_rect(*window_rect)
53
+
54
+ if meltygui.drag_in_progress:
55
+ if meltygui.dragged_item is None:
56
+ meltygui.drag_in_progress = False
57
+
58
+ elif id(meltygui.dragged_item._input_value) == id(collection):
59
+ return False, 0.0
60
+
61
+ if meltygui.drag_in_progress and do_flow and not on_drag and mouse_over_window:
62
+ flow_spacing = drop_gap * bell_curve * drag_delta_curve
63
+ else:
64
+ flow_spacing = 0.0
65
+ drag_delta_curve = 1.0
66
+
67
+ if tag == "top":
68
+ Core.melty.flow_spacing += (flow_spacing)
69
+ # imgui.set_cursor_pos_y(imgui.get_cursor_pos()[1] + (flow_spacing))
70
+
71
+ draw_list = imgui.get_window_draw_list()
72
+ # if Core.melty.channels_split:
73
+ # draw_list.channels_set_current(min(Core.melty.max_depth - 1, depth + 2))
74
+
75
+ # line_width = imgui.get_style().frame_padding.y * 2.0
76
+ # color = style_manager.make_color_rgb(*(1.0, 1.0, 1.0), factor=1.0,
77
+ # value=1.0, alpha=1.0, saturation_scale=0.3)
78
+
79
+ # cursor_bottom = imgui.get_cursor_screen_pos()[1]
80
+ # ------------------ end spacing -----------
81
+ cursor_bottom = cursor_top + max(2.0, flow_spacing)
82
+
83
+
84
+ if tag == "bottom":
85
+ # span = cursor_bottom - cursor_top
86
+ cursor_bottom += 0
87
+ cursor_top += 0
88
+
89
+ if meltygui.drag_in_progress and not on_drag and do_flow and mouse_over_window:
90
+ if draw_state.height is not None:
91
+ active_drop = (meltygui.drag_drop_target == draw_state.unique
92
+ and tag == meltygui.drag_drop_target_tag)
93
+
94
+ if Core.melty.channels_split:
95
+ draw_list.channels_set_current(min(Core.melty.get_channel() + 1, Core.melty.max_depth - 1))
96
+
97
+ if active_drop:
98
+ draw_list.channels_set_current(min(Core.melty.get_channel() + 2, Core.melty.max_depth - 1))
99
+ cursor_bottom += ((1.0 - drag_delta_curve) * drop_gap)
100
+
101
+ if distance_to_mouse < meltygui.nearest_drop_distance:
102
+ meltygui.nearest_drop_distance = distance_to_mouse
103
+ meltygui.nearest_drop_target = draw_state.unique
104
+ meltygui.nearest_drop_target_tag = tag
105
+
106
+ meltygui.drag_drop_action.target_unique = draw_state.unique
107
+ meltygui.drag_drop_action.target_tag = tag
108
+ meltygui.drag_drop_action.target_key = key
109
+ meltygui.drag_drop_action.target_collection = collection
110
+ meltygui.drag_drop_action.target_draw_state = draw_state
111
+
112
+ if meltygui.drag_drop_action.target_key is None:
113
+ pass
114
+
115
+ height_as_factor = 800.0
116
+ drag_distance = sqrt(meltygui.drag_delta[0] ** 2 + meltygui.drag_delta[1] ** 2)
117
+ initial_fade_offset = max(min(1.0, meltygui.total_drag_distance / 10.0), 0.0)
118
+ if meltygui.total_drag_frames < 1:
119
+ initial_fade_offset = 0.0
120
+ opacity = max(0.0, min(1.0, 1.0 - (distance_to_mouse / (height_as_factor * 0.3))))
121
+ opacity *= initial_fade_offset
122
+ # opacity = 1.0 if active_drop else opacity
123
+
124
+ bg_tint = Core.melty.get_bg_color(-1)
125
+ bg_style = GlobalStyle.get_global_constant("bg_style", folder="bg_styles")
126
+
127
+ color = style_manager.make_custom_styled(*bg_tint, input=bg_style,
128
+ value=1.3,
129
+ alpha=opacity, saturation=0.8)
130
+
131
+ # color = style_manager.make_color_rgb(*bg_tint, factor=0.0,
132
+ # value=1.0, alpha=opacity, saturation_scale=1.0)
133
+ inactive_color = style_manager.make_custom_styled(*bg_tint, input=bg_style,
134
+ value=0.7,
135
+ alpha=opacity, saturation=0.8)
136
+ # if draw_state.width == None:
137
+ # draw_state.width = min_width
138
+ # if draw_state.left == None:
139
+ # draw_state.left = 1
140
+
141
+ padding = imgui.get_style().frame_padding.x
142
+
143
+ color = color if active_drop else inactive_color
144
+
145
+ top = cursor_top - 1
146
+ bottom = max(draw_state.abs_top, cursor_bottom - 1)
147
+ left = draw_state.abs_left + offset
148
+ right = draw_state.abs_left + draw_state.width - indent_size
149
+ width = draw_state.width
150
+ height = draw_state.height
151
+
152
+ draw_list.add_rect_filled(left, top, right, bottom,
153
+ col=pack_color(*color), rounding=4.0)
154
+
155
+ if opacity > 0:
156
+ Core.melty.cache.mask_mark_rect(draw_state, Core.melty.max_depth - 1, draw_state.shadow_depth, left,
157
+ top, width,
158
+ height,
159
+ key=f"{left}x{top}_flow")
160
+ #
161
+ # draw_list.add_line(draw_state.left, draw_state.abs_top - 2 - offset,
162
+ # draw_state.left + draw_state.width,
163
+ # draw_state.abs_top - 2 - offset,
164
+ # col=pack_color(*color), thickness=3)
165
+
166
+ return False, flow_spacing
167
+
168
+
169
+ def draw_vertical_scrollbar(content_height: float,
170
+ view_height: float,
171
+ view_width: float,
172
+ scroll_offset: float,
173
+ scrollbar_width: float,
174
+ left: float = 0.0,
175
+ top: float = 0.0,
176
+ *,
177
+ pad: float = 0.0,
178
+ rounding: float = 3.0,
179
+ min_grab_size: float | None = None):
180
+ # Style & colors
181
+ style = imgui.get_style()
182
+ if min_grab_size is None:
183
+ min_grab_size = float(style.grab_min_size)
184
+
185
+ col_track = pack_color(0, 0, 0, 0.1)
186
+ col_grab = pack_color(1, 1, 1, 0.3)
187
+ col_border = imgui.get_color_u32(imgui.COLOR_BORDER)
188
+
189
+ # Early clamps & deriveds
190
+ view_height = max(0.0, float(view_height))
191
+ view_width = max(0.0, float(view_width))
192
+ content_height = max(0.0, float(content_height))
193
+ scrollbar_width = max(0.0, float(scrollbar_width))
194
+
195
+ max_scroll = max(0.0, content_height - view_height)
196
+ scroll_offset = float(max(0.0, min(scroll_offset, max_scroll)))
197
+
198
+ # Anchor the container at the current cursor position in screen space
199
+ origin_x, origin_y = (left, top)
200
+
201
+ bar_margin = 4.0
202
+ bar_margin_x = 1.0
203
+
204
+ # Track geometry (stick it to the right edge of the container)
205
+ track_w = min(scrollbar_width, view_width)
206
+ track_h = view_height
207
+ track_x1 = origin_x + (view_width - track_w) - bar_margin_x
208
+ track_y1 = origin_y + bar_margin
209
+ track_x2 = track_x1 + track_w - bar_margin_x
210
+ track_y2 = track_y1 + track_h - bar_margin * 2
211
+
212
+ # Compute grab size & position
213
+ if content_height <= 0.0 or track_h <= 0.0:
214
+ grab_h = 0.0
215
+ t = 0.0
216
+ else:
217
+ # Proportional size with a minimum; cap to track height.
218
+ ratio = view_height / content_height if content_height > 0.0 else 1.0
219
+ grab_h = max(min_grab_size, ratio * track_h)
220
+ grab_h = min(grab_h, track_h)
221
+
222
+ # Normalized scroll position -> grab top
223
+ travel = max(0.0, track_h - grab_h)
224
+ t = 0.0 if max_scroll == 0.0 else (scroll_offset / max_scroll)
225
+ t = max(0.0, min(1.0, t)) # clamp just in case
226
+
227
+ grab_y1 = track_y1 + (max(0.0, track_h - grab_h) * t)
228
+ grab_y2 = grab_y1 + grab_h
229
+
230
+ # Inner padding for nicer visuals
231
+ inner_x1 = track_x1 + pad
232
+ inner_x2 = track_x2 - pad
233
+ inner_y1 = track_y1 + pad
234
+ inner_y2 = track_y2 - pad
235
+ grab_x1 = inner_x1
236
+ grab_x2 = inner_x2
237
+ grab_y1 = max(inner_y1, min(grab_y1, inner_y2 - (grab_y2 - grab_y1)))
238
+ grab_y2 = grab_y1 + max(0.0, min(grab_h, inner_y2 - inner_y1))
239
+
240
+ # Draw
241
+ dl = imgui.get_window_draw_list()
242
+ # Track
243
+ track_w = track_x2 - track_x1
244
+ track_h = track_y2 - track_y1
245
+ dl.add_rect_filled(track_x1, track_y1, track_x2, track_y2, col_track, rounding)
246
+ # Core.melty.cache.mask_mark_rect(Core.melty.depth, track_x1, track_y1, track_w, track_h,
247
+ # key=str(Core.melty.unique_stack[-1]) + "scrollbar")
248
+
249
+ dl.add_rect(track_x1, track_y1, track_x2, track_y2, col_border, rounding)
250
+ # Grab
251
+ if grab_y2 > grab_y1 and grab_x2 > grab_x1:
252
+ dl.add_rect_filled(grab_x1, grab_y1, grab_x2, grab_y2, col_grab, rounding)
253
+ dl.add_rect(grab_x1, grab_y1, grab_x2, grab_y2, col_border, rounding)
254
+
255
+ return {
256
+ "offset": scroll_offset,
257
+ "track_min": (track_x1, track_y1),
258
+ "track_max": (track_x2, track_y2),
259
+ "grab_min": (grab_x1, grab_y1),
260
+ "grab_max": (grab_x2, grab_y2),
261
+ "visible": content_height > view_height
262
+ }
263
+
264
+
265
+ @window
266
+ def draw_bg(left=25, top=0, width=0, height=57, depth=0, rounding=6.0, bg_offset=0,
267
+ outline=True, bg_color=None, opacity=0.0,
268
+ style_manager=None, tint=None, outline_tint=None, selected=False,
269
+ hovered=False, pressed=False, nested_bg=False, saturation=1.0, max_bg_depth=None,
270
+ max_bg_value=None, **kwargs):
271
+ # -- Constants ---------------------------------
272
+ from meltygui.core.cache.tile_cache import snap_int
273
+ from meltygui.core.rendering.render_dispatch import _DRAW_BG_COLOUR_MEMO
274
+ from meltygui.core.rendering.render_dispatch import _DRAW_BG_FILL_MEMO
275
+ from meltygui.model.color_model import _clamp_bg_value
276
+
277
+ min_value = -0.272
278
+ depth_wrap = 300
279
+ depth_scale = 6.241
280
+
281
+ # [tint=(2,1,1)]
282
+ corner_radius = rounding
283
+ border_inset = 2.802
284
+ border_inset_half = 1.5
285
+ if not outline:
286
+ # The inset only exists to seat the fill inside the outline stroke.
287
+ # With no outline the fill IS the view's edge (freeze_resize panes
288
+ # via draw_freeze_bg): keep the inset and content clipped at the
289
+ # view edge hangs a few px past its own background.
290
+ border_inset = 0.0
291
+ stroke_width = 4.0
292
+ # How depth maps to color intensity
293
+ intensity_factor = 0.021
294
+ intensity_offset = 10.018
295
+
296
+ some_var = [32, 18, 19]
297
+ # Outline color tuning
298
+ outline_base = 1.765
299
+ outline_depth_mul = 0.786
300
+ outline_sat = {'default': 1.1, 'nested': 1.473}
301
+
302
+ # More text
303
+ bleed_mix = {'nested': 0.472, 'default': 0.526}
304
+ bleed_style = {'value': -0.035, 'alpha': 1.112, 'saturation': 6.592}
305
+ outline_bleed_mix = 0.272
306
+ # Hover offsets per interaction state
307
+ hover_offset_by_state = {
308
+ 'default': -1.807,
309
+ 'selected': -1.401,
310
+ 'pressed_hi': -1.813, # pressed + opacity > 0.5
311
+ 'pressed_lo': -0.441,
312
+ }
313
+ bg_style = {
314
+ 'value': -0.004, 'saturation': 1.101,
315
+ 'alpha': 0.504, 'max_value': 1.8,
316
+ }
317
+
318
+ # ── Helpers ────────────────────────────────────────────────
319
+ def current_indent_px():
320
+ return Core.melty.current_indent
321
+
322
+ def mix_colors(color_a, color_b, factor):
323
+ return (
324
+ color_a[0] * (1 - factor) + color_b[0] * factor,
325
+ color_a[1] * (1 - factor) + color_b[1] * factor,
326
+ color_a[2] * (1 - factor) + color_b[2] * factor,
327
+ )
328
+
329
+ # -- Depth calculation -------------------
330
+ max_depth = 30
331
+ if Core.melty.bg_depth + bg_offset < 2:
332
+ wrapped_depth = min(max_depth, (Core.melty.bg_depth) + bg_offset)
333
+ else:
334
+ wrapped_depth = min(max_depth, (Core.melty.bg_depth % depth_wrap) + bg_offset)
335
+
336
+ # Caller-supplied ceiling on the effective depth: after this step the view
337
+ # keeps the color entry for max_bg_depth instead of getting lighter.
338
+ if max_bg_depth is not None:
339
+ wrapped_depth = min(wrapped_depth, max_bg_depth)
340
+
341
+ scaled_depth = wrapped_depth * depth_scale
342
+ depth_intensity = (scaled_depth + intensity_offset) * intensity_factor
343
+ max_depth_intensity = 0.652
344
+ depth_intensity = min(depth_intensity, max_depth_intensity)
345
+
346
+ # ── Geometry ───────────────────────────────────────────────
347
+ right = left + width
348
+ bottom = top + height
349
+
350
+ fill_rect = (
351
+ snap_int(left) + border_inset, snap_int(top) + border_inset,
352
+ snap_int(right) - border_inset, snap_int(bottom) - border_inset,
353
+ )
354
+ outline_rect = (
355
+ snap_int(left) + border_inset_half, snap_int(top) + border_inset_half,
356
+ snap_int(right) - border_inset_half, snap_int(bottom) - border_inset_half,
357
+ )
358
+
359
+ # ── Interaction hover offset ───────────────────────────────
360
+ hover_offset = hover_offset_by_state['default']
361
+ if selected:
362
+ hover_offset = hover_offset_by_state['selected']
363
+ elif pressed:
364
+ if opacity > 0.5:
365
+ hover_offset = hover_offset_by_state['pressed_hi']
366
+ else:
367
+ hover_offset = hover_offset_by_state['pressed_lo']
368
+
369
+ # ── Outline style ──────────────────────────────────────────
370
+ sat = outline_sat['default']
371
+ depth_mul = outline_depth_mul
372
+ if not nested_bg:
373
+ depth_mul *= 1.00
374
+ sat = outline_sat['nested']
375
+
376
+ # ── Background bleed color ─────────────────────────────────
377
+ bleed_factor = bleed_mix['nested'] if nested_bg else bleed_mix['default']
378
+
379
+ # The bleed / outline colours are a pure function of the style manager,
380
+ # the two bg-stack colours behind this box and a few scalars - memoized,
381
+ # since ~40 draw_bg calls a frame (inline widgets, flat buttons) each
382
+ # require four hsv round trips for the same handful of params.
383
+ bg_m2 = Core.melty.get_bg_color(-2)
384
+ bg_m1 = Core.melty.get_bg_color(-1)
385
+ outline_value = max(min_value, depth_intensity * depth_mul + outline_base + hover_offset)
386
+ colour_key = (style_manager.hsv, bg_m2, bg_m1, outline_value, sat)
387
+ memo = _DRAW_BG_COLOUR_MEMO.get(colour_key)
388
+ if memo is None:
389
+ bleed_color = style_manager.make_custom_styled(
390
+ *bg_m2, input=bg_style, **bleed_style,
391
+ )
392
+ bleed_base = mix(*bg_m1[:3], *bleed_color[:3], 0.32)
393
+ bleed_color = style_manager.make_custom_styled(
394
+ *bleed_base, input=bg_style, **bleed_style,
395
+ )
396
+ # ── Outline rendering ──────────────────────────────────────
397
+ outline_color = style_manager.make_color_style_value(
398
+ input=bg_style, saturation=sat, value=outline_value,
399
+ )
400
+ outline_color = mix_colors(outline_color, bleed_color, outline_bleed_mix)
401
+ if len(_DRAW_BG_COLOUR_MEMO) > 2048:
402
+ _DRAW_BG_COLOUR_MEMO.clear()
403
+ memo = _DRAW_BG_COLOUR_MEMO[colour_key] = (bleed_color, outline_color)
404
+ bleed_color, outline_color = memo
405
+
406
+ if outline:
407
+ packed_outline = pack_color(*outline_color[:3], 1.0)
408
+ if outline_tint is not None:
409
+ packed_outline = pack_color(*outline_tint[:3], 1.0)
410
+ imgui.get_window_draw_list().add_rect(
411
+ *outline_rect, col=packed_outline, rounding=corner_radius, thickness=stroke_width,
412
+ )
413
+
414
+ # ── Fill rendering ─────────────────────────────────────────
415
+ if bg_color is None:
416
+ # Fill colour memoized beside the bleed/outline memo: same inputs
417
+ # plus the fill's own saturation / depth intensity / bleed factor.
418
+ fill_key = (colour_key, saturation, depth_intensity, bleed_factor)
419
+ bg_color = _DRAW_BG_FILL_MEMO.get(fill_key)
420
+ if bg_color is None:
421
+ bg_color = style_manager.make_color_style_value(input=bg_style, saturation=bg_style['saturation'] * saturation,
422
+ value=max(min_value, depth_intensity))
423
+ bg_color = mix_colors(bg_color, bleed_color, bleed_factor)
424
+ if len(_DRAW_BG_FILL_MEMO) > 2048:
425
+ _DRAW_BG_FILL_MEMO.clear()
426
+ _DRAW_BG_FILL_MEMO[fill_key] = bg_color
427
+
428
+ # Applies to whatever ends up as the fill - depth-ramp color OR a passed
429
+ # bg_color/tint, so the cap holds regardless of the input's hue/brightness.
430
+ bg_color = _clamp_bg_value(bg_color, max_bg_value)
431
+ packed_fill = pack_color(bg_color[0], bg_color[1], bg_color[2], 1.0)
432
+ if tint is not None:
433
+ tinted = _clamp_bg_value(tint, max_bg_value)
434
+ packed_fill = pack_color(*tinted[:3], opacity)
435
+
436
+ if opacity > 0.0:
437
+ imgui.get_window_draw_list().add_rect_filled(*fill_rect, col=packed_fill, rounding=corner_radius)
438
+
439
+ return False, bg_color
@@ -0,0 +1,177 @@
1
+ """Diagnostic view functions and supporting definitions."""
2
+ from meltygui.core.conversion.path_finder import Pending
3
+ from meltygui.hdr_color import pack_color
4
+ from meltygui.core.rendering.modes import Modes
5
+ from meltygui.core.core_render import render_func
6
+ from meltygui.state.core_enums import PendingAction
7
+ from meltygui.state.core_undo import NavUndo
8
+ from meltygui.state.new_core_model import DrawState
9
+ from meltygui.view.header_view import draw_header
10
+ from meltygui_imgui.core import _DrawList
11
+ from pathlib import Path
12
+ import meltygui_imgui as imgui
13
+ import threading
14
+ import types
15
+
16
+
17
+ @render_func(is_default_for=(types.FrameType), use_cache=True, tint=(0.6, 0.2, 0.0),
18
+ header_same_line=False, show_bg=False, align_header=False, closed=False,
19
+ shadow=True, selectable=False, wrap=False, with_header=draw_header,
20
+ indent_size=5, searchable=True, shaodw=False, bg_offset=3)
21
+ def draw_frame(input_value: types.FrameType, draw_state, **kwargs):
22
+ from meltygui.core.styling.fonts import Font
23
+ from meltygui.view.control_view import button
24
+ from meltygui.view.text_view import draw_text
25
+ from meltygui.core.rendering.render_dispatch import draw_any
26
+
27
+ file_name_truncated = Path(input_value.f_code.co_filename).name
28
+ imgui.text(f"{file_name_truncated}:{input_value.f_lineno} in {input_value.f_code.co_name}")
29
+
30
+
31
+ # threaded open_in_intellij pattern the jump-to-calling button uses. # Jump-to-error: open the frame's source file at the failing line. Same
32
+ if button(f"{file_name_truncated}:{input_value.f_lineno}",
33
+ height=59, value=0.4, saturation=1.5, name="jump_to_frame")[0]:
34
+ from meltygui.utils.jump_to_code import open_in_intellij
35
+
36
+ threading.Thread(
37
+ target=open_in_intellij,
38
+ args=(str(input_value.f_code.co_filename),),
39
+ kwargs={"line_number": input_value.f_lineno},
40
+ daemon=True).start()
41
+ # Loop over the frame's local variables, which are the most relevant to debugging.
42
+
43
+ draw_text("Locals", name="Locals", show_header=False,
44
+ font=Font.JETBRAINS_MONO_40, bg_offset=3)
45
+
46
+ for var_name, var_value in input_value.f_locals.items():
47
+ # Display the variable name and its value.
48
+ imgui.set_cursor_screen_pos((imgui.get_cursor_screen_pos()[0] + 40, imgui.get_cursor_screen_pos()[1]))
49
+ imgui.begin_group()
50
+ draw_any(var_value, with_header=draw_header, show_header=True, name=var_name, mode=Modes.READ_ONLY)
51
+ imgui.end_group()
52
+
53
+
54
+ @render_func
55
+ def draw_draw_state(input_value, **kwargs):
56
+ pass
57
+
58
+
59
+ def render_profiler_time(input_value=None, brief=False, style_manager=None):
60
+ """
61
+ Renders the time taken for a specific operation in the profiler.
62
+ """
63
+ from meltygui.core.styling.global_style import GlobalStyle
64
+
65
+ in_ms = input_value * 1000.0
66
+ if brief:
67
+ if in_ms >= 0.99:
68
+ formatted_value = f"{(in_ms):.1f}ms"
69
+ else:
70
+ formatted_value = f"{(in_ms):.2f}ms"
71
+ if formatted_value.startswith("0."):
72
+ formatted_value = formatted_value[1:]
73
+ else:
74
+ formatted_value = f"{in_ms:.2f} ms"
75
+ golden_yellow = (2.0, 0.5, 0)
76
+ dynamic_saturation_factor = GlobalStyle.profiler["object_attr"][
77
+ "dynamic_saturation_factor"]
78
+ dynamic_saturation_offset = GlobalStyle.profiler["object_attr"][
79
+ "dynamic_saturation_offset"]
80
+ saturation = GlobalStyle.profiler["object_attr"]["saturation"]
81
+ value = GlobalStyle.profiler["object_attr"]["value"]
82
+ dynamic_sat = (float(in_ms + dynamic_saturation_offset) * dynamic_saturation_factor)
83
+ text_tint = style_manager.make_color_rgb(*golden_yellow, factor=1.0 - dynamic_sat,
84
+ value=min(1.0, max(0, value + dynamic_sat * 0.5)),
85
+ alpha=1.0,
86
+ saturation_scale=max(0, saturation - dynamic_sat))[:3]
87
+ imgui.text_colored(f"{formatted_value}", *text_tint)
88
+ return False, input_value
89
+
90
+
91
+ @render_func(is_default_for="ImGuiStyleManager", tint=(0.8, 0.7, 0), use_cache=True, with_header=None)
92
+ def draw_style_manager(input_val):
93
+ imgui.text("Style Manager")
94
+
95
+ return False, input_val
96
+
97
+
98
+ @render_func(show_header=False, show_name=False, show_bg=True, with_header=draw_header)
99
+ def draw_debug_label(input_value: str):
100
+ imgui.text(input_value)
101
+
102
+
103
+ def draw_debug(x, y, label, color=(1, 0, 0), size=16):
104
+ draw_list: _DrawList = imgui.get_overlay_draw_list()
105
+ draw_list.add_circle_filled(x, y, size, pack_color(*color, 1.0))
106
+ draw_list.add_text(x + size + 2, y - size / 2, pack_color(*color, 1.0), label)
107
+
108
+
109
+ @render_func(show_bg=True, use_cache=True, shadow=False, with_header=draw_header)
110
+ def draw_undo_manager(input_value, **kwargs):
111
+ """Render both undo timelines — edits (input_value is the UndoManager
112
+ class, handed in by @window) and NavUndo's navigation stack — grouped by
113
+ undo step (one user action), newest first. Changes from the same action
114
+ share a group_id and undo together, so we draw a separator between groups
115
+ and indent the changes within each."""
116
+ for title, stack in (("Edits", input_value.stack), ("Navigation", NavUndo.stack)):
117
+ history = list(stack.history)
118
+ group_count = len({c.group_id for c in history})
119
+ imgui.text(f"{title}: {group_count} undo step(s), {len(history)} change(s)"
120
+ f" (redo: {len(stack.redo_stack)})")
121
+ prev_gid = None
122
+ shown = 0
123
+ for change in reversed(history):
124
+ if change.group_id != prev_gid:
125
+ imgui.separator()
126
+ prev_gid = change.group_id
127
+ from_val = str(change.old)[:20] # truncate long values for readability
128
+ to_val = str(change.new)[:20]
129
+ imgui.text(f" {change.display_name}: {from_val} -> {to_val}")
130
+ shown += 1
131
+ if shown >= 12:
132
+ imgui.text(f"... and {len(history) - shown} more")
133
+ break
134
+ imgui.dummy(1, 8)
135
+ return False, input_value
136
+
137
+
138
+ @render_func(is_default_for=(DrawState), tint=(0.2, 0.6, 0.8), show_bg=True, shadow=False, with_header=None)
139
+ def draw_draw_state_info(input_value: DrawState):
140
+ imgui.text(f"DrawState")
141
+ imgui.text(f"Tile ID: {input_value._tile_id}")
142
+ imgui.text(f"Content WxH: {input_value.content_width} x {input_value.content_height}")
143
+
144
+
145
+ @render_func(use_cache=True, with_header=draw_header, show_bg=True, is_default_for=Pending)
146
+ def draw_pending(input_value, draw_state=None):
147
+ imgui.text(input_value.originated.__name__)
148
+ imgui.push_text_wrap_pos(draw_state.left + draw_state.content_width)
149
+ imgui.text_wrapped(str(input_value.status))
150
+ imgui.pop_text_wrap_pos()
151
+
152
+ return False, input_value
153
+
154
+
155
+ @render_func(use_cache=True, show_header=False, shadow=True)
156
+ def pending_window(input_value, button_name, pending=None, draw_state=None,
157
+ show_revert=False, show_load=False):
158
+ from meltygui.view.control_view import button
159
+ from meltygui.view.text_view import draw_text
160
+ from meltygui.core.layout.cursor_core import same_line
161
+
162
+ draw_text(str(pending.status), width=draw_state.width, name="Status", show_bg=True, shadow=False, with_footer=None)
163
+ imgui.dummy(0, 5)
164
+
165
+ if button(str(button_name), width=100, height=25)[0]:
166
+ return True, PendingAction.APPLY
167
+ if show_revert:
168
+ same_line()
169
+ if button("Revert", width=100, height=25, color=(0.8, 0.3, 0.3),
170
+ factor=0.3, value=0.0, text_value=2.0, saturation=0.4)[0]:
171
+ return True, PendingAction.REVERT
172
+ if show_load:
173
+ same_line()
174
+ if button("Load", width=100, height=25, color=(0.3, 0.5, 0.8), factor=0.8)[0]:
175
+ return True, PendingAction.LOAD
176
+
177
+ return False, input_value