mirror of
https://github.com/csd4ni3l/music-player.git
synced 2026-01-01 04:03:42 +01:00
Initial commit
This commit is contained in:
68
menus/add_music.py
Normal file
68
menus/add_music.py
Normal file
@@ -0,0 +1,68 @@
|
||||
import arcade, arcade.gui, os, json
|
||||
|
||||
from utils.constants import button_style, dropdown_style
|
||||
from utils.preload import button_texture, button_hovered_texture
|
||||
from utils.utils import UIFocusTextureButton
|
||||
|
||||
from arcade.gui.experimental.focus import UIFocusGroup
|
||||
|
||||
class AddMusic(arcade.gui.UIView):
|
||||
def __init__(self, pypresence_client, current_mode, current_music_name, current_length, current_music_player, queue, loaded_sounds, shuffle):
|
||||
super().__init__()
|
||||
|
||||
self.current_mode = current_mode
|
||||
self.current_music_name = current_music_name
|
||||
self.current_length = current_length
|
||||
self.current_music_player = current_music_player
|
||||
self.queue = queue
|
||||
self.loaded_sounds = loaded_sounds
|
||||
self.shuffle = shuffle
|
||||
|
||||
with open("settings.json", "r") as file:
|
||||
self.settings_dict = json.load(file)
|
||||
|
||||
self.playlists = self.settings_dict.get("playlists", {})
|
||||
|
||||
self.pypresence_client = pypresence_client
|
||||
self.pypresence_client.update(state="Adding music to playlist", start=self.pypresence_client.start_time)
|
||||
|
||||
def on_show_view(self):
|
||||
super().on_show_view()
|
||||
|
||||
self.anchor = self.add_widget(UIFocusGroup(size_hint=(1, 1)))
|
||||
self.box = self.anchor.add(arcade.gui.UIBoxLayout(space_between=10), anchor_x="center", anchor_y="center")
|
||||
|
||||
self.playlist_label = self.box.add(arcade.gui.UILabel(text="Playlist", font_name="Protest Strike", font_size=32))
|
||||
self.playlist_option = self.box.add(arcade.gui.UIDropdown(default=list(self.playlists.keys())[0], options=list(self.playlists.keys()), width=self.window.width / 2, height=self.window.height / 15, primary_style=dropdown_style, dropdown_style=dropdown_style, active_style=dropdown_style))
|
||||
self.music_label = self.box.add(arcade.gui.UILabel(text="Music File Path", font_name="Protest Strike", font_size=32))
|
||||
self.add_music_input = self.box.add(arcade.gui.UIInputText(font_name="Protest Strike", font_size=32, width=self.window.width / 2, height=self.window.height / 10))
|
||||
self.add_music_button = self.box.add(UIFocusTextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text='Add Music', style=button_style, width=self.window.width / 2, height=self.window.height / 10))
|
||||
self.add_music_button.on_click = lambda event: self.add_music()
|
||||
|
||||
self.back_button = self.anchor.add(UIFocusTextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text='<--', style=button_style, width=100, height=50), anchor_x="left", anchor_y="top", align_x=5, align_y=-5)
|
||||
self.back_button.on_click = lambda event: self.main_exit()
|
||||
|
||||
self.anchor.detect_focusable_widgets()
|
||||
|
||||
def add_music(self):
|
||||
music_path = self.add_music_input.text
|
||||
playlist = self.playlist_option.value
|
||||
|
||||
if not music_path:
|
||||
return
|
||||
|
||||
if not os.path.exists(os.path.expanduser(music_path)) or not os.path.isfile(os.path.expanduser(music_path)) or not os.path.isabs(os.path.expanduser(music_path)):
|
||||
return
|
||||
|
||||
if music_path in self.playlists[playlist] or os.path.expanduser(music_path) in self.playlists[playlist]:
|
||||
return
|
||||
|
||||
self.playlists[playlist].append(os.path.expanduser(music_path))
|
||||
self.settings_dict["playlists"] = self.playlists
|
||||
|
||||
with open("settings.json", "w") as file:
|
||||
file.write(json.dumps(self.settings_dict))
|
||||
|
||||
def main_exit(self):
|
||||
from menus.main import Main
|
||||
self.window.show_view(Main(self.pypresence_client, self.current_mode, self.current_music_name, self.current_length, self.current_music_player, self.queue, self.loaded_sounds, self.shuffle))
|
||||
137
menus/downloader.py
Normal file
137
menus/downloader.py
Normal file
@@ -0,0 +1,137 @@
|
||||
from yt_dlp import YoutubeDL
|
||||
from mutagen.easyid3 import EasyID3
|
||||
from pydub import AudioSegment
|
||||
|
||||
import arcade, arcade.gui, os, json, yt_dlp, threading
|
||||
|
||||
from arcade.gui.experimental.focus import UIFocusGroup
|
||||
|
||||
from utils.utils import UIFocusTextureButton, BufferLogger
|
||||
from utils.constants import button_style, dropdown_style, yt_dlp_parameters
|
||||
from utils.preload import button_texture, button_hovered_texture
|
||||
|
||||
class Downloader(arcade.gui.UIView):
|
||||
def __init__(self, pypresence_client, current_mode, current_music_name, current_length, current_music_player, queue, loaded_sounds, shuffle):
|
||||
super().__init__()
|
||||
|
||||
self.current_mode = current_mode
|
||||
self.current_music_name = current_music_name
|
||||
self.current_length = current_length
|
||||
self.current_music_player = current_music_player
|
||||
self.queue = queue
|
||||
self.loaded_sounds = loaded_sounds
|
||||
self.shuffle = shuffle
|
||||
|
||||
self.pypresence_client = pypresence_client
|
||||
self.pypresence_client.update(state="Downloading music", start=self.pypresence_client.start_time)
|
||||
|
||||
with open("settings.json", "r") as file:
|
||||
self.settings_dict = json.load(file)
|
||||
|
||||
self.tab_options = self.settings_dict.get("tab_options", ["~/Music", "~/Downloads"])
|
||||
|
||||
self.yt_dl = YoutubeDL(params=yt_dlp_parameters)
|
||||
self.yt_dl.params["logger"] = self.yt_dl_logger = BufferLogger()
|
||||
|
||||
def on_show_view(self):
|
||||
super().on_show_view()
|
||||
|
||||
self.anchor = self.add_widget(UIFocusGroup(size_hint=(1, 1)))
|
||||
|
||||
self.download_box = self.anchor.add(arcade.gui.UIBoxLayout(space_between=10), anchor_x="center", anchor_y="center")
|
||||
|
||||
self.url_name_label = self.download_box.add(arcade.gui.UILabel(text="URL or Name:", font_name="Protest Strike", font_size=36))
|
||||
self.url_name_input = self.download_box.add(arcade.gui.UIInputText(font_name="Protest Strike", width=self.window.width / 2, height=self.window.height / 15, font_size=36))
|
||||
self.url_name_input.activate()
|
||||
|
||||
self.tab_label = self.download_box.add(arcade.gui.UILabel(text="Path:", font_name="Protest Strike", font_size=36))
|
||||
self.tab_selector = self.download_box.add(arcade.gui.UIDropdown(default=self.tab_options[0], options=self.tab_options, width=self.window.width / 2, height=self.window.height / 15, primary_style=dropdown_style, dropdown_style=dropdown_style, active_style=dropdown_style))
|
||||
|
||||
self.status_label = self.download_box.add(arcade.gui.UILabel(text="No errors.", font_size=16, text_color=arcade.color.LIGHT_GREEN))
|
||||
|
||||
self.download_button = self.anchor.add(arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text='Download', style=button_style, width=self.window.width / 2, height=self.window.height / 10), anchor_x="center", anchor_y="bottom", align_y=10)
|
||||
self.download_button.on_click = lambda event: threading.Thread(target=self.download, daemon=True).start()
|
||||
|
||||
self.back_button = self.anchor.add(arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text='<--', style=button_style, width=100, height=50), anchor_x="left", anchor_y="top", align_x=5, align_y=-5)
|
||||
self.back_button.on_click = lambda event: self.main_exit()
|
||||
|
||||
self.anchor.detect_focusable_widgets()
|
||||
|
||||
def on_update(self, delta_time: float) -> bool | None:
|
||||
self.status_label.text = self.yt_dl_logger.buffer
|
||||
|
||||
if "WARNING" in self.yt_dl_logger.buffer:
|
||||
self.status_label.update_font(font_color=arcade.color.YELLOW)
|
||||
elif "ERROR" in self.yt_dl_logger.buffer:
|
||||
self.status_label.update_font(font_color=arcade.color.RED)
|
||||
else:
|
||||
self.status_label.update_font(font_color=arcade.color.LIGHT_GREEN)
|
||||
|
||||
def download(self):
|
||||
if not self.tab_selector.value:
|
||||
return
|
||||
|
||||
url = self.url_name_input.text
|
||||
|
||||
if not "http" in url:
|
||||
url = f"ytsearch1:{url}"
|
||||
|
||||
path = os.path.expanduser(self.tab_selector.value)
|
||||
|
||||
try:
|
||||
info = self.yt_dl.extract_info(url, download=True)
|
||||
except yt_dlp.DownloadError as e:
|
||||
message = "".join(e.msg.strip().split("] ")[1:]) if e.msg else "Unknown yt-dlp error."
|
||||
self.yt_dl_logger.buffer = f"ERROR: {message}"
|
||||
return
|
||||
|
||||
if info:
|
||||
entry = info['entries'][0] if 'entries' in info else info
|
||||
title = entry.get('title', 'Unknown')
|
||||
uploader = entry.get('uploader', 'Unknown')
|
||||
|
||||
if " - " in title:
|
||||
artist, track_title = title.split(" - ", 1)
|
||||
else:
|
||||
artist = uploader
|
||||
track_title = title
|
||||
title = f"{artist} - {track_title}"
|
||||
|
||||
try:
|
||||
audio = EasyID3("downloaded_music.mp3")
|
||||
audio["artist"] = artist
|
||||
audio["title"] = track_title
|
||||
audio.save()
|
||||
except Exception as meta_err:
|
||||
self.yt_dl_logger.buffer = f"ERROR: Tried to override metadata based on title, but failed: {meta_err}"
|
||||
return
|
||||
|
||||
if self.settings_dict.get("normalize_audio", True):
|
||||
try:
|
||||
audio = AudioSegment.from_file("downloaded_music.mp3")
|
||||
|
||||
if audio.dBFS < self.settings_dict.get("normalized_volume", -8):
|
||||
change = self.settings_dict.get("normalized_volume", -8) - audio.dBFS
|
||||
audio = audio.apply_gain(change)
|
||||
|
||||
audio.export("downloaded_music.mp3", format="mp3")
|
||||
|
||||
except Exception as e:
|
||||
self.yt_dl_logger.buffer = f"ERROR: Could not normalize volume due to an error: {e}"
|
||||
return
|
||||
try:
|
||||
output_filename = os.path.join(path, f"{title}.mp3")
|
||||
os.replace("downloaded_music.mp3", output_filename)
|
||||
|
||||
except Exception as e:
|
||||
self.yt_dl_logger.buffer = f"ERROR: Could not move file due to an error: {e}"
|
||||
return
|
||||
else:
|
||||
self.yt_dl_logger.buffer = f"ERROR: Info unavailable. This maybe due to being unable to download it due to DRM or other issues"
|
||||
return
|
||||
|
||||
self.yt_dl_logger.buffer = f"Successfully downloaded {title} to {path}"
|
||||
|
||||
def main_exit(self):
|
||||
from menus.main import Main
|
||||
self.window.show_view(Main(self.pypresence_client, self.current_mode, self.current_music_name, self.current_length, self.current_music_player, self.queue, self.loaded_sounds, self.shuffle))
|
||||
464
menus/main.py
Normal file
464
menus/main.py
Normal file
@@ -0,0 +1,464 @@
|
||||
import random, asyncio, pypresence, time, copy, json, os, logging
|
||||
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, extract_metadata, truncate_end
|
||||
|
||||
from arcade.gui.property import bind
|
||||
from thefuzz import process, fuzz
|
||||
from pydub import AudioSegment
|
||||
|
||||
from arcade.gui.experimental.scroll_area import UIScrollArea, UIScrollBar
|
||||
from arcade.gui.experimental.focus import UIFocusGroup
|
||||
|
||||
class Main(arcade.gui.UIView):
|
||||
def __init__(self, pypresence_client: None | FakePyPresence | pypresence.Presence=None, current_mode: str | None=None, current_music_name: str | None=None,
|
||||
current_length: int | None=None, current_music_player: pyglet.media.Player | None=None, queue: list | None=None,
|
||||
loaded_sounds: dict | None=None, shuffle: bool=False):
|
||||
super().__init__()
|
||||
self.pypresence_client = pypresence_client
|
||||
|
||||
with open("settings.json", "r") as file:
|
||||
self.settings_dict = json.load(file)
|
||||
|
||||
if self.settings_dict.get('discord_rpc', True):
|
||||
if self.pypresence_client == None: # Game has started
|
||||
try:
|
||||
asyncio.get_event_loop()
|
||||
except:
|
||||
asyncio.set_event_loop(asyncio.new_event_loop())
|
||||
|
||||
try:
|
||||
self.pypresence_client = pypresence.Presence(discord_presence_id)
|
||||
self.pypresence_client.connect()
|
||||
self.pypresence_client.start_time = time.time()
|
||||
except:
|
||||
self.pypresence_client = FakePyPresence()
|
||||
self.pypresence_client.start_time = time.time()
|
||||
|
||||
elif isinstance(self.pypresence_client, FakePyPresence): # the user has enabled RPC in the settings in this session.
|
||||
# get start time from old object
|
||||
start_time = copy.deepcopy(self.pypresence_client.start_time)
|
||||
try:
|
||||
self.pypresence_client = pypresence.Presence(discord_presence_id)
|
||||
self.pypresence_client.connect()
|
||||
self.pypresence_client.start_time = start_time
|
||||
except:
|
||||
self.pypresence_client = FakePyPresence()
|
||||
self.pypresence_client.start_time = start_time
|
||||
|
||||
else:
|
||||
self.pypresence_client = pypresence_client
|
||||
else: # game has started, but the user has disabled RPC in the settings.
|
||||
self.pypresence_client = FakePyPresence()
|
||||
self.pypresence_client.start_time = time.time()
|
||||
|
||||
self.tab_options = self.settings_dict.get("tab_options", ["~/Music", "~/Downloads"])
|
||||
self.tab_content = {}
|
||||
self.playlist_content = {}
|
||||
self.tab_buttons = {}
|
||||
self.music_buttons = {}
|
||||
|
||||
self.current_music_name = current_music_name
|
||||
self.current_length = current_length if current_length else 0
|
||||
self.current_music_player = current_music_player
|
||||
self.current_mode = current_mode or "files"
|
||||
self.current_playlist = None
|
||||
self.time_to_seek = None
|
||||
self.current_tab = self.tab_options[0]
|
||||
self.queue = queue if queue else []
|
||||
self.loaded_sounds = loaded_sounds if loaded_sounds else {}
|
||||
self.shuffle = shuffle
|
||||
self.search_term = ""
|
||||
self.highest_score_file = ""
|
||||
self.volume = self.settings_dict.get("default_volume", 100)
|
||||
|
||||
def on_show_view(self):
|
||||
super().on_show_view()
|
||||
|
||||
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1)))
|
||||
|
||||
self.ui_box = self.anchor.add(arcade.gui.UIBoxLayout(size_hint=(1, 1), space_between=10))
|
||||
|
||||
# Tabs
|
||||
|
||||
self.load_content()
|
||||
if self.current_mode == "playlist" and not self.current_playlist:
|
||||
self.current_playlist = list(self.playlist_content.keys())[0] if self.playlist_content else None
|
||||
self.load_tabs()
|
||||
|
||||
# Scrollable Sounds
|
||||
self.scroll_box = self.ui_box.add(arcade.gui.UIBoxLayout(size_hint=(0.95, 0.8), space_between=15, vertical=False))
|
||||
|
||||
self.scroll_area = UIScrollArea(size_hint=(0.9, 1)) # center on screen
|
||||
self.scroll_area.scroll_speed = -50
|
||||
self.scroll_box.add(self.scroll_area)
|
||||
|
||||
self.scrollbar = UIScrollBar(self.scroll_area)
|
||||
self.scrollbar.size_hint = (0.02, 1)
|
||||
self.scroll_box.add(self.scrollbar)
|
||||
|
||||
self.music_box = arcade.gui.UIBoxLayout(space_between=2)
|
||||
self.scroll_area.add(self.music_box)
|
||||
|
||||
# Utility
|
||||
|
||||
self.settings_box = self.anchor.add(arcade.gui.UIBoxLayout(space_between=10), anchor_x="right", anchor_y="center", align_x=-10)
|
||||
|
||||
self.new_tab_button = self.settings_box.add(UIFocusTextureButton(texture=plus_icon, texture_hovered=plus_icon, texture_pressed=plus_icon, style=button_style))
|
||||
self.new_tab_button.on_click = lambda event: self.new_tab()
|
||||
|
||||
self.downloader_button = self.settings_box.add(UIFocusTextureButton(texture=download_icon, texture_hovered=download_icon, texture_pressed=download_icon, style=button_style))
|
||||
self.downloader_button.on_click = lambda event: self.downloader()
|
||||
|
||||
self.reload_button = self.settings_box.add(UIFocusTextureButton(texture=reload_icon, texture_hovered=reload_icon, texture_pressed=reload_icon, style=button_style))
|
||||
self.reload_button.on_click = lambda event: self.reload()
|
||||
|
||||
mode_icon = playlist_icon if self.current_mode == "files" else files_icon
|
||||
|
||||
self.mode_button = self.settings_box.add(UIFocusTextureButton(texture=mode_icon, texture_hovered=mode_icon, texture_pressed=mode_icon, style=button_style))
|
||||
self.mode_button.on_click = lambda event: self.change_mode()
|
||||
|
||||
self.settings_button = self.settings_box.add(UIFocusTextureButton(texture=settings_icon, style=button_style))
|
||||
self.settings_button.on_click = lambda event: self.settings()
|
||||
|
||||
# Controls
|
||||
|
||||
self.control_box = self.ui_box.add(arcade.gui.UIBoxLayout(size_hint=(0.95, 0.1), space_between=10, vertical=False))
|
||||
self.current_music_label = self.control_box.add(arcade.gui.UILabel(text=truncate_end(self.current_music_name, int(self.window.width / 30)) if self.current_music_name else "No songs playing", font_name="Protest Strike", font_size=16))
|
||||
self.time_label = self.control_box.add(arcade.gui.UILabel(text="00:00", font_name="Protest Strike", font_size=16))
|
||||
|
||||
self.progressbar = self.control_box.add(arcade.gui.UISlider(style=slider_style, width=self.window.width / 3, height=35))
|
||||
self.progressbar.on_change = self.on_progress_change
|
||||
|
||||
self.pause_start_button = self.control_box.add(UIFocusTextureButton(texture=pause_icon if not self.current_music_player or self.current_music_player.playing else resume_icon))
|
||||
self.pause_start_button.on_click = lambda event: self.pause_start()
|
||||
|
||||
self.skip_button = self.control_box.add(UIFocusTextureButton(texture=stop_icon))
|
||||
self.skip_button.on_click = lambda event: self.skip_sound()
|
||||
|
||||
self.loop_button = self.control_box.add(UIFocusTextureButton(texture=no_loop_icon if not self.current_music_player or self.current_music_player.loop else loop_icon))
|
||||
self.loop_button.on_click = lambda event: self.loop_sound()
|
||||
|
||||
self.shuffle_button = self.control_box.add(UIFocusTextureButton(texture=shuffle_icon))
|
||||
self.shuffle_button.on_click = lambda event: self.shuffle_sound()
|
||||
|
||||
if self.current_music_player:
|
||||
self.progressbar.max_value = self.current_length
|
||||
self.volume = int(self.current_music_player.volume * 100)
|
||||
|
||||
self.volume_label = self.control_box.add(arcade.gui.UILabel(text=f"{self.volume}%", font_name="Protest Strike", font_size=16))
|
||||
self.volume_slider = self.control_box.add(arcade.gui.UISlider(style=slider_style, width=self.window.width / 10, height=35, value=self.volume, max_value=100))
|
||||
self.volume_slider.on_change = self.on_volume_slider_change
|
||||
|
||||
if self.current_mode == "files":
|
||||
self.show_content(os.path.expanduser(self.current_tab))
|
||||
elif self.current_mode == "playlist":
|
||||
self.show_content(self.current_playlist)
|
||||
|
||||
arcade.schedule(self.update_presence, 2.5)
|
||||
|
||||
self.update_presence(None)
|
||||
|
||||
def update_buttons(self):
|
||||
if self.current_mode == "files":
|
||||
self.mode_button.texture = playlist_icon
|
||||
self.mode_button.texture_hovered = playlist_icon
|
||||
self.mode_button.texture_pressed = playlist_icon
|
||||
|
||||
elif self.current_mode == "playlist":
|
||||
self.mode_button.texture = files_icon
|
||||
self.mode_button.texture_hovered = files_icon
|
||||
self.mode_button.texture_pressed = files_icon
|
||||
|
||||
self.shuffle_button.texture = no_shuffle_icon if self.shuffle else shuffle_icon
|
||||
self.shuffle_button.texture_hovered = no_shuffle_icon if self.shuffle else shuffle_icon
|
||||
self.shuffle_button.texture_pressed = no_shuffle_icon if self.shuffle else shuffle_icon
|
||||
|
||||
if self.current_music_player:
|
||||
self.pause_start_button.texture = pause_icon if self.current_music_player.playing else resume_icon
|
||||
self.pause_start_button.texture_hovered = pause_icon if self.current_music_player.playing else resume_icon
|
||||
self.pause_start_button.texture_pressed = pause_icon if self.current_music_player.playing else resume_icon
|
||||
|
||||
self.loop_button.texture = no_loop_icon if self.current_music_player.loop else loop_icon
|
||||
self.loop_button.texture_hovered = no_loop_icon if self.current_music_player.loop else loop_icon
|
||||
self.loop_button.texture_pressed = no_loop_icon if self.current_music_player.loop else loop_icon
|
||||
else:
|
||||
self.pause_start_button.texture = pause_icon
|
||||
self.pause_start_button.texture_hovered = pause_icon
|
||||
self.pause_start_button.texture_pressed = pause_icon
|
||||
|
||||
self.loop_button.texture = loop_icon
|
||||
self.loop_button.texture_hovered = loop_icon
|
||||
self.loop_button.texture_pressed = loop_icon
|
||||
|
||||
def change_mode(self):
|
||||
self.current_mode = "playlist" if self.current_mode == "files" else "files"
|
||||
|
||||
self.current_playlist = list(self.playlist_content.keys())[0] if self.playlist_content else None
|
||||
|
||||
self.highest_score_file = ""
|
||||
self.search_term = ""
|
||||
|
||||
self.reload()
|
||||
|
||||
def skip_sound(self):
|
||||
if not self.current_music_player is None:
|
||||
if self.current_music_player.loop:
|
||||
self.current_music_player.seek(0)
|
||||
return
|
||||
|
||||
if self.settings_dict.get("music_mode", "Streaming") == "Streaming":
|
||||
del self.loaded_sounds[self.current_music_name]
|
||||
|
||||
self.current_length = 0
|
||||
self.current_music_name = None
|
||||
self.current_music_player.delete()
|
||||
self.current_music_player = None
|
||||
self.progressbar.value = 0
|
||||
self.current_music_label.text = "No songs playing"
|
||||
self.time_label.text = "00:00"
|
||||
|
||||
self.update_buttons()
|
||||
|
||||
def pause_start(self):
|
||||
if self.current_music_player is not None:
|
||||
self.current_music_player._set_playing(not self.current_music_player.playing)
|
||||
self.update_buttons()
|
||||
|
||||
def loop_sound(self):
|
||||
if not self.current_music_player is None:
|
||||
self.current_music_player.loop = not self.current_music_player.loop
|
||||
self.update_buttons()
|
||||
|
||||
def shuffle_sound(self):
|
||||
if not self.current_music_player is None:
|
||||
self.shuffle = not self.shuffle
|
||||
self.update_buttons()
|
||||
|
||||
def show_content(self, tab):
|
||||
self.music_box.clear()
|
||||
self.music_buttons.clear()
|
||||
|
||||
if self.current_mode == "files":
|
||||
self.current_tab = tab
|
||||
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 match in matches:
|
||||
music_filename = match[0]
|
||||
self.music_buttons[music_filename] = self.music_box.add(arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text=music_filename, style=button_style, width=self.window.width * 0.85, height=self.window.height / 30))
|
||||
self.music_buttons[music_filename].on_click = lambda event, tab=tab, music_filename=music_filename: self.queue.append(f"{tab}/{music_filename}")
|
||||
|
||||
else:
|
||||
self.highest_score_file = ""
|
||||
for music_filename in self.tab_content[tab]:
|
||||
self.music_buttons[music_filename] = self.music_box.add(arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text=music_filename, style=button_style, width=self.window.width * 0.85, height=self.window.height / 30))
|
||||
self.music_buttons[music_filename].on_click = lambda event, tab=tab, music_filename=music_filename: self.queue.append(f"{tab}/{music_filename}")
|
||||
|
||||
elif self.current_mode == "playlist":
|
||||
self.current_playlist = tab
|
||||
|
||||
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 match in matches:
|
||||
music_filename = match[0]
|
||||
self.music_buttons[music_filename] = self.music_box.add(arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text=music_filename, style=button_style, width=self.window.width * 0.85, height=self.window.height / 30))
|
||||
self.music_buttons[music_filename].on_click = lambda event, tab=tab, music_filename=music_filename: self.queue.append(music_filename)
|
||||
|
||||
else:
|
||||
self.highest_score_file = ""
|
||||
for music_filename in self.playlist_content[tab]:
|
||||
self.music_buttons[music_filename] = self.music_box.add(arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text=music_filename, style=button_style, width=self.window.width * 0.85, height=self.window.height / 30))
|
||||
self.music_buttons[music_filename].on_click = lambda event, tab=tab, music_filename=music_filename: self.queue.append(music_filename)
|
||||
|
||||
self.music_buttons["add_music"] = self.music_box.add(arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text="Add Music", style=button_style, width=self.window.width * 0.85, height=self.window.height / 30))
|
||||
self.music_buttons["add_music"].on_click = lambda event: self.add_music()
|
||||
|
||||
self.update_buttons()
|
||||
|
||||
def load_content(self):
|
||||
self.tab_content.clear()
|
||||
self.playlist_content.clear()
|
||||
|
||||
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:
|
||||
self.tab_content[os.path.expanduser(tab)].append(filename)
|
||||
|
||||
for playlist, content in self.settings_dict.get("playlists", {}).items():
|
||||
self.playlist_content[playlist] = content
|
||||
|
||||
def load_tabs(self):
|
||||
self.tab_box = self.ui_box.add(arcade.gui.UIBoxLayout(size_hint=(0.95, 0.1), space_between=10, vertical=False))
|
||||
|
||||
if self.current_mode == "files":
|
||||
for tab in self.tab_options:
|
||||
self.tab_buttons[os.path.expanduser(tab)] = self.tab_box.add(UIFocusTextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text=os.path.basename(os.path.normpath(os.path.expanduser(tab))), style=button_style, width=self.window.width / 10, height=self.window.height / 15))
|
||||
self.tab_buttons[os.path.expanduser(tab)].on_click = lambda event, tab=os.path.expanduser(tab): self.show_content(tab)
|
||||
elif self.current_mode == "playlist":
|
||||
for playlist in self.playlist_content:
|
||||
self.tab_buttons[playlist] = self.tab_box.add(UIFocusTextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text=playlist, style=button_style, width=self.window.width / 10, height=self.window.height / 15))
|
||||
self.tab_buttons[playlist].on_click = lambda event, playlist=playlist: self.show_content(playlist)
|
||||
|
||||
def on_progress_change(self, event):
|
||||
if not self.current_music_player is None:
|
||||
scale = self.progressbar.value / self.progressbar.max_value
|
||||
|
||||
self.time_to_seek = self.current_length * scale
|
||||
|
||||
def on_volume_slider_change(self, event):
|
||||
self.volume = int(self.volume_slider.value)
|
||||
self.volume_label.text = f"{self.volume}%"
|
||||
|
||||
if not self.current_music_player is None:
|
||||
self.current_music_player.volume = self.volume / 100
|
||||
|
||||
def on_update(self, delta_time):
|
||||
if self.current_music_player is None or self.current_music_player.time == 0:
|
||||
if len(self.queue) > 0:
|
||||
music_path = self.queue.pop(0)
|
||||
|
||||
artist, title = extract_metadata(music_path)
|
||||
|
||||
music_name = f"{artist} - {title}"
|
||||
|
||||
if self.settings_dict.get("normalize_audio", True):
|
||||
try:
|
||||
audio = AudioSegment.from_file(music_path)
|
||||
|
||||
if int(audio.dBFS) != self.settings_dict.get("normalized_volume", -8):
|
||||
change = self.settings_dict.get("normalized_volume", -8) - audio.dBFS
|
||||
audio = audio.apply_gain(change)
|
||||
|
||||
audio.export(music_path, format="mp3")
|
||||
except Exception as e:
|
||||
logging.error(f"Couldn't normalize volume for {music_path}: {e}")
|
||||
|
||||
if not music_name in self.loaded_sounds:
|
||||
self.loaded_sounds[music_name] = arcade.Sound(music_path, streaming=self.settings_dict.get("music_mode", "Stream") == "Stream")
|
||||
|
||||
self.volume = self.settings_dict.get("default_volume", 100)
|
||||
self.volume_label.text = f"{self.volume}%"
|
||||
self.volume_slider.value = self.volume
|
||||
|
||||
self.current_music_player = self.loaded_sounds[music_name].play()
|
||||
self.current_music_player.volume = self.volume / 100
|
||||
self.current_length = self.loaded_sounds[music_name].get_length()
|
||||
|
||||
self.current_music_name = music_name
|
||||
self.current_music_label.text = truncate_end(music_name, int(self.window.width / 25))
|
||||
self.time_label.text = "00:00"
|
||||
self.progressbar.max_value = self.current_length
|
||||
self.progressbar.value = 0
|
||||
|
||||
else:
|
||||
if self.current_music_player is not None:
|
||||
self.skip_sound() # reset properties
|
||||
|
||||
if self.shuffle:
|
||||
self.queue.append(f"{self.current_tab}/{random.choice(self.tab_content[self.current_tab])}")
|
||||
|
||||
if not self.current_music_player is None:
|
||||
if self.time_to_seek is not None:
|
||||
self.current_music_player.seek(self.time_to_seek)
|
||||
self.progressbar.value = self.time_to_seek
|
||||
self.time_to_seek = None
|
||||
else:
|
||||
self.progressbar.value = self.current_music_player.time
|
||||
mins, secs = divmod(self.current_music_player.time, 60)
|
||||
self.time_label.text = f"{int(mins):02d}:{int(secs):02d}"
|
||||
|
||||
def on_key_press(self, symbol: int, modifiers: int) -> bool | None:
|
||||
if symbol == arcade.key.SPACE:
|
||||
self.pause_start()
|
||||
elif symbol == arcade.key.DELETE:
|
||||
self.skip_sound()
|
||||
elif symbol == arcade.key.RIGHT and self.current_music_player:
|
||||
self.current_music_player.seek(self.current_music_player.time + 5)
|
||||
elif symbol == arcade.key.LEFT and self.current_music_player:
|
||||
self.current_music_player.seek(self.current_music_player.time - 5)
|
||||
elif symbol == arcade.key.UP and self.current_music_player:
|
||||
self.current_music_player.pitch += 0.1 # type: ignore
|
||||
elif symbol == arcade.key.DOWN and self.current_music_player:
|
||||
self.current_music_player.pitch -= 0.1 # type: ignore
|
||||
elif symbol == arcade.key.BACKSPACE:
|
||||
self.search_term = self.search_term[:-1]
|
||||
if self.current_mode == "files":
|
||||
self.show_content(self.current_tab)
|
||||
elif self.current_mode == "playlist":
|
||||
self.show_content(self.current_playlist)
|
||||
elif symbol == arcade.key.ENTER and self.highest_score_file:
|
||||
self.queue.append(self.highest_score_file)
|
||||
self.highest_score_file = ""
|
||||
self.search_term = ""
|
||||
if self.current_mode == "files":
|
||||
self.show_content(self.current_tab)
|
||||
elif self.current_mode == "playlist":
|
||||
self.show_content(self.current_playlist)
|
||||
elif symbol == arcade.key.ESCAPE:
|
||||
self.highest_score_file = ""
|
||||
self.search_term = ""
|
||||
if self.current_mode == "files":
|
||||
self.show_content(self.current_tab)
|
||||
elif self.current_mode == "playlist":
|
||||
self.show_content(self.current_playlist)
|
||||
|
||||
def on_text(self, text):
|
||||
if not text.isprintable() or text == " ":
|
||||
return
|
||||
|
||||
self.search_term += text
|
||||
|
||||
if self.current_mode == "files":
|
||||
self.show_content(self.current_tab)
|
||||
elif self.current_mode == "playlist":
|
||||
self.show_content(self.current_playlist)
|
||||
|
||||
def settings(self):
|
||||
from menus.settings import Settings
|
||||
arcade.unschedule(self.update_presence)
|
||||
self.ui.clear()
|
||||
self.window.show_view(Settings(self.pypresence_client, self.current_mode, self.current_music_name, self.current_length, self.current_music_player, self.queue, self.loaded_sounds, self.shuffle))
|
||||
|
||||
def new_tab(self):
|
||||
from menus.new_tab import NewTab
|
||||
arcade.unschedule(self.update_presence)
|
||||
self.ui.clear()
|
||||
self.window.show_view(NewTab(self.pypresence_client, self.current_mode, self.current_music_name, self.current_length, self.current_music_player, self.queue, self.loaded_sounds, self.shuffle))
|
||||
|
||||
def add_music(self):
|
||||
from menus.add_music import AddMusic
|
||||
arcade.unschedule(self.update_presence)
|
||||
self.ui.clear()
|
||||
self.window.show_view(AddMusic(self.pypresence_client, self.current_mode, self.current_music_name, self.current_length, self.current_music_player, self.queue, self.loaded_sounds, self.shuffle))
|
||||
|
||||
def downloader(self):
|
||||
from menus.downloader import Downloader
|
||||
arcade.unschedule(self.update_presence)
|
||||
self.ui.clear()
|
||||
self.window.show_view(Downloader(self.pypresence_client, self.current_mode, self.current_music_name, self.current_length, self.current_music_player, self.queue, self.loaded_sounds, self.shuffle))
|
||||
|
||||
def reload(self):
|
||||
self.ui.clear()
|
||||
self.on_show_view()
|
||||
self.update_buttons()
|
||||
|
||||
def update_presence(self, _):
|
||||
if self.current_music_label.text != "No songs playing" and self.current_music_player:
|
||||
details = f"Listening to {self.current_music_name}"
|
||||
|
||||
if self.current_music_player.playing:
|
||||
mins, secs = divmod(self.current_length, 60)
|
||||
state = f"{self.time_label.text} / {int(mins):02d}:{int(secs):02d}"
|
||||
else:
|
||||
state = "Paused"
|
||||
else:
|
||||
details = ""
|
||||
state = "No songs playing"
|
||||
|
||||
self.pypresence_client.update(state=state, details=details, start=self.pypresence_client.start_time)
|
||||
77
menus/new_tab.py
Normal file
77
menus/new_tab.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import arcade, arcade.gui, os, json
|
||||
|
||||
from utils.constants import button_style
|
||||
from utils.preload import button_texture, button_hovered_texture
|
||||
from utils.utils import UIFocusTextureButton
|
||||
|
||||
from arcade.gui.experimental.focus import UIFocusGroup
|
||||
|
||||
class NewTab(arcade.gui.UIView):
|
||||
def __init__(self, pypresence_client, current_mode, current_music_name, current_length, current_music_player, queue, loaded_sounds, shuffle):
|
||||
super().__init__()
|
||||
|
||||
self.current_mode = current_mode
|
||||
self.current_music_name = current_music_name
|
||||
self.current_length = current_length
|
||||
self.current_music_player = current_music_player
|
||||
self.queue = queue
|
||||
self.loaded_sounds = loaded_sounds
|
||||
self.shuffle = shuffle
|
||||
|
||||
with open("settings.json", "r") as file:
|
||||
self.settings_dict = json.load(file)
|
||||
|
||||
self.tab_options = self.settings_dict.get("tab_options", ["~/Music", "~/Downloads"])
|
||||
self.playlists = self.settings_dict.get("playlists", {})
|
||||
|
||||
self.pypresence_client = pypresence_client
|
||||
self.pypresence_client.update(state="Adding new tab", start=self.pypresence_client.start_time)
|
||||
|
||||
def on_show_view(self):
|
||||
super().on_show_view()
|
||||
|
||||
self.anchor = self.add_widget(UIFocusGroup(size_hint=(1, 1)))
|
||||
self.box = self.anchor.add(arcade.gui.UIBoxLayout(space_between=10), anchor_x="center", anchor_y="center")
|
||||
|
||||
if self.current_mode == "files":
|
||||
self.new_tab_label = self.box.add(arcade.gui.UILabel(text="New Tab Path:", font_name="Protest Strike", font_size=32))
|
||||
self.new_tab_input = self.box.add(arcade.gui.UIInputText(font_name="Protest Strike", font_size=32, width=self.window.width / 2, height=self.window.height / 10))
|
||||
self.new_tab_button = self.box.add(UIFocusTextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text='Add new tab', style=button_style, width=self.window.width / 2, height=self.window.height / 10))
|
||||
self.new_tab_button.on_click = lambda event: self.add_tab()
|
||||
elif self.current_mode == "playlist":
|
||||
self.new_tab_label = self.box.add(arcade.gui.UILabel(text="New Playlist Name:", font_name="Protest Strike", font_size=32))
|
||||
self.new_tab_input = self.box.add(arcade.gui.UIInputText(font_name="Protest Strike", font_size=32, width=self.window.width / 2, height=self.window.height / 10))
|
||||
self.new_tab_button = self.box.add(UIFocusTextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text='Add new Playlist', style=button_style, width=self.window.width / 2, height=self.window.height / 10))
|
||||
self.new_tab_button.on_click = lambda event: self.add_tab()
|
||||
|
||||
self.back_button = self.anchor.add(UIFocusTextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text='<--', style=button_style, width=100, height=50), anchor_x="left", anchor_y="top", align_x=5, align_y=-5)
|
||||
self.back_button.on_click = lambda event: self.main_exit()
|
||||
|
||||
self.anchor.detect_focusable_widgets()
|
||||
|
||||
def add_tab(self):
|
||||
if self.current_mode == "files":
|
||||
tab_path = self.new_tab_input.text
|
||||
|
||||
if not tab_path:
|
||||
return
|
||||
|
||||
if not os.path.exists(os.path.expanduser(tab_path)) or not os.path.isdir(os.path.expanduser(tab_path)) or not os.path.isabs(os.path.expanduser(tab_path)):
|
||||
return
|
||||
|
||||
if tab_path in self.tab_options or os.path.expanduser(tab_path) in self.tab_options:
|
||||
return
|
||||
|
||||
self.tab_options.append(tab_path)
|
||||
self.settings_dict["tab_options"] = self.tab_options
|
||||
|
||||
elif self.current_mode == "playlist":
|
||||
self.playlists[self.new_tab_input.text] = []
|
||||
self.settings_dict["playlists"] = self.playlists
|
||||
|
||||
with open("settings.json", "w") as file:
|
||||
file.write(json.dumps(self.settings_dict))
|
||||
|
||||
def main_exit(self):
|
||||
from menus.main import Main
|
||||
self.window.show_view(Main(self.pypresence_client, self.current_mode, self.current_music_name, self.current_length, self.current_music_player, self.queue, self.loaded_sounds, self.shuffle))
|
||||
298
menus/settings.py
Normal file
298
menus/settings.py
Normal file
@@ -0,0 +1,298 @@
|
||||
import copy, pypresence, json
|
||||
|
||||
import arcade, arcade.gui
|
||||
|
||||
from utils.constants import button_style, dropdown_style, slider_style, settings, discord_presence_id, settings_start_category
|
||||
from utils.utils import FakePyPresence, UIFocusTextureButton
|
||||
from utils.preload import button_texture, button_hovered_texture
|
||||
|
||||
from arcade.gui.experimental.focus import UIFocusGroup
|
||||
|
||||
class Settings(arcade.gui.UIView):
|
||||
def __init__(self, pypresence_client, current_mode, current_music_name, current_length, current_music_player, queue, loaded_sounds, shuffle):
|
||||
super().__init__()
|
||||
|
||||
self.current_mode = current_mode
|
||||
self.current_music_name = current_music_name
|
||||
self.current_length = current_length
|
||||
self.current_music_player = current_music_player
|
||||
self.queue = queue
|
||||
self.loaded_sounds = loaded_sounds
|
||||
self.shuffle = shuffle
|
||||
|
||||
with open("settings.json", "r") as file:
|
||||
self.settings_dict = json.load(file)
|
||||
|
||||
self.pypresence_client = pypresence_client
|
||||
self.pypresence_client.update(state='In Settings', details='Modifying Settings', start=self.pypresence_client.start_time)
|
||||
|
||||
self.slider_labels = {}
|
||||
self.sliders = {}
|
||||
|
||||
self.on_radiobuttons = {}
|
||||
self.off_radiobuttons = {}
|
||||
|
||||
self.current_category = settings_start_category
|
||||
|
||||
self.modified_settings = {}
|
||||
|
||||
def create_layouts(self):
|
||||
self.anchor = self.add_widget(UIFocusGroup(size_hint=(1, 1)))
|
||||
|
||||
self.box = arcade.gui.UIBoxLayout(space_between=50, align="center", vertical=False)
|
||||
self.anchor.add(self.box, anchor_x="center", anchor_y="top", align_x=10, align_y=-75)
|
||||
|
||||
self.top_box = arcade.gui.UIBoxLayout(space_between=self.window.width / 160, vertical=False)
|
||||
self.anchor.add(self.top_box, anchor_x="left", anchor_y="top", align_x=10, align_y=-10)
|
||||
|
||||
self.key_layout = self.box.add(arcade.gui.UIBoxLayout(space_between=20, align='left'))
|
||||
self.value_layout = self.box.add(arcade.gui.UIBoxLayout(space_between=13, align='left'))
|
||||
|
||||
def on_show_view(self):
|
||||
super().on_show_view()
|
||||
|
||||
self.create_layouts()
|
||||
|
||||
self.ui.push_handlers(self)
|
||||
|
||||
self.back_button = UIFocusTextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text='<--', style=button_style, width=100, height=50)
|
||||
self.back_button.on_click = lambda event: self.main_exit()
|
||||
self.top_box.add(self.back_button)
|
||||
|
||||
self.display_categories()
|
||||
|
||||
self.display_category(settings_start_category)
|
||||
|
||||
self.anchor.detect_focusable_widgets()
|
||||
|
||||
def display_categories(self):
|
||||
for category in settings:
|
||||
category_button = UIFocusTextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text=category, style=button_style, width=self.window.width / 10, height=50)
|
||||
|
||||
if not category == "Credits":
|
||||
category_button.on_click = lambda event, category=category: self.display_category(category)
|
||||
else:
|
||||
category_button.on_click = lambda event: self.credits()
|
||||
|
||||
self.top_box.add(category_button)
|
||||
|
||||
self.anchor.detect_focusable_widgets()
|
||||
|
||||
def display_category(self, category):
|
||||
if hasattr(self, 'apply_button'):
|
||||
self.anchor.remove(self.apply_button)
|
||||
del self.apply_button
|
||||
|
||||
if hasattr(self, 'credits_label'):
|
||||
self.anchor.remove(self.credits_label)
|
||||
del self.credits_label
|
||||
|
||||
self.current_category = category
|
||||
|
||||
self.key_layout.clear()
|
||||
self.value_layout.clear()
|
||||
|
||||
for setting in settings[category]:
|
||||
label = arcade.gui.UILabel(text=setting, font_name="Protest Strike", font_size=28, text_color=arcade.color.WHITE )
|
||||
self.key_layout.add(label)
|
||||
|
||||
setting_dict = settings[category][setting]
|
||||
|
||||
if setting_dict['type'] == "option":
|
||||
dropdown = arcade.gui.UIDropdown(options=setting_dict['options'], width=200, height=50, default=self.settings_dict.get(setting_dict["config_key"], setting_dict["options"][0]), active_style=dropdown_style, dropdown_style=dropdown_style, primary_style=dropdown_style)
|
||||
dropdown.on_change = lambda _, setting=setting, dropdown=dropdown: self.update(setting, dropdown.value, "option")
|
||||
self.value_layout.add(dropdown)
|
||||
|
||||
elif setting_dict['type'] == "bool":
|
||||
button_layout = self.value_layout.add(arcade.gui.UIBoxLayout(space_between=50, vertical=False))
|
||||
|
||||
on_radiobutton = UIFocusTextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text="ON", style=button_style, width=150, height=50)
|
||||
self.on_radiobuttons[setting] = on_radiobutton
|
||||
on_radiobutton.on_click = lambda _, setting=setting: self.update(setting, True, "bool")
|
||||
button_layout.add(on_radiobutton)
|
||||
|
||||
off_radiobutton = UIFocusTextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text="OFF", style=button_style, width=150, height=50)
|
||||
self.off_radiobuttons[setting] = off_radiobutton
|
||||
off_radiobutton.on_click = lambda _, setting=setting: self.update(setting, False, "bool")
|
||||
button_layout.add(off_radiobutton)
|
||||
|
||||
if self.settings_dict.get(setting_dict["config_key"], setting_dict["default"]):
|
||||
self.set_highlighted_style(on_radiobutton)
|
||||
self.set_normal_style(off_radiobutton)
|
||||
else:
|
||||
self.set_highlighted_style(off_radiobutton)
|
||||
self.set_normal_style(on_radiobutton)
|
||||
|
||||
elif setting_dict['type'] == "slider":
|
||||
if setting == "FPS Limit":
|
||||
if self.settings_dict.get(setting_dict["config_key"]) == 0:
|
||||
label_text = "FPS Limit: Disabled"
|
||||
else:
|
||||
label_text = f"FPS Limit: {self.settings_dict.get(setting_dict['config_key'], setting_dict['default'])}"
|
||||
else:
|
||||
label_text = f"{setting}: {int(self.settings_dict.get(setting_dict['config_key'], setting_dict['default']))}"
|
||||
|
||||
label.text = label_text
|
||||
|
||||
self.slider_labels[setting] = label
|
||||
|
||||
slider = arcade.gui.UISlider(width=400, height=50, value=self.settings_dict.get(setting_dict["config_key"], setting_dict["default"]), min_value=setting_dict['min'], max_value=setting_dict['max'], style=slider_style)
|
||||
slider.on_change = lambda _, setting=setting, slider=slider: self.update(setting, slider.value, "slider")
|
||||
|
||||
self.sliders[setting] = slider
|
||||
self.value_layout.add(slider)
|
||||
|
||||
self.apply_button = UIFocusTextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text='Apply', style=button_style, width=200, height=100)
|
||||
self.apply_button.on_click = lambda event: self.apply_settings()
|
||||
self.anchor.add(self.apply_button, anchor_x="right", anchor_y="bottom", align_x=-10, align_y=10)
|
||||
|
||||
self.anchor.detect_focusable_widgets()
|
||||
|
||||
def apply_settings(self):
|
||||
for config_key, value in self.modified_settings.items():
|
||||
self.settings_dict[config_key] = value
|
||||
|
||||
if self.settings_dict['window_mode'] == "Fullscreen":
|
||||
self.window.set_fullscreen(True)
|
||||
else:
|
||||
self.window.set_fullscreen(False)
|
||||
width, height = map(int, self.settings_dict['resolution'].split('x'))
|
||||
self.window.set_size(width, height)
|
||||
|
||||
if self.settings_dict['vsync']:
|
||||
self.window.set_vsync(True)
|
||||
display_mode = self.window.display.get_default_screen().get_mode()
|
||||
refresh_rate = display_mode.rate
|
||||
self.window.set_update_rate(1 / refresh_rate)
|
||||
self.window.set_draw_rate(1 / refresh_rate)
|
||||
|
||||
elif not self.settings_dict['fps_limit'] == 0:
|
||||
self.window.set_vsync(False)
|
||||
self.window.set_update_rate(1 / self.settings_dict['fps_limit'])
|
||||
self.window.set_draw_rate(1 / self.settings_dict['fps_limit'])
|
||||
|
||||
else:
|
||||
self.window.set_vsync(False)
|
||||
self.window.set_update_rate(1 / 99999999)
|
||||
self.window.set_draw_rate(1 / 99999999)
|
||||
|
||||
if self.settings_dict['discord_rpc']:
|
||||
if isinstance(self.pypresence_client, FakePyPresence): # the user has enabled RPC in the settings in this session.
|
||||
start_time = copy.deepcopy(self.pypresence_client.start_time)
|
||||
self.pypresence_client.close()
|
||||
del self.pypresence_client
|
||||
try:
|
||||
self.pypresence_client = pypresence.Presence(discord_presence_id)
|
||||
self.pypresence_client.connect()
|
||||
self.pypresence_client.update(state='In Settings', details='Modifying Settings', start=start_time)
|
||||
self.pypresence_client.start_time = start_time
|
||||
except:
|
||||
self.pypresence_client = FakePyPresence()
|
||||
self.pypresence_client.start_time = start_time
|
||||
else:
|
||||
if not isinstance(self.pypresence_client, FakePyPresence):
|
||||
start_time = copy.deepcopy(self.pypresence_client.start_time)
|
||||
self.pypresence_client.update()
|
||||
self.pypresence_client.close()
|
||||
del self.pypresence_client
|
||||
self.pypresence_client = FakePyPresence()
|
||||
self.pypresence_client.start_time = start_time
|
||||
|
||||
self.ui_cleanup()
|
||||
|
||||
self.ui = arcade.gui.UIManager()
|
||||
self.ui.enable()
|
||||
|
||||
self.create_layouts()
|
||||
|
||||
self.back_button = UIFocusTextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text='<--', style=button_style, width=100, height=50)
|
||||
self.back_button.on_click = lambda event: self.main_exit()
|
||||
self.top_box.add(self.back_button)
|
||||
|
||||
self.display_categories()
|
||||
|
||||
self.display_category(self.current_category)
|
||||
|
||||
with open("settings.json", "w") as file:
|
||||
file.write(json.dumps(self.settings_dict, indent=4))
|
||||
|
||||
def update(self, setting=None, button_state=None, setting_type="bool"):
|
||||
setting_dict = settings[self.current_category][setting]
|
||||
config_key = settings[self.current_category][setting]["config_key"]
|
||||
|
||||
if setting_type == "option":
|
||||
self.modified_settings[config_key] = button_state
|
||||
|
||||
elif setting_type == "bool":
|
||||
self.modified_settings[config_key] = button_state
|
||||
|
||||
if button_state:
|
||||
self.set_highlighted_style(self.on_radiobuttons[setting])
|
||||
self.set_normal_style(self.off_radiobuttons[setting])
|
||||
else:
|
||||
self.set_highlighted_style(self.off_radiobuttons[setting])
|
||||
self.set_normal_style(self.on_radiobuttons[setting])
|
||||
|
||||
elif setting_type == "slider":
|
||||
new_value = int(button_state)
|
||||
|
||||
self.modified_settings[config_key] = new_value
|
||||
self.sliders[setting].value = new_value
|
||||
|
||||
if setting == "FPS Limit":
|
||||
if new_value == 0:
|
||||
label_text = "FPS Limit: Disabled"
|
||||
else:
|
||||
label_text = f"FPS Limit: {str(new_value).rjust(8)}"
|
||||
else:
|
||||
label_text = f"{setting}: {str(new_value).rjust(8)}"
|
||||
|
||||
self.slider_labels[setting].text = label_text
|
||||
|
||||
def credits(self):
|
||||
if hasattr(self, 'apply_button'):
|
||||
self.anchor.remove(self.apply_button)
|
||||
del self.apply_button
|
||||
|
||||
if hasattr(self, 'credits_label'):
|
||||
self.anchor.remove(self.credits_label)
|
||||
del self.credits_label
|
||||
|
||||
self.key_layout.clear()
|
||||
self.value_layout.clear()
|
||||
|
||||
with open('CREDITS', 'r') as file:
|
||||
text = file.read()
|
||||
|
||||
if self.window.width == 3840:
|
||||
font_size = 30
|
||||
elif self.window.width == 2560:
|
||||
font_size = 20
|
||||
elif self.window.width == 1920:
|
||||
font_size = 17
|
||||
elif self.window.width >= 1440:
|
||||
font_size = 14
|
||||
else:
|
||||
font_size = 12
|
||||
|
||||
self.credits_label = arcade.gui.UILabel(text=text, text_color=arcade.color.WHITE, font_name="Protest Strike", font_size=font_size, align="center", multiline=True)
|
||||
|
||||
self.key_layout.add(self.credits_label)
|
||||
|
||||
self.anchor.detect_focusable_widgets()
|
||||
|
||||
def set_highlighted_style(self, element):
|
||||
element.texture = button_hovered_texture
|
||||
element.texture_hovered = button_texture
|
||||
|
||||
def set_normal_style(self, element):
|
||||
element.texture_hovered = button_hovered_texture
|
||||
element.texture = button_texture
|
||||
|
||||
def main_exit(self):
|
||||
from menus.main import Main
|
||||
self.window.show_view(Main(self.pypresence_client, self.current_mode, self.current_music_name, self.current_length, self.current_music_player, self.queue, self.loaded_sounds, self.shuffle))
|
||||
|
||||
def ui_cleanup(self):
|
||||
self.ui.clear()
|
||||
del self.ui
|
||||
Reference in New Issue
Block a user