bauiv1lib.playlist.mapselect
Provides UI for selecting maps in playlists.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Provides UI for selecting maps in playlists.""" 4 5from __future__ import annotations 6 7import math 8from typing import TYPE_CHECKING, override 9 10import bauiv1 as bui 11 12if TYPE_CHECKING: 13 from typing import Any, Callable 14 15 import bascenev1 as bs 16 17 18class PlaylistMapSelectWindow(bui.MainWindow): 19 """Window to select a map.""" 20 21 def __init__( 22 self, 23 gametype: type[bs.GameActivity], 24 sessiontype: type[bs.Session], 25 config: dict[str, Any], 26 edit_info: dict[str, Any], 27 completion_call: Callable[[dict[str, Any] | None, bui.MainWindow], Any], 28 transition: str | None = 'in_right', 29 origin_widget: bui.Widget | None = None, 30 select_get_more_maps_button: bool = False, 31 ): 32 # pylint: disable=too-many-locals 33 # pylint: disable=too-many-positional-arguments 34 35 from bascenev1 import get_filtered_map_name 36 37 self._gametype = gametype 38 self._sessiontype = sessiontype 39 self._config = config 40 self._completion_call = completion_call 41 self._edit_info = edit_info 42 self._maps: list[tuple[str, bui.Texture]] = [] 43 self._selected_get_more_maps = False 44 try: 45 self._previous_map = get_filtered_map_name( 46 config['settings']['map'] 47 ) 48 except Exception: 49 self._previous_map = '' 50 51 assert bui.app.classic is not None 52 uiscale = bui.app.ui_v1.uiscale 53 width = 815 if uiscale is bui.UIScale.SMALL else 615 54 x_inset = 100 if uiscale is bui.UIScale.SMALL else 0 55 height = ( 56 420 57 if uiscale is bui.UIScale.SMALL 58 else 480 if uiscale is bui.UIScale.MEDIUM else 600 59 ) 60 yoffs = -37 if uiscale is bui.UIScale.SMALL else 0 61 62 super().__init__( 63 root_widget=bui.containerwidget( 64 size=(width, height), 65 scale=( 66 1.95 67 if uiscale is bui.UIScale.SMALL 68 else 1.3 if uiscale is bui.UIScale.MEDIUM else 1.0 69 ), 70 stack_offset=( 71 (0, 0) if uiscale is bui.UIScale.SMALL else (0, 0) 72 ), 73 ), 74 transition=transition, 75 origin_widget=origin_widget, 76 ) 77 78 self._cancel_button = btn = bui.buttonwidget( 79 parent=self._root_widget, 80 position=(38 + x_inset, height - 67 + yoffs), 81 size=(140, 50), 82 scale=0.9, 83 text_scale=1.0, 84 autoselect=True, 85 label=bui.Lstr(resource='cancelText'), 86 on_activate_call=self.main_window_back, 87 ) 88 89 bui.containerwidget(edit=self._root_widget, cancel_button=btn) 90 bui.textwidget( 91 parent=self._root_widget, 92 position=(width * 0.5, height - 46 + yoffs), 93 size=(0, 0), 94 maxwidth=260, 95 scale=1.1, 96 text=bui.Lstr( 97 resource='mapSelectTitleText', 98 subs=[('${GAME}', self._gametype.get_display_string())], 99 ), 100 color=bui.app.ui_v1.title_color, 101 h_align='center', 102 v_align='center', 103 ) 104 v = height - 70 + yoffs 105 self._scroll_width = width - (80 + 2 * x_inset) 106 self._scroll_height = height - ( 107 170 if uiscale is bui.UIScale.SMALL else 140 108 ) 109 110 self._scrollwidget = bui.scrollwidget( 111 parent=self._root_widget, 112 position=(40 + x_inset, v - self._scroll_height), 113 size=(self._scroll_width, self._scroll_height), 114 border_opacity=0.4, 115 ) 116 bui.containerwidget( 117 edit=self._root_widget, selected_child=self._scrollwidget 118 ) 119 bui.containerwidget(edit=self._scrollwidget, claims_left_right=True) 120 121 self._subcontainer: bui.Widget | None = None 122 self._refresh(select_get_more_maps_button=select_get_more_maps_button) 123 124 @override 125 def get_main_window_state(self) -> bui.MainWindowState: 126 # Support recreating our window for back/refresh purposes. 127 cls = type(self) 128 129 # Pull things out of self here; if we do it in the lambda we'll 130 # keep ourself alive. 131 gametype = self._gametype 132 sessiontype = self._sessiontype 133 config = self._config 134 edit_info = self._edit_info 135 completion_call = self._completion_call 136 select_get_more_maps = self._selected_get_more_maps 137 138 return bui.BasicMainWindowState( 139 create_call=lambda transition, origin_widget: cls( 140 transition=transition, 141 origin_widget=origin_widget, 142 gametype=gametype, 143 sessiontype=sessiontype, 144 config=config, 145 edit_info=edit_info, 146 completion_call=completion_call, 147 select_get_more_maps_button=select_get_more_maps, 148 ) 149 ) 150 151 def _refresh(self, select_get_more_maps_button: bool = False) -> None: 152 # pylint: disable=too-many-statements 153 # pylint: disable=too-many-branches 154 # pylint: disable=too-many-locals 155 from bascenev1 import ( 156 get_map_class, 157 get_map_display_string, 158 ) 159 160 assert bui.app.classic is not None 161 store = bui.app.classic.store 162 # Kill old. 163 if self._subcontainer is not None: 164 self._subcontainer.delete() 165 166 mesh_opaque = bui.getmesh('level_select_button_opaque') 167 mesh_transparent = bui.getmesh('level_select_button_transparent') 168 169 self._maps = [] 170 map_list = self._gametype.get_supported_maps(self._sessiontype) 171 map_list_sorted = list(map_list) 172 map_list_sorted.sort() 173 unowned_maps = store.get_unowned_maps() 174 175 for mapname in map_list_sorted: 176 # Disallow ones we don't own. 177 if mapname in unowned_maps: 178 continue 179 map_tex_name = get_map_class(mapname).get_preview_texture_name() 180 if map_tex_name is not None: 181 try: 182 map_tex = bui.gettexture(map_tex_name) 183 self._maps.append((mapname, map_tex)) 184 except Exception: 185 print(f'Invalid map preview texture: "{map_tex_name}".') 186 else: 187 print('Error: no map preview texture for map:', mapname) 188 189 count = len(self._maps) 190 columns = 2 191 rows = int(math.ceil(float(count) / columns)) 192 button_width = 220 193 button_height = button_width * 0.5 194 button_buffer_h = 16 195 button_buffer_v = 19 196 self._sub_width = self._scroll_width * 0.95 197 self._sub_height = ( 198 5 + rows * (button_height + 2 * button_buffer_v) + 100 199 ) 200 self._subcontainer = bui.containerwidget( 201 parent=self._scrollwidget, 202 size=(self._sub_width, self._sub_height), 203 background=False, 204 ) 205 index = 0 206 mask_texture = bui.gettexture('mapPreviewMask') 207 h_offs = 130 if len(self._maps) == 1 else 0 208 for y in range(rows): 209 for x in range(columns): 210 pos = ( 211 x * (button_width + 2 * button_buffer_h) 212 + button_buffer_h 213 + h_offs, 214 self._sub_height 215 - (y + 1) * (button_height + 2 * button_buffer_v) 216 + 12, 217 ) 218 btn = bui.buttonwidget( 219 parent=self._subcontainer, 220 button_type='square', 221 size=(button_width, button_height), 222 autoselect=True, 223 texture=self._maps[index][1], 224 mask_texture=mask_texture, 225 mesh_opaque=mesh_opaque, 226 mesh_transparent=mesh_transparent, 227 label='', 228 color=(1, 1, 1), 229 on_activate_call=bui.Call( 230 self._select_with_delay, self._maps[index][0] 231 ), 232 position=pos, 233 ) 234 if x == 0: 235 bui.widget(edit=btn, left_widget=self._cancel_button) 236 if y == 0: 237 bui.widget(edit=btn, up_widget=self._cancel_button) 238 if x == columns - 1: 239 bui.widget( 240 edit=btn, 241 right_widget=bui.get_special_widget('squad_button'), 242 ) 243 244 bui.widget(edit=btn, show_buffer_top=60, show_buffer_bottom=60) 245 if self._maps[index][0] == self._previous_map: 246 bui.containerwidget( 247 edit=self._subcontainer, 248 selected_child=btn, 249 visible_child=btn, 250 ) 251 name = get_map_display_string(self._maps[index][0]) 252 bui.textwidget( 253 parent=self._subcontainer, 254 text=name, 255 position=(pos[0] + button_width * 0.5, pos[1] - 12), 256 size=(0, 0), 257 scale=0.5, 258 maxwidth=button_width, 259 draw_controller=btn, 260 h_align='center', 261 v_align='center', 262 color=(0.8, 0.8, 0.8, 0.8), 263 ) 264 index += 1 265 266 if index >= count: 267 break 268 if index >= count: 269 break 270 self._get_more_maps_button = btn = bui.buttonwidget( 271 parent=self._subcontainer, 272 size=(self._sub_width * 0.8, 60), 273 position=(self._sub_width * 0.1, 30), 274 label=bui.Lstr(resource='mapSelectGetMoreMapsText'), 275 on_activate_call=self._on_store_press, 276 color=(0.6, 0.53, 0.63), 277 textcolor=(0.75, 0.7, 0.8), 278 autoselect=True, 279 ) 280 bui.widget(edit=btn, show_buffer_top=30, show_buffer_bottom=30) 281 if select_get_more_maps_button: 282 bui.containerwidget( 283 edit=self._subcontainer, selected_child=btn, visible_child=btn 284 ) 285 286 def _on_store_press(self) -> None: 287 from bauiv1lib.account.signin import show_sign_in_prompt 288 from bauiv1lib.store.browser import StoreBrowserWindow 289 290 # No-op if we're not in control. 291 if not self.main_window_has_control(): 292 return 293 294 plus = bui.app.plus 295 assert plus is not None 296 297 if plus.get_v1_account_state() != 'signed_in': 298 show_sign_in_prompt() 299 return 300 301 self._selected_get_more_maps = True 302 303 self.main_window_replace( 304 StoreBrowserWindow( 305 show_tab=StoreBrowserWindow.TabID.MAPS, 306 origin_widget=self._get_more_maps_button, 307 minimal_toolbars=True, 308 ) 309 ) 310 311 def _select(self, map_name: str) -> None: 312 313 # no-op if our underlying widget is dead or on its way out. 314 if not self.main_window_has_control(): 315 return 316 317 self._config['settings']['map'] = map_name 318 self.main_window_back() 319 320 def _select_with_delay(self, map_name: str) -> None: 321 bui.lock_all_input() 322 bui.apptimer(0.1, bui.unlock_all_input) 323 bui.apptimer(0.1, bui.WeakCall(self._select, map_name))
class
PlaylistMapSelectWindow(bauiv1._uitypes.MainWindow):
19class PlaylistMapSelectWindow(bui.MainWindow): 20 """Window to select a map.""" 21 22 def __init__( 23 self, 24 gametype: type[bs.GameActivity], 25 sessiontype: type[bs.Session], 26 config: dict[str, Any], 27 edit_info: dict[str, Any], 28 completion_call: Callable[[dict[str, Any] | None, bui.MainWindow], Any], 29 transition: str | None = 'in_right', 30 origin_widget: bui.Widget | None = None, 31 select_get_more_maps_button: bool = False, 32 ): 33 # pylint: disable=too-many-locals 34 # pylint: disable=too-many-positional-arguments 35 36 from bascenev1 import get_filtered_map_name 37 38 self._gametype = gametype 39 self._sessiontype = sessiontype 40 self._config = config 41 self._completion_call = completion_call 42 self._edit_info = edit_info 43 self._maps: list[tuple[str, bui.Texture]] = [] 44 self._selected_get_more_maps = False 45 try: 46 self._previous_map = get_filtered_map_name( 47 config['settings']['map'] 48 ) 49 except Exception: 50 self._previous_map = '' 51 52 assert bui.app.classic is not None 53 uiscale = bui.app.ui_v1.uiscale 54 width = 815 if uiscale is bui.UIScale.SMALL else 615 55 x_inset = 100 if uiscale is bui.UIScale.SMALL else 0 56 height = ( 57 420 58 if uiscale is bui.UIScale.SMALL 59 else 480 if uiscale is bui.UIScale.MEDIUM else 600 60 ) 61 yoffs = -37 if uiscale is bui.UIScale.SMALL else 0 62 63 super().__init__( 64 root_widget=bui.containerwidget( 65 size=(width, height), 66 scale=( 67 1.95 68 if uiscale is bui.UIScale.SMALL 69 else 1.3 if uiscale is bui.UIScale.MEDIUM else 1.0 70 ), 71 stack_offset=( 72 (0, 0) if uiscale is bui.UIScale.SMALL else (0, 0) 73 ), 74 ), 75 transition=transition, 76 origin_widget=origin_widget, 77 ) 78 79 self._cancel_button = btn = bui.buttonwidget( 80 parent=self._root_widget, 81 position=(38 + x_inset, height - 67 + yoffs), 82 size=(140, 50), 83 scale=0.9, 84 text_scale=1.0, 85 autoselect=True, 86 label=bui.Lstr(resource='cancelText'), 87 on_activate_call=self.main_window_back, 88 ) 89 90 bui.containerwidget(edit=self._root_widget, cancel_button=btn) 91 bui.textwidget( 92 parent=self._root_widget, 93 position=(width * 0.5, height - 46 + yoffs), 94 size=(0, 0), 95 maxwidth=260, 96 scale=1.1, 97 text=bui.Lstr( 98 resource='mapSelectTitleText', 99 subs=[('${GAME}', self._gametype.get_display_string())], 100 ), 101 color=bui.app.ui_v1.title_color, 102 h_align='center', 103 v_align='center', 104 ) 105 v = height - 70 + yoffs 106 self._scroll_width = width - (80 + 2 * x_inset) 107 self._scroll_height = height - ( 108 170 if uiscale is bui.UIScale.SMALL else 140 109 ) 110 111 self._scrollwidget = bui.scrollwidget( 112 parent=self._root_widget, 113 position=(40 + x_inset, v - self._scroll_height), 114 size=(self._scroll_width, self._scroll_height), 115 border_opacity=0.4, 116 ) 117 bui.containerwidget( 118 edit=self._root_widget, selected_child=self._scrollwidget 119 ) 120 bui.containerwidget(edit=self._scrollwidget, claims_left_right=True) 121 122 self._subcontainer: bui.Widget | None = None 123 self._refresh(select_get_more_maps_button=select_get_more_maps_button) 124 125 @override 126 def get_main_window_state(self) -> bui.MainWindowState: 127 # Support recreating our window for back/refresh purposes. 128 cls = type(self) 129 130 # Pull things out of self here; if we do it in the lambda we'll 131 # keep ourself alive. 132 gametype = self._gametype 133 sessiontype = self._sessiontype 134 config = self._config 135 edit_info = self._edit_info 136 completion_call = self._completion_call 137 select_get_more_maps = self._selected_get_more_maps 138 139 return bui.BasicMainWindowState( 140 create_call=lambda transition, origin_widget: cls( 141 transition=transition, 142 origin_widget=origin_widget, 143 gametype=gametype, 144 sessiontype=sessiontype, 145 config=config, 146 edit_info=edit_info, 147 completion_call=completion_call, 148 select_get_more_maps_button=select_get_more_maps, 149 ) 150 ) 151 152 def _refresh(self, select_get_more_maps_button: bool = False) -> None: 153 # pylint: disable=too-many-statements 154 # pylint: disable=too-many-branches 155 # pylint: disable=too-many-locals 156 from bascenev1 import ( 157 get_map_class, 158 get_map_display_string, 159 ) 160 161 assert bui.app.classic is not None 162 store = bui.app.classic.store 163 # Kill old. 164 if self._subcontainer is not None: 165 self._subcontainer.delete() 166 167 mesh_opaque = bui.getmesh('level_select_button_opaque') 168 mesh_transparent = bui.getmesh('level_select_button_transparent') 169 170 self._maps = [] 171 map_list = self._gametype.get_supported_maps(self._sessiontype) 172 map_list_sorted = list(map_list) 173 map_list_sorted.sort() 174 unowned_maps = store.get_unowned_maps() 175 176 for mapname in map_list_sorted: 177 # Disallow ones we don't own. 178 if mapname in unowned_maps: 179 continue 180 map_tex_name = get_map_class(mapname).get_preview_texture_name() 181 if map_tex_name is not None: 182 try: 183 map_tex = bui.gettexture(map_tex_name) 184 self._maps.append((mapname, map_tex)) 185 except Exception: 186 print(f'Invalid map preview texture: "{map_tex_name}".') 187 else: 188 print('Error: no map preview texture for map:', mapname) 189 190 count = len(self._maps) 191 columns = 2 192 rows = int(math.ceil(float(count) / columns)) 193 button_width = 220 194 button_height = button_width * 0.5 195 button_buffer_h = 16 196 button_buffer_v = 19 197 self._sub_width = self._scroll_width * 0.95 198 self._sub_height = ( 199 5 + rows * (button_height + 2 * button_buffer_v) + 100 200 ) 201 self._subcontainer = bui.containerwidget( 202 parent=self._scrollwidget, 203 size=(self._sub_width, self._sub_height), 204 background=False, 205 ) 206 index = 0 207 mask_texture = bui.gettexture('mapPreviewMask') 208 h_offs = 130 if len(self._maps) == 1 else 0 209 for y in range(rows): 210 for x in range(columns): 211 pos = ( 212 x * (button_width + 2 * button_buffer_h) 213 + button_buffer_h 214 + h_offs, 215 self._sub_height 216 - (y + 1) * (button_height + 2 * button_buffer_v) 217 + 12, 218 ) 219 btn = bui.buttonwidget( 220 parent=self._subcontainer, 221 button_type='square', 222 size=(button_width, button_height), 223 autoselect=True, 224 texture=self._maps[index][1], 225 mask_texture=mask_texture, 226 mesh_opaque=mesh_opaque, 227 mesh_transparent=mesh_transparent, 228 label='', 229 color=(1, 1, 1), 230 on_activate_call=bui.Call( 231 self._select_with_delay, self._maps[index][0] 232 ), 233 position=pos, 234 ) 235 if x == 0: 236 bui.widget(edit=btn, left_widget=self._cancel_button) 237 if y == 0: 238 bui.widget(edit=btn, up_widget=self._cancel_button) 239 if x == columns - 1: 240 bui.widget( 241 edit=btn, 242 right_widget=bui.get_special_widget('squad_button'), 243 ) 244 245 bui.widget(edit=btn, show_buffer_top=60, show_buffer_bottom=60) 246 if self._maps[index][0] == self._previous_map: 247 bui.containerwidget( 248 edit=self._subcontainer, 249 selected_child=btn, 250 visible_child=btn, 251 ) 252 name = get_map_display_string(self._maps[index][0]) 253 bui.textwidget( 254 parent=self._subcontainer, 255 text=name, 256 position=(pos[0] + button_width * 0.5, pos[1] - 12), 257 size=(0, 0), 258 scale=0.5, 259 maxwidth=button_width, 260 draw_controller=btn, 261 h_align='center', 262 v_align='center', 263 color=(0.8, 0.8, 0.8, 0.8), 264 ) 265 index += 1 266 267 if index >= count: 268 break 269 if index >= count: 270 break 271 self._get_more_maps_button = btn = bui.buttonwidget( 272 parent=self._subcontainer, 273 size=(self._sub_width * 0.8, 60), 274 position=(self._sub_width * 0.1, 30), 275 label=bui.Lstr(resource='mapSelectGetMoreMapsText'), 276 on_activate_call=self._on_store_press, 277 color=(0.6, 0.53, 0.63), 278 textcolor=(0.75, 0.7, 0.8), 279 autoselect=True, 280 ) 281 bui.widget(edit=btn, show_buffer_top=30, show_buffer_bottom=30) 282 if select_get_more_maps_button: 283 bui.containerwidget( 284 edit=self._subcontainer, selected_child=btn, visible_child=btn 285 ) 286 287 def _on_store_press(self) -> None: 288 from bauiv1lib.account.signin import show_sign_in_prompt 289 from bauiv1lib.store.browser import StoreBrowserWindow 290 291 # No-op if we're not in control. 292 if not self.main_window_has_control(): 293 return 294 295 plus = bui.app.plus 296 assert plus is not None 297 298 if plus.get_v1_account_state() != 'signed_in': 299 show_sign_in_prompt() 300 return 301 302 self._selected_get_more_maps = True 303 304 self.main_window_replace( 305 StoreBrowserWindow( 306 show_tab=StoreBrowserWindow.TabID.MAPS, 307 origin_widget=self._get_more_maps_button, 308 minimal_toolbars=True, 309 ) 310 ) 311 312 def _select(self, map_name: str) -> None: 313 314 # no-op if our underlying widget is dead or on its way out. 315 if not self.main_window_has_control(): 316 return 317 318 self._config['settings']['map'] = map_name 319 self.main_window_back() 320 321 def _select_with_delay(self, map_name: str) -> None: 322 bui.lock_all_input() 323 bui.apptimer(0.1, bui.unlock_all_input) 324 bui.apptimer(0.1, bui.WeakCall(self._select, map_name))
Window to select a map.
PlaylistMapSelectWindow( gametype: type[bascenev1.GameActivity], sessiontype: type[bascenev1.Session], config: dict[str, typing.Any], edit_info: dict[str, typing.Any], completion_call: Callable[[dict[str, Any] | None, bauiv1.MainWindow], Any], transition: str | None = 'in_right', origin_widget: _bauiv1.Widget | None = None, select_get_more_maps_button: bool = False)
22 def __init__( 23 self, 24 gametype: type[bs.GameActivity], 25 sessiontype: type[bs.Session], 26 config: dict[str, Any], 27 edit_info: dict[str, Any], 28 completion_call: Callable[[dict[str, Any] | None, bui.MainWindow], Any], 29 transition: str | None = 'in_right', 30 origin_widget: bui.Widget | None = None, 31 select_get_more_maps_button: bool = False, 32 ): 33 # pylint: disable=too-many-locals 34 # pylint: disable=too-many-positional-arguments 35 36 from bascenev1 import get_filtered_map_name 37 38 self._gametype = gametype 39 self._sessiontype = sessiontype 40 self._config = config 41 self._completion_call = completion_call 42 self._edit_info = edit_info 43 self._maps: list[tuple[str, bui.Texture]] = [] 44 self._selected_get_more_maps = False 45 try: 46 self._previous_map = get_filtered_map_name( 47 config['settings']['map'] 48 ) 49 except Exception: 50 self._previous_map = '' 51 52 assert bui.app.classic is not None 53 uiscale = bui.app.ui_v1.uiscale 54 width = 815 if uiscale is bui.UIScale.SMALL else 615 55 x_inset = 100 if uiscale is bui.UIScale.SMALL else 0 56 height = ( 57 420 58 if uiscale is bui.UIScale.SMALL 59 else 480 if uiscale is bui.UIScale.MEDIUM else 600 60 ) 61 yoffs = -37 if uiscale is bui.UIScale.SMALL else 0 62 63 super().__init__( 64 root_widget=bui.containerwidget( 65 size=(width, height), 66 scale=( 67 1.95 68 if uiscale is bui.UIScale.SMALL 69 else 1.3 if uiscale is bui.UIScale.MEDIUM else 1.0 70 ), 71 stack_offset=( 72 (0, 0) if uiscale is bui.UIScale.SMALL else (0, 0) 73 ), 74 ), 75 transition=transition, 76 origin_widget=origin_widget, 77 ) 78 79 self._cancel_button = btn = bui.buttonwidget( 80 parent=self._root_widget, 81 position=(38 + x_inset, height - 67 + yoffs), 82 size=(140, 50), 83 scale=0.9, 84 text_scale=1.0, 85 autoselect=True, 86 label=bui.Lstr(resource='cancelText'), 87 on_activate_call=self.main_window_back, 88 ) 89 90 bui.containerwidget(edit=self._root_widget, cancel_button=btn) 91 bui.textwidget( 92 parent=self._root_widget, 93 position=(width * 0.5, height - 46 + yoffs), 94 size=(0, 0), 95 maxwidth=260, 96 scale=1.1, 97 text=bui.Lstr( 98 resource='mapSelectTitleText', 99 subs=[('${GAME}', self._gametype.get_display_string())], 100 ), 101 color=bui.app.ui_v1.title_color, 102 h_align='center', 103 v_align='center', 104 ) 105 v = height - 70 + yoffs 106 self._scroll_width = width - (80 + 2 * x_inset) 107 self._scroll_height = height - ( 108 170 if uiscale is bui.UIScale.SMALL else 140 109 ) 110 111 self._scrollwidget = bui.scrollwidget( 112 parent=self._root_widget, 113 position=(40 + x_inset, v - self._scroll_height), 114 size=(self._scroll_width, self._scroll_height), 115 border_opacity=0.4, 116 ) 117 bui.containerwidget( 118 edit=self._root_widget, selected_child=self._scrollwidget 119 ) 120 bui.containerwidget(edit=self._scrollwidget, claims_left_right=True) 121 122 self._subcontainer: bui.Widget | None = None 123 self._refresh(select_get_more_maps_button=select_get_more_maps_button)
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.
125 @override 126 def get_main_window_state(self) -> bui.MainWindowState: 127 # Support recreating our window for back/refresh purposes. 128 cls = type(self) 129 130 # Pull things out of self here; if we do it in the lambda we'll 131 # keep ourself alive. 132 gametype = self._gametype 133 sessiontype = self._sessiontype 134 config = self._config 135 edit_info = self._edit_info 136 completion_call = self._completion_call 137 select_get_more_maps = self._selected_get_more_maps 138 139 return bui.BasicMainWindowState( 140 create_call=lambda transition, origin_widget: cls( 141 transition=transition, 142 origin_widget=origin_widget, 143 gametype=gametype, 144 sessiontype=sessiontype, 145 config=config, 146 edit_info=edit_info, 147 completion_call=completion_call, 148 select_get_more_maps_button=select_get_more_maps, 149 ) 150 )
Return a WindowState to recreate this window, if supported.