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