bauiv1lib.playlist.edit
Provides a window for editing individual game playlists.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Provides a window for editing individual game playlists.""" 4 5from __future__ import annotations 6 7import logging 8from typing import TYPE_CHECKING, cast 9 10import bascenev1 as bs 11import bauiv1 as bui 12 13if TYPE_CHECKING: 14 from bauiv1lib.playlist.editcontroller import PlaylistEditController 15 16 17class PlaylistEditWindow(bui.Window): 18 """Window for editing an individual game playlist.""" 19 20 def __init__( 21 self, 22 editcontroller: PlaylistEditController, 23 transition: str = 'in_right', 24 ): 25 # pylint: disable=too-many-statements 26 # pylint: disable=too-many-locals 27 prev_selection: str | None 28 self._editcontroller = editcontroller 29 self._r = 'editGameListWindow' 30 prev_selection = self._editcontroller.get_edit_ui_selection() 31 32 assert bui.app.classic is not None 33 uiscale = bui.app.ui_v1.uiscale 34 self._width = 770 if uiscale is bui.UIScale.SMALL else 670 35 x_inset = 50 if uiscale is bui.UIScale.SMALL else 0 36 self._height = ( 37 400 38 if uiscale is bui.UIScale.SMALL 39 else 470 40 if uiscale is bui.UIScale.MEDIUM 41 else 540 42 ) 43 44 top_extra = 20 if uiscale is bui.UIScale.SMALL else 0 45 super().__init__( 46 root_widget=bui.containerwidget( 47 size=(self._width, self._height + top_extra), 48 transition=transition, 49 scale=( 50 2.0 51 if uiscale is bui.UIScale.SMALL 52 else 1.3 53 if uiscale is bui.UIScale.MEDIUM 54 else 1.0 55 ), 56 stack_offset=(0, -16) 57 if uiscale is bui.UIScale.SMALL 58 else (0, 0), 59 ) 60 ) 61 cancel_button = bui.buttonwidget( 62 parent=self._root_widget, 63 position=(35 + x_inset, self._height - 60), 64 scale=0.8, 65 size=(175, 60), 66 autoselect=True, 67 label=bui.Lstr(resource='cancelText'), 68 text_scale=1.2, 69 ) 70 save_button = btn = bui.buttonwidget( 71 parent=self._root_widget, 72 position=(self._width - (195 + x_inset), self._height - 60), 73 scale=0.8, 74 size=(190, 60), 75 autoselect=True, 76 left_widget=cancel_button, 77 label=bui.Lstr(resource='saveText'), 78 text_scale=1.2, 79 ) 80 81 if bui.app.ui_v1.use_toolbars: 82 bui.widget( 83 edit=btn, 84 right_widget=bui.get_special_widget('party_button'), 85 ) 86 87 bui.widget( 88 edit=cancel_button, 89 left_widget=cancel_button, 90 right_widget=save_button, 91 ) 92 93 bui.textwidget( 94 parent=self._root_widget, 95 position=(-10, self._height - 50), 96 size=(self._width, 25), 97 text=bui.Lstr(resource=self._r + '.titleText'), 98 color=bui.app.ui_v1.title_color, 99 scale=1.05, 100 h_align='center', 101 v_align='center', 102 maxwidth=270, 103 ) 104 105 v = self._height - 115.0 106 107 self._scroll_width = self._width - (205 + 2 * x_inset) 108 109 bui.textwidget( 110 parent=self._root_widget, 111 text=bui.Lstr(resource=self._r + '.listNameText'), 112 position=(196 + x_inset, v + 31), 113 maxwidth=150, 114 color=(0.8, 0.8, 0.8, 0.5), 115 size=(0, 0), 116 scale=0.75, 117 h_align='right', 118 v_align='center', 119 ) 120 121 self._text_field = bui.textwidget( 122 parent=self._root_widget, 123 position=(210 + x_inset, v + 7), 124 size=(self._scroll_width - 53, 43), 125 text=self._editcontroller.getname(), 126 h_align='left', 127 v_align='center', 128 max_chars=40, 129 autoselect=True, 130 color=(0.9, 0.9, 0.9, 1.0), 131 description=bui.Lstr(resource=self._r + '.listNameText'), 132 editable=True, 133 padding=4, 134 on_return_press_call=self._save_press_with_sound, 135 ) 136 bui.widget(edit=cancel_button, down_widget=self._text_field) 137 138 self._list_widgets: list[bui.Widget] = [] 139 140 h = 40 + x_inset 141 v = self._height - 172.0 142 143 b_color = (0.6, 0.53, 0.63) 144 b_textcolor = (0.75, 0.7, 0.8) 145 146 v -= 2.0 147 v += 63 148 149 scl = ( 150 1.03 151 if uiscale is bui.UIScale.SMALL 152 else 1.36 153 if uiscale is bui.UIScale.MEDIUM 154 else 1.74 155 ) 156 v -= 63.0 * scl 157 158 add_game_button = bui.buttonwidget( 159 parent=self._root_widget, 160 position=(h, v), 161 size=(110, 61.0 * scl), 162 on_activate_call=self._add, 163 on_select_call=bui.Call(self._set_ui_selection, 'add_button'), 164 autoselect=True, 165 button_type='square', 166 color=b_color, 167 textcolor=b_textcolor, 168 text_scale=0.8, 169 label=bui.Lstr(resource=self._r + '.addGameText'), 170 ) 171 bui.widget(edit=add_game_button, up_widget=self._text_field) 172 v -= 63.0 * scl 173 174 self._edit_button = edit_game_button = bui.buttonwidget( 175 parent=self._root_widget, 176 position=(h, v), 177 size=(110, 61.0 * scl), 178 on_activate_call=self._edit, 179 on_select_call=bui.Call(self._set_ui_selection, 'editButton'), 180 autoselect=True, 181 button_type='square', 182 color=b_color, 183 textcolor=b_textcolor, 184 text_scale=0.8, 185 label=bui.Lstr(resource=self._r + '.editGameText'), 186 ) 187 v -= 63.0 * scl 188 189 remove_game_button = bui.buttonwidget( 190 parent=self._root_widget, 191 position=(h, v), 192 size=(110, 61.0 * scl), 193 text_scale=0.8, 194 on_activate_call=self._remove, 195 autoselect=True, 196 button_type='square', 197 color=b_color, 198 textcolor=b_textcolor, 199 label=bui.Lstr(resource=self._r + '.removeGameText'), 200 ) 201 v -= 40 202 h += 9 203 bui.buttonwidget( 204 parent=self._root_widget, 205 position=(h, v), 206 size=(42, 35), 207 on_activate_call=self._move_up, 208 label=bui.charstr(bui.SpecialChar.UP_ARROW), 209 button_type='square', 210 color=b_color, 211 textcolor=b_textcolor, 212 autoselect=True, 213 repeat=True, 214 ) 215 h += 52 216 bui.buttonwidget( 217 parent=self._root_widget, 218 position=(h, v), 219 size=(42, 35), 220 on_activate_call=self._move_down, 221 autoselect=True, 222 button_type='square', 223 color=b_color, 224 textcolor=b_textcolor, 225 label=bui.charstr(bui.SpecialChar.DOWN_ARROW), 226 repeat=True, 227 ) 228 229 v = self._height - 100 230 scroll_height = self._height - 155 231 scrollwidget = bui.scrollwidget( 232 parent=self._root_widget, 233 position=(160 + x_inset, v - scroll_height), 234 highlight=False, 235 on_select_call=bui.Call(self._set_ui_selection, 'gameList'), 236 size=(self._scroll_width, (scroll_height - 15)), 237 ) 238 bui.widget( 239 edit=scrollwidget, 240 left_widget=add_game_button, 241 right_widget=scrollwidget, 242 ) 243 self._columnwidget = bui.columnwidget( 244 parent=scrollwidget, border=2, margin=0 245 ) 246 bui.widget(edit=self._columnwidget, up_widget=self._text_field) 247 248 for button in [add_game_button, edit_game_button, remove_game_button]: 249 bui.widget( 250 edit=button, left_widget=button, right_widget=scrollwidget 251 ) 252 253 self._refresh() 254 255 bui.buttonwidget(edit=cancel_button, on_activate_call=self._cancel) 256 bui.containerwidget( 257 edit=self._root_widget, 258 cancel_button=cancel_button, 259 selected_child=scrollwidget, 260 ) 261 262 bui.buttonwidget(edit=save_button, on_activate_call=self._save_press) 263 bui.containerwidget(edit=self._root_widget, start_button=save_button) 264 265 if prev_selection == 'add_button': 266 bui.containerwidget( 267 edit=self._root_widget, selected_child=add_game_button 268 ) 269 elif prev_selection == 'editButton': 270 bui.containerwidget( 271 edit=self._root_widget, selected_child=edit_game_button 272 ) 273 elif prev_selection == 'gameList': 274 bui.containerwidget( 275 edit=self._root_widget, selected_child=scrollwidget 276 ) 277 278 def _set_ui_selection(self, selection: str) -> None: 279 self._editcontroller.set_edit_ui_selection(selection) 280 281 def _cancel(self) -> None: 282 from bauiv1lib.playlist.customizebrowser import ( 283 PlaylistCustomizeBrowserWindow, 284 ) 285 286 bui.getsound('powerdown01').play() 287 bui.containerwidget(edit=self._root_widget, transition='out_right') 288 assert bui.app.classic is not None 289 bui.app.ui_v1.set_main_menu_window( 290 PlaylistCustomizeBrowserWindow( 291 transition='in_left', 292 sessiontype=self._editcontroller.get_session_type(), 293 select_playlist=( 294 self._editcontroller.get_existing_playlist_name() 295 ), 296 ).get_root_widget() 297 ) 298 299 def _add(self) -> None: 300 # Store list name then tell the session to perform an add. 301 self._editcontroller.setname( 302 cast(str, bui.textwidget(query=self._text_field)) 303 ) 304 self._editcontroller.add_game_pressed() 305 306 def _edit(self) -> None: 307 # Store list name then tell the session to perform an add. 308 self._editcontroller.setname( 309 cast(str, bui.textwidget(query=self._text_field)) 310 ) 311 self._editcontroller.edit_game_pressed() 312 313 def _save_press(self) -> None: 314 from bauiv1lib.playlist.customizebrowser import ( 315 PlaylistCustomizeBrowserWindow, 316 ) 317 318 plus = bui.app.plus 319 assert plus is not None 320 321 new_name = cast(str, bui.textwidget(query=self._text_field)) 322 if ( 323 new_name != self._editcontroller.get_existing_playlist_name() 324 and new_name 325 in bui.app.config[ 326 self._editcontroller.get_config_name() + ' Playlists' 327 ] 328 ): 329 bui.screenmessage( 330 bui.Lstr(resource=self._r + '.cantSaveAlreadyExistsText') 331 ) 332 bui.getsound('error').play() 333 return 334 if not new_name: 335 bui.getsound('error').play() 336 return 337 if not self._editcontroller.get_playlist(): 338 bui.screenmessage( 339 bui.Lstr(resource=self._r + '.cantSaveEmptyListText') 340 ) 341 bui.getsound('error').play() 342 return 343 344 # We couldn't actually replace the default list anyway, but disallow 345 # using its exact name to avoid confusion. 346 if new_name == self._editcontroller.get_default_list_name().evaluate(): 347 bui.screenmessage( 348 bui.Lstr(resource=self._r + '.cantOverwriteDefaultText') 349 ) 350 bui.getsound('error').play() 351 return 352 353 # If we had an old one, delete it. 354 if self._editcontroller.get_existing_playlist_name() is not None: 355 plus.add_v1_account_transaction( 356 { 357 'type': 'REMOVE_PLAYLIST', 358 'playlistType': self._editcontroller.get_config_name(), 359 'playlistName': ( 360 self._editcontroller.get_existing_playlist_name() 361 ), 362 } 363 ) 364 365 plus.add_v1_account_transaction( 366 { 367 'type': 'ADD_PLAYLIST', 368 'playlistType': self._editcontroller.get_config_name(), 369 'playlistName': new_name, 370 'playlist': self._editcontroller.get_playlist(), 371 } 372 ) 373 plus.run_v1_account_transactions() 374 375 bui.containerwidget(edit=self._root_widget, transition='out_right') 376 bui.getsound('gunCocking').play() 377 assert bui.app.classic is not None 378 bui.app.ui_v1.set_main_menu_window( 379 PlaylistCustomizeBrowserWindow( 380 transition='in_left', 381 sessiontype=self._editcontroller.get_session_type(), 382 select_playlist=new_name, 383 ).get_root_widget() 384 ) 385 386 def _save_press_with_sound(self) -> None: 387 bui.getsound('swish').play() 388 self._save_press() 389 390 def _select(self, index: int) -> None: 391 self._editcontroller.set_selected_index(index) 392 393 def _refresh(self) -> None: 394 # Need to grab this here as rebuilding the list will 395 # change it otherwise. 396 old_selection_index = self._editcontroller.get_selected_index() 397 398 while self._list_widgets: 399 self._list_widgets.pop().delete() 400 for index, pentry in enumerate(self._editcontroller.get_playlist()): 401 try: 402 cls = bui.getclass(pentry['type'], subclassof=bs.GameActivity) 403 desc = cls.get_settings_display_string(pentry) 404 except Exception: 405 logging.exception('Error in playlist refresh.') 406 desc = "(invalid: '" + pentry['type'] + "')" 407 408 txtw = bui.textwidget( 409 parent=self._columnwidget, 410 size=(self._width - 80, 30), 411 on_select_call=bui.Call(self._select, index), 412 always_highlight=True, 413 color=(0.8, 0.8, 0.8, 1.0), 414 padding=0, 415 maxwidth=self._scroll_width * 0.93, 416 text=desc, 417 on_activate_call=self._edit_button.activate, 418 v_align='center', 419 selectable=True, 420 ) 421 bui.widget(edit=txtw, show_buffer_top=50, show_buffer_bottom=50) 422 423 # Wanna be able to jump up to the text field from the top one. 424 if index == 0: 425 bui.widget(edit=txtw, up_widget=self._text_field) 426 self._list_widgets.append(txtw) 427 if old_selection_index == index: 428 bui.columnwidget( 429 edit=self._columnwidget, 430 selected_child=txtw, 431 visible_child=txtw, 432 ) 433 434 def _move_down(self) -> None: 435 playlist = self._editcontroller.get_playlist() 436 index = self._editcontroller.get_selected_index() 437 if index >= len(playlist) - 1: 438 return 439 tmp = playlist[index] 440 playlist[index] = playlist[index + 1] 441 playlist[index + 1] = tmp 442 index += 1 443 self._editcontroller.set_playlist(playlist) 444 self._editcontroller.set_selected_index(index) 445 self._refresh() 446 447 def _move_up(self) -> None: 448 playlist = self._editcontroller.get_playlist() 449 index = self._editcontroller.get_selected_index() 450 if index < 1: 451 return 452 tmp = playlist[index] 453 playlist[index] = playlist[index - 1] 454 playlist[index - 1] = tmp 455 index -= 1 456 self._editcontroller.set_playlist(playlist) 457 self._editcontroller.set_selected_index(index) 458 self._refresh() 459 460 def _remove(self) -> None: 461 playlist = self._editcontroller.get_playlist() 462 index = self._editcontroller.get_selected_index() 463 if not playlist: 464 return 465 del playlist[index] 466 if index >= len(playlist): 467 index = len(playlist) - 1 468 self._editcontroller.set_playlist(playlist) 469 self._editcontroller.set_selected_index(index) 470 bui.getsound('shieldDown').play() 471 self._refresh()
class
PlaylistEditWindow(bauiv1._uitypes.Window):
18class PlaylistEditWindow(bui.Window): 19 """Window for editing an individual game playlist.""" 20 21 def __init__( 22 self, 23 editcontroller: PlaylistEditController, 24 transition: str = 'in_right', 25 ): 26 # pylint: disable=too-many-statements 27 # pylint: disable=too-many-locals 28 prev_selection: str | None 29 self._editcontroller = editcontroller 30 self._r = 'editGameListWindow' 31 prev_selection = self._editcontroller.get_edit_ui_selection() 32 33 assert bui.app.classic is not None 34 uiscale = bui.app.ui_v1.uiscale 35 self._width = 770 if uiscale is bui.UIScale.SMALL else 670 36 x_inset = 50 if uiscale is bui.UIScale.SMALL else 0 37 self._height = ( 38 400 39 if uiscale is bui.UIScale.SMALL 40 else 470 41 if uiscale is bui.UIScale.MEDIUM 42 else 540 43 ) 44 45 top_extra = 20 if uiscale is bui.UIScale.SMALL else 0 46 super().__init__( 47 root_widget=bui.containerwidget( 48 size=(self._width, self._height + top_extra), 49 transition=transition, 50 scale=( 51 2.0 52 if uiscale is bui.UIScale.SMALL 53 else 1.3 54 if uiscale is bui.UIScale.MEDIUM 55 else 1.0 56 ), 57 stack_offset=(0, -16) 58 if uiscale is bui.UIScale.SMALL 59 else (0, 0), 60 ) 61 ) 62 cancel_button = bui.buttonwidget( 63 parent=self._root_widget, 64 position=(35 + x_inset, self._height - 60), 65 scale=0.8, 66 size=(175, 60), 67 autoselect=True, 68 label=bui.Lstr(resource='cancelText'), 69 text_scale=1.2, 70 ) 71 save_button = btn = bui.buttonwidget( 72 parent=self._root_widget, 73 position=(self._width - (195 + x_inset), self._height - 60), 74 scale=0.8, 75 size=(190, 60), 76 autoselect=True, 77 left_widget=cancel_button, 78 label=bui.Lstr(resource='saveText'), 79 text_scale=1.2, 80 ) 81 82 if bui.app.ui_v1.use_toolbars: 83 bui.widget( 84 edit=btn, 85 right_widget=bui.get_special_widget('party_button'), 86 ) 87 88 bui.widget( 89 edit=cancel_button, 90 left_widget=cancel_button, 91 right_widget=save_button, 92 ) 93 94 bui.textwidget( 95 parent=self._root_widget, 96 position=(-10, self._height - 50), 97 size=(self._width, 25), 98 text=bui.Lstr(resource=self._r + '.titleText'), 99 color=bui.app.ui_v1.title_color, 100 scale=1.05, 101 h_align='center', 102 v_align='center', 103 maxwidth=270, 104 ) 105 106 v = self._height - 115.0 107 108 self._scroll_width = self._width - (205 + 2 * x_inset) 109 110 bui.textwidget( 111 parent=self._root_widget, 112 text=bui.Lstr(resource=self._r + '.listNameText'), 113 position=(196 + x_inset, v + 31), 114 maxwidth=150, 115 color=(0.8, 0.8, 0.8, 0.5), 116 size=(0, 0), 117 scale=0.75, 118 h_align='right', 119 v_align='center', 120 ) 121 122 self._text_field = bui.textwidget( 123 parent=self._root_widget, 124 position=(210 + x_inset, v + 7), 125 size=(self._scroll_width - 53, 43), 126 text=self._editcontroller.getname(), 127 h_align='left', 128 v_align='center', 129 max_chars=40, 130 autoselect=True, 131 color=(0.9, 0.9, 0.9, 1.0), 132 description=bui.Lstr(resource=self._r + '.listNameText'), 133 editable=True, 134 padding=4, 135 on_return_press_call=self._save_press_with_sound, 136 ) 137 bui.widget(edit=cancel_button, down_widget=self._text_field) 138 139 self._list_widgets: list[bui.Widget] = [] 140 141 h = 40 + x_inset 142 v = self._height - 172.0 143 144 b_color = (0.6, 0.53, 0.63) 145 b_textcolor = (0.75, 0.7, 0.8) 146 147 v -= 2.0 148 v += 63 149 150 scl = ( 151 1.03 152 if uiscale is bui.UIScale.SMALL 153 else 1.36 154 if uiscale is bui.UIScale.MEDIUM 155 else 1.74 156 ) 157 v -= 63.0 * scl 158 159 add_game_button = bui.buttonwidget( 160 parent=self._root_widget, 161 position=(h, v), 162 size=(110, 61.0 * scl), 163 on_activate_call=self._add, 164 on_select_call=bui.Call(self._set_ui_selection, 'add_button'), 165 autoselect=True, 166 button_type='square', 167 color=b_color, 168 textcolor=b_textcolor, 169 text_scale=0.8, 170 label=bui.Lstr(resource=self._r + '.addGameText'), 171 ) 172 bui.widget(edit=add_game_button, up_widget=self._text_field) 173 v -= 63.0 * scl 174 175 self._edit_button = edit_game_button = bui.buttonwidget( 176 parent=self._root_widget, 177 position=(h, v), 178 size=(110, 61.0 * scl), 179 on_activate_call=self._edit, 180 on_select_call=bui.Call(self._set_ui_selection, 'editButton'), 181 autoselect=True, 182 button_type='square', 183 color=b_color, 184 textcolor=b_textcolor, 185 text_scale=0.8, 186 label=bui.Lstr(resource=self._r + '.editGameText'), 187 ) 188 v -= 63.0 * scl 189 190 remove_game_button = bui.buttonwidget( 191 parent=self._root_widget, 192 position=(h, v), 193 size=(110, 61.0 * scl), 194 text_scale=0.8, 195 on_activate_call=self._remove, 196 autoselect=True, 197 button_type='square', 198 color=b_color, 199 textcolor=b_textcolor, 200 label=bui.Lstr(resource=self._r + '.removeGameText'), 201 ) 202 v -= 40 203 h += 9 204 bui.buttonwidget( 205 parent=self._root_widget, 206 position=(h, v), 207 size=(42, 35), 208 on_activate_call=self._move_up, 209 label=bui.charstr(bui.SpecialChar.UP_ARROW), 210 button_type='square', 211 color=b_color, 212 textcolor=b_textcolor, 213 autoselect=True, 214 repeat=True, 215 ) 216 h += 52 217 bui.buttonwidget( 218 parent=self._root_widget, 219 position=(h, v), 220 size=(42, 35), 221 on_activate_call=self._move_down, 222 autoselect=True, 223 button_type='square', 224 color=b_color, 225 textcolor=b_textcolor, 226 label=bui.charstr(bui.SpecialChar.DOWN_ARROW), 227 repeat=True, 228 ) 229 230 v = self._height - 100 231 scroll_height = self._height - 155 232 scrollwidget = bui.scrollwidget( 233 parent=self._root_widget, 234 position=(160 + x_inset, v - scroll_height), 235 highlight=False, 236 on_select_call=bui.Call(self._set_ui_selection, 'gameList'), 237 size=(self._scroll_width, (scroll_height - 15)), 238 ) 239 bui.widget( 240 edit=scrollwidget, 241 left_widget=add_game_button, 242 right_widget=scrollwidget, 243 ) 244 self._columnwidget = bui.columnwidget( 245 parent=scrollwidget, border=2, margin=0 246 ) 247 bui.widget(edit=self._columnwidget, up_widget=self._text_field) 248 249 for button in [add_game_button, edit_game_button, remove_game_button]: 250 bui.widget( 251 edit=button, left_widget=button, right_widget=scrollwidget 252 ) 253 254 self._refresh() 255 256 bui.buttonwidget(edit=cancel_button, on_activate_call=self._cancel) 257 bui.containerwidget( 258 edit=self._root_widget, 259 cancel_button=cancel_button, 260 selected_child=scrollwidget, 261 ) 262 263 bui.buttonwidget(edit=save_button, on_activate_call=self._save_press) 264 bui.containerwidget(edit=self._root_widget, start_button=save_button) 265 266 if prev_selection == 'add_button': 267 bui.containerwidget( 268 edit=self._root_widget, selected_child=add_game_button 269 ) 270 elif prev_selection == 'editButton': 271 bui.containerwidget( 272 edit=self._root_widget, selected_child=edit_game_button 273 ) 274 elif prev_selection == 'gameList': 275 bui.containerwidget( 276 edit=self._root_widget, selected_child=scrollwidget 277 ) 278 279 def _set_ui_selection(self, selection: str) -> None: 280 self._editcontroller.set_edit_ui_selection(selection) 281 282 def _cancel(self) -> None: 283 from bauiv1lib.playlist.customizebrowser import ( 284 PlaylistCustomizeBrowserWindow, 285 ) 286 287 bui.getsound('powerdown01').play() 288 bui.containerwidget(edit=self._root_widget, transition='out_right') 289 assert bui.app.classic is not None 290 bui.app.ui_v1.set_main_menu_window( 291 PlaylistCustomizeBrowserWindow( 292 transition='in_left', 293 sessiontype=self._editcontroller.get_session_type(), 294 select_playlist=( 295 self._editcontroller.get_existing_playlist_name() 296 ), 297 ).get_root_widget() 298 ) 299 300 def _add(self) -> None: 301 # Store list name then tell the session to perform an add. 302 self._editcontroller.setname( 303 cast(str, bui.textwidget(query=self._text_field)) 304 ) 305 self._editcontroller.add_game_pressed() 306 307 def _edit(self) -> None: 308 # Store list name then tell the session to perform an add. 309 self._editcontroller.setname( 310 cast(str, bui.textwidget(query=self._text_field)) 311 ) 312 self._editcontroller.edit_game_pressed() 313 314 def _save_press(self) -> None: 315 from bauiv1lib.playlist.customizebrowser import ( 316 PlaylistCustomizeBrowserWindow, 317 ) 318 319 plus = bui.app.plus 320 assert plus is not None 321 322 new_name = cast(str, bui.textwidget(query=self._text_field)) 323 if ( 324 new_name != self._editcontroller.get_existing_playlist_name() 325 and new_name 326 in bui.app.config[ 327 self._editcontroller.get_config_name() + ' Playlists' 328 ] 329 ): 330 bui.screenmessage( 331 bui.Lstr(resource=self._r + '.cantSaveAlreadyExistsText') 332 ) 333 bui.getsound('error').play() 334 return 335 if not new_name: 336 bui.getsound('error').play() 337 return 338 if not self._editcontroller.get_playlist(): 339 bui.screenmessage( 340 bui.Lstr(resource=self._r + '.cantSaveEmptyListText') 341 ) 342 bui.getsound('error').play() 343 return 344 345 # We couldn't actually replace the default list anyway, but disallow 346 # using its exact name to avoid confusion. 347 if new_name == self._editcontroller.get_default_list_name().evaluate(): 348 bui.screenmessage( 349 bui.Lstr(resource=self._r + '.cantOverwriteDefaultText') 350 ) 351 bui.getsound('error').play() 352 return 353 354 # If we had an old one, delete it. 355 if self._editcontroller.get_existing_playlist_name() is not None: 356 plus.add_v1_account_transaction( 357 { 358 'type': 'REMOVE_PLAYLIST', 359 'playlistType': self._editcontroller.get_config_name(), 360 'playlistName': ( 361 self._editcontroller.get_existing_playlist_name() 362 ), 363 } 364 ) 365 366 plus.add_v1_account_transaction( 367 { 368 'type': 'ADD_PLAYLIST', 369 'playlistType': self._editcontroller.get_config_name(), 370 'playlistName': new_name, 371 'playlist': self._editcontroller.get_playlist(), 372 } 373 ) 374 plus.run_v1_account_transactions() 375 376 bui.containerwidget(edit=self._root_widget, transition='out_right') 377 bui.getsound('gunCocking').play() 378 assert bui.app.classic is not None 379 bui.app.ui_v1.set_main_menu_window( 380 PlaylistCustomizeBrowserWindow( 381 transition='in_left', 382 sessiontype=self._editcontroller.get_session_type(), 383 select_playlist=new_name, 384 ).get_root_widget() 385 ) 386 387 def _save_press_with_sound(self) -> None: 388 bui.getsound('swish').play() 389 self._save_press() 390 391 def _select(self, index: int) -> None: 392 self._editcontroller.set_selected_index(index) 393 394 def _refresh(self) -> None: 395 # Need to grab this here as rebuilding the list will 396 # change it otherwise. 397 old_selection_index = self._editcontroller.get_selected_index() 398 399 while self._list_widgets: 400 self._list_widgets.pop().delete() 401 for index, pentry in enumerate(self._editcontroller.get_playlist()): 402 try: 403 cls = bui.getclass(pentry['type'], subclassof=bs.GameActivity) 404 desc = cls.get_settings_display_string(pentry) 405 except Exception: 406 logging.exception('Error in playlist refresh.') 407 desc = "(invalid: '" + pentry['type'] + "')" 408 409 txtw = bui.textwidget( 410 parent=self._columnwidget, 411 size=(self._width - 80, 30), 412 on_select_call=bui.Call(self._select, index), 413 always_highlight=True, 414 color=(0.8, 0.8, 0.8, 1.0), 415 padding=0, 416 maxwidth=self._scroll_width * 0.93, 417 text=desc, 418 on_activate_call=self._edit_button.activate, 419 v_align='center', 420 selectable=True, 421 ) 422 bui.widget(edit=txtw, show_buffer_top=50, show_buffer_bottom=50) 423 424 # Wanna be able to jump up to the text field from the top one. 425 if index == 0: 426 bui.widget(edit=txtw, up_widget=self._text_field) 427 self._list_widgets.append(txtw) 428 if old_selection_index == index: 429 bui.columnwidget( 430 edit=self._columnwidget, 431 selected_child=txtw, 432 visible_child=txtw, 433 ) 434 435 def _move_down(self) -> None: 436 playlist = self._editcontroller.get_playlist() 437 index = self._editcontroller.get_selected_index() 438 if index >= len(playlist) - 1: 439 return 440 tmp = playlist[index] 441 playlist[index] = playlist[index + 1] 442 playlist[index + 1] = tmp 443 index += 1 444 self._editcontroller.set_playlist(playlist) 445 self._editcontroller.set_selected_index(index) 446 self._refresh() 447 448 def _move_up(self) -> None: 449 playlist = self._editcontroller.get_playlist() 450 index = self._editcontroller.get_selected_index() 451 if index < 1: 452 return 453 tmp = playlist[index] 454 playlist[index] = playlist[index - 1] 455 playlist[index - 1] = tmp 456 index -= 1 457 self._editcontroller.set_playlist(playlist) 458 self._editcontroller.set_selected_index(index) 459 self._refresh() 460 461 def _remove(self) -> None: 462 playlist = self._editcontroller.get_playlist() 463 index = self._editcontroller.get_selected_index() 464 if not playlist: 465 return 466 del playlist[index] 467 if index >= len(playlist): 468 index = len(playlist) - 1 469 self._editcontroller.set_playlist(playlist) 470 self._editcontroller.set_selected_index(index) 471 bui.getsound('shieldDown').play() 472 self._refresh()
Window for editing an individual game playlist.
PlaylistEditWindow( editcontroller: bauiv1lib.playlist.editcontroller.PlaylistEditController, transition: str = 'in_right')
21 def __init__( 22 self, 23 editcontroller: PlaylistEditController, 24 transition: str = 'in_right', 25 ): 26 # pylint: disable=too-many-statements 27 # pylint: disable=too-many-locals 28 prev_selection: str | None 29 self._editcontroller = editcontroller 30 self._r = 'editGameListWindow' 31 prev_selection = self._editcontroller.get_edit_ui_selection() 32 33 assert bui.app.classic is not None 34 uiscale = bui.app.ui_v1.uiscale 35 self._width = 770 if uiscale is bui.UIScale.SMALL else 670 36 x_inset = 50 if uiscale is bui.UIScale.SMALL else 0 37 self._height = ( 38 400 39 if uiscale is bui.UIScale.SMALL 40 else 470 41 if uiscale is bui.UIScale.MEDIUM 42 else 540 43 ) 44 45 top_extra = 20 if uiscale is bui.UIScale.SMALL else 0 46 super().__init__( 47 root_widget=bui.containerwidget( 48 size=(self._width, self._height + top_extra), 49 transition=transition, 50 scale=( 51 2.0 52 if uiscale is bui.UIScale.SMALL 53 else 1.3 54 if uiscale is bui.UIScale.MEDIUM 55 else 1.0 56 ), 57 stack_offset=(0, -16) 58 if uiscale is bui.UIScale.SMALL 59 else (0, 0), 60 ) 61 ) 62 cancel_button = bui.buttonwidget( 63 parent=self._root_widget, 64 position=(35 + x_inset, self._height - 60), 65 scale=0.8, 66 size=(175, 60), 67 autoselect=True, 68 label=bui.Lstr(resource='cancelText'), 69 text_scale=1.2, 70 ) 71 save_button = btn = bui.buttonwidget( 72 parent=self._root_widget, 73 position=(self._width - (195 + x_inset), self._height - 60), 74 scale=0.8, 75 size=(190, 60), 76 autoselect=True, 77 left_widget=cancel_button, 78 label=bui.Lstr(resource='saveText'), 79 text_scale=1.2, 80 ) 81 82 if bui.app.ui_v1.use_toolbars: 83 bui.widget( 84 edit=btn, 85 right_widget=bui.get_special_widget('party_button'), 86 ) 87 88 bui.widget( 89 edit=cancel_button, 90 left_widget=cancel_button, 91 right_widget=save_button, 92 ) 93 94 bui.textwidget( 95 parent=self._root_widget, 96 position=(-10, self._height - 50), 97 size=(self._width, 25), 98 text=bui.Lstr(resource=self._r + '.titleText'), 99 color=bui.app.ui_v1.title_color, 100 scale=1.05, 101 h_align='center', 102 v_align='center', 103 maxwidth=270, 104 ) 105 106 v = self._height - 115.0 107 108 self._scroll_width = self._width - (205 + 2 * x_inset) 109 110 bui.textwidget( 111 parent=self._root_widget, 112 text=bui.Lstr(resource=self._r + '.listNameText'), 113 position=(196 + x_inset, v + 31), 114 maxwidth=150, 115 color=(0.8, 0.8, 0.8, 0.5), 116 size=(0, 0), 117 scale=0.75, 118 h_align='right', 119 v_align='center', 120 ) 121 122 self._text_field = bui.textwidget( 123 parent=self._root_widget, 124 position=(210 + x_inset, v + 7), 125 size=(self._scroll_width - 53, 43), 126 text=self._editcontroller.getname(), 127 h_align='left', 128 v_align='center', 129 max_chars=40, 130 autoselect=True, 131 color=(0.9, 0.9, 0.9, 1.0), 132 description=bui.Lstr(resource=self._r + '.listNameText'), 133 editable=True, 134 padding=4, 135 on_return_press_call=self._save_press_with_sound, 136 ) 137 bui.widget(edit=cancel_button, down_widget=self._text_field) 138 139 self._list_widgets: list[bui.Widget] = [] 140 141 h = 40 + x_inset 142 v = self._height - 172.0 143 144 b_color = (0.6, 0.53, 0.63) 145 b_textcolor = (0.75, 0.7, 0.8) 146 147 v -= 2.0 148 v += 63 149 150 scl = ( 151 1.03 152 if uiscale is bui.UIScale.SMALL 153 else 1.36 154 if uiscale is bui.UIScale.MEDIUM 155 else 1.74 156 ) 157 v -= 63.0 * scl 158 159 add_game_button = bui.buttonwidget( 160 parent=self._root_widget, 161 position=(h, v), 162 size=(110, 61.0 * scl), 163 on_activate_call=self._add, 164 on_select_call=bui.Call(self._set_ui_selection, 'add_button'), 165 autoselect=True, 166 button_type='square', 167 color=b_color, 168 textcolor=b_textcolor, 169 text_scale=0.8, 170 label=bui.Lstr(resource=self._r + '.addGameText'), 171 ) 172 bui.widget(edit=add_game_button, up_widget=self._text_field) 173 v -= 63.0 * scl 174 175 self._edit_button = edit_game_button = bui.buttonwidget( 176 parent=self._root_widget, 177 position=(h, v), 178 size=(110, 61.0 * scl), 179 on_activate_call=self._edit, 180 on_select_call=bui.Call(self._set_ui_selection, 'editButton'), 181 autoselect=True, 182 button_type='square', 183 color=b_color, 184 textcolor=b_textcolor, 185 text_scale=0.8, 186 label=bui.Lstr(resource=self._r + '.editGameText'), 187 ) 188 v -= 63.0 * scl 189 190 remove_game_button = bui.buttonwidget( 191 parent=self._root_widget, 192 position=(h, v), 193 size=(110, 61.0 * scl), 194 text_scale=0.8, 195 on_activate_call=self._remove, 196 autoselect=True, 197 button_type='square', 198 color=b_color, 199 textcolor=b_textcolor, 200 label=bui.Lstr(resource=self._r + '.removeGameText'), 201 ) 202 v -= 40 203 h += 9 204 bui.buttonwidget( 205 parent=self._root_widget, 206 position=(h, v), 207 size=(42, 35), 208 on_activate_call=self._move_up, 209 label=bui.charstr(bui.SpecialChar.UP_ARROW), 210 button_type='square', 211 color=b_color, 212 textcolor=b_textcolor, 213 autoselect=True, 214 repeat=True, 215 ) 216 h += 52 217 bui.buttonwidget( 218 parent=self._root_widget, 219 position=(h, v), 220 size=(42, 35), 221 on_activate_call=self._move_down, 222 autoselect=True, 223 button_type='square', 224 color=b_color, 225 textcolor=b_textcolor, 226 label=bui.charstr(bui.SpecialChar.DOWN_ARROW), 227 repeat=True, 228 ) 229 230 v = self._height - 100 231 scroll_height = self._height - 155 232 scrollwidget = bui.scrollwidget( 233 parent=self._root_widget, 234 position=(160 + x_inset, v - scroll_height), 235 highlight=False, 236 on_select_call=bui.Call(self._set_ui_selection, 'gameList'), 237 size=(self._scroll_width, (scroll_height - 15)), 238 ) 239 bui.widget( 240 edit=scrollwidget, 241 left_widget=add_game_button, 242 right_widget=scrollwidget, 243 ) 244 self._columnwidget = bui.columnwidget( 245 parent=scrollwidget, border=2, margin=0 246 ) 247 bui.widget(edit=self._columnwidget, up_widget=self._text_field) 248 249 for button in [add_game_button, edit_game_button, remove_game_button]: 250 bui.widget( 251 edit=button, left_widget=button, right_widget=scrollwidget 252 ) 253 254 self._refresh() 255 256 bui.buttonwidget(edit=cancel_button, on_activate_call=self._cancel) 257 bui.containerwidget( 258 edit=self._root_widget, 259 cancel_button=cancel_button, 260 selected_child=scrollwidget, 261 ) 262 263 bui.buttonwidget(edit=save_button, on_activate_call=self._save_press) 264 bui.containerwidget(edit=self._root_widget, start_button=save_button) 265 266 if prev_selection == 'add_button': 267 bui.containerwidget( 268 edit=self._root_widget, selected_child=add_game_button 269 ) 270 elif prev_selection == 'editButton': 271 bui.containerwidget( 272 edit=self._root_widget, selected_child=edit_game_button 273 ) 274 elif prev_selection == 'gameList': 275 bui.containerwidget( 276 edit=self._root_widget, selected_child=scrollwidget 277 )
Inherited Members
- bauiv1._uitypes.Window
- get_root_widget