fix encoding errors and weird paths

This commit is contained in:
Yonokid
2025-08-15 00:05:08 -04:00
parent 223fc0707c
commit 64ce14bd3c
2 changed files with 261 additions and 210 deletions

View File

@@ -177,12 +177,27 @@ def calculate_base_score(play_note_list: deque[Note | Drumroll | Balloon]) -> in
total_score = (1000000 - (balloon_count * 100) - (drumroll_sec * 1692.0079999994086)) / total_notes total_score = (1000000 - (balloon_count * 100) - (drumroll_sec * 1692.0079999994086)) / total_notes
return math.ceil(total_score / 10) * 10 return math.ceil(total_score / 10) * 10
def test_encodings(file_path):
encodings = ['utf-8-sig', 'shift-jis', 'utf-8']
final_encoding = None
for encoding in encodings:
try:
_ = file_path.read_text(encoding=encoding).splitlines()
final_encoding = encoding
break
except UnicodeDecodeError:
continue
return final_encoding
class TJAParser: class TJAParser:
DIFFS = {0: "easy", 1: "normal", 2: "hard", 3: "oni", 4: "edit", 5: "tower", 6: "dan"} DIFFS = {0: "easy", 1: "normal", 2: "hard", 3: "oni", 4: "edit", 5: "tower", 6: "dan"}
def __init__(self, path: Path, start_delay: int = 0, distance: int = 866): def __init__(self, path: Path, start_delay: int = 0, distance: int = 866):
self.file_path: Path = path self.file_path: Path = path
lines = self.file_path.read_text(encoding='utf-8-sig').splitlines() encoding = test_encodings(self.file_path)
lines = self.file_path.read_text(encoding=encoding).splitlines()
self.data = [cleaned for line in lines self.data = [cleaned for line in lines
if (cleaned := strip_comments(line).strip())] if (cleaned := strip_comments(line).strip())]
@@ -218,7 +233,7 @@ class TJAParser:
elif item.startswith('OFFSET'): elif item.startswith('OFFSET'):
self.metadata.offset = float(item.split(':')[1]) self.metadata.offset = float(item.split(':')[1])
elif item.startswith('DEMOSTART'): elif item.startswith('DEMOSTART'):
self.metadata.demostart = float(item.split(':')[1]) self.metadata.demostart = float(item.split(':')[1]) if item.split(':')[1] != '' else 0
elif item.startswith('BGMOVIE'): elif item.startswith('BGMOVIE'):
self.metadata.bgmovie = self.file_path.parent / item.split(':')[1].strip() self.metadata.bgmovie = self.file_path.parent / item.split(':')[1].strip()
elif item.startswith('MOVIEOFFSET'): elif item.startswith('MOVIEOFFSET'):
@@ -262,6 +277,9 @@ class TJAParser:
continue continue
self.metadata.course_data[current_diff].balloon = [int(x) for x in balloon_data.split(',') if x != ''] self.metadata.course_data[current_diff].balloon = [int(x) for x in balloon_data.split(',') if x != '']
elif item.startswith('BALLOON'): elif item.startswith('BALLOON'):
if item.find(':') == -1:
self.metadata.course_data[current_diff].balloon = []
continue
balloon_data = item.split(':')[1] balloon_data = item.split(':')[1]
if balloon_data == '': if balloon_data == '':
continue continue
@@ -270,12 +288,16 @@ class TJAParser:
score_init = item.split(':')[1] score_init = item.split(':')[1]
if score_init == '': if score_init == '':
continue continue
self.metadata.course_data[current_diff].scoreinit = [int(x) for x in score_init.split(',')] try:
self.metadata.course_data[current_diff].scoreinit = [int(x) for x in score_init.split(',') if x != '']
except Exception as e:
print("Failed to parse SCOREINIT: ", e)
self.metadata.course_data[current_diff].scoreinit = [0, 0]
elif item.startswith('SCOREDIFF'): elif item.startswith('SCOREDIFF'):
score_diff = item.split(':')[1] score_diff = item.split(':')[1]
if score_diff == '': if score_diff == '':
continue continue
self.metadata.course_data[current_diff].scorediff = int(score_diff) self.metadata.course_data[current_diff].scorediff = int(float(score_diff))
for region_code in self.metadata.title: for region_code in self.metadata.title:
if '-New Audio-' in self.metadata.title[region_code] or '-新曲-' in self.metadata.title[region_code]: if '-New Audio-' in self.metadata.title[region_code] or '-新曲-' in self.metadata.title[region_code]:
self.metadata.title[region_code] = self.metadata.title[region_code].strip('-New Audio-') self.metadata.title[region_code] = self.metadata.title[region_code].strip('-New Audio-')

View File

@@ -9,7 +9,7 @@ import pyray as ray
from libs.animation import Animation, MoveAnimation from libs.animation import Animation, MoveAnimation
from libs.audio import audio from libs.audio import audio
from libs.texture import tex from libs.texture import tex
from libs.tja import TJAParser from libs.tja import TJAParser, test_encodings
from libs.transition import Transition from libs.transition import Transition
from libs.utils import ( from libs.utils import (
OutlinedText, OutlinedText,
@@ -1253,20 +1253,16 @@ class FileNavigator:
self.all_directories: dict[str, Directory] = {} # path -> Directory self.all_directories: dict[str, Directory] = {} # path -> Directory
self.all_song_files: dict[str, SongFile] = {} # path -> SongFile self.all_song_files: dict[str, SongFile] = {} # path -> SongFile
self.directory_contents: dict[str, list[Union[Directory, SongFile]]] = {} # path -> list of items self.directory_contents: dict[str, list[Union[Directory, SongFile]]] = {} # path -> list of items
self.root_items: list[Union[Directory, SongFile]] = []
# OPTION 2: Lazy crown calculation with caching # OPTION 2: Lazy crown calculation with caching
self.directory_crowns: dict[str, dict] = dict() # path -> crown list self.directory_crowns: dict[str, dict] = dict() # path -> crown list
self.crown_cache_dirty: set[str] = set() # directories that need crown recalculation self.crown_cache_dirty: set[str] = set() # directories that need crown recalculation
# Navigation state # Navigation state - simplified without root-specific state
self.in_root_selection = True self.current_dir = Path() # Empty path represents virtual root
self.current_dir = Path()
self.current_root_dir = Path()
self.items: list[Directory | SongFile] = [] self.items: list[Directory | SongFile] = []
self.new_items: list[Directory | SongFile] = [] self.new_items: list[Directory | SongFile] = []
self.favorite_folder: Optional[Directory] = None self.favorite_folder: Optional[Directory] = None
self.in_favorites = False
self.recent_folder: Optional[Directory] = None self.recent_folder: Optional[Directory] = None
self.selected_index = 0 self.selected_index = 0
self.diff_sort_diff = 4 self.diff_sort_diff = 4
@@ -1278,45 +1274,77 @@ class FileNavigator:
# Generate all objects upfront # Generate all objects upfront
self._generate_all_objects() self._generate_all_objects()
self.load_root_directories() self._create_virtual_root()
self.load_current_directory()
def _create_virtual_root(self):
"""Create a virtual root directory containing all root directories"""
virtual_root_items = []
for root_path in self.root_dirs:
if not root_path.exists():
continue
root_key = str(root_path)
if root_key in self.all_directories:
# Root has box.def, add the directory itself
virtual_root_items.append(self.all_directories[root_key])
else:
# Root doesn't have box.def, add its immediate children with box.def
for child_path in sorted(root_path.iterdir()):
if child_path.is_dir():
child_key = str(child_path)
if child_key in self.all_directories:
virtual_root_items.append(self.all_directories[child_key])
# Also add direct TJA files from root
all_tja_files = self._find_tja_files_recursive(root_path)
for tja_path in sorted(all_tja_files):
song_key = str(tja_path)
if song_key in self.all_song_files:
virtual_root_items.append(self.all_song_files[song_key])
# Store virtual root contents (empty path key represents root)
self.directory_contents["."] = virtual_root_items
def _generate_all_objects(self): def _generate_all_objects(self):
"""Generate all Directory and SongFile objects in advance""" """Generate all Directory and SongFile objects in advance"""
print("Generating all Directory and SongFile objects...") print("Generating all Directory and SongFile objects...")
# First, generate objects for each root directory # Generate objects for each root directory
for root_path in self.root_dirs: for root_path in self.root_dirs:
if not root_path.exists(): if not root_path.exists():
print(f"Root directory does not exist: {root_path}") print(f"Root directory does not exist: {root_path}")
continue continue
self._generate_objects_recursive(root_path, is_root=True) self._generate_objects_recursive(root_path)
print(f"Object generation complete. " print(f"Object generation complete. "
f"Directories: {len(self.all_directories)}, " f"Directories: {len(self.all_directories)}, "
f"Songs: {len(self.all_song_files)}") f"Songs: {len(self.all_song_files)}")
def _generate_objects_recursive(self, dir_path: Path, is_root=False): def _generate_objects_recursive(self, dir_path: Path):
"""Recursively generate Directory and SongFile objects for a directory""" """Recursively generate Directory and SongFile objects for a directory"""
if not dir_path.is_dir(): if not dir_path.is_dir():
return return
dir_key = str(dir_path) dir_key = str(dir_path)
# Check for box.def # Check for box.def
has_box_def = (dir_path / "box.def").exists() has_box_def = (dir_path / "box.def").exists()
# Only create Directory objects for directories with box.def
if has_box_def:
# Parse box.def if it exists # Parse box.def if it exists
name = dir_path.name if dir_path.name else str(dir_path) name = dir_path.name if dir_path.name else str(dir_path)
texture_index = 9 texture_index = 9
box_texture = None box_texture = None
collection = None collection = None
if has_box_def: name, texture_index, collection = self._parse_box_def(dir_path)
name, texture_index, collection = self._parse_box_def(dir_path) box_png_path = dir_path / "box.png"
box_png_path = dir_path / "box.png" if box_png_path.exists():
if box_png_path.exists(): box_texture = str(box_png_path)
box_texture = str(box_png_path)
# Count TJA files for this directory # Count TJA files for this directory
tja_count = self._count_tja_files(dir_path) tja_count = self._count_tja_files(dir_path)
@@ -1380,25 +1408,189 @@ class FileNavigator:
# OPTION 2: Mark directory for lazy crown calculation # OPTION 2: Mark directory for lazy crown calculation
self.crown_cache_dirty.add(dir_key) self.crown_cache_dirty.add(dir_key)
# If this is a root directory, add to root items else:
if is_root: # For directories without box.def, still process their children
if has_box_def: for item_path in dir_path.iterdir():
self.root_items.append(directory_obj) if item_path.is_dir():
self._generate_objects_recursive(item_path)
# Create SongFile objects for TJA files in non-boxed directories
tja_files = self._find_tja_files_in_directory_only(dir_path)
for tja_path in sorted(tja_files):
song_key = str(tja_path)
if song_key not in self.all_song_files:
try:
song_obj = SongFile(tja_path, tja_path.name, 9)
self.song_count += 1
global_data.song_progress = self.song_count / global_data.total_songs
self.all_song_files[song_key] = song_obj
except Exception as e:
print(f"Error creating SongFile for {tja_path}: {e}")
continue
def is_at_root(self) -> bool:
"""Check if currently at the virtual root"""
return self.current_dir == Path()
def load_current_directory(self, selected_item: Optional[Directory] = None):
"""Load pre-generated items for the current directory (unified for root and subdirs)"""
dir_key = str(self.current_dir)
# Determine if current directory has child directories with box.def
has_children = False
if self.is_at_root():
has_children = True # Root always has "children" (the root directories)
else:
has_children = any(item.is_dir() and (item / "box.def").exists()
for item in self.current_dir.iterdir())
self.genre_bg = None
self.in_favorites = False
if has_children:
self.items = []
if not self.box_open:
self.selected_index = 0
start_box = None
end_box = None
# Add back navigation item (only if not at root)
if not self.is_at_root():
back_dir = Directory(self.current_dir.parent, "", 17, back=True)
if not has_children:
start_box = back_dir.box
self.items.insert(self.selected_index, back_dir)
# Add pre-generated content for this directory
if dir_key in self.directory_contents:
content_items = self.directory_contents[dir_key]
# Handle special collections (same logic as before)
if isinstance(selected_item, Directory):
if selected_item.collection == Directory.COLLECTIONS[0]:
content_items = self.new_items
elif selected_item.collection == Directory.COLLECTIONS[1]:
if self.recent_folder is None:
raise Exception("tried to enter recent folder without recents")
self._generate_objects_recursive(self.recent_folder.path)
selected_item.box.tja_count_text = None
selected_item.box.tja_count = self._count_tja_files(self.recent_folder.path)
content_items = self.directory_contents[dir_key]
elif selected_item.collection == Directory.COLLECTIONS[2]:
if self.favorite_folder is None:
raise Exception("tried to enter favorite folder without favorites")
self._generate_objects_recursive(self.favorite_folder.path)
selected_item.box.tja_count_text = None
selected_item.box.tja_count = self._count_tja_files(self.favorite_folder.path)
content_items = self.directory_contents[dir_key]
self.in_favorites = True
elif selected_item.collection == Directory.COLLECTIONS[3]:
content_items = []
parent_dir = selected_item.path.parent
for sibling_path in parent_dir.iterdir():
if sibling_path.is_dir() and sibling_path != selected_item.path:
sibling_key = str(sibling_path)
if sibling_key in self.directory_contents:
for item in self.directory_contents[sibling_key]:
if isinstance(item, SongFile) and item:
if self.diff_sort_diff in item.tja.metadata.course_data and item.tja.metadata.course_data[self.diff_sort_diff].level == self.diff_sort_level:
if item not in content_items:
content_items.append(item)
elif selected_item.collection == Directory.COLLECTIONS[4]:
parent_dir = selected_item.path.parent
temp_items = []
for sibling_path in parent_dir.iterdir():
if sibling_path.is_dir() and sibling_path != selected_item.path:
sibling_key = str(sibling_path)
if sibling_key in self.directory_contents:
for item in self.directory_contents[sibling_key]:
temp_items.append(item)
content_items = random.sample(temp_items, 10)
i = 1
for item in content_items:
if isinstance(item, SongFile):
if i % 10 == 0 and i != 0:
back_dir = Directory(self.current_dir.parent, "", 17, back=True)
self.items.insert(self.selected_index+i, back_dir)
i += 1
if not has_children:
if selected_item is not None:
item.box.texture_index = selected_item.box.texture_index
self.items.insert(self.selected_index+i, item)
else: else:
# For roots without box.def, add their TJA files directly self.items.append(item)
all_tja_files = self._find_tja_files_recursive(dir_path) i += 1
for tja_path in sorted(all_tja_files):
song_key = str(tja_path) if not has_children:
if song_key not in self.all_song_files: self.box_open = True
try: end_box = content_items[-1].box
song_obj = SongFile(tja_path, tja_path.name, 9) if selected_item in self.items:
self.song_count += 1 self.items.remove(selected_item)
global_data.song_progress = self.song_count / global_data.total_songs
self.all_song_files[song_key] = song_obj # Calculate crowns for directories
except Exception as e: for item in self.items:
print(f"Error creating SongFile for {tja_path}: {e}") if isinstance(item, Directory):
continue item_key = str(item.path)
self.root_items.append(self.all_song_files[song_key]) if item_key in self.directory_contents: # Only for real directories
item.box.crown = self._get_directory_crowns_cached(item_key)
else:
# Navigation items (back/to_root)
item.box.crown = dict()
self.calculate_box_positions()
if (not has_children and start_box is not None
and end_box is not None and selected_item is not None
and selected_item.box.hori_name is not None):
hori_name = selected_item.box.hori_name
diff_sort = None
if selected_item.collection == Directory.COLLECTIONS[3]:
diff_sort = self.diff_sort_level
diffs = ['かんたん', 'ふつう', 'むずかしい', 'おに']
hori_name = OutlinedText(diffs[min(3, self.diff_sort_diff)], 40, ray.WHITE, ray.BLACK, outline_thickness=5)
self.genre_bg = GenreBG(start_box, end_box, hori_name, diff_sort)
def select_current_item(self):
"""Select the currently highlighted item"""
if not self.items or self.selected_index >= len(self.items):
return
selected_item = self.items[self.selected_index]
if isinstance(selected_item, Directory):
if self.box_open:
self.go_back()
return
if selected_item.back:
# Handle back navigation
if self.current_dir.parent == Path():
# Going back to root
self.current_dir = Path()
else:
self.current_dir = self.current_dir.parent
else:
# Save current state to history
self.history.append((self.current_dir, self.selected_index))
self.current_dir = selected_item.path
self.load_current_directory(selected_item=selected_item)
elif isinstance(selected_item, SongFile):
return selected_item
def go_back(self):
"""Navigate back to the previous directory"""
if self.history:
previous_dir, previous_index = self.history.pop()
self.current_dir = previous_dir
self.selected_index = previous_index
self.load_current_directory()
self.box_open = False
# ... (rest of the methods remain the same: navigate_left, navigate_right, etc.)
def _count_tja_files(self, folder_path: Path): def _count_tja_files(self, folder_path: Path):
"""Count TJA files in directory""" """Count TJA files in directory"""
@@ -1427,6 +1619,7 @@ class FileNavigator:
self.crown_cache_dirty.discard(dir_key) self.crown_cache_dirty.discard(dir_key)
return self.directory_crowns.get(dir_key, dict()) return self.directory_crowns.get(dir_key, dict())
def _calculate_directory_crowns(self, dir_key: str, tja_files: list): def _calculate_directory_crowns(self, dir_key: str, tja_files: list):
"""Pre-calculate crowns for a directory""" """Pre-calculate crowns for a directory"""
all_scores = dict() all_scores = dict()
@@ -1454,8 +1647,6 @@ class FileNavigator:
if (directory / 'song_list.txt').exists(): if (directory / 'song_list.txt').exists():
return self._read_song_list(directory) return self._read_song_list(directory)
else: else:
# For directories with box.def, we want their direct TJA files
# Set box_def_dirs_only=False to ensure we get files from this directory
return self._find_tja_files_in_directory_only(directory) return self._find_tja_files_in_directory_only(directory)
def _find_tja_files_in_directory_only(self, directory: Path): def _find_tja_files_in_directory_only(self, directory: Path):
@@ -1477,11 +1668,7 @@ class FileNavigator:
tja_files: list[Path] = [] tja_files: list[Path] = []
has_box_def = (directory / "box.def").exists() has_box_def = (directory / "box.def").exists()
# Fixed: Only skip if box_def_dirs_only is True AND has_box_def AND it's not the directory we're currently processing
# During object generation, we want to get files from directories with box.def
if box_def_dirs_only and has_box_def and directory != self.current_dir: if box_def_dirs_only and has_box_def and directory != self.current_dir:
# This logic should only apply during navigation, not during object generation
# During object generation, we want to collect all TJA files
return [] return []
for path in directory.iterdir(): for path in directory.iterdir():
@@ -1499,9 +1686,10 @@ class FileNavigator:
texture_index = 9 texture_index = 9
name = path.name name = path.name
collection = None collection = None
encoding = test_encodings(path / "box.def")
try: try:
with open(path / "box.def", 'r', encoding='utf-8') as box_def: with open(path / "box.def", 'r', encoding=encoding) as box_def:
for line in box_def: for line in box_def:
line = line.strip() line = line.strip()
if line.startswith("#GENRE:"): if line.startswith("#GENRE:"):
@@ -1593,126 +1781,6 @@ class FileNavigator:
else: else:
item.box.target_position = position item.box.target_position = position
def load_root_directories(self):
"""Load the pre-generated root directory items"""
self.items = self.root_items.copy()
self.in_root_selection = True
self.current_dir = Path()
self.current_root_dir = Path()
# Reset selection
self.selected_index = 0 if self.items else -1
self.calculate_box_positions()
def load_current_directory(self, selected_item: Optional[Directory]=None):
"""Load pre-generated items for the current directory"""
has_children = any(item.is_dir() and (item / "box.def").exists() for item in self.current_dir.iterdir())
self.genre_bg = None
self.in_favorites = False
if has_children:
self.items = []
if not self.box_open:
self.selected_index = 0
dir_key = str(self.current_dir)
start_box = None
end_box = None
# Add back/to_root navigation items
if self.current_dir != self.current_root_dir:
back_dir = Directory(self.current_dir.parent, "", 17, back=True)
if not has_children:
start_box = back_dir.box
self.items.insert(self.selected_index, back_dir)
elif not self.in_root_selection:
to_root_dir = Directory(Path(), "", 17, to_root=True)
self.items.append(to_root_dir)
# Add pre-generated content for this directory
if dir_key in self.directory_contents:
content_items = self.directory_contents[dir_key]
if isinstance(selected_item, Directory):
if selected_item.collection == Directory.COLLECTIONS[0]:
content_items = self.new_items
elif selected_item.collection == Directory.COLLECTIONS[1]:
if self.recent_folder is None:
raise Exception("tried to enter recent folder without recents")
self._generate_objects_recursive(self.recent_folder.path)
selected_item.box.tja_count_text = None
selected_item.box.tja_count = self._count_tja_files(self.recent_folder.path)
content_items = self.directory_contents[dir_key]
elif selected_item.collection == Directory.COLLECTIONS[2]:
if self.favorite_folder is None:
raise Exception("tried to enter favorite folder without favorites")
self._generate_objects_recursive(self.favorite_folder.path)
selected_item.box.tja_count_text = None
selected_item.box.tja_count = self._count_tja_files(self.favorite_folder.path)
content_items = self.directory_contents[dir_key]
self.in_favorites = True
elif selected_item.collection == Directory.COLLECTIONS[3]:
content_items = []
parent_dir = selected_item.path.parent
for sibling_path in parent_dir.iterdir():
if sibling_path.is_dir() and sibling_path != selected_item.path:
sibling_key = str(sibling_path)
if sibling_key in self.directory_contents:
for item in self.directory_contents[sibling_key]:
if isinstance(item, SongFile) and item:
if self.diff_sort_diff in item.tja.metadata.course_data and item.tja.metadata.course_data[self.diff_sort_diff].level == self.diff_sort_level:
if item not in content_items:
content_items.append(item)
elif selected_item.collection == Directory.COLLECTIONS[4]:
parent_dir = selected_item.path.parent
temp_items = []
for sibling_path in parent_dir.iterdir():
if sibling_path.is_dir() and sibling_path != selected_item.path:
sibling_key = str(sibling_path)
if sibling_key in self.directory_contents:
for item in self.directory_contents[sibling_key]:
temp_items.append(item)
content_items = random.sample(temp_items, 10)
i = 1
for item in content_items:
if isinstance(item, SongFile):
if i % 10 == 0 and i != 0:
back_dir = Directory(self.current_dir.parent, "", 17, back=True)
self.items.insert(self.selected_index+i, back_dir)
i += 1
if not has_children:
if selected_item is not None:
item.box.texture_index = selected_item.box.texture_index
self.items.insert(self.selected_index+i, item)
else:
self.items.append(item)
i += 1
if not has_children:
self.box_open = True
end_box = content_items[-1].box
if selected_item in self.items:
self.items.remove(selected_item)
# OPTIMIZED: Use cached crowns (calculated on-demand)
for item in self.items:
if isinstance(item, Directory):
item_key = str(item.path)
if item_key in self.directory_contents: # Only for real directories
item.box.crown = self._get_directory_crowns_cached(item_key)
else:
# Navigation items (back/to_root)
item.box.crown = dict()
self.calculate_box_positions()
if (not has_children and start_box is not None
and end_box is not None and selected_item is not None
and selected_item.box.hori_name is not None):
hori_name = selected_item.box.hori_name
diff_sort = None
if selected_item.collection == Directory.COLLECTIONS[3]:
diff_sort = self.diff_sort_level
diffs = ['かんたん', 'ふつう', 'むずかしい', 'おに']
hori_name = OutlinedText(diffs[min(3, self.diff_sort_diff)], 40, ray.WHITE, ray.BLACK, outline_thickness=5)
self.genre_bg = GenreBG(start_box, end_box, hori_name, diff_sort)
def mark_crowns_dirty_for_song(self, song_file: SongFile): def mark_crowns_dirty_for_song(self, song_file: SongFile):
"""Mark directories as needing crown recalculation when a song's score changes""" """Mark directories as needing crown recalculation when a song's score changes"""
song_path = song_file.path song_path = song_file.path
@@ -1736,45 +1804,6 @@ class FileNavigator:
self.selected_index = (self.selected_index + 1) % len(self.items) self.selected_index = (self.selected_index + 1) % len(self.items)
self.calculate_box_positions() self.calculate_box_positions()
def select_current_item(self):
"""Select the currently highlighted item"""
if not self.items or self.selected_index >= len(self.items):
return
selected_item = self.items[self.selected_index]
if isinstance(selected_item, Directory):
if self.box_open:
self.go_back()
if selected_item.to_root:
self.load_root_directories()
else:
# Save current state to history
if self.current_dir is not None:
self.history.append((self.current_dir, self.selected_index, self.in_root_selection, self.current_root_dir))
self.current_dir = selected_item.path
if self.in_root_selection:
self.current_root_dir = selected_item.path
self.in_root_selection = False
self.load_current_directory(selected_item=selected_item)
elif isinstance(selected_item, SongFile):
return selected_item
def go_back(self):
"""Navigate back to the previous directory"""
if self.history:
previous_dir, previous_index, previous_in_root, previous_root_dir = self.history.pop()
self.current_dir = previous_dir
self.selected_index = previous_index
self.in_root_selection = previous_in_root
self.current_root_dir = previous_root_dir
if self.in_root_selection:
self.load_root_directories()
else:
self.load_current_directory()
self.box_open = False
def get_current_item(self): def get_current_item(self):
"""Get the currently selected item""" """Get the currently selected item"""
if self.items and 0 <= self.selected_index < len(self.items): if self.items and 0 <= self.selected_index < len(self.items):