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.
- meltygui/__init__.py +107 -0
- meltygui/accounts/__init__.py +0 -0
- meltygui/accounts/internet_accounts.py +1355 -0
- meltygui/chat/__init__.py +91 -0
- meltygui/chat/activity.py +75 -0
- meltygui/chat/backends.py +36 -0
- meltygui/chat/chat_interface.py +732 -0
- meltygui/chat/chat_proxy.py +352 -0
- meltygui/chat/codex_proxy.py +592 -0
- meltygui/chat/codex_settings.py +100 -0
- meltygui/chat/codex_transport.py +60 -0
- meltygui/chat/command_parser.py +204 -0
- meltygui/chat/images.py +227 -0
- meltygui/chat/messages.py +417 -0
- meltygui/chat/metadata.py +139 -0
- meltygui/chat/writer_locks.py +64 -0
- meltygui/code/__init__.py +0 -0
- meltygui/code/basic_converters.py +533 -0
- meltygui/code/chain_converters.py +2111 -0
- meltygui/code/code_checks.py +2209 -0
- meltygui/code/core_syntax.py +1430 -0
- meltygui/code/file_converters.py +1933 -0
- meltygui/code/fileref.py +702 -0
- meltygui/code/hotswap_guard.py +144 -0
- meltygui/code/libcst_conversion.py +9724 -0
- meltygui/code/live_instrument.py +392 -0
- meltygui/code/live_view.py +2490 -0
- meltygui/code/melty_scan.py +2684 -0
- meltygui/code/new_codecs.py +1255 -0
- meltygui/code/new_converters.py +3017 -0
- meltygui/code/project_code.py +278 -0
- meltygui/code/source_context.py +63 -0
- meltygui/code/symbol_roster.py +1588 -0
- meltygui/code/syntax_check.py +34 -0
- meltygui/code/syntax_check_worker.py +114 -0
- meltygui/completion/__init__.py +0 -0
- meltygui/completion/fim.py +1232 -0
- meltygui/completion/fim_context.py +481 -0
- meltygui/completion/providers/__init__.py +0 -0
- meltygui/completion/providers/anthropic_oauth.py +446 -0
- meltygui/completion/providers/anthropic_requests.py +69 -0
- meltygui/completion/providers/claude.py +203 -0
- meltygui/completion/providers/claude_usage.py +499 -0
- meltygui/completion/providers/codex_accounts.py +180 -0
- meltygui/completion/providers/copilot.py +617 -0
- meltygui/completion/providers/oauth_popup.py +220 -0
- meltygui/completion/providers/ollama.py +320 -0
- meltygui/completion/providers/profiles.py +23 -0
- meltygui/core/README.md +88 -0
- meltygui/core/__init__.py +1 -0
- meltygui/core/automation/__init__.py +1 -0
- meltygui/core/automation/action_core.py +153 -0
- meltygui/core/automation/collection_action.py +45 -0
- meltygui/core/automation/mcp_eval.py +167 -0
- meltygui/core/automation/mcp_hotswap.py +107 -0
- meltygui/core/automation/mcp_query.py +552 -0
- meltygui/core/automation/mcp_server.py +657 -0
- meltygui/core/automation/orchestration_core.py +2636 -0
- meltygui/core/automation/query_core.py +124 -0
- meltygui/core/automation/search_core.py +26 -0
- meltygui/core/automation/selector_core.py +340 -0
- meltygui/core/automation/value_core.py +1752 -0
- meltygui/core/cache/__init__.py +1 -0
- meltygui/core/cache/cache_diagnostics.py +0 -0
- meltygui/core/cache/invalidation_decoration.py +153 -0
- meltygui/core/cache/invalidation_tracker.py +43 -0
- meltygui/core/cache/tile_cache.py +5968 -0
- meltygui/core/conversion/__init__.py +1 -0
- meltygui/core/conversion/bubbling.py +599 -0
- meltygui/core/conversion/cache_tree.py +188 -0
- meltygui/core/conversion/chain.py +113 -0
- meltygui/core/conversion/converter_register.py +145 -0
- meltygui/core/conversion/data_decoration.py +67 -0
- meltygui/core/conversion/dict_conversion.py +1815 -0
- meltygui/core/conversion/dict_conversion_util.py +177 -0
- meltygui/core/conversion/dynamic_obj.py +89 -0
- meltygui/core/conversion/graph_compare.py +183 -0
- meltygui/core/conversion/load_save_v2.py +1032 -0
- meltygui/core/conversion/missing_saved_class.py +39 -0
- meltygui/core/conversion/path_finder.py +606 -0
- meltygui/core/conversion/render_host.py +1083 -0
- meltygui/core/core_render.py +6537 -0
- meltygui/core/definition_hotswap.py +231 -0
- meltygui/core/diagnostics/__init__.py +1 -0
- meltygui/core/diagnostics/attribute_churn.py +38 -0
- meltygui/core/diagnostics/fps_counter.py +39 -0
- meltygui/core/diagnostics/gpu_frame_timer.py +103 -0
- meltygui/core/diagnostics/inspection_core.py +169 -0
- meltygui/core/diagnostics/monitor_core.py +105 -0
- meltygui/core/diagnostics/notifications.py +706 -0
- meltygui/core/diagnostics/perf_trace.py +281 -0
- meltygui/core/diagnostics/profile_decoration.py +88 -0
- meltygui/core/diagnostics/resize_trace.py +62 -0
- meltygui/core/diagnostics/screenshot_core.py +247 -0
- meltygui/core/diagnostics/session_status.py +98 -0
- meltygui/core/diagnostics/trace_core.py +445 -0
- meltygui/core/files/__init__.py +1 -0
- meltygui/core/files/file_core.py +208 -0
- meltygui/core/files/file_explorer_core.py +104 -0
- meltygui/core/files/file_tree_core.py +198 -0
- meltygui/core/files/file_watch_core.py +43 -0
- meltygui/core/files/import_graph_core.py +43 -0
- meltygui/core/files/metadata_core.py +51 -0
- meltygui/core/graphics/__init__.py +1 -0
- meltygui/core/graphics/cuda_context_core.py +166 -0
- meltygui/core/graphics/cuda_interop_core.py +136 -0
- meltygui/core/graphics/cuda_kernel_core.py +91 -0
- meltygui/core/graphics/framebuffer_recorder.py +337 -0
- meltygui/core/graphics/gl_state.py +658 -0
- meltygui/core/graphics/lut_core.py +52 -0
- meltygui/core/graphics/overlay_renderer.py +984 -0
- meltygui/core/graphics/scene_target.py +180 -0
- meltygui/core/graphics/screenshot.py +439 -0
- meltygui/core/graphics/shader_func.py +478 -0
- meltygui/core/graphics/tensor_core.py +45 -0
- meltygui/core/graphics/text_texture.py +329 -0
- meltygui/core/graphics/wayland_color.py +635 -0
- meltygui/core/input/__init__.py +1 -0
- meltygui/core/input/collision.py +165 -0
- meltygui/core/input/drag_drop_core.py +1525 -0
- meltygui/core/input/hypr_left_drag.py +323 -0
- meltygui/core/input/input_core.py +245 -0
- meltygui/core/input/input_handler.py +1101 -0
- meltygui/core/input/mouse_cursor.py +355 -0
- meltygui/core/input/pynput_backend.py +1054 -0
- meltygui/core/input/space_mouse.py +338 -0
- meltygui/core/input/touchpad_backend.py +393 -0
- meltygui/core/input/view_selection.py +177 -0
- meltygui/core/layout/__init__.py +1 -0
- meltygui/core/layout/column_core.py +2153 -0
- meltygui/core/layout/cursor_core.py +161 -0
- meltygui/core/layout/dropdown_core.py +278 -0
- meltygui/core/layout/edge_constraints.py +155 -0
- meltygui/core/layout/grid_core.py +117 -0
- meltygui/core/layout/header_core.py +23 -0
- meltygui/core/layout/header_runtime.py +67 -0
- meltygui/core/layout/layout_core.py +87 -0
- meltygui/core/layout/tile_manager_core.py +591 -0
- meltygui/core/melty.py +6726 -0
- meltygui/core/module_map.json +896 -0
- meltygui/core/module_names.py +19 -0
- meltygui/core/rendering/__init__.py +1 -0
- meltygui/core/rendering/core_decoration.py +431 -0
- meltygui/core/rendering/core_render_helpers.py +328 -0
- meltygui/core/rendering/func_metadata.py +398 -0
- meltygui/core/rendering/mode.py +818 -0
- meltygui/core/rendering/mode_defaults.py +41 -0
- meltygui/core/rendering/modes.py +136 -0
- meltygui/core/rendering/parameter_core.py +1665 -0
- meltygui/core/rendering/render_dispatch.py +1891 -0
- meltygui/core/rendering/render_funcs.py +273 -0
- meltygui/core/rendering/shaped.py +312 -0
- meltygui/core/rendering/window_decoration.py +25 -0
- meltygui/core/runtime/__init__.py +1 -0
- meltygui/core/runtime/app.py +735 -0
- meltygui/core/runtime/app_session.py +140 -0
- meltygui/core/runtime/background.py +564 -0
- meltygui/core/runtime/extensions.py +53 -0
- meltygui/core/runtime/gc_manager.py +1163 -0
- meltygui/core/runtime/lifecycle.py +21 -0
- meltygui/core/runtime/paths.py +27 -0
- meltygui/core/runtime/settings.py +14 -0
- meltygui/core/runtime/singleton.py +16 -0
- meltygui/core/runtime/thread_safe_bool.py +24 -0
- meltygui/core/runtime/thread_signal.py +30 -0
- meltygui/core/runtime/toggles.py +3115 -0
- meltygui/core/services/__init__.py +1 -0
- meltygui/core/services/account_core.py +10 -0
- meltygui/core/services/chat_core.py +19 -0
- meltygui/core/services/claude_terminal_core.py +346 -0
- meltygui/core/services/terminal_core.py +458 -0
- meltygui/core/services/terminal_runtime.py +78 -0
- meltygui/core/styling/__init__.py +1 -0
- meltygui/core/styling/color_core.py +46 -0
- meltygui/core/styling/fonts.py +639 -0
- meltygui/core/styling/global_style.py +338 -0
- meltygui/core/styling/style.py +198 -0
- meltygui/core/styling/style_core.py +522 -0
- meltygui/core/styling/warm_start.py +149 -0
- meltygui/core/windowing/__init__.py +1 -0
- meltygui/core/windowing/backends/PYIMGUI_LICENSE +28 -0
- meltygui/core/windowing/backends/__init__.py +1 -0
- meltygui/core/windowing/backends/imgui_renderer.py +138 -0
- meltygui/core/windowing/backends/native_wayland.py +850 -0
- meltygui/core/windowing/backends/protocols/xdg-decoration-unstable-v1.xml +156 -0
- meltygui/core/windowing/backends/protocols/xdg-shell.xml +1420 -0
- meltygui/core/windowing/backends/wayland_protocol.py +101 -0
- meltygui/core/windowing/dock_core.py +182 -0
- meltygui/core/windowing/frame_geometry.py +42 -0
- meltygui/core/windowing/geometry_feed.py +864 -0
- meltygui/core/windowing/glfw_utils.py +1343 -0
- meltygui/core/windowing/os_frame.py +1552 -0
- meltygui/core/windowing/surface.py +643 -0
- meltygui/core/windowing/titlebar.py +1560 -0
- meltygui/core/windowing/titlebar_buttons.py +281 -0
- meltygui/core/windowing/wayland_move.py +932 -0
- meltygui/core/windowing/window_api.py +62 -0
- meltygui/core/windowing/window_constants.py +339 -0
- meltygui/core/windowing/window_visibility.py +162 -0
- meltygui/debug/__init__.py +0 -0
- meltygui/debug/app_view_utils.py +9 -0
- meltygui/editor/__init__.py +0 -0
- meltygui/editor/bash_syntax.py +30 -0
- meltygui/editor/code_line_fast.py +152 -0
- meltygui/editor/diff.py +139 -0
- meltygui/editor/external_changes.py +159 -0
- meltygui/editor/file_header.py +41 -0
- meltygui/editor/live_usage.py +169 -0
- meltygui/editor/live_view_views.py +1803 -0
- meltygui/editor/pending_save.py +1351 -0
- meltygui/editor/roster_tints.py +547 -0
- meltygui/editor/source_preview.py +16 -0
- meltygui/editor/source_tools.py +10 -0
- meltygui/editor/source_ui.py +70 -0
- meltygui/editor/spell_check.py +77 -0
- meltygui/editor/text_editor.py +9076 -0
- meltygui/editor/usage_picker.py +538 -0
- meltygui/events/__init__.py +0 -0
- meltygui/events/example.py +118 -0
- meltygui/examples/__init__.py +0 -0
- meltygui/examples/columns_demo.py +33 -0
- meltygui/examples/columns_window_demo.py +60 -0
- meltygui/examples/context_menu_demo.py +24 -0
- meltygui/examples/context_menu_window_demo.py +49 -0
- meltygui/examples/gui_playground.py +127 -0
- meltygui/examples/live_view_playground.py +256 -0
- meltygui/examples/lora.py +43 -0
- meltygui/examples/lora_data.py +59 -0
- meltygui/examples/lora_policies.py +67 -0
- meltygui/examples/mode_demo.py +49 -0
- meltygui/examples/modifies_demo.py +119 -0
- meltygui/examples/scalar_policies.py +60 -0
- meltygui/examples/style_layouts.py +149 -0
- meltygui/examples/tile_manager_demo.py +74 -0
- meltygui/examples/tint_demo.py +160 -0
- meltygui/examples/tint_functions.py +56 -0
- meltygui/examples/trace_demo.py +88 -0
- meltygui/examples/two_windows.py +36 -0
- meltygui/files/__init__.py +0 -0
- meltygui/files/fast_file_explorer.py +439 -0
- meltygui/gnome_extension/lsd-window-geometry@latent-descent/extension.js +237 -0
- meltygui/gnome_extension/lsd-window-geometry@latent-descent/lsd-window-geometry@latent-descent.iml +9 -0
- meltygui/gnome_extension/lsd-window-geometry@latent-descent/metadata.json +7 -0
- meltygui/graphics/__init__.py +6 -0
- meltygui/graphics/base.py +85 -0
- meltygui/graphics/examples.py +507 -0
- meltygui/graphics/executor.py +520 -0
- meltygui/graphics/filter.py +667 -0
- meltygui/graphics/filter.pyi +856 -0
- meltygui/graphics/generate_stubs.py +22 -0
- meltygui/graphics/registry.py +203 -0
- meltygui/graphics/shader_compiler.py +155 -0
- meltygui/graphics/shaders.py +1302 -0
- meltygui/graphics/stub_generator.py +250 -0
- meltygui/graphics/texture_manager.py +170 -0
- meltygui/graphics/texture_min_max.py +295 -0
- meltygui/hdr_color.py +757 -0
- meltygui/image_load.py +308 -0
- meltygui/model/__init__.py +1 -0
- meltygui/model/account_model.py +142 -0
- meltygui/model/camera_model.py +159 -0
- meltygui/model/chat_model.py +86 -0
- meltygui/model/code_model.py +62 -0
- meltygui/model/code_proxy_model.py +876 -0
- meltygui/model/collection_model.py +41 -0
- meltygui/model/color_model.py +127 -0
- meltygui/model/cuda_tensor_model.py +36 -0
- meltygui/model/cuda_texture_model.py +149 -0
- meltygui/model/dropdown_model.py +137 -0
- meltygui/model/file_metadata_model.py +73 -0
- meltygui/model/file_model.py +289 -0
- meltygui/model/format_model.py +390 -0
- meltygui/model/graph_model.py +98 -0
- meltygui/model/icon_model.py +1024 -0
- meltygui/model/import_graph_model.py +468 -0
- meltygui/model/layout_model.py +15 -0
- meltygui/model/lut_model.py +266 -0
- meltygui/model/search_model.py +173 -0
- meltygui/model/tensor_model.py +402 -0
- meltygui/model/terminal_model.py +329 -0
- meltygui/model/texture_model.py +146 -0
- meltygui/model/tile_model.py +24 -0
- meltygui/model/trace_model.py +198 -0
- meltygui/model/trace_report_model.py +146 -0
- meltygui/models/__init__.py +0 -0
- meltygui/models/file_meta.py +613 -0
- meltygui/models/function_console.py +184 -0
- meltygui/models/orchestration.py +48 -0
- meltygui/pbr.py +1576 -0
- meltygui/png_unfilter.c +49 -0
- meltygui/resources/JetBrainsMono-Regular.ttf +0 -0
- meltygui/resources/THIRD_PARTY_NOTICES.md +21 -0
- meltygui/resources/dejavu/DejaVuSans-Bold.ttf +0 -0
- meltygui/resources/dejavu/DejaVuSans-ExtraLight.ttf +0 -0
- meltygui/resources/dejavu/DejaVuSans.ttf +0 -0
- meltygui/resources/dejavu/LICENSE.txt +78 -0
- meltygui/resources/fontawesome-LICENSE.txt +121 -0
- meltygui/resources/fontawesome-webfont.ttf +0 -0
- meltygui/resources/hdri/studio_small_09_1k.hdr +0 -0
- meltygui/resources/jetbrains-weights/JetBrainsMono-Bold.ttf +0 -0
- meltygui/resources/jetbrains-weights/JetBrainsMono-ExtraBold.ttf +0 -0
- meltygui/resources/jetbrains-weights/JetBrainsMono-ExtraLight.ttf +0 -0
- meltygui/resources/jetbrains-weights/JetBrainsMono-Light.ttf +0 -0
- meltygui/resources/jetbrains-weights/JetBrainsMono-Medium.ttf +0 -0
- meltygui/resources/jetbrains-weights/JetBrainsMono-SemiBold.ttf +0 -0
- meltygui/resources/jetbrains-weights/JetBrainsMono-Thin.ttf +0 -0
- meltygui/resources/jetbrains-weights/OFL.txt +93 -0
- meltygui/resources/jetbrains-weights/README.md +2 -0
- meltygui/state/__init__.py +0 -0
- meltygui/state/account_state.py +22 -0
- meltygui/state/animation_state.py +97 -0
- meltygui/state/annotation_state.py +22 -0
- meltygui/state/chat_state.py +36 -0
- meltygui/state/code_state.py +10 -0
- meltygui/state/core_enums.py +59 -0
- meltygui/state/core_markers.py +115 -0
- meltygui/state/core_undo.py +1075 -0
- meltygui/state/file_state.py +75 -0
- meltygui/state/graph_state.py +26 -0
- meltygui/state/inspection_state.py +47 -0
- meltygui/state/menu_state.py +10 -0
- meltygui/state/model_enums.py +11 -0
- meltygui/state/new_core_model.py +2394 -0
- meltygui/state/orchestration_state.py +14 -0
- meltygui/state/query_state.py +24 -0
- meltygui/state/tensor_state.py +10 -0
- meltygui/state/terminal_state.py +23 -0
- meltygui/state/trace_state.py +32 -0
- meltygui/state/voxel_state.py +12 -0
- meltygui/text_index.py +816 -0
- meltygui/utils/__init__.py +0 -0
- meltygui/utils/jump_to_code.py +344 -0
- meltygui/utils/pkl_inspect.py +90 -0
- meltygui/utils/render_utils.py +1419 -0
- meltygui/view/__init__.py +1 -0
- meltygui/view/account_view.py +524 -0
- meltygui/view/action_view.py +73 -0
- meltygui/view/chat_decoration_view.py +112 -0
- meltygui/view/chat_view.py +1703 -0
- meltygui/view/code_view.py +2677 -0
- meltygui/view/collection_view.py +1185 -0
- meltygui/view/color_view.py +824 -0
- meltygui/view/control_view.py +559 -0
- meltygui/view/decoration_view.py +439 -0
- meltygui/view/diagnostic_view.py +177 -0
- meltygui/view/dropdown_view.py +1082 -0
- meltygui/view/file_view.py +1599 -0
- meltygui/view/graph_cuda_view.py +105 -0
- meltygui/view/graph_view.py +882 -0
- meltygui/view/header_view.py +848 -0
- meltygui/view/input_view.py +238 -0
- meltygui/view/inspection_view.py +1783 -0
- meltygui/view/layout_view.py +596 -0
- meltygui/view/lut_view.py +45 -0
- meltygui/view/menu_view.py +212 -0
- meltygui/view/orchestration_view.py +658 -0
- meltygui/view/query_view.py +118 -0
- meltygui/view/search_view.py +342 -0
- meltygui/view/tab_view.py +258 -0
- meltygui/view/tensor_view.py +430 -0
- meltygui/view/terminal_view.py +355 -0
- meltygui/view/text_view.py +8031 -0
- meltygui/view/texture_view.py +480 -0
- meltygui/view/tile_view.py +38 -0
- meltygui/view/trace_view.py +923 -0
- meltygui/view/voxel_cuda_view.py +824 -0
- meltygui/view/voxel_view.py +1860 -0
- meltygui/view/window_view.py +111 -0
- meltygui-0.1.0.dist-info/METADATA +143 -0
- meltygui-0.1.0.dist-info/RECORD +372 -0
- meltygui-0.1.0.dist-info/WHEEL +4 -0
- 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
|