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            claims_tab=True,
 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            claims_tab=True,
 75            selection_loops_to_parent=True,
 76        )
 77
 78        bui.textwidget(
 79            parent=self._column,
 80            size=(self._width - 80, 22),
 81            text=bui.Lstr(resource=f'{self._r}.fetchingITunesText'),
 82            color=(0.6, 0.9, 0.6, 1.0),
 83            scale=0.8,
 84        )
 85        assert bui.app.classic is not None
 86        musicplayer = bui.app.classic.music.get_music_player()
 87        assert isinstance(musicplayer, MacMusicAppMusicPlayer)
 88        musicplayer.get_playlists(self._playlists_cb)
 89        bui.containerwidget(
 90            edit=self._root_widget, selected_child=self._scrollwidget
 91        )
 92
 93    @override
 94    def get_main_window_state(self) -> bui.MainWindowState:
 95        # Support recreating our window for back/refresh purposes.
 96        cls = type(self)
 97
 98        # Pull stuff out of self here; if we do it in the lambda we wind
 99        # up keeping self alive which we don't want.
100        callback = self._callback
101        existing_playlist = self._existing_playlist
102        existing_entry = self._existing_entry
103
104        return bui.BasicMainWindowState(
105            create_call=lambda transition, origin_widget: cls(
106                callback=callback,
107                existing_playlist=existing_playlist,
108                existing_entry=existing_entry,
109                transition=transition,
110                origin_widget=origin_widget,
111            )
112        )
113
114    def _playlists_cb(self, playlists: list[str]) -> None:
115        if self._column:
116            for widget in self._column.get_children():
117                widget.delete()
118            for i, playlist in enumerate(playlists):
119                txt = bui.textwidget(
120                    parent=self._column,
121                    size=(self._width - 80, 30),
122                    text=playlist,
123                    v_align='center',
124                    maxwidth=self._width - 110,
125                    selectable=True,
126                    on_activate_call=bui.Call(self._sel, playlist),
127                    click_activate=True,
128                )
129                bui.widget(edit=txt, show_buffer_top=40, show_buffer_bottom=40)
130                if playlist == self._existing_playlist:
131                    bui.columnwidget(
132                        edit=self._column, selected_child=txt, visible_child=txt
133                    )
134                if i == len(playlists) - 1:
135                    bui.widget(edit=txt, down_widget=txt)
136
137    def _sel(self, selection: str) -> None:
138        if self._root_widget:
139            # bui.containerwidget(
140            # edit=self._root_widget, transition='out_right')
141            self._callback({'type': 'iTunesPlaylist', 'name': selection})
142            self.main_window_back()
143
144    def _back(self) -> None:
145        # bui.containerwidget(edit=self._root_widget, transition='out_right')
146        self.main_window_back()
147        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            claims_tab=True,
 70            selection_loops_to_parent=True,
 71        )
 72        bui.widget(edit=self._scrollwidget, right_widget=self._scrollwidget)
 73        self._column = bui.columnwidget(
 74            parent=self._scrollwidget,
 75            claims_tab=True,
 76            selection_loops_to_parent=True,
 77        )
 78
 79        bui.textwidget(
 80            parent=self._column,
 81            size=(self._width - 80, 22),
 82            text=bui.Lstr(resource=f'{self._r}.fetchingITunesText'),
 83            color=(0.6, 0.9, 0.6, 1.0),
 84            scale=0.8,
 85        )
 86        assert bui.app.classic is not None
 87        musicplayer = bui.app.classic.music.get_music_player()
 88        assert isinstance(musicplayer, MacMusicAppMusicPlayer)
 89        musicplayer.get_playlists(self._playlists_cb)
 90        bui.containerwidget(
 91            edit=self._root_widget, selected_child=self._scrollwidget
 92        )
 93
 94    @override
 95    def get_main_window_state(self) -> bui.MainWindowState:
 96        # Support recreating our window for back/refresh purposes.
 97        cls = type(self)
 98
 99        # Pull stuff out of self here; if we do it in the lambda we wind
100        # up keeping self alive which we don't want.
101        callback = self._callback
102        existing_playlist = self._existing_playlist
103        existing_entry = self._existing_entry
104
105        return bui.BasicMainWindowState(
106            create_call=lambda transition, origin_widget: cls(
107                callback=callback,
108                existing_playlist=existing_playlist,
109                existing_entry=existing_entry,
110                transition=transition,
111                origin_widget=origin_widget,
112            )
113        )
114
115    def _playlists_cb(self, playlists: list[str]) -> None:
116        if self._column:
117            for widget in self._column.get_children():
118                widget.delete()
119            for i, playlist in enumerate(playlists):
120                txt = bui.textwidget(
121                    parent=self._column,
122                    size=(self._width - 80, 30),
123                    text=playlist,
124                    v_align='center',
125                    maxwidth=self._width - 110,
126                    selectable=True,
127                    on_activate_call=bui.Call(self._sel, playlist),
128                    click_activate=True,
129                )
130                bui.widget(edit=txt, show_buffer_top=40, show_buffer_bottom=40)
131                if playlist == self._existing_playlist:
132                    bui.columnwidget(
133                        edit=self._column, selected_child=txt, visible_child=txt
134                    )
135                if i == len(playlists) - 1:
136                    bui.widget(edit=txt, down_widget=txt)
137
138    def _sel(self, selection: str) -> None:
139        if self._root_widget:
140            # bui.containerwidget(
141            # edit=self._root_widget, transition='out_right')
142            self._callback({'type': 'iTunesPlaylist', 'name': selection})
143            self.main_window_back()
144
145    def _back(self) -> None:
146        # bui.containerwidget(edit=self._root_widget, transition='out_right')
147        self.main_window_back()
148        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            claims_tab=True,
70            selection_loops_to_parent=True,
71        )
72        bui.widget(edit=self._scrollwidget, right_widget=self._scrollwidget)
73        self._column = bui.columnwidget(
74            parent=self._scrollwidget,
75            claims_tab=True,
76            selection_loops_to_parent=True,
77        )
78
79        bui.textwidget(
80            parent=self._column,
81            size=(self._width - 80, 22),
82            text=bui.Lstr(resource=f'{self._r}.fetchingITunesText'),
83            color=(0.6, 0.9, 0.6, 1.0),
84            scale=0.8,
85        )
86        assert bui.app.classic is not None
87        musicplayer = bui.app.classic.music.get_music_player()
88        assert isinstance(musicplayer, MacMusicAppMusicPlayer)
89        musicplayer.get_playlists(self._playlists_cb)
90        bui.containerwidget(
91            edit=self._root_widget, selected_child=self._scrollwidget
92        )

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

Return a WindowState to recreate this window, if supported.