Source code for bauiv1lib.soundtrack.macmusicapp

# Released under the MIT License. See LICENSE for details.
#
"""UI functionality related to using the macOS Music app for soundtracks."""

from __future__ import annotations

import copy
from typing import TYPE_CHECKING, override

import bauiv1 as bui

if TYPE_CHECKING:
    from typing import Any, Callable


[docs] class MacMusicAppPlaylistSelectWindow(bui.MainWindow): """Window for selecting an iTunes playlist.""" def __init__( self, callback: Callable[[Any], Any], existing_playlist: str | None, existing_entry: Any, *, transition: str | None = 'in_right', origin_widget: bui.Widget | None = None, ): from baclassic.macmusicapp import MacMusicAppMusicPlayer self._r = 'editSoundtrackWindow' self._callback = callback self._existing_playlist = existing_playlist self._existing_entry = copy.deepcopy(existing_entry) self._width = 520.0 self._height = 520.0 self._spacing = 45.0 v = self._height - 90.0 v -= self._spacing * 1.0 super().__init__( root_widget=bui.containerwidget(size=(self._width, self._height)), transition=transition, origin_widget=origin_widget, ) btn = bui.buttonwidget( parent=self._root_widget, position=(35, self._height - 65), size=(130, 50), label=bui.Lstr(resource='cancelText'), on_activate_call=self._back, autoselect=True, ) bui.containerwidget(edit=self._root_widget, cancel_button=btn) assert bui.app.classic is not None bui.textwidget( parent=self._root_widget, position=(20, self._height - 54), size=(self._width, 25), text=bui.Lstr(resource=f'{self._r}.selectAPlaylistText'), color=bui.app.ui_v1.title_color, h_align='center', v_align='center', maxwidth=200, ) self._scrollwidget = bui.scrollwidget( parent=self._root_widget, position=(40, v - 340), size=(self._width - 80, 400), selection_loops_to_parent=True, ) bui.widget(edit=self._scrollwidget, right_widget=self._scrollwidget) self._column = bui.columnwidget( parent=self._scrollwidget, selection_loops_to_parent=True, ) bui.textwidget( parent=self._column, size=(self._width - 80, 22), text=bui.Lstr(resource=f'{self._r}.fetchingITunesText'), color=(0.6, 0.9, 0.6, 1.0), scale=0.8, ) assert bui.app.classic is not None musicplayer = bui.app.classic.music.get_music_player() assert isinstance(musicplayer, MacMusicAppMusicPlayer) musicplayer.get_playlists(self._playlists_cb) bui.containerwidget( edit=self._root_widget, selected_child=self._scrollwidget )
[docs] @override def get_main_window_state(self) -> bui.MainWindowState: # Support recreating our window for back/refresh purposes. cls = type(self) # Pull stuff out of self here; if we do it in the lambda we wind # up keeping self alive which we don't want. callback = self._callback existing_playlist = self._existing_playlist existing_entry = self._existing_entry return bui.BasicMainWindowState( create_call=lambda transition, origin_widget: cls( callback=callback, existing_playlist=existing_playlist, existing_entry=existing_entry, transition=transition, origin_widget=origin_widget, ) )
def _playlists_cb(self, playlists: list[str]) -> None: if self._column: for widget in self._column.get_children(): widget.delete() for i, playlist in enumerate(playlists): txt = bui.textwidget( parent=self._column, size=(self._width - 80, 30), text=playlist, v_align='center', maxwidth=self._width - 110, selectable=True, on_activate_call=bui.Call(self._sel, playlist), click_activate=True, ) bui.widget(edit=txt, show_buffer_top=40, show_buffer_bottom=40) if playlist == self._existing_playlist: bui.columnwidget( edit=self._column, selected_child=txt, visible_child=txt ) if i == len(playlists) - 1: bui.widget(edit=txt, down_widget=txt) def _sel(self, selection: str) -> None: if self._root_widget: # bui.containerwidget( # edit=self._root_widget, transition='out_right') self._callback({'type': 'iTunesPlaylist', 'name': selection}) self.main_window_back() def _back(self) -> None: # bui.containerwidget(edit=self._root_widget, transition='out_right') self.main_window_back() self._callback(self._existing_entry)
# Docs-generation hack; import some stuff that we likely only forward-declared # in our actual source code so that docs tools can find it. from typing import (Coroutine, Any, Literal, Callable, Generator, Awaitable, Sequence, Self) import asyncio from concurrent.futures import Future from pathlib import Path from enum import Enum