From 429bb9242c152765ec314360b3c15c98b7c7a8d7 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sun, 8 Mar 2026 22:11:22 -0400 Subject: [PATCH] feat(ui): Implement Multi-Viewport and UI Layout Presets management --- src/gui_2.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/gui_2.py b/src/gui_2.py index 8485841..ca15a63 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -113,6 +113,10 @@ class App: self.ui_separate_message_panel = gui_cfg.get("separate_message_panel", False) self.ui_separate_response_panel = gui_cfg.get("separate_response_panel", False) self.ui_separate_tool_calls_panel = gui_cfg.get("separate_tool_calls_panel", False) + self.ui_multi_viewport = gui_cfg.get("multi_viewport", False) + self.layout_presets = self.config.get("layout_presets", {}) + self._new_preset_name = "" + self._show_save_preset_modal = False self._comms_log_cache: list[dict[str, Any]] = [] self._comms_log_dirty: bool = True self._tool_log_cache: list[dict[str, Any]] = [] @@ -295,6 +299,7 @@ class App: self._tool_log_dirty = True self._render_track_proposal_modal() self._render_patch_modal() + self._render_save_preset_modal() # Auto-save (every 60s) now = time.time() if now - self._last_autosave >= self._autosave_interval: @@ -789,6 +794,30 @@ class App: if self.perf_profiling_enabled: self.perf_monitor.end_component("_gui_func") + def _render_save_preset_modal(self) -> None: + if not self._show_save_preset_modal: return + imgui.open_popup("Save Layout Preset") + if imgui.begin_popup_modal("Save Layout Preset", True, imgui.WindowFlags_.always_auto_resize)[0]: + imgui.text("Preset Name:") + _, self._new_preset_name = imgui.input_text("##preset_name", self._new_preset_name) + if imgui.button("Save", imgui.ImVec2(120, 0)): + if self._new_preset_name.strip(): + ini_data = imgui.save_ini_settings_to_memory() + self.layout_presets[self._new_preset_name.strip()] = { + "ini": ini_data, + "multi_viewport": self.ui_multi_viewport + } + self.config["layout_presets"] = self.layout_presets + models.save_config(self.config) + self._show_save_preset_modal = False + self._new_preset_name = "" + imgui.close_current_popup() + imgui.same_line() + if imgui.button("Cancel", imgui.ImVec2(120, 0)): + self._show_save_preset_modal = False + imgui.close_current_popup() + imgui.end_popup() + def _render_projects_panel(self) -> None: if self.perf_profiling_enabled: self.perf_monitor.start_component("_render_projects_panel") proj_name = self.project.get("project", {}).get("name", Path(self.active_project_path).stem) @@ -2804,7 +2833,7 @@ class App: self.runner_params = hello_imgui.RunnerParams() self.runner_params.app_window_params.window_title = "manual slop" self.runner_params.app_window_params.window_geometry.size = (1680, 1200) - self.runner_params.imgui_window_params.enable_viewports = False + self.runner_params.imgui_window_params.enable_viewports = getattr(self, "ui_multi_viewport", False) self.runner_params.imgui_window_params.default_imgui_window_type = hello_imgui.DefaultImGuiWindowType.provide_full_screen_dock_space # Detect Monitor Refresh Rate for capping