mirror of
https://github.com/csd4ni3l/music-player.git
synced 2026-01-01 04:03:42 +01:00
Convert from card based view to list based view with thumbnails
This commit is contained in:
@@ -3,7 +3,7 @@ import arcade, 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, get_wrapped_text, adjust_volume
|
||||
from utils.utils import FakePyPresence, UIFocusTextureButton, ListItem, extract_metadata, get_audio_thumbnail_texture, truncate_end, adjust_volume
|
||||
|
||||
from math import ceil
|
||||
from thefuzz import process, fuzz
|
||||
@@ -56,9 +56,7 @@ 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 = {}
|
||||
@@ -107,8 +105,8 @@ 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=8)
|
||||
self.scroll_area.add(self.music_grid)
|
||||
self.music_box = arcade.gui.UIBoxLayout(space_between=5)
|
||||
self.scroll_area.add(self.music_box)
|
||||
|
||||
# Utility
|
||||
|
||||
@@ -262,11 +260,11 @@ class Main(arcade.gui.UIView):
|
||||
def show_content(self, tab):
|
||||
for music_button in self.music_buttons.values():
|
||||
music_button.remove(music_button.button)
|
||||
music_button.remove(music_button.label)
|
||||
self.music_grid.remove(music_button)
|
||||
music_button.remove(music_button.image)
|
||||
self.music_box.remove(music_button)
|
||||
del music_button
|
||||
|
||||
self.music_grid.clear()
|
||||
self.music_box.clear()
|
||||
self.music_buttons.clear()
|
||||
|
||||
if self.current_mode == "files":
|
||||
@@ -274,61 +272,46 @@ class Main(arcade.gui.UIView):
|
||||
if not self.search_term == "":
|
||||
matches = process.extract(self.search_term, self.tab_content[self.current_tab], limit=5, processor=lambda text: text.lower(), scorer=fuzz.partial_token_sort_ratio)
|
||||
self.highest_score_file = f"{self.current_tab}/{matches[0][0]}"
|
||||
for n, match in enumerate(matches):
|
||||
for match in matches:
|
||||
music_filename = match[0]
|
||||
self.music_buttons[f"{tab}/{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[f"{tab}/{music_filename}"] = self.music_box.add(ListItem(texture=self.thumbnails[f"{tab}/{music_filename}"], font_name="Roboto", font_size=13, text=music_filename, width=self.window.width / 1.2, height=self.window.height / 11))
|
||||
self.music_buttons[f"{tab}/{music_filename}"].button.on_click = lambda event, tab=tab, music_filename=music_filename: self.music_button_click(event, f"{tab}/{music_filename}")
|
||||
|
||||
else:
|
||||
self.music_grid.row_count = ceil(len(self.tab_content[tab]) / 8)
|
||||
|
||||
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 // 8
|
||||
col = n % 8
|
||||
|
||||
self.music_buttons[f"{tab}/{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)
|
||||
for music_filename in self.tab_content[tab]:
|
||||
self.music_buttons[f"{tab}/{music_filename}"] = self.music_box.add(ListItem(texture=self.thumbnails[f"{tab}/{music_filename}"], font_name="Roboto", font_size=13, text=music_filename, width=self.window.width / 1.2, height=self.window.height / 11))
|
||||
self.music_buttons[f"{tab}/{music_filename}"].button.on_click = lambda event, tab=tab, music_filename=music_filename: self.music_button_click(event, f"{tab}/{music_filename}")
|
||||
|
||||
self.music_grid._update_size_hints()
|
||||
self.music_box._update_size_hints()
|
||||
|
||||
elif self.current_mode == "playlist":
|
||||
self.current_playlist = tab
|
||||
|
||||
n = 0
|
||||
|
||||
if self.current_playlist:
|
||||
if not self.search_term == "":
|
||||
matches = process.extract(self.search_term, self.playlist_content[tab], limit=5, processor=lambda text: text.lower(), scorer=fuzz.partial_token_sort_ratio)
|
||||
self.highest_score_file = matches[0][0]
|
||||
for n, match in enumerate(matches):
|
||||
for match in 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 / 11, height=self.window.height / 11), row=0, column=n)
|
||||
self.music_buttons[music_filename] = self.music_box.add(ListItem(texture=self.thumbnails[music_filename], font_name="Roboto", font_size=13, text=music_filename, width=self.window.width / 1.2, height=self.window.height / 11))
|
||||
self.music_buttons[music_filename].button.on_click = lambda event, music_filename=music_filename: self.music_button_click(event, music_filename)
|
||||
|
||||
else:
|
||||
self.music_grid.row_count = ceil((len(self.playlist_content[tab]) + 1) / 8)
|
||||
|
||||
self.highest_score_file = ""
|
||||
|
||||
self.no_music_label.visible = not self.playlist_content[tab]
|
||||
|
||||
for n, music_filename in enumerate(self.playlist_content[tab]):
|
||||
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=self.playlist_wrapped_text[tab][n], width=self.window.width / 11, height=self.window.height / 11), row=row, column=col)
|
||||
for music_filename in self.playlist_content[tab]:
|
||||
self.music_buttons[music_filename] = self.music_box.add(ListItem(texture=self.thumbnails[music_filename], font_name="Roboto", font_size=13, text=music_filename, width=self.window.width / 1.2, height=self.window.height / 11))
|
||||
self.music_buttons[music_filename].button.on_click = lambda event, music_filename=music_filename: self.music_button_click(event, music_filename)
|
||||
|
||||
self.music_grid._update_size_hints()
|
||||
self.music_box._update_size_hints()
|
||||
|
||||
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 / 11, height=self.window.height / 11), row=row, column=col)
|
||||
self.music_buttons["add_music"] = self.music_box.add(ListItem(texture=plus_icon, font_name="Roboto", font_size=13, text="Add Music", width=self.window.width / 1.2, height=self.window.height / 11))
|
||||
self.music_buttons["add_music"].button.on_click = lambda event: self.add_music()
|
||||
|
||||
self.anchor.detect_focusable_widgets()
|
||||
@@ -350,9 +333,7 @@ class Main(arcade.gui.UIView):
|
||||
|
||||
def load_content(self):
|
||||
self.tab_content.clear()
|
||||
self.tab_wrapped_text.clear()
|
||||
self.playlist_content.clear()
|
||||
self.playlist_wrapped_text.clear()
|
||||
|
||||
for tab in self.tab_options:
|
||||
expanded_tab = os.path.expanduser(tab)
|
||||
@@ -369,8 +350,6 @@ class Main(arcade.gui.UIView):
|
||||
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 not os.path.exists(file) or not os.path.isfile(file):
|
||||
@@ -381,7 +360,6 @@ class Main(arcade.gui.UIView):
|
||||
self.thumbnails[file] = get_audio_thumbnail_texture(file, self.window.size)
|
||||
|
||||
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()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import logging, sys, traceback, os, re, platform, urllib.request, textwrap, io, base64, tempfile
|
||||
import logging, sys, traceback, os, re, platform, urllib.request, io, base64, tempfile
|
||||
|
||||
from mutagen.easyid3 import EasyID3
|
||||
from mutagen.id3 import ID3
|
||||
@@ -8,7 +8,8 @@ from pydub import AudioSegment
|
||||
|
||||
from PIL import Image
|
||||
|
||||
from utils.constants import menu_background_color
|
||||
from utils.constants import menu_background_color, button_style
|
||||
from utils.preload import button_texture, button_hovered_texture
|
||||
|
||||
import pyglet, arcade, arcade.gui
|
||||
|
||||
@@ -86,50 +87,28 @@ class UIFocusTextureButton(arcade.gui.UITextureButton):
|
||||
else:
|
||||
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):
|
||||
super().__init__(width=width, height=height, space_between=padding, align="top")
|
||||
class ListItem(arcade.gui.UIBoxLayout):
|
||||
def __init__(self, width: int, height: int, font_name: str, font_size: int, text: str, texture: arcade.Texture, padding=10):
|
||||
super().__init__(width=width, height=height, space_between=padding, align="top", vertical=False)
|
||||
|
||||
self.image = self.add(arcade.gui.UIImage(
|
||||
texture=texture,
|
||||
width=width * 0.1,
|
||||
height=height
|
||||
))
|
||||
|
||||
self.button = self.add(arcade.gui.UITextureButton(
|
||||
texture=card_texture,
|
||||
texture_hovered=card_texture,
|
||||
texture_pressed=card_texture,
|
||||
texture_disabled=card_texture,
|
||||
width=width,
|
||||
text=text,
|
||||
texture=button_texture,
|
||||
texture_hovered=button_hovered_texture,
|
||||
texture_pressed=button_texture,
|
||||
texture_disabled=button_texture,
|
||||
style=button_style,
|
||||
width=width * 0.9,
|
||||
height=height,
|
||||
interaction_buttons=[arcade.MOUSE_BUTTON_LEFT, arcade.MOUSE_BUTTON_RIGHT]
|
||||
))
|
||||
|
||||
self.label = self.add(arcade.gui.UILabel(
|
||||
text=text,
|
||||
font_name=font_name,
|
||||
font_size=font_size,
|
||||
width=width,
|
||||
height=height * 0.1,
|
||||
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))}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user