From f5ef2d850f8821a2a0a08da74e36ed4f7311de83 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 23 Feb 2026 22:36:45 -0500 Subject: [PATCH] refactor(gui): Implement user feedback for UI layout --- gui_2.py | 151 +++++++++++++++++++------------------- refactor_gui2_v2.py | 128 ++++++++++++++++++++++++++++++++ tests/test_gui2_layout.py | 4 +- 3 files changed, 206 insertions(+), 77 deletions(-) create mode 100644 refactor_gui2_v2.py diff --git a/gui_2.py b/gui_2.py index 70c0b09..5951638 100644 --- a/gui_2.py +++ b/gui_2.py @@ -159,9 +159,11 @@ class App: _default_windows = { "Context Hub": True, - "AI Settings Hub": True, + "Files & Media": True, + "AI Settings": True, "Discussion Hub": True, "Operations Hub": True, + "Theme": True, "Diagnostics": False, } saved = self.config.get("gui", {}).get("show_windows", {}) @@ -683,62 +685,57 @@ class App: # imgui.end_main_menu_bar() - # ---- Context Hub + + # --- Hubs --- 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() + self._render_projects_panel() 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 self.show_windows.get("Files & Media", False): + exp, self.show_windows["Files & Media"] = imgui.begin("Files & Media", self.show_windows["Files & Media"]) 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() + if imgui.collapsing_header("Files"): + self._render_files_panel() + if imgui.collapsing_header("Screenshots"): + self._render_screenshots_panel() imgui.end() - # ---- Discussion Hub + if self.show_windows.get("AI Settings", False): + exp, self.show_windows["AI Settings"] = imgui.begin("AI Settings", self.show_windows["AI Settings"]) + if exp: + if imgui.collapsing_header("Provider & Model"): + self._render_provider_panel() + if imgui.collapsing_header("System Prompts"): + self._render_system_prompts_panel() + imgui.end() + + if self.show_windows.get("Theme", False): + self._render_theme_panel() + 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"): + # Top part for the history + with imgui.begin_child("HistoryChild", size=(0, -200)): + self._render_discussion_panel() + + # Bottom part with tabs for message and response + if imgui.begin_tab_bar("MessageResponseTabs"): 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() + imgui.end_tab_bar() + imgui.end() + + 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("Tool Calls")[0]: self._render_tool_calls_panel() imgui.end_tab_item() @@ -747,7 +744,6 @@ class App: imgui.end_tab_item() imgui.end_tab_bar() imgui.end() - # ---- Diagnostics if self.show_windows["Diagnostics"]: exp, self.show_windows["Diagnostics"] = imgui.begin("Diagnostics", self.show_windows["Diagnostics"]) if exp: @@ -1609,42 +1605,45 @@ class App: ch, self.ui_project_system_prompt = imgui.input_text_multiline("##psp", self.ui_project_system_prompt, imgui.ImVec2(-1, 100)) def _render_theme_panel(self): - imgui.text("Palette") - cp = theme.get_current_palette() - if imgui.begin_combo("##pal", cp): - for p in theme.get_palette_names(): - if imgui.selectable(p, p == cp)[0]: - theme.apply(p) - imgui.end_combo() - imgui.separator() - imgui.text("Font") - imgui.push_item_width(-150) - ch, path = imgui.input_text("##fontp", theme.get_current_font_path()) - imgui.pop_item_width() - if ch: theme._current_font_path = path - imgui.same_line() - if imgui.button("Browse##font"): - r = hide_tk_root() - p = filedialog.askopenfilename(filetypes=[("Fonts", "*.ttf *.otf"), ("All", "*.*")]) - r.destroy() - if p: theme._current_font_path = p + exp, self.show_windows["Theme"] = imgui.begin("Theme", self.show_windows["Theme"]) + if exp: + imgui.text("Palette") + cp = theme.get_current_palette() + if imgui.begin_combo("##pal", cp): + for p in theme.get_palette_names(): + if imgui.selectable(p, p == cp)[0]: + theme.apply(p) + imgui.end_combo() + imgui.separator() + imgui.text("Font") + imgui.push_item_width(-150) + ch, path = imgui.input_text("##fontp", theme.get_current_font_path()) + imgui.pop_item_width() + if ch: theme._current_font_path = path + imgui.same_line() + if imgui.button("Browse##font"): + r = hide_tk_root() + p = filedialog.askopenfilename(filetypes=[("Fonts", "*.ttf *.otf"), ("All", "*.*")]) + r.destroy() + if p: theme._current_font_path = p + + imgui.text("Size (px)") + imgui.same_line() + imgui.push_item_width(100) + ch, size = imgui.input_float("##fonts", theme.get_current_font_size(), 1.0, 1.0, "%.0f") + if ch: theme._current_font_size = size + imgui.pop_item_width() + imgui.same_line() + if imgui.button("Apply Font (Requires Restart)"): + self._flush_to_config() + save_config(self.config) + self.ai_status = "Font settings saved. Restart required." - imgui.text("Size (px)") - imgui.same_line() - imgui.push_item_width(100) - ch, size = imgui.input_float("##fonts", theme.get_current_font_size(), 1.0, 1.0, "%.0f") - if ch: theme._current_font_size = size - imgui.pop_item_width() - imgui.same_line() - if imgui.button("Apply Font (Requires Restart)"): - self._flush_to_config() - save_config(self.config) - self.ai_status = "Font settings saved. Restart required." - - imgui.separator() - imgui.text("UI Scale (DPI)") - ch, scale = imgui.slider_float("##scale", theme.get_current_scale(), 0.5, 3.0, "%.2f") - if ch: theme.set_scale(scale) + imgui.separator() + imgui.text("UI Scale (DPI)") + ch, scale = imgui.slider_float("##scale", theme.get_current_scale(), 0.5, 3.0, "%.2f") + if ch: theme.set_scale(scale) + imgui.end() def _load_fonts(self): font_path, font_size = theme.get_font_loading_params() diff --git a/refactor_gui2_v2.py b/refactor_gui2_v2.py new file mode 100644 index 0000000..be635b6 --- /dev/null +++ b/refactor_gui2_v2.py @@ -0,0 +1,128 @@ +import re +import sys + +def main(): + with open("gui_2.py", "r", encoding="utf-8") as f: + content = f.read() + + # Define the new structure for the GUI function + new_gui_func_body = """ + # --- Hubs --- + 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: + self._render_projects_panel() + imgui.end() + + if self.show_windows.get("Files & Media", False): + exp, self.show_windows["Files & Media"] = imgui.begin("Files & Media", self.show_windows["Files & Media"]) + if exp: + if imgui.collapsing_header("Files"): + self._render_files_panel() + if imgui.collapsing_header("Screenshots"): + self._render_screenshots_panel() + imgui.end() + + if self.show_windows.get("AI Settings", False): + exp, self.show_windows["AI Settings"] = imgui.begin("AI Settings", self.show_windows["AI Settings"]) + if exp: + if imgui.collapsing_header("Provider & Model"): + self._render_provider_panel() + if imgui.collapsing_header("System Prompts"): + self._render_system_prompts_panel() + imgui.end() + + if self.show_windows.get("Theme", False): + self._render_theme_panel() + + 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: + # Top part for the history + with imgui.begin_child("HistoryChild", size=(0, -200)): + self._render_discussion_panel() + + # Bottom part with tabs for message and response + if imgui.begin_tab_bar("MessageResponseTabs"): + 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() + imgui.end_tab_bar() + imgui.end() + + 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("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 the old hub code with the new one + start_marker = "# ---- Context Hub" + end_marker = "# ---- Diagnostics" + + start_idx = content.find(start_marker) + end_idx = content.find(end_marker) + + if start_idx != -1 and end_idx != -1: + indented_new_code = "\\n".join([f" {line}" for line in new_gui_func_body.split("\\n")]) + content = content[:start_idx] + indented_new_code + content[end_idx:] + else: + print("Could not find the hub markers to replace.") + sys.exit(1) + + # Update the _default_windows dictionary to reflect the new layout + old_default = """ _default_windows = { + "Context Hub": True, + "AI Settings Hub": True, + "Discussion Hub": True, + "Operations Hub": True, + "Diagnostics": False, + }""" + new_default = """ _default_windows = { + "Context Hub": True, + "Files & Media": True, + "AI Settings": True, + "Discussion Hub": True, + "Operations Hub": True, + "Theme": True, + "Diagnostics": False, + }""" + content = content.replace(old_default, new_default) + + theme_method_start = "def _render_theme_panel(self):" + theme_method_end_line = "theme.set_scale(scale)" + + theme_start_idx = content.find(theme_method_start) + if theme_start_idx != -1: + theme_end_idx = content.find(theme_method_end_line, theme_start_idx) + if theme_end_idx != -1: + theme_end_idx += len(theme_method_end_line) + body = content[theme_start_idx + len(theme_method_start) : theme_end_idx] + + new_theme_method = """ def _render_theme_panel(self): + exp, self.show_windows["Theme"] = imgui.begin("Theme", self.show_windows["Theme"]) + if exp: +{} + imgui.end() +""".format(body) + old_method_text = content[theme_start_idx : theme_end_idx+1] + content = content.replace(old_method_text, new_theme_method) + + with open("gui_2.py", "w", encoding="utf-8") as f: + f.write(content) + + print("GUI refactoring V2 complete.") + +if __name__ == "__main__": + main() diff --git a/tests/test_gui2_layout.py b/tests/test_gui2_layout.py index 1fa475b..55bdd85 100644 --- a/tests/test_gui2_layout.py +++ b/tests/test_gui2_layout.py @@ -24,9 +24,11 @@ def test_gui2_hubs_exist_in_show_windows(app_instance): """ expected_hubs = [ "Context Hub", - "AI Settings Hub", + "AI Settings", "Discussion Hub", "Operations Hub", + "Files & Media", + "Theme", ] for hub in expected_hubs: