From 2f389c8d0e51567a175f5cfb6ee26b4901c3417f Mon Sep 17 00:00:00 2001 From: SantaSpeen Date: Thu, 27 Mar 2025 13:13:25 +0300 Subject: [PATCH] [~] Optimize render --- boxes/CTkMessageBox.py | 56 ++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/boxes/CTkMessageBox.py b/boxes/CTkMessageBox.py index 5721387..2abdb2b 100644 --- a/boxes/CTkMessageBox.py +++ b/boxes/CTkMessageBox.py @@ -26,8 +26,8 @@ class CTkMessageBox(ctk.CTkToplevel): }, "error": {"Ok": {"output": True, "row": 0, "column": 0, "sticky": "center"}}, "yesno": { - "Yes": {"output": True, "row": 0, "column": 0, "sticky": "e"}, - "No": {"output": False, "row": 0, "column": 1, "sticky": "w"} + "Yes": {"output": True, "row": 0, "width": 60, "padx": (0, 75)}, + "No": {"output": False, "row": 0, "width": 60, "padx": (0, 0)} } } def __init__(self, @@ -53,6 +53,8 @@ class CTkMessageBox(ctk.CTkToplevel): buttons: Dict[str, Any] | str = 'auto'): super().__init__(fg_color=fg_color) + self.resizable(False, False) + self.withdraw() self._fg_color = ThemeManager.theme["CTkToplevel"]["fg_color"] if fg_color is None else self._check_color_type(fg_color) self._text_color = ThemeManager.theme["CTkLabel"]["text_color"] if text_color is None else self._check_color_type(button_hover_color) @@ -73,7 +75,7 @@ class CTkMessageBox(ctk.CTkToplevel): _text_slt = [] - _x = 0 + self._x = 0 for line in self._text.split('\n'): if len(line) * 7 > 700: wrapped_lines = wrap_text(line, max_message_line_width) @@ -81,55 +83,52 @@ class CTkMessageBox(ctk.CTkToplevel): else: _text_slt.append(line) - _x = max(_x, max(len(w) * 7 for w in _text_slt)) - _x += 20 # Add 20 pixels for padding on the left and right - _x += 10 # Add 10 pixels for padding on the left and right + self._x = max(self._x, max(len(w) * 7 for w in _text_slt)) + self._x += 20 # Add 20 pixels for padding on the left and right + self._x += 10 # Add 10 pixels for padding on the left and right - _x = max(_x, (len(self.header_map[mode]) * 16) + 25 + 20) # Set width to the length of the title if it's longer than the message + self._x = max(self._x, (len(self.header_map[mode]) * 16) + 25 + 20) # Set width to the length of the title if it's longer than the message self._text = "\n".join(_text_slt) - _y = 0 - _y += 24 + 10 + 5 # Add 24 pixels for the header (icon + text) and 15 pixels for padding - _y += len(_text_slt) * 12 # Calculate height based on the number of lines in self._text - _y += 15 + 10 # Add 25 pixels for padding between the header and the message + self._y = 0 + self._y += 24 + 10 + 5 # Add 24 pixels for the header (icon + text) and 15 pixels for padding + self._y += len(_text_slt) * 12 # Calculate height based on the number of lines in self._text + self._y += 15 + 10 # Add 25 pixels for padding between the header and the message if timeout > 0: if self._header: header = self._header(self, self.title(), disable_hide=True, disable_close=True) header.pack(fill="x", pady=(0, 0)) - self.geometry(f"{_x}x{_y}") + self.geometry(f"{self._x}x{self._y}") self.overrideredirect(True) # remove window decorations - self.after(self._timeout, self.destroy) # close window after timeout + self.after(self._timeout, self._on_closing) # close window after timeout self._buttons = {} else: - _y += 30 + 10 + 12 # Add 30 pixels for the buttons - self.geometry(f"{_x}x{_y+12}") # Add 12 pixels to the height for the title bar + self._y += 30 + 10 + 12 # Add 30 pixels for the buttons + self.geometry(f"{self._x}x{self._y+12}") # Add 12 pixels to the height for the title bar if buttons == "auto": self._buttons = self.buttons_map.get(self._mode, {}) elif isinstance(buttons, str): self._buttons = {buttons: {"output": True, "row": 0, "column": 0, "sticky": "center"}} self.attributes("-topmost", True) # stay on top + self._center() self.transient(parent) self.title(title) - self.lift() # lift window on top - self.protocol("WM_DELETE_WINDOW", self._on_closing) self._create_widgets() - self.resizable(False, False) - self._set_on_pos() - self.grab_set() # make other windows not clickable - - def _set_on_pos(self): - self.update_idletasks() - y = (self.winfo_screenheight() - self.winfo_reqheight()) // 8 - self.geometry(f"+{y}+{y}") + self.protocol("WM_DELETE_WINDOW", self._on_closing) def _on_closing(self): + self.withdraw() self.grab_release() - if self.winfo_exists(): - self.destroy() + self.destroy() + + def _center(self): + x = (self.winfo_screenwidth() - self._x) // 2 + y = (self.winfo_screenheight() - self._y) // 2 + self.geometry(f'{x}+{y}') def _create_widgets(self): # Иконки для типов сообщений @@ -166,6 +165,9 @@ class CTkMessageBox(ctk.CTkToplevel): self._on_closing() def get_output(self): + self.lift() + self.grab_set() + self.deiconify() self.master.wait_window(self) if self._timeout > 0 and not self._input: return