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,19 @@
|
|
|
1
|
+
"""Translate identifiers in older saved sessions to the canonical package."""
|
|
2
|
+
import json
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
_MODULES = json.loads(Path(__file__).with_name('module_map.json').read_text())
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def canonical_name(name):
|
|
9
|
+
parts = name.split('.')
|
|
10
|
+
for boundary in range(len(parts), 0, -1):
|
|
11
|
+
prefix = '.'.join(parts[:boundary])
|
|
12
|
+
if prefix in _MODULES:
|
|
13
|
+
return '.'.join([_MODULES[prefix], *parts[boundary:]])
|
|
14
|
+
return name
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def register_names(names):
|
|
18
|
+
"""Let application packages migrate their own persisted identifiers."""
|
|
19
|
+
_MODULES.update(names)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Shared framework rendering machinery."""
|
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class _MockNode:
|
|
5
|
+
"""A lazy reference to a location reachable from the mock meltygui, e.g.
|
|
6
|
+
``meltygui.type_defaults[cls]`` or ``meltygui.cache.invalidate_up_by_obj``.
|
|
7
|
+
|
|
8
|
+
Attribute/item access returns further nodes so chains keep building; writes
|
|
9
|
+
(``__setattr__`` / ``__setitem__``) and calls (``__call__``) append an entry
|
|
10
|
+
to the shared op-log instead of touching anything real. ``path`` is the chain
|
|
11
|
+
of steps needed to reach this location from the meltygui root.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, ops, path):
|
|
15
|
+
object.__setattr__(self, "_ops", ops)
|
|
16
|
+
object.__setattr__(self, "_path", path)
|
|
17
|
+
|
|
18
|
+
def __getattr__(self, name):
|
|
19
|
+
if name.startswith("_"):
|
|
20
|
+
raise AttributeError(name)
|
|
21
|
+
return _MockNode(self._ops, self._path + (("attr", name),))
|
|
22
|
+
|
|
23
|
+
def __setattr__(self, name, value):
|
|
24
|
+
self._ops.append((self._path + (("attr", name),), "set", value))
|
|
25
|
+
|
|
26
|
+
def __getitem__(self, key):
|
|
27
|
+
return _MockNode(self._ops, self._path + (("item", key),))
|
|
28
|
+
|
|
29
|
+
def __setitem__(self, key, value):
|
|
30
|
+
self._ops.append((self._path + (("item", key),), "set", value))
|
|
31
|
+
|
|
32
|
+
# Without these, ``x in node`` falls back to the sequence protocol and calls
|
|
33
|
+
# __getitem__(0), __getitem__(1), ... forever (each returns a node, never
|
|
34
|
+
# IndexError) -> hang. A pre-init collection is empty: nothing is in it.
|
|
35
|
+
def __contains__(self, key):
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
def __iter__(self):
|
|
39
|
+
return iter(())
|
|
40
|
+
|
|
41
|
+
def __call__(self, *args, **kwargs):
|
|
42
|
+
self._ops.append((self._path, "call", (args, kwargs)))
|
|
43
|
+
# Allow chaining off the return value (e.g. meltygui.foo(...).bar = x). The
|
|
44
|
+
# call's args travel with the step so replay can reproduce it faithfully.
|
|
45
|
+
return _MockNode(self._ops, self._path + (("call", args, kwargs),))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class MockMelty:
|
|
49
|
+
"""Stand-in for ``Melty`` used before ``Melty.init()`` runs.
|
|
50
|
+
|
|
51
|
+
``core_decoration.py`` must not import ``meltygui`` (circular import), so all
|
|
52
|
+
pre-init access to Melty — chiefly the ``@defaults`` decorator writing
|
|
53
|
+
``type_defaults[cls] = meta`` at class-definition time — goes through this
|
|
54
|
+
recorder. Every write and call is appended to a flat op-log; ``replay``
|
|
55
|
+
re-applies that log against the real Melty during init so nothing done at
|
|
56
|
+
import/decoration time is lost.
|
|
57
|
+
"""
|
|
58
|
+
def __init__(self):
|
|
59
|
+
# Each entry is (path, kind, payload):
|
|
60
|
+
# path - tuple of ("attr", name) / ("item", key) / ("call",) steps
|
|
61
|
+
# kind - "set" | "call"
|
|
62
|
+
# payload - the value (for "set") or (args, kwargs) (for "call")
|
|
63
|
+
object.__setattr__(self, "_ops", [])
|
|
64
|
+
|
|
65
|
+
def __getattr__(self, name):
|
|
66
|
+
if name.startswith("_"):
|
|
67
|
+
raise AttributeError(name)
|
|
68
|
+
return _MockNode(self._ops, (("attr", name),))
|
|
69
|
+
|
|
70
|
+
def __setattr__(self, name, value):
|
|
71
|
+
self._ops.append(((("attr", name),), "set", value))
|
|
72
|
+
|
|
73
|
+
@staticmethod
|
|
74
|
+
def _walk(target, path):
|
|
75
|
+
cur = target
|
|
76
|
+
for kind, *rest in path:
|
|
77
|
+
if kind == "attr":
|
|
78
|
+
cur = getattr(cur, rest[0])
|
|
79
|
+
elif kind == "item":
|
|
80
|
+
cur = cur[rest[0]]
|
|
81
|
+
elif kind == "call":
|
|
82
|
+
args, kwargs = rest
|
|
83
|
+
cur = cur(*args, **kwargs)
|
|
84
|
+
return cur
|
|
85
|
+
|
|
86
|
+
def _apply(self, target, path, kind, payload):
|
|
87
|
+
if kind == "set":
|
|
88
|
+
container = self._walk(target, path[:-1])
|
|
89
|
+
last_kind, last_arg = path[-1]
|
|
90
|
+
if last_kind == "attr":
|
|
91
|
+
setattr(container, last_arg, payload)
|
|
92
|
+
else: # item
|
|
93
|
+
container[last_arg] = payload
|
|
94
|
+
elif kind == "call":
|
|
95
|
+
fn = self._walk(target, path)
|
|
96
|
+
args, kwargs = payload
|
|
97
|
+
fn(*args, **kwargs)
|
|
98
|
+
|
|
99
|
+
def replay(self, target):
|
|
100
|
+
"""Re-apply every recorded interaction against the real meltygui ``target``.
|
|
101
|
+
|
|
102
|
+
Best-effort: the only op that must land is ``@defaults`` writing
|
|
103
|
+
``type_defaults[cls] = meta``. Other entries are incidental side effects
|
|
104
|
+
of pre-init read-chains (e.g. ``type_defaults.get(...)`` lookups or
|
|
105
|
+
live-attribute registration on objects built before init) — those re-run
|
|
106
|
+
naturally at runtime, so a failure to replay one is skipped, not fatal.
|
|
107
|
+
"""
|
|
108
|
+
applied = skipped = 0
|
|
109
|
+
for path, kind, payload in self._ops:
|
|
110
|
+
try:
|
|
111
|
+
self._apply(target, path, kind, payload)
|
|
112
|
+
applied += 1
|
|
113
|
+
except Exception as exc:
|
|
114
|
+
skipped += 1
|
|
115
|
+
names = ".".join(str(s[1]) for s in path if len(s) > 1)
|
|
116
|
+
print(f"MockMelty.replay: skipped {kind} on '{names}': {exc!r}")
|
|
117
|
+
return applied, skipped
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class Core:
|
|
121
|
+
melty = MockMelty()
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def defaults(*args, **kwargs):
|
|
125
|
+
"""Class decorator setting Meta defaults.
|
|
126
|
+
|
|
127
|
+
Without ``attr`` the Meta applies to the class itself (registered in
|
|
128
|
+
``type_defaults``). With ``attr`` the remaining kwargs become the Meta for
|
|
129
|
+
that attribute, stored as ``{name}_meta`` on the class — exactly where
|
|
130
|
+
``Meta.get_child_meta`` looks it up. ``attr`` accepts a single name or an
|
|
131
|
+
iterable of names sharing the same overrides:
|
|
132
|
+
|
|
133
|
+
@defaults(attr="some_attrib", show_tint=False, show_bg=True)
|
|
134
|
+
@defaults(show_name=True) # class-level default
|
|
135
|
+
class Foo: ...
|
|
136
|
+
|
|
137
|
+
``attrib`` is accepted as an alias for ``attr``.
|
|
138
|
+
"""
|
|
139
|
+
attr = kwargs.pop("attr", None)
|
|
140
|
+
if attr is None:
|
|
141
|
+
attr = kwargs.pop("attrib", None)
|
|
142
|
+
else:
|
|
143
|
+
kwargs.pop("attrib", None)
|
|
144
|
+
|
|
145
|
+
def decorator(cls):
|
|
146
|
+
|
|
147
|
+
# from meltygui.state.annotation_state import Meta
|
|
148
|
+
if attr is None:
|
|
149
|
+
# DecorationManager.melty.type_defaults[cls] = Meta(**kwargs)
|
|
150
|
+
for key in kwargs:
|
|
151
|
+
Core.melty.default_kwargs_by_type[cls][key] = kwargs[key]
|
|
152
|
+
|
|
153
|
+
else:
|
|
154
|
+
names = [attr] if isinstance(attr, str) else list(attr)
|
|
155
|
+
for name in names:
|
|
156
|
+
for key in kwargs:
|
|
157
|
+
Core.melty.default_kwargs_by_attrib_type[cls][name][key] = kwargs[key]
|
|
158
|
+
print(f"Registered default for {cls.__name__}.{name}: {key}={kwargs[key]}")
|
|
159
|
+
if key == "view_function" or key == "func":
|
|
160
|
+
Core.melty.default_funcs_by_name_type[cls][name] = kwargs[key]
|
|
161
|
+
|
|
162
|
+
# child_meta = Meta(**kwargs)
|
|
163
|
+
# child_meta.name = name
|
|
164
|
+
# setattr(cls, f"{name}_meta", child_meta)
|
|
165
|
+
return cls
|
|
166
|
+
|
|
167
|
+
return decorator
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def attribute(func):
|
|
171
|
+
"""Decorator that makes a method appear in __dict__"""
|
|
172
|
+
func._add_to_dict = True
|
|
173
|
+
return func
|
|
174
|
+
|
|
175
|
+
class auto_eval:
|
|
176
|
+
_add_to_dict = True # Class attribute
|
|
177
|
+
|
|
178
|
+
def __init__(self, fget=None, fset=None, fdel=None):
|
|
179
|
+
self.fget = fget
|
|
180
|
+
self._add_to_dict = True # Set on the instance
|
|
181
|
+
self.fset = fset
|
|
182
|
+
self.fdel = fdel
|
|
183
|
+
self.name = None
|
|
184
|
+
self.last_known_value = None
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def __set_name__(self, owner, name):
|
|
188
|
+
self.name = name
|
|
189
|
+
self.private_name = f'_{name}'
|
|
190
|
+
|
|
191
|
+
def __get__(self, obj, objtype=None):
|
|
192
|
+
if obj is None:
|
|
193
|
+
self.last_known_value = None
|
|
194
|
+
return self
|
|
195
|
+
|
|
196
|
+
# Register on first access if not already registered
|
|
197
|
+
if obj not in Core.melty.live_attributes:
|
|
198
|
+
Core.melty.live_attributes[obj] = set()
|
|
199
|
+
if self.name not in Core.melty.live_attributes[obj]:
|
|
200
|
+
Core.melty.live_attributes[obj].add(self.name)
|
|
201
|
+
|
|
202
|
+
if self.fget is None:
|
|
203
|
+
new_val = obj.__dict__.get(self.private_name)
|
|
204
|
+
self._on_change(obj, self.last_known_value, new_val)
|
|
205
|
+
self.last_known_value = new_val
|
|
206
|
+
return new_val
|
|
207
|
+
|
|
208
|
+
new_val = self.fget(obj)
|
|
209
|
+
self._on_change(obj, self.last_known_value, new_val)
|
|
210
|
+
self.last_known_value = new_val
|
|
211
|
+
return new_val
|
|
212
|
+
|
|
213
|
+
def __set__(self, obj, value):
|
|
214
|
+
# Register on first set if not already registered
|
|
215
|
+
if obj not in Core.melty.live_attributes:
|
|
216
|
+
Core.melty.live_attributes[obj] = set()
|
|
217
|
+
if self.name not in Core.melty.live_attributes[obj]:
|
|
218
|
+
Core.melty.live_attributes[obj].add(self.name)
|
|
219
|
+
|
|
220
|
+
old_value = obj.__dict__.get(self.private_name)
|
|
221
|
+
|
|
222
|
+
if self.fset is None:
|
|
223
|
+
obj.__dict__[self.private_name] = value
|
|
224
|
+
else:
|
|
225
|
+
self.fset(obj, value)
|
|
226
|
+
|
|
227
|
+
# Your custom callback logic here
|
|
228
|
+
if old_value != value:
|
|
229
|
+
self._on_change(obj, old_value, value)
|
|
230
|
+
|
|
231
|
+
def __delete__(self, obj):
|
|
232
|
+
if self.fdel is None:
|
|
233
|
+
del obj.__dict__[self.private_name]
|
|
234
|
+
else:
|
|
235
|
+
self.fdel(obj)
|
|
236
|
+
|
|
237
|
+
def setter(self, fset):
|
|
238
|
+
return type(self)(self.fget, fset, self.fdel)
|
|
239
|
+
|
|
240
|
+
def deleter(self, fdel):
|
|
241
|
+
return type(self)(self.fget, self.fset, fdel)
|
|
242
|
+
|
|
243
|
+
def _on_change(self, obj, old_value, new_value):
|
|
244
|
+
from meltygui.core.windowing.glfw_utils import request_render
|
|
245
|
+
deep_refresh_names = getattr(self, '__deep_refresh__', set())
|
|
246
|
+
|
|
247
|
+
if Core.melty.silence_invalidate:
|
|
248
|
+
return
|
|
249
|
+
|
|
250
|
+
excluded = getattr(obj, '__excluded_attrs__', set())
|
|
251
|
+
invalidate_all_flag = getattr(self, '__invalidate_all__', set())
|
|
252
|
+
|
|
253
|
+
do_deep_refresh = self.name in deep_refresh_names and not Core.melty.window_drag
|
|
254
|
+
visible = self.name not in excluded
|
|
255
|
+
visible = visible or do_deep_refresh
|
|
256
|
+
|
|
257
|
+
if self.name in invalidate_all_flag:
|
|
258
|
+
Core.melty.cache.invalidate_all()
|
|
259
|
+
print(f"Invalidate all called due to change in {self.name}")
|
|
260
|
+
request_render()
|
|
261
|
+
return
|
|
262
|
+
|
|
263
|
+
if old_value != new_value:
|
|
264
|
+
if visible and not self.name.startswith('_') \
|
|
265
|
+
and self.name != "driver" and Core.melty.frame_count > 3:
|
|
266
|
+
Core.melty.last_attr = self.name
|
|
267
|
+
from meltygui.core.cache.invalidation_tracker import Note
|
|
268
|
+
if do_deep_refresh:
|
|
269
|
+
note = Note(name="Core decoration", reason="invalidate_up_by_obj", tint=(0, 0, 1))
|
|
270
|
+
Core.melty.cache.invalidate_up_by_obj(obj=obj, name=self.name, max_depth=6, force=True, note=note)
|
|
271
|
+
request_render()
|
|
272
|
+
|
|
273
|
+
if hasattr(self, "context_menu_ds"):
|
|
274
|
+
print(f"Context menu ds found, invalidating {self.name}")
|
|
275
|
+
else:
|
|
276
|
+
note = Note(name="Core decoration", reason="invalidate_up_by_obj", tint=(0, 0, 1))
|
|
277
|
+
|
|
278
|
+
Core.melty.cache.invalidate_up_by_obj(obj, self.name, max_depth=3, note=note)
|
|
279
|
+
request_render()
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
"""Override this or add your universal callback logic here"""
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def setter(self, fset):
|
|
287
|
+
return type(self)(self.fget, fset, self.fdel)
|
|
288
|
+
|
|
289
|
+
def deleter(self, fdel):
|
|
290
|
+
return type(self)(self.fget, self.fset, fdel)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def deep_refresh(*args, **kwargs):
|
|
294
|
+
def decorator(cls):
|
|
295
|
+
if len(args) == 1 and isinstance(args[0], (list, set, tuple)):
|
|
296
|
+
from_args = args[0]
|
|
297
|
+
else:
|
|
298
|
+
from_args = set(args)
|
|
299
|
+
already_excluded = getattr(cls, '__deep_refresh__', set())
|
|
300
|
+
merged_names = already_excluded.union(set(from_args))
|
|
301
|
+
merged_names = merged_names.union(from_args)
|
|
302
|
+
|
|
303
|
+
setattr(cls, '__deep_refresh__', merged_names)
|
|
304
|
+
return cls
|
|
305
|
+
|
|
306
|
+
return decorator
|
|
307
|
+
#
|
|
308
|
+
# def tint(*args, **kwargs):
|
|
309
|
+
# def decorator(cls):
|
|
310
|
+
# if len(args) == 1 and isinstance(args[0], (list, set, tuple, dict)):
|
|
311
|
+
# from_args = args[0]
|
|
312
|
+
# setattr(cls, '__tint__', from_args)
|
|
313
|
+
# return cls
|
|
314
|
+
#
|
|
315
|
+
# return decorator
|
|
316
|
+
|
|
317
|
+
def invalidate_all(*args, **kwargs):
|
|
318
|
+
def decorator(cls):
|
|
319
|
+
if len(args) == 1 and isinstance(args[0], (list, set, tuple)):
|
|
320
|
+
from_args = args[0]
|
|
321
|
+
else:
|
|
322
|
+
from_args = set(args)
|
|
323
|
+
already_excluded = getattr(cls, '__invalidate_all__', set())
|
|
324
|
+
merged_names = already_excluded.union(set(from_args))
|
|
325
|
+
merged_names = merged_names.union(from_args)
|
|
326
|
+
|
|
327
|
+
setattr(cls, '__invalidate_all__', merged_names)
|
|
328
|
+
return cls
|
|
329
|
+
|
|
330
|
+
return decorator
|
|
331
|
+
|
|
332
|
+
global_hotkeys = {}
|
|
333
|
+
|
|
334
|
+
def no_save(*args, **kwargs):
|
|
335
|
+
def decorator(cls):
|
|
336
|
+
if len(args) == 1 and isinstance(args[0], (list, set, tuple)):
|
|
337
|
+
from_args = args[0]
|
|
338
|
+
else:
|
|
339
|
+
from_args = set(args)
|
|
340
|
+
already_excluded = getattr(cls, '__no_save__', set())
|
|
341
|
+
merged_names = already_excluded.union(set(from_args))
|
|
342
|
+
merged_names = merged_names.union(from_args)
|
|
343
|
+
|
|
344
|
+
setattr(cls, '__no_save__', merged_names)
|
|
345
|
+
return cls
|
|
346
|
+
|
|
347
|
+
return decorator
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def exclude(*args, **kwargs):
|
|
351
|
+
def decorator(cls):
|
|
352
|
+
if len(args) == 1 and isinstance(args[0], (list, set, tuple)):
|
|
353
|
+
from_args = args[0]
|
|
354
|
+
else:
|
|
355
|
+
from_args = set(args)
|
|
356
|
+
already_excluded = getattr(cls, '__excluded_attrs__', set())
|
|
357
|
+
merged_names = already_excluded.union(set(from_args))
|
|
358
|
+
merged_names = merged_names.union(from_args)
|
|
359
|
+
|
|
360
|
+
setattr(cls, '__excluded_attrs__', merged_names)
|
|
361
|
+
return cls
|
|
362
|
+
|
|
363
|
+
return decorator
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
def no_save_exclude(*args, **kwargs):
|
|
367
|
+
def decorator(cls):
|
|
368
|
+
if len(args) == 1 and isinstance(args[0], (list, set, tuple)):
|
|
369
|
+
from_args = args[0]
|
|
370
|
+
else:
|
|
371
|
+
from_args = set(args)
|
|
372
|
+
already_excluded = getattr(cls, '__excluded_attrs__', set())
|
|
373
|
+
merged_names = already_excluded.union(set(from_args))
|
|
374
|
+
merged_names = merged_names.union(from_args)
|
|
375
|
+
setattr(cls, '__excluded_attrs__', merged_names)
|
|
376
|
+
|
|
377
|
+
already_no_save = getattr(cls, '__no_save__', set())
|
|
378
|
+
merged_names_ns = already_no_save.union(set(from_args))
|
|
379
|
+
merged_names_ns = merged_names_ns.union(from_args)
|
|
380
|
+
|
|
381
|
+
setattr(cls, '__no_save__', merged_names_ns)
|
|
382
|
+
|
|
383
|
+
return cls
|
|
384
|
+
|
|
385
|
+
return decorator
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def hotkey(key):
|
|
390
|
+
"""
|
|
391
|
+
This is the decorator factory. It takes arguments for the decorator.
|
|
392
|
+
"""
|
|
393
|
+
|
|
394
|
+
def actual_decorator(func):
|
|
395
|
+
"""
|
|
396
|
+
This is the actual decorator. It takes the function to be decorated.
|
|
397
|
+
"""
|
|
398
|
+
sig = inspect.signature(func)
|
|
399
|
+
params = sig.parameters
|
|
400
|
+
|
|
401
|
+
if isinstance(key, int):
|
|
402
|
+
from meltygui.state.new_core_model import Hotkey
|
|
403
|
+
the_hotkey = Hotkey(key=key)
|
|
404
|
+
else:
|
|
405
|
+
the_hotkey = key
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
def wrapper(*args, **kwargs):
|
|
409
|
+
to_remove = []
|
|
410
|
+
for name, arg in kwargs.items():
|
|
411
|
+
if name not in params:
|
|
412
|
+
to_remove.append(name)
|
|
413
|
+
for name in to_remove:
|
|
414
|
+
kwargs.pop(name)
|
|
415
|
+
|
|
416
|
+
for wanted_name, param in params.items():
|
|
417
|
+
if wanted_name in Core.melty.global_attrs and wanted_name not in kwargs:
|
|
418
|
+
kwargs[wanted_name] = Core.melty.global_attrs[wanted_name]
|
|
419
|
+
|
|
420
|
+
result = func(*args, **kwargs) # Call the original function
|
|
421
|
+
return result
|
|
422
|
+
|
|
423
|
+
if hotkey in global_hotkeys:
|
|
424
|
+
print(f"Warning: hotkey '{hotkey}' is already registered to "
|
|
425
|
+
f"{global_hotkeys[hotkey].__name__}, overwriting with {func.__name__}")
|
|
426
|
+
global_hotkeys[the_hotkey] = wrapper
|
|
427
|
+
|
|
428
|
+
return wrapper
|
|
429
|
+
|
|
430
|
+
return actual_decorator
|
|
431
|
+
|