bauiv1lib.play

Provides the top level play window.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Provides the top level play window."""
  4
  5from __future__ import annotations
  6
  7import logging
  8
  9import bascenev1 as bs
 10import bauiv1 as bui
 11
 12
 13class PlayWindow(bui.Window):
 14    """Window for selecting overall play type."""
 15
 16    def __init__(
 17        self,
 18        transition: str = 'in_right',
 19        origin_widget: bui.Widget | None = None,
 20    ):
 21        # pylint: disable=too-many-statements
 22        # pylint: disable=too-many-locals
 23        import threading
 24
 25        # Preload some modules we use in a background thread so we won't
 26        # have a visual hitch when the user taps them.
 27        threading.Thread(target=self._preload_modules).start()
 28
 29        # We can currently be used either for main menu duty or for selecting
 30        # playlists (should make this more elegant/general).
 31        assert bui.app.classic is not None
 32        self._is_main_menu = not bui.app.ui_v1.selecting_private_party_playlist
 33
 34        uiscale = bui.app.ui_v1.uiscale
 35        width = 1000 if uiscale is bui.UIScale.SMALL else 800
 36        x_offs = 100 if uiscale is bui.UIScale.SMALL else 0
 37        height = 550
 38        button_width = 400
 39
 40        scale_origin: tuple[float, float] | None
 41        if origin_widget is not None:
 42            self._transition_out = 'out_scale'
 43            scale_origin = origin_widget.get_screen_space_center()
 44            transition = 'in_scale'
 45        else:
 46            self._transition_out = 'out_right'
 47            scale_origin = None
 48
 49        self._r = 'playWindow'
 50
 51        super().__init__(
 52            root_widget=bui.containerwidget(
 53                size=(width, height),
 54                transition=transition,
 55                toolbar_visibility='menu_full',
 56                scale_origin_stack_offset=scale_origin,
 57                scale=(
 58                    1.6
 59                    if uiscale is bui.UIScale.SMALL
 60                    else 0.9
 61                    if uiscale is bui.UIScale.MEDIUM
 62                    else 0.8
 63                ),
 64                stack_offset=(0, 0) if uiscale is bui.UIScale.SMALL else (0, 0),
 65            )
 66        )
 67        self._back_button = back_button = btn = bui.buttonwidget(
 68            parent=self._root_widget,
 69            position=(55 + x_offs, height - 132),
 70            size=(120, 60),
 71            scale=1.1,
 72            text_res_scale=1.5,
 73            text_scale=1.2,
 74            autoselect=True,
 75            label=bui.Lstr(resource='backText'),
 76            button_type='back',
 77        )
 78
 79        txt = bui.textwidget(
 80            parent=self._root_widget,
 81            position=(width * 0.5, height - 101),
 82            # position=(width * 0.5, height -
 83            #           (101 if main_menu else 61)),
 84            size=(0, 0),
 85            text=bui.Lstr(
 86                resource=(self._r + '.titleText')
 87                if self._is_main_menu
 88                else 'playlistsText'
 89            ),
 90            scale=1.7,
 91            res_scale=2.0,
 92            maxwidth=400,
 93            color=bui.app.ui_v1.heading_color,
 94            h_align='center',
 95            v_align='center',
 96        )
 97
 98        bui.buttonwidget(
 99            edit=btn,
100            button_type='backSmall',
101            size=(60, 60),
102            label=bui.charstr(bui.SpecialChar.BACK),
103        )
104        if bui.app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL:
105            bui.textwidget(edit=txt, text='')
106
107        v = height - (110 if self._is_main_menu else 90)
108        v -= 100
109        clr = (0.6, 0.7, 0.6, 1.0)
110        v -= 280 if self._is_main_menu else 180
111        v += (
112            30
113            if bui.app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL
114            else 0
115        )
116        hoffs = x_offs + 80 if self._is_main_menu else x_offs - 100
117        scl = 1.13 if self._is_main_menu else 0.68
118
119        self._lineup_tex = bui.gettexture('playerLineup')
120        angry_computer_transparent_mesh = bui.getmesh(
121            'angryComputerTransparent'
122        )
123        self._lineup_1_transparent_mesh = bui.getmesh(
124            'playerLineup1Transparent'
125        )
126        self._lineup_2_transparent_mesh = bui.getmesh(
127            'playerLineup2Transparent'
128        )
129        self._lineup_3_transparent_mesh = bui.getmesh(
130            'playerLineup3Transparent'
131        )
132        self._lineup_4_transparent_mesh = bui.getmesh(
133            'playerLineup4Transparent'
134        )
135        self._eyes_mesh = bui.getmesh('plasticEyesTransparent')
136
137        self._coop_button: bui.Widget | None = None
138
139        # Only show coop button in main-menu variant.
140        if self._is_main_menu:
141            self._coop_button = btn = bui.buttonwidget(
142                parent=self._root_widget,
143                position=(hoffs, v + (scl * 15)),
144                size=(
145                    scl * button_width,
146                    scl * 300,
147                ),
148                extra_touch_border_scale=0.1,
149                autoselect=True,
150                label='',
151                button_type='square',
152                text_scale=1.13,
153                on_activate_call=self._coop,
154            )
155
156            if bui.app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL:
157                bui.widget(
158                    edit=btn,
159                    left_widget=bui.get_special_widget('back_button'),
160                )
161                bui.widget(
162                    edit=btn,
163                    up_widget=bui.get_special_widget('account_button'),
164                )
165                bui.widget(
166                    edit=btn,
167                    down_widget=bui.get_special_widget('settings_button'),
168                )
169
170            self._draw_dude(
171                0,
172                btn,
173                hoffs,
174                v,
175                scl,
176                position=(140, 30),
177                color=(0.72, 0.4, 1.0),
178            )
179            self._draw_dude(
180                1,
181                btn,
182                hoffs,
183                v,
184                scl,
185                position=(185, 53),
186                color=(0.71, 0.5, 1.0),
187            )
188            self._draw_dude(
189                2,
190                btn,
191                hoffs,
192                v,
193                scl,
194                position=(220, 27),
195                color=(0.67, 0.44, 1.0),
196            )
197            self._draw_dude(
198                3, btn, hoffs, v, scl, position=(255, 57), color=(0.7, 0.3, 1.0)
199            )
200            bui.imagewidget(
201                parent=self._root_widget,
202                draw_controller=btn,
203                position=(hoffs + scl * 230, v + scl * 153),
204                size=(scl * 115, scl * 115),
205                texture=self._lineup_tex,
206                mesh_transparent=angry_computer_transparent_mesh,
207            )
208
209            bui.textwidget(
210                parent=self._root_widget,
211                draw_controller=btn,
212                position=(hoffs + scl * (-10), v + scl * 95),
213                size=(scl * button_width, scl * 50),
214                text=bui.Lstr(
215                    resource='playModes.singlePlayerCoopText',
216                    fallback_resource='playModes.coopText',
217                ),
218                maxwidth=scl * button_width * 0.7,
219                res_scale=1.5,
220                h_align='center',
221                v_align='center',
222                color=(0.7, 0.9, 0.7, 1.0),
223                scale=scl * 2.3,
224            )
225
226            bui.textwidget(
227                parent=self._root_widget,
228                draw_controller=btn,
229                position=(hoffs + scl * (-10), v + (scl * 54)),
230                size=(scl * button_width, scl * 30),
231                text=bui.Lstr(resource=self._r + '.oneToFourPlayersText'),
232                h_align='center',
233                v_align='center',
234                scale=0.83 * scl,
235                flatness=1.0,
236                maxwidth=scl * button_width * 0.7,
237                color=clr,
238            )
239
240        scl = 0.5 if self._is_main_menu else 0.68
241        hoffs += 440 if self._is_main_menu else 216
242        v += 180 if self._is_main_menu else -68
243
244        self._teams_button = btn = bui.buttonwidget(
245            parent=self._root_widget,
246            position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)),
247            size=(
248                scl * button_width,
249                scl * (300 if self._is_main_menu else 360),
250            ),
251            extra_touch_border_scale=0.1,
252            autoselect=True,
253            label='',
254            button_type='square',
255            text_scale=1.13,
256            on_activate_call=self._team_tourney,
257        )
258
259        if bui.app.ui_v1.use_toolbars:
260            bui.widget(
261                edit=btn,
262                up_widget=bui.get_special_widget('tickets_plus_button'),
263                right_widget=bui.get_special_widget('party_button'),
264            )
265
266        xxx = -14
267        self._draw_dude(
268            2,
269            btn,
270            hoffs,
271            v,
272            scl,
273            position=(xxx + 148, 30),
274            color=(0.2, 0.4, 1.0),
275        )
276        self._draw_dude(
277            3,
278            btn,
279            hoffs,
280            v,
281            scl,
282            position=(xxx + 181, 53),
283            color=(0.3, 0.4, 1.0),
284        )
285        self._draw_dude(
286            1,
287            btn,
288            hoffs,
289            v,
290            scl,
291            position=(xxx + 216, 33),
292            color=(0.3, 0.5, 1.0),
293        )
294        self._draw_dude(
295            0,
296            btn,
297            hoffs,
298            v,
299            scl,
300            position=(xxx + 245, 57),
301            color=(0.3, 0.5, 1.0),
302        )
303
304        xxx = 155
305        self._draw_dude(
306            0,
307            btn,
308            hoffs,
309            v,
310            scl,
311            position=(xxx + 151, 30),
312            color=(1.0, 0.5, 0.4),
313        )
314        self._draw_dude(
315            1,
316            btn,
317            hoffs,
318            v,
319            scl,
320            position=(xxx + 189, 53),
321            color=(1.0, 0.58, 0.58),
322        )
323        self._draw_dude(
324            3,
325            btn,
326            hoffs,
327            v,
328            scl,
329            position=(xxx + 223, 27),
330            color=(1.0, 0.5, 0.5),
331        )
332        self._draw_dude(
333            2,
334            btn,
335            hoffs,
336            v,
337            scl,
338            position=(xxx + 257, 57),
339            color=(1.0, 0.5, 0.5),
340        )
341
342        bui.textwidget(
343            parent=self._root_widget,
344            draw_controller=btn,
345            position=(hoffs + scl * (-10), v + scl * 95),
346            size=(scl * button_width, scl * 50),
347            text=bui.Lstr(
348                resource='playModes.teamsText', fallback_resource='teamsText'
349            ),
350            res_scale=1.5,
351            maxwidth=scl * button_width * 0.7,
352            h_align='center',
353            v_align='center',
354            color=(0.7, 0.9, 0.7, 1.0),
355            scale=scl * 2.3,
356        )
357        bui.textwidget(
358            parent=self._root_widget,
359            draw_controller=btn,
360            position=(hoffs + scl * (-10), v + (scl * 54)),
361            size=(scl * button_width, scl * 30),
362            text=bui.Lstr(resource=self._r + '.twoToEightPlayersText'),
363            h_align='center',
364            v_align='center',
365            res_scale=1.5,
366            scale=0.9 * scl,
367            flatness=1.0,
368            maxwidth=scl * button_width * 0.7,
369            color=clr,
370        )
371
372        hoffs += 0 if self._is_main_menu else 300
373        v -= 155 if self._is_main_menu else 0
374        self._free_for_all_button = btn = bui.buttonwidget(
375            parent=self._root_widget,
376            position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)),
377            size=(
378                scl * button_width,
379                scl * (300 if self._is_main_menu else 360),
380            ),
381            extra_touch_border_scale=0.1,
382            autoselect=True,
383            label='',
384            button_type='square',
385            text_scale=1.13,
386            on_activate_call=self._free_for_all,
387        )
388
389        xxx = -5
390        self._draw_dude(
391            0,
392            btn,
393            hoffs,
394            v,
395            scl,
396            position=(xxx + 140, 30),
397            color=(0.4, 1.0, 0.4),
398        )
399        self._draw_dude(
400            3,
401            btn,
402            hoffs,
403            v,
404            scl,
405            position=(xxx + 185, 53),
406            color=(1.0, 0.4, 0.5),
407        )
408        self._draw_dude(
409            1,
410            btn,
411            hoffs,
412            v,
413            scl,
414            position=(xxx + 220, 27),
415            color=(0.4, 0.5, 1.0),
416        )
417        self._draw_dude(
418            2,
419            btn,
420            hoffs,
421            v,
422            scl,
423            position=(xxx + 255, 57),
424            color=(0.5, 1.0, 0.4),
425        )
426        xxx = 140
427        self._draw_dude(
428            2,
429            btn,
430            hoffs,
431            v,
432            scl,
433            position=(xxx + 148, 30),
434            color=(1.0, 0.9, 0.4),
435        )
436        self._draw_dude(
437            0,
438            btn,
439            hoffs,
440            v,
441            scl,
442            position=(xxx + 182, 53),
443            color=(0.7, 1.0, 0.5),
444        )
445        self._draw_dude(
446            3,
447            btn,
448            hoffs,
449            v,
450            scl,
451            position=(xxx + 233, 27),
452            color=(0.7, 0.5, 0.9),
453        )
454        self._draw_dude(
455            1,
456            btn,
457            hoffs,
458            v,
459            scl,
460            position=(xxx + 266, 53),
461            color=(0.4, 0.5, 0.8),
462        )
463        bui.textwidget(
464            parent=self._root_widget,
465            draw_controller=btn,
466            position=(hoffs + scl * (-10), v + scl * 95),
467            size=(scl * button_width, scl * 50),
468            text=bui.Lstr(
469                resource='playModes.freeForAllText',
470                fallback_resource='freeForAllText',
471            ),
472            maxwidth=scl * button_width * 0.7,
473            h_align='center',
474            v_align='center',
475            color=(0.7, 0.9, 0.7, 1.0),
476            scale=scl * 1.9,
477        )
478        bui.textwidget(
479            parent=self._root_widget,
480            draw_controller=btn,
481            position=(hoffs + scl * (-10), v + (scl * 54)),
482            size=(scl * button_width, scl * 30),
483            text=bui.Lstr(resource=self._r + '.twoToEightPlayersText'),
484            h_align='center',
485            v_align='center',
486            scale=0.9 * scl,
487            flatness=1.0,
488            maxwidth=scl * button_width * 0.7,
489            color=clr,
490        )
491
492        if bui.app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL:
493            back_button.delete()
494            bui.containerwidget(
495                edit=self._root_widget,
496                on_cancel_call=self._back,
497                selected_child=self._coop_button
498                if self._is_main_menu
499                else self._teams_button,
500            )
501        else:
502            bui.buttonwidget(edit=back_button, on_activate_call=self._back)
503            bui.containerwidget(
504                edit=self._root_widget,
505                cancel_button=back_button,
506                selected_child=self._coop_button
507                if self._is_main_menu
508                else self._teams_button,
509            )
510
511        self._restore_state()
512
513    # noinspection PyUnresolvedReferences
514    @staticmethod
515    def _preload_modules() -> None:
516        """Preload modules we use; avoids hitches (called in bg thread)."""
517        import bauiv1lib.mainmenu as _unused1
518        import bauiv1lib.account as _unused2
519        import bauiv1lib.coop.browser as _unused3
520        import bauiv1lib.playlist.browser as _unused4
521
522    def _back(self) -> None:
523        # pylint: disable=cyclic-import
524        if self._is_main_menu:
525            from bauiv1lib.mainmenu import MainMenuWindow
526
527            self._save_state()
528            assert bui.app.classic is not None
529            bui.app.ui_v1.set_main_menu_window(
530                MainMenuWindow(transition='in_left').get_root_widget()
531            )
532            bui.containerwidget(
533                edit=self._root_widget, transition=self._transition_out
534            )
535        else:
536            from bauiv1lib.gather import GatherWindow
537
538            self._save_state()
539            assert bui.app.classic is not None
540            bui.app.ui_v1.set_main_menu_window(
541                GatherWindow(transition='in_left').get_root_widget()
542            )
543            bui.containerwidget(
544                edit=self._root_widget, transition=self._transition_out
545            )
546
547    def _coop(self) -> None:
548        # pylint: disable=cyclic-import
549        from bauiv1lib.account import show_sign_in_prompt
550        from bauiv1lib.coop.browser import CoopBrowserWindow
551
552        plus = bui.app.plus
553        assert plus is not None
554
555        if plus.get_v1_account_state() != 'signed_in':
556            show_sign_in_prompt()
557            return
558        self._save_state()
559        bui.containerwidget(edit=self._root_widget, transition='out_left')
560        assert bui.app.classic is not None
561        bui.app.ui_v1.set_main_menu_window(
562            CoopBrowserWindow(origin_widget=self._coop_button).get_root_widget()
563        )
564
565    def _team_tourney(self) -> None:
566        # pylint: disable=cyclic-import
567        from bauiv1lib.playlist.browser import PlaylistBrowserWindow
568
569        self._save_state()
570        bui.containerwidget(edit=self._root_widget, transition='out_left')
571        assert bui.app.classic is not None
572        bui.app.ui_v1.set_main_menu_window(
573            PlaylistBrowserWindow(
574                origin_widget=self._teams_button, sessiontype=bs.DualTeamSession
575            ).get_root_widget()
576        )
577
578    def _free_for_all(self) -> None:
579        # pylint: disable=cyclic-import
580        from bauiv1lib.playlist.browser import PlaylistBrowserWindow
581
582        self._save_state()
583        bui.containerwidget(edit=self._root_widget, transition='out_left')
584        assert bui.app.classic is not None
585        bui.app.ui_v1.set_main_menu_window(
586            PlaylistBrowserWindow(
587                origin_widget=self._free_for_all_button,
588                sessiontype=bs.FreeForAllSession,
589            ).get_root_widget()
590        )
591
592    def _draw_dude(
593        self,
594        i: int,
595        btn: bui.Widget,
596        hoffs: float,
597        v: float,
598        scl: float,
599        position: tuple[float, float],
600        color: tuple[float, float, float],
601    ) -> None:
602        h_extra = -100
603        v_extra = 130
604        eye_color = (
605            0.7 * 1.0 + 0.3 * color[0],
606            0.7 * 1.0 + 0.3 * color[1],
607            0.7 * 1.0 + 0.3 * color[2],
608        )
609        if i == 0:
610            bui.imagewidget(
611                parent=self._root_widget,
612                draw_controller=btn,
613                position=(
614                    hoffs + scl * (h_extra + position[0]),
615                    v + scl * (v_extra + position[1]),
616                ),
617                size=(scl * 60, scl * 80),
618                color=color,
619                texture=self._lineup_tex,
620                mesh_transparent=self._lineup_1_transparent_mesh,
621            )
622            bui.imagewidget(
623                parent=self._root_widget,
624                draw_controller=btn,
625                position=(
626                    hoffs + scl * (h_extra + position[0] + 12),
627                    v + scl * (v_extra + position[1] + 53),
628                ),
629                size=(scl * 36, scl * 18),
630                texture=self._lineup_tex,
631                color=eye_color,
632                mesh_transparent=self._eyes_mesh,
633            )
634        elif i == 1:
635            bui.imagewidget(
636                parent=self._root_widget,
637                draw_controller=btn,
638                position=(
639                    hoffs + scl * (h_extra + position[0]),
640                    v + scl * (v_extra + position[1]),
641                ),
642                size=(scl * 45, scl * 90),
643                color=color,
644                texture=self._lineup_tex,
645                mesh_transparent=self._lineup_2_transparent_mesh,
646            )
647            bui.imagewidget(
648                parent=self._root_widget,
649                draw_controller=btn,
650                position=(
651                    hoffs + scl * (h_extra + position[0] + 5),
652                    v + scl * (v_extra + position[1] + 67),
653                ),
654                size=(scl * 32, scl * 16),
655                texture=self._lineup_tex,
656                color=eye_color,
657                mesh_transparent=self._eyes_mesh,
658            )
659        elif i == 2:
660            bui.imagewidget(
661                parent=self._root_widget,
662                draw_controller=btn,
663                position=(
664                    hoffs + scl * (h_extra + position[0]),
665                    v + scl * (v_extra + position[1]),
666                ),
667                size=(scl * 45, scl * 90),
668                color=color,
669                texture=self._lineup_tex,
670                mesh_transparent=self._lineup_3_transparent_mesh,
671            )
672            bui.imagewidget(
673                parent=self._root_widget,
674                draw_controller=btn,
675                position=(
676                    hoffs + scl * (h_extra + position[0] + 5),
677                    v + scl * (v_extra + position[1] + 59),
678                ),
679                size=(scl * 34, scl * 17),
680                texture=self._lineup_tex,
681                color=eye_color,
682                mesh_transparent=self._eyes_mesh,
683            )
684        elif i == 3:
685            bui.imagewidget(
686                parent=self._root_widget,
687                draw_controller=btn,
688                position=(
689                    hoffs + scl * (h_extra + position[0]),
690                    v + scl * (v_extra + position[1]),
691                ),
692                size=(scl * 48, scl * 96),
693                color=color,
694                texture=self._lineup_tex,
695                mesh_transparent=self._lineup_4_transparent_mesh,
696            )
697            bui.imagewidget(
698                parent=self._root_widget,
699                draw_controller=btn,
700                position=(
701                    hoffs + scl * (h_extra + position[0] + 2),
702                    v + scl * (v_extra + position[1] + 62),
703                ),
704                size=(scl * 38, scl * 19),
705                texture=self._lineup_tex,
706                color=eye_color,
707                mesh_transparent=self._eyes_mesh,
708            )
709
710    def _save_state(self) -> None:
711        try:
712            sel = self._root_widget.get_selected_child()
713            if sel == self._teams_button:
714                sel_name = 'Team Games'
715            elif self._coop_button is not None and sel == self._coop_button:
716                sel_name = 'Co-op Games'
717            elif sel == self._free_for_all_button:
718                sel_name = 'Free-for-All Games'
719            elif sel == self._back_button:
720                sel_name = 'Back'
721            else:
722                raise ValueError(f'unrecognized selection {sel}')
723            assert bui.app.classic is not None
724            bui.app.ui_v1.window_states[type(self)] = sel_name
725        except Exception:
726            logging.exception('Error saving state for %s.', self)
727
728    def _restore_state(self) -> None:
729        try:
730            assert bui.app.classic is not None
731            sel_name = bui.app.ui_v1.window_states.get(type(self))
732            if sel_name == 'Team Games':
733                sel = self._teams_button
734            elif sel_name == 'Co-op Games' and self._coop_button is not None:
735                sel = self._coop_button
736            elif sel_name == 'Free-for-All Games':
737                sel = self._free_for_all_button
738            elif sel_name == 'Back':
739                sel = self._back_button
740            else:
741                sel = (
742                    self._coop_button
743                    if self._coop_button is not None
744                    else self._teams_button
745                )
746            bui.containerwidget(edit=self._root_widget, selected_child=sel)
747        except Exception:
748            logging.exception('Error restoring state for %s.', self)
class PlayWindow(bauiv1._uitypes.Window):
 14class PlayWindow(bui.Window):
 15    """Window for selecting overall play type."""
 16
 17    def __init__(
 18        self,
 19        transition: str = 'in_right',
 20        origin_widget: bui.Widget | None = None,
 21    ):
 22        # pylint: disable=too-many-statements
 23        # pylint: disable=too-many-locals
 24        import threading
 25
 26        # Preload some modules we use in a background thread so we won't
 27        # have a visual hitch when the user taps them.
 28        threading.Thread(target=self._preload_modules).start()
 29
 30        # We can currently be used either for main menu duty or for selecting
 31        # playlists (should make this more elegant/general).
 32        assert bui.app.classic is not None
 33        self._is_main_menu = not bui.app.ui_v1.selecting_private_party_playlist
 34
 35        uiscale = bui.app.ui_v1.uiscale
 36        width = 1000 if uiscale is bui.UIScale.SMALL else 800
 37        x_offs = 100 if uiscale is bui.UIScale.SMALL else 0
 38        height = 550
 39        button_width = 400
 40
 41        scale_origin: tuple[float, float] | None
 42        if origin_widget is not None:
 43            self._transition_out = 'out_scale'
 44            scale_origin = origin_widget.get_screen_space_center()
 45            transition = 'in_scale'
 46        else:
 47            self._transition_out = 'out_right'
 48            scale_origin = None
 49
 50        self._r = 'playWindow'
 51
 52        super().__init__(
 53            root_widget=bui.containerwidget(
 54                size=(width, height),
 55                transition=transition,
 56                toolbar_visibility='menu_full',
 57                scale_origin_stack_offset=scale_origin,
 58                scale=(
 59                    1.6
 60                    if uiscale is bui.UIScale.SMALL
 61                    else 0.9
 62                    if uiscale is bui.UIScale.MEDIUM
 63                    else 0.8
 64                ),
 65                stack_offset=(0, 0) if uiscale is bui.UIScale.SMALL else (0, 0),
 66            )
 67        )
 68        self._back_button = back_button = btn = bui.buttonwidget(
 69            parent=self._root_widget,
 70            position=(55 + x_offs, height - 132),
 71            size=(120, 60),
 72            scale=1.1,
 73            text_res_scale=1.5,
 74            text_scale=1.2,
 75            autoselect=True,
 76            label=bui.Lstr(resource='backText'),
 77            button_type='back',
 78        )
 79
 80        txt = bui.textwidget(
 81            parent=self._root_widget,
 82            position=(width * 0.5, height - 101),
 83            # position=(width * 0.5, height -
 84            #           (101 if main_menu else 61)),
 85            size=(0, 0),
 86            text=bui.Lstr(
 87                resource=(self._r + '.titleText')
 88                if self._is_main_menu
 89                else 'playlistsText'
 90            ),
 91            scale=1.7,
 92            res_scale=2.0,
 93            maxwidth=400,
 94            color=bui.app.ui_v1.heading_color,
 95            h_align='center',
 96            v_align='center',
 97        )
 98
 99        bui.buttonwidget(
100            edit=btn,
101            button_type='backSmall',
102            size=(60, 60),
103            label=bui.charstr(bui.SpecialChar.BACK),
104        )
105        if bui.app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL:
106            bui.textwidget(edit=txt, text='')
107
108        v = height - (110 if self._is_main_menu else 90)
109        v -= 100
110        clr = (0.6, 0.7, 0.6, 1.0)
111        v -= 280 if self._is_main_menu else 180
112        v += (
113            30
114            if bui.app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL
115            else 0
116        )
117        hoffs = x_offs + 80 if self._is_main_menu else x_offs - 100
118        scl = 1.13 if self._is_main_menu else 0.68
119
120        self._lineup_tex = bui.gettexture('playerLineup')
121        angry_computer_transparent_mesh = bui.getmesh(
122            'angryComputerTransparent'
123        )
124        self._lineup_1_transparent_mesh = bui.getmesh(
125            'playerLineup1Transparent'
126        )
127        self._lineup_2_transparent_mesh = bui.getmesh(
128            'playerLineup2Transparent'
129        )
130        self._lineup_3_transparent_mesh = bui.getmesh(
131            'playerLineup3Transparent'
132        )
133        self._lineup_4_transparent_mesh = bui.getmesh(
134            'playerLineup4Transparent'
135        )
136        self._eyes_mesh = bui.getmesh('plasticEyesTransparent')
137
138        self._coop_button: bui.Widget | None = None
139
140        # Only show coop button in main-menu variant.
141        if self._is_main_menu:
142            self._coop_button = btn = bui.buttonwidget(
143                parent=self._root_widget,
144                position=(hoffs, v + (scl * 15)),
145                size=(
146                    scl * button_width,
147                    scl * 300,
148                ),
149                extra_touch_border_scale=0.1,
150                autoselect=True,
151                label='',
152                button_type='square',
153                text_scale=1.13,
154                on_activate_call=self._coop,
155            )
156
157            if bui.app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL:
158                bui.widget(
159                    edit=btn,
160                    left_widget=bui.get_special_widget('back_button'),
161                )
162                bui.widget(
163                    edit=btn,
164                    up_widget=bui.get_special_widget('account_button'),
165                )
166                bui.widget(
167                    edit=btn,
168                    down_widget=bui.get_special_widget('settings_button'),
169                )
170
171            self._draw_dude(
172                0,
173                btn,
174                hoffs,
175                v,
176                scl,
177                position=(140, 30),
178                color=(0.72, 0.4, 1.0),
179            )
180            self._draw_dude(
181                1,
182                btn,
183                hoffs,
184                v,
185                scl,
186                position=(185, 53),
187                color=(0.71, 0.5, 1.0),
188            )
189            self._draw_dude(
190                2,
191                btn,
192                hoffs,
193                v,
194                scl,
195                position=(220, 27),
196                color=(0.67, 0.44, 1.0),
197            )
198            self._draw_dude(
199                3, btn, hoffs, v, scl, position=(255, 57), color=(0.7, 0.3, 1.0)
200            )
201            bui.imagewidget(
202                parent=self._root_widget,
203                draw_controller=btn,
204                position=(hoffs + scl * 230, v + scl * 153),
205                size=(scl * 115, scl * 115),
206                texture=self._lineup_tex,
207                mesh_transparent=angry_computer_transparent_mesh,
208            )
209
210            bui.textwidget(
211                parent=self._root_widget,
212                draw_controller=btn,
213                position=(hoffs + scl * (-10), v + scl * 95),
214                size=(scl * button_width, scl * 50),
215                text=bui.Lstr(
216                    resource='playModes.singlePlayerCoopText',
217                    fallback_resource='playModes.coopText',
218                ),
219                maxwidth=scl * button_width * 0.7,
220                res_scale=1.5,
221                h_align='center',
222                v_align='center',
223                color=(0.7, 0.9, 0.7, 1.0),
224                scale=scl * 2.3,
225            )
226
227            bui.textwidget(
228                parent=self._root_widget,
229                draw_controller=btn,
230                position=(hoffs + scl * (-10), v + (scl * 54)),
231                size=(scl * button_width, scl * 30),
232                text=bui.Lstr(resource=self._r + '.oneToFourPlayersText'),
233                h_align='center',
234                v_align='center',
235                scale=0.83 * scl,
236                flatness=1.0,
237                maxwidth=scl * button_width * 0.7,
238                color=clr,
239            )
240
241        scl = 0.5 if self._is_main_menu else 0.68
242        hoffs += 440 if self._is_main_menu else 216
243        v += 180 if self._is_main_menu else -68
244
245        self._teams_button = btn = bui.buttonwidget(
246            parent=self._root_widget,
247            position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)),
248            size=(
249                scl * button_width,
250                scl * (300 if self._is_main_menu else 360),
251            ),
252            extra_touch_border_scale=0.1,
253            autoselect=True,
254            label='',
255            button_type='square',
256            text_scale=1.13,
257            on_activate_call=self._team_tourney,
258        )
259
260        if bui.app.ui_v1.use_toolbars:
261            bui.widget(
262                edit=btn,
263                up_widget=bui.get_special_widget('tickets_plus_button'),
264                right_widget=bui.get_special_widget('party_button'),
265            )
266
267        xxx = -14
268        self._draw_dude(
269            2,
270            btn,
271            hoffs,
272            v,
273            scl,
274            position=(xxx + 148, 30),
275            color=(0.2, 0.4, 1.0),
276        )
277        self._draw_dude(
278            3,
279            btn,
280            hoffs,
281            v,
282            scl,
283            position=(xxx + 181, 53),
284            color=(0.3, 0.4, 1.0),
285        )
286        self._draw_dude(
287            1,
288            btn,
289            hoffs,
290            v,
291            scl,
292            position=(xxx + 216, 33),
293            color=(0.3, 0.5, 1.0),
294        )
295        self._draw_dude(
296            0,
297            btn,
298            hoffs,
299            v,
300            scl,
301            position=(xxx + 245, 57),
302            color=(0.3, 0.5, 1.0),
303        )
304
305        xxx = 155
306        self._draw_dude(
307            0,
308            btn,
309            hoffs,
310            v,
311            scl,
312            position=(xxx + 151, 30),
313            color=(1.0, 0.5, 0.4),
314        )
315        self._draw_dude(
316            1,
317            btn,
318            hoffs,
319            v,
320            scl,
321            position=(xxx + 189, 53),
322            color=(1.0, 0.58, 0.58),
323        )
324        self._draw_dude(
325            3,
326            btn,
327            hoffs,
328            v,
329            scl,
330            position=(xxx + 223, 27),
331            color=(1.0, 0.5, 0.5),
332        )
333        self._draw_dude(
334            2,
335            btn,
336            hoffs,
337            v,
338            scl,
339            position=(xxx + 257, 57),
340            color=(1.0, 0.5, 0.5),
341        )
342
343        bui.textwidget(
344            parent=self._root_widget,
345            draw_controller=btn,
346            position=(hoffs + scl * (-10), v + scl * 95),
347            size=(scl * button_width, scl * 50),
348            text=bui.Lstr(
349                resource='playModes.teamsText', fallback_resource='teamsText'
350            ),
351            res_scale=1.5,
352            maxwidth=scl * button_width * 0.7,
353            h_align='center',
354            v_align='center',
355            color=(0.7, 0.9, 0.7, 1.0),
356            scale=scl * 2.3,
357        )
358        bui.textwidget(
359            parent=self._root_widget,
360            draw_controller=btn,
361            position=(hoffs + scl * (-10), v + (scl * 54)),
362            size=(scl * button_width, scl * 30),
363            text=bui.Lstr(resource=self._r + '.twoToEightPlayersText'),
364            h_align='center',
365            v_align='center',
366            res_scale=1.5,
367            scale=0.9 * scl,
368            flatness=1.0,
369            maxwidth=scl * button_width * 0.7,
370            color=clr,
371        )
372
373        hoffs += 0 if self._is_main_menu else 300
374        v -= 155 if self._is_main_menu else 0
375        self._free_for_all_button = btn = bui.buttonwidget(
376            parent=self._root_widget,
377            position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)),
378            size=(
379                scl * button_width,
380                scl * (300 if self._is_main_menu else 360),
381            ),
382            extra_touch_border_scale=0.1,
383            autoselect=True,
384            label='',
385            button_type='square',
386            text_scale=1.13,
387            on_activate_call=self._free_for_all,
388        )
389
390        xxx = -5
391        self._draw_dude(
392            0,
393            btn,
394            hoffs,
395            v,
396            scl,
397            position=(xxx + 140, 30),
398            color=(0.4, 1.0, 0.4),
399        )
400        self._draw_dude(
401            3,
402            btn,
403            hoffs,
404            v,
405            scl,
406            position=(xxx + 185, 53),
407            color=(1.0, 0.4, 0.5),
408        )
409        self._draw_dude(
410            1,
411            btn,
412            hoffs,
413            v,
414            scl,
415            position=(xxx + 220, 27),
416            color=(0.4, 0.5, 1.0),
417        )
418        self._draw_dude(
419            2,
420            btn,
421            hoffs,
422            v,
423            scl,
424            position=(xxx + 255, 57),
425            color=(0.5, 1.0, 0.4),
426        )
427        xxx = 140
428        self._draw_dude(
429            2,
430            btn,
431            hoffs,
432            v,
433            scl,
434            position=(xxx + 148, 30),
435            color=(1.0, 0.9, 0.4),
436        )
437        self._draw_dude(
438            0,
439            btn,
440            hoffs,
441            v,
442            scl,
443            position=(xxx + 182, 53),
444            color=(0.7, 1.0, 0.5),
445        )
446        self._draw_dude(
447            3,
448            btn,
449            hoffs,
450            v,
451            scl,
452            position=(xxx + 233, 27),
453            color=(0.7, 0.5, 0.9),
454        )
455        self._draw_dude(
456            1,
457            btn,
458            hoffs,
459            v,
460            scl,
461            position=(xxx + 266, 53),
462            color=(0.4, 0.5, 0.8),
463        )
464        bui.textwidget(
465            parent=self._root_widget,
466            draw_controller=btn,
467            position=(hoffs + scl * (-10), v + scl * 95),
468            size=(scl * button_width, scl * 50),
469            text=bui.Lstr(
470                resource='playModes.freeForAllText',
471                fallback_resource='freeForAllText',
472            ),
473            maxwidth=scl * button_width * 0.7,
474            h_align='center',
475            v_align='center',
476            color=(0.7, 0.9, 0.7, 1.0),
477            scale=scl * 1.9,
478        )
479        bui.textwidget(
480            parent=self._root_widget,
481            draw_controller=btn,
482            position=(hoffs + scl * (-10), v + (scl * 54)),
483            size=(scl * button_width, scl * 30),
484            text=bui.Lstr(resource=self._r + '.twoToEightPlayersText'),
485            h_align='center',
486            v_align='center',
487            scale=0.9 * scl,
488            flatness=1.0,
489            maxwidth=scl * button_width * 0.7,
490            color=clr,
491        )
492
493        if bui.app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL:
494            back_button.delete()
495            bui.containerwidget(
496                edit=self._root_widget,
497                on_cancel_call=self._back,
498                selected_child=self._coop_button
499                if self._is_main_menu
500                else self._teams_button,
501            )
502        else:
503            bui.buttonwidget(edit=back_button, on_activate_call=self._back)
504            bui.containerwidget(
505                edit=self._root_widget,
506                cancel_button=back_button,
507                selected_child=self._coop_button
508                if self._is_main_menu
509                else self._teams_button,
510            )
511
512        self._restore_state()
513
514    # noinspection PyUnresolvedReferences
515    @staticmethod
516    def _preload_modules() -> None:
517        """Preload modules we use; avoids hitches (called in bg thread)."""
518        import bauiv1lib.mainmenu as _unused1
519        import bauiv1lib.account as _unused2
520        import bauiv1lib.coop.browser as _unused3
521        import bauiv1lib.playlist.browser as _unused4
522
523    def _back(self) -> None:
524        # pylint: disable=cyclic-import
525        if self._is_main_menu:
526            from bauiv1lib.mainmenu import MainMenuWindow
527
528            self._save_state()
529            assert bui.app.classic is not None
530            bui.app.ui_v1.set_main_menu_window(
531                MainMenuWindow(transition='in_left').get_root_widget()
532            )
533            bui.containerwidget(
534                edit=self._root_widget, transition=self._transition_out
535            )
536        else:
537            from bauiv1lib.gather import GatherWindow
538
539            self._save_state()
540            assert bui.app.classic is not None
541            bui.app.ui_v1.set_main_menu_window(
542                GatherWindow(transition='in_left').get_root_widget()
543            )
544            bui.containerwidget(
545                edit=self._root_widget, transition=self._transition_out
546            )
547
548    def _coop(self) -> None:
549        # pylint: disable=cyclic-import
550        from bauiv1lib.account import show_sign_in_prompt
551        from bauiv1lib.coop.browser import CoopBrowserWindow
552
553        plus = bui.app.plus
554        assert plus is not None
555
556        if plus.get_v1_account_state() != 'signed_in':
557            show_sign_in_prompt()
558            return
559        self._save_state()
560        bui.containerwidget(edit=self._root_widget, transition='out_left')
561        assert bui.app.classic is not None
562        bui.app.ui_v1.set_main_menu_window(
563            CoopBrowserWindow(origin_widget=self._coop_button).get_root_widget()
564        )
565
566    def _team_tourney(self) -> None:
567        # pylint: disable=cyclic-import
568        from bauiv1lib.playlist.browser import PlaylistBrowserWindow
569
570        self._save_state()
571        bui.containerwidget(edit=self._root_widget, transition='out_left')
572        assert bui.app.classic is not None
573        bui.app.ui_v1.set_main_menu_window(
574            PlaylistBrowserWindow(
575                origin_widget=self._teams_button, sessiontype=bs.DualTeamSession
576            ).get_root_widget()
577        )
578
579    def _free_for_all(self) -> None:
580        # pylint: disable=cyclic-import
581        from bauiv1lib.playlist.browser import PlaylistBrowserWindow
582
583        self._save_state()
584        bui.containerwidget(edit=self._root_widget, transition='out_left')
585        assert bui.app.classic is not None
586        bui.app.ui_v1.set_main_menu_window(
587            PlaylistBrowserWindow(
588                origin_widget=self._free_for_all_button,
589                sessiontype=bs.FreeForAllSession,
590            ).get_root_widget()
591        )
592
593    def _draw_dude(
594        self,
595        i: int,
596        btn: bui.Widget,
597        hoffs: float,
598        v: float,
599        scl: float,
600        position: tuple[float, float],
601        color: tuple[float, float, float],
602    ) -> None:
603        h_extra = -100
604        v_extra = 130
605        eye_color = (
606            0.7 * 1.0 + 0.3 * color[0],
607            0.7 * 1.0 + 0.3 * color[1],
608            0.7 * 1.0 + 0.3 * color[2],
609        )
610        if i == 0:
611            bui.imagewidget(
612                parent=self._root_widget,
613                draw_controller=btn,
614                position=(
615                    hoffs + scl * (h_extra + position[0]),
616                    v + scl * (v_extra + position[1]),
617                ),
618                size=(scl * 60, scl * 80),
619                color=color,
620                texture=self._lineup_tex,
621                mesh_transparent=self._lineup_1_transparent_mesh,
622            )
623            bui.imagewidget(
624                parent=self._root_widget,
625                draw_controller=btn,
626                position=(
627                    hoffs + scl * (h_extra + position[0] + 12),
628                    v + scl * (v_extra + position[1] + 53),
629                ),
630                size=(scl * 36, scl * 18),
631                texture=self._lineup_tex,
632                color=eye_color,
633                mesh_transparent=self._eyes_mesh,
634            )
635        elif i == 1:
636            bui.imagewidget(
637                parent=self._root_widget,
638                draw_controller=btn,
639                position=(
640                    hoffs + scl * (h_extra + position[0]),
641                    v + scl * (v_extra + position[1]),
642                ),
643                size=(scl * 45, scl * 90),
644                color=color,
645                texture=self._lineup_tex,
646                mesh_transparent=self._lineup_2_transparent_mesh,
647            )
648            bui.imagewidget(
649                parent=self._root_widget,
650                draw_controller=btn,
651                position=(
652                    hoffs + scl * (h_extra + position[0] + 5),
653                    v + scl * (v_extra + position[1] + 67),
654                ),
655                size=(scl * 32, scl * 16),
656                texture=self._lineup_tex,
657                color=eye_color,
658                mesh_transparent=self._eyes_mesh,
659            )
660        elif i == 2:
661            bui.imagewidget(
662                parent=self._root_widget,
663                draw_controller=btn,
664                position=(
665                    hoffs + scl * (h_extra + position[0]),
666                    v + scl * (v_extra + position[1]),
667                ),
668                size=(scl * 45, scl * 90),
669                color=color,
670                texture=self._lineup_tex,
671                mesh_transparent=self._lineup_3_transparent_mesh,
672            )
673            bui.imagewidget(
674                parent=self._root_widget,
675                draw_controller=btn,
676                position=(
677                    hoffs + scl * (h_extra + position[0] + 5),
678                    v + scl * (v_extra + position[1] + 59),
679                ),
680                size=(scl * 34, scl * 17),
681                texture=self._lineup_tex,
682                color=eye_color,
683                mesh_transparent=self._eyes_mesh,
684            )
685        elif i == 3:
686            bui.imagewidget(
687                parent=self._root_widget,
688                draw_controller=btn,
689                position=(
690                    hoffs + scl * (h_extra + position[0]),
691                    v + scl * (v_extra + position[1]),
692                ),
693                size=(scl * 48, scl * 96),
694                color=color,
695                texture=self._lineup_tex,
696                mesh_transparent=self._lineup_4_transparent_mesh,
697            )
698            bui.imagewidget(
699                parent=self._root_widget,
700                draw_controller=btn,
701                position=(
702                    hoffs + scl * (h_extra + position[0] + 2),
703                    v + scl * (v_extra + position[1] + 62),
704                ),
705                size=(scl * 38, scl * 19),
706                texture=self._lineup_tex,
707                color=eye_color,
708                mesh_transparent=self._eyes_mesh,
709            )
710
711    def _save_state(self) -> None:
712        try:
713            sel = self._root_widget.get_selected_child()
714            if sel == self._teams_button:
715                sel_name = 'Team Games'
716            elif self._coop_button is not None and sel == self._coop_button:
717                sel_name = 'Co-op Games'
718            elif sel == self._free_for_all_button:
719                sel_name = 'Free-for-All Games'
720            elif sel == self._back_button:
721                sel_name = 'Back'
722            else:
723                raise ValueError(f'unrecognized selection {sel}')
724            assert bui.app.classic is not None
725            bui.app.ui_v1.window_states[type(self)] = sel_name
726        except Exception:
727            logging.exception('Error saving state for %s.', self)
728
729    def _restore_state(self) -> None:
730        try:
731            assert bui.app.classic is not None
732            sel_name = bui.app.ui_v1.window_states.get(type(self))
733            if sel_name == 'Team Games':
734                sel = self._teams_button
735            elif sel_name == 'Co-op Games' and self._coop_button is not None:
736                sel = self._coop_button
737            elif sel_name == 'Free-for-All Games':
738                sel = self._free_for_all_button
739            elif sel_name == 'Back':
740                sel = self._back_button
741            else:
742                sel = (
743                    self._coop_button
744                    if self._coop_button is not None
745                    else self._teams_button
746                )
747            bui.containerwidget(edit=self._root_widget, selected_child=sel)
748        except Exception:
749            logging.exception('Error restoring state for %s.', self)

Window for selecting overall play type.

PlayWindow( transition: str = 'in_right', origin_widget: _bauiv1.Widget | None = None)
 17    def __init__(
 18        self,
 19        transition: str = 'in_right',
 20        origin_widget: bui.Widget | None = None,
 21    ):
 22        # pylint: disable=too-many-statements
 23        # pylint: disable=too-many-locals
 24        import threading
 25
 26        # Preload some modules we use in a background thread so we won't
 27        # have a visual hitch when the user taps them.
 28        threading.Thread(target=self._preload_modules).start()
 29
 30        # We can currently be used either for main menu duty or for selecting
 31        # playlists (should make this more elegant/general).
 32        assert bui.app.classic is not None
 33        self._is_main_menu = not bui.app.ui_v1.selecting_private_party_playlist
 34
 35        uiscale = bui.app.ui_v1.uiscale
 36        width = 1000 if uiscale is bui.UIScale.SMALL else 800
 37        x_offs = 100 if uiscale is bui.UIScale.SMALL else 0
 38        height = 550
 39        button_width = 400
 40
 41        scale_origin: tuple[float, float] | None
 42        if origin_widget is not None:
 43            self._transition_out = 'out_scale'
 44            scale_origin = origin_widget.get_screen_space_center()
 45            transition = 'in_scale'
 46        else:
 47            self._transition_out = 'out_right'
 48            scale_origin = None
 49
 50        self._r = 'playWindow'
 51
 52        super().__init__(
 53            root_widget=bui.containerwidget(
 54                size=(width, height),
 55                transition=transition,
 56                toolbar_visibility='menu_full',
 57                scale_origin_stack_offset=scale_origin,
 58                scale=(
 59                    1.6
 60                    if uiscale is bui.UIScale.SMALL
 61                    else 0.9
 62                    if uiscale is bui.UIScale.MEDIUM
 63                    else 0.8
 64                ),
 65                stack_offset=(0, 0) if uiscale is bui.UIScale.SMALL else (0, 0),
 66            )
 67        )
 68        self._back_button = back_button = btn = bui.buttonwidget(
 69            parent=self._root_widget,
 70            position=(55 + x_offs, height - 132),
 71            size=(120, 60),
 72            scale=1.1,
 73            text_res_scale=1.5,
 74            text_scale=1.2,
 75            autoselect=True,
 76            label=bui.Lstr(resource='backText'),
 77            button_type='back',
 78        )
 79
 80        txt = bui.textwidget(
 81            parent=self._root_widget,
 82            position=(width * 0.5, height - 101),
 83            # position=(width * 0.5, height -
 84            #           (101 if main_menu else 61)),
 85            size=(0, 0),
 86            text=bui.Lstr(
 87                resource=(self._r + '.titleText')
 88                if self._is_main_menu
 89                else 'playlistsText'
 90            ),
 91            scale=1.7,
 92            res_scale=2.0,
 93            maxwidth=400,
 94            color=bui.app.ui_v1.heading_color,
 95            h_align='center',
 96            v_align='center',
 97        )
 98
 99        bui.buttonwidget(
100            edit=btn,
101            button_type='backSmall',
102            size=(60, 60),
103            label=bui.charstr(bui.SpecialChar.BACK),
104        )
105        if bui.app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL:
106            bui.textwidget(edit=txt, text='')
107
108        v = height - (110 if self._is_main_menu else 90)
109        v -= 100
110        clr = (0.6, 0.7, 0.6, 1.0)
111        v -= 280 if self._is_main_menu else 180
112        v += (
113            30
114            if bui.app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL
115            else 0
116        )
117        hoffs = x_offs + 80 if self._is_main_menu else x_offs - 100
118        scl = 1.13 if self._is_main_menu else 0.68
119
120        self._lineup_tex = bui.gettexture('playerLineup')
121        angry_computer_transparent_mesh = bui.getmesh(
122            'angryComputerTransparent'
123        )
124        self._lineup_1_transparent_mesh = bui.getmesh(
125            'playerLineup1Transparent'
126        )
127        self._lineup_2_transparent_mesh = bui.getmesh(
128            'playerLineup2Transparent'
129        )
130        self._lineup_3_transparent_mesh = bui.getmesh(
131            'playerLineup3Transparent'
132        )
133        self._lineup_4_transparent_mesh = bui.getmesh(
134            'playerLineup4Transparent'
135        )
136        self._eyes_mesh = bui.getmesh('plasticEyesTransparent')
137
138        self._coop_button: bui.Widget | None = None
139
140        # Only show coop button in main-menu variant.
141        if self._is_main_menu:
142            self._coop_button = btn = bui.buttonwidget(
143                parent=self._root_widget,
144                position=(hoffs, v + (scl * 15)),
145                size=(
146                    scl * button_width,
147                    scl * 300,
148                ),
149                extra_touch_border_scale=0.1,
150                autoselect=True,
151                label='',
152                button_type='square',
153                text_scale=1.13,
154                on_activate_call=self._coop,
155            )
156
157            if bui.app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL:
158                bui.widget(
159                    edit=btn,
160                    left_widget=bui.get_special_widget('back_button'),
161                )
162                bui.widget(
163                    edit=btn,
164                    up_widget=bui.get_special_widget('account_button'),
165                )
166                bui.widget(
167                    edit=btn,
168                    down_widget=bui.get_special_widget('settings_button'),
169                )
170
171            self._draw_dude(
172                0,
173                btn,
174                hoffs,
175                v,
176                scl,
177                position=(140, 30),
178                color=(0.72, 0.4, 1.0),
179            )
180            self._draw_dude(
181                1,
182                btn,
183                hoffs,
184                v,
185                scl,
186                position=(185, 53),
187                color=(0.71, 0.5, 1.0),
188            )
189            self._draw_dude(
190                2,
191                btn,
192                hoffs,
193                v,
194                scl,
195                position=(220, 27),
196                color=(0.67, 0.44, 1.0),
197            )
198            self._draw_dude(
199                3, btn, hoffs, v, scl, position=(255, 57), color=(0.7, 0.3, 1.0)
200            )
201            bui.imagewidget(
202                parent=self._root_widget,
203                draw_controller=btn,
204                position=(hoffs + scl * 230, v + scl * 153),
205                size=(scl * 115, scl * 115),
206                texture=self._lineup_tex,
207                mesh_transparent=angry_computer_transparent_mesh,
208            )
209
210            bui.textwidget(
211                parent=self._root_widget,
212                draw_controller=btn,
213                position=(hoffs + scl * (-10), v + scl * 95),
214                size=(scl * button_width, scl * 50),
215                text=bui.Lstr(
216                    resource='playModes.singlePlayerCoopText',
217                    fallback_resource='playModes.coopText',
218                ),
219                maxwidth=scl * button_width * 0.7,
220                res_scale=1.5,
221                h_align='center',
222                v_align='center',
223                color=(0.7, 0.9, 0.7, 1.0),
224                scale=scl * 2.3,
225            )
226
227            bui.textwidget(
228                parent=self._root_widget,
229                draw_controller=btn,
230                position=(hoffs + scl * (-10), v + (scl * 54)),
231                size=(scl * button_width, scl * 30),
232                text=bui.Lstr(resource=self._r + '.oneToFourPlayersText'),
233                h_align='center',
234                v_align='center',
235                scale=0.83 * scl,
236                flatness=1.0,
237                maxwidth=scl * button_width * 0.7,
238                color=clr,
239            )
240
241        scl = 0.5 if self._is_main_menu else 0.68
242        hoffs += 440 if self._is_main_menu else 216
243        v += 180 if self._is_main_menu else -68
244
245        self._teams_button = btn = bui.buttonwidget(
246            parent=self._root_widget,
247            position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)),
248            size=(
249                scl * button_width,
250                scl * (300 if self._is_main_menu else 360),
251            ),
252            extra_touch_border_scale=0.1,
253            autoselect=True,
254            label='',
255            button_type='square',
256            text_scale=1.13,
257            on_activate_call=self._team_tourney,
258        )
259
260        if bui.app.ui_v1.use_toolbars:
261            bui.widget(
262                edit=btn,
263                up_widget=bui.get_special_widget('tickets_plus_button'),
264                right_widget=bui.get_special_widget('party_button'),
265            )
266
267        xxx = -14
268        self._draw_dude(
269            2,
270            btn,
271            hoffs,
272            v,
273            scl,
274            position=(xxx + 148, 30),
275            color=(0.2, 0.4, 1.0),
276        )
277        self._draw_dude(
278            3,
279            btn,
280            hoffs,
281            v,
282            scl,
283            position=(xxx + 181, 53),
284            color=(0.3, 0.4, 1.0),
285        )
286        self._draw_dude(
287            1,
288            btn,
289            hoffs,
290            v,
291            scl,
292            position=(xxx + 216, 33),
293            color=(0.3, 0.5, 1.0),
294        )
295        self._draw_dude(
296            0,
297            btn,
298            hoffs,
299            v,
300            scl,
301            position=(xxx + 245, 57),
302            color=(0.3, 0.5, 1.0),
303        )
304
305        xxx = 155
306        self._draw_dude(
307            0,
308            btn,
309            hoffs,
310            v,
311            scl,
312            position=(xxx + 151, 30),
313            color=(1.0, 0.5, 0.4),
314        )
315        self._draw_dude(
316            1,
317            btn,
318            hoffs,
319            v,
320            scl,
321            position=(xxx + 189, 53),
322            color=(1.0, 0.58, 0.58),
323        )
324        self._draw_dude(
325            3,
326            btn,
327            hoffs,
328            v,
329            scl,
330            position=(xxx + 223, 27),
331            color=(1.0, 0.5, 0.5),
332        )
333        self._draw_dude(
334            2,
335            btn,
336            hoffs,
337            v,
338            scl,
339            position=(xxx + 257, 57),
340            color=(1.0, 0.5, 0.5),
341        )
342
343        bui.textwidget(
344            parent=self._root_widget,
345            draw_controller=btn,
346            position=(hoffs + scl * (-10), v + scl * 95),
347            size=(scl * button_width, scl * 50),
348            text=bui.Lstr(
349                resource='playModes.teamsText', fallback_resource='teamsText'
350            ),
351            res_scale=1.5,
352            maxwidth=scl * button_width * 0.7,
353            h_align='center',
354            v_align='center',
355            color=(0.7, 0.9, 0.7, 1.0),
356            scale=scl * 2.3,
357        )
358        bui.textwidget(
359            parent=self._root_widget,
360            draw_controller=btn,
361            position=(hoffs + scl * (-10), v + (scl * 54)),
362            size=(scl * button_width, scl * 30),
363            text=bui.Lstr(resource=self._r + '.twoToEightPlayersText'),
364            h_align='center',
365            v_align='center',
366            res_scale=1.5,
367            scale=0.9 * scl,
368            flatness=1.0,
369            maxwidth=scl * button_width * 0.7,
370            color=clr,
371        )
372
373        hoffs += 0 if self._is_main_menu else 300
374        v -= 155 if self._is_main_menu else 0
375        self._free_for_all_button = btn = bui.buttonwidget(
376            parent=self._root_widget,
377            position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)),
378            size=(
379                scl * button_width,
380                scl * (300 if self._is_main_menu else 360),
381            ),
382            extra_touch_border_scale=0.1,
383            autoselect=True,
384            label='',
385            button_type='square',
386            text_scale=1.13,
387            on_activate_call=self._free_for_all,
388        )
389
390        xxx = -5
391        self._draw_dude(
392            0,
393            btn,
394            hoffs,
395            v,
396            scl,
397            position=(xxx + 140, 30),
398            color=(0.4, 1.0, 0.4),
399        )
400        self._draw_dude(
401            3,
402            btn,
403            hoffs,
404            v,
405            scl,
406            position=(xxx + 185, 53),
407            color=(1.0, 0.4, 0.5),
408        )
409        self._draw_dude(
410            1,
411            btn,
412            hoffs,
413            v,
414            scl,
415            position=(xxx + 220, 27),
416            color=(0.4, 0.5, 1.0),
417        )
418        self._draw_dude(
419            2,
420            btn,
421            hoffs,
422            v,
423            scl,
424            position=(xxx + 255, 57),
425            color=(0.5, 1.0, 0.4),
426        )
427        xxx = 140
428        self._draw_dude(
429            2,
430            btn,
431            hoffs,
432            v,
433            scl,
434            position=(xxx + 148, 30),
435            color=(1.0, 0.9, 0.4),
436        )
437        self._draw_dude(
438            0,
439            btn,
440            hoffs,
441            v,
442            scl,
443            position=(xxx + 182, 53),
444            color=(0.7, 1.0, 0.5),
445        )
446        self._draw_dude(
447            3,
448            btn,
449            hoffs,
450            v,
451            scl,
452            position=(xxx + 233, 27),
453            color=(0.7, 0.5, 0.9),
454        )
455        self._draw_dude(
456            1,
457            btn,
458            hoffs,
459            v,
460            scl,
461            position=(xxx + 266, 53),
462            color=(0.4, 0.5, 0.8),
463        )
464        bui.textwidget(
465            parent=self._root_widget,
466            draw_controller=btn,
467            position=(hoffs + scl * (-10), v + scl * 95),
468            size=(scl * button_width, scl * 50),
469            text=bui.Lstr(
470                resource='playModes.freeForAllText',
471                fallback_resource='freeForAllText',
472            ),
473            maxwidth=scl * button_width * 0.7,
474            h_align='center',
475            v_align='center',
476            color=(0.7, 0.9, 0.7, 1.0),
477            scale=scl * 1.9,
478        )
479        bui.textwidget(
480            parent=self._root_widget,
481            draw_controller=btn,
482            position=(hoffs + scl * (-10), v + (scl * 54)),
483            size=(scl * button_width, scl * 30),
484            text=bui.Lstr(resource=self._r + '.twoToEightPlayersText'),
485            h_align='center',
486            v_align='center',
487            scale=0.9 * scl,
488            flatness=1.0,
489            maxwidth=scl * button_width * 0.7,
490            color=clr,
491        )
492
493        if bui.app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL:
494            back_button.delete()
495            bui.containerwidget(
496                edit=self._root_widget,
497                on_cancel_call=self._back,
498                selected_child=self._coop_button
499                if self._is_main_menu
500                else self._teams_button,
501            )
502        else:
503            bui.buttonwidget(edit=back_button, on_activate_call=self._back)
504            bui.containerwidget(
505                edit=self._root_widget,
506                cancel_button=back_button,
507                selected_child=self._coop_button
508                if self._is_main_menu
509                else self._teams_button,
510            )
511
512        self._restore_state()
Inherited Members
bauiv1._uitypes.Window
get_root_widget