bauiv1lib.soundtrack.macmusicapp

UI functionality related to using the macOS Music app for soundtracks.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""UI functionality related to using the macOS Music app for soundtracks."""
  4
  5from __future__ import annotations
  6
  7import copy
  8from typing import TYPE_CHECKING, override
  9
 10import bauiv1 as bui
 11
 12if TYPE_CHECKING:
 13    from typing import Any, Callable
 14
 15
 16class MacMusicAppPlaylistSelectWindow(bui.MainWindow):
 17    """Window for selecting an iTunes playlist."""
 18
 19    def __init__(
 20        self,
 21        callback: Callable[[Any], Any],
 22        existing_playlist: str | None,
 23        existing_entry: Any,
 24        *,
 25        transition: str | None = 'in_right',
 26        origin_widget: bui.Widget | None = None,
 27    ):
 28        from baclassic.macmusicapp import MacMusicAppMusicPlayer
 29
 30        self._r = 'editSoundtrackWindow'
 31        self._callback = callback
 32        self._existing_playlist = existing_playlist
 33        self._existing_entry = copy.deepcopy(existing_entry)
 34        self._width = 520.0
 35        self._height = 520.0
 36        self._spacing = 45.0
 37        v = self._height - 90.0
 38        v -= self._spacing * 1.0
 39        super().__init__(
 40            root_widget=bui.containerwidget(size=(self._width, self._height)),
 41            transition=transition,
 42            origin_widget=origin_widget,
 43        )
 44        btn = bui.buttonwidget(
 45            parent=self._root_widget,
 46            position=(35, self._height - 65),
 47            size=(130, 50),
 48            label=bui.Lstr(resource='cancelText'),
 49            on_activate_call=self._back,
 50            autoselect=True,
 51        )
 52        bui.containerwidget(edit=self._root_widget, cancel_button=btn)
 53        assert bui.app.classic is not None
 54        bui.textwidget(
 55            parent=self._root_widget,
 56            position=(20, self._height - 54),
 57            size=(self._width, 25),
 58            text=bui.Lstr(resource=f'{self._r}.selectAPlaylistText'),
 59            color=bui.app.ui_v1.title_color,
 60            h_align='center',
 61            v_align='center',
 62            maxwidth=200,
 63        )
 64        self._scrollwidget = bui.scrollwidget(
 65            parent=self._root_widget,
 66            position=(40, v - 340),
 67            size=(self._width - 80, 400),
 68            selection_loops_to_parent=True,
 69        )
 70        bui.widget(edit=self._scrollwidget, right_widget=self._scrollwidget)
 71        self._column = bui.columnwidget(
 72            parent=self._scrollwidget,
 73            selection_loops_to_parent=True,
 74        )
 75
 76        bui.textwidget(
 77            parent=self._column,
 78            size=(self._width - 80, 22),
 79            text=bui.Lstr(resource=f'{self._r}.fetchingITunesText'),
 80            color=(0.6, 0.9, 0.6, 1.0),
 81            scale=0.8,
 82        )
 83        assert bui.app.classic is not None
 84        musicplayer = bui.app.classic.music.get_music_player()
 85        assert isinstance(musicplayer, MacMusicAppMusicPlayer)
 86        musicplayer.get_playlists(self._playlists_cb)
 87        bui.containerwidget(
 88            edit=self._root_widget, selected_child=self._scrollwidget
 89        )
 90
 91    @override
 92    def get_main_window_state(self) -> bui.MainWindowState:
 93        # Support recreating our window for back/refresh purposes.
 94        cls = type(self)
 95
 96        # Pull stuff out of self here; if we do it in the lambda we wind
 97        # up keeping self alive which we don't want.
 98        callback = self._callback
 99        existing_playlist = self._existing_playlist
100        existing_entry = self._existing_entry
101
102        return bui.BasicMainWindowState(
103            create_call=lambda transition, origin_widget: cls(
104                callback=callback,
105                existing_playlist=existing_playlist,
106                existing_entry=existing_entry,
107                transition=transition,
108                origin_widget=origin_widget,
109            )
110        )
111
112    def _playlists_cb(self, playlists: list[str]) -> None:
113        if self._column:
114            for widget in self._column.get_children():
115                widget.delete()
116            for i, playlist in enumerate(playlists):
117                txt = bui.textwidget(
118                    parent=self._column,
119                    size=(self._width - 80, 30),
120                    text=playlist,
121                    v_align='center',
122                    maxwidth=self._width - 110,
123                    selectable=True,
124                    on_activate_call=bui.Call(self._sel, playlist),
125                    click_activate=True,
126                )
127                bui.widget(edit=txt, show_buffer_top=40, show_buffer_bottom=40)
128                if playlist == self._existing_playlist:
129                    bui.columnwidget(
130                        edit=self._column, selected_child=txt, visible_child=txt
131                    )
132                if i == len(playlists) - 1:
133                    bui.widget(edit=txt, down_widget=txt)
134
135    def _sel(self, selection: str) -> None:
136        if self._root_widget:
137            # bui.containerwidget(
138            # edit=self._root_widget, transition='out_right')
139            self._callback({'type': 'iTunesPlaylist', 'name': selection})
140            self.main_window_back()
141
142    def _back(self) -> None:
143        # bui.containerwidget(edit=self._root_widget, transition='out_right')
144        self.main_window_back()
145        self._callback(self._existing_entry)
class MacMusicAppPlaylistSelectWindow(bauiv1._uitypes.MainWindow):
 17class MacMusicAppPlaylistSelectWindow(bui.MainWindow):
 18    """Window for selecting an iTunes playlist."""
 19
 20    def __init__(
 21        self,
 22        callback: Callable[[Any], Any],
 23        existing_playlist: str | None,
 24        existing_entry: Any,
 25        *,
 26        transition: str | None = 'in_right',
 27        origin_widget: bui.Widget | None = None,
 28    ):
 29        from baclassic.macmusicapp import MacMusicAppMusicPlayer
 30
 31        self._r = 'editSoundtrackWindow'
 32        self._callback = callback
 33        self._existing_playlist = existing_playlist
 34        self._existing_entry = copy.deepcopy(existing_entry)
 35        self._width = 520.0
 36        self._height = 520.0
 37        self._spacing = 45.0
 38        v = self._height - 90.0
 39        v -= self._spacing * 1.0
 40        super().__init__(
 41            root_widget=bui.containerwidget(size=(self._width, self._height)),
 42            transition=transition,
 43            origin_widget=origin_widget,
 44        )
 45        btn = bui.buttonwidget(
 46            parent=self._root_widget,
 47            position=(35, self._height - 65),
 48            size=(130, 50),
 49            label=bui.Lstr(resource='cancelText'),
 50            on_activate_call=self._back,
 51            autoselect=True,
 52        )
 53        bui.containerwidget(edit=self._root_widget, cancel_button=btn)
 54        assert bui.app.classic is not None
 55        bui.textwidget(
 56            parent=self._root_widget,
 57            position=(20, self._height - 54),
 58            size=(self._width, 25),
 59            text=bui.Lstr(resource=f'{self._r}.selectAPlaylistText'),
 60            color=bui.app.ui_v1.title_color,
 61            h_align='center',
 62            v_align='center',
 63            maxwidth=200,
 64        )
 65        self._scrollwidget = bui.scrollwidget(
 66            parent=self._root_widget,
 67            position=(40, v - 340),
 68            size=(self._width - 80, 400),
 69            selection_loops_to_parent=True,
 70        )
 71        bui.widget(edit=self._scrollwidget, right_widget=self._scrollwidget)
 72        self._column = bui.columnwidget(
 73            parent=self._scrollwidget,
 74            selection_loops_to_parent=True,
 75        )
 76
 77        bui.textwidget(
 78            parent=self._column,
 79            size=(self._width - 80, 22),
 80            text=bui.Lstr(resource=f'{self._r}.fetchingITunesText'),
 81            color=(0.6, 0.9, 0.6, 1.0),
 82            scale=0.8,
 83        )
 84        assert bui.app.classic is not None
 85        musicplayer = bui.app.classic.music.get_music_player()
 86        assert isinstance(musicplayer, MacMusicAppMusicPlayer)
 87        musicplayer.get_playlists(self._playlists_cb)
 88        bui.containerwidget(
 89            edit=self._root_widget, selected_child=self._scrollwidget
 90        )
 91
 92    @override
 93    def get_main_window_state(self) -> bui.MainWindowState:
 94        # Support recreating our window for back/refresh purposes.
 95        cls = type(self)
 96
 97        # Pull stuff out of self here; if we do it in the lambda we wind
 98        # up keeping self alive which we don't want.
 99        callback = self._callback
100        existing_playlist = self._existing_playlist
101        existing_entry = self._existing_entry
102
103        return bui.BasicMainWindowState(
104            create_call=lambda transition, origin_widget: cls(
105                callback=callback,
106                existing_playlist=existing_playlist,
107                existing_entry=existing_entry,
108                transition=transition,
109                origin_widget=origin_widget,
110            )
111        )
112
113    def _playlists_cb(self, playlists: list[str]) -> None:
114        if self._column:
115            for widget in self._column.get_children():
116                widget.delete()
117            for i, playlist in enumerate(playlists):
118                txt = bui.textwidget(
119                    parent=self._column,
120                    size=(self._width - 80, 30),
121                    text=playlist,
122                    v_align='center',
123                    maxwidth=self._width - 110,
124                    selectable=True,
125                    on_activate_call=bui.Call(self._sel, playlist),
126                    click_activate=True,
127                )
128                bui.widget(edit=txt, show_buffer_top=40, show_buffer_bottom=40)
129                if playlist == self._existing_playlist:
130                    bui.columnwidget(
131                        edit=self._column, selected_child=txt, visible_child=txt
132                    )
133                if i == len(playlists) - 1:
134                    bui.widget(edit=txt, down_widget=txt)
135
136    def _sel(self, selection: str) -> None:
137        if self._root_widget:
138            # bui.containerwidget(
139            # edit=self._root_widget, transition='out_right')
140            self._callback({'type': 'iTunesPlaylist', 'name': selection})
141            self.main_window_back()
142
143    def _back(self) -> None:
144        # bui.containerwidget(edit=self._root_widget, transition='out_right')
145        self.main_window_back()
146        self._callback(self._existing_entry)

Window for selecting an iTunes playlist.

MacMusicAppPlaylistSelectWindow( callback: Callable[[Any], Any], existing_playlist: str | None, existing_entry: Any, *, transition: str | None = 'in_right', origin_widget: _bauiv1.Widget | None = None)
20    def __init__(
21        self,
22        callback: Callable[[Any], Any],
23        existing_playlist: str | None,
24        existing_entry: Any,
25        *,
26        transition: str | None = 'in_right',
27        origin_widget: bui.Widget | None = None,
28    ):
29        from baclassic.macmusicapp import MacMusicAppMusicPlayer
30
31        self._r = 'editSoundtrackWindow'
32        self._callback = callback
33        self._existing_playlist = existing_playlist
34        self._existing_entry = copy.deepcopy(existing_entry)
35        self._width = 520.0
36        self._height = 520.0
37        self._spacing = 45.0
38        v = self._height - 90.0
39        v -= self._spacing * 1.0
40        super().__init__(
41            root_widget=bui.containerwidget(size=(self._width, self._height)),
42            transition=transition,
43            origin_widget=origin_widget,
44        )
45        btn = bui.buttonwidget(
46            parent=self._root_widget,
47            position=(35, self._height - 65),
48            size=(130, 50),
49            label=bui.Lstr(resource='cancelText'),
50            on_activate_call=self._back,
51            autoselect=True,
52        )
53        bui.containerwidget(edit=self._root_widget, cancel_button=btn)
54        assert bui.app.classic is not None
55        bui.textwidget(
56            parent=self._root_widget,
57            position=(20, self._height - 54),
58            size=(self._width, 25),
59            text=bui.Lstr(resource=f'{self._r}.selectAPlaylistText'),
60            color=bui.app.ui_v1.title_color,
61            h_align='center',
62            v_align='center',
63            maxwidth=200,
64        )
65        self._scrollwidget = bui.scrollwidget(
66            parent=self._root_widget,
67            position=(40, v - 340),
68            size=(self._width - 80, 400),
69            selection_loops_to_parent=True,
70        )
71        bui.widget(edit=self._scrollwidget, right_widget=self._scrollwidget)
72        self._column = bui.columnwidget(
73            parent=self._scrollwidget,
74            selection_loops_to_parent=True,
75        )
76
77        bui.textwidget(
78            parent=self._column,
79            size=(self._width - 80, 22),
80            text=bui.Lstr(resource=f'{self._r}.fetchingITunesText'),
81            color=(0.6, 0.9, 0.6, 1.0),
82            scale=0.8,
83        )
84        assert bui.app.classic is not None
85        musicplayer = bui.app.classic.music.get_music_player()
86        assert isinstance(musicplayer, MacMusicAppMusicPlayer)
87        musicplayer.get_playlists(self._playlists_cb)
88        bui.containerwidget(
89            edit=self._root_widget, selected_child=self._scrollwidget
90        )

Create a MainWindow given a root widget and transition info.

Automatically handles in and out transitions on the provided widget, so there is no need to set transitions when creating it.

@override
def get_main_window_state(self) -> bauiv1.MainWindowState:
 92    @override
 93    def get_main_window_state(self) -> bui.MainWindowState:
 94        # Support recreating our window for back/refresh purposes.
 95        cls = type(self)
 96
 97        # Pull stuff out of self here; if we do it in the lambda we wind
 98        # up keeping self alive which we don't want.
 99        callback = self._callback
100        existing_playlist = self._existing_playlist
101        existing_entry = self._existing_entry
102
103        return bui.BasicMainWindowState(
104            create_call=lambda transition, origin_widget: cls(
105                callback=callback,
106                existing_playlist=existing_playlist,
107                existing_entry=existing_entry,
108                transition=transition,
109                origin_widget=origin_widget,
110            )
111        )

Return a WindowState to recreate this window, if supported.