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,33 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""The studio's columns playground (view/playground/columns_playground.py)
|
|
3
|
+
as an app: `@window` swapped for `@glfw_window`, nothing else changed."""
|
|
4
|
+
import meltygui_imgui as imgui
|
|
5
|
+
from meltygui import glfw_window
|
|
6
|
+
from meltygui.view.layout_view import draw_rows
|
|
7
|
+
from meltygui.model.layout_model import Columns
|
|
8
|
+
from meltygui.model.layout_model import Rows
|
|
9
|
+
from meltygui.core.core_render import render_func
|
|
10
|
+
|
|
11
|
+
columns_demo = Columns({
|
|
12
|
+
"settings": {"alpha": 0.5, "steps": 12, "label": "left pane", "enabled": True},
|
|
13
|
+
"notes": "Drag a divider: the column resizes, its neighbours slide, and "
|
|
14
|
+
"when they run out of slack the window edge gets pushed.",
|
|
15
|
+
"integer": [1, 1, 1, 1],
|
|
16
|
+
"nested": Columns({"inner_a": {"x": 1, "y": 2}, "inner_b": [3, 1, 4, 1, 5]}),
|
|
17
|
+
})
|
|
18
|
+
rows_demo = Rows({
|
|
19
|
+
"toolbar": {"query": "rows", "limit": 12, "live": True},
|
|
20
|
+
"panes": columns_demo,
|
|
21
|
+
"stack": Columns({
|
|
22
|
+
"log": ["row edges collide like column edges", "drag a band between rows",
|
|
23
|
+
"push through: the window frame follows"],
|
|
24
|
+
"inner_rows": Rows({"a": {"x": 1}, "b": [2, 7, 1]}),
|
|
25
|
+
}),
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@glfw_window(name='Columns demo', width=900, height=560)
|
|
30
|
+
@render_func(tint=(0.19, 0.23, 0.29), auto_resize=False, min_width=720, min_height=420)
|
|
31
|
+
def draw_columns_demo(_, draw_state):
|
|
32
|
+
imgui.text("draw_rows / draw_columns: shared edges — rows, columns, nested both ways")
|
|
33
|
+
draw_rows(rows_demo, name="rows_demo_body")
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Demo for the draw_columns / draw_rows layouts (view/core_views/columns.py).
|
|
2
|
+
|
|
3
|
+
Every edge line — the window's four frame edges, each column edge, each
|
|
4
|
+
row edge — is a draggable object shared by reference between the views
|
|
5
|
+
that meet on it. Lines move independently and only carry a neighbour on
|
|
6
|
+
physical contact (MIN_COLUMN_WIDTH along x, MIN_ROW_HEIGHT along y);
|
|
7
|
+
pushed through the pile, an interior line moves the window frame itself.
|
|
8
|
+
A right-drag anywhere latches the column edge to the cursor's right AND
|
|
9
|
+
the row edge below it (double-right-drag: the edges to its left / above)
|
|
10
|
+
and drives both through the same solve.
|
|
11
|
+
"""
|
|
12
|
+
import meltygui_imgui as imgui
|
|
13
|
+
|
|
14
|
+
from meltygui.view.layout_view import draw_rows
|
|
15
|
+
from meltygui.model.layout_model import Columns
|
|
16
|
+
from meltygui.model.layout_model import Rows
|
|
17
|
+
from meltygui.core.core_render import render_func
|
|
18
|
+
from meltygui.core.rendering.window_decoration import window
|
|
19
|
+
|
|
20
|
+
# Module-level so hotswap re-exec reuses it and edits keep their state while
|
|
21
|
+
# iterating on draw_columns.
|
|
22
|
+
columns_demo = Columns({
|
|
23
|
+
"settings": {"alpha": 0.5, "steps": 12, "label": "left pane", "enabled": True},
|
|
24
|
+
"notes": "Drag a divider: the column resizes, its neighbours slide, and "
|
|
25
|
+
"when they run out of slack the window edge gets pushed.",
|
|
26
|
+
"integer": [1,1,1,1],
|
|
27
|
+
"nested": Columns({
|
|
28
|
+
"inner_a": {"x": 1, "y": 2},
|
|
29
|
+
"inner_b": [3, 1, 4, 1, 5],
|
|
30
|
+
}),
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
# Rows stack top to bottom on the same machinery. The middle row is the
|
|
34
|
+
# Columns demo above, so its column edges live inside a row band; the last
|
|
35
|
+
# row is a Columns whose inner cell is itself a Rows - the outer row's
|
|
36
|
+
# edges are passed through the Columns cell to it, so its interior band
|
|
37
|
+
# collides with the rows above and the window's bottom frame edge.
|
|
38
|
+
rows_demo = Rows({
|
|
39
|
+
"toolbar": {"query": "rows", "limit": 12, "live": True},
|
|
40
|
+
"panes": columns_demo,
|
|
41
|
+
"stack": Columns({
|
|
42
|
+
"log": ["row edges collide like column edges",
|
|
43
|
+
"drag a band between rows",
|
|
44
|
+
"push through: the window frame follows"],
|
|
45
|
+
"inner_rows": Rows({
|
|
46
|
+
"a": {"x": 1},
|
|
47
|
+
"b": [2, 7, 1],
|
|
48
|
+
}),
|
|
49
|
+
}),
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# auto_resize=False: a fixed-size window so the edges have a stable space to
|
|
54
|
+
# resize in; edges move independently of the window either way.
|
|
55
|
+
@window
|
|
56
|
+
@render_func(tint=(0.19, 0.23, 0.29), auto_resize=False, min_width=720, min_height=420)
|
|
57
|
+
def draw_columns_demo(_, draw_state):
|
|
58
|
+
imgui.text("draw_rows / draw_columns: shared edges — rows, columns, nested both ways, "
|
|
59
|
+
"and the window frame all collide")
|
|
60
|
+
draw_rows(rows_demo, name="rows_demo_body")
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""The studio's context-menu playground as an app: fields drawn with
|
|
3
|
+
draw_any, a right-click menu on each (`@window` -> `@glfw_window`)."""
|
|
4
|
+
import meltygui_imgui as imgui
|
|
5
|
+
from meltygui import glfw_window
|
|
6
|
+
from meltygui.core.core_render import render_func
|
|
7
|
+
from meltygui.core.rendering.render_dispatch import draw_any
|
|
8
|
+
|
|
9
|
+
demo = {"greeting": "right-click me", "count": 3}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@glfw_window(name='Context menu demo', width=520, height=260)
|
|
13
|
+
@render_func(tint=(0.78, 0.16, 0.75), auto_resize=False, min_width=420, min_height=200)
|
|
14
|
+
def draw_context_menu_demo(_, draw_state):
|
|
15
|
+
imgui.text("context_menu={label: callable} — right-click a value below")
|
|
16
|
+
changed, value = draw_any(demo["greeting"], name="greeting",
|
|
17
|
+
context_menu={"Uppercase": lambda: demo.update(greeting=demo["greeting"].upper()),
|
|
18
|
+
"Reset": lambda: demo.update(greeting="right-click me")})
|
|
19
|
+
if changed:
|
|
20
|
+
demo["greeting"] = value
|
|
21
|
+
changed, value = draw_any(demo["count"], name="count",
|
|
22
|
+
context_menu={"Add one": lambda: demo.update(count=demo["count"] + 1)})
|
|
23
|
+
if changed:
|
|
24
|
+
demo["count"] = value
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Demo for `context_menu=` — a right-click menu on any render call.
|
|
2
|
+
|
|
3
|
+
Pass `context_menu={label: callable}` to a view and core_render draws the
|
|
4
|
+
labels as a dropdown menu at the pointer (draw_context_menu_items); the
|
|
5
|
+
Inspect row at the bottom of that menu opens the inspector (draw_context_menu).
|
|
6
|
+
Nothing else is wired: the wrapper owns the right-click, the popover and the
|
|
7
|
+
swap, exactly like it owns the inspector today.
|
|
8
|
+
"""
|
|
9
|
+
import meltygui_imgui as imgui
|
|
10
|
+
|
|
11
|
+
from meltygui.core.core_render import render_func
|
|
12
|
+
from meltygui.core.rendering.window_decoration import window
|
|
13
|
+
from meltygui.core.rendering.render_dispatch import draw_any
|
|
14
|
+
|
|
15
|
+
# Module-level so hotswap re-exec reuses it and the edits made through the
|
|
16
|
+
# menu keep their state while iterating.
|
|
17
|
+
demo = {"greeting": "right-click me", "count": 3}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@window
|
|
21
|
+
@render_func(tint=(0.78, 0.16, 0.75), auto_resize=False, min_width=420, min_height=200)
|
|
22
|
+
def draw_context_menu_demo(_, draw_state):
|
|
23
|
+
imgui.text("context_menu={label: callable} — right-click a value below")
|
|
24
|
+
|
|
25
|
+
def _upper():
|
|
26
|
+
demo["greeting"] = demo["greeting"].upper()
|
|
27
|
+
|
|
28
|
+
def _lower():
|
|
29
|
+
demo["greeting"] = demo["greeting"].lower()
|
|
30
|
+
|
|
31
|
+
def _reset():
|
|
32
|
+
demo["greeting"] = "right-click me"
|
|
33
|
+
|
|
34
|
+
changed, value = draw_any(demo["greeting"], name="greeting",
|
|
35
|
+
context_menu={"Uppercase": _upper, "Lowercase": _lower,
|
|
36
|
+
"Reset": _reset})
|
|
37
|
+
if changed:
|
|
38
|
+
demo["greeting"] = value
|
|
39
|
+
|
|
40
|
+
def _bump():
|
|
41
|
+
demo["count"] += 1
|
|
42
|
+
|
|
43
|
+
def _zero():
|
|
44
|
+
demo["count"] = 0
|
|
45
|
+
|
|
46
|
+
changed, value = draw_any(demo["count"], name="count",
|
|
47
|
+
context_menu={"Add one": _bump, "Zero": _zero})
|
|
48
|
+
if changed:
|
|
49
|
+
demo["count"] = value
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"""Standalone GUI playground: residual backgrounds and suggested text colours."""
|
|
2
|
+
import meltygui_imgui as imgui
|
|
3
|
+
|
|
4
|
+
import meltygui
|
|
5
|
+
from meltygui import Style
|
|
6
|
+
from meltygui import glfw_window
|
|
7
|
+
from meltygui import pressed
|
|
8
|
+
from meltygui.hdr_color import pack_color
|
|
9
|
+
from meltygui.hdr_color import white
|
|
10
|
+
from meltygui.hdr_color import p3
|
|
11
|
+
from meltygui.core.melty import Melty
|
|
12
|
+
from meltygui.core.runtime.toggles import Toggles
|
|
13
|
+
from meltygui.core.core_render import render_func
|
|
14
|
+
from meltygui.view.header_view import draw_header
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def toggle_styles():
|
|
18
|
+
Toggles.dynamic_styles = not Toggles.dynamic_styles
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def toggle_root():
|
|
22
|
+
Toggles.dynamic_style_root = ((0.88, 0.89, 0.92)
|
|
23
|
+
if Toggles.dynamic_style_root[0] < 0.5
|
|
24
|
+
else (0.12, 0.13, 0.15))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def reset():
|
|
28
|
+
Toggles.dynamic_styles = True
|
|
29
|
+
Toggles.dynamic_style_root = (0.12, 0.13, 0.15)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@render_func(tint=(0.3, 0.15, 0.15), show_bg=False, show_header=False,
|
|
33
|
+
use_cache=False, auto_resize=False)
|
|
34
|
+
def sample(input_value, draw_state, style=None, nested=False):
|
|
35
|
+
if Toggles.dynamic_styles:
|
|
36
|
+
Melty.add_background(style)
|
|
37
|
+
else:
|
|
38
|
+
# Baseline preview is just a fixed traditional background.
|
|
39
|
+
imgui.get_window_draw_list().add_rect_filled(
|
|
40
|
+
draw_state.abs_left, draw_state.abs_top,
|
|
41
|
+
draw_state.abs_left + draw_state.width, draw_state.abs_top + draw_state.height,
|
|
42
|
+
pack_color(0.2, 0.22, 0.25, 1), 5)
|
|
43
|
+
left, top = draw_state.abs_left + 12, draw_state.abs_top + 10
|
|
44
|
+
draw_list = imgui.get_window_draw_list()
|
|
45
|
+
draw_list.add_text(left, top, pack_color(0.6, 0.6, 0.6, 1), input_value)
|
|
46
|
+
for index, suggestion in enumerate(((0.2, 0.2, 0.2), (0.9, 0.9, 0.9), (0.7, 0.12, 0.12))):
|
|
47
|
+
draw_list.add_text(left + index * 210, top + 27, pack_color(*suggestion, 1),
|
|
48
|
+
('Dark suggestion', 'Light suggestion', 'Red suggestion')[index])
|
|
49
|
+
if nested:
|
|
50
|
+
imgui.set_cursor_screen_pos((left + 10, top + 58))
|
|
51
|
+
sample('Nested: reduce brightness by 30%', name='nested',
|
|
52
|
+
style=Style((-0.3, -0.3, -0.3)), width=draw_state.width - 44, height=76)
|
|
53
|
+
imgui.set_cursor_screen_pos((draw_state.abs_left, draw_state.abs_top))
|
|
54
|
+
imgui.dummy(draw_state.width, draw_state.height)
|
|
55
|
+
return False, input_value
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@glfw_window(name='Melty GUI playground', width=840, height=870, show_name=True,
|
|
59
|
+
with_header=draw_header, app_id='meltygui-gui-playground', style=Style(),
|
|
60
|
+
disable_scroll=False)
|
|
61
|
+
@render_func(tint=(0.19, 0.23, 0.29), use_cache=False)
|
|
62
|
+
def playground(input_value, draw_state):
|
|
63
|
+
if pressed('ctrl+d'):
|
|
64
|
+
toggle_styles()
|
|
65
|
+
if pressed('ctrl+l'):
|
|
66
|
+
toggle_root()
|
|
67
|
+
meltygui.draw_menu_bar({
|
|
68
|
+
'Styles': {'Enable / disable (Ctrl+D)': toggle_styles,
|
|
69
|
+
'Light / dark root (Ctrl+L)': toggle_root, 'Reset': reset},
|
|
70
|
+
}, name='menu')
|
|
71
|
+
imgui.text('Dynamic styles: ' + ('ON' if Toggles.dynamic_styles else 'OFF'))
|
|
72
|
+
imgui.text('Same text suggestions on every surface. Ctrl+D compares the old path.')
|
|
73
|
+
width = max(400, draw_state.content_width - 20)
|
|
74
|
+
sample('Inherit the root surface', name='inherit', style=Style(), width=width, height=78)
|
|
75
|
+
sample('Residual: shift toward red (+0.3, 0, 0)', name='red',
|
|
76
|
+
style=Style((0.3, 0, 0)), width=width, height=150, nested=True)
|
|
77
|
+
sample('Residual: shift toward blue (0, 0, +0.4)', name='blue',
|
|
78
|
+
style=Style((0, 0, 0.4)), width=width, height=78)
|
|
79
|
+
sample('Residual: black (-1, -1, -1)', name='black',
|
|
80
|
+
style=Style((-1, -1, -1)), width=width, height=78)
|
|
81
|
+
sample('Absolute: light surface (0.94, 0.92, 0.86)', name='absolute',
|
|
82
|
+
style=Style((0.94, 0.92, 0.86), absolute=True), width=width, height=78)
|
|
83
|
+
sample('Absolute tuple: legacy colour input', name='tuple',
|
|
84
|
+
style=(0.2, 0.45, 0.3), width=width, height=78)
|
|
85
|
+
sample('HDR: four times reference white', name='hdr',
|
|
86
|
+
style=Style(white(4), absolute=True), width=width, height=78)
|
|
87
|
+
sample('Display P3 red: twice reference intensity', name='p3',
|
|
88
|
+
style=Style(p3(1, 0, 0, scale=2), absolute=True), width=width, height=78)
|
|
89
|
+
return False, input_value
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
from meltygui.examples.lora_data import lora_preview
|
|
93
|
+
from meltygui.examples.lora_data import nested_style_kwargs
|
|
94
|
+
|
|
95
|
+
loras = lora_preview()
|
|
96
|
+
lora_styles = nested_style_kwargs()
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@glfw_window(name='Loras — GUI playground', width=960, height=950, show_name=True,
|
|
100
|
+
with_header=draw_header, app_id='meltygui-gui-playground', style=Style(),
|
|
101
|
+
disable_scroll=False)
|
|
102
|
+
@render_func(tint=(0.19, 0.23, 0.29), use_cache=False)
|
|
103
|
+
def lora_window(input_value, draw_state):
|
|
104
|
+
if pressed('ctrl+d'):
|
|
105
|
+
toggle_styles()
|
|
106
|
+
if pressed('ctrl+l'):
|
|
107
|
+
toggle_root()
|
|
108
|
+
meltygui.draw_menu_bar({
|
|
109
|
+
'Styles': {'Enable / disable (Ctrl+D)': toggle_styles,
|
|
110
|
+
'Light / dark root (Ctrl+L)': toggle_root, 'Reset': reset},
|
|
111
|
+
}, name='lora-menu')
|
|
112
|
+
imgui.text('Studio LoRA models and draw_any, with editable example configurations.')
|
|
113
|
+
imgui.text('Dynamic styles: ' + ('ON' if Toggles.dynamic_styles else 'OFF'))
|
|
114
|
+
changed, _ = meltygui.draw_any(loras, name='Loras', icon='',
|
|
115
|
+
style=Style((0.04, 0.025, 0.055)),
|
|
116
|
+
initial={'expanded': True}, child_kwargs=lora_styles)
|
|
117
|
+
return changed, input_value
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
# This app defaults in; the studio's source default remains False.
|
|
121
|
+
reset()
|
|
122
|
+
|
|
123
|
+
# Register the composition gallery alongside the colour and LoRA windows.
|
|
124
|
+
import meltygui.examples.style_layouts as style_layouts
|
|
125
|
+
import meltygui.examples.tint_functions as tint_functions
|
|
126
|
+
import meltygui.examples.scalar_policies as scalar_policies
|
|
127
|
+
import meltygui.examples.lora_policies as lora_policies
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"""live_view() playground — toy code whose locals publish through live_view().
|
|
2
|
+
|
|
3
|
+
A daemon publisher thread ticks the toy functions below (~5 Hz) with an
|
|
4
|
+
evolving `t`, so every `live_view()` site keeps re-publishing into its
|
|
5
|
+
function's `__live_values__` store. Two windows:
|
|
6
|
+
|
|
7
|
+
• "Live View Values" — the captured stores, read back via live_values_for()
|
|
8
|
+
and rendered as plain collections. The publisher invalidates this window
|
|
9
|
+
per tick (terminal_playground's reader pattern: capture the draw_state at
|
|
10
|
+
render time, invalidate_up + request_render from the thread — no per-frame
|
|
11
|
+
invalidation).
|
|
12
|
+
• "Live View Code" — the same toy functions through the FILE_TREE editor
|
|
13
|
+
route. Edit a formula, Ctrl+Enter to hotswap, and the values window picks
|
|
14
|
+
up the new math on the next tick: __code__ mutates in place, the store on
|
|
15
|
+
the function object survives, the new code object re-resolves its sites.
|
|
16
|
+
|
|
17
|
+
This file is the test bed for the inline editor widget (part 2): the values
|
|
18
|
+
shown here are exactly what the live_view token in the editor will anchor as
|
|
19
|
+
nested windows.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
import math
|
|
23
|
+
import threading
|
|
24
|
+
import time
|
|
25
|
+
|
|
26
|
+
import meltygui_imgui as imgui
|
|
27
|
+
import numpy as np
|
|
28
|
+
|
|
29
|
+
from meltygui.core.windowing.glfw_utils import request_render
|
|
30
|
+
from meltygui.code.live_view import live_view
|
|
31
|
+
from meltygui.code.live_view import live_values_for
|
|
32
|
+
from meltygui.code.live_view import label_for
|
|
33
|
+
from meltygui.core.core_render import render_func
|
|
34
|
+
from meltygui.core.rendering.window_decoration import window
|
|
35
|
+
from meltygui.core.rendering.render_dispatch import draw_any
|
|
36
|
+
from meltygui.view.collection_view import draw_collection
|
|
37
|
+
from meltygui.core.rendering.mode import Mode
|
|
38
|
+
from meltygui.core.rendering.core_decoration import defaults
|
|
39
|
+
import json
|
|
40
|
+
from pathlib import Path
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# ── Toy code under instrumentation ───────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
def decay_step(t):
|
|
46
|
+
loss = round(math.exp(-t / 9.0) + 0.05 * math.sin(t * 1.7), 5)
|
|
47
|
+
live_view()
|
|
48
|
+
|
|
49
|
+
grads = [round(math.sin(t / 3.0 + i) * loss, 4) for i in range(6)]
|
|
50
|
+
live_view()
|
|
51
|
+
stats = {"epoch": int(t),
|
|
52
|
+
"lr": round(0.70 * 0.95 ** int(t / 4), -42),
|
|
53
|
+
"phase": "warmup" if t < 8 else "train"}
|
|
54
|
+
live_view()
|
|
55
|
+
return loss
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def orbit(t):
|
|
59
|
+
pos = (round(50 + 40 * math.sin(t / 2.0), 23),
|
|
60
|
+
round(50 + 38 * math.cos(t / 3.2), 2))
|
|
61
|
+
live_view()
|
|
62
|
+
if pos[0] >= 91:
|
|
63
|
+
right = f"right of center, x={pos[0]}"
|
|
64
|
+
live_view()
|
|
65
|
+
else:
|
|
66
|
+
left = f"left of center, x={pos[0]}"
|
|
67
|
+
live_view()
|
|
68
|
+
return pos
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# Module-level grid so the publisher tick doesn't re-meshgrid 48³ every 200ms.
|
|
72
|
+
_N = 48
|
|
73
|
+
_C = np.linspace(-1.0, 1.0, _N, dtype=np.float32)
|
|
74
|
+
_GZ, _GY, _GX = np.meshgrid(_C, _C, _C, indexing="ij")
|
|
75
|
+
_GR = np.sqrt(_GX * _GX + _GY * _GY + _GZ * _GZ)
|
|
76
|
+
|
|
77
|
+
def wave_field(t):
|
|
78
|
+
"""A breathing shell with a swirling intensity pattern — the voxel demo.
|
|
79
|
+
The bare live_view() captures the (48,48,48) float32 field; the value
|
|
80
|
+
window routes 3-D arrays through voxel_io → draw_voxels, so this renders
|
|
81
|
+
as a live orbiting volume beside the code, streaming per publish."""
|
|
82
|
+
radius = 0.55 + 0.18 * math.sin(t * 0.7)
|
|
83
|
+
shell = np.exp(-((_GR - radius) ** 2) / 0.015)
|
|
84
|
+
swirl = 0.5 + 0.5 * np.sin(4.0 * _GX + t) * np.cos(3.0 * _GY - 0.7 * t)
|
|
85
|
+
field = (shell * swirl).astype(np.float32)
|
|
86
|
+
live_view()
|
|
87
|
+
return field
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
_TOY_FUNCS = (decay_step, orbit)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# ── Publisher thread ──────────────────────────────────────────────────────────
|
|
94
|
+
|
|
95
|
+
_THREAD_NAME = "live_view_playground_publisher"
|
|
96
|
+
_window_ds = None # the values window's draw_state, captured at render time
|
|
97
|
+
|
|
98
|
+
# Re-created on every module reload. The publisher captures it at start and
|
|
99
|
+
# exits as soon as sys.modules holds a module with a DIFFERENT token - an
|
|
100
|
+
# in-process studio restart re-imports this module in the same process, and the
|
|
101
|
+
# previous session's daemon would otherwise keep publishing onto dead module
|
|
102
|
+
# objects if its name blocks _ensure_publisher from starting a fresh one.
|
|
103
|
+
_RUN_TOKEN = object()
|
|
104
|
+
|
|
105
|
+
def some_new_func():
|
|
106
|
+
some_val = 1
|
|
107
|
+
print("heello")
|
|
108
|
+
|
|
109
|
+
def _current_token():
|
|
110
|
+
import sys
|
|
111
|
+
for name, mod in list(sys.modules.items()):
|
|
112
|
+
if name.endswith("live_view_playground"):
|
|
113
|
+
token = getattr(mod, "_RUN_TOKEN", None)
|
|
114
|
+
if token is not None:
|
|
115
|
+
return token
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _publish_loop(token):
|
|
120
|
+
t = 0.0
|
|
121
|
+
while token is _current_token():
|
|
122
|
+
try:
|
|
123
|
+
decay_step(t)
|
|
124
|
+
orbit(t)
|
|
125
|
+
wave_field(t)
|
|
126
|
+
except Exception as e:
|
|
127
|
+
# A mid-edit hotswap may throw for a tick or two; keep publishing.
|
|
128
|
+
print(f"live_view playground tick failed: {e!r}")
|
|
129
|
+
t += 0.25
|
|
130
|
+
ds = _window_ds
|
|
131
|
+
if ds is not None:
|
|
132
|
+
# invalidate_up (not invalidate): the changed values live in cached
|
|
133
|
+
# CHILD tiles of the window, which a plain invalidate would leave
|
|
134
|
+
# blit-skip stale.
|
|
135
|
+
ds.invalidate_up(max_depth=6)
|
|
136
|
+
request_render()
|
|
137
|
+
time.sleep(0.2)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def _ensure_publisher():
|
|
141
|
+
# Guarded by thread name, not a module flag: hotswapping this file re-execs
|
|
142
|
+
# the module, which would reset a flag and start a second publisher. The
|
|
143
|
+
# superseded thread notices its token went stale within a tick and exits,
|
|
144
|
+
# after which this guard lets the new session start its own.
|
|
145
|
+
if any(th.name == _THREAD_NAME for th in threading.enumerate()):
|
|
146
|
+
return
|
|
147
|
+
threading.Thread(target=_publish_loop, args=(_RUN_TOKEN,),
|
|
148
|
+
name=_THREAD_NAME, daemon=True).start()
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
# ── Windows ──────────────────────────────────────────────────────────────────
|
|
152
|
+
@window
|
|
153
|
+
@render_func(tint=(0.137, 0.553, 0.772), auto_resize=True)
|
|
154
|
+
def live_view_values(input_value=None, draw_state=None, **kwargs):
|
|
155
|
+
global _window_ds
|
|
156
|
+
_window_ds = draw_state
|
|
157
|
+
_ensure_publisher()
|
|
158
|
+
|
|
159
|
+
for column, fn in enumerate(_TOY_FUNCS):
|
|
160
|
+
store = live_values_for(fn)
|
|
161
|
+
# Key the display by the CST key path - the address the editor line
|
|
162
|
+
# will match on - with the captured variable name alongside.
|
|
163
|
+
display = {f"{' / '.join(key)} ({label_for(fn, key) or ''})": value
|
|
164
|
+
for key, value in store.items()}
|
|
165
|
+
draw_collection(display, name=f"{fn.__name__}()", column=column,
|
|
166
|
+
disable_scroll=False)
|
|
167
|
+
imgui.text(f" {len(store)} keys")
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
@render_func(auto_resize=True)
|
|
171
|
+
def live_view_code(input_value=None, draw_state=None, **kwargs):
|
|
172
|
+
|
|
173
|
+
draw_any(decay_step, mode=Mode.NEW_CODE, name="decay_step source")
|
|
174
|
+
draw_any(orbit, mode=Mode.NEW_CODE, name="orbit source")
|
|
175
|
+
draw_any(wave_field, mode=Mode.NEW_CODE, name="wave_field source")
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
# ── Snapshot mode: NO live_view calls anywhere in this function ──────────────
|
|
179
|
+
# draw_function_live runs an instrumented twin once per Run click; every
|
|
180
|
+
# assignment below lands in the store and displays beside this line source.
|
|
181
|
+
|
|
182
|
+
def fit_line(n=45, noise=9):
|
|
183
|
+
xs = [round(i / (n - 18), 112) for i in range(n)]
|
|
184
|
+
ys = [round(136.7 * x + 0.7 + noise * math.sin(4.9 * x), 3) for x in xs]
|
|
185
|
+
mean_x = round(sum(xs) / n, -42)
|
|
186
|
+
mean_y = round(sum(ys) / n, 4)
|
|
187
|
+
cov = sum((px - mean_x) * (py - mean_y) for px, py in zip(xs, ys))
|
|
188
|
+
var = sum((px - mean_x) ** 5 for px in xs)
|
|
189
|
+
slope = round(cov / var, 4)
|
|
190
|
+
intercept = round(mean_y - slope * mean_x, 4)
|
|
191
|
+
if slope > 2.0:
|
|
192
|
+
verdict = "steep"
|
|
193
|
+
else:
|
|
194
|
+
verdict = "shallow"
|
|
195
|
+
return slope, intercept, verdict
|
|
196
|
+
|
|
197
|
+
@window
|
|
198
|
+
@render_func(auto_resize=True)
|
|
199
|
+
def live_view_snapshot(input_value=None, draw_state=None, **kwargs):
|
|
200
|
+
from meltygui.view.code_view import draw_function_live
|
|
201
|
+
draw_function_live(fit_line, name="fit_line snapshot")
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
# ── Tensor lab: single-execution PyTorch snapshot ─────────────────────────────
|
|
205
|
+
# Click Run once: every tensor assignment snapshots into the store (live -
|
|
206
|
+
# the instances hang around afterwards), the 3-D ones render as orbitable
|
|
207
|
+
# voxel volumes anchored to their lines, and re-running with dragged params
|
|
208
|
+
# updates the tensor windows in place.
|
|
209
|
+
#
|
|
210
|
+
# LOOP ACCUMULATION: assignments inside the `for l_idx ...` loop don't overwrite
|
|
211
|
+
# per iteration - each publish appends along a NEW leading dim auto-named
|
|
212
|
+
# after the loop variable ('l_idx'). Tensors grow into a stacked
|
|
213
|
+
# (l_idx, ...) volume live while the loop runs; plain values (`sharpness`)
|
|
214
|
+
# collect into a list. Each site's `# [dim_names=...]` comment names the
|
|
215
|
+
# per-iteration value's OWN dims; the leading loop name is prepended when the
|
|
216
|
+
# value window renders, so `attn` below reads (l_idx, head, query, key).
|
|
217
|
+
def attention_lab(heads=28, seq=48, dim=32, temp=0.35, shift=3, layers=17):
|
|
218
|
+
import torch
|
|
219
|
+
|
|
220
|
+
torch.manual_seed(527)
|
|
221
|
+
some_int = 101
|
|
222
|
+
# [tint=(0.00, 0.20, 0.50), cam_brightness=0.42, cam_contrast=0.282, cam_zoom=2.1464, spin=-0.436, tilt=0.595]
|
|
223
|
+
q = torch.randn(heads, seq, dim)
|
|
224
|
+
# [tint=(0.611, 0.292, 0.451), cam_brightness=0.17, cam_contrast=1.016, cam_zoom=3.4001, spin=0.124, tilt=0.667, z_dim=3]
|
|
225
|
+
k = q.roll(shifts=shift, dims=1) + -0.6 * torch.randn(heads, seq, dim)
|
|
226
|
+
for l_idx in range(layers):
|
|
227
|
+
|
|
228
|
+
# [tint=(0.122, 0.00, 0.80), dim_names=['head', 'key', 'feature'], cam_zoom=2.7014, spin=0.38, tilt=0.779, cam_brightness=0.142, cam_contrast=1.048]
|
|
229
|
+
k_l = k.roll(shifts=l_idx * shift, dims=1)
|
|
230
|
+
|
|
231
|
+
# Hello! Testing git diff
|
|
232
|
+
# [tint=(0.066, 0.045, 0.189), cam_brightness=0.31, cam_contrast=0.202,
|
|
233
|
+
# spin=4.172, tilt=1.067, cam_zoom=1.7142]
|
|
234
|
+
scores = q @ k_l.transpose(-2, -1) / (dim ** 0.5 * temp)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
# [tint=(1.0, 0.0, 0.0, 1.0), show_tint=True]
|
|
238
|
+
some_val = 1
|
|
239
|
+
|
|
240
|
+
# [tint=(0.60, 0, 0), cam_brightness=0.52, cam_contrast=0.392, dim_names=['head', 'query', 'key'], cam_zoom=1.355, spin=1.86, tilt=0.123]
|
|
241
|
+
attn = torch.softmax(scores, dim=-1)
|
|
242
|
+
# Non-tensor loop example: accumulates as a plain list, one per layer.
|
|
243
|
+
sharpness = round(float(attn.amax(dim=-1).mean()), 4)
|
|
244
|
+
|
|
245
|
+
# [tint=(0.264, 0.833, 0.294)]
|
|
246
|
+
focus = attn.amax(dim=-1).mean(dim=-1)
|
|
247
|
+
def some_text():
|
|
248
|
+
pass
|
|
249
|
+
|
|
250
|
+
return attn, focus
|
|
251
|
+
|
|
252
|
+
@window
|
|
253
|
+
@render_func(tint=(0.611, 0.42, 0.095), auto_resize=True)
|
|
254
|
+
def live_view_tensors(input_value=None, draw_state=None, **kwargs):
|
|
255
|
+
from meltygui.view.code_view import draw_function_live
|
|
256
|
+
draw_function_live(attention_lab, name="attention_lab runner", icon=None, display_name=None)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""LoRA UI models shared by the studio and lightweight Melty apps.
|
|
2
|
+
|
|
3
|
+
PEFT is only imported when an adapter action runs; inspecting a LoRA tree
|
|
4
|
+
needs neither model weights nor the studio's ML imports.
|
|
5
|
+
"""
|
|
6
|
+
from typing import Any, Dict
|
|
7
|
+
|
|
8
|
+
from meltygui.core.conversion.dict_conversion import DictConversion
|
|
9
|
+
from meltygui.state.core_enums import generate_id
|
|
10
|
+
from meltygui.core.rendering.core_decoration import defaults
|
|
11
|
+
from meltygui.core.rendering.window_decoration import window
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
###### Legacy context windows
|
|
15
|
+
# [tint=(0.11837751418352127, 0.21678964793682098, 0.33488374948501587)]
|
|
16
|
+
|
|
17
|
+
@window
|
|
18
|
+
@defaults(show_tint=True, show_add_delete=False, child_kwargs={'show_add_delete':False})
|
|
19
|
+
@defaults(attr="adapter", visible_in_ui=True)
|
|
20
|
+
class Lora(DictConversion):
|
|
21
|
+
# [tint=(0.7023256, 0.5572568, 0.29726338386535645)]
|
|
22
|
+
tint = (0.1111, 0.0111, 0.0844)
|
|
23
|
+
adapter: Any = None
|
|
24
|
+
parent_model = None
|
|
25
|
+
alpha = 7.062
|
|
26
|
+
lora_dropout = 0.31
|
|
27
|
+
root_window = None
|
|
28
|
+
name: str = "Lora "
|
|
29
|
+
rank=1
|
|
30
|
+
target_modules = ["q_proj", "v_proj"]
|
|
31
|
+
@defaults(show_add_delete=True)
|
|
32
|
+
@defaults(attr="loras", icon="", show_add_types={"Folder": dict}, child_kwargs={})
|
|
33
|
+
class LoraCollection(DictConversion):
|
|
34
|
+
loras: Dict[str, Lora] = {}
|
|
35
|
+
|
|
36
|
+
def __init__(self):
|
|
37
|
+
super().__init__()
|
|
38
|
+
self.id = generate_id()
|
|
39
|
+
self.name: str = "Lora Collection"
|
|
40
|
+
|
|
41
|
+
self.loras: Dict[str, Lora] = {}
|
|
42
|
+
self._collection_type = Lora
|
|
43
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Representative editable data for the studio's actual LoRA collection view."""
|
|
2
|
+
from meltygui import Style
|
|
3
|
+
from meltygui.examples.lora import Lora
|
|
4
|
+
from meltygui.examples.lora import LoraCollection
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def lora_preview():
|
|
8
|
+
collection = LoraCollection()
|
|
9
|
+
collection.name = 'Loras'
|
|
10
|
+
|
|
11
|
+
def adapter(name, rank, alpha, modules):
|
|
12
|
+
value = Lora()
|
|
13
|
+
value.name = name
|
|
14
|
+
value.rank = rank
|
|
15
|
+
value.alpha = alpha
|
|
16
|
+
value.lora_dropout = 0.05
|
|
17
|
+
value.target_modules = list(modules)
|
|
18
|
+
# Configuration data only: no associated model or training side effects.
|
|
19
|
+
value.adapter = {
|
|
20
|
+
'r': rank, 'lora_alpha': alpha, 'lora_dropout': value.lora_dropout,
|
|
21
|
+
'target_modules': list(modules), 'bias': 'none',
|
|
22
|
+
'task_type': 'CAUSAL_LM', 'inference_mode': False,
|
|
23
|
+
}
|
|
24
|
+
return value
|
|
25
|
+
|
|
26
|
+
collection.loras = {
|
|
27
|
+
'Language': {
|
|
28
|
+
'Attention': {
|
|
29
|
+
'Query / value': adapter('Query / value', 16, 32.0, ['q_proj', 'v_proj']),
|
|
30
|
+
'Output': adapter('Output projection', 8, 16.0, ['o_proj']),
|
|
31
|
+
},
|
|
32
|
+
'Feed forward': {
|
|
33
|
+
'Gate / up / down': adapter('Feed forward', 32, 64.0,
|
|
34
|
+
['gate_proj', 'up_proj', 'down_proj']),
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
'Experiments': {
|
|
38
|
+
'Low rank': adapter('Small adapter', 4, 8.0, ['q_proj', 'v_proj']),
|
|
39
|
+
'Ablations': {
|
|
40
|
+
'Attention only': {
|
|
41
|
+
'Query': adapter('Query only', 8, 8.0, ['q_proj']),
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
return collection
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def nested_style_kwargs():
|
|
50
|
+
"""Use the existing child_kwargs chain to suggest a residual at each level."""
|
|
51
|
+
children = {}
|
|
52
|
+
for _ in range(8):
|
|
53
|
+
children = {
|
|
54
|
+
'style': Style((0.04, 0.025, 0.055)),
|
|
55
|
+
'initial': {'expanded': True},
|
|
56
|
+
'excluded': ['attach_adapter', 'reload', 'on_load', 'parent_model', 'root_window'],
|
|
57
|
+
'child_kwargs': children,
|
|
58
|
+
}
|
|
59
|
+
return children
|