diff --git a/src/gui_2.py b/src/gui_2.py index 09620c44..a7e36f53 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -115,43 +115,72 @@ class App: """ [C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__] """ + # --- Core Dependencies & State --- self.controller = app_controller.AppController() self.controller._app = self from src import history, performance_monitor self.perf_monitor = performance_monitor.PerformanceMonitor() self.history = history.HistoryManager(max_capacity=100) + # --- Undo/Redo & Snapshot State --- self._last_ui_snapshot: Optional[history.UISnapshot] = None self._snapshot_timer: float = 0.0 self._snapshot_debounce: float = 1.5 self._pending_snapshot: bool = False self._is_applying_snapshot: bool = False - + # --- Initialization --- self.controller.init_state() self.workspace_manager = workspace_manager.WorkspaceManager(project_root=self.controller.active_project_root) self.workspace_profiles = self.workspace_manager.load_all_profiles() - self.show_windows.setdefault("Diagnostics", False) self.controller.start_services(self) + # --- Controller Callbacks & Actions --- self.controller._predefined_callbacks['_render_text_viewer'] = self._render_text_viewer self.controller._predefined_callbacks['save_context_preset'] = self.save_context_preset self.controller._predefined_callbacks['load_context_preset'] = self.load_context_preset self.controller._predefined_callbacks['set_ui_file_paths'] = lambda p: setattr(self, 'ui_file_paths', p) self.controller._predefined_callbacks['set_ui_screenshot_paths'] = lambda p: setattr(self, 'ui_screenshot_paths', p) + self.controller._predefined_callbacks['simulate_save_preset'] = self._simulate_save_preset self.controller._clickable_actions.update({ 'btn_undo': self._handle_undo, 'btn_redo': self._handle_redo, 'btn_open_external_editor': self._open_patch_in_external_editor, }) - def simulate_save_preset(name: str): - from src import models - item = models.FileItem(path='test.py') - self.files = [item] - self.context_files = [item] - self.screenshots = ['test.png'] - self.save_context_preset(name) - self.controller._predefined_callbacks['simulate_save_preset'] = simulate_save_preset + # --- UI Component State --- self.text_viewer_wrap = True self._text_viewer_editor: Optional[ced.TextEditor] = None + self.show_windows.setdefault("Diagnostics", False) + self.show_windows.setdefault("Usage Analytics", False) + self.show_windows.setdefault("Tier 1: Strategy", False) + self.show_windows.setdefault("Tier 2: Tech Lead", False) + self.show_windows.setdefault("Tier 3: Workers", False) + self.show_windows.setdefault("Tier 4: QA", False) + self.show_windows.setdefault('External Tools', False) + self.show_windows.setdefault('Shader Editor', False) + self.show_windows.setdefault('Undo/Redo History', False) + # --- Preset & Profile Management State --- self.ui_active_context_preset = "" + self.ui_new_context_preset_name = "" + self._new_preset_name = "" + self._editing_preset_name = "" + self._editing_preset_system_prompt = "" + self._editing_preset_temperature = 0.0 + self._editing_preset_top_p = 1.0 + self._editing_preset_max_output_tokens = 4096 + self._editing_preset_scope = "project" + self._editing_preset_is_new = False + self._presets_list: dict[str, dict] = {} + self._selected_preset_idx = -1 + self._show_save_preset_modal = False + self._editing_tool_preset_name = '' + self._editing_tool_preset_categories = {} + self._editing_tool_preset_scope = 'project' + self._selected_tool_preset_idx = -1 + self._editing_bias_profile_name = "" + self._editing_bias_profile_tool_weights: dict[str, int] = {} + self._editing_bias_profile_category_multipliers: dict[str, float] = {} + self._editing_bias_profile_scope = "project" + self._selected_bias_profile_idx = -1 + self._new_bias_tool_name = "run_powershell" + self._new_bias_category_name = "General" self._editing_persona_name = "" self._editing_persona_description = "" self._editing_persona_provider = "" @@ -169,28 +198,7 @@ class App: self._editing_persona_is_new = True self._persona_editor_opened = False self._personas_list: dict[str, dict] = {} - self._editing_bias_profile_name = "" - self._editing_bias_profile_tool_weights: dict[str, int] = {} - self._editing_bias_profile_category_multipliers: dict[str, float] = {} - self._editing_bias_profile_scope = "project" - self._editing_tool_preset_name = '' - self._editing_tool_preset_categories = {} - self._editing_tool_preset_scope = 'project' - self._selected_preset_idx = -1 - self._selected_tool_preset_idx = -1 - self._selected_bias_profile_idx = -1 - self._last_selected_context_index = -1 - self._new_bias_tool_name = "run_powershell" - self._new_bias_category_name = "General" - self._editing_preset_name = "" - self._editing_preset_system_prompt = "" - self._editing_preset_temperature = 0.0 - self._editing_preset_top_p = 1.0 - self._editing_preset_max_output_tokens = 4096 - self._editing_preset_scope = "project" - self._editing_preset_is_new = False - self._presets_list: dict[str, dict] = {} - # Layout state + # --- Layout State --- self._persona_split_v = 0.4 self._persona_models_open = True self._persona_prompt_open = True @@ -201,7 +209,16 @@ class App: self._bias_weights_open = True self._bias_cats_open = True self._prompt_md_preview = False - # Aliases for controller-owned locks + self.ui_discussion_split_h = 300.0 + # --- Workspace State --- + gui_cfg = self.config.get("gui", {}) + self.ui_multi_viewport = gui_cfg.get("multi_viewport", False) + self.layout_presets = self.config.get("layout_presets", {}) + self._show_save_workspace_profile_modal = False + self._new_workspace_profile_name = "" + self._new_workspace_profile_scope = "project" + self.ui_new_vp_name = "" + # --- Controller Lock Aliases --- self._send_thread_lock = self.controller._send_thread_lock self._disc_entries_lock = self.controller._disc_entries_lock self._pending_comms_lock = self.controller._pending_comms_lock @@ -210,45 +227,24 @@ class App: self._pending_gui_tasks_lock = self.controller._pending_gui_tasks_lock self._pending_dialog_lock = self.controller._pending_dialog_lock self._api_event_queue_lock = self.controller._api_event_queue_lock + # --- Cache & Discussion State --- self._discussion_names_cache: list[str] = [] self._discussion_names_dirty: bool = True - # Initialize node editor context + self._comms_log_cache: list[dict[str, Any]] = [] + self._tool_log_cache: list[dict[str, Any]] = [] + self._focus_md_cache: dict[str, str] = {} + self._last_ui_focus_agent: Optional[str] = None + self._log_registry: Optional[log_registry.LogRegistry] = None + # --- Node Editor State --- self.node_editor_config = ed.Config() self.node_editor_ctx = ed.create_editor(self.node_editor_config) + # --- Context & AST State --- self.ui_selected_ticket_id: Optional[str] = None self.ui_selected_tickets: set[str] = set() self.ui_selected_context_files: set[str] = set() self.ui_new_ticket_priority: str = 'medium' self._autofocus_response_tab = False - gui_cfg = self.config.get("gui", {}) - self.show_windows.setdefault("Usage Analytics", False) - self.show_windows.setdefault("Tier 1: Strategy", False) - self.show_windows.setdefault("Tier 2: Tech Lead", False) - self.show_windows.setdefault("Tier 3: Workers", False) - self.show_windows.setdefault("Tier 4: QA", False) - self.show_windows.setdefault('External Tools', False) - self.show_windows.setdefault('Shader Editor', False) - self.show_windows.setdefault('Undo/Redo History', 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._show_save_workspace_profile_modal = False - self._new_workspace_profile_name = "" - self._new_workspace_profile_scope = "project" - self._comms_log_cache: list[dict[str, Any]] = [] - self._tool_log_cache: list[dict[str, Any]] = [] - self._last_ui_focus_agent: Optional[str] = None - self._log_registry: Optional[log_registry.LogRegistry] = None - self.perf_show_graphs: dict[str, bool] = {} - self.ui_crt_filter = False - self.ui_tool_filter_category = "All" - self.ui_discussion_split_h = 300.0 - self.shader_uniforms = {'crt': 1.0, 'scanline': 0.5, 'bloom': 0.8} - self.shader_uniforms = {'crt': 1.0, 'scanline': 0.5, 'bloom': 0.8} - self.ui_new_context_preset_name = "" - self.ui_new_vp_name = "" - self._focus_md_cache: dict[str, str] = {} + self._last_selected_context_index = -1 self.ui_inspecting_ast_file = None self._show_ast_inspector = False self._cached_ast_nodes = [] @@ -258,8 +254,23 @@ class App: self._slice_sel_start = -1 self._slice_sel_end = -1 self.context_files = [] + # --- Rendering & Theme State --- + self.perf_show_graphs: dict[str, bool] = {} + self.ui_crt_filter = False + self.ui_tool_filter_category = "All" + self.shader_uniforms = {'crt': 1.0, 'scanline': 0.5, 'bloom': 0.8} + + def _simulate_save_preset(self, name: str) -> None: + from src import models + item = models.FileItem(path='test.py') + self.files = [item] + self.context_files = [item] + self.screenshots = ['test.png'] + self.save_context_preset(name) + + def _handle_approve_ask(self) -> None: """UI-level wrapper for approving a pending tool execution ask.""" - self._handle_approve_ask() + self.controller._handle_approve_ask() def _post_init(self) -> None: theme.apply_current()