bauiv1lib.soundtrack.entrytypeselect
Provides UI for selecting soundtrack entry types.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Provides UI for selecting soundtrack entry types.""" 4from __future__ import annotations 5 6import copy 7from typing import TYPE_CHECKING, override 8 9import bauiv1 as bui 10 11if TYPE_CHECKING: 12 from typing import Any, Callable 13 14 15class SoundtrackEntryTypeSelectWindow(bui.MainWindow): 16 """Window for selecting a soundtrack entry type.""" 17 18 def __init__( 19 self, 20 callback: Callable[[Any], Any], 21 current_entry: Any, 22 selection_target_name: str, 23 transition: str | None = 'in_right', 24 origin_widget: bui.Widget | None = None, 25 ): 26 # pylint: disable=too-many-locals 27 assert bui.app.classic is not None 28 music = bui.app.classic.music 29 self._r = 'editSoundtrackWindow' 30 31 self._selection_target_name = selection_target_name 32 self._callback = callback 33 self._current_entry = copy.deepcopy(current_entry) 34 35 self._width = 580 36 self._height = 220 37 spacing = 80 38 39 # FIXME: Generalize this so new custom soundtrack types can add 40 # themselves here. 41 do_default = True 42 do_mac_music_app_playlist = music.supports_soundtrack_entry_type( 43 'iTunesPlaylist' 44 ) 45 do_music_file = music.supports_soundtrack_entry_type('musicFile') 46 do_music_folder = music.supports_soundtrack_entry_type('musicFolder') 47 48 if do_mac_music_app_playlist: 49 self._height += spacing 50 if do_music_file: 51 self._height += spacing 52 if do_music_folder: 53 self._height += spacing 54 55 uiscale = bui.app.ui_v1.uiscale 56 57 # NOTE: When something is selected, we close our UI and kick off 58 # another window which then calls us back when its done, so the 59 # standard UI-cleanup-check complains that something is holding 60 # on to our instance after its ui is gone. Should restructure in 61 # a cleaner way, but just disabling that check for now. 62 super().__init__( 63 root_widget=bui.containerwidget( 64 size=(self._width, self._height), 65 scale=( 66 1.7 67 if uiscale is bui.UIScale.SMALL 68 else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0 69 ), 70 ), 71 cleanupcheck=False, 72 transition=transition, 73 origin_widget=origin_widget, 74 ) 75 btn = bui.buttonwidget( 76 parent=self._root_widget, 77 position=(35, self._height - 65), 78 size=(160, 60), 79 scale=0.8, 80 text_scale=1.2, 81 label=bui.Lstr(resource='cancelText'), 82 on_activate_call=self._on_cancel_press, 83 ) 84 bui.containerwidget(edit=self._root_widget, cancel_button=btn) 85 bui.textwidget( 86 parent=self._root_widget, 87 position=(self._width * 0.5, self._height - 32), 88 size=(0, 0), 89 text=bui.Lstr(resource=f'{self._r}.selectASourceText'), 90 color=bui.app.ui_v1.title_color, 91 maxwidth=230, 92 h_align='center', 93 v_align='center', 94 ) 95 96 bui.textwidget( 97 parent=self._root_widget, 98 position=(self._width * 0.5, self._height - 56), 99 size=(0, 0), 100 text=selection_target_name, 101 color=bui.app.ui_v1.infotextcolor, 102 scale=0.7, 103 maxwidth=230, 104 h_align='center', 105 v_align='center', 106 ) 107 108 v = self._height - 155 109 110 current_entry_type = music.get_soundtrack_entry_type(current_entry) 111 112 if do_default: 113 btn = bui.buttonwidget( 114 parent=self._root_widget, 115 size=(self._width - 100, 60), 116 position=(50, v), 117 label=bui.Lstr(resource=f'{self._r}.useDefaultGameMusicText'), 118 on_activate_call=self._on_default_press, 119 ) 120 if current_entry_type == 'default': 121 bui.containerwidget(edit=self._root_widget, selected_child=btn) 122 v -= spacing 123 124 if do_mac_music_app_playlist: 125 btn = bui.buttonwidget( 126 parent=self._root_widget, 127 size=(self._width - 100, 60), 128 position=(50, v), 129 label=bui.Lstr(resource=f'{self._r}.useITunesPlaylistText'), 130 on_activate_call=self._on_mac_music_app_playlist_press, 131 icon=None, 132 ) 133 if current_entry_type == 'iTunesPlaylist': 134 bui.containerwidget(edit=self._root_widget, selected_child=btn) 135 v -= spacing 136 137 if do_music_file: 138 btn = bui.buttonwidget( 139 parent=self._root_widget, 140 size=(self._width - 100, 60), 141 position=(50, v), 142 label=bui.Lstr(resource=f'{self._r}.useMusicFileText'), 143 on_activate_call=self._on_music_file_press, 144 icon=bui.gettexture('file'), 145 ) 146 if current_entry_type == 'musicFile': 147 bui.containerwidget(edit=self._root_widget, selected_child=btn) 148 v -= spacing 149 150 if do_music_folder: 151 btn = bui.buttonwidget( 152 parent=self._root_widget, 153 size=(self._width - 100, 60), 154 position=(50, v), 155 label=bui.Lstr(resource=f'{self._r}.useMusicFolderText'), 156 on_activate_call=self._on_music_folder_press, 157 icon=bui.gettexture('folder'), 158 icon_color=(1.1, 0.8, 0.2), 159 ) 160 if current_entry_type == 'musicFolder': 161 bui.containerwidget(edit=self._root_widget, selected_child=btn) 162 v -= spacing 163 164 @override 165 def get_main_window_state(self) -> bui.MainWindowState: 166 # Support recreating our window for back/refresh purposes. 167 cls = type(self) 168 169 # Pull these out of self here; if we reference self in the 170 # lambda we'll keep our window alive which is bad. 171 current_entry = self._current_entry 172 callback = self._callback 173 selection_target_name = self._selection_target_name 174 175 return bui.BasicMainWindowState( 176 create_call=lambda transition, origin_widget: cls( 177 transition=transition, 178 origin_widget=origin_widget, 179 current_entry=current_entry, 180 callback=callback, 181 selection_target_name=selection_target_name, 182 ) 183 ) 184 185 def _on_mac_music_app_playlist_press(self) -> None: 186 assert bui.app.classic is not None 187 music = bui.app.classic.music 188 from bauiv1lib.soundtrack.macmusicapp import ( 189 MacMusicAppPlaylistSelectWindow, 190 ) 191 192 # no-op if we're not in control. 193 if not self.main_window_has_control(): 194 return 195 196 current_playlist_entry: str | None 197 if ( 198 music.get_soundtrack_entry_type(self._current_entry) 199 == 'iTunesPlaylist' 200 ): 201 current_playlist_entry = music.get_soundtrack_entry_name( 202 self._current_entry 203 ) 204 else: 205 current_playlist_entry = None 206 207 self.main_window_replace( 208 MacMusicAppPlaylistSelectWindow( 209 self._callback, current_playlist_entry, self._current_entry 210 ) 211 ) 212 213 def _on_music_file_press(self) -> None: 214 from babase import android_get_external_files_dir 215 from baclassic.osmusic import OSMusicPlayer 216 from bauiv1lib.fileselector import FileSelectorWindow 217 218 # no-op if we're not in control. 219 if not self.main_window_has_control(): 220 return 221 222 base_path = android_get_external_files_dir() 223 assert bui.app.classic is not None 224 225 self.main_window_replace( 226 FileSelectorWindow( 227 base_path, 228 callback=self._music_file_selector_cb, 229 show_base_path=False, 230 valid_file_extensions=( 231 OSMusicPlayer.get_valid_music_file_extensions() 232 ), 233 allow_folders=False, 234 ), 235 ) 236 237 def _on_music_folder_press(self) -> None: 238 from bauiv1lib.fileselector import FileSelectorWindow 239 from babase import android_get_external_files_dir 240 241 # no-op if we're not in control. 242 if not self.main_window_has_control(): 243 return 244 245 base_path = android_get_external_files_dir() 246 assert bui.app.classic is not None 247 248 self.main_window_replace( 249 FileSelectorWindow( 250 base_path, 251 callback=self._music_folder_selector_cb, 252 show_base_path=False, 253 valid_file_extensions=[], 254 allow_folders=True, 255 ), 256 ) 257 258 def _music_file_selector_cb(self, result: str | None) -> None: 259 if result is None: 260 self._callback(self._current_entry) 261 else: 262 self._callback({'type': 'musicFile', 'name': result}) 263 264 def _music_folder_selector_cb(self, result: str | None) -> None: 265 if result is None: 266 self._callback(self._current_entry) 267 else: 268 self._callback({'type': 'musicFolder', 'name': result}) 269 270 def _on_default_press(self) -> None: 271 self.main_window_back() 272 self._callback(None) 273 274 def _on_cancel_press(self) -> None: 275 self.main_window_back() 276 self._callback(self._current_entry)
class
SoundtrackEntryTypeSelectWindow(bauiv1._uitypes.MainWindow):
16class SoundtrackEntryTypeSelectWindow(bui.MainWindow): 17 """Window for selecting a soundtrack entry type.""" 18 19 def __init__( 20 self, 21 callback: Callable[[Any], Any], 22 current_entry: Any, 23 selection_target_name: str, 24 transition: str | None = 'in_right', 25 origin_widget: bui.Widget | None = None, 26 ): 27 # pylint: disable=too-many-locals 28 assert bui.app.classic is not None 29 music = bui.app.classic.music 30 self._r = 'editSoundtrackWindow' 31 32 self._selection_target_name = selection_target_name 33 self._callback = callback 34 self._current_entry = copy.deepcopy(current_entry) 35 36 self._width = 580 37 self._height = 220 38 spacing = 80 39 40 # FIXME: Generalize this so new custom soundtrack types can add 41 # themselves here. 42 do_default = True 43 do_mac_music_app_playlist = music.supports_soundtrack_entry_type( 44 'iTunesPlaylist' 45 ) 46 do_music_file = music.supports_soundtrack_entry_type('musicFile') 47 do_music_folder = music.supports_soundtrack_entry_type('musicFolder') 48 49 if do_mac_music_app_playlist: 50 self._height += spacing 51 if do_music_file: 52 self._height += spacing 53 if do_music_folder: 54 self._height += spacing 55 56 uiscale = bui.app.ui_v1.uiscale 57 58 # NOTE: When something is selected, we close our UI and kick off 59 # another window which then calls us back when its done, so the 60 # standard UI-cleanup-check complains that something is holding 61 # on to our instance after its ui is gone. Should restructure in 62 # a cleaner way, but just disabling that check for now. 63 super().__init__( 64 root_widget=bui.containerwidget( 65 size=(self._width, self._height), 66 scale=( 67 1.7 68 if uiscale is bui.UIScale.SMALL 69 else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0 70 ), 71 ), 72 cleanupcheck=False, 73 transition=transition, 74 origin_widget=origin_widget, 75 ) 76 btn = bui.buttonwidget( 77 parent=self._root_widget, 78 position=(35, self._height - 65), 79 size=(160, 60), 80 scale=0.8, 81 text_scale=1.2, 82 label=bui.Lstr(resource='cancelText'), 83 on_activate_call=self._on_cancel_press, 84 ) 85 bui.containerwidget(edit=self._root_widget, cancel_button=btn) 86 bui.textwidget( 87 parent=self._root_widget, 88 position=(self._width * 0.5, self._height - 32), 89 size=(0, 0), 90 text=bui.Lstr(resource=f'{self._r}.selectASourceText'), 91 color=bui.app.ui_v1.title_color, 92 maxwidth=230, 93 h_align='center', 94 v_align='center', 95 ) 96 97 bui.textwidget( 98 parent=self._root_widget, 99 position=(self._width * 0.5, self._height - 56), 100 size=(0, 0), 101 text=selection_target_name, 102 color=bui.app.ui_v1.infotextcolor, 103 scale=0.7, 104 maxwidth=230, 105 h_align='center', 106 v_align='center', 107 ) 108 109 v = self._height - 155 110 111 current_entry_type = music.get_soundtrack_entry_type(current_entry) 112 113 if do_default: 114 btn = bui.buttonwidget( 115 parent=self._root_widget, 116 size=(self._width - 100, 60), 117 position=(50, v), 118 label=bui.Lstr(resource=f'{self._r}.useDefaultGameMusicText'), 119 on_activate_call=self._on_default_press, 120 ) 121 if current_entry_type == 'default': 122 bui.containerwidget(edit=self._root_widget, selected_child=btn) 123 v -= spacing 124 125 if do_mac_music_app_playlist: 126 btn = bui.buttonwidget( 127 parent=self._root_widget, 128 size=(self._width - 100, 60), 129 position=(50, v), 130 label=bui.Lstr(resource=f'{self._r}.useITunesPlaylistText'), 131 on_activate_call=self._on_mac_music_app_playlist_press, 132 icon=None, 133 ) 134 if current_entry_type == 'iTunesPlaylist': 135 bui.containerwidget(edit=self._root_widget, selected_child=btn) 136 v -= spacing 137 138 if do_music_file: 139 btn = bui.buttonwidget( 140 parent=self._root_widget, 141 size=(self._width - 100, 60), 142 position=(50, v), 143 label=bui.Lstr(resource=f'{self._r}.useMusicFileText'), 144 on_activate_call=self._on_music_file_press, 145 icon=bui.gettexture('file'), 146 ) 147 if current_entry_type == 'musicFile': 148 bui.containerwidget(edit=self._root_widget, selected_child=btn) 149 v -= spacing 150 151 if do_music_folder: 152 btn = bui.buttonwidget( 153 parent=self._root_widget, 154 size=(self._width - 100, 60), 155 position=(50, v), 156 label=bui.Lstr(resource=f'{self._r}.useMusicFolderText'), 157 on_activate_call=self._on_music_folder_press, 158 icon=bui.gettexture('folder'), 159 icon_color=(1.1, 0.8, 0.2), 160 ) 161 if current_entry_type == 'musicFolder': 162 bui.containerwidget(edit=self._root_widget, selected_child=btn) 163 v -= spacing 164 165 @override 166 def get_main_window_state(self) -> bui.MainWindowState: 167 # Support recreating our window for back/refresh purposes. 168 cls = type(self) 169 170 # Pull these out of self here; if we reference self in the 171 # lambda we'll keep our window alive which is bad. 172 current_entry = self._current_entry 173 callback = self._callback 174 selection_target_name = self._selection_target_name 175 176 return bui.BasicMainWindowState( 177 create_call=lambda transition, origin_widget: cls( 178 transition=transition, 179 origin_widget=origin_widget, 180 current_entry=current_entry, 181 callback=callback, 182 selection_target_name=selection_target_name, 183 ) 184 ) 185 186 def _on_mac_music_app_playlist_press(self) -> None: 187 assert bui.app.classic is not None 188 music = bui.app.classic.music 189 from bauiv1lib.soundtrack.macmusicapp import ( 190 MacMusicAppPlaylistSelectWindow, 191 ) 192 193 # no-op if we're not in control. 194 if not self.main_window_has_control(): 195 return 196 197 current_playlist_entry: str | None 198 if ( 199 music.get_soundtrack_entry_type(self._current_entry) 200 == 'iTunesPlaylist' 201 ): 202 current_playlist_entry = music.get_soundtrack_entry_name( 203 self._current_entry 204 ) 205 else: 206 current_playlist_entry = None 207 208 self.main_window_replace( 209 MacMusicAppPlaylistSelectWindow( 210 self._callback, current_playlist_entry, self._current_entry 211 ) 212 ) 213 214 def _on_music_file_press(self) -> None: 215 from babase import android_get_external_files_dir 216 from baclassic.osmusic import OSMusicPlayer 217 from bauiv1lib.fileselector import FileSelectorWindow 218 219 # no-op if we're not in control. 220 if not self.main_window_has_control(): 221 return 222 223 base_path = android_get_external_files_dir() 224 assert bui.app.classic is not None 225 226 self.main_window_replace( 227 FileSelectorWindow( 228 base_path, 229 callback=self._music_file_selector_cb, 230 show_base_path=False, 231 valid_file_extensions=( 232 OSMusicPlayer.get_valid_music_file_extensions() 233 ), 234 allow_folders=False, 235 ), 236 ) 237 238 def _on_music_folder_press(self) -> None: 239 from bauiv1lib.fileselector import FileSelectorWindow 240 from babase import android_get_external_files_dir 241 242 # no-op if we're not in control. 243 if not self.main_window_has_control(): 244 return 245 246 base_path = android_get_external_files_dir() 247 assert bui.app.classic is not None 248 249 self.main_window_replace( 250 FileSelectorWindow( 251 base_path, 252 callback=self._music_folder_selector_cb, 253 show_base_path=False, 254 valid_file_extensions=[], 255 allow_folders=True, 256 ), 257 ) 258 259 def _music_file_selector_cb(self, result: str | None) -> None: 260 if result is None: 261 self._callback(self._current_entry) 262 else: 263 self._callback({'type': 'musicFile', 'name': result}) 264 265 def _music_folder_selector_cb(self, result: str | None) -> None: 266 if result is None: 267 self._callback(self._current_entry) 268 else: 269 self._callback({'type': 'musicFolder', 'name': result}) 270 271 def _on_default_press(self) -> None: 272 self.main_window_back() 273 self._callback(None) 274 275 def _on_cancel_press(self) -> None: 276 self.main_window_back() 277 self._callback(self._current_entry)
Window for selecting a soundtrack entry type.
SoundtrackEntryTypeSelectWindow( callback: Callable[[Any], Any], current_entry: Any, selection_target_name: str, transition: str | None = 'in_right', origin_widget: _bauiv1.Widget | None = None)
19 def __init__( 20 self, 21 callback: Callable[[Any], Any], 22 current_entry: Any, 23 selection_target_name: str, 24 transition: str | None = 'in_right', 25 origin_widget: bui.Widget | None = None, 26 ): 27 # pylint: disable=too-many-locals 28 assert bui.app.classic is not None 29 music = bui.app.classic.music 30 self._r = 'editSoundtrackWindow' 31 32 self._selection_target_name = selection_target_name 33 self._callback = callback 34 self._current_entry = copy.deepcopy(current_entry) 35 36 self._width = 580 37 self._height = 220 38 spacing = 80 39 40 # FIXME: Generalize this so new custom soundtrack types can add 41 # themselves here. 42 do_default = True 43 do_mac_music_app_playlist = music.supports_soundtrack_entry_type( 44 'iTunesPlaylist' 45 ) 46 do_music_file = music.supports_soundtrack_entry_type('musicFile') 47 do_music_folder = music.supports_soundtrack_entry_type('musicFolder') 48 49 if do_mac_music_app_playlist: 50 self._height += spacing 51 if do_music_file: 52 self._height += spacing 53 if do_music_folder: 54 self._height += spacing 55 56 uiscale = bui.app.ui_v1.uiscale 57 58 # NOTE: When something is selected, we close our UI and kick off 59 # another window which then calls us back when its done, so the 60 # standard UI-cleanup-check complains that something is holding 61 # on to our instance after its ui is gone. Should restructure in 62 # a cleaner way, but just disabling that check for now. 63 super().__init__( 64 root_widget=bui.containerwidget( 65 size=(self._width, self._height), 66 scale=( 67 1.7 68 if uiscale is bui.UIScale.SMALL 69 else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0 70 ), 71 ), 72 cleanupcheck=False, 73 transition=transition, 74 origin_widget=origin_widget, 75 ) 76 btn = bui.buttonwidget( 77 parent=self._root_widget, 78 position=(35, self._height - 65), 79 size=(160, 60), 80 scale=0.8, 81 text_scale=1.2, 82 label=bui.Lstr(resource='cancelText'), 83 on_activate_call=self._on_cancel_press, 84 ) 85 bui.containerwidget(edit=self._root_widget, cancel_button=btn) 86 bui.textwidget( 87 parent=self._root_widget, 88 position=(self._width * 0.5, self._height - 32), 89 size=(0, 0), 90 text=bui.Lstr(resource=f'{self._r}.selectASourceText'), 91 color=bui.app.ui_v1.title_color, 92 maxwidth=230, 93 h_align='center', 94 v_align='center', 95 ) 96 97 bui.textwidget( 98 parent=self._root_widget, 99 position=(self._width * 0.5, self._height - 56), 100 size=(0, 0), 101 text=selection_target_name, 102 color=bui.app.ui_v1.infotextcolor, 103 scale=0.7, 104 maxwidth=230, 105 h_align='center', 106 v_align='center', 107 ) 108 109 v = self._height - 155 110 111 current_entry_type = music.get_soundtrack_entry_type(current_entry) 112 113 if do_default: 114 btn = bui.buttonwidget( 115 parent=self._root_widget, 116 size=(self._width - 100, 60), 117 position=(50, v), 118 label=bui.Lstr(resource=f'{self._r}.useDefaultGameMusicText'), 119 on_activate_call=self._on_default_press, 120 ) 121 if current_entry_type == 'default': 122 bui.containerwidget(edit=self._root_widget, selected_child=btn) 123 v -= spacing 124 125 if do_mac_music_app_playlist: 126 btn = bui.buttonwidget( 127 parent=self._root_widget, 128 size=(self._width - 100, 60), 129 position=(50, v), 130 label=bui.Lstr(resource=f'{self._r}.useITunesPlaylistText'), 131 on_activate_call=self._on_mac_music_app_playlist_press, 132 icon=None, 133 ) 134 if current_entry_type == 'iTunesPlaylist': 135 bui.containerwidget(edit=self._root_widget, selected_child=btn) 136 v -= spacing 137 138 if do_music_file: 139 btn = bui.buttonwidget( 140 parent=self._root_widget, 141 size=(self._width - 100, 60), 142 position=(50, v), 143 label=bui.Lstr(resource=f'{self._r}.useMusicFileText'), 144 on_activate_call=self._on_music_file_press, 145 icon=bui.gettexture('file'), 146 ) 147 if current_entry_type == 'musicFile': 148 bui.containerwidget(edit=self._root_widget, selected_child=btn) 149 v -= spacing 150 151 if do_music_folder: 152 btn = bui.buttonwidget( 153 parent=self._root_widget, 154 size=(self._width - 100, 60), 155 position=(50, v), 156 label=bui.Lstr(resource=f'{self._r}.useMusicFolderText'), 157 on_activate_call=self._on_music_folder_press, 158 icon=bui.gettexture('folder'), 159 icon_color=(1.1, 0.8, 0.2), 160 ) 161 if current_entry_type == 'musicFolder': 162 bui.containerwidget(edit=self._root_widget, selected_child=btn) 163 v -= spacing
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.
165 @override 166 def get_main_window_state(self) -> bui.MainWindowState: 167 # Support recreating our window for back/refresh purposes. 168 cls = type(self) 169 170 # Pull these out of self here; if we reference self in the 171 # lambda we'll keep our window alive which is bad. 172 current_entry = self._current_entry 173 callback = self._callback 174 selection_target_name = self._selection_target_name 175 176 return bui.BasicMainWindowState( 177 create_call=lambda transition, origin_widget: cls( 178 transition=transition, 179 origin_widget=origin_widget, 180 current_entry=current_entry, 181 callback=callback, 182 selection_target_name=selection_target_name, 183 ) 184 )
Return a WindowState to recreate this window, if supported.
Inherited Members
- bauiv1._uitypes.MainWindow
- main_window_back_state
- main_window_is_top_level
- main_window_close
- main_window_has_control
- main_window_back
- main_window_replace
- on_main_window_close
- bauiv1._uitypes.Window
- get_root_widget