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,22 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Standalone script to generate type stub files.
4
+
5
+ Run from the shader_library directory:
6
+ python3 generate_stubs.py
7
+ """
8
+
9
+ import sys
10
+ import os
11
+
12
+ # Import to register all shaders
13
+ from meltygui.graphics.stub_generator import generate_filter_stub
14
+
15
+ # Generate the stub file
16
+ stub_path = os.path.join(os.path.dirname(__file__), '', 'filter.pyi')
17
+ content = generate_filter_stub(stub_path)
18
+
19
+ lines = len(content.splitlines())
20
+ print(f"✓ Generated {stub_path}")
21
+ print(f"✓ {lines} lines")
22
+ print(f"✓ Shaders included: {content.count('def ') - 20}") # Subtract non-shader methods
@@ -0,0 +1,203 @@
1
+ """
2
+ Shader and shader type registry with decorator-based registration.
3
+ """
4
+
5
+ from typing import Dict, Type, Any, Optional, Callable
6
+ from dataclasses import dataclass, field
7
+
8
+ from meltygui.graphics.base import ShaderType
9
+ from meltygui.graphics.base import Shader
10
+ from meltygui.graphics.base import camel_to_snake
11
+ from meltygui.graphics.base import GLType
12
+
13
+
14
+ class ShaderRegistry:
15
+ """
16
+ Central registry for shader types and shaders.
17
+
18
+ This is a singleton that holds all registered shader types and shaders.
19
+ """
20
+ _instance: Optional['ShaderRegistry'] = None
21
+
22
+ def __new__(cls) -> 'ShaderRegistry':
23
+ if cls._instance is None:
24
+ cls._instance = super().__new__(cls)
25
+ cls._instance._shader_types: Dict[str, ShaderType] = {}
26
+ cls._instance._shaders: Dict[str, Shader] = {}
27
+ return cls._instance
28
+
29
+ @property
30
+ def shader_types(self) -> Dict[str, ShaderType]:
31
+ return self._shader_types
32
+
33
+ @property
34
+ def shaders(self) -> Dict[str, Shader]:
35
+ return self._shaders
36
+
37
+ def register_type(self, shader_type: ShaderType) -> None:
38
+ """Register a shader type."""
39
+ self._shader_types[shader_type.name] = shader_type
40
+
41
+ def register_shader(self, shader: Shader) -> None:
42
+ """Register a shader."""
43
+ self._shaders[shader.name] = shader
44
+
45
+ def get_type(self, name: str) -> Optional[ShaderType]:
46
+ """Get a shader type by name."""
47
+ return self._shader_types.get(name)
48
+
49
+ def get_shader(self, name: str) -> Optional[Shader]:
50
+ """Get a shader by name."""
51
+ return self._shaders.get(name)
52
+
53
+ def clear(self) -> None:
54
+ """Clear all registrations (mainly for testing)."""
55
+ self._shader_types.clear()
56
+ self._shaders.clear()
57
+
58
+
59
+ # Global registry instance
60
+
61
+ _registry = ShaderRegistry()
62
+
63
+
64
+ def get_registry() -> ShaderRegistry:
65
+ """Get the global shader registry."""
66
+ return _registry
67
+
68
+
69
+ def register_shader_type(cls: Type) -> Type:
70
+ """
71
+ Decorator to register a shader type.
72
+
73
+ The type name is inferred from the class name (converted to snake_case).
74
+
75
+ Example:
76
+ @register_shader_type
77
+ class Standard:
78
+ vertex_in = {'position': GLType.VEC3, 'texcoord': GLType.VEC2}
79
+ vertex_out = {'v_texcoord': GLType.VEC2}
80
+ vertex_code = '''
81
+ void main() {
82
+ v_texcoord = texcoord;
83
+ gl_Position = vec4(position, 1.0);
84
+ }
85
+ '''
86
+ """
87
+ name = camel_to_snake(cls.__name__)
88
+
89
+ # Extract attributes from class
90
+ vertex_in = getattr(cls, 'vertex_in', {})
91
+ vertex_out = getattr(cls, 'vertex_out', {})
92
+ vertex_code = getattr(cls, 'vertex_code', '')
93
+
94
+ # Convert string type names to GLType if needed
95
+ vertex_in = _normalize_type_dict(vertex_in)
96
+ vertex_out = _normalize_type_dict(vertex_out)
97
+
98
+ shader_type = ShaderType(
99
+ name=name,
100
+ vertex_in=vertex_in,
101
+ vertex_out=vertex_out,
102
+ vertex_code=vertex_code
103
+ )
104
+
105
+ _registry.register_type(shader_type)
106
+
107
+ # Store the ShaderType on the class for reference
108
+ cls._shader_type = shader_type
109
+
110
+ return cls
111
+
112
+
113
+ def register_shader(cls: Type = None, *, shader_type: str = 'standard') -> Callable:
114
+ """
115
+ Decorator to register a shader.
116
+
117
+ The shader name is inferred from the class name (converted to snake_case).
118
+
119
+ Can be used with or without arguments:
120
+ @register_shader
121
+ class BrightnessContrast:
122
+ ...
123
+
124
+ @register_shader(shader_type='fullscreen')
125
+ class GaussianBlur:
126
+ ...
127
+
128
+ Example:
129
+ @register_shader
130
+ class BrightnessContrast:
131
+ uniforms = {
132
+ 'brightness': (GLType.FLOAT, 0.0),
133
+ 'contrast': (GLType.FLOAT, 1.0),
134
+ }
135
+ fragment_code = '''
136
+ void main() {
137
+ vec4 color = texture(u_texture, v_texcoord);
138
+ color.rgb = (color.rgb - 0.5) * contrast + 0.5 + brightness;
139
+ fragColor = color;
140
+ }
141
+ '''
142
+ """
143
+ def decorator(cls: Type) -> Type:
144
+ name = camel_to_snake(cls.__name__)
145
+
146
+ # Extract attributes from class
147
+ uniforms = getattr(cls, 'uniforms', {})
148
+ fragment_code = getattr(cls, 'fragment_code', '')
149
+ vertex_code = getattr(cls, 'vertex_code', None)
150
+ type_name = getattr(cls, 'shader_type', shader_type)
151
+
152
+ # Normalize uniforms
153
+ uniforms = _normalize_uniforms(uniforms)
154
+
155
+ shader = Shader(
156
+ name=name,
157
+ shader_type=type_name,
158
+ fragment_code=fragment_code,
159
+ vertex_code=vertex_code,
160
+ uniforms=uniforms
161
+ )
162
+
163
+ _registry.register_shader(shader)
164
+
165
+ # Store the Shader on the class for reference
166
+ cls._shader = shader
167
+
168
+ return cls
169
+
170
+ # Handle both @register_shader and @register_shader() syntax
171
+ if cls is not None:
172
+ return decorator(cls)
173
+ return decorator
174
+
175
+
176
+ def _normalize_type_dict(d: Dict[str, Any]) -> Dict[str, GLType]:
177
+ """Convert string type names to GLType enum values."""
178
+ result = {}
179
+ for name, type_val in d.items():
180
+ if isinstance(type_val, str):
181
+ type_val = GLType(type_val)
182
+ elif isinstance(type_val, GLType):
183
+ pass
184
+ else:
185
+ print(f"Warning: Unexpected type for {name}: {type_val}")
186
+ result[name] = type_val
187
+ return result
188
+
189
+
190
+ def _normalize_uniforms(uniforms: Dict[str, Any]) -> Dict[str, tuple]:
191
+ """Normalize uniform definitions to (GLType, default) tuples."""
192
+ result = {}
193
+ for name, value in uniforms.items():
194
+ if isinstance(value, tuple):
195
+ gl_type, default = value
196
+ if isinstance(gl_type, str):
197
+ gl_type = GLType(gl_type)
198
+ result[name] = (gl_type, default)
199
+ elif isinstance(value, GLType):
200
+ result[name] = (value, None)
201
+ else:
202
+ print(f"Warning: Unexpected uniform definition for {name}: {value}")
203
+ return result
@@ -0,0 +1,155 @@
1
+ """
2
+ OpenGL shader program compilation and management.
3
+ """
4
+
5
+ from typing import Dict, Optional, Any, Tuple
6
+ from dataclasses import dataclass
7
+ import ctypes
8
+
9
+ from meltygui.graphics.base import ShaderType
10
+ from meltygui.graphics.base import Shader
11
+
12
+ # GLSL version header
13
+ GLSL_VERSION = "#version 330 core\n"
14
+
15
+
16
+ def _get_gl():
17
+ """Lazy import of OpenGL."""
18
+ from OpenGL import GL
19
+ from OpenGL.GL import shaders
20
+ return GL, shaders
21
+
22
+
23
+ @dataclass
24
+ class CompiledProgram:
25
+ """A compiled shader program with its metadata."""
26
+ program_id: int
27
+ shader: Shader
28
+ shader_type: ShaderType
29
+ uniform_locations: Dict[str, int]
30
+ attribute_locations: Dict[str, int]
31
+
32
+
33
+ class ProgramCompiler:
34
+ """
35
+ Compiles and manages OpenGL shader programs.
36
+ """
37
+
38
+ def __init__(self):
39
+ """Initialize the program compiler."""
40
+ self._programs: Dict[str, CompiledProgram] = {}
41
+
42
+ def compile(self, shader: Shader, shader_type: ShaderType) -> CompiledProgram:
43
+ """
44
+ Compile a shader into an OpenGL program.
45
+
46
+ Args:
47
+ shader: The shader definition
48
+ shader_type: The shader type definition
49
+
50
+ Returns:
51
+ CompiledProgram with the program ID and metadata
52
+ """
53
+ GL, shaders = _get_gl()
54
+
55
+ # Generate full shader source code
56
+ vertex_src = self._generate_vertex_source(shader, shader_type)
57
+ fragment_src = self._generate_fragment_source(shader, shader_type)
58
+
59
+ try:
60
+ vertex_shader = shaders.compileShader(vertex_src, GL.GL_VERTEX_SHADER)
61
+ fragment_shader = shaders.compileShader(fragment_src, GL.GL_FRAGMENT_SHADER)
62
+ program_id = shaders.compileProgram(vertex_shader, fragment_shader)
63
+ except shaders.ShaderCompilationError as e:
64
+ raise ShaderCompilationError(f"Failed to compile shader '{shader.name}': {e}")
65
+
66
+ # Get uniform locations
67
+ uniform_locations = {}
68
+ for name in shader.uniforms.keys():
69
+ uniform_locations[name] = GL.glGetUniformLocation(program_id, name)
70
+ uniform_locations['u_texture'] = GL.glGetUniformLocation(program_id, 'u_texture')
71
+ uniform_locations['u_projection'] = GL.glGetUniformLocation(program_id, 'u_projection')
72
+ uniform_locations['u_modelview'] = GL.glGetUniformLocation(program_id, 'u_modelview')
73
+
74
+ # Get attribute locations
75
+ attribute_locations = {}
76
+ for name in shader_type.vertex_in.keys():
77
+ attribute_locations[name] = GL.glGetAttribLocation(program_id, name)
78
+
79
+ compiled = CompiledProgram(
80
+ program_id=program_id,
81
+ shader=shader,
82
+ shader_type=shader_type,
83
+ uniform_locations=uniform_locations,
84
+ attribute_locations=attribute_locations
85
+ )
86
+
87
+ self._programs[shader.name] = compiled
88
+ return compiled
89
+
90
+ def _generate_vertex_source(self, shader: Shader, shader_type: ShaderType) -> str:
91
+ """Generate the complete vertex shader source."""
92
+ parts = [GLSL_VERSION]
93
+
94
+ # Add input declarations
95
+ for name, gl_type in shader_type.vertex_in.items():
96
+ parts.append(f"in {gl_type.value} {name};")
97
+
98
+ # Add output declarations (varyings)
99
+ for name, gl_type in shader_type.vertex_out.items():
100
+ parts.append(f"out {gl_type.value} {name};")
101
+
102
+ # Add common uniforms
103
+ parts.append("uniform mat4 u_projection;")
104
+ parts.append("uniform mat4 u_modelview;")
105
+
106
+ # Add the vertex code
107
+ vertex_code = shader.vertex_code if shader.vertex_code else shader_type.vertex_code
108
+ parts.append(vertex_code)
109
+
110
+ return '\n'.join(parts)
111
+
112
+ def _generate_fragment_source(self, shader: Shader, shader_type: ShaderType) -> str:
113
+ """Generate the complete fragment shader source."""
114
+ parts = [GLSL_VERSION]
115
+
116
+ # Add input declarations (varyings from vertex shader)
117
+ for name, gl_type in shader_type.vertex_out.items():
118
+ parts.append(f"in {gl_type.value} {name};")
119
+
120
+ # Add output declaration
121
+ parts.append("out vec4 fragColor;")
122
+
123
+ # Add texture sampler
124
+ parts.append("uniform sampler2D u_texture;")
125
+
126
+ # Add shader-specific uniforms
127
+ for name, (gl_type, _) in shader.uniforms.items():
128
+ parts.append(f"uniform {gl_type.value} {name};")
129
+
130
+ # Add the fragment code
131
+ parts.append(shader.fragment_code)
132
+
133
+ return '\n'.join(parts)
134
+
135
+ def get_program(self, name: str) -> Optional[CompiledProgram]:
136
+ """Get a compiled program by shader name."""
137
+ return self._programs.get(name)
138
+
139
+ def delete_program(self, name: str) -> None:
140
+ """Delete a compiled program."""
141
+ if name in self._programs:
142
+ GL, _ = _get_gl()
143
+ compiled = self._programs[name]
144
+ GL.glDeleteProgram(compiled.program_id)
145
+ del self._programs[name]
146
+
147
+ def cleanup(self) -> None:
148
+ """Clean up all compiled programs."""
149
+ for name in list(self._programs.keys()):
150
+ self.delete_program(name)
151
+
152
+
153
+ class ShaderCompilationError(Exception):
154
+ """Raised when shader compilation fails."""
155
+ pass