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, override
  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.MainWindow):
 17    """Window for selecting a game type to add to a playlist."""
 18
 19    def __init__(
 20        self,
 21        editcontroller: PlaylistEditController,
 22        transition: str | None = 'in_right',
 23        origin_widget: bui.Widget | None = None,
 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 if uiscale is bui.UIScale.MEDIUM else 440
 35        )
 36        top_extra = 30 if uiscale is bui.UIScale.SMALL else 20
 37        self._scroll_width = 210
 38
 39        super().__init__(
 40            root_widget=bui.containerwidget(
 41                size=(self._width, self._height + top_extra),
 42                scale=(
 43                    1.95
 44                    if uiscale is bui.UIScale.SMALL
 45                    else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
 46                ),
 47                stack_offset=(0, 1) if uiscale is bui.UIScale.SMALL else (0, 0),
 48                toolbar_visibility='menu_minimal',
 49            ),
 50            transition=transition,
 51            origin_widget=origin_widget,
 52        )
 53
 54        if uiscale is bui.UIScale.SMALL:
 55            self._back_button = bui.get_special_widget('back_button')
 56        else:
 57            self._back_button = bui.buttonwidget(
 58                parent=self._root_widget,
 59                position=(58 + x_inset, self._height - 53),
 60                size=(60, 48),
 61                label=bui.charstr(bui.SpecialChar.BACK),
 62                autoselect=True,
 63                button_type='backSmall',
 64                on_activate_call=self.main_window_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        bui.widget(
 78            edit=select_button,
 79            right_widget=bui.get_special_widget('squad_button'),
 80        )
 81
 82        bui.textwidget(
 83            parent=self._root_widget,
 84            position=(self._width * 0.5, self._height - 28),
 85            size=(0, 0),
 86            scale=1.0,
 87            text=bui.Lstr(resource=f'{self._r}.titleText'),
 88            h_align='center',
 89            color=bui.app.ui_v1.title_color,
 90            maxwidth=250,
 91            v_align='center',
 92        )
 93        v = self._height - 64
 94
 95        self._selected_title_text = bui.textwidget(
 96            parent=self._root_widget,
 97            position=(x_inset + self._scroll_width + 50 + 30, v - 15),
 98            size=(0, 0),
 99            scale=1.0,
100            color=(0.7, 1.0, 0.7, 1.0),
101            maxwidth=self._width - self._scroll_width - 150 - x_inset * 2,
102            h_align='left',
103            v_align='center',
104        )
105        v -= 30
106
107        self._selected_description_text = bui.textwidget(
108            parent=self._root_widget,
109            position=(x_inset + self._scroll_width + 50 + 30, v),
110            size=(0, 0),
111            scale=0.7,
112            color=(0.5, 0.8, 0.5, 1.0),
113            maxwidth=self._width - self._scroll_width - 150 - x_inset * 2,
114            h_align='left',
115        )
116
117        scroll_height = self._height - 100
118
119        v = self._height - 60
120
121        self._scrollwidget = bui.scrollwidget(
122            parent=self._root_widget,
123            position=(x_inset + 61, v - scroll_height),
124            size=(self._scroll_width, scroll_height),
125            highlight=False,
126        )
127        bui.widget(
128            edit=self._scrollwidget,
129            up_widget=self._back_button,
130            left_widget=self._back_button,
131            right_widget=select_button,
132        )
133        self._column: bui.Widget | None = None
134
135        v -= 35
136
137        if uiscale is bui.UIScale.SMALL:
138            bui.containerwidget(
139                edit=self._root_widget, on_cancel_call=self.main_window_back
140            )
141        else:
142            bui.containerwidget(
143                edit=self._root_widget,
144                cancel_button=self._back_button,
145            )
146        bui.containerwidget(edit=self._root_widget, start_button=select_button)
147
148        self._selected_game_type: type[bs.GameActivity] | None = None
149
150        bui.containerwidget(
151            edit=self._root_widget, selected_child=self._scrollwidget
152        )
153
154        self._game_types: list[type[bs.GameActivity]] = []
155
156        # Get actual games loading in the bg.
157        bui.app.meta.load_exported_classes(
158            bs.GameActivity,
159            self._on_game_types_loaded,
160            completion_cb_in_bg_thread=True,
161        )
162
163        # Refresh with our initial empty list. We'll refresh again once
164        # game loading is complete.
165        self._refresh()
166
167    @override
168    def get_main_window_state(self) -> bui.MainWindowState:
169        # Support recreating our window for back/refresh purposes.
170        cls = type(self)
171
172        # Avoid dereferencing self from the lambda or we'll keep
173        # ourself alive indefinitely.
174        editcontroller = self._editcontroller
175
176        return bui.BasicMainWindowState(
177            create_call=lambda transition, origin_widget: cls(
178                transition=transition,
179                origin_widget=origin_widget,
180                editcontroller=editcontroller,
181            )
182        )
183
184    def _on_game_types_loaded(
185        self, gametypes: list[type[bs.GameActivity]]
186    ) -> None:
187        assert bui.app.classic is not None
188        store = bui.app.classic.store
189
190        # We asked for a bg thread completion cb so we can do some
191        # filtering here in the bg thread where its not gonna cause hitches.
192        assert not bui.in_logic_thread()
193        sessiontype = self._editcontroller.get_session_type()
194        unowned = store.get_unowned_game_types()
195        self._game_types = [
196            gt
197            for gt in gametypes
198            if gt not in unowned and gt.supports_session_type(sessiontype)
199        ]
200
201        # Sort in the current language.
202        self._game_types.sort(key=lambda g: g.get_display_string().evaluate())
203
204        # Tell ourself to refresh back in the logic thread.
205        bui.pushcall(self._refresh, from_other_thread=True)
206
207    def _refresh(self, select_get_more_games_button: bool = False) -> None:
208        if self._column is not None:
209            self._column.delete()
210
211        self._column = bui.columnwidget(
212            parent=self._scrollwidget, border=2, margin=0
213        )
214
215        for i, gametype in enumerate(self._game_types):
216
217            def _doit() -> None:
218                if self._select_button:
219                    bui.apptimer(0.1, self._select_button.activate)
220
221            txt = bui.textwidget(
222                parent=self._column,
223                position=(0, 0),
224                size=(self._scroll_width * 1.1, 24),
225                text=gametype.get_display_string(),
226                h_align='left',
227                v_align='center',
228                color=(0.8, 0.8, 0.8, 1.0),
229                maxwidth=self._scroll_width * 0.8,
230                on_select_call=bui.Call(self._set_selected_game_type, gametype),
231                always_highlight=True,
232                selectable=True,
233                on_activate_call=_doit,
234            )
235            if i == 0:
236                bui.widget(edit=txt, up_widget=self._back_button)
237
238        self._get_more_games_button = bui.buttonwidget(
239            parent=self._column,
240            autoselect=True,
241            label=bui.Lstr(resource=f'{self._r}.getMoreGamesText'),
242            color=(0.54, 0.52, 0.67),
243            textcolor=(0.7, 0.65, 0.7),
244            on_activate_call=self._on_get_more_games_press,
245            size=(178, 50),
246        )
247        if select_get_more_games_button:
248            bui.containerwidget(
249                edit=self._column,
250                selected_child=self._get_more_games_button,
251                visible_child=self._get_more_games_button,
252            )
253
254    def _on_get_more_games_press(self) -> None:
255        from bauiv1lib.account import show_sign_in_prompt
256        from bauiv1lib.store.browser import StoreBrowserWindow
257
258        # No-op if we're not in control.
259        if self.main_window_has_control():
260            return
261
262        plus = bui.app.plus
263        assert plus is not None
264
265        if plus.get_v1_account_state() != 'signed_in':
266            show_sign_in_prompt()
267            return
268
269        self.main_window_replace(
270            StoreBrowserWindow(
271                # modal=True,
272                show_tab=StoreBrowserWindow.TabID.MINIGAMES,
273                # on_close_call=self._on_store_close,
274                origin_widget=self._get_more_games_button,
275                minimal_toolbars=True,
276            )
277        )
278
279    # def _on_store_close(self) -> None:
280    #     self._refresh(select_get_more_games_button=True)
281
282    def _add(self) -> None:
283        bui.lock_all_input()  # Make sure no more commands happen.
284        bui.apptimer(0.1, bui.unlock_all_input)
285        assert self._selected_game_type is not None
286        self._editcontroller.add_game_type_selected(
287            self._selected_game_type, from_window=self
288        )
289
290    def _set_selected_game_type(self, gametype: type[bs.GameActivity]) -> None:
291        self._selected_game_type = gametype
292        bui.textwidget(
293            edit=self._selected_title_text, text=gametype.get_display_string()
294        )
295        bui.textwidget(
296            edit=self._selected_description_text,
297            text=gametype.get_description_display_string(
298                self._editcontroller.get_session_type()
299            ),
300        )
class PlaylistAddGameWindow(bauiv1._uitypes.MainWindow):
 17class PlaylistAddGameWindow(bui.MainWindow):
 18    """Window for selecting a game type to add to a playlist."""
 19
 20    def __init__(
 21        self,
 22        editcontroller: PlaylistEditController,
 23        transition: str | None = 'in_right',
 24        origin_widget: bui.Widget | None = None,
 25    ):
 26        self._editcontroller = editcontroller
 27        self._r = 'addGameWindow'
 28        assert bui.app.classic is not None
 29        uiscale = bui.app.ui_v1.uiscale
 30        self._width = 750 if uiscale is bui.UIScale.SMALL else 650
 31        x_inset = 50 if uiscale is bui.UIScale.SMALL else 0
 32        self._height = (
 33            346
 34            if uiscale is bui.UIScale.SMALL
 35            else 380 if uiscale is bui.UIScale.MEDIUM 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                scale=(
 44                    1.95
 45                    if uiscale is bui.UIScale.SMALL
 46                    else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
 47                ),
 48                stack_offset=(0, 1) if uiscale is bui.UIScale.SMALL else (0, 0),
 49                toolbar_visibility='menu_minimal',
 50            ),
 51            transition=transition,
 52            origin_widget=origin_widget,
 53        )
 54
 55        if uiscale is bui.UIScale.SMALL:
 56            self._back_button = bui.get_special_widget('back_button')
 57        else:
 58            self._back_button = bui.buttonwidget(
 59                parent=self._root_widget,
 60                position=(58 + x_inset, self._height - 53),
 61                size=(60, 48),
 62                label=bui.charstr(bui.SpecialChar.BACK),
 63                autoselect=True,
 64                button_type='backSmall',
 65                on_activate_call=self.main_window_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        bui.widget(
 79            edit=select_button,
 80            right_widget=bui.get_special_widget('squad_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=f'{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
138        if uiscale is bui.UIScale.SMALL:
139            bui.containerwidget(
140                edit=self._root_widget, on_cancel_call=self.main_window_back
141            )
142        else:
143            bui.containerwidget(
144                edit=self._root_widget,
145                cancel_button=self._back_button,
146            )
147        bui.containerwidget(edit=self._root_widget, start_button=select_button)
148
149        self._selected_game_type: type[bs.GameActivity] | None = None
150
151        bui.containerwidget(
152            edit=self._root_widget, selected_child=self._scrollwidget
153        )
154
155        self._game_types: list[type[bs.GameActivity]] = []
156
157        # Get actual games loading in the bg.
158        bui.app.meta.load_exported_classes(
159            bs.GameActivity,
160            self._on_game_types_loaded,
161            completion_cb_in_bg_thread=True,
162        )
163
164        # Refresh with our initial empty list. We'll refresh again once
165        # game loading is complete.
166        self._refresh()
167
168    @override
169    def get_main_window_state(self) -> bui.MainWindowState:
170        # Support recreating our window for back/refresh purposes.
171        cls = type(self)
172
173        # Avoid dereferencing self from the lambda or we'll keep
174        # ourself alive indefinitely.
175        editcontroller = self._editcontroller
176
177        return bui.BasicMainWindowState(
178            create_call=lambda transition, origin_widget: cls(
179                transition=transition,
180                origin_widget=origin_widget,
181                editcontroller=editcontroller,
182            )
183        )
184
185    def _on_game_types_loaded(
186        self, gametypes: list[type[bs.GameActivity]]
187    ) -> None:
188        assert bui.app.classic is not None
189        store = bui.app.classic.store
190
191        # We asked for a bg thread completion cb so we can do some
192        # filtering here in the bg thread where its not gonna cause hitches.
193        assert not bui.in_logic_thread()
194        sessiontype = self._editcontroller.get_session_type()
195        unowned = store.get_unowned_game_types()
196        self._game_types = [
197            gt
198            for gt in gametypes
199            if gt not in unowned and gt.supports_session_type(sessiontype)
200        ]
201
202        # Sort in the current language.
203        self._game_types.sort(key=lambda g: g.get_display_string().evaluate())
204
205        # Tell ourself to refresh back in the logic thread.
206        bui.pushcall(self._refresh, from_other_thread=True)
207
208    def _refresh(self, select_get_more_games_button: bool = False) -> None:
209        if self._column is not None:
210            self._column.delete()
211
212        self._column = bui.columnwidget(
213            parent=self._scrollwidget, border=2, margin=0
214        )
215
216        for i, gametype in enumerate(self._game_types):
217
218            def _doit() -> None:
219                if self._select_button:
220                    bui.apptimer(0.1, self._select_button.activate)
221
222            txt = bui.textwidget(
223                parent=self._column,
224                position=(0, 0),
225                size=(self._scroll_width * 1.1, 24),
226                text=gametype.get_display_string(),
227                h_align='left',
228                v_align='center',
229                color=(0.8, 0.8, 0.8, 1.0),
230                maxwidth=self._scroll_width * 0.8,
231                on_select_call=bui.Call(self._set_selected_game_type, gametype),
232                always_highlight=True,
233                selectable=True,
234                on_activate_call=_doit,
235            )
236            if i == 0:
237                bui.widget(edit=txt, up_widget=self._back_button)
238
239        self._get_more_games_button = bui.buttonwidget(
240            parent=self._column,
241            autoselect=True,
242            label=bui.Lstr(resource=f'{self._r}.getMoreGamesText'),
243            color=(0.54, 0.52, 0.67),
244            textcolor=(0.7, 0.65, 0.7),
245            on_activate_call=self._on_get_more_games_press,
246            size=(178, 50),
247        )
248        if select_get_more_games_button:
249            bui.containerwidget(
250                edit=self._column,
251                selected_child=self._get_more_games_button,
252                visible_child=self._get_more_games_button,
253            )
254
255    def _on_get_more_games_press(self) -> None:
256        from bauiv1lib.account import show_sign_in_prompt
257        from bauiv1lib.store.browser import StoreBrowserWindow
258
259        # No-op if we're not in control.
260        if self.main_window_has_control():
261            return
262
263        plus = bui.app.plus
264        assert plus is not None
265
266        if plus.get_v1_account_state() != 'signed_in':
267            show_sign_in_prompt()
268            return
269
270        self.main_window_replace(
271            StoreBrowserWindow(
272                # modal=True,
273                show_tab=StoreBrowserWindow.TabID.MINIGAMES,
274                # on_close_call=self._on_store_close,
275                origin_widget=self._get_more_games_button,
276                minimal_toolbars=True,
277            )
278        )
279
280    # def _on_store_close(self) -> None:
281    #     self._refresh(select_get_more_games_button=True)
282
283    def _add(self) -> None:
284        bui.lock_all_input()  # Make sure no more commands happen.
285        bui.apptimer(0.1, bui.unlock_all_input)
286        assert self._selected_game_type is not None
287        self._editcontroller.add_game_type_selected(
288            self._selected_game_type, from_window=self
289        )
290
291    def _set_selected_game_type(self, gametype: type[bs.GameActivity]) -> None:
292        self._selected_game_type = gametype
293        bui.textwidget(
294            edit=self._selected_title_text, text=gametype.get_display_string()
295        )
296        bui.textwidget(
297            edit=self._selected_description_text,
298            text=gametype.get_description_display_string(
299                self._editcontroller.get_session_type()
300            ),
301        )

Window for selecting a game type to add to a playlist.

PlaylistAddGameWindow( editcontroller: bauiv1lib.playlist.editcontroller.PlaylistEditController, transition: str | None = 'in_right', origin_widget: _bauiv1.Widget | None = None)
 20    def __init__(
 21        self,
 22        editcontroller: PlaylistEditController,
 23        transition: str | None = 'in_right',
 24        origin_widget: bui.Widget | None = None,
 25    ):
 26        self._editcontroller = editcontroller
 27        self._r = 'addGameWindow'
 28        assert bui.app.classic is not None
 29        uiscale = bui.app.ui_v1.uiscale
 30        self._width = 750 if uiscale is bui.UIScale.SMALL else 650
 31        x_inset = 50 if uiscale is bui.UIScale.SMALL else 0
 32        self._height = (
 33            346
 34            if uiscale is bui.UIScale.SMALL
 35            else 380 if uiscale is bui.UIScale.MEDIUM 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                scale=(
 44                    1.95
 45                    if uiscale is bui.UIScale.SMALL
 46                    else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
 47                ),
 48                stack_offset=(0, 1) if uiscale is bui.UIScale.SMALL else (0, 0),
 49                toolbar_visibility='menu_minimal',
 50            ),
 51            transition=transition,
 52            origin_widget=origin_widget,
 53        )
 54
 55        if uiscale is bui.UIScale.SMALL:
 56            self._back_button = bui.get_special_widget('back_button')
 57        else:
 58            self._back_button = bui.buttonwidget(
 59                parent=self._root_widget,
 60                position=(58 + x_inset, self._height - 53),
 61                size=(60, 48),
 62                label=bui.charstr(bui.SpecialChar.BACK),
 63                autoselect=True,
 64                button_type='backSmall',
 65                on_activate_call=self.main_window_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        bui.widget(
 79            edit=select_button,
 80            right_widget=bui.get_special_widget('squad_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=f'{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
138        if uiscale is bui.UIScale.SMALL:
139            bui.containerwidget(
140                edit=self._root_widget, on_cancel_call=self.main_window_back
141            )
142        else:
143            bui.containerwidget(
144                edit=self._root_widget,
145                cancel_button=self._back_button,
146            )
147        bui.containerwidget(edit=self._root_widget, start_button=select_button)
148
149        self._selected_game_type: type[bs.GameActivity] | None = None
150
151        bui.containerwidget(
152            edit=self._root_widget, selected_child=self._scrollwidget
153        )
154
155        self._game_types: list[type[bs.GameActivity]] = []
156
157        # Get actual games loading in the bg.
158        bui.app.meta.load_exported_classes(
159            bs.GameActivity,
160            self._on_game_types_loaded,
161            completion_cb_in_bg_thread=True,
162        )
163
164        # Refresh with our initial empty list. We'll refresh again once
165        # game loading is complete.
166        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.

@override
def get_main_window_state(self) -> bauiv1.MainWindowState:
168    @override
169    def get_main_window_state(self) -> bui.MainWindowState:
170        # Support recreating our window for back/refresh purposes.
171        cls = type(self)
172
173        # Avoid dereferencing self from the lambda or we'll keep
174        # ourself alive indefinitely.
175        editcontroller = self._editcontroller
176
177        return bui.BasicMainWindowState(
178            create_call=lambda transition, origin_widget: cls(
179                transition=transition,
180                origin_widget=origin_widget,
181                editcontroller=editcontroller,
182            )
183        )

Return a WindowState to recreate this window, if supported.

Inherited Members
bauiv1._uitypes.MainWindow
main_window_back_state
main_window_is_top_level
main_window_close
main_window_has_control
main_window_back
main_window_replace
on_main_window_close
bauiv1._uitypes.Window
get_root_widget