bauiv1lib.help

Provides help related ui.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Provides help related ui."""
  4
  5from __future__ import annotations
  6
  7from typing import override
  8
  9import random
 10
 11import bauiv1 as bui
 12
 13
 14class HelpWindow(bui.MainWindow):
 15    """A window providing help on how to play."""
 16
 17    def __init__(
 18        self,
 19        transition: str | None = 'in_right',
 20        origin_widget: bui.Widget | None = None,
 21    ):
 22        # pylint: disable=too-many-statements
 23        # pylint: disable=too-many-locals
 24
 25        bui.set_analytics_screen('Help Window')
 26
 27        self._r = 'helpWindow'
 28
 29        getres = bui.app.lang.get_resource
 30
 31        assert bui.app.classic is not None
 32        uiscale = bui.app.ui_v1.uiscale
 33        width = 1050 if uiscale is bui.UIScale.SMALL else 750
 34
 35        height = (
 36            700
 37            if uiscale is bui.UIScale.SMALL
 38            else 530 if uiscale is bui.UIScale.MEDIUM else 600
 39        )
 40
 41        # Do some fancy math to fill all available screen area up to the
 42        # size of our backing container. This lets us fit to the exact
 43        # screen shape at small ui scale.
 44        screensize = bui.get_virtual_screen_size()
 45        scale = (
 46            1.8
 47            if uiscale is bui.UIScale.SMALL
 48            else 1.15 if uiscale is bui.UIScale.MEDIUM else 1.0
 49        )
 50        # Calc screen size in our local container space and clamp to a
 51        # bit smaller than our container size.
 52        target_width = min(width - 90, screensize[0] / scale)
 53        target_height = min(height - 90, screensize[1] / scale)
 54
 55        # To get top/left coords, go to the center of our window and
 56        # offset by half the width/height of our target area.
 57        yoffs = 0.5 * height + 0.5 * target_height + 30.0
 58
 59        scroll_width = target_width
 60        scroll_height = target_height - 36
 61        scroll_bottom = yoffs - 64 - scroll_height
 62
 63        super().__init__(
 64            root_widget=bui.containerwidget(
 65                size=(width, height),
 66                toolbar_visibility=(
 67                    'menu_minimal'
 68                    if uiscale is bui.UIScale.SMALL
 69                    else 'menu_full'
 70                ),
 71                scale=scale,
 72            ),
 73            transition=transition,
 74            origin_widget=origin_widget,
 75            # We're affected by screen size only at small ui-scale.
 76            refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL,
 77        )
 78
 79        if uiscale is bui.UIScale.SMALL:
 80            bui.containerwidget(
 81                edit=self._root_widget, on_cancel_call=self.main_window_back
 82            )
 83        else:
 84            btn = bui.buttonwidget(
 85                parent=self._root_widget,
 86                position=(50, yoffs - 45),
 87                size=(60, 55),
 88                scale=0.8,
 89                label=bui.charstr(bui.SpecialChar.BACK),
 90                button_type='backSmall',
 91                extra_touch_border_scale=2.0,
 92                autoselect=True,
 93                on_activate_call=self.main_window_back,
 94            )
 95            bui.containerwidget(edit=self._root_widget, cancel_button=btn)
 96
 97        bui.textwidget(
 98            parent=self._root_widget,
 99            position=(
100                width * 0.5,
101                yoffs - (47 if uiscale is bui.UIScale.SMALL else 25),
102            ),
103            size=(0, 0),
104            text=bui.Lstr(
105                resource=f'{self._r}.titleText',
106                subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
107            ),
108            scale=0.9,
109            maxwidth=scroll_width * 0.7,
110            color=bui.app.ui_v1.title_color,
111            h_align='center',
112            v_align='center',
113        )
114
115        self._scrollwidget = bui.scrollwidget(
116            parent=self._root_widget,
117            size=(scroll_width, scroll_height),
118            position=(width * 0.5 - scroll_width * 0.5, scroll_bottom),
119            simple_culling_v=100.0,
120            capture_arrows=True,
121            border_opacity=0.4,
122            center_small_content_horizontally=True,
123        )
124
125        if uiscale is bui.UIScale.SMALL:
126            bui.widget(
127                edit=self._scrollwidget,
128                left_widget=bui.get_special_widget('back_button'),
129            )
130
131        bui.widget(
132            edit=self._scrollwidget,
133            right_widget=bui.get_special_widget('squad_button'),
134        )
135        bui.containerwidget(
136            edit=self._root_widget, selected_child=self._scrollwidget
137        )
138
139        # self._sub_width = 810 if uiscale is bui.UIScale.SMALL else 660
140        self._sub_width = 660
141        self._sub_height = (
142            1590
143            + bui.app.lang.get_resource(f'{self._r}.someDaysExtraSpace')
144            + bui.app.lang.get_resource(
145                f'{self._r}.orPunchingSomethingExtraSpace'
146            )
147        )
148
149        self._subcontainer = bui.containerwidget(
150            parent=self._scrollwidget,
151            size=(self._sub_width, self._sub_height),
152            background=False,
153            claims_left_right=False,
154        )
155
156        spacing = 1.0
157        h = self._sub_width * 0.5
158        v = self._sub_height - 55
159        logo_tex = bui.gettexture('logo')
160        icon_buffer = 1.1
161        header = (0.7, 1.0, 0.7, 1.0)
162        header2 = (0.8, 0.8, 1.0, 1.0)
163        paragraph = (0.8, 0.8, 1.0, 1.0)
164
165        txt = bui.Lstr(
166            resource=f'{self._r}.welcomeText',
167            subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
168        ).evaluate()
169        txt_scale = 1.4
170        txt_maxwidth = 480
171        bui.textwidget(
172            parent=self._subcontainer,
173            position=(h, v),
174            size=(0, 0),
175            scale=txt_scale,
176            flatness=0.5,
177            res_scale=1.5,
178            text=txt,
179            h_align='center',
180            color=header,
181            v_align='center',
182            maxwidth=txt_maxwidth,
183        )
184        txt_width = min(
185            txt_maxwidth,
186            bui.get_string_width(txt, suppress_warning=True) * txt_scale,
187        )
188
189        icon_size = 70
190        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
191        bui.imagewidget(
192            parent=self._subcontainer,
193            size=(icon_size, icon_size),
194            position=(hval2 - 0.5 * icon_size, v - 0.45 * icon_size),
195            texture=logo_tex,
196        )
197
198        app = bui.app
199        assert app.classic is not None
200
201        v -= spacing * 50.0
202        txt = bui.Lstr(resource=f'{self._r}.someDaysText').evaluate()
203        bui.textwidget(
204            parent=self._subcontainer,
205            position=(h, v),
206            size=(0, 0),
207            scale=1.2,
208            maxwidth=self._sub_width * 0.9,
209            text=txt,
210            h_align='center',
211            color=paragraph,
212            v_align='center',
213            flatness=1.0,
214        )
215        v -= spacing * 25.0 + getres(f'{self._r}.someDaysExtraSpace')
216        txt_scale = 0.66
217        txt = bui.Lstr(resource=f'{self._r}.orPunchingSomethingText').evaluate()
218        bui.textwidget(
219            parent=self._subcontainer,
220            position=(h, v),
221            size=(0, 0),
222            scale=txt_scale,
223            maxwidth=self._sub_width * 0.9,
224            text=txt,
225            h_align='center',
226            color=paragraph,
227            v_align='center',
228            flatness=1.0,
229        )
230        v -= spacing * 27.0 + getres(f'{self._r}.orPunchingSomethingExtraSpace')
231        txt_scale = 1.0
232        txt = bui.Lstr(
233            resource=f'{self._r}.canHelpText',
234            subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
235        ).evaluate()
236        bui.textwidget(
237            parent=self._subcontainer,
238            position=(h, v),
239            size=(0, 0),
240            scale=txt_scale,
241            flatness=1.0,
242            text=txt,
243            h_align='center',
244            color=paragraph,
245            v_align='center',
246        )
247
248        v -= spacing * 70.0
249        txt_scale = 1.0
250        txt = bui.Lstr(resource=f'{self._r}.toGetTheMostText').evaluate()
251        bui.textwidget(
252            parent=self._subcontainer,
253            position=(h, v),
254            size=(0, 0),
255            scale=txt_scale,
256            maxwidth=self._sub_width * 0.9,
257            text=txt,
258            h_align='center',
259            color=header,
260            v_align='center',
261            flatness=1.0,
262        )
263
264        v -= spacing * 40.0
265        txt_scale = 0.74
266        txt = bui.Lstr(resource=f'{self._r}.friendsText').evaluate()
267        hval2 = h - 220
268        bui.textwidget(
269            parent=self._subcontainer,
270            position=(hval2, v),
271            size=(0, 0),
272            scale=txt_scale,
273            maxwidth=100,
274            text=txt,
275            h_align='right',
276            color=header,
277            v_align='center',
278            flatness=1.0,
279        )
280
281        txt = bui.Lstr(
282            resource=f'{self._r}.friendsGoodText',
283            subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
284        ).evaluate()
285        txt_scale = 0.7
286        bui.textwidget(
287            parent=self._subcontainer,
288            position=(hval2 + 10, v + 8),
289            size=(0, 0),
290            scale=txt_scale,
291            maxwidth=500,
292            text=txt,
293            h_align='left',
294            color=paragraph,
295            flatness=1.0,
296        )
297
298        app = bui.app
299
300        v -= spacing * 45.0
301        txt = (
302            bui.Lstr(resource=f'{self._r}.devicesText').evaluate()
303            if app.env.vr
304            else bui.Lstr(resource=f'{self._r}.controllersText').evaluate()
305        )
306        txt_scale = 0.74
307        hval2 = h - 220
308        bui.textwidget(
309            parent=self._subcontainer,
310            position=(hval2, v),
311            size=(0, 0),
312            scale=txt_scale,
313            maxwidth=100,
314            text=txt,
315            h_align='right',
316            v_align='center',
317            color=header,
318            flatness=1.0,
319        )
320
321        txt_scale = 0.7
322        if not app.env.vr:
323            infotxt = '.controllersInfoText'
324            txt = bui.Lstr(
325                resource=self._r + infotxt,
326                fallback_resource=f'{self._r}.controllersInfoText',
327                subs=[
328                    ('${APP_NAME}', bui.Lstr(resource='titleText')),
329                    ('${REMOTE_APP_NAME}', bui.get_remote_app_name()),
330                ],
331            ).evaluate()
332        else:
333            txt = bui.Lstr(
334                resource=f'{self._r}.devicesInfoText',
335                subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
336            ).evaluate()
337
338        bui.textwidget(
339            parent=self._subcontainer,
340            position=(hval2 + 10, v + 8),
341            size=(0, 0),
342            scale=txt_scale,
343            maxwidth=500,
344            max_height=105,
345            text=txt,
346            h_align='left',
347            color=paragraph,
348            flatness=1.0,
349        )
350
351        v -= spacing * 150.0
352
353        txt = bui.Lstr(resource=f'{self._r}.controlsText').evaluate()
354        txt_scale = 1.4
355        txt_maxwidth = 480
356        bui.textwidget(
357            parent=self._subcontainer,
358            position=(h, v),
359            size=(0, 0),
360            scale=txt_scale,
361            flatness=0.5,
362            text=txt,
363            h_align='center',
364            color=header,
365            v_align='center',
366            res_scale=1.5,
367            maxwidth=txt_maxwidth,
368        )
369        txt_width = min(
370            txt_maxwidth,
371            bui.get_string_width(txt, suppress_warning=True) * txt_scale,
372        )
373        icon_size = 70
374
375        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
376        bui.imagewidget(
377            parent=self._subcontainer,
378            size=(icon_size, icon_size),
379            position=(hval2 - 0.5 * icon_size, v - 0.45 * icon_size),
380            texture=logo_tex,
381        )
382
383        v -= spacing * 45.0
384
385        txt_scale = 0.7
386        txt = bui.Lstr(
387            resource=f'{self._r}.controlsSubtitleText',
388            subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
389        ).evaluate()
390        bui.textwidget(
391            parent=self._subcontainer,
392            position=(h, v),
393            size=(0, 0),
394            scale=txt_scale,
395            maxwidth=self._sub_width * 0.9,
396            flatness=1.0,
397            text=txt,
398            h_align='center',
399            color=paragraph,
400            v_align='center',
401        )
402        v -= spacing * 160.0
403
404        sep = 70
405        icon_size = 100
406        # icon_size_2 = 30
407        hval2 = h - sep
408        vval2 = v
409        bui.buttonwidget(
410            parent=self._subcontainer,
411            label='',
412            size=(icon_size, icon_size),
413            position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size),
414            texture=bui.gettexture('buttonPunch'),
415            color=(1, 0.7, 0.3),
416            selectable=False,
417            enable_sound=False,
418            on_activate_call=bui.WeakCall(self._play_sound, 'spazAttack0', 4),
419        )
420
421        txt_scale = getres(f'{self._r}.punchInfoTextScale')
422        txt = bui.Lstr(resource=f'{self._r}.punchInfoText').evaluate()
423        bui.textwidget(
424            parent=self._subcontainer,
425            position=(h - sep - 185 + 70, v + 120),
426            size=(0, 0),
427            scale=txt_scale,
428            flatness=1.0,
429            text=txt,
430            h_align='center',
431            color=(1, 0.7, 0.3, 1.0),
432            v_align='top',
433        )
434
435        hval2 = h + sep
436        vval2 = v
437        bui.buttonwidget(
438            parent=self._subcontainer,
439            label='',
440            size=(icon_size, icon_size),
441            position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size),
442            texture=bui.gettexture('buttonBomb'),
443            color=(1, 0.3, 0.3),
444            selectable=False,
445            enable_sound=False,
446            on_activate_call=bui.WeakCall(self._play_sound, 'explosion0', 5),
447        )
448
449        txt = bui.Lstr(resource=f'{self._r}.bombInfoText').evaluate()
450        txt_scale = getres(f'{self._r}.bombInfoTextScale')
451        bui.textwidget(
452            parent=self._subcontainer,
453            position=(h + sep + 50 + 60, v - 35),
454            size=(0, 0),
455            scale=txt_scale,
456            flatness=1.0,
457            maxwidth=270,
458            text=txt,
459            h_align='center',
460            color=(1, 0.3, 0.3, 1.0),
461            v_align='top',
462        )
463
464        hval2 = h
465        vval2 = v + sep
466        bui.buttonwidget(
467            parent=self._subcontainer,
468            label='',
469            size=(icon_size, icon_size),
470            position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size),
471            texture=bui.gettexture('buttonPickUp'),
472            color=(0.5, 0.5, 1),
473            selectable=False,
474            enable_sound=False,
475            on_activate_call=bui.WeakCall(self._play_sound, 'spazPickup0', 1),
476        )
477
478        txtl = bui.Lstr(resource=f'{self._r}.pickUpInfoText')
479        txt_scale = getres(f'{self._r}.pickUpInfoTextScale')
480        bui.textwidget(
481            parent=self._subcontainer,
482            position=(h + 60 + 120, v + sep + 50),
483            size=(0, 0),
484            scale=txt_scale,
485            flatness=1.0,
486            text=txtl,
487            h_align='center',
488            color=(0.5, 0.5, 1, 1.0),
489            v_align='top',
490        )
491
492        hval2 = h
493        vval2 = v - sep
494        bui.buttonwidget(
495            parent=self._subcontainer,
496            label='',
497            size=(icon_size, icon_size),
498            position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size),
499            texture=bui.gettexture('buttonJump'),
500            color=(0.4, 1, 0.4),
501            selectable=False,
502            enable_sound=False,
503            on_activate_call=bui.WeakCall(self._play_sound, 'spazJump0', 4),
504        )
505
506        txt = bui.Lstr(resource=f'{self._r}.jumpInfoText').evaluate()
507        txt_scale = getres(f'{self._r}.jumpInfoTextScale')
508        bui.textwidget(
509            parent=self._subcontainer,
510            position=(h - 250 + 75, v - sep - 15 + 30),
511            size=(0, 0),
512            scale=txt_scale,
513            flatness=1.0,
514            text=txt,
515            h_align='center',
516            color=(0.4, 1, 0.4, 1.0),
517            v_align='top',
518        )
519
520        txt = bui.Lstr(resource=f'{self._r}.runInfoText').evaluate()
521        txt_scale = getres(f'{self._r}.runInfoTextScale')
522        bui.textwidget(
523            parent=self._subcontainer,
524            position=(h, v - sep - 100),
525            size=(0, 0),
526            scale=txt_scale,
527            maxwidth=self._sub_width * 0.93,
528            flatness=1.0,
529            text=txt,
530            h_align='center',
531            color=(0.7, 0.7, 1.0, 1.0),
532            v_align='center',
533        )
534
535        v -= spacing * 280.0
536
537        txt = bui.Lstr(resource=f'{self._r}.powerupsText').evaluate()
538        txt_scale = 1.4
539        txt_maxwidth = 480
540        bui.textwidget(
541            parent=self._subcontainer,
542            position=(h, v),
543            size=(0, 0),
544            scale=txt_scale,
545            flatness=0.5,
546            text=txt,
547            h_align='center',
548            color=header,
549            v_align='center',
550            maxwidth=txt_maxwidth,
551        )
552        txt_width = min(
553            txt_maxwidth,
554            bui.get_string_width(txt, suppress_warning=True) * txt_scale,
555        )
556        icon_size = 70
557        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
558        bui.imagewidget(
559            parent=self._subcontainer,
560            size=(icon_size, icon_size),
561            position=(hval2 - 0.5 * icon_size, v - 0.45 * icon_size),
562            texture=logo_tex,
563        )
564
565        v -= spacing * 50.0
566        txt_scale = getres(f'{self._r}.powerupsSubtitleTextScale')
567        txt = bui.Lstr(resource=f'{self._r}.powerupsSubtitleText').evaluate()
568        bui.textwidget(
569            parent=self._subcontainer,
570            position=(h, v),
571            size=(0, 0),
572            scale=txt_scale,
573            maxwidth=self._sub_width * 0.9,
574            text=txt,
575            h_align='center',
576            color=paragraph,
577            v_align='center',
578            flatness=1.0,
579        )
580
581        v -= spacing * 1.0
582
583        mm1 = -270
584        mm2 = -215
585        mm3 = 0
586        icon_size = 50
587        shadow_size = 80
588        shadow_offs_x = 3
589        shadow_offs_y = -4
590        t_big = 1.1
591        t_small = 0.65
592
593        shadow_tex = bui.gettexture('shadowSharp')
594
595        for tex in [
596            'powerupPunch',
597            'powerupShield',
598            'powerupBomb',
599            'powerupHealth',
600            'powerupIceBombs',
601            'powerupImpactBombs',
602            'powerupStickyBombs',
603            'powerupLandMines',
604            'powerupCurse',
605        ]:
606            name = bui.Lstr(resource=f'{self._r}.' + tex + 'NameText')
607            desc = bui.Lstr(resource=f'{self._r}.' + tex + 'DescriptionText')
608
609            v -= spacing * 60.0
610
611            bui.imagewidget(
612                parent=self._subcontainer,
613                size=(shadow_size, shadow_size),
614                position=(
615                    h + mm1 + shadow_offs_x - 0.5 * shadow_size,
616                    v + shadow_offs_y - 0.5 * shadow_size,
617                ),
618                texture=shadow_tex,
619                color=(0, 0, 0),
620                opacity=0.5,
621            )
622            bui.imagewidget(
623                parent=self._subcontainer,
624                size=(icon_size, icon_size),
625                position=(h + mm1 - 0.5 * icon_size, v - 0.5 * icon_size),
626                texture=bui.gettexture(tex),
627            )
628
629            txt_scale = t_big
630            txtl = name
631            bui.textwidget(
632                parent=self._subcontainer,
633                position=(h + mm2, v + 3),
634                size=(0, 0),
635                scale=txt_scale,
636                maxwidth=200,
637                flatness=1.0,
638                text=txtl,
639                h_align='left',
640                color=header2,
641                v_align='center',
642            )
643            txt_scale = t_small
644            txtl = desc
645            bui.textwidget(
646                parent=self._subcontainer,
647                position=(h + mm3, v),
648                size=(0, 0),
649                scale=txt_scale,
650                maxwidth=300,
651                flatness=1.0,
652                text=txtl,
653                h_align='left',
654                color=paragraph,
655                v_align='center',
656                res_scale=0.5,
657            )
658
659    def _play_sound(self, text: str, num: int) -> None:
660        bui.getsound(text + str(random.randint(1, num))).play()
661
662    @override
663    def get_main_window_state(self) -> bui.MainWindowState:
664        # Support recreating our window for back/refresh purposes.
665        cls = type(self)
666        return bui.BasicMainWindowState(
667            create_call=lambda transition, origin_widget: cls(
668                transition=transition, origin_widget=origin_widget
669            )
670        )
class HelpWindow(bauiv1._uitypes.MainWindow):
 15class HelpWindow(bui.MainWindow):
 16    """A window providing help on how to play."""
 17
 18    def __init__(
 19        self,
 20        transition: str | None = 'in_right',
 21        origin_widget: bui.Widget | None = None,
 22    ):
 23        # pylint: disable=too-many-statements
 24        # pylint: disable=too-many-locals
 25
 26        bui.set_analytics_screen('Help Window')
 27
 28        self._r = 'helpWindow'
 29
 30        getres = bui.app.lang.get_resource
 31
 32        assert bui.app.classic is not None
 33        uiscale = bui.app.ui_v1.uiscale
 34        width = 1050 if uiscale is bui.UIScale.SMALL else 750
 35
 36        height = (
 37            700
 38            if uiscale is bui.UIScale.SMALL
 39            else 530 if uiscale is bui.UIScale.MEDIUM else 600
 40        )
 41
 42        # Do some fancy math to fill all available screen area up to the
 43        # size of our backing container. This lets us fit to the exact
 44        # screen shape at small ui scale.
 45        screensize = bui.get_virtual_screen_size()
 46        scale = (
 47            1.8
 48            if uiscale is bui.UIScale.SMALL
 49            else 1.15 if uiscale is bui.UIScale.MEDIUM else 1.0
 50        )
 51        # Calc screen size in our local container space and clamp to a
 52        # bit smaller than our container size.
 53        target_width = min(width - 90, screensize[0] / scale)
 54        target_height = min(height - 90, screensize[1] / scale)
 55
 56        # To get top/left coords, go to the center of our window and
 57        # offset by half the width/height of our target area.
 58        yoffs = 0.5 * height + 0.5 * target_height + 30.0
 59
 60        scroll_width = target_width
 61        scroll_height = target_height - 36
 62        scroll_bottom = yoffs - 64 - scroll_height
 63
 64        super().__init__(
 65            root_widget=bui.containerwidget(
 66                size=(width, height),
 67                toolbar_visibility=(
 68                    'menu_minimal'
 69                    if uiscale is bui.UIScale.SMALL
 70                    else 'menu_full'
 71                ),
 72                scale=scale,
 73            ),
 74            transition=transition,
 75            origin_widget=origin_widget,
 76            # We're affected by screen size only at small ui-scale.
 77            refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL,
 78        )
 79
 80        if uiscale is bui.UIScale.SMALL:
 81            bui.containerwidget(
 82                edit=self._root_widget, on_cancel_call=self.main_window_back
 83            )
 84        else:
 85            btn = bui.buttonwidget(
 86                parent=self._root_widget,
 87                position=(50, yoffs - 45),
 88                size=(60, 55),
 89                scale=0.8,
 90                label=bui.charstr(bui.SpecialChar.BACK),
 91                button_type='backSmall',
 92                extra_touch_border_scale=2.0,
 93                autoselect=True,
 94                on_activate_call=self.main_window_back,
 95            )
 96            bui.containerwidget(edit=self._root_widget, cancel_button=btn)
 97
 98        bui.textwidget(
 99            parent=self._root_widget,
100            position=(
101                width * 0.5,
102                yoffs - (47 if uiscale is bui.UIScale.SMALL else 25),
103            ),
104            size=(0, 0),
105            text=bui.Lstr(
106                resource=f'{self._r}.titleText',
107                subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
108            ),
109            scale=0.9,
110            maxwidth=scroll_width * 0.7,
111            color=bui.app.ui_v1.title_color,
112            h_align='center',
113            v_align='center',
114        )
115
116        self._scrollwidget = bui.scrollwidget(
117            parent=self._root_widget,
118            size=(scroll_width, scroll_height),
119            position=(width * 0.5 - scroll_width * 0.5, scroll_bottom),
120            simple_culling_v=100.0,
121            capture_arrows=True,
122            border_opacity=0.4,
123            center_small_content_horizontally=True,
124        )
125
126        if uiscale is bui.UIScale.SMALL:
127            bui.widget(
128                edit=self._scrollwidget,
129                left_widget=bui.get_special_widget('back_button'),
130            )
131
132        bui.widget(
133            edit=self._scrollwidget,
134            right_widget=bui.get_special_widget('squad_button'),
135        )
136        bui.containerwidget(
137            edit=self._root_widget, selected_child=self._scrollwidget
138        )
139
140        # self._sub_width = 810 if uiscale is bui.UIScale.SMALL else 660
141        self._sub_width = 660
142        self._sub_height = (
143            1590
144            + bui.app.lang.get_resource(f'{self._r}.someDaysExtraSpace')
145            + bui.app.lang.get_resource(
146                f'{self._r}.orPunchingSomethingExtraSpace'
147            )
148        )
149
150        self._subcontainer = bui.containerwidget(
151            parent=self._scrollwidget,
152            size=(self._sub_width, self._sub_height),
153            background=False,
154            claims_left_right=False,
155        )
156
157        spacing = 1.0
158        h = self._sub_width * 0.5
159        v = self._sub_height - 55
160        logo_tex = bui.gettexture('logo')
161        icon_buffer = 1.1
162        header = (0.7, 1.0, 0.7, 1.0)
163        header2 = (0.8, 0.8, 1.0, 1.0)
164        paragraph = (0.8, 0.8, 1.0, 1.0)
165
166        txt = bui.Lstr(
167            resource=f'{self._r}.welcomeText',
168            subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
169        ).evaluate()
170        txt_scale = 1.4
171        txt_maxwidth = 480
172        bui.textwidget(
173            parent=self._subcontainer,
174            position=(h, v),
175            size=(0, 0),
176            scale=txt_scale,
177            flatness=0.5,
178            res_scale=1.5,
179            text=txt,
180            h_align='center',
181            color=header,
182            v_align='center',
183            maxwidth=txt_maxwidth,
184        )
185        txt_width = min(
186            txt_maxwidth,
187            bui.get_string_width(txt, suppress_warning=True) * txt_scale,
188        )
189
190        icon_size = 70
191        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
192        bui.imagewidget(
193            parent=self._subcontainer,
194            size=(icon_size, icon_size),
195            position=(hval2 - 0.5 * icon_size, v - 0.45 * icon_size),
196            texture=logo_tex,
197        )
198
199        app = bui.app
200        assert app.classic is not None
201
202        v -= spacing * 50.0
203        txt = bui.Lstr(resource=f'{self._r}.someDaysText').evaluate()
204        bui.textwidget(
205            parent=self._subcontainer,
206            position=(h, v),
207            size=(0, 0),
208            scale=1.2,
209            maxwidth=self._sub_width * 0.9,
210            text=txt,
211            h_align='center',
212            color=paragraph,
213            v_align='center',
214            flatness=1.0,
215        )
216        v -= spacing * 25.0 + getres(f'{self._r}.someDaysExtraSpace')
217        txt_scale = 0.66
218        txt = bui.Lstr(resource=f'{self._r}.orPunchingSomethingText').evaluate()
219        bui.textwidget(
220            parent=self._subcontainer,
221            position=(h, v),
222            size=(0, 0),
223            scale=txt_scale,
224            maxwidth=self._sub_width * 0.9,
225            text=txt,
226            h_align='center',
227            color=paragraph,
228            v_align='center',
229            flatness=1.0,
230        )
231        v -= spacing * 27.0 + getres(f'{self._r}.orPunchingSomethingExtraSpace')
232        txt_scale = 1.0
233        txt = bui.Lstr(
234            resource=f'{self._r}.canHelpText',
235            subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
236        ).evaluate()
237        bui.textwidget(
238            parent=self._subcontainer,
239            position=(h, v),
240            size=(0, 0),
241            scale=txt_scale,
242            flatness=1.0,
243            text=txt,
244            h_align='center',
245            color=paragraph,
246            v_align='center',
247        )
248
249        v -= spacing * 70.0
250        txt_scale = 1.0
251        txt = bui.Lstr(resource=f'{self._r}.toGetTheMostText').evaluate()
252        bui.textwidget(
253            parent=self._subcontainer,
254            position=(h, v),
255            size=(0, 0),
256            scale=txt_scale,
257            maxwidth=self._sub_width * 0.9,
258            text=txt,
259            h_align='center',
260            color=header,
261            v_align='center',
262            flatness=1.0,
263        )
264
265        v -= spacing * 40.0
266        txt_scale = 0.74
267        txt = bui.Lstr(resource=f'{self._r}.friendsText').evaluate()
268        hval2 = h - 220
269        bui.textwidget(
270            parent=self._subcontainer,
271            position=(hval2, v),
272            size=(0, 0),
273            scale=txt_scale,
274            maxwidth=100,
275            text=txt,
276            h_align='right',
277            color=header,
278            v_align='center',
279            flatness=1.0,
280        )
281
282        txt = bui.Lstr(
283            resource=f'{self._r}.friendsGoodText',
284            subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
285        ).evaluate()
286        txt_scale = 0.7
287        bui.textwidget(
288            parent=self._subcontainer,
289            position=(hval2 + 10, v + 8),
290            size=(0, 0),
291            scale=txt_scale,
292            maxwidth=500,
293            text=txt,
294            h_align='left',
295            color=paragraph,
296            flatness=1.0,
297        )
298
299        app = bui.app
300
301        v -= spacing * 45.0
302        txt = (
303            bui.Lstr(resource=f'{self._r}.devicesText').evaluate()
304            if app.env.vr
305            else bui.Lstr(resource=f'{self._r}.controllersText').evaluate()
306        )
307        txt_scale = 0.74
308        hval2 = h - 220
309        bui.textwidget(
310            parent=self._subcontainer,
311            position=(hval2, v),
312            size=(0, 0),
313            scale=txt_scale,
314            maxwidth=100,
315            text=txt,
316            h_align='right',
317            v_align='center',
318            color=header,
319            flatness=1.0,
320        )
321
322        txt_scale = 0.7
323        if not app.env.vr:
324            infotxt = '.controllersInfoText'
325            txt = bui.Lstr(
326                resource=self._r + infotxt,
327                fallback_resource=f'{self._r}.controllersInfoText',
328                subs=[
329                    ('${APP_NAME}', bui.Lstr(resource='titleText')),
330                    ('${REMOTE_APP_NAME}', bui.get_remote_app_name()),
331                ],
332            ).evaluate()
333        else:
334            txt = bui.Lstr(
335                resource=f'{self._r}.devicesInfoText',
336                subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
337            ).evaluate()
338
339        bui.textwidget(
340            parent=self._subcontainer,
341            position=(hval2 + 10, v + 8),
342            size=(0, 0),
343            scale=txt_scale,
344            maxwidth=500,
345            max_height=105,
346            text=txt,
347            h_align='left',
348            color=paragraph,
349            flatness=1.0,
350        )
351
352        v -= spacing * 150.0
353
354        txt = bui.Lstr(resource=f'{self._r}.controlsText').evaluate()
355        txt_scale = 1.4
356        txt_maxwidth = 480
357        bui.textwidget(
358            parent=self._subcontainer,
359            position=(h, v),
360            size=(0, 0),
361            scale=txt_scale,
362            flatness=0.5,
363            text=txt,
364            h_align='center',
365            color=header,
366            v_align='center',
367            res_scale=1.5,
368            maxwidth=txt_maxwidth,
369        )
370        txt_width = min(
371            txt_maxwidth,
372            bui.get_string_width(txt, suppress_warning=True) * txt_scale,
373        )
374        icon_size = 70
375
376        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
377        bui.imagewidget(
378            parent=self._subcontainer,
379            size=(icon_size, icon_size),
380            position=(hval2 - 0.5 * icon_size, v - 0.45 * icon_size),
381            texture=logo_tex,
382        )
383
384        v -= spacing * 45.0
385
386        txt_scale = 0.7
387        txt = bui.Lstr(
388            resource=f'{self._r}.controlsSubtitleText',
389            subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
390        ).evaluate()
391        bui.textwidget(
392            parent=self._subcontainer,
393            position=(h, v),
394            size=(0, 0),
395            scale=txt_scale,
396            maxwidth=self._sub_width * 0.9,
397            flatness=1.0,
398            text=txt,
399            h_align='center',
400            color=paragraph,
401            v_align='center',
402        )
403        v -= spacing * 160.0
404
405        sep = 70
406        icon_size = 100
407        # icon_size_2 = 30
408        hval2 = h - sep
409        vval2 = v
410        bui.buttonwidget(
411            parent=self._subcontainer,
412            label='',
413            size=(icon_size, icon_size),
414            position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size),
415            texture=bui.gettexture('buttonPunch'),
416            color=(1, 0.7, 0.3),
417            selectable=False,
418            enable_sound=False,
419            on_activate_call=bui.WeakCall(self._play_sound, 'spazAttack0', 4),
420        )
421
422        txt_scale = getres(f'{self._r}.punchInfoTextScale')
423        txt = bui.Lstr(resource=f'{self._r}.punchInfoText').evaluate()
424        bui.textwidget(
425            parent=self._subcontainer,
426            position=(h - sep - 185 + 70, v + 120),
427            size=(0, 0),
428            scale=txt_scale,
429            flatness=1.0,
430            text=txt,
431            h_align='center',
432            color=(1, 0.7, 0.3, 1.0),
433            v_align='top',
434        )
435
436        hval2 = h + sep
437        vval2 = v
438        bui.buttonwidget(
439            parent=self._subcontainer,
440            label='',
441            size=(icon_size, icon_size),
442            position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size),
443            texture=bui.gettexture('buttonBomb'),
444            color=(1, 0.3, 0.3),
445            selectable=False,
446            enable_sound=False,
447            on_activate_call=bui.WeakCall(self._play_sound, 'explosion0', 5),
448        )
449
450        txt = bui.Lstr(resource=f'{self._r}.bombInfoText').evaluate()
451        txt_scale = getres(f'{self._r}.bombInfoTextScale')
452        bui.textwidget(
453            parent=self._subcontainer,
454            position=(h + sep + 50 + 60, v - 35),
455            size=(0, 0),
456            scale=txt_scale,
457            flatness=1.0,
458            maxwidth=270,
459            text=txt,
460            h_align='center',
461            color=(1, 0.3, 0.3, 1.0),
462            v_align='top',
463        )
464
465        hval2 = h
466        vval2 = v + sep
467        bui.buttonwidget(
468            parent=self._subcontainer,
469            label='',
470            size=(icon_size, icon_size),
471            position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size),
472            texture=bui.gettexture('buttonPickUp'),
473            color=(0.5, 0.5, 1),
474            selectable=False,
475            enable_sound=False,
476            on_activate_call=bui.WeakCall(self._play_sound, 'spazPickup0', 1),
477        )
478
479        txtl = bui.Lstr(resource=f'{self._r}.pickUpInfoText')
480        txt_scale = getres(f'{self._r}.pickUpInfoTextScale')
481        bui.textwidget(
482            parent=self._subcontainer,
483            position=(h + 60 + 120, v + sep + 50),
484            size=(0, 0),
485            scale=txt_scale,
486            flatness=1.0,
487            text=txtl,
488            h_align='center',
489            color=(0.5, 0.5, 1, 1.0),
490            v_align='top',
491        )
492
493        hval2 = h
494        vval2 = v - sep
495        bui.buttonwidget(
496            parent=self._subcontainer,
497            label='',
498            size=(icon_size, icon_size),
499            position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size),
500            texture=bui.gettexture('buttonJump'),
501            color=(0.4, 1, 0.4),
502            selectable=False,
503            enable_sound=False,
504            on_activate_call=bui.WeakCall(self._play_sound, 'spazJump0', 4),
505        )
506
507        txt = bui.Lstr(resource=f'{self._r}.jumpInfoText').evaluate()
508        txt_scale = getres(f'{self._r}.jumpInfoTextScale')
509        bui.textwidget(
510            parent=self._subcontainer,
511            position=(h - 250 + 75, v - sep - 15 + 30),
512            size=(0, 0),
513            scale=txt_scale,
514            flatness=1.0,
515            text=txt,
516            h_align='center',
517            color=(0.4, 1, 0.4, 1.0),
518            v_align='top',
519        )
520
521        txt = bui.Lstr(resource=f'{self._r}.runInfoText').evaluate()
522        txt_scale = getres(f'{self._r}.runInfoTextScale')
523        bui.textwidget(
524            parent=self._subcontainer,
525            position=(h, v - sep - 100),
526            size=(0, 0),
527            scale=txt_scale,
528            maxwidth=self._sub_width * 0.93,
529            flatness=1.0,
530            text=txt,
531            h_align='center',
532            color=(0.7, 0.7, 1.0, 1.0),
533            v_align='center',
534        )
535
536        v -= spacing * 280.0
537
538        txt = bui.Lstr(resource=f'{self._r}.powerupsText').evaluate()
539        txt_scale = 1.4
540        txt_maxwidth = 480
541        bui.textwidget(
542            parent=self._subcontainer,
543            position=(h, v),
544            size=(0, 0),
545            scale=txt_scale,
546            flatness=0.5,
547            text=txt,
548            h_align='center',
549            color=header,
550            v_align='center',
551            maxwidth=txt_maxwidth,
552        )
553        txt_width = min(
554            txt_maxwidth,
555            bui.get_string_width(txt, suppress_warning=True) * txt_scale,
556        )
557        icon_size = 70
558        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
559        bui.imagewidget(
560            parent=self._subcontainer,
561            size=(icon_size, icon_size),
562            position=(hval2 - 0.5 * icon_size, v - 0.45 * icon_size),
563            texture=logo_tex,
564        )
565
566        v -= spacing * 50.0
567        txt_scale = getres(f'{self._r}.powerupsSubtitleTextScale')
568        txt = bui.Lstr(resource=f'{self._r}.powerupsSubtitleText').evaluate()
569        bui.textwidget(
570            parent=self._subcontainer,
571            position=(h, v),
572            size=(0, 0),
573            scale=txt_scale,
574            maxwidth=self._sub_width * 0.9,
575            text=txt,
576            h_align='center',
577            color=paragraph,
578            v_align='center',
579            flatness=1.0,
580        )
581
582        v -= spacing * 1.0
583
584        mm1 = -270
585        mm2 = -215
586        mm3 = 0
587        icon_size = 50
588        shadow_size = 80
589        shadow_offs_x = 3
590        shadow_offs_y = -4
591        t_big = 1.1
592        t_small = 0.65
593
594        shadow_tex = bui.gettexture('shadowSharp')
595
596        for tex in [
597            'powerupPunch',
598            'powerupShield',
599            'powerupBomb',
600            'powerupHealth',
601            'powerupIceBombs',
602            'powerupImpactBombs',
603            'powerupStickyBombs',
604            'powerupLandMines',
605            'powerupCurse',
606        ]:
607            name = bui.Lstr(resource=f'{self._r}.' + tex + 'NameText')
608            desc = bui.Lstr(resource=f'{self._r}.' + tex + 'DescriptionText')
609
610            v -= spacing * 60.0
611
612            bui.imagewidget(
613                parent=self._subcontainer,
614                size=(shadow_size, shadow_size),
615                position=(
616                    h + mm1 + shadow_offs_x - 0.5 * shadow_size,
617                    v + shadow_offs_y - 0.5 * shadow_size,
618                ),
619                texture=shadow_tex,
620                color=(0, 0, 0),
621                opacity=0.5,
622            )
623            bui.imagewidget(
624                parent=self._subcontainer,
625                size=(icon_size, icon_size),
626                position=(h + mm1 - 0.5 * icon_size, v - 0.5 * icon_size),
627                texture=bui.gettexture(tex),
628            )
629
630            txt_scale = t_big
631            txtl = name
632            bui.textwidget(
633                parent=self._subcontainer,
634                position=(h + mm2, v + 3),
635                size=(0, 0),
636                scale=txt_scale,
637                maxwidth=200,
638                flatness=1.0,
639                text=txtl,
640                h_align='left',
641                color=header2,
642                v_align='center',
643            )
644            txt_scale = t_small
645            txtl = desc
646            bui.textwidget(
647                parent=self._subcontainer,
648                position=(h + mm3, v),
649                size=(0, 0),
650                scale=txt_scale,
651                maxwidth=300,
652                flatness=1.0,
653                text=txtl,
654                h_align='left',
655                color=paragraph,
656                v_align='center',
657                res_scale=0.5,
658            )
659
660    def _play_sound(self, text: str, num: int) -> None:
661        bui.getsound(text + str(random.randint(1, num))).play()
662
663    @override
664    def get_main_window_state(self) -> bui.MainWindowState:
665        # Support recreating our window for back/refresh purposes.
666        cls = type(self)
667        return bui.BasicMainWindowState(
668            create_call=lambda transition, origin_widget: cls(
669                transition=transition, origin_widget=origin_widget
670            )
671        )

A window providing help on how to play.

HelpWindow( transition: str | None = 'in_right', origin_widget: _bauiv1.Widget | None = None)
 18    def __init__(
 19        self,
 20        transition: str | None = 'in_right',
 21        origin_widget: bui.Widget | None = None,
 22    ):
 23        # pylint: disable=too-many-statements
 24        # pylint: disable=too-many-locals
 25
 26        bui.set_analytics_screen('Help Window')
 27
 28        self._r = 'helpWindow'
 29
 30        getres = bui.app.lang.get_resource
 31
 32        assert bui.app.classic is not None
 33        uiscale = bui.app.ui_v1.uiscale
 34        width = 1050 if uiscale is bui.UIScale.SMALL else 750
 35
 36        height = (
 37            700
 38            if uiscale is bui.UIScale.SMALL
 39            else 530 if uiscale is bui.UIScale.MEDIUM else 600
 40        )
 41
 42        # Do some fancy math to fill all available screen area up to the
 43        # size of our backing container. This lets us fit to the exact
 44        # screen shape at small ui scale.
 45        screensize = bui.get_virtual_screen_size()
 46        scale = (
 47            1.8
 48            if uiscale is bui.UIScale.SMALL
 49            else 1.15 if uiscale is bui.UIScale.MEDIUM else 1.0
 50        )
 51        # Calc screen size in our local container space and clamp to a
 52        # bit smaller than our container size.
 53        target_width = min(width - 90, screensize[0] / scale)
 54        target_height = min(height - 90, screensize[1] / scale)
 55
 56        # To get top/left coords, go to the center of our window and
 57        # offset by half the width/height of our target area.
 58        yoffs = 0.5 * height + 0.5 * target_height + 30.0
 59
 60        scroll_width = target_width
 61        scroll_height = target_height - 36
 62        scroll_bottom = yoffs - 64 - scroll_height
 63
 64        super().__init__(
 65            root_widget=bui.containerwidget(
 66                size=(width, height),
 67                toolbar_visibility=(
 68                    'menu_minimal'
 69                    if uiscale is bui.UIScale.SMALL
 70                    else 'menu_full'
 71                ),
 72                scale=scale,
 73            ),
 74            transition=transition,
 75            origin_widget=origin_widget,
 76            # We're affected by screen size only at small ui-scale.
 77            refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL,
 78        )
 79
 80        if uiscale is bui.UIScale.SMALL:
 81            bui.containerwidget(
 82                edit=self._root_widget, on_cancel_call=self.main_window_back
 83            )
 84        else:
 85            btn = bui.buttonwidget(
 86                parent=self._root_widget,
 87                position=(50, yoffs - 45),
 88                size=(60, 55),
 89                scale=0.8,
 90                label=bui.charstr(bui.SpecialChar.BACK),
 91                button_type='backSmall',
 92                extra_touch_border_scale=2.0,
 93                autoselect=True,
 94                on_activate_call=self.main_window_back,
 95            )
 96            bui.containerwidget(edit=self._root_widget, cancel_button=btn)
 97
 98        bui.textwidget(
 99            parent=self._root_widget,
100            position=(
101                width * 0.5,
102                yoffs - (47 if uiscale is bui.UIScale.SMALL else 25),
103            ),
104            size=(0, 0),
105            text=bui.Lstr(
106                resource=f'{self._r}.titleText',
107                subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
108            ),
109            scale=0.9,
110            maxwidth=scroll_width * 0.7,
111            color=bui.app.ui_v1.title_color,
112            h_align='center',
113            v_align='center',
114        )
115
116        self._scrollwidget = bui.scrollwidget(
117            parent=self._root_widget,
118            size=(scroll_width, scroll_height),
119            position=(width * 0.5 - scroll_width * 0.5, scroll_bottom),
120            simple_culling_v=100.0,
121            capture_arrows=True,
122            border_opacity=0.4,
123            center_small_content_horizontally=True,
124        )
125
126        if uiscale is bui.UIScale.SMALL:
127            bui.widget(
128                edit=self._scrollwidget,
129                left_widget=bui.get_special_widget('back_button'),
130            )
131
132        bui.widget(
133            edit=self._scrollwidget,
134            right_widget=bui.get_special_widget('squad_button'),
135        )
136        bui.containerwidget(
137            edit=self._root_widget, selected_child=self._scrollwidget
138        )
139
140        # self._sub_width = 810 if uiscale is bui.UIScale.SMALL else 660
141        self._sub_width = 660
142        self._sub_height = (
143            1590
144            + bui.app.lang.get_resource(f'{self._r}.someDaysExtraSpace')
145            + bui.app.lang.get_resource(
146                f'{self._r}.orPunchingSomethingExtraSpace'
147            )
148        )
149
150        self._subcontainer = bui.containerwidget(
151            parent=self._scrollwidget,
152            size=(self._sub_width, self._sub_height),
153            background=False,
154            claims_left_right=False,
155        )
156
157        spacing = 1.0
158        h = self._sub_width * 0.5
159        v = self._sub_height - 55
160        logo_tex = bui.gettexture('logo')
161        icon_buffer = 1.1
162        header = (0.7, 1.0, 0.7, 1.0)
163        header2 = (0.8, 0.8, 1.0, 1.0)
164        paragraph = (0.8, 0.8, 1.0, 1.0)
165
166        txt = bui.Lstr(
167            resource=f'{self._r}.welcomeText',
168            subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
169        ).evaluate()
170        txt_scale = 1.4
171        txt_maxwidth = 480
172        bui.textwidget(
173            parent=self._subcontainer,
174            position=(h, v),
175            size=(0, 0),
176            scale=txt_scale,
177            flatness=0.5,
178            res_scale=1.5,
179            text=txt,
180            h_align='center',
181            color=header,
182            v_align='center',
183            maxwidth=txt_maxwidth,
184        )
185        txt_width = min(
186            txt_maxwidth,
187            bui.get_string_width(txt, suppress_warning=True) * txt_scale,
188        )
189
190        icon_size = 70
191        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
192        bui.imagewidget(
193            parent=self._subcontainer,
194            size=(icon_size, icon_size),
195            position=(hval2 - 0.5 * icon_size, v - 0.45 * icon_size),
196            texture=logo_tex,
197        )
198
199        app = bui.app
200        assert app.classic is not None
201
202        v -= spacing * 50.0
203        txt = bui.Lstr(resource=f'{self._r}.someDaysText').evaluate()
204        bui.textwidget(
205            parent=self._subcontainer,
206            position=(h, v),
207            size=(0, 0),
208            scale=1.2,
209            maxwidth=self._sub_width * 0.9,
210            text=txt,
211            h_align='center',
212            color=paragraph,
213            v_align='center',
214            flatness=1.0,
215        )
216        v -= spacing * 25.0 + getres(f'{self._r}.someDaysExtraSpace')
217        txt_scale = 0.66
218        txt = bui.Lstr(resource=f'{self._r}.orPunchingSomethingText').evaluate()
219        bui.textwidget(
220            parent=self._subcontainer,
221            position=(h, v),
222            size=(0, 0),
223            scale=txt_scale,
224            maxwidth=self._sub_width * 0.9,
225            text=txt,
226            h_align='center',
227            color=paragraph,
228            v_align='center',
229            flatness=1.0,
230        )
231        v -= spacing * 27.0 + getres(f'{self._r}.orPunchingSomethingExtraSpace')
232        txt_scale = 1.0
233        txt = bui.Lstr(
234            resource=f'{self._r}.canHelpText',
235            subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
236        ).evaluate()
237        bui.textwidget(
238            parent=self._subcontainer,
239            position=(h, v),
240            size=(0, 0),
241            scale=txt_scale,
242            flatness=1.0,
243            text=txt,
244            h_align='center',
245            color=paragraph,
246            v_align='center',
247        )
248
249        v -= spacing * 70.0
250        txt_scale = 1.0
251        txt = bui.Lstr(resource=f'{self._r}.toGetTheMostText').evaluate()
252        bui.textwidget(
253            parent=self._subcontainer,
254            position=(h, v),
255            size=(0, 0),
256            scale=txt_scale,
257            maxwidth=self._sub_width * 0.9,
258            text=txt,
259            h_align='center',
260            color=header,
261            v_align='center',
262            flatness=1.0,
263        )
264
265        v -= spacing * 40.0
266        txt_scale = 0.74
267        txt = bui.Lstr(resource=f'{self._r}.friendsText').evaluate()
268        hval2 = h - 220
269        bui.textwidget(
270            parent=self._subcontainer,
271            position=(hval2, v),
272            size=(0, 0),
273            scale=txt_scale,
274            maxwidth=100,
275            text=txt,
276            h_align='right',
277            color=header,
278            v_align='center',
279            flatness=1.0,
280        )
281
282        txt = bui.Lstr(
283            resource=f'{self._r}.friendsGoodText',
284            subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
285        ).evaluate()
286        txt_scale = 0.7
287        bui.textwidget(
288            parent=self._subcontainer,
289            position=(hval2 + 10, v + 8),
290            size=(0, 0),
291            scale=txt_scale,
292            maxwidth=500,
293            text=txt,
294            h_align='left',
295            color=paragraph,
296            flatness=1.0,
297        )
298
299        app = bui.app
300
301        v -= spacing * 45.0
302        txt = (
303            bui.Lstr(resource=f'{self._r}.devicesText').evaluate()
304            if app.env.vr
305            else bui.Lstr(resource=f'{self._r}.controllersText').evaluate()
306        )
307        txt_scale = 0.74
308        hval2 = h - 220
309        bui.textwidget(
310            parent=self._subcontainer,
311            position=(hval2, v),
312            size=(0, 0),
313            scale=txt_scale,
314            maxwidth=100,
315            text=txt,
316            h_align='right',
317            v_align='center',
318            color=header,
319            flatness=1.0,
320        )
321
322        txt_scale = 0.7
323        if not app.env.vr:
324            infotxt = '.controllersInfoText'
325            txt = bui.Lstr(
326                resource=self._r + infotxt,
327                fallback_resource=f'{self._r}.controllersInfoText',
328                subs=[
329                    ('${APP_NAME}', bui.Lstr(resource='titleText')),
330                    ('${REMOTE_APP_NAME}', bui.get_remote_app_name()),
331                ],
332            ).evaluate()
333        else:
334            txt = bui.Lstr(
335                resource=f'{self._r}.devicesInfoText',
336                subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
337            ).evaluate()
338
339        bui.textwidget(
340            parent=self._subcontainer,
341            position=(hval2 + 10, v + 8),
342            size=(0, 0),
343            scale=txt_scale,
344            maxwidth=500,
345            max_height=105,
346            text=txt,
347            h_align='left',
348            color=paragraph,
349            flatness=1.0,
350        )
351
352        v -= spacing * 150.0
353
354        txt = bui.Lstr(resource=f'{self._r}.controlsText').evaluate()
355        txt_scale = 1.4
356        txt_maxwidth = 480
357        bui.textwidget(
358            parent=self._subcontainer,
359            position=(h, v),
360            size=(0, 0),
361            scale=txt_scale,
362            flatness=0.5,
363            text=txt,
364            h_align='center',
365            color=header,
366            v_align='center',
367            res_scale=1.5,
368            maxwidth=txt_maxwidth,
369        )
370        txt_width = min(
371            txt_maxwidth,
372            bui.get_string_width(txt, suppress_warning=True) * txt_scale,
373        )
374        icon_size = 70
375
376        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
377        bui.imagewidget(
378            parent=self._subcontainer,
379            size=(icon_size, icon_size),
380            position=(hval2 - 0.5 * icon_size, v - 0.45 * icon_size),
381            texture=logo_tex,
382        )
383
384        v -= spacing * 45.0
385
386        txt_scale = 0.7
387        txt = bui.Lstr(
388            resource=f'{self._r}.controlsSubtitleText',
389            subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
390        ).evaluate()
391        bui.textwidget(
392            parent=self._subcontainer,
393            position=(h, v),
394            size=(0, 0),
395            scale=txt_scale,
396            maxwidth=self._sub_width * 0.9,
397            flatness=1.0,
398            text=txt,
399            h_align='center',
400            color=paragraph,
401            v_align='center',
402        )
403        v -= spacing * 160.0
404
405        sep = 70
406        icon_size = 100
407        # icon_size_2 = 30
408        hval2 = h - sep
409        vval2 = v
410        bui.buttonwidget(
411            parent=self._subcontainer,
412            label='',
413            size=(icon_size, icon_size),
414            position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size),
415            texture=bui.gettexture('buttonPunch'),
416            color=(1, 0.7, 0.3),
417            selectable=False,
418            enable_sound=False,
419            on_activate_call=bui.WeakCall(self._play_sound, 'spazAttack0', 4),
420        )
421
422        txt_scale = getres(f'{self._r}.punchInfoTextScale')
423        txt = bui.Lstr(resource=f'{self._r}.punchInfoText').evaluate()
424        bui.textwidget(
425            parent=self._subcontainer,
426            position=(h - sep - 185 + 70, v + 120),
427            size=(0, 0),
428            scale=txt_scale,
429            flatness=1.0,
430            text=txt,
431            h_align='center',
432            color=(1, 0.7, 0.3, 1.0),
433            v_align='top',
434        )
435
436        hval2 = h + sep
437        vval2 = v
438        bui.buttonwidget(
439            parent=self._subcontainer,
440            label='',
441            size=(icon_size, icon_size),
442            position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size),
443            texture=bui.gettexture('buttonBomb'),
444            color=(1, 0.3, 0.3),
445            selectable=False,
446            enable_sound=False,
447            on_activate_call=bui.WeakCall(self._play_sound, 'explosion0', 5),
448        )
449
450        txt = bui.Lstr(resource=f'{self._r}.bombInfoText').evaluate()
451        txt_scale = getres(f'{self._r}.bombInfoTextScale')
452        bui.textwidget(
453            parent=self._subcontainer,
454            position=(h + sep + 50 + 60, v - 35),
455            size=(0, 0),
456            scale=txt_scale,
457            flatness=1.0,
458            maxwidth=270,
459            text=txt,
460            h_align='center',
461            color=(1, 0.3, 0.3, 1.0),
462            v_align='top',
463        )
464
465        hval2 = h
466        vval2 = v + sep
467        bui.buttonwidget(
468            parent=self._subcontainer,
469            label='',
470            size=(icon_size, icon_size),
471            position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size),
472            texture=bui.gettexture('buttonPickUp'),
473            color=(0.5, 0.5, 1),
474            selectable=False,
475            enable_sound=False,
476            on_activate_call=bui.WeakCall(self._play_sound, 'spazPickup0', 1),
477        )
478
479        txtl = bui.Lstr(resource=f'{self._r}.pickUpInfoText')
480        txt_scale = getres(f'{self._r}.pickUpInfoTextScale')
481        bui.textwidget(
482            parent=self._subcontainer,
483            position=(h + 60 + 120, v + sep + 50),
484            size=(0, 0),
485            scale=txt_scale,
486            flatness=1.0,
487            text=txtl,
488            h_align='center',
489            color=(0.5, 0.5, 1, 1.0),
490            v_align='top',
491        )
492
493        hval2 = h
494        vval2 = v - sep
495        bui.buttonwidget(
496            parent=self._subcontainer,
497            label='',
498            size=(icon_size, icon_size),
499            position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size),
500            texture=bui.gettexture('buttonJump'),
501            color=(0.4, 1, 0.4),
502            selectable=False,
503            enable_sound=False,
504            on_activate_call=bui.WeakCall(self._play_sound, 'spazJump0', 4),
505        )
506
507        txt = bui.Lstr(resource=f'{self._r}.jumpInfoText').evaluate()
508        txt_scale = getres(f'{self._r}.jumpInfoTextScale')
509        bui.textwidget(
510            parent=self._subcontainer,
511            position=(h - 250 + 75, v - sep - 15 + 30),
512            size=(0, 0),
513            scale=txt_scale,
514            flatness=1.0,
515            text=txt,
516            h_align='center',
517            color=(0.4, 1, 0.4, 1.0),
518            v_align='top',
519        )
520
521        txt = bui.Lstr(resource=f'{self._r}.runInfoText').evaluate()
522        txt_scale = getres(f'{self._r}.runInfoTextScale')
523        bui.textwidget(
524            parent=self._subcontainer,
525            position=(h, v - sep - 100),
526            size=(0, 0),
527            scale=txt_scale,
528            maxwidth=self._sub_width * 0.93,
529            flatness=1.0,
530            text=txt,
531            h_align='center',
532            color=(0.7, 0.7, 1.0, 1.0),
533            v_align='center',
534        )
535
536        v -= spacing * 280.0
537
538        txt = bui.Lstr(resource=f'{self._r}.powerupsText').evaluate()
539        txt_scale = 1.4
540        txt_maxwidth = 480
541        bui.textwidget(
542            parent=self._subcontainer,
543            position=(h, v),
544            size=(0, 0),
545            scale=txt_scale,
546            flatness=0.5,
547            text=txt,
548            h_align='center',
549            color=header,
550            v_align='center',
551            maxwidth=txt_maxwidth,
552        )
553        txt_width = min(
554            txt_maxwidth,
555            bui.get_string_width(txt, suppress_warning=True) * txt_scale,
556        )
557        icon_size = 70
558        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
559        bui.imagewidget(
560            parent=self._subcontainer,
561            size=(icon_size, icon_size),
562            position=(hval2 - 0.5 * icon_size, v - 0.45 * icon_size),
563            texture=logo_tex,
564        )
565
566        v -= spacing * 50.0
567        txt_scale = getres(f'{self._r}.powerupsSubtitleTextScale')
568        txt = bui.Lstr(resource=f'{self._r}.powerupsSubtitleText').evaluate()
569        bui.textwidget(
570            parent=self._subcontainer,
571            position=(h, v),
572            size=(0, 0),
573            scale=txt_scale,
574            maxwidth=self._sub_width * 0.9,
575            text=txt,
576            h_align='center',
577            color=paragraph,
578            v_align='center',
579            flatness=1.0,
580        )
581
582        v -= spacing * 1.0
583
584        mm1 = -270
585        mm2 = -215
586        mm3 = 0
587        icon_size = 50
588        shadow_size = 80
589        shadow_offs_x = 3
590        shadow_offs_y = -4
591        t_big = 1.1
592        t_small = 0.65
593
594        shadow_tex = bui.gettexture('shadowSharp')
595
596        for tex in [
597            'powerupPunch',
598            'powerupShield',
599            'powerupBomb',
600            'powerupHealth',
601            'powerupIceBombs',
602            'powerupImpactBombs',
603            'powerupStickyBombs',
604            'powerupLandMines',
605            'powerupCurse',
606        ]:
607            name = bui.Lstr(resource=f'{self._r}.' + tex + 'NameText')
608            desc = bui.Lstr(resource=f'{self._r}.' + tex + 'DescriptionText')
609
610            v -= spacing * 60.0
611
612            bui.imagewidget(
613                parent=self._subcontainer,
614                size=(shadow_size, shadow_size),
615                position=(
616                    h + mm1 + shadow_offs_x - 0.5 * shadow_size,
617                    v + shadow_offs_y - 0.5 * shadow_size,
618                ),
619                texture=shadow_tex,
620                color=(0, 0, 0),
621                opacity=0.5,
622            )
623            bui.imagewidget(
624                parent=self._subcontainer,
625                size=(icon_size, icon_size),
626                position=(h + mm1 - 0.5 * icon_size, v - 0.5 * icon_size),
627                texture=bui.gettexture(tex),
628            )
629
630            txt_scale = t_big
631            txtl = name
632            bui.textwidget(
633                parent=self._subcontainer,
634                position=(h + mm2, v + 3),
635                size=(0, 0),
636                scale=txt_scale,
637                maxwidth=200,
638                flatness=1.0,
639                text=txtl,
640                h_align='left',
641                color=header2,
642                v_align='center',
643            )
644            txt_scale = t_small
645            txtl = desc
646            bui.textwidget(
647                parent=self._subcontainer,
648                position=(h + mm3, v),
649                size=(0, 0),
650                scale=txt_scale,
651                maxwidth=300,
652                flatness=1.0,
653                text=txtl,
654                h_align='left',
655                color=paragraph,
656                v_align='center',
657                res_scale=0.5,
658            )

Create a MainWindow given a root widget and transition info.

Automatically handles in and out transitions on the provided widget, so there is no need to set transitions when creating it.

@override
def get_main_window_state(self) -> bauiv1.MainWindowState:
663    @override
664    def get_main_window_state(self) -> bui.MainWindowState:
665        # Support recreating our window for back/refresh purposes.
666        cls = type(self)
667        return bui.BasicMainWindowState(
668            create_call=lambda transition, origin_widget: cls(
669                transition=transition, origin_widget=origin_widget
670            )
671        )

Return a WindowState to recreate this window, if supported.