Пример #1
0
    def __init__(self,
                 existing_profile: Optional[str],
                 in_main_menu: bool,
                 transition: str = 'in_right'):
        # FIXME: Tidy this up a bit.
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        from ba.internal import get_player_profile_colors
        self._in_main_menu = in_main_menu
        self._existing_profile = existing_profile
        self._r = 'editProfileWindow'
        self._spazzes: List[str] = []
        self._icon_textures: List[ba.Texture] = []
        self._icon_tint_textures: List[ba.Texture] = []

        # Grab profile colors or pick random ones.
        self._color, self._highlight = get_player_profile_colors(
            existing_profile)
        self._width = width = 780.0 if ba.app.small_ui else 680.0
        self._x_inset = x_inset = 50.0 if ba.app.small_ui else 0.0
        self._height = height = (350.0 if ba.app.small_ui else
                                 400.0 if ba.app.med_ui else 450.0)
        spacing = 40
        self._base_scale = (2.05 if ba.app.small_ui else
                            1.5 if ba.app.med_ui else 1.0)
        top_extra = 15 if ba.app.small_ui else 15
        super().__init__(root_widget=ba.containerwidget(
            size=(width, height + top_extra),
            transition=transition,
            scale=self._base_scale,
            stack_offset=(0, 15) if ba.app.small_ui else (0, 0)))
        cancel_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(52 + x_inset, height - 60),
            size=(155, 60),
            scale=0.8,
            autoselect=True,
            label=ba.Lstr(resource='cancelText'),
            on_activate_call=self._cancel)
        ba.containerwidget(edit=self._root_widget, cancel_button=btn)
        save_button = btn = ba.buttonwidget(parent=self._root_widget,
                                            position=(width - (177 + x_inset),
                                                      height - 60),
                                            size=(155, 60),
                                            autoselect=True,
                                            scale=0.8,
                                            label=ba.Lstr(resource='saveText'))
        ba.widget(edit=save_button, left_widget=cancel_button)
        ba.widget(edit=cancel_button, right_widget=save_button)
        ba.containerwidget(edit=self._root_widget, start_button=btn)
        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, height - 38),
                      size=(0, 0),
                      text=(ba.Lstr(resource=self._r + '.titleNewText')
                            if existing_profile is None else ba.Lstr(
                                resource=self._r + '.titleEditText')),
                      color=ba.app.title_color,
                      maxwidth=290,
                      scale=1.0,
                      h_align='center',
                      v_align='center')

        # Make a list of spaz icons.
        self.refresh_characters()
        profile = ba.app.config.get('Player Profiles',
                                    {}).get(self._existing_profile, {})

        if 'global' in profile:
            self._global = profile['global']
        else:
            self._global = False

        if 'icon' in profile:
            self._icon = profile['icon']
        else:
            self._icon = ba.charstr(ba.SpecialChar.LOGO)

        assigned_random_char = False

        # Look for existing character choice or pick random one otherwise.
        try:
            icon_index = self._spazzes.index(profile['character'])
        except Exception:
            # Let's set the default icon to spaz for our first profile; after
            # that we go random.
            # (SCRATCH THAT.. we now hard-code account-profiles to start with
            # spaz which has a similar effect)
            # try: p_len = len(ba.app.config['Player Profiles'])
            # except Exception: p_len = 0
            # if p_len == 0: icon_index = self._spazzes.index('Spaz')
            # else:
            random.seed()
            icon_index = random.randrange(len(self._spazzes))
            assigned_random_char = True
        self._icon_index = icon_index
        ba.buttonwidget(edit=save_button, on_activate_call=self.save)

        v = height - 115.0
        self._name = ('' if self._existing_profile is None else
                      self._existing_profile)
        self._is_account_profile = (self._name == '__account__')

        # If we just picked a random character, see if it has specific
        # colors/highlights associated with it and assign them if so.
        if assigned_random_char:
            clr = ba.app.spaz_appearances[
                self._spazzes[icon_index]].default_color
            if clr is not None:
                self._color = clr
            highlight = ba.app.spaz_appearances[
                self._spazzes[icon_index]].default_highlight
            if highlight is not None:
                self._highlight = highlight

        # Assign a random name if they had none.
        if self._name == '':
            names = _ba.get_random_names()
            self._name = names[random.randrange(len(names))]

        self._clipped_name_text = ba.textwidget(parent=self._root_widget,
                                                text='',
                                                position=(540 + x_inset,
                                                          v - 8),
                                                flatness=1.0,
                                                shadow=0.0,
                                                scale=0.55,
                                                size=(0, 0),
                                                maxwidth=100,
                                                h_align='center',
                                                v_align='center',
                                                color=(1, 1, 0, 0.5))

        if not self._is_account_profile and not self._global:
            ba.textwidget(parent=self._root_widget,
                          text=ba.Lstr(resource=self._r + '.nameText'),
                          position=(200 + x_inset, v - 6),
                          size=(0, 0),
                          h_align='right',
                          v_align='center',
                          color=(1, 1, 1, 0.5),
                          scale=0.9)

        self._upgrade_button = None
        if self._is_account_profile:
            if _ba.get_account_state() == 'signed_in':
                sval = _ba.get_account_display_string()
            else:
                sval = '??'
            ba.textwidget(parent=self._root_widget,
                          position=(self._width * 0.5, v - 7),
                          size=(0, 0),
                          scale=1.2,
                          text=sval,
                          maxwidth=270,
                          h_align='center',
                          v_align='center')
            txtl = ba.Lstr(
                resource='editProfileWindow.accountProfileText').evaluate()
            b_width = min(
                270.0,
                _ba.get_string_width(txtl, suppress_warning=True) * 0.6)
            ba.textwidget(parent=self._root_widget,
                          position=(self._width * 0.5, v - 39),
                          size=(0, 0),
                          scale=0.6,
                          color=ba.app.infotextcolor,
                          text=txtl,
                          maxwidth=270,
                          h_align='center',
                          v_align='center')
            self._account_type_info_button = ba.buttonwidget(
                parent=self._root_widget,
                label='?',
                size=(15, 15),
                text_scale=0.6,
                position=(self._width * 0.5 + b_width * 0.5 + 13, v - 47),
                button_type='square',
                color=(0.6, 0.5, 0.65),
                autoselect=True,
                on_activate_call=self.show_account_profile_info)
        elif self._global:

            b_size = 60
            self._icon_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                autoselect=True,
                position=(self._width * 0.5 - 160 - b_size * 0.5, v - 38 - 15),
                size=(b_size, b_size),
                color=(0.6, 0.5, 0.6),
                label='',
                button_type='square',
                text_scale=1.2,
                on_activate_call=self._on_icon_press)
            self._icon_button_label = ba.textwidget(
                parent=self._root_widget,
                position=(self._width * 0.5 - 160, v - 35),
                draw_controller=btn,
                h_align='center',
                v_align='center',
                size=(0, 0),
                color=(1, 1, 1),
                text='',
                scale=2.0)

            ba.textwidget(parent=self._root_widget,
                          h_align='center',
                          v_align='center',
                          position=(self._width * 0.5 - 160, v - 55 - 15),
                          size=(0, 0),
                          draw_controller=btn,
                          text=ba.Lstr(resource=self._r + '.iconText'),
                          scale=0.7,
                          color=ba.app.title_color,
                          maxwidth=120)

            self._update_icon()

            ba.textwidget(parent=self._root_widget,
                          position=(self._width * 0.5, v - 7),
                          size=(0, 0),
                          scale=1.2,
                          text=self._name,
                          maxwidth=240,
                          h_align='center',
                          v_align='center')
            # FIXME hard coded strings are bad
            txtl = ba.Lstr(
                resource='editProfileWindow.globalProfileText').evaluate()
            b_width = min(
                240.0,
                _ba.get_string_width(txtl, suppress_warning=True) * 0.6)
            ba.textwidget(parent=self._root_widget,
                          position=(self._width * 0.5, v - 39),
                          size=(0, 0),
                          scale=0.6,
                          color=ba.app.infotextcolor,
                          text=txtl,
                          maxwidth=240,
                          h_align='center',
                          v_align='center')
            self._account_type_info_button = ba.buttonwidget(
                parent=self._root_widget,
                label='?',
                size=(15, 15),
                text_scale=0.6,
                position=(self._width * 0.5 + b_width * 0.5 + 13, v - 47),
                button_type='square',
                color=(0.6, 0.5, 0.65),
                autoselect=True,
                on_activate_call=self.show_global_profile_info)
        else:
            self._text_field = ba.textwidget(
                parent=self._root_widget,
                position=(220 + x_inset, v - 30),
                size=(265, 40),
                text=self._name,
                h_align='left',
                v_align='center',
                max_chars=16,
                description=ba.Lstr(resource=self._r + '.nameDescriptionText'),
                autoselect=True,
                editable=True,
                padding=4,
                color=(0.9, 0.9, 0.9, 1.0),
                on_return_press_call=ba.Call(save_button.activate))

            # FIXME hard coded strings are bad
            txtl = ba.Lstr(
                resource='editProfileWindow.localProfileText').evaluate()
            b_width = min(
                270.0,
                _ba.get_string_width(txtl, suppress_warning=True) * 0.6)
            ba.textwidget(parent=self._root_widget,
                          position=(self._width * 0.5, v - 43),
                          size=(0, 0),
                          scale=0.6,
                          color=ba.app.infotextcolor,
                          text=txtl,
                          maxwidth=270,
                          h_align='center',
                          v_align='center')
            self._account_type_info_button = ba.buttonwidget(
                parent=self._root_widget,
                label='?',
                size=(15, 15),
                text_scale=0.6,
                position=(self._width * 0.5 + b_width * 0.5 + 13, v - 50),
                button_type='square',
                color=(0.6, 0.5, 0.65),
                autoselect=True,
                on_activate_call=self.show_local_profile_info)
            self._upgrade_button = ba.buttonwidget(
                parent=self._root_widget,
                label=ba.Lstr(resource='upgradeText'),
                size=(40, 17),
                text_scale=1.0,
                button_type='square',
                position=(self._width * 0.5 + b_width * 0.5 + 13 + 43, v - 51),
                color=(0.6, 0.5, 0.65),
                autoselect=True,
                on_activate_call=self.upgrade_profile)

        self._update_clipped_name()
        self._clipped_name_timer = ba.Timer(0.333,
                                            ba.WeakCall(
                                                self._update_clipped_name),
                                            timetype=ba.TimeType.REAL,
                                            repeat=True)

        v -= spacing * 3.0
        b_size = 80
        b_size_2 = 100
        b_offs = 150
        self._color_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(self._width * 0.5 - b_offs - b_size * 0.5, v - 50),
            size=(b_size, b_size),
            color=self._color,
            label='',
            button_type='square')
        origin = self._color_button.get_screen_space_center()
        ba.buttonwidget(edit=self._color_button,
                        on_activate_call=ba.WeakCall(self._make_picker,
                                                     'color', origin))
        ba.textwidget(parent=self._root_widget,
                      h_align='center',
                      v_align='center',
                      position=(self._width * 0.5 - b_offs, v - 65),
                      size=(0, 0),
                      draw_controller=btn,
                      text=ba.Lstr(resource=self._r + '.colorText'),
                      scale=0.7,
                      color=ba.app.title_color,
                      maxwidth=120)

        self._character_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(self._width * 0.5 - b_size_2 * 0.5, v - 60),
            up_widget=self._account_type_info_button,
            on_activate_call=self._on_character_press,
            size=(b_size_2, b_size_2),
            label='',
            color=(1, 1, 1),
            mask_texture=ba.gettexture('characterIconMask'))
        if not self._is_account_profile and not self._global:
            ba.containerwidget(edit=self._root_widget,
                               selected_child=self._text_field)
        ba.textwidget(parent=self._root_widget,
                      h_align='center',
                      v_align='center',
                      position=(self._width * 0.5, v - 80),
                      size=(0, 0),
                      draw_controller=btn,
                      text=ba.Lstr(resource=self._r + '.characterText'),
                      scale=0.7,
                      color=ba.app.title_color,
                      maxwidth=130)

        self._highlight_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(self._width * 0.5 + b_offs - b_size * 0.5, v - 50),
            up_widget=self._upgrade_button if self._upgrade_button is not None
            else self._account_type_info_button,
            size=(b_size, b_size),
            color=self._highlight,
            label='',
            button_type='square')

        if not self._is_account_profile and not self._global:
            ba.widget(edit=cancel_button, down_widget=self._text_field)
            ba.widget(edit=save_button, down_widget=self._text_field)
            ba.widget(edit=self._color_button, up_widget=self._text_field)
        ba.widget(edit=self._account_type_info_button,
                  down_widget=self._character_button)

        origin = self._highlight_button.get_screen_space_center()
        ba.buttonwidget(edit=self._highlight_button,
                        on_activate_call=ba.WeakCall(self._make_picker,
                                                     'highlight', origin))
        ba.textwidget(parent=self._root_widget,
                      h_align='center',
                      v_align='center',
                      position=(self._width * 0.5 + b_offs, v - 65),
                      size=(0, 0),
                      draw_controller=btn,
                      text=ba.Lstr(resource=self._r + '.highlightText'),
                      scale=0.7,
                      color=ba.app.title_color,
                      maxwidth=120)
        self._update_character()
Пример #2
0
    def _build_favorites_tab(self, region_height: float) -> None:

        c_height = region_height - 20
        v = c_height - 35 - 25 - 30

        uiscale = ba.app.ui.uiscale
        self._width = 1240 if uiscale is ba.UIScale.SMALL else 1040
        x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
        self._height = (578 if uiscale is ba.UIScale.SMALL else
                        670 if uiscale is ba.UIScale.MEDIUM else 800)

        self._scroll_width = self._width - 130 + 2 * x_inset
        self._scroll_height = self._height - 180
        x_inset = 100 if uiscale is ba.UIScale.SMALL else 0

        c_height = self._scroll_height - 20
        sub_scroll_height = c_height - 63
        self._favorites_scroll_width = sub_scroll_width = (
            680 if uiscale is ba.UIScale.SMALL else 640)

        v = c_height - 30

        b_width = 140 if uiscale is ba.UIScale.SMALL else 178
        b_height = (107 if uiscale is ba.UIScale.SMALL else
                    142 if uiscale is ba.UIScale.MEDIUM else 190)
        b_space_extra = (0 if uiscale is ba.UIScale.SMALL else
                         -2 if uiscale is ba.UIScale.MEDIUM else -5)

        btnv = (c_height - (48 if uiscale is ba.UIScale.SMALL else
                            45 if uiscale is ba.UIScale.MEDIUM else 40) -
                b_height)

        self._favorites_connect_button = btn1 = ba.buttonwidget(
            parent=self._container,
            size=(b_width, b_height),
            position=(40 if uiscale is ba.UIScale.SMALL else 40, btnv),
            button_type='square',
            color=(0.6, 0.53, 0.63),
            textcolor=(0.75, 0.7, 0.8),
            on_activate_call=self._on_favorites_connect_press,
            text_scale=1.0 if uiscale is ba.UIScale.SMALL else 1.2,
            label=ba.Lstr(resource='gatherWindow.manualConnectText'),
            autoselect=True)
        if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
            ba.widget(edit=btn1,
                      left_widget=_ba.get_special_widget('back_button'))
        btnv -= b_height + b_space_extra
        ba.buttonwidget(parent=self._container,
                        size=(b_width, b_height),
                        position=(40 if uiscale is ba.UIScale.SMALL else 40,
                                  btnv),
                        button_type='square',
                        color=(0.6, 0.53, 0.63),
                        textcolor=(0.75, 0.7, 0.8),
                        on_activate_call=self._on_favorites_rename_press,
                        text_scale=1.0 if uiscale is ba.UIScale.SMALL else 1.2,
                        label=ba.Lstr(resource='renameText'),
                        autoselect=True)
        btnv -= b_height + b_space_extra
        ba.buttonwidget(parent=self._container,
                        size=(b_width, b_height),
                        position=(40 if uiscale is ba.UIScale.SMALL else 40,
                                  btnv),
                        button_type='square',
                        color=(0.6, 0.53, 0.63),
                        textcolor=(0.75, 0.7, 0.8),
                        on_activate_call=self._on_favorite_delete_press,
                        text_scale=1.0 if uiscale is ba.UIScale.SMALL else 1.2,
                        label=ba.Lstr(resource='deleteText'),
                        autoselect=True)

        v -= sub_scroll_height + 23
        self._scrollwidget = scrlw = ba.scrollwidget(
            parent=self._container,
            position=(190 if uiscale is ba.UIScale.SMALL else 225, v),
            size=(sub_scroll_width, sub_scroll_height),
            claims_left_right=True)
        ba.widget(edit=self._favorites_connect_button,
                  right_widget=self._scrollwidget)
        self._columnwidget = ba.columnwidget(parent=scrlw,
                                             left_border=10,
                                             border=2,
                                             margin=0,
                                             claims_left_right=True)

        self._favorite_selected = None
        self._refresh_favorites()
Пример #3
0
    def _on_show_my_address_button_press(self, v2: float,
                                         container: Optional[ba.Widget],
                                         c_width: float) -> None:
        if not container:
            return

        tscl = 0.85
        tspc = 25

        ba.playsound(ba.getsound('swish'))
        ba.textwidget(parent=container,
                      position=(c_width * 0.5 - 10, v2),
                      color=(0.6, 1.0, 0.6),
                      scale=tscl,
                      size=(0, 0),
                      maxwidth=c_width * 0.45,
                      flatness=1.0,
                      h_align='right',
                      v_align='center',
                      text=ba.Lstr(resource='gatherWindow.'
                                   'manualYourLocalAddressText'))
        self._checking_state_text = ba.textwidget(
            parent=container,
            position=(c_width * 0.5, v2),
            color=(0.5, 0.5, 0.5),
            scale=tscl,
            size=(0, 0),
            maxwidth=c_width * 0.45,
            flatness=1.0,
            h_align='left',
            v_align='center',
            text=ba.Lstr(resource='gatherWindow.'
                         'checkingText'))

        threading.Thread(target=self._run_addr_fetch).start()

        v2 -= tspc
        ba.textwidget(parent=container,
                      position=(c_width * 0.5 - 10, v2),
                      color=(0.6, 1.0, 0.6),
                      scale=tscl,
                      size=(0, 0),
                      maxwidth=c_width * 0.45,
                      flatness=1.0,
                      h_align='right',
                      v_align='center',
                      text=ba.Lstr(resource='gatherWindow.'
                                   'manualYourAddressFromInternetText'))

        t_addr = ba.textwidget(parent=container,
                               position=(c_width * 0.5, v2),
                               color=(0.5, 0.5, 0.5),
                               scale=tscl,
                               size=(0, 0),
                               maxwidth=c_width * 0.45,
                               h_align='left',
                               v_align='center',
                               flatness=1.0,
                               text=ba.Lstr(resource='gatherWindow.'
                                            'checkingText'))
        v2 -= tspc
        ba.textwidget(parent=container,
                      position=(c_width * 0.5 - 10, v2),
                      color=(0.6, 1.0, 0.6),
                      scale=tscl,
                      size=(0, 0),
                      maxwidth=c_width * 0.45,
                      flatness=1.0,
                      h_align='right',
                      v_align='center',
                      text=ba.Lstr(resource='gatherWindow.'
                                   'manualJoinableFromInternetText'))

        t_accessible = ba.textwidget(parent=container,
                                     position=(c_width * 0.5, v2),
                                     color=(0.5, 0.5, 0.5),
                                     scale=tscl,
                                     size=(0, 0),
                                     maxwidth=c_width * 0.45,
                                     flatness=1.0,
                                     h_align='left',
                                     v_align='center',
                                     text=ba.Lstr(resource='gatherWindow.'
                                                  'checkingText'))
        v2 -= 28
        t_accessible_extra = ba.textwidget(parent=container,
                                           position=(c_width * 0.5, v2),
                                           color=(1, 0.5, 0.2),
                                           scale=0.7,
                                           size=(0, 0),
                                           maxwidth=c_width * 0.9,
                                           flatness=1.0,
                                           h_align='center',
                                           v_align='center',
                                           text='')

        self._doing_access_check = False
        self._access_check_count = 0  # Cap our refreshes eventually.
        self._access_check_timer = ba.Timer(
            10.0,
            ba.WeakCall(self._access_check_update, t_addr, t_accessible,
                        t_accessible_extra),
            repeat=True,
            timetype=ba.TimeType.REAL)

        # Kick initial off.
        self._access_check_update(t_addr, t_accessible, t_accessible_extra)
        if self._check_button:
            self._check_button.delete()
Пример #4
0
    def _smooth_update(self) -> None:
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-statements
        try:
            if not self._button:
                return
            if self._ticking_node is None:
                with ba.Context('ui'):
                    self._ticking_node = ba.newnode(
                        'sound',
                        attrs={
                            'sound': ba.getsound('scoreIncrease'),
                            'positional': False
                        })
            self._bg_flash = (not self._bg_flash)
            color_used = ((self._color[0] * 2, self._color[1] * 2,
                           self._color[2] *
                           2) if self._bg_flash else self._color)
            textcolor_used = ((1, 1, 1) if self._bg_flash else self._textcolor)
            header_color_used = ((1, 1,
                                  1) if self._bg_flash else self._header_color)

            if self._rank is not None:
                assert self._smooth_rank is not None
                self._smooth_rank -= 1.0 * self._smooth_increase_speed
                finished = (int(self._smooth_rank) <= self._rank)
            elif self._smooth_percent is not None:
                self._smooth_percent += 1.0 * self._smooth_increase_speed
                assert self._percent is not None
                finished = (int(self._smooth_percent) >= self._percent)
            else:
                finished = True
            if finished:
                if self._rank is not None:
                    self._smooth_rank = float(self._rank)
                elif self._percent is not None:
                    self._smooth_percent = float(self._percent)
                color_used = self._color
                textcolor_used = self._textcolor
                self._smooth_update_timer = None
                if self._ticking_node is not None:
                    self._ticking_node.delete()
                    self._ticking_node = None
                ba.playsound(ba.getsound('cashRegister2'))
                assert self._improvement_text is not None
                diff_text = ba.textwidget(
                    parent=self._parent,
                    size=(0, 0),
                    h_align='center',
                    v_align='center',
                    text='+' + self._improvement_text + '!',
                    position=(self._position[0] +
                              self._size[0] * 0.5 * self._scale,
                              self._position[1] +
                              self._size[1] * -0.2 * self._scale),
                    color=(0, 1, 0),
                    flatness=1.0,
                    shadow=0.0,
                    scale=self._scale * 0.7)

                def safe_delete(widget: ba.Widget) -> None:
                    if widget:
                        widget.delete()

                ba.timer(2.0,
                         ba.Call(safe_delete, diff_text),
                         timetype=ba.TimeType.REAL)
            status_text: Union[str, ba.Lstr]
            if self._rank is not None:
                assert self._smooth_rank is not None
                status_text = ba.Lstr(resource='numberText',
                                      subs=[('${NUMBER}',
                                             str(int(self._smooth_rank)))])
            elif self._smooth_percent is not None:
                status_text = str(int(self._smooth_percent)) + '%'
            else:
                status_text = '-'
            ba.textwidget(edit=self._value_text,
                          text=status_text,
                          color=textcolor_used)
            ba.textwidget(edit=self._title_text, color=header_color_used)
            ba.buttonwidget(edit=self._button, color=color_used)

        except Exception:
            ba.print_exception('Error doing smooth update.')
            self._smooth_update_timer = None
Пример #5
0
    def __init__(self,
                 parent: ba.Widget,
                 position: Tuple[float, float],
                 size: Tuple[float, float],
                 scale: float,
                 on_activate_call: Callable[[], Any] = None,
                 transition_delay: float = None,
                 color: Tuple[float, float, float] = None,
                 textcolor: Tuple[float, float, float] = None,
                 smooth_update_delay: float = None):
        from ba.internal import get_cached_league_rank_data
        if on_activate_call is None:
            on_activate_call = ba.WeakCall(self._default_on_activate_call)
        self._on_activate_call = on_activate_call
        if smooth_update_delay is None:
            smooth_update_delay = 1000
        self._smooth_update_delay = smooth_update_delay
        self._size = size
        self._scale = scale
        if color is None:
            color = (0.5, 0.6, 0.5)
        if textcolor is None:
            textcolor = (1, 1, 1)
        self._color = color
        self._textcolor = textcolor
        self._header_color = (0.8, 0.8, 2.0)
        self._parent = parent
        self._position: Tuple[float, float] = (0.0, 0.0)

        self._button = ba.buttonwidget(parent=parent,
                                       size=size,
                                       label='',
                                       button_type='square',
                                       scale=scale,
                                       autoselect=True,
                                       on_activate_call=self._on_activate,
                                       transition_delay=transition_delay,
                                       color=color)

        self._title_text = ba.textwidget(
            parent=parent,
            size=(0, 0),
            draw_controller=self._button,
            h_align='center',
            v_align='center',
            maxwidth=size[0] * scale * 0.85,
            text=ba.Lstr(
                resource='league.leagueRankText',
                fallback_resource='coopSelectWindow.powerRankingText'),
            color=self._header_color,
            flatness=1.0,
            shadow=1.0,
            scale=scale * 0.5,
            transition_delay=transition_delay)

        self._value_text = ba.textwidget(parent=parent,
                                         size=(0, 0),
                                         h_align='center',
                                         v_align='center',
                                         maxwidth=size[0] * scale * 0.85,
                                         text='-',
                                         draw_controller=self._button,
                                         big=True,
                                         scale=scale,
                                         transition_delay=transition_delay,
                                         color=textcolor)

        self._smooth_percent: Optional[float] = None
        self._percent: Optional[int] = None
        self._smooth_rank: Optional[float] = None
        self._rank: Optional[int] = None
        self._ticking_node: Optional[ba.Node] = None
        self._smooth_increase_speed = 1.0
        self._league: Optional[str] = None
        self._improvement_text: Optional[str] = None

        self._smooth_update_timer: Optional[ba.Timer] = None

        # Take note of our account state; we'll refresh later if this changes.
        self._account_state_num = _ba.get_account_state_num()
        self._last_power_ranking_query_time: Optional[float] = None
        self._doing_power_ranking_query = False
        self.set_position(position)
        self._bg_flash = False
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)
        self._update()

        # If we've got cached power-ranking data already, apply it.
        data = get_cached_league_rank_data()
        if data is not None:
            self._update_for_league_rank_data(data)
Пример #6
0
    def __init__(self,
                 transition: str = 'in_right',
                 origin_widget: ba.Widget = None):
        # FIXME: should tidy up here.
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        # pylint: disable=cyclic-import
        from bastd.ui import popup as popup_ui
        self._have_selected_child = False

        scale_origin: Optional[Tuple[float, float]]

        # If they provided an origin-widget, scale up from that.
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None

        self._r = 'configControllersWindow'
        app = ba.app

        # is_fire_tv = _ba.is_running_on_fire_tv()

        spacing = 50.0
        button_width = 350.0
        width = 460.0
        height = 130.0

        space_height = spacing * 0.3

        # FIXME: should create vis settings in platform for these,
        #  not hard code them here.

        show_gamepads = False
        platform = app.platform
        subplatform = app.subplatform
        non_vr_windows = (platform == 'windows'
                          and (subplatform != 'oculus' or not app.vr_mode))
        if platform in ('linux', 'android', 'mac') or non_vr_windows:
            show_gamepads = True
            height += spacing

        show_touch = False
        if _ba.have_touchscreen_input():
            show_touch = True
            height += spacing

        show_space_1 = False
        if show_gamepads or show_touch:
            show_space_1 = True
            height += space_height

        show_keyboard = False
        if _ba.getinputdevice('Keyboard', '#1', doraise=False) is not None:
            show_keyboard = True
            height += spacing
        show_keyboard_p2 = False if app.vr_mode else show_keyboard
        if show_keyboard_p2:
            height += spacing

        show_space_2 = False
        if show_keyboard:
            show_space_2 = True
            height += space_height

        if bool(True):
            show_remote = True
            height += spacing
        else:
            show_remote = False

        show_ps3 = False
        # if platform == 'mac':
        #     show_ps3 = True
        #     height += spacing

        show360 = False
        # if platform == 'mac' or is_fire_tv:
        #     show360 = True
        #     height += spacing

        show_mac_wiimote = False
        # if platform == 'mac' and _ba.is_xcode_build():
        #     show_mac_wiimote = True
        #     height += spacing

        # On windows (outside of oculus/vr), show an option to disable xinput.
        show_xinput_toggle = False
        if platform == 'windows' and not app.vr_mode:
            show_xinput_toggle = True

        # On mac builds, show an option to switch between generic and
        # made-for-iOS/Mac systems
        # (we can run into problems where devices register as one of each
        # type otherwise)..
        show_mac_controller_subsystem = False
        if platform == 'mac' and _ba.is_xcode_build():
            show_mac_controller_subsystem = True

        if show_mac_controller_subsystem:
            height += spacing * 1.5

        if show_xinput_toggle:
            height += spacing

        uiscale = ba.app.ui.uiscale
        smallscale = (1.7 if show_keyboard else 2.2)
        super().__init__(root_widget=ba.containerwidget(
            size=(width, height),
            transition=transition,
            scale_origin_stack_offset=scale_origin,
            stack_offset=((0, -10) if uiscale is ba.UIScale.SMALL else (0, 0)),
            scale=(smallscale if uiscale is ba.UIScale.SMALL else
                   1.5 if uiscale is ba.UIScale.MEDIUM else 1.0)))
        self._back_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(35, height - 60),
            size=(140, 65),
            scale=0.8,
            text_scale=1.2,
            autoselect=True,
            label=ba.Lstr(resource='backText'),
            button_type='back',
            on_activate_call=self._back)
        ba.containerwidget(edit=self._root_widget, cancel_button=btn)

        # We need these vars to exist even if the buttons don't.
        self._gamepads_button: Optional[ba.Widget] = None
        self._touch_button: Optional[ba.Widget] = None
        self._keyboard_button: Optional[ba.Widget] = None
        self._keyboard_2_button: Optional[ba.Widget] = None
        self._idevices_button: Optional[ba.Widget] = None
        self._ps3_button: Optional[ba.Widget] = None
        self._xbox_360_button: Optional[ba.Widget] = None
        self._wiimotes_button: Optional[ba.Widget] = None

        ba.textwidget(parent=self._root_widget,
                      position=(0, height - 49),
                      size=(width, 25),
                      text=ba.Lstr(resource=self._r + '.titleText'),
                      color=ba.app.ui.title_color,
                      h_align='center',
                      v_align='top')
        ba.buttonwidget(edit=btn,
                        button_type='backSmall',
                        size=(60, 60),
                        label=ba.charstr(ba.SpecialChar.BACK))

        v = height - 75
        v -= spacing

        if show_touch:
            self._touch_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                position=((width - button_width) / 2, v),
                size=(button_width, 43),
                autoselect=True,
                label=ba.Lstr(resource=self._r + '.configureTouchText'),
                on_activate_call=self._do_touchscreen)
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            if not self._have_selected_child:
                ba.containerwidget(edit=self._root_widget,
                                   selected_child=self._touch_button)
                ba.widget(edit=self._back_button,
                          down_widget=self._touch_button)
                self._have_selected_child = True
            v -= spacing

        if show_gamepads:
            self._gamepads_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                position=((width - button_width) / 2 - 7, v),
                size=(button_width, 43),
                autoselect=True,
                label=ba.Lstr(resource=self._r + '.configureControllersText'),
                on_activate_call=self._do_gamepads)
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            if not self._have_selected_child:
                ba.containerwidget(edit=self._root_widget,
                                   selected_child=self._gamepads_button)
                ba.widget(edit=self._back_button,
                          down_widget=self._gamepads_button)
                self._have_selected_child = True
            v -= spacing
        else:
            self._gamepads_button = None

        if show_space_1:
            v -= space_height

        if show_keyboard:
            self._keyboard_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                position=((width - button_width) / 2 + 5, v),
                size=(button_width, 43),
                autoselect=True,
                label=ba.Lstr(resource=self._r + '.configureKeyboardText'),
                on_activate_call=self._config_keyboard)
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            if not self._have_selected_child:
                ba.containerwidget(edit=self._root_widget,
                                   selected_child=self._keyboard_button)
                ba.widget(edit=self._back_button,
                          down_widget=self._keyboard_button)
                self._have_selected_child = True
            v -= spacing
        if show_keyboard_p2:
            self._keyboard_2_button = ba.buttonwidget(
                parent=self._root_widget,
                position=((width - button_width) / 2 - 3, v),
                size=(button_width, 43),
                autoselect=True,
                label=ba.Lstr(resource=self._r + '.configureKeyboard2Text'),
                on_activate_call=self._config_keyboard2)
            v -= spacing
        if show_space_2:
            v -= space_height
        if show_remote:
            self._idevices_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                position=((width - button_width) / 2 - 5, v),
                size=(button_width, 43),
                autoselect=True,
                label=ba.Lstr(resource=self._r + '.configureMobileText'),
                on_activate_call=self._do_mobile_devices)
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            if not self._have_selected_child:
                ba.containerwidget(edit=self._root_widget,
                                   selected_child=self._idevices_button)
                ba.widget(edit=self._back_button,
                          down_widget=self._idevices_button)
                self._have_selected_child = True
            v -= spacing
        if show_ps3:
            self._ps3_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                position=((width - button_width) / 2 + 5, v),
                size=(button_width, 43),
                autoselect=True,
                label=ba.Lstr(resource=self._r + '.ps3Text'),
                on_activate_call=self._do_ps3_controllers)
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            v -= spacing
        if show360:
            self._xbox_360_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                position=((width - button_width) / 2 - 1, v),
                size=(button_width, 43),
                autoselect=True,
                label=ba.Lstr(resource=self._r + '.xbox360Text'),
                on_activate_call=self._do_360_controllers)
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            v -= spacing
        if show_mac_wiimote:
            self._wiimotes_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                position=((width - button_width) / 2 + 5, v),
                size=(button_width, 43),
                autoselect=True,
                label=ba.Lstr(resource=self._r + '.wiimotesText'),
                on_activate_call=self._do_wiimotes)
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            v -= spacing

        if show_xinput_toggle:

            def do_toggle(value: bool) -> None:
                ba.screenmessage(
                    ba.Lstr(resource='settingsWindowAdvanced.mustRestartText'),
                    color=(1, 1, 0))
                ba.playsound(ba.getsound('gunCocking'))
                _ba.set_low_level_config_value('enablexinput', not value)

            ba.checkboxwidget(
                parent=self._root_widget,
                position=(100, v + 3),
                size=(120, 30),
                value=(not _ba.get_low_level_config_value('enablexinput', 1)),
                maxwidth=200,
                on_value_change_call=do_toggle,
                text=ba.Lstr(resource='disableXInputText'),
                autoselect=True)
            ba.textwidget(
                parent=self._root_widget,
                position=(width * 0.5, v - 5),
                size=(0, 0),
                text=ba.Lstr(resource='disableXInputDescriptionText'),
                scale=0.5,
                h_align='center',
                v_align='center',
                color=ba.app.ui.infotextcolor,
                maxwidth=width * 0.8)
            v -= spacing
        if show_mac_controller_subsystem:
            popup_ui.PopupMenu(
                parent=self._root_widget,
                position=(260, v - 10),
                width=160,
                button_size=(150, 50),
                scale=1.5,
                choices=['Classic', 'MFi', 'Both'],
                choices_display=[
                    ba.Lstr(resource='macControllerSubsystemClassicText'),
                    ba.Lstr(resource='macControllerSubsystemMFiText'),
                    ba.Lstr(resource='macControllerSubsystemBothText')
                ],
                current_choice=ba.app.config.resolve(
                    'Mac Controller Subsystem'),
                on_value_change_call=self._set_mac_controller_subsystem)
            ba.textwidget(
                parent=self._root_widget,
                position=(245, v + 13),
                size=(0, 0),
                text=ba.Lstr(resource='macControllerSubsystemTitleText'),
                scale=1.0,
                h_align='right',
                v_align='center',
                color=ba.app.ui.infotextcolor,
                maxwidth=180)
            ba.textwidget(
                parent=self._root_widget,
                position=(width * 0.5, v - 20),
                size=(0, 0),
                text=ba.Lstr(resource='macControllerSubsystemDescriptionText'),
                scale=0.5,
                h_align='center',
                v_align='center',
                color=ba.app.ui.infotextcolor,
                maxwidth=width * 0.8)
            v -= spacing * 1.5
        self._restore_state()
Пример #7
0
def instantiate_store_item_display(item_name: str,
                                   item: Dict[str, Any],
                                   parent_widget: ba.Widget,
                                   b_pos: Tuple[float, float],
                                   b_width: float,
                                   b_height: float,
                                   boffs_h: float = 0.0,
                                   boffs_h2: float = 0.0,
                                   boffs_v2: float = 0,
                                   delay: float = 0.0,
                                   button: bool = True) -> None:
    """(internal)"""
    # pylint: disable=too-many-statements
    # pylint: disable=too-many-branches
    # pylint: disable=too-many-locals
    from ba.internal import (get_store_item, get_store_item_name_translated,
                             get_clean_price)
    del boffs_h  # unused arg
    del boffs_h2  # unused arg
    del boffs_v2  # unused arg
    item_info = get_store_item(item_name)
    title_v = 0.24
    price_v = 0.145
    base_text_scale = 1.0

    item['name'] = title = get_store_item_name_translated(item_name)

    btn: Optional[ba.Widget]
    if button:
        item['button'] = btn = ba.buttonwidget(parent=parent_widget,
                                               position=b_pos,
                                               transition_delay=delay,
                                               show_buffer_top=76.0,
                                               enable_sound=False,
                                               button_type='square',
                                               size=(b_width, b_height),
                                               autoselect=True,
                                               label='')
        ba.widget(edit=btn, show_buffer_bottom=76.0)
    else:
        btn = None

    b_offs_x = -0.015 * b_width
    check_pos = 0.76

    icon_tex = None
    tint_tex = None
    tint_color = None
    tint2_color = None
    tex_name: Optional[str] = None
    desc: Optional[str] = None
    modes: Optional[ba.Lstr] = None

    if item_name.startswith('characters.'):
        character = ba.app.spaz_appearances[item_info['character']]
        tint_color = (
            item_info['color'] if 'color' in item_info else
            character.default_color if character.default_color is not None else
            (1, 1, 1))
        tint2_color = (item_info['highlight'] if 'highlight' in item_info else
                       character.default_highlight if
                       character.default_highlight is not None else (1, 1, 1))
        icon_tex = character.icon_texture
        tint_tex = character.icon_mask_texture
        title_v = 0.255
        price_v = 0.145
    elif item_name in ['upgrades.pro', 'pro']:
        base_text_scale = 0.6
        title_v = 0.85
        price_v = 0.15
    elif item_name.startswith('maps.'):
        map_type = item_info['map_type']
        tex_name = map_type.get_preview_texture_name()
        title_v = 0.312
        price_v = 0.17

    elif item_name.startswith('games.'):
        gametype = item_info['gametype']
        modes_l = []
        if gametype.supports_session_type(ba.CoopSession):
            modes_l.append(ba.Lstr(resource='playModes.coopText'))
        if gametype.supports_session_type(ba.DualTeamSession):
            modes_l.append(ba.Lstr(resource='playModes.teamsText'))
        if gametype.supports_session_type(ba.FreeForAllSession):
            modes_l.append(ba.Lstr(resource='playModes.freeForAllText'))

        if len(modes_l) == 3:
            modes = ba.Lstr(value='${A}, ${B}, ${C}',
                            subs=[('${A}', modes_l[0]), ('${B}', modes_l[1]),
                                  ('${C}', modes_l[2])])
        elif len(modes_l) == 2:
            modes = ba.Lstr(value='${A}, ${B}',
                            subs=[('${A}', modes_l[0]), ('${B}', modes_l[1])])
        elif len(modes_l) == 1:
            modes = modes_l[0]
        else:
            raise Exception()
        desc = gametype.get_description_display_string(ba.CoopSession)
        tex_name = item_info['previewTex']
        base_text_scale = 0.8
        title_v = 0.48
        price_v = 0.17

    elif item_name.startswith('icons.'):
        base_text_scale = 1.5
        price_v = 0.2
        check_pos = 0.6

    if item_name.startswith('characters.'):
        frame_size = b_width * 0.7
        im_dim = frame_size * (100.0 / 113.0)
        im_pos = (b_pos[0] + b_width * 0.5 - im_dim * 0.5 + b_offs_x,
                  b_pos[1] + b_height * 0.57 - im_dim * 0.5)
        mask_texture = ba.gettexture('characterIconMask')
        assert icon_tex is not None
        assert tint_tex is not None
        ba.imagewidget(parent=parent_widget,
                       position=im_pos,
                       size=(im_dim, im_dim),
                       color=(1, 1, 1),
                       transition_delay=delay,
                       mask_texture=mask_texture,
                       draw_controller=btn,
                       texture=ba.gettexture(icon_tex),
                       tint_texture=ba.gettexture(tint_tex),
                       tint_color=tint_color,
                       tint2_color=tint2_color)

    if item_name in ['pro', 'upgrades.pro']:
        frame_size = b_width * 0.5
        im_dim = frame_size * (100.0 / 113.0)
        im_pos = (b_pos[0] + b_width * 0.5 - im_dim * 0.5 + b_offs_x,
                  b_pos[1] + b_height * 0.5 - im_dim * 0.5)
        ba.imagewidget(parent=parent_widget,
                       position=im_pos,
                       size=(im_dim, im_dim),
                       transition_delay=delay,
                       draw_controller=btn,
                       color=(0.3, 0.0, 0.3),
                       opacity=0.3,
                       texture=ba.gettexture('logo'))
        txt = ba.Lstr(resource='store.bombSquadProNewDescriptionText')

        # t = 'foo\nfoo\nfoo\nfoo\nfoo\nfoo'
        item['descriptionText'] = ba.textwidget(
            parent=parent_widget,
            text=txt,
            position=(b_pos[0] + b_width * 0.5, b_pos[1] + b_height * 0.69),
            transition_delay=delay,
            scale=b_width * (1.0 / 230.0) * base_text_scale * 0.75,
            maxwidth=b_width * 0.75,
            max_height=b_height * 0.2,
            size=(0, 0),
            h_align='center',
            v_align='center',
            draw_controller=btn,
            color=(0.3, 1, 0.3))

        extra_backings = item['extra_backings'] = []
        extra_images = item['extra_images'] = []
        extra_texts = item['extra_texts'] = []
        extra_texts_2 = item['extra_texts_2'] = []

        backing_color = (0.5, 0.8, 0.3) if button else (0.6, 0.5, 0.65)
        b_square_texture = ba.gettexture('buttonSquare')
        char_mask_texture = ba.gettexture('characterIconMask')

        pos = (0.17, 0.43)
        tile_size = (b_width * 0.16 * 1.2, b_width * 0.2 * 1.2)
        tile_pos = (b_pos[0] + b_width * pos[0], b_pos[1] + b_height * pos[1])
        extra_backings.append(
            ba.imagewidget(parent=parent_widget,
                           position=(tile_pos[0] - tile_size[0] * 0.5,
                                     tile_pos[1] - tile_size[1] * 0.5),
                           size=tile_size,
                           transition_delay=delay,
                           draw_controller=btn,
                           color=backing_color,
                           texture=b_square_texture))
        im_size = tile_size[0] * 0.8
        extra_images.append(
            ba.imagewidget(parent=parent_widget,
                           position=(tile_pos[0] - im_size * 0.5,
                                     tile_pos[1] - im_size * 0.4),
                           size=(im_size, im_size),
                           transition_delay=delay,
                           draw_controller=btn,
                           color=(1, 1, 1),
                           texture=ba.gettexture('ticketsMore')))
        bonus_tickets = str(
            _ba.get_account_misc_read_val('proBonusTickets', 100))
        extra_texts.append(
            ba.textwidget(parent=parent_widget,
                          draw_controller=btn,
                          position=(tile_pos[0] - tile_size[0] * 0.03,
                                    tile_pos[1] - tile_size[1] * 0.25),
                          size=(0, 0),
                          color=(0.6, 1, 0.6),
                          transition_delay=delay,
                          h_align='center',
                          v_align='center',
                          maxwidth=tile_size[0] * 0.7,
                          scale=0.55,
                          text=ba.Lstr(resource='getTicketsWindow.ticketsText',
                                       subs=[('${COUNT}', bonus_tickets)]),
                          flatness=1.0,
                          shadow=0.0))

        for charname, pos in [('Kronk', (0.32, 0.45)), ('Zoe', (0.425, 0.4)),
                              ('Jack Morgan', (0.555, 0.45)),
                              ('Mel', (0.645, 0.4))]:
            tile_size = (b_width * 0.16 * 0.9, b_width * 0.2 * 0.9)
            tile_pos = (b_pos[0] + b_width * pos[0],
                        b_pos[1] + b_height * pos[1])
            character = ba.app.spaz_appearances[charname]
            extra_backings.append(
                ba.imagewidget(parent=parent_widget,
                               position=(tile_pos[0] - tile_size[0] * 0.5,
                                         tile_pos[1] - tile_size[1] * 0.5),
                               size=tile_size,
                               transition_delay=delay,
                               draw_controller=btn,
                               color=backing_color,
                               texture=b_square_texture))
            im_size = tile_size[0] * 0.7
            extra_images.append(
                ba.imagewidget(parent=parent_widget,
                               position=(tile_pos[0] - im_size * 0.53,
                                         tile_pos[1] - im_size * 0.35),
                               size=(im_size, im_size),
                               transition_delay=delay,
                               draw_controller=btn,
                               color=(1, 1, 1),
                               texture=ba.gettexture(character.icon_texture),
                               tint_texture=ba.gettexture(
                                   character.icon_mask_texture),
                               tint_color=character.default_color,
                               tint2_color=character.default_highlight,
                               mask_texture=char_mask_texture))
            extra_texts.append(
                ba.textwidget(parent=parent_widget,
                              draw_controller=btn,
                              position=(tile_pos[0] - im_size * 0.03,
                                        tile_pos[1] - im_size * 0.51),
                              size=(0, 0),
                              color=(0.6, 1, 0.6),
                              transition_delay=delay,
                              h_align='center',
                              v_align='center',
                              maxwidth=tile_size[0] * 0.7,
                              scale=0.55,
                              text=ba.Lstr(translate=('characterNames',
                                                      charname)),
                              flatness=1.0,
                              shadow=0.0))

        # If we have a 'total-worth' item-id for this id, show that price so
        # the user knows how much this is worth.
        total_worth_item = _ba.get_account_misc_read_val('twrths',
                                                         {}).get(item_name)
        total_worth_price: Optional[str]
        if total_worth_item is not None:
            price = _ba.get_price(total_worth_item)
            total_worth_price = (get_clean_price(price)
                                 if price is not None else '??')
        else:
            total_worth_price = None

        if total_worth_price is not None:
            total_worth_text = ba.Lstr(resource='store.totalWorthText',
                                       subs=[('${TOTAL_WORTH}',
                                              total_worth_price)])
            extra_texts_2.append(
                ba.textwidget(parent=parent_widget,
                              text=total_worth_text,
                              position=(b_pos[0] + b_width * 0.5 + b_offs_x,
                                        b_pos[1] + b_height * 0.25),
                              transition_delay=delay,
                              scale=b_width * (1.0 / 230.0) * base_text_scale *
                              0.45,
                              maxwidth=b_width * 0.5,
                              size=(0, 0),
                              h_align='center',
                              v_align='center',
                              shadow=1.0,
                              flatness=1.0,
                              draw_controller=btn,
                              color=(0.3, 1, 1)))

        model_opaque = ba.getmodel('level_select_button_opaque')
        model_transparent = ba.getmodel('level_select_button_transparent')
        mask_tex = ba.gettexture('mapPreviewMask')
        for levelname, preview_tex_name, pos in [
            ('Infinite Onslaught', 'doomShroomPreview', (0.80, 0.48)),
            ('Infinite Runaround', 'towerDPreview', (0.80, 0.32))
        ]:
            tile_size = (b_width * 0.2, b_width * 0.13)
            tile_pos = (b_pos[0] + b_width * pos[0],
                        b_pos[1] + b_height * pos[1])
            im_size = tile_size[0] * 0.8
            extra_backings.append(
                ba.imagewidget(parent=parent_widget,
                               position=(tile_pos[0] - tile_size[0] * 0.5,
                                         tile_pos[1] - tile_size[1] * 0.5),
                               size=tile_size,
                               transition_delay=delay,
                               draw_controller=btn,
                               color=backing_color,
                               texture=b_square_texture))

            # Hack - gotta draw two transparent versions to avoid z issues.
            for mod in model_opaque, model_transparent:
                extra_images.append(
                    ba.imagewidget(parent=parent_widget,
                                   position=(tile_pos[0] - im_size * 0.52,
                                             tile_pos[1] - im_size * 0.2),
                                   size=(im_size, im_size * 0.5),
                                   transition_delay=delay,
                                   model_transparent=mod,
                                   mask_texture=mask_tex,
                                   draw_controller=btn,
                                   texture=ba.gettexture(preview_tex_name)))

            extra_texts.append(
                ba.textwidget(parent=parent_widget,
                              draw_controller=btn,
                              position=(tile_pos[0] - im_size * 0.03,
                                        tile_pos[1] - im_size * 0.2),
                              size=(0, 0),
                              color=(0.6, 1, 0.6),
                              transition_delay=delay,
                              h_align='center',
                              v_align='center',
                              maxwidth=tile_size[0] * 0.7,
                              scale=0.55,
                              text=ba.Lstr(translate=('coopLevelNames',
                                                      levelname)),
                              flatness=1.0,
                              shadow=0.0))

    if item_name.startswith('icons.'):
        item['icon_text'] = ba.textwidget(
            parent=parent_widget,
            text=item_info['icon'],
            position=(b_pos[0] + b_width * 0.5, b_pos[1] + b_height * 0.5),
            transition_delay=delay,
            scale=b_width * (1.0 / 230.0) * base_text_scale * 2.0,
            maxwidth=b_width * 0.9,
            max_height=b_height * 0.9,
            size=(0, 0),
            h_align='center',
            v_align='center',
            draw_controller=btn)

    if item_name.startswith('maps.'):
        frame_size = b_width * 0.9
        im_dim = frame_size * (100.0 / 113.0)
        im_pos = (b_pos[0] + b_width * 0.5 - im_dim * 0.5 + b_offs_x,
                  b_pos[1] + b_height * 0.62 - im_dim * 0.25)
        model_opaque = ba.getmodel('level_select_button_opaque')
        model_transparent = ba.getmodel('level_select_button_transparent')
        mask_tex = ba.gettexture('mapPreviewMask')
        assert tex_name is not None
        ba.imagewidget(parent=parent_widget,
                       position=im_pos,
                       size=(im_dim, im_dim * 0.5),
                       transition_delay=delay,
                       model_opaque=model_opaque,
                       model_transparent=model_transparent,
                       mask_texture=mask_tex,
                       draw_controller=btn,
                       texture=ba.gettexture(tex_name))

    if item_name.startswith('games.'):
        frame_size = b_width * 0.8
        im_dim = frame_size * (100.0 / 113.0)
        im_pos = (b_pos[0] + b_width * 0.5 - im_dim * 0.5 + b_offs_x,
                  b_pos[1] + b_height * 0.72 - im_dim * 0.25)
        model_opaque = ba.getmodel('level_select_button_opaque')
        model_transparent = ba.getmodel('level_select_button_transparent')
        mask_tex = ba.gettexture('mapPreviewMask')
        assert tex_name is not None
        ba.imagewidget(parent=parent_widget,
                       position=im_pos,
                       size=(im_dim, im_dim * 0.5),
                       transition_delay=delay,
                       model_opaque=model_opaque,
                       model_transparent=model_transparent,
                       mask_texture=mask_tex,
                       draw_controller=btn,
                       texture=ba.gettexture(tex_name))
        item['descriptionText'] = ba.textwidget(
            parent=parent_widget,
            text=desc,
            position=(b_pos[0] + b_width * 0.5, b_pos[1] + b_height * 0.36),
            transition_delay=delay,
            scale=b_width * (1.0 / 230.0) * base_text_scale * 0.78,
            maxwidth=b_width * 0.8,
            max_height=b_height * 0.14,
            size=(0, 0),
            h_align='center',
            v_align='center',
            draw_controller=btn,
            flatness=1.0,
            shadow=0.0,
            color=(0.6, 1, 0.6))
        item['gameModesText'] = ba.textwidget(
            parent=parent_widget,
            text=modes,
            position=(b_pos[0] + b_width * 0.5, b_pos[1] + b_height * 0.26),
            transition_delay=delay,
            scale=b_width * (1.0 / 230.0) * base_text_scale * 0.65,
            maxwidth=b_width * 0.8,
            size=(0, 0),
            h_align='center',
            v_align='center',
            draw_controller=btn,
            shadow=0,
            flatness=1.0,
            color=(0.6, 0.8, 0.6))

    if not item_name.startswith('icons.'):
        item['title_text'] = ba.textwidget(
            parent=parent_widget,
            text=title,
            position=(b_pos[0] + b_width * 0.5 + b_offs_x,
                      b_pos[1] + b_height * title_v),
            transition_delay=delay,
            scale=b_width * (1.0 / 230.0) * base_text_scale,
            maxwidth=b_width * 0.8,
            size=(0, 0),
            h_align='center',
            v_align='center',
            draw_controller=btn,
            color=(0.7, 0.9, 0.7, 1.0))

    item['purchase_check'] = ba.imagewidget(
        parent=parent_widget,
        position=(b_pos[0] + b_width * check_pos, b_pos[1] + b_height * 0.05),
        transition_delay=delay,
        model_transparent=ba.getmodel('checkTransparent'),
        opacity=0.0,
        size=(60, 60),
        color=(0.6, 0.5, 0.8),
        draw_controller=btn,
        texture=ba.gettexture('uiAtlas'))
    item['price_widget'] = ba.textwidget(
        parent=parent_widget,
        text='',
        position=(b_pos[0] + b_width * 0.5 + b_offs_x,
                  b_pos[1] + b_height * price_v),
        transition_delay=delay,
        scale=b_width * (1.0 / 300.0) * base_text_scale,
        maxwidth=b_width * 0.9,
        size=(0, 0),
        h_align='center',
        v_align='center',
        draw_controller=btn,
        color=(0.2, 1, 0.2, 1.0))
    item['price_widget_left'] = ba.textwidget(
        parent=parent_widget,
        text='',
        position=(b_pos[0] + b_width * 0.33 + b_offs_x,
                  b_pos[1] + b_height * price_v),
        transition_delay=delay,
        scale=b_width * (1.0 / 300.0) * base_text_scale,
        maxwidth=b_width * 0.3,
        size=(0, 0),
        h_align='center',
        v_align='center',
        draw_controller=btn,
        color=(0.2, 1, 0.2, 0.5))
    item['price_widget_right'] = ba.textwidget(
        parent=parent_widget,
        text='',
        position=(b_pos[0] + b_width * 0.66 + b_offs_x,
                  b_pos[1] + b_height * price_v),
        transition_delay=delay,
        scale=1.1 * b_width * (1.0 / 300.0) * base_text_scale,
        maxwidth=b_width * 0.3,
        size=(0, 0),
        h_align='center',
        v_align='center',
        draw_controller=btn,
        color=(0.2, 1, 0.2, 1.0))
    item['price_slash_widget'] = ba.imagewidget(
        parent=parent_widget,
        position=(b_pos[0] + b_width * 0.33 + b_offs_x - 36,
                  b_pos[1] + b_height * price_v - 35),
        transition_delay=delay,
        texture=ba.gettexture('slash'),
        opacity=0.0,
        size=(70, 70),
        draw_controller=btn,
        color=(1, 0, 0))
    badge_rad = 44
    badge_center = (b_pos[0] + b_width * 0.1 + b_offs_x,
                    b_pos[1] + b_height * 0.87)
    item['sale_bg_widget'] = ba.imagewidget(
        parent=parent_widget,
        position=(badge_center[0] - badge_rad, badge_center[1] - badge_rad),
        opacity=0.0,
        transition_delay=delay,
        texture=ba.gettexture('circleZigZag'),
        draw_controller=btn,
        size=(badge_rad * 2, badge_rad * 2),
        color=(0.5, 0, 1))
    item['sale_title_widget'] = ba.textwidget(parent=parent_widget,
                                              position=(badge_center[0],
                                                        badge_center[1] + 12),
                                              transition_delay=delay,
                                              scale=1.0,
                                              maxwidth=badge_rad * 1.6,
                                              size=(0, 0),
                                              h_align='center',
                                              v_align='center',
                                              draw_controller=btn,
                                              shadow=0.0,
                                              flatness=1.0,
                                              color=(0, 1, 0))
    item['sale_time_widget'] = ba.textwidget(parent=parent_widget,
                                             position=(badge_center[0],
                                                       badge_center[1] - 12),
                                             transition_delay=delay,
                                             scale=0.7,
                                             maxwidth=badge_rad * 1.6,
                                             size=(0, 0),
                                             h_align='center',
                                             v_align='center',
                                             draw_controller=btn,
                                             shadow=0.0,
                                             flatness=1.0,
                                             color=(0.0, 1, 0.0, 1))
Пример #8
0
    def __init__(self, transition: str = 'in_right'):
        # pylint: disable=too-many-locals, too-many-statements
        from bastd.ui.confirm import QuitWindow
        self._width = 720.0
        self._height = 340.0

        def _do_cancel() -> None:
            QuitWindow(swish=True, back=True)

        super().__init__(
            root_widget=ba.containerwidget(size=(self._width, self._height),
                                           transition=transition,
                                           on_cancel_call=_do_cancel,
                                           background=False,
                                           stack_offset=(0, -130)))

        self._r = 'kioskWindow'

        self._show_multiplayer = False

        # Let's reset all random player names every time we hit the main menu.
        _ba.reset_random_player_names()

        # Reset achievements too (at least locally).
        ba.app.config['Achievements'] = {}

        t_delay_base = 0.0
        t_delay_scale = 0.0
        if not ba.app.did_menu_intro:
            t_delay_base = 1.0
            t_delay_scale = 1.0

        model_opaque = ba.getmodel('level_select_button_opaque')
        model_transparent = ba.getmodel('level_select_button_transparent')
        mask_tex = ba.gettexture('mapPreviewMask')

        y_extra = 130.0 + (0.0 if self._show_multiplayer else -130.0)
        b_width = 250.0
        b_height = 200.0
        b_space = 280.0
        b_v = 80.0 + y_extra
        label_height = 130.0 + y_extra
        img_width = 180.0
        img_v = 158.0 + y_extra

        if self._show_multiplayer:
            tdelay = t_delay_base + t_delay_scale * 1.3
            ba.textwidget(
                parent=self._root_widget,
                size=(0, 0),
                position=(self._width * 0.5, self._height + y_extra - 44),
                transition_delay=tdelay,
                text=ba.Lstr(resource=self._r + '.singlePlayerExamplesText'),
                flatness=1.0,
                scale=1.2,
                h_align='center',
                v_align='center',
                shadow=1.0)
        else:
            tdelay = t_delay_base + t_delay_scale * 0.7
            ba.textwidget(
                parent=self._root_widget,
                size=(0, 0),
                position=(self._width * 0.5, self._height + y_extra - 34),
                transition_delay=tdelay,
                text=(ba.Lstr(resource='demoText',
                              fallback_resource='mainMenu.demoMenuText')
                      if ba.app.demo_mode else 'ARCADE'),
                flatness=1.0,
                scale=1.2,
                h_align='center',
                v_align='center',
                shadow=1.0)
        h = self._width * 0.5 - b_space
        tdelay = t_delay_base + t_delay_scale * 0.7
        self._b1 = btn = ba.buttonwidget(parent=self._root_widget,
                                         autoselect=True,
                                         size=(b_width, b_height),
                                         on_activate_call=ba.Call(
                                             self._do_game, 'easy'),
                                         transition_delay=tdelay,
                                         position=(h - b_width * 0.5, b_v),
                                         label='',
                                         button_type='square')
        ba.textwidget(parent=self._root_widget,
                      draw_controller=btn,
                      transition_delay=tdelay,
                      size=(0, 0),
                      position=(h, label_height),
                      maxwidth=b_width * 0.7,
                      text=ba.Lstr(resource=self._r + '.easyText'),
                      scale=1.3,
                      h_align='center',
                      v_align='center')
        ba.imagewidget(parent=self._root_widget,
                       draw_controller=btn,
                       size=(img_width, 0.5 * img_width),
                       transition_delay=tdelay,
                       position=(h - img_width * 0.5, img_v),
                       texture=ba.gettexture('doomShroomPreview'),
                       model_opaque=model_opaque,
                       model_transparent=model_transparent,
                       mask_texture=mask_tex)
        h = self._width * 0.5
        tdelay = t_delay_base + t_delay_scale * 0.65
        self._b2 = btn = ba.buttonwidget(parent=self._root_widget,
                                         autoselect=True,
                                         size=(b_width, b_height),
                                         on_activate_call=ba.Call(
                                             self._do_game, 'medium'),
                                         position=(h - b_width * 0.5, b_v),
                                         label='',
                                         button_type='square',
                                         transition_delay=tdelay)
        ba.textwidget(parent=self._root_widget,
                      draw_controller=btn,
                      transition_delay=tdelay,
                      size=(0, 0),
                      position=(h, label_height),
                      maxwidth=b_width * 0.7,
                      text=ba.Lstr(resource=self._r + '.mediumText'),
                      scale=1.3,
                      h_align='center',
                      v_align='center')
        ba.imagewidget(parent=self._root_widget,
                       draw_controller=btn,
                       size=(img_width, 0.5 * img_width),
                       transition_delay=tdelay,
                       position=(h - img_width * 0.5, img_v),
                       texture=ba.gettexture('footballStadiumPreview'),
                       model_opaque=model_opaque,
                       model_transparent=model_transparent,
                       mask_texture=mask_tex)
        h = self._width * 0.5 + b_space
        tdelay = t_delay_base + t_delay_scale * 0.6
        self._b3 = btn = ba.buttonwidget(parent=self._root_widget,
                                         autoselect=True,
                                         size=(b_width, b_height),
                                         on_activate_call=ba.Call(
                                             self._do_game, 'hard'),
                                         transition_delay=tdelay,
                                         position=(h - b_width * 0.5, b_v),
                                         label='',
                                         button_type='square')
        ba.textwidget(parent=self._root_widget,
                      draw_controller=btn,
                      transition_delay=tdelay,
                      size=(0, 0),
                      position=(h, label_height),
                      maxwidth=b_width * 0.7,
                      text='Hard',
                      scale=1.3,
                      h_align='center',
                      v_align='center')
        ba.imagewidget(parent=self._root_widget,
                       draw_controller=btn,
                       transition_delay=tdelay,
                       size=(img_width, 0.5 * img_width),
                       position=(h - img_width * 0.5, img_v),
                       texture=ba.gettexture('courtyardPreview'),
                       model_opaque=model_opaque,
                       model_transparent=model_transparent,
                       mask_texture=mask_tex)
        if not ba.app.did_menu_intro:
            ba.app.did_menu_intro = True

        self._b4: Optional[ba.Widget]
        self._b5: Optional[ba.Widget]
        self._b6: Optional[ba.Widget]

        if bool(False):
            ba.textwidget(
                parent=self._root_widget,
                size=(0, 0),
                position=(self._width * 0.5, self._height + y_extra - 44),
                transition_delay=tdelay,
                text=ba.Lstr(resource=self._r + '.versusExamplesText'),
                flatness=1.0,
                scale=1.2,
                h_align='center',
                v_align='center',
                shadow=1.0)
            h = self._width * 0.5 - b_space
            tdelay = t_delay_base + t_delay_scale * 0.7
            self._b4 = btn = ba.buttonwidget(parent=self._root_widget,
                                             autoselect=True,
                                             size=(b_width, b_height),
                                             on_activate_call=ba.Call(
                                                 self._do_game, 'ctf'),
                                             transition_delay=tdelay,
                                             position=(h - b_width * 0.5, b_v),
                                             label='',
                                             button_type='square')
            ba.textwidget(parent=self._root_widget,
                          draw_controller=btn,
                          transition_delay=tdelay,
                          size=(0, 0),
                          position=(h, label_height),
                          maxwidth=b_width * 0.7,
                          text=ba.Lstr(translate=('gameNames',
                                                  'Capture the Flag')),
                          scale=1.3,
                          h_align='center',
                          v_align='center')
            ba.imagewidget(parent=self._root_widget,
                           draw_controller=btn,
                           size=(img_width, 0.5 * img_width),
                           transition_delay=tdelay,
                           position=(h - img_width * 0.5, img_v),
                           texture=ba.gettexture('bridgitPreview'),
                           model_opaque=model_opaque,
                           model_transparent=model_transparent,
                           mask_texture=mask_tex)

            h = self._width * 0.5
            tdelay = t_delay_base + t_delay_scale * 0.65
            self._b5 = btn = ba.buttonwidget(parent=self._root_widget,
                                             autoselect=True,
                                             size=(b_width, b_height),
                                             on_activate_call=ba.Call(
                                                 self._do_game, 'hockey'),
                                             position=(h - b_width * 0.5, b_v),
                                             label='',
                                             button_type='square',
                                             transition_delay=tdelay)
            ba.textwidget(parent=self._root_widget,
                          draw_controller=btn,
                          transition_delay=tdelay,
                          size=(0, 0),
                          position=(h, label_height),
                          maxwidth=b_width * 0.7,
                          text=ba.Lstr(translate=('gameNames', 'Hockey')),
                          scale=1.3,
                          h_align='center',
                          v_align='center')
            ba.imagewidget(parent=self._root_widget,
                           draw_controller=btn,
                           size=(img_width, 0.5 * img_width),
                           transition_delay=tdelay,
                           position=(h - img_width * 0.5, img_v),
                           texture=ba.gettexture('hockeyStadiumPreview'),
                           model_opaque=model_opaque,
                           model_transparent=model_transparent,
                           mask_texture=mask_tex)
            h = self._width * 0.5 + b_space
            tdelay = t_delay_base + t_delay_scale * 0.6
            self._b6 = btn = ba.buttonwidget(parent=self._root_widget,
                                             autoselect=True,
                                             size=(b_width, b_height),
                                             on_activate_call=ba.Call(
                                                 self._do_game, 'epic'),
                                             transition_delay=tdelay,
                                             position=(h - b_width * 0.5, b_v),
                                             label='',
                                             button_type='square')
            ba.textwidget(parent=self._root_widget,
                          draw_controller=btn,
                          transition_delay=tdelay,
                          size=(0, 0),
                          position=(h, label_height),
                          maxwidth=b_width * 0.7,
                          text=ba.Lstr(resource=self._r + '.epicModeText'),
                          scale=1.3,
                          h_align='center',
                          v_align='center')
            ba.imagewidget(parent=self._root_widget,
                           draw_controller=btn,
                           transition_delay=tdelay,
                           size=(img_width, 0.5 * img_width),
                           position=(h - img_width * 0.5, img_v),
                           texture=ba.gettexture('tipTopPreview'),
                           model_opaque=model_opaque,
                           model_transparent=model_transparent,
                           mask_texture=mask_tex)
        else:
            self._b4 = self._b5 = self._b6 = None

        self._b7: Optional[ba.Widget]
        if ba.app.arcade_mode:
            self._b7 = ba.buttonwidget(
                parent=self._root_widget,
                autoselect=True,
                size=(b_width, 50),
                color=(0.45, 0.55, 0.45),
                textcolor=(0.7, 0.8, 0.7),
                scale=0.5,
                position=(self._width * 0.5 - 60.0, b_v - 70.0),
                transition_delay=tdelay,
                label=ba.Lstr(resource=self._r + '.fullMenuText'),
                on_activate_call=self._do_full_menu)
        else:
            self._b7 = None
        self._restore_state()
        self._update()
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)
Пример #9
0
    def __init__(self,
                 callback: Callable[[Any], Any],
                 current_entry: Any,
                 selection_target_name: str,
                 transition: str = 'in_right'):
        from ba.internal import (get_soundtrack_entry_type,
                                 supports_soundtrack_entry_type)
        self._r = 'editSoundtrackWindow'

        self._callback = callback
        self._current_entry = copy.deepcopy(current_entry)

        self._width = 580
        self._height = 220
        spacing = 80

        do_default = True
        do_mac_music_app_playlist = supports_soundtrack_entry_type(
            'iTunesPlaylist')
        do_music_file = supports_soundtrack_entry_type('musicFile')
        do_music_folder = supports_soundtrack_entry_type('musicFolder')

        if do_mac_music_app_playlist:
            self._height += spacing
        if do_music_file:
            self._height += spacing
        if do_music_folder:
            self._height += spacing

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height),
            transition=transition,
            scale=1.7 if ba.app.small_ui else 1.4 if ba.app.med_ui else 1.0))
        btn = ba.buttonwidget(parent=self._root_widget,
                              position=(35, self._height - 65),
                              size=(160, 60),
                              scale=0.8,
                              text_scale=1.2,
                              label=ba.Lstr(resource='cancelText'),
                              on_activate_call=self._on_cancel_press)
        ba.containerwidget(edit=self._root_widget, cancel_button=btn)
        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height - 32),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r + '.selectASourceText'),
                      color=ba.app.title_color,
                      maxwidth=230,
                      h_align="center",
                      v_align="center")

        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height - 56),
                      size=(0, 0),
                      text=selection_target_name,
                      color=ba.app.infotextcolor,
                      scale=0.7,
                      maxwidth=230,
                      h_align="center",
                      v_align="center")

        v = self._height - 155

        current_entry_type = get_soundtrack_entry_type(current_entry)

        if do_default:
            btn = ba.buttonwidget(parent=self._root_widget,
                                  size=(self._width - 100, 60),
                                  position=(50, v),
                                  label=ba.Lstr(resource=self._r +
                                                '.useDefaultGameMusicText'),
                                  on_activate_call=self._on_default_press)
            if current_entry_type == 'default':
                ba.containerwidget(edit=self._root_widget, selected_child=btn)
            v -= spacing

        if do_mac_music_app_playlist:
            btn = ba.buttonwidget(
                parent=self._root_widget,
                size=(self._width - 100, 60),
                position=(50, v),
                label=ba.Lstr(resource=self._r + '.useITunesPlaylistText'),
                on_activate_call=self._on_mac_music_app_playlist_press,
                icon=None)
            if current_entry_type == 'iTunesPlaylist':
                ba.containerwidget(edit=self._root_widget, selected_child=btn)
            v -= spacing

        if do_music_file:
            btn = ba.buttonwidget(parent=self._root_widget,
                                  size=(self._width - 100, 60),
                                  position=(50, v),
                                  label=ba.Lstr(resource=self._r +
                                                '.useMusicFileText'),
                                  on_activate_call=self._on_music_file_press,
                                  icon=ba.gettexture('file'))
            if current_entry_type == 'musicFile':
                ba.containerwidget(edit=self._root_widget, selected_child=btn)
            v -= spacing

        if do_music_folder:
            btn = ba.buttonwidget(parent=self._root_widget,
                                  size=(self._width - 100, 60),
                                  position=(50, v),
                                  label=ba.Lstr(resource=self._r +
                                                '.useMusicFolderText'),
                                  on_activate_call=self._on_music_folder_press,
                                  icon=ba.gettexture('folder'),
                                  icon_color=(1.1, 0.8, 0.2))
            if current_entry_type == 'musicFolder':
                ba.containerwidget(edit=self._root_widget, selected_child=btn)
            v -= spacing
Пример #10
0
    def __init__(self,
                 edit_profile_window: EditProfileWindow,
                 transition: str = 'in_right'):
        from ba.internal import master_server_get
        self._r = 'editProfileWindow'

        self._width = 680
        self._height = 350
        uiscale = ba.app.ui.uiscale
        self._base_scale = (2.05 if uiscale is ba.UIScale.SMALL else
                            1.5 if uiscale is ba.UIScale.MEDIUM else 1.2)
        self._upgrade_start_time: Optional[float] = None
        self._name = edit_profile_window.getname()
        self._edit_profile_window = weakref.ref(edit_profile_window)

        top_extra = 15 if uiscale is ba.UIScale.SMALL else 15
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + top_extra),
            toolbar_visibility='menu_currency',
            transition=transition,
            scale=self._base_scale,
            stack_offset=(0, 15) if uiscale is ba.UIScale.SMALL else (0, 0)))
        cancel_button = ba.buttonwidget(parent=self._root_widget,
                                        position=(52, 30),
                                        size=(155, 60),
                                        scale=0.8,
                                        autoselect=True,
                                        label=ba.Lstr(resource='cancelText'),
                                        on_activate_call=self._cancel)
        self._upgrade_button = ba.buttonwidget(
            parent=self._root_widget,
            position=(self._width - 190, 30),
            size=(155, 60),
            scale=0.8,
            autoselect=True,
            label=ba.Lstr(resource='upgradeText'),
            on_activate_call=self._on_upgrade_press)
        ba.containerwidget(edit=self._root_widget,
                           cancel_button=cancel_button,
                           start_button=self._upgrade_button,
                           selected_child=self._upgrade_button)

        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height - 38),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r +
                                   '.upgradeToGlobalProfileText'),
                      color=ba.app.ui.title_color,
                      maxwidth=self._width * 0.45,
                      scale=1.0,
                      h_align='center',
                      v_align='center')

        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height - 100),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r +
                                   '.upgradeProfileInfoText'),
                      color=ba.app.ui.infotextcolor,
                      maxwidth=self._width * 0.8,
                      scale=0.7,
                      h_align='center',
                      v_align='center')

        self._status_text = ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height - 160),
            size=(0, 0),
            text=ba.Lstr(resource=self._r + '.checkingAvailabilityText',
                         subs=[('${NAME}', self._name)]),
            color=(0.8, 0.4, 0.0),
            maxwidth=self._width * 0.8,
            scale=0.65,
            h_align='center',
            v_align='center')

        self._price_text = ba.textwidget(parent=self._root_widget,
                                         position=(self._width * 0.5,
                                                   self._height - 230),
                                         size=(0, 0),
                                         text='',
                                         color=(0.2, 1, 0.2),
                                         maxwidth=self._width * 0.8,
                                         scale=1.5,
                                         h_align='center',
                                         v_align='center')

        self._tickets_text: Optional[ba.Widget]
        if not ba.app.ui.use_toolbars:
            self._tickets_text = ba.textwidget(
                parent=self._root_widget,
                position=(self._width * 0.9 - 5, self._height - 30),
                size=(0, 0),
                text=ba.charstr(ba.SpecialChar.TICKET) + '123',
                color=(0.2, 1, 0.2),
                maxwidth=100,
                scale=0.5,
                h_align='right',
                v_align='center')
        else:
            self._tickets_text = None

        master_server_get('bsGlobalProfileCheck', {
            'name': self._name,
            'b': ba.app.build_number
        },
                          callback=ba.WeakCall(self._profile_check_result))
        self._cost = _ba.get_account_misc_read_val('price.global_profile', 500)
        self._status: Optional[str] = 'waiting'
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)
        self._update()
Пример #11
0
    def __init__(self,
                 parent: ba.Widget,
                 position: Tuple[float, float] = (0.0, 0.0),
                 delegate: Any = None,
                 scale: float = None,
                 offset: Tuple[float, float] = (0.0, 0.0),
                 tint_color: Sequence[float] = (1.0, 1.0, 1.0),
                 tint2_color: Sequence[float] = (1.0, 1.0, 1.0),
                 selected_icon: str = None):
        # pylint: disable=too-many-locals
        del parent  # unused here
        del tint_color  # unused_here
        del tint2_color  # unused here
        uiscale = ba.app.ui.uiscale
        if scale is None:
            scale = (1.85 if uiscale is ba.UIScale.SMALL else
                     1.65 if uiscale is ba.UIScale.MEDIUM else 1.23)

        self._delegate = delegate
        self._transitioning_out = False

        self._icons = [ba.charstr(ba.SpecialChar.LOGO)
                       ] + ba.app.accounts.get_purchased_icons()
        count = len(self._icons)
        columns = 4
        rows = int(math.ceil(float(count) / columns))

        button_width = 50
        button_height = 50
        button_buffer_h = 10
        button_buffer_v = 5

        self._width = (10 + columns * (button_width + 2 * button_buffer_h) *
                       (1.0 / 0.95) * (1.0 / 0.8))
        self._height = (self._width *
                        (0.8 if uiscale is ba.UIScale.SMALL else 1.06))

        self._scroll_width = self._width * 0.8
        self._scroll_height = self._height * 0.8
        self._scroll_position = ((self._width - self._scroll_width) * 0.5,
                                 (self._height - self._scroll_height) * 0.5)

        # creates our _root_widget
        popup.PopupWindow.__init__(self,
                                   position=position,
                                   size=(self._width, self._height),
                                   scale=scale,
                                   bg_color=(0.5, 0.5, 0.5),
                                   offset=offset,
                                   focus_position=self._scroll_position,
                                   focus_size=(self._scroll_width,
                                               self._scroll_height))

        self._scrollwidget = ba.scrollwidget(parent=self.root_widget,
                                             size=(self._scroll_width,
                                                   self._scroll_height),
                                             color=(0.55, 0.55, 0.55),
                                             highlight=False,
                                             position=self._scroll_position)
        ba.containerwidget(edit=self._scrollwidget, claims_left_right=True)

        self._sub_width = self._scroll_width * 0.95
        self._sub_height = 5 + rows * (button_height +
                                       2 * button_buffer_v) + 100
        self._subcontainer = ba.containerwidget(parent=self._scrollwidget,
                                                size=(self._sub_width,
                                                      self._sub_height),
                                                background=False)
        index = 0
        for y in range(rows):
            for x in range(columns):
                pos = (x * (button_width + 2 * button_buffer_h) +
                       button_buffer_h, self._sub_height - (y + 1) *
                       (button_height + 2 * button_buffer_v) + 0)
                btn = ba.buttonwidget(parent=self._subcontainer,
                                      button_type='square',
                                      size=(button_width, button_height),
                                      autoselect=True,
                                      text_scale=1.2,
                                      label='',
                                      color=(0.65, 0.65, 0.65),
                                      on_activate_call=ba.Call(
                                          self._select_icon,
                                          self._icons[index]),
                                      position=pos)
                ba.textwidget(parent=self._subcontainer,
                              h_align='center',
                              v_align='center',
                              size=(0, 0),
                              position=(pos[0] + 0.5 * button_width - 1,
                                        pos[1] + 15),
                              draw_controller=btn,
                              text=self._icons[index],
                              scale=1.8)
                ba.widget(edit=btn, show_buffer_top=60, show_buffer_bottom=60)
                if self._icons[index] == selected_icon:
                    ba.containerwidget(edit=self._subcontainer,
                                       selected_child=btn,
                                       visible_child=btn)
                index += 1

                if index >= count:
                    break
            if index >= count:
                break
        self._get_more_icons_button = btn = ba.buttonwidget(
            parent=self._subcontainer,
            size=(self._sub_width * 0.8, 60),
            position=(self._sub_width * 0.1, 30),
            label=ba.Lstr(resource='editProfileWindow.getMoreIconsText'),
            on_activate_call=self._on_store_press,
            color=(0.6, 0.6, 0.6),
            textcolor=(0.8, 0.8, 0.8),
            autoselect=True)
        ba.widget(edit=btn, show_buffer_top=30, show_buffer_bottom=30)
 def _show_restart_needed(self, value: Any) -> None:
     del value  # Unused.
     ba.screenmessage(ba.Lstr(resource=self._r + '.mustRestartText'),
                      color=(1, 1, 0))
    def _rebuild(self) -> None:
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        from bastd.ui.config import ConfigCheckBox
        from ba.modutils import show_user_scripts

        available_languages = ba.app.lang.available_languages

        # Don't rebuild if the menu is open or if our language and
        # language-list hasn't changed.
        # NOTE - although we now support widgets updating their own
        # translations, we still change the label formatting on the language
        # menu based on the language so still need this. ...however we could
        # make this more limited to it only rebuilds that one menu instead
        # of everything.
        if self._menu_open or (self._prev_lang == _ba.app.config.get(
                'Lang', None) and self._prev_lang_list == available_languages):
            return
        self._prev_lang = _ba.app.config.get('Lang', None)
        self._prev_lang_list = available_languages

        # Clear out our sub-container.
        children = self._subcontainer.get_children()
        for child in children:
            child.delete()

        v = self._sub_height - 35

        v -= self._spacing * 1.2

        # Update our existing back button and title.
        if self._back_button is not None:
            ba.buttonwidget(edit=self._back_button,
                            label=ba.Lstr(resource='backText'))
            ba.buttonwidget(edit=self._back_button,
                            label=ba.charstr(ba.SpecialChar.BACK))

        ba.textwidget(edit=self._title_text,
                      text=ba.Lstr(resource=self._r + '.titleText'))

        this_button_width = 410

        self._promo_code_button = ba.buttonwidget(
            parent=self._subcontainer,
            position=(self._sub_width / 2 - this_button_width / 2, v - 14),
            size=(this_button_width, 60),
            autoselect=True,
            label=ba.Lstr(resource=self._r + '.enterPromoCodeText'),
            text_scale=1.0,
            on_activate_call=self._on_promo_code_press)
        if self._back_button is not None:
            ba.widget(edit=self._promo_code_button,
                      up_widget=self._back_button,
                      left_widget=self._back_button)
        v -= self._extra_button_spacing * 0.8

        ba.textwidget(parent=self._subcontainer,
                      position=(200, v + 10),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r + '.languageText'),
                      maxwidth=150,
                      scale=0.95,
                      color=ba.app.ui.title_color,
                      h_align='right',
                      v_align='center')

        languages = _ba.app.lang.available_languages
        cur_lang = _ba.app.config.get('Lang', None)
        if cur_lang is None:
            cur_lang = 'Auto'

        # We have a special dict of language names in that language
        # so we don't have to go digging through each full language.
        try:
            import json
            with open('ba_data/data/langdata.json',
                      encoding='utf-8') as infile:
                lang_names_translated = (json.loads(
                    infile.read())['lang_names_translated'])
        except Exception:
            ba.print_exception('Error reading lang data.')
            lang_names_translated = {}

        langs_translated = {}
        for lang in languages:
            langs_translated[lang] = lang_names_translated.get(lang, lang)

        langs_full = {}
        for lang in languages:
            lang_translated = ba.Lstr(translate=('languages', lang)).evaluate()
            if langs_translated[lang] == lang_translated:
                langs_full[lang] = lang_translated
            else:
                langs_full[lang] = (langs_translated[lang] + ' (' +
                                    lang_translated + ')')

        self._language_popup = popup_ui.PopupMenu(
            parent=self._subcontainer,
            position=(210, v - 19),
            width=150,
            opening_call=ba.WeakCall(self._on_menu_open),
            closing_call=ba.WeakCall(self._on_menu_close),
            autoselect=False,
            on_value_change_call=ba.WeakCall(self._on_menu_choice),
            choices=['Auto'] + languages,
            button_size=(250, 60),
            choices_display=([
                ba.Lstr(value=(ba.Lstr(resource='autoText').evaluate() + ' (' +
                               ba.Lstr(translate=('languages',
                                                  ba.app.lang.default_language
                                                  )).evaluate() + ')'))
            ] + [ba.Lstr(value=langs_full[l]) for l in languages]),
            current_choice=cur_lang)

        v -= self._spacing * 1.8

        ba.textwidget(parent=self._subcontainer,
                      position=(self._sub_width * 0.5, v + 10),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r + '.helpTranslateText',
                                   subs=[('${APP_NAME}',
                                          ba.Lstr(resource='titleText'))]),
                      maxwidth=self._sub_width * 0.9,
                      max_height=55,
                      flatness=1.0,
                      scale=0.65,
                      color=(0.4, 0.9, 0.4, 0.8),
                      h_align='center',
                      v_align='center')
        v -= self._spacing * 1.9
        this_button_width = 410
        self._translation_editor_button = ba.buttonwidget(
            parent=self._subcontainer,
            position=(self._sub_width / 2 - this_button_width / 2, v - 24),
            size=(this_button_width, 60),
            label=ba.Lstr(resource=self._r + '.translationEditorButtonText',
                          subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))
                                ]),
            autoselect=True,
            on_activate_call=ba.Call(
                ba.open_url, 'https://legacy.ballistica.net/translate'))

        self._lang_status_text = ba.textwidget(parent=self._subcontainer,
                                               position=(self._sub_width * 0.5,
                                                         v - 40),
                                               size=(0, 0),
                                               text='',
                                               flatness=1.0,
                                               scale=0.63,
                                               h_align='center',
                                               v_align='center',
                                               maxwidth=400.0)
        self._update_lang_status()
        v -= 40

        lang_inform = _ba.get_account_misc_val('langInform', False)

        self._language_inform_checkbox = cbw = ba.checkboxwidget(
            parent=self._subcontainer,
            position=(50, v - 50),
            size=(self._sub_width - 100, 30),
            autoselect=True,
            maxwidth=430,
            textcolor=(0.8, 0.8, 0.8),
            value=lang_inform,
            text=ba.Lstr(resource=self._r + '.translationInformMe'),
            on_value_change_call=ba.WeakCall(
                self._on_lang_inform_value_change))

        ba.widget(edit=self._translation_editor_button,
                  down_widget=cbw,
                  up_widget=self._language_popup.get_button())

        v -= self._spacing * 3.0

        self._kick_idle_players_check_box = ConfigCheckBox(
            parent=self._subcontainer,
            position=(50, v),
            size=(self._sub_width - 100, 30),
            configkey='Kick Idle Players',
            displayname=ba.Lstr(resource=self._r + '.kickIdlePlayersText'),
            scale=1.0,
            maxwidth=430)

        v -= 42
        self._disable_camera_shake_check_box = ConfigCheckBox(
            parent=self._subcontainer,
            position=(50, v),
            size=(self._sub_width - 100, 30),
            configkey='Disable Camera Shake',
            displayname=ba.Lstr(resource=self._r + '.disableCameraShakeText'),
            scale=1.0,
            maxwidth=430)

        self._disable_gyro_check_box: Optional[ConfigCheckBox] = None
        if self._show_disable_gyro:
            v -= 42
            self._disable_gyro_check_box = ConfigCheckBox(
                parent=self._subcontainer,
                position=(50, v),
                size=(self._sub_width - 100, 30),
                configkey='Disable Camera Gyro',
                displayname=ba.Lstr(resource=self._r +
                                    '.disableCameraGyroscopeMotionText'),
                scale=1.0,
                maxwidth=430)

        self._always_use_internal_keyboard_check_box: Optional[ConfigCheckBox]
        if self._show_always_use_internal_keyboard:
            v -= 42
            self._always_use_internal_keyboard_check_box = ConfigCheckBox(
                parent=self._subcontainer,
                position=(50, v),
                size=(self._sub_width - 100, 30),
                configkey='Always Use Internal Keyboard',
                autoselect=True,
                displayname=ba.Lstr(resource=self._r +
                                    '.alwaysUseInternalKeyboardText'),
                scale=1.0,
                maxwidth=430)
            ba.textwidget(
                parent=self._subcontainer,
                position=(90, v - 10),
                size=(0, 0),
                text=ba.Lstr(resource=self._r +
                             '.alwaysUseInternalKeyboardDescriptionText'),
                maxwidth=400,
                flatness=1.0,
                scale=0.65,
                color=(0.4, 0.9, 0.4, 0.8),
                h_align='left',
                v_align='center')
            v -= 20
        else:
            self._always_use_internal_keyboard_check_box = None

        v -= self._spacing * 2.1

        this_button_width = 410
        self._show_user_mods_button = ba.buttonwidget(
            parent=self._subcontainer,
            position=(self._sub_width / 2 - this_button_width / 2, v - 10),
            size=(this_button_width, 60),
            autoselect=True,
            label=ba.Lstr(resource=self._r + '.showUserModsText'),
            text_scale=1.0,
            on_activate_call=show_user_scripts)
        if self._show_always_use_internal_keyboard:
            assert self._always_use_internal_keyboard_check_box is not None
            ba.widget(edit=self._always_use_internal_keyboard_check_box.widget,
                      down_widget=self._show_user_mods_button)
            ba.widget(
                edit=self._show_user_mods_button,
                up_widget=self._always_use_internal_keyboard_check_box.widget)
        else:
            ba.widget(edit=self._show_user_mods_button,
                      up_widget=self._kick_idle_players_check_box.widget)
            ba.widget(edit=self._kick_idle_players_check_box.widget,
                      down_widget=self._show_user_mods_button)

        v -= self._spacing * 2.0

        self._modding_guide_button = ba.buttonwidget(
            parent=self._subcontainer,
            position=(self._sub_width / 2 - this_button_width / 2, v - 10),
            size=(this_button_width, 60),
            autoselect=True,
            label=ba.Lstr(resource=self._r + '.moddingGuideText'),
            text_scale=1.0,
            on_activate_call=ba.Call(
                ba.open_url,
                'http://www.froemling.net/docs/bombsquad-modding-guide'))

        v -= self._spacing * 2.0

        self._plugins_button = ba.buttonwidget(
            parent=self._subcontainer,
            position=(self._sub_width / 2 - this_button_width / 2, v - 10),
            size=(this_button_width, 60),
            autoselect=True,
            label=ba.Lstr(resource='pluginsText'),
            text_scale=1.0,
            on_activate_call=self._on_plugins_button_press)

        v -= self._spacing * 0.6

        self._vr_test_button: Optional[ba.Widget]
        if self._do_vr_test_button:
            v -= self._extra_button_spacing
            self._vr_test_button = ba.buttonwidget(
                parent=self._subcontainer,
                position=(self._sub_width / 2 - this_button_width / 2, v - 14),
                size=(this_button_width, 60),
                autoselect=True,
                label=ba.Lstr(resource=self._r + '.vrTestingText'),
                text_scale=1.0,
                on_activate_call=self._on_vr_test_press)
        else:
            self._vr_test_button = None

        self._net_test_button: Optional[ba.Widget]
        if self._do_net_test_button:
            v -= self._extra_button_spacing
            self._net_test_button = ba.buttonwidget(
                parent=self._subcontainer,
                position=(self._sub_width / 2 - this_button_width / 2, v - 14),
                size=(this_button_width, 60),
                autoselect=True,
                label=ba.Lstr(resource=self._r + '.netTestingText'),
                text_scale=1.0,
                on_activate_call=self._on_net_test_press)
        else:
            self._net_test_button = None

        v -= 70
        self._benchmarks_button = ba.buttonwidget(
            parent=self._subcontainer,
            position=(self._sub_width / 2 - this_button_width / 2, v - 14),
            size=(this_button_width, 60),
            autoselect=True,
            label=ba.Lstr(resource=self._r + '.benchmarksText'),
            text_scale=1.0,
            on_activate_call=self._on_benchmark_press)

        for child in self._subcontainer.get_children():
            ba.widget(edit=child, show_buffer_bottom=30, show_buffer_top=20)

        if ba.app.ui.use_toolbars:
            pbtn = _ba.get_special_widget('party_button')
            ba.widget(edit=self._scrollwidget, right_widget=pbtn)
            if self._back_button is None:
                ba.widget(edit=self._scrollwidget,
                          left_widget=_ba.get_special_widget('back_button'))

        self._restore_state()
    def __init__(self,
                 transition: str = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        from ba.internal import master_server_get
        import threading

        # Preload some modules we use in a background thread so we won't
        # have a visual hitch when the user taps them.
        threading.Thread(target=self._preload_modules).start()

        app = ba.app

        # If they provided an origin-widget, scale up from that.
        scale_origin: Optional[tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None

        uiscale = ba.app.ui.uiscale
        self._width = 870.0 if uiscale is ba.UIScale.SMALL else 670.0
        x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
        self._height = (390.0 if uiscale is ba.UIScale.SMALL else
                        450.0 if uiscale is ba.UIScale.MEDIUM else 520.0)
        self._spacing = 32
        self._menu_open = False
        top_extra = 10 if uiscale is ba.UIScale.SMALL else 0
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + top_extra),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(2.06 if uiscale is ba.UIScale.SMALL else
                   1.4 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -25) if uiscale is ba.UIScale.SMALL else (0, 0)))
        self._prev_lang = ''
        self._prev_lang_list: list[str] = []
        self._complete_langs_list: Optional[list] = None
        self._complete_langs_error = False
        self._language_popup: Optional[popup_ui.PopupMenu] = None

        # In vr-mode, the internal keyboard is currently the *only* option,
        # so no need to show this.
        self._show_always_use_internal_keyboard = (not app.vr_mode
                                                   and not app.iircade_mode)

        self._scroll_width = self._width - (100 + 2 * x_inset)
        self._scroll_height = self._height - 115.0
        self._sub_width = self._scroll_width * 0.95
        self._sub_height = 724.0

        if self._show_always_use_internal_keyboard:
            self._sub_height += 62

        self._show_disable_gyro = app.platform in {'ios', 'android'}
        if self._show_disable_gyro:
            self._sub_height += 42

        self._do_vr_test_button = app.vr_mode
        self._do_net_test_button = True
        self._extra_button_spacing = self._spacing * 2.5

        if self._do_vr_test_button:
            self._sub_height += self._extra_button_spacing
        if self._do_net_test_button:
            self._sub_height += self._extra_button_spacing
        self._sub_height += self._spacing * 2.0  # plugins

        self._r = 'settingsWindowAdvanced'

        if app.ui.use_toolbars and uiscale is ba.UIScale.SMALL:
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._do_back)
            self._back_button = None
        else:
            self._back_button = ba.buttonwidget(
                parent=self._root_widget,
                position=(53 + x_inset, self._height - 60),
                size=(140, 60),
                scale=0.8,
                autoselect=True,
                label=ba.Lstr(resource='backText'),
                button_type='back',
                on_activate_call=self._do_back)
            ba.containerwidget(edit=self._root_widget,
                               cancel_button=self._back_button)

        self._title_text = ba.textwidget(parent=self._root_widget,
                                         position=(0, self._height - 52),
                                         size=(self._width, 25),
                                         text=ba.Lstr(resource=self._r +
                                                      '.titleText'),
                                         color=app.ui.title_color,
                                         h_align='center',
                                         v_align='top')

        if self._back_button is not None:
            ba.buttonwidget(edit=self._back_button,
                            button_type='backSmall',
                            size=(60, 60),
                            label=ba.charstr(ba.SpecialChar.BACK))

        self._scrollwidget = ba.scrollwidget(parent=self._root_widget,
                                             position=(50 + x_inset, 50),
                                             simple_culling_v=20.0,
                                             highlight=False,
                                             size=(self._scroll_width,
                                                   self._scroll_height),
                                             selection_loops_to_parent=True)
        ba.widget(edit=self._scrollwidget, right_widget=self._scrollwidget)
        self._subcontainer = ba.containerwidget(parent=self._scrollwidget,
                                                size=(self._sub_width,
                                                      self._sub_height),
                                                background=False,
                                                selection_loops_to_parent=True)

        self._rebuild()

        # Rebuild periodically to pick up language changes/additions/etc.
        self._rebuild_timer = ba.Timer(1.0,
                                       ba.WeakCall(self._rebuild),
                                       repeat=True,
                                       timetype=ba.TimeType.REAL)

        # Fetch the list of completed languages.
        master_server_get('bsLangGetCompleted', {'b': app.build_number},
                          callback=ba.WeakCall(self._completed_langs_cb))
Пример #15
0
    def __init__(self,
                 sessiontype: Type[ba.Session],
                 transition: Optional[str] = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        # pylint: disable=cyclic-import
        from bastd.ui.playlist import PlaylistTypeVars

        # If they provided an origin-widget, scale up from that.
        scale_origin: Optional[Tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None

        # Store state for when we exit the next game.
        if issubclass(sessiontype, ba.DualTeamSession):
            ba.app.ui.set_main_menu_location('Team Game Select')
            ba.set_analytics_screen('Teams Window')
        elif issubclass(sessiontype, ba.FreeForAllSession):
            ba.app.ui.set_main_menu_location('Free-for-All Game Select')
            ba.set_analytics_screen('FreeForAll Window')
        else:
            raise TypeError(f'Invalid sessiontype: {sessiontype}.')
        self._pvars = PlaylistTypeVars(sessiontype)

        self._sessiontype = sessiontype

        self._customize_button: Optional[ba.Widget] = None
        self._sub_width: Optional[float] = None
        self._sub_height: Optional[float] = None

        # On new installations, go ahead and create a few playlists
        # besides the hard-coded default one:
        if not _ba.get_account_misc_val('madeStandardPlaylists', False):
            _ba.add_transaction({
                'type':
                'ADD_PLAYLIST',
                'playlistType':
                'Free-for-All',
                'playlistName':
                ba.Lstr(
                    resource='singleGamePlaylistNameText').evaluate().replace(
                        '${GAME}',
                        ba.Lstr(translate=('gameNames',
                                           'Death Match')).evaluate()),
                'playlist': [
                    {
                        'type': 'bs_death_match.DeathMatchGame',
                        'settings': {
                            'Epic Mode': False,
                            'Kills to Win Per Player': 10,
                            'Respawn Times': 1.0,
                            'Time Limit': 300,
                            'map': 'Doom Shroom'
                        }
                    },
                    {
                        'type': 'bs_death_match.DeathMatchGame',
                        'settings': {
                            'Epic Mode': False,
                            'Kills to Win Per Player': 10,
                            'Respawn Times': 1.0,
                            'Time Limit': 300,
                            'map': 'Crag Castle'
                        }
                    },
                ]
            })
            _ba.add_transaction({
                'type':
                'ADD_PLAYLIST',
                'playlistType':
                'Team Tournament',
                'playlistName':
                ba.Lstr(
                    resource='singleGamePlaylistNameText').evaluate().replace(
                        '${GAME}',
                        ba.Lstr(translate=('gameNames',
                                           'Capture the Flag')).evaluate()),
                'playlist': [
                    {
                        'type': 'bs_capture_the_flag.CTFGame',
                        'settings': {
                            'map': 'Bridgit',
                            'Score to Win': 3,
                            'Flag Idle Return Time': 30,
                            'Flag Touch Return Time': 0,
                            'Respawn Times': 1.0,
                            'Time Limit': 600,
                            'Epic Mode': False
                        }
                    },
                    {
                        'type': 'bs_capture_the_flag.CTFGame',
                        'settings': {
                            'map': 'Roundabout',
                            'Score to Win': 2,
                            'Flag Idle Return Time': 30,
                            'Flag Touch Return Time': 0,
                            'Respawn Times': 1.0,
                            'Time Limit': 600,
                            'Epic Mode': False
                        }
                    },
                    {
                        'type': 'bs_capture_the_flag.CTFGame',
                        'settings': {
                            'map': 'Tip Top',
                            'Score to Win': 2,
                            'Flag Idle Return Time': 30,
                            'Flag Touch Return Time': 3,
                            'Respawn Times': 1.0,
                            'Time Limit': 300,
                            'Epic Mode': False
                        }
                    },
                ]
            })
            _ba.add_transaction({
                'type':
                'ADD_PLAYLIST',
                'playlistType':
                'Team Tournament',
                'playlistName':
                ba.Lstr(translate=('playlistNames', 'Just Sports')).evaluate(),
                'playlist': [
                    {
                        'type': 'bs_hockey.HockeyGame',
                        'settings': {
                            'Time Limit': 0,
                            'map': 'Hockey Stadium',
                            'Score to Win': 1,
                            'Respawn Times': 1.0
                        }
                    },
                    {
                        'type': 'bs_football.FootballTeamGame',
                        'settings': {
                            'Time Limit': 0,
                            'map': 'Football Stadium',
                            'Score to Win': 21,
                            'Respawn Times': 1.0
                        }
                    },
                ]
            })
            _ba.add_transaction({
                'type':
                'ADD_PLAYLIST',
                'playlistType':
                'Free-for-All',
                'playlistName':
                ba.Lstr(translate=('playlistNames', 'Just Epic')).evaluate(),
                'playlist': [{
                    'type': 'bs_elimination.EliminationGame',
                    'settings': {
                        'Time Limit': 120,
                        'map': 'Tip Top',
                        'Respawn Times': 1.0,
                        'Lives Per Player': 1,
                        'Epic Mode': 1
                    }
                }]
            })
            _ba.add_transaction({
                'type': 'SET_MISC_VAL',
                'name': 'madeStandardPlaylists',
                'value': True
            })
            _ba.run_transactions()

        # Get the current selection (if any).
        self._selected_playlist = ba.app.config.get(self._pvars.config_name +
                                                    ' Playlist Selection')

        uiscale = ba.app.uiscale
        self._width = 900 if uiscale is ba.UIScale.SMALL else 800
        x_inset = 50 if uiscale is ba.UIScale.SMALL else 0
        self._height = (480 if uiscale is ba.UIScale.SMALL else
                        510 if uiscale is ba.UIScale.MEDIUM else 580)

        top_extra = 20 if uiscale is ba.UIScale.SMALL else 0

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + top_extra),
            transition=transition,
            toolbar_visibility='menu_full',
            scale_origin_stack_offset=scale_origin,
            scale=(1.69 if uiscale is ba.UIScale.SMALL else
                   1.05 if uiscale is ba.UIScale.MEDIUM else 0.9),
            stack_offset=(0, -26) if uiscale is ba.UIScale.SMALL else (0, 0)))

        self._back_button: Optional[ba.Widget] = ba.buttonwidget(
            parent=self._root_widget,
            position=(59 + x_inset, self._height - 70),
            size=(120, 60),
            scale=1.0,
            on_activate_call=self._on_back_press,
            autoselect=True,
            label=ba.Lstr(resource='backText'),
            button_type='back')
        ba.containerwidget(edit=self._root_widget,
                           cancel_button=self._back_button)
        txt = self._title_text = ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height - 41),
            size=(0, 0),
            text=self._pvars.window_title_name,
            scale=1.3,
            res_scale=1.5,
            color=ba.app.ui.heading_color,
            h_align='center',
            v_align='center')
        if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
            ba.textwidget(edit=txt, text='')

        ba.buttonwidget(edit=self._back_button,
                        button_type='backSmall',
                        size=(60, 54),
                        position=(59 + x_inset, self._height - 67),
                        label=ba.charstr(ba.SpecialChar.BACK))

        if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
            self._back_button.delete()
            self._back_button = None
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._on_back_press)
            scroll_offs = 33
        else:
            scroll_offs = 0
        self._scroll_width = self._width - (100 + 2 * x_inset)
        self._scroll_height = (self._height -
                               (146 if uiscale is ba.UIScale.SMALL
                                and ba.app.ui.use_toolbars else 136))
        self._scrollwidget = ba.scrollwidget(
            parent=self._root_widget,
            highlight=False,
            size=(self._scroll_width, self._scroll_height),
            position=((self._width - self._scroll_width) * 0.5,
                      65 + scroll_offs))
        ba.containerwidget(edit=self._scrollwidget, claims_left_right=True)
        self._subcontainer: Optional[ba.Widget] = None
        self._config_name_full = self._pvars.config_name + ' Playlists'
        self._last_config = None

        # Update now and once per second.
        # (this should do our initial refresh)
        self._update()
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)
Пример #16
0
            def _change_phrase(self) -> None:
                from bastd.actor.text import Text

                # If our news is way out of date, lets re-request it;
                # otherwise, rotate our phrase.
                assert ba.app.main_menu_last_news_fetch_time is not None
                if time.time() - ba.app.main_menu_last_news_fetch_time > 600.0:
                    self._fetch_news()
                    self._text = None
                else:
                    if self._text is not None:
                        if not self._phrases:
                            for phr in self._used_phrases:
                                self._phrases.insert(0, phr)
                        val = self._phrases.pop()
                        if val == '__ACH__':
                            vrmode = app.vr_mode
                            Text(ba.Lstr(resource='nextAchievementsText'),
                                 color=((1, 1, 1, 1) if vrmode else
                                        (0.95, 0.9, 1, 0.4)),
                                 host_only=True,
                                 maxwidth=200,
                                 position=(-300, -35),
                                 h_align=Text.HAlign.RIGHT,
                                 transition=Text.Transition.FADE_IN,
                                 scale=0.9 if vrmode else 0.7,
                                 flatness=1.0 if vrmode else 0.6,
                                 shadow=1.0 if vrmode else 0.5,
                                 h_attach=Text.HAttach.CENTER,
                                 v_attach=Text.VAttach.TOP,
                                 transition_delay=1.0,
                                 transition_out_delay=self._message_duration
                                 ).autoretain()
                            achs = [
                                a for a in app.ach.achievements
                                if not a.complete
                            ]
                            if achs:
                                ach = achs.pop(
                                    random.randrange(min(4, len(achs))))
                                ach.create_display(
                                    -180,
                                    -35,
                                    1.0,
                                    outdelay=self._message_duration,
                                    style='news')
                            if achs:
                                ach = achs.pop(
                                    random.randrange(min(8, len(achs))))
                                ach.create_display(
                                    180,
                                    -35,
                                    1.25,
                                    outdelay=self._message_duration,
                                    style='news')
                        else:
                            spc = self._message_spacing
                            keys = {
                                spc: 0.0,
                                spc + 1.0: 1.0,
                                spc + self._message_duration - 1.0: 1.0,
                                spc + self._message_duration: 0.0
                            }
                            assert self._text.node
                            ba.animate(self._text.node, 'opacity', keys)
                            # {k: v
                            #  for k, v in list(keys.items())})
                            self._text.node.text = val
Пример #17
0
    def __init__(self, parent_window: gpsui.GamepadSettingsWindow):
        # pylint: disable=too-many-statements
        self._parent_window = parent_window

        app = ba.app

        self._r = parent_window.get_r()
        uiscale = ba.app.uiscale
        self._width = 900 if uiscale is ba.UIScale.SMALL else 700
        self._x_inset = x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
        self._height = 402 if uiscale is ba.UIScale.SMALL else 512
        self._textwidgets: Dict[str, ba.Widget] = {}
        super().__init__(root_widget=ba.containerwidget(
            transition='in_scale',
            size=(self._width, self._height),
            scale=1.06 * (1.85 if uiscale is ba.UIScale.SMALL else
                          1.35 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -25) if uiscale is ba.UIScale.SMALL else (0, 0),
            scale_origin_stack_offset=(parent_window.get_advanced_button().
                                       get_screen_space_center())))

        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height -
                                (40 if uiscale is ba.UIScale.SMALL else 34)),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r + '.advancedTitleText'),
                      maxwidth=320,
                      color=ba.app.ui.title_color,
                      h_align='center',
                      v_align='center')

        back_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(self._width - (176 + x_inset), self._height -
                      (60 if uiscale is ba.UIScale.SMALL else 55)),
            size=(120, 48),
            text_scale=0.8,
            label=ba.Lstr(resource='doneText'),
            on_activate_call=self._done)
        ba.containerwidget(edit=self._root_widget,
                           start_button=btn,
                           on_cancel_call=btn.activate)

        self._scroll_width = self._width - (100 + 2 * x_inset)
        self._scroll_height = self._height - 110
        self._sub_width = self._scroll_width - 20
        self._sub_height = (940 if self._parent_window.get_is_secondary() else
                            1040)
        if app.vr_mode:
            self._sub_height += 50
        self._scrollwidget = ba.scrollwidget(
            parent=self._root_widget,
            position=((self._width - self._scroll_width) * 0.5,
                      self._height - 65 - self._scroll_height),
            size=(self._scroll_width, self._scroll_height))
        self._subcontainer = ba.containerwidget(parent=self._scrollwidget,
                                                size=(self._sub_width,
                                                      self._sub_height),
                                                background=False)
        ba.containerwidget(edit=self._scrollwidget,
                           claims_left_right=True,
                           claims_tab=True,
                           selection_loop_to_parent=True)
        ba.containerwidget(edit=self._subcontainer,
                           claims_left_right=True,
                           claims_tab=True,
                           selection_loop_to_parent=True)
        ba.containerwidget(edit=self._root_widget,
                           selected_child=self._scrollwidget)

        h = 30
        v = self._sub_height - 10

        h2 = h + 12

        # don't allow secondary joysticks to handle unassigned buttons
        if not self._parent_window.get_is_secondary():
            v -= 40
            cb1 = ba.checkboxwidget(
                parent=self._subcontainer,
                position=(h + 70, v),
                size=(500, 30),
                text=ba.Lstr(resource=self._r + '.unassignedButtonsRunText'),
                textcolor=(0.8, 0.8, 0.8),
                maxwidth=330,
                scale=1.0,
                on_value_change_call=self._parent_window.
                set_unassigned_buttons_run_value,
                autoselect=True,
                value=self._parent_window.get_unassigned_buttons_run_value())
            ba.widget(edit=cb1, up_widget=back_button)
        v -= 60
        capb = self._capture_button(
            pos=(h2, v),
            name=ba.Lstr(resource=self._r + '.runButton1Text'),
            control='buttonRun1' + self._parent_window.get_ext())
        if self._parent_window.get_is_secondary():
            for widget in capb:
                ba.widget(edit=widget, up_widget=back_button)
        v -= 42
        self._capture_button(
            pos=(h2, v),
            name=ba.Lstr(resource=self._r + '.runButton2Text'),
            control='buttonRun2' + self._parent_window.get_ext())
        ba.textwidget(parent=self._subcontainer,
                      position=(self._sub_width * 0.5, v - 24),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r +
                                   '.runTriggerDescriptionText'),
                      color=(0.7, 1, 0.7, 0.6),
                      maxwidth=self._sub_width * 0.8,
                      scale=0.7,
                      h_align='center',
                      v_align='center')

        v -= 85

        self._capture_button(
            pos=(h2, v),
            name=ba.Lstr(resource=self._r + '.runTrigger1Text'),
            control='triggerRun1' + self._parent_window.get_ext(),
            message=ba.Lstr(resource=self._r + '.pressAnyAnalogTriggerText'))
        v -= 42
        self._capture_button(
            pos=(h2, v),
            name=ba.Lstr(resource=self._r + '.runTrigger2Text'),
            control='triggerRun2' + self._parent_window.get_ext(),
            message=ba.Lstr(resource=self._r + '.pressAnyAnalogTriggerText'))

        # in vr mode, allow assigning a reset-view button
        if app.vr_mode:
            v -= 50
            self._capture_button(
                pos=(h2, v),
                name=ba.Lstr(resource=self._r + '.vrReorientButtonText'),
                control='buttonVRReorient' + self._parent_window.get_ext())

        v -= 60
        self._capture_button(
            pos=(h2, v),
            name=ba.Lstr(resource=self._r + '.extraStartButtonText'),
            control='buttonStart2' + self._parent_window.get_ext())
        v -= 60
        self._capture_button(
            pos=(h2, v),
            name=ba.Lstr(resource=self._r + '.ignoredButton1Text'),
            control='buttonIgnored' + self._parent_window.get_ext())
        v -= 42
        self._capture_button(
            pos=(h2, v),
            name=ba.Lstr(resource=self._r + '.ignoredButton2Text'),
            control='buttonIgnored2' + self._parent_window.get_ext())
        v -= 42
        self._capture_button(
            pos=(h2, v),
            name=ba.Lstr(resource=self._r + '.ignoredButton3Text'),
            control='buttonIgnored3' + self._parent_window.get_ext())
        v -= 42
        self._capture_button(
            pos=(h2, v),
            name=ba.Lstr(resource=self._r + '.ignoredButton4Text'),
            control='buttonIgnored4' + self._parent_window.get_ext())
        ba.textwidget(parent=self._subcontainer,
                      position=(self._sub_width * 0.5, v - 14),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r +
                                   '.ignoredButtonDescriptionText'),
                      color=(0.7, 1, 0.7, 0.6),
                      scale=0.8,
                      maxwidth=self._sub_width * 0.8,
                      h_align='center',
                      v_align='center')

        v -= 80
        ba.checkboxwidget(parent=self._subcontainer,
                          autoselect=True,
                          position=(h + 50, v),
                          size=(400, 30),
                          text=ba.Lstr(resource=self._r +
                                       '.startButtonActivatesDefaultText'),
                          textcolor=(0.8, 0.8, 0.8),
                          maxwidth=450,
                          scale=0.9,
                          on_value_change_call=self._parent_window.
                          set_start_button_activates_default_widget_value,
                          value=self._parent_window.
                          get_start_button_activates_default_widget_value())
        ba.textwidget(
            parent=self._subcontainer,
            position=(self._sub_width * 0.5, v - 12),
            size=(0, 0),
            text=ba.Lstr(resource=self._r +
                         '.startButtonActivatesDefaultDescriptionText'),
            color=(0.7, 1, 0.7, 0.6),
            maxwidth=self._sub_width * 0.8,
            scale=0.7,
            h_align='center',
            v_align='center')

        v -= 80
        ba.checkboxwidget(
            parent=self._subcontainer,
            autoselect=True,
            position=(h + 50, v),
            size=(400, 30),
            text=ba.Lstr(resource=self._r + '.uiOnlyText'),
            textcolor=(0.8, 0.8, 0.8),
            maxwidth=450,
            scale=0.9,
            on_value_change_call=self._parent_window.set_ui_only_value,
            value=self._parent_window.get_ui_only_value())
        ba.textwidget(parent=self._subcontainer,
                      position=(self._sub_width * 0.5, v - 12),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r +
                                   '.uiOnlyDescriptionText'),
                      color=(0.7, 1, 0.7, 0.6),
                      maxwidth=self._sub_width * 0.8,
                      scale=0.7,
                      h_align='center',
                      v_align='center')

        v -= 80
        ba.checkboxwidget(
            parent=self._subcontainer,
            autoselect=True,
            position=(h + 50, v),
            size=(400, 30),
            text=ba.Lstr(resource=self._r + '.ignoreCompletelyText'),
            textcolor=(0.8, 0.8, 0.8),
            maxwidth=450,
            scale=0.9,
            on_value_change_call=self._parent_window.
            set_ignore_completely_value,
            value=self._parent_window.get_ignore_completely_value())
        ba.textwidget(parent=self._subcontainer,
                      position=(self._sub_width * 0.5, v - 12),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r +
                                   '.ignoreCompletelyDescriptionText'),
                      color=(0.7, 1, 0.7, 0.6),
                      maxwidth=self._sub_width * 0.8,
                      scale=0.7,
                      h_align='center',
                      v_align='center')

        v -= 80

        cb1 = ba.checkboxwidget(
            parent=self._subcontainer,
            autoselect=True,
            position=(h + 50, v),
            size=(400, 30),
            text=ba.Lstr(resource=self._r + '.autoRecalibrateText'),
            textcolor=(0.8, 0.8, 0.8),
            maxwidth=450,
            scale=0.9,
            on_value_change_call=self._parent_window.
            set_auto_recalibrate_analog_stick_value,
            value=self._parent_window.get_auto_recalibrate_analog_stick_value(
            ))
        ba.textwidget(parent=self._subcontainer,
                      position=(self._sub_width * 0.5, v - 12),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r +
                                   '.autoRecalibrateDescriptionText'),
                      color=(0.7, 1, 0.7, 0.6),
                      maxwidth=self._sub_width * 0.8,
                      scale=0.7,
                      h_align='center',
                      v_align='center')
        v -= 80

        buttons = self._config_value_editor(
            ba.Lstr(resource=self._r + '.analogStickDeadZoneText'),
            control=('analogStickDeadZone' + self._parent_window.get_ext()),
            position=(h + 40, v),
            min_val=0,
            max_val=10.0,
            increment=0.1,
            x_offset=100)
        ba.widget(edit=buttons[0], left_widget=cb1, up_widget=cb1)
        ba.widget(edit=cb1, right_widget=buttons[0], down_widget=buttons[0])

        ba.textwidget(parent=self._subcontainer,
                      position=(self._sub_width * 0.5, v - 12),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r +
                                   '.analogStickDeadZoneDescriptionText'),
                      color=(0.7, 1, 0.7, 0.6),
                      maxwidth=self._sub_width * 0.8,
                      scale=0.7,
                      h_align='center',
                      v_align='center')
        v -= 100

        # child joysticks cant have child joysticks.. that's just
        # crazy talk
        if not self._parent_window.get_is_secondary():
            ba.buttonwidget(
                parent=self._subcontainer,
                autoselect=True,
                label=ba.Lstr(resource=self._r + '.twoInOneSetupText'),
                position=(40, v),
                size=(self._sub_width - 80, 50),
                on_activate_call=self._parent_window.show_secondary_editor,
                up_widget=buttons[0])

        # set a bigger bottom show-buffer for the widgets we just made
        # so we can see the text below them when navigating with
        # a gamepad
        for child in self._subcontainer.get_children():
            ba.widget(edit=child, show_buffer_bottom=30, show_buffer_top=30)
Пример #18
0
    def on_transition_in(self) -> None:
        super().on_transition_in()
        random.seed(123)
        self._logo_node: Optional[ba.Node] = None
        self._custom_logo_tex_name: Optional[str] = None
        self._word_actors: List[ba.Actor] = []
        app = ba.app

        # FIXME: We shouldn't be doing things conditionally based on whether
        #  the host is VR mode or not (clients may differ in that regard).
        #  Any differences need to happen at the engine level so everyone
        #  sees things in their own optimal way.
        vr_mode = ba.app.vr_mode

        if not ba.app.toolbar_test:
            color = ((1.0, 1.0, 1.0, 1.0) if vr_mode else (0.5, 0.6, 0.5, 0.6))

            # FIXME: Need a node attr for vr-specific-scale.
            scale = (0.9 if
                     (app.ui.uiscale is ba.UIScale.SMALL or vr_mode) else 0.7)
            self.my_name = ba.NodeActor(
                ba.newnode('text',
                           attrs={
                               'v_attach': 'bottom',
                               'h_align': 'center',
                               'color': color,
                               'flatness': 1.0,
                               'shadow': 1.0 if vr_mode else 0.5,
                               'scale': scale,
                               'position': (0, 10),
                               'vr_depth': -10,
                               'text': '\xa9 2011-2020 Eric Froemling'
                           }))

        # Throw up some text that only clients can see so they know that the
        # host is navigating menus while they're just staring at an
        # empty-ish screen.
        tval = ba.Lstr(resource='hostIsNavigatingMenusText',
                       subs=[('${HOST}', _ba.get_account_display_string())])
        self._host_is_navigating_text = ba.NodeActor(
            ba.newnode('text',
                       attrs={
                           'text': tval,
                           'client_only': True,
                           'position': (0, -200),
                           'flatness': 1.0,
                           'h_align': 'center'
                       }))
        if not ba.app.main_menu_did_initial_transition and hasattr(
                self, 'my_name'):
            assert self.my_name.node
            ba.animate(self.my_name.node, 'opacity', {2.3: 0, 3.0: 1.0})

        # FIXME: We shouldn't be doing things conditionally based on whether
        #  the host is vr mode or not (clients may not be or vice versa).
        #  Any differences need to happen at the engine level so everyone sees
        #  things in their own optimal way.
        vr_mode = app.vr_mode
        uiscale = app.ui.uiscale

        # In cases where we're doing lots of dev work lets always show the
        # build number.
        force_show_build_number = False

        if not ba.app.toolbar_test:
            if app.debug_build or app.test_build or force_show_build_number:
                if app.debug_build:
                    text = ba.Lstr(value='${V} (${B}) (${D})',
                                   subs=[
                                       ('${V}', app.version),
                                       ('${B}', str(app.build_number)),
                                       ('${D}', ba.Lstr(resource='debugText')),
                                   ])
                else:
                    text = ba.Lstr(value='${V} (${B})',
                                   subs=[
                                       ('${V}', app.version),
                                       ('${B}', str(app.build_number)),
                                   ])
            else:
                text = ba.Lstr(value='${V}', subs=[('${V}', app.version)])
            scale = 0.9 if (uiscale is ba.UIScale.SMALL or vr_mode) else 0.7
            color = (1, 1, 1, 1) if vr_mode else (0.5, 0.6, 0.5, 0.7)
            self.version = ba.NodeActor(
                ba.newnode('text',
                           attrs={
                               'v_attach': 'bottom',
                               'h_attach': 'right',
                               'h_align': 'right',
                               'flatness': 1.0,
                               'vr_depth': -10,
                               'shadow': 1.0 if vr_mode else 0.5,
                               'color': color,
                               'scale': scale,
                               'position': (-260, 10) if vr_mode else
                               (-10, 10),
                               'text': text
                           }))
            if not ba.app.main_menu_did_initial_transition:
                assert self.version.node
                ba.animate(self.version.node, 'opacity', {2.3: 0, 3.0: 1.0})

        # Show the iircade logo on our iircade build.
        if app.iircade_mode:
            img = ba.NodeActor(
                ba.newnode('image',
                           attrs={
                               'texture': ba.gettexture('iircadeLogo'),
                               'attach': 'center',
                               'scale': (250, 250),
                               'position': (0, 0),
                               'tilt_translate': 0.21,
                               'absolute_scale': True
                           })).autoretain()
            imgdelay = 0.0 if app.main_menu_did_initial_transition else 1.0
            ba.animate(img.node, 'opacity', {
                imgdelay + 1.5: 0.0,
                imgdelay + 2.5: 1.0
            })

        # Throw in test build info.
        self.beta_info = self.beta_info_2 = None
        if app.test_build and not (app.demo_mode or app.arcade_mode):
            pos = ((230, 125) if (app.demo_mode or app.arcade_mode) else
                   (230, 35))
            self.beta_info = ba.NodeActor(
                ba.newnode('text',
                           attrs={
                               'v_attach': 'center',
                               'h_align': 'center',
                               'color': (1, 1, 1, 1),
                               'shadow': 0.5,
                               'flatness': 0.5,
                               'scale': 1,
                               'vr_depth': -60,
                               'position': pos,
                               'text': ba.Lstr(resource='testBuildText')
                           }))
            if not ba.app.main_menu_did_initial_transition:
                assert self.beta_info.node
                ba.animate(self.beta_info.node, 'opacity', {1.3: 0, 1.8: 1.0})

        model = ba.getmodel('thePadLevel')
        trees_model = ba.getmodel('trees')
        bottom_model = ba.getmodel('thePadLevelBottom')
        color_texture = ba.gettexture('thePadLevelColor')
        trees_texture = ba.gettexture('treesColor')
        bgtex = ba.gettexture('menuBG')
        bgmodel = ba.getmodel('thePadBG')

        # Load these last since most platforms don't use them.
        vr_bottom_fill_model = ba.getmodel('thePadVRFillBottom')
        vr_top_fill_model = ba.getmodel('thePadVRFillTop')

        gnode = self.globalsnode
        gnode.camera_mode = 'rotate'

        tint = (1.14, 1.1, 1.0)
        gnode.tint = tint
        gnode.ambient_color = (1.06, 1.04, 1.03)
        gnode.vignette_outer = (0.45, 0.55, 0.54)
        gnode.vignette_inner = (0.99, 0.98, 0.98)

        self.bottom = ba.NodeActor(
            ba.newnode('terrain',
                       attrs={
                           'model': bottom_model,
                           'lighting': False,
                           'reflection': 'soft',
                           'reflection_scale': [0.45],
                           'color_texture': color_texture
                       }))
        self.vr_bottom_fill = ba.NodeActor(
            ba.newnode('terrain',
                       attrs={
                           'model': vr_bottom_fill_model,
                           'lighting': False,
                           'vr_only': True,
                           'color_texture': color_texture
                       }))
        self.vr_top_fill = ba.NodeActor(
            ba.newnode('terrain',
                       attrs={
                           'model': vr_top_fill_model,
                           'vr_only': True,
                           'lighting': False,
                           'color_texture': bgtex
                       }))
        self.terrain = ba.NodeActor(
            ba.newnode('terrain',
                       attrs={
                           'model': model,
                           'color_texture': color_texture,
                           'reflection': 'soft',
                           'reflection_scale': [0.3]
                       }))
        self.trees = ba.NodeActor(
            ba.newnode('terrain',
                       attrs={
                           'model': trees_model,
                           'lighting': False,
                           'reflection': 'char',
                           'reflection_scale': [0.1],
                           'color_texture': trees_texture
                       }))
        self.bgterrain = ba.NodeActor(
            ba.newnode('terrain',
                       attrs={
                           'model': bgmodel,
                           'color': (0.92, 0.91, 0.9),
                           'lighting': False,
                           'background': True,
                           'color_texture': bgtex
                       }))

        self._ts = 0.86

        self._language: Optional[str] = None
        self._update_timer = ba.Timer(1.0, self._update, repeat=True)
        self._update()

        # Hopefully this won't hitch but lets space these out anyway.
        _ba.add_clean_frame_callback(ba.WeakCall(self._start_preloads))

        random.seed()

        # On the main menu, also show our news.
        class News:
            """Wrangles news display."""
            def __init__(self, activity: ba.Activity):
                self._valid = True
                self._message_duration = 10.0
                self._message_spacing = 2.0
                self._text: Optional[ba.NodeActor] = None
                self._activity = weakref.ref(activity)

                # If we're signed in, fetch news immediately.
                # Otherwise wait until we are signed in.
                self._fetch_timer: Optional[ba.Timer] = ba.Timer(
                    1.0, ba.WeakCall(self._try_fetching_news), repeat=True)
                self._try_fetching_news()

            # We now want to wait until we're signed in before fetching news.
            def _try_fetching_news(self) -> None:
                if _ba.get_account_state() == 'signed_in':
                    self._fetch_news()
                    self._fetch_timer = None

            def _fetch_news(self) -> None:
                ba.app.main_menu_last_news_fetch_time = time.time()

                # UPDATE - We now just pull news from MRVs.
                news = _ba.get_account_misc_read_val('n', None)
                if news is not None:
                    self._got_news(news)

            def _change_phrase(self) -> None:
                from bastd.actor.text import Text

                # If our news is way out of date, lets re-request it;
                # otherwise, rotate our phrase.
                assert ba.app.main_menu_last_news_fetch_time is not None
                if time.time() - ba.app.main_menu_last_news_fetch_time > 600.0:
                    self._fetch_news()
                    self._text = None
                else:
                    if self._text is not None:
                        if not self._phrases:
                            for phr in self._used_phrases:
                                self._phrases.insert(0, phr)
                        val = self._phrases.pop()
                        if val == '__ACH__':
                            vrmode = app.vr_mode
                            Text(ba.Lstr(resource='nextAchievementsText'),
                                 color=((1, 1, 1, 1) if vrmode else
                                        (0.95, 0.9, 1, 0.4)),
                                 host_only=True,
                                 maxwidth=200,
                                 position=(-300, -35),
                                 h_align=Text.HAlign.RIGHT,
                                 transition=Text.Transition.FADE_IN,
                                 scale=0.9 if vrmode else 0.7,
                                 flatness=1.0 if vrmode else 0.6,
                                 shadow=1.0 if vrmode else 0.5,
                                 h_attach=Text.HAttach.CENTER,
                                 v_attach=Text.VAttach.TOP,
                                 transition_delay=1.0,
                                 transition_out_delay=self._message_duration
                                 ).autoretain()
                            achs = [
                                a for a in app.ach.achievements
                                if not a.complete
                            ]
                            if achs:
                                ach = achs.pop(
                                    random.randrange(min(4, len(achs))))
                                ach.create_display(
                                    -180,
                                    -35,
                                    1.0,
                                    outdelay=self._message_duration,
                                    style='news')
                            if achs:
                                ach = achs.pop(
                                    random.randrange(min(8, len(achs))))
                                ach.create_display(
                                    180,
                                    -35,
                                    1.25,
                                    outdelay=self._message_duration,
                                    style='news')
                        else:
                            spc = self._message_spacing
                            keys = {
                                spc: 0.0,
                                spc + 1.0: 1.0,
                                spc + self._message_duration - 1.0: 1.0,
                                spc + self._message_duration: 0.0
                            }
                            assert self._text.node
                            ba.animate(self._text.node, 'opacity', keys)
                            # {k: v
                            #  for k, v in list(keys.items())})
                            self._text.node.text = val

            def _got_news(self, news: str) -> None:
                # Run this stuff in the context of our activity since we
                # need to make nodes and stuff.. should fix the serverget
                # call so it.
                activity = self._activity()
                if activity is None or activity.expired:
                    return
                with ba.Context(activity):

                    self._phrases: List[str] = []

                    # Show upcoming achievements in non-vr versions
                    # (currently too hard to read in vr).
                    self._used_phrases = (
                        ['__ACH__'] if not ba.app.vr_mode else
                        []) + [s for s in news.split('<br>\n') if s != '']
                    self._phrase_change_timer = ba.Timer(
                        (self._message_duration + self._message_spacing),
                        ba.WeakCall(self._change_phrase),
                        repeat=True)

                    scl = 1.2 if (ba.app.ui.uiscale is ba.UIScale.SMALL
                                  or ba.app.vr_mode) else 0.8

                    color2 = ((1, 1, 1, 1) if ba.app.vr_mode else
                              (0.7, 0.65, 0.75, 1.0))
                    shadow = (1.0 if ba.app.vr_mode else 0.4)
                    self._text = ba.NodeActor(
                        ba.newnode('text',
                                   attrs={
                                       'v_attach': 'top',
                                       'h_attach': 'center',
                                       'h_align': 'center',
                                       'vr_depth': -20,
                                       'shadow': shadow,
                                       'flatness': 0.8,
                                       'v_align': 'top',
                                       'color': color2,
                                       'scale': scl,
                                       'maxwidth': 900.0 / scl,
                                       'position': (0, -10)
                                   }))
                    self._change_phrase()

        if not (app.demo_mode or app.arcade_mode) and not app.toolbar_test:
            self._news = News(self)

        # Bring up the last place we were, or start at the main menu otherwise.
        with ba.Context('ui'):
            from bastd.ui import specialoffer
            if bool(False):
                uicontroller = ba.app.ui.controller
                assert uicontroller is not None
                uicontroller.show_main_menu()
            else:
                main_menu_location = ba.app.ui.get_main_menu_location()

                # When coming back from a kiosk-mode game, jump to
                # the kiosk start screen.
                if ba.app.demo_mode or ba.app.arcade_mode:
                    # pylint: disable=cyclic-import
                    from bastd.ui.kiosk import KioskWindow
                    ba.app.ui.set_main_menu_window(
                        KioskWindow().get_root_widget())
                # ..or in normal cases go back to the main menu
                else:
                    if main_menu_location == 'Gather':
                        # pylint: disable=cyclic-import
                        from bastd.ui.gather import GatherWindow
                        ba.app.ui.set_main_menu_window(
                            GatherWindow(transition=None).get_root_widget())
                    elif main_menu_location == 'Watch':
                        # pylint: disable=cyclic-import
                        from bastd.ui.watch import WatchWindow
                        ba.app.ui.set_main_menu_window(
                            WatchWindow(transition=None).get_root_widget())
                    elif main_menu_location == 'Team Game Select':
                        # pylint: disable=cyclic-import
                        from bastd.ui.playlist.browser import (
                            PlaylistBrowserWindow)
                        ba.app.ui.set_main_menu_window(
                            PlaylistBrowserWindow(
                                sessiontype=ba.DualTeamSession,
                                transition=None).get_root_widget())
                    elif main_menu_location == 'Free-for-All Game Select':
                        # pylint: disable=cyclic-import
                        from bastd.ui.playlist.browser import (
                            PlaylistBrowserWindow)
                        ba.app.ui.set_main_menu_window(
                            PlaylistBrowserWindow(
                                sessiontype=ba.FreeForAllSession,
                                transition=None).get_root_widget())
                    elif main_menu_location == 'Coop Select':
                        # pylint: disable=cyclic-import
                        from bastd.ui.coop.browser import CoopBrowserWindow
                        ba.app.ui.set_main_menu_window(
                            CoopBrowserWindow(
                                transition=None).get_root_widget())
                    else:
                        # pylint: disable=cyclic-import
                        from bastd.ui.mainmenu import MainMenuWindow
                        ba.app.ui.set_main_menu_window(
                            MainMenuWindow(transition=None).get_root_widget())

                # attempt to show any pending offers immediately.
                # If that doesn't work, try again in a few seconds
                # (we may not have heard back from the server)
                # ..if that doesn't work they'll just have to wait
                # until the next opportunity.
                if not specialoffer.show_offer():

                    def try_again() -> None:
                        if not specialoffer.show_offer():
                            # Try one last time..
                            ba.timer(2.0,
                                     specialoffer.show_offer,
                                     timetype=ba.TimeType.REAL)

                    ba.timer(2.0, try_again, timetype=ba.TimeType.REAL)
        ba.app.main_menu_did_initial_transition = True
Пример #19
0
 def do_toggle(value: bool) -> None:
     ba.screenmessage(
         ba.Lstr(resource='settingsWindowAdvanced.mustRestartText'),
         color=(1, 1, 0))
     ba.playsound(ba.getsound('gunCocking'))
     _ba.set_low_level_config_value('enablexinput', not value)
Пример #20
0
    def __init__(self, data: Dict[str, Any]):
        from ba.internal import is_browser_likely_available
        ba.set_analytics_screen('Friend Promo Code')
        self._width = 650
        self._height = 400
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height),
            color=(0.45, 0.63, 0.15),
            transition='in_scale',
            scale=1.7 if ba.app.small_ui else 1.35 if ba.app.med_ui else 1.0))
        self._data = copy.deepcopy(data)
        ba.playsound(ba.getsound('cashRegister'))
        ba.playsound(ba.getsound('swish'))

        self._cancel_button = ba.buttonwidget(parent=self._root_widget,
                                              scale=0.7,
                                              position=(50, self._height - 50),
                                              size=(60, 60),
                                              label='',
                                              on_activate_call=self.close,
                                              autoselect=True,
                                              color=(0.45, 0.63, 0.15),
                                              icon=ba.gettexture('crossOut'),
                                              iconscale=1.2)
        ba.containerwidget(edit=self._root_widget,
                           cancel_button=self._cancel_button)

        ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height * 0.8),
            size=(0, 0),
            color=ba.app.infotextcolor,
            scale=1.0,
            flatness=1.0,
            h_align="center",
            v_align="center",
            text=ba.Lstr(resource='gatherWindow.shareThisCodeWithFriendsText'),
            maxwidth=self._width * 0.85)

        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height * 0.645),
                      size=(0, 0),
                      color=(1.0, 3.0, 1.0),
                      scale=2.0,
                      h_align="center",
                      v_align="center",
                      text=data['code'],
                      maxwidth=self._width * 0.85)

        award_str: Optional[Union[str, ba.Lstr]]
        if self._data['awardTickets'] != 0:
            award_str = ba.Lstr(
                resource='gatherWindow.friendPromoCodeAwardText',
                subs=[('${COUNT}', str(self._data['awardTickets']))])
        else:
            award_str = ''
        ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height * 0.37),
            size=(0, 0),
            color=ba.app.infotextcolor,
            scale=1.0,
            flatness=1.0,
            h_align="center",
            v_align="center",
            text=ba.Lstr(
                value='${A}\n${B}\n${C}\n${D}',
                subs=[
                    ('${A}',
                     ba.Lstr(
                         resource='gatherWindow.friendPromoCodeRedeemLongText',
                         subs=[('${COUNT}', str(self._data['tickets'])),
                               ('${MAX_USES}',
                                str(self._data['usesRemaining']))])),
                    ('${B}',
                     ba.Lstr(resource=(
                         'gatherWindow.friendPromoCodeWhereToEnterText'))),
                    ('${C}', award_str),
                    ('${D}',
                     ba.Lstr(resource='gatherWindow.friendPromoCodeExpireText',
                             subs=[('${EXPIRE_HOURS}',
                                    str(self._data['expireHours']))]))
                ]),
            maxwidth=self._width * 0.9,
            max_height=self._height * 0.35)

        if is_browser_likely_available():
            xoffs = 0
            ba.buttonwidget(parent=self._root_widget,
                            size=(200, 40),
                            position=(self._width * 0.5 - 100 + xoffs, 39),
                            autoselect=True,
                            label=ba.Lstr(resource='gatherWindow.emailItText'),
                            on_activate_call=ba.WeakCall(self._email))
Пример #21
0
    def __init__(self,
                 player: ba.Player,
                 position: Tuple[float, float],
                 scale: float,
                 show_lives: bool = True,
                 show_death: bool = True,
                 name_scale: float = 1.0,
                 name_maxwidth: float = 115.0,
                 flatness: float = 1.0,
                 shadow: float = 1.0):
        super().__init__()

        self._player = player
        self._show_lives = show_lives
        self._show_death = show_death
        self._name_scale = name_scale
        self._outline_tex = ba.gettexture('characterIconMask')

        icon = player.get_icon()
        self.node = ba.newnode('image',
                               delegate=self,
                               attrs={
                                   'texture': icon['texture'],
                                   'tint_texture': icon['tint_texture'],
                                   'tint_color': icon['tint_color'],
                                   'vr_depth': 400,
                                   'tint2_color': icon['tint2_color'],
                                   'mask_texture': self._outline_tex,
                                   'opacity': 1.0,
                                   'absolute_scale': True,
                                   'attach': 'bottomCenter'
                               })
        self._name_text = ba.newnode(
            'text',
            owner=self.node,
            attrs={
                'text': ba.Lstr(value=player.get_name()),
                'color': ba.safecolor(player.team.color),
                'h_align': 'center',
                'v_align': 'center',
                'vr_depth': 410,
                'maxwidth': name_maxwidth,
                'shadow': shadow,
                'flatness': flatness,
                'h_attach': 'center',
                'v_attach': 'bottom'
            })
        if self._show_lives:
            self._lives_text = ba.newnode('text',
                                          owner=self.node,
                                          attrs={
                                              'text': 'x0',
                                              'color': (1, 1, 0.5),
                                              'h_align': 'left',
                                              'vr_depth': 430,
                                              'shadow': 1.0,
                                              'flatness': 1.0,
                                              'h_attach': 'center',
                                              'v_attach': 'bottom'
                                          })
        self.set_position_and_scale(position, scale)
Пример #22
0
    def __init__(self) -> None:
        ba.set_analytics_screen('AppInviteWindow')
        self._data: Optional[Dict[str, Any]] = None
        self._width = 650
        self._height = 400

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height),
            transition='in_scale',
            scale=1.8 if ba.app.small_ui else 1.35 if ba.app.med_ui else 1.0))

        self._cancel_button = ba.buttonwidget(parent=self._root_widget,
                                              scale=0.8,
                                              position=(60, self._height - 50),
                                              size=(50, 50),
                                              label='',
                                              on_activate_call=self.close,
                                              autoselect=True,
                                              color=(0.4, 0.4, 0.6),
                                              icon=ba.gettexture('crossOut'),
                                              iconscale=1.2)

        ba.containerwidget(edit=self._root_widget,
                           cancel_button=self._cancel_button)

        ba.textwidget(
            parent=self._root_widget,
            size=(0, 0),
            position=(self._width * 0.5, self._height * 0.5 + 110),
            autoselect=True,
            scale=0.8,
            maxwidth=self._width * 0.9,
            h_align='center',
            v_align='center',
            color=(0.3, 0.8, 0.3),
            flatness=1.0,
            text=ba.Lstr(
                resource='gatherWindow.earnTicketsForRecommendingAmountText',
                fallback_resource=(
                    'gatherWindow.earnTicketsForRecommendingText'),
                subs=[
                    ('${COUNT}',
                     str(_ba.get_account_misc_read_val('friendTryTickets',
                                                       300))),
                    ('${YOU_COUNT}',
                     str(
                         _ba.get_account_misc_read_val('friendTryAwardTickets',
                                                       100)))
                ]))

        or_text = ba.Lstr(resource='orText',
                          subs=[('${A}', ''),
                                ('${B}', '')]).evaluate().strip()
        ba.buttonwidget(
            parent=self._root_widget,
            size=(250, 150),
            position=(self._width * 0.5 - 125, self._height * 0.5 - 80),
            autoselect=True,
            button_type='square',
            label=ba.Lstr(resource='gatherWindow.inviteFriendsText'),
            on_activate_call=ba.WeakCall(self._google_invites))

        ba.textwidget(parent=self._root_widget,
                      size=(0, 0),
                      position=(self._width * 0.5, self._height * 0.5 - 94),
                      autoselect=True,
                      scale=0.9,
                      h_align='center',
                      v_align='center',
                      color=(0.5, 0.5, 0.5),
                      flatness=1.0,
                      text=or_text)

        ba.buttonwidget(
            parent=self._root_widget,
            size=(180, 50),
            position=(self._width * 0.5 - 90, self._height * 0.5 - 170),
            autoselect=True,
            color=(0.5, 0.5, 0.6),
            textcolor=(0.7, 0.7, 0.8),
            text_scale=0.8,
            label=ba.Lstr(resource='gatherWindow.appInviteSendACodeText'),
            on_activate_call=ba.WeakCall(self._send_code))

        # kick off a transaction to get our code
        _ba.add_transaction(
            {
                'type': 'FRIEND_PROMO_CODE_REQUEST',
                'ali': False,
                'expire_time': time.time() + 20
            },
            callback=ba.WeakCall(self._on_code_result))
        _ba.run_transactions()
Пример #23
0
    def _update_for_league_rank_data(self, data: Optional[Dict[str,
                                                               Any]]) -> None:
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-statements
        from ba.internal import get_league_rank_points

        # If our button has died, ignore.
        if not self._button:
            return

        status_text: Union[str, ba.Lstr]

        in_top = data is not None and data['rank'] is not None
        do_percent = False
        if data is None or _ba.get_account_state() != 'signed_in':
            self._percent = self._rank = None
            status_text = '-'
        elif in_top:
            self._percent = None
            self._rank = data['rank']
            prev_league = self._league
            self._league = data['l']

            # If this is the first set, league has changed, or rank has gotten
            # worse, snap the smooth value immediately.
            assert self._rank is not None
            if (self._smooth_rank is None or prev_league != self._league
                    or self._rank > int(self._smooth_rank)):
                self._smooth_rank = float(self._rank)
            status_text = ba.Lstr(resource='numberText',
                                  subs=[('${NUMBER}',
                                         str(int(self._smooth_rank)))])
        else:
            try:
                if not data['scores'] or data['scores'][-1][1] <= 0:
                    self._percent = self._rank = None
                    status_text = '-'
                else:
                    our_points = get_league_rank_points(data)
                    progress = float(our_points) / data['scores'][-1][1]
                    self._percent = int(progress * 100.0)
                    self._rank = None
                    do_percent = True
                    prev_league = self._league
                    self._league = data['l']

                    # If this is the first set, league has changed, or percent
                    # has decreased, snap the smooth value immediately.
                    if (self._smooth_percent is None
                            or prev_league != self._league
                            or self._percent < int(self._smooth_percent)):
                        self._smooth_percent = float(self._percent)
                    status_text = str(int(self._smooth_percent)) + '%'

            except Exception:
                ba.print_exception('Error updating power ranking.')
                self._percent = self._rank = None
                status_text = '-'

        # If we're doing a smooth update, set a timer.
        if (self._rank is not None and self._smooth_rank is not None
                and int(self._smooth_rank) != self._rank):
            self._improvement_text = str(-(int(self._rank) -
                                           int(self._smooth_rank)))
            diff = abs(self._rank - self._smooth_rank)
            if diff > 100:
                self._smooth_increase_speed = diff / 80.0
            elif diff > 50:
                self._smooth_increase_speed = diff / 70.0
            elif diff > 25:
                self._smooth_increase_speed = diff / 55.0
            else:
                self._smooth_increase_speed = diff / 40.0
            self._smooth_increase_speed = max(0.4, self._smooth_increase_speed)
            ba.timer(self._smooth_update_delay,
                     ba.WeakCall(self._start_smooth_update),
                     timetype=ba.TimeType.REAL,
                     timeformat=ba.TimeFormat.MILLISECONDS)

        if (self._percent is not None and self._smooth_percent is not None
                and int(self._smooth_percent) != self._percent):
            self._improvement_text = str(
                (int(self._percent) - int(self._smooth_percent)))
            self._smooth_increase_speed = 0.3
            ba.timer(self._smooth_update_delay,
                     ba.WeakCall(self._start_smooth_update),
                     timetype=ba.TimeType.REAL,
                     timeformat=ba.TimeFormat.MILLISECONDS)

        if do_percent:
            ba.textwidget(
                edit=self._title_text,
                text=ba.Lstr(resource='coopSelectWindow.toRankedText'))
        else:
            try:
                assert data is not None
                txt = ba.Lstr(
                    resource='league.leagueFullText',
                    subs=[
                        (
                            '${NAME}',
                            ba.Lstr(translate=('leagueNames', data['l']['n'])),
                        ),
                    ],
                )
                t_color = data['l']['c']
            except Exception:
                txt = ba.Lstr(
                    resource='league.leagueRankText',
                    fallback_resource='coopSelectWindow.powerRankingText')
                t_color = ba.app.title_color
            ba.textwidget(edit=self._title_text, text=txt, color=t_color)
        ba.textwidget(edit=self._value_text, text=status_text)
    def __init__(self,
                 tournament_id: str,
                 tournament_activity: ba.Activity = None,
                 position: Tuple[float, float] = (0.0, 0.0),
                 delegate: Any = None,
                 scale: float = None,
                 offset: Tuple[float, float] = (0.0, 0.0),
                 on_close_call: Callable[[], Any] = None):
        # Needs some tidying.
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements

        ba.set_analytics_screen('Tournament Entry Window')

        self._tournament_id = tournament_id
        self._tournament_info = (ba.app.tournament_info[self._tournament_id])

        # Set a few vars depending on the tourney fee.
        self._fee = self._tournament_info['fee']
        self._allow_ads = self._tournament_info['allowAds']
        if self._fee == 4:
            self._purchase_name = 'tournament_entry_4'
            self._purchase_price_name = 'price.tournament_entry_4'
        elif self._fee == 3:
            self._purchase_name = 'tournament_entry_3'
            self._purchase_price_name = 'price.tournament_entry_3'
        elif self._fee == 2:
            self._purchase_name = 'tournament_entry_2'
            self._purchase_price_name = 'price.tournament_entry_2'
        elif self._fee == 1:
            self._purchase_name = 'tournament_entry_1'
            self._purchase_price_name = 'price.tournament_entry_1'
        else:
            if self._fee != 0:
                raise ValueError('invalid fee: ' + str(self._fee))
            self._purchase_name = 'tournament_entry_0'
            self._purchase_price_name = 'price.tournament_entry_0'

        self._purchase_price: Optional[int] = None

        self._on_close_call = on_close_call
        if scale is None:
            uiscale = ba.app.ui.uiscale
            scale = (2.3 if uiscale is ba.UIScale.SMALL else
                     1.65 if uiscale is ba.UIScale.MEDIUM else 1.23)
        self._delegate = delegate
        self._transitioning_out = False

        self._tournament_activity = tournament_activity

        self._width = 340
        self._height = 220

        bg_color = (0.5, 0.4, 0.6)

        # Creates our root_widget.
        popup.PopupWindow.__init__(self,
                                   position=position,
                                   size=(self._width, self._height),
                                   scale=scale,
                                   bg_color=bg_color,
                                   offset=offset,
                                   toolbar_visibility='menu_currency')

        self._last_ad_press_time = -9999.0
        self._last_ticket_press_time = -9999.0
        self._entering = False
        self._launched = False

        # Show the ad button only if we support ads *and* it has a level 1 fee.
        self._do_ad_btn = (_ba.has_video_ads() and self._allow_ads)

        x_offs = 0 if self._do_ad_btn else 85

        self._cancel_button = ba.buttonwidget(parent=self.root_widget,
                                              position=(20, self._height - 30),
                                              size=(50, 50),
                                              scale=0.5,
                                              label='',
                                              color=bg_color,
                                              on_activate_call=self._on_cancel,
                                              autoselect=True,
                                              icon=ba.gettexture('crossOut'),
                                              iconscale=1.2)

        self._title_text = ba.textwidget(
            parent=self.root_widget,
            position=(self._width * 0.5, self._height - 20),
            size=(0, 0),
            h_align='center',
            v_align='center',
            scale=0.6,
            text=ba.Lstr(resource='tournamentEntryText'),
            maxwidth=200,
            color=(1, 1, 1, 0.4))

        btn = self._pay_with_tickets_button = ba.buttonwidget(
            parent=self.root_widget,
            position=(30 + x_offs, 60),
            autoselect=True,
            button_type='square',
            size=(120, 120),
            label='',
            on_activate_call=self._on_pay_with_tickets_press)
        self._ticket_img_pos = (50 + x_offs, 94)
        self._ticket_img_pos_free = (50 + x_offs, 80)
        self._ticket_img = ba.imagewidget(parent=self.root_widget,
                                          draw_controller=btn,
                                          size=(80, 80),
                                          position=self._ticket_img_pos,
                                          texture=ba.gettexture('tickets'))
        self._ticket_cost_text_position = (87 + x_offs, 88)
        self._ticket_cost_text_position_free = (87 + x_offs, 120)
        self._ticket_cost_text = ba.textwidget(
            parent=self.root_widget,
            draw_controller=btn,
            position=self._ticket_cost_text_position,
            size=(0, 0),
            h_align='center',
            v_align='center',
            scale=0.6,
            text='',
            maxwidth=95,
            color=(0, 1, 0))
        self._free_plays_remaining_text = ba.textwidget(
            parent=self.root_widget,
            draw_controller=btn,
            position=(87 + x_offs, 78),
            size=(0, 0),
            h_align='center',
            v_align='center',
            scale=0.33,
            text='',
            maxwidth=95,
            color=(0, 0.8, 0))
        self._pay_with_ad_btn: Optional[ba.Widget]
        if self._do_ad_btn:
            btn = self._pay_with_ad_btn = ba.buttonwidget(
                parent=self.root_widget,
                position=(190, 60),
                autoselect=True,
                button_type='square',
                size=(120, 120),
                label='',
                on_activate_call=self._on_pay_with_ad_press)
            self._pay_with_ad_img = ba.imagewidget(parent=self.root_widget,
                                                   draw_controller=btn,
                                                   size=(80, 80),
                                                   position=(210, 94),
                                                   texture=ba.gettexture('tv'))

            self._ad_text_position = (251, 88)
            self._ad_text_position_remaining = (251, 92)
            have_ad_tries_remaining = (
                self._tournament_info['adTriesRemaining'] is not None)
            self._ad_text = ba.textwidget(
                parent=self.root_widget,
                draw_controller=btn,
                position=self._ad_text_position_remaining
                if have_ad_tries_remaining else self._ad_text_position,
                size=(0, 0),
                h_align='center',
                v_align='center',
                scale=0.6,
                text=ba.Lstr(resource='watchAVideoText',
                             fallback_resource='watchAnAdText'),
                maxwidth=95,
                color=(0, 1, 0))
            ad_plays_remaining_text = (
                '' if not have_ad_tries_remaining else '' +
                str(self._tournament_info['adTriesRemaining']))
            self._ad_plays_remaining_text = ba.textwidget(
                parent=self.root_widget,
                draw_controller=btn,
                position=(251, 78),
                size=(0, 0),
                h_align='center',
                v_align='center',
                scale=0.33,
                text=ad_plays_remaining_text,
                maxwidth=95,
                color=(0, 0.8, 0))

            ba.textwidget(parent=self.root_widget,
                          position=(self._width * 0.5, 120),
                          size=(0, 0),
                          h_align='center',
                          v_align='center',
                          scale=0.6,
                          text=ba.Lstr(resource='orText',
                                       subs=[('${A}', ''), ('${B}', '')]),
                          maxwidth=35,
                          color=(1, 1, 1, 0.5))
        else:
            self._pay_with_ad_btn = None

        self._get_tickets_button: Optional[ba.Widget]
        if not ba.app.ui.use_toolbars:
            self._get_tickets_button = ba.buttonwidget(
                parent=self.root_widget,
                position=(self._width - 190 + 110, 15),
                autoselect=True,
                scale=0.6,
                size=(120, 60),
                textcolor=(0.2, 1, 0.2),
                label=ba.charstr(ba.SpecialChar.TICKET),
                color=(0.6, 0.4, 0.7),
                on_activate_call=self._on_get_tickets_press)
        else:
            self._get_tickets_button = None

        self._seconds_remaining = None

        ba.containerwidget(edit=self.root_widget,
                           cancel_button=self._cancel_button)

        # Let's also ask the server for info about this tournament
        # (time remaining, etc) so we can show the user time remaining,
        # disallow entry if time has run out, etc.
        xoffs = 104 if ba.app.ui.use_toolbars else 0
        self._time_remaining_text = ba.textwidget(parent=self.root_widget,
                                                  position=(70 + xoffs, 23),
                                                  size=(0, 0),
                                                  h_align='center',
                                                  v_align='center',
                                                  text='-',
                                                  scale=0.65,
                                                  maxwidth=100,
                                                  flatness=1.0,
                                                  color=(0.7, 0.7, 0.7))
        self._time_remaining_label_text = ba.textwidget(
            parent=self.root_widget,
            position=(70 + xoffs, 40),
            size=(0, 0),
            h_align='center',
            v_align='center',
            text=ba.Lstr(resource='coopSelectWindow.timeRemainingText'),
            scale=0.45,
            flatness=1.0,
            maxwidth=100,
            color=(0.7, 0.7, 0.7))

        self._last_query_time: Optional[float] = None

        # If there seems to be a relatively-recent valid cached info for this
        # tournament, use it. Otherwise we'll kick off a query ourselves.
        if (self._tournament_id in ba.app.tournament_info
                and ba.app.tournament_info[self._tournament_id]['valid'] and
            (ba.time(ba.TimeType.REAL, ba.TimeFormat.MILLISECONDS) -
             ba.app.tournament_info[self._tournament_id]['timeReceived'] <
             1000 * 60 * 5)):
            try:
                info = ba.app.tournament_info[self._tournament_id]
                self._seconds_remaining = max(
                    0, info['timeRemaining'] - int(
                        (ba.time(ba.TimeType.REAL, ba.TimeFormat.MILLISECONDS)
                         - info['timeReceived']) / 1000))
                self._have_valid_data = True
                self._last_query_time = ba.time(ba.TimeType.REAL)
            except Exception:
                ba.print_exception('error using valid tourney data')
                self._have_valid_data = False
        else:
            self._have_valid_data = False

        self._fg_state = ba.app.fg_state
        self._running_query = False
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      repeat=True,
                                      timetype=ba.TimeType.REAL)
        self._update()
        self._restore_state()
Пример #25
0
    def _build_join_by_address_tab(self, region_width: float,
                                   region_height: float) -> None:
        c_width = region_width
        c_height = region_height - 20
        last_addr = ba.app.config.get('Last Manual Party Connect Address', '')
        v = c_height - 70
        v -= 70
        ba.textwidget(parent=self._container,
                      position=(c_width * 0.5 - 260 - 50, v),
                      color=(0.6, 1.0, 0.6),
                      scale=1.0,
                      size=(0, 0),
                      maxwidth=130,
                      h_align='right',
                      v_align='center',
                      text=ba.Lstr(resource='gatherWindow.'
                                   'manualAddressText'))
        txt = ba.textwidget(parent=self._container,
                            editable=True,
                            description=ba.Lstr(resource='gatherWindow.'
                                                'manualAddressText'),
                            position=(c_width * 0.5 - 240 - 50, v - 30),
                            text=last_addr,
                            autoselect=True,
                            v_align='center',
                            scale=1.0,
                            size=(420, 60))
        ba.widget(edit=self._join_by_address_text, down_widget=txt)
        ba.widget(edit=self._favorites_text, down_widget=txt)
        ba.textwidget(parent=self._container,
                      position=(c_width * 0.5 - 260 + 490, v),
                      color=(0.6, 1.0, 0.6),
                      scale=1.0,
                      size=(0, 0),
                      maxwidth=80,
                      h_align='right',
                      v_align='center',
                      text=ba.Lstr(resource='gatherWindow.'
                                   'portText'))
        txt2 = ba.textwidget(parent=self._container,
                             editable=True,
                             description=ba.Lstr(resource='gatherWindow.'
                                                 'portText'),
                             text='43210',
                             autoselect=True,
                             max_chars=5,
                             position=(c_width * 0.5 - 240 + 490, v - 30),
                             v_align='center',
                             scale=1.0,
                             size=(170, 60))

        v -= 110

        btn = ba.buttonwidget(parent=self._container,
                              size=(300, 70),
                              label=ba.Lstr(resource='gatherWindow.'
                                            'manualConnectText'),
                              position=(c_width * 0.5 - 300, v),
                              autoselect=True,
                              on_activate_call=ba.Call(self._connect, txt,
                                                       txt2))
        savebutton = ba.buttonwidget(
            parent=self._container,
            size=(300, 70),
            label=ba.Lstr(resource='gatherWindow.favoritesSaveText'),
            position=(c_width * 0.5 - 240 + 490 - 200, v),
            autoselect=True,
            on_activate_call=ba.Call(self._save_server, txt, txt2))
        ba.widget(edit=btn, right_widget=savebutton)
        ba.widget(edit=savebutton, left_widget=btn, up_widget=txt2)
        ba.textwidget(edit=txt, on_return_press_call=btn.activate)
        ba.textwidget(edit=txt2, on_return_press_call=btn.activate)
        v -= 45

        self._check_button = ba.textwidget(
            parent=self._container,
            size=(250, 60),
            text=ba.Lstr(resource='gatherWindow.'
                         'showMyAddressText'),
            v_align='center',
            h_align='center',
            click_activate=True,
            position=(c_width * 0.5 - 125, v - 30),
            autoselect=True,
            color=(0.5, 0.9, 0.5),
            scale=0.8,
            selectable=True,
            on_activate_call=ba.Call(self._on_show_my_address_button_press, v,
                                     self._container, c_width))
        ba.widget(edit=self._check_button, up_widget=btn)
    def _update(self) -> None:
        # We may outlive our widgets.
        if not self.root_widget:
            return

        # If we've been foregrounded/backgrounded we need to re-grab data.
        if self._fg_state != ba.app.fg_state:
            self._fg_state = ba.app.fg_state
            self._have_valid_data = False

        # If we need to run another tournament query, do so.
        if not self._running_query and (
            (self._last_query_time is None) or (not self._have_valid_data) or
            (ba.time(ba.TimeType.REAL) - self._last_query_time > 30.0)):
            _ba.tournament_query(args={
                'source':
                'entry window'
                if self._tournament_activity is None else 'retry entry window'
            },
                                 callback=ba.WeakCall(
                                     self._on_tournament_query_response))
            self._last_query_time = ba.time(ba.TimeType.REAL)
            self._running_query = True

        # Grab the latest info on our tourney.
        self._tournament_info = ba.app.tournament_info[self._tournament_id]

        # If we don't have valid data always show a '-' for time.
        if not self._have_valid_data:
            ba.textwidget(edit=self._time_remaining_text, text='-')
        else:
            if self._seconds_remaining is not None:
                self._seconds_remaining = max(0, self._seconds_remaining - 1)
                ba.textwidget(edit=self._time_remaining_text,
                              text=ba.timestring(
                                  self._seconds_remaining * 1000,
                                  centi=False,
                                  timeformat=ba.TimeFormat.MILLISECONDS))

        # Keep price up-to-date and update the button with it.
        self._purchase_price = _ba.get_account_misc_read_val(
            self._purchase_price_name, None)

        ba.textwidget(
            edit=self._ticket_cost_text,
            text=(ba.Lstr(resource='getTicketsWindow.freeText')
                  if self._purchase_price == 0 else ba.Lstr(
                      resource='getTicketsWindow.ticketsText',
                      subs=[('${COUNT}', str(self._purchase_price)
                             if self._purchase_price is not None else '?')])),
            position=self._ticket_cost_text_position_free
            if self._purchase_price == 0 else self._ticket_cost_text_position,
            scale=1.0 if self._purchase_price == 0 else 0.6)

        ba.textwidget(
            edit=self._free_plays_remaining_text,
            text='' if
            (self._tournament_info['freeTriesRemaining'] in [None, 0]
             or self._purchase_price != 0) else '' +
            str(self._tournament_info['freeTriesRemaining']))

        ba.imagewidget(edit=self._ticket_img,
                       opacity=0.2 if self._purchase_price == 0 else 1.0,
                       position=self._ticket_img_pos_free
                       if self._purchase_price == 0 else self._ticket_img_pos)

        if self._do_ad_btn:
            enabled = _ba.have_incentivized_ad()
            have_ad_tries_remaining = (
                self._tournament_info['adTriesRemaining'] is not None
                and self._tournament_info['adTriesRemaining'] > 0)
            ba.textwidget(edit=self._ad_text,
                          position=self._ad_text_position_remaining if
                          have_ad_tries_remaining else self._ad_text_position,
                          color=(0, 1, 0) if enabled else (0.5, 0.5, 0.5))
            ba.imagewidget(edit=self._pay_with_ad_img,
                           opacity=1.0 if enabled else 0.2)
            ba.buttonwidget(edit=self._pay_with_ad_btn,
                            color=(0.5, 0.7, 0.2) if enabled else
                            (0.5, 0.5, 0.5))
            ad_plays_remaining_text = (
                '' if not have_ad_tries_remaining else '' +
                str(self._tournament_info['adTriesRemaining']))
            ba.textwidget(edit=self._ad_plays_remaining_text,
                          text=ad_plays_remaining_text,
                          color=(0, 0.8, 0) if enabled else (0.4, 0.4, 0.4))

        try:
            t_str = str(_ba.get_account_ticket_count())
        except Exception:
            t_str = '?'
        if self._get_tickets_button is not None:
            ba.buttonwidget(edit=self._get_tickets_button,
                            label=ba.charstr(ba.SpecialChar.TICKET) + t_str)
Пример #27
0
 def _no_favorite_selected_error(self) -> None:
     ba.screenmessage(ba.Lstr(resource='nothingIsSelectedErrorText'),
                      color=(1, 0, 0))
     ba.playsound(ba.getsound('error'))
Пример #28
0
    def _refresh(self) -> None:
        # FIXME: Should tidy this up.
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-nested-blocks
        from ba.internal import (get_map_class,
                                 get_default_free_for_all_playlist,
                                 get_default_teams_playlist, filter_playlist)
        if not self._root_widget:
            return
        if self._subcontainer is not None:
            self._save_state()
            self._subcontainer.delete()

        # Make sure config exists.
        if self._config_name_full not in ba.app.config:
            ba.app.config[self._config_name_full] = {}

        items = list(ba.app.config[self._config_name_full].items())

        # Make sure everything is unicode.
        items = [(i[0].decode(), i[1]) if not isinstance(i[0], str) else i
                 for i in items]

        items.sort(key=lambda x2: x2[0].lower())
        items = [['__default__', None]] + items  # default is always first

        count = len(items)
        columns = 3
        rows = int(math.ceil(float(count) / columns))
        button_width = 230
        button_height = 230
        button_buffer_h = -3
        button_buffer_v = 0

        self._sub_width = self._scroll_width
        self._sub_height = 40 + rows * (button_height +
                                        2 * button_buffer_v) + 90
        assert self._sub_width is not None
        assert self._sub_height is not None
        self._subcontainer = ba.containerwidget(parent=self._scrollwidget,
                                                size=(self._sub_width,
                                                      self._sub_height),
                                                background=False)

        children = self._subcontainer.get_children()
        for child in children:
            child.delete()

        ba.textwidget(parent=self._subcontainer,
                      text=ba.Lstr(resource='playlistsText'),
                      position=(40, self._sub_height - 26),
                      size=(0, 0),
                      scale=1.0,
                      maxwidth=400,
                      color=ba.app.ui.title_color,
                      h_align='left',
                      v_align='center')

        index = 0
        appconfig = ba.app.config

        model_opaque = ba.getmodel('level_select_button_opaque')
        model_transparent = ba.getmodel('level_select_button_transparent')
        mask_tex = ba.gettexture('mapPreviewMask')

        h_offs = 225 if count == 1 else 115 if count == 2 else 0
        h_offs_bottom = 0

        uiscale = ba.app.uiscale
        for y in range(rows):
            for x in range(columns):
                name = items[index][0]
                assert name is not None
                pos = (x * (button_width + 2 * button_buffer_h) +
                       button_buffer_h + 8 + h_offs, self._sub_height - 47 -
                       (y + 1) * (button_height + 2 * button_buffer_v))
                btn = ba.buttonwidget(parent=self._subcontainer,
                                      button_type='square',
                                      size=(button_width, button_height),
                                      autoselect=True,
                                      label='',
                                      position=pos)

                if (x == 0 and ba.app.ui.use_toolbars
                        and uiscale is ba.UIScale.SMALL):
                    ba.widget(
                        edit=btn,
                        left_widget=_ba.get_special_widget('back_button'))
                if (x == columns - 1 and ba.app.ui.use_toolbars
                        and uiscale is ba.UIScale.SMALL):
                    ba.widget(
                        edit=btn,
                        right_widget=_ba.get_special_widget('party_button'))
                ba.buttonwidget(
                    edit=btn,
                    on_activate_call=ba.Call(self._on_playlist_press, btn,
                                             name),
                    on_select_call=ba.Call(self._on_playlist_select, name))
                ba.widget(edit=btn, show_buffer_top=50, show_buffer_bottom=50)

                if self._selected_playlist == name:
                    ba.containerwidget(edit=self._subcontainer,
                                       selected_child=btn,
                                       visible_child=btn)

                if self._back_button is not None:
                    if y == 0:
                        ba.widget(edit=btn, up_widget=self._back_button)
                    if x == 0:
                        ba.widget(edit=btn, left_widget=self._back_button)

                print_name: Optional[Union[str, ba.Lstr]]
                if name == '__default__':
                    print_name = self._pvars.default_list_name
                else:
                    print_name = name
                ba.textwidget(parent=self._subcontainer,
                              text=print_name,
                              position=(pos[0] + button_width * 0.5,
                                        pos[1] + button_height * 0.79),
                              size=(0, 0),
                              scale=button_width * 0.003,
                              maxwidth=button_width * 0.7,
                              draw_controller=btn,
                              h_align='center',
                              v_align='center')

                # Poke into this playlist and see if we can display some of
                # its maps.
                map_images = []
                try:
                    map_textures = []
                    map_texture_entries = []
                    if name == '__default__':
                        if self._sessiontype is ba.FreeForAllSession:
                            playlist = (get_default_free_for_all_playlist())
                        elif self._sessiontype is ba.DualTeamSession:
                            playlist = get_default_teams_playlist()
                        else:
                            raise Exception('unrecognized session-type: ' +
                                            str(self._sessiontype))
                    else:
                        if name not in appconfig[self._pvars.config_name +
                                                 ' Playlists']:
                            print(
                                'NOT FOUND ERR',
                                appconfig[self._pvars.config_name +
                                          ' Playlists'])
                        playlist = appconfig[self._pvars.config_name +
                                             ' Playlists'][name]
                    playlist = filter_playlist(playlist,
                                               self._sessiontype,
                                               remove_unowned=False,
                                               mark_unowned=True)
                    for entry in playlist:
                        mapname = entry['settings']['map']
                        maptype: Optional[Type[ba.Map]]
                        try:
                            maptype = get_map_class(mapname)
                        except ba.NotFoundError:
                            maptype = None
                        if maptype is not None:
                            tex_name = maptype.get_preview_texture_name()
                            if tex_name is not None:
                                map_textures.append(tex_name)
                                map_texture_entries.append(entry)
                        if len(map_textures) >= 6:
                            break

                    if len(map_textures) > 4:
                        img_rows = 3
                        img_columns = 2
                        scl = 0.33
                        h_offs_img = 30
                        v_offs_img = 126
                    elif len(map_textures) > 2:
                        img_rows = 2
                        img_columns = 2
                        scl = 0.35
                        h_offs_img = 24
                        v_offs_img = 110
                    elif len(map_textures) > 1:
                        img_rows = 2
                        img_columns = 1
                        scl = 0.5
                        h_offs_img = 47
                        v_offs_img = 105
                    else:
                        img_rows = 1
                        img_columns = 1
                        scl = 0.75
                        h_offs_img = 20
                        v_offs_img = 65

                    v = None
                    for row in range(img_rows):
                        for col in range(img_columns):
                            tex_index = row * img_columns + col
                            if tex_index < len(map_textures):
                                entry = map_texture_entries[tex_index]

                                owned = not (('is_unowned_map' in entry
                                              and entry['is_unowned_map']) or
                                             ('is_unowned_game' in entry
                                              and entry['is_unowned_game']))

                                tex_name = map_textures[tex_index]
                                h = pos[0] + h_offs_img + scl * 250 * col
                                v = pos[1] + v_offs_img - scl * 130 * row
                                map_images.append(
                                    ba.imagewidget(
                                        parent=self._subcontainer,
                                        size=(scl * 250.0, scl * 125.0),
                                        position=(h, v),
                                        texture=ba.gettexture(tex_name),
                                        opacity=1.0 if owned else 0.25,
                                        draw_controller=btn,
                                        model_opaque=model_opaque,
                                        model_transparent=model_transparent,
                                        mask_texture=mask_tex))
                                if not owned:
                                    ba.imagewidget(
                                        parent=self._subcontainer,
                                        size=(scl * 100.0, scl * 100.0),
                                        position=(h + scl * 75, v + scl * 10),
                                        texture=ba.gettexture('lock'),
                                        draw_controller=btn)
                        if v is not None:
                            v -= scl * 130.0

                except Exception:
                    ba.print_exception('Error listing playlist maps.')

                if not map_images:
                    ba.textwidget(parent=self._subcontainer,
                                  text='???',
                                  scale=1.5,
                                  size=(0, 0),
                                  color=(1, 1, 1, 0.5),
                                  h_align='center',
                                  v_align='center',
                                  draw_controller=btn,
                                  position=(pos[0] + button_width * 0.5,
                                            pos[1] + button_height * 0.5))

                index += 1

                if index >= count:
                    break
            if index >= count:
                break
        self._customize_button = btn = ba.buttonwidget(
            parent=self._subcontainer,
            size=(100, 30),
            position=(34 + h_offs_bottom, 50),
            text_scale=0.6,
            label=ba.Lstr(resource='customizeText'),
            on_activate_call=self._on_customize_press,
            color=(0.54, 0.52, 0.67),
            textcolor=(0.7, 0.65, 0.7),
            autoselect=True)
        ba.widget(edit=btn, show_buffer_top=22, show_buffer_bottom=28)
        self._restore_state()
Пример #29
0
    def on_activate(
        self,
        parent_widget: ba.Widget,
        tab_button: ba.Widget,
        region_width: float,
        region_height: float,
        region_left: float,
        region_bottom: float,
    ) -> ba.Widget:

        c_width = region_width
        c_height = region_height - 20

        self._container = ba.containerwidget(
            parent=parent_widget,
            position=(region_left,
                      region_bottom + (region_height - c_height) * 0.5),
            size=(c_width, c_height),
            background=False,
            selection_loops_to_parent=True)
        v = c_height - 30
        self._join_by_address_text = ba.textwidget(
            parent=self._container,
            position=(c_width * 0.5 - 245, v - 13),
            color=(0.6, 1.0, 0.6),
            scale=1.3,
            size=(200, 30),
            maxwidth=250,
            h_align='center',
            v_align='center',
            click_activate=True,
            selectable=True,
            autoselect=True,
            on_activate_call=lambda: self._set_sub_tab(
                SubTabType.JOIN_BY_ADDRESS,
                region_width,
                region_height,
                playsound=True,
            ),
            text=ba.Lstr(resource='gatherWindow.manualJoinSectionText'))
        self._favorites_text = ba.textwidget(
            parent=self._container,
            position=(c_width * 0.5 + 45, v - 13),
            color=(0.6, 1.0, 0.6),
            scale=1.3,
            size=(200, 30),
            maxwidth=250,
            h_align='center',
            v_align='center',
            click_activate=True,
            selectable=True,
            autoselect=True,
            on_activate_call=lambda: self._set_sub_tab(
                SubTabType.FAVORITES,
                region_width,
                region_height,
                playsound=True,
            ),
            text=ba.Lstr(resource='gatherWindow.favoritesText'))
        ba.widget(edit=self._join_by_address_text, up_widget=tab_button)
        ba.widget(edit=self._favorites_text,
                  left_widget=self._join_by_address_text,
                  up_widget=tab_button)
        ba.widget(edit=tab_button, down_widget=self._favorites_text)
        ba.widget(edit=self._join_by_address_text,
                  right_widget=self._favorites_text)
        self._set_sub_tab(self._sub_tab, region_width, region_height)

        return self._container
    def __init__(self,
                 transition: str = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-statements
        from bastd.ui import popup
        from bastd.ui.config import ConfigCheckBox, ConfigNumberEdit
        # if they provided an origin-widget, scale up from that
        scale_origin: Optional[tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None

        self._r = 'graphicsSettingsWindow'
        app = ba.app

        spacing = 32
        self._have_selected_child = False
        uiscale = app.ui.uiscale
        width = 450.0
        height = 302.0

        self._show_fullscreen = False
        fullscreen_spacing_top = spacing * 0.2
        fullscreen_spacing = spacing * 1.2
        if uiscale == ba.UIScale.LARGE and app.platform != 'android':
            self._show_fullscreen = True
            height += fullscreen_spacing + fullscreen_spacing_top

        show_gamma = False
        gamma_spacing = spacing * 1.3
        if _ba.has_gamma_control():
            show_gamma = True
            height += gamma_spacing

        show_vsync = False
        if app.platform == 'mac':
            show_vsync = True

        show_resolution = True
        if app.vr_mode:
            show_resolution = (app.platform == 'android'
                               and app.subplatform == 'cardboard')

        uiscale = ba.app.ui.uiscale
        base_scale = (2.4 if uiscale is ba.UIScale.SMALL else
                      1.5 if uiscale is ba.UIScale.MEDIUM else 1.0)
        popup_menu_scale = base_scale * 1.2
        v = height - 50
        v -= spacing * 1.15
        super().__init__(root_widget=ba.containerwidget(
            size=(width, height),
            transition=transition,
            scale_origin_stack_offset=scale_origin,
            scale=base_scale,
            stack_offset=(0, -30) if uiscale is ba.UIScale.SMALL else (0, 0)))

        btn = ba.buttonwidget(parent=self._root_widget,
                              position=(35, height - 50),
                              size=(120, 60),
                              scale=0.8,
                              text_scale=1.2,
                              autoselect=True,
                              label=ba.Lstr(resource='backText'),
                              button_type='back',
                              on_activate_call=self._back)

        ba.containerwidget(edit=self._root_widget, cancel_button=btn)

        ba.textwidget(parent=self._root_widget,
                      position=(0, height - 44),
                      size=(width, 25),
                      text=ba.Lstr(resource=self._r + '.titleText'),
                      color=ba.app.ui.title_color,
                      h_align='center',
                      v_align='top')

        ba.buttonwidget(edit=btn,
                        button_type='backSmall',
                        size=(60, 60),
                        label=ba.charstr(ba.SpecialChar.BACK))

        self._fullscreen_checkbox: Optional[ba.Widget]
        if self._show_fullscreen:
            v -= fullscreen_spacing_top
            self._fullscreen_checkbox = ConfigCheckBox(
                parent=self._root_widget,
                position=(100, v),
                maxwidth=200,
                size=(300, 30),
                configkey='Fullscreen',
                displayname=ba.Lstr(resource=self._r +
                                    ('.fullScreenCmdText' if app.platform ==
                                     'mac' else '.fullScreenCtrlText'))).widget
            if not self._have_selected_child:
                ba.containerwidget(edit=self._root_widget,
                                   selected_child=self._fullscreen_checkbox)
                self._have_selected_child = True
            v -= fullscreen_spacing
        else:
            self._fullscreen_checkbox = None

        self._gamma_controls: Optional[ConfigNumberEdit]
        if show_gamma:
            self._gamma_controls = gmc = ConfigNumberEdit(
                parent=self._root_widget,
                position=(90, v),
                configkey='Screen Gamma',
                displayname=ba.Lstr(resource=self._r + '.gammaText'),
                minval=0.1,
                maxval=2.0,
                increment=0.1,
                xoffset=-70,
                textscale=0.85)
            if ba.app.ui.use_toolbars:
                ba.widget(edit=gmc.plusbutton,
                          right_widget=_ba.get_special_widget('party_button'))
            if not self._have_selected_child:
                ba.containerwidget(edit=self._root_widget,
                                   selected_child=gmc.minusbutton)
                self._have_selected_child = True
            v -= gamma_spacing
        else:
            self._gamma_controls = None

        self._selected_color = (0.5, 1, 0.5, 1)
        self._unselected_color = (0.7, 0.7, 0.7, 1)

        # quality
        ba.textwidget(parent=self._root_widget,
                      position=(60, v),
                      size=(160, 25),
                      text=ba.Lstr(resource=self._r + '.visualsText'),
                      color=ba.app.ui.heading_color,
                      scale=0.65,
                      maxwidth=150,
                      h_align='center',
                      v_align='center')
        popup.PopupMenu(
            parent=self._root_widget,
            position=(60, v - 50),
            width=150,
            scale=popup_menu_scale,
            choices=['Auto', 'Higher', 'High', 'Medium', 'Low'],
            choices_disabled=['Higher', 'High']
            if _ba.get_max_graphics_quality() == 'Medium' else [],
            choices_display=[
                ba.Lstr(resource='autoText'),
                ba.Lstr(resource=self._r + '.higherText'),
                ba.Lstr(resource=self._r + '.highText'),
                ba.Lstr(resource=self._r + '.mediumText'),
                ba.Lstr(resource=self._r + '.lowText')
            ],
            current_choice=ba.app.config.resolve('Graphics Quality'),
            on_value_change_call=self._set_quality)

        # texture controls
        ba.textwidget(parent=self._root_widget,
                      position=(230, v),
                      size=(160, 25),
                      text=ba.Lstr(resource=self._r + '.texturesText'),
                      color=ba.app.ui.heading_color,
                      scale=0.65,
                      maxwidth=150,
                      h_align='center',
                      v_align='center')
        textures_popup = popup.PopupMenu(
            parent=self._root_widget,
            position=(230, v - 50),
            width=150,
            scale=popup_menu_scale,
            choices=['Auto', 'High', 'Medium', 'Low'],
            choices_display=[
                ba.Lstr(resource='autoText'),
                ba.Lstr(resource=self._r + '.highText'),
                ba.Lstr(resource=self._r + '.mediumText'),
                ba.Lstr(resource=self._r + '.lowText')
            ],
            current_choice=ba.app.config.resolve('Texture Quality'),
            on_value_change_call=self._set_textures)
        if ba.app.ui.use_toolbars:
            ba.widget(edit=textures_popup.get_button(),
                      right_widget=_ba.get_special_widget('party_button'))
        v -= 80

        h_offs = 0

        if show_resolution:
            # resolution
            ba.textwidget(parent=self._root_widget,
                          position=(h_offs + 60, v),
                          size=(160, 25),
                          text=ba.Lstr(resource=self._r + '.resolutionText'),
                          color=ba.app.ui.heading_color,
                          scale=0.65,
                          maxwidth=150,
                          h_align='center',
                          v_align='center')

            # on standard android we have 'Auto', 'Native', and a few
            # HD standards
            if app.platform == 'android':
                # on cardboard/daydream android we have a few
                # render-target-scale options
                if app.subplatform == 'cardboard':
                    current_res_cardboard = (str(min(100, max(10, int(round(
                        ba.app.config.resolve('GVR Render Target Scale')
                        * 100.0))))) + '%')  # yapf: disable
                    popup.PopupMenu(
                        parent=self._root_widget,
                        position=(h_offs + 60, v - 50),
                        width=120,
                        scale=popup_menu_scale,
                        choices=['100%', '75%', '50%', '35%'],
                        current_choice=current_res_cardboard,
                        on_value_change_call=self._set_gvr_render_target_scale)
                else:
                    native_res = _ba.get_display_resolution()
                    assert native_res is not None
                    choices = ['Auto', 'Native']
                    choices_display = [
                        ba.Lstr(resource='autoText'),
                        ba.Lstr(resource='nativeText')
                    ]
                    for res in [1440, 1080, 960, 720, 480]:
                        # nav bar is 72px so lets allow for that in what
                        # choices we show
                        if native_res[1] >= res - 72:
                            res_str = str(res) + 'p'
                            choices.append(res_str)
                            choices_display.append(ba.Lstr(value=res_str))
                    current_res_android = ba.app.config.resolve(
                        'Resolution (Android)')
                    popup.PopupMenu(parent=self._root_widget,
                                    position=(h_offs + 60, v - 50),
                                    width=120,
                                    scale=popup_menu_scale,
                                    choices=choices,
                                    choices_display=choices_display,
                                    current_choice=current_res_android,
                                    on_value_change_call=self._set_android_res)
            else:
                # if we're on a system that doesn't allow setting resolution,
                # set pixel-scale instead
                current_res = _ba.get_display_resolution()
                if current_res is None:
                    current_res2 = (str(min(100, max(10, int(round(
                        ba.app.config.resolve('Screen Pixel Scale')
                        * 100.0))))) + '%')  # yapf: disable
                    popup.PopupMenu(
                        parent=self._root_widget,
                        position=(h_offs + 60, v - 50),
                        width=120,
                        scale=popup_menu_scale,
                        choices=['100%', '88%', '75%', '63%', '50%'],
                        current_choice=current_res2,
                        on_value_change_call=self._set_pixel_scale)
                else:
                    raise Exception('obsolete path; discrete resolutions'
                                    ' no longer supported')

        # vsync
        if show_vsync:
            ba.textwidget(parent=self._root_widget,
                          position=(230, v),
                          size=(160, 25),
                          text=ba.Lstr(resource=self._r + '.verticalSyncText'),
                          color=ba.app.ui.heading_color,
                          scale=0.65,
                          maxwidth=150,
                          h_align='center',
                          v_align='center')

            popup.PopupMenu(
                parent=self._root_widget,
                position=(230, v - 50),
                width=150,
                scale=popup_menu_scale,
                choices=['Auto', 'Always', 'Never'],
                choices_display=[
                    ba.Lstr(resource='autoText'),
                    ba.Lstr(resource=self._r + '.alwaysText'),
                    ba.Lstr(resource=self._r + '.neverText')
                ],
                current_choice=ba.app.config.resolve('Vertical Sync'),
                on_value_change_call=self._set_vsync)

        v -= 90
        fpsc = ConfigCheckBox(parent=self._root_widget,
                              position=(69, v - 6),
                              size=(210, 30),
                              scale=0.86,
                              configkey='Show FPS',
                              displayname=ba.Lstr(resource=self._r +
                                                  '.showFPSText'),
                              maxwidth=130)

        # (tv mode doesnt apply to vr)
        if not ba.app.vr_mode:
            tvc = ConfigCheckBox(parent=self._root_widget,
                                 position=(240, v - 6),
                                 size=(210, 30),
                                 scale=0.86,
                                 configkey='TV Border',
                                 displayname=ba.Lstr(resource=self._r +
                                                     '.tvBorderText'),
                                 maxwidth=130)
            # grumble..
            ba.widget(edit=fpsc.widget, right_widget=tvc.widget)
        try:
            pass

        except Exception:
            ba.print_exception('Exception wiring up graphics settings UI:')

        v -= spacing

        # make a timer to update our controls in case the config changes
        # under us
        self._update_timer = ba.Timer(0.25,
                                      ba.WeakCall(self._update_controls),
                                      repeat=True,
                                      timetype=ba.TimeType.REAL)