[~] Optimize render

This commit is contained in:
Maxim Khomutov 2025-03-27 13:13:25 +03:00
parent cf62a0e750
commit 2f389c8d0e

View File

@ -26,8 +26,8 @@ class CTkMessageBox(ctk.CTkToplevel):
}, },
"error": {"Ok": {"output": True, "row": 0, "column": 0, "sticky": "center"}}, "error": {"Ok": {"output": True, "row": 0, "column": 0, "sticky": "center"}},
"yesno": { "yesno": {
"Yes": {"output": True, "row": 0, "column": 0, "sticky": "e"}, "Yes": {"output": True, "row": 0, "width": 60, "padx": (0, 75)},
"No": {"output": False, "row": 0, "column": 1, "sticky": "w"} "No": {"output": False, "row": 0, "width": 60, "padx": (0, 0)}
} }
} }
def __init__(self, def __init__(self,
@ -53,6 +53,8 @@ class CTkMessageBox(ctk.CTkToplevel):
buttons: Dict[str, Any] | str = 'auto'): buttons: Dict[str, Any] | str = 'auto'):
super().__init__(fg_color=fg_color) 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._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) 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 = [] _text_slt = []
_x = 0 self._x = 0
for line in self._text.split('\n'): for line in self._text.split('\n'):
if len(line) * 7 > 700: if len(line) * 7 > 700:
wrapped_lines = wrap_text(line, max_message_line_width) wrapped_lines = wrap_text(line, max_message_line_width)
@ -81,56 +83,53 @@ class CTkMessageBox(ctk.CTkToplevel):
else: else:
_text_slt.append(line) _text_slt.append(line)
_x = max(_x, max(len(w) * 7 for w in _text_slt)) self._x = max(self._x, max(len(w) * 7 for w in _text_slt))
_x += 20 # Add 20 pixels for padding on the left and right self._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 += 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) self._text = "\n".join(_text_slt)
_y = 0 self._y = 0
_y += 24 + 10 + 5 # Add 24 pixels for the header (icon + text) and 15 pixels for padding self._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 self._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 += 15 + 10 # Add 25 pixels for padding between the header and the message
if timeout > 0: if timeout > 0:
if self._header: if self._header:
header = self._header(self, self.title(), disable_hide=True, disable_close=True) header = self._header(self, self.title(), disable_hide=True, disable_close=True)
header.pack(fill="x", pady=(0, 0)) 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.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 = {} self._buttons = {}
else: else:
_y += 30 + 10 + 12 # Add 30 pixels for the buttons self._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.geometry(f"{self._x}x{self._y+12}") # Add 12 pixels to the height for the title bar
if buttons == "auto": if buttons == "auto":
self._buttons = self.buttons_map.get(self._mode, {}) self._buttons = self.buttons_map.get(self._mode, {})
elif isinstance(buttons, str): elif isinstance(buttons, str):
self._buttons = {buttons: {"output": True, "row": 0, "column": 0, "sticky": "center"}} self._buttons = {buttons: {"output": True, "row": 0, "column": 0, "sticky": "center"}}
self.attributes("-topmost", True) # stay on top self.attributes("-topmost", True) # stay on top
self._center()
self.transient(parent) self.transient(parent)
self.title(title) self.title(title)
self.lift() # lift window on top
self.protocol("WM_DELETE_WINDOW", self._on_closing)
self._create_widgets() self._create_widgets()
self.resizable(False, False) self.protocol("WM_DELETE_WINDOW", self._on_closing)
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}")
def _on_closing(self): def _on_closing(self):
self.withdraw()
self.grab_release() 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): def _create_widgets(self):
# Иконки для типов сообщений # Иконки для типов сообщений
icon_text = self.icon_map.get(self._mode, "?") icon_text = self.icon_map.get(self._mode, "?")
@ -166,6 +165,9 @@ class CTkMessageBox(ctk.CTkToplevel):
self._on_closing() self._on_closing()
def get_output(self): def get_output(self):
self.lift()
self.grab_set()
self.deiconify()
self.master.wait_window(self) self.master.wait_window(self)
if self._timeout > 0 and not self._input: if self._timeout > 0 and not self._input:
return return