bauiv1lib.playlist.editcontroller
Defines a controller for wrangling playlist edit UIs.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Defines a controller for wrangling playlist edit UIs.""" 4 5from __future__ import annotations 6 7import copy 8from typing import TYPE_CHECKING 9 10import bascenev1 as bs 11import bauiv1 as bui 12 13if TYPE_CHECKING: 14 from typing import Any 15 16 17class PlaylistEditController: 18 """Coordinates various UIs involved in playlist editing.""" 19 20 def __init__( 21 self, 22 sessiontype: type[bs.Session], 23 existing_playlist_name: str | None = None, 24 transition: str = 'in_right', 25 playlist: list[dict[str, Any]] | None = None, 26 playlist_name: str | None = None, 27 ): 28 from bascenev1 import filter_playlist 29 from bauiv1lib.playlist import PlaylistTypeVars 30 from bauiv1lib.playlist.edit import PlaylistEditWindow 31 32 appconfig = bui.app.config 33 34 # Since we may be showing our map list momentarily, 35 # lets go ahead and preload all map preview textures. 36 if bui.app.classic is not None: 37 bui.app.classic.preload_map_preview_media() 38 39 self._sessiontype = sessiontype 40 41 self._editing_game = False 42 self._editing_game_type: type[bs.GameActivity] | None = None 43 self._pvars = PlaylistTypeVars(sessiontype) 44 self._existing_playlist_name = existing_playlist_name 45 self._config_name_full = self._pvars.config_name + ' Playlists' 46 47 # Make sure config exists. 48 if self._config_name_full not in appconfig: 49 appconfig[self._config_name_full] = {} 50 51 self._selected_index = 0 52 if existing_playlist_name: 53 self._name = existing_playlist_name 54 55 # Filter out invalid games. 56 self._playlist = filter_playlist( 57 appconfig[self._pvars.config_name + ' Playlists'][ 58 existing_playlist_name 59 ], 60 sessiontype=sessiontype, 61 remove_unowned=False, 62 name=existing_playlist_name, 63 ) 64 self._edit_ui_selection = None 65 else: 66 if playlist is not None: 67 self._playlist = playlist 68 else: 69 self._playlist = [] 70 if playlist_name is not None: 71 self._name = playlist_name 72 else: 73 # Find a good unused name. 74 i = 1 75 while True: 76 self._name = ( 77 self._pvars.default_new_list_name.evaluate() 78 + ((' ' + str(i)) if i > 1 else '') 79 ) 80 if ( 81 self._name 82 not in appconfig[self._pvars.config_name + ' Playlists'] 83 ): 84 break 85 i += 1 86 87 # Also we want it to start with 'add' highlighted since its empty 88 # and that's all they can do. 89 self._edit_ui_selection = 'add_button' 90 91 assert bui.app.classic is not None 92 bui.app.ui_v1.set_main_menu_window( 93 PlaylistEditWindow( 94 editcontroller=self, transition=transition 95 ).get_root_widget() 96 ) 97 98 def get_config_name(self) -> str: 99 """(internal)""" 100 return self._pvars.config_name 101 102 def get_existing_playlist_name(self) -> str | None: 103 """(internal)""" 104 return self._existing_playlist_name 105 106 def get_edit_ui_selection(self) -> str | None: 107 """(internal)""" 108 return self._edit_ui_selection 109 110 def set_edit_ui_selection(self, selection: str) -> None: 111 """(internal)""" 112 self._edit_ui_selection = selection 113 114 def getname(self) -> str: 115 """(internal)""" 116 return self._name 117 118 def setname(self, name: str) -> None: 119 """(internal)""" 120 self._name = name 121 122 def get_playlist(self) -> list[dict[str, Any]]: 123 """Return the current state of the edited playlist.""" 124 return copy.deepcopy(self._playlist) 125 126 def set_playlist(self, playlist: list[dict[str, Any]]) -> None: 127 """Set the playlist contents.""" 128 self._playlist = copy.deepcopy(playlist) 129 130 def get_session_type(self) -> type[bs.Session]: 131 """Return the bascenev1.Session type for this edit-session.""" 132 return self._sessiontype 133 134 def get_selected_index(self) -> int: 135 """Return the index of the selected playlist.""" 136 return self._selected_index 137 138 def get_default_list_name(self) -> bui.Lstr: 139 """(internal)""" 140 return self._pvars.default_list_name 141 142 def set_selected_index(self, index: int) -> None: 143 """Sets the selected playlist index.""" 144 self._selected_index = index 145 146 def add_game_pressed(self) -> None: 147 """(internal)""" 148 from bauiv1lib.playlist.addgame import PlaylistAddGameWindow 149 150 assert bui.app.classic is not None 151 bui.app.ui_v1.clear_main_menu_window(transition='out_left') 152 bui.app.ui_v1.set_main_menu_window( 153 PlaylistAddGameWindow(editcontroller=self).get_root_widget() 154 ) 155 156 def edit_game_pressed(self) -> None: 157 """Should be called by supplemental UIs when a game is to be edited.""" 158 159 if not self._playlist: 160 return 161 self._show_edit_ui( 162 gametype=bui.getclass( 163 self._playlist[self._selected_index]['type'], 164 subclassof=bs.GameActivity, 165 ), 166 settings=self._playlist[self._selected_index], 167 ) 168 169 def add_game_cancelled(self) -> None: 170 """(internal)""" 171 from bauiv1lib.playlist.edit import PlaylistEditWindow 172 173 assert bui.app.classic is not None 174 bui.app.ui_v1.clear_main_menu_window(transition='out_right') 175 bui.app.ui_v1.set_main_menu_window( 176 PlaylistEditWindow( 177 editcontroller=self, transition='in_left' 178 ).get_root_widget() 179 ) 180 181 def _show_edit_ui( 182 self, gametype: type[bs.GameActivity], settings: dict[str, Any] | None 183 ) -> None: 184 self._editing_game = settings is not None 185 self._editing_game_type = gametype 186 assert self._sessiontype is not None 187 gametype.create_settings_ui( 188 self._sessiontype, copy.deepcopy(settings), self._edit_game_done 189 ) 190 191 def add_game_type_selected(self, gametype: type[bs.GameActivity]) -> None: 192 """(internal)""" 193 self._show_edit_ui(gametype=gametype, settings=None) 194 195 def _edit_game_done(self, config: dict[str, Any] | None) -> None: 196 from bauiv1lib.playlist.edit import PlaylistEditWindow 197 from bauiv1lib.playlist.addgame import PlaylistAddGameWindow 198 199 assert bui.app.classic is not None 200 if config is None: 201 # If we were editing, go back to our list. 202 if self._editing_game: 203 bui.getsound('powerdown01').play() 204 bui.app.ui_v1.clear_main_menu_window(transition='out_right') 205 bui.app.ui_v1.set_main_menu_window( 206 PlaylistEditWindow( 207 editcontroller=self, transition='in_left' 208 ).get_root_widget() 209 ) 210 211 # Otherwise we were adding; go back to the add type choice list. 212 else: 213 bui.app.ui_v1.clear_main_menu_window(transition='out_right') 214 bui.app.ui_v1.set_main_menu_window( 215 PlaylistAddGameWindow( 216 editcontroller=self, transition='in_left' 217 ).get_root_widget() 218 ) 219 else: 220 # Make sure type is in there. 221 assert self._editing_game_type is not None 222 config['type'] = bui.get_type_name(self._editing_game_type) 223 224 if self._editing_game: 225 self._playlist[self._selected_index] = copy.deepcopy(config) 226 else: 227 # Add a new entry to the playlist. 228 insert_index = min( 229 len(self._playlist), self._selected_index + 1 230 ) 231 self._playlist.insert(insert_index, copy.deepcopy(config)) 232 self._selected_index = insert_index 233 234 bui.getsound('gunCocking').play() 235 bui.app.ui_v1.clear_main_menu_window(transition='out_right') 236 bui.app.ui_v1.set_main_menu_window( 237 PlaylistEditWindow( 238 editcontroller=self, transition='in_left' 239 ).get_root_widget() 240 )
class
PlaylistEditController:
18class PlaylistEditController: 19 """Coordinates various UIs involved in playlist editing.""" 20 21 def __init__( 22 self, 23 sessiontype: type[bs.Session], 24 existing_playlist_name: str | None = None, 25 transition: str = 'in_right', 26 playlist: list[dict[str, Any]] | None = None, 27 playlist_name: str | None = None, 28 ): 29 from bascenev1 import filter_playlist 30 from bauiv1lib.playlist import PlaylistTypeVars 31 from bauiv1lib.playlist.edit import PlaylistEditWindow 32 33 appconfig = bui.app.config 34 35 # Since we may be showing our map list momentarily, 36 # lets go ahead and preload all map preview textures. 37 if bui.app.classic is not None: 38 bui.app.classic.preload_map_preview_media() 39 40 self._sessiontype = sessiontype 41 42 self._editing_game = False 43 self._editing_game_type: type[bs.GameActivity] | None = None 44 self._pvars = PlaylistTypeVars(sessiontype) 45 self._existing_playlist_name = existing_playlist_name 46 self._config_name_full = self._pvars.config_name + ' Playlists' 47 48 # Make sure config exists. 49 if self._config_name_full not in appconfig: 50 appconfig[self._config_name_full] = {} 51 52 self._selected_index = 0 53 if existing_playlist_name: 54 self._name = existing_playlist_name 55 56 # Filter out invalid games. 57 self._playlist = filter_playlist( 58 appconfig[self._pvars.config_name + ' Playlists'][ 59 existing_playlist_name 60 ], 61 sessiontype=sessiontype, 62 remove_unowned=False, 63 name=existing_playlist_name, 64 ) 65 self._edit_ui_selection = None 66 else: 67 if playlist is not None: 68 self._playlist = playlist 69 else: 70 self._playlist = [] 71 if playlist_name is not None: 72 self._name = playlist_name 73 else: 74 # Find a good unused name. 75 i = 1 76 while True: 77 self._name = ( 78 self._pvars.default_new_list_name.evaluate() 79 + ((' ' + str(i)) if i > 1 else '') 80 ) 81 if ( 82 self._name 83 not in appconfig[self._pvars.config_name + ' Playlists'] 84 ): 85 break 86 i += 1 87 88 # Also we want it to start with 'add' highlighted since its empty 89 # and that's all they can do. 90 self._edit_ui_selection = 'add_button' 91 92 assert bui.app.classic is not None 93 bui.app.ui_v1.set_main_menu_window( 94 PlaylistEditWindow( 95 editcontroller=self, transition=transition 96 ).get_root_widget() 97 ) 98 99 def get_config_name(self) -> str: 100 """(internal)""" 101 return self._pvars.config_name 102 103 def get_existing_playlist_name(self) -> str | None: 104 """(internal)""" 105 return self._existing_playlist_name 106 107 def get_edit_ui_selection(self) -> str | None: 108 """(internal)""" 109 return self._edit_ui_selection 110 111 def set_edit_ui_selection(self, selection: str) -> None: 112 """(internal)""" 113 self._edit_ui_selection = selection 114 115 def getname(self) -> str: 116 """(internal)""" 117 return self._name 118 119 def setname(self, name: str) -> None: 120 """(internal)""" 121 self._name = name 122 123 def get_playlist(self) -> list[dict[str, Any]]: 124 """Return the current state of the edited playlist.""" 125 return copy.deepcopy(self._playlist) 126 127 def set_playlist(self, playlist: list[dict[str, Any]]) -> None: 128 """Set the playlist contents.""" 129 self._playlist = copy.deepcopy(playlist) 130 131 def get_session_type(self) -> type[bs.Session]: 132 """Return the bascenev1.Session type for this edit-session.""" 133 return self._sessiontype 134 135 def get_selected_index(self) -> int: 136 """Return the index of the selected playlist.""" 137 return self._selected_index 138 139 def get_default_list_name(self) -> bui.Lstr: 140 """(internal)""" 141 return self._pvars.default_list_name 142 143 def set_selected_index(self, index: int) -> None: 144 """Sets the selected playlist index.""" 145 self._selected_index = index 146 147 def add_game_pressed(self) -> None: 148 """(internal)""" 149 from bauiv1lib.playlist.addgame import PlaylistAddGameWindow 150 151 assert bui.app.classic is not None 152 bui.app.ui_v1.clear_main_menu_window(transition='out_left') 153 bui.app.ui_v1.set_main_menu_window( 154 PlaylistAddGameWindow(editcontroller=self).get_root_widget() 155 ) 156 157 def edit_game_pressed(self) -> None: 158 """Should be called by supplemental UIs when a game is to be edited.""" 159 160 if not self._playlist: 161 return 162 self._show_edit_ui( 163 gametype=bui.getclass( 164 self._playlist[self._selected_index]['type'], 165 subclassof=bs.GameActivity, 166 ), 167 settings=self._playlist[self._selected_index], 168 ) 169 170 def add_game_cancelled(self) -> None: 171 """(internal)""" 172 from bauiv1lib.playlist.edit import PlaylistEditWindow 173 174 assert bui.app.classic is not None 175 bui.app.ui_v1.clear_main_menu_window(transition='out_right') 176 bui.app.ui_v1.set_main_menu_window( 177 PlaylistEditWindow( 178 editcontroller=self, transition='in_left' 179 ).get_root_widget() 180 ) 181 182 def _show_edit_ui( 183 self, gametype: type[bs.GameActivity], settings: dict[str, Any] | None 184 ) -> None: 185 self._editing_game = settings is not None 186 self._editing_game_type = gametype 187 assert self._sessiontype is not None 188 gametype.create_settings_ui( 189 self._sessiontype, copy.deepcopy(settings), self._edit_game_done 190 ) 191 192 def add_game_type_selected(self, gametype: type[bs.GameActivity]) -> None: 193 """(internal)""" 194 self._show_edit_ui(gametype=gametype, settings=None) 195 196 def _edit_game_done(self, config: dict[str, Any] | None) -> None: 197 from bauiv1lib.playlist.edit import PlaylistEditWindow 198 from bauiv1lib.playlist.addgame import PlaylistAddGameWindow 199 200 assert bui.app.classic is not None 201 if config is None: 202 # If we were editing, go back to our list. 203 if self._editing_game: 204 bui.getsound('powerdown01').play() 205 bui.app.ui_v1.clear_main_menu_window(transition='out_right') 206 bui.app.ui_v1.set_main_menu_window( 207 PlaylistEditWindow( 208 editcontroller=self, transition='in_left' 209 ).get_root_widget() 210 ) 211 212 # Otherwise we were adding; go back to the add type choice list. 213 else: 214 bui.app.ui_v1.clear_main_menu_window(transition='out_right') 215 bui.app.ui_v1.set_main_menu_window( 216 PlaylistAddGameWindow( 217 editcontroller=self, transition='in_left' 218 ).get_root_widget() 219 ) 220 else: 221 # Make sure type is in there. 222 assert self._editing_game_type is not None 223 config['type'] = bui.get_type_name(self._editing_game_type) 224 225 if self._editing_game: 226 self._playlist[self._selected_index] = copy.deepcopy(config) 227 else: 228 # Add a new entry to the playlist. 229 insert_index = min( 230 len(self._playlist), self._selected_index + 1 231 ) 232 self._playlist.insert(insert_index, copy.deepcopy(config)) 233 self._selected_index = insert_index 234 235 bui.getsound('gunCocking').play() 236 bui.app.ui_v1.clear_main_menu_window(transition='out_right') 237 bui.app.ui_v1.set_main_menu_window( 238 PlaylistEditWindow( 239 editcontroller=self, transition='in_left' 240 ).get_root_widget() 241 )
Coordinates various UIs involved in playlist editing.
PlaylistEditController( sessiontype: type[bascenev1._session.Session], existing_playlist_name: str | None = None, transition: str = 'in_right', playlist: list[dict[str, typing.Any]] | None = None, playlist_name: str | None = None)
21 def __init__( 22 self, 23 sessiontype: type[bs.Session], 24 existing_playlist_name: str | None = None, 25 transition: str = 'in_right', 26 playlist: list[dict[str, Any]] | None = None, 27 playlist_name: str | None = None, 28 ): 29 from bascenev1 import filter_playlist 30 from bauiv1lib.playlist import PlaylistTypeVars 31 from bauiv1lib.playlist.edit import PlaylistEditWindow 32 33 appconfig = bui.app.config 34 35 # Since we may be showing our map list momentarily, 36 # lets go ahead and preload all map preview textures. 37 if bui.app.classic is not None: 38 bui.app.classic.preload_map_preview_media() 39 40 self._sessiontype = sessiontype 41 42 self._editing_game = False 43 self._editing_game_type: type[bs.GameActivity] | None = None 44 self._pvars = PlaylistTypeVars(sessiontype) 45 self._existing_playlist_name = existing_playlist_name 46 self._config_name_full = self._pvars.config_name + ' Playlists' 47 48 # Make sure config exists. 49 if self._config_name_full not in appconfig: 50 appconfig[self._config_name_full] = {} 51 52 self._selected_index = 0 53 if existing_playlist_name: 54 self._name = existing_playlist_name 55 56 # Filter out invalid games. 57 self._playlist = filter_playlist( 58 appconfig[self._pvars.config_name + ' Playlists'][ 59 existing_playlist_name 60 ], 61 sessiontype=sessiontype, 62 remove_unowned=False, 63 name=existing_playlist_name, 64 ) 65 self._edit_ui_selection = None 66 else: 67 if playlist is not None: 68 self._playlist = playlist 69 else: 70 self._playlist = [] 71 if playlist_name is not None: 72 self._name = playlist_name 73 else: 74 # Find a good unused name. 75 i = 1 76 while True: 77 self._name = ( 78 self._pvars.default_new_list_name.evaluate() 79 + ((' ' + str(i)) if i > 1 else '') 80 ) 81 if ( 82 self._name 83 not in appconfig[self._pvars.config_name + ' Playlists'] 84 ): 85 break 86 i += 1 87 88 # Also we want it to start with 'add' highlighted since its empty 89 # and that's all they can do. 90 self._edit_ui_selection = 'add_button' 91 92 assert bui.app.classic is not None 93 bui.app.ui_v1.set_main_menu_window( 94 PlaylistEditWindow( 95 editcontroller=self, transition=transition 96 ).get_root_widget() 97 )
def
get_playlist(self) -> list[dict[str, typing.Any]]:
123 def get_playlist(self) -> list[dict[str, Any]]: 124 """Return the current state of the edited playlist.""" 125 return copy.deepcopy(self._playlist)
Return the current state of the edited playlist.
def
set_playlist(self, playlist: list[dict[str, typing.Any]]) -> None:
127 def set_playlist(self, playlist: list[dict[str, Any]]) -> None: 128 """Set the playlist contents.""" 129 self._playlist = copy.deepcopy(playlist)
Set the playlist contents.
def
get_session_type(self) -> type[bascenev1._session.Session]:
131 def get_session_type(self) -> type[bs.Session]: 132 """Return the bascenev1.Session type for this edit-session.""" 133 return self._sessiontype
Return the bascenev1.Session type for this edit-session.
def
get_selected_index(self) -> int:
135 def get_selected_index(self) -> int: 136 """Return the index of the selected playlist.""" 137 return self._selected_index
Return the index of the selected playlist.
def
set_selected_index(self, index: int) -> None:
143 def set_selected_index(self, index: int) -> None: 144 """Sets the selected playlist index.""" 145 self._selected_index = index
Sets the selected playlist index.
def
edit_game_pressed(self) -> None:
157 def edit_game_pressed(self) -> None: 158 """Should be called by supplemental UIs when a game is to be edited.""" 159 160 if not self._playlist: 161 return 162 self._show_edit_ui( 163 gametype=bui.getclass( 164 self._playlist[self._selected_index]['type'], 165 subclassof=bs.GameActivity, 166 ), 167 settings=self._playlist[self._selected_index], 168 )
Should be called by supplemental UIs when a game is to be edited.