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,7 @@
1
+ {
2
+ "uuid": "lsd-window-geometry@latent-descent",
3
+ "name": "LSD Window Geometry",
4
+ "description": "Publishes window frame rectangles and monitor work areas over the session D-Bus (org.latentdescent.WindowGeometry). Wayland never tells a client where its window sits on the screen; LSD Studio needs that to treat the screen edges as collision walls for its own window edges. Installed and managed from the studio (gl_gui/installation_helper.py).",
5
+ "shell-version": ["45", "46", "47", "48"],
6
+ "version": 1
7
+ }
@@ -0,0 +1,6 @@
1
+ """Shader filters, textures, and the built-in shader registry."""
2
+ from meltygui.graphics.filter import Filter
3
+ from meltygui.graphics.texture_manager import TextureManager
4
+ from meltygui.graphics import shaders
5
+
6
+ __all__ = ['Filter', 'TextureManager', 'shaders']
@@ -0,0 +1,85 @@
1
+ """
2
+ Base classes for shader types and shaders.
3
+ """
4
+
5
+ from abc import ABC
6
+ from dataclasses import dataclass, field
7
+ from typing import Dict, Any, Optional, List
8
+ from enum import Enum
9
+
10
+
11
+ class GLType(Enum):
12
+ """OpenGL data types for shader attributes and uniforms."""
13
+ FLOAT = 'float'
14
+ VEC2 = 'vec2'
15
+ VEC3 = 'vec3'
16
+ VEC4 = 'vec4'
17
+ MAT2 = 'mat2'
18
+ MAT3 = 'mat3'
19
+ MAT4 = 'mat4'
20
+ INT = 'int'
21
+ IVEC2 = 'ivec2'
22
+ IVEC3 = 'ivec3'
23
+ IVEC4 = 'ivec4'
24
+ SAMPLER2D = 'sampler2D'
25
+ BOOL = 'bool'
26
+
27
+
28
+ @dataclass
29
+ class ShaderType:
30
+ """
31
+ Defines a shader type (vertex shader structure).
32
+
33
+ Attributes:
34
+ name: The type name (inferred from class name)
35
+ vertex_in: Input attributes {name: GLType}
36
+ vertex_out: Output varyings {name: GLType}
37
+ vertex_code: The vertex shader code template
38
+ """
39
+ name: str
40
+ vertex_in: Dict[str, GLType] = field(default_factory=dict)
41
+ vertex_out: Dict[str, GLType] = field(default_factory=dict)
42
+ vertex_code: str = ""
43
+
44
+ def generate_vertex_declarations(self) -> str:
45
+ """Generate GLSL declarations for vertex shader inputs/outputs."""
46
+ lines = []
47
+ for attr_name, attr_type in self.vertex_in.items():
48
+ lines.append(f"in {attr_type.value} {attr_name};")
49
+ for var_name, var_type in self.vertex_out.items():
50
+ lines.append(f"out {var_type.value} {var_name};")
51
+ return '\n'.join(lines)
52
+
53
+
54
+ @dataclass
55
+ class Shader:
56
+ """
57
+ Defines a complete shader (fragment shader with optional vertex override).
58
+
59
+ Attributes:
60
+ name: The shader name (inferred from class name, converted to snake_case)
61
+ shader_type: The ShaderType this shader uses
62
+ fragment_code: The fragment shader code
63
+ vertex_code: Optional vertex shader code override
64
+ uniforms: Uniform definitions {name: (GLType, default_value)}
65
+ """
66
+ name: str
67
+ shader_type: Optional[str] = None # Name of shader type to use
68
+ fragment_code: str = ""
69
+ vertex_code: Optional[str] = None # Override vertex code if provided
70
+ uniforms: Dict[str, tuple] = field(default_factory=dict) # {name: (GLType, default)}
71
+
72
+ def get_uniform_declarations(self) -> str:
73
+ """Generate GLSL uniform declarations."""
74
+ lines = []
75
+ for name, (gl_type, _) in self.uniforms.items():
76
+ lines.append(f"uniform {gl_type.value} {name};")
77
+ return '\n'.join(lines)
78
+
79
+
80
+ def camel_to_snake(name: str) -> str:
81
+ """Convert CamelCase to snake_case."""
82
+ import re
83
+ # Insert underscore before uppercase letters and convert to lowercase
84
+ s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
85
+ return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
@@ -0,0 +1,507 @@
1
+ """
2
+ Example usage of the Melty shader library.
3
+
4
+ This demonstrates:
5
+ 1. Basic filter application
6
+ 2. Creating custom shaders
7
+ 3. Filter chaining
8
+ 4. Custom shader types
9
+ """
10
+ from meltygui.core.melty import Melty
11
+ from meltygui.graphics.base import GLType
12
+ from meltygui.graphics.filter import Filter
13
+ from meltygui.graphics.registry import register_shader
14
+ from meltygui.graphics.registry import register_shader_type
15
+ from meltygui.graphics.registry import get_registry
16
+
17
+
18
+ # =============================================================================
19
+ # CUSTOM SHADER EXAMPLE
20
+ # =============================================================================
21
+
22
+ @register_shader
23
+ class ColorTint:
24
+ """Apply a color tint to the image."""
25
+ shader_type = 'standard'
26
+ uniforms = {
27
+ 'tint_color': (GLType.VEC3, (1.0, 0.8, 0.6)),
28
+ 'amount': (GLType.FLOAT, 0.3),
29
+ }
30
+ fragment_code = """
31
+ void main() {
32
+ vec4 color = texture(u_texture, v_texcoord);
33
+ color.rgb = mix(color.rgb, color.rgb * tint_color, amount);
34
+ fragColor = color;
35
+ }
36
+ """
37
+
38
+
39
+ @register_shader
40
+ class FilmGrain:
41
+ """Add film grain noise effect."""
42
+ shader_type = 'standard'
43
+ uniforms = {
44
+ 'amount': (GLType.FLOAT, 0.1),
45
+ 'time': (GLType.FLOAT, 0.0), # Animate with time for varying grain
46
+ }
47
+ fragment_code = """
48
+ // Simple hash function for noise
49
+ float hash(vec2 p) {
50
+ return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
51
+ }
52
+
53
+ void main() {
54
+ vec4 color = texture(u_texture, v_texcoord);
55
+
56
+ // Generate noise based on position and time
57
+ float noise = hash(v_texcoord * 1000.0 + time) * 2.0 - 1.0;
58
+
59
+ // Apply grain
60
+ color.rgb += noise * amount;
61
+ color.rgb = clamp(color.rgb, 0.0, 1.0);
62
+
63
+ fragColor = color;
64
+ }
65
+ """
66
+
67
+
68
+ @register_shader
69
+ class Sharpen:
70
+ """Sharpening filter using unsharp mask."""
71
+ shader_type = 'standard'
72
+ uniforms = {
73
+ 'amount': (GLType.FLOAT, 1.0),
74
+ 'texture_size': (GLType.VEC2, (512.0, 512.0)),
75
+ }
76
+ fragment_code = """
77
+ void main() {
78
+ vec2 texel = 1.0 / texture_size;
79
+
80
+ // Sample center and neighbors
81
+ vec4 center = texture(u_texture, v_texcoord);
82
+ vec4 top = texture(u_texture, v_texcoord + vec2(0, -1) * texel);
83
+ vec4 bottom = texture(u_texture, v_texcoord + vec2(0, 1) * texel);
84
+ vec4 left = texture(u_texture, v_texcoord + vec2(-1, 0) * texel);
85
+ vec4 right = texture(u_texture, v_texcoord + vec2(1, 0) * texel);
86
+
87
+ // Sharpen kernel: -1, -1, -1 / -1, 9, -1 / -1, -1, -1 (simplified)
88
+ vec4 sharpened = center * (1.0 + 4.0 * amount) - (top + bottom + left + right) * amount;
89
+
90
+ fragColor = clamp(sharpened, 0.0, 1.0);
91
+ }
92
+ """
93
+
94
+
95
+ # =============================================================================
96
+ # CUSTOM SHADER TYPE EXAMPLE
97
+ # =============================================================================
98
+
99
+ @register_shader_type
100
+ class MultiTexture:
101
+ """
102
+ Shader type that supports multiple texture inputs.
103
+ Useful for blend modes, masks, etc.
104
+ """
105
+ vertex_in = {
106
+ 'position': GLType.VEC3,
107
+ 'texcoord': GLType.VEC2,
108
+ }
109
+ vertex_out = {
110
+ 'v_texcoord': GLType.VEC2,
111
+ }
112
+ vertex_code = """
113
+ void main() {
114
+ v_texcoord = texcoord;
115
+ gl_Position = vec4(position, 1.0);
116
+ }
117
+ """
118
+
119
+
120
+ @register_shader(shader_type='multi_texture')
121
+ class BlendMultiply:
122
+ """Multiply blend two textures."""
123
+ uniforms = {
124
+ 'blend_texture': (GLType.SAMPLER2D, 0),
125
+ 'opacity': (GLType.FLOAT, 1.0),
126
+ }
127
+ fragment_code = """
128
+ uniform sampler2D blend_texture;
129
+
130
+ void main() {
131
+ vec4 base = texture(u_texture, v_texcoord);
132
+ vec4 blend = texture(blend_texture, v_texcoord);
133
+
134
+ vec3 result = base.rgb * blend.rgb;
135
+ fragColor = vec4(mix(base.rgb, result, opacity), base.a);
136
+ }
137
+ """
138
+
139
+
140
+ # =============================================================================
141
+ # INTEGRATION EXAMPLE - How your Melty class would use Filter
142
+ # =============================================================================
143
+
144
+ # class Melty:
145
+ # """Example of how your existing Melty class would integrate with Filter."""
146
+ #
147
+ # def __init__(self):
148
+ # self.filter = Filter()
149
+ #
150
+ # def cleanup(self):
151
+ # self.filter.cleanup()
152
+
153
+
154
+ # =============================================================================
155
+ # USAGE EXAMPLES
156
+ # =============================================================================
157
+
158
+ def basic_usage_example():
159
+ """Demonstrate basic filter usage."""
160
+
161
+ # Your Melty class holds the Filter instance
162
+
163
+ # Assuming you have a texture_id defined somewhere
164
+ texture_id = 1 # Placeholder
165
+
166
+ # Apply a single filter
167
+ result = Melty.filter.brightness_contrast(
168
+ texture_id,
169
+ brightness=0.2,
170
+ contrast=1.3
171
+ )
172
+
173
+ # Apply in-place (modifies original texture)
174
+ Melty.filter.grayscale(texture_id, in_place=True)
175
+
176
+ # Apply multiple filters
177
+ result = Melty.filter.hue_saturation(result, saturation=1.5)
178
+ result = Melty.filter.vignette(result, radius=0.8, amount=0.3)
179
+
180
+ # Clean up
181
+ Melty.cleanup()
182
+
183
+
184
+ def direct_to_screen_example():
185
+ """Demonstrate rendering filters directly to the main framebuffer (screen)."""
186
+
187
+ texture_id = 1 # Placeholder
188
+
189
+ # Apply filter directly to main framebuffer (0) - no off-screen buffer!
190
+ # This is perfect for final post-processing effects
191
+ Melty.filter.vignette(
192
+ texture_id,
193
+ output_framebuffer=0, # Render to main screen
194
+ radius=0.8,
195
+ amount=0.4
196
+ )
197
+
198
+ # The filter is applied directly to the screen
199
+ # No texture is created - returns 0
200
+
201
+ # You can also render to a custom framebuffer
202
+ custom_fbo = 5 # Your framebuffer ID
203
+ Melty.filter.gaussian_blur(
204
+ texture_id,
205
+ output_framebuffer=custom_fbo,
206
+ radius=5.0
207
+ )
208
+
209
+ Melty.cleanup()
210
+
211
+
212
+ def framebuffer_input_example():
213
+ """Demonstrate using framebuffers as input (e.g., apply filters to screen contents)."""
214
+
215
+ # Apply a filter to whatever is currently rendered on screen!
216
+ # Reads from framebuffer 0 (main screen) and outputs to a texture
217
+ result_texture = Melty.filter.vignette(
218
+ input_framebuffer=0, # Read from main screen
219
+ radius=0.8,
220
+ amount=0.5
221
+ )
222
+ # Returns a texture with the filtered screen contents
223
+
224
+ # You can also do screen-to-screen filtering (both input and output are framebuffers)
225
+ Melty.filter.gaussian_blur(
226
+ input_framebuffer=0, # Read from main screen
227
+ output_framebuffer=0, # Write back to main screen
228
+ radius=5.0
229
+ )
230
+ # This applies the blur directly to the screen in-place!
231
+
232
+ # Read from custom framebuffer and output to texture
233
+ custom_fbo = 5 # Your framebuffer ID
234
+ result = Melty.filter.brightness_contrast(
235
+ input_framebuffer=custom_fbo,
236
+ brightness=0.2,
237
+ contrast=1.3
238
+ )
239
+
240
+ # Read from custom framebuffer and write to another framebuffer
241
+ output_fbo = 6
242
+ Melty.filter.sepia(
243
+ input_framebuffer=custom_fbo,
244
+ output_framebuffer=output_fbo,
245
+ amount=0.8
246
+ )
247
+
248
+ Melty.cleanup()
249
+
250
+
251
+ def chaining_example():
252
+ """Demonstrate filter chaining."""
253
+
254
+ texture_id = 1 # Placeholder
255
+
256
+ # Create a filter chain
257
+ # Note: texture_size is automatically detected - no need to pass it!
258
+ result = (Melty.filter.chain()
259
+ .brightness_contrast(brightness=0.1, contrast=1.2)
260
+ .hue_saturation(saturation=1.2)
261
+ .vignette(radius=0.7, softness=0.5, amount=0.4)
262
+ .sharpen(amount=0.5)
263
+ .apply(texture_id))
264
+
265
+ # Apply chain in-place
266
+ (Melty.filter.chain()
267
+ .sepia(amount=0.8)
268
+ .film_grain(amount=0.05)
269
+ .apply(texture_id, in_place=True))
270
+
271
+ Melty.cleanup()
272
+
273
+
274
+ def context_manager_example():
275
+ """Using Filter as a context manager."""
276
+
277
+ texture_id = 1 # Placeholder
278
+
279
+ with Filter() as f:
280
+ result = f.posterize(texture_id, levels=4)
281
+
282
+ # Resources are automatically cleaned up
283
+
284
+
285
+ def listing_shaders_example():
286
+ """List available shaders and their info."""
287
+
288
+ f = Filter()
289
+
290
+ # List all available shaders
291
+ print("Available shaders:")
292
+ for name in f.list_shaders():
293
+ info = f.get_shader_info(name)
294
+ print(f" {name}:")
295
+ print(f" type: {info['shader_type']}")
296
+ print(f" uniforms: {list(info['uniforms'].keys())}")
297
+
298
+ # List shader types
299
+ print("\nAvailable shader types:")
300
+ for name in f.list_shader_types():
301
+ print(f" {name}")
302
+
303
+ f.cleanup()
304
+
305
+
306
+ def texture_caching_example():
307
+ """Demonstrate automatic texture caching for efficient multi-frame processing."""
308
+
309
+ texture_id = 1 # Placeholder for input texture
310
+
311
+ f = Filter()
312
+
313
+ # Process multiple frames efficiently
314
+ # Output textures are automatically cached per input texture ID
315
+ for frame in range(10):
316
+ # Apply filters - same output texture is cached each frame!
317
+ result1 = f.brightness_contrast(texture_id, brightness=0.1)
318
+ result2 = f.vignette(result1, amount=0.3)
319
+
320
+ # Use the final result...
321
+ # (In a real app, you'd render it or save it)
322
+
323
+ # No need to manually release - caching is automatic!
324
+
325
+ # Check cache statistics
326
+ stats = f.get_cache_stats()
327
+ print("Texture cache stats:", stats['textures'])
328
+ # Output: {1: (10, 512, 512), 10: (11, 512, 512)}
329
+ # Maps input_texture_id -> (output_texture_id, width, height)
330
+
331
+ # Clear cache when done to free GPU memory
332
+ f.clear_texture_cache()
333
+
334
+ f.cleanup()
335
+
336
+
337
+ def cache_benefits_example():
338
+ """
339
+ Demonstrate the benefits of automatic texture caching.
340
+
341
+ With automatic caching:
342
+ - Each input texture ID gets its own persistent output texture
343
+ - Textures are automatically reused across frames
344
+ - Zero manual management required
345
+ - Optimal performance for multi-frame processing
346
+ """
347
+
348
+ texture_id = 1 # Placeholder
349
+ width, height = 1920, 1080
350
+
351
+ f = Filter()
352
+
353
+ # Process 100 frames with filter chain
354
+ for frame in range(100):
355
+ # Apply multiple filters
356
+ # Each intermediate result automatically gets its own cached texture
357
+ temp1 = f.brightness_contrast(texture_id, brightness=0.1)
358
+ # Note: texture_size is automatically detected from the texture!
359
+ temp2 = f.gaussian_blur_h(temp1, radius=5.0)
360
+ final = f.gaussian_blur_v(temp2, radius=5.0)
361
+
362
+ # Use final result...
363
+ # No manual release needed!
364
+
365
+ # After 100 iterations, 3 textures exist (one per unique input texture ID)
366
+ stats = f.get_cache_stats()
367
+ print(f"Cached textures: {len(stats['textures'])}")
368
+ # Output: 3 (one for texture_id=1, one for temp1, one for temp2)
369
+
370
+ f.cleanup()
371
+
372
+
373
+ def multi_size_caching_example():
374
+ """
375
+ Demonstrate automatic FBO and texture caching for multiple texture sizes.
376
+
377
+ This is the key use case: when processing textures of different sizes
378
+ in the same session, FBOs and output textures are cached automatically.
379
+ """
380
+
381
+ f = Filter()
382
+
383
+ # Simulate rendering two different sized textures each frame
384
+ texture_a = 1 # 512x512 texture
385
+ texture_b = 2 # 1920x1080 texture
386
+
387
+ for frame in range(100):
388
+ # Process texture A (512x512)
389
+ # Frame 1: Creates FBO for 512x512 and output texture for texture_a
390
+ # Frame 2+: Reuses both!
391
+ result_a = f.brightness_contrast(texture_a, brightness=0.1)
392
+ # Use result_a...
393
+
394
+ # Process texture B (1920x1080)
395
+ # Frame 1: Creates FBO for 1920x1080 and output texture for texture_b
396
+ # Frame 2+: Reuses both!
397
+ result_b = f.vignette(texture_b, amount=0.3)
398
+ # Use result_b...
399
+
400
+ # No manual management needed!
401
+
402
+ # Check cache stats
403
+ stats = f.get_cache_stats()
404
+ print("Cache statistics:")
405
+ print(f" Output textures: {stats['textures']}")
406
+ # e.g., {1: (10, 512, 512), 2: (11, 1920, 1080)}
407
+ # Maps input_texture_id -> (output_texture_id, width, height)
408
+ print(f" FBOs cached: {list(stats['fbos'].keys())}")
409
+ # e.g., [(512, 512), (1920, 1080)]
410
+ print(f" Temp textures: {list(stats['temp_textures'].keys())}")
411
+ # e.g., [(512, 512), (1920, 1080)]
412
+
413
+ # Each size has its own FBO and temp texture - no extra overhead!
414
+ # Each input texture has its own output texture - automatic reuse!
415
+
416
+ f.cleanup()
417
+
418
+
419
+ def normalize_example():
420
+ """
421
+ Demonstrate GPU-accelerated texture normalization.
422
+
423
+ The normalize filter efficiently calculates the min/max values
424
+ using parallel reduction on the GPU, then remaps all values to [0, 1].
425
+ """
426
+
427
+ f = Filter()
428
+
429
+ texture_id = 1 # Placeholder input texture that may have non-normalized values
430
+
431
+ # Normalize the texture - automatically finds min/max and remaps to [0, 1]
432
+ # This uses GPU parallel reduction - much faster than reading all pixels!
433
+ result = f.normalize(texture_id)
434
+
435
+ # Can also normalize in-place (modifies original texture)
436
+ f.normalize(texture_id, in_place=True)
437
+
438
+ # How normalization works under the hood:
439
+ # 1. Progressively downsamples the texture using min/max reduction shader
440
+ # - 1024x1024 -> 512x512 -> 256x256 -> ... -> 1x1
441
+ # 2. Reads the final 1x1 pixel (only 4 float values!) to get min/max
442
+ # 3. Applies normalization remap shader with calculated min/max
443
+ #
444
+ # For a 1024x1024 texture, this reads ~10 reduction passes + 1 pixel
445
+ # instead of reading 1 million pixels on the CPU!
446
+
447
+ f.cleanup()
448
+
449
+
450
+ # =============================================================================
451
+ # PYGAME INTEGRATION EXAMPLE
452
+ # =============================================================================
453
+
454
+ # def pygame_integration_example():
455
+ # """Example integration with Pygame."""
456
+ # import pygame
457
+ # from pygame.locals import *
458
+ # from OpenGL.GL import *
459
+ #
460
+ # # Initialize Pygame and OpenGL
461
+ # pygame.init()
462
+ # pygame.display.set_mode((800, 600), DOUBLEBUF | OPENGL)
463
+ #
464
+ # # Initialize Melty class with Filter
465
+ # meltygui = Melty()
466
+ #
467
+ # # Load an image as texture (simplified)
468
+ # def load_texture(path):
469
+ # surface = pygame.image.load(path)
470
+ # data = pygame.image.tostring(surface, "RGBA", True)
471
+ # width, height = surface.get_size()
472
+ #
473
+ # texture = glGenTextures(1)
474
+ # glBindTexture(GL_TEXTURE_2D, texture)
475
+ # glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
476
+ # GL_RGBA, GL_UNSIGNED_BYTE, data)
477
+ # glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
478
+ # glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
479
+ #
480
+ # return texture, (width, height)
481
+ #
482
+ # # Example usage:
483
+ # # texture, size = load_texture("image.png")
484
+ # # texture = meltygui.filter.brightness_contrast(texture, brightness=0.2)
485
+ #
486
+ # meltygui.cleanup()
487
+ # pygame.quit()
488
+
489
+
490
+ if __name__ == '__main__':
491
+ # Just list available shaders (doesn't need OpenGL context)
492
+
493
+ registry = get_registry()
494
+
495
+ print("Melty Shader Library")
496
+ print("=" * 40)
497
+
498
+ print("\nRegistered Shader Types:")
499
+ for name, shader_type in registry.shader_types.items():
500
+ print(f" @{name}")
501
+ print(f" inputs: {list(shader_type.vertex_in.keys())}")
502
+ print(f" outputs: {list(shader_type.vertex_out.keys())}")
503
+
504
+ print("\nRegistered Shaders:")
505
+ for name, shader in registry.shaders.items():
506
+ uniforms = ', '.join(f"{k}={v[1]}" for k, v in shader.uniforms.items())
507
+ print(f" {name}({uniforms})")