bauiv1lib.playlist.addgame
Provides a window for selecting a game type to add to a playlist.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Provides a window for selecting a game type to add to a playlist.""" 4 5from __future__ import annotations 6 7from typing import TYPE_CHECKING 8 9import bascenev1 as bs 10import bauiv1 as bui 11 12if TYPE_CHECKING: 13 from bauiv1lib.playlist.editcontroller import PlaylistEditController 14 15 16class PlaylistAddGameWindow(bui.Window): 17 """Window for selecting a game type to add to a playlist.""" 18 19 def __init__( 20 self, 21 editcontroller: PlaylistEditController, 22 transition: str = 'in_right', 23 ): 24 self._editcontroller = editcontroller 25 self._r = 'addGameWindow' 26 assert bui.app.classic is not None 27 uiscale = bui.app.ui_v1.uiscale 28 self._width = 750 if uiscale is bui.UIScale.SMALL else 650 29 x_inset = 50 if uiscale is bui.UIScale.SMALL else 0 30 self._height = ( 31 346 32 if uiscale is bui.UIScale.SMALL 33 else 380 34 if uiscale is bui.UIScale.MEDIUM 35 else 440 36 ) 37 top_extra = 30 if uiscale is bui.UIScale.SMALL else 20 38 self._scroll_width = 210 39 40 super().__init__( 41 root_widget=bui.containerwidget( 42 size=(self._width, self._height + top_extra), 43 transition=transition, 44 scale=( 45 2.17 46 if uiscale is bui.UIScale.SMALL 47 else 1.5 48 if uiscale is bui.UIScale.MEDIUM 49 else 1.0 50 ), 51 stack_offset=(0, 1) if uiscale is bui.UIScale.SMALL else (0, 0), 52 ) 53 ) 54 55 self._back_button = bui.buttonwidget( 56 parent=self._root_widget, 57 position=(58 + x_inset, self._height - 53), 58 size=(165, 70), 59 scale=0.75, 60 text_scale=1.2, 61 label=bui.Lstr(resource='backText'), 62 autoselect=True, 63 button_type='back', 64 on_activate_call=self._back, 65 ) 66 self._select_button = select_button = bui.buttonwidget( 67 parent=self._root_widget, 68 position=(self._width - (172 + x_inset), self._height - 50), 69 autoselect=True, 70 size=(160, 60), 71 scale=0.75, 72 text_scale=1.2, 73 label=bui.Lstr(resource='selectText'), 74 on_activate_call=self._add, 75 ) 76 77 if bui.app.ui_v1.use_toolbars: 78 bui.widget( 79 edit=select_button, 80 right_widget=bui.get_special_widget('party_button'), 81 ) 82 83 bui.textwidget( 84 parent=self._root_widget, 85 position=(self._width * 0.5, self._height - 28), 86 size=(0, 0), 87 scale=1.0, 88 text=bui.Lstr(resource=self._r + '.titleText'), 89 h_align='center', 90 color=bui.app.ui_v1.title_color, 91 maxwidth=250, 92 v_align='center', 93 ) 94 v = self._height - 64 95 96 self._selected_title_text = bui.textwidget( 97 parent=self._root_widget, 98 position=(x_inset + self._scroll_width + 50 + 30, v - 15), 99 size=(0, 0), 100 scale=1.0, 101 color=(0.7, 1.0, 0.7, 1.0), 102 maxwidth=self._width - self._scroll_width - 150 - x_inset * 2, 103 h_align='left', 104 v_align='center', 105 ) 106 v -= 30 107 108 self._selected_description_text = bui.textwidget( 109 parent=self._root_widget, 110 position=(x_inset + self._scroll_width + 50 + 30, v), 111 size=(0, 0), 112 scale=0.7, 113 color=(0.5, 0.8, 0.5, 1.0), 114 maxwidth=self._width - self._scroll_width - 150 - x_inset * 2, 115 h_align='left', 116 ) 117 118 scroll_height = self._height - 100 119 120 v = self._height - 60 121 122 self._scrollwidget = bui.scrollwidget( 123 parent=self._root_widget, 124 position=(x_inset + 61, v - scroll_height), 125 size=(self._scroll_width, scroll_height), 126 highlight=False, 127 ) 128 bui.widget( 129 edit=self._scrollwidget, 130 up_widget=self._back_button, 131 left_widget=self._back_button, 132 right_widget=select_button, 133 ) 134 self._column: bui.Widget | None = None 135 136 v -= 35 137 bui.containerwidget( 138 edit=self._root_widget, 139 cancel_button=self._back_button, 140 start_button=select_button, 141 ) 142 self._selected_game_type: type[bs.GameActivity] | None = None 143 144 bui.containerwidget( 145 edit=self._root_widget, selected_child=self._scrollwidget 146 ) 147 148 self._game_types: list[type[bs.GameActivity]] = [] 149 150 # Get actual games loading in the bg. 151 bui.app.meta.load_exported_classes( 152 bs.GameActivity, 153 self._on_game_types_loaded, 154 completion_cb_in_bg_thread=True, 155 ) 156 157 # Refresh with our initial empty list. We'll refresh again once 158 # game loading is complete. 159 self._refresh() 160 161 def _on_game_types_loaded( 162 self, gametypes: list[type[bs.GameActivity]] 163 ) -> None: 164 assert bui.app.classic is not None 165 store = bui.app.classic.store 166 167 # We asked for a bg thread completion cb so we can do some 168 # filtering here in the bg thread where its not gonna cause hitches. 169 assert not bui.in_logic_thread() 170 sessiontype = self._editcontroller.get_session_type() 171 unowned = store.get_unowned_game_types() 172 self._game_types = [ 173 gt 174 for gt in gametypes 175 if gt not in unowned and gt.supports_session_type(sessiontype) 176 ] 177 178 # Sort in the current language. 179 self._game_types.sort(key=lambda g: g.get_display_string().evaluate()) 180 181 # Tell ourself to refresh back in the logic thread. 182 bui.pushcall(self._refresh, from_other_thread=True) 183 184 def _refresh(self, select_get_more_games_button: bool = False) -> None: 185 if self._column is not None: 186 self._column.delete() 187 188 self._column = bui.columnwidget( 189 parent=self._scrollwidget, border=2, margin=0 190 ) 191 192 for i, gametype in enumerate(self._game_types): 193 194 def _doit() -> None: 195 if self._select_button: 196 bui.apptimer(0.1, self._select_button.activate) 197 198 txt = bui.textwidget( 199 parent=self._column, 200 position=(0, 0), 201 size=(self._width - 88, 24), 202 text=gametype.get_display_string(), 203 h_align='left', 204 v_align='center', 205 color=(0.8, 0.8, 0.8, 1.0), 206 maxwidth=self._scroll_width * 0.8, 207 on_select_call=bui.Call(self._set_selected_game_type, gametype), 208 always_highlight=True, 209 selectable=True, 210 on_activate_call=_doit, 211 ) 212 if i == 0: 213 bui.widget(edit=txt, up_widget=self._back_button) 214 215 self._get_more_games_button = bui.buttonwidget( 216 parent=self._column, 217 autoselect=True, 218 label=bui.Lstr(resource=self._r + '.getMoreGamesText'), 219 color=(0.54, 0.52, 0.67), 220 textcolor=(0.7, 0.65, 0.7), 221 on_activate_call=self._on_get_more_games_press, 222 size=(178, 50), 223 ) 224 if select_get_more_games_button: 225 bui.containerwidget( 226 edit=self._column, 227 selected_child=self._get_more_games_button, 228 visible_child=self._get_more_games_button, 229 ) 230 231 def _on_get_more_games_press(self) -> None: 232 from bauiv1lib.account import show_sign_in_prompt 233 from bauiv1lib.store.browser import StoreBrowserWindow 234 235 plus = bui.app.plus 236 assert plus is not None 237 238 if plus.get_v1_account_state() != 'signed_in': 239 show_sign_in_prompt() 240 return 241 StoreBrowserWindow( 242 modal=True, 243 show_tab=StoreBrowserWindow.TabID.MINIGAMES, 244 on_close_call=self._on_store_close, 245 origin_widget=self._get_more_games_button, 246 ) 247 248 def _on_store_close(self) -> None: 249 self._refresh(select_get_more_games_button=True) 250 251 def _add(self) -> None: 252 bui.lock_all_input() # Make sure no more commands happen. 253 bui.apptimer(0.1, bui.unlock_all_input) 254 assert self._selected_game_type is not None 255 self._editcontroller.add_game_type_selected(self._selected_game_type) 256 257 def _set_selected_game_type(self, gametype: type[bs.GameActivity]) -> None: 258 self._selected_game_type = gametype 259 bui.textwidget( 260 edit=self._selected_title_text, text=gametype.get_display_string() 261 ) 262 bui.textwidget( 263 edit=self._selected_description_text, 264 text=gametype.get_description_display_string( 265 self._editcontroller.get_session_type() 266 ), 267 ) 268 269 def _back(self) -> None: 270 self._editcontroller.add_game_cancelled()
class
PlaylistAddGameWindow(bauiv1._uitypes.Window):
17class PlaylistAddGameWindow(bui.Window): 18 """Window for selecting a game type to add to a playlist.""" 19 20 def __init__( 21 self, 22 editcontroller: PlaylistEditController, 23 transition: str = 'in_right', 24 ): 25 self._editcontroller = editcontroller 26 self._r = 'addGameWindow' 27 assert bui.app.classic is not None 28 uiscale = bui.app.ui_v1.uiscale 29 self._width = 750 if uiscale is bui.UIScale.SMALL else 650 30 x_inset = 50 if uiscale is bui.UIScale.SMALL else 0 31 self._height = ( 32 346 33 if uiscale is bui.UIScale.SMALL 34 else 380 35 if uiscale is bui.UIScale.MEDIUM 36 else 440 37 ) 38 top_extra = 30 if uiscale is bui.UIScale.SMALL else 20 39 self._scroll_width = 210 40 41 super().__init__( 42 root_widget=bui.containerwidget( 43 size=(self._width, self._height + top_extra), 44 transition=transition, 45 scale=( 46 2.17 47 if uiscale is bui.UIScale.SMALL 48 else 1.5 49 if uiscale is bui.UIScale.MEDIUM 50 else 1.0 51 ), 52 stack_offset=(0, 1) if uiscale is bui.UIScale.SMALL else (0, 0), 53 ) 54 ) 55 56 self._back_button = bui.buttonwidget( 57 parent=self._root_widget, 58 position=(58 + x_inset, self._height - 53), 59 size=(165, 70), 60 scale=0.75, 61 text_scale=1.2, 62 label=bui.Lstr(resource='backText'), 63 autoselect=True, 64 button_type='back', 65 on_activate_call=self._back, 66 ) 67 self._select_button = select_button = bui.buttonwidget( 68 parent=self._root_widget, 69 position=(self._width - (172 + x_inset), self._height - 50), 70 autoselect=True, 71 size=(160, 60), 72 scale=0.75, 73 text_scale=1.2, 74 label=bui.Lstr(resource='selectText'), 75 on_activate_call=self._add, 76 ) 77 78 if bui.app.ui_v1.use_toolbars: 79 bui.widget( 80 edit=select_button, 81 right_widget=bui.get_special_widget('party_button'), 82 ) 83 84 bui.textwidget( 85 parent=self._root_widget, 86 position=(self._width * 0.5, self._height - 28), 87 size=(0, 0), 88 scale=1.0, 89 text=bui.Lstr(resource=self._r + '.titleText'), 90 h_align='center', 91 color=bui.app.ui_v1.title_color, 92 maxwidth=250, 93 v_align='center', 94 ) 95 v = self._height - 64 96 97 self._selected_title_text = bui.textwidget( 98 parent=self._root_widget, 99 position=(x_inset + self._scroll_width + 50 + 30, v - 15), 100 size=(0, 0), 101 scale=1.0, 102 color=(0.7, 1.0, 0.7, 1.0), 103 maxwidth=self._width - self._scroll_width - 150 - x_inset * 2, 104 h_align='left', 105 v_align='center', 106 ) 107 v -= 30 108 109 self._selected_description_text = bui.textwidget( 110 parent=self._root_widget, 111 position=(x_inset + self._scroll_width + 50 + 30, v), 112 size=(0, 0), 113 scale=0.7, 114 color=(0.5, 0.8, 0.5, 1.0), 115 maxwidth=self._width - self._scroll_width - 150 - x_inset * 2, 116 h_align='left', 117 ) 118 119 scroll_height = self._height - 100 120 121 v = self._height - 60 122 123 self._scrollwidget = bui.scrollwidget( 124 parent=self._root_widget, 125 position=(x_inset + 61, v - scroll_height), 126 size=(self._scroll_width, scroll_height), 127 highlight=False, 128 ) 129 bui.widget( 130 edit=self._scrollwidget, 131 up_widget=self._back_button, 132 left_widget=self._back_button, 133 right_widget=select_button, 134 ) 135 self._column: bui.Widget | None = None 136 137 v -= 35 138 bui.containerwidget( 139 edit=self._root_widget, 140 cancel_button=self._back_button, 141 start_button=select_button, 142 ) 143 self._selected_game_type: type[bs.GameActivity] | None = None 144 145 bui.containerwidget( 146 edit=self._root_widget, selected_child=self._scrollwidget 147 ) 148 149 self._game_types: list[type[bs.GameActivity]] = [] 150 151 # Get actual games loading in the bg. 152 bui.app.meta.load_exported_classes( 153 bs.GameActivity, 154 self._on_game_types_loaded, 155 completion_cb_in_bg_thread=True, 156 ) 157 158 # Refresh with our initial empty list. We'll refresh again once 159 # game loading is complete. 160 self._refresh() 161 162 def _on_game_types_loaded( 163 self, gametypes: list[type[bs.GameActivity]] 164 ) -> None: 165 assert bui.app.classic is not None 166 store = bui.app.classic.store 167 168 # We asked for a bg thread completion cb so we can do some 169 # filtering here in the bg thread where its not gonna cause hitches. 170 assert not bui.in_logic_thread() 171 sessiontype = self._editcontroller.get_session_type() 172 unowned = store.get_unowned_game_types() 173 self._game_types = [ 174 gt 175 for gt in gametypes 176 if gt not in unowned and gt.supports_session_type(sessiontype) 177 ] 178 179 # Sort in the current language. 180 self._game_types.sort(key=lambda g: g.get_display_string().evaluate()) 181 182 # Tell ourself to refresh back in the logic thread. 183 bui.pushcall(self._refresh, from_other_thread=True) 184 185 def _refresh(self, select_get_more_games_button: bool = False) -> None: 186 if self._column is not None: 187 self._column.delete() 188 189 self._column = bui.columnwidget( 190 parent=self._scrollwidget, border=2, margin=0 191 ) 192 193 for i, gametype in enumerate(self._game_types): 194 195 def _doit() -> None: 196 if self._select_button: 197 bui.apptimer(0.1, self._select_button.activate) 198 199 txt = bui.textwidget( 200 parent=self._column, 201 position=(0, 0), 202 size=(self._width - 88, 24), 203 text=gametype.get_display_string(), 204 h_align='left', 205 v_align='center', 206 color=(0.8, 0.8, 0.8, 1.0), 207 maxwidth=self._scroll_width * 0.8, 208 on_select_call=bui.Call(self._set_selected_game_type, gametype), 209 always_highlight=True, 210 selectable=True, 211 on_activate_call=_doit, 212 ) 213 if i == 0: 214 bui.widget(edit=txt, up_widget=self._back_button) 215 216 self._get_more_games_button = bui.buttonwidget( 217 parent=self._column, 218 autoselect=True, 219 label=bui.Lstr(resource=self._r + '.getMoreGamesText'), 220 color=(0.54, 0.52, 0.67), 221 textcolor=(0.7, 0.65, 0.7), 222 on_activate_call=self._on_get_more_games_press, 223 size=(178, 50), 224 ) 225 if select_get_more_games_button: 226 bui.containerwidget( 227 edit=self._column, 228 selected_child=self._get_more_games_button, 229 visible_child=self._get_more_games_button, 230 ) 231 232 def _on_get_more_games_press(self) -> None: 233 from bauiv1lib.account import show_sign_in_prompt 234 from bauiv1lib.store.browser import StoreBrowserWindow 235 236 plus = bui.app.plus 237 assert plus is not None 238 239 if plus.get_v1_account_state() != 'signed_in': 240 show_sign_in_prompt() 241 return 242 StoreBrowserWindow( 243 modal=True, 244 show_tab=StoreBrowserWindow.TabID.MINIGAMES, 245 on_close_call=self._on_store_close, 246 origin_widget=self._get_more_games_button, 247 ) 248 249 def _on_store_close(self) -> None: 250 self._refresh(select_get_more_games_button=True) 251 252 def _add(self) -> None: 253 bui.lock_all_input() # Make sure no more commands happen. 254 bui.apptimer(0.1, bui.unlock_all_input) 255 assert self._selected_game_type is not None 256 self._editcontroller.add_game_type_selected(self._selected_game_type) 257 258 def _set_selected_game_type(self, gametype: type[bs.GameActivity]) -> None: 259 self._selected_game_type = gametype 260 bui.textwidget( 261 edit=self._selected_title_text, text=gametype.get_display_string() 262 ) 263 bui.textwidget( 264 edit=self._selected_description_text, 265 text=gametype.get_description_display_string( 266 self._editcontroller.get_session_type() 267 ), 268 ) 269 270 def _back(self) -> None: 271 self._editcontroller.add_game_cancelled()
Window for selecting a game type to add to a playlist.
PlaylistAddGameWindow( editcontroller: bauiv1lib.playlist.editcontroller.PlaylistEditController, transition: str = 'in_right')
20 def __init__( 21 self, 22 editcontroller: PlaylistEditController, 23 transition: str = 'in_right', 24 ): 25 self._editcontroller = editcontroller 26 self._r = 'addGameWindow' 27 assert bui.app.classic is not None 28 uiscale = bui.app.ui_v1.uiscale 29 self._width = 750 if uiscale is bui.UIScale.SMALL else 650 30 x_inset = 50 if uiscale is bui.UIScale.SMALL else 0 31 self._height = ( 32 346 33 if uiscale is bui.UIScale.SMALL 34 else 380 35 if uiscale is bui.UIScale.MEDIUM 36 else 440 37 ) 38 top_extra = 30 if uiscale is bui.UIScale.SMALL else 20 39 self._scroll_width = 210 40 41 super().__init__( 42 root_widget=bui.containerwidget( 43 size=(self._width, self._height + top_extra), 44 transition=transition, 45 scale=( 46 2.17 47 if uiscale is bui.UIScale.SMALL 48 else 1.5 49 if uiscale is bui.UIScale.MEDIUM 50 else 1.0 51 ), 52 stack_offset=(0, 1) if uiscale is bui.UIScale.SMALL else (0, 0), 53 ) 54 ) 55 56 self._back_button = bui.buttonwidget( 57 parent=self._root_widget, 58 position=(58 + x_inset, self._height - 53), 59 size=(165, 70), 60 scale=0.75, 61 text_scale=1.2, 62 label=bui.Lstr(resource='backText'), 63 autoselect=True, 64 button_type='back', 65 on_activate_call=self._back, 66 ) 67 self._select_button = select_button = bui.buttonwidget( 68 parent=self._root_widget, 69 position=(self._width - (172 + x_inset), self._height - 50), 70 autoselect=True, 71 size=(160, 60), 72 scale=0.75, 73 text_scale=1.2, 74 label=bui.Lstr(resource='selectText'), 75 on_activate_call=self._add, 76 ) 77 78 if bui.app.ui_v1.use_toolbars: 79 bui.widget( 80 edit=select_button, 81 right_widget=bui.get_special_widget('party_button'), 82 ) 83 84 bui.textwidget( 85 parent=self._root_widget, 86 position=(self._width * 0.5, self._height - 28), 87 size=(0, 0), 88 scale=1.0, 89 text=bui.Lstr(resource=self._r + '.titleText'), 90 h_align='center', 91 color=bui.app.ui_v1.title_color, 92 maxwidth=250, 93 v_align='center', 94 ) 95 v = self._height - 64 96 97 self._selected_title_text = bui.textwidget( 98 parent=self._root_widget, 99 position=(x_inset + self._scroll_width + 50 + 30, v - 15), 100 size=(0, 0), 101 scale=1.0, 102 color=(0.7, 1.0, 0.7, 1.0), 103 maxwidth=self._width - self._scroll_width - 150 - x_inset * 2, 104 h_align='left', 105 v_align='center', 106 ) 107 v -= 30 108 109 self._selected_description_text = bui.textwidget( 110 parent=self._root_widget, 111 position=(x_inset + self._scroll_width + 50 + 30, v), 112 size=(0, 0), 113 scale=0.7, 114 color=(0.5, 0.8, 0.5, 1.0), 115 maxwidth=self._width - self._scroll_width - 150 - x_inset * 2, 116 h_align='left', 117 ) 118 119 scroll_height = self._height - 100 120 121 v = self._height - 60 122 123 self._scrollwidget = bui.scrollwidget( 124 parent=self._root_widget, 125 position=(x_inset + 61, v - scroll_height), 126 size=(self._scroll_width, scroll_height), 127 highlight=False, 128 ) 129 bui.widget( 130 edit=self._scrollwidget, 131 up_widget=self._back_button, 132 left_widget=self._back_button, 133 right_widget=select_button, 134 ) 135 self._column: bui.Widget | None = None 136 137 v -= 35 138 bui.containerwidget( 139 edit=self._root_widget, 140 cancel_button=self._back_button, 141 start_button=select_button, 142 ) 143 self._selected_game_type: type[bs.GameActivity] | None = None 144 145 bui.containerwidget( 146 edit=self._root_widget, selected_child=self._scrollwidget 147 ) 148 149 self._game_types: list[type[bs.GameActivity]] = [] 150 151 # Get actual games loading in the bg. 152 bui.app.meta.load_exported_classes( 153 bs.GameActivity, 154 self._on_game_types_loaded, 155 completion_cb_in_bg_thread=True, 156 ) 157 158 # Refresh with our initial empty list. We'll refresh again once 159 # game loading is complete. 160 self._refresh()
Inherited Members
- bauiv1._uitypes.Window
- get_root_widget