import re import sys def main(): with open("gui_2.py", "r", encoding="utf-8") as f: content = f.read() # 1. Update _default_windows dictionary old_default = """ _default_windows = { "Projects": True, "Files": True, "Screenshots": True, "Discussion History": True, "Provider": True, "Message": True, "Response": True, "Tool Calls": True, "Comms History": True, "System Prompts": True, "Theme": True, "Diagnostics": False, }""" new_default = """ _default_windows = { "Context Hub": True, "AI Settings Hub": True, "Discussion Hub": True, "Operations Hub": True, "Diagnostics": False, }""" if old_default in content: content = content.replace(old_default, new_default) else: print("Could not find _default_windows block") # 2. Extract panels into methods panels = { "Projects": "_render_projects_panel", "Files": "_render_files_panel", "Screenshots": "_render_screenshots_panel", "Discussion History": "_render_discussion_panel", "Provider": "_render_provider_panel", "Message": "_render_message_panel", "Response": "_render_response_panel", "Tool Calls": "_render_tool_calls_panel", "Comms History": "_render_comms_history_panel", "System Prompts": "_render_system_prompts_panel", "Theme": "_render_theme_panel", } methods = [] # We will search for: # # ---- PanelName # if self.show_windows["PanelName"]: # ... (until imgui.end()) for panel_name, method_name in panels.items(): # Build a regex to match the entire panel block # We need to capture from the comment to the corresponding imgui.end() # This requires matching balanced indentation or looking for specific end tokens. # Since each block ends with ` imgui.end()\n`, we can use that. # But wait, some panels like 'Response' might have different structures. # A simpler way: split the file by `# ---- ` comments. pass # Actually, the safest way is to replace the whole `_gui_func` body from `# ---- Projects` down to just before `# ---- Diagnostics`. start_marker = " # ---- Projects" end_marker = " # ---- Diagnostics" start_idx = content.find(start_marker) end_idx = content.find(end_marker) if start_idx == -1 or end_idx == -1: print("Markers not found!") sys.exit(1) panels_text = content[start_idx:end_idx] # Now split panels_text by `# ---- ` panel_chunks = panels_text.split(" # ---- ") methods_code = "" for chunk in panel_chunks: if not chunk.strip(): continue # Find the panel name (first line) lines = chunk.split('\n') name = lines[0].strip() if name not in panels: continue method_name = panels[name] # The rest of the lines are the panel logic. # We need to remove the `if self.show_windows["..."]:` check and the `imgui.begin()`/`imgui.end()` calls. # But wait! For ImGui, when we move them to child tabs, we DON'T want `imgui.begin` and `imgui.end`. # We just want the contents inside `if exp:` # This is critical! A tab item acts as the container. # Let's extract everything inside `if exp:` or just before `imgui.begin()`. # Find the line with `imgui.begin(` begin_line_idx = -1 end_line_idx = -1 for i, line in enumerate(lines): if "imgui.begin(" in line: begin_line_idx = i elif "imgui.end()" in line: end_line_idx = i if begin_line_idx == -1 or end_line_idx == -1: print(f"Could not parse begin/end for {name}") continue # Lines before begin (e.g. blinking logic in Response) pre_begin_lines = lines[2:begin_line_idx] # skipping `if self.show_windows...:` # Lines between `if exp:` and `imgui.end()` # Usually it's ` if exp:\n ...` # We need to check if line after begin is `if exp:` exp_check_idx = begin_line_idx + 1 content_lines = [] if "if exp:" in lines[exp_check_idx] or "if expanded:" in lines[exp_check_idx]: content_lines = lines[exp_check_idx+1:end_line_idx] else: content_lines = lines[begin_line_idx+1:end_line_idx] # Post end lines (e.g. pop_style_color in Response) # Wait, the pop_style_color is BEFORE imgui.end() # So it's already in content_lines. # Reconstruct the method body method_body = [] for line in pre_begin_lines: # unindent by 12 spaces (was under `if self.show_windows...`) if line.startswith(" "): method_body.append(line[12:]) else: method_body.append(line) for line in content_lines: # unindent by 16 spaces (was under `if exp:`) if line.startswith(" "): method_body.append(line[8:]) elif line.startswith(" "): # like pop_style_color which is under `if show_windows` method_body.append(line[12:]) else: method_body.append(line) methods_code += f" def {method_name}(self):\n" for line in method_body: methods_code += f" {line}\n" methods_code += "\n" # Hub rendering code hub_code = """ # ---- Context Hub if self.show_windows.get("Context Hub", False): exp, self.show_windows["Context Hub"] = imgui.begin("Context Hub", self.show_windows["Context Hub"]) if exp: if imgui.begin_tab_bar("ContextTabs"): if imgui.begin_tab_item("Projects")[0]: self._render_projects_panel() imgui.end_tab_item() if imgui.begin_tab_item("Files")[0]: self._render_files_panel() imgui.end_tab_item() if imgui.begin_tab_item("Screenshots")[0]: self._render_screenshots_panel() imgui.end_tab_item() imgui.end_tab_bar() imgui.end() # ---- AI Settings Hub if self.show_windows.get("AI Settings Hub", False): exp, self.show_windows["AI Settings Hub"] = imgui.begin("AI Settings Hub", self.show_windows["AI Settings Hub"]) if exp: if imgui.begin_tab_bar("AISettingsTabs"): if imgui.begin_tab_item("Provider")[0]: self._render_provider_panel() imgui.end_tab_item() if imgui.begin_tab_item("System Prompts")[0]: self._render_system_prompts_panel() imgui.end_tab_item() if imgui.begin_tab_item("Theme")[0]: self._render_theme_panel() imgui.end_tab_item() imgui.end_tab_bar() imgui.end() # ---- Discussion Hub if self.show_windows.get("Discussion Hub", False): exp, self.show_windows["Discussion Hub"] = imgui.begin("Discussion Hub", self.show_windows["Discussion Hub"]) if exp: if imgui.begin_tab_bar("DiscussionTabs"): if imgui.begin_tab_item("History")[0]: self._render_discussion_panel() imgui.end_tab_item() imgui.end_tab_bar() imgui.end() # ---- Operations Hub if self.show_windows.get("Operations Hub", False): exp, self.show_windows["Operations Hub"] = imgui.begin("Operations Hub", self.show_windows["Operations Hub"]) if exp: if imgui.begin_tab_bar("OperationsTabs"): if imgui.begin_tab_item("Message")[0]: self._render_message_panel() imgui.end_tab_item() if imgui.begin_tab_item("Response")[0]: self._render_response_panel() imgui.end_tab_item() if imgui.begin_tab_item("Tool Calls")[0]: self._render_tool_calls_panel() imgui.end_tab_item() if imgui.begin_tab_item("Comms History")[0]: self._render_comms_history_panel() imgui.end_tab_item() imgui.end_tab_bar() imgui.end() """ # Replace panels_text with hub_code content = content[:start_idx] + hub_code + content[end_idx:] # Append methods_code to the end of the App class # We find the end of the class by looking for `def _load_fonts(self):` # and inserting methods_code right before it. fonts_idx = content.find(" def _load_fonts(self):") content = content[:fonts_idx] + methods_code + content[fonts_idx:] with open("gui_2.py", "w", encoding="utf-8") as f: f.write(content) print("Refactoring complete.") if __name__ == "__main__": main()