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,559 @@
1
+ """Control view functions and supporting definitions."""
2
+ from enum import Enum
3
+ from meltygui.hdr_color import pack_color
4
+ from meltygui.core.melty import Melty
5
+ from meltygui.core.core_render import render_func
6
+ from meltygui.core.rendering.core_decoration import Core
7
+ from meltygui.state.new_core_model import TileMode
8
+ from meltygui.core.runtime.toggles import Tint
9
+ from meltygui.view.header_view import draw_header
10
+ from meltygui_imgui.core import _DrawList
11
+ from types import NoneType
12
+ import meltygui_imgui as imgui
13
+ import types
14
+
15
+
16
+ @render_func(use_cache=True, show_bg=True, width=20, height=22, tile_mode=TileMode.MAX,
17
+ auto_resize=False, just_shadow=True, selectable=False, no_cursor=True, temp=True)
18
+ def empty(input_val):
19
+ pass
20
+
21
+
22
+ @render_func(use_cache=True, selectable=False, disable_scroll=True, indent_size=0, show_bg=False, min_width=5,
23
+ min_height=10, wrap=True, show_add_delete=False, rounding=None, icon=None, tint=(0.0, 0.241, 0.556))
24
+ def button(input_value="", width=5, height=14, draw_state=None, alpha=1.00, left_mouse_held=False, shadow=True,
25
+ left_mouse_down=False,
26
+ # DEPRECATED (09-12): a render_func widget costs ~0.7 ms of wrapper per call.
27
+ # New code draws buttons with headers/links (draw a rect + label, the
28
+ # click claimed through the parent view's draw_state.on_click); existing
29
+ # call sites migrate as they are converted. Do not add new callers.
30
+ color=(0.533, 0.068, 0.5), icon=None, highlight_hovered=True, hovered=False, style_manager=None,
31
+ show_button_bg=True,
32
+ factor=1.0, tint_value=0.16, text_value=0.694, saturation=1.2, text_saturation=1.2, text_align="center",
33
+ search_match=False, search_current=False, tint=None, rounding=None, corner_radius=6.0, text_pad=15,
34
+ max_bg_brightness=0.25):
35
+ from meltygui.model.color_model import _brightness_clamp
36
+ from meltygui.core.windowing.glfw_utils import request_render
37
+ from meltygui.view.search_view import draw_search_highlight
38
+
39
+ if color is not None:
40
+ if not isinstance(color, tuple) or len(color) < 3:
41
+ color = (2.558, 0.5, 0.5)
42
+ if shadow:
43
+ if left_mouse_held:
44
+ draw_state.z_offset = 0
45
+ else:
46
+ draw_state.z_offset = 3.0
47
+ else:
48
+ draw_state.z_offset = 0.0
49
+
50
+ if hovered and highlight_hovered:
51
+ mixed_color = style_manager.make_color_rgb(color[0], color[1], color[2], value=tint_value + 0.05,
52
+ factor=factor, saturation_scale=saturation, alpha=1.0)
53
+ else:
54
+ mixed_color = style_manager.make_color_rgb(color[0], color[1], color[2], value=tint_value,
55
+ factor=factor, saturation_scale=saturation, alpha=1.0)
56
+ # Brightness guard: cap the bg's perceived brightness (scale-preserving,
57
+ # same clamp as the window's tint washes) so the bright text keeps
58
+ # contrast even when a vivid/near-white color is passed in.
59
+ mixed_color = _brightness_clamp(mixed_color[0], mixed_color[1], mixed_color[2],
60
+ 0.0, max_bg_brightness)
61
+ text_color = style_manager.make_color_rgb(color[0], color[1], color[2],
62
+ value=text_value + (1.5 if hovered else 0.0),
63
+ factor=factor, saturation_scale=text_saturation, alpha=1.0)
64
+ else:
65
+ text_color = (1.0, 1.0, 1.0)
66
+ mixed_color = (0, 0, 0)
67
+
68
+ button_txt = str(input_value).split("##")[0]
69
+ if icon is not None:
70
+ button_txt = f"{icon} {button_txt}"
71
+
72
+ min_size = imgui.calc_text_size(button_txt)
73
+ # text_pad is an authored padding value, so it tracks the UI scale;
74
+ # width/height are NOT scaled here - callers pass physical pixels through
75
+ # them (the drag pickup size through height=), which would scale twice.
76
+ width = max(width, min_size[0] + Melty.px(text_pad))
77
+ height = max(height, min_size[1])
78
+ draw_list: _DrawList = imgui.get_window_draw_list()
79
+ bx0, by0 = imgui.get_cursor_screen_pos()
80
+
81
+ imgui.dummy(width, height)
82
+ draw_state.width = width
83
+ draw_state.height = height
84
+
85
+ # draw_state.width = btn_size[0]
86
+ # draw_state.height = btn_size[1]
87
+
88
+ bx1, by1 = bx0 + width, by0 + height
89
+ # `corner_radius` is an auto-state param: Mode / class defaults, internal
90
+ # draw_state.corner_radius writes all flow into it, and the mirror keeps
91
+ # framework painters (selection highlight, blit mask) in sync. `rounding`
92
+ # is an individual per-call override on top (e.g. the search results,
93
+ # which read as a flat list of items, pass rounding to square the corners).
94
+ rnd = corner_radius if rounding is None else rounding
95
+
96
+ if alpha > 0.0 and show_button_bg:
97
+ draw_list.add_rect_filled(bx0, by0, bx1, by1,
98
+ pack_color(*mixed_color[:3], alpha), rounding=rnd)
99
+
100
+ # Tint fill: button mutes `color` into a dark bg, so to show a window's tint
101
+ # we paint the raw colour over it — at low alpha so it stays a subtle wash.
102
+ elif tint is not None and show_button_bg:
103
+ draw_list.add_rect_filled(bx0, by0, bx1, by1,
104
+ pack_color(tint[0], tint[1], tint[2], 0.33),
105
+ rounding=rnd)
106
+
107
+ # Search match highlight (drawn under the text): the current row radiates a
108
+ # circular gradient glow with its rect cut out so its content stays legible;
109
+ # other matches get a thin outline. Tunable via Toggles.SearchSettings.
110
+ # Lifted to a higher depth channel (restored after) so the halo's glow
111
+ # past this row's rect isn't composited over by sibling rows' backgrounds.
112
+ if search_match:
113
+ if Melty.channels_split:
114
+ draw_list.channels_set_current(
115
+ min(Melty.get_channel() + 2, Melty.max_depth - 1))
116
+ draw_search_highlight(draw_list, bx0, by0, bx1, by1, current=search_current, rounding=rnd)
117
+ if Melty.channels_split:
118
+ draw_list.channels_set_current(Melty.get_channel())
119
+
120
+ if text_align == "left":
121
+ draw_list.add_text(draw_state.abs_left + 5,
122
+ draw_state.abs_top + (height - min_size[1]) / 2.0 - 1,
123
+ pack_color(*text_color[:3], 1.0), button_txt)
124
+ elif text_align == "right":
125
+ draw_list.add_text(draw_state.abs_left + width - min_size[0] - 5,
126
+ draw_state.abs_top + (height - min_size[1]) / 2.0 - 1,
127
+ pack_color(*text_color[:3], 1.0), button_txt)
128
+ else:
129
+ draw_list.add_text(draw_state.abs_left + (width - min_size[0]) / 2.0 + 2,
130
+ draw_state.abs_top + (height - min_size[1]) / 2.0 - 1,
131
+ pack_color(*text_color[:3], 1.0), button_txt)
132
+
133
+ if left_mouse_down:
134
+ # Effect ledger, exactly as flat_button: a fired button is an
135
+ # observable change with an undo record - the Orchestrator cues
136
+ # replays off it. The button's OWN draw_state and rect flow in, so
137
+ # the cue's chain, press_rect and press_rect all describe the
138
+ # button (a header-owned flat_button can only offer its position).
139
+ if Melty.effect_hook is not None:
140
+ try:
141
+ Melty.effect_hook("button", button_txt, draw_state,
142
+ rect=(bx0, by0, width, height))
143
+ except Exception:
144
+ pass
145
+ request_render()
146
+ return True, input_value
147
+
148
+ return False, None
149
+
150
+
151
+ @render_func(header_same_line=True, use_cache=True, is_default_for=(types.NoneType),
152
+ shadow=False, is_tree=False, with_header=draw_header, temp=True)
153
+ def draw_none(input_value: NoneType):
154
+ imgui.align_text_to_frame_padding()
155
+ imgui.text_colored("None", *(0.164, 0.389, 0.197), 0.4)
156
+ return False, input_value
157
+
158
+
159
+ @render_func(is_default_for=(bool), use_cache=True,
160
+ is_tree=False, min_width=83, shadow=False,
161
+ with_header=draw_header, temp=True,
162
+ # Give the @render_func a unique tint. Note how in the editor this function has a bg tint
163
+ # pulled from the render_func! Please note, the supplied tint may be muted and darkened by
164
+ # meltygui at the frameworks discretion when used as a tint.
165
+ tint=(0.0, 0.527, 0.817))
166
+ def draw_bool(
167
+ # Important inputs to functions can be given tints!
168
+ # [tint=(0.85, 0.75, 0.05)]
169
+ input_value: bool,
170
+ draw_state, left_mouse_clicked=None, max_width=359,
171
+ max_height=100, min_height=20, header_same_line=True,
172
+ selectable=False, left_mouse_drag=None, left_mouse_held=False, align_header=True,
173
+ left_mouse_down=False):
174
+
175
+ # Use meltygui #[ comments liberally. Constants in the func should always have tints
176
+ # As a generally rule, local constants are preferable to constants referenced elsewhere.
177
+ # Melty is designed to make local variables easy to find. Scatter constants are actually encouraged
178
+ # inside meltygui. Place constants as close to their usage whenever possible.
179
+
180
+ # [tint=(0.939, 0.453, 0.245)]
181
+ left_margin = 3
182
+
183
+ # [tint=(0.994, 0.872, 0.0), show_tint=True]
184
+ text_inset = 11
185
+
186
+ # [tint=(0.939, 0.836, 0.595, 1.0), show_tint=True]
187
+ cursor_start = imgui.get_cursor_pos_x()
188
+
189
+ if input_value:
190
+ bg_color = pack_color(*Tint.checkbox_bg_selected(), 1.0)
191
+ text_color = (*Tint.checkbox_text_true(), 1.0)
192
+ # icons are available as a dropdown! Use f"{}" is encouraged
193
+ icon = f""
194
+ else:
195
+ bg_color = pack_color(*Tint.checkbox_bg(), 1.0)
196
+ text_color = (*Tint.checkbox_text(), 0.45)
197
+ icon = f""
198
+
199
+ # [tint=(0.989, 0.17, 0.497), show_tint=True]
200
+ label = f"{icon} {input_value}"
201
+ icon_w = imgui.calc_text_size(icon)[0]
202
+ label_w = imgui.calc_text_size(label)[0]
203
+
204
+ leftover = draw_state.abs_left + draw_state.width - 10 - cursor_start
205
+ cell_width = min(draw_state.content_width, leftover)
206
+
207
+
208
+ avail = min(draw_state.width - 18, cell_width)
209
+ full_width = left_margin + text_inset * 2 + label_w
210
+ compact = full_width > avail
211
+
212
+ if compact:
213
+ width = 30
214
+ else:
215
+ width = full_width
216
+
217
+ imgui.dummy(width, 21)
218
+
219
+ # draw list should not be abbrivated ds
220
+ draw_list = imgui.get_window_draw_list()
221
+ outline_color = pack_color(*Tint.checkbox_outline(), 1.0)
222
+
223
+ # This is an example of a comment I don't really like. Documenting what something
224
+ # does is fine but if that's needed it usually means the code is written poorly.
225
+ # Ideally the code should be easy enough that it's obvious what it does.
226
+ # Comments that explain how to change the code, placed precisely in places that
227
+ # may plausiblly be changed in the future is highly discouraged.
228
+
229
+ # Align the box to the right edge of the value cell: the leftover space
230
+ # between the content width and the box's own width becomes the left offset.
231
+ # When the box is wider than the cell this goes negative, pinning the right
232
+ # edge and letting the box grow left over the header - so when there's
233
+ # absolutely no room it starts overlapping the header rather than overflowing.
234
+ right_offset = cell_width - width
235
+ box_left = imgui.get_cursor_pos_x() + left_margin + right_offset
236
+ box_right = imgui.get_cursor_pos_x() + width + right_offset
237
+
238
+ # abs_top and abs_left should be used when the top/left of the view port is needed
239
+ box_top = draw_state.abs_top
240
+ box_bottom = draw_state.abs_top + draw_state.content_height
241
+
242
+ # Draw list is always prefered for perforance
243
+ draw_list.add_rect_filled(box_left, box_top, box_right, box_bottom,
244
+ rounding=4, col=bg_color)
245
+ draw_list.add_rect(box_left, box_top, box_right, box_bottom,
246
+ rounding=4, col=outline_color, thickness=1.5)
247
+
248
+ # The hit target is the box itself, not the whole value cell - the rest of
249
+ # the row (the header) stays usable for its own drag-and-drop. _bounding_hovered
250
+ # keeps occlusion/z-order correct (no clicking through an overlapping window);
251
+ # the rect test narrows it to the drawn box.
252
+ box_hovered = draw_state._bounding_hovered and imgui.is_mouse_hovering_rect(
253
+ box_left, box_top, box_right, box_bottom)
254
+
255
+ if box_hovered:
256
+ hover_color = pack_color(*Tint.checkbox_bg_hovered(), 0.2)
257
+ draw_list.add_rect_filled(box_left, box_top, box_right, box_bottom,
258
+ rounding=4, col=hover_color)
259
+
260
+ if compact:
261
+ # Center just the icon inside the square (which spans [left_margin, width]).
262
+ # Don't abriviate variables names. Use full box_width
263
+ box_w = width - left_margin
264
+ imgui.same_line(left_margin + (box_w - icon_w) / 2.0 + right_offset + 1)
265
+ imgui.set_cursor_pos_y(imgui.get_cursor_pos_y() + 2)
266
+ imgui.text_colored(icon, *text_color)
267
+ else:
268
+ imgui.same_line(text_inset + left_margin + right_offset)
269
+ imgui.set_cursor_pos_y(imgui.get_cursor_pos_y() + 2)
270
+ imgui.text_colored(label, *text_color)
271
+
272
+ # Melty click events are preferable to imgui ones. left_mouse_down, left_mouse_clicked, left_mouse_drag etc
273
+ # Are injected automatically when those arguments are present in a @render_func signature.
274
+ if box_hovered and imgui.is_mouse_clicked(0):
275
+ return True, not input_value
276
+ else:
277
+ return False, input_value
278
+
279
+
280
+ @render_func(is_default_for=(str), shadow=False, wrap_text=False, show_bg=False, is_tree=False, wrap=False,
281
+ show_header=False,
282
+ show_add_delete=False, show_name=False, use_cache=True,
283
+ disable_scroll=True, min_width=30, with_header=draw_header, temp=True)
284
+ def text(input_value: str, wrap, wrap_text=False, text_color=(1, 1, 1), draw_state=None, font=None):
285
+ _font_pushed = False
286
+ if font is not None and Core.melty.font_mgr is not None:
287
+ _font_handle = Core.melty.font_mgr.get(font)
288
+ if _font_handle is not None:
289
+ imgui.push_font(_font_handle)
290
+ _font_pushed = True
291
+
292
+ text_size = imgui.calc_text_size(str(input_value), wrap_width=draw_state.content_width)
293
+ if wrap_text and text_size[1] > imgui.get_text_line_height() * 4 and not wrap:
294
+ imgui.push_text_wrap_pos(draw_state.abs_left + draw_state.width)
295
+ imgui.push_style_color(imgui.COLOR_TEXT, text_color[0], text_color[1], text_color[2], 1.0)
296
+ imgui.text_wrapped(str(input_value))
297
+ imgui.pop_style_color()
298
+ imgui.pop_text_wrap_pos()
299
+
300
+ else:
301
+ if text_color is not None:
302
+ imgui.text_colored(str(input_value), text_color[0], text_color[1], text_color[2], 1.0)
303
+ else:
304
+ imgui.text(str(input_value))
305
+
306
+ if font is not None:
307
+ imgui.pop_font()
308
+
309
+ return False, input_value
310
+
311
+
312
+ @render_func(is_default_for=(str), shadow=False, show_bg=False, wrap=False, selectable=False,
313
+ is_tree=False, show_add_delete=False, use_cache=True, min_height=20,
314
+ disable_scroll=True, with_header=draw_header, temp=True)
315
+ def draw_str(input_value: str, draw_state, editable=True, wrap=False, min_width=110, immediate_return=False, alpha=1.0):
316
+ from meltygui.view.text_view import draw_text
317
+
318
+ if not editable:
319
+ imgui.push_style_var(imgui.STYLE_ALPHA, alpha)
320
+
321
+ text_size = imgui.calc_text_size(str(input_value), wrap_width=draw_state.content_width)
322
+ imgui.push_text_wrap_pos(draw_state.abs_left + draw_state.width)
323
+ imgui.text_wrapped(str(input_value))
324
+ imgui.pop_text_wrap_pos()
325
+
326
+ imgui.pop_style_var(1)
327
+ return False, input_value
328
+
329
+ some_int = 29
330
+ line_count = input_value.count('\n') + 1
331
+ line_height = imgui.get_text_line_height()
332
+ text_height = imgui.calc_text_size(str(input_value))[1] + line_height * 2
333
+ if line_count == 1:
334
+ padding = imgui.get_style().frame_padding.y
335
+ height = imgui.get_text_line_height() + padding
336
+
337
+ else:
338
+ text_bottom = draw_state.abs_top + text_height
339
+ clamped_bottom = text_bottom
340
+ height = clamped_bottom - draw_state.abs_top
341
+
342
+ show_controls = True
343
+
344
+ if not show_controls:
345
+ imgui.push_style_var(imgui.STYLE_ALPHA, 0)
346
+
347
+ if False:
348
+ if not wrap:
349
+ item_width = draw_state.content_width - 1
350
+ else:
351
+ item_width = min_width
352
+
353
+ if immediate_return:
354
+ imgui.set_next_item_width(item_width)
355
+ changed, value = imgui.input_text("##str", str(input_value))
356
+ else:
357
+ imgui.set_next_item_width(item_width)
358
+ changed, value = imgui.input_text("##str", str(input_value),
359
+ flags=imgui.INPUT_TEXT_ENTER_RETURNS_TRUE)
360
+ else:
361
+ # disable scrolling
362
+ changed, value = draw_text(str(input_value), name=draw_state.name + "##innder", show_bg=True,
363
+ editable=True, with_header=draw_header, width=draw_state.content_width - 10,
364
+ show_name=False, is_tree=False, temp=True,
365
+ # A VALUE field holds prose/data, not code -
366
+ # the auto-suggestion popup is noise here
367
+ # (params-panel input boxes especially).
368
+ autocomplete=False)
369
+
370
+ if not show_controls:
371
+ imgui.pop_style_var(1)
372
+
373
+ if changed:
374
+ return True, value
375
+ return changed, value
376
+
377
+
378
+ @render_func
379
+ def draw_float_ctx(input_value):
380
+ imgui.text('Float content menu')
381
+ imgui.dummy(30, 30)
382
+ draw_float(0.0, name="test")
383
+ imgui.text(f"WxH {input_value.width} {input_value.height}")
384
+ imgui.text(f"Content width {input_value.content_width} {input_value.height}")
385
+
386
+ imgui.text(f"Abs Left/Top {input_value.abs_left} {input_value.abs_top}")
387
+ imgui.text(f"Header WxH {input_value.header_width} {input_value.header_height}")
388
+
389
+ draw_list: _DrawList = imgui.get_overlay_draw_list()
390
+ draw_list.add_rect(upper_left_x=input_value.abs_left, upper_left_y=input_value.abs_top,
391
+ lower_right_x=input_value.abs_left + input_value.width,
392
+ lower_right_y=input_value.abs_top + input_value.height,
393
+ col=pack_color(1, 0, 0, 0.5), thickness=1.0)
394
+
395
+
396
+ @render_func(is_default_for=(float), shadow=False, use_cache=False, wrap=False, tint=(0.114, 0.087, 0.35),
397
+ is_tree=False, with_header=draw_header, align_header=True, temp=True)
398
+ def draw_float(input_value: float,
399
+ draw_state,
400
+ wrap=False,
401
+ min_width=80,
402
+ max_height=100, min_height=20,
403
+ min_value=-98.703,
404
+ max_value=99.264,
405
+ speed=0.0042):
406
+ if not wrap:
407
+ imgui.set_next_item_width(draw_state.content_width)
408
+ else:
409
+ imgui.set_next_item_width(min_width)
410
+ changed, value = imgui.drag_float("", input_value,
411
+ format='%.3f',
412
+ change_speed=speed,
413
+ min_value=min_value,
414
+ max_value=max_value)
415
+
416
+ if changed:
417
+ return True, value
418
+
419
+ return False, input_value
420
+
421
+
422
+ @render_func(shadow=False, use_cache=False, wrap=False, is_tree=False,
423
+ with_header=draw_header, align_header=True, temp=True, tint=(0.071, 0.354, 0.511))
424
+ def draw_button(input_value="", draw_state=None, label="", tint=(1.0, 1.0, 1.0, 1.0), min_width=80,
425
+ min_height=14, wrap=False, height=23):
426
+ """A VALUE-ROW button — draw_float's shape with a button where the slider
427
+ sits, so it composes with the standard header (name label, tint, layout)
428
+ that `def button` fights. `changed` IS the click; input_value passes
429
+ through untouched (the caller acts on the click, e.g. the info tab's +
430
+ stamping a param into a source).
431
+
432
+ Styled from draw_state.tint (raw imgui.button's stock style reads pure
433
+ white in the meltygui theme). The label wraps: it's drawn OVER a label-less
434
+ button with a text-wrap pos, and the button height grows to fit."""
435
+ from meltygui.core.cache.tile_cache import add_shadow
436
+
437
+ w = min_width if wrap else (draw_state.content_width or min_width)
438
+ _t = tint
439
+ r, g, b = (_t[:3] if isinstance(_t, (tuple, list)) and len(_t) >= 3
440
+ else (0.45, 0.47, 0.55))
441
+ pad_x, pad_y = 6, 2
442
+ _lbl = str(label)
443
+ ts = imgui.calc_text_size(_lbl, wrap_width=max(10.0, w - pad_x * 2))
444
+ h = height or max(min_height, ts[1] + pad_y * 2)
445
+
446
+ imgui.push_style_color(imgui.COLOR_BUTTON, r * 0.28, g * 0.28, b * 0.28, 0.6)
447
+ imgui.push_style_color(imgui.COLOR_BUTTON_HOVERED, r * 0.42, g * 0.42, b * 0.42, 0.8)
448
+ imgui.push_style_color(imgui.COLOR_BUTTON_ACTIVE, r * 0.55, g * 0.55, b * 0.55, 0.95)
449
+ pos = imgui.get_cursor_screen_pos()
450
+ # Shadow on the button rect only - the default shadow (decorator
451
+ # shadow=True) would mark the whole value row, name label included.
452
+ add_shadow((pos[0], pos[1], w, h),
453
+ corner_radius=imgui.get_style().frame_rounding)
454
+ clicked = imgui.button("##btn", width=w, height=h)
455
+ imgui.pop_style_color(3)
456
+
457
+ # Wrapped label over the button; restore the flow cursor after.
458
+ flow = imgui.get_cursor_screen_pos()
459
+ imgui.set_cursor_screen_pos((pos[0] + pad_x, pos[1] + pad_y))
460
+ imgui.push_text_wrap_pos(imgui.get_cursor_pos_x() + w - pad_x * 2)
461
+ imgui.text(_lbl)
462
+ imgui.pop_text_wrap_pos()
463
+ imgui.set_cursor_screen_pos(flow)
464
+ return clicked, input_value
465
+
466
+
467
+ @render_func(is_default_for=(int), shadow=False, use_cache=False, wrap=False,
468
+ is_tree=False, with_header=draw_header, align_header=True, temp=True)
469
+ def draw_int(input_value: int, draw_state=None, max_height=100, min_height=20,
470
+ min_width=80, wrap=False, min_value=-1000.0,
471
+ max_value=1000.0, speed=0.1, unique=0):
472
+ if not wrap:
473
+ imgui.set_next_item_width(draw_state.content_width)
474
+ else:
475
+ imgui.set_next_item_width(min_width)
476
+
477
+ max_int = 2147483647
478
+ if input_value < max_int:
479
+ changed, value = imgui.drag_int("##int", input_value,
480
+ change_speed=speed,
481
+ min_value=min_value,
482
+ max_value=max_value)
483
+ if changed:
484
+ return True, value
485
+
486
+ return changed, value
487
+ return False, input_value
488
+
489
+
490
+ @render_func(tint=(0.18, 0.46, 0.67), use_cache=True, shadow=False,
491
+ with_header=draw_header, header_same_line=True, wrap=False,
492
+ min_width=80, min_height=22, auto_resize=False)
493
+ def draw_int_slider(input_value: int, draw_state=None, min_value=0, max_value=100,
494
+ left_mouse_down=None, left_mouse_drag=None):
495
+ """A bounded integer edited through the view's injected pointer events."""
496
+ left, top = imgui.get_cursor_screen_pos()
497
+ width = max(1.0, draw_state.content_width)
498
+ height = 22.0
499
+ draw_state.event_rect(('left_mouse_down', 'left_mouse_drag'),
500
+ (left, top, left + width, top + height))
501
+ value = max(min_value, min(max_value, input_value))
502
+ event = left_mouse_drag if left_mouse_drag is not None else left_mouse_down
503
+ if event is not None and max_value > min_value:
504
+ fraction = max(0.0, min(1.0, (event.x - left) / width))
505
+ value = round(min_value + fraction * (max_value - min_value))
506
+ fraction = (value - min_value) / max(1, max_value - min_value)
507
+ draw_list = imgui.get_window_draw_list()
508
+ draw_list.add_rect_filled(left, top + 4, left + width, top + height - 4,
509
+ pack_color(*Tint.checkbox_bg(), 1.0), rounding=3)
510
+ draw_list.add_rect_filled(left, top + 4, left + width * fraction, top + height - 4,
511
+ pack_color(*Tint.checkbox_bg_selected(), 1.0), rounding=3)
512
+ label = str(value)
513
+ label_width, label_height = imgui.calc_text_size(label)
514
+ draw_list.add_text(left + (width - label_width) / 2,
515
+ top + (height - label_height) / 2,
516
+ pack_color(*Tint.checkbox_text(), 1.0), label)
517
+ imgui.dummy(width, height)
518
+ changed = event is not None and value != input_value
519
+ return changed, value if changed else input_value
520
+
521
+
522
+ @render_func(is_default_for=Enum, is_tree=False, shadow=False, align_header=False,
523
+ selectable=False, show_add_delete=False,
524
+ parent_show_add_delete=False, with_header=draw_header, temp=True)
525
+ def draw_enum(input_value: Enum, draw_state=None, unique=0, style_manager=None, enum_tint=(0.3, 0.3, 0.3)):
526
+ # Delegate to draw_tab_bar so enums get its wrapping + styling for free.
527
+ # Enums are single-select: pass the current value as the lone selection and
528
+ # render every member as a tab; names are the prettified member names.
529
+ from meltygui.view.dropdown_view import draw_dropdown
530
+ from meltygui.view.tab_view import draw_tab_bar
531
+
532
+ options = list(input_value.__class__)
533
+
534
+ if len(options) > 4:
535
+ changed, selection = draw_dropdown(input_value, collection=options, show_header=False,
536
+ name=f"{input_value.__class__.__name__}##{unique}enum")
537
+
538
+ if changed:
539
+ return True, selection
540
+ else:
541
+
542
+ names = [opt.name.replace("_", " ").capitalize() for opt in options]
543
+ changed, selected = draw_tab_bar([input_value], collection=options, names=names, name=f"{unique}_enum",
544
+ wrap=True,
545
+ z_offset=-1, rounding=5, as_toggles=False, bg_offset=-3)
546
+ if changed and selected:
547
+ return True, selected[0]
548
+ return False, input_value
549
+
550
+
551
+ @render_func(use_cache=True, show_header=True, selectable=False, with_header=draw_header)
552
+ def draw_single(input_value: any, view_func=None, mode: any = None, **kwargs):
553
+ changed, return_val = view_func(input_value, mode=mode)
554
+ return changed, return_val
555
+
556
+
557
+ @render_func(use_cache=False, show_header=True, max_height=30, selectable=False, with_header=draw_header)
558
+ def draw_blank(input_value: any, **kwargs):
559
+ return False, None