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,480 @@
1
+ """Texture view functions and supporting definitions."""
2
+ from meltygui.core.graphics.gl_state import GLState
3
+ from meltygui.core.graphics.shader_func import shader_func
4
+ from meltygui.graphics.texture_manager import PendingTexture
5
+ from meltygui.hdr_color import pack_color
6
+ from meltygui.core.core_render import render_func
7
+ from meltygui.core.rendering.core_decoration import Core
8
+ from meltygui.state.new_core_model import ZoomState
9
+ from meltygui.view.header_view import draw_header
10
+ from meltygui_imgui.core import _DrawList
11
+ import OpenGL.GL as gl
12
+ import math
13
+ import meltygui_imgui as imgui
14
+ import numpy
15
+
16
+
17
+ @render_func(is_default_for=PendingTexture, use_cache=True, wrap=True, z_offset=0, selectable=False,
18
+ show_bg=False, auto_resize=True, with_header=draw_header)
19
+ def draw_pending_texture(input_value: PendingTexture, draw_state, **kwargs):
20
+ from meltygui.view.texture_view import draw_texture
21
+
22
+ if input_value.texture_id is None:
23
+ imgui.text(f"Uploading... {id(input_value)}")
24
+ return False, input_value
25
+
26
+ # Sized by the caller (an editor pane passes width+height): fill the box
27
+ # - draw_texture fits the image inside it with zoom/pan. Otherwise (a
28
+ # folder-tree leaf) a 300px thumbnail at the image's resolution.
29
+ fill_w, fill_h = kwargs.get("width"), kwargs.get("height")
30
+ if fill_w and fill_h:
31
+ size_kwargs = {"width": max(35, fill_w - 4), "height": max(35, fill_h - 4)}
32
+ else:
33
+ max_size = 300
34
+ if input_value.tex_width > input_value.tex_height:
35
+ width = max_size
36
+ height = int(max_size * input_value.tex_height / input_value.tex_width)
37
+ else:
38
+ height = max_size
39
+ width = int(max_size * input_value.tex_width / input_value.tex_height)
40
+ size_kwargs = {"initial": {"width": width, "height": height}}
41
+
42
+ return_val = draw_texture(input_value.texture_id, **size_kwargs,
43
+ name=f"{draw_state.id}_inner", auto_resize=False,
44
+ show_header=False, use_cache=True, wrap=False, tint=(0.11, 0.29, 0.52))
45
+
46
+ return return_val
47
+
48
+
49
+ @render_func(is_default_for=numpy.uint32, show_bg=False, use_cache=False, show_add_delete=False, z_offset=0,
50
+ fill_height=True, selectable=False,
51
+ indent_size=0, min_width=35, min_height=35, wrap=False, disable_scroll=True,
52
+ zoom_speed=0.3, with_header=draw_header, manual_content_height=True)
53
+ def draw_texture(input_value: numpy.uint32, hovered, scroll_y_changed, middle_mouse_drag, double_right_mouse_drag,
54
+ zoom_state: ZoomState, zoom_speed, header_height=0, min_zoom=0.1,
55
+ max_zoom=50.0, style_manager=None, max_brightness=5.0, max_contrast=5.0,
56
+ draw_state=None, jet=False, nearest=False, dim_outside=None, dim_alpha=0.55, show_info=True, flip_y=False, **kwargs):
57
+ import meltygui.core.windowing.window_api as glfw
58
+
59
+ original_id = input_value
60
+ texture_id = input_value
61
+ imgui.dummy(draw_state.width, draw_state.height - 20)
62
+
63
+ # Ensure we have valid state if this is the first run
64
+ if not hasattr(zoom_state, 'zoom'):
65
+ zoom_state.zoom = 1.0
66
+ zoom_state.center_u = 0.5
67
+ zoom_state.center_v = 0.5
68
+
69
+ # Check if opengl texture ID is valid
70
+ if not gl.glIsTexture(texture_id):
71
+ imgui.text(f"Error: {texture_id} is not a valid texture")
72
+ return False, input_value
73
+
74
+ # 1. Query Texture Properties
75
+ original_texture = gl.glGetIntegerv(gl.GL_TEXTURE_BINDING_2D)
76
+ gl.glBindTexture(gl.GL_TEXTURE_2D, texture_id)
77
+
78
+ width = gl.glGetTexLevelParameteriv(gl.GL_TEXTURE_2D, 0, gl.GL_TEXTURE_WIDTH)
79
+ height = gl.glGetTexLevelParameteriv(gl.GL_TEXTURE_2D, 0, gl.GL_TEXTURE_HEIGHT)
80
+ gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
81
+
82
+ if width > 16384 or height > 16384:
83
+ imgui.text(f"Error: Texture size {width}x{height} exceeds maximum supported size.")
84
+ return False, input_value
85
+
86
+ if width == 0 or height == 0:
87
+ return False, input_value
88
+
89
+ # 2. Canvas Setup (Fill all space)
90
+ view_width = max(1, draw_state.width)
91
+ view_height = max(1, draw_state.height)
92
+
93
+ # 3. Calculate Aspect Ratio Corrections
94
+ tex_aspect = width / height
95
+ view_aspect = view_width / view_height
96
+
97
+ # Calculate the visible UV width/height based on zoom and aspect ratio.
98
+ if view_aspect > tex_aspect:
99
+ # View is wider: Fit to Height
100
+ uv_height_size = 1.0 / zoom_state.zoom
101
+ uv_width_size = uv_height_size * (view_aspect / tex_aspect)
102
+ else:
103
+ # View is taller: Fit to Width
104
+ uv_width_size = 1.0 / zoom_state.zoom
105
+ uv_height_size = uv_width_size * (tex_aspect / view_aspect)
106
+
107
+ mixed_color = (1, 1, 1, 1)
108
+ highlight_color = (1, 1, 1, 1)
109
+
110
+ if style_manager is not None:
111
+ mixed_color = style_manager.make_color_rgb(*mixed_color[:3],
112
+ value=0.3,
113
+ factor=0.9,
114
+ saturation_scale=1.0,
115
+ alpha=1.0)
116
+ highlight_color = style_manager.make_color_rgb(*mixed_color[:3],
117
+ value=1.0,
118
+ factor=0.9,
119
+ saturation_scale=1.0,
120
+ alpha=1.0)
121
+ io = imgui.get_io()
122
+ overlay: _DrawList = imgui.get_overlay_draw_list()
123
+
124
+ if double_right_mouse_drag:
125
+ b_str = f"{zoom_state.brightness:.3f}"
126
+ overlay.add_text(double_right_mouse_drag.x, double_right_mouse_drag.y - 30,
127
+ col=pack_color(*highlight_color[:3], 1),
128
+ text=f"brightness:{zoom_state.brightness:.3}\ncontrast:{zoom_state.contrast:.3}")
129
+
130
+ if io.key_shift:
131
+ if io.key_ctrl:
132
+ zoom_state.hue += double_right_mouse_drag.dx * 0.001
133
+ zoom_state.saturation -= double_right_mouse_drag.dy * 0.001
134
+ else:
135
+ zoom_state.brightness += double_right_mouse_drag.dx * 0.001
136
+ zoom_state.contrast -= double_right_mouse_drag.dy * 0.001
137
+ else:
138
+ if io.key_ctrl:
139
+ zoom_state.hue += double_right_mouse_drag.dx * 0.005
140
+ zoom_state.saturation -= double_right_mouse_drag.dy * 0.005
141
+ else:
142
+ zoom_state.brightness += double_right_mouse_drag.dx * 0.005
143
+ zoom_state.contrast -= double_right_mouse_drag.dy * 0.005
144
+
145
+ # zoom_state.brightness = max(0.0, min(max_brightness, zoom_state.brightness))
146
+ # zoom_state.contrast = max(0.0, min(max_contrast, zoom_state.contrast))
147
+
148
+ if jet:
149
+ texture_id = Core.melty.filter.brightness_contrast(
150
+ input_value,
151
+ brightness=zoom_state.brightness,
152
+ contrast=zoom_state.contrast
153
+ )
154
+
155
+ # texture_id = Core.melty.filter.swirl(
156
+ # input_value,
157
+ # radius=zoom_state.brightness,
158
+ # angle=zoom_state.contrast
159
+ #
160
+ # )
161
+ texture_id = Core.melty.filter.jet(texture_id, offset=zoom_state.hue)
162
+ else:
163
+ texture_id = Core.melty.filter.brightness_contrast(
164
+ input_value,
165
+ brightness=zoom_state.brightness,
166
+ contrast=zoom_state.contrast
167
+ )
168
+
169
+ # texture_id = Core.melty.filter.swirl(
170
+ # input_value,
171
+ # radius=zoom_state.brightness,
172
+ # angle=zoom_state.contrast
173
+ #
174
+ # )
175
+ texture_id = Core.melty.filter.hue_saturation(
176
+ texture_id,
177
+ saturation=(zoom_state.saturation),
178
+ hue_shift=(zoom_state.hue),
179
+ )
180
+
181
+ # texture_id = Core.melty.filter.swirl(
182
+ # input_value,
183
+ # radius=1.0,
184
+ # angle=(zoom_state.brightness * 5),
185
+ # )
186
+ # texture_id = Core.melty.filter.swirl(
187
+ # texture_id,
188
+ # angle=zoom_state.brightness,
189
+ # radius=zoom_state.contrast
190
+ # )
191
+
192
+ # `dim_outside=(x0, y0, x1, y1)` (texels, row 0 = top): the image is drawn
193
+ # darkened by `dim_alpha` (the `multiply` filter) and the rectangle is
194
+ # drawn over it from the undimmed texture, then outlined -- the
195
+ # hdr-viewer's crop selection. Translucent fills on the image never
196
+ # showed here (09-14); the image path does.
197
+ bright_texture_id = texture_id
198
+ if dim_outside is not None:
199
+ texture_id = Core.melty.filter.multiply(texture_id, factor=1.0 - dim_alpha)
200
+
201
+ # Pixel mode: `nearest=True` shows the texels as hard squares when zoomed
202
+ # in (see hdr-viewer: "Pixel Mode Nearest" menu item), else bilinear.
203
+ # Stamped every frame on the filter chain's OUTPUT texture - that is what
204
+ # gets drawn, and the filter may hand back a different or reused texture
205
+ # from one frame to the next.
206
+ filter_mode = gl.GL_NEAREST if nearest else gl.GL_LINEAR
207
+ gl.glBindTexture(gl.GL_TEXTURE_2D, texture_id)
208
+ gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, filter_mode)
209
+ gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, filter_mode)
210
+ gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
211
+
212
+ p_min = (draw_state.abs_left + 2, draw_state.abs_top + 2)
213
+ p_max = (draw_state.abs_left + draw_state.width, draw_state.abs_top + draw_state.height - 2)
214
+ p_min_x, p_min_y = p_min[0], p_min[1]
215
+
216
+ scroll_delta = 0
217
+ if scroll_y_changed is not None:
218
+ scroll_delta = scroll_y_changed.value
219
+
220
+ # --- Logic: Zoom and Pan ---
221
+
222
+ zoom_delta = 0.0
223
+
224
+ # 4a. Handle Zoom Triggers (Scroll & Keyboard)
225
+
226
+ # Keyboard Shortcuts (1, 2, 3, 4)
227
+ forced_zoom = -1.0
228
+ key_1 = 49
229
+ numpad_key_1 = 321
230
+ # Not while a text field has the keyboard (a meltygui draw_text editor or an
231
+ # imgui input): typing a path with a "4" in it over the image zoomed the
232
+ # hdr-viewer to 12.5 % (09-14).
233
+ typing = Core.melty.text_focused_ds is not None or io.want_text_input
234
+ if hovered and not typing:
235
+ if imgui.is_key_pressed(key_1) or imgui.is_key_pressed(numpad_key_1): # Key '1'
236
+ forced_zoom = 1.0
237
+ # Reset Pan to Center
238
+ zoom_state.center_u = 0.5
239
+ zoom_state.center_v = 0.5
240
+ zoom_state.brightness = 0.0
241
+ zoom_state.contrast = 1.0
242
+ zoom_state.hue = 0.0
243
+ zoom_state.saturation = 1.0
244
+ elif imgui.is_key_pressed(50): # Key '2'
245
+ forced_zoom = 0.5
246
+ zoom_state.brightness = 0.0
247
+ zoom_state.contrast = 1.0
248
+ zoom_state.hue = 0.0
249
+ zoom_state.saturation = 1.0
250
+ elif imgui.is_key_pressed(51): # Key '3'
251
+ forced_zoom = 0.25
252
+ zoom_state.brightness = 0.0
253
+ zoom_state.contrast = 1.0
254
+ zoom_state.hue = 0.0
255
+ zoom_state.saturation = 1.0
256
+ elif imgui.is_key_pressed(52): # Key '4'
257
+ forced_zoom = 0.125
258
+ zoom_state.brightness = 0.0
259
+ zoom_state.contrast = 1.0
260
+ zoom_state.hue = 0.0
261
+ zoom_state.saturation = 1.0
262
+
263
+ # Double-click toggles between the image centred at native size (one
264
+ # texel per pixel, which "100 %" scrolling rarely lands on exactly) and
265
+ # fit. Zoom 1.0 is fit, and native is the texture's size over the view's
266
+ # along the fitted axis; "at native" allows a hair of float slop.
267
+ # The toggle fires on the RELEASE of a double click that did not drag:
268
+ # a double-click-and-drag is the hdr-viewer's crop gesture (09-14), and
269
+ # toggling on the press would jump the view under the drag.
270
+ if hovered and imgui.is_mouse_double_clicked(0):
271
+ zoom_state.double_click_armed = True
272
+ double_click = False
273
+ if getattr(zoom_state, 'double_click_armed', False):
274
+ if imgui.is_mouse_dragging(0, 4.0):
275
+ zoom_state.double_click_armed = False
276
+ elif imgui.is_mouse_released(0):
277
+ zoom_state.double_click_armed = False
278
+ double_click = True
279
+ if double_click:
280
+ if view_aspect > tex_aspect:
281
+ native_zoom = height / max(1.0, view_height)
282
+ else:
283
+ native_zoom = width / max(1.0, view_width)
284
+ native_zoom = max(min_zoom, min(native_zoom, max_zoom))
285
+ at_native = abs(math.log2(zoom_state.zoom / native_zoom)) < 0.01
286
+ forced_zoom = 1.0 if at_native else native_zoom
287
+ zoom_state.center_u = 0.5
288
+ zoom_state.center_v = 0.5
289
+
290
+ if forced_zoom > 0:
291
+ zoom_state.zoom = forced_zoom
292
+ # Recalculate uv sizes immediately for consistent bounding this frame
293
+ if view_aspect > tex_aspect:
294
+ uv_height_size = 1.0 / zoom_state.zoom
295
+ uv_width_size = uv_height_size * (view_aspect / tex_aspect)
296
+ else:
297
+ uv_width_size = 1.0 / zoom_state.zoom
298
+ uv_height_size = uv_width_size * (tex_aspect / view_aspect)
299
+
300
+ # Scroll Logic: zoom_delta is in STOPS (log2): a notch multiplies the
301
+ # zoom by 2^(zoom_speed/2) (~11 % at the default 0.3), shift is 0.3x
302
+ # that. Exponential steps are symmetric, so zooming up and down cancel
303
+ # exactly instead of drifting (the old 1 + delta style gained ~9 % per
304
+ # round trip and the view could never find its way home to fit).
305
+ zoom_step = zoom_speed * 0.5
306
+ if scroll_delta != 0:
307
+ if io.key_shift:
308
+ zoom_delta = scroll_delta * zoom_step * 0.3
309
+ else:
310
+ zoom_delta = scroll_delta * zoom_step
311
+ elif middle_mouse_drag and middle_mouse_drag.modifiers == glfw.MOD_CONTROL:
312
+ zoom_delta = io.mouse_delta.y * -0.008
313
+
314
+ # 4b. Handle Pan (Middle Click Drag)
315
+ if middle_mouse_drag and middle_mouse_drag.modifiers != glfw.MOD_CONTROL:
316
+ u_scale = uv_width_size / view_width
317
+ v_scale = uv_height_size / view_height
318
+ if middle_mouse_drag.modifiers == glfw.MOD_SHIFT:
319
+ zoom_state.center_u -= middle_mouse_drag.dx * u_scale * 0.5
320
+ zoom_state.center_v += middle_mouse_drag.dy * v_scale * 0.5
321
+ else:
322
+ zoom_state.center_u -= middle_mouse_drag.dx * u_scale
323
+ zoom_state.center_v += middle_mouse_drag.dy * v_scale
324
+
325
+ # 4c. Apply Zoom Logic (Zoom to Cursor)
326
+ if zoom_delta != 0.0:
327
+ new_zoom = max(min_zoom, min(zoom_state.zoom * (2.0 ** zoom_delta), max_zoom))
328
+
329
+ if new_zoom != zoom_state.zoom:
330
+ mouse_pos = imgui.get_mouse_pos()
331
+
332
+ if io.key_ctrl:
333
+ mouse_u_ratio, mouse_v_ratio = (0.5, 0.5)
334
+ else:
335
+ mouse_u_ratio = (mouse_pos[0] - p_min_x) / view_width
336
+ mouse_v_ratio = (mouse_pos[1] - p_min_y) / view_height
337
+
338
+ curr_uv_w = uv_width_size
339
+ curr_uv_h = uv_height_size
340
+
341
+ # Recalculate new UV dimensions
342
+ if view_aspect > tex_aspect:
343
+ new_uv_h = 1.0 / new_zoom
344
+ new_uv_w = new_uv_h * (view_aspect / tex_aspect)
345
+ else:
346
+ new_uv_w = 1.0 / new_zoom
347
+ new_uv_h = new_uv_w * (tex_aspect / view_aspect)
348
+
349
+ diff_w = curr_uv_w - new_uv_w
350
+ diff_h = curr_uv_h - new_uv_h
351
+
352
+ # Every step anchors on the mouse, zooming out included: the
353
+ # image is not pulled back to centre on the way to fit (that
354
+ # homing was removed 09-14; the bounding step below still keeps
355
+ # it on screen).
356
+ zoom_state.center_u += diff_w * (mouse_u_ratio - 0.5)
357
+ zoom_state.center_v += diff_h * (0.5 - mouse_v_ratio)
358
+
359
+ zoom_state.zoom = new_zoom
360
+
361
+ # Update these for Step 5
362
+ uv_width_size = new_uv_w
363
+ uv_height_size = new_uv_h
364
+
365
+ # 5. Calculate Final UVs and Clamp to Bounds
366
+ half_uv_w = uv_width_size * 0.5
367
+ half_uv_h = uv_height_size * 0.5
368
+
369
+ # --- Bounding Logic Start ---
370
+ margin_px = 20.0
371
+
372
+ pixel_u = uv_width_size / view_width
373
+ pixel_v = uv_height_size / view_height
374
+ margin_u = margin_px * pixel_u
375
+ margin_v = margin_px * pixel_v
376
+
377
+ min_u = -half_uv_w + margin_u
378
+ max_u = 1.0 + half_uv_w - margin_u
379
+
380
+ if min_u > max_u:
381
+ zoom_state.center_u = 0.5
382
+ else:
383
+ zoom_state.center_u = max(min_u, min(zoom_state.center_u, max_u))
384
+
385
+ min_v = -half_uv_h + margin_v
386
+ max_v = 1.0 + half_uv_h - margin_v
387
+
388
+ if min_v > max_v:
389
+ zoom_state.center_v = 0.5
390
+ else:
391
+ zoom_state.center_v = max(min_v, min(zoom_state.center_v, max_v))
392
+ # --- Bounding Logic End ---
393
+
394
+ uv_x_min = zoom_state.center_u - half_uv_w
395
+ uv_x_max = zoom_state.center_u + half_uv_w
396
+ uv_y_min = zoom_state.center_v - half_uv_h
397
+ uv_y_max = zoom_state.center_v + half_uv_h
398
+
399
+ # Top-down uploads (for example chat images) keep the same pan/zoom
400
+ # geometry and reverse only the texture sampling coordinates.
401
+ uv_a = (uv_x_min, 1.0 - uv_y_max if flip_y else uv_y_max)
402
+ uv_b = (uv_x_max, 1.0 - uv_y_min if flip_y else uv_y_min)
403
+
404
+ # 6. Clip and Draw
405
+ scale_u_px = view_width / uv_width_size
406
+ scale_v_px = view_height / uv_height_size
407
+
408
+ # Project UV Edges
409
+ raw_img_left = p_min_x + (0.0 - uv_x_min) * scale_u_px
410
+ raw_img_right = p_min_x + (1.0 - uv_x_min) * scale_u_px
411
+ raw_img_top = p_min_y + (uv_y_max - 1.0) * scale_v_px
412
+ raw_img_bottom = p_min_y + (uv_y_max - 0.0) * scale_v_px
413
+
414
+ # Intersect with Viewport
415
+ clip_left = max(p_min_x, raw_img_left)
416
+ clip_right = min(p_max[0], raw_img_right)
417
+ clip_top = max(p_min_y, raw_img_top)
418
+ clip_bottom = min(p_max[1], raw_img_bottom)
419
+ draw_list: _DrawList = imgui.get_window_draw_list()
420
+
421
+ if imgui.is_mouse_hovering_rect(clip_left, clip_top, clip_right, clip_bottom):
422
+ draw_state.hover_reported = True
423
+ else:
424
+ draw_state.hover_reported = False
425
+
426
+ Core.melty.push_clip((clip_left, clip_top, clip_right - 3, clip_bottom))
427
+ draw_list.add_image_rounded(texture_id,
428
+ a=p_min,
429
+ b=p_max,
430
+ uv_a=uv_a,
431
+ uv_b=uv_b,
432
+ rounding=5.0)
433
+ draw_list.add_rect(raw_img_left, raw_img_top, raw_img_right + 1, raw_img_bottom + 1,
434
+ pack_color(*mixed_color[:3], 1.0),
435
+ 0.0, 0, 1.0)
436
+ if dim_outside is not None:
437
+ x0, y0, x1, y1 = dim_outside
438
+ sx = (raw_img_right - raw_img_left) / max(1, width)
439
+ sy = (raw_img_bottom - raw_img_top) / max(1, height)
440
+ sl, st = raw_img_left + x0 * sx, raw_img_top + y0 * sy
441
+ sr, sb = raw_img_left + x1 * sx, raw_img_top + y1 * sy
442
+ sl, st = max(sl, clip_left), max(st, clip_top)
443
+ sr, sb = min(sr, clip_right - 3), min(sb, clip_bottom)
444
+ if sr > sl and sb > st:
445
+ def uv(x, y):
446
+ v = uv_y_max - (y - p_min_y) / scale_v_px
447
+ return uv_x_min + (x - p_min_x) / scale_u_px, 1.0 - v if flip_y else v
448
+ gl.glBindTexture(gl.GL_TEXTURE_2D, bright_texture_id)
449
+ gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, filter_mode)
450
+ gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, filter_mode)
451
+ gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
452
+ draw_list.add_image(bright_texture_id, (sl, st), (sr, sb), uv(sl, st), uv(sr, sb))
453
+ draw_list.add_rect(sl, st, sr, sb, pack_color(1.0, 1.0, 1.0, 0.9), 0.0, 0, 1.0)
454
+ Core.melty.pop_clip()
455
+
456
+ if show_info:
457
+ line_height = imgui.get_text_line_height()
458
+ draw_list.add_text(max(p_min_x + 5, raw_img_left), clip_top - line_height - 5,
459
+ pack_color(*mixed_color[:3], 1.0),
460
+ text=f"{original_id} - {texture_id} - {width}x{height} - Zoom: {zoom_state.zoom:.2f}x")
461
+
462
+ gl.glBindTexture(gl.GL_TEXTURE_2D, original_texture)
463
+
464
+ return False, draw_state
465
+
466
+
467
+ IMAGE_BLIT_FRAG = """
468
+ #version 330 core
469
+ out vec4 FragColor;
470
+ uniform sampler2D image;
471
+ void main() { FragColor = texelFetch(image, ivec2(gl_FragCoord.xy), 0); }
472
+ """
473
+
474
+
475
+ @shader_func(fragment=IMAGE_BLIT_FRAG)
476
+ def image_blit_pass(gl_state: GLState = None, image=None, program=None, **kwargs):
477
+ """Fullscreen copy of `image` (a 2-D GLTexture the size of the target)
478
+ into the bound FBO — the voxel_pass stand-in for cuda_march frames."""
479
+ gl.glBindVertexArray(gl_state.vao("fs_triangle"))
480
+ gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3)
@@ -0,0 +1,38 @@
1
+ """A tile's editor picker and the selected render function's content."""
2
+ from meltygui import imgui
3
+ from meltygui.model.tile_model import Tile
4
+ from meltygui.view.dropdown_view import draw_dropdown
5
+
6
+
7
+ def draw_tile_content(input_value: Tile, width, height, multi_instance_renderers=(),
8
+ layout_frame=None):
9
+ # Change the picker height here; the editor receives the remaining tile area.
10
+ picker_height = 28.0
11
+ tile = input_value
12
+ choices = {"Empty": None}
13
+ choices.update({renderer.__name__: renderer for renderer in multi_instance_renderers})
14
+ left, top = imgui.get_cursor_screen_pos()
15
+ selected, renderer = draw_dropdown(
16
+ tile.render_func, collection=choices, name="Editor type", key=tile.id,
17
+ show_name=False, width=width, height=picker_height,
18
+ show_header=False,
19
+ display_label="Empty" if tile.render_func is None else tile.render_func.__name__,
20
+ )
21
+ if selected:
22
+ tile.render_func = renderer
23
+
24
+ changed = selected
25
+ if tile.render_func is not None:
26
+ imgui.set_cursor_screen_pos((left, top + picker_height))
27
+ content_changed, value = tile.render_func(
28
+ tile.input_value,
29
+ unique_name=f"{tile.render_func.__module__}.{tile.render_func.__qualname__}",
30
+ width=width,
31
+ height=max(0.0, height - picker_height),
32
+ auto_resize=False, show_header=False,
33
+ key=tile.id, instance=tile.id, layout_frame=layout_frame,
34
+ )
35
+ if content_changed:
36
+ tile.input_value = value
37
+ changed |= content_changed
38
+ return changed, tile