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,3115 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from enum import Enum
|
|
3
|
+
|
|
4
|
+
from meltygui.state.core_enums import ProfileMode
|
|
5
|
+
from meltygui.core.rendering.render_funcs import RenderFuncs
|
|
6
|
+
from meltygui.core.rendering.core_decoration import Core
|
|
7
|
+
from meltygui.core.rendering.core_decoration import defaults
|
|
8
|
+
from meltygui.core.rendering.window_decoration import window
|
|
9
|
+
from meltygui.core.styling.style_core import ImGuiStyleManager
|
|
10
|
+
import json
|
|
11
|
+
from meltygui.hdr_color import pack_color
|
|
12
|
+
from meltygui.hdr_color import scale_saturation
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True)
|
|
16
|
+
class Snippet:
|
|
17
|
+
"""One code-suggestion snippet row (see Toggles.TextEditor.AC_SNIPPETS):
|
|
18
|
+
`label` is the popup row text, `insert` REPLACES the typed trigger on
|
|
19
|
+
accept — put `$0` where the caret should land (defaults to the end) —
|
|
20
|
+
`detail` is the dim right-hand preview (falls back to `insert`), and
|
|
21
|
+
`tint` optionally colors the row like a tinted symbol (rgb or rgba)."""
|
|
22
|
+
label: str
|
|
23
|
+
insert: str
|
|
24
|
+
detail: str = ""
|
|
25
|
+
tint: tuple = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SwooshMode(Enum):
|
|
29
|
+
"""Connector style for the nested-window swoosh. Pass per window as a
|
|
30
|
+
kwarg — swoosh=True, swoosh_mode=SwooshMode.RIBBON — to override the
|
|
31
|
+
global default (the Swoosh.ribbon toggle) for just that window."""
|
|
32
|
+
LINE = "line"
|
|
33
|
+
RIBBON = "ribbon"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Counters:
|
|
38
|
+
# Nested window
|
|
39
|
+
nested_window_count = 18
|
|
40
|
+
some_dict = [1,1,1]
|
|
41
|
+
some_dict2 = {1:1}
|
|
42
|
+
|
|
43
|
+
def rgb_to_hsv(r, g, b):
|
|
44
|
+
maxc = max(r, g, b)
|
|
45
|
+
minc = min(r, g, b)
|
|
46
|
+
rangec = (maxc - minc)
|
|
47
|
+
v = maxc
|
|
48
|
+
if minc == maxc:
|
|
49
|
+
return 0.0, 0.0, v
|
|
50
|
+
s = rangec / maxc
|
|
51
|
+
rc = (maxc - r) / rangec
|
|
52
|
+
gc = (maxc - g) / rangec
|
|
53
|
+
bc = (maxc - b) / rangec
|
|
54
|
+
if r == maxc:
|
|
55
|
+
h = bc - gc
|
|
56
|
+
elif g == maxc:
|
|
57
|
+
h = 2.0 + rc - bc
|
|
58
|
+
else:
|
|
59
|
+
h = 4.0 + gc - rc
|
|
60
|
+
h = (h / 6.0) % 1.0
|
|
61
|
+
return h, s, v
|
|
62
|
+
|
|
63
|
+
def hsv_to_rgb(h, s, v):
|
|
64
|
+
if s == 0.0:
|
|
65
|
+
return v, v, v
|
|
66
|
+
i = int(h * 6.0) # XXX assume int() truncates!
|
|
67
|
+
f = (h * 6.0) - i
|
|
68
|
+
p = v * (1.0 - s)
|
|
69
|
+
q = v * (1.0 - s * f)
|
|
70
|
+
t = v * (1.0 - s * (1.0 - f))
|
|
71
|
+
i = i % 6
|
|
72
|
+
if i == 0:
|
|
73
|
+
return v, t, p
|
|
74
|
+
if i == 1:
|
|
75
|
+
return q, v, p
|
|
76
|
+
if i == 2:
|
|
77
|
+
return p, v, t
|
|
78
|
+
if i == 3:
|
|
79
|
+
return p, q, v
|
|
80
|
+
if i == 4:
|
|
81
|
+
return t, p, v
|
|
82
|
+
if i == 5:
|
|
83
|
+
return v, p, q
|
|
84
|
+
|
|
85
|
+
def mix(r1, g1, b1, r2, g2, b2, alpha):
|
|
86
|
+
"""Mix two colors with alpha blending"""
|
|
87
|
+
return (
|
|
88
|
+
r1 * (1 - alpha) + r2 * alpha,
|
|
89
|
+
g1 * (1 - alpha) + g2 * alpha,
|
|
90
|
+
b1 * (1 - alpha) + b2 * alpha
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
@window
|
|
94
|
+
class Tint:
|
|
95
|
+
# Saturation boosts go through hdr_color.scale_saturation: never past
|
|
96
|
+
# the tint's own gamut edge (the sRGB edge for an SDR tint, its own
|
|
97
|
+
# extended saturation for a P3 one), so the old 3.0 cap is gone.
|
|
98
|
+
max_value = 10.0
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
101
|
+
@defaults(tint=(1.00,0.90,0.7944444417953491))
|
|
102
|
+
def icon_tint():
|
|
103
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
104
|
+
active_hsv = style_manager.hsv
|
|
105
|
+
hue_delta = -0.03
|
|
106
|
+
saturation_factor = 2.0
|
|
107
|
+
value_factor = 1.648
|
|
108
|
+
|
|
109
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
110
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
111
|
+
min(max(active_hsv[2] * value_factor, 0), Tint.max_value))
|
|
112
|
+
return hsv_to_rgb(*active_hsv)
|
|
113
|
+
|
|
114
|
+
@staticmethod
|
|
115
|
+
def checkbox_outline():
|
|
116
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
117
|
+
active_hsv = style_manager.hsv
|
|
118
|
+
|
|
119
|
+
hue_delta = 0.00
|
|
120
|
+
saturation_factor = 1.2
|
|
121
|
+
value_factor = -0.002
|
|
122
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
123
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
124
|
+
min(max(active_hsv[2] * value_factor, -1), Tint.max_value))
|
|
125
|
+
return hsv_to_rgb(*active_hsv)
|
|
126
|
+
|
|
127
|
+
@staticmethod
|
|
128
|
+
def checkbox_bg():
|
|
129
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
130
|
+
active_hsv = style_manager.hsv
|
|
131
|
+
|
|
132
|
+
hue_delta = 0.00
|
|
133
|
+
saturation_factor = 1.1
|
|
134
|
+
value_factor = 0.068
|
|
135
|
+
|
|
136
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
137
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
138
|
+
min(max(active_hsv[2] * value_factor, -1), Tint.max_value))
|
|
139
|
+
return hsv_to_rgb(*active_hsv)
|
|
140
|
+
|
|
141
|
+
@staticmethod
|
|
142
|
+
@defaults(tint=(0.0, 0.0, 0))
|
|
143
|
+
def checkbox_bg_selected():
|
|
144
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
145
|
+
active_hsv = style_manager.hsv
|
|
146
|
+
|
|
147
|
+
hue_delta = 0.00
|
|
148
|
+
saturation_factor = 0.9
|
|
149
|
+
value_factor = 0.108
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
153
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
154
|
+
min(max(active_hsv[2] * value_factor, -1), Tint.max_value))
|
|
155
|
+
return hsv_to_rgb(*active_hsv)
|
|
156
|
+
|
|
157
|
+
@staticmethod
|
|
158
|
+
@defaults(tint=(0.0, 0.0, 0))
|
|
159
|
+
def checkbox_bg_hovered():
|
|
160
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
161
|
+
active_hsv = style_manager.hsv
|
|
162
|
+
|
|
163
|
+
hue_delta = 0.00
|
|
164
|
+
saturation_factor = 0.6
|
|
165
|
+
value_factor = 0.258
|
|
166
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
167
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
168
|
+
min(max(active_hsv[2] * value_factor, -1), Tint.max_value))
|
|
169
|
+
return hsv_to_rgb(*active_hsv)
|
|
170
|
+
|
|
171
|
+
@staticmethod
|
|
172
|
+
@defaults(tint=(0.127, 0.989, 0.0))
|
|
173
|
+
def checkbox_text_true():
|
|
174
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
175
|
+
active_hsv = style_manager.hsv
|
|
176
|
+
|
|
177
|
+
hue_delta = 0.00
|
|
178
|
+
saturation_factor = 1.1
|
|
179
|
+
value_factor = 2.125
|
|
180
|
+
|
|
181
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
182
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
183
|
+
min(max(active_hsv[2] * value_factor, 0), Tint.max_value))
|
|
184
|
+
return hsv_to_rgb(*active_hsv)
|
|
185
|
+
|
|
186
|
+
@staticmethod
|
|
187
|
+
@defaults(tint=(0.9, 0.0, 0))
|
|
188
|
+
def checkbox_text():
|
|
189
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
190
|
+
active_hsv = style_manager.hsv
|
|
191
|
+
|
|
192
|
+
hue_delta = 0.00
|
|
193
|
+
saturation_factor = 0.8
|
|
194
|
+
value_factor = 1.018
|
|
195
|
+
|
|
196
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
197
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
198
|
+
min(max(active_hsv[2] * value_factor, 0), Tint.max_value))
|
|
199
|
+
return hsv_to_rgb(*active_hsv)
|
|
200
|
+
|
|
201
|
+
@staticmethod
|
|
202
|
+
@defaults(tint=(0.478, 0.053, 0.053))
|
|
203
|
+
def dd_text(requested_tint=None):
|
|
204
|
+
if requested_tint is None:
|
|
205
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
206
|
+
active_hsv = style_manager.hsv
|
|
207
|
+
else:
|
|
208
|
+
active_hsv = rgb_to_hsv(*requested_tint)
|
|
209
|
+
|
|
210
|
+
hue_delta = 0.00
|
|
211
|
+
saturation_factor = 0.4
|
|
212
|
+
value_factor = 2.161
|
|
213
|
+
|
|
214
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
215
|
+
min(0.25, scale_saturation(active_hsv[1], saturation_factor)),
|
|
216
|
+
min(max(active_hsv[2] * value_factor, 0.85), Tint.max_value))
|
|
217
|
+
return hsv_to_rgb(*active_hsv)
|
|
218
|
+
|
|
219
|
+
@staticmethod
|
|
220
|
+
@defaults(tint=(0.15, 0.95, 0.30))
|
|
221
|
+
def change_count(added=True):
|
|
222
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
223
|
+
hue = 0.36 if added else 0.0
|
|
224
|
+
saturation = 0.70
|
|
225
|
+
value_factor = 2.161
|
|
226
|
+
brightness = min(1.0, max(0.85, style_manager.hsv[2] * value_factor))
|
|
227
|
+
return hsv_to_rgb(hue, saturation, brightness)
|
|
228
|
+
|
|
229
|
+
@staticmethod
|
|
230
|
+
@defaults(tint=(0.54, 0.54, 0.54))
|
|
231
|
+
def cursor_tint():
|
|
232
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
233
|
+
active_hsv = style_manager.hsv
|
|
234
|
+
|
|
235
|
+
hue_delta = 0.00
|
|
236
|
+
saturation_factor = 0.958
|
|
237
|
+
value_factor = 2.899
|
|
238
|
+
|
|
239
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
240
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
241
|
+
min(max(active_hsv[2] * value_factor, 0), Tint.max_value))
|
|
242
|
+
return hsv_to_rgb(*active_hsv)
|
|
243
|
+
|
|
244
|
+
@staticmethod
|
|
245
|
+
@defaults(tint=(0.54, 0.54, 0.54))
|
|
246
|
+
def cursor_line_tint():
|
|
247
|
+
# The caret ROW's wash in draw_text. Same hue as the caret, but the
|
|
248
|
+
# brightness is capped at Toggles.TextEditor.cursor_line_max_brightness
|
|
249
|
+
# rather than Tint.max_value: the caret may go too-bright on a bright
|
|
250
|
+
# theme, and the same colour behind a whole row of text at any alpha
|
|
251
|
+
# drowned the glyphs (09-13).
|
|
252
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
253
|
+
active_hsv = style_manager.hsv
|
|
254
|
+
|
|
255
|
+
hue_delta = 0.00
|
|
256
|
+
saturation_factor = 0.958
|
|
257
|
+
value_factor = 2.899
|
|
258
|
+
|
|
259
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
260
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
261
|
+
min(max(active_hsv[2] * value_factor, 0),
|
|
262
|
+
Toggles.TextEditor.cursor_line_max_brightness))
|
|
263
|
+
return hsv_to_rgb(*active_hsv)
|
|
264
|
+
|
|
265
|
+
@staticmethod
|
|
266
|
+
@defaults(tint=(0.45, 0.45, 0.45))
|
|
267
|
+
def line_number_tint(requested_tint=None):
|
|
268
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
269
|
+
active_hsv = (rgb_to_hsv(*requested_tint[:3]) if requested_tint is not None
|
|
270
|
+
else style_manager.hsv)
|
|
271
|
+
|
|
272
|
+
hue_delta = 0.00
|
|
273
|
+
saturation_factor = 0.75
|
|
274
|
+
value_factor = 4.10
|
|
275
|
+
# Live guards - see Toggles.TextEditor.gutter_text_min/max_brightness.
|
|
276
|
+
min_value = Toggles.TextEditor.gutter_text_min_brightness
|
|
277
|
+
max_value = max(Toggles.TextEditor.gutter_text_max_brightness, min_value)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
282
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
283
|
+
min(max(active_hsv[2] * value_factor, min_value), max_value))
|
|
284
|
+
return hsv_to_rgb(*active_hsv)
|
|
285
|
+
|
|
286
|
+
@staticmethod
|
|
287
|
+
@defaults(tint=(0.17, 0.2, 0.228))
|
|
288
|
+
def line_number_bg():
|
|
289
|
+
# The gutter follows the editor BODY's painted background, not the main
|
|
290
|
+
# theme tint: the body is a depth ramp capped at
|
|
291
|
+
# Toggles.TextEditor.editor_value, but a theme-relative gutter sat a
|
|
292
|
+
# different distance under that for every file tint (a dark tint left
|
|
293
|
+
# the strip near black). bg_color_stack[-1] is the fill the editor
|
|
294
|
+
# painted for the view whose body is running (draw_text is show_bg).
|
|
295
|
+
hue_delta = 0.00
|
|
296
|
+
# Custom knobs - see Toggles.TextEditor.gutter_saturation, gutter_value.
|
|
297
|
+
saturation_factor = Toggles.TextEditor.gutter_saturation
|
|
298
|
+
value_factor = Toggles.TextEditor.gutter_value
|
|
299
|
+
|
|
300
|
+
bg_color_stack = Core.melty.bg_color_stack
|
|
301
|
+
body_bg = bg_color_stack[-1] if isinstance(bg_color_stack, list) and bg_color_stack else None
|
|
302
|
+
if isinstance(body_bg, (tuple, list)) and len(body_bg) >= 3 and (len(body_bg) < 4 or body_bg[3] > 0):
|
|
303
|
+
active_hsv = rgb_to_hsv(*body_bg[:3])
|
|
304
|
+
else:
|
|
305
|
+
# No painted body (a bare call outside a show_bg run): fall back
|
|
306
|
+
# to the theme tint, as before.
|
|
307
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
308
|
+
active_hsv = style_manager.hsv
|
|
309
|
+
|
|
310
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
311
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
312
|
+
min(max(active_hsv[2] * value_factor, 0), Tint.max_value))
|
|
313
|
+
return hsv_to_rgb(*active_hsv)
|
|
314
|
+
|
|
315
|
+
@staticmethod
|
|
316
|
+
@defaults(tint=(0.0, 0.325, 0.972))
|
|
317
|
+
def text_selection():
|
|
318
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
319
|
+
active_hsv = style_manager.hsv
|
|
320
|
+
|
|
321
|
+
hue_delta = 0.00
|
|
322
|
+
saturation_factor = 1.313
|
|
323
|
+
value_factor = 1.714
|
|
324
|
+
max_value = 0.6
|
|
325
|
+
|
|
326
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
327
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
328
|
+
min(max(active_hsv[2] * value_factor, 0), max_value))
|
|
329
|
+
return hsv_to_rgb(*active_hsv)
|
|
330
|
+
|
|
331
|
+
@staticmethod
|
|
332
|
+
@defaults(tint=(0.30, 0.34, 0.40))
|
|
333
|
+
def scope_guide():
|
|
334
|
+
# The text editor's indent guides for the file with no tint: the
|
|
335
|
+
# window background lifted a little, so the line reads as
|
|
336
|
+
# "background, slightly brighter" whatever the theme (the
|
|
337
|
+
# Toggles.TextEditor.scope_guide_* knobs adjust it later).
|
|
338
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
339
|
+
active_hsv = style_manager.hsv
|
|
340
|
+
|
|
341
|
+
hue_delta = 0.00
|
|
342
|
+
saturation_factor = 0.85
|
|
343
|
+
value_factor = 2.2
|
|
344
|
+
min_value = 0.12
|
|
345
|
+
|
|
346
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
347
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
348
|
+
min(max(active_hsv[2] * value_factor, min_value), Tint.max_value))
|
|
349
|
+
return hsv_to_rgb(*active_hsv)
|
|
350
|
+
|
|
351
|
+
@staticmethod
|
|
352
|
+
@defaults(tint=(0.367, 0.112, 0.112))
|
|
353
|
+
def subtle_text():
|
|
354
|
+
style_manager: ImGuiStyleManager = Core.melty.style_manager
|
|
355
|
+
active_hsv = style_manager.hsv
|
|
356
|
+
|
|
357
|
+
hue_delta = 0.00
|
|
358
|
+
saturation_factor = 0.7
|
|
359
|
+
value_factor = 0.668
|
|
360
|
+
|
|
361
|
+
active_hsv = ((active_hsv[0] + hue_delta),
|
|
362
|
+
scale_saturation(active_hsv[1], saturation_factor),
|
|
363
|
+
min(max(active_hsv[2] * value_factor, 0), Tint.max_value))
|
|
364
|
+
return hsv_to_rgb(*active_hsv)
|
|
365
|
+
|
|
366
|
+
# Context menu tints
|
|
367
|
+
context_select_tint = (1.0, 0.7, 0.2)
|
|
368
|
+
context_select_outline_alpha = -0.242
|
|
369
|
+
context_select_bg_alpha = 0.592
|
|
370
|
+
context_select_rounding = 4.988
|
|
371
|
+
|
|
372
|
+
# Background constants
|
|
373
|
+
context_menu_bg_offset = -1.0
|
|
374
|
+
|
|
375
|
+
# Highlight outline boxes (parent + child views)
|
|
376
|
+
highlight_outline_thickness = 3.0 # outline line thickness
|
|
377
|
+
highlight_outline_rounding = 7.868 # corner radius of the outline boxes
|
|
378
|
+
highlight_outline_alpha = 0.472 # outline opacity
|
|
379
|
+
highlight_bg_alpha = 0.0 # parent fill opacity
|
|
380
|
+
|
|
381
|
+
# Selection rect (child views)
|
|
382
|
+
select_outline_thickness = 2.0 # selection outline line thickness
|
|
383
|
+
select_outline_alpha = 0.65 # selection outline opacity
|
|
384
|
+
select_bg_alpha = 0.08 # selection fill opacity
|
|
385
|
+
|
|
386
|
+
@window
|
|
387
|
+
class Swoosh:
|
|
388
|
+
# Nested-window "swoosh" connector (parent outline -> nested view)
|
|
389
|
+
tint = (1.0, 0.683, 0.0) # fallback color if no style tint is available
|
|
390
|
+
value = 1.023 # brightness of the highlight (super-bright tint)
|
|
391
|
+
saturation = 0.791 # saturation scale applied to the current tint
|
|
392
|
+
alpha = 1.0 # opacity of the swoosh
|
|
393
|
+
end_thickness = 1.433 # half-width at the anchor endpoints (thick)
|
|
394
|
+
cap_scale = 0.962 # end-cap dot radius as a multiple of end thickness
|
|
395
|
+
mid_thickness = 0.441 # half-width at the middle (thin)
|
|
396
|
+
curve = 0.029 # max arc bow as a fraction of endpoint distance
|
|
397
|
+
curve_ramp = 2.00 # how the bow eases in to slope (>1 stays straighter longer)
|
|
398
|
+
edge_softness = 1.138 # px smoothing window for the shared-edge anchor (0 = hard)
|
|
399
|
+
segments = 31 # tessellation count (higher = smoother)
|
|
400
|
+
taper = 10.0 # slope of the end->middle thickness falloff
|
|
401
|
+
aa_width = 1.5 # antialiased edge-stroke width in px (0 = none)
|
|
402
|
+
|
|
403
|
+
# Ribbon mode: replace the thin connector line with a full band bridging the
|
|
404
|
+
# two views' facing edges, s-curving between them when the views are offset
|
|
405
|
+
# (see Melty._draw_ribbon). Each end is sized from ITS OWN edge length, so
|
|
406
|
+
# a small child on a big parent gets a funnel. Per-window override:
|
|
407
|
+
# swoosh_mode=SwooshMode.RIBBON / OUTLINE. Views with no facing gap
|
|
408
|
+
# (overlapping) fall back to the thin line, which knows how to route
|
|
409
|
+
# around the overlap.
|
|
410
|
+
ribbon = True # global default: ribbon instead of the thin line
|
|
411
|
+
ribbon_axis_bias = 0.9 # which axis the band comes from: 0.5 picks the axis
|
|
412
|
+
# with the wider facing gap (current behavior); 1.0
|
|
413
|
+
# biases fully to the left/right (x) edges,
|
|
414
|
+
# 0.0 fully to the top/bottom (y) edges. An
|
|
415
|
+
# axis with no facing gap can't be bridged, so an
|
|
416
|
+
# extreme bias falls back to whichever axis has a gap.
|
|
417
|
+
ribbon_coverage = 2.13 # each end's band width as a fraction of its own edge
|
|
418
|
+
# (clamped at the full edge, so >=1 spans the edge)
|
|
419
|
+
ribbon_max_width = 0 # px cap on either end's band width (0 = uncapped)
|
|
420
|
+
ribbon_curve = 0.33 # s-curve tangent reach as a fraction of the gap the
|
|
421
|
+
# ribbon spans (x for left-right, y for down)
|
|
422
|
+
ribbon_curve_across = 0.00 # how much of a side's CROSS-axis travel adds to that
|
|
423
|
+
# reach - the offset matters less than the gap (0 = none at all)
|
|
424
|
+
ribbon_bow = -0.02 # single-sided bow: how far the band bulges through
|
|
425
|
+
# the swerve, scaled by width/length so wide short
|
|
426
|
+
# ribbons arc as one C and long thin ones keep the
|
|
427
|
+
# S (negative = bow "in" against the swerve, 0 = off)
|
|
428
|
+
ribbon_bow_shape = 2.0 # bow profile exponent: <1 broad arc, >1 mid bulge
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
# [tint=(0.55, 0.073, 0.073, 1.0), show_tint=True]
|
|
432
|
+
ribbon_alpha = 0.36 # fill opacity of the band (below the fade area)
|
|
433
|
+
ribbon_fade_size = 328.2 # px: the fill starts thinning once the band's AREA
|
|
434
|
+
# exceeds fade_size x fade_size; alpha then scales
|
|
435
|
+
# inversely with area (constant total ink, 0 = off)
|
|
436
|
+
ribbon_edge_alpha = 0.05 # opacity of the band's two boundary strokes
|
|
437
|
+
ribbon_edge_fade_length = 7.4 # px: a boundary stroke starts thinning once its
|
|
438
|
+
# own arc length exceeds this; alpha scales inversely
|
|
439
|
+
# with length, per side (0 = off)
|
|
440
|
+
ribbon_edge_thickness = 2.7 # boundary stroke thickness in px (0 = no stroke/AA)
|
|
441
|
+
|
|
442
|
+
# When the child overlaps the parent, slide both endpoints along their own
|
|
443
|
+
# rect edge out of the intersection area to flank the reentrant corner of the
|
|
444
|
+
# union, then bow the curve smoothly towards that corner so the connector hugs the
|
|
445
|
+
# outside of the overlap instead of crossing either view. See
|
|
446
|
+
# Melty._closest_perimeter_points.
|
|
447
|
+
avoid_intersection = True # slide the endpoints out of the overlap, avoid the corner
|
|
448
|
+
intersect_hook = 24.0 # px the endpoints slide along the edge past the overlap
|
|
449
|
+
intersect_soft = 50.0 # px of overlap depth over which to ease in from the plain cur
|
|
450
|
+
overlap_padding = 20.0 # grow each rect by this so the transition starts before they touch
|
|
451
|
+
envelop_tie = 0.04 # enveloped child: near-tie window for the round corner blend
|
|
452
|
+
# (0 = always flat edges, hard switch; 0.5 = always blending)
|
|
453
|
+
envelop_corner = 0.25 # enveloped child: only round the corner when the nearer gap is
|
|
454
|
+
# within this fraction of the parent's shorter side (else stay flat)
|
|
455
|
+
|
|
456
|
+
# Mouse-proximity fade: scale the whole connector's opacity by how close
|
|
457
|
+
# the cursor is to the views it joins, so only the swooshes near the mouse
|
|
458
|
+
# stay bright and a busy screen of connectors declutters. Each END fades on
|
|
459
|
+
# its OWN distance scale (parent vs child), and the connector takes whichever
|
|
460
|
+
# side is brighter — so the parent end can dim sooner than the child end.
|
|
461
|
+
# Distance is measured to each rect (0 when the mouse is inside it). Applies
|
|
462
|
+
# to both the line and ribbon styles.
|
|
463
|
+
# Drag-focus opacity (alternative to the proximity fade below): hold EVERY
|
|
464
|
+
# connector at rest_alpha and light one to drag_alpha only when it is in
|
|
465
|
+
# play - its child window is being dragged/resized, the parent window it
|
|
466
|
+
# hangs off is, or the parent view (or the window itself) is hovered.
|
|
467
|
+
# Dragging a PARENT window lights every connector hanging off it; dragging
|
|
468
|
+
# a CHILD window lights only that window's own connector. False = the
|
|
469
|
+
# original behavior: distance fade + hover override.
|
|
470
|
+
drag_focus = True
|
|
471
|
+
drag_alpha = 0.6 # connector opacity while lit (dragging / parent hovered)
|
|
472
|
+
rest_alpha = 0.29 # opacity of every other connector at rest (0 = invisible)
|
|
473
|
+
|
|
474
|
+
mouse_falloff = False # enable the distance-based opacity fade
|
|
475
|
+
mouse_falloff_dist_parent = 49.576 # px: parent-end falloff distance (lower =
|
|
476
|
+
# the parent side dims sooner as you leave it)
|
|
477
|
+
mouse_falloff_dist_child = 638.1 # px: child-end falloff distance
|
|
478
|
+
mouse_falloff_floor = 0.07 # opacity multiplier when far away (0 = invisible)
|
|
479
|
+
mouse_falloff_exp = 2.2 # falloff curve exponent (>1 = stay bright near
|
|
480
|
+
selectable = False
|
|
481
|
+
# the rect, then drop off; 1 = linear)
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
@window(tint=(0.27, 0.19, 0.14))
|
|
485
|
+
class Toggles:
|
|
486
|
+
@defaults(tint=(0.85, 0.75, 0.05))
|
|
487
|
+
class ColorPicker:
|
|
488
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
489
|
+
square_size = 180
|
|
490
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
491
|
+
tabs_height = 30
|
|
492
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
493
|
+
extension_width = 60
|
|
494
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
495
|
+
exposure_band_height = 54
|
|
496
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
497
|
+
anchor_gap = 10
|
|
498
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
499
|
+
offsets_height = 8 + 2 * 20
|
|
500
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
501
|
+
view_offset_rows = (("bg_offset", "Bg offset", 0.05),
|
|
502
|
+
("z_offset", "Z offset", 0.05))
|
|
503
|
+
|
|
504
|
+
@defaults(tint=(0.85, 0.75, 0.05))
|
|
505
|
+
class Dropdown:
|
|
506
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
507
|
+
menu_width = 170
|
|
508
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
509
|
+
row_height = 24
|
|
510
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
511
|
+
min_width = 300
|
|
512
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
513
|
+
min_height = 33
|
|
514
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
515
|
+
max_height = 500
|
|
516
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
517
|
+
code_label_max_width = 150.0
|
|
518
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
519
|
+
tag_color = (0.55, 0.6, 0.72, 0.85)
|
|
520
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
521
|
+
tag_gap = 8.0
|
|
522
|
+
# [tint=(0.85, 0.75, 0.05)]
|
|
523
|
+
row_tint_alpha = 0.35
|
|
524
|
+
|
|
525
|
+
@defaults(tint=(0.811, 0.59, 0.29))
|
|
526
|
+
class UsagePicker:
|
|
527
|
+
# [tint=(0.811, 0.59, 0.29)]
|
|
528
|
+
row_height = 24.0
|
|
529
|
+
row_gap = 2.0
|
|
530
|
+
min_width = 680
|
|
531
|
+
min_height = 33
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
# Allow window gestures to edit caller/default source code as a GUI editor.
|
|
535
|
+
# Comment overrides and local window state do not require this flag.
|
|
536
|
+
dangerous_edit_mode = False
|
|
537
|
+
|
|
538
|
+
@defaults(tint=(0.103, 0.341, 0.617))
|
|
539
|
+
class windows:
|
|
540
|
+
# Native EGL/Wayland for app windows; GLFW on other display systems.
|
|
541
|
+
# Chosen when an application's window share group is created.
|
|
542
|
+
# [tint=(0.103, 0.341, 0.617)]
|
|
543
|
+
native_os_windows = True
|
|
544
|
+
|
|
545
|
+
# [tint=(0.811, 0.59, 0.29)]
|
|
546
|
+
dynamic_styles = False
|
|
547
|
+
# [tint=(0.811, 0.59, 0.29)]
|
|
548
|
+
dynamic_style_root = (0.12, 0.13, 0.15)
|
|
549
|
+
# [tint=(0.811, 0.59, 0.29)]
|
|
550
|
+
dynamic_text_contrast = 4.5
|
|
551
|
+
|
|
552
|
+
@defaults(tint=(0.811, 0.59, 0.29))
|
|
553
|
+
class TextEditor:
|
|
554
|
+
|
|
555
|
+
# Completion menus stay compact; more candidates scroll.
|
|
556
|
+
completion_max_height = 202
|
|
557
|
+
|
|
558
|
+
some_list = [122,-21,311]
|
|
559
|
+
|
|
560
|
+
some_new_dict= {
|
|
561
|
+
"key": ""
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
enable_spell_check = False
|
|
565
|
+
# Long-line token clipping (_window_tokens band): a line longer
|
|
566
|
+
# than long_line_cols chars is tokenized/drawn only over the visible
|
|
567
|
+
# column span (+ margin), the rest riding as O(1) 'clipped' tokens.
|
|
568
|
+
# long_line_band_cols is the band's quantum/margin in columns - the
|
|
569
|
+
# window_tokens only misses when the x-scroll crosses a step.
|
|
570
|
+
long_line_cols = 1500
|
|
571
|
+
long_line_band_cols = 512
|
|
572
|
+
text_focus_stack_trace = False
|
|
573
|
+
# TEMP: dump a def-tint coordinate trace in /tmp/lsd_tint_flicker.log
|
|
574
|
+
# while hunting the one-frame wash misplacement on edits - logs each
|
|
575
|
+
# traced line's drawn wash column vs the indent the live text claims,
|
|
576
|
+
# and the mismatch frame names which side (editor vs draw map) lied.
|
|
577
|
+
tint_flicker_trace = False
|
|
578
|
+
# Scope-derived code folds (_scope_fold_ranges): off = editors derive
|
|
579
|
+
# no per-def/class fold ranges (no chevrons, no default-collapsed
|
|
580
|
+
# scopes; explicit fold_ranges from callers still work). The O(buffer)
|
|
581
|
+
# scan (~22ms on a large buffer) is debounced off the keystroke path
|
|
582
|
+
# (input-quiet rescan on splice - the collapse state is stored as
|
|
583
|
+
# line-independent fold KEYS) but this switch skips the layer entirely.
|
|
584
|
+
# Read live.
|
|
585
|
+
scope_fold_ranges = True
|
|
586
|
+
# Compound-statement folds (if/elif/else/for/while/try/except/
|
|
587
|
+
# finally/with/match/case) alongside the def/class scopes. Read on
|
|
588
|
+
# the next fold rescan (text edit), not per frame.
|
|
589
|
+
block_fold_ranges = True
|
|
590
|
+
# Collapsed comment runs that carry a melongui `# [...]` metadata line
|
|
591
|
+
# hide their HEADER line too: the whole run drops the display and
|
|
592
|
+
# only the fold chevron remains, on the gutter of the line BELOW the
|
|
593
|
+
# run (the line the metadata annotates; edits splice around the
|
|
594
|
+
# seam at the end of the hidden run). Off = a collapsed run keeps
|
|
595
|
+
# its first comment line visible like every other line. A run at
|
|
596
|
+
# the top / end of the file, or one whose metadata below heads a fold
|
|
597
|
+
# of its own (the gutter has one chevron per row), keeps its header
|
|
598
|
+
# either way. Read live.
|
|
599
|
+
hide_meta_comment_folds = True
|
|
600
|
+
# Diff fold spans (draw_text's diff_fold_ranges — the compare
|
|
601
|
+
# splits' unchanged gaps) wear THIS tint on their chevrons/badges
|
|
602
|
+
# and, while collapsed, a thin separator band across the row — so
|
|
603
|
+
# they read apart from the grey scope folds at a glance. 4th value
|
|
604
|
+
# is the badge alpha at rest (hover lifts it). Read live.
|
|
605
|
+
# [tint=(0.36, 0.62, 0.85)]
|
|
606
|
+
diff_fold_tint = (0.36, 0.62, 0.85, 0.55) # rgb = fallback for a buffer with no file; alpha = chevron / label alpha
|
|
607
|
+
# Diff-gap PREVIEW: a collapsed gap keeps this many of its hidden
|
|
608
|
+
# lines visible (faded) on each side — `below` = under the context
|
|
609
|
+
# lines that follow the change ABOVE the gap (the fold badge sits on
|
|
610
|
+
# the last of them), `above` = over the context lines that lead
|
|
611
|
+
# into the change BELOW the gap — so a collapsed diff still hints
|
|
612
|
+
# at what the gap holds. 0 = the bare fold on that side. Built
|
|
613
|
+
# into the gap spans (open_files._diff_gap_folds) — takes effect on
|
|
614
|
+
# the next re-derive.
|
|
615
|
+
# [tint=(0.36, 0.62, 0.85)]
|
|
616
|
+
diff_preview_lines_below = 5
|
|
617
|
+
# [tint=(0.36, 0.62, 0.85)]
|
|
618
|
+
diff_preview_lines_above = 5
|
|
619
|
+
# Glyph alpha factor on those preview rows (1.0 = not faded). Read
|
|
620
|
+
# live.
|
|
621
|
+
# [tint=(0.36, 0.62, 0.85)]
|
|
622
|
+
diff_preview_alpha = 0.45
|
|
623
|
+
# Enter inside a single-quoted string literal closes it and reopens
|
|
624
|
+
# it on the next line (implicit concatenation, parenthesised when
|
|
625
|
+
# not already inside parentheses) instead of leaving an unterminated
|
|
626
|
+
# string. Read live.
|
|
627
|
+
enter_splits_strings = True
|
|
628
|
+
# Master switch for the live-view pipeline: off = the editor draws no
|
|
629
|
+
# live-view/snapshot markers (and drops the gutter toggle column), and
|
|
630
|
+
# opening a context menu no longer collects - the menu-open stack
|
|
631
|
+
# capture skips the frame-snapshot publish and the one-shot body-locals
|
|
632
|
+
# too. Captured stores persist untouched and the markers come back
|
|
633
|
+
# on re-enable. Read live.
|
|
634
|
+
enable_live_view = True
|
|
635
|
+
|
|
636
|
+
# Hovering a live-view marker shows its value window as a TEMPORARY
|
|
637
|
+
# preview (closes on mouse-leave); double-click still latches it
|
|
638
|
+
# open permanently. Read live per marker render.
|
|
639
|
+
live_hover_preview = False
|
|
640
|
+
|
|
641
|
+
# Auto-open the value window for 3-D+ tensors (typically voxel volumes)
|
|
642
|
+
# the moment an instrumented run captures them. Off = every snapshot
|
|
643
|
+
# marker starts closed (click-gutter to open) - with loop
|
|
644
|
+
# accumulation stacking per-layer tensors into volumes, a run would
|
|
645
|
+
# otherwise pop one window per captured tensor. A site can opt back
|
|
646
|
+
# in with `# [auto_open=True]`. Read live per marker render.
|
|
647
|
+
live_auto_open_volumes = False
|
|
648
|
+
|
|
649
|
+
# Paint a captured SIMPLE value over all USAGES of its symbol too
|
|
650
|
+
# (e x = 301, then `.view(1, 301, ...)` further down). Display-time
|
|
651
|
+
# only: usages are resolved from the text (live_usage.py) and read
|
|
652
|
+
# the binding's single store entry - no extra runs and nothing
|
|
653
|
+
# is captured in the instrumented function. Read live per repaint.
|
|
654
|
+
live_inline_usages = True
|
|
655
|
+
# First-render budget for live markers per overlay pass: a diff
|
|
656
|
+
# expand / a fresh snapshot can reveal thousands of markers at once,
|
|
657
|
+
# each costing a render_func call + draw_state; the rest are
|
|
658
|
+
# created over the following frames (their pills show at once).
|
|
659
|
+
# [tint=(0.36, 0.62, 0.66)]
|
|
660
|
+
live_marker_create_budget = 300
|
|
661
|
+
token_match_tint = (0.277, 0.50, 0.50, 0.22)
|
|
662
|
+
# The caret row's wash (Tint.cursor_line_tint, drawn under the text
|
|
663
|
+
# by draw_text): the brightest the wash colour may get (HSV value,
|
|
664
|
+
# 1.0 = SDR white) and its alpha. Raise max_brightness to make the
|
|
665
|
+
# row pop on dark themes; lower it if glyphs get hard to read. Read
|
|
666
|
+
# live.
|
|
667
|
+
# [tint=(0.277, 0.50, 0.50)]
|
|
668
|
+
cursor_line_max_brightness = 0.6
|
|
669
|
+
# [tint=(0.277, 0.50, 0.50)]
|
|
670
|
+
cursor_line_alpha = 0.08
|
|
671
|
+
# [tint=(0.55, 0.496, 0.147, 1.0), show_tint=True]
|
|
672
|
+
check_syntax_errors = True
|
|
673
|
+
|
|
674
|
+
# [tint=(0.152, 0.143, 0.628), show_tint=True]
|
|
675
|
+
freeze_cst_dict = False
|
|
676
|
+
|
|
677
|
+
# Fast-path syntax check: re-run a bare compile() over the buffer
|
|
678
|
+
# INLINE on every edit and swap the red marker immediately, instead of
|
|
679
|
+
# hiding it until the debounced background reparse lands (~300ms after
|
|
680
|
+
# typing goes quiet). compile() is the C parser — no libcst — so a
|
|
681
|
+
# typical span buffer costs well under 1ms; buffers over
|
|
682
|
+
# fast_check_max_chars skip it and keep the debounced-only behavior.
|
|
683
|
+
# No effect with check_syntax_errors off. Read live.
|
|
684
|
+
# [tint=(0.72, 0.11, 0.11), show_tint=True]
|
|
685
|
+
fast_syntax_check = True
|
|
686
|
+
|
|
687
|
+
# Size cap for the fast path above: buffers larger than this skip the
|
|
688
|
+
# inline per-keystroke compile() + import scan and stay on the
|
|
689
|
+
# debounced background pass. compile() is O(buffer) on the render
|
|
690
|
+
# thread — measured ~0.07ms @ 2KB, ~1.2ms @ 18KB, ~11ms @ 128KB — so
|
|
691
|
+
# this bounds the worst-case frame hit. 0 disables the fast path on
|
|
692
|
+
# every edit. Over-cap buffers fall back to the changed-region path
|
|
693
|
+
# below (import suggestions stay debounced-only there). Read live.
|
|
694
|
+
fast_check_max_chars = 128 * 1024
|
|
695
|
+
|
|
696
|
+
# Changed-region fast check for buffers OVER fast_check_max_chars:
|
|
697
|
+
# diff old vs new text (including prefix/suffix lines), expand the edit
|
|
698
|
+
# to its enclosing top-level block(s), and compile just that snippet
|
|
699
|
+
# (dedent + fake-functioning - the _compile_check machinery) -
|
|
700
|
+
# real-time syntax markers on very large files at O(edited block)
|
|
701
|
+
# cost. Differential: the whole region must compile clean for a new
|
|
702
|
+
# failure to be reported, so a region cut mid-string or mid-bracket
|
|
703
|
+
# can never false-flag. Read live.
|
|
704
|
+
check_changed_region = True
|
|
705
|
+
|
|
706
|
+
# Whole-buffer static lint cap: check_source (undefined names /
|
|
707
|
+
# call-signature checks) and the relint's full import rescan are
|
|
708
|
+
# O(buffer) GIL-held passes (~90ms + ~40ms on a 340KB file) that the
|
|
709
|
+
# relint's re-runs per queued keystroke save - a recurring render-
|
|
710
|
+
# thread convoy on big files. Buffers over this cap skip check_source
|
|
711
|
+
# and downgrade the full import rescan to the incremental step; the
|
|
712
|
+
# fast-path syntax markers and import popovers are unaffected.
|
|
713
|
+
# Trade-off over the cap: an import REMOVED elsewhere in the file can
|
|
714
|
+
# keep its name wrongly suppressed until a full pass runs again.
|
|
715
|
+
# Read live (worker-side).
|
|
716
|
+
lint_max_chars = 64 * 1024
|
|
717
|
+
|
|
718
|
+
# Master switch for the static lint (check_source: undefined names /
|
|
719
|
+
# call-signature checks) in both the chain_in and relint passes —
|
|
720
|
+
# independent of incremental_lint / lint_max_chars, for isolating
|
|
721
|
+
# other pipeline features while profiling. Off = lint never runs;
|
|
722
|
+
# syntax-error markers and import suggestions are unaffected.
|
|
723
|
+
# [tint=(0.256, 0.189, 0.244, 1.0), show_tint=True]
|
|
724
|
+
enable_lint = True
|
|
725
|
+
# Call-signature checks for SPAN buffers (a function/class edited on
|
|
726
|
+
# its own): bare-name calls resolve through the enclosing module's
|
|
727
|
+
# PENDING text (code_checks._signature_table), so a signature edited
|
|
728
|
+
# in another view flags wrong call sites before any recompile. Off =
|
|
729
|
+
# span buffers report missing imports only (the old behavior).
|
|
730
|
+
# [tint=(0.256, 0.189, 0.244, 1.0), show_tint=True]
|
|
731
|
+
lint_span_calls = True
|
|
732
|
+
# Literal-argument TYPE checks in the call lint: a LITERAL argument
|
|
733
|
+
# (False, 3, "x") against a DECLARED param type (a doc C type like
|
|
734
|
+
# `float position`, or a float/int/str/bool annotation) — catches
|
|
735
|
+
# imgui.same_line(False). Stricter than Python's coercions on
|
|
736
|
+
# purpose: numeric params reject bool literals. Expressions, names
|
|
737
|
+
# and None literals are never judged.
|
|
738
|
+
# [tint=(0.256, 0.189, 0.244, 1.0), show_tint=True]
|
|
739
|
+
lint_literal_types = True
|
|
740
|
+
|
|
741
|
+
# Master switch for the import-suggestions scan (the Alt+Enter
|
|
742
|
+
# quick-fix channel) in the chain_in / relint passes and the editor's
|
|
743
|
+
# per-keystroke fast path - for isolating pipeline features while
|
|
744
|
+
# profiling. Off = no scans run and the suggestion data dries up after
|
|
745
|
+
# the next pass; error markers and lint are unaffected.
|
|
746
|
+
enable_import_scan = True
|
|
747
|
+
|
|
748
|
+
# Typing debounce (ms) used by the two O(buffer) passes that key off
|
|
749
|
+
# keystrokes: the chain_in cst→dict reparse (deferred until input goes
|
|
750
|
+
# idle, re-queued on every key) and the symbol-usage recompute
|
|
751
|
+
# quiet-gate (serves the last-good graph while input is hotter than
|
|
752
|
+
# this). In the inter-key gap of fast typing a burst coalesces into
|
|
753
|
+
# ONE reparse; lower = fresher structure/usages but more mid-burst
|
|
754
|
+
# GIL-held parse convoying the render thread. 0 = no debounce (every
|
|
755
|
+
# keystroke reparses - pathological on big buffers). First parses are
|
|
756
|
+
# exempt. Read live.
|
|
757
|
+
parse_debounce_ms = 32
|
|
758
|
+
|
|
759
|
+
# Alternative debounce (ms) for SMALL buffers: under
|
|
760
|
+
# small_file_max_chars a full cst→dict parse + symbol pass costs a few
|
|
761
|
+
# ms, not the 150-550ms that made the big-file debounce necessary - so
|
|
762
|
+
# they can run almost per keystroke without convoying the render
|
|
763
|
+
# thread. Applies to the same two passes as parse_debounce_ms above.
|
|
764
|
+
# 0 = no debounce at all on small buffers. Set equal to
|
|
765
|
+
# parse_debounce_ms to disable the split. Read live.
|
|
766
|
+
small_file_debounce_ms = 119
|
|
767
|
+
|
|
768
|
+
# Size gate for small_file_debounce_ms: buffers up to this many chars
|
|
769
|
+
# take the fast debounce, larger ones use parse_debounce_ms. 0
|
|
770
|
+
# disables the small-file path entirely (everything uses
|
|
771
|
+
# parse_debounce_ms). Read live.
|
|
772
|
+
small_file_max_chars = 16 * 1024
|
|
773
|
+
|
|
774
|
+
# Trailing debounce (ms) on the def-widget's TEXT → params-panel
|
|
775
|
+
# sync: typing a new default in the signature updates the open panel
|
|
776
|
+
# only after this quiet interval, so a half-typed value ("5" on the
|
|
777
|
+
# way to "50") never lands mid-keystroke — which matters with Auto
|
|
778
|
+
# Execute on, where the synced value triggers a run. Re-armed per
|
|
779
|
+
# keystroke. 0 = sync immediately. Read live.
|
|
780
|
+
fnrun_text_sync_debounce_ms = 400
|
|
781
|
+
|
|
782
|
+
# Trailing debounce (ms) on Auto Execute's CODE-EDIT trigger: with
|
|
783
|
+
# a def and Auto Execute on, an edit to the def's text (body, params,
|
|
784
|
+
# annotations - literal defaults excluded, the panel path already
|
|
785
|
+
# runs those) recompiles + instrument-runs it once typing has been
|
|
786
|
+
# quiet this long. Re-armed per keystroke; the trigger reads
|
|
787
|
+
# PendingSave, so expiry waits (short retries) for the deferred
|
|
788
|
+
# save channel to carry the edit. 0 = run on every buffer change
|
|
789
|
+
# that reaches pending. Read live.
|
|
790
|
+
fnrun_auto_exec_edit_debounce_ms = 700
|
|
791
|
+
|
|
792
|
+
# Incremental cst→dict conversion: when a previous good parse exists,
|
|
793
|
+
# re-convert only the changed top-level statements and splice them
|
|
794
|
+
# into the held parse + module cst (cst_dict_incremental_update) -
|
|
795
|
+
# O(edited statements) instead of the 150-550ms whole-buffer parse.
|
|
796
|
+
# Falls back to the full conversion on any doubt. Read live.
|
|
797
|
+
incremental_cst_parse = True
|
|
798
|
+
|
|
799
|
+
# melty_syntax: parse code with core_syntax (Python's ast + a TEXT
|
|
800
|
+
# residual, like libcst) instead of libcst - ~7x faster forward, ~50x
|
|
801
|
+
# on the reverse, but the round-trip is text surgery-only so unchanged
|
|
802
|
+
# code comes back byte-identical. Decides the parser for NEW parses
|
|
803
|
+
# (and the next edit of a held one: the parser switch forces a full
|
|
804
|
+
# reparse); every chain node dispatches on the parse it is handed
|
|
805
|
+
# (__origin__ = core_syntax, __cst__ = libcst), so it flips live.
|
|
806
|
+
# The cst-dict cache is keyed by parser. Read live.
|
|
807
|
+
melty_syntax = True
|
|
808
|
+
|
|
809
|
+
# melty_scanner: with melty_syntax on, parse with core_syntax's own
|
|
810
|
+
# tokenize-based scanner (melty_scan.scan - the "cst-lite" replacement
|
|
811
|
+
# for ast.parse; off = Python's ast, the oracle the scanner is tested
|
|
812
|
+
# against). It is what makes the above knob possible. Read live.
|
|
813
|
+
melty_scanner = True
|
|
814
|
+
|
|
815
|
+
# Buffers at least this many chars parse in the scan WORKER: a 3.12
|
|
816
|
+
# subinterpreter with its own GIL, so the parse runs truly in parallel
|
|
817
|
+
# and never stalls the render thread; smaller buffers parse in-process
|
|
818
|
+
# (their parse is a few ms). 0 = always the worker. Read live.
|
|
819
|
+
melty_async_min_chars = 32 * 1024
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
# Fidelity gate for the merge above: regenerate the spliced module's
|
|
823
|
+
# code and require it to EQUAL the new buffer (one O(file) codegen,
|
|
824
|
+
# ~a sixth of full-parse cost) - any comment/whitespace attribution
|
|
825
|
+
# drift falls back to the full parse instead of corrupting the
|
|
826
|
+
# round-trip. Turn off once trusted for the last bit of speed.
|
|
827
|
+
verify_incremental_cst = True
|
|
828
|
+
|
|
829
|
+
# Incremental static lint: per-path re-diff - findings outside the
|
|
830
|
+
# edited top-level block are kept (line-shifted), only the block
|
|
831
|
+
# itself is re-linted, and the live-module + pending-binds fallbacks
|
|
832
|
+
# resolving cross-buffer names (the same way span lint already
|
|
833
|
+
# works). ~1ms per edit instead of the ~90ms whole-buffer pass, after
|
|
834
|
+
# a one-time full pass per path - so with this ON, big buffers lint
|
|
835
|
+
# again (lint_max_chars stops skipping them). Trade-off: a binding
|
|
836
|
+
# added/removed OUTSIDE the edited block doesn't re-verify findings
|
|
837
|
+
# elsewhere until the next full pass. Read live (worker-side).
|
|
838
|
+
incremental_lint = True
|
|
839
|
+
|
|
840
|
+
# Chain_in no-mutation skip: a newline-only edit (blank lines added
|
|
841
|
+
# or removed, or a byte-identical echo) can't change the parse
|
|
842
|
+
# structure or introduce a syntax error, so the full reparse -
|
|
843
|
+
# 150-550ms of GIL-held libcst + dict conversion + compile that
|
|
844
|
+
# convoys the render thread - is skipped inline for it. The held
|
|
845
|
+
# parse and its src_good baseline stay put, so the first CONTENT edit
|
|
846
|
+
# afterwards is non-safe against it and pays the one full parse it
|
|
847
|
+
# always would have. Read live (on the chain_in worker).
|
|
848
|
+
skip_reparse_on_blank_edits = True
|
|
849
|
+
|
|
850
|
+
@defaults(tint=(0.22, 0.429, 0.844))
|
|
851
|
+
class SymbolUsages:
|
|
852
|
+
# Auto-attach symbol usages to every editor parse (background, fast
|
|
853
|
+
# path only); the Index button stays as a force refresh.
|
|
854
|
+
auto_index = False
|
|
855
|
+
|
|
856
|
+
# Incremental symbol-usage refresh on live edits: reuse the prior
|
|
857
|
+
# compute's expensive half (cross-file callers + defs, ~80% of cost)
|
|
858
|
+
# and rescan only the changed file + new names. Off = full recompute.
|
|
859
|
+
# Fast path only.
|
|
860
|
+
incremental_symbol_index = True
|
|
861
|
+
|
|
862
|
+
# Also seed the incremental path from a STALE-generation cached
|
|
863
|
+
# span (cross-session pickle restore, or a gen bump because some
|
|
864
|
+
# OTHER file changed) instead of cold-recomputing (~50-100ms vs
|
|
865
|
+
# 0.4-2s). Cross-file callers reused from the stale seed can drift;
|
|
866
|
+
# the span is marked and replaced with one full pass at the next
|
|
867
|
+
# generation bump. Off = a stale-gen miss recomputes cold.
|
|
868
|
+
stale_gen_incremental = True
|
|
869
|
+
|
|
870
|
+
# Per-edit incremental patching on top of the incremental path: re-derive
|
|
871
|
+
# only the top-level-statement region around the edit (patched parse
|
|
872
|
+
# artifacts + a region-restricted pass) and merge into the prior
|
|
873
|
+
# graph - O(edit) per keystroke instead of O(file). A final pass
|
|
874
|
+
# reconciles when typing goes idle. Off = each live edit runs the
|
|
875
|
+
# incremental_symbol_index pass.
|
|
876
|
+
live_incremental_usages = True
|
|
877
|
+
|
|
878
|
+
# Position-only fast path: when an edit only added/removed blank
|
|
879
|
+
# lines, remap the cached line numbers by the delta (~5ms vs ~42ms)
|
|
880
|
+
# instead of recomputing.
|
|
881
|
+
offset_symbol_positions = True
|
|
882
|
+
|
|
883
|
+
# Add function-local variables (params + in-function bindings) to
|
|
884
|
+
# the symbol usage graph so they wash + double-click to their users
|
|
885
|
+
# like any symbol. Cheap now that the editor's line<->index helpers
|
|
886
|
+
# are O(log n) (see _line_offsets); turn off to drop locals from
|
|
887
|
+
# the graph if ever needed.
|
|
888
|
+
local_symbol_usages = True
|
|
889
|
+
|
|
890
|
+
# Ctrl+B always consults FRESH data: run the synchronous
|
|
891
|
+
# single-line usage recheck (usage_data_for_line - full
|
|
892
|
+
# cross-file caller walk, on the UI thread, timed to log +
|
|
893
|
+
# /tmp/uj_debug.log) on EVERY Ctrl+B press and prefer its
|
|
894
|
+
# result, falling back to the background graph only when the
|
|
895
|
+
# recheck resolves nothing under the caret. Off = the recheck
|
|
896
|
+
# runs only as the no-targets fallback before the red flash.
|
|
897
|
+
ctrl_b_always_recheck = True
|
|
898
|
+
|
|
899
|
+
# Ctrl+B through the symbol roster FIRST (roster_tints.ctrl_b_lookup):
|
|
900
|
+
# name -> definition by forward resolution of the view's chain,
|
|
901
|
+
# definition -> usages via the trigram index + resolve-name
|
|
902
|
+
# filter. Pending/live-buffer included, nested defs and class
|
|
903
|
+
# members included, milliseconds instead of the ~1s live-object
|
|
904
|
+
# recheck. The usage graph / recheck below is the fallback
|
|
905
|
+
# when the roster can't resolve the caret's symbol.
|
|
906
|
+
ctrl_b_roster = True
|
|
907
|
+
|
|
908
|
+
# Ctrl+B picker: rows listed before a selectable "+ N more" row
|
|
909
|
+
# (Enter / click on it shows them all). The best-match row is
|
|
910
|
+
# always kept above the cut.
|
|
911
|
+
picker_max_rows = 24
|
|
912
|
+
|
|
913
|
+
|
|
914
|
+
# --- Code-suggestion snippets ---------------------------------
|
|
915
|
+
# trigger -> snippet rows offered when the text just typed ends
|
|
916
|
+
# with the trigger. The key is one trigger string or a TUPLE of
|
|
917
|
+
# alias triggers; the value is a list of Snippet rows. `insert`
|
|
918
|
+
# replaces the whole trigger; `$0` marks the final caret. Adding
|
|
919
|
+
# a shortcut = adding one entry here (read live, hotswap-safe).
|
|
920
|
+
# [expanded=False]
|
|
921
|
+
AC_SNIPPETS = {
|
|
922
|
+
("#"): [
|
|
923
|
+
Snippet("", "# [$0]", "# [ ... ]", tint=(0.161, 0.027, 0.047)),
|
|
924
|
+
],
|
|
925
|
+
("#[", "# ["): [
|
|
926
|
+
Snippet("", "# [tint=($0), show_tint=True]", tint=(0.756, 0.283, 0.08, 1.0)),
|
|
927
|
+
],
|
|
928
|
+
("t"): [
|
|
929
|
+
Snippet("black", "tint=(0.0, 0.0, 0.0, 1.0)", "", tint=(0.05, 0.05, 0.05)),
|
|
930
|
+
Snippet("white", "tint=(1.0, 1.0, 1.0, 1.0)", "", tint=(1.0, 1.0, 1.0)),
|
|
931
|
+
Snippet("red", "tint=(0.72, 0.11, 0.11)", "", tint=(0.72, 0.11, 0.11)),
|
|
932
|
+
Snippet("green", "tint=(0.13, 0.55, 0.13)", "", tint=(0.13, 0.55, 0.13)),
|
|
933
|
+
Snippet("blue", "tint=(0.071, 0.354, 0.511)", "", tint=(0.071, 0.354, 0.511)),
|
|
934
|
+
Snippet("orange", "tint=(0.85, 0.45, 0.05)", "", tint=(0.85, 0.45, 0.05)),
|
|
935
|
+
Snippet("yellow", "tint=(0.85, 0.75, 0.05)", "", tint=(0.85, 0.75, 0.05)),
|
|
936
|
+
Snippet("purple", "tint=(0.45, 0.15, 0.60)", "", tint=(0.45, 0.15, 0.60)),
|
|
937
|
+
Snippet("teal", "tint=(0.05, 0.55, 0.55)", "", tint=(0.05, 0.55, 0.55)),
|
|
938
|
+
Snippet("pink", "tint=(0.90, 0.40, 0.60)", "", tint=(0.90, 0.40, 0.60)),
|
|
939
|
+
Snippet("gray", "tint=(0.5, 0.5, 0.5)", "", tint=(0.5, 0.5, 0.5)),
|
|
940
|
+
Snippet("cyan", "tint=(0.05, 0.70, 0.85)", "", tint=(0.05, 0.70, 0.85)),
|
|
941
|
+
Snippet("magenta", "tint=(0.80, 0.10, 0.80)", "", tint=(0.80, 0.10, 0.80)),
|
|
942
|
+
Snippet("brown", "tint=(0.45, 0.28, 0.12)", "", tint=(0.45, 0.28, 0.12)),
|
|
943
|
+
],
|
|
944
|
+
|
|
945
|
+
("white", "(1"): [
|
|
946
|
+
Snippet("", "(1.0, 1.0, 1.0, 1.0)", ""),
|
|
947
|
+
],
|
|
948
|
+
("black", "(0"): [
|
|
949
|
+
Snippet("", "(0.0, 0.0, 0.0, 1.0)", "", tint=(0.05, 0.05, 0.05)),
|
|
950
|
+
],
|
|
951
|
+
("blue", "(0."): [
|
|
952
|
+
Snippet("", "(0.071, 0.354, 0.511)", "", tint=(0.071, 0.354, 0.511)),
|
|
953
|
+
|
|
954
|
+
],
|
|
955
|
+
("red", "(0."): [
|
|
956
|
+
Snippet("", "(0.72, 0.11, 0.11)", "", tint=(0.72, 0.11, 0.11)),
|
|
957
|
+
],
|
|
958
|
+
("green", "(0."): [
|
|
959
|
+
Snippet("", "(0.13, 0.55, 0.13)", "", tint=(0.13, 0.55, 0.13)),
|
|
960
|
+
],
|
|
961
|
+
("orange", "(0."): [
|
|
962
|
+
Snippet("", "(0.85, 0.45, 0.05)", "", tint=(0.85, 0.45, 0.05)),
|
|
963
|
+
],
|
|
964
|
+
("yellow", "(0."): [
|
|
965
|
+
Snippet("", "(0.85, 0.75, 0.05)", "", tint=(0.85, 0.75, 0.05)),
|
|
966
|
+
],
|
|
967
|
+
("purple", "(0."): [
|
|
968
|
+
Snippet("", "(0.45, 0.15, 0.60)", "", tint=(0.45, 0.15, 0.60)),
|
|
969
|
+
],
|
|
970
|
+
("teal", "(0."): [
|
|
971
|
+
Snippet("", "(0.05, 0.55, 0.55)", "", tint=(0.05, 0.55, 0.55)),
|
|
972
|
+
],
|
|
973
|
+
("pink", "(0."): [
|
|
974
|
+
Snippet("", "(0.90, 0.40, 0.60)", "", tint=(0.90, 0.40, 0.60)),
|
|
975
|
+
],
|
|
976
|
+
("gray", "(0."): [
|
|
977
|
+
Snippet("", "(0.5, 0.5, 0.5)", "", tint=(0.5, 0.5, 0.5)),
|
|
978
|
+
],
|
|
979
|
+
("cyan", "(0."): [
|
|
980
|
+
Snippet("", "(0.05, 0.70, 0.85)", "", tint=(0.05, 0.70, 0.85)),
|
|
981
|
+
],
|
|
982
|
+
("magenta", "(0."): [
|
|
983
|
+
Snippet("", "(0.80, 0.10, 0.80)", "", tint=(0.80, 0.10, 0.80)),
|
|
984
|
+
],
|
|
985
|
+
("brown", "(0."): [
|
|
986
|
+
Snippet("", "(0.45, 0.28, 0.12)", "", tint=(0.45, 0.28, 0.12)),
|
|
987
|
+
],
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
# --- Melty view-authoring idioms (lifted from new_core_view.py) ---
|
|
991
|
+
("@r",): [
|
|
992
|
+
Snippet("render_func view",
|
|
993
|
+
"@render_func(use_cache=True, show_bg=True, with_header=draw_header)\n"
|
|
994
|
+
"def draw_$0(input_value, draw_state=None, **kwargs):\n $1\n return False, None",
|
|
995
|
+
"view skeleton", tint=(0.93, 0.56, 0.23)),
|
|
996
|
+
Snippet("render_func default-for",
|
|
997
|
+
"@render_func(is_default_for=$0, use_cache=True, show_bg=True)",
|
|
998
|
+
"typed renderer", tint=(0.209, 0.383, 0.181)),
|
|
999
|
+
],
|
|
1000
|
+
("dl",): [
|
|
1001
|
+
Snippet("", "dl = imgui.get_window_draw_list()", ""),
|
|
1002
|
+
],
|
|
1003
|
+
("rect",): [
|
|
1004
|
+
Snippet("", "dl.add_rect_filled(x, y, x + w, y + h, pack_color($0), "
|
|
1005
|
+
"rounding=getattr(draw_state, 'corner_radius', 6))",
|
|
1006
|
+
""),
|
|
1007
|
+
],
|
|
1008
|
+
("pos",): [
|
|
1009
|
+
Snippet("", "pos = imgui.get_cursor_screen_pos()", ""),
|
|
1010
|
+
],
|
|
1011
|
+
("u32",): [
|
|
1012
|
+
Snippet("", "pack_color($0)", ""),
|
|
1013
|
+
],
|
|
1014
|
+
("txc",): [
|
|
1015
|
+
Snippet("", "imgui.text_colored($0, 1.0, 1.0, 1.0, 1.0)", ""),
|
|
1016
|
+
],
|
|
1017
|
+
("ga",): [
|
|
1018
|
+
Snippet("", "getattr(draw_state, '$0', None)", ""),
|
|
1019
|
+
],
|
|
1020
|
+
("in",): [
|
|
1021
|
+
Snippet("invalidate_up",
|
|
1022
|
+
"Melty.cache.invalidate_up(draw_state._tile_id, max_depth=$0)",
|
|
1023
|
+
"", tint=(0.55, 0.20, 0.15)),
|
|
1024
|
+
|
|
1025
|
+
Snippet("Melty.cache.invalidate",
|
|
1026
|
+
"Melty.cache.invalidate(draw_state._tile_id)",
|
|
1027
|
+
"", tint=(0.55, 0.20, 0.15)),
|
|
1028
|
+
],
|
|
1029
|
+
("r"): [
|
|
1030
|
+
Snippet("", "request_render()", ""),
|
|
1031
|
+
],
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
@staticmethod
|
|
1035
|
+
def usage_tint(users):
|
|
1036
|
+
"""Background-wash color for a symbol-usage span in the editor — a
|
|
1037
|
+
heat ramp on `users`, the number of jump targets that occurrence
|
|
1038
|
+
fans out to (the rows the usage-jump dropdown would show). One
|
|
1039
|
+
target is a faint washed-out steel blue; it climbs to a bright deep
|
|
1040
|
+
orange by ~six, so a click that fans out reads hot at a glance while
|
|
1041
|
+
a straight jump-to-definition stays cool. The hue walks the warm
|
|
1042
|
+
side of the wheel (blue → violet → red → orange) rather than lerping
|
|
1043
|
+
straight down through green.
|
|
1044
|
+
|
|
1045
|
+
Returns (r, g, b, a) floats in 0..1 (a = opacity). Edit freely to
|
|
1046
|
+
restyle the wash — it is read live, so changes show immediately."""
|
|
1047
|
+
import colorsys
|
|
1048
|
+
t = min(max(users, 1) - 1, 5) / 5.2
|
|
1049
|
+
v = max(0.13, 0.88 * t + 0.3)
|
|
1050
|
+
usage_tint = (0.204, 0.224, 0.239)
|
|
1051
|
+
usage_tint = (*usage_tint, v)
|
|
1052
|
+
return usage_tint
|
|
1053
|
+
# Definition tints: a class/def whose definition carries a tint
|
|
1054
|
+
# (@defaults(tint=...), a '# [tint=...]' override comment, or a
|
|
1055
|
+
# class-body tint=...) gets a full-body background wash in the editor,
|
|
1056
|
+
# and every occurrence of that symbol - even when its definition lives
|
|
1057
|
+
# in another file - gets a small wash of the same color. The washes take
|
|
1058
|
+
# the tint's rgb with these alphas (the tint's own alpha is a view-
|
|
1059
|
+
# wide opacity, not meant for text washes). All read live
|
|
1060
|
+
|
|
1061
|
+
# [tint=(0.0875, 0.2815, 0.477, 1.00), show_tint=True]
|
|
1062
|
+
definition_tints = True
|
|
1063
|
+
|
|
1064
|
+
# Definition tints from the text-derived SYMBOL ROSTER
|
|
1065
|
+
# (core_conversion/symbol_roster.py + core_views/roster_tints.py):
|
|
1066
|
+
# washes come from the live buffer + pending text of every file,
|
|
1067
|
+
# no cst-dict parse, no background usage graph, no live objects —
|
|
1068
|
+
# a tinted def typed anywhere paints its references on the next
|
|
1069
|
+
# rebuild without saving or hotswapping. Off = the legacy
|
|
1070
|
+
# _collect_def_tints path (cst-dict + __symbol_usages__).
|
|
1071
|
+
# [tint=(0.0875, 0.2815, 0.477, 1.00), show_tint=True]
|
|
1072
|
+
roster_def_tints = True
|
|
1073
|
+
|
|
1074
|
+
# Definition block washes of ROOT symbols (blocks no other block in
|
|
1075
|
+
# the buffer contains — top-level classes/defs). Embeds that paint
|
|
1076
|
+
# the enclosing class's background themselves (global-search rows)
|
|
1077
|
+
# ask draw_text to skip these via show_root_backgrounds=False; with
|
|
1078
|
+
# this True that request is ignored and root symbols keep their
|
|
1079
|
+
# tints everywhere, False honours it.
|
|
1080
|
+
# [tint=(0.0875, 0.2815, 0.477, 1.00), show_tint=True]
|
|
1081
|
+
root_symbol_tints = True
|
|
1082
|
+
|
|
1083
|
+
# When the caret rests on an identifier, every OTHER place that exact
|
|
1084
|
+
# token appears in the visible buffer gets this background wash. A dumb,
|
|
1085
|
+
# identifier-bounded character match - no CST / symbol-DB metadata is
|
|
1086
|
+
# involved, so it works in any text, mid-edit or unparseable. Flip the
|
|
1087
|
+
# toggle to disable; the (r, g, b, a) tint is read live.
|
|
1088
|
+
highlight_token_matches = True
|
|
1089
|
+
|
|
1090
|
+
# Scope guides: a thin vertical line down the indent column of every
|
|
1091
|
+
# indented block. A tinted def/class draws its guide in its
|
|
1092
|
+
# definition tint, nested blocks inherit the nearest enclosing
|
|
1093
|
+
# tinted block's, and outside any tinted block the file's tint
|
|
1094
|
+
# (else Tint.scope_guide) applies. Colours run through the
|
|
1095
|
+
# same hsv adjustment as the washes with the four knobs below
|
|
1096
|
+
# (saturation / value multipliers, then a brightness clamp).
|
|
1097
|
+
# [tint=(0.0875, 0.2815, 0.477, 1.00), show_tint=True]
|
|
1098
|
+
scope_guides = True
|
|
1099
|
+
# [tint=(0.72, 0.11, 0.11), show_tint=True]
|
|
1100
|
+
scope_guide_alpha = 0.5
|
|
1101
|
+
scope_guide_thickness = 1.0
|
|
1102
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
1103
|
+
scope_guide_saturation = 0.8
|
|
1104
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
1105
|
+
scope_guide_value = 1.6
|
|
1106
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
1107
|
+
scope_guide_min_value = 0.16
|
|
1108
|
+
scope_guide_max_value = 0.32
|
|
1109
|
+
# The guide of the block the caret sits in (focused editor): its
|
|
1110
|
+
# own alpha / value / brightness cap, so it stands out from the rest.
|
|
1111
|
+
# [tint=(0.72, 0.11, 0.11), show_tint=True]
|
|
1112
|
+
scope_guide_active_alpha = 0.9
|
|
1113
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
1114
|
+
scope_guide_active_value = 2.6
|
|
1115
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
1116
|
+
scope_guide_active_max_value = 0.55
|
|
1117
|
+
|
|
1118
|
+
# [tint=(0.72, 0.11, 0.11), show_tint=True]
|
|
1119
|
+
def_block_alpha = 1.0
|
|
1120
|
+
|
|
1121
|
+
# [tint=(0.72, 0.11, 0.11), show_tint=True]
|
|
1122
|
+
def_symbol_alpha = 1.0
|
|
1123
|
+
|
|
1124
|
+
# [tint=(0.72, 0.11, 0.11), show_tint=True]
|
|
1125
|
+
def_line_alpha = 0.078
|
|
1126
|
+
|
|
1127
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
1128
|
+
bg_tint_saturation = 0.67
|
|
1129
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
1130
|
+
bg_tint_value = 0.12
|
|
1131
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
1132
|
+
bg_min_brightness = 0.01
|
|
1133
|
+
bg_max_brightness = 0.137
|
|
1134
|
+
|
|
1135
|
+
# Per-occurrence symbol-wash color adjustment - same hsv factor
|
|
1136
|
+
# pattern as bg_tint_*, but independent of the block/line washes so
|
|
1137
|
+
# the chips can run hotter or duller than the surfaces under them.
|
|
1138
|
+
# The shared brightness clamp (bg_min/max) still applies after.
|
|
1139
|
+
symbol_tint_saturation = 1.02
|
|
1140
|
+
symbol_tint_value = 0.25
|
|
1141
|
+
|
|
1142
|
+
# Line-band color adjustment - the third independent hsv pair
|
|
1143
|
+
# (blocks = bg_tint_*, symbols = symbol_tint_*). Applies to the
|
|
1144
|
+
# hard rect AND the blurred band alike. Shared clamp applies.
|
|
1145
|
+
line_tint_saturation = 0.72
|
|
1146
|
+
line_tint_value = 0.54
|
|
1147
|
+
|
|
1148
|
+
# Outline drawn around the BG washes ( class/func block rects and
|
|
1149
|
+
# hard line bands) - so the highlight edges read crisply against
|
|
1150
|
+
# the background. The outline color is the wash color BRIGHTENED by
|
|
1151
|
+
# def_outline_brightness (multiplied after the bg brightness clamp,
|
|
1152
|
+
# so it pops where the fill stays muted). 0 alpha disables.
|
|
1153
|
+
def_outline_alpha = 1.0
|
|
1154
|
+
def_outline_brightness = 1.6
|
|
1155
|
+
def_outline_thickness = 0.3
|
|
1156
|
+
# Same three knobs for the per-occurrence symbol wash outlines,
|
|
1157
|
+
# independent of the bg wash above. 0 alpha disables.
|
|
1158
|
+
def_symbol_outline_alpha = 1.0
|
|
1159
|
+
def_symbol_outline_brightness = 1.1
|
|
1160
|
+
def_symbol_outline_thickness = 0.3
|
|
1161
|
+
# Compositor shadows under the def-tint washes (add_shadow depth
|
|
1162
|
+
# marks): the signed depth offset for class/func block rects and for
|
|
1163
|
+
# per-occurrence symbol washes. Symbols sit above blocks so the widget
|
|
1164
|
+
# chip casts onto its enclosing block wash; negative values recess
|
|
1165
|
+
# instead; 0 disables.
|
|
1166
|
+
def_block_shadow_offset = 0.05
|
|
1167
|
+
def_symbol_shadow_offset = 3.7
|
|
1168
|
+
# Line-number shadows: negative = recessed below the editor surface
|
|
1169
|
+
# (the body casts into the gutter along its edge); 0 disables.
|
|
1170
|
+
gutter_shadow_offset = 0.157
|
|
1171
|
+
# Master switch for the gutter usage-heat buttons: the per-line
|
|
1172
|
+
# summed-usage boxes behind the line numbers AND their click-to-open
|
|
1173
|
+
# usage picker. Off also skips the per-frame heat aggregation pass
|
|
1174
|
+
# (gutter clicks fall through to caret placement). Read live.
|
|
1175
|
+
# [tint=(0.0875, 0.2815, 0.477, 1.00), show_tint=True]
|
|
1176
|
+
usage_heat_gutter = True
|
|
1177
|
+
# Compositor shadow under the gutter usage-heat boxes: each use
|
|
1178
|
+
# counted on the line adds this much lift, so hotter lines float
|
|
1179
|
+
# higher off the gutter background. The magnitude is capped at
|
|
1180
|
+
# usage_heat_shadow_max (sign preserved - negative recesses);
|
|
1181
|
+
# 0 disables.
|
|
1182
|
+
usage_heat_shadow_offset = 0.362
|
|
1183
|
+
usage_heat_shadow_max = 1.092
|
|
1184
|
+
# Gutter background saturation/value — the hsv multipliers
|
|
1185
|
+
# Tint.line_number_bg applies to the editor BODY's painted background
|
|
1186
|
+
# (the show_bg fill under the text, already capped by editor_value),
|
|
1187
|
+
# so gutter_value is the strip's brightness as a FRACTION of the
|
|
1188
|
+
# body's: 1.0 = same brightness as the text background, lower =
|
|
1189
|
+
# darker strip. Lower saturation = greyer, calmer strip. (Before
|
|
1190
|
+
# 09-14 both applied to the raw theme tint, value 0.325.)
|
|
1191
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
1192
|
+
gutter_saturation = 1.046
|
|
1193
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
1194
|
+
gutter_value = 0.8
|
|
1195
|
+
# Gutter TEXT (line numbers) hsv-value guards, applied in
|
|
1196
|
+
# Tint.line_number_tint AFTER its value scale: the floor keeps the
|
|
1197
|
+
# numbers legible on a dark theme tint, the ceiling stops a bright
|
|
1198
|
+
# one from pushing them to full white over the body text. Hue and
|
|
1199
|
+
# saturation kept. The floor wins if they cross.
|
|
1200
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
1201
|
+
gutter_text_min_brightness = 0.45
|
|
1202
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
1203
|
+
gutter_text_max_brightness = 0.8
|
|
1204
|
+
|
|
1205
|
+
# Code editor body background — draw_code_editor forwards these into
|
|
1206
|
+
# its draw_text panes as the show_bg saturation multiplier and the
|
|
1207
|
+
# max_bg_value brightness cap (draw_text's decorator defaults are
|
|
1208
|
+
# saturation=0.9 / max_bg_value=0.05).
|
|
1209
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
1210
|
+
editor_saturation = 0.394
|
|
1211
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
1212
|
+
editor_value = 0.346
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
# Assignment propagation: a local defined FROM tinted symbols takes a
|
|
1216
|
+
# faded blend of their colors (single-symbol assignment averages the distinct
|
|
1217
|
+
# tints), fading a further step per hop so a value's color trail
|
|
1218
|
+
# weakens as it flows. Fade multiplies the wash alpha per hop -
|
|
1219
|
+
# LOWER = colors die out faster along assignment chains (0.55 puts
|
|
1220
|
+
# hop 1 at 55%, hop 2 at 30%; chains below 20% stop washing at all).
|
|
1221
|
+
def_tint_propagation = True
|
|
1222
|
+
def_propagation_fade = 0.025
|
|
1223
|
+
|
|
1224
|
+
# When enabled the line tint rect above fills the whole line -
|
|
1225
|
+
# gutter edge to the view's right edge - instead of hugging the
|
|
1226
|
+
# line's text extent (indent → last non-ws column).
|
|
1227
|
+
def_line_full_width = False
|
|
1228
|
+
|
|
1229
|
+
# Soft-edged line band: instead of a solid rect the line tint draws
|
|
1230
|
+
# as a feathered stack of expanding translucent rects, fading the
|
|
1231
|
+
# color out over def_line_blur_radius pixels past the band's edge
|
|
1232
|
+
# (a cheap drawcall gaussian - no blur pass). The radius also
|
|
1233
|
+
# bleeds vertically into neighboring lines, which is the point.
|
|
1234
|
+
def_line_blur = True
|
|
1235
|
+
|
|
1236
|
+
# Render the line band through the GL glow pipeline (add_glow →
|
|
1237
|
+
# low-res light buffer → shadow composite) instead of the draw-list
|
|
1238
|
+
# feather stack: the band becomes a real light source - it brightens
|
|
1239
|
+
# neighbors and pushes back compositor shadows - and costs one small
|
|
1240
|
+
# quad instead of def_line_blur_samples rects of overdraw. Falls back
|
|
1241
|
+
# to the draw-list stack when False (or Toggles.glow is off).
|
|
1242
|
+
def_line_glow = True
|
|
1243
|
+
# Intensity of the emitted light for line bands (on top of the band
|
|
1244
|
+
# alpha; Toggles.glow_intensity scales all glows globally).
|
|
1245
|
+
def_line_glow_intensity = 0.495
|
|
1246
|
+
# Emit light from each PER-OCCURRENCE chip (the per-token wash
|
|
1247
|
+
# rects) instead of / in addition to the line band - the glow then
|
|
1248
|
+
# highlights the individual token background's edges. Pair with
|
|
1249
|
+
# def_line_glow = False to make tokens the only light source.
|
|
1250
|
+
def_symbol_glow = True
|
|
1251
|
+
# Intensity of the emitted light per token chip (on top of
|
|
1252
|
+
# def_symbol_alpha and any per-hop propagation scale).
|
|
1253
|
+
def_symbol_glow_intensity = -0.04
|
|
1254
|
+
# Falloff skirt radius for token-chip light, px. Deliberately its
|
|
1255
|
+
# own knob - token halos want a far shorter throw than the
|
|
1256
|
+
# line-band def_line_blur_radius.
|
|
1257
|
+
def_symbol_glow_radius = 65.532
|
|
1258
|
+
|
|
1259
|
+
def_line_blur_radius = 126
|
|
1260
|
+
# Alpha multiplier for the blurred band only - feathering spreads
|
|
1261
|
+
# the color thin, so the blur usually wants MORE alpha than the
|
|
1262
|
+
# hard rect's def_line_alpha. 1.0 = same as the hard band.
|
|
1263
|
+
def_line_blur_alpha = 1.985
|
|
1264
|
+
# Falloff hardness for the blur's inverse-square profile - how
|
|
1265
|
+
# concentrated the "lightsource" is. Higher = tighter core with a
|
|
1266
|
+
# longer radial tail; 0 falls back to the default linear feather.
|
|
1267
|
+
def_line_blur_falloff = 3.044
|
|
1268
|
+
# Perceived-brightness clamp on the BLURRED band's color only -
|
|
1269
|
+
# applied on top of the line_tint_* adjustment (which already ran
|
|
1270
|
+
# through bg_min/max), so the feathered glow can hold a different
|
|
1271
|
+
# brightness window than the hard band. 0.0/1.0 = no extra clamp.
|
|
1272
|
+
def_line_blur_min_value = 0.401
|
|
1273
|
+
def_line_blur_max_value = 6.338
|
|
1274
|
+
# Layer count for the feather stack. More samples = smoother
|
|
1275
|
+
# gradient (fewer visible bands) at the cost of overdraw - large
|
|
1276
|
+
# radii need more; ~1 sample per 3-4px of radius reads smooth.
|
|
1277
|
+
def_line_blur_samples = 7
|
|
1278
|
+
|
|
1279
|
+
# Glyphs inside a symbol wash lean this fraction toward the wash
|
|
1280
|
+
# color (syntax color stays the base) — the slight text tinting used
|
|
1281
|
+
# app-wide so text reads as part of its panel. 0 disables.
|
|
1282
|
+
# [tint=(0.789, 0.18, 0.332, 1.0)]
|
|
1283
|
+
def_text_tint_mix = 0.293
|
|
1284
|
+
|
|
1285
|
+
# Brightness multiplier for glyphs on NON-tinted lines while
|
|
1286
|
+
# Toggles.presentation_mode is on (lines with a def-tint line wash
|
|
1287
|
+
# keep full brightness). 1 = no dimming; 0 = black. Read live.
|
|
1288
|
+
presentation_text_brightness = 0.292
|
|
1289
|
+
|
|
1290
|
+
# Compensation for the inline value widgets (bool/number) inside
|
|
1291
|
+
# tint comments: their text renders through the widget's own hsv
|
|
1292
|
+
# pipeline, so reads darker than the plain comment glyphs at the
|
|
1293
|
+
# same dimmed tint - multiply their dimming by this so both
|
|
1294
|
+
# land at the same visual level. 1 = no boost. Read live.
|
|
1295
|
+
presentation_widget_boost = 1.953
|
|
1296
|
+
|
|
1297
|
+
# Background-chip brightness for the faded comment widgets, relative
|
|
1298
|
+
# to their (already boosted) dimmed text color - a step brighter so
|
|
1299
|
+
# the widget stands out as a spot on a dim line. Read live.
|
|
1300
|
+
presentation_widget_bg_boost = 0.115
|
|
1301
|
+
|
|
1302
|
+
# Text alpha for the faded COLORED value widgets (ones whose
|
|
1303
|
+
# comment carries a tint) - saturated colors read brighter than the
|
|
1304
|
+
# grey at equal value, so they get a transparency cut on top of the
|
|
1305
|
+
# brightness boost. Untinted (grey) widgets stay opaque. 1 = opaque.
|
|
1306
|
+
# Read live.
|
|
1307
|
+
presentation_widget_alpha = 0.409
|
|
1308
|
+
|
|
1309
|
+
# The number widget's chip paints brighter than the bool's at the
|
|
1310
|
+
# same tint (depth-clamped blur + drag-frame fill stack) - extra dim
|
|
1311
|
+
# factor on its background in the presentation mode, applied on top
|
|
1312
|
+
# of presentation_widget_bg_boost (also lowers the chip's max_bg_value
|
|
1313
|
+
# legibility cap). 1 = same as bool. Read live.
|
|
1314
|
+
presentation_number_bg_dim = 4.001
|
|
1315
|
+
|
|
1316
|
+
# Glyph-mix TARGET color adjustment (which color text leans toward
|
|
1317
|
+
# inside a wash) - same hsv factor pattern as comment_tint_* /
|
|
1318
|
+
# bg_tint_*, independent of the wash's own factors; the shared
|
|
1319
|
+
# brightness clamp (bg_min/max) still applies after. 1/1 = raw tint.
|
|
1320
|
+
text_tint_saturation = 1.0
|
|
1321
|
+
text_tint_value = 1.0
|
|
1322
|
+
|
|
1323
|
+
# Tint-comment TEXT color adjustment (hsv factors, the Tint-class
|
|
1324
|
+
# pattern): an override comment wears its own [tint=...] color,
|
|
1325
|
+
# desaturated and darkened by these so it reads as commentary, not
|
|
1326
|
+
# code. Both read live; 1.0/1.0 = the raw tint.
|
|
1327
|
+
# [tint=(1.0, 0.661, 0.0, 1.0)]
|
|
1328
|
+
comment_tint_saturation = 0.49
|
|
1329
|
+
|
|
1330
|
+
# [tint=(0.3813193440437317, 0.7055555582046509, 0.14895063638687134), show_tint=True]
|
|
1331
|
+
comment_tint_value = 0.160
|
|
1332
|
+
# Legibility floor for tinted COMMENT TEXT - independent of the
|
|
1333
|
+
# washes' bg_min_brightness (text needs a higher floor than a
|
|
1334
|
+
# background does); the brightness clamp still shares bg_max_brightness.
|
|
1335
|
+
comment_min_brightness = 0.170
|
|
1336
|
+
|
|
1337
|
+
|
|
1338
|
+
# [tint=(0.013, 0.583, 0.013), show_tint=True]
|
|
1339
|
+
class Voxels:
|
|
1340
|
+
# Artistic curve on the finished volume image, applied to the LINEAR
|
|
1341
|
+
# light the raymarch hands the fp16 scene (the presentation pass
|
|
1342
|
+
# does the one sRGB encode): 1.0 = untouched (colorimetrically
|
|
1343
|
+
# "correct"), above 1 darkens the mids against the studio's darks.
|
|
1344
|
+
# Read live per frame by draw_voxels.
|
|
1345
|
+
gamma = 1.00
|
|
1346
|
+
|
|
1347
|
+
# Auto neural flow: when nf_on is OFF and a DISPLAYED axis is longer
|
|
1348
|
+
# than this (or than GL_MAX_3D_TEXTURE_SIZE, whichever is smaller),
|
|
1349
|
+
# draw_voxels wraps it itself - chops it into ~sqrt-sized chunks spaced
|
|
1350
|
+
# along the shortest visible axis - so a (1, 32000)) row renders
|
|
1351
|
+
# as a readable slab instead of a hairline (or a clamped prefix).
|
|
1352
|
+
# 0 disables. Read live per render.
|
|
1353
|
+
auto_flow_extent = 8192
|
|
1354
|
+
|
|
1355
|
+
# Navigation model of the MOUSE orbit (middle-drag) - the 3D mouse has
|
|
1356
|
+
# its own below (SpaceMouse.navigation), so each device can keep the
|
|
1357
|
+
# feel that suits it. "turntable": drag x spins about the world UP
|
|
1358
|
+
# axis, drag y tilts, the horizon never rolls. "trackball": the drag
|
|
1359
|
+
# is a rotation in VIEW space about the orbit center, roll included.
|
|
1360
|
+
# Read live per frame.
|
|
1361
|
+
mouse_navigation = "turntable"
|
|
1362
|
+
|
|
1363
|
+
# What the volume's FLOOR shadow darkens toward (both the GL and the
|
|
1364
|
+
# cuda_march paths). Neutral grey-black; the UI's own window
|
|
1365
|
+
# shadows keep their blue-black Toggles.shadow_color. Read live
|
|
1366
|
+
# per render.
|
|
1367
|
+
floor_shadow_color = (0.03, 0.03, 0.03)
|
|
1368
|
+
|
|
1369
|
+
@defaults(tint=(0.545, 0.451, 0.248))
|
|
1370
|
+
class UIScale:
|
|
1371
|
+
# Auto-pick the UI scale each frame from the resolution of the monitor
|
|
1372
|
+
# the OS window sits on: 4k-and-larger panels get 1.5, everything else
|
|
1373
|
+
# 1.0 (detect_auto_scale in fonts.py; rechecked every ~120 frames, so
|
|
1374
|
+
# dragging the window to another monitor retunes soon after). False =
|
|
1375
|
+
# use the manual scale below. Read live.
|
|
1376
|
+
auto_scale = False
|
|
1377
|
+
|
|
1378
|
+
# The scaling dial, used when auto_scale is off. It reaches the screen
|
|
1379
|
+
# exactly two ways (Melty.apply_ui_scale / Melty.begin_frame): every
|
|
1380
|
+
# font is RE-BAKED at scale x its authored physical size, and imgui's
|
|
1381
|
+
# style metrics (padding, spacing, rounding, borders) are multiplied
|
|
1382
|
+
# by it. Coordinates are untouched - window sizes and hand-placed
|
|
1383
|
+
# pixel offsets in the code do NOT scale, so this is a text-and-chrome
|
|
1384
|
+
# scale, not a zoom. That's on purpose: the whole-interface zoom this
|
|
1385
|
+
# replaced (logical display + magnify at present time) forced every
|
|
1386
|
+
# offscreen tile to allocate and repaint at physical resolution and
|
|
1387
|
+
# put a resample between tile and screen - slow, and soft at any scale
|
|
1388
|
+
# but 1. Sanitized through glfw_utils.clamp_ui_scale: outside
|
|
1389
|
+
# 0.5..3.0 (or NaN/garbage) is read as 1.0, so a typo can't bake a
|
|
1390
|
+
# 20x font atlas. Changing it re-rasterizes all 18 fonts - a ~0.3s
|
|
1391
|
+
# operation and a ~64->128MB atlas at 1.25 - so it is a setting to
|
|
1392
|
+
# change deliberately, not to animate. 1.0 = the authored look.
|
|
1393
|
+
scale = 1.00
|
|
1394
|
+
|
|
1395
|
+
@defaults(tint=(0.545, 0.451, 0.248))
|
|
1396
|
+
class Fonts:
|
|
1397
|
+
# Subpixel (LCD & "ClearType"-style) text anti-aliasing. The at
|
|
1398
|
+
# atlas is baked 3x oversampled horizontally, and each glyph quad
|
|
1399
|
+
# covers 3 atlas texels per screen pixel; the imgui renderer
|
|
1400
|
+
# (split_overlay_renderer.py) samples those as per-channel R/G/B
|
|
1401
|
+
# coverage and blends them with dual-source blending - tripling the
|
|
1402
|
+
# horizontal resolution of lines and curves the way IntelliJ and the
|
|
1403
|
+
# desktop do. Off = classic grayscale AA (same atlas, one tap).
|
|
1404
|
+
# Turn off on a ROTATED monitor (stripes run vertically there) or
|
|
1405
|
+
# when text must be fringe-free. Read live per frame.
|
|
1406
|
+
lcd_subpixel = True
|
|
1407
|
+
|
|
1408
|
+
# Subpixel stripe order of the panel. Nearly every desktop panel is
|
|
1409
|
+
# RGB left-to-right; a BGR panel shows orange/blue fringes on the
|
|
1410
|
+
# wrong sides of every glyph - flip this. Read live per frame.
|
|
1411
|
+
lcd_bgr = False
|
|
1412
|
+
|
|
1413
|
+
# Contrast curve on glyph coverage: coverage ** (1 / text_gamma).
|
|
1414
|
+
# > 1 darkens the anti-aliased mid-tones so strokes read thicker
|
|
1415
|
+
# (Java2D's "high contrast"); 1.0 = linear coverage, the unaltered
|
|
1416
|
+
# rasterizer output. Applies in both LCD and grayscale modes to glyphs
|
|
1417
|
+
# only - never to rects / lines / images. Read live per frame.
|
|
1418
|
+
text_gamma = 1.0
|
|
1419
|
+
|
|
1420
|
+
# Replace stb_truetype's glyph bitmaps with FreeType light-hinted
|
|
1421
|
+
# LCD renders at atlas bake (FontManager.hint_atlas): baselines,
|
|
1422
|
+
# x-heights and crossbars snap to pixel rows instead of smearing
|
|
1423
|
+
# over two - the other half of the LCD look, grayscale being the
|
|
1424
|
+
# first. Needs freetype-py; glyphs the hinter grows past their
|
|
1425
|
+
# atlas rect keep stb's bitmap. Read at atlas bake: must under a
|
|
1426
|
+
# UI-scale change to apply.
|
|
1427
|
+
freetype_hinting = True
|
|
1428
|
+
|
|
1429
|
+
# Style variants (FontManager.styled_font: a Font at another native
|
|
1430
|
+
# size / weight) stay in the atlas until they're not drawn for this
|
|
1431
|
+
# many flushes (one flush = one surface resize, Melty.apply_ui_scale)
|
|
1432
|
+
# AND a bake happens anyway. Too short and windows that draw in turns
|
|
1433
|
+
# evict each other's fonts, so every frame re-bakes the atlas (~0.6 s
|
|
1434
|
+
# each, text jumping to the fallback face in between; the 09-13
|
|
1435
|
+
# playground ran at 1.5 fps). Only a bake can evict.
|
|
1436
|
+
variant_idle_flushes = 600
|
|
1437
|
+
# Hard cap on retained variants past the idle window: the least
|
|
1438
|
+
# recently drawn go first. Bounds the atlas after a long style drag.
|
|
1439
|
+
max_font_variants = 96
|
|
1440
|
+
|
|
1441
|
+
# [icon=""]
|
|
1442
|
+
|
|
1443
|
+
@defaults(tint=(0.62, 0.36, 0.52))
|
|
1444
|
+
class HDR:
|
|
1445
|
+
# HDR / wide-gamut colour (gl_gui/hdr_color.py). Colour tuples are
|
|
1446
|
+
# EXTENDED sRGB: 1.0 = the panel's SDR reference white, above it is
|
|
1447
|
+
# brighter and negatives are outside the sRGB gamut (write them with
|
|
1448
|
+
# white(n) / p3(r, g, b)). The GPU works in linear scRGB fp16 and
|
|
1449
|
+
# the presentation pass (Melty.post_frame) encodes for the output.
|
|
1450
|
+
|
|
1451
|
+
# Ceiling of the HDR byte curve, in multiples of reference white on
|
|
1452
|
+
# P3 primaries: the brightest fully saturated colour a vertex can
|
|
1453
|
+
# carry (white(64) on a 250-nit desktop is 16 000 nits — headroom
|
|
1454
|
+
# for a dimmed desktop, not a target). Raising it spreads the same
|
|
1455
|
+
# 255 codes over more octaves (see vertex_octaves). Read live by the
|
|
1456
|
+
# packer and the shaders.
|
|
1457
|
+
# [tint=(0.62, 0.36, 0.52)]
|
|
1458
|
+
vertex_range = 64.0
|
|
1459
|
+
# Octaves below vertex_range the 255 codes cover: code 1 sits at
|
|
1460
|
+
# vertex_range / 2^vertex_octaves, code 0 is exactly zero. 12 -> ~21
|
|
1461
|
+
# codes per doubling (a 3.3 % step), enough for accents; long
|
|
1462
|
+
# smooth HDR gradients want more codes, not more octaves.
|
|
1463
|
+
# [tint=(0.62, 0.36, 0.52)]
|
|
1464
|
+
vertex_octaves = 12.0
|
|
1465
|
+
# Presentation encode of the linear scRGB scene into the 8-bit
|
|
1466
|
+
# swapchain AND the surface's colour tag (wayland_color.py):
|
|
1467
|
+
# "auto" — PQ whenever the compositor offers colour management (the
|
|
1468
|
+
# Hyprland HDR session), sRGB otherwise (GNOME); "pq" — BT.2020 +
|
|
1469
|
+
# ST 2084, surface tagged PQ; "srgb" — SDR, untagged: everything
|
|
1470
|
+
# clips to the sRGB gamut and to white. Read live.
|
|
1471
|
+
# [tint=(0.62, 0.36, 0.52)]
|
|
1472
|
+
output = "auto"
|
|
1473
|
+
# Under the "pq" encode a colour of 1.0 is shown at the desktop's
|
|
1474
|
+
# SDR reference white — read from the compositor's preferred image
|
|
1475
|
+
# description for our surface (wayland_color.query_preferred;
|
|
1476
|
+
# Hyprland: the monitor's sdr_max_luminance) and re-read whenever
|
|
1477
|
+
# it changes, so the studio's white tracks the desktop's SDR white
|
|
1478
|
+
# setting like every untagged window. Off = pin pq_reference_nits.
|
|
1479
|
+
# [tint=(0.62, 0.36, 0.52)]
|
|
1480
|
+
follow_desktop_white = True
|
|
1481
|
+
# Nits of reference white (a colour of 1.0) under the "pq" encode
|
|
1482
|
+
# when the compositor doesn't say (no luminances in its preferred
|
|
1483
|
+
# description) or follow_desktop_white is off.
|
|
1484
|
+
# [tint=(0.62, 0.36, 0.52)]
|
|
1485
|
+
pq_reference_nits = 250.0
|
|
1486
|
+
# The colour picker's Wide tab: how far above white its square
|
|
1487
|
+
# reaches, in stops (4 = white(16)), and the fraction of the
|
|
1488
|
+
# square's height that exposure band takes (the rest is the classic
|
|
1489
|
+
# value axis). Read live.
|
|
1490
|
+
# [tint=(0.62, 0.36, 0.52)]
|
|
1491
|
+
picker_max_stops = 4.0
|
|
1492
|
+
# [tint=(0.62, 0.36, 0.52)]
|
|
1493
|
+
picker_top_fraction = 0.3
|
|
1494
|
+
# Emphasis flashes (Melty.emphasize / emphasize_click, the overlay
|
|
1495
|
+
# pass): how far above the desktop's white the flash is lifted, in
|
|
1496
|
+
# stops of linear light — the outline / ripple rings at
|
|
1497
|
+
# 2^emphasis_stops (3 = white(8): 2000 nits on a 250-nit desktop),
|
|
1498
|
+
# the rect's fill at 2^emphasis_fill_stops, the bloom halo around
|
|
1499
|
+
# the outline at emphasis_stops too but faint. Callers pass a hue
|
|
1500
|
+
# tint (SDR or P3) and the lift is applied at draw time, so an edit
|
|
1501
|
+
# here is live. Under the "srgb" output everything clips to white
|
|
1502
|
+
# and the flash just reads as a bright, saturated highlight.
|
|
1503
|
+
# [tint=(0.62, 0.36, 0.52)]
|
|
1504
|
+
emphasis_stops = 3.0
|
|
1505
|
+
# [tint=(0.62, 0.36, 0.52)]
|
|
1506
|
+
emphasis_fill_stops = 1.0
|
|
1507
|
+
# Ceiling on TEXT brightness, in stops above the desktop's white:
|
|
1508
|
+
# glyph pixels of the draw-list renderer and the text-texture bake
|
|
1509
|
+
# are scaled down (hue kept) so no channel exceeds 2^text_max_stops
|
|
1510
|
+
# — an HDR colour reaching a label through a style, a tint or an
|
|
1511
|
+
# emphasis lift read as blinding white on the PQ desktop (09-14).
|
|
1512
|
+
# Backgrounds, icons drawn as rects and images keep their full
|
|
1513
|
+
# headroom; 0 = clamp text at reference white. Read live.
|
|
1514
|
+
# [tint=(0.62, 0.36, 0.52)]
|
|
1515
|
+
text_max_stops = 1.0
|
|
1516
|
+
|
|
1517
|
+
@defaults(tint=(0.36, 0.42, 0.52))
|
|
1518
|
+
class Melty:
|
|
1519
|
+
# Every tree / expand arrow (the header arrows, the chat's carets and
|
|
1520
|
+
# the sidebar's folder arrows) draws at this fraction of its recipe's
|
|
1521
|
+
# brightness and alpha; 1 = as designed.
|
|
1522
|
+
# [tint=(0.62, 0.36, 0.52), show_tint=True]
|
|
1523
|
+
arrow_brightness = 0.5
|
|
1524
|
+
# Custom client-side titlebar: undecorated OS window so the UI sticks
|
|
1525
|
+
# to the top of the display, with min/max/close drawn to the overlay
|
|
1526
|
+
# drawlist top-right and drag/edge-resize handed to the WM via
|
|
1527
|
+
# _NET_WM_MOVERESIZE (titlebar.py). X11/XWayland only: on native
|
|
1528
|
+
# Wayland this is NOT consulted - with wayland_native_frame (below)
|
|
1529
|
+
# the min/max/close buttons always draw (GLFW's fallback frame has
|
|
1530
|
+
# none of its own) while the OS window KEEPS that frame (its caption
|
|
1531
|
+
# strip + borders are the only move/resize surface there; no GLFW
|
|
1532
|
+
# route to xdg_toplevel.move). Applied live per frame
|
|
1533
|
+
# (glfw.set_window_attrib) and read at boot for the DECORATED hint.
|
|
1534
|
+
enhanced_titlebar = False
|
|
1535
|
+
|
|
1536
|
+
# GNOME Wayland only. GNOME offers no server-side decorations, so
|
|
1537
|
+
# GLFW hands its OS window to libdecor, and its GNOME plugin
|
|
1538
|
+
# repaints the whole title bar + frame on the fly for EVERY resize
|
|
1539
|
+
# configure: 38 ms a step at a 4072×2136 window, 59 ms at 7000×2000,
|
|
1540
|
+
# inside glfw.wait_events before render() even starts, and the
|
|
1541
|
+
# configures queue up while the frame runs - the 2s OS-window
|
|
1542
|
+
# resize. On, GLFW skips libdecor (WAYLAND_DISABLE_LIBDECOR init
|
|
1543
|
+
# hint) and draws its own fallback frame: a plain caption strip +
|
|
1544
|
+
# 4 px borders that move/resize through the compositor at <1 ms a
|
|
1545
|
+
# step, with no buttons - titlebar.py draws min/max/close over it. Read
|
|
1546
|
+
# by the FIRST glfw.init() of the day (the launcher process,
|
|
1547
|
+
# glfw_utils.apply_wayland_frame_hint), so a change takes effect on
|
|
1548
|
+
# the next model_server restart, like the cursor size.
|
|
1549
|
+
wayland_native_frame = True
|
|
1550
|
+
|
|
1551
|
+
# With wayland_native_frame: keep GLFW's fallback frame - a 24 px
|
|
1552
|
+
# caption strip (drag = move) + 4 px borders (drag = resize), sizes
|
|
1553
|
+
# GLFW hardcodes - or drop it and run frameless: the buttons are
|
|
1554
|
+
# titlebar.py's, resizing is the right-drag anywhere in the window
|
|
1555
|
+
# (app-driven glfw.set_window_size, bottom-right corner - Wayland
|
|
1556
|
+
# prefers the top-left; the edge zones ask the compositor:
|
|
1557
|
+
# xdg_toplevel.resize) and MOVING is xdg_toplevel.move from the
|
|
1558
|
+
# drag strip / drag-anywhere (gl_gui/wayland_move.py - Super+drag
|
|
1559
|
+
# semantics, driven by the compositor). Applied live
|
|
1560
|
+
# (sync_decoration).
|
|
1561
|
+
wayland_show_frame = False
|
|
1562
|
+
|
|
1563
|
+
# px height of the invisible drag strip along the top edge - a drag
|
|
1564
|
+
# outside inside it (a few px of travel past the press) moves the OS
|
|
1565
|
+
# window; a clean click there falls through to whatever view is under
|
|
1566
|
+
# the cursor. Double-click toggles maximize (unless
|
|
1567
|
+
# disable_double_click_maximize below).
|
|
1568
|
+
drag_strip_height = 50
|
|
1569
|
+
|
|
1570
|
+
# On (default): the drag strip never subscribes to double-click, so
|
|
1571
|
+
# it falls through to the view under the cursor like any other
|
|
1572
|
+
# click. Off: a double-click on the strip toggles the OS window's
|
|
1573
|
+
# maximize, the WM caption rule. Applied live (each frame).
|
|
1574
|
+
disable_double_click_maximize = True
|
|
1575
|
+
|
|
1576
|
+
# Left-drag ANYWHERE in the window moves the OS window, the meltygui
|
|
1577
|
+
# way — as the worst-priority drag subscriber: a view that wants the
|
|
1578
|
+
# drag (window headers, sliders, text selection, dnd) always wins,
|
|
1579
|
+
# while an unclaimed drag on bare background moves the window. Off =
|
|
1580
|
+
# only the strip moves. Double-click-maximize stays strip-only.
|
|
1581
|
+
move_drag_anywhere = True
|
|
1582
|
+
|
|
1583
|
+
# Show the desktop's "move" pointer (mouse_state.MOVE) wherever a
|
|
1584
|
+
# left drag would move a window: a meltygui window's bare areas (its
|
|
1585
|
+
# resize handle) and the OS window's drag strip / drag-anywhere
|
|
1586
|
+
# background. Off = the normal arrow there.
|
|
1587
|
+
window_move_cursor = True
|
|
1588
|
+
|
|
1589
|
+
# Which window controls the frameless chrome shows, and on which
|
|
1590
|
+
# side. "" (the default) follows the DESKTOP's own title-bar button
|
|
1591
|
+
# setting, what GTK / Qt header bars follow (gl_gui/titlebar_buttons
|
|
1592
|
+
# .py: the GNOME key `org.gnome.desktop.wm.preferences button-layout`
|
|
1593
|
+
# via gsettings — GNOME, Budgie, and any desktop with a dconf
|
|
1594
|
+
# profile, Hyprland included — Cinnamon's and MATE's keys, KDE's
|
|
1595
|
+
# kwinrc, xfwm4's button_layout, then the settings portal), read on
|
|
1596
|
+
# a background thread at boot, on focus gain and every
|
|
1597
|
+
# titlebar_button_refresh_s. A GNOME-syntax string pins it instead:
|
|
1598
|
+
# "left:right", comma-separated minimize / maximize / close —
|
|
1599
|
+
# "close,minimize,maximize:" puts every control on the left,
|
|
1600
|
+
# ":minimize,close" drops the maximize button, "" + no colon is all
|
|
1601
|
+
# left (mutter's rule). Applied live (each frame).
|
|
1602
|
+
# [tint=(0.55, 0.75, 0.35)]
|
|
1603
|
+
titlebar_button_layout = ""
|
|
1604
|
+
# Seconds between re-reads of the desktop's button setting while
|
|
1605
|
+
# frames render (0 = only at boot and on focus gain).
|
|
1606
|
+
# [tint=(0.55, 0.75, 0.35)]
|
|
1607
|
+
titlebar_button_refresh_s = 30
|
|
1608
|
+
# On Lukas's patched Hyprland (the compositor has
|
|
1609
|
+
# general:left_drag_move) the chrome also shows the desktop's
|
|
1610
|
+
# window-gesture toggle — the hyprbars `state = "left_drag_move"`
|
|
1611
|
+
# button: lit while the COMPOSITOR moves this app's windows on a
|
|
1612
|
+
# plain left drag and resizes them on a right drag, faded while the
|
|
1613
|
+
# app is in left_drag_move_exclude + right_drag_resize_exclude and
|
|
1614
|
+
# does both itself (drag-anywhere xdg move, right-drag through the
|
|
1615
|
+
# edge physics, nested meltygui windows' own right-drag). A click flips
|
|
1616
|
+
# it through desktop/left-drag-toggle --gestures (persisted by the
|
|
1617
|
+
# desktop's Settings). Innermost of the right group.
|
|
1618
|
+
# Off = never shown. (gl_gui/hypr_left_drag.py)
|
|
1619
|
+
# [tint=(0.55, 0.75, 0.35)]
|
|
1620
|
+
titlebar_move_toggle = True
|
|
1621
|
+
|
|
1622
|
+
# px hit zones for edge/corner resize on the undecorated window.
|
|
1623
|
+
resize_border = 6
|
|
1624
|
+
resize_corner = 18
|
|
1625
|
+
|
|
1626
|
+
# The GLFW window's four edges are collision edges in the column
|
|
1627
|
+
# edge system, one level above the nested meltygui windows
|
|
1628
|
+
# (gl_gui/os_edges.py): a meltygui window edge or a column cascade
|
|
1629
|
+
# pushed into the OS edge moves it (the surface grows, or the
|
|
1630
|
+
# window moves), the screen's work area is the wall outside it (its
|
|
1631
|
+
# position from the GNOME extension's feed — installation_helper
|
|
1632
|
+
# — glfw on X11), and an edge blocked by a wall grows its window on
|
|
1633
|
+
# the other side, just like a meltygui window's edge against the
|
|
1634
|
+
# display. Off, or with no position feed: the display edges are
|
|
1635
|
+
# immovable walls and the old in-display pin-and-slide remains.
|
|
1636
|
+
push_os_window_edges = True
|
|
1637
|
+
# A window MOVED by hand (left-drag) pushes the OS window's edge it
|
|
1638
|
+
# runs into out of its way, like any collision — but the move
|
|
1639
|
+
# itself is not clamped: the OS edge stops at the screen and the
|
|
1640
|
+
# window keeps going, so a window can be dragged partly off the
|
|
1641
|
+
# display on purpose (Lukas 08-27) - except above the display's
|
|
1642
|
+
# TOP (window_top_hard_limit).
|
|
1643
|
+
window_move_pushes_os_edges = True
|
|
1644
|
+
# A meltygui window's TOP never passes the top of the DISPLAY (the
|
|
1645
|
+
# work area, os_frame.display_rect): a hand move - its own or a
|
|
1646
|
+
# parent's it rides with - first pushes the OS edge back to the
|
|
1647
|
+
# screen as usual, then the remainder is clamped, so the window's
|
|
1648
|
+
# header always stays reachable (Lukas 08-28). The other three
|
|
1649
|
+
# sides stay free.
|
|
1650
|
+
window_top_hard_limit = True
|
|
1651
|
+
# Console trace of the OS edge model (foreign moves / resizes seen,
|
|
1652
|
+
# OS edges pushed and the surface request per frame). Off: it prints
|
|
1653
|
+
# per push and per frame, a real cost at 120 fps.
|
|
1654
|
+
push_os_window_edges_trace = False
|
|
1655
|
+
# Hyprland has no window-geometry event, so the position feed
|
|
1656
|
+
# (geometry_feed's hyprland backend) POLLS its request intervals
|
|
1657
|
+
# this often on its own thread - a `j/clients` round trip is
|
|
1658
|
+
# ~0.03 ms, so 120 Hz is reasonable; lower it temporarily to reduce
|
|
1659
|
+
# the OS edge physics' reaction time on purpose.
|
|
1660
|
+
hyprland_feed_poll_hz = 120
|
|
1661
|
+
|
|
1662
|
+
# Tint of the OS-window chrome: the minimize / maximize / close
|
|
1663
|
+
# controls titlebar.py draws top-right. Each is painted exactly like
|
|
1664
|
+
# a window header's close button (draw_header_end's flat_button),
|
|
1665
|
+
# with this tint set in the style manager the way the header runs
|
|
1666
|
+
# under its window's tint — copy a window's tint here to match it.
|
|
1667
|
+
# [tint=(0.55, 0.75, 0.35)]
|
|
1668
|
+
melty_window_tint = (0.653, 0.758, 0.806)
|
|
1669
|
+
|
|
1670
|
+
# Tint of a meltygui APP's root surface (surface.Surface.frame): the
|
|
1671
|
+
# ground every @glfw_window body draws on, painted through draw_bg
|
|
1672
|
+
# exactly as the studio's Main Window paints its desktop, so a
|
|
1673
|
+
# window filling the surface sits at bg depth 1 like a studio window
|
|
1674
|
+
# (at depth 0 over a black bg stack every root came out black,
|
|
1675
|
+
# 09-12). A `@glfw_window(tint=...)` overrides it per window. The
|
|
1676
|
+
# studio's default draw_state tint, so the two look alike.
|
|
1677
|
+
# [tint=(0.55, 0.75, 0.35)]
|
|
1678
|
+
app_root_tint = (0.11, 0.12, 0.14)
|
|
1679
|
+
|
|
1680
|
+
# Rounded corners on the frameless OS window (px; 0 = square). The
|
|
1681
|
+
# window is created with a transparent framebuffer (boot-time -
|
|
1682
|
+
# restart to change 0 ↔ >0) and titlebar.composite_window_frame runs
|
|
1683
|
+
# last in Melty.post_frame: a fullscreen pass premultiplying the
|
|
1684
|
+
# frame by the surface's rounded-rect coverage (anti-aliased mask),
|
|
1685
|
+
# which also clips the alpha imgui's blending leaves below 1 -
|
|
1686
|
+
# without it the desktop would bleed through every translucent
|
|
1687
|
+
# draw. The radius itself applies live; 0 while maximized.
|
|
1688
|
+
window_corner_radius = 14
|
|
1689
|
+
|
|
1690
|
+
# Client-side window shadow (GNOME draws none for Wayland clients):
|
|
1691
|
+
# px of transparent margin the OS surface keeps around the content.
|
|
1692
|
+
# imgui sees only the content (SplitOverlayRenderer insets the
|
|
1693
|
+
# viewport and offsets the pointer); the masks cover the whole
|
|
1694
|
+
# surface, and the shadow pass (ShadowPass, frame_* uniforms)
|
|
1695
|
+
# writes whatever shadow lands outside the content with premultiplied
|
|
1696
|
+
# alpha - the inner windows' own shadow casts, continued beyond the
|
|
1697
|
+
# content. This is the FLOOR: the ceiling grows to the shadow's reach on
|
|
1698
|
+
# the current surface (titlebar.shadow_reach, from the cast
|
|
1699
|
+
# shader's terms - ~80 px at 4072 wide, ~144 at 7680), since a
|
|
1700
|
+
# margin shorter than the shadow cuts it mid-fall as a hard band.
|
|
1701
|
+
# Collapses to 0 while maximized / fullscreen. 0 = no margin.
|
|
1702
|
+
# Applies live.
|
|
1703
|
+
window_shadow_margin = 40
|
|
1704
|
+
|
|
1705
|
+
# add_shadow lift of the whole content rect over the transparent
|
|
1706
|
+
# surroundings (draw_melty_windows) - how pronounced the OS window's
|
|
1707
|
+
# shadow is. Depth is at paint rank 0: keep it deep below the
|
|
1708
|
+
# windows' ranks (they start at layer 64) or it would flatten the
|
|
1709
|
+
# inner windows' own shadow. 0 = only the root's own mark casts.
|
|
1710
|
+
window_shadow_lift = 20
|
|
1711
|
+
# add_shadow() rect marks stamped as ONE instanced draw per blend
|
|
1712
|
+
# equation (blit_offscreen._stamp_shadow_marks_batched) instead of
|
|
1713
|
+
# ~10 GL calls per mark: 2.5 ms → ~0.3 ms a frame with ~280 marks.
|
|
1714
|
+
# Off = the per-mark path (compare if a shadow looks different).
|
|
1715
|
+
# [tint=(0.95, 0.55, 0.15)]
|
|
1716
|
+
batch_shadow_stamps = True
|
|
1717
|
+
# finalize_captures rebuilds the tile / full depth masks and the glow
|
|
1718
|
+
# buffer (passes 4–6) only when their INPUTS changed — mask rects,
|
|
1719
|
+
# shadow marks, retained emitters, window order — and keeps last
|
|
1720
|
+
# frame's textures otherwise (a keystroke or selection drag changes
|
|
1721
|
+
# pixels, not geometry). Off = the old rebuild-every-frame path.
|
|
1722
|
+
# [tint=(0.95, 0.55, 0.15)]
|
|
1723
|
+
mask_rebuild_on_change = True
|
|
1724
|
+
|
|
1725
|
+
@defaults(tint=(0.635, 0.728, 0.725))
|
|
1726
|
+
class Style:
|
|
1727
|
+
# Ceiling on the PERCEIVED brightness (0.299r + 0.587g + 0.114b) of
|
|
1728
|
+
# the imgui widget fills the style manager derives from the window
|
|
1729
|
+
# tint — buttons, frame backgrounds (text edits, drag/slider tracks)
|
|
1730
|
+
# and slider grabs — applied in ImGuiStyleManager.set_imgui_tint
|
|
1731
|
+
# right after the hsv transform. Those fills sit under light text,
|
|
1732
|
+
# so a bright background tint (v -> 1) lifted them to the text's
|
|
1733
|
+
# brightness and the widgets read blank; the cap SCALES the channels
|
|
1734
|
+
# (hue and saturation kept) instead of washing toward gray. Text,
|
|
1735
|
+
# check-mark and window/header colors are not capped. Read live on
|
|
1736
|
+
# every set_imgui_tint call. 0 disables.
|
|
1737
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
1738
|
+
widget_max_brightness = 0.3
|
|
1739
|
+
# How far a tint chip's edit (draw_tuple_fast: window-header tints,
|
|
1740
|
+
# editor tab tints, file-row tints) cascades through the blit cache.
|
|
1741
|
+
# Every LIVE change from the picker invalidates the chip's host and
|
|
1742
|
+
# its children to tint_edit_live_depth (1 = the host + its direct
|
|
1743
|
+
# children — the bg the tint paints and the rows/headers sitting
|
|
1744
|
+
# right on it); a full invalidate_up per frame walked the whole
|
|
1745
|
+
# subtree and was the drag's cost. CLOSING the picker (click away,
|
|
1746
|
+
# Esc, re-click) runs one deep cascade to tint_edit_close_depth so
|
|
1747
|
+
# every nested tile under the host settles on the final colour.
|
|
1748
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
1749
|
+
tint_edit_live_depth = 1
|
|
1750
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
1751
|
+
tint_edit_close_depth = 10
|
|
1752
|
+
|
|
1753
|
+
@defaults(tint=(0.103, 0.341, 0.617))
|
|
1754
|
+
class WindowSettings:
|
|
1755
|
+
# Sticky resize: re-anchor the window top at the drag-start point each
|
|
1756
|
+
# frame so only the min-on-display clamp displaces it.
|
|
1757
|
+
sticky_drag = True
|
|
1758
|
+
|
|
1759
|
+
# Breathing room, in px, left at every display edge by
|
|
1760
|
+
# Melty.clamp_window_pos - a bound applied whenever a window is
|
|
1761
|
+
# PLACED programmatically (summoned by the dock / a search hit /
|
|
1762
|
+
# Ctrl+Shift+F, or shown for the first time), so it can't open half
|
|
1763
|
+
# off-screen or with its bottom below the bottom of the display.
|
|
1764
|
+
# Dragging is unaffected: a window you drag off the edge just
|
|
1765
|
+
# stays where you put it. A window taller/wider than the display
|
|
1766
|
+
# keeps its top-left in view and overflows the far edge. Read live.
|
|
1767
|
+
edge_margin = 20
|
|
1768
|
+
|
|
1769
|
+
@defaults(tint=(0.719, 0.478, 0.208))
|
|
1770
|
+
class Orchestrator:
|
|
1771
|
+
# Replay pacing multiplier over the recorded timeline: 1.0 replays in
|
|
1772
|
+
# real time, 2.0 twice as fast. The event stream keeps its ordering
|
|
1773
|
+
# either way; cues still gate progress regardless of speed. Read live.
|
|
1774
|
+
# [tint=(0.939, 0.453, 0.245)]
|
|
1775
|
+
replay_speed = 1.0
|
|
1776
|
+
# How many frames a replay waits at a cue for the expected undo-stack
|
|
1777
|
+
# change to appear before trying its correction (re-aiming the click
|
|
1778
|
+
# at the cue target's LIVE rect), and again before aborting. At 120fps
|
|
1779
|
+
# this is ~0.75s — enough for background converters to land a value.
|
|
1780
|
+
# [tint=(0.939, 0.453, 0.245)]
|
|
1781
|
+
cue_wait_frames = 90
|
|
1782
|
+
# Cursor moves smaller than this (px, either axis) are not recorded —
|
|
1783
|
+
# keeps a long hover from bloating the event list with jitter. Replay
|
|
1784
|
+
# interpolates nothing, so keep it small or drags get steppy.
|
|
1785
|
+
# [tint=(0.939, 0.453, 0.245)]
|
|
1786
|
+
move_sample_min_px = 1.0
|
|
1787
|
+
# When True a cue only matches a live change whose recorded value repr
|
|
1788
|
+
# equals the recorded one - strict verification. Off by default:
|
|
1789
|
+
# value reprs drift for coalesced drags, the change type + target
|
|
1790
|
+
# name is the reliable part of the anchor.
|
|
1791
|
+
cue_match_values = False
|
|
1792
|
+
# change_value's drag servo: the first nudge (px) that measures the
|
|
1793
|
+
# live gain, the per-step travel cap (a wild residual/gain estimate
|
|
1794
|
+
# can't fling the cursor across the screen), and the step budget
|
|
1795
|
+
# before "didn't converge".
|
|
1796
|
+
# [tint=(0.939, 0.453, 0.245)]
|
|
1797
|
+
servo_probe_px = 8.0
|
|
1798
|
+
# [tint=(0.939, 0.453, 0.245)]
|
|
1799
|
+
servo_max_step_px = 400.0
|
|
1800
|
+
# [tint=(0.939, 0.453, 0.245)]
|
|
1801
|
+
servo_max_steps = 60
|
|
1802
|
+
# How many times change_value re-tries the SAME collapsed/closed gate
|
|
1803
|
+
# (it re-closed, or the fix missed) before giving up. Distinct gates
|
|
1804
|
+
# on the way in are passes, not attempts — a deep nest never counts
|
|
1805
|
+
# against this.
|
|
1806
|
+
# [tint=(0.939, 0.453, 0.245)]
|
|
1807
|
+
gate_attempts = 100
|
|
1808
|
+
# Precondition fixes, ranked by ONE number — how much of the user's
|
|
1809
|
+
# state each disturbs: the cheapest applicable fix runs first, the
|
|
1810
|
+
# predicate is re-checked, the next runs only when it did not help.
|
|
1811
|
+
# A command may cap what it is allowed to disturb (max_disturbance).
|
|
1812
|
+
# [tint=(0.62, 0.55, 0.85)]
|
|
1813
|
+
fix_costs = {"re_pick": 0, "raise": 1, "scroll": 2, "expand": 2,
|
|
1814
|
+
"move": 3, "open": 4, "anchor_window_penalty": 1}
|
|
1815
|
+
# [tint=(0.62, 0.55, 0.85)]
|
|
1816
|
+
max_disturbance = 10
|
|
1817
|
+
# A fix's own press point can need fixing (an obscurer's header is
|
|
1818
|
+
# itself covered): sub-goals nest at most this deep. Expanding a
|
|
1819
|
+
# covered gate is already three levels (expand → raise its window →
|
|
1820
|
+
# the header's own re-pick / move), so 2 gave up on the common case.
|
|
1821
|
+
# [tint=(0.62, 0.55, 0.85)]
|
|
1822
|
+
fix_depth = 4
|
|
1823
|
+
# The orchestrator window re-lists each visible command's unmet
|
|
1824
|
+
# preconditions (closed / collapsed / covered …) this often, in
|
|
1825
|
+
# frames — a live view of what the solver would do next.
|
|
1826
|
+
# [tint=(0.62, 0.55, 0.85)]
|
|
1827
|
+
precondition_refresh_frames = 20
|
|
1828
|
+
# A window raise only records as a "raise" cue when the press that
|
|
1829
|
+
# caused it was an EXPLICIT one: on a window's header band, or
|
|
1830
|
+
# outside the raised window altogether (a fast-dock row, another
|
|
1831
|
+
# window's button). A click inside a window's body raises it too,
|
|
1832
|
+
# and those press-raises were landing in takes as stray raise
|
|
1833
|
+
# commands (Lukas 09-01). Off = every actual restack records.
|
|
1834
|
+
# [tint=(0.62, 0.55, 0.85)]
|
|
1835
|
+
raise_cue_needs_explicit_press = True
|
|
1836
|
+
# A gate's control (the expand chevron) is small: a re-pick for a
|
|
1837
|
+
# covered gate press stays within this many px of the demonstrated
|
|
1838
|
+
# offset, else the cover is answered by a raise / move.
|
|
1839
|
+
# [tint=(0.62, 0.55, 0.85)]
|
|
1840
|
+
gate_hit_radius_px = 6.0
|
|
1841
|
+
# A synthesized header press (raise / move) lands at the MIDDLE of
|
|
1842
|
+
# the header strip between these two margins: the left one clears
|
|
1843
|
+
# the collapse chevron, the right one the close / pin buttons.
|
|
1844
|
+
# [tint=(0.62, 0.55, 0.85)]
|
|
1845
|
+
header_safe_left_px = 40.0
|
|
1846
|
+
# [tint=(0.62, 0.55, 0.85)]
|
|
1847
|
+
header_safe_right_px = 80.0
|
|
1848
|
+
# Height of the strip a header press may land in.
|
|
1849
|
+
# [tint=(0.62, 0.55, 0.85)]
|
|
1850
|
+
header_height_px = 24.0
|
|
1851
|
+
# How far past the press point a moved window is pushed.
|
|
1852
|
+
# [tint=(0.62, 0.55, 0.85)]
|
|
1853
|
+
uncover_margin_px = 12.0
|
|
1854
|
+
# A replayed window move verifies by geometry: the window's corner
|
|
1855
|
+
# must land within this many px of the recorded delta.
|
|
1856
|
+
# [tint=(0.62, 0.55, 0.85)]
|
|
1857
|
+
move_tolerance_px = 4.0
|
|
1858
|
+
# Wheel steps a scroll fix may send before giving up.
|
|
1859
|
+
# [tint=(0.62, 0.55, 0.85)]
|
|
1860
|
+
scroll_attempts = 40
|
|
1861
|
+
# change_value presses only once the target's tile reports hover
|
|
1862
|
+
# (its wrapper ran live, so the imgui widget is submitted — a press
|
|
1863
|
+
# on a blit-cached tile reaches only the window's move handle). This
|
|
1864
|
+
# many pumps is the cap for a view that never reports hover.
|
|
1865
|
+
# [tint=(0.939, 0.453, 0.245)]
|
|
1866
|
+
settle_hover_pumps = 30
|
|
1867
|
+
# After a fix reflowed the UI (expand / scroll / move): how many pumps
|
|
1868
|
+
# to wait for the target to be laid out again and hold still before
|
|
1869
|
+
# its press point is read.
|
|
1870
|
+
# [tint=(0.939, 0.453, 0.245)]
|
|
1871
|
+
layout_settle_pumps = 30
|
|
1872
|
+
# The virtual cursor's travel speed for synthesized moves (an
|
|
1873
|
+
# approach to a target, a gate click, the continuous-mouse glide):
|
|
1874
|
+
# WALL-CLOCK paced — a per-frame step (60 px/pump) was ~7,000 px/s
|
|
1875
|
+
# at 120 fps, i.e. invisible. A glide lasts distance /
|
|
1876
|
+
# glide_px_per_second, clamped to [glide_min_s, glide_max_s].
|
|
1877
|
+
# [tint=(0.939, 0.453, 0.245)]
|
|
1878
|
+
glide_px_per_second = 1400.0
|
|
1879
|
+
# [tint=(0.939, 0.453, 0.245)]
|
|
1880
|
+
glide_min_s = 0.18
|
|
1881
|
+
# [tint=(0.939, 0.453, 0.245)]
|
|
1882
|
+
glide_max_s = 0.9
|
|
1883
|
+
# Continuous mouse for EVERY injection (not just change_value's own
|
|
1884
|
+
# approach): a move/press far from the virtual cursor glides there
|
|
1885
|
+
# first (glide_px_per_second / glide_min_s / glide_max_s), so reused takes —
|
|
1886
|
+
# gate fragments, offset clicks, a replay resuming after a remap —
|
|
1887
|
+
# travel instead of snapping. Off = the raw recorded/synthesized
|
|
1888
|
+
# positions.
|
|
1889
|
+
# [tint=(0.939, 0.453, 0.245)]
|
|
1890
|
+
continuous_mouse = True
|
|
1891
|
+
|
|
1892
|
+
@defaults(tint=(0.103, 0.341, 0.617))
|
|
1893
|
+
class FastDock:
|
|
1894
|
+
# Floor on the hsv VALUE of an OPEN (active) row's name/icon text in
|
|
1895
|
+
# the Fast Dock, applied AFTER the theme mix (fast_dock.draw_fast_dock
|
|
1896
|
+
# -> _floor_value). The row text is the window's tint pushed through
|
|
1897
|
+
# make_color_rgb, so a dark window tint scaled toward black and the
|
|
1898
|
+
# open row read no brighter than a closed one; the floor lifts just
|
|
1899
|
+
# the value (hue and saturation kept) so every active row stays
|
|
1900
|
+
# legible. The summon button is untouched. 0 disables. Read live.
|
|
1901
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
1902
|
+
active_text_min_brightness = 0.55
|
|
1903
|
+
# Same floor for CLOSED (inactive) rows. Their text mix is already
|
|
1904
|
+
# dim by design (closed_text_value in draw_fast_dock), so a dark
|
|
1905
|
+
# window tint took it below reading contrast against the dock
|
|
1906
|
+
# background. Keep this under active_text_min_brightness or open and
|
|
1907
|
+
# closed rows stop reading as different states. 0 disables. Read live.
|
|
1908
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
1909
|
+
inactive_text_min_brightness = 0.45
|
|
1910
|
+
# How many of the most recently first-seen windows
|
|
1911
|
+
# (AppModel.render_windows) the Important tab lists under its
|
|
1912
|
+
# "Recently added" heading, newest first. 0 hides the section.
|
|
1913
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
1914
|
+
recently_added_count = 3
|
|
1915
|
+
|
|
1916
|
+
@defaults(tint=(0.478, 0.053, 0.053))
|
|
1917
|
+
class CrashReports:
|
|
1918
|
+
# Every trace print_stack_trace prints is also written, ANSI-stripped,
|
|
1919
|
+
# as a text file under `directory` (glfw_utils.save_crash_report);
|
|
1920
|
+
# the Crash Reports window (view/playground/crash_reports.py) lists
|
|
1921
|
+
# them. Off = print only.
|
|
1922
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
1923
|
+
auto_save = True
|
|
1924
|
+
# Where the reports go — one file per trace, named by time + error.
|
|
1925
|
+
# [tint=(0.35, 0.85, 0.94), show_tint=True]
|
|
1926
|
+
directory = "~/.lsd/crash_reports"
|
|
1927
|
+
# The oldest reports are deleted once more than this many exist, so
|
|
1928
|
+
# a crash loop can't fill the disk. 0 = keep everything.
|
|
1929
|
+
# [tint=(0.994, 0.872, 0.0), show_tint=True]
|
|
1930
|
+
max_reports = 300
|
|
1931
|
+
|
|
1932
|
+
# [icon=""]
|
|
1933
|
+
@defaults(tint=(0.427, 0.541, 0.616))
|
|
1934
|
+
class ContextMenu:
|
|
1935
|
+
# Which tab a newly opened context menu selects, as an index into its
|
|
1936
|
+
# tab bar: 0 Info, 1 Config, 2 view type, 3 Eval, 4 Input, 5 Tint.
|
|
1937
|
+
default_tab = 0
|
|
1938
|
+
|
|
1939
|
+
# Code tab: hide render-dispatch stack frames (the render_func
|
|
1940
|
+
# dispatch / draw_inner_main, draw_any re-dispatch - the same
|
|
1941
|
+
# _is_dispatch_frame filter the func-stack stacks use) so the trace
|
|
1942
|
+
# reads caller → caller → view function.
|
|
1943
|
+
code_tab_hide_dispatch = True
|
|
1944
|
+
|
|
1945
|
+
# ── Info tab source dropdown styling ────────────────────────────────
|
|
1946
|
+
# Row wash + trigger tint marking the source actively driving a param.
|
|
1947
|
+
active_source_tint = (0.9, 0.8, 0.2)
|
|
1948
|
+
# Row LABEL text pulled toward the menu background (0 = the stock
|
|
1949
|
+
# near/black dd text, 1 = invisible) so the active-source yellow
|
|
1950
|
+
# stands out against quiet rows.
|
|
1951
|
+
source_text_toward_bg = 0.55
|
|
1952
|
+
|
|
1953
|
+
@defaults(tint=(0.378, 0.286, 0.201))
|
|
1954
|
+
class Collection:
|
|
1955
|
+
pre_load_items = 26
|
|
1956
|
+
placeholder_height = 30.0
|
|
1957
|
+
drop_tail_height = 8
|
|
1958
|
+
# Drag-and-drop chrome (slot lines, the home icon) starts INVISIBLE
|
|
1959
|
+
# at pickup and eases up to full opacity once the cursor has
|
|
1960
|
+
# travelled this many px (cumulative path length, never fading back
|
|
1961
|
+
# on a return trip) - nothing pops in on a short drag. 0 = instant.
|
|
1962
|
+
dnd_reveal_distance = 10.0
|
|
1963
|
+
|
|
1964
|
+
max_preferred_header_width = 70
|
|
1965
|
+
preferred_header_width = 132
|
|
1966
|
+
|
|
1967
|
+
# [icon=""]
|
|
1968
|
+
@defaults(tint=(0.65, 0.385, 0.069, 1.0))
|
|
1969
|
+
class SearchSettings:
|
|
1970
|
+
# Auto-scroll to the current match while the search term is being
|
|
1971
|
+
# typed. When False, typing only recounts/highlights in place; the
|
|
1972
|
+
# view scrolls to the current match only on explicit navigation
|
|
1973
|
+
# (Enter / Shift+Enter / the find bar's arrows).
|
|
1974
|
+
scroll_while_typing = True
|
|
1975
|
+
|
|
1976
|
+
# Search matches are highlighted with a circular gradient "glow" that
|
|
1977
|
+
# radiates out from the matched rectangle (rounded-rect cutout), with the
|
|
1978
|
+
# rect itself cut out so the matched text stays readable. The CURRENT
|
|
1979
|
+
# match uses ActiveElement; every other match uses InactiveElements, so
|
|
1980
|
+
# the two can be tuned (color/falloff/alpha/...) independently. Glows
|
|
1981
|
+
# combine where they overlap. Applies in both the text editor (draw_text)
|
|
1982
|
+
# and collections (draw_collection rows). See view/core_views/search_glow.py.
|
|
1983
|
+
|
|
1984
|
+
@defaults(tint=(0.406, 0.30, 0.16))
|
|
1985
|
+
class ActiveElement:
|
|
1986
|
+
gradient_color = (0.86, 0.67, 0.23) # RGB of the halo
|
|
1987
|
+
outline_color = (0.88, 0.56, 0.15) # RGB of the optional cutout outline
|
|
1988
|
+
falloff = 26.696 # px the glow radiates out past the match edge
|
|
1989
|
+
opacity = 0.176 # peak opacity, % at the cutout edge
|
|
1990
|
+
falloff_exp = 2.105 # >1 = bright inside the word, then drops off fast
|
|
1991
|
+
inner_pad = 0.00 # px the cutout is grown beyond the match rect
|
|
1992
|
+
cutout_radius = 5.0 # corner radius of the rounded cutout
|
|
1993
|
+
rings = 86 # radial tessellation steps (higher = smoother)
|
|
1994
|
+
corner_segments = 15 # arc subdivisions in each rounded cutout corner
|
|
1995
|
+
outline_alpha = 1.00 # 0 = rely on the glow's bright inner halo alone
|
|
1996
|
+
outline_thickness = 1.626
|
|
1997
|
+
|
|
1998
|
+
@defaults(tint=(0.36, 0.52, 0.93, 0.484))
|
|
1999
|
+
class InactiveElements:
|
|
2000
|
+
gradient_color = (0.73, 0.84, 0.91) # cooler hue so the active match stands out
|
|
2001
|
+
outline_color = (0.6, 0.72, 1.0)
|
|
2002
|
+
falloff = 15.664
|
|
2003
|
+
opacity = 0.077
|
|
2004
|
+
falloff_exp = 2.491
|
|
2005
|
+
inner_pad = 0.00
|
|
2006
|
+
cutout_radius = 5.00
|
|
2007
|
+
rings = 16
|
|
2008
|
+
corner_segments = 5
|
|
2009
|
+
outline_alpha = 1.00
|
|
2010
|
+
outline_thickness = 1.366
|
|
2011
|
+
|
|
2012
|
+
@defaults(tint=(0.58, 0.47, 0.24))
|
|
2013
|
+
class GlobalSearch:
|
|
2014
|
+
# Category order for the search selector and the All tab's interleave:
|
|
2015
|
+
# All shows each category's #1 hit first (in this order), then each
|
|
2016
|
+
# category's next-best hits up to all_tab_per_category per category.
|
|
2017
|
+
# Kinds not matching here fall in after these.
|
|
2018
|
+
search_priority = ("Toggles", "Actions", "Windows", "Code", "Text")
|
|
2019
|
+
# Hits each category contributes to the All tab (the #1 lands in the
|
|
2020
|
+
# top block; the rest sit under the category's own label).
|
|
2021
|
+
all_tab_per_category = 13
|
|
2022
|
+
# Files the Code tab lists at first - the rest fold into a trailing
|
|
2023
|
+
# "+ n more files" row that reveals this many more per pick. The
|
|
2024
|
+
# per-file row cap (FILE_ROW_CAP; "+ n more" inside a file) is
|
|
2025
|
+
# separate. 0 = list every file.
|
|
2026
|
+
code_files_per_page = 4
|
|
2027
|
+
# Lay the All tab out horizontally: one column per category (its
|
|
2028
|
+
# first on top, hits below), instead of the vertical Top-block
|
|
2029
|
+
# interleave.
|
|
2030
|
+
all_tab_horizontal = False
|
|
2031
|
+
# Per-category cap for the horizontal layout's columns (replaces
|
|
2032
|
+
# all_tab_per_category there - columns have the vertical room).
|
|
2033
|
+
all_tab_horizontal_per_category = 15
|
|
2034
|
+
# Where the window may reappear on Ctrl+Shift+S: its top edge is
|
|
2035
|
+
# pushed down to at least this fraction of the display height. The
|
|
2036
|
+
# window remembers its last spot otherwise - 0.5 = never above the
|
|
2037
|
+
# middle of the screen, 0.0 = reopen it where it was closed.
|
|
2038
|
+
summon_min_top_fraction = 0.5
|
|
2039
|
+
# Seconds a keystroke must sit unchanged before a search pass runs
|
|
2040
|
+
# (the exact pass and the full-text trigram pass share this; tab
|
|
2041
|
+
# switches and load-all skip this - no text changed). Typing pays
|
|
2042
|
+
# nothing on the render thread: the passes run on a background
|
|
2043
|
+
# worker (_kick_search) and repaint when their hits arrive.
|
|
2044
|
+
input_debounce_s = 0.15
|
|
2045
|
+
# Seconds the query must sit unchanged before the typo-tolerant
|
|
2046
|
+
# (fuzzy) Code pass runs (measured from the keystroke, so the worker
|
|
2047
|
+
# sleeps the remainder of input_debounce_s). Fuzzy hits arrive as
|
|
2048
|
+
# a trailing section, never moving the hits already shown.
|
|
2049
|
+
fuzzy_debounce_s = 0.2
|
|
2050
|
+
|
|
2051
|
+
@defaults(tint=(0.47, 0.463, 0.417))
|
|
2052
|
+
class ScrollSettings:
|
|
2053
|
+
scroll_speed = 214
|
|
2054
|
+
max_increment_fraction = 0.169
|
|
2055
|
+
acceleration_threshold = 0.036 # ms
|
|
2056
|
+
bg_offset = 30
|
|
2057
|
+
debug_scroll = False
|
|
2058
|
+
# Compositor shadow under the scrollbar grab (add_shadow depth offset,
|
|
2059
|
+
# signed px from the view's surface; 0 disables). The grab gets
|
|
2060
|
+
# its own plane in the depth map, so it reads the same whether
|
|
2061
|
+
# it is drawn in the view list - lit by the composite, so it
|
|
2062
|
+
# otherwise inherits the view edge's specular rim and any
|
|
2063
|
+
# neighbour's cast shadow - or on the overlay list mid freeze-drag,
|
|
2064
|
+
# which renders after the composite.
|
|
2065
|
+
scrollbar_shadow_offset = 1.0
|
|
2066
|
+
|
|
2067
|
+
# [icon=""]
|
|
2068
|
+
@defaults(tint=(0.315, 0.489, 0.322))
|
|
2069
|
+
class LoadSave:
|
|
2070
|
+
# When True, save() ALSO writes the raw custom.ini (root_new eval blob)
|
|
2071
|
+
# as a backout alongside the new-pickle custom.pkl. Set False to go
|
|
2072
|
+
# pickle-only (skip the .ini dual-write). NOTE: model_server still treats
|
|
2073
|
+
# custom.ini as the main host identity / hot-reload cache anchor, so kee
|
|
2074
|
+
# this off until the .ini is fully deprecated.
|
|
2075
|
+
ini_save = False
|
|
2076
|
+
|
|
2077
|
+
|
|
2078
|
+
@defaults(tint=(0.04, 0.05, 0.07))
|
|
2079
|
+
class CodeEditor:
|
|
2080
|
+
# Record navigation (file tab switches, jump-to, split open/close)
|
|
2081
|
+
# onto NavUndo's own stack - separate from the Ctrl+Z edit history.
|
|
2082
|
+
# Step back/forward with Ctrl+Shift+Left/Right or the Fast Dock's
|
|
2083
|
+
# arrow buttons.
|
|
2084
|
+
undo_navigation = True
|
|
2085
|
+
# Also record the text caret (NavUndo.poll_caret): moves inside a
|
|
2086
|
+
# draw_text (arrow keys, clicks) and tab focus hopping between
|
|
2087
|
+
# draw_texts. Consecutive moves in one view fold into a single step
|
|
2088
|
+
# while they come within nav_caret_coalesce_s seconds of each other
|
|
2089
|
+
# AND stay within nav_caret_step_lines lines of where the step
|
|
2090
|
+
# already ended (an arrow-key walk = one step; a far click = a new
|
|
2091
|
+
# one). Typing never records (the edit stack does that caret), and
|
|
2092
|
+
# jumps / tab switches keep recording as locations. Needs
|
|
2093
|
+
# undo_navigation.
|
|
2094
|
+
undo_navigation_caret = True
|
|
2095
|
+
nav_caret_coalesce_s = 0.6
|
|
2096
|
+
nav_caret_step_lines = 10
|
|
2097
|
+
|
|
2098
|
+
# ── Text undo steps (UndoManager.record, IntelliJ-style) ──
|
|
2099
|
+
# Typing folds into one Ctrl+Z step while it stays in one place ( one
|
|
2100
|
+
# editor, keystrokes landing on the selection's caret edge, same
|
|
2101
|
+
# insert/delete direction) and, with undo_word_steps, until a new
|
|
2102
|
+
# word starts with a non-space typed character after whitespace: "hello
|
|
2103
|
+
# world" undoes as "world" then "hello"; a Backspace run mirrors this
|
|
2104
|
+
# (" world" then "hello"). No pause ever commits a step, and nothing
|
|
2105
|
+
# folds across an undo/redo. An edit that is not keystroke-sized -
|
|
2106
|
+
# inserts or removes a line (Enter + auto-indent), more than
|
|
2107
|
+
# undo_typing_max_chars characters at once (paste, tab, a completion,
|
|
2108
|
+
# a comment toggle) or replaces a selection - is always its own step.
|
|
2109
|
+
# Raise undo_typing_max_chars if fast typing on a slow frame splits
|
|
2110
|
+
# words too often (a frame's keystrokes arrive as one edit).
|
|
2111
|
+
undo_word_steps = True
|
|
2112
|
+
undo_typing_max_chars = 3
|
|
2113
|
+
|
|
2114
|
+
# ── Compare-split ribbons (open_files._draw_compare_ribbons) ──
|
|
2115
|
+
# Block colors by kind. Read live per frame.
|
|
2116
|
+
ribbon_insert_tint = (0.315, 0.928, 0.294) # lines only in the buffer
|
|
2117
|
+
ribbon_delete_tint = (0.737, 0.76, 0.767) # lines only in the reference
|
|
2118
|
+
ribbon_replace_tint = (0.294, 0.675, 0.928) # changed in place
|
|
2119
|
+
# Merge mode (merge_files) colors: a CONFLICT region - a pending edit
|
|
2120
|
+
# and an external edit touch the same original row and disagree.
|
|
2121
|
+
# Red on purpose: the eye must land here first.
|
|
2122
|
+
ribbon_conflict_tint = (0.93, 0.25, 0.25)
|
|
2123
|
+
# A conflict region whose pending side already equals the external
|
|
2124
|
+
# side (taken with the arrow, or edited to match) - no longer red.
|
|
2125
|
+
ribbon_resolved_tint = (0.55, 0.85, 0.55)
|
|
2126
|
+
# A DECLINED side's band (its ✗ marker set): grey, and the 4th
|
|
2127
|
+
# component scales the band's fill/edge alpha down - a rejected
|
|
2128
|
+
# change should recede, not glow.
|
|
2129
|
+
ribbon_declined_tint = (0.55, 0.58, 0.62, 0.45)
|
|
2130
|
+
# Shared fill alpha for the block washes AND the seam band - same fill
|
|
2131
|
+
# so highlight → band → highlight reads as ONE continuous shape.
|
|
2132
|
+
ribbon_fill_alpha = 0.10
|
|
2133
|
+
# Boundary stroke around the whole shape (wash edges + S-curves).
|
|
2134
|
+
ribbon_edge_alpha = 0.00
|
|
2135
|
+
ribbon_edge_thickness = -0.35
|
|
2136
|
+
# Thin insertion line where a side has no rows (pure insert/delete).
|
|
2137
|
+
ribbon_insertion_alpha = 0.242
|
|
2138
|
+
ribbon_insertion_thickness = 3
|
|
2139
|
+
# Seam curve sampling (smoothstep slices).
|
|
2140
|
+
ribbon_curve_steps = 40
|
|
2141
|
+
# AA feather for the seam band's S-curve edges: the band fills with
|
|
2142
|
+
# aliased triangles (per-triangle AA reads as seams), so its two
|
|
2143
|
+
# boundary curves are stroked with an antialiased polyline in the
|
|
2144
|
+
# FILL_COLOR at this thickness - same trick as Swoosh.aa_width in
|
|
2145
|
+
# Melty._draw_ribbon. 0 disables.
|
|
2146
|
+
ribbon_aa_width = 1.0
|
|
2147
|
+
# Signed depth offset for the shadow cast behind the whole swoosh
|
|
2148
|
+
# (washes + seam band, add_shadow semantics: positive lifts it off
|
|
2149
|
+
# the editor surface, negative carves a hole). 0 disables.
|
|
2150
|
+
ribbon_shadow_offset = 0.397
|
|
2151
|
+
# Card shadow under each of the Merge Files column's five cells
|
|
2152
|
+
# (files spread over their whole band, panes below their chevron
|
|
2153
|
+
# row - add_shadow semantics: positive lifts the card off the
|
|
2154
|
+
# column, negative sinks it). 0 disables.
|
|
2155
|
+
merge_column_shadow_offset = 0.5
|
|
2156
|
+
# Take-arrow chips riding the swooshes (pull a block from the
|
|
2157
|
+
# reference pane into the buffer): flat_buttons colored by the
|
|
2158
|
+
# block's ribbon tint - hover boost and text color come from
|
|
2159
|
+
# flat_button's own pipeline.
|
|
2160
|
+
take_arrow_size = 20.6
|
|
2161
|
+
take_arrow_alpha = 1.0
|
|
2162
|
+
# ── Editor tab bar (open_files.draw_code_editor) ──
|
|
2163
|
+
# Styling knobs for the file tabs, read live per frame. The ACTIVE
|
|
2164
|
+
# tab draws a tinted bg + text; INACTIVE tabs draw a MUTED bg
|
|
2165
|
+
# (the tab_inactive_bg_* knobs below) plus their own text knobs.
|
|
2166
|
+
#
|
|
2167
|
+
# The bg pair feeds flat_button's theme-mix pipeline (value /
|
|
2168
|
+
# saturation_scale of make_color_rgb).
|
|
2169
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
2170
|
+
tab_active_bg_brightness = 0.51
|
|
2171
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
2172
|
+
tab_active_bg_saturation = 1.184
|
|
2173
|
+
# Hard cap the active-tab bg is clamped to AFTER the hsv transform —
|
|
2174
|
+
# raise it along with tab_active_bg_brightness or the brightness
|
|
2175
|
+
# knob tops out here.
|
|
2176
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2177
|
+
tab_active_bg_max_brightness = 0.31
|
|
2178
|
+
# Inactive-tab bg: the same theme-mix pipeline, muted — lower
|
|
2179
|
+
# brightness / saturation and a cap well under the active tab's so
|
|
2180
|
+
# the selected tab still reads first. Alpha 0 = no bg at all.
|
|
2181
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
2182
|
+
tab_inactive_bg_brightness = 0.30
|
|
2183
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
2184
|
+
tab_inactive_bg_saturation = 0.45
|
|
2185
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2186
|
+
tab_inactive_bg_max_brightness = 0.08
|
|
2187
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2188
|
+
tab_inactive_bg_alpha = 0.6
|
|
2189
|
+
# Shadow lift (add_shadow offset) of the tab bgs — keep the inactive
|
|
2190
|
+
# one under the active so the selected tab pops out.
|
|
2191
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2192
|
+
tab_active_shadow_offset = 2.0
|
|
2193
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2194
|
+
tab_inactive_shadow_offset = 0.21
|
|
2195
|
+
# Closing a tab HOLDS the bar's layout (Safari-style: the next tab
|
|
2196
|
+
# slides into the closed slot at the closed tab's width) until the
|
|
2197
|
+
# mouse travels this many pixels, so repeated close × / middle
|
|
2198
|
+
# clicks on one spot close tab after tab. 0 = no hold.
|
|
2199
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2200
|
+
tab_close_hold_move_px = 8.0
|
|
2201
|
+
# The text pairs are FULL-RANGE hsv multipliers applied directly to
|
|
2202
|
+
# each tab's tint (open_files._tab_text_color → flat_button
|
|
2203
|
+
# text_color): brightness scales hsv value (0 = black, 1 = the
|
|
2204
|
+
# tint's own value, higher pushes toward full-bright), saturation
|
|
2205
|
+
# scales hsv saturation (0 = greyscale, 1 = the tint's own).
|
|
2206
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
2207
|
+
tab_active_text_brightness = 1.111
|
|
2208
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
2209
|
+
tab_active_text_saturation = 0.420
|
|
2210
|
+
# Floor on the ACTIVE tab label's hsv value AFTER the brightness
|
|
2211
|
+
# scale (same floor as the inactive one below) — a dark file tint
|
|
2212
|
+
# otherwise scales the selected tab's text toward black against its
|
|
2213
|
+
# bright bg.
|
|
2214
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
2215
|
+
tab_active_text_min_brightness = 0.83
|
|
2216
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
2217
|
+
tab_inactive_text_brightness = 0.390
|
|
2218
|
+
# [tint=(0.923, 0.989, 0.0), show_tint=True]
|
|
2219
|
+
tab_inactive_text_saturation = 0.522
|
|
2220
|
+
# Floor on the inactive-tab label's hsv value AFTER the brightness
|
|
2221
|
+
# scale — dark tints stay legible instead of scaling toward black.
|
|
2222
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
2223
|
+
tab_inactive_text_min_brightness = 0.387
|
|
2224
|
+
# Diff gap folds (open_files._diff_gap_folds): unchanged
|
|
2225
|
+
# context lines kept visible on each side of a change block; the
|
|
2226
|
+
# rest of the gap folds away, so collapse-all skims the changes
|
|
2227
|
+
# without scrolling.
|
|
2228
|
+
diff_fold_context = 2
|
|
2229
|
+
# Debug trace of the compare split's resolve, printed on every
|
|
2230
|
+
# CHANGE of its state (file, reference, loading, served/warm,
|
|
2231
|
+
# blocks, diff folds, switch, per-pane cursor offset + display
|
|
2232
|
+
# lines) - for pinning down a boot that shows the wrong fold
|
|
2233
|
+
# state. Read live; off = silent.
|
|
2234
|
+
trace_compare_boot = False
|
|
2235
|
+
# Tab tint for a file whose FileMeta carries none — the tab bar, the
|
|
2236
|
+
# compare files column, and the editor toolbar buttons all key off it.
|
|
2237
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
2238
|
+
tab_tint_fallback = (0.485, 0.61, 0.76)
|
|
2239
|
+
# Editor toolbar back/forward buttons (open_files._draw_editor_toolbar):
|
|
2240
|
+
# hsv SCALES applied straight to the target file's tint (1.0 = the
|
|
2241
|
+
# tint as is) before it reaches flat_button — its own saturation /
|
|
2242
|
+
# tint_value knobs only shape the theme colour mixed in at `factor`,
|
|
2243
|
+
# which left these buttons unmoved. The disabled side is theme grey
|
|
2244
|
+
# and carries no file tint, so nothing here touches it.
|
|
2245
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
2246
|
+
nav_button_saturation = 2.5
|
|
2247
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
2248
|
+
nav_button_value = 0.34
|
|
2249
|
+
# Hard cap the button bg is clamped to AFTER the scale — raise it
|
|
2250
|
+
# along with nav_button_value or the value knob tops out here.
|
|
2251
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2252
|
+
nav_button_max_brightness = 0.25
|
|
2253
|
+
# The arrow glyph on an enabled button: hsv scales of the target
|
|
2254
|
+
# file's UNSCALED tint (not the bg above — dimming the bg leaves the
|
|
2255
|
+
# glyph alone), handed to flat_button as text_color the way the tab
|
|
2256
|
+
# labels are. brightness scales value (1.0 = the tint's own, higher
|
|
2257
|
+
# pushes toward full-bright), saturation scales hsv saturation.
|
|
2258
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
2259
|
+
nav_button_text_brightness = 1.0
|
|
2260
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
2261
|
+
nav_button_text_saturation = 0.8
|
|
2262
|
+
# Floor on the glyph's hsv value AFTER the brightness scale — a dark
|
|
2263
|
+
# file tint stays legible instead of scaling toward black.
|
|
2264
|
+
# [tint=(0.13, 0.55, 0.13), show_tint=True]
|
|
2265
|
+
nav_button_text_min_brightness = 0.6
|
|
2266
|
+
# ColumnLayout padding the compare column renders with (cell content
|
|
2267
|
+
# is inset by this from its dividers on both sides). The layout
|
|
2268
|
+
# reframe math (open_files._cmp_layout_reframe) keys on the SAME
|
|
2269
|
+
# value - change them together by changing only this.
|
|
2270
|
+
compare_padding = 14.0
|
|
2271
|
+
# Compact file-column rows; shared by layout, paint and keyboard scroll.
|
|
2272
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
2273
|
+
compare_row_height = 20.0
|
|
2274
|
+
# Nearest baked JetBrains Mono size, in pixels before UI scaling.
|
|
2275
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
2276
|
+
compare_font_size = 16
|
|
2277
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
2278
|
+
compare_file_max_width = 650.0
|
|
2279
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
2280
|
+
compare_file_bg_value = 0.020
|
|
2281
|
+
# Unselected file labels in the files column (draw_changed_file_header):
|
|
2282
|
+
# the same hsv scale / floor as the tab_inactive_text_* pair, but
|
|
2283
|
+
# brighter — the column's unpainted rows draw no bg to read against.
|
|
2284
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
2285
|
+
compare_file_text_brightness = 0.75
|
|
2286
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
2287
|
+
compare_file_text_min_brightness = 0.66
|
|
2288
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
2289
|
+
compare_row_gap = 1.0
|
|
2290
|
+
|
|
2291
|
+
@defaults(tint=(0.72, 0.35, 0.3))
|
|
2292
|
+
class FileSafety:
|
|
2293
|
+
# Kill switch for folder_io's reconcile deletes: while True, a key
|
|
2294
|
+
# removed from a held folder tree never unlinks/rmtrees on disk (the
|
|
2295
|
+
# poller re-discovers the file and the key comes back). Flip off when
|
|
2296
|
+
# the file machinery has earned trust.
|
|
2297
|
+
block_file_delete = True
|
|
2298
|
+
|
|
2299
|
+
@defaults(tint=(0.103, 0.561, 0.145))
|
|
2300
|
+
class HostLifecycle:
|
|
2301
|
+
# Deregister a RenderHost from Melty.render_hosts (stops its background
|
|
2302
|
+
# draw/parse) once none of its consumer windows are active. Host + parse
|
|
2303
|
+
# stay cached; reopening re-registers (notify_on_change → register).
|
|
2304
|
+
deregister_idle = True
|
|
2305
|
+
# A consumer is gone when its window is abs_closed, or it hasn't
|
|
2306
|
+
# re-registered within this many frames (safety net for closes abs_closed
|
|
2307
|
+
# misses). Also the birth grace before a new host can be swept.
|
|
2308
|
+
idle_frames = 120
|
|
2309
|
+
# Trailing debounce (ms) on consumer-notify invalidations while the
|
|
2310
|
+
# host's value is being actively edited (typing). Each second editor
|
|
2311
|
+
# window over the same file is a consumer of the shared code_host -
|
|
2312
|
+
# without this it re-renders (and re-runs its background chain) on
|
|
2313
|
+
# every keystroke's finished reconvert. The notify is deferred and
|
|
2314
|
+
# re-armed per edit; it fires once, this long after the last local
|
|
2315
|
+
# edit. Notifies with no recent local edit (external file reload,
|
|
2316
|
+
# initial load) pass through live. 0 disables.
|
|
2317
|
+
consumer_notify_debounce_ms = 2000
|
|
2318
|
+
# Skip ALL RenderHost draws (the draw_main host loop) for this long
|
|
2319
|
+
# after each keypress while a draw_text editor is focused - the same
|
|
2320
|
+
# deferral the loop already applies during click/drag/scroll. Host
|
|
2321
|
+
# draws and deferrable background work (reconverts, saves) that
|
|
2322
|
+
# otherwise leak into typing frames; they catch up on a self-armed
|
|
2323
|
+
# wake once the window expires. 0 disables.
|
|
2324
|
+
host_typing_debounce_ms = 25
|
|
2325
|
+
|
|
2326
|
+
@defaults(tint=(0.181, 0.119, 0.294))
|
|
2327
|
+
class InputHandlerToggles:
|
|
2328
|
+
show_debug = False
|
|
2329
|
+
|
|
2330
|
+
# 3D mouse (3Dconnexion SpaceMouse). The device side is read by
|
|
2331
|
+
# events/space_mouse.py - the spacenavd socket client and the per-frame
|
|
2332
|
+
# pump that feeds the InputHandler a "space_mouse" axes event, each axis
|
|
2333
|
+
# the deflection integrated over the frame in full-deflection-seconds -
|
|
2334
|
+
# and the navigation knobs below are how draw_voxels turns those axes
|
|
2335
|
+
# into tilt / spin / roll / cam_zoom / pan (voxel_camera.apply_space_mouse),
|
|
2336
|
+
# so every sensitivity reads "per second at full push". All read live.
|
|
2337
|
+
@defaults(tint=(0.181, 0.119, 0.294))
|
|
2338
|
+
class SpaceMouse:
|
|
2339
|
+
# ── navigation (draw_voxels) ──
|
|
2340
|
+
|
|
2341
|
+
# Rotation model, independent of the mouse's
|
|
2342
|
+
# (Toggles.Voxels.mouse_navigation). "trackball": the puck's full
|
|
2343
|
+
# rotation vector rotates the view freely about the orbit center in
|
|
2344
|
+
# VIEW space, roll included (Blender's "Free" default) - the
|
|
2345
|
+
# camera's roll param carries the third degree of freedom.
|
|
2346
|
+
# "turntable": the puck's yaw (ry) spins about the world UP, and
|
|
2347
|
+
# its pitch (rx) tilts; the horizon never rolls, roll (rz) is ignored.
|
|
2348
|
+
navigation = "trackball"
|
|
2349
|
+
|
|
2350
|
+
# What a rotation turns about. "camera": the eye stays where it is
|
|
2351
|
+
# and the VIEW turns - looking around, the scene sweeps across the
|
|
2352
|
+
# screen (the orbit center rides along the new view direction).
|
|
2353
|
+
# "target": the camera orbits the volume's orbit target like the
|
|
2354
|
+
# mouse does - the volume turns in place on screen.
|
|
2355
|
+
pivot = "camera"
|
|
2356
|
+
|
|
2357
|
+
# Orbit sensitivity: radians per second at full deflection of a
|
|
2358
|
+
# rotation axis. Higher = faster orbit.
|
|
2359
|
+
# [tint=(0.181, 0.119, 0.294)]
|
|
2360
|
+
orbit_sensitivity = 1.50
|
|
2361
|
+
|
|
2362
|
+
# Translation sensitivity. pivot "camera": WORLD units per second
|
|
2363
|
+
# at full deflection on all three axes (right / up / forward — a
|
|
2364
|
+
# rigid flight, the volume is ~2 units across; nothing scales with
|
|
2365
|
+
# the camera distance). pivot "target": camera distances (cam_zoom)
|
|
2366
|
+
# per second in the screen plane, the mouse pan's rule. Higher =
|
|
2367
|
+
# faster.
|
|
2368
|
+
# [tint=(0.181, 0.119, 0.294)]
|
|
2369
|
+
pan_sensitivity = 1.0
|
|
2370
|
+
|
|
2371
|
+
# Zoom sensitivity, pivot "target" only: e-folds of cam_zoom per
|
|
2372
|
+
# second at full push / pull (tz). With pivot "camera" push / pull
|
|
2373
|
+
# is flight along the view at pan_sensitivity. Higher = faster.
|
|
2374
|
+
# [tint=(0.181, 0.119, 0.294)]
|
|
2375
|
+
zoom_sensitivity = 1.0
|
|
2376
|
+
|
|
2377
|
+
# Per-axis sensitivity, one float per degree of freedom, applied to
|
|
2378
|
+
# the normalized reading in space_mouse.normalize (so every view
|
|
2379
|
+
# sees it, on top of the orbit / pan / zoom sensitivities above).
|
|
2380
|
+
# 1.0 = as the device reports; 0 disables that axis. Translation:
|
|
2381
|
+
# tx right, ty up, tz push / pull. Rotation: rx pitch, ry yaw,
|
|
2382
|
+
# rz roll.
|
|
2383
|
+
# [tint=(0.181, 0.119, 0.294)]
|
|
2384
|
+
tx_sensitivity = 1.0
|
|
2385
|
+
# [tint=(0.181, 0.119, 0.294)]
|
|
2386
|
+
ty_sensitivity = 1.0
|
|
2387
|
+
# [tint=(0.181, 0.119, 0.294)]
|
|
2388
|
+
tz_sensitivity = 1.0
|
|
2389
|
+
# [tint=(0.181, 0.119, 0.294)]
|
|
2390
|
+
rx_sensitivity = 1.0
|
|
2391
|
+
# [tint=(0.181, 0.119, 0.294)]
|
|
2392
|
+
ry_sensitivity = 2.239
|
|
2393
|
+
# [tint=(0.181, 0.119, 0.294)]
|
|
2394
|
+
rz_sensitivity = 0.875
|
|
2395
|
+
|
|
2396
|
+
# Environment lighting the puck in draw_space_mouse: an HDR photo
|
|
2397
|
+
# from pbr.HDRIS ("studio", resources/hdri) or a cube map from
|
|
2398
|
+
# pbr.ENVIRONMENTS ("room", "outdoor"). Read live.
|
|
2399
|
+
environment = "studio"
|
|
2400
|
+
|
|
2401
|
+
# A real model of the device (OBJ / STL / GLB, absolute or relative
|
|
2402
|
+
# to the src tree) drawn instead of the procedural one. Parts whose
|
|
2403
|
+
# name contains "cap", "knob" or "puck" ride the reading (the
|
|
2404
|
+
# the cap); everything else is the base. Empty = procedural.
|
|
2405
|
+
# Model UP axis: "y" or "z" (CAD exports are usually Z-up).
|
|
2406
|
+
model_path = ""
|
|
2407
|
+
model_up = "z"
|
|
2408
|
+
|
|
2409
|
+
# How much of the WINDOW's tint colours the environment light on the
|
|
2410
|
+
# puck (0 = white light, 1 = fully the tint's hue). Read live.
|
|
2411
|
+
# [tint=(0.181, 0.119, 0.294)]
|
|
2412
|
+
environment_tint_strength = 0.6
|
|
2413
|
+
|
|
2414
|
+
# ── device (events/space_mouse.py) ──
|
|
2415
|
+
|
|
2416
|
+
# Master switch: off = the reader parks (socket closed) and no view
|
|
2417
|
+
# receives space_mouse events. Read live.
|
|
2418
|
+
enabled = True
|
|
2419
|
+
|
|
2420
|
+
# spacenavd's listen socket (protocol 0 stream). Debian/Ubuntu's
|
|
2421
|
+
# package installs here; /var/run/spnav.sock is the same path.
|
|
2422
|
+
socket_path = "/run/spnav.sock"
|
|
2423
|
+
|
|
2424
|
+
# The units spacenavd reports at full push / twist. 3Dconnexion
|
|
2425
|
+
# devices saturate at ±350 through spacenavd's default sensitivity;
|
|
2426
|
+
# raise your /etc/spnavrc sensitivity and this stays the ceiling
|
|
2427
|
+
# (readings clamp to ±1.0).
|
|
2428
|
+
full_deflection = 350
|
|
2429
|
+
|
|
2430
|
+
# Dead zone as a percentage of full deflection: readings below it are
|
|
2431
|
+
# zero (a resting cap never drifts the camera), the live range is
|
|
2432
|
+
# re-scaled so motion starts smoothly at the edge. spacenavd has its
|
|
2433
|
+
# own dead zone (spnavrc), this one stacks on top.
|
|
2434
|
+
dead_zone = 0.03
|
|
2435
|
+
|
|
2436
|
+
# Axis convention. The reader assumes spacenavd's graphics-style
|
|
2437
|
+
# frame: tx right, ty UP, tz toward the viewer (pull = +), rx pitch
|
|
2438
|
+
# about right, ry yaw about up, rz roll about the view axis. If the
|
|
2439
|
+
# daemon is configured for the device's original Z-up frame, flip
|
|
2440
|
+
# this so y / z (and ry / rz) swap into the frame above.
|
|
2441
|
+
swap_yz = False
|
|
2442
|
+
|
|
2443
|
+
# Flip the sign of individual axes: any of "tx", "ty", "tz", "rx",
|
|
2444
|
+
# "ry", "rz". The defaults match Blender (space_mouse.BLENDER_SIGNS,
|
|
2445
|
+
# measured); this is for a view that wants it otherwise. Applied
|
|
2446
|
+
# after swap_yz.
|
|
2447
|
+
invert_axes = ()
|
|
2448
|
+
|
|
2449
|
+
# A deflection older than this (no motion frame since) reads as
|
|
2450
|
+
# zero - spacenavd dying mid-push or a lost release frame must never
|
|
2451
|
+
# keep the camera moving. Devices report at 60–100 Hz while held.
|
|
2452
|
+
stale_s = 0.25
|
|
2453
|
+
|
|
2454
|
+
# Cap on the frame interval the pump integrates over: a stalled
|
|
2455
|
+
# frame (a load, a hotswap) hands the view at most this much motion
|
|
2456
|
+
# instead of a jump.
|
|
2457
|
+
max_frame_dt = 0.10
|
|
2458
|
+
|
|
2459
|
+
# Seconds between connection attempts while spacenavd is away.
|
|
2460
|
+
retry_s = 3.0
|
|
2461
|
+
|
|
2462
|
+
@defaults(tint=(0.652, 0.672, 0.733))
|
|
2463
|
+
class TerminalSettings:
|
|
2464
|
+
# Minimum logical terminal size, in pixels - independent of the window size.
|
|
2465
|
+
min_height = 605.7
|
|
2466
|
+
min_width = 94.154
|
|
2467
|
+
|
|
2468
|
+
@defaults(tint=(0.239, 0.435, 0.408))
|
|
2469
|
+
class Thermostat:
|
|
2470
|
+
# The thermostat web server (Desktop/thermostat/server.py). The proxy in
|
|
2471
|
+
# playground/thermostat_data.py pulls the chart histories from HERE,
|
|
2472
|
+
# not the raw jsonl files.
|
|
2473
|
+
server_url = "http://127.0.0.1:8765"
|
|
2474
|
+
# The charts' window query: hours back from now, or "all" for the whole
|
|
2475
|
+
# log (the server stride-samples each answer to ~2000 points either way).
|
|
2476
|
+
history_hours = "all"
|
|
2477
|
+
# How often the poller re-pulls the data (seconds).
|
|
2478
|
+
poll_s = 60.0
|
|
2479
|
+
|
|
2480
|
+
@defaults(tint=(0.478, 0.265, 0.265))
|
|
2481
|
+
class InvalidateTracker:
|
|
2482
|
+
keep_for_frames = 100
|
|
2483
|
+
enable = False
|
|
2484
|
+
draw_rect = True
|
|
2485
|
+
# [tint=(0.85, 0.45, 0.05), show_tint=True]
|
|
2486
|
+
invalidate_stack_trace = False
|
|
2487
|
+
# [tint=(0.028, 0.561, 0.115), show_tint=True]
|
|
2488
|
+
invalidate_request_render = False
|
|
2489
|
+
attrib_change_stack_trace = False
|
|
2490
|
+
# [tint=(0.0, 0.56, 0.872), show_tint=True]
|
|
2491
|
+
draw_bvh = False
|
|
2492
|
+
|
|
2493
|
+
|
|
2494
|
+
@defaults(tint=(0.16, 0.132, 0.194))
|
|
2495
|
+
class Fim:
|
|
2496
|
+
# Fill-in-the-middle code completion (ghost text) in code editors -
|
|
2497
|
+
# fim.py. Providers register with @fim_provider; `profile` names a
|
|
2498
|
+
# provider or a fim_profile() variant (fim_providers/profiles.py);
|
|
2499
|
+
# an editor can override it with draw_text(fim="...").
|
|
2500
|
+
enabled = True
|
|
2501
|
+
profile = "ollama"
|
|
2502
|
+
|
|
2503
|
+
# Idle time after the last keystroke before a request is sent.
|
|
2504
|
+
debounce_s = 0.25
|
|
2505
|
+
|
|
2506
|
+
# Only generate when the caret is at the end of its line (nothing but
|
|
2507
|
+
# whitespace after it) - never mid-line. Off = complete anywhere.
|
|
2508
|
+
only_at_line_end = True
|
|
2509
|
+
|
|
2510
|
+
# Ghost text is shown one CHUNK at a time: this many newline-
|
|
2511
|
+
# separated lines (a partial rest-of-line counts as one). Tab
|
|
2512
|
+
# accepts the chunk and the next one appears instantly from the
|
|
2513
|
+
# buffered completion - small chunks add more steering options.
|
|
2514
|
+
chunk_lines = 1
|
|
2515
|
+
|
|
2516
|
+
# Length of ONE provider request (tokens). The buffer refills with
|
|
2517
|
+
# a continuation request when it runs low, so this is the fetch
|
|
2518
|
+
# granularity, not a cap on how far repeated Tabs can go.
|
|
2519
|
+
max_tokens = 256
|
|
2520
|
+
|
|
2521
|
+
# Fetch the continuation while the current chunk is still showing
|
|
2522
|
+
# so the next Tab never waits.
|
|
2523
|
+
prefetch = True
|
|
2524
|
+
|
|
2525
|
+
# Token budget for the context block (definitions, enclosing code,
|
|
2526
|
+
# enclosing types, last-run values). Split ~60/25/15 across the
|
|
2527
|
+
# stable / run / volatile tiers.
|
|
2528
|
+
context_tokens = 4000
|
|
2529
|
+
|
|
2530
|
+
|
|
2531
|
+
|
|
2532
|
+
# A definition longer than this is truncated (its signature line
|
|
2533
|
+
# is kept as the budget-degrade form).
|
|
2534
|
+
definition_max_lines = 80
|
|
2535
|
+
|
|
2536
|
+
# Lines above and below the caret the per-request scans look at
|
|
2537
|
+
# (referenced definitions, runtime values). Bounds context assembly
|
|
2538
|
+
# on large-file buffers - a 14k-line span is not scanned end to end.
|
|
2539
|
+
scan_lines = 120
|
|
2540
|
+
|
|
2541
|
+
# Re-derive the stable context after this many seconds even when
|
|
2542
|
+
# its key (file, pending gen, enclosing def) hasn't moved.
|
|
2543
|
+
stable_refresh_s = 2.0
|
|
2544
|
+
|
|
2545
|
+
# Most last-run values to annotate (nearest the caret first).
|
|
2546
|
+
live_values_max = 40
|
|
2547
|
+
# Also report min/mean/max for tensors - a GPU reduce per value.
|
|
2548
|
+
live_value_stats = False
|
|
2549
|
+
|
|
2550
|
+
# Close a provider session (language client / Copilot LS process) that
|
|
2551
|
+
# no editor has used for this long.
|
|
2552
|
+
session_idle_s = 600.0
|
|
2553
|
+
|
|
2554
|
+
# How long Ollama keeps a model resident after a request / a Load
|
|
2555
|
+
# from Internet Accounts (Ollama duration string; 0 = disable).
|
|
2556
|
+
ollama_keep_alive = "30m"
|
|
2557
|
+
|
|
2558
|
+
# Print provider/context tracebacks.
|
|
2559
|
+
debug_print = False
|
|
2560
|
+
|
|
2561
|
+
|
|
2562
|
+
@defaults(tint=(0.85, 0.55, 0.35))
|
|
2563
|
+
class InternetAccounts:
|
|
2564
|
+
# Codex app-server CLI integration; empty executable searches PATH.
|
|
2565
|
+
codex_bin = ""
|
|
2566
|
+
codex_request_timeout_s = 30.0
|
|
2567
|
+
codex_login_timeout_s = 300.0
|
|
2568
|
+
# The Anthropic "Sign in" button (Internet Accounts.py →
|
|
2569
|
+
# fim_providers/anthropic_oauth.py): the same OAuth login that
|
|
2570
|
+
# `ant auth login` performs, written as an SDK profile the
|
|
2571
|
+
# anthropic client reads and refreshes for itself.
|
|
2572
|
+
#
|
|
2573
|
+
# OAuth client the login runs as - the official CLI's public id,
|
|
2574
|
+
# so the profile it mints is one `ant` and the SDKs share/refresh.
|
|
2575
|
+
anthropic_oauth_client_id = "41077d10-94b8-4194-be48-d251e9eb21b4"
|
|
2576
|
+
# Console that hosts the /oauth/authorize consent page.
|
|
2577
|
+
anthropic_console_url = "https://platform.claude.com"
|
|
2578
|
+
# Scopes requested at login (space separated).
|
|
2579
|
+
anthropic_oauth_scope = "user:profile user:inference user:developer"
|
|
2580
|
+
# SDK profile the sign-in writes: ~/.config/anthropic/{configs,
|
|
2581
|
+
# credentials}/<name>.json. Named - not "default" and never made the
|
|
2582
|
+
# active profile - so Claude Code / a bare Anthropic() elsewhere keep
|
|
2583
|
+
# their own login; the studio passes profile= explicitly. Extra
|
|
2584
|
+
# Anthropic accounts use "<name>-<account id>" unless their Login
|
|
2585
|
+
# profile field says otherwise.
|
|
2586
|
+
anthropic_profile = "lsd"
|
|
2587
|
+
# Give up waiting for the browser redirect after this long.
|
|
2588
|
+
anthropic_login_timeout_s = 300.0
|
|
2589
|
+
# Claude plan usage panel (Anthropic row): NO background poll (it
|
|
2590
|
+
# rate-limited the endpoint, 08-25). One GET /api/oauth/usage when
|
|
2591
|
+
# the panel opens, when a REPAINT finds the numbers older than
|
|
2592
|
+
# usage_refresh_s, and from the Refresh button. No panel = nothing.
|
|
2593
|
+
usage_refresh_s = 300.0
|
|
2594
|
+
# Every AUTOMATIC usage fetch (panel opened, numbers found stale by
|
|
2595
|
+
# a repaint, the persisted-open panel at boot) waits this long
|
|
2596
|
+
# before the request fires; last session's cached bars show
|
|
2597
|
+
# meanwhile (AccountsPanelState.usage), so a quick restart cycle
|
|
2598
|
+
# never reaches the endpoint. 0 = fire at once. Refresh is immediate.
|
|
2599
|
+
usage_fetch_delay_s = 60.0
|
|
2600
|
+
# Hard floor between two usage requests for one account, whatever
|
|
2601
|
+
# asks (a redraw, the poller, an identity change) - only the Refresh
|
|
2602
|
+
# button goes under it. A 429 backs off for its Retry-After, else
|
|
2603
|
+
# usage_backoff_s, doubling per repeat up to usage_backoff_max_s.
|
|
2604
|
+
usage_min_interval_s = 20.0
|
|
2605
|
+
usage_backoff_s = 300.0
|
|
2606
|
+
usage_backoff_max_s = 1800.0
|
|
2607
|
+
# The Claude Code executable the "Use in Claude Code" button runs
|
|
2608
|
+
# (`claude auth login --email ...`); empty = PATH / the usual installs.
|
|
2609
|
+
claude_code_bin = ""
|
|
2610
|
+
# Sign-in pages open as a PLACED popup: a chromeless Chromium --app
|
|
2611
|
+
# window forced into Xwayland (positioning works there) and parked
|
|
2612
|
+
# beside the pointer by xdotool (fim_providers/oauth_popup.py); a
|
|
2613
|
+
# dedicated profile ~/.lsd/oauth-browser keeps the Google session
|
|
2614
|
+
# between sign-ins. Off / no Chromium / no xdotool → plain xdg-open.
|
|
2615
|
+
use_oauth_popup = True
|
|
2616
|
+
oauth_popup_browser = ""
|
|
2617
|
+
oauth_popup_size = (520, 760)
|
|
2618
|
+
# A toast (tag "anthropic") + log line for EVERY Anthropic API
|
|
2619
|
+
# request the studio makes - usage fetches, FIM completions, Test,
|
|
2620
|
+
# sign-in token exchanges, retries (fim_providers/anthropic_requests.py).
|
|
2621
|
+
notify_requests = True
|
|
2622
|
+
|
|
2623
|
+
|
|
2624
|
+
@defaults(tint=(0.63, 0.44, 0.2))
|
|
2625
|
+
class GC:
|
|
2626
|
+
# Deliberate collector scheduling (gc_manager.tick in Melty.end_frame):
|
|
2627
|
+
# gen2's auto-trigger is deferred and full collects run at
|
|
2628
|
+
# input-idle instead of landing mid-keystroke (the observed 3.3s
|
|
2629
|
+
# gen2 stall in the render thread). Off = stock collector.
|
|
2630
|
+
enable = True
|
|
2631
|
+
manage = True
|
|
2632
|
+
# Auto gen2 threshold while managed - effectively "manual threshold";
|
|
2633
|
+
# the idle collector below is what actually runs full passes.
|
|
2634
|
+
gen2_threshold = 1000000
|
|
2635
|
+
# Seconds of input quiet before the boot freeze / an idle collect.
|
|
2636
|
+
idle_seconds = 15.0
|
|
2637
|
+
# Minimum spacing between idle collects.
|
|
2638
|
+
idle_collect_s = 120.0
|
|
2639
|
+
# Minimum spacing for a collect that at the moment the window
|
|
2640
|
+
# LOSES focus (alt-tab / minimize): the one frame nobody is watching.
|
|
2641
|
+
# Focus-gain restarts the idle clock, so returning never collects.
|
|
2642
|
+
unfocus_collect_s = 200.0
|
|
2643
|
+
# The focus-loss collect fires only after the window has stayed
|
|
2644
|
+
# unfocused, with no mouse presence, this long: the polled focus
|
|
2645
|
+
# edge is also what the first frame BACK reads (pointer over the
|
|
2646
|
+
# window, focus not regained yet), and collecting there froze the
|
|
2647
|
+
# return. Raise it if a loss still lands in your face; it costs
|
|
2648
|
+
# nothing while away.
|
|
2649
|
+
unfocus_confirm_s = 1.0
|
|
2650
|
+
# The BOOT pass (full-graph walk, seconds) needs a real absence when
|
|
2651
|
+
# it goes by idle rather than by focus loss: this long input quiet
|
|
2652
|
+
# with the window focused. Ordinary auto-freeze collects use
|
|
2653
|
+
# idle_seconds.
|
|
2654
|
+
boot_idle_seconds = 120.0
|
|
2655
|
+
# Minimum spacing between post-run collects (collect_after_run -
|
|
2656
|
+
# the live lab's per-run VRAM retirement). Auto Execute runs the
|
|
2657
|
+
# previewed function per mouse-drag tick; collecting after every
|
|
2658
|
+
# one was a ~120ms stall per frame, and even every few seconds the
|
|
2659
|
+
# accumulating garbage made each pass a ~400ms GIL stall. Within this
|
|
2660
|
+
# window runs coalesce onto a trailing one-shot collect that fires
|
|
2661
|
+
# once the burst rests, so the LAST run's garbage (the VRAM that
|
|
2662
|
+
# matters) always retires - at most one full pass per window. VRAM
|
|
2663
|
+
# from all generations inside the window stays pinned until then;
|
|
2664
|
+
# lower this if iterating on models that fill the card. 0 = collect
|
|
2665
|
+
# after every run.
|
|
2666
|
+
post_run_min_s = 120.0
|
|
2667
|
+
# Minimum spacing between post-run torch.cuda.empty_cache() calls -
|
|
2668
|
+
# separate from the collect above: freeing cached blocks is cheap
|
|
2669
|
+
# and is what makes freed activations actually leave VRAM (nvidia-
|
|
2670
|
+
# smi) while a typing burst runs the lab every keystroke. 0 = every run.
|
|
2671
|
+
post_run_cache_release_s = 2.0
|
|
2672
|
+
# Never freeze/collect before the app has been up this long (caches
|
|
2673
|
+
# still filling - freezing mid-load would pin a half-built graph).
|
|
2674
|
+
boot_delay_s = 30.0
|
|
2675
|
+
# On a CUDA out-of-memory, print gc_manager.report_vram_holders()
|
|
2676
|
+
# BEFORE the responder sweeps: the largest CUDA storages and who
|
|
2677
|
+
# references them (store key / draw / attr / frame / module).
|
|
2678
|
+
# A few seconds of gc walk, OOM-time only.
|
|
2679
|
+
oom_holder_report = True
|
|
2680
|
+
# Every scheduled collect writes a report of WHAT it reclaimed
|
|
2681
|
+
# (class / module / dict-signature / function, with sample
|
|
2682
|
+
# reprs) - one file per collect under report_dir - and its "lag"
|
|
2683
|
+
# toast names the top types; clicking the toast opens the report in
|
|
2684
|
+
# the code editor. Off = bare gc.collect(), no toast.
|
|
2685
|
+
reports = True
|
|
2686
|
+
report_dir = "~/meltygui/gc_reports"
|
|
2687
|
+
# Oldest reports pruned past this many.
|
|
2688
|
+
report_keep = 50
|
|
2689
|
+
cam_zoom = 1.5585
|
|
2690
|
+
|
|
2691
|
+
# Presentation mode: dim the text editor's glyphs everywhere EXCEPT on
|
|
2692
|
+
# lines carrying a def-tint line band, so the tinted lines read as the
|
|
2693
|
+
# selected content for an audience. Requires TextEditor.definition_tints
|
|
2694
|
+
# for the exception lines to exist - with it off, every line dims. Dimmed
|
|
2695
|
+
# brightness comes from TextEditor.presentation_text_brightness. Also
|
|
2696
|
+
# hides the Fast Dock (draw_main skips it; summon windows via the global
|
|
2697
|
+
# search instead). Read live.
|
|
2698
|
+
presentation_mode = False
|
|
2699
|
+
|
|
2700
|
+
# Master switch for the always-on debug chrome painted over the app: the
|
|
2701
|
+
# red/white texture-init tile counter in the top-left (LSDStudio's render
|
|
2702
|
+
# loop) and the notification / "Live" value bands along the right edge
|
|
2703
|
+
# (notifications.draw_notifications, gated in Melty.draw). Off = a clean
|
|
2704
|
+
# screen for demos and screenshots; notify()/display() keep recording, so
|
|
2705
|
+
# flipping it back shows the history. The GPU readout is unaffected.
|
|
2706
|
+
# also live.
|
|
2707
|
+
developer_mode = False
|
|
2708
|
+
# Frame rate (and, for app windows, render-thread frame time) in the
|
|
2709
|
+
# titlebar of every OS window (titlebar.paint_fps). Apps start with it off.
|
|
2710
|
+
show_fps = True
|
|
2711
|
+
|
|
2712
|
+
# The notification overlay (notifications.draw_notifications, gated by
|
|
2713
|
+
# developer_mode above): categories stack vertically along the right
|
|
2714
|
+
# edge, each in its own fixed-height scrolling band. Read live.
|
|
2715
|
+
@defaults(tint=(0.85, 0.64, 0.13))
|
|
2716
|
+
class Notifications:
|
|
2717
|
+
# Vertical space one category's band gets (title included). Entries
|
|
2718
|
+
# beyond it scroll: wheel over the band, sticky at the newest end,
|
|
2719
|
+
# "N new" badge while scrolled back.
|
|
2720
|
+
# [tint=(0.85, 0.64, 0.13), show_tint=True]
|
|
2721
|
+
category_height = 300
|
|
2722
|
+
|
|
2723
|
+
class Chat:
|
|
2724
|
+
# Centered transcript and right-aligned user bubble width limits.
|
|
2725
|
+
# [tint=(0.45, 0.48, 0.52)]
|
|
2726
|
+
transcript_max_width = 900.0
|
|
2727
|
+
# [tint=(0.72, 0.43, 0.28)]
|
|
2728
|
+
user_message_max_width = 680.0
|
|
2729
|
+
# Sidebar navigation stays neutral when the selected conversation changes.
|
|
2730
|
+
# [tint=(0.45, 0.48, 0.52), show_tint=True]
|
|
2731
|
+
navigation_tint = (0.45, 0.48, 0.52)
|
|
2732
|
+
# [tint=(0.58, 0.6, 0.63), show_tint=True]
|
|
2733
|
+
codex_tag_tint = (0.58, 0.6, 0.63)
|
|
2734
|
+
# [tint=(0.72, 0.43, 0.28), show_tint=True]
|
|
2735
|
+
claude_tag_tint = (0.72, 0.43, 0.28)
|
|
2736
|
+
# Selected sidebar chats rise above their folder plate.
|
|
2737
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2738
|
+
selected_chat_shadow_offset = 5.0
|
|
2739
|
+
# Drop-shadow offsets in the Chat window (cards, code blocks, buttons,
|
|
2740
|
+
# the transcript scrollbar thumb). 0 disables a shadow.
|
|
2741
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2742
|
+
shadow_offset = 1.5
|
|
2743
|
+
# A selected conversation card / pressed button lifts a little higher.
|
|
2744
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2745
|
+
selected_shadow_offset = 2.0
|
|
2746
|
+
# Bash / terminal blocks paint flat.
|
|
2747
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2748
|
+
bash_shadow_offset = 0.0
|
|
2749
|
+
# The file tags on write-file rows (the compare column's tab look), flat.
|
|
2750
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2751
|
+
file_tag_shadow_offset = 0.0
|
|
2752
|
+
# Code blocks darken the window's painted fill by these factors:
|
|
2753
|
+
# bash a small step under the window, python darker.
|
|
2754
|
+
# [tint=(0.95, 0.6, 0.25), show_tint=True]
|
|
2755
|
+
bash_darken = 0.74
|
|
2756
|
+
# [tint=(0.95, 0.6, 0.25), show_tint=True]
|
|
2757
|
+
python_darken = 0.65
|
|
2758
|
+
# The dimmed first line of a collapsed command row (1 = full text tint).
|
|
2759
|
+
# [tint=(0.95, 0.6, 0.25), show_tint=True]
|
|
2760
|
+
command_text_brightness = 0.6
|
|
2761
|
+
# The row icons (terminal / pencil / brain) in their chips (1 = full text tint).
|
|
2762
|
+
# [tint=(0.95, 0.6, 0.25), show_tint=True]
|
|
2763
|
+
icon_brightness = 0.7
|
|
2764
|
+
# The Failed badge's plate / icon / text, scaled down from their design colours.
|
|
2765
|
+
# [tint=(0.95, 0.6, 0.25), show_tint=True]
|
|
2766
|
+
failed_badge_brightness = 0.7
|
|
2767
|
+
# Layout: the provider / account dropdowns' trigger height, the margin
|
|
2768
|
+
# under them before the sidebar and transcript, the gap between the
|
|
2769
|
+
# sidebar column and the transcript column, and the gap between the
|
|
2770
|
+
# conversation list and the New conversation button (all px).
|
|
2771
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2772
|
+
dropdown_height = 30
|
|
2773
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2774
|
+
header_margin = 8
|
|
2775
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2776
|
+
column_gap = 14
|
|
2777
|
+
# [tint=(0.635, 0.728, 0.725, 1.0), show_tint=True]
|
|
2778
|
+
new_conversation_margin = 8
|
|
2779
|
+
# Tallest an inline picture (a pasted image, a Read of an image file)
|
|
2780
|
+
# draws in the transcript, in px; wider ones fit the span.
|
|
2781
|
+
# [tint=(0.95, 0.6, 0.25), show_tint=True]
|
|
2782
|
+
image_max_height = 360
|
|
2783
|
+
# Brightness cap (HSV value) of a user message's card; the sidebar's
|
|
2784
|
+
# conversation cards stay at draw_bg's 0.18.
|
|
2785
|
+
# [tint=(0.95, 0.6, 0.25), show_tint=True]
|
|
2786
|
+
user_message_bg_value = 0.3
|
|
2787
|
+
# Widest a command row (terminal block, file tags) or assistant prose
|
|
2788
|
+
# gets, in px; long lines clip / wrap at it.
|
|
2789
|
+
# [tint=(0.95, 0.6, 0.25), show_tint=True]
|
|
2790
|
+
terminal_max_width = 748
|
|
2791
|
+
|
|
2792
|
+
show_filled_tiles = False
|
|
2793
|
+
gl_check_error = False
|
|
2794
|
+
|
|
2795
|
+
# [tint=(0.0, 0.374, 0.744), show_tint=True]
|
|
2796
|
+
enable_jedi = True
|
|
2797
|
+
jedi_correctness = False
|
|
2798
|
+
|
|
2799
|
+
# Build the node→span map from Python's `ast` (C code) instead of libcst's
|
|
2800
|
+
# PositionProvider (whole-tree codegen, ~64% of cst→dict cost).
|
|
2801
|
+
new_position_map = True
|
|
2802
|
+
|
|
2803
|
+
# While typing, pause the background cst→dict parse at statement boundaries so
|
|
2804
|
+
# the render thread gets the GIL uncontended. Never sleeps render
|
|
2805
|
+
# [tint=(0.75, 0.46218, 0.00)]
|
|
2806
|
+
yield_to_ui = True
|
|
2807
|
+
|
|
2808
|
+
# Timeline logging of the symbol-index / code-host load path: every
|
|
2809
|
+
# meaningful unit of work (parse, graph compute, warmer pass, drag wait,
|
|
2810
|
+
# attach) writes a timestamped, thread-labeled line to
|
|
2811
|
+
# /tmp/lsd_symbol_perf.log (perf_trace.py). Near-zero cost when off.
|
|
2812
|
+
symbol_perf_log = False # TEMP: enabled to capture the 1300ms frame shortly after boot
|
|
2813
|
+
attrib_churn_log = False
|
|
2814
|
+
debug_threads = False
|
|
2815
|
+
|
|
2816
|
+
slow_down_threads = False
|
|
2817
|
+
|
|
2818
|
+
# [tint=(0.025, 0.372, 0.326)]
|
|
2819
|
+
profile_mode = ProfileMode.LIGHT
|
|
2820
|
+
debug_stale_tint = False
|
|
2821
|
+
|
|
2822
|
+
# Filter Settings
|
|
2823
|
+
# [tint=(0.418, 0.656, 0.744)]
|
|
2824
|
+
brightness = 0.144
|
|
2825
|
+
# [tint=(0.458, 0.474, 0.5)]
|
|
2826
|
+
contrast = 1.213
|
|
2827
|
+
|
|
2828
|
+
debug_z_depth = False
|
|
2829
|
+
filters = True
|
|
2830
|
+
filter_brightness = False
|
|
2831
|
+
show_excluded = True
|
|
2832
|
+
layer_stack_trace = False
|
|
2833
|
+
show_line_breaks = False
|
|
2834
|
+
|
|
2835
|
+
memory_profile = False
|
|
2836
|
+
|
|
2837
|
+
# Shadow Settings - the compositor shadow pass (meltygui.py post_frame:
|
|
2838
|
+
# ShadowCast at reduced res over the R16 rank mask, then
|
|
2839
|
+
# ShadowComposite's joint bilateral upsample onto the frame). Read live
|
|
2840
|
+
# per frame.
|
|
2841
|
+
shadow_downscale = 3
|
|
2842
|
+
# Per-view cap for add_shadow/add_glow marks: a view (draw_state)
|
|
2843
|
+
# can emit at most this many marks of each kind per frame; extra
|
|
2844
|
+
# emissions are dropped and the budget recycles next frame. Backstop
|
|
2845
|
+
# against a view leaking unbounded marks into the retained stores
|
|
2846
|
+
# (every retained mark re-stamps every finalize).
|
|
2847
|
+
shadow_cap = 100
|
|
2848
|
+
shadow_edge_sharpness = 0.021
|
|
2849
|
+
# Light direction the shadows are cast AWAY from, as a screen-space
|
|
2850
|
+
# vector (x right, y down in UV space). Only the direction matters -
|
|
2851
|
+
# the shader normalizes it; travel distance comes from
|
|
2852
|
+
# shadow_height_scale.
|
|
2853
|
+
shadow_light_dir = (-0.196, 0.265)
|
|
2854
|
+
# How far a shadow travels per unit of caster/receiver depth gap
|
|
2855
|
+
# (in units): higher = deeper stacks cast longer shadows.
|
|
2856
|
+
shadow_height_scale = 3.716
|
|
2857
|
+
# Penumbra widening per unit of depth gap: bigger = softer, more
|
|
2858
|
+
# diffuse shadows from tall casters.
|
|
2859
|
+
shadow_blur_scale = 0.16
|
|
2860
|
+
# Contact-hardening: curve of penumbra growth along the shadow's
|
|
2861
|
+
# LENGTH - 0 at the caster's silhouette edge, 1 at the shadow tip
|
|
2862
|
+
# (the shader measures the edge distance by bisecting along
|
|
2863
|
+
# light_dir). shadow_blur_scale stays the blur magnitude at the far
|
|
2864
|
+
# end; this shapes the ramp: < 1 blooms the blur rapidly just past
|
|
2865
|
+
# the contact edge (long shadows that go soft fast), 1 = linear
|
|
2866
|
+
# growth, > 1 stays crisp for most of the run and softens only the
|
|
2867
|
+
# tip. 0 = legacy uniform blur along the whole shadow.
|
|
2868
|
+
shadow_blur_exponent = -0.312
|
|
2869
|
+
# Blur samples in ShadowCast's penumbra ring (x3 radii per sample).
|
|
2870
|
+
# More = finer/less grainy penumbra, linearly more fragment work at
|
|
2871
|
+
# the shadow edge.
|
|
2872
|
+
shadow_blur_samples = 6
|
|
2873
|
+
# Occlusion each caster hit contributes before the depth-gap decay -
|
|
2874
|
+
# the base darkness of a shadow right under its caster.
|
|
2875
|
+
shadow_hit_strength = 0.503
|
|
2876
|
+
# How fast that contribution decays per unit of caster/receiver depth
|
|
2877
|
+
# gap: higher = deep stacks fade their shadows out sooner (clamped at
|
|
2878
|
+
# 0 in-shader, never lightens).
|
|
2879
|
+
shadow_hit_falloff = 69.627
|
|
2880
|
+
# Max fraction of light a deep stack of casters can block inside
|
|
2881
|
+
# ShadowCast (the light-transmission model's ceiling).
|
|
2882
|
+
shadow_strength = 0.683
|
|
2883
|
+
# Composite-time darkening: how far shadowed pixels mix toward
|
|
2884
|
+
# shadow_color (scales the ShadowCast intensity at the final blend).
|
|
2885
|
+
shadow_opacity = 0.684
|
|
2886
|
+
# What shadows mix TOWARD - a slightly blue gray by default.
|
|
2887
|
+
shadow_color = (0.0, 0.02, 0.05)
|
|
2888
|
+
# Specular highlight on the LIT edge of raised backgrounds — the edge
|
|
2889
|
+
# facing the light source (top-left when the shadow falls down-right;
|
|
2890
|
+
# direction derives from shadow_light_dir so the two always agree).
|
|
2891
|
+
# Value = bevel radius in px: the width of the highlight rim and the
|
|
2892
|
+
# apparent roundness of the edge. 0 disables the pass.
|
|
2893
|
+
# [tint=(0.85, 0.75, 0.05), show_tint=True]
|
|
2894
|
+
specular_bevel = 1.243
|
|
2895
|
+
|
|
2896
|
+
# Global surface roughness for the specular rim, (0, 1]: low = tight
|
|
2897
|
+
# bright crest line at the edge, high = broad dim sheen at the bevel.
|
|
2898
|
+
specular_roughness = 0.094
|
|
2899
|
+
# Peak brightness of the highlight (white light added at composite).
|
|
2900
|
+
specular_opacity = 0.286
|
|
2901
|
+
# Fade of the highlight ALONG the lit edges, in px: brightest at the
|
|
2902
|
+
# lit corner (top-left when the shadow falls down-right), dying out
|
|
2903
|
+
# over this distance scanning down the left edge / across the top
|
|
2904
|
+
# edge. Distances come from edge walks (smooth-min over silhouette edge
|
|
2905
|
+
# tests on an absolute sample grid), so the gradient is smooth - no
|
|
2906
|
+
# dashes or stair steps. 0 = uniform rim, no fade.
|
|
2907
|
+
specular_fade = 3280.821
|
|
2908
|
+
# Size-relative cap on the fade: per axis the fade length becomes
|
|
2909
|
+
# min(specular_fade, rel * edge_extent), the extent being the soft
|
|
2910
|
+
# forward+backward distances. Large windows keep the fixed
|
|
2911
|
+
# specular_fade look; small widgets fade out within their own edge
|
|
2912
|
+
# instead of holding a uniform bright rim. 0 = pure fixed fade.
|
|
2913
|
+
specular_fade_rel = 0
|
|
2914
|
+
|
|
2915
|
+
# Depth falloff: specular intensity decays as exp(-depth * rate), so
|
|
2916
|
+
# surfaces near the floor catch the full highlight and high-stacked
|
|
2917
|
+
# windows progressively lose it. One layer slot is ~0.3 depth steps
|
|
2918
|
+
# at the 64x32 layer/depth config; 0 = depth-independent.
|
|
2919
|
+
specular_depth_falloff = 0.0
|
|
2920
|
+
# Slope tolerance for the bevel edge march, in depth units per px: a
|
|
2921
|
+
# sample only counts as a silhouette edge when it drops more than
|
|
2922
|
+
# eps + slope*distance below the start depth. Backgrounds interpolate
|
|
2923
|
+
# depth across their quad, so without this a tilted surface can read
|
|
2924
|
+
# as a phantom edge.
|
|
2925
|
+
specular_slope_tol = 0.003
|
|
2926
|
+
|
|
2927
|
+
# Glow Settings - add_glow() marks rendered as light sources in the
|
|
2928
|
+
# shadow composite (blit_offscreen PASS 6 stamps the low-res light
|
|
2929
|
+
# buffer; ShadowComposite adds it and cuts shadow under it).
|
|
2930
|
+
glow = True
|
|
2931
|
+
# Resolution divisor for the glow light buffer. The falloff is smooth by
|
|
2932
|
+
# construction, so it survives aggressive downscaling; the composite's
|
|
2933
|
+
# bilinear fetch upsamples for free.
|
|
2934
|
+
glow_downscale = 1
|
|
2935
|
+
# Master strength of the glow light at composite time.
|
|
2936
|
+
glow_strength = 0.091
|
|
2937
|
+
# How strongly glow luminance cancels shadow beneath it (0 = shadows
|
|
2938
|
+
# ignore glows, >1 = a full lit glow erases the shadow under it).
|
|
2939
|
+
# Keep MODEST: shadows are cast relative from the casters (light_dir),
|
|
2940
|
+
# so a strong cut brightens a band-shaped region DISPLACED from the
|
|
2941
|
+
# glow - it reads as a second copy of the glow drawn over itself, and
|
|
2942
|
+
# it shifts between live-rendered and blit-served frames because the
|
|
2943
|
+
# depth detail under the band differs subtly between those paths.
|
|
2944
|
+
# (Confirmed by glow_debug_log: dups=0 = one stamping, one composite
|
|
2945
|
+
# - the "double" is this cut, not a second glow rendering.)
|
|
2946
|
+
glow_shadow_cut = -0.291
|
|
2947
|
+
|
|
2948
|
+
# Downward AREA-LIGHT glow mode. Off = the omnidirectional
|
|
2949
|
+
# inverse-square skirt. On = each glow rect reads as a downward-facing
|
|
2950
|
+
# area l
|
|
2951
|
+
# ight: no light above or beside the source, a lit trapezoid below
|
|
2952
|
+
# it that widens by glow_area_spread px per px of drop, brightness held
|
|
2953
|
+
# flat for the first glow_area_hold fraction of the falloff radius and
|
|
2954
|
+
# then cut off with a sharp smoothstep - a much harder transition than
|
|
2955
|
+
# the inverse-square tail.
|
|
2956
|
+
glow_area_light = False
|
|
2957
|
+
# Fraction of the falloff radius over which the area light holds full
|
|
2958
|
+
# brightness before the gradient cutoff begins (0 = fade from the edge,
|
|
2959
|
+
# 0.9 = bright almost all the way down, then a hard stop).
|
|
2960
|
+
glow_area_hold = -1.119
|
|
2961
|
+
# Lateral widening of the lit trapezoid, in px per px of drop below
|
|
2962
|
+
# the rect (tan of the light cone's half-angle; 0 = straight down).
|
|
2963
|
+
glow_area_spread = 0.647
|
|
2964
|
+
# Falloff curve exponent past the hold point: brightness falls as
|
|
2965
|
+
# smoothstep^exponent, smooth at BOTH ends so there is no hard edge at
|
|
2966
|
+
# the far extent. 1 = plain smoothstep; higher = the light dies faster
|
|
2967
|
+
# near the source and trails out longer - a more prominent gradient.
|
|
2968
|
+
glow_area_falloff = 2.25
|
|
2969
|
+
# Fan-edge penumbra: the side edges of the light cone blur by this many
|
|
2970
|
+
# px per px of drop (symmetric about the trapezoid center) - razor-sharp
|
|
2971
|
+
# at the source and progressively softer with distance, like a real
|
|
2972
|
+
# area-light penumbra. 0 = hard fan edges all the way down.
|
|
2973
|
+
glow_area_edge_blur = 9.113
|
|
2974
|
+
# Tilt of the light, in degrees from straight down (clamped to +/-80).
|
|
2975
|
+
# Positive shears the fan toward screen-right as it drops; the whole
|
|
2976
|
+
# fan (center, edges, penumbra) shifts by tan(angle) px per px of drop.
|
|
2977
|
+
glow_area_angle = 0.00
|
|
2978
|
+
# Which edge of the emitting rect the light hangs from. True = the TOP
|
|
2979
|
+
# edge: the fan starts there and washes down THROUGH the rect and past
|
|
2980
|
+
# it (the rect interior gets the gradient too). False = the BOTTOM
|
|
2981
|
+
# edge: the rect interior stays fully lit and the fan starts under it.
|
|
2982
|
+
glow_area_top_edge = False
|
|
2983
|
+
# Emit from the token background's LEFT, RIGHT and BOTTOM edges
|
|
2984
|
+
# instead of a single downward fan (ignore glow_area_top_edge while
|
|
2985
|
+
# on). The hold/falloff profile runs on the distance from the rounded
|
|
2986
|
+
# rect itself, sheared sideways by glow_area_angle as it drops below
|
|
2987
|
+
# the top edge, and the skirt tapers to nothing approaching the top
|
|
2988
|
+
# rect so the top edge remains dark. glow_area_spread /
|
|
2989
|
+
# glow_area_edge_blur are fan-only and ignored here.
|
|
2990
|
+
glow_area_edges = False
|
|
2991
|
+
|
|
2992
|
+
# Band offsets for the glow receiver mask, applied live in PASS 6 (no
|
|
2993
|
+
# re-render needed to tune). Lower bound is relative to the emitter's
|
|
2994
|
+
# ROOT WINDOW surface (negative reaches below the window, positive
|
|
2995
|
+
# trims up into it); upper bound is relative to the EMITTER's own
|
|
2996
|
+
# surface (how far above it a receiver may sit and still catch light).
|
|
2997
|
+
# Units: one shallow depth step (~one Melty.shadow_depth increment
|
|
2998
|
+
# near depth 0). Applied LINEARLY in rank space - shadow_depth_at's
|
|
2999
|
+
# depth curve is non-monotone, so offsets never go through it, which
|
|
3000
|
+
# makes large values (+/-1000) genuinely open the whole band, same as
|
|
3001
|
+
# glow_debug_no_mask.
|
|
3002
|
+
glow_mask_lower_offset = 0.054
|
|
3003
|
+
glow_mask_upper_offset = 0.151
|
|
3004
|
+
|
|
3005
|
+
# How many consecutive EMPTY body runs (cleared without re-emitting)
|
|
3006
|
+
# before an emitter's retained glow drops. 1 = AUTHORITATIVE: the
|
|
3007
|
+
# first empty run drops the glow - live edits shed stale glow
|
|
3008
|
+
# instantly. Raise it if async tint recomputes (all views rebuilding
|
|
3009
|
+
# their tree per publish, background symbol indexing) start reading as
|
|
3010
|
+
# random glow loss again: each unit is another body run of grace against
|
|
3011
|
+
# a transient stale tint state.
|
|
3012
|
+
glow_clear_hold_frames = 0
|
|
3013
|
+
|
|
3014
|
+
# Automatic culling of retained glow/depth marks from views judged no
|
|
3015
|
+
# longer visible (territory-repaint kills: tab switches, jump-to
|
|
3016
|
+
# content swaps). OFF = retained marks only ever change by the
|
|
3017
|
+
# emitter's own re-emission or explicit clears - stale glow may linger
|
|
3018
|
+
# after tab switches, but if a mysterious glow LOSS stops happening
|
|
3019
|
+
# with this off, the culling misjudged it; if it persists, the
|
|
3020
|
+
# depth-mask gate or the stamp path is the culprit. A narrowing tool.
|
|
3021
|
+
glow_auto_cull = True
|
|
3022
|
+
|
|
3023
|
+
# --- Glow debug ---
|
|
3024
|
+
# Bypass the glow-mask receiver gate: light falls on EVERY pixel under
|
|
3025
|
+
# the quad. Glows appearing only with this on = the rank maths is broken
|
|
3026
|
+
# (emitter/floor vs the mask's receiver ranks), not the stamping.
|
|
3027
|
+
glow_debug_no_mask = False
|
|
3028
|
+
# Stamp hard full-intensity rects instead of the falloff: solid inside
|
|
3029
|
+
# the emitting quad, 30% across the skirt - shows position + radius
|
|
3030
|
+
# extent through the real pipeline.
|
|
3031
|
+
glow_debug_rects = False
|
|
3032
|
+
# Draw the entire low-res glow buffer over the whole frame (replaces the
|
|
3033
|
+
# image). Buffer has content but the normal view doesn't = composite
|
|
3034
|
+
# hookup broken; buffer empty = stamping broken.
|
|
3035
|
+
glow_debug_view = False
|
|
3036
|
+
# ~1/sec console print of pipeline counts (frame marks, retained
|
|
3037
|
+
# emitters, stamped quads, first mark's rank/floor band).
|
|
3038
|
+
glow_debug_log = False
|
|
3039
|
+
|
|
3040
|
+
caller_walk_steps = 7
|
|
3041
|
+
draw_legacy = False
|
|
3042
|
+
show_full_call_stack = False
|
|
3043
|
+
|
|
3044
|
+
# Screenshot output dir (screenshot.py / context menu capture)
|
|
3045
|
+
screenshots = "" # Default: the user's XDG cache directory.
|
|
3046
|
+
|
|
3047
|
+
debug_set_anywhere = False
|
|
3048
|
+
ignore_call_from = ()
|
|
3049
|
+
|
|
3050
|
+
|
|
3051
|
+
@window
|
|
3052
|
+
class Actions:
|
|
3053
|
+
"""General-purpose stash for app triggers ("New file", "New Render
|
|
3054
|
+
Function", ...). Rendered by draw_actions (actions_playground.py)."""
|
|
3055
|
+
|
|
3056
|
+
@staticmethod
|
|
3057
|
+
def new_file(name: str):
|
|
3058
|
+
pass
|
|
3059
|
+
|
|
3060
|
+
@defaults(icon="")
|
|
3061
|
+
@staticmethod
|
|
3062
|
+
def new_render_func(name="draw_other"):
|
|
3063
|
+
pass
|
|
3064
|
+
|
|
3065
|
+
@defaults(icon="\uf030")
|
|
3066
|
+
@staticmethod
|
|
3067
|
+
def screenshot():
|
|
3068
|
+
"""Arm the region screenshot tool (also Ctrl+Shift+3): a crosshair
|
|
3069
|
+
follows the cursor; click-drag a box; on release the framebuffer
|
|
3070
|
+
pixels inside it are saved as a PNG (Toggles.screenshots), opened in
|
|
3071
|
+
the code editor, and the file path is copied to the clipboard. Esc
|
|
3072
|
+
cancels."""
|
|
3073
|
+
from meltygui.core.diagnostics.screenshot_core import arm
|
|
3074
|
+
arm()
|
|
3075
|
+
|
|
3076
|
+
@staticmethod
|
|
3077
|
+
def claude_terminal():
|
|
3078
|
+
"""Open a gnome-terminal window running `claude-d` (Claude Code in a
|
|
3079
|
+
studio-discoverable tmux session — see ~/bin/claude-d). The script owns
|
|
3080
|
+
the session lifetime; closing the window kills it."""
|
|
3081
|
+
import subprocess
|
|
3082
|
+
# Full paths + close_fds=False -> posix_spawn, not fork (forking this
|
|
3083
|
+
# process stalls the render thread).
|
|
3084
|
+
import shutil
|
|
3085
|
+
terminal, command = shutil.which("gnome-terminal"), shutil.which("claude-d")
|
|
3086
|
+
if terminal is None or command is None:
|
|
3087
|
+
from meltygui.core.diagnostics.notifications import notify
|
|
3088
|
+
notify("Install gnome-terminal and claude-d to use this action")
|
|
3089
|
+
return
|
|
3090
|
+
subprocess.Popen([terminal, "--", command], close_fds=False)
|
|
3091
|
+
|
|
3092
|
+
|
|
3093
|
+
@window
|
|
3094
|
+
class LegacyToggles:
|
|
3095
|
+
# All the padding settings from imgui style
|
|
3096
|
+
item_spacing = (3, 2)
|
|
3097
|
+
frame_padding = (4, 1)
|
|
3098
|
+
window_padding = (6, 6)
|
|
3099
|
+
line_height = 16
|
|
3100
|
+
|
|
3101
|
+
|
|
3102
|
+
# =========
|
|
3103
|
+
def shadow_depth_at(depth, active_layer):
|
|
3104
|
+
scaling = 53.42
|
|
3105
|
+
cap = 5.975
|
|
3106
|
+
|
|
3107
|
+
divisor = max(cap, depth - scaling)
|
|
3108
|
+
|
|
3109
|
+
depth_and_layer = active_layer * Core.melty.max_depth + (depth * (scaling / (divisor)))
|
|
3110
|
+
depth_and_layer *= Core.melty.layer_inc
|
|
3111
|
+
return depth_and_layer
|
|
3112
|
+
|
|
3113
|
+
|
|
3114
|
+
class WindowManager:
|
|
3115
|
+
excluded_windows = ["demo test", "Egg Time", "Layer 1"]
|