From 2c1456703f9eab4a924708ac9ac68c4894e4cb21 Mon Sep 17 00:00:00 2001 From: csd4ni3l Date: Sun, 15 Jun 2025 09:18:02 +0200 Subject: [PATCH] Fix text wrapping --- menus/main.py | 56 ++++++++++++++++++++++++++++---------------------- utils/utils.py | 28 ++++++++++++++++++++----- 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/menus/main.py b/menus/main.py index 38f153a..e70636a 100644 --- a/menus/main.py +++ b/menus/main.py @@ -3,7 +3,7 @@ import arcade, arcade.gui, pyglet from utils.preload import * from utils.constants import button_style, slider_style, audio_extensions, discord_presence_id -from utils.utils import FakePyPresence, UIFocusTextureButton, Card, extract_metadata, get_audio_thumbnail_texture, truncate_end +from utils.utils import FakePyPresence, UIFocusTextureButton, Card, extract_metadata, get_audio_thumbnail_texture, truncate_end, get_wrapped_text from math import ceil from thefuzz import process, fuzz @@ -56,7 +56,9 @@ class Main(arcade.gui.UIView): self.tab_options = self.settings_dict.get("tab_options", [os.path.join("~", "Music"), os.path.join("~", "Downloads")]) self.tab_content = {} + self.tab_wrapped_text = {} self.playlist_content = {} + self.playlist_wrapped_text = {} self.thumbnails = {} self.tab_buttons = {} self.music_buttons = {} @@ -105,7 +107,7 @@ class Main(arcade.gui.UIView): self.scrollbar.size_hint = (0.02, 1) self.scroll_box.add(self.scrollbar) - self.music_grid = arcade.gui.UIGridLayout(horizontal_spacing=30, vertical_spacing=30, row_count=100, column_count=5) + self.music_grid = arcade.gui.UIGridLayout(horizontal_spacing=30, vertical_spacing=30, row_count=100, column_count=8) self.scroll_area.add(self.music_grid) # Utility @@ -259,20 +261,21 @@ class Main(arcade.gui.UIView): self.highest_score_file = f"{self.current_tab}/{matches[0][0]}" for n, match in enumerate(matches): music_filename = match[0] - self.music_buttons[music_filename] = self.music_grid.add(Card(card_texture=self.thumbnails[f"{tab}/{music_filename}"], font_name="Roboto", font_size=13, text=music_filename, width=self.window.width / 7, height=self.window.height / 7), row=0, column=n) + self.music_buttons[music_filename] = self.music_grid.add(Card(card_texture=self.thumbnails[f"{tab}/{music_filename}"], font_name="Roboto", font_size=13, text=music_filename, width=self.window.width / 11, height=self.window.height / 11), row=0, column=n) self.music_buttons[music_filename].button.on_click = lambda event, tab=tab, music_filename=music_filename: self.queue.append(f"{tab}/{music_filename}") else: - self.music_grid.row_count = ceil(len(self.tab_content[tab]) / 5) + self.music_grid.row_count = ceil(len(self.tab_content[tab]) / 8) self.music_grid._update_size_hints() self.highest_score_file = "" self.no_music_label.visible = not self.tab_content[tab] - for n, music_filename in enumerate(self.tab_content[tab]): - row = n // 5 - col = n % 5 - self.music_buttons[music_filename] = self.music_grid.add(Card(card_texture=self.thumbnails[f"{tab}/{music_filename}"], font_name="Roboto", font_size=13, text=music_filename, width=self.window.width / 7, height=self.window.height / 7), row=row, column=col) + for n, music_filename in enumerate(self.tab_content[tab]): + row = n // 8 + col = n % 8 + + self.music_buttons[music_filename] = self.music_grid.add(Card(card_texture=self.thumbnails[f"{tab}/{music_filename}"], font_name="Roboto", font_size=13, text=self.tab_wrapped_text[tab][n], width=self.window.width / 11, height=self.window.height / 11), row=row, column=col) self.music_buttons[music_filename].button.on_click = lambda event, tab=tab, music_filename=music_filename: self.queue.append(f"{tab}/{music_filename}") elif self.current_mode == "playlist": @@ -284,11 +287,11 @@ class Main(arcade.gui.UIView): self.highest_score_file = matches[0][0] for n, match in enumerate(matches): music_filename = match[0] - self.music_buttons[music_filename] = self.music_grid.add(Card(card_texture=self.thumbnails[music_filename], font_name="Roboto", font_size=13, text=music_filename, width=self.window.width / 6, height=self.window.height / 5), row=0, column=n) + self.music_buttons[music_filename] = self.music_grid.add(Card(card_texture=self.thumbnails[music_filename], font_name="Roboto", font_size=13, text=music_filename, width=self.window.width / 11, height=self.window.height / 11), row=0, column=n) self.music_buttons[music_filename].button.on_click = lambda event, tab=tab, music_filename=music_filename: self.queue.append(music_filename) else: - self.music_grid.row_count = ceil((len(self.playlist_content[tab]) + 1) / 5) + self.music_grid.row_count = ceil((len(self.playlist_content[tab]) + 1) / 8) self.music_grid._update_size_hints() self.highest_score_file = "" @@ -296,34 +299,39 @@ class Main(arcade.gui.UIView): self.no_music_label.visible = not self.playlist_content[tab] for n, music_filename in enumerate(self.playlist_content[tab]): - row = n // 5 - col = n % 5 + row = n // 8 + col = n % 8 - self.music_buttons[music_filename] = self.music_grid.add(Card(card_texture=self.thumbnails[music_filename], font_name="Roboto", font_size=13, text=music_filename, width=self.window.width / 6, height=self.window.height / 5), row=row, column=col) + self.music_buttons[music_filename] = self.music_grid.add(Card(card_texture=self.thumbnails[music_filename], font_name="Roboto", font_size=13, text=self.playlist_wrapped_text[tab][n], width=self.window.width / 11, height=self.window.height / 11), row=row, column=col) self.music_buttons[music_filename].button.on_click = lambda event, tab=tab, music_filename=music_filename: self.queue.append(music_filename) - row = (n + 1) // 5 - col = (n + 1) % 5 + row = (n + 1) // 8 + col = (n + 1) % 8 - self.music_buttons["add_music"] = self.music_grid.add(Card(card_texture=music_icon, font_name="Roboto", font_size=13, text="Add Music", width=self.window.width / 6, height=self.window.height / 5), row=row, column=col) + self.music_buttons["add_music"] = self.music_grid.add(Card(card_texture=music_icon, font_name="Roboto", font_size=13, text="Add Music", width=self.window.width / 11, height=self.window.height / 11), row=row, column=col) self.music_buttons["add_music"].button.on_click = lambda event: self.add_music() self.update_buttons() def load_content(self): for tab in self.tab_options: - self.tab_content[os.path.expanduser(tab)] = [] - for filename in os.listdir(os.path.expanduser(tab)): - if filename.split(".")[-1] in audio_extensions: - if f"{os.path.expanduser(tab)}/{filename}" not in self.thumbnails: - self.thumbnails[f"{os.path.expanduser(tab)}/{filename}"] = get_audio_thumbnail_texture(f"{os.path.expanduser(tab)}/{filename}", self.window.size) - self.tab_content[os.path.expanduser(tab)].append(filename) + expanded_tab = os.path.expanduser(tab) + self.tab_content[expanded_tab] = [] - for content in self.settings_dict.get("playlists", {}).values(): + for filename in os.listdir(expanded_tab): + if filename.split(".")[-1] in audio_extensions: + if f"{expanded_tab}/{filename}" not in self.thumbnails: + self.thumbnails[f"{expanded_tab}/{filename}"] = get_audio_thumbnail_texture(f"{expanded_tab}/{filename}", self.window.size) + self.tab_content[expanded_tab].append(filename) + + self.tab_wrapped_text[expanded_tab] = get_wrapped_text(self.tab_content[expanded_tab], self.window.width // 11, 14) + + for playlist, content in self.settings_dict.get("playlists", {}).items(): for file in content: if file not in self.thumbnails: self.thumbnails[file] = get_audio_thumbnail_texture(file, self.window.size) - self.playlist_content = self.settings_dict.get("playlists", {}) + self.playlist_content[playlist] = content + self.playlist_wrapped_text[playlist] = get_wrapped_text(content, self.window.width // 11, 14) def load_tabs(self): self.tab_box.clear() diff --git a/utils/utils.py b/utils/utils.py index 9548e45..c952436 100644 --- a/utils/utils.py +++ b/utils/utils.py @@ -80,7 +80,7 @@ class UIFocusTextureButton(arcade.gui.UITextureButton): self.resize(width=self.width / 1.1, height=self.height / 1.1) class Card(arcade.gui.UIBoxLayout): - def __init__(self, width: int, height: int, font_name: str, font_size: int, text: str, card_texture: arcade.Texture, padding=10): + def __init__(self, width: int, height: int, font_name: str, font_size: int, text: str, card_texture: arcade.Texture, padding=10, new_lines=3): super().__init__(width=width, height=height, space_between=padding, align="top") self.button = self.add(arcade.gui.UITextureButton( @@ -92,11 +92,8 @@ class Card(arcade.gui.UIBoxLayout): height=height, )) - wrapped_lines = textwrap.wrap(text, width=int(width / (font_size * 0.6))) - wrapped_text = "\n".join(wrapped_lines) - self.label = self.add(arcade.gui.UILabel( - text=wrapped_text, + text=text, font_name=font_name, font_size=font_size, width=width, @@ -104,6 +101,27 @@ class Card(arcade.gui.UIBoxLayout): multiline=True, )) +def get_wrapped_text(text_list: list[str], width: int, font_size: int): + max_lines = 0 + wrapped_line_list = [] + wrapped_text_list = [] + + for text in text_list: # get max lines and wrap text + wrapped_lines = textwrap.wrap(text, width=int(width / (font_size * 0.6))) + if len(wrapped_lines) > max_lines: + max_lines = len(wrapped_lines) + + wrapped_line_list.append(wrapped_lines) + + for wrapped_lines in wrapped_line_list: + if len(wrapped_lines) < max_lines: # adjust text to maximum lines + for i in range(max_lines - len(wrapped_lines)): + wrapped_lines.append("") + + wrapped_text_list.append("\n".join(wrapped_lines)) + + return wrapped_text_list + def on_exception(*exc_info): logging.error(f"Unhandled exception:\n{''.join(traceback.format_exception(exc_info[1], limit=None))}")