""" Main application window — sidebar + tabview layout. """ import customtkinter as ctk from tkinter import messagebox from core.server_store import ServerStore from core.status_checker import StatusChecker from gui.sidebar import Sidebar from gui.server_dialog import ServerDialog from gui.tabs.terminal_tab import TerminalTab from gui.tabs.files_tab import FilesTab from gui.tabs.info_tab import InfoTab from gui.tabs.keys_tab import KeysTab class App(ctk.CTk): def __init__(self): super().__init__() # Window config self.title("ServerManager") self.geometry("1100x700") self.minsize(900, 500) ctk.set_appearance_mode("dark") ctk.set_default_color_theme("blue") # Core self.store = ServerStore() self.checker = StatusChecker(self.store, interval=60) # Layout self._build_layout() # Status checker self.checker.set_gui_callback(lambda: self.after(0, self._on_status_update)) self.checker.start() self.checker.check_all_now() # Cleanup on close self.protocol("WM_DELETE_WINDOW", self._on_close) def _build_layout(self): # Sidebar self.sidebar = Sidebar(self, self.store, on_select=self._on_server_select) self.sidebar.pack(side="left", fill="y") self.sidebar.add_callback = self._add_server self.sidebar.edit_callback = self._edit_server self.sidebar.delete_callback = self._delete_server # Main area main = ctk.CTkFrame(self, fg_color="transparent") main.pack(side="right", fill="both", expand=True) # Tabview self.tabview = ctk.CTkTabview(main) self.tabview.pack(fill="both", expand=True, padx=10, pady=10) # Tabs self.tabview.add("Terminal") self.tabview.add("Files") self.tabview.add("Info") self.tabview.add("Keys") self.terminal_tab = TerminalTab(self.tabview.tab("Terminal"), self.store) self.terminal_tab.pack(fill="both", expand=True) self.files_tab = FilesTab(self.tabview.tab("Files"), self.store) self.files_tab.pack(fill="both", expand=True) self.info_tab = InfoTab(self.tabview.tab("Info"), self.store, edit_callback=self._edit_server) self.info_tab.pack(fill="both", expand=True) self.keys_tab = KeysTab(self.tabview.tab("Keys"), self.store) self.keys_tab.pack(fill="both", expand=True) def _on_server_select(self, alias: str): self.terminal_tab.set_server(alias) self.files_tab.set_server(alias) self.info_tab.set_server(alias) self.keys_tab.set_server(alias) def _add_server(self): dialog = ServerDialog(self, self.store) self.wait_window(dialog) def _edit_server(self, alias: str): server = self.store.get_server(alias) if server: dialog = ServerDialog(self, self.store, server=server) self.wait_window(dialog) self.info_tab.refresh() def _delete_server(self, alias: str): if messagebox.askyesno("Delete Server", f"Remove '{alias}'?"): self.store.remove_server(alias) self._on_server_select(None) def _on_status_update(self): self.sidebar.update_statuses() self.info_tab.refresh() def _on_close(self): self.checker.stop() self.destroy()