def draw_canvas(self): width = self.guiconfig["preferences"]["width"] height = self.guiconfig["preferences"]["height"] self.canvas = CanvasGraph(self, self.core, width, height) self.canvas.pack(fill=tk.BOTH, expand=True) scroll_x = ttk.Scrollbar(self.canvas, orient=tk.HORIZONTAL, command=self.canvas.xview) scroll_x.pack(side=tk.BOTTOM, fill=tk.X) scroll_y = ttk.Scrollbar(self.canvas, command=self.canvas.yview) scroll_y.pack(side=tk.RIGHT, fill=tk.Y) self.canvas.configure(xscrollcommand=scroll_x.set) self.canvas.configure(yscrollcommand=scroll_y.set)
def draw_canvas(self) -> None: canvas_frame = ttk.Frame(self.right_frame) canvas_frame.rowconfigure(0, weight=1) canvas_frame.columnconfigure(0, weight=1) canvas_frame.grid(sticky="nsew", pady=1) self.canvas = CanvasGraph(canvas_frame, self, self.core) self.canvas.grid(sticky="nsew") scroll_y = ttk.Scrollbar(canvas_frame, command=self.canvas.yview) scroll_y.grid(row=0, column=1, sticky="ns") scroll_x = ttk.Scrollbar(canvas_frame, orient=tk.HORIZONTAL, command=self.canvas.xview) scroll_x.grid(row=1, column=0, sticky="ew") self.canvas.configure(xscrollcommand=scroll_x.set) self.canvas.configure(yscrollcommand=scroll_y.set)
def add_canvas(self, canvas_id: int = None) -> CanvasGraph: # create tab frame tab = ttk.Frame(self.notebook, padding=0) tab.grid(sticky=tk.NSEW) tab.columnconfigure(0, weight=1) tab.rowconfigure(0, weight=1) if canvas_id is None: canvas_id = self._next_id() self.notebook.add(tab, text=f"Canvas {canvas_id}") unique_id = self.notebook.tabs()[-1] logging.info("creating canvas(%s)", canvas_id) self.canvas_ids[unique_id] = canvas_id self.unique_ids[canvas_id] = unique_id # create canvas canvas = CanvasGraph( tab, self.app, self, self.core, canvas_id, self.default_dimensions ) canvas.grid(sticky=tk.NSEW) self.canvases[canvas_id] = canvas # add scrollbars scroll_y = ttk.Scrollbar(tab, command=canvas.yview) scroll_y.grid(row=0, column=1, sticky=tk.NS) scroll_x = ttk.Scrollbar(tab, orient=tk.HORIZONTAL, command=canvas.xview) scroll_x.grid(row=1, column=0, sticky=tk.EW) canvas.configure(xscrollcommand=scroll_x.set) canvas.configure(yscrollcommand=scroll_y.set) return canvas
class Application(ttk.Frame): def __init__(self, proxy: bool) -> None: super().__init__() # load node icons NodeUtils.setup() # widgets self.menubar = None self.toolbar = None self.right_frame = None self.canvas = None self.statusbar = None self.progress = None # fonts self.fonts_size = None self.icon_text_font = None self.edge_font = None # setup self.guiconfig = appconfig.read() self.app_scale = self.guiconfig.scale self.setup_scaling() self.style = ttk.Style() self.setup_theme() self.core = CoreClient(self, proxy) self.setup_app() self.draw() self.core.setup() def setup_scaling(self) -> None: self.fonts_size = { name: font.nametofont(name)["size"] for name in font.names() } text_scale = self.app_scale if self.app_scale < 1 else math.sqrt( self.app_scale) themes.scale_fonts(self.fonts_size, self.app_scale) self.icon_text_font = font.Font(family="TkIconFont", size=int(12 * text_scale)) self.edge_font = font.Font(family="TkDefaultFont", size=int(8 * text_scale), weight=font.BOLD) def setup_theme(self) -> None: themes.load(self.style) self.master.bind_class("Menu", "<<ThemeChanged>>", themes.theme_change_menu) self.master.bind("<<ThemeChanged>>", themes.theme_change) self.style.theme_use(self.guiconfig.preferences.theme) def setup_app(self) -> None: self.master.title("CORE") self.center() self.master.protocol("WM_DELETE_WINDOW", self.on_closing) image = Images.get(ImageEnum.CORE, 16) self.master.tk.call("wm", "iconphoto", self.master._w, image) self.master.option_add("*tearOff", tk.FALSE) self.setup_file_dialogs() def setup_file_dialogs(self) -> None: """ Hack code that needs to initialize a bad dialog so that we can apply, global settings for dialogs to not show hidden files by default and display the hidden file toggle. :return: nothing """ try: self.master.tk.call("tk_getOpenFile", "-foobar") except tk.TclError: pass self.master.tk.call("set", "::tk::dialog::file::showHiddenBtn", "1") self.master.tk.call("set", "::tk::dialog::file::showHiddenVar", "0") def center(self) -> None: screen_width = self.master.winfo_screenwidth() screen_height = self.master.winfo_screenheight() x = int((screen_width / 2) - (WIDTH * self.app_scale / 2)) y = int((screen_height / 2) - (HEIGHT * self.app_scale / 2)) self.master.geometry( f"{int(WIDTH * self.app_scale)}x{int(HEIGHT * self.app_scale)}+{x}+{y}" ) def draw(self) -> None: self.master.rowconfigure(0, weight=1) self.master.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self.columnconfigure(1, weight=1) self.grid(sticky="nsew") self.toolbar = Toolbar(self) self.toolbar.grid(sticky="ns") self.right_frame = ttk.Frame(self) self.right_frame.columnconfigure(0, weight=1) self.right_frame.rowconfigure(0, weight=1) self.right_frame.grid(row=0, column=1, sticky="nsew") self.draw_canvas() self.draw_status() self.progress = Progressbar(self.right_frame, mode="indeterminate") self.menubar = Menubar(self) self.master.config(menu=self.menubar) def draw_canvas(self) -> None: canvas_frame = ttk.Frame(self.right_frame) canvas_frame.rowconfigure(0, weight=1) canvas_frame.columnconfigure(0, weight=1) canvas_frame.grid(sticky="nsew", pady=1) self.canvas = CanvasGraph(canvas_frame, self, self.core) self.canvas.grid(sticky="nsew") scroll_y = ttk.Scrollbar(canvas_frame, command=self.canvas.yview) scroll_y.grid(row=0, column=1, sticky="ns") scroll_x = ttk.Scrollbar(canvas_frame, orient=tk.HORIZONTAL, command=self.canvas.xview) scroll_x.grid(row=1, column=0, sticky="ew") self.canvas.configure(xscrollcommand=scroll_x.set) self.canvas.configure(yscrollcommand=scroll_y.set) def draw_status(self) -> None: self.statusbar = StatusBar(self.right_frame, self) self.statusbar.grid(sticky="ew") def show_grpc_exception(self, title: str, e: grpc.RpcError) -> None: logging.exception("app grpc exception", exc_info=e) message = e.details() self.show_error(title, message) def show_exception(self, title: str, e: Exception) -> None: logging.exception("app exception", exc_info=e) self.show_error(title, str(e)) def show_error(self, title: str, message: str) -> None: self.after(0, lambda: ErrorDialog(self, title, message).show()) def on_closing(self) -> None: if self.toolbar.picker: self.toolbar.picker.destroy() self.menubar.prompt_save_running_session(True) def save_config(self) -> None: appconfig.save(self.guiconfig) def joined_session_update(self) -> None: if self.core.is_runtime(): self.toolbar.set_runtime() else: self.toolbar.set_design() def get_icon(self, image_enum: ImageEnum, width: int) -> PhotoImage: return Images.get(image_enum, int(width * self.app_scale)) def get_custom_icon(self, image_file: str, width: int) -> PhotoImage: return Images.get_custom(image_file, int(width * self.app_scale)) def close(self) -> None: self.master.destroy()
class Application(tk.Frame): def __init__(self, proxy: bool): super().__init__(master=None) # load node icons NodeUtils.setup() # widgets self.menubar = None self.toolbar = None self.canvas = None self.statusbar = None self.validation = None # setup self.guiconfig = appconfig.read() self.style = ttk.Style() self.setup_theme() self.core = CoreClient(self, proxy) self.setup_app() self.draw() self.core.set_up() def setup_theme(self): themes.load(self.style) self.master.bind_class("Menu", "<<ThemeChanged>>", themes.theme_change_menu) self.master.bind("<<ThemeChanged>>", themes.theme_change) self.style.theme_use(self.guiconfig["preferences"]["theme"]) def setup_app(self): self.master.title("CORE") self.center() self.master.protocol("WM_DELETE_WINDOW", self.on_closing) image = Images.get(ImageEnum.CORE, 16) self.master.tk.call("wm", "iconphoto", self.master._w, image) self.pack(fill=tk.BOTH, expand=True) self.validation = InputValidation(self) def center(self): screen_width = self.master.winfo_screenwidth() screen_height = self.master.winfo_screenheight() x = int((screen_width / 2) - (WIDTH / 2)) y = int((screen_height / 2) - (HEIGHT / 2)) self.master.geometry(f"{WIDTH}x{HEIGHT}+{x}+{y}") def draw(self): self.master.option_add("*tearOff", tk.FALSE) self.menubar = Menubar(self.master, self) self.toolbar = Toolbar(self, self) self.toolbar.pack(side=tk.LEFT, fill=tk.Y, ipadx=2, ipady=2) self.draw_canvas() self.draw_status() def draw_canvas(self): width = self.guiconfig["preferences"]["width"] height = self.guiconfig["preferences"]["height"] self.canvas = CanvasGraph(self, self.core, width, height) self.canvas.pack(fill=tk.BOTH, expand=True) scroll_x = ttk.Scrollbar(self.canvas, orient=tk.HORIZONTAL, command=self.canvas.xview) scroll_x.pack(side=tk.BOTTOM, fill=tk.X) scroll_y = ttk.Scrollbar(self.canvas, command=self.canvas.yview) scroll_y.pack(side=tk.RIGHT, fill=tk.Y) self.canvas.configure(xscrollcommand=scroll_x.set) self.canvas.configure(yscrollcommand=scroll_y.set) def draw_status(self): self.statusbar = StatusBar(master=self, app=self) self.statusbar.pack(side=tk.BOTTOM, fill=tk.X) def on_closing(self): menu_action = MenuAction(self, self.master) menu_action.on_quit() def save_config(self): appconfig.save(self.guiconfig) def joined_session_update(self): self.statusbar.progress_bar.stop() if self.core.is_runtime(): self.toolbar.set_runtime() else: self.toolbar.set_design() def close(self): self.master.destroy()