Source code for bauiv1lib.kiosk

# Released under the MIT License. See LICENSE for details.
#
"""UI functionality for running the game in kiosk mode."""

from __future__ import annotations

from typing import override

import bascenev1 as bs
import bauiv1 as bui


[docs] class KioskWindow(bui.MainWindow): """Kiosk mode window.""" def __init__( self, transition: str | None = 'in_right', origin_widget: bui.Widget | None = None, ): # pylint: disable=too-many-locals, too-many-statements from bauiv1lib.confirm import QuitWindow assert bui.app.classic is not None self._width = 720.0 self._height = 340.0 def _do_cancel() -> None: QuitWindow(swish=True, quit_type=bui.QuitType.BACK) super().__init__( root_widget=bui.containerwidget( size=(self._width, self._height), # transition=transition, on_cancel_call=_do_cancel, background=False, stack_offset=(0, -130), ), transition=transition, origin_widget=origin_widget, ) self._r = 'kioskWindow' self._show_multiplayer = False # Let's reset all random player names every time we hit the main menu. bs.reset_random_player_names() # Reset achievements too (at least locally). bui.app.config['Achievements'] = {} t_delay_base = 0.0 t_delay_scale = 0.0 if not bui.app.classic.did_menu_intro: t_delay_base = 1.0 t_delay_scale = 1.0 mesh_opaque = bui.getmesh('level_select_button_opaque') mesh_transparent = bui.getmesh('level_select_button_transparent') mask_tex = bui.gettexture('mapPreviewMask') y_extra = 130.0 + (0.0 if self._show_multiplayer else -130.0) b_width = 250.0 b_height = 200.0 b_space = 280.0 b_v = 80.0 + y_extra label_height = 130.0 + y_extra img_width = 180.0 img_v = 158.0 + y_extra if self._show_multiplayer: tdelay = t_delay_base + t_delay_scale * 1.3 bui.textwidget( parent=self._root_widget, size=(0, 0), position=(self._width * 0.5, self._height + y_extra - 44), transition_delay=tdelay, text=bui.Lstr(resource=f'{self._r}.singlePlayerExamplesText'), flatness=1.0, scale=1.2, h_align='center', v_align='center', shadow=1.0, ) else: tdelay = t_delay_base + t_delay_scale * 0.7 bui.textwidget( parent=self._root_widget, size=(0, 0), position=(self._width * 0.5, self._height + y_extra - 34), transition_delay=tdelay, text=( bui.Lstr( resource='demoText', fallback_resource='mainMenu.demoMenuText', ) if bui.app.env.demo else 'ARCADE' ), flatness=1.0, scale=1.2, h_align='center', v_align='center', shadow=1.0, ) h = self._width * 0.5 - b_space tdelay = t_delay_base + t_delay_scale * 0.7 self._b1 = btn = bui.buttonwidget( parent=self._root_widget, autoselect=True, size=(b_width, b_height), on_activate_call=bui.Call(self._do_game, 'easy'), transition_delay=tdelay, position=(h - b_width * 0.5, b_v), label='', button_type='square', ) bui.textwidget( parent=self._root_widget, draw_controller=btn, transition_delay=tdelay, size=(0, 0), position=(h, label_height), maxwidth=b_width * 0.7, text=bui.Lstr(resource=f'{self._r}.easyText'), scale=1.3, h_align='center', v_align='center', ) bui.imagewidget( parent=self._root_widget, draw_controller=btn, size=(img_width, 0.5 * img_width), transition_delay=tdelay, position=(h - img_width * 0.5, img_v), texture=bui.gettexture('doomShroomPreview'), mesh_opaque=mesh_opaque, mesh_transparent=mesh_transparent, mask_texture=mask_tex, ) h = self._width * 0.5 tdelay = t_delay_base + t_delay_scale * 0.65 self._b2 = btn = bui.buttonwidget( parent=self._root_widget, autoselect=True, size=(b_width, b_height), on_activate_call=bui.Call(self._do_game, 'medium'), position=(h - b_width * 0.5, b_v), label='', button_type='square', transition_delay=tdelay, ) bui.textwidget( parent=self._root_widget, draw_controller=btn, transition_delay=tdelay, size=(0, 0), position=(h, label_height), maxwidth=b_width * 0.7, text=bui.Lstr(resource=f'{self._r}.mediumText'), scale=1.3, h_align='center', v_align='center', ) bui.imagewidget( parent=self._root_widget, draw_controller=btn, size=(img_width, 0.5 * img_width), transition_delay=tdelay, position=(h - img_width * 0.5, img_v), texture=bui.gettexture('footballStadiumPreview'), mesh_opaque=mesh_opaque, mesh_transparent=mesh_transparent, mask_texture=mask_tex, ) h = self._width * 0.5 + b_space tdelay = t_delay_base + t_delay_scale * 0.6 self._b3 = btn = bui.buttonwidget( parent=self._root_widget, autoselect=True, size=(b_width, b_height), on_activate_call=bui.Call(self._do_game, 'hard'), transition_delay=tdelay, position=(h - b_width * 0.5, b_v), label='', button_type='square', ) bui.textwidget( parent=self._root_widget, draw_controller=btn, transition_delay=tdelay, size=(0, 0), position=(h, label_height), maxwidth=b_width * 0.7, text='Hard', scale=1.3, h_align='center', v_align='center', ) bui.imagewidget( parent=self._root_widget, draw_controller=btn, transition_delay=tdelay, size=(img_width, 0.5 * img_width), position=(h - img_width * 0.5, img_v), texture=bui.gettexture('courtyardPreview'), mesh_opaque=mesh_opaque, mesh_transparent=mesh_transparent, mask_texture=mask_tex, ) if not bui.app.classic.did_menu_intro: bui.app.classic.did_menu_intro = True self._b4: bui.Widget | None self._b5: bui.Widget | None self._b6: bui.Widget | None if bool(False): bui.textwidget( parent=self._root_widget, size=(0, 0), position=(self._width * 0.5, self._height + y_extra - 44), transition_delay=tdelay, text=bui.Lstr(resource=f'{self._r}.versusExamplesText'), flatness=1.0, scale=1.2, h_align='center', v_align='center', shadow=1.0, ) h = self._width * 0.5 - b_space tdelay = t_delay_base + t_delay_scale * 0.7 self._b4 = btn = bui.buttonwidget( parent=self._root_widget, autoselect=True, size=(b_width, b_height), on_activate_call=bui.Call(self._do_game, 'ctf'), transition_delay=tdelay, position=(h - b_width * 0.5, b_v), label='', button_type='square', ) bui.textwidget( parent=self._root_widget, draw_controller=btn, transition_delay=tdelay, size=(0, 0), position=(h, label_height), maxwidth=b_width * 0.7, text=bui.Lstr(translate=('gameNames', 'Capture the Flag')), scale=1.3, h_align='center', v_align='center', ) bui.imagewidget( parent=self._root_widget, draw_controller=btn, size=(img_width, 0.5 * img_width), transition_delay=tdelay, position=(h - img_width * 0.5, img_v), texture=bui.gettexture('bridgitPreview'), mesh_opaque=mesh_opaque, mesh_transparent=mesh_transparent, mask_texture=mask_tex, ) h = self._width * 0.5 tdelay = t_delay_base + t_delay_scale * 0.65 self._b5 = btn = bui.buttonwidget( parent=self._root_widget, autoselect=True, size=(b_width, b_height), on_activate_call=bui.Call(self._do_game, 'hockey'), position=(h - b_width * 0.5, b_v), label='', button_type='square', transition_delay=tdelay, ) bui.textwidget( parent=self._root_widget, draw_controller=btn, transition_delay=tdelay, size=(0, 0), position=(h, label_height), maxwidth=b_width * 0.7, text=bui.Lstr(translate=('gameNames', 'Hockey')), scale=1.3, h_align='center', v_align='center', ) bui.imagewidget( parent=self._root_widget, draw_controller=btn, size=(img_width, 0.5 * img_width), transition_delay=tdelay, position=(h - img_width * 0.5, img_v), texture=bui.gettexture('hockeyStadiumPreview'), mesh_opaque=mesh_opaque, mesh_transparent=mesh_transparent, mask_texture=mask_tex, ) h = self._width * 0.5 + b_space tdelay = t_delay_base + t_delay_scale * 0.6 self._b6 = btn = bui.buttonwidget( parent=self._root_widget, autoselect=True, size=(b_width, b_height), on_activate_call=bui.Call(self._do_game, 'epic'), transition_delay=tdelay, position=(h - b_width * 0.5, b_v), label='', button_type='square', ) bui.textwidget( parent=self._root_widget, draw_controller=btn, transition_delay=tdelay, size=(0, 0), position=(h, label_height), maxwidth=b_width * 0.7, text=bui.Lstr(resource=f'{self._r}.epicModeText'), scale=1.3, h_align='center', v_align='center', ) bui.imagewidget( parent=self._root_widget, draw_controller=btn, transition_delay=tdelay, size=(img_width, 0.5 * img_width), position=(h - img_width * 0.5, img_v), texture=bui.gettexture('tipTopPreview'), mesh_opaque=mesh_opaque, mesh_transparent=mesh_transparent, mask_texture=mask_tex, ) else: self._b4 = self._b5 = self._b6 = None self._b7: bui.Widget | None if bui.app.env.arcade: self._b7 = bui.buttonwidget( parent=self._root_widget, autoselect=True, size=(b_width, 50), color=(0.45, 0.55, 0.45), textcolor=(0.7, 0.8, 0.7), scale=0.5, position=(self._width * 0.5 - 60.0, b_v - 70.0), transition_delay=tdelay, label=bui.Lstr(resource=f'{self._r}.fullMenuText'), on_activate_call=self._do_full_menu, ) else: self._b7 = None self._restore_state() self._update() self._update_timer = bui.AppTimer( 1.0, bui.WeakCall(self._update), repeat=True )
[docs] @override def get_main_window_state(self) -> bui.MainWindowState: # Support recreating our window for back/refresh purposes. cls = type(self) return bui.BasicMainWindowState( create_call=lambda transition, origin_widget: cls( transition=transition, origin_widget=origin_widget ) )
[docs] @override def on_main_window_close(self) -> None: self._save_state()
def _restore_state(self) -> None: assert bui.app.classic is not None sel_name = bui.app.ui_v1.window_states.get(type(self)) sel: bui.Widget | None if sel_name == 'b1': sel = self._b1 elif sel_name == 'b2': sel = self._b2 elif sel_name == 'b3': sel = self._b3 elif sel_name == 'b4': sel = self._b4 elif sel_name == 'b5': sel = self._b5 elif sel_name == 'b6': sel = self._b6 elif sel_name == 'b7': sel = self._b7 else: sel = self._b1 if sel: bui.containerwidget(edit=self._root_widget, selected_child=sel) def _save_state(self) -> None: sel = self._root_widget.get_selected_child() if sel == self._b1: sel_name = 'b1' elif sel == self._b2: sel_name = 'b2' elif sel == self._b3: sel_name = 'b3' elif sel == self._b4: sel_name = 'b4' elif sel == self._b5: sel_name = 'b5' elif sel == self._b6: sel_name = 'b6' elif sel == self._b7: sel_name = 'b7' else: sel_name = 'b1' assert bui.app.classic is not None bui.app.ui_v1.window_states[type(self)] = sel_name def _update(self) -> None: plus = bui.app.plus assert plus is not None # Kiosk-mode is designed to be used signed-out... try for force # the issue. if plus.get_v1_account_state() == 'signed_in': # _bs.sign_out() # FIXME: Try to delete player profiles here too. pass else: # Also make sure there's no player profiles. appconfig = bui.app.config appconfig['Player Profiles'] = {} def _do_game(self, mode: str) -> None: assert bui.app.classic is not None self._save_state() if mode in ['epic', 'ctf', 'hockey']: appconfig = bui.app.config if 'Team Tournament Playlists' not in appconfig: appconfig['Team Tournament Playlists'] = {} if 'Free-for-All Playlists' not in appconfig: appconfig['Free-for-All Playlists'] = {} appconfig['Show Tutorial'] = False if mode == 'epic': appconfig['Free-for-All Playlists']['Just Epic Elim'] = [ { 'settings': { 'Epic Mode': 1, 'Lives Per Player': 1, 'Respawn Times': 1.0, 'Time Limit': 0, 'map': 'Tip Top', }, 'type': 'bs_elimination.EliminationGame', } ] appconfig['Free-for-All Playlist Selection'] = 'Just Epic Elim' bui.fade_screen( False, endcall=bui.Call( bui.pushcall, bui.Call(bs.new_host_session, bs.FreeForAllSession), ), ) else: if mode == 'ctf': appconfig['Team Tournament Playlists']['Just CTF'] = [ { 'settings': { 'Epic Mode': False, 'Flag Idle Return Time': 30, 'Flag Touch Return Time': 0, 'Respawn Times': 1.0, 'Score to Win': 3, 'Time Limit': 0, 'map': 'Bridgit', }, 'type': 'bs_capture_the_flag.CTFGame', } ] appconfig['Team Tournament Playlist Selection'] = 'Just CTF' else: appconfig['Team Tournament Playlists']['Just Hockey'] = [ { 'settings': { 'Respawn Times': 1.0, 'Score to Win': 1, 'Time Limit': 0, 'map': 'Hockey Stadium', }, 'type': 'bs_hockey.HockeyGame', } ] appconfig['Team Tournament Playlist Selection'] = ( 'Just Hockey' ) bui.fade_screen( False, endcall=bui.Call( bui.pushcall, bui.Call(bs.new_host_session, bs.DualTeamSession), ), ) bui.containerwidget(edit=self._root_widget, transition='out_left') return game = ( 'Easy:Onslaught Training' if mode == 'easy' else ( 'Easy:Rookie Football' if mode == 'medium' else 'Easy:Uber Onslaught' ) ) cfg = bui.app.config cfg['Selected Coop Game'] = game cfg.commit() if bui.app.classic.launch_coop_game(game, force=True): bui.containerwidget(edit=self._root_widget, transition='out_left') def _do_full_menu(self) -> None: # pylint: disable=cyclic-import from bauiv1lib.mainmenu import MainMenuWindow # no-op if we're not in control. if not self.main_window_has_control(): return assert bui.app.classic is not None self._save_state() bui.app.classic.did_menu_intro = True # prevent delayed transition-in self.main_window_replace(MainMenuWindow())