[+] wrap_text

[+] auto X-Y
This commit is contained in:
Maxim Khomutov 2025-03-20 14:46:57 +03:00
parent 34ca830c5e
commit df69a6cfdd
3 changed files with 49 additions and 8 deletions

View File

@ -3,7 +3,7 @@ from typing import Optional, Union, Tuple, Dict, Any, Literal
import customtkinter as ctk import customtkinter as ctk
from customtkinter import CTkFont, ThemeManager from customtkinter import CTkFont, ThemeManager
from ..utils import Strings, Icons from ..utils import Strings, Icons, wrap_text
class CTkMessageBox(ctk.CTkToplevel): class CTkMessageBox(ctk.CTkToplevel):
header_map = { header_map = {
@ -37,6 +37,8 @@ class CTkMessageBox(ctk.CTkToplevel):
timeout: int = 0, timeout: int = 0,
font: Optional[Union[tuple, CTkFont]] = None, font: Optional[Union[tuple, CTkFont]] = None,
max_message_line_width: int = 500,
fg_color: Optional[Union[str, Tuple[str, str]]] = None, fg_color: Optional[Union[str, Tuple[str, str]]] = None,
text_color: Optional[Union[str, Tuple[str, str]]] = None, text_color: Optional[Union[str, Tuple[str, str]]] = None,
button_fg_color: Optional[Union[str, Tuple[str, str]]] = None, button_fg_color: Optional[Union[str, Tuple[str, str]]] = None,
@ -69,20 +71,39 @@ class CTkMessageBox(ctk.CTkToplevel):
self._font = font or ("Arial", 12) self._font = font or ("Arial", 12)
self._input = None self._input = None
_y = len(self._text.split('\n')) * 7 # Calculate height based on the number of lines in self._text
_y += 30 _text_slt = []
_x = 0
for line in self._text.split('\n'):
if len(line) * 7 > 700:
wrapped_lines = wrap_text(line, max_message_line_width)
_text_slt.extend(wrapped_lines)
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._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
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"150x{_y}") self.geometry(f"{_x}x{_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.destroy) # close window after timeout
self._buttons = {} self._buttons = {}
else: else:
# self.geometry(f"150x{_y+12}") _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
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):
@ -125,8 +146,8 @@ class CTkMessageBox(ctk.CTkToplevel):
header_label = ctk.CTkLabel(main_frame, text=self.header_map.get(self._mode, "Unknown"), font=("Arial", 16)) header_label = ctk.CTkLabel(main_frame, text=self.header_map.get(self._mode, "Unknown"), font=("Arial", 16))
header_label.grid(row=0, column=0, padx=(10+40, 10), pady=(12, 3), sticky="w", columnspan=2) header_label.grid(row=0, column=0, padx=(10+40, 10), pady=(12, 3), sticky="w", columnspan=2)
message_label = ctk.CTkLabel(main_frame, text=self._text, font=self._font) message_label = ctk.CTkLabel(main_frame, text=self._text, font=self._font, justify="left")
message_label.grid(row=1, column=0, padx=(15, 10), pady=5, sticky="w", rowspan=2) message_label.grid(row=1, column=0, padx=(15, 10), pady=5, rowspan=2, sticky="w")
for t, setts in self._buttons.items(): for t, setts in self._buttons.items():
btn = ctk.CTkButton(main_frame, text=t, command=lambda b=setts['output']: self._on_button_click(b)) btn = ctk.CTkButton(main_frame, text=t, command=lambda b=setts['output']: self._on_button_click(b))

View File

@ -1,3 +1,3 @@
from . import fonts from . import fonts
from .params import Strings, Icons from .params import Strings, Icons
from .utils import base_path, get_file from .utils import base_path, get_file, wrap_text

View File

@ -1,6 +1,26 @@
import sys import sys
from pathlib import Path from pathlib import Path
def wrap_text(text, max_width, char_width=7):
words = text.split()
lines = []
current_line = []
current_width = 0
for word in words:
word_width = len(word) * char_width
if current_width + word_width + char_width > max_width:
lines.append(" ".join(current_line))
current_line = [word]
current_width = word_width
else:
current_line.append(word)
current_width += word_width + char_width # Добавляем пробел
if current_line:
lines.append(" ".join(current_line))
return lines
def base_path(): def base_path():
# PyInstaller creates a temp folder and stores path in _MEIPASS # PyInstaller creates a temp folder and stores path in _MEIPASS