bauiv1lib.kiosk

UI functionality for running the game in kiosk mode.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""UI functionality for running the game in kiosk mode."""
  4
  5from __future__ import annotations
  6
  7import bascenev1 as bs
  8import bauiv1 as bui
  9
 10
 11class KioskWindow(bui.Window):
 12    """Kiosk mode window."""
 13
 14    def __init__(self, transition: str = 'in_right'):
 15        # pylint: disable=too-many-locals, too-many-statements
 16        from bauiv1lib.confirm import QuitWindow
 17
 18        assert bui.app.classic is not None
 19
 20        self._width = 720.0
 21        self._height = 340.0
 22
 23        def _do_cancel() -> None:
 24            QuitWindow(swish=True, quit_type=bui.QuitType.BACK)
 25
 26        super().__init__(
 27            root_widget=bui.containerwidget(
 28                size=(self._width, self._height),
 29                transition=transition,
 30                on_cancel_call=_do_cancel,
 31                background=False,
 32                stack_offset=(0, -130),
 33            )
 34        )
 35
 36        self._r = 'kioskWindow'
 37
 38        self._show_multiplayer = False
 39
 40        # Let's reset all random player names every time we hit the main menu.
 41        bs.reset_random_player_names()
 42
 43        # Reset achievements too (at least locally).
 44        bui.app.config['Achievements'] = {}
 45
 46        t_delay_base = 0.0
 47        t_delay_scale = 0.0
 48        if not bui.app.classic.did_menu_intro:
 49            t_delay_base = 1.0
 50            t_delay_scale = 1.0
 51
 52        mesh_opaque = bui.getmesh('level_select_button_opaque')
 53        mesh_transparent = bui.getmesh('level_select_button_transparent')
 54        mask_tex = bui.gettexture('mapPreviewMask')
 55
 56        y_extra = 130.0 + (0.0 if self._show_multiplayer else -130.0)
 57        b_width = 250.0
 58        b_height = 200.0
 59        b_space = 280.0
 60        b_v = 80.0 + y_extra
 61        label_height = 130.0 + y_extra
 62        img_width = 180.0
 63        img_v = 158.0 + y_extra
 64
 65        if self._show_multiplayer:
 66            tdelay = t_delay_base + t_delay_scale * 1.3
 67            bui.textwidget(
 68                parent=self._root_widget,
 69                size=(0, 0),
 70                position=(self._width * 0.5, self._height + y_extra - 44),
 71                transition_delay=tdelay,
 72                text=bui.Lstr(resource=self._r + '.singlePlayerExamplesText'),
 73                flatness=1.0,
 74                scale=1.2,
 75                h_align='center',
 76                v_align='center',
 77                shadow=1.0,
 78            )
 79        else:
 80            tdelay = t_delay_base + t_delay_scale * 0.7
 81            bui.textwidget(
 82                parent=self._root_widget,
 83                size=(0, 0),
 84                position=(self._width * 0.5, self._height + y_extra - 34),
 85                transition_delay=tdelay,
 86                text=(
 87                    bui.Lstr(
 88                        resource='demoText',
 89                        fallback_resource='mainMenu.demoMenuText',
 90                    )
 91                    if bui.app.env.demo
 92                    else 'ARCADE'
 93                ),
 94                flatness=1.0,
 95                scale=1.2,
 96                h_align='center',
 97                v_align='center',
 98                shadow=1.0,
 99            )
100        h = self._width * 0.5 - b_space
101        tdelay = t_delay_base + t_delay_scale * 0.7
102        self._b1 = btn = bui.buttonwidget(
103            parent=self._root_widget,
104            autoselect=True,
105            size=(b_width, b_height),
106            on_activate_call=bui.Call(self._do_game, 'easy'),
107            transition_delay=tdelay,
108            position=(h - b_width * 0.5, b_v),
109            label='',
110            button_type='square',
111        )
112        bui.textwidget(
113            parent=self._root_widget,
114            draw_controller=btn,
115            transition_delay=tdelay,
116            size=(0, 0),
117            position=(h, label_height),
118            maxwidth=b_width * 0.7,
119            text=bui.Lstr(resource=self._r + '.easyText'),
120            scale=1.3,
121            h_align='center',
122            v_align='center',
123        )
124        bui.imagewidget(
125            parent=self._root_widget,
126            draw_controller=btn,
127            size=(img_width, 0.5 * img_width),
128            transition_delay=tdelay,
129            position=(h - img_width * 0.5, img_v),
130            texture=bui.gettexture('doomShroomPreview'),
131            mesh_opaque=mesh_opaque,
132            mesh_transparent=mesh_transparent,
133            mask_texture=mask_tex,
134        )
135        h = self._width * 0.5
136        tdelay = t_delay_base + t_delay_scale * 0.65
137        self._b2 = btn = bui.buttonwidget(
138            parent=self._root_widget,
139            autoselect=True,
140            size=(b_width, b_height),
141            on_activate_call=bui.Call(self._do_game, 'medium'),
142            position=(h - b_width * 0.5, b_v),
143            label='',
144            button_type='square',
145            transition_delay=tdelay,
146        )
147        bui.textwidget(
148            parent=self._root_widget,
149            draw_controller=btn,
150            transition_delay=tdelay,
151            size=(0, 0),
152            position=(h, label_height),
153            maxwidth=b_width * 0.7,
154            text=bui.Lstr(resource=self._r + '.mediumText'),
155            scale=1.3,
156            h_align='center',
157            v_align='center',
158        )
159        bui.imagewidget(
160            parent=self._root_widget,
161            draw_controller=btn,
162            size=(img_width, 0.5 * img_width),
163            transition_delay=tdelay,
164            position=(h - img_width * 0.5, img_v),
165            texture=bui.gettexture('footballStadiumPreview'),
166            mesh_opaque=mesh_opaque,
167            mesh_transparent=mesh_transparent,
168            mask_texture=mask_tex,
169        )
170        h = self._width * 0.5 + b_space
171        tdelay = t_delay_base + t_delay_scale * 0.6
172        self._b3 = btn = bui.buttonwidget(
173            parent=self._root_widget,
174            autoselect=True,
175            size=(b_width, b_height),
176            on_activate_call=bui.Call(self._do_game, 'hard'),
177            transition_delay=tdelay,
178            position=(h - b_width * 0.5, b_v),
179            label='',
180            button_type='square',
181        )
182        bui.textwidget(
183            parent=self._root_widget,
184            draw_controller=btn,
185            transition_delay=tdelay,
186            size=(0, 0),
187            position=(h, label_height),
188            maxwidth=b_width * 0.7,
189            text='Hard',
190            scale=1.3,
191            h_align='center',
192            v_align='center',
193        )
194        bui.imagewidget(
195            parent=self._root_widget,
196            draw_controller=btn,
197            transition_delay=tdelay,
198            size=(img_width, 0.5 * img_width),
199            position=(h - img_width * 0.5, img_v),
200            texture=bui.gettexture('courtyardPreview'),
201            mesh_opaque=mesh_opaque,
202            mesh_transparent=mesh_transparent,
203            mask_texture=mask_tex,
204        )
205        if not bui.app.classic.did_menu_intro:
206            bui.app.classic.did_menu_intro = True
207
208        self._b4: bui.Widget | None
209        self._b5: bui.Widget | None
210        self._b6: bui.Widget | None
211
212        if bool(False):
213            bui.textwidget(
214                parent=self._root_widget,
215                size=(0, 0),
216                position=(self._width * 0.5, self._height + y_extra - 44),
217                transition_delay=tdelay,
218                text=bui.Lstr(resource=self._r + '.versusExamplesText'),
219                flatness=1.0,
220                scale=1.2,
221                h_align='center',
222                v_align='center',
223                shadow=1.0,
224            )
225            h = self._width * 0.5 - b_space
226            tdelay = t_delay_base + t_delay_scale * 0.7
227            self._b4 = btn = bui.buttonwidget(
228                parent=self._root_widget,
229                autoselect=True,
230                size=(b_width, b_height),
231                on_activate_call=bui.Call(self._do_game, 'ctf'),
232                transition_delay=tdelay,
233                position=(h - b_width * 0.5, b_v),
234                label='',
235                button_type='square',
236            )
237            bui.textwidget(
238                parent=self._root_widget,
239                draw_controller=btn,
240                transition_delay=tdelay,
241                size=(0, 0),
242                position=(h, label_height),
243                maxwidth=b_width * 0.7,
244                text=bui.Lstr(translate=('gameNames', 'Capture the Flag')),
245                scale=1.3,
246                h_align='center',
247                v_align='center',
248            )
249            bui.imagewidget(
250                parent=self._root_widget,
251                draw_controller=btn,
252                size=(img_width, 0.5 * img_width),
253                transition_delay=tdelay,
254                position=(h - img_width * 0.5, img_v),
255                texture=bui.gettexture('bridgitPreview'),
256                mesh_opaque=mesh_opaque,
257                mesh_transparent=mesh_transparent,
258                mask_texture=mask_tex,
259            )
260
261            h = self._width * 0.5
262            tdelay = t_delay_base + t_delay_scale * 0.65
263            self._b5 = btn = bui.buttonwidget(
264                parent=self._root_widget,
265                autoselect=True,
266                size=(b_width, b_height),
267                on_activate_call=bui.Call(self._do_game, 'hockey'),
268                position=(h - b_width * 0.5, b_v),
269                label='',
270                button_type='square',
271                transition_delay=tdelay,
272            )
273            bui.textwidget(
274                parent=self._root_widget,
275                draw_controller=btn,
276                transition_delay=tdelay,
277                size=(0, 0),
278                position=(h, label_height),
279                maxwidth=b_width * 0.7,
280                text=bui.Lstr(translate=('gameNames', 'Hockey')),
281                scale=1.3,
282                h_align='center',
283                v_align='center',
284            )
285            bui.imagewidget(
286                parent=self._root_widget,
287                draw_controller=btn,
288                size=(img_width, 0.5 * img_width),
289                transition_delay=tdelay,
290                position=(h - img_width * 0.5, img_v),
291                texture=bui.gettexture('hockeyStadiumPreview'),
292                mesh_opaque=mesh_opaque,
293                mesh_transparent=mesh_transparent,
294                mask_texture=mask_tex,
295            )
296            h = self._width * 0.5 + b_space
297            tdelay = t_delay_base + t_delay_scale * 0.6
298            self._b6 = btn = bui.buttonwidget(
299                parent=self._root_widget,
300                autoselect=True,
301                size=(b_width, b_height),
302                on_activate_call=bui.Call(self._do_game, 'epic'),
303                transition_delay=tdelay,
304                position=(h - b_width * 0.5, b_v),
305                label='',
306                button_type='square',
307            )
308            bui.textwidget(
309                parent=self._root_widget,
310                draw_controller=btn,
311                transition_delay=tdelay,
312                size=(0, 0),
313                position=(h, label_height),
314                maxwidth=b_width * 0.7,
315                text=bui.Lstr(resource=self._r + '.epicModeText'),
316                scale=1.3,
317                h_align='center',
318                v_align='center',
319            )
320            bui.imagewidget(
321                parent=self._root_widget,
322                draw_controller=btn,
323                transition_delay=tdelay,
324                size=(img_width, 0.5 * img_width),
325                position=(h - img_width * 0.5, img_v),
326                texture=bui.gettexture('tipTopPreview'),
327                mesh_opaque=mesh_opaque,
328                mesh_transparent=mesh_transparent,
329                mask_texture=mask_tex,
330            )
331        else:
332            self._b4 = self._b5 = self._b6 = None
333
334        self._b7: bui.Widget | None
335        if bui.app.env.arcade:
336            self._b7 = bui.buttonwidget(
337                parent=self._root_widget,
338                autoselect=True,
339                size=(b_width, 50),
340                color=(0.45, 0.55, 0.45),
341                textcolor=(0.7, 0.8, 0.7),
342                scale=0.5,
343                position=(self._width * 0.5 - 60.0, b_v - 70.0),
344                transition_delay=tdelay,
345                label=bui.Lstr(resource=self._r + '.fullMenuText'),
346                on_activate_call=self._do_full_menu,
347            )
348        else:
349            self._b7 = None
350        self._restore_state()
351        self._update()
352        self._update_timer = bui.AppTimer(
353            1.0, bui.WeakCall(self._update), repeat=True
354        )
355
356    def _restore_state(self) -> None:
357        assert bui.app.classic is not None
358        sel_name = bui.app.ui_v1.window_states.get(type(self))
359        sel: bui.Widget | None
360        if sel_name == 'b1':
361            sel = self._b1
362        elif sel_name == 'b2':
363            sel = self._b2
364        elif sel_name == 'b3':
365            sel = self._b3
366        elif sel_name == 'b4':
367            sel = self._b4
368        elif sel_name == 'b5':
369            sel = self._b5
370        elif sel_name == 'b6':
371            sel = self._b6
372        elif sel_name == 'b7':
373            sel = self._b7
374        else:
375            sel = self._b1
376        if sel:
377            bui.containerwidget(edit=self._root_widget, selected_child=sel)
378
379    def _save_state(self) -> None:
380        sel = self._root_widget.get_selected_child()
381        if sel == self._b1:
382            sel_name = 'b1'
383        elif sel == self._b2:
384            sel_name = 'b2'
385        elif sel == self._b3:
386            sel_name = 'b3'
387        elif sel == self._b4:
388            sel_name = 'b4'
389        elif sel == self._b5:
390            sel_name = 'b5'
391        elif sel == self._b6:
392            sel_name = 'b6'
393        elif sel == self._b7:
394            sel_name = 'b7'
395        else:
396            sel_name = 'b1'
397        assert bui.app.classic is not None
398        bui.app.ui_v1.window_states[type(self)] = sel_name
399
400    def _update(self) -> None:
401        plus = bui.app.plus
402        assert plus is not None
403
404        # Kiosk-mode is designed to be used signed-out... try for force
405        # the issue.
406        if plus.get_v1_account_state() == 'signed_in':
407            # _bs.sign_out()
408            # FIXME: Try to delete player profiles here too.
409            pass
410        else:
411            # Also make sure there's no player profiles.
412            appconfig = bui.app.config
413            appconfig['Player Profiles'] = {}
414
415    def _do_game(self, mode: str) -> None:
416        assert bui.app.classic is not None
417        self._save_state()
418        if mode in ['epic', 'ctf', 'hockey']:
419            appconfig = bui.app.config
420            if 'Team Tournament Playlists' not in appconfig:
421                appconfig['Team Tournament Playlists'] = {}
422            if 'Free-for-All Playlists' not in appconfig:
423                appconfig['Free-for-All Playlists'] = {}
424            appconfig['Show Tutorial'] = False
425            if mode == 'epic':
426                appconfig['Free-for-All Playlists']['Just Epic Elim'] = [
427                    {
428                        'settings': {
429                            'Epic Mode': 1,
430                            'Lives Per Player': 1,
431                            'Respawn Times': 1.0,
432                            'Time Limit': 0,
433                            'map': 'Tip Top',
434                        },
435                        'type': 'bs_elimination.EliminationGame',
436                    }
437                ]
438                appconfig['Free-for-All Playlist Selection'] = 'Just Epic Elim'
439                bui.fade_screen(
440                    False,
441                    endcall=bui.Call(
442                        bui.pushcall,
443                        bui.Call(bs.new_host_session, bs.FreeForAllSession),
444                    ),
445                )
446            else:
447                if mode == 'ctf':
448                    appconfig['Team Tournament Playlists']['Just CTF'] = [
449                        {
450                            'settings': {
451                                'Epic Mode': False,
452                                'Flag Idle Return Time': 30,
453                                'Flag Touch Return Time': 0,
454                                'Respawn Times': 1.0,
455                                'Score to Win': 3,
456                                'Time Limit': 0,
457                                'map': 'Bridgit',
458                            },
459                            'type': 'bs_capture_the_flag.CTFGame',
460                        }
461                    ]
462                    appconfig['Team Tournament Playlist Selection'] = 'Just CTF'
463                else:
464                    appconfig['Team Tournament Playlists']['Just Hockey'] = [
465                        {
466                            'settings': {
467                                'Respawn Times': 1.0,
468                                'Score to Win': 1,
469                                'Time Limit': 0,
470                                'map': 'Hockey Stadium',
471                            },
472                            'type': 'bs_hockey.HockeyGame',
473                        }
474                    ]
475                    appconfig['Team Tournament Playlist Selection'] = (
476                        'Just Hockey'
477                    )
478                bui.fade_screen(
479                    False,
480                    endcall=bui.Call(
481                        bui.pushcall,
482                        bui.Call(bs.new_host_session, bs.DualTeamSession),
483                    ),
484                )
485            bui.containerwidget(edit=self._root_widget, transition='out_left')
486            return
487
488        game = (
489            'Easy:Onslaught Training'
490            if mode == 'easy'
491            else (
492                'Easy:Rookie Football'
493                if mode == 'medium'
494                else 'Easy:Uber Onslaught'
495            )
496        )
497        cfg = bui.app.config
498        cfg['Selected Coop Game'] = game
499        cfg.commit()
500        if bui.app.classic.launch_coop_game(game, force=True):
501            bui.containerwidget(edit=self._root_widget, transition='out_left')
502
503    def _do_full_menu(self) -> None:
504        from bauiv1lib.mainmenu import MainMenuWindow
505
506        # no-op if our underlying widget is dead or on its way out.
507        if not self._root_widget or self._root_widget.transitioning_out:
508            return
509
510        assert bui.app.classic is not None
511
512        self._save_state()
513        bui.containerwidget(edit=self._root_widget, transition='out_left')
514        bui.app.classic.did_menu_intro = True  # prevent delayed transition-in
515        bui.app.ui_v1.set_main_menu_window(
516            MainMenuWindow().get_root_widget(), from_window=self._root_widget
517        )
class KioskWindow(bauiv1._uitypes.Window):
 12class KioskWindow(bui.Window):
 13    """Kiosk mode window."""
 14
 15    def __init__(self, transition: str = 'in_right'):
 16        # pylint: disable=too-many-locals, too-many-statements
 17        from bauiv1lib.confirm import QuitWindow
 18
 19        assert bui.app.classic is not None
 20
 21        self._width = 720.0
 22        self._height = 340.0
 23
 24        def _do_cancel() -> None:
 25            QuitWindow(swish=True, quit_type=bui.QuitType.BACK)
 26
 27        super().__init__(
 28            root_widget=bui.containerwidget(
 29                size=(self._width, self._height),
 30                transition=transition,
 31                on_cancel_call=_do_cancel,
 32                background=False,
 33                stack_offset=(0, -130),
 34            )
 35        )
 36
 37        self._r = 'kioskWindow'
 38
 39        self._show_multiplayer = False
 40
 41        # Let's reset all random player names every time we hit the main menu.
 42        bs.reset_random_player_names()
 43
 44        # Reset achievements too (at least locally).
 45        bui.app.config['Achievements'] = {}
 46
 47        t_delay_base = 0.0
 48        t_delay_scale = 0.0
 49        if not bui.app.classic.did_menu_intro:
 50            t_delay_base = 1.0
 51            t_delay_scale = 1.0
 52
 53        mesh_opaque = bui.getmesh('level_select_button_opaque')
 54        mesh_transparent = bui.getmesh('level_select_button_transparent')
 55        mask_tex = bui.gettexture('mapPreviewMask')
 56
 57        y_extra = 130.0 + (0.0 if self._show_multiplayer else -130.0)
 58        b_width = 250.0
 59        b_height = 200.0
 60        b_space = 280.0
 61        b_v = 80.0 + y_extra
 62        label_height = 130.0 + y_extra
 63        img_width = 180.0
 64        img_v = 158.0 + y_extra
 65
 66        if self._show_multiplayer:
 67            tdelay = t_delay_base + t_delay_scale * 1.3
 68            bui.textwidget(
 69                parent=self._root_widget,
 70                size=(0, 0),
 71                position=(self._width * 0.5, self._height + y_extra - 44),
 72                transition_delay=tdelay,
 73                text=bui.Lstr(resource=self._r + '.singlePlayerExamplesText'),
 74                flatness=1.0,
 75                scale=1.2,
 76                h_align='center',
 77                v_align='center',
 78                shadow=1.0,
 79            )
 80        else:
 81            tdelay = t_delay_base + t_delay_scale * 0.7
 82            bui.textwidget(
 83                parent=self._root_widget,
 84                size=(0, 0),
 85                position=(self._width * 0.5, self._height + y_extra - 34),
 86                transition_delay=tdelay,
 87                text=(
 88                    bui.Lstr(
 89                        resource='demoText',
 90                        fallback_resource='mainMenu.demoMenuText',
 91                    )
 92                    if bui.app.env.demo
 93                    else 'ARCADE'
 94                ),
 95                flatness=1.0,
 96                scale=1.2,
 97                h_align='center',
 98                v_align='center',
 99                shadow=1.0,
100            )
101        h = self._width * 0.5 - b_space
102        tdelay = t_delay_base + t_delay_scale * 0.7
103        self._b1 = btn = bui.buttonwidget(
104            parent=self._root_widget,
105            autoselect=True,
106            size=(b_width, b_height),
107            on_activate_call=bui.Call(self._do_game, 'easy'),
108            transition_delay=tdelay,
109            position=(h - b_width * 0.5, b_v),
110            label='',
111            button_type='square',
112        )
113        bui.textwidget(
114            parent=self._root_widget,
115            draw_controller=btn,
116            transition_delay=tdelay,
117            size=(0, 0),
118            position=(h, label_height),
119            maxwidth=b_width * 0.7,
120            text=bui.Lstr(resource=self._r + '.easyText'),
121            scale=1.3,
122            h_align='center',
123            v_align='center',
124        )
125        bui.imagewidget(
126            parent=self._root_widget,
127            draw_controller=btn,
128            size=(img_width, 0.5 * img_width),
129            transition_delay=tdelay,
130            position=(h - img_width * 0.5, img_v),
131            texture=bui.gettexture('doomShroomPreview'),
132            mesh_opaque=mesh_opaque,
133            mesh_transparent=mesh_transparent,
134            mask_texture=mask_tex,
135        )
136        h = self._width * 0.5
137        tdelay = t_delay_base + t_delay_scale * 0.65
138        self._b2 = btn = bui.buttonwidget(
139            parent=self._root_widget,
140            autoselect=True,
141            size=(b_width, b_height),
142            on_activate_call=bui.Call(self._do_game, 'medium'),
143            position=(h - b_width * 0.5, b_v),
144            label='',
145            button_type='square',
146            transition_delay=tdelay,
147        )
148        bui.textwidget(
149            parent=self._root_widget,
150            draw_controller=btn,
151            transition_delay=tdelay,
152            size=(0, 0),
153            position=(h, label_height),
154            maxwidth=b_width * 0.7,
155            text=bui.Lstr(resource=self._r + '.mediumText'),
156            scale=1.3,
157            h_align='center',
158            v_align='center',
159        )
160        bui.imagewidget(
161            parent=self._root_widget,
162            draw_controller=btn,
163            size=(img_width, 0.5 * img_width),
164            transition_delay=tdelay,
165            position=(h - img_width * 0.5, img_v),
166            texture=bui.gettexture('footballStadiumPreview'),
167            mesh_opaque=mesh_opaque,
168            mesh_transparent=mesh_transparent,
169            mask_texture=mask_tex,
170        )
171        h = self._width * 0.5 + b_space
172        tdelay = t_delay_base + t_delay_scale * 0.6
173        self._b3 = btn = bui.buttonwidget(
174            parent=self._root_widget,
175            autoselect=True,
176            size=(b_width, b_height),
177            on_activate_call=bui.Call(self._do_game, 'hard'),
178            transition_delay=tdelay,
179            position=(h - b_width * 0.5, b_v),
180            label='',
181            button_type='square',
182        )
183        bui.textwidget(
184            parent=self._root_widget,
185            draw_controller=btn,
186            transition_delay=tdelay,
187            size=(0, 0),
188            position=(h, label_height),
189            maxwidth=b_width * 0.7,
190            text='Hard',
191            scale=1.3,
192            h_align='center',
193            v_align='center',
194        )
195        bui.imagewidget(
196            parent=self._root_widget,
197            draw_controller=btn,
198            transition_delay=tdelay,
199            size=(img_width, 0.5 * img_width),
200            position=(h - img_width * 0.5, img_v),
201            texture=bui.gettexture('courtyardPreview'),
202            mesh_opaque=mesh_opaque,
203            mesh_transparent=mesh_transparent,
204            mask_texture=mask_tex,
205        )
206        if not bui.app.classic.did_menu_intro:
207            bui.app.classic.did_menu_intro = True
208
209        self._b4: bui.Widget | None
210        self._b5: bui.Widget | None
211        self._b6: bui.Widget | None
212
213        if bool(False):
214            bui.textwidget(
215                parent=self._root_widget,
216                size=(0, 0),
217                position=(self._width * 0.5, self._height + y_extra - 44),
218                transition_delay=tdelay,
219                text=bui.Lstr(resource=self._r + '.versusExamplesText'),
220                flatness=1.0,
221                scale=1.2,
222                h_align='center',
223                v_align='center',
224                shadow=1.0,
225            )
226            h = self._width * 0.5 - b_space
227            tdelay = t_delay_base + t_delay_scale * 0.7
228            self._b4 = btn = bui.buttonwidget(
229                parent=self._root_widget,
230                autoselect=True,
231                size=(b_width, b_height),
232                on_activate_call=bui.Call(self._do_game, 'ctf'),
233                transition_delay=tdelay,
234                position=(h - b_width * 0.5, b_v),
235                label='',
236                button_type='square',
237            )
238            bui.textwidget(
239                parent=self._root_widget,
240                draw_controller=btn,
241                transition_delay=tdelay,
242                size=(0, 0),
243                position=(h, label_height),
244                maxwidth=b_width * 0.7,
245                text=bui.Lstr(translate=('gameNames', 'Capture the Flag')),
246                scale=1.3,
247                h_align='center',
248                v_align='center',
249            )
250            bui.imagewidget(
251                parent=self._root_widget,
252                draw_controller=btn,
253                size=(img_width, 0.5 * img_width),
254                transition_delay=tdelay,
255                position=(h - img_width * 0.5, img_v),
256                texture=bui.gettexture('bridgitPreview'),
257                mesh_opaque=mesh_opaque,
258                mesh_transparent=mesh_transparent,
259                mask_texture=mask_tex,
260            )
261
262            h = self._width * 0.5
263            tdelay = t_delay_base + t_delay_scale * 0.65
264            self._b5 = btn = bui.buttonwidget(
265                parent=self._root_widget,
266                autoselect=True,
267                size=(b_width, b_height),
268                on_activate_call=bui.Call(self._do_game, 'hockey'),
269                position=(h - b_width * 0.5, b_v),
270                label='',
271                button_type='square',
272                transition_delay=tdelay,
273            )
274            bui.textwidget(
275                parent=self._root_widget,
276                draw_controller=btn,
277                transition_delay=tdelay,
278                size=(0, 0),
279                position=(h, label_height),
280                maxwidth=b_width * 0.7,
281                text=bui.Lstr(translate=('gameNames', 'Hockey')),
282                scale=1.3,
283                h_align='center',
284                v_align='center',
285            )
286            bui.imagewidget(
287                parent=self._root_widget,
288                draw_controller=btn,
289                size=(img_width, 0.5 * img_width),
290                transition_delay=tdelay,
291                position=(h - img_width * 0.5, img_v),
292                texture=bui.gettexture('hockeyStadiumPreview'),
293                mesh_opaque=mesh_opaque,
294                mesh_transparent=mesh_transparent,
295                mask_texture=mask_tex,
296            )
297            h = self._width * 0.5 + b_space
298            tdelay = t_delay_base + t_delay_scale * 0.6
299            self._b6 = btn = bui.buttonwidget(
300                parent=self._root_widget,
301                autoselect=True,
302                size=(b_width, b_height),
303                on_activate_call=bui.Call(self._do_game, 'epic'),
304                transition_delay=tdelay,
305                position=(h - b_width * 0.5, b_v),
306                label='',
307                button_type='square',
308            )
309            bui.textwidget(
310                parent=self._root_widget,
311                draw_controller=btn,
312                transition_delay=tdelay,
313                size=(0, 0),
314                position=(h, label_height),
315                maxwidth=b_width * 0.7,
316                text=bui.Lstr(resource=self._r + '.epicModeText'),
317                scale=1.3,
318                h_align='center',
319                v_align='center',
320            )
321            bui.imagewidget(
322                parent=self._root_widget,
323                draw_controller=btn,
324                transition_delay=tdelay,
325                size=(img_width, 0.5 * img_width),
326                position=(h - img_width * 0.5, img_v),
327                texture=bui.gettexture('tipTopPreview'),
328                mesh_opaque=mesh_opaque,
329                mesh_transparent=mesh_transparent,
330                mask_texture=mask_tex,
331            )
332        else:
333            self._b4 = self._b5 = self._b6 = None
334
335        self._b7: bui.Widget | None
336        if bui.app.env.arcade:
337            self._b7 = bui.buttonwidget(
338                parent=self._root_widget,
339                autoselect=True,
340                size=(b_width, 50),
341                color=(0.45, 0.55, 0.45),
342                textcolor=(0.7, 0.8, 0.7),
343                scale=0.5,
344                position=(self._width * 0.5 - 60.0, b_v - 70.0),
345                transition_delay=tdelay,
346                label=bui.Lstr(resource=self._r + '.fullMenuText'),
347                on_activate_call=self._do_full_menu,
348            )
349        else:
350            self._b7 = None
351        self._restore_state()
352        self._update()
353        self._update_timer = bui.AppTimer(
354            1.0, bui.WeakCall(self._update), repeat=True
355        )
356
357    def _restore_state(self) -> None:
358        assert bui.app.classic is not None
359        sel_name = bui.app.ui_v1.window_states.get(type(self))
360        sel: bui.Widget | None
361        if sel_name == 'b1':
362            sel = self._b1
363        elif sel_name == 'b2':
364            sel = self._b2
365        elif sel_name == 'b3':
366            sel = self._b3
367        elif sel_name == 'b4':
368            sel = self._b4
369        elif sel_name == 'b5':
370            sel = self._b5
371        elif sel_name == 'b6':
372            sel = self._b6
373        elif sel_name == 'b7':
374            sel = self._b7
375        else:
376            sel = self._b1
377        if sel:
378            bui.containerwidget(edit=self._root_widget, selected_child=sel)
379
380    def _save_state(self) -> None:
381        sel = self._root_widget.get_selected_child()
382        if sel == self._b1:
383            sel_name = 'b1'
384        elif sel == self._b2:
385            sel_name = 'b2'
386        elif sel == self._b3:
387            sel_name = 'b3'
388        elif sel == self._b4:
389            sel_name = 'b4'
390        elif sel == self._b5:
391            sel_name = 'b5'
392        elif sel == self._b6:
393            sel_name = 'b6'
394        elif sel == self._b7:
395            sel_name = 'b7'
396        else:
397            sel_name = 'b1'
398        assert bui.app.classic is not None
399        bui.app.ui_v1.window_states[type(self)] = sel_name
400
401    def _update(self) -> None:
402        plus = bui.app.plus
403        assert plus is not None
404
405        # Kiosk-mode is designed to be used signed-out... try for force
406        # the issue.
407        if plus.get_v1_account_state() == 'signed_in':
408            # _bs.sign_out()
409            # FIXME: Try to delete player profiles here too.
410            pass
411        else:
412            # Also make sure there's no player profiles.
413            appconfig = bui.app.config
414            appconfig['Player Profiles'] = {}
415
416    def _do_game(self, mode: str) -> None:
417        assert bui.app.classic is not None
418        self._save_state()
419        if mode in ['epic', 'ctf', 'hockey']:
420            appconfig = bui.app.config
421            if 'Team Tournament Playlists' not in appconfig:
422                appconfig['Team Tournament Playlists'] = {}
423            if 'Free-for-All Playlists' not in appconfig:
424                appconfig['Free-for-All Playlists'] = {}
425            appconfig['Show Tutorial'] = False
426            if mode == 'epic':
427                appconfig['Free-for-All Playlists']['Just Epic Elim'] = [
428                    {
429                        'settings': {
430                            'Epic Mode': 1,
431                            'Lives Per Player': 1,
432                            'Respawn Times': 1.0,
433                            'Time Limit': 0,
434                            'map': 'Tip Top',
435                        },
436                        'type': 'bs_elimination.EliminationGame',
437                    }
438                ]
439                appconfig['Free-for-All Playlist Selection'] = 'Just Epic Elim'
440                bui.fade_screen(
441                    False,
442                    endcall=bui.Call(
443                        bui.pushcall,
444                        bui.Call(bs.new_host_session, bs.FreeForAllSession),
445                    ),
446                )
447            else:
448                if mode == 'ctf':
449                    appconfig['Team Tournament Playlists']['Just CTF'] = [
450                        {
451                            'settings': {
452                                'Epic Mode': False,
453                                'Flag Idle Return Time': 30,
454                                'Flag Touch Return Time': 0,
455                                'Respawn Times': 1.0,
456                                'Score to Win': 3,
457                                'Time Limit': 0,
458                                'map': 'Bridgit',
459                            },
460                            'type': 'bs_capture_the_flag.CTFGame',
461                        }
462                    ]
463                    appconfig['Team Tournament Playlist Selection'] = 'Just CTF'
464                else:
465                    appconfig['Team Tournament Playlists']['Just Hockey'] = [
466                        {
467                            'settings': {
468                                'Respawn Times': 1.0,
469                                'Score to Win': 1,
470                                'Time Limit': 0,
471                                'map': 'Hockey Stadium',
472                            },
473                            'type': 'bs_hockey.HockeyGame',
474                        }
475                    ]
476                    appconfig['Team Tournament Playlist Selection'] = (
477                        'Just Hockey'
478                    )
479                bui.fade_screen(
480                    False,
481                    endcall=bui.Call(
482                        bui.pushcall,
483                        bui.Call(bs.new_host_session, bs.DualTeamSession),
484                    ),
485                )
486            bui.containerwidget(edit=self._root_widget, transition='out_left')
487            return
488
489        game = (
490            'Easy:Onslaught Training'
491            if mode == 'easy'
492            else (
493                'Easy:Rookie Football'
494                if mode == 'medium'
495                else 'Easy:Uber Onslaught'
496            )
497        )
498        cfg = bui.app.config
499        cfg['Selected Coop Game'] = game
500        cfg.commit()
501        if bui.app.classic.launch_coop_game(game, force=True):
502            bui.containerwidget(edit=self._root_widget, transition='out_left')
503
504    def _do_full_menu(self) -> None:
505        from bauiv1lib.mainmenu import MainMenuWindow
506
507        # no-op if our underlying widget is dead or on its way out.
508        if not self._root_widget or self._root_widget.transitioning_out:
509            return
510
511        assert bui.app.classic is not None
512
513        self._save_state()
514        bui.containerwidget(edit=self._root_widget, transition='out_left')
515        bui.app.classic.did_menu_intro = True  # prevent delayed transition-in
516        bui.app.ui_v1.set_main_menu_window(
517            MainMenuWindow().get_root_widget(), from_window=self._root_widget
518        )

Kiosk mode window.

KioskWindow(transition: str = 'in_right')
 15    def __init__(self, transition: str = 'in_right'):
 16        # pylint: disable=too-many-locals, too-many-statements
 17        from bauiv1lib.confirm import QuitWindow
 18
 19        assert bui.app.classic is not None
 20
 21        self._width = 720.0
 22        self._height = 340.0
 23
 24        def _do_cancel() -> None:
 25            QuitWindow(swish=True, quit_type=bui.QuitType.BACK)
 26
 27        super().__init__(
 28            root_widget=bui.containerwidget(
 29                size=(self._width, self._height),
 30                transition=transition,
 31                on_cancel_call=_do_cancel,
 32                background=False,
 33                stack_offset=(0, -130),
 34            )
 35        )
 36
 37        self._r = 'kioskWindow'
 38
 39        self._show_multiplayer = False
 40
 41        # Let's reset all random player names every time we hit the main menu.
 42        bs.reset_random_player_names()
 43
 44        # Reset achievements too (at least locally).
 45        bui.app.config['Achievements'] = {}
 46
 47        t_delay_base = 0.0
 48        t_delay_scale = 0.0
 49        if not bui.app.classic.did_menu_intro:
 50            t_delay_base = 1.0
 51            t_delay_scale = 1.0
 52
 53        mesh_opaque = bui.getmesh('level_select_button_opaque')
 54        mesh_transparent = bui.getmesh('level_select_button_transparent')
 55        mask_tex = bui.gettexture('mapPreviewMask')
 56
 57        y_extra = 130.0 + (0.0 if self._show_multiplayer else -130.0)
 58        b_width = 250.0
 59        b_height = 200.0
 60        b_space = 280.0
 61        b_v = 80.0 + y_extra
 62        label_height = 130.0 + y_extra
 63        img_width = 180.0
 64        img_v = 158.0 + y_extra
 65
 66        if self._show_multiplayer:
 67            tdelay = t_delay_base + t_delay_scale * 1.3
 68            bui.textwidget(
 69                parent=self._root_widget,
 70                size=(0, 0),
 71                position=(self._width * 0.5, self._height + y_extra - 44),
 72                transition_delay=tdelay,
 73                text=bui.Lstr(resource=self._r + '.singlePlayerExamplesText'),
 74                flatness=1.0,
 75                scale=1.2,
 76                h_align='center',
 77                v_align='center',
 78                shadow=1.0,
 79            )
 80        else:
 81            tdelay = t_delay_base + t_delay_scale * 0.7
 82            bui.textwidget(
 83                parent=self._root_widget,
 84                size=(0, 0),
 85                position=(self._width * 0.5, self._height + y_extra - 34),
 86                transition_delay=tdelay,
 87                text=(
 88                    bui.Lstr(
 89                        resource='demoText',
 90                        fallback_resource='mainMenu.demoMenuText',
 91                    )
 92                    if bui.app.env.demo
 93                    else 'ARCADE'
 94                ),
 95                flatness=1.0,
 96                scale=1.2,
 97                h_align='center',
 98                v_align='center',
 99                shadow=1.0,
100            )
101        h = self._width * 0.5 - b_space
102        tdelay = t_delay_base + t_delay_scale * 0.7
103        self._b1 = btn = bui.buttonwidget(
104            parent=self._root_widget,
105            autoselect=True,
106            size=(b_width, b_height),
107            on_activate_call=bui.Call(self._do_game, 'easy'),
108            transition_delay=tdelay,
109            position=(h - b_width * 0.5, b_v),
110            label='',
111            button_type='square',
112        )
113        bui.textwidget(
114            parent=self._root_widget,
115            draw_controller=btn,
116            transition_delay=tdelay,
117            size=(0, 0),
118            position=(h, label_height),
119            maxwidth=b_width * 0.7,
120            text=bui.Lstr(resource=self._r + '.easyText'),
121            scale=1.3,
122            h_align='center',
123            v_align='center',
124        )
125        bui.imagewidget(
126            parent=self._root_widget,
127            draw_controller=btn,
128            size=(img_width, 0.5 * img_width),
129            transition_delay=tdelay,
130            position=(h - img_width * 0.5, img_v),
131            texture=bui.gettexture('doomShroomPreview'),
132            mesh_opaque=mesh_opaque,
133            mesh_transparent=mesh_transparent,
134            mask_texture=mask_tex,
135        )
136        h = self._width * 0.5
137        tdelay = t_delay_base + t_delay_scale * 0.65
138        self._b2 = btn = bui.buttonwidget(
139            parent=self._root_widget,
140            autoselect=True,
141            size=(b_width, b_height),
142            on_activate_call=bui.Call(self._do_game, 'medium'),
143            position=(h - b_width * 0.5, b_v),
144            label='',
145            button_type='square',
146            transition_delay=tdelay,
147        )
148        bui.textwidget(
149            parent=self._root_widget,
150            draw_controller=btn,
151            transition_delay=tdelay,
152            size=(0, 0),
153            position=(h, label_height),
154            maxwidth=b_width * 0.7,
155            text=bui.Lstr(resource=self._r + '.mediumText'),
156            scale=1.3,
157            h_align='center',
158            v_align='center',
159        )
160        bui.imagewidget(
161            parent=self._root_widget,
162            draw_controller=btn,
163            size=(img_width, 0.5 * img_width),
164            transition_delay=tdelay,
165            position=(h - img_width * 0.5, img_v),
166            texture=bui.gettexture('footballStadiumPreview'),
167            mesh_opaque=mesh_opaque,
168            mesh_transparent=mesh_transparent,
169            mask_texture=mask_tex,
170        )
171        h = self._width * 0.5 + b_space
172        tdelay = t_delay_base + t_delay_scale * 0.6
173        self._b3 = btn = bui.buttonwidget(
174            parent=self._root_widget,
175            autoselect=True,
176            size=(b_width, b_height),
177            on_activate_call=bui.Call(self._do_game, 'hard'),
178            transition_delay=tdelay,
179            position=(h - b_width * 0.5, b_v),
180            label='',
181            button_type='square',
182        )
183        bui.textwidget(
184            parent=self._root_widget,
185            draw_controller=btn,
186            transition_delay=tdelay,
187            size=(0, 0),
188            position=(h, label_height),
189            maxwidth=b_width * 0.7,
190            text='Hard',
191            scale=1.3,
192            h_align='center',
193            v_align='center',
194        )
195        bui.imagewidget(
196            parent=self._root_widget,
197            draw_controller=btn,
198            transition_delay=tdelay,
199            size=(img_width, 0.5 * img_width),
200            position=(h - img_width * 0.5, img_v),
201            texture=bui.gettexture('courtyardPreview'),
202            mesh_opaque=mesh_opaque,
203            mesh_transparent=mesh_transparent,
204            mask_texture=mask_tex,
205        )
206        if not bui.app.classic.did_menu_intro:
207            bui.app.classic.did_menu_intro = True
208
209        self._b4: bui.Widget | None
210        self._b5: bui.Widget | None
211        self._b6: bui.Widget | None
212
213        if bool(False):
214            bui.textwidget(
215                parent=self._root_widget,
216                size=(0, 0),
217                position=(self._width * 0.5, self._height + y_extra - 44),
218                transition_delay=tdelay,
219                text=bui.Lstr(resource=self._r + '.versusExamplesText'),
220                flatness=1.0,
221                scale=1.2,
222                h_align='center',
223                v_align='center',
224                shadow=1.0,
225            )
226            h = self._width * 0.5 - b_space
227            tdelay = t_delay_base + t_delay_scale * 0.7
228            self._b4 = btn = bui.buttonwidget(
229                parent=self._root_widget,
230                autoselect=True,
231                size=(b_width, b_height),
232                on_activate_call=bui.Call(self._do_game, 'ctf'),
233                transition_delay=tdelay,
234                position=(h - b_width * 0.5, b_v),
235                label='',
236                button_type='square',
237            )
238            bui.textwidget(
239                parent=self._root_widget,
240                draw_controller=btn,
241                transition_delay=tdelay,
242                size=(0, 0),
243                position=(h, label_height),
244                maxwidth=b_width * 0.7,
245                text=bui.Lstr(translate=('gameNames', 'Capture the Flag')),
246                scale=1.3,
247                h_align='center',
248                v_align='center',
249            )
250            bui.imagewidget(
251                parent=self._root_widget,
252                draw_controller=btn,
253                size=(img_width, 0.5 * img_width),
254                transition_delay=tdelay,
255                position=(h - img_width * 0.5, img_v),
256                texture=bui.gettexture('bridgitPreview'),
257                mesh_opaque=mesh_opaque,
258                mesh_transparent=mesh_transparent,
259                mask_texture=mask_tex,
260            )
261
262            h = self._width * 0.5
263            tdelay = t_delay_base + t_delay_scale * 0.65
264            self._b5 = btn = bui.buttonwidget(
265                parent=self._root_widget,
266                autoselect=True,
267                size=(b_width, b_height),
268                on_activate_call=bui.Call(self._do_game, 'hockey'),
269                position=(h - b_width * 0.5, b_v),
270                label='',
271                button_type='square',
272                transition_delay=tdelay,
273            )
274            bui.textwidget(
275                parent=self._root_widget,
276                draw_controller=btn,
277                transition_delay=tdelay,
278                size=(0, 0),
279                position=(h, label_height),
280                maxwidth=b_width * 0.7,
281                text=bui.Lstr(translate=('gameNames', 'Hockey')),
282                scale=1.3,
283                h_align='center',
284                v_align='center',
285            )
286            bui.imagewidget(
287                parent=self._root_widget,
288                draw_controller=btn,
289                size=(img_width, 0.5 * img_width),
290                transition_delay=tdelay,
291                position=(h - img_width * 0.5, img_v),
292                texture=bui.gettexture('hockeyStadiumPreview'),
293                mesh_opaque=mesh_opaque,
294                mesh_transparent=mesh_transparent,
295                mask_texture=mask_tex,
296            )
297            h = self._width * 0.5 + b_space
298            tdelay = t_delay_base + t_delay_scale * 0.6
299            self._b6 = btn = bui.buttonwidget(
300                parent=self._root_widget,
301                autoselect=True,
302                size=(b_width, b_height),
303                on_activate_call=bui.Call(self._do_game, 'epic'),
304                transition_delay=tdelay,
305                position=(h - b_width * 0.5, b_v),
306                label='',
307                button_type='square',
308            )
309            bui.textwidget(
310                parent=self._root_widget,
311                draw_controller=btn,
312                transition_delay=tdelay,
313                size=(0, 0),
314                position=(h, label_height),
315                maxwidth=b_width * 0.7,
316                text=bui.Lstr(resource=self._r + '.epicModeText'),
317                scale=1.3,
318                h_align='center',
319                v_align='center',
320            )
321            bui.imagewidget(
322                parent=self._root_widget,
323                draw_controller=btn,
324                transition_delay=tdelay,
325                size=(img_width, 0.5 * img_width),
326                position=(h - img_width * 0.5, img_v),
327                texture=bui.gettexture('tipTopPreview'),
328                mesh_opaque=mesh_opaque,
329                mesh_transparent=mesh_transparent,
330                mask_texture=mask_tex,
331            )
332        else:
333            self._b4 = self._b5 = self._b6 = None
334
335        self._b7: bui.Widget | None
336        if bui.app.env.arcade:
337            self._b7 = bui.buttonwidget(
338                parent=self._root_widget,
339                autoselect=True,
340                size=(b_width, 50),
341                color=(0.45, 0.55, 0.45),
342                textcolor=(0.7, 0.8, 0.7),
343                scale=0.5,
344                position=(self._width * 0.5 - 60.0, b_v - 70.0),
345                transition_delay=tdelay,
346                label=bui.Lstr(resource=self._r + '.fullMenuText'),
347                on_activate_call=self._do_full_menu,
348            )
349        else:
350            self._b7 = None
351        self._restore_state()
352        self._update()
353        self._update_timer = bui.AppTimer(
354            1.0, bui.WeakCall(self._update), repeat=True
355        )
Inherited Members
bauiv1._uitypes.Window
get_root_widget