diff --git a/src/app_controller.py b/src/app_controller.py index 961f96d0..2bfb394e 100644 --- a/src/app_controller.py +++ b/src/app_controller.py @@ -2076,8 +2076,8 @@ class AppController: self.ui_separate_tool_calls_panel = _uip.separate_tool_calls_panel self.ui_auto_switch_layout = gui_cfg.get("auto_switch_layout", False) self.ui_tier_layout_bindings = gui_cfg.get("tier_layout_bindings", {"Tier 1": "", "Tier 2": "", "Tier 3": "", "Tier 4": ""}) - from src import bg_shader - bg_shader.get_bg().enabled = gui_cfg.get("bg_shader_enabled", False) + from src.gui_2 import get_bg + get_bg().enabled = gui_cfg.get("bg_shader_enabled", False) _default_windows = { "Project Settings": True, @@ -3018,7 +3018,7 @@ class AppController: self.config["rag"] = self.rag_config.to_dict() self.config["projects"] = {"paths": self.project_paths, "active": self.active_project_path} - from src import bg_shader + from src.gui_2 import get_bg # Update gui section while preserving other keys like bg_shader_enabled gui_cfg = self.config.get("gui", {}) gui_cfg.update({ @@ -3033,7 +3033,7 @@ class AppController: "separate_tier2": self.ui_separate_tier2, "separate_tier3": self.ui_separate_tier3, "separate_tier4": self.ui_separate_tier4, - "bg_shader_enabled": bg_shader.get_bg().enabled + "bg_shader_enabled": get_bg().enabled }) self.config["gui"] = gui_cfg diff --git a/src/bg_shader.py b/src/bg_shader.py deleted file mode 100644 index 62515af2..00000000 --- a/src/bg_shader.py +++ /dev/null @@ -1,75 +0,0 @@ -# src/bg_shader.py -import time -import math - -from typing import Optional -from imgui_bundle import imgui, nanovg as nvg, hello_imgui - - -class BackgroundShader: - def __init__(self): - """ - [C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__] - """ - self.enabled = False - self.start_time = time.time() - self.ctx: Optional[nvg.Context] = None - - def render(self, width: float, height: float): - """ - [C: src/gui_2.py:App._gui_func, src/gui_2.py:App._render_discussion_entry_read_mode, src/gui_2.py:App._render_heavy_text, src/gui_2.py:App._render_markdown_test, src/gui_2.py:App._render_prior_session_view, src/gui_2.py:App._render_response_panel, src/gui_2.py:App._render_snapshot_tab, src/gui_2.py:App._render_text_viewer_window, src/markdown_helper.py:MarkdownRenderer._render_code_block, src/markdown_helper.py:MarkdownRenderer.render, src/markdown_helper.py:render, src/theme_2.py:render_post_fx, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render] - """ - if not self.enabled or width <= 0 or height <= 0: - return - - # In imgui-bundle, hello_imgui handles the background. - # We can use the background_draw_list to draw primitives. - # Since we don't have raw GLSL easily in Python without PyOpenGL, - # we'll use a "faux-shader" approach with NanoVG or DrawList gradients. - - t = time.time() - self.start_time - dl = imgui.get_background_draw_list() - - # Base deep sea color - dl.add_rect_filled(imgui.ImVec2(0, 0), imgui.ImVec2(width, height), imgui.get_color_u32(imgui.ImVec4(0.01, 0.07, 0.20, 1.0))) - - # Layer 1: Slow moving large blobs (FBM approximation) - for i in range(3): - phase = t * (0.1 + i * 0.05) - x = (math.sin(phase) * 0.5 + 0.5) * width - y = (math.cos(phase * 0.8) * 0.5 + 0.5) * height - radius = (0.4 + 0.2 * math.sin(t * 0.2)) * max(width, height) - - col = imgui.ImVec4(0.02, 0.26, 0.55, 0.3) - dl.add_circle_filled(imgui.ImVec2(x, y), radius, imgui.get_color_u32(col), num_segments=32) - - # Layer 2: Shimmering caustics (Animated Lines) - num_lines = 15 - for i in range(num_lines): - offset = (t * 20.0 + i * (width / num_lines)) % width - alpha = 0.1 * (1.0 + math.sin(t + i)) - col = imgui.get_color_u32(imgui.ImVec4(0.08, 0.60, 0.88, alpha)) - - p1 = imgui.ImVec2(offset, 0) - p2 = imgui.ImVec2(offset - 100, height) - dl.add_line(p1, p2, col, thickness=2.0) - - # Vignette - center = imgui.ImVec2(width/2, height/2) - radius = max(width, height) * 0.8 - # Draw multiple concentric circles for a soft vignette - for i in range(10): - r = radius + (i * 50) - alpha = (i / 10.0) * 0.5 - dl.add_circle(center, r, imgui.get_color_u32(imgui.ImVec4(0, 0, 0, alpha)), num_segments=64, thickness=60.0) - -_bg: Optional[BackgroundShader] = None - -def get_bg(): - """ - [C: src/gui_2.py:App._gui_func, src/gui_2.py:App._render_theme_panel] - """ - global _bg - if _bg is None: - _bg = BackgroundShader() - return _bg \ No newline at end of file diff --git a/src/gui_2.py b/src/gui_2.py index bdf1bcb0..3174327e 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -100,7 +100,6 @@ from src import ai_client from src import aggregate from src import api_hooks from src import app_controller -from src import bg_shader from src import cost_tracker from src import history from src import imgui_scopes as imscope @@ -114,7 +113,6 @@ from src import models from src.models import GenerateRequest, ConfirmRequest from src import mcp_client from src import markdown_helper -from src import shaders from src import synthesis_formatter from src import theme_2 as theme from src import thinking_parser @@ -1095,7 +1093,7 @@ class App: pushed_prior_tint = False # Render background shader - bg = bg_shader.get_bg() + bg = get_bg() ws = imgui.get_io().display_size if bg.enabled: bg.render(ws.x, ws.y) @@ -6267,7 +6265,7 @@ def render_theme_panel(app: App) -> None: ch_ct, ctrans = imgui.slider_float("##ctrans", theme.get_child_transparency(), 0.1, 1.0, "%.2f") if ch_ct: theme.set_child_transparency(ctrans) - bg = bg_shader.get_bg() + bg = get_bg() ch_bg, bg.enabled = imgui.checkbox("Animated Background Shader", bg.enabled) if ch_bg: gui_cfg = app.config.setdefault("gui", {}) @@ -8438,3 +8436,50 @@ def _capture_workspace_profile_ini_result(app: "App") -> Result[str]: #endregion: Phase 8 Property Setter / State Result Helpers #endregion: MMA + +#region: Bg Shader (moved from src/bg_shader.py) +import time as _bg_time +import math as _bg_math + +_bg: _Optional["BackgroundShader"] = None + +class BackgroundShader: + def __init__(self): + self.enabled = False + self.start_time = _bg_time.time() + self.ctx: _Optional[_Any] = None + + def render(self, width: float, height: float): + if not self.enabled or width <= 0 or height <= 0: + return + t = _bg_time.time() - self.start_time + dl = imgui.get_background_draw_list() + dl.add_rect_filled(imgui.ImVec2(0, 0), imgui.ImVec2(width, height), imgui.get_color_u32(imgui.ImVec4(0.01, 0.07, 0.20, 1.0))) + for i in range(3): + phase = t * (0.1 + i * 0.05) + x = (_bg_math.sin(phase) * 0.5 + 0.5) * width + y = (_bg_math.cos(phase * 0.8) * 0.5 + 0.5) * height + radius = (0.4 + 0.2 * _bg_math.sin(t * 0.2)) * max(width, height) + col = imgui.ImVec4(0.02, 0.26, 0.55, 0.3) + dl.add_circle_filled(imgui.ImVec2(x, y), radius, imgui.get_color_u32(col), num_segments=32) + num_lines = 15 + for i in range(num_lines): + offset = (t * 20.0 + i * (width / num_lines)) % width + alpha = 0.1 * (1.0 + _bg_math.sin(t + i)) + col = imgui.get_color_u32(imgui.ImVec4(0.08, 0.60, 0.88, alpha)) + p1 = imgui.ImVec2(offset, 0) + p2 = imgui.ImVec2(offset - 100, height) + dl.add_line(p1, p2, col, thickness=2.0) + center = imgui.ImVec2(width/2, height/2) + radius = max(width, height) * 0.8 + for i in range(10): + r = radius + (i * 50) + alpha = (i / 10.0) * 0.5 + dl.add_circle(center, r, imgui.get_color_u32(imgui.ImVec4(0, 0, 0, alpha)), num_segments=64, thickness=60.0) + +def get_bg() -> BackgroundShader: + global _bg + if _bg is None: + _bg = BackgroundShader() + return _bg +#endregion: Bg Shader