def __init__(self,
                 sessiontype: type[ba.Session],
                 playlist: str,
                 scale_origin: tuple[float, float],
                 delegate: Any = None):
        # FIXME: Tidy this up.
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        from ba.internal import get_map_class, getclass, filter_playlist
        from bastd.ui.playlist import PlaylistTypeVars

        self._r = 'gameListWindow'
        self._delegate = delegate
        self._pvars = PlaylistTypeVars(sessiontype)
        self._transitioning_out = False

        # We behave differently if we're being used for playlist selection
        # vs starting a game directly (should make this more elegant).
        self._selecting_mode = ba.app.ui.selecting_private_party_playlist

        self._do_randomize_val = (ba.app.config.get(
            self._pvars.config_name + ' Playlist Randomize', 0))

        self._sessiontype = sessiontype
        self._playlist = playlist

        self._width = 500.0
        self._height = 330.0 - 50.0

        # In teams games, show the custom names/colors button.
        if self._sessiontype is ba.DualTeamSession:
            self._height += 50.0

        self._row_height = 45.0

        # Grab our maps to display.
        model_opaque = ba.getmodel('level_select_button_opaque')
        model_transparent = ba.getmodel('level_select_button_transparent')
        mask_tex = ba.gettexture('mapPreviewMask')

        # Poke into this playlist and see if we can display some of its maps.
        map_textures = []
        map_texture_entries = []
        rows = 0
        columns = 0
        game_count = 0
        scl = 0.35
        c_width_total = 0.0
        try:
            max_columns = 5
            name = playlist
            if name == '__default__':
                plst = self._pvars.get_default_list_call()
            else:
                try:
                    plst = ba.app.config[self._pvars.config_name +
                                         ' Playlists'][name]
                except Exception:
                    print('ERROR INFO: self._config_name is:',
                          self._pvars.config_name)
                    print(
                        'ERROR INFO: playlist names are:',
                        list(ba.app.config[self._pvars.config_name +
                                           ' Playlists'].keys()))
                    raise
            plst = filter_playlist(plst,
                                   self._sessiontype,
                                   remove_unowned=False,
                                   mark_unowned=True)
            game_count = len(plst)
            for entry in plst:
                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)
            rows = (max(0, len(map_textures) - 1) // max_columns) + 1
            columns = min(max_columns, len(map_textures))

            if len(map_textures) == 1:
                scl = 1.1
            elif len(map_textures) == 2:
                scl = 0.7
            elif len(map_textures) == 3:
                scl = 0.55
            else:
                scl = 0.35
            self._row_height = 128.0 * scl
            c_width_total = scl * 250.0 * columns
            if map_textures:
                self._height += self._row_height * rows

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

        show_shuffle_check_box = game_count > 1

        if show_shuffle_check_box:
            self._height += 40

        # Creates our _root_widget.
        uiscale = ba.app.ui.uiscale
        scale = (1.69 if uiscale is ba.UIScale.SMALL else
                 1.1 if uiscale is ba.UIScale.MEDIUM else 0.85)
        super().__init__(position=scale_origin,
                         size=(self._width, self._height),
                         scale=scale)

        playlist_name: Union[str, ba.Lstr] = (self._pvars.default_list_name
                                              if playlist == '__default__' else
                                              playlist)
        self._title_text = ba.textwidget(parent=self.root_widget,
                                         position=(self._width * 0.5,
                                                   self._height - 89 + 51),
                                         size=(0, 0),
                                         text=playlist_name,
                                         scale=1.4,
                                         color=(1, 1, 1),
                                         maxwidth=self._width * 0.7,
                                         h_align='center',
                                         v_align='center')

        self._cancel_button = ba.buttonwidget(
            parent=self.root_widget,
            position=(25, self._height - 53),
            size=(50, 50),
            scale=0.7,
            label='',
            color=(0.42, 0.73, 0.2),
            on_activate_call=self._on_cancel_press,
            autoselect=True,
            icon=ba.gettexture('crossOut'),
            iconscale=1.2)

        h_offs_img = self._width * 0.5 - c_width_total * 0.5
        v_offs_img = self._height - 118 - scl * 125.0 + 50
        bottom_row_buttons = []
        self._have_at_least_one_owned = False

        for row in range(rows):
            for col in range(columns):
                tex_index = row * columns + col
                if tex_index < len(map_textures):
                    tex_name = map_textures[tex_index]
                    h = h_offs_img + scl * 250 * col
                    v = v_offs_img - self._row_height * row
                    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']))

                    if owned:
                        self._have_at_least_one_owned = True

                    try:
                        desc = getclass(entry['type'],
                                        subclassof=ba.GameActivity
                                        ).get_settings_display_string(entry)
                        if not owned:
                            desc = ba.Lstr(
                                value='${DESC}\n${UNLOCK}',
                                subs=[
                                    ('${DESC}', desc),
                                    ('${UNLOCK}',
                                     ba.Lstr(
                                         resource='unlockThisInTheStoreText'))
                                ])
                        desc_color = (0, 1, 0) if owned else (1, 0, 0)
                    except Exception:
                        desc = ba.Lstr(value='(invalid)')
                        desc_color = (1, 0, 0)

                    btn = ba.buttonwidget(
                        parent=self.root_widget,
                        size=(scl * 240.0, scl * 120.0),
                        position=(h, v),
                        texture=ba.gettexture(tex_name if owned else 'empty'),
                        model_opaque=model_opaque if owned else None,
                        on_activate_call=ba.Call(ba.screenmessage, desc,
                                                 desc_color),
                        label='',
                        color=(1, 1, 1),
                        autoselect=True,
                        extra_touch_border_scale=0.0,
                        model_transparent=model_transparent if owned else None,
                        mask_texture=mask_tex if owned else None)
                    if row == 0 and col == 0:
                        ba.widget(edit=self._cancel_button, down_widget=btn)
                    if row == rows - 1:
                        bottom_row_buttons.append(btn)
                    if not owned:

                        # Ewww; buttons don't currently have alpha so in this
                        # case we draw an image over our button with an empty
                        # texture on it.
                        ba.imagewidget(parent=self.root_widget,
                                       size=(scl * 260.0, scl * 130.0),
                                       position=(h - 10.0 * scl,
                                                 v - 4.0 * scl),
                                       draw_controller=btn,
                                       color=(1, 1, 1),
                                       texture=ba.gettexture(tex_name),
                                       model_opaque=model_opaque,
                                       opacity=0.25,
                                       model_transparent=model_transparent,
                                       mask_texture=mask_tex)

                        ba.imagewidget(parent=self.root_widget,
                                       size=(scl * 100, scl * 100),
                                       draw_controller=btn,
                                       position=(h + scl * 70, v + scl * 10),
                                       texture=ba.gettexture('lock'))

        # Team names/colors.
        self._custom_colors_names_button: Optional[ba.Widget]
        if self._sessiontype is ba.DualTeamSession:
            y_offs = 50 if show_shuffle_check_box else 0
            self._custom_colors_names_button = ba.buttonwidget(
                parent=self.root_widget,
                position=(100, 200 + y_offs),
                size=(290, 35),
                on_activate_call=ba.WeakCall(self._custom_colors_names_press),
                autoselect=True,
                textcolor=(0.8, 0.8, 0.8),
                label=ba.Lstr(resource='teamNamesColorText'))
            if not ba.app.accounts.have_pro():
                ba.imagewidget(
                    parent=self.root_widget,
                    size=(30, 30),
                    position=(95, 202 + y_offs),
                    texture=ba.gettexture('lock'),
                    draw_controller=self._custom_colors_names_button)
        else:
            self._custom_colors_names_button = None

        # Shuffle.
        def _cb_callback(val: bool) -> None:
            self._do_randomize_val = val
            cfg = ba.app.config
            cfg[self._pvars.config_name +
                ' Playlist Randomize'] = self._do_randomize_val
            cfg.commit()

        if show_shuffle_check_box:
            self._shuffle_check_box = ba.checkboxwidget(
                parent=self.root_widget,
                position=(110, 200),
                scale=1.0,
                size=(250, 30),
                autoselect=True,
                text=ba.Lstr(resource=self._r + '.shuffleGameOrderText'),
                maxwidth=300,
                textcolor=(0.8, 0.8, 0.8),
                value=self._do_randomize_val,
                on_value_change_call=_cb_callback)

        # Show tutorial.
        show_tutorial = bool(ba.app.config.get('Show Tutorial', True))

        def _cb_callback_2(val: bool) -> None:
            cfg = ba.app.config
            cfg['Show Tutorial'] = val
            cfg.commit()

        self._show_tutorial_check_box = ba.checkboxwidget(
            parent=self.root_widget,
            position=(110, 151),
            scale=1.0,
            size=(250, 30),
            autoselect=True,
            text=ba.Lstr(resource=self._r + '.showTutorialText'),
            maxwidth=300,
            textcolor=(0.8, 0.8, 0.8),
            value=show_tutorial,
            on_value_change_call=_cb_callback_2)

        # Grumble: current autoselect doesn't do a very good job
        # with checkboxes.
        if self._custom_colors_names_button is not None:
            for btn in bottom_row_buttons:
                ba.widget(edit=btn,
                          down_widget=self._custom_colors_names_button)
            if show_shuffle_check_box:
                ba.widget(edit=self._custom_colors_names_button,
                          down_widget=self._shuffle_check_box)
                ba.widget(edit=self._shuffle_check_box,
                          up_widget=self._custom_colors_names_button)
            else:
                ba.widget(edit=self._custom_colors_names_button,
                          down_widget=self._show_tutorial_check_box)
                ba.widget(edit=self._show_tutorial_check_box,
                          up_widget=self._custom_colors_names_button)

        self._ok_button = ba.buttonwidget(
            parent=self.root_widget,
            position=(70, 44),
            size=(200, 45),
            scale=1.8,
            text_res_scale=1.5,
            on_activate_call=self._on_ok_press,
            autoselect=True,
            label=ba.Lstr(
                resource='okText' if self._selecting_mode else 'playText'))

        ba.widget(edit=self._ok_button,
                  up_widget=self._show_tutorial_check_box)

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

        # Update now and once per second.
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)
        self._update()
Exemple #2
0
        def __init__(self, parent: PartyQueueWindow, distance: float,
                     initial_offset: float, is_player: bool, account_id: str,
                     name: str):
            self.claimed = False
            self._line_left = parent.get_line_left()
            self._line_width = parent.get_line_width()
            self._line_bottom = parent.get_line_bottom()
            self._target_distance = distance
            self._distance = distance + initial_offset
            self._boost_brightness = 0.0
            self._debug = False
            self._sc = sc = 1.1 if is_player else 0.6 + random.random() * 0.2
            self._y_offs = -30.0 if is_player else -47.0 * sc
            self._last_boost_time = 0.0
            self._color = (0.2, 1.0,
                           0.2) if is_player else (0.5 + 0.3 * random.random(),
                                                   0.4 + 0.2 * random.random(),
                                                   0.5 + 0.3 * random.random())
            self._eye_color = (0.7 * 1.0 + 0.3 * self._color[0],
                               0.7 * 1.0 + 0.3 * self._color[1],
                               0.7 * 1.0 + 0.3 * self._color[2])
            self._body_image = ba.buttonwidget(
                parent=parent.get_root_widget(),
                selectable=True,
                label='',
                size=(sc * 60, sc * 80),
                color=self._color,
                texture=parent.lineup_tex,
                model_transparent=parent.lineup_1_transparent_model)
            ba.buttonwidget(edit=self._body_image,
                            on_activate_call=ba.WeakCall(
                                parent.on_account_press, account_id,
                                self._body_image))
            ba.widget(edit=self._body_image, autoselect=True)
            self._eyes_image = ba.imagewidget(
                parent=parent.get_root_widget(),
                size=(sc * 36, sc * 18),
                texture=parent.lineup_tex,
                color=self._eye_color,
                model_transparent=parent.eyes_model)
            self._name_text = ba.textwidget(parent=parent.get_root_widget(),
                                            size=(0, 0),
                                            shadow=0,
                                            flatness=1.0,
                                            text=name,
                                            maxwidth=100,
                                            h_align='center',
                                            v_align='center',
                                            scale=0.75,
                                            color=(1, 1, 1, 0.6))
            self._update_image()

            # DEBUG: vis target pos..
            self._body_image_target: Optional[ba.Widget]
            self._eyes_image_target: Optional[ba.Widget]
            if self._debug:
                self._body_image_target = ba.imagewidget(
                    parent=parent.get_root_widget(),
                    size=(sc * 60, sc * 80),
                    color=self._color,
                    texture=parent.lineup_tex,
                    model_transparent=parent.lineup_1_transparent_model)
                self._eyes_image_target = ba.imagewidget(
                    parent=parent.get_root_widget(),
                    size=(sc * 36, sc * 18),
                    texture=parent.lineup_tex,
                    color=self._eye_color,
                    model_transparent=parent.eyes_model)
                # (updates our image positions)
                self.set_target_distance(self._target_distance)
            else:
                self._body_image_target = self._eyes_image_target = None
Exemple #3
0
    def __init__(self,
                 parent: ba.Widget,
                 position: Tuple[float, float],
                 initial_color: Sequence[float] = (1.0, 1.0, 1.0),
                 delegate: Any = None,
                 scale: float = None,
                 offset: Tuple[float, float] = (0.0, 0.0),
                 tag: Any = ''):
        # pylint: disable=too-many-locals
        from ba.internal import have_pro, get_player_colors

        c_raw = get_player_colors()
        assert len(c_raw) == 16
        self.colors = [c_raw[0:4], c_raw[4:8], c_raw[8:12], c_raw[12:16]]

        uiscale = ba.app.ui.uiscale
        if scale is None:
            scale = (2.3 if uiscale is ba.UIScale.SMALL else
                     1.65 if uiscale is ba.UIScale.MEDIUM else 1.23)
        self._parent = parent
        self._position = position
        self._scale = scale
        self._offset = offset
        self._delegate = delegate
        self._transitioning_out = False
        self._tag = tag
        self._initial_color = initial_color

        # Create our _root_widget.
        PopupWindow.__init__(self,
                             position=position,
                             size=(210, 240),
                             scale=scale,
                             focus_position=(10, 10),
                             focus_size=(190, 220),
                             bg_color=(0.5, 0.5, 0.5),
                             offset=offset)
        rows: List[List[ba.Widget]] = []
        closest_dist = 9999.0
        closest = (0, 0)
        for y in range(4):
            row: List[ba.Widget] = []
            rows.append(row)
            for x in range(4):
                color = self.colors[y][x]
                dist = (abs(color[0] - initial_color[0]) +
                        abs(color[1] - initial_color[1]) +
                        abs(color[2] - initial_color[2]))
                if dist < closest_dist:
                    closest = (x, y)
                    closest_dist = dist
                btn = ba.buttonwidget(parent=self.root_widget,
                                      position=(22 + 45 * x, 185 - 45 * y),
                                      size=(35, 40),
                                      label='',
                                      button_type='square',
                                      on_activate_call=ba.WeakCall(
                                          self._select, x, y),
                                      autoselect=True,
                                      color=color,
                                      extra_touch_border_scale=0.0)
                row.append(btn)
        other_button = ba.buttonwidget(
            parent=self.root_widget,
            position=(105 - 60, 13),
            color=(0.7, 0.7, 0.7),
            text_scale=0.5,
            textcolor=(0.8, 0.8, 0.8),
            size=(120, 30),
            label=ba.Lstr(resource='otherText',
                          fallback_resource='coopSelectWindow.customText'),
            autoselect=True,
            on_activate_call=ba.WeakCall(self._select_other))

        # Custom colors are limited to pro currently.
        if not have_pro():
            ba.imagewidget(parent=self.root_widget,
                           position=(50, 12),
                           size=(30, 30),
                           texture=ba.gettexture('lock'),
                           draw_controller=other_button)

        # If their color is close to one of our swatches, select it.
        # Otherwise select 'other'.
        if closest_dist < 0.03:
            ba.containerwidget(edit=self.root_widget,
                               selected_child=rows[closest[1]][closest[0]])
        else:
            ba.containerwidget(edit=self.root_widget,
                               selected_child=other_button)
Exemple #4
0
    def __init__(self,
                 transition: Optional[str] = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        from bastd.ui.tabs import TabRow
        ba.set_analytics_screen('Watch Window')
        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
        ba.app.ui.set_main_menu_location('Watch')
        self._tab_data: Dict[str, Any] = {}
        self._my_replays_scroll_width: Optional[float] = None
        self._my_replays_watch_replay_button: Optional[ba.Widget] = None
        self._scrollwidget: Optional[ba.Widget] = None
        self._columnwidget: Optional[ba.Widget] = None
        self._my_replay_selected: Optional[str] = None
        self._my_replays_rename_window: Optional[ba.Widget] = None
        self._my_replay_rename_text: Optional[ba.Widget] = None
        self._r = 'watchWindow'
        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._current_tab: Optional[WatchWindow.TabID] = None
        extra_top = 20 if uiscale is ba.UIScale.SMALL else 0

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + extra_top),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(1.3 if uiscale is ba.UIScale.SMALL else
                   0.97 if uiscale is ba.UIScale.MEDIUM else 0.8),
            stack_offset=(0, -10) if uiscale is ba.UIScale.SMALL else (
                0, 15) if uiscale is ba.UIScale.MEDIUM else (0, 0)))

        if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._back)
            self._back_button = None
        else:
            self._back_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                autoselect=True,
                position=(70 + x_inset, self._height - 74),
                size=(140, 60),
                scale=1.1,
                label=ba.Lstr(resource='backText'),
                button_type='back',
                on_activate_call=self._back)
            ba.containerwidget(edit=self._root_widget, cancel_button=btn)
            ba.buttonwidget(edit=btn,
                            button_type='backSmall',
                            size=(60, 60),
                            label=ba.charstr(ba.SpecialChar.BACK))

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

        tabdefs = [
            (self.TabID.MY_REPLAYS,
             ba.Lstr(resource=self._r + '.myReplaysText')),
            # (self.TabID.TEST_TAB, ba.Lstr(value='Testing')),
        ]

        scroll_buffer_h = 130 + 2 * x_inset
        tab_buffer_h = 750 + 2 * x_inset

        self._tab_row = TabRow(self._root_widget,
                               tabdefs,
                               pos=(tab_buffer_h * 0.5, self._height - 130),
                               size=(self._width - tab_buffer_h, 50),
                               on_select_call=self._set_tab)

        if ba.app.ui.use_toolbars:
            first_tab = self._tab_row.tabs[tabdefs[0][0]]
            last_tab = self._tab_row.tabs[tabdefs[-1][0]]
            ba.widget(edit=last_tab.button,
                      right_widget=_ba.get_special_widget('party_button'))
            if uiscale is ba.UIScale.SMALL:
                bbtn = _ba.get_special_widget('back_button')
                ba.widget(edit=first_tab.button,
                          up_widget=bbtn,
                          left_widget=bbtn)

        self._scroll_width = self._width - scroll_buffer_h
        self._scroll_height = self._height - 180

        # Not actually using a scroll widget anymore; just an image.
        scroll_left = (self._width - self._scroll_width) * 0.5
        scroll_bottom = self._height - self._scroll_height - 79 - 48
        buffer_h = 10
        buffer_v = 4
        ba.imagewidget(parent=self._root_widget,
                       position=(scroll_left - buffer_h,
                                 scroll_bottom - buffer_v),
                       size=(self._scroll_width + 2 * buffer_h,
                             self._scroll_height + 2 * buffer_v),
                       texture=ba.gettexture('scrollWidget'),
                       model_transparent=ba.getmodel('softEdgeOutside'))
        self._tab_container: Optional[ba.Widget] = None

        self._restore_state()
Exemple #5
0
 def _draw_dude(self, i: int, btn: ba.Widget, hoffs: float, v: float,
                scl: float, position: Tuple[float, float],
                color: Tuple[float, float, float]) -> None:
     h_extra = -100
     v_extra = 130
     eye_color = (0.7 * 1.0 + 0.3 * color[0], 0.7 * 1.0 + 0.3 * color[1],
                  0.7 * 1.0 + 0.3 * color[2])
     if i == 0:
         ba.imagewidget(parent=self._root_widget,
                        draw_controller=btn,
                        position=(hoffs + scl * (h_extra + position[0]),
                                  v + scl * (v_extra + position[1])),
                        size=(scl * 60, scl * 80),
                        color=color,
                        texture=self._lineup_tex,
                        model_transparent=self._lineup_1_transparent_model)
         ba.imagewidget(
             parent=self._root_widget,
             draw_controller=btn,
             position=(hoffs + scl * (h_extra + position[0] + 12),
                       v + scl * (v_extra + position[1] + 53)),
             size=(scl * 36, scl * 18),
             texture=self._lineup_tex,
             color=eye_color,
             model_transparent=self._eyes_model)
     elif i == 1:
         ba.imagewidget(parent=self._root_widget,
                        draw_controller=btn,
                        position=(hoffs + scl * (h_extra + position[0]),
                                  v + scl * (v_extra + position[1])),
                        size=(scl * 45, scl * 90),
                        color=color,
                        texture=self._lineup_tex,
                        model_transparent=self._lineup_2_transparent_model)
         ba.imagewidget(parent=self._root_widget,
                        draw_controller=btn,
                        position=(hoffs + scl * (h_extra + position[0] + 5),
                                  v + scl * (v_extra + position[1] + 67)),
                        size=(scl * 32, scl * 16),
                        texture=self._lineup_tex,
                        color=eye_color,
                        model_transparent=self._eyes_model)
     elif i == 2:
         ba.imagewidget(parent=self._root_widget,
                        draw_controller=btn,
                        position=(hoffs + scl * (h_extra + position[0]),
                                  v + scl * (v_extra + position[1])),
                        size=(scl * 45, scl * 90),
                        color=color,
                        texture=self._lineup_tex,
                        model_transparent=self._lineup_3_transparent_model)
         ba.imagewidget(parent=self._root_widget,
                        draw_controller=btn,
                        position=(hoffs + scl * (h_extra + position[0] + 5),
                                  v + scl * (v_extra + position[1] + 59)),
                        size=(scl * 34, scl * 17),
                        texture=self._lineup_tex,
                        color=eye_color,
                        model_transparent=self._eyes_model)
     elif i == 3:
         ba.imagewidget(parent=self._root_widget,
                        draw_controller=btn,
                        position=(hoffs + scl * (h_extra + position[0]),
                                  v + scl * (v_extra + position[1])),
                        size=(scl * 48, scl * 96),
                        color=color,
                        texture=self._lineup_tex,
                        model_transparent=self._lineup_4_transparent_model)
         ba.imagewidget(parent=self._root_widget,
                        draw_controller=btn,
                        position=(hoffs + scl * (h_extra + position[0] + 2),
                                  v + scl * (v_extra + position[1] + 62)),
                        size=(scl * 38, scl * 19),
                        texture=self._lineup_tex,
                        color=eye_color,
                        model_transparent=self._eyes_model)
    def __init__(self,
                 sessiontype: type[ba.Session],
                 transition: str = 'in_right',
                 select_playlist: str = None,
                 origin_widget: ba.Widget = None):
        # Yes this needs tidying.
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        # pylint: disable=cyclic-import
        from bastd.ui import playlist
        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._sessiontype = sessiontype
        self._pvars = playlist.PlaylistTypeVars(sessiontype)
        self._max_playlists = 30
        self._r = 'gameListWindow'
        uiscale = ba.app.ui.uiscale
        self._width = 750.0 if uiscale is ba.UIScale.SMALL else 650.0
        x_inset = 50.0 if uiscale is ba.UIScale.SMALL else 0.0
        self._height = (380.0 if uiscale is ba.UIScale.SMALL else
                        420.0 if uiscale is ba.UIScale.MEDIUM else 500.0)
        top_extra = 20.0 if uiscale is ba.UIScale.SMALL else 0.0

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + top_extra),
            transition=transition,
            scale_origin_stack_offset=scale_origin,
            scale=(2.05 if uiscale is ba.UIScale.SMALL else
                   1.5 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -10) if uiscale is ba.UIScale.SMALL else (0, 0)))

        self._back_button = back_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(43 + x_inset, self._height - 60),
            size=(160, 68),
            scale=0.77,
            autoselect=True,
            text_scale=1.3,
            label=ba.Lstr(resource='backText'),
            button_type='back')

        ba.textwidget(parent=self._root_widget,
                      position=(0, self._height - 47),
                      size=(self._width, 25),
                      text=ba.Lstr(resource=self._r + '.titleText',
                                   subs=[('${TYPE}',
                                          self._pvars.window_title_name)]),
                      color=ba.app.ui.heading_color,
                      maxwidth=290,
                      h_align='center',
                      v_align='center')

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

        v = self._height - 59.0
        h = 41 + x_inset
        b_color = (0.6, 0.53, 0.63)
        b_textcolor = (0.75, 0.7, 0.8)
        self._lock_images: list[ba.Widget] = []
        lock_tex = ba.gettexture('lock')

        scl = (1.1 if uiscale is ba.UIScale.SMALL else
               1.27 if uiscale is ba.UIScale.MEDIUM else 1.57)
        scl *= 0.63
        v -= 65.0 * scl
        new_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(h, v),
            size=(90, 58.0 * scl),
            on_activate_call=self._new_playlist,
            color=b_color,
            autoselect=True,
            button_type='square',
            textcolor=b_textcolor,
            text_scale=0.7,
            label=ba.Lstr(resource='newText',
                          fallback_resource=self._r + '.newText'))
        self._lock_images.append(
            ba.imagewidget(parent=self._root_widget,
                           size=(30, 30),
                           draw_controller=btn,
                           position=(h - 10, v + 58.0 * scl - 28),
                           texture=lock_tex))

        v -= 65.0 * scl
        self._edit_button = edit_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(h, v),
            size=(90, 58.0 * scl),
            on_activate_call=self._edit_playlist,
            color=b_color,
            autoselect=True,
            textcolor=b_textcolor,
            button_type='square',
            text_scale=0.7,
            label=ba.Lstr(resource='editText',
                          fallback_resource=self._r + '.editText'))
        self._lock_images.append(
            ba.imagewidget(parent=self._root_widget,
                           size=(30, 30),
                           draw_controller=btn,
                           position=(h - 10, v + 58.0 * scl - 28),
                           texture=lock_tex))

        v -= 65.0 * scl
        duplicate_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(h, v),
            size=(90, 58.0 * scl),
            on_activate_call=self._duplicate_playlist,
            color=b_color,
            autoselect=True,
            textcolor=b_textcolor,
            button_type='square',
            text_scale=0.7,
            label=ba.Lstr(resource='duplicateText',
                          fallback_resource=self._r + '.duplicateText'))
        self._lock_images.append(
            ba.imagewidget(parent=self._root_widget,
                           size=(30, 30),
                           draw_controller=btn,
                           position=(h - 10, v + 58.0 * scl - 28),
                           texture=lock_tex))

        v -= 65.0 * scl
        delete_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(h, v),
            size=(90, 58.0 * scl),
            on_activate_call=self._delete_playlist,
            color=b_color,
            autoselect=True,
            textcolor=b_textcolor,
            button_type='square',
            text_scale=0.7,
            label=ba.Lstr(resource='deleteText',
                          fallback_resource=self._r + '.deleteText'))
        self._lock_images.append(
            ba.imagewidget(parent=self._root_widget,
                           size=(30, 30),
                           draw_controller=btn,
                           position=(h - 10, v + 58.0 * scl - 28),
                           texture=lock_tex))
        v -= 65.0 * scl
        self._import_button = ba.buttonwidget(
            parent=self._root_widget,
            position=(h, v),
            size=(90, 58.0 * scl),
            on_activate_call=self._import_playlist,
            color=b_color,
            autoselect=True,
            textcolor=b_textcolor,
            button_type='square',
            text_scale=0.7,
            label=ba.Lstr(resource='importText'))
        v -= 65.0 * scl
        btn = ba.buttonwidget(parent=self._root_widget,
                              position=(h, v),
                              size=(90, 58.0 * scl),
                              on_activate_call=self._share_playlist,
                              color=b_color,
                              autoselect=True,
                              textcolor=b_textcolor,
                              button_type='square',
                              text_scale=0.7,
                              label=ba.Lstr(resource='shareText'))
        self._lock_images.append(
            ba.imagewidget(parent=self._root_widget,
                           size=(30, 30),
                           draw_controller=btn,
                           position=(h - 10, v + 58.0 * scl - 28),
                           texture=lock_tex))

        v = self._height - 75
        self._scroll_height = self._height - 119
        scrollwidget = ba.scrollwidget(parent=self._root_widget,
                                       position=(140 + x_inset,
                                                 v - self._scroll_height),
                                       size=(self._width - (180 + 2 * x_inset),
                                             self._scroll_height + 10),
                                       highlight=False)
        ba.widget(edit=back_button, right_widget=scrollwidget)
        self._columnwidget = ba.columnwidget(parent=scrollwidget,
                                             border=2,
                                             margin=0)

        h = 145

        self._do_randomize_val = ba.app.config.get(
            self._pvars.config_name + ' Playlist Randomize', 0)

        h += 210

        for btn in [new_button, delete_button, edit_button, duplicate_button]:
            ba.widget(edit=btn, right_widget=scrollwidget)
        ba.widget(edit=scrollwidget,
                  left_widget=new_button,
                  right_widget=_ba.get_special_widget('party_button')
                  if ba.app.ui.use_toolbars else None)

        # make sure config exists
        self._config_name_full = self._pvars.config_name + ' Playlists'

        if self._config_name_full not in ba.app.config:
            ba.app.config[self._config_name_full] = {}

        self._selected_playlist_name: Optional[str] = None
        self._selected_playlist_index: Optional[int] = None
        self._playlist_widgets: list[ba.Widget] = []

        self._refresh(select_playlist=select_playlist)

        ba.buttonwidget(edit=back_button, on_activate_call=self._back)
        ba.containerwidget(edit=self._root_widget, cancel_button=back_button)

        ba.containerwidget(edit=self._root_widget, selected_child=scrollwidget)

        # Keep our lock images up to date/etc.
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)
        self._update()
Exemple #7
0
def ask_for_rating() -> Optional[ba.Widget]:
    """(internal)"""
    app = ba.app
    platform = app.platform
    subplatform = app.subplatform

    # FIXME: should whitelist platforms we *do* want this for.
    if ba.app.test_build:
        return None
    if not (platform == 'mac' or (platform == 'android'
                                  and subplatform in ['google', 'cardboard'])):
        return None
    width = 700
    height = 400
    spacing = 40
    uiscale = ba.app.ui.uiscale
    dlg = ba.containerwidget(
        size=(width, height),
        transition='in_right',
        scale=(1.6 if uiscale is ba.UIScale.SMALL else
               1.35 if uiscale is ba.UIScale.MEDIUM else 1.0))
    v = height - 50
    v -= spacing
    v -= 140
    ba.imagewidget(parent=dlg,
                   position=(width / 2 - 100, v + 10),
                   size=(200, 200),
                   texture=ba.gettexture('cuteSpaz'))
    ba.textwidget(parent=dlg,
                  position=(15, v - 55),
                  size=(width - 30, 30),
                  color=ba.app.ui.infotextcolor,
                  text=ba.Lstr(resource='pleaseRateText',
                               subs=[('${APP_NAME}',
                                      ba.Lstr(resource='titleText'))]),
                  maxwidth=width * 0.95,
                  max_height=130,
                  scale=0.85,
                  h_align='center',
                  v_align='center')

    def do_rating() -> None:
        import _ba
        if platform == 'android':
            appname = _ba.appname()
            if subplatform == 'google':
                url = f'market://details?id=net.froemling.{appname}'
            else:
                url = 'market://details?id=net.froemling.{appname}cb'
        else:
            url = 'macappstore://itunes.apple.com/app/id416482767?ls=1&mt=12'

        ba.open_url(url)
        ba.containerwidget(edit=dlg, transition='out_left')

    ba.buttonwidget(parent=dlg,
                    position=(60, 20),
                    size=(200, 60),
                    label=ba.Lstr(resource='wellSureText'),
                    autoselect=True,
                    on_activate_call=do_rating)

    def close() -> None:
        ba.containerwidget(edit=dlg, transition='out_left')

    btn = ba.buttonwidget(parent=dlg,
                          position=(width - 270, 20),
                          size=(200, 60),
                          label=ba.Lstr(resource='noThanksText'),
                          autoselect=True,
                          on_activate_call=close)
    ba.containerwidget(edit=dlg, cancel_button=btn, selected_child=btn)
    return dlg
Exemple #8
0
    def __init__(self, address: str):

        # in some cases we might want to show it as a qr code
        # (for long URLs especially)
        app = ba.app
        if app.platform == 'android' and app.subplatform == 'alibaba':
            self._width = 500
            self._height = 500
            super().__init__(root_widget=ba.containerwidget(
                size=(self._width, self._height),
                transition='in_right',
                scale=(1.25 if ba.app.small_ui else 1.25 if ba.app.
                       med_ui else 1.25)))
            self._cancel_button = ba.buttonwidget(
                parent=self._root_widget,
                position=(50, self._height - 30),
                size=(50, 50),
                scale=0.6,
                label='',
                color=(0.6, 0.5, 0.6),
                on_activate_call=self._done,
                autoselect=True,
                icon=ba.gettexture('crossOut'),
                iconscale=1.2)
            qr_size = 400
            ba.imagewidget(parent=self._root_widget,
                           position=(self._width * 0.5 - qr_size * 0.5,
                                     self._height * 0.5 - qr_size * 0.5),
                           size=(qr_size, qr_size),
                           texture=_ba.get_qrcode_texture(address))
            ba.containerwidget(edit=self._root_widget,
                               cancel_button=self._cancel_button)
        else:
            # show it as a simple string...
            self._width = 800
            self._height = 200
            self._root_widget = ba.containerwidget(
                size=(self._width, self._height + 40),
                transition='in_right',
                scale=1.25
                if ba.app.small_ui else 1.25 if ba.app.med_ui else 1.25)
            ba.textwidget(parent=self._root_widget,
                          position=(self._width * 0.5, self._height - 10),
                          size=(0, 0),
                          color=ba.app.title_color,
                          h_align='center',
                          v_align='center',
                          text=ba.Lstr(resource='directBrowserToURLText'),
                          maxwidth=self._width * 0.95)
            ba.textwidget(parent=self._root_widget,
                          position=(self._width * 0.5,
                                    self._height * 0.5 + 29),
                          size=(0, 0),
                          scale=1.3,
                          color=ba.app.infotextcolor,
                          h_align='center',
                          v_align='center',
                          text=address,
                          maxwidth=self._width * 0.95)
            button_width = 200
            btn = ba.buttonwidget(parent=self._root_widget,
                                  position=(self._width * 0.5 -
                                            button_width * 0.5, 20),
                                  size=(button_width, 65),
                                  label=ba.Lstr(resource='doneText'),
                                  on_activate_call=self._done)
            # we have no 'cancel' button but still want to be able to
            # hit back/escape/etc to leave..
            ba.containerwidget(edit=self._root_widget,
                               selected_child=btn,
                               start_button=btn,
                               on_cancel_call=btn.activate)
 def _update(self) -> None:
     from ba.internal import have_pro_options
     have = have_pro_options()
     for lock in self._lock_images:
         ba.imagewidget(edit=lock, opacity=0.0 if have else 1.0)
Exemple #10
0
    def __init__(self,
                 main_menu: bool = False,
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        from ba.internal import get_remote_app_name
        ba.set_analytics_screen('Help Window')

        # 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
            transition = 'in_right'

        self._r = 'helpWindow'

        getres = ba.app.lang.get_resource

        self._main_menu = main_menu
        uiscale = ba.app.ui.uiscale
        width = 950 if uiscale is ba.UIScale.SMALL else 750
        x_offs = 100 if uiscale is ba.UIScale.SMALL else 0
        height = (460 if uiscale is ba.UIScale.SMALL else
                  530 if uiscale is ba.UIScale.MEDIUM else 600)

        super().__init__(root_widget=ba.containerwidget(
            size=(width, height),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(1.77 if uiscale is ba.UIScale.SMALL else
                   1.25 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -30) if uiscale is ba.UIScale.SMALL else (
                0, 15) if uiscale is ba.UIScale.MEDIUM else (0, 0)))

        ba.textwidget(parent=self._root_widget,
                      position=(0, height -
                                (50 if uiscale is ba.UIScale.SMALL else 45)),
                      size=(width, 25),
                      text=ba.Lstr(resource=self._r + '.titleText',
                                   subs=[('${APP_NAME}',
                                          ba.Lstr(resource='titleText'))]),
                      color=ba.app.ui.title_color,
                      h_align='center',
                      v_align='top')

        self._scrollwidget = ba.scrollwidget(
            parent=self._root_widget,
            position=(44 + x_offs, 55 if uiscale is ba.UIScale.SMALL else 55),
            simple_culling_v=100.0,
            size=(width - (88 + 2 * x_offs),
                  height - 120 + (5 if uiscale is ba.UIScale.SMALL else 0)),
            capture_arrows=True)

        if ba.app.ui.use_toolbars:
            ba.widget(edit=self._scrollwidget,
                      right_widget=_ba.get_special_widget('party_button'))
        ba.containerwidget(edit=self._root_widget,
                           selected_child=self._scrollwidget)

        # ugly: create this last so it gets first dibs at touch events (since
        # we have it close to the scroll widget)
        if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._close)
            ba.widget(edit=self._scrollwidget,
                      left_widget=_ba.get_special_widget('back_button'))
        else:
            btn = ba.buttonwidget(
                parent=self._root_widget,
                position=(x_offs +
                          (40 + 0 if uiscale is ba.UIScale.SMALL else 70),
                          height -
                          (59 if uiscale is ba.UIScale.SMALL else 50)),
                size=(140, 60),
                scale=0.7 if uiscale is ba.UIScale.SMALL else 0.8,
                label=ba.Lstr(
                    resource='backText') if self._main_menu else 'Close',
                button_type='back' if self._main_menu else None,
                extra_touch_border_scale=2.0,
                autoselect=True,
                on_activate_call=self._close)
            ba.containerwidget(edit=self._root_widget, cancel_button=btn)

            if self._main_menu:
                ba.buttonwidget(edit=btn,
                                button_type='backSmall',
                                size=(60, 55),
                                label=ba.charstr(ba.SpecialChar.BACK))

        self._sub_width = 660
        self._sub_height = 1590 + ba.app.lang.get_resource(
            self._r + '.someDaysExtraSpace') + ba.app.lang.get_resource(
                self._r + '.orPunchingSomethingExtraSpace')

        self._subcontainer = ba.containerwidget(parent=self._scrollwidget,
                                                size=(self._sub_width,
                                                      self._sub_height),
                                                background=False,
                                                claims_left_right=False,
                                                claims_tab=False)

        spacing = 1.0
        h = self._sub_width * 0.5
        v = self._sub_height - 55
        logo_tex = ba.gettexture('logo')
        icon_buffer = 1.1
        header = (0.7, 1.0, 0.7, 1.0)
        header2 = (0.8, 0.8, 1.0, 1.0)
        paragraph = (0.8, 0.8, 1.0, 1.0)

        txt = ba.Lstr(resource=self._r + '.welcomeText',
                      subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))
                            ]).evaluate()
        txt_scale = 1.4
        txt_maxwidth = 480
        ba.textwidget(parent=self._subcontainer,
                      position=(h, v),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=0.5,
                      res_scale=1.5,
                      text=txt,
                      h_align='center',
                      color=header,
                      v_align='center',
                      maxwidth=txt_maxwidth)
        txt_width = min(
            txt_maxwidth,
            _ba.get_string_width(txt, suppress_warning=True) * txt_scale)

        icon_size = 70
        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 v - 0.45 * icon_size),
                       texture=logo_tex)

        force_test = False
        app = ba.app
        if (app.platform == 'android'
                and app.subplatform == 'alibaba') or force_test:
            v -= 120.0
            txtv = (
                '\xe8\xbf\x99\xe6\x98\xaf\xe4\xb8\x80\xe4\xb8\xaa\xe5\x8f\xaf'
                '\xe4\xbb\xa5\xe5\x92\x8c\xe5\xae\xb6\xe4\xba\xba\xe6\x9c\x8b'
                '\xe5\x8f\x8b\xe4\xb8\x80\xe8\xb5\xb7\xe7\x8e\xa9\xe7\x9a\x84'
                '\xe6\xb8\xb8\xe6\x88\x8f,\xe5\x90\x8c\xe6\x97\xb6\xe6\x94\xaf'
                '\xe6\x8c\x81\xe8\x81\x94 \xe2\x80\xa8\xe7\xbd\x91\xe5\xaf\xb9'
                '\xe6\x88\x98\xe3\x80\x82\n'
                '\xe5\xa6\x82\xe6\xb2\xa1\xe6\x9c\x89\xe6\xb8\xb8\xe6\x88\x8f'
                '\xe6\x89\x8b\xe6\x9f\x84,\xe5\x8f\xaf\xe4\xbb\xa5\xe4\xbd\xbf'
                '\xe7\x94\xa8\xe7\xa7\xbb\xe5\x8a\xa8\xe8\xae\xbe\xe5\xa4\x87'
                '\xe6\x89\xab\xe7\xa0\x81\xe4\xb8\x8b\xe8\xbd\xbd\xe2\x80\x9c'
                '\xe9\x98\xbf\xe9\x87\x8c\xc2'
                '\xa0TV\xc2\xa0\xe5\x8a\xa9\xe6\x89'
                '\x8b\xe2\x80\x9d\xe7\x94\xa8 \xe6\x9d\xa5\xe4\xbb\xa3\xe6\x9b'
                '\xbf\xe5\xa4\x96\xe8\xae\xbe\xe3\x80\x82\n'
                '\xe6\x9c\x80\xe5\xa4\x9a\xe6\x94\xaf\xe6\x8c\x81\xe6\x8e\xa5'
                '\xe5\x85\xa5\xc2\xa08\xc2\xa0\xe4\xb8\xaa\xe5\xa4\x96\xe8'
                '\xae\xbe')
            ba.textwidget(parent=self._subcontainer,
                          size=(0, 0),
                          h_align='center',
                          v_align='center',
                          maxwidth=self._sub_width * 0.9,
                          position=(self._sub_width * 0.5, v - 180),
                          text=txtv)
            ba.imagewidget(parent=self._subcontainer,
                           position=(self._sub_width - 320, v - 120),
                           size=(200, 200),
                           texture=ba.gettexture('aliControllerQR'))
            ba.imagewidget(parent=self._subcontainer,
                           position=(90, v - 130),
                           size=(210, 210),
                           texture=ba.gettexture('multiplayerExamples'))
            v -= 120.0

        else:
            v -= spacing * 50.0
            txt = ba.Lstr(resource=self._r + '.someDaysText').evaluate()
            ba.textwidget(parent=self._subcontainer,
                          position=(h, v),
                          size=(0, 0),
                          scale=1.2,
                          maxwidth=self._sub_width * 0.9,
                          text=txt,
                          h_align='center',
                          color=paragraph,
                          v_align='center',
                          flatness=1.0)
            v -= (spacing * 25.0 + getres(self._r + '.someDaysExtraSpace'))
            txt_scale = 0.66
            txt = ba.Lstr(resource=self._r +
                          '.orPunchingSomethingText').evaluate()
            ba.textwidget(parent=self._subcontainer,
                          position=(h, v),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=self._sub_width * 0.9,
                          text=txt,
                          h_align='center',
                          color=paragraph,
                          v_align='center',
                          flatness=1.0)
            v -= (spacing * 27.0 +
                  getres(self._r + '.orPunchingSomethingExtraSpace'))
            txt_scale = 1.0
            txt = ba.Lstr(resource=self._r + '.canHelpText',
                          subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))
                                ]).evaluate()
            ba.textwidget(parent=self._subcontainer,
                          position=(h, v),
                          size=(0, 0),
                          scale=txt_scale,
                          flatness=1.0,
                          text=txt,
                          h_align='center',
                          color=paragraph,
                          v_align='center')

            v -= spacing * 70.0
            txt_scale = 1.0
            txt = ba.Lstr(resource=self._r + '.toGetTheMostText').evaluate()
            ba.textwidget(parent=self._subcontainer,
                          position=(h, v),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=self._sub_width * 0.9,
                          text=txt,
                          h_align='center',
                          color=header,
                          v_align='center',
                          flatness=1.0)

            v -= spacing * 40.0
            txt_scale = 0.74
            txt = ba.Lstr(resource=self._r + '.friendsText').evaluate()
            hval2 = h - 220
            ba.textwidget(parent=self._subcontainer,
                          position=(hval2, v),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=100,
                          text=txt,
                          h_align='right',
                          color=header,
                          v_align='center',
                          flatness=1.0)

            txt = ba.Lstr(resource=self._r + '.friendsGoodText',
                          subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))
                                ]).evaluate()
            txt_scale = 0.7
            ba.textwidget(parent=self._subcontainer,
                          position=(hval2 + 10, v + 8),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=500,
                          text=txt,
                          h_align='left',
                          color=paragraph,
                          flatness=1.0)

            app = ba.app

            v -= spacing * 45.0
            txt = (ba.Lstr(resource=self._r + '.devicesText').evaluate()
                   if app.vr_mode else ba.Lstr(resource=self._r +
                                               '.controllersText').evaluate())
            txt_scale = 0.74
            hval2 = h - 220
            ba.textwidget(parent=self._subcontainer,
                          position=(hval2, v),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=100,
                          text=txt,
                          h_align='right',
                          v_align='center',
                          color=header,
                          flatness=1.0)

            txt_scale = 0.7
            if not app.vr_mode:
                infotxt = ('.controllersInfoTextRemoteOnly'
                           if app.iircade_mode else '.controllersInfoText')
                txt = ba.Lstr(
                    resource=self._r + infotxt,
                    fallback_resource=self._r + '.controllersInfoText',
                    subs=[('${APP_NAME}', ba.Lstr(resource='titleText')),
                          ('${REMOTE_APP_NAME}', get_remote_app_name())
                          ]).evaluate()
            else:
                txt = ba.Lstr(resource=self._r + '.devicesInfoText',
                              subs=[('${APP_NAME}',
                                     ba.Lstr(resource='titleText'))
                                    ]).evaluate()

            ba.textwidget(parent=self._subcontainer,
                          position=(hval2 + 10, v + 8),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=500,
                          max_height=105,
                          text=txt,
                          h_align='left',
                          color=paragraph,
                          flatness=1.0)

        v -= spacing * 150.0

        txt = ba.Lstr(resource=self._r + '.controlsText').evaluate()
        txt_scale = 1.4
        txt_maxwidth = 480
        ba.textwidget(parent=self._subcontainer,
                      position=(h, v),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=0.5,
                      text=txt,
                      h_align='center',
                      color=header,
                      v_align='center',
                      res_scale=1.5,
                      maxwidth=txt_maxwidth)
        txt_width = min(
            txt_maxwidth,
            _ba.get_string_width(txt, suppress_warning=True) * txt_scale)
        icon_size = 70

        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 v - 0.45 * icon_size),
                       texture=logo_tex)

        v -= spacing * 45.0

        txt_scale = 0.7
        txt = ba.Lstr(resource=self._r + '.controlsSubtitleText',
                      subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))
                            ]).evaluate()
        ba.textwidget(parent=self._subcontainer,
                      position=(h, v),
                      size=(0, 0),
                      scale=txt_scale,
                      maxwidth=self._sub_width * 0.9,
                      flatness=1.0,
                      text=txt,
                      h_align='center',
                      color=paragraph,
                      v_align='center')
        v -= spacing * 160.0

        sep = 70
        icon_size = 100
        # icon_size_2 = 30
        hval2 = h - sep
        vval2 = v
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 vval2 - 0.5 * icon_size),
                       texture=ba.gettexture('buttonPunch'),
                       color=(1, 0.7, 0.3))

        txt_scale = getres(self._r + '.punchInfoTextScale')
        txt = ba.Lstr(resource=self._r + '.punchInfoText').evaluate()
        ba.textwidget(parent=self._subcontainer,
                      position=(h - sep - 185 + 70, v + 120),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=1.0,
                      text=txt,
                      h_align='center',
                      color=(1, 0.7, 0.3, 1.0),
                      v_align='top')

        hval2 = h + sep
        vval2 = v
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 vval2 - 0.5 * icon_size),
                       texture=ba.gettexture('buttonBomb'),
                       color=(1, 0.3, 0.3))

        txt = ba.Lstr(resource=self._r + '.bombInfoText').evaluate()
        txt_scale = getres(self._r + '.bombInfoTextScale')
        ba.textwidget(parent=self._subcontainer,
                      position=(h + sep + 50 + 60, v - 35),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=1.0,
                      maxwidth=270,
                      text=txt,
                      h_align='center',
                      color=(1, 0.3, 0.3, 1.0),
                      v_align='top')

        hval2 = h
        vval2 = v + sep
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 vval2 - 0.5 * icon_size),
                       texture=ba.gettexture('buttonPickUp'),
                       color=(0.5, 0.5, 1))

        txtl = ba.Lstr(resource=self._r + '.pickUpInfoText')
        txt_scale = getres(self._r + '.pickUpInfoTextScale')
        ba.textwidget(parent=self._subcontainer,
                      position=(h + 60 + 120, v + sep + 50),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=1.0,
                      text=txtl,
                      h_align='center',
                      color=(0.5, 0.5, 1, 1.0),
                      v_align='top')

        hval2 = h
        vval2 = v - sep
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 vval2 - 0.5 * icon_size),
                       texture=ba.gettexture('buttonJump'),
                       color=(0.4, 1, 0.4))

        txt = ba.Lstr(resource=self._r + '.jumpInfoText').evaluate()
        txt_scale = getres(self._r + '.jumpInfoTextScale')
        ba.textwidget(parent=self._subcontainer,
                      position=(h - 250 + 75, v - sep - 15 + 30),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=1.0,
                      text=txt,
                      h_align='center',
                      color=(0.4, 1, 0.4, 1.0),
                      v_align='top')

        txt = ba.Lstr(resource=self._r + '.runInfoText').evaluate()
        txt_scale = getres(self._r + '.runInfoTextScale')
        ba.textwidget(parent=self._subcontainer,
                      position=(h, v - sep - 100),
                      size=(0, 0),
                      scale=txt_scale,
                      maxwidth=self._sub_width * 0.93,
                      flatness=1.0,
                      text=txt,
                      h_align='center',
                      color=(0.7, 0.7, 1.0, 1.0),
                      v_align='center')

        v -= spacing * 280.0

        txt = ba.Lstr(resource=self._r + '.powerupsText').evaluate()
        txt_scale = 1.4
        txt_maxwidth = 480
        ba.textwidget(parent=self._subcontainer,
                      position=(h, v),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=0.5,
                      text=txt,
                      h_align='center',
                      color=header,
                      v_align='center',
                      maxwidth=txt_maxwidth)
        txt_width = min(
            txt_maxwidth,
            _ba.get_string_width(txt, suppress_warning=True) * txt_scale)
        icon_size = 70
        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 v - 0.45 * icon_size),
                       texture=logo_tex)

        v -= spacing * 50.0
        txt_scale = getres(self._r + '.powerupsSubtitleTextScale')
        txt = ba.Lstr(resource=self._r + '.powerupsSubtitleText').evaluate()
        ba.textwidget(parent=self._subcontainer,
                      position=(h, v),
                      size=(0, 0),
                      scale=txt_scale,
                      maxwidth=self._sub_width * 0.9,
                      text=txt,
                      h_align='center',
                      color=paragraph,
                      v_align='center',
                      flatness=1.0)

        v -= spacing * 1.0

        mm1 = -270
        mm2 = -215
        mm3 = 0
        icon_size = 50
        shadow_size = 80
        shadow_offs_x = 3
        shadow_offs_y = -4
        t_big = 1.1
        t_small = 0.65

        shadow_tex = ba.gettexture('shadowSharp')

        for tex in [
                'powerupPunch', 'powerupShield', 'powerupBomb',
                'powerupHealth', 'powerupIceBombs', 'powerupImpactBombs',
                'powerupStickyBombs', 'powerupLandMines', 'powerupCurse'
        ]:
            name = ba.Lstr(resource=self._r + '.' + tex + 'NameText')
            desc = ba.Lstr(resource=self._r + '.' + tex + 'DescriptionText')

            v -= spacing * 60.0

            ba.imagewidget(
                parent=self._subcontainer,
                size=(shadow_size, shadow_size),
                position=(h + mm1 + shadow_offs_x - 0.5 * shadow_size,
                          v + shadow_offs_y - 0.5 * shadow_size),
                texture=shadow_tex,
                color=(0, 0, 0),
                opacity=0.5)
            ba.imagewidget(parent=self._subcontainer,
                           size=(icon_size, icon_size),
                           position=(h + mm1 - 0.5 * icon_size,
                                     v - 0.5 * icon_size),
                           texture=ba.gettexture(tex))

            txt_scale = t_big
            txtl = name
            ba.textwidget(parent=self._subcontainer,
                          position=(h + mm2, v + 3),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=200,
                          flatness=1.0,
                          text=txtl,
                          h_align='left',
                          color=header2,
                          v_align='center')
            txt_scale = t_small
            txtl = desc
            ba.textwidget(parent=self._subcontainer,
                          position=(h + mm3, v),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=300,
                          flatness=1.0,
                          text=txtl,
                          h_align='left',
                          color=paragraph,
                          v_align='center',
                          res_scale=0.5)
Exemple #11
0
    def _refresh(self):
        if self._scrollwidget:
            self._scrollwidget.delete()

        if self._subcontainer:
            self._subcontainer.delete()

        self._scrollwidget = ba.scrollwidget(
            parent=self._root_widget,
            position=((self._width - self._scroll_width) * 0.5,
                      self._height - self._scroll_height - 119),
            size=(self._scroll_width, self._scroll_height))

        entries = bap.repo.get_available_packages()
        entry_height = 35
        icon_size = 35

        self._subcontainerheight = entry_height * len(entries)
        v = self._subcontainerheight

        self._subcontainer = ba.containerwidget(
            parent=self._scrollwidget,
            size=(self._scroll_width, self._subcontainerheight),
            background=False)

        ba.containerwidget(edit=self._scrollwidget,
                           claims_left_right=False,
                           claims_tab=False)
        ba.containerwidget(edit=self._subcontainer,
                           claims_left_right=False,
                           claims_tab=False,
                           selection_loops=False,
                           print_list_exit_instructions=False)
        ba.widget(edit=self._subcontainer, up_widget=self._back_button)

        for num, entry in enumerate(entries):
            cnt = ba.containerwidget(parent=self._subcontainer,
                                     position=(0, v - entry_height),
                                     size=(self._scroll_width, entry_height),
                                     root_selectable=True,
                                     background=False,
                                     click_activate=True,
                                     on_activate_call=ba.Call(
                                         self._on_entry_activated, entry))
            if num == 0:
                ba.widget(edit=cnt, up_widget=self._back_button)
            ba.imagewidget(parent=cnt,
                           size=(icon_size, icon_size),
                           position=(10, 0.5 * entry_height - icon_size * 0.5),
                           opacity=1.0,
                           draw_controller=cnt,
                           texture=ba.gettexture('file'),
                           color=(0.1, 0.9, 0.1))
            ba.textwidget(parent=cnt,
                          draw_controller=cnt,
                          text=entry.name,
                          h_align='left',
                          v_align='center',
                          position=(10 + icon_size * 1.05, entry_height * 0.5),
                          size=(0, 0),
                          maxwidth=self._scroll_width * 0.93 - 50,
                          color=(1, 1, 1, 1))
            ba.textwidget(parent=cnt,
                          draw_controller=cnt,
                          text=entry.version.to_string(),
                          h_align='left',
                          v_align='center',
                          position=(self._scroll_width * 0.93 - 50,
                                    entry_height * 0.5),
                          size=(0, 0),
                          maxwidth=self._scroll_width * 0.93 - 50,
                          color=(1, 1, 1, 1))
            v -= entry_height
Exemple #12
0
    def _refresh(self, file_names: List[str], error: Optional[str]) -> None:
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        if not self._root_widget:
            return

        scrollwidget_selected = (self._scrollwidget is None
                                 or self._root_widget.get_selected_child()
                                 == self._scrollwidget)

        in_top_folder = (self._path == self._base_path)
        hide_top_folder = in_top_folder and self._show_base_path is False

        if hide_top_folder:
            folder_name = ''
        elif self._path == '/':
            folder_name = '/'
        else:
            assert self._path is not None
            folder_name = os.path.basename(self._path)

        b_color = (0.6, 0.53, 0.63)
        b_color_disabled = (0.65, 0.65, 0.65)

        if len(self._recent_paths) < 2:
            ba.buttonwidget(edit=self._back_button,
                            color=b_color_disabled,
                            textcolor=(0.5, 0.5, 0.5))
        else:
            ba.buttonwidget(edit=self._back_button,
                            color=b_color,
                            textcolor=(0.75, 0.7, 0.8))

        max_str_width = 300.0
        str_width = min(
            max_str_width,
            _ba.get_string_width(folder_name, suppress_warning=True))
        ba.textwidget(edit=self._path_text,
                      text=folder_name,
                      maxwidth=max_str_width)
        ba.imagewidget(edit=self._folder_icon,
                       position=(self._folder_center - str_width * 0.5 - 40,
                                 self._height - 117),
                       opacity=0.0 if hide_top_folder else 1.0)

        if self._scrollwidget is not None:
            self._scrollwidget.delete()

        if self._use_folder_button is not None:
            self._use_folder_button.delete()
            ba.widget(edit=self._cancel_button, right_widget=self._back_button)

        self._scrollwidget = ba.scrollwidget(
            parent=self._root_widget,
            position=((self._width - self._scroll_width) * 0.5,
                      self._height - self._scroll_height - 119),
            size=(self._scroll_width, self._scroll_height))

        if scrollwidget_selected:
            ba.containerwidget(edit=self._root_widget,
                               selected_child=self._scrollwidget)

        # show error case..
        if error is not None:
            self._subcontainer = ba.containerwidget(parent=self._scrollwidget,
                                                    size=(self._scroll_width,
                                                          self._scroll_height),
                                                    background=False)
            ba.textwidget(parent=self._subcontainer,
                          color=(1, 1, 0, 1),
                          text=error,
                          maxwidth=self._scroll_width * 0.9,
                          position=(self._scroll_width * 0.48,
                                    self._scroll_height * 0.57),
                          size=(0, 0),
                          h_align='center',
                          v_align='center')

        else:
            file_names = [f for f in file_names if not f.startswith('.')]
            file_names.sort(key=lambda x: x[0].lower())

            entries = file_names
            entry_height = 35
            folder_entry_height = 100
            show_folder_entry = False
            show_use_folder_button = (self._allow_folders
                                      and not in_top_folder)

            self._subcontainerheight = entry_height * len(entries) + (
                folder_entry_height if show_folder_entry else 0)
            v = self._subcontainerheight - (folder_entry_height
                                            if show_folder_entry else 0)

            self._subcontainer = ba.containerwidget(
                parent=self._scrollwidget,
                size=(self._scroll_width, self._subcontainerheight),
                background=False)

            ba.containerwidget(edit=self._scrollwidget,
                               claims_left_right=False,
                               claims_tab=False)
            ba.containerwidget(edit=self._subcontainer,
                               claims_left_right=False,
                               claims_tab=False,
                               selection_loops=False,
                               print_list_exit_instructions=False)
            ba.widget(edit=self._subcontainer, up_widget=self._back_button)

            if show_use_folder_button:
                self._use_folder_button = btn = ba.buttonwidget(
                    parent=self._root_widget,
                    position=(self._width - self._button_width - 35 -
                              self._x_inset, self._height - 67),
                    size=(self._button_width, 50),
                    label=ba.Lstr(resource=self._r +
                                  '.useThisFolderButtonText'),
                    on_activate_call=self._on_folder_entry_activated)
                ba.widget(edit=btn,
                          left_widget=self._cancel_button,
                          down_widget=self._scrollwidget)
                ba.widget(edit=self._cancel_button, right_widget=btn)
                ba.containerwidget(edit=self._root_widget, start_button=btn)

            folder_icon_size = 35
            for num, entry in enumerate(entries):
                cnt = ba.containerwidget(
                    parent=self._subcontainer,
                    position=(0, v - entry_height),
                    size=(self._scroll_width, entry_height),
                    root_selectable=True,
                    background=False,
                    click_activate=True,
                    on_activate_call=ba.Call(self._on_entry_activated, entry))
                if num == 0:
                    ba.widget(edit=cnt, up_widget=self._back_button)
                is_valid_file_path = self._is_valid_file_path(entry)
                assert self._path is not None
                is_dir = os.path.isdir(self._path + '/' + entry)
                if is_dir:
                    ba.imagewidget(parent=cnt,
                                   size=(folder_icon_size, folder_icon_size),
                                   position=(10, 0.5 * entry_height -
                                             folder_icon_size * 0.5),
                                   draw_controller=cnt,
                                   texture=self._folder_tex,
                                   color=self._folder_color)
                else:
                    ba.imagewidget(parent=cnt,
                                   size=(folder_icon_size, folder_icon_size),
                                   position=(10, 0.5 * entry_height -
                                             folder_icon_size * 0.5),
                                   opacity=1.0 if is_valid_file_path else 0.5,
                                   draw_controller=cnt,
                                   texture=self._file_tex,
                                   color=self._file_color)
                ba.textwidget(parent=cnt,
                              draw_controller=cnt,
                              text=entry,
                              h_align='left',
                              v_align='center',
                              position=(10 + folder_icon_size * 1.05,
                                        entry_height * 0.5),
                              size=(0, 0),
                              maxwidth=self._scroll_width * 0.93 - 50,
                              color=(1, 1, 1, 1) if
                              (is_valid_file_path or is_dir) else
                              (0.5, 0.5, 0.5, 1))
                v -= entry_height
Exemple #13
0
    def __init__(self,
                 path: str,
                 callback: Callable[[Optional[str]], Any] = None,
                 show_base_path: bool = True,
                 valid_file_extensions: Sequence[str] = None,
                 allow_folders: bool = False):
        if valid_file_extensions is None:
            valid_file_extensions = []
        uiscale = ba.app.ui.uiscale
        self._width = 700 if uiscale is ba.UIScale.SMALL else 600
        self._x_inset = x_inset = 50 if uiscale is ba.UIScale.SMALL else 0
        self._height = 365 if uiscale is ba.UIScale.SMALL else 418
        self._callback = callback
        self._base_path = path
        self._path: Optional[str] = None
        self._recent_paths: List[str] = []
        self._show_base_path = show_base_path
        self._valid_file_extensions = [
            '.' + ext for ext in valid_file_extensions
        ]
        self._allow_folders = allow_folders
        self._subcontainer: Optional[ba.Widget] = None
        self._subcontainerheight: Optional[float] = None
        self._scroll_width = self._width - (80 + 2 * x_inset)
        self._scroll_height = self._height - 170
        self._r = 'fileSelectorWindow'
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height),
            transition='in_right',
            scale=(2.23 if uiscale is ba.UIScale.SMALL else
                   1.4 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -35) if uiscale is ba.UIScale.SMALL else (0, 0)))
        ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height - 42),
            size=(0, 0),
            color=ba.app.ui.title_color,
            h_align='center',
            v_align='center',
            text=ba.Lstr(resource=self._r + '.titleFolderText') if
            (allow_folders and not valid_file_extensions) else ba.Lstr(
                resource=self._r +
                '.titleFileText') if not allow_folders else ba.Lstr(
                    resource=self._r + '.titleFileFolderText'),
            maxwidth=210)

        self._button_width = 146
        self._cancel_button = ba.buttonwidget(
            parent=self._root_widget,
            position=(35 + x_inset, self._height - 67),
            autoselect=True,
            size=(self._button_width, 50),
            label=ba.Lstr(resource='cancelText'),
            on_activate_call=self._cancel)
        ba.widget(edit=self._cancel_button, left_widget=self._cancel_button)

        b_color = (0.6, 0.53, 0.63)

        self._back_button = ba.buttonwidget(
            parent=self._root_widget,
            button_type='square',
            position=(43 + x_inset, self._height - 113),
            color=b_color,
            textcolor=(0.75, 0.7, 0.8),
            enable_sound=False,
            size=(55, 35),
            label=ba.charstr(ba.SpecialChar.LEFT_ARROW),
            on_activate_call=self._on_back_press)

        self._folder_tex = ba.gettexture('folder')
        self._folder_color = (1.1, 0.8, 0.2)
        self._file_tex = ba.gettexture('file')
        self._file_color = (1, 1, 1)
        self._use_folder_button: Optional[ba.Widget] = None
        self._folder_center = self._width * 0.5 + 15
        self._folder_icon = ba.imagewidget(parent=self._root_widget,
                                           size=(40, 40),
                                           position=(40, self._height - 117),
                                           texture=self._folder_tex,
                                           color=self._folder_color)
        self._path_text = ba.textwidget(parent=self._root_widget,
                                        position=(self._folder_center,
                                                  self._height - 98),
                                        size=(0, 0),
                                        color=ba.app.ui.title_color,
                                        h_align='center',
                                        v_align='center',
                                        text=self._path,
                                        maxwidth=self._width * 0.9)
        self._scrollwidget: Optional[ba.Widget] = None
        ba.containerwidget(edit=self._root_widget,
                           cancel_button=self._cancel_button)
        self._set_path(path)
    def __init__(self,
                 gametype: type[ba.GameActivity],
                 sessiontype: type[ba.Session],
                 config: Optional[dict[str, Any]],
                 completion_call: Callable[[Optional[dict[str, Any]]], Any],
                 default_selection: str = None,
                 transition: str = 'in_right',
                 edit_info: dict[str, Any] = None):
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        from ba.internal import (get_unowned_maps, get_filtered_map_name,
                                 get_map_class, get_map_display_string)
        self._gametype = gametype
        self._sessiontype = sessiontype

        # If we're within an editing session we get passed edit_info
        # (returning from map selection window, etc).
        if edit_info is not None:
            self._edit_info = edit_info

        # ..otherwise determine whether we're adding or editing a game based
        # on whether an existing config was passed to us.
        else:
            if config is None:
                self._edit_info = {'editType': 'add'}
            else:
                self._edit_info = {'editType': 'edit'}

        self._r = 'gameSettingsWindow'

        valid_maps = gametype.get_supported_maps(sessiontype)
        if not valid_maps:
            ba.screenmessage(ba.Lstr(resource='noValidMapsErrorText'))
            raise Exception('No valid maps')

        self._settings_defs = gametype.get_available_settings(sessiontype)
        self._completion_call = completion_call

        # To start with, pick a random map out of the ones we own.
        unowned_maps = get_unowned_maps()
        valid_maps_owned = [m for m in valid_maps if m not in unowned_maps]
        if valid_maps_owned:
            self._map = valid_maps[random.randrange(len(valid_maps_owned))]

        # Hmmm.. we own none of these maps.. just pick a random un-owned one
        # I guess.. should this ever happen?
        else:
            self._map = valid_maps[random.randrange(len(valid_maps))]

        is_add = (self._edit_info['editType'] == 'add')

        # If there's a valid map name in the existing config, use that.
        try:
            if (config is not None and 'settings' in config
                    and 'map' in config['settings']):
                filtered_map_name = get_filtered_map_name(
                    config['settings']['map'])
                if filtered_map_name in valid_maps:
                    self._map = filtered_map_name
        except Exception:
            ba.print_exception('Error getting map for editor.')

        if config is not None and 'settings' in config:
            self._settings = config['settings']
        else:
            self._settings = {}

        self._choice_selections: dict[str, int] = {}

        uiscale = ba.app.ui.uiscale
        width = 720 if uiscale is ba.UIScale.SMALL else 620
        x_inset = 50 if uiscale is ba.UIScale.SMALL else 0
        height = (365 if uiscale is ba.UIScale.SMALL else
                  460 if uiscale is ba.UIScale.MEDIUM else 550)
        spacing = 52
        y_extra = 15
        y_extra2 = 21

        map_tex_name = (get_map_class(self._map).get_preview_texture_name())
        if map_tex_name is None:
            raise Exception('no map preview tex found for' + self._map)
        map_tex = ba.gettexture(map_tex_name)

        top_extra = 20 if uiscale is ba.UIScale.SMALL else 0
        super().__init__(root_widget=ba.containerwidget(
            size=(width, height + top_extra),
            transition=transition,
            scale=(2.19 if uiscale is ba.UIScale.SMALL else
                   1.35 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -17) if uiscale is ba.UIScale.SMALL else (0, 0)))

        btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(45 + x_inset, height - 82 + y_extra2),
            size=(180, 70) if is_add else (180, 65),
            label=ba.Lstr(resource='backText') if is_add else ba.Lstr(
                resource='cancelText'),
            button_type='back' if is_add else None,
            autoselect=True,
            scale=0.75,
            text_scale=1.3,
            on_activate_call=ba.Call(self._cancel))
        ba.containerwidget(edit=self._root_widget, cancel_button=btn)

        add_button = ba.buttonwidget(
            parent=self._root_widget,
            position=(width - (193 + x_inset), height - 82 + y_extra2),
            size=(200, 65),
            scale=0.75,
            text_scale=1.3,
            label=ba.Lstr(resource=self._r +
                          '.addGameText') if is_add else ba.Lstr(
                              resource='doneText'))

        if ba.app.ui.use_toolbars:
            pbtn = _ba.get_special_widget('party_button')
            ba.widget(edit=add_button, right_widget=pbtn, up_widget=pbtn)

        ba.textwidget(parent=self._root_widget,
                      position=(-8, height - 70 + y_extra2),
                      size=(width, 25),
                      text=gametype.get_display_string(),
                      color=ba.app.ui.title_color,
                      maxwidth=235,
                      scale=1.1,
                      h_align='center',
                      v_align='center')

        map_height = 100

        scroll_height = map_height + 10  # map select and margin

        # Calc our total height we'll need
        scroll_height += spacing * len(self._settings_defs)

        scroll_width = width - (86 + 2 * x_inset)
        self._scrollwidget = ba.scrollwidget(parent=self._root_widget,
                                             position=(44 + x_inset,
                                                       35 + y_extra),
                                             size=(scroll_width, height - 116),
                                             highlight=False,
                                             claims_left_right=True,
                                             claims_tab=True,
                                             selection_loops_to_parent=True)
        self._subcontainer = ba.containerwidget(parent=self._scrollwidget,
                                                size=(scroll_width,
                                                      scroll_height),
                                                background=False,
                                                claims_left_right=True,
                                                claims_tab=True,
                                                selection_loops_to_parent=True)

        v = scroll_height - 5
        h = -40

        # Keep track of all the selectable widgets we make so we can wire
        # them up conveniently.
        widget_column: list[list[ba.Widget]] = []

        # Map select button.
        ba.textwidget(parent=self._subcontainer,
                      position=(h + 49, v - 63),
                      size=(100, 30),
                      maxwidth=110,
                      text=ba.Lstr(resource='mapText'),
                      h_align='left',
                      color=(0.8, 0.8, 0.8, 1.0),
                      v_align='center')

        ba.imagewidget(
            parent=self._subcontainer,
            size=(256 * 0.7, 125 * 0.7),
            position=(h + 261 - 128 + 128.0 * 0.56, v - 90),
            texture=map_tex,
            model_opaque=ba.getmodel('level_select_button_opaque'),
            model_transparent=ba.getmodel('level_select_button_transparent'),
            mask_texture=ba.gettexture('mapPreviewMask'))
        map_button = btn = ba.buttonwidget(
            parent=self._subcontainer,
            size=(140, 60),
            position=(h + 448, v - 72),
            on_activate_call=ba.Call(self._select_map),
            scale=0.7,
            label=ba.Lstr(resource='mapSelectText'))
        widget_column.append([btn])

        ba.textwidget(parent=self._subcontainer,
                      position=(h + 363 - 123, v - 114),
                      size=(100, 30),
                      flatness=1.0,
                      shadow=1.0,
                      scale=0.55,
                      maxwidth=256 * 0.7 * 0.8,
                      text=get_map_display_string(self._map),
                      h_align='center',
                      color=(0.6, 1.0, 0.6, 1.0),
                      v_align='center')
        v -= map_height

        for setting in self._settings_defs:
            value = setting.default
            value_type = type(value)

            # Now, if there's an existing value for it in the config,
            # override with that.
            try:
                if (config is not None and 'settings' in config
                        and setting.name in config['settings']):
                    value = value_type(config['settings'][setting.name])
            except Exception:
                ba.print_exception()

            # Shove the starting value in there to start.
            self._settings[setting.name] = value

            name_translated = self._get_localized_setting_name(setting.name)

            mw1 = 280
            mw2 = 70

            # Handle types with choices specially:
            if isinstance(setting, ba.ChoiceSetting):
                for choice in setting.choices:
                    if len(choice) != 2:
                        raise ValueError(
                            "Expected 2-member tuples for 'choices'; got: " +
                            repr(choice))
                    if not isinstance(choice[0], str):
                        raise TypeError(
                            'First value for choice tuple must be a str; got: '
                            + repr(choice))
                    if not isinstance(choice[1], value_type):
                        raise TypeError(
                            'Choice type does not match default value; choice:'
                            + repr(choice) + '; setting:' + repr(setting))
                if value_type not in (int, float):
                    raise TypeError(
                        'Choice type setting must have int or float default; '
                        'got: ' + repr(setting))

                # Start at the choice corresponding to the default if possible.
                self._choice_selections[setting.name] = 0
                for index, choice in enumerate(setting.choices):
                    if choice[1] == value:
                        self._choice_selections[setting.name] = index
                        break

                v -= spacing
                ba.textwidget(parent=self._subcontainer,
                              position=(h + 50, v),
                              size=(100, 30),
                              maxwidth=mw1,
                              text=name_translated,
                              h_align='left',
                              color=(0.8, 0.8, 0.8, 1.0),
                              v_align='center')
                txt = ba.textwidget(
                    parent=self._subcontainer,
                    position=(h + 509 - 95, v),
                    size=(0, 28),
                    text=self._get_localized_setting_name(setting.choices[
                        self._choice_selections[setting.name]][0]),
                    editable=False,
                    color=(0.6, 1.0, 0.6, 1.0),
                    maxwidth=mw2,
                    h_align='right',
                    v_align='center',
                    padding=2)
                btn1 = ba.buttonwidget(parent=self._subcontainer,
                                       position=(h + 509 - 50 - 1, v),
                                       size=(28, 28),
                                       label='<',
                                       autoselect=True,
                                       on_activate_call=ba.Call(
                                           self._choice_inc, setting.name, txt,
                                           setting, -1),
                                       repeat=True)
                btn2 = ba.buttonwidget(parent=self._subcontainer,
                                       position=(h + 509 + 5, v),
                                       size=(28, 28),
                                       label='>',
                                       autoselect=True,
                                       on_activate_call=ba.Call(
                                           self._choice_inc, setting.name, txt,
                                           setting, 1),
                                       repeat=True)
                widget_column.append([btn1, btn2])

            elif isinstance(setting, (ba.IntSetting, ba.FloatSetting)):
                v -= spacing
                min_value = setting.min_value
                max_value = setting.max_value
                increment = setting.increment
                ba.textwidget(parent=self._subcontainer,
                              position=(h + 50, v),
                              size=(100, 30),
                              text=name_translated,
                              h_align='left',
                              color=(0.8, 0.8, 0.8, 1.0),
                              v_align='center',
                              maxwidth=mw1)
                txt = ba.textwidget(parent=self._subcontainer,
                                    position=(h + 509 - 95, v),
                                    size=(0, 28),
                                    text=str(value),
                                    editable=False,
                                    color=(0.6, 1.0, 0.6, 1.0),
                                    maxwidth=mw2,
                                    h_align='right',
                                    v_align='center',
                                    padding=2)
                btn1 = ba.buttonwidget(parent=self._subcontainer,
                                       position=(h + 509 - 50 - 1, v),
                                       size=(28, 28),
                                       label='-',
                                       autoselect=True,
                                       on_activate_call=ba.Call(
                                           self._inc, txt, min_value,
                                           max_value, -increment, value_type,
                                           setting.name),
                                       repeat=True)
                btn2 = ba.buttonwidget(parent=self._subcontainer,
                                       position=(h + 509 + 5, v),
                                       size=(28, 28),
                                       label='+',
                                       autoselect=True,
                                       on_activate_call=ba.Call(
                                           self._inc, txt, min_value,
                                           max_value, increment, value_type,
                                           setting.name),
                                       repeat=True)
                widget_column.append([btn1, btn2])

            elif value_type == bool:
                v -= spacing
                ba.textwidget(parent=self._subcontainer,
                              position=(h + 50, v),
                              size=(100, 30),
                              text=name_translated,
                              h_align='left',
                              color=(0.8, 0.8, 0.8, 1.0),
                              v_align='center',
                              maxwidth=mw1)
                txt = ba.textwidget(
                    parent=self._subcontainer,
                    position=(h + 509 - 95, v),
                    size=(0, 28),
                    text=ba.Lstr(resource='onText') if value else ba.Lstr(
                        resource='offText'),
                    editable=False,
                    color=(0.6, 1.0, 0.6, 1.0),
                    maxwidth=mw2,
                    h_align='right',
                    v_align='center',
                    padding=2)
                cbw = ba.checkboxwidget(parent=self._subcontainer,
                                        text='',
                                        position=(h + 505 - 50 - 5, v - 2),
                                        size=(200, 30),
                                        autoselect=True,
                                        textcolor=(0.8, 0.8, 0.8),
                                        value=value,
                                        on_value_change_call=ba.Call(
                                            self._check_value_change,
                                            setting.name, txt))
                widget_column.append([cbw])

            else:
                raise Exception()

        # Ok now wire up the column.
        try:
            # pylint: disable=unsubscriptable-object
            prev_widgets: Optional[list[ba.Widget]] = None
            for cwdg in widget_column:
                if prev_widgets is not None:
                    # Wire our rightmost to their rightmost.
                    ba.widget(edit=prev_widgets[-1], down_widget=cwdg[-1])
                    ba.widget(cwdg[-1], up_widget=prev_widgets[-1])

                    # Wire our leftmost to their leftmost.
                    ba.widget(edit=prev_widgets[0], down_widget=cwdg[0])
                    ba.widget(cwdg[0], up_widget=prev_widgets[0])
                prev_widgets = cwdg
        except Exception:
            ba.print_exception(
                'Error wiring up game-settings-select widget column.')

        ba.buttonwidget(edit=add_button, on_activate_call=ba.Call(self._add))
        ba.containerwidget(edit=self._root_widget,
                           selected_child=add_button,
                           start_button=add_button)

        if default_selection == 'map':
            ba.containerwidget(edit=self._root_widget,
                               selected_child=self._scrollwidget)
            ba.containerwidget(edit=self._subcontainer,
                               selected_child=map_button)
Exemple #15
0
    def __init__(self,
                 transition: Optional[str] = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        ba.set_analytics_screen('Gather Window')
        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
        ba.app.ui.set_main_menu_location('Gather')
        _ba.set_party_icon_always_visible(True)
        uiscale = ba.app.ui.uiscale
        self._width = 1240 if uiscale is ba.UIScale.SMALL else 1040
        x_offs = 100 if uiscale is ba.UIScale.SMALL else 0
        self._height = (582 if uiscale is ba.UIScale.SMALL else
                        680 if uiscale is ba.UIScale.MEDIUM else 800)
        self._current_tab: Optional[GatherWindow.TabID] = None
        extra_top = 20 if uiscale is ba.UIScale.SMALL else 0
        self._r = 'gatherWindow'

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + extra_top),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(1.3 if uiscale is ba.UIScale.SMALL else
                   0.97 if uiscale is ba.UIScale.MEDIUM else 0.8),
            stack_offset=(0, -11) if uiscale is ba.UIScale.SMALL else (
                0, 0) if uiscale is ba.UIScale.MEDIUM else (0, 0)))

        if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._back)
            self._back_button = None
        else:
            self._back_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                position=(70 + x_offs, self._height - 74),
                size=(140, 60),
                scale=1.1,
                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.buttonwidget(edit=btn,
                            button_type='backSmall',
                            position=(70 + x_offs, self._height - 78),
                            size=(60, 60),
                            label=ba.charstr(ba.SpecialChar.BACK))

        condensed = uiscale is not ba.UIScale.LARGE
        t_offs_y = (0 if not condensed else
                    25 if uiscale is ba.UIScale.MEDIUM else 17)
        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5,
                                self._height - 42 + t_offs_y),
                      size=(0, 0),
                      color=ba.app.ui.title_color,
                      scale=(1.5 if not condensed else
                             1.0 if uiscale is ba.UIScale.MEDIUM else 0.6),
                      h_align='center',
                      v_align='center',
                      text=ba.Lstr(resource=self._r + '.titleText'),
                      maxwidth=550)

        platform = ba.app.platform
        subplatform = ba.app.subplatform

        scroll_buffer_h = 130 + 2 * x_offs
        tab_buffer_h = ((320 if condensed else 250) + 2 * x_offs)

        # Build up the set of tabs we want.
        tabdefs: List[Tuple[GatherWindow.TabID, ba.Lstr]] = [
            (self.TabID.ABOUT, ba.Lstr(resource=self._r + '.aboutText'))
        ]
        if _ba.get_account_misc_read_val('enablePublicParties', True):
            tabdefs.append((self.TabID.INTERNET,
                            ba.Lstr(resource=self._r + '.internetText')))
        if platform == 'android' and subplatform == 'google':
            tabdefs.append((self.TabID.GOOGLE_PLAY,
                            ba.Lstr(resource=self._r + '.googlePlayText')))
        tabdefs.append((self.TabID.LOCAL_NETWORK,
                        ba.Lstr(resource=self._r + '.localNetworkText')))
        tabdefs.append(
            (self.TabID.MANUAL, ba.Lstr(resource=self._r + '.manualText')))

        # On small UI, push our tabs up closer to the top of the screen to
        # save a bit of space.
        tabs_top_extra = 42 if condensed else 0
        self._tab_row = TabRow(self._root_widget,
                               tabdefs,
                               pos=(tab_buffer_h * 0.5,
                                    self._height - 130 + tabs_top_extra),
                               size=(self._width - tab_buffer_h, 50),
                               on_select_call=ba.WeakCall(self._set_tab))

        # Now instantiate handlers for these tabs.
        tabtypes: Dict[GatherWindow.TabID, Type[GatherTab]] = {
            self.TabID.ABOUT: AboutGatherTab,
            self.TabID.MANUAL: ManualGatherTab,
            self.TabID.GOOGLE_PLAY: GooglePlayGatherTab,
            self.TabID.INTERNET: PublicGatherTab,
            self.TabID.LOCAL_NETWORK: NearbyGatherTab
        }
        self._tabs: Dict[GatherWindow.TabID, GatherTab] = {}
        for tab_id in self._tab_row.tabs:
            tabtype = tabtypes.get(tab_id)
            if tabtype is not None:
                self._tabs[tab_id] = tabtype(self)

        if ba.app.ui.use_toolbars:
            ba.widget(edit=self._tab_row.tabs[tabdefs[-1][0]].button,
                      right_widget=_ba.get_special_widget('party_button'))
            if uiscale is ba.UIScale.SMALL:
                ba.widget(edit=self._tab_row.tabs[tabdefs[0][0]].button,
                          left_widget=_ba.get_special_widget('back_button'))

        self._scroll_width = self._width - scroll_buffer_h
        self._scroll_height = self._height - 180.0 + tabs_top_extra

        self._scroll_left = (self._width - self._scroll_width) * 0.5
        self._scroll_bottom = (self._height - self._scroll_height - 79 - 48 +
                               tabs_top_extra)
        buffer_h = 10
        buffer_v = 4

        # Not actually using a scroll widget anymore; just an image.
        ba.imagewidget(parent=self._root_widget,
                       position=(self._scroll_left - buffer_h,
                                 self._scroll_bottom - buffer_v),
                       size=(self._scroll_width + 2 * buffer_h,
                             self._scroll_height + 2 * buffer_v),
                       texture=ba.gettexture('scrollWidget'),
                       model_transparent=ba.getmodel('softEdgeOutside'))
        self._tab_container: Optional[ba.Widget] = None

        self._restore_state()
Exemple #16
0
    def __init__(self,
                 transition: str = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        ba.set_analytics_screen('Settings Window')
        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
        width = 900 if ba.app.small_ui else 580
        x_inset = 75 if ba.app.small_ui else 0
        height = 435
        # button_height = 42
        self._r = 'settingsWindow'
        top_extra = 20 if ba.app.small_ui else 0

        super().__init__(root_widget=ba.containerwidget(
            size=(width, height + top_extra),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(
                1.75 if ba.app.small_ui else 1.35 if ba.app.med_ui else 1.0),
            stack_offset=(0, -8) if ba.app.small_ui else (0, 0)))

        if ba.app.toolbars and ba.app.small_ui:
            self._back_button = None
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._do_back)
        else:
            self._back_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                autoselect=True,
                position=(40 + x_inset, height - 55),
                size=(130, 60),
                scale=0.8,
                text_scale=1.2,
                label=ba.Lstr(resource='backText'),
                button_type='back',
                on_activate_call=self._do_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.title_color,
                      h_align='center',
                      v_align='center',
                      maxwidth=130)

        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))

        v = height - 80
        v -= 145

        basew = 280 if ba.app.small_ui else 230
        baseh = 170
        x_offs = x_inset + (105
                            if ba.app.small_ui else 72) - basew  # now unused
        x_offs2 = x_offs + basew - 7
        x_offs3 = x_offs + 2 * (basew - 7)
        x_offs4 = x_offs2
        x_offs5 = x_offs3

        def _b_title(x: float, y: float, button: ba.Widget,
                     text: Union[str, ba.Lstr]) -> None:
            ba.textwidget(parent=self._root_widget,
                          text=text,
                          position=(x + basew * 0.47, y + baseh * 0.22),
                          maxwidth=basew * 0.7,
                          size=(0, 0),
                          h_align='center',
                          v_align='center',
                          draw_controller=button,
                          color=(0.7, 0.9, 0.7, 1.0))

        ctb = self._controllers_button = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(x_offs2, v),
            size=(basew, baseh),
            button_type='square',
            label='',
            on_activate_call=self._do_controllers)
        if ba.app.toolbars and self._back_button is None:
            bbtn = _ba.get_special_widget('back_button')
            ba.widget(edit=ctb, left_widget=bbtn)
        _b_title(x_offs2, v, ctb,
                 ba.Lstr(resource=self._r + '.controllersText'))
        imgw = imgh = 130
        ba.imagewidget(parent=self._root_widget,
                       position=(x_offs2 + basew * 0.49 - imgw * 0.5, v + 35),
                       size=(imgw, imgh),
                       texture=ba.gettexture('controllerIcon'),
                       draw_controller=ctb)

        gfxb = self._graphics_button = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(x_offs3, v),
            size=(basew, baseh),
            button_type='square',
            label='',
            on_activate_call=self._do_graphics)
        if ba.app.toolbars:
            pbtn = _ba.get_special_widget('party_button')
            ba.widget(edit=gfxb, up_widget=pbtn, right_widget=pbtn)
        _b_title(x_offs3, v, gfxb, ba.Lstr(resource=self._r + '.graphicsText'))
        imgw = imgh = 110
        ba.imagewidget(parent=self._root_widget,
                       position=(x_offs3 + basew * 0.49 - imgw * 0.5, v + 42),
                       size=(imgw, imgh),
                       texture=ba.gettexture('graphicsIcon'),
                       draw_controller=gfxb)

        v -= (baseh - 5)

        abtn = self._audio_button = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(x_offs4, v),
            size=(basew, baseh),
            button_type='square',
            label='',
            on_activate_call=self._do_audio)
        _b_title(x_offs4, v, abtn, ba.Lstr(resource=self._r + '.audioText'))
        imgw = imgh = 120
        ba.imagewidget(parent=self._root_widget,
                       position=(x_offs4 + basew * 0.49 - imgw * 0.5 + 5,
                                 v + 35),
                       size=(imgw, imgh),
                       color=(1, 1, 0),
                       texture=ba.gettexture('audioIcon'),
                       draw_controller=abtn)

        avb = self._advanced_button = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(x_offs5, v),
            size=(basew, baseh),
            button_type='square',
            label='',
            on_activate_call=self._do_advanced)
        _b_title(x_offs5, v, avb, ba.Lstr(resource=self._r + '.advancedText'))
        imgw = imgh = 120
        ba.imagewidget(parent=self._root_widget,
                       position=(x_offs5 + basew * 0.49 - imgw * 0.5 + 5,
                                 v + 35),
                       size=(imgw, imgh),
                       color=(0.8, 0.95, 1),
                       texture=ba.gettexture('advancedIcon'),
                       draw_controller=avb)
Exemple #17
0
    def __init__(self, transition: str = 'in_right'):
        # pylint: disable=too-many-locals, too-many-statements
        from bastd.ui import confirm
        self._width = 720.0
        self._height = 340.0

        def _do_cancel() -> None:
            confirm.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'),
                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 bool(False):
            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 - 37.5,
                           y_extra + 120) if not self._show_multiplayer else
                          (self._width + 100,
                           y_extra + (140 if ba.app.small_ui else 120))),
                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)
Exemple #18
0
    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)
 def _update(self) -> None:
     have = ba.app.accounts.have_pro_options()
     for lock in self._lock_images:
         ba.imagewidget(edit=lock, opacity=0.0 if have else 1.0)
Exemple #20
0
    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-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:
            scale = (2.3
                     if ba.app.small_ui else 1.65 if ba.app.med_ui 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.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.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()
Exemple #21
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.title_color,
                      h_align='left',
                      v_align='center')

        index = 0
        bs_config = 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

        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.toolbars and ba.app.small_ui:
                    ba.widget(
                        edit=btn,
                        left_widget=_ba.get_special_widget('back_button'))
                if x == columns - 1 and ba.app.toolbars and ba.app.small_ui:
                    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.TeamsSession:
                            playlist = get_default_teams_playlist()
                        else:
                            raise Exception("unrecognized session-type: " +
                                            str(self._sessiontype))
                    else:
                        if name not in bs_config[self._pvars.config_name +
                                                 ' Playlists']:
                            print(
                                'NOT FOUND ERR',
                                bs_config[self._pvars.config_name +
                                          ' Playlists'])
                        playlist = bs_config[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 Exception:
                            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()
Exemple #22
0
    def _on_query_response(self, data: Optional[dict[str, Any]]) -> None:
        # FIXME: Tidy this up.
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-nested-blocks
        if data is None:
            ba.textwidget(
                edit=self._loading_text,
                text=ba.Lstr(resource='internal.unavailableNoConnectionText'))
        else:
            try:
                self._loading_text.delete()
                trophystr = ''
                try:
                    trophystr = data['trophies']
                    num = 10
                    chunks = [
                        trophystr[i:i + num]
                        for i in range(0, len(trophystr), num)
                    ]
                    trophystr = ('\n\n'.join(chunks))
                    if trophystr == '':
                        trophystr = '-'
                except Exception:
                    ba.print_exception('Error displaying trophies.')
                account_name_spacing = 15
                tscale = 0.65
                ts_height = _ba.get_string_height(trophystr,
                                                  suppress_warning=True)
                sub_width = self._width - 80
                sub_height = 200 + ts_height * tscale + \
                    account_name_spacing * len(data['accountDisplayStrings'])
                self._subcontainer = ba.containerwidget(
                    parent=self._scrollwidget,
                    size=(sub_width, sub_height),
                    background=False)
                v = sub_height - 20

                title_scale = 0.37
                center = 0.3
                maxwidth_scale = 0.45
                showing_character = False
                if data['profileDisplayString'] is not None:
                    tint_color = (1, 1, 1)
                    try:
                        if data['profile'] is not None:
                            profile = data['profile']
                            character = ba.app.spaz_appearances.get(
                                profile['character'], None)
                            if character is not None:
                                tint_color = (profile['color'] if 'color'
                                              in profile else (1, 1, 1))
                                tint2_color = (profile['highlight']
                                               if 'highlight' in profile else
                                               (1, 1, 1))
                                icon_tex = character.icon_texture
                                tint_tex = character.icon_mask_texture
                                mask_texture = ba.gettexture(
                                    'characterIconMask')
                                ba.imagewidget(
                                    parent=self._subcontainer,
                                    position=(sub_width * center - 40, v - 80),
                                    size=(80, 80),
                                    color=(1, 1, 1),
                                    mask_texture=mask_texture,
                                    texture=ba.gettexture(icon_tex),
                                    tint_texture=ba.gettexture(tint_tex),
                                    tint_color=tint_color,
                                    tint2_color=tint2_color)
                                v -= 95
                    except Exception:
                        ba.print_exception('Error displaying character.')
                    ba.textwidget(
                        parent=self._subcontainer,
                        size=(0, 0),
                        position=(sub_width * center, v),
                        h_align='center',
                        v_align='center',
                        scale=0.9,
                        color=ba.safecolor(tint_color, 0.7),
                        shadow=1.0,
                        text=ba.Lstr(value=data['profileDisplayString']),
                        maxwidth=sub_width * maxwidth_scale * 0.75)
                    showing_character = True
                    v -= 33

                center = 0.75 if showing_character else 0.5
                maxwidth_scale = 0.45 if showing_character else 0.9

                v = sub_height - 20
                if len(data['accountDisplayStrings']) <= 1:
                    account_title = ba.Lstr(
                        resource='settingsWindow.accountText')
                else:
                    account_title = ba.Lstr(
                        resource='accountSettingsWindow.accountsText',
                        fallback_resource='settingsWindow.accountText')
                ba.textwidget(parent=self._subcontainer,
                              size=(0, 0),
                              position=(sub_width * center, v),
                              flatness=1.0,
                              h_align='center',
                              v_align='center',
                              scale=title_scale,
                              color=ba.app.ui.infotextcolor,
                              text=account_title,
                              maxwidth=sub_width * maxwidth_scale)
                draw_small = (showing_character
                              or len(data['accountDisplayStrings']) > 1)
                v -= 14 if draw_small else 20
                for account_string in data['accountDisplayStrings']:
                    ba.textwidget(parent=self._subcontainer,
                                  size=(0, 0),
                                  position=(sub_width * center, v),
                                  h_align='center',
                                  v_align='center',
                                  scale=0.55 if draw_small else 0.8,
                                  text=account_string,
                                  maxwidth=sub_width * maxwidth_scale)
                    v -= account_name_spacing

                v += account_name_spacing
                v -= 25 if showing_character else 29

                ba.textwidget(parent=self._subcontainer,
                              size=(0, 0),
                              position=(sub_width * center, v),
                              flatness=1.0,
                              h_align='center',
                              v_align='center',
                              scale=title_scale,
                              color=ba.app.ui.infotextcolor,
                              text=ba.Lstr(resource='rankText'),
                              maxwidth=sub_width * maxwidth_scale)
                v -= 14
                if data['rank'] is None:
                    rank_str = '-'
                    suffix_offset = None
                else:
                    str_raw = ba.Lstr(
                        resource='league.rankInLeagueText').evaluate()
                    # FIXME: Would be nice to not have to eval this.
                    rank_str = ba.Lstr(
                        resource='league.rankInLeagueText',
                        subs=[('${RANK}', str(data['rank'][2])),
                              ('${NAME}',
                               ba.Lstr(translate=('leagueNames',
                                                  data['rank'][0]))),
                              ('${SUFFIX}', '')]).evaluate()
                    rank_str_width = min(
                        sub_width * maxwidth_scale,
                        _ba.get_string_width(rank_str, suppress_warning=True) *
                        0.55)

                    # Only tack our suffix on if its at the end and only for
                    # non-diamond leagues.
                    if (str_raw.endswith('${SUFFIX}')
                            and data['rank'][0] != 'Diamond'):
                        suffix_offset = rank_str_width * 0.5 + 2
                    else:
                        suffix_offset = None

                ba.textwidget(parent=self._subcontainer,
                              size=(0, 0),
                              position=(sub_width * center, v),
                              h_align='center',
                              v_align='center',
                              scale=0.55,
                              text=rank_str,
                              maxwidth=sub_width * maxwidth_scale)
                if suffix_offset is not None:
                    assert data['rank'] is not None
                    ba.textwidget(parent=self._subcontainer,
                                  size=(0, 0),
                                  position=(sub_width * center + suffix_offset,
                                            v + 3),
                                  h_align='left',
                                  v_align='center',
                                  scale=0.29,
                                  flatness=1.0,
                                  text='[' + str(data['rank'][1]) + ']')
                v -= 14

                str_raw = ba.Lstr(
                    resource='league.rankInLeagueText').evaluate()
                old_offs = -50
                prev_ranks_shown = 0
                for prev_rank in data['prevRanks']:
                    rank_str = ba.Lstr(
                        value='${S}:    ${I}',
                        subs=[
                            ('${S}',
                             ba.Lstr(resource='league.seasonText',
                                     subs=[('${NUMBER}', str(prev_rank[0]))])),
                            ('${I}',
                             ba.Lstr(resource='league.rankInLeagueText',
                                     subs=[('${RANK}', str(prev_rank[3])),
                                           ('${NAME}',
                                            ba.Lstr(translate=('leagueNames',
                                                               prev_rank[1]))),
                                           ('${SUFFIX}', '')]))
                        ]).evaluate()
                    rank_str_width = min(
                        sub_width * maxwidth_scale,
                        _ba.get_string_width(rank_str, suppress_warning=True) *
                        0.3)

                    # Only tack our suffix on if its at the end and only for
                    # non-diamond leagues.
                    if (str_raw.endswith('${SUFFIX}')
                            and prev_rank[1] != 'Diamond'):
                        suffix_offset = rank_str_width + 2
                    else:
                        suffix_offset = None
                    ba.textwidget(parent=self._subcontainer,
                                  size=(0, 0),
                                  position=(sub_width * center + old_offs, v),
                                  h_align='left',
                                  v_align='center',
                                  scale=0.3,
                                  text=rank_str,
                                  flatness=1.0,
                                  maxwidth=sub_width * maxwidth_scale)
                    if suffix_offset is not None:
                        ba.textwidget(parent=self._subcontainer,
                                      size=(0, 0),
                                      position=(sub_width * center + old_offs +
                                                suffix_offset, v + 1),
                                      h_align='left',
                                      v_align='center',
                                      scale=0.20,
                                      flatness=1.0,
                                      text='[' + str(prev_rank[2]) + ']')
                    prev_ranks_shown += 1
                    v -= 10

                v -= 13

                ba.textwidget(parent=self._subcontainer,
                              size=(0, 0),
                              position=(sub_width * center, v),
                              flatness=1.0,
                              h_align='center',
                              v_align='center',
                              scale=title_scale,
                              color=ba.app.ui.infotextcolor,
                              text=ba.Lstr(resource='achievementsText'),
                              maxwidth=sub_width * maxwidth_scale)
                v -= 14
                ba.textwidget(parent=self._subcontainer,
                              size=(0, 0),
                              position=(sub_width * center, v),
                              h_align='center',
                              v_align='center',
                              scale=0.55,
                              text=str(data['achievementsCompleted']) + ' / ' +
                              str(len(ba.app.ach.achievements)),
                              maxwidth=sub_width * maxwidth_scale)
                v -= 25

                if prev_ranks_shown == 0 and showing_character:
                    v -= 20
                elif prev_ranks_shown == 1 and showing_character:
                    v -= 10

                center = 0.5
                maxwidth_scale = 0.9

                ba.textwidget(parent=self._subcontainer,
                              size=(0, 0),
                              position=(sub_width * center, v),
                              h_align='center',
                              v_align='center',
                              scale=title_scale,
                              color=ba.app.ui.infotextcolor,
                              flatness=1.0,
                              text=ba.Lstr(resource='trophiesThisSeasonText',
                                           fallback_resource='trophiesText'),
                              maxwidth=sub_width * maxwidth_scale)
                v -= 19
                ba.textwidget(parent=self._subcontainer,
                              size=(0, ts_height),
                              position=(sub_width * 0.5,
                                        v - ts_height * tscale),
                              h_align='center',
                              v_align='top',
                              corner_scale=tscale,
                              text=trophystr)

            except Exception:
                ba.print_exception('Error displaying account info.')
Exemple #23
0
    def __init__(self,
                 transition: str = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        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()

        new_style = True
        uiscale = ba.app.uiscale
        width = 1000 if uiscale is ba.UIScale.SMALL else 800
        x_offs = 100 if uiscale is ba.UIScale.SMALL else 0
        height = 550 if new_style else 400
        button_width = 400

        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 = 'playWindow'

        super().__init__(root_widget=ba.containerwidget(
            size=(width, height),
            transition=transition,
            toolbar_visibility='menu_full',
            scale_origin_stack_offset=scale_origin,
            scale=((1.6 if new_style else 1.52) if uiscale is ba.UIScale.SMALL
                   else 0.9 if uiscale is ba.UIScale.MEDIUM else 0.8),
            stack_offset=((0, 0) if new_style else (
                10, 7)) if uiscale is ba.UIScale.SMALL else (0, 0)))
        self._back_button = back_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(55 + x_offs, height - 132) if new_style else
            (55, height - 92),
            size=(120, 60),
            scale=1.1,
            text_res_scale=1.5,
            text_scale=1.2,
            autoselect=True,
            label=ba.Lstr(resource='backText'),
            button_type='back')

        txt = ba.textwidget(parent=self._root_widget,
                            position=(width * 0.5,
                                      height - (101 if new_style else 61)),
                            size=(0, 0),
                            text=ba.Lstr(resource=self._r + '.titleText'),
                            scale=1.7,
                            res_scale=2.0,
                            maxwidth=400,
                            color=ba.app.ui.heading_color,
                            h_align='center',
                            v_align='center')

        ba.buttonwidget(edit=btn,
                        button_type='backSmall',
                        size=(60, 60),
                        label=ba.charstr(ba.SpecialChar.BACK))
        if ba.app.ui.use_toolbars and uiscale is ba.UIScale.SMALL:
            ba.textwidget(edit=txt, text='')

        v = height - (110 if new_style else 60)
        v -= 100
        clr = (0.6, 0.7, 0.6, 1.0)
        v -= 280 if new_style else 180
        v += (30
              if ba.app.ui.use_toolbars and uiscale is ba.UIScale.SMALL else 0)
        hoffs = x_offs + 80 if new_style else 0
        scl = 1.13 if new_style else 0.68

        self._lineup_tex = ba.gettexture('playerLineup')
        angry_computer_transparent_model = ba.getmodel(
            'angryComputerTransparent')
        self._lineup_1_transparent_model = ba.getmodel(
            'playerLineup1Transparent')
        self._lineup_2_transparent_model = ba.getmodel(
            'playerLineup2Transparent')
        self._lineup_3_transparent_model = ba.getmodel(
            'playerLineup3Transparent')
        self._lineup_4_transparent_model = ba.getmodel(
            'playerLineup4Transparent')
        self._eyes_model = ba.getmodel('plasticEyesTransparent')

        self._coop_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(hoffs, v + (scl * 15 if new_style else 0)),
            size=(scl * button_width, scl * (300 if new_style else 360)),
            extra_touch_border_scale=0.1,
            autoselect=True,
            label='',
            button_type='square',
            text_scale=1.13,
            on_activate_call=self._coop)

        if ba.app.ui.use_toolbars and uiscale is ba.UIScale.SMALL:
            ba.widget(edit=btn,
                      left_widget=_ba.get_special_widget('back_button'))
            ba.widget(edit=btn,
                      up_widget=_ba.get_special_widget('account_button'))
            ba.widget(edit=btn,
                      down_widget=_ba.get_special_widget('settings_button'))

        self._draw_dude(0,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(140, 30),
                        color=(0.72, 0.4, 1.0))
        self._draw_dude(1,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(185, 53),
                        color=(0.71, 0.5, 1.0))
        self._draw_dude(2,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(220, 27),
                        color=(0.67, 0.44, 1.0))
        self._draw_dude(3,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(255, 57),
                        color=(0.7, 0.3, 1.0))
        ba.imagewidget(parent=self._root_widget,
                       draw_controller=btn,
                       position=(hoffs + scl * 230, v + scl * 153),
                       size=(scl * 115, scl * 115),
                       texture=self._lineup_tex,
                       model_transparent=angry_computer_transparent_model)

        ba.textwidget(parent=self._root_widget,
                      draw_controller=btn,
                      position=(hoffs + scl * (-10), v + scl * 95),
                      size=(scl * button_width, scl * 50),
                      text=ba.Lstr(resource='playModes.singlePlayerCoopText',
                                   fallback_resource='playModes.coopText'),
                      maxwidth=scl * button_width * 0.7,
                      res_scale=1.5,
                      h_align='center',
                      v_align='center',
                      color=(0.7, 0.9, 0.7, 1.0),
                      scale=scl * 2.3)

        ba.textwidget(parent=self._root_widget,
                      draw_controller=btn,
                      position=(hoffs + scl * (-10), v + (scl * 54)),
                      size=(scl * button_width, scl * 30),
                      text=ba.Lstr(resource=self._r + '.oneToFourPlayersText'),
                      h_align='center',
                      v_align='center',
                      scale=0.83 * scl,
                      flatness=1.0,
                      maxwidth=scl * button_width * 0.7,
                      color=clr)

        scl = 0.5 if new_style else 0.68
        hoffs += 440 if new_style else 260
        v += 180 if new_style else 0

        self._teams_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(hoffs, v + (scl * 15 if new_style else 0)),
            size=(scl * button_width, scl * (300 if new_style else 360)),
            extra_touch_border_scale=0.1,
            autoselect=True,
            label='',
            button_type='square',
            text_scale=1.13,
            on_activate_call=self._team_tourney)

        if ba.app.ui.use_toolbars:
            ba.widget(edit=btn,
                      up_widget=_ba.get_special_widget('tickets_plus_button'),
                      right_widget=_ba.get_special_widget('party_button'))

        xxx = -14
        self._draw_dude(2,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 148, 30),
                        color=(0.2, 0.4, 1.0))
        self._draw_dude(3,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 181, 53),
                        color=(0.3, 0.4, 1.0))
        self._draw_dude(1,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 216, 33),
                        color=(0.3, 0.5, 1.0))
        self._draw_dude(0,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 245, 57),
                        color=(0.3, 0.5, 1.0))

        xxx = 155
        self._draw_dude(0,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 151, 30),
                        color=(1.0, 0.5, 0.4))
        self._draw_dude(1,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 189, 53),
                        color=(1.0, 0.58, 0.58))
        self._draw_dude(3,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 223, 27),
                        color=(1.0, 0.5, 0.5))
        self._draw_dude(2,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 257, 57),
                        color=(1.0, 0.5, 0.5))

        ba.textwidget(parent=self._root_widget,
                      draw_controller=btn,
                      position=(hoffs + scl * (-10), v + scl * 95),
                      size=(scl * button_width, scl * 50),
                      text=ba.Lstr(resource='playModes.teamsText',
                                   fallback_resource='teamsText'),
                      res_scale=1.5,
                      maxwidth=scl * button_width * 0.7,
                      h_align='center',
                      v_align='center',
                      color=(0.7, 0.9, 0.7, 1.0),
                      scale=scl * 2.3)
        ba.textwidget(parent=self._root_widget,
                      draw_controller=btn,
                      position=(hoffs + scl * (-10), v + (scl * 54)),
                      size=(scl * button_width, scl * 30),
                      text=ba.Lstr(resource=self._r +
                                   '.twoToEightPlayersText'),
                      h_align='center',
                      v_align='center',
                      res_scale=1.5,
                      scale=0.9 * scl,
                      flatness=1.0,
                      maxwidth=scl * button_width * 0.7,
                      color=clr)

        hoffs += 0 if new_style else 260
        v -= 155 if new_style else 0
        self._free_for_all_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(hoffs, v + (scl * 15 if new_style else 0)),
            size=(scl * button_width, scl * (300 if new_style else 360)),
            extra_touch_border_scale=0.1,
            autoselect=True,
            label='',
            button_type='square',
            text_scale=1.13,
            on_activate_call=self._free_for_all)

        xxx = -5
        self._draw_dude(0,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 140, 30),
                        color=(0.4, 1.0, 0.4))
        self._draw_dude(3,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 185, 53),
                        color=(1.0, 0.4, 0.5))
        self._draw_dude(1,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 220, 27),
                        color=(0.4, 0.5, 1.0))
        self._draw_dude(2,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 255, 57),
                        color=(0.5, 1.0, 0.4))
        xxx = 140
        self._draw_dude(2,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 148, 30),
                        color=(1.0, 0.9, 0.4))
        self._draw_dude(0,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 182, 53),
                        color=(0.7, 1.0, 0.5))
        self._draw_dude(3,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 233, 27),
                        color=(0.7, 0.5, 0.9))
        self._draw_dude(1,
                        btn,
                        hoffs,
                        v,
                        scl,
                        position=(xxx + 266, 53),
                        color=(0.4, 0.5, 0.8))
        ba.textwidget(parent=self._root_widget,
                      draw_controller=btn,
                      position=(hoffs + scl * (-10), v + scl * 95),
                      size=(scl * button_width, scl * 50),
                      text=ba.Lstr(resource='playModes.freeForAllText',
                                   fallback_resource='freeForAllText'),
                      maxwidth=scl * button_width * 0.7,
                      h_align='center',
                      v_align='center',
                      color=(0.7, 0.9, 0.7, 1.0),
                      scale=scl * 1.9)
        ba.textwidget(parent=self._root_widget,
                      draw_controller=btn,
                      position=(hoffs + scl * (-10), v + (scl * 54)),
                      size=(scl * button_width, scl * 30),
                      text=ba.Lstr(resource=self._r +
                                   '.twoToEightPlayersText'),
                      h_align='center',
                      v_align='center',
                      scale=0.9 * scl,
                      flatness=1.0,
                      maxwidth=scl * button_width * 0.7,
                      color=clr)

        if ba.app.ui.use_toolbars and uiscale is ba.UIScale.SMALL:
            back_button.delete()
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._back,
                               selected_child=self._coop_button)
        else:
            ba.buttonwidget(edit=back_button, on_activate_call=self._back)
            ba.containerwidget(edit=self._root_widget,
                               cancel_button=back_button,
                               selected_child=self._coop_button)

        self._restore_state()
Exemple #24
0
    def __init__(self, offer: dict[str, Any], transition: str = 'in_right'):
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        from ba.internal import (get_store_item_display_size, get_clean_price)
        from ba import SpecialChar
        from bastd.ui.store import item as storeitemui
        self._cancel_delay = offer.get('cancelDelay', 0)

        # First thing: if we're offering pro or an IAP, see if we have a
        # price for it.
        # If not, abort and go into zombie mode (the user should never see
        # us that way).

        real_price: Optional[str]

        # Misnomer: 'pro' actually means offer 'pro_sale'.
        if offer['item'] in ['pro', 'pro_fullprice']:
            real_price = _ba.get_price('pro' if offer['item'] ==
                                       'pro_fullprice' else 'pro_sale')
            if real_price is None and ba.app.debug_build:
                print('NOTE: Faking prices for debug build.')
                real_price = '$1.23'
            zombie = real_price is None
        elif isinstance(offer['price'], str):
            # (a string price implies IAP id)
            real_price = _ba.get_price(offer['price'])
            if real_price is None and ba.app.debug_build:
                print('NOTE: Faking price for debug build.')
                real_price = '$1.23'
            zombie = real_price is None
        else:
            real_price = None
            zombie = False
        if real_price is None:
            real_price = '?'

        if offer['item'] in ['pro', 'pro_fullprice']:
            self._offer_item = 'pro'
        else:
            self._offer_item = offer['item']

        # If we wanted a real price but didn't find one, go zombie.
        if zombie:
            return

        # This can pop up suddenly, so lets block input for 1 second.
        _ba.lock_all_input()
        ba.timer(1.0, _ba.unlock_all_input, timetype=ba.TimeType.REAL)
        ba.playsound(ba.getsound('ding'))
        ba.timer(0.3,
                 lambda: ba.playsound(ba.getsound('ooh')),
                 timetype=ba.TimeType.REAL)
        self._offer = copy.deepcopy(offer)
        self._width = 580
        self._height = 590
        uiscale = ba.app.ui.uiscale
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height),
            transition=transition,
            scale=(1.2 if uiscale is ba.UIScale.SMALL else
                   1.15 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -15) if uiscale is ba.UIScale.SMALL else (0, 0)))
        self._is_bundle_sale = False
        try:
            if offer['item'] in ['pro', 'pro_fullprice']:
                original_price_str = _ba.get_price('pro')
                if original_price_str is None:
                    original_price_str = '?'
                new_price_str = _ba.get_price('pro_sale')
                if new_price_str is None:
                    new_price_str = '?'
                percent_off_text = ''
            else:
                # If the offer includes bonus tickets, it's a bundle-sale.
                if ('bonusTickets' in offer
                        and offer['bonusTickets'] is not None):
                    self._is_bundle_sale = True
                original_price = _ba.get_v1_account_misc_read_val(
                    'price.' + self._offer_item, 9999)

                # For pure ticket prices we can show a percent-off.
                if isinstance(offer['price'], int):
                    new_price = offer['price']
                    tchar = ba.charstr(SpecialChar.TICKET)
                    original_price_str = tchar + str(original_price)
                    new_price_str = tchar + str(new_price)
                    percent_off = int(
                        round(100.0 -
                              (float(new_price) / original_price) * 100.0))
                    percent_off_text = ' ' + ba.Lstr(
                        resource='store.salePercentText').evaluate().replace(
                            '${PERCENT}', str(percent_off))
                else:
                    original_price_str = new_price_str = '?'
                    percent_off_text = ''

        except Exception:
            print(f'Offer: {offer}')
            ba.print_exception('Error setting up special-offer')
            original_price_str = new_price_str = '?'
            percent_off_text = ''

        # If its a bundle sale, change the title.
        if self._is_bundle_sale:
            sale_text = ba.Lstr(resource='store.saleBundleText',
                                fallback_resource='store.saleText').evaluate()
        else:
            # For full pro we say 'Upgrade?' since its not really a sale.
            if offer['item'] == 'pro_fullprice':
                sale_text = ba.Lstr(
                    resource='store.upgradeQuestionText',
                    fallback_resource='store.saleExclaimText').evaluate()
            else:
                sale_text = ba.Lstr(
                    resource='store.saleExclaimText',
                    fallback_resource='store.saleText').evaluate()

        self._title_text = ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height - 40),
            size=(0, 0),
            text=sale_text +
            ((' ' + ba.Lstr(resource='store.oneTimeOnlyText').evaluate())
             if self._offer['oneTimeOnly'] else '') + percent_off_text,
            h_align='center',
            v_align='center',
            maxwidth=self._width * 0.9 - 220,
            scale=1.4,
            color=(0.3, 1, 0.3))

        self._flash_on = False
        self._flashing_timer: Optional[ba.Timer] = ba.Timer(
            0.05,
            ba.WeakCall(self._flash_cycle),
            repeat=True,
            timetype=ba.TimeType.REAL)
        ba.timer(0.6,
                 ba.WeakCall(self._stop_flashing),
                 timetype=ba.TimeType.REAL)

        size = get_store_item_display_size(self._offer_item)
        display: dict[str, Any] = {}
        storeitemui.instantiate_store_item_display(
            self._offer_item,
            display,
            parent_widget=self._root_widget,
            b_pos=(self._width * 0.5 - size[0] * 0.5 + 10 -
                   ((size[0] * 0.5 + 30) if self._is_bundle_sale else 0),
                   self._height * 0.5 - size[1] * 0.5 + 20 +
                   (20 if self._is_bundle_sale else 0)),
            b_width=size[0],
            b_height=size[1],
            button=not self._is_bundle_sale)

        # Wire up the parts we need.
        if self._is_bundle_sale:
            self._plus_text = ba.textwidget(parent=self._root_widget,
                                            position=(self._width * 0.5,
                                                      self._height * 0.5 + 50),
                                            size=(0, 0),
                                            text='+',
                                            h_align='center',
                                            v_align='center',
                                            maxwidth=self._width * 0.9,
                                            scale=1.4,
                                            color=(0.5, 0.5, 0.5))
            self._plus_tickets = ba.textwidget(
                parent=self._root_widget,
                position=(self._width * 0.5 + 120, self._height * 0.5 + 50),
                size=(0, 0),
                text=ba.charstr(SpecialChar.TICKET_BACKING) +
                str(offer['bonusTickets']),
                h_align='center',
                v_align='center',
                maxwidth=self._width * 0.9,
                scale=2.5,
                color=(0.2, 1, 0.2))
            self._price_text = ba.textwidget(parent=self._root_widget,
                                             position=(self._width * 0.5, 150),
                                             size=(0, 0),
                                             text=real_price,
                                             h_align='center',
                                             v_align='center',
                                             maxwidth=self._width * 0.9,
                                             scale=1.4,
                                             color=(0.2, 1, 0.2))
            # Total-value if they supplied it.
            total_worth_item = offer.get('valueItem', None)
            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 None)
                if total_worth_price is not None:
                    total_worth_text = ba.Lstr(resource='store.totalWorthText',
                                               subs=[('${TOTAL_WORTH}',
                                                      total_worth_price)])
                    self._total_worth_text = ba.textwidget(
                        parent=self._root_widget,
                        text=total_worth_text,
                        position=(self._width * 0.5, 210),
                        scale=0.9,
                        maxwidth=self._width * 0.7,
                        size=(0, 0),
                        h_align='center',
                        v_align='center',
                        shadow=1.0,
                        flatness=1.0,
                        color=(0.3, 1, 1))

        elif offer['item'] == 'pro_fullprice':
            # for full-price pro we simply show full price
            ba.textwidget(edit=display['price_widget'], text=real_price)
            ba.buttonwidget(edit=display['button'],
                            on_activate_call=self._purchase)
        else:
            # Show old/new prices otherwise (for pro sale).
            ba.buttonwidget(edit=display['button'],
                            on_activate_call=self._purchase)
            ba.imagewidget(edit=display['price_slash_widget'], opacity=1.0)
            ba.textwidget(edit=display['price_widget_left'],
                          text=original_price_str)
            ba.textwidget(edit=display['price_widget_right'],
                          text=new_price_str)

        # Add ticket button only if this is ticket-purchasable.
        if isinstance(offer.get('price'), int):
            self._get_tickets_button = ba.buttonwidget(
                parent=self._root_widget,
                position=(self._width - 125, self._height - 68),
                size=(90, 55),
                scale=1.0,
                button_type='square',
                color=(0.7, 0.5, 0.85),
                textcolor=(0.2, 1, 0.2),
                autoselect=True,
                label=ba.Lstr(resource='getTicketsWindow.titleText'),
                on_activate_call=self._on_get_more_tickets_press)

            self._ticket_text_update_timer = ba.Timer(
                1.0,
                ba.WeakCall(self._update_tickets_text),
                timetype=ba.TimeType.REAL,
                repeat=True)
            self._update_tickets_text()

        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)

        self._cancel_button = ba.buttonwidget(
            parent=self._root_widget,
            position=(50, 40) if self._is_bundle_sale else
            (self._width * 0.5 - 75, 40),
            size=(150, 60),
            scale=1.0,
            on_activate_call=self._cancel,
            autoselect=True,
            label=ba.Lstr(resource='noThanksText'))
        self._cancel_countdown_text = ba.textwidget(
            parent=self._root_widget,
            text='',
            position=(50 + 150 + 20, 40 + 27) if self._is_bundle_sale else
            (self._width * 0.5 - 75 + 150 + 20, 40 + 27),
            scale=1.1,
            size=(0, 0),
            h_align='left',
            v_align='center',
            shadow=1.0,
            flatness=1.0,
            color=(0.6, 0.5, 0.5))
        self._update_cancel_button_graphics()

        if self._is_bundle_sale:
            self._purchase_button = ba.buttonwidget(
                parent=self._root_widget,
                position=(self._width - 200, 40),
                size=(150, 60),
                scale=1.0,
                on_activate_call=self._purchase,
                autoselect=True,
                label=ba.Lstr(resource='store.purchaseText'))

        ba.containerwidget(edit=self._root_widget,
                           cancel_button=self._cancel_button,
                           start_button=self._purchase_button
                           if self._is_bundle_sale else None,
                           selected_child=self._purchase_button
                           if self._is_bundle_sale else display['button'])
Exemple #25
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)
            assert price is not None
            total_worth_price = get_clean_price(price)
        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))
Exemple #26
0
    def __init__(self,
                 transition: str = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements

        # 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 = 'editSoundtrackWindow'
        uiscale = ba.app.ui.uiscale
        self._width = 800 if uiscale is ba.UIScale.SMALL else 600
        x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
        self._height = (340 if uiscale is ba.UIScale.SMALL else
                        370 if uiscale is ba.UIScale.MEDIUM else 440)
        spacing = 40.0
        v = self._height - 40.0
        v -= spacing * 1.0

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(2.3 if uiscale is ba.UIScale.SMALL else
                   1.6 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -18) if uiscale is ba.UIScale.SMALL else (0, 0)))

        if ba.app.ui.use_toolbars and uiscale is ba.UIScale.SMALL:
            self._back_button = None
        else:
            self._back_button = ba.buttonwidget(
                parent=self._root_widget,
                position=(45 + x_inset, self._height - 60),
                size=(120, 60),
                scale=0.8,
                label=ba.Lstr(resource='backText'),
                button_type='back',
                autoselect=True)
            ba.buttonwidget(edit=self._back_button,
                            button_type='backSmall',
                            size=(60, 60),
                            label=ba.charstr(ba.SpecialChar.BACK))
        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height - 35),
                      size=(0, 0),
                      maxwidth=300,
                      text=ba.Lstr(resource=self._r + '.titleText'),
                      color=ba.app.ui.title_color,
                      h_align='center',
                      v_align='center')

        h = 43 + x_inset
        v = self._height - 60
        b_color = (0.6, 0.53, 0.63)
        b_textcolor = (0.75, 0.7, 0.8)
        lock_tex = ba.gettexture('lock')
        self._lock_images: List[ba.Widget] = []

        scl = (1.0 if uiscale is ba.UIScale.SMALL else
               1.13 if uiscale is ba.UIScale.MEDIUM else 1.4)
        v -= 60.0 * scl
        self._new_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(h, v),
            size=(100, 55.0 * scl),
            on_activate_call=self._new_soundtrack,
            color=b_color,
            button_type='square',
            autoselect=True,
            textcolor=b_textcolor,
            text_scale=0.7,
            label=ba.Lstr(resource=self._r + '.newText'))
        self._lock_images.append(
            ba.imagewidget(parent=self._root_widget,
                           size=(30, 30),
                           draw_controller=btn,
                           position=(h - 10, v + 55.0 * scl - 28),
                           texture=lock_tex))

        if self._back_button is None:
            ba.widget(edit=btn,
                      left_widget=_ba.get_special_widget('back_button'))
        v -= 60.0 * scl

        self._edit_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(h, v),
            size=(100, 55.0 * scl),
            on_activate_call=self._edit_soundtrack,
            color=b_color,
            button_type='square',
            autoselect=True,
            textcolor=b_textcolor,
            text_scale=0.7,
            label=ba.Lstr(resource=self._r + '.editText'))
        self._lock_images.append(
            ba.imagewidget(parent=self._root_widget,
                           size=(30, 30),
                           draw_controller=btn,
                           position=(h - 10, v + 55.0 * scl - 28),
                           texture=lock_tex))
        if self._back_button is None:
            ba.widget(edit=btn,
                      left_widget=_ba.get_special_widget('back_button'))
        v -= 60.0 * scl

        self._duplicate_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(h, v),
            size=(100, 55.0 * scl),
            on_activate_call=self._duplicate_soundtrack,
            button_type='square',
            autoselect=True,
            color=b_color,
            textcolor=b_textcolor,
            text_scale=0.7,
            label=ba.Lstr(resource=self._r + '.duplicateText'))
        self._lock_images.append(
            ba.imagewidget(parent=self._root_widget,
                           size=(30, 30),
                           draw_controller=btn,
                           position=(h - 10, v + 55.0 * scl - 28),
                           texture=lock_tex))
        if self._back_button is None:
            ba.widget(edit=btn,
                      left_widget=_ba.get_special_widget('back_button'))
        v -= 60.0 * scl

        self._delete_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(h, v),
            size=(100, 55.0 * scl),
            on_activate_call=self._delete_soundtrack,
            color=b_color,
            button_type='square',
            autoselect=True,
            textcolor=b_textcolor,
            text_scale=0.7,
            label=ba.Lstr(resource=self._r + '.deleteText'))
        self._lock_images.append(
            ba.imagewidget(parent=self._root_widget,
                           size=(30, 30),
                           draw_controller=btn,
                           position=(h - 10, v + 55.0 * scl - 28),
                           texture=lock_tex))
        if self._back_button is None:
            ba.widget(edit=btn,
                      left_widget=_ba.get_special_widget('back_button'))

        # Keep our lock images up to date/etc.
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)
        self._update()

        v = self._height - 65
        scroll_height = self._height - 105
        v -= scroll_height
        self._scrollwidget = scrollwidget = ba.scrollwidget(
            parent=self._root_widget,
            position=(152 + x_inset, v),
            highlight=False,
            size=(self._width - (205 + 2 * x_inset), scroll_height))
        ba.widget(edit=self._scrollwidget,
                  left_widget=self._new_button,
                  right_widget=_ba.get_special_widget('party_button')
                  if ba.app.ui.use_toolbars else self._scrollwidget)
        self._col = ba.columnwidget(parent=scrollwidget, border=2, margin=0)

        self._soundtracks: Optional[Dict[str, Any]] = None
        self._selected_soundtrack: Optional[str] = None
        self._selected_soundtrack_index: Optional[int] = None
        self._soundtrack_widgets: List[ba.Widget] = []
        self._allow_changing_soundtracks = False
        self._refresh()
        if self._back_button is not None:
            ba.buttonwidget(edit=self._back_button,
                            on_activate_call=self._back)
            ba.containerwidget(edit=self._root_widget,
                               cancel_button=self._back_button)
        else:
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._back)
Exemple #27
0
    def __init__(self,
                 parent: ba.Widget,
                 position: Tuple[float, float],
                 initial_color: Sequence[float] = (1.0, 1.0, 1.0),
                 delegate: Any = None,
                 scale: float = None,
                 offset: Tuple[float, float] = (0.0, 0.0),
                 tag: Any = ''):
        # pylint: disable=too-many-locals
        del parent  # Unused var.
        from ba.internal import get_player_colors
        c_raw = get_player_colors()
        assert len(c_raw) == 16
        self.colors = [c_raw[0:4], c_raw[4:8], c_raw[8:12], c_raw[12:16]]

        uiscale = ba.app.ui.uiscale
        if scale is None:
            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._tag = tag
        self._color = list(initial_color)
        self._last_press_time = ba.time(ba.TimeType.REAL,
                                        ba.TimeFormat.MILLISECONDS)
        self._last_press_color_name: Optional[str] = None
        self._last_press_increasing: Optional[bool] = None
        self._change_speed = 1.0
        width = 180.0
        height = 240.0

        # Creates our _root_widget.
        PopupWindow.__init__(self,
                             position=position,
                             size=(width, height),
                             scale=scale,
                             focus_position=(10, 10),
                             focus_size=(width - 20, height - 20),
                             bg_color=(0.5, 0.5, 0.5),
                             offset=offset)
        self._swatch = ba.imagewidget(parent=self.root_widget,
                                      position=(width * 0.5 - 50, height - 70),
                                      size=(100, 70),
                                      texture=ba.gettexture('buttonSquare'),
                                      color=(1, 0, 0))
        x = 50
        y = height - 90
        self._label_r: ba.Widget
        self._label_g: ba.Widget
        self._label_b: ba.Widget
        for color_name, color_val in [('r', (1, 0.15, 0.15)),
                                      ('g', (0.15, 1, 0.15)),
                                      ('b', (0.15, 0.15, 1))]:
            txt = ba.textwidget(parent=self.root_widget,
                                position=(x - 10, y),
                                size=(0, 0),
                                h_align='center',
                                color=color_val,
                                v_align='center',
                                text='0.12')
            setattr(self, '_label_' + color_name, txt)
            for b_label, bhval, binc in [('-', 30, False), ('+', 75, True)]:
                ba.buttonwidget(parent=self.root_widget,
                                position=(x + bhval, y - 15),
                                scale=0.8,
                                repeat=True,
                                text_scale=1.3,
                                size=(40, 40),
                                label=b_label,
                                autoselect=True,
                                enable_sound=False,
                                on_activate_call=ba.WeakCall(
                                    self._color_change_press, color_name,
                                    binc))
            y -= 42

        btn = ba.buttonwidget(parent=self.root_widget,
                              position=(width * 0.5 - 40, 10),
                              size=(80, 30),
                              text_scale=0.6,
                              color=(0.6, 0.6, 0.6),
                              textcolor=(0.7, 0.7, 0.7),
                              label=ba.Lstr(resource='doneText'),
                              on_activate_call=ba.WeakCall(
                                  self._transition_out),
                              autoselect=True)
        ba.containerwidget(edit=self.root_widget, start_button=btn)

        # Unlike the swatch picker, we stay open and constantly push our
        # color to the delegate, so start doing that.
        self._update_for_color()
    def __init__(self, position: Tuple[float, float], scale: float = None):
        # pylint: disable=too-many-locals
        uiscale = ba.app.uiscale
        if scale is None:
            scale = (2.3 if uiscale is ba.UIScale.SMALL else
                     1.65 if uiscale is ba.UIScale.MEDIUM else 1.23)
        self._transitioning_out = False
        self._width = 450
        self._height = (300 if uiscale is ba.UIScale.SMALL else
                        370 if uiscale is ba.UIScale.MEDIUM else 450)
        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)

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

        achievements = ba.app.achievements
        num_complete = len([a for a in achievements if a.complete])

        txt_final = ba.Lstr(
            resource='accountSettingsWindow.achievementProgressText',
            subs=[('${COUNT}', str(num_complete)),
                  ('${TOTAL}', str(len(achievements)))])
        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=txt_final,
                                         maxwidth=200,
                                         color=(1, 1, 1, 0.4))

        self._scrollwidget = ba.scrollwidget(parent=self.root_widget,
                                             size=(self._width - 60,
                                                   self._height - 70),
                                             position=(30, 30),
                                             capture_arrows=True,
                                             simple_culling_v=10)
        ba.widget(edit=self._scrollwidget, autoselect=True)

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

        incr = 36
        sub_width = self._width - 90
        sub_height = 40 + len(achievements) * incr

        eq_rsrc = 'coopSelectWindow.powerRankingPointsEqualsText'
        pts_rsrc = 'coopSelectWindow.powerRankingPointsText'

        self._subcontainer = ba.containerwidget(parent=self._scrollwidget,
                                                size=(sub_width, sub_height),
                                                background=False)

        total_pts = 0
        for i, ach in enumerate(achievements):
            complete = ach.complete
            ba.textwidget(parent=self._subcontainer,
                          position=(sub_width * 0.08 - 5,
                                    sub_height - 20 - incr * i),
                          maxwidth=20,
                          scale=0.5,
                          color=(0.6, 0.6, 0.7) if complete else
                          (0.6, 0.6, 0.7, 0.2),
                          flatness=1.0,
                          shadow=0.0,
                          text=str(i + 1),
                          size=(0, 0),
                          h_align='right',
                          v_align='center')

            ba.imagewidget(parent=self._subcontainer,
                           position=(sub_width * 0.10 + 1, sub_height - 20 -
                                     incr * i - 9) if complete else
                           (sub_width * 0.10 - 4,
                            sub_height - 20 - incr * i - 14),
                           size=(18, 18) if complete else (27, 27),
                           opacity=1.0 if complete else 0.3,
                           color=ach.get_icon_color(complete)[:3],
                           texture=ach.get_icon_texture(complete))
            if complete:
                ba.imagewidget(parent=self._subcontainer,
                               position=(sub_width * 0.10 - 4,
                                         sub_height - 25 - incr * i - 9),
                               size=(28, 28),
                               color=(2, 1.4, 0),
                               texture=ba.gettexture('achievementOutline'))
            ba.textwidget(parent=self._subcontainer,
                          position=(sub_width * 0.19,
                                    sub_height - 19 - incr * i + 3),
                          maxwidth=sub_width * 0.62,
                          scale=0.6,
                          flatness=1.0,
                          shadow=0.0,
                          color=(1, 1, 1) if complete else (1, 1, 1, 0.2),
                          text=ach.display_name,
                          size=(0, 0),
                          h_align='left',
                          v_align='center')

            ba.textwidget(parent=self._subcontainer,
                          position=(sub_width * 0.19,
                                    sub_height - 19 - incr * i - 10),
                          maxwidth=sub_width * 0.62,
                          scale=0.4,
                          flatness=1.0,
                          shadow=0.0,
                          color=(0.83, 0.8, 0.85) if complete else
                          (0.8, 0.8, 0.8, 0.2),
                          text=ach.description_full_complete
                          if complete else ach.description_full,
                          size=(0, 0),
                          h_align='left',
                          v_align='center')

            pts = ach.power_ranking_value
            ba.textwidget(parent=self._subcontainer,
                          position=(sub_width * 0.92,
                                    sub_height - 20 - incr * i),
                          maxwidth=sub_width * 0.15,
                          color=(0.7, 0.8, 1.0) if complete else
                          (0.9, 0.9, 1.0, 0.3),
                          flatness=1.0,
                          shadow=0.0,
                          scale=0.6,
                          text=ba.Lstr(resource=pts_rsrc,
                                       subs=[('${NUMBER}', str(pts))]),
                          size=(0, 0),
                          h_align='center',
                          v_align='center')
            if complete:
                total_pts += pts

        ba.textwidget(parent=self._subcontainer,
                      position=(sub_width * 1.0,
                                sub_height - 20 - incr * len(achievements)),
                      maxwidth=sub_width * 0.5,
                      scale=0.7,
                      color=(0.7, 0.8, 1.0),
                      flatness=1.0,
                      shadow=0.0,
                      text=ba.Lstr(
                          value='${A} ${B}',
                          subs=[
                              ('${A}',
                               ba.Lstr(resource='coopSelectWindow.totalText')),
                              ('${B}',
                               ba.Lstr(resource=eq_rsrc,
                                       subs=[('${NUMBER}', str(total_pts))]))
                          ]),
                      size=(0, 0),
                      h_align='right',
                      v_align='center')
Exemple #29
0
 def _add_button(item: str,
                 position: Tuple[float, float],
                 size: Tuple[float, float],
                 label: ba.Lstr,
                 price: str = None,
                 tex_name: str = None,
                 tex_opacity: float = 1.0,
                 tex_scale: float = 1.0,
                 enabled: bool = True,
                 text_scale: float = 1.0) -> ba.Widget:
     btn2 = ba.buttonwidget(
         parent=self._root_widget,
         position=position,
         button_type='square',
         size=size,
         label='',
         autoselect=True,
         color=None if enabled else (0.5, 0.5, 0.5),
         on_activate_call=(ba.Call(self._purchase, item)
                           if enabled else self._disabled_press))
     txt = ba.textwidget(parent=self._root_widget,
                         text=label,
                         position=(position[0] + size[0] * 0.5,
                                   position[1] + size[1] * 0.3),
                         scale=text_scale,
                         maxwidth=size[0] * 0.75,
                         size=(0, 0),
                         h_align='center',
                         v_align='center',
                         draw_controller=btn2,
                         color=(0.7, 0.9, 0.7, 1.0 if enabled else 0.2))
     if price is not None and enabled:
         ba.textwidget(parent=self._root_widget,
                       text=price,
                       position=(position[0] + size[0] * 0.5,
                                 position[1] + size[1] * 0.17),
                       scale=0.7,
                       maxwidth=size[0] * 0.75,
                       size=(0, 0),
                       h_align='center',
                       v_align='center',
                       draw_controller=btn2,
                       color=(0.4, 0.9, 0.4, 1.0))
     i = None
     if tex_name is not None:
         tex_size = 90.0 * tex_scale
         i = ba.imagewidget(
             parent=self._root_widget,
             texture=ba.gettexture(tex_name),
             position=(position[0] + size[0] * 0.5 - tex_size * 0.5,
                       position[1] + size[1] * 0.66 - tex_size * 0.5),
             size=(tex_size, tex_size),
             draw_controller=btn2,
             opacity=tex_opacity * (1.0 if enabled else 0.25))
     if item == 'ad':
         self._ad_button = btn2
         self._ad_label = txt
         assert i is not None
         self._ad_image = i
         self._ad_time_text = ba.textwidget(
             parent=self._root_widget,
             text='1m 10s',
             position=(position[0] + size[0] * 0.5,
                       position[1] + size[1] * 0.5),
             scale=text_scale * 1.2,
             maxwidth=size[0] * 0.85,
             size=(0, 0),
             h_align='center',
             v_align='center',
             draw_controller=btn2,
             color=(0.4, 0.9, 0.4, 1.0))
     return btn2
Exemple #30
0
    def _update(self) -> None:
        import datetime

        # if we somehow get signed out, just die..
        if _ba.get_account_state() != 'signed_in':
            self._back()
            return

        self._ticket_count = _ba.get_account_ticket_count()

        # update our incentivized ad button depending on whether ads are
        # available
        if self._ad_button is not None:
            next_reward_ad_time = _ba.get_account_misc_read_val_2(
                'nextRewardAdTime', None)
            if next_reward_ad_time is not None:
                next_reward_ad_time = datetime.datetime.utcfromtimestamp(
                    next_reward_ad_time)
            now = datetime.datetime.utcnow()
            if (_ba.have_incentivized_ad() and
                (next_reward_ad_time is None or next_reward_ad_time <= now)):
                self._ad_button_greyed = False
                ba.buttonwidget(edit=self._ad_button, color=(0.65, 0.5, 0.7))
                ba.textwidget(edit=self._ad_label, color=(0.7, 0.9, 0.7, 1.0))
                ba.textwidget(edit=self._ad_free_text, color=(1, 1, 0, 1))
                ba.imagewidget(edit=self._ad_image, opacity=0.6)
                ba.textwidget(edit=self._ad_time_text, text='')
            else:
                self._ad_button_greyed = True
                ba.buttonwidget(edit=self._ad_button, color=(0.5, 0.5, 0.5))
                ba.textwidget(edit=self._ad_label, color=(0.7, 0.9, 0.7, 0.2))
                ba.textwidget(edit=self._ad_free_text, color=(1, 1, 0, 0.2))
                ba.imagewidget(edit=self._ad_image, opacity=0.6 * 0.25)
                sval: Union[str, ba.Lstr]
                if (next_reward_ad_time is not None
                        and next_reward_ad_time > now):
                    sval = ba.timestring(
                        (next_reward_ad_time - now).total_seconds() * 1000.0,
                        centi=False,
                        timeformat=ba.TimeFormat.MILLISECONDS)
                else:
                    sval = ''
                ba.textwidget(edit=self._ad_time_text, text=sval)

        # if this is our first update, assign immediately; otherwise kick
        # off a smooth transition if the value has changed
        if self._smooth_ticket_count is None:
            self._smooth_ticket_count = float(self._ticket_count)
            self._smooth_update()  # will set the text widget

        elif (self._ticket_count != int(self._smooth_ticket_count)
              and self._smooth_update_timer is None):
            self._smooth_update_timer = ba.Timer(0.05,
                                                 ba.WeakCall(
                                                     self._smooth_update),
                                                 repeat=True,
                                                 timetype=ba.TimeType.REAL)
            diff = abs(float(self._ticket_count) - self._smooth_ticket_count)
            self._smooth_increase_speed = (diff /
                                           100.0 if diff >= 5000 else diff /
                                           50.0 if diff >= 1500 else diff /
                                           30.0 if diff >= 500 else diff /
                                           15.0)