Exemplo n.º 1
0
    def _rebuild_ui(self) -> None:
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        from ba.internal import get_device_value

        # Clear existing UI.
        for widget in self._root_widget.get_children():
            widget.delete()

        self._textwidgets: Dict[str, ba.Widget] = {}

        # If we were supplied with settings, we're a secondary joystick and
        # just operate on that. in the other (normal) case we make our own.
        if not self._is_secondary:

            # Fill our temp config with present values (for our primary and
            # secondary controls).
            self._settings = {}
            for skey in [
                    'buttonJump',
                    'buttonJump_B',
                    'buttonPunch',
                    'buttonPunch_B',
                    'buttonBomb',
                    'buttonBomb_B',
                    'buttonPickUp',
                    'buttonPickUp_B',
                    'buttonStart',
                    'buttonStart_B',
                    'buttonStart2',
                    'buttonStart2_B',
                    'buttonUp',
                    'buttonUp_B',
                    'buttonDown',
                    'buttonDown_B',
                    'buttonLeft',
                    'buttonLeft_B',
                    'buttonRight',
                    'buttonRight_B',
                    'buttonRun1',
                    'buttonRun1_B',
                    'buttonRun2',
                    'buttonRun2_B',
                    'triggerRun1',
                    'triggerRun1_B',
                    'triggerRun2',
                    'triggerRun2_B',
                    'buttonIgnored',
                    'buttonIgnored_B',
                    'buttonIgnored2',
                    'buttonIgnored2_B',
                    'buttonIgnored3',
                    'buttonIgnored3_B',
                    'buttonIgnored4',
                    'buttonIgnored4_B',
                    'buttonVRReorient',
                    'buttonVRReorient_B',
                    'analogStickDeadZone',
                    'analogStickDeadZone_B',
                    'dpad',
                    'dpad_B',
                    'unassignedButtonsRun',
                    'unassignedButtonsRun_B',
                    'startButtonActivatesDefaultWidget',
                    'startButtonActivatesDefaultWidget_B',
                    'uiOnly',
                    'uiOnly_B',
                    'ignoreCompletely',
                    'ignoreCompletely_B',
                    'autoRecalibrateAnalogStick',
                    'autoRecalibrateAnalogStick_B',
                    'analogStickLR',
                    'analogStickLR_B',
                    'analogStickUD',
                    'analogStickUD_B',
                    'enableSecondary',
            ]:
                val = get_device_value(self._input, skey)
                if val != -1:
                    self._settings[skey] = val

        back_button: Optional[ba.Widget]

        if self._is_secondary:
            back_button = ba.buttonwidget(parent=self._root_widget,
                                          position=(self._width - 180,
                                                    self._height - 65),
                                          autoselect=True,
                                          size=(160, 60),
                                          label=ba.Lstr(resource='doneText'),
                                          scale=0.9,
                                          on_activate_call=self._save)
            ba.containerwidget(edit=self._root_widget,
                               start_button=back_button,
                               on_cancel_call=back_button.activate)
            cancel_button = None
        else:
            cancel_button = ba.buttonwidget(
                parent=self._root_widget,
                position=(51, self._height - 65),
                autoselect=True,
                size=(160, 60),
                label=ba.Lstr(resource='cancelText'),
                scale=0.9,
                on_activate_call=self._cancel)
            ba.containerwidget(edit=self._root_widget,
                               cancel_button=cancel_button)

        save_button: Optional[ba.Widget]
        if not self._is_secondary:
            save_button = ba.buttonwidget(
                parent=self._root_widget,
                position=(self._width - (165 if self._is_secondary else 195),
                          self._height - 65),
                size=((160 if self._is_secondary else 180), 60),
                autoselect=True,
                label=ba.Lstr(resource='doneText')
                if self._is_secondary else ba.Lstr(resource='saveText'),
                scale=0.9,
                on_activate_call=self._save)
            ba.containerwidget(edit=self._root_widget,
                               start_button=save_button)
        else:
            save_button = None

        if not self._is_secondary:
            v = self._height - 59
            ba.textwidget(parent=self._root_widget,
                          position=(0, v + 5),
                          size=(self._width, 25),
                          text=ba.Lstr(resource=self._r + '.titleText'),
                          color=ba.app.ui.title_color,
                          maxwidth=310,
                          h_align='center',
                          v_align='center')
            v -= 48

            ba.textwidget(parent=self._root_widget,
                          position=(0, v + 3),
                          size=(self._width, 25),
                          text=self._name,
                          color=ba.app.ui.infotextcolor,
                          maxwidth=self._width * 0.9,
                          h_align='center',
                          v_align='center')
            v -= self._spacing * 1

            ba.textwidget(parent=self._root_widget,
                          position=(50, v + 10),
                          size=(self._width - 100, 30),
                          text=ba.Lstr(resource=self._r + '.appliesToAllText'),
                          maxwidth=330,
                          scale=0.65,
                          color=(0.5, 0.6, 0.5, 1.0),
                          h_align='center',
                          v_align='center')
            v -= 70
            self._enable_check_box = None
        else:
            v = self._height - 49
            ba.textwidget(parent=self._root_widget,
                          position=(0, v + 5),
                          size=(self._width, 25),
                          text=ba.Lstr(resource=self._r + '.secondaryText'),
                          color=ba.app.ui.title_color,
                          maxwidth=300,
                          h_align='center',
                          v_align='center')
            v -= self._spacing * 1

            ba.textwidget(parent=self._root_widget,
                          position=(50, v + 10),
                          size=(self._width - 100, 30),
                          text=ba.Lstr(resource=self._r + '.secondHalfText'),
                          maxwidth=300,
                          scale=0.65,
                          color=(0.6, 0.8, 0.6, 1.0),
                          h_align='center')
            self._enable_check_box = ba.checkboxwidget(
                parent=self._root_widget,
                position=(self._width * 0.5 - 80, v - 73),
                value=self.get_enable_secondary_value(),
                autoselect=True,
                on_value_change_call=self._enable_check_box_changed,
                size=(200, 30),
                text=ba.Lstr(resource=self._r + '.secondaryEnableText'),
                scale=1.2)
            v = self._height - 205

        h_offs = 160
        dist = 70
        d_color = (0.4, 0.4, 0.8)
        sclx = 1.2
        scly = 0.98
        dpm = ba.Lstr(resource=self._r + '.pressAnyButtonOrDpadText')
        dpm2 = ba.Lstr(resource=self._r + '.ifNothingHappensTryAnalogText')
        self._capture_button(pos=(h_offs, v + scly * dist),
                             color=d_color,
                             button='buttonUp' + self._ext,
                             texture=ba.gettexture('upButton'),
                             scale=1.0,
                             message=dpm,
                             message2=dpm2)
        self._capture_button(pos=(h_offs - sclx * dist, v),
                             color=d_color,
                             button='buttonLeft' + self._ext,
                             texture=ba.gettexture('leftButton'),
                             scale=1.0,
                             message=dpm,
                             message2=dpm2)
        self._capture_button(pos=(h_offs + sclx * dist, v),
                             color=d_color,
                             button='buttonRight' + self._ext,
                             texture=ba.gettexture('rightButton'),
                             scale=1.0,
                             message=dpm,
                             message2=dpm2)
        self._capture_button(pos=(h_offs, v - scly * dist),
                             color=d_color,
                             button='buttonDown' + self._ext,
                             texture=ba.gettexture('downButton'),
                             scale=1.0,
                             message=dpm,
                             message2=dpm2)

        dpm3 = ba.Lstr(resource=self._r + '.ifNothingHappensTryDpadText')
        self._capture_button(pos=(h_offs + 130, v - 125),
                             color=(0.4, 0.4, 0.6),
                             button='analogStickLR' + self._ext,
                             maxwidth=140,
                             texture=ba.gettexture('analogStick'),
                             scale=1.2,
                             message=ba.Lstr(resource=self._r +
                                             '.pressLeftRightText'),
                             message2=dpm3)

        self._capture_button(pos=(self._width * 0.5, v),
                             color=(0.4, 0.4, 0.6),
                             button='buttonStart' + self._ext,
                             texture=ba.gettexture('startButton'),
                             scale=0.7)

        h_offs = self._width - 160

        self._capture_button(pos=(h_offs, v + scly * dist),
                             color=(0.6, 0.4, 0.8),
                             button='buttonPickUp' + self._ext,
                             texture=ba.gettexture('buttonPickUp'),
                             scale=1.0)
        self._capture_button(pos=(h_offs - sclx * dist, v),
                             color=(0.7, 0.5, 0.1),
                             button='buttonPunch' + self._ext,
                             texture=ba.gettexture('buttonPunch'),
                             scale=1.0)
        self._capture_button(pos=(h_offs + sclx * dist, v),
                             color=(0.5, 0.2, 0.1),
                             button='buttonBomb' + self._ext,
                             texture=ba.gettexture('buttonBomb'),
                             scale=1.0)
        self._capture_button(pos=(h_offs, v - scly * dist),
                             color=(0.2, 0.5, 0.2),
                             button='buttonJump' + self._ext,
                             texture=ba.gettexture('buttonJump'),
                             scale=1.0)

        self._advanced_button = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            label=ba.Lstr(resource=self._r + '.advancedText'),
            text_scale=0.9,
            color=(0.45, 0.4, 0.5),
            textcolor=(0.65, 0.6, 0.7),
            position=(self._width - 300, 30),
            size=(130, 40),
            on_activate_call=self._do_advanced)

        try:
            if cancel_button is not None and save_button is not None:
                ba.widget(edit=cancel_button, right_widget=save_button)
                ba.widget(edit=save_button, left_widget=cancel_button)
        except Exception:
            ba.print_exception('Error wiring up gamepad config window.')
Exemplo n.º 2
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
Exemplo n.º 3
0
    def _set_tab(self, tab_id: TabID) -> None:
        # pylint: disable=too-many-locals

        if self._current_tab == tab_id:
            return
        self._current_tab = tab_id

        # Preserve our current tab between runs.
        cfg = ba.app.config
        cfg['Watch Tab'] = tab_id.value
        cfg.commit()

        # Update tab colors based on which is selected.
        # tabs.update_tab_button_colors(self._tab_buttons, tab)
        self._tab_row.update_appearance(tab_id)

        if self._tab_container:
            self._tab_container.delete()
        scroll_left = (self._width - self._scroll_width) * 0.5
        scroll_bottom = self._height - self._scroll_height - 79 - 48

        # A place where tabs can store data to get cleared when
        # switching to a different tab
        self._tab_data = {}

        uiscale = ba.app.ui.uiscale
        if tab_id is self.TabID.MY_REPLAYS:
            c_width = self._scroll_width
            c_height = self._scroll_height - 20
            sub_scroll_height = c_height - 63
            self._my_replays_scroll_width = sub_scroll_width = (
                680 if uiscale is ba.UIScale.SMALL else 640)

            self._tab_container = cnt = ba.containerwidget(
                parent=self._root_widget,
                position=(scroll_left, scroll_bottom +
                          (self._scroll_height - c_height) * 0.5),
                size=(c_width, c_height),
                background=False,
                selection_loops_to_parent=True)

            v = c_height - 30
            ba.textwidget(parent=cnt,
                          position=(c_width * 0.5, v),
                          color=(0.6, 1.0, 0.6),
                          scale=0.7,
                          size=(0, 0),
                          maxwidth=c_width * 0.9,
                          h_align='center',
                          v_align='center',
                          text=ba.Lstr(
                              resource='replayRenameWarningText',
                              subs=[('${REPLAY}',
                                     ba.Lstr(resource='replayNameDefaultText'))
                                    ]))

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

            b_color = (0.6, 0.53, 0.63)
            b_textcolor = (0.75, 0.7, 0.8)
            btnv = (c_height - (48 if uiscale is ba.UIScale.SMALL else
                                45 if uiscale is ba.UIScale.MEDIUM else 40) -
                    b_height)
            btnh = 40 if uiscale is ba.UIScale.SMALL else 40
            smlh = 190 if uiscale is ba.UIScale.SMALL else 225
            tscl = 1.0 if uiscale is ba.UIScale.SMALL else 1.2
            self._my_replays_watch_replay_button = btn1 = ba.buttonwidget(
                parent=cnt,
                size=(b_width, b_height),
                position=(btnh, btnv),
                button_type='square',
                color=b_color,
                textcolor=b_textcolor,
                on_activate_call=self._on_my_replay_play_press,
                text_scale=tscl,
                label=ba.Lstr(resource=self._r + '.watchReplayButtonText'),
                autoselect=True)
            ba.widget(edit=btn1, up_widget=self._tab_row.tabs[tab_id].button)
            if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
                ba.widget(edit=btn1,
                          left_widget=_ba.get_special_widget('back_button'))
            btnv -= b_height + b_space_extra
            ba.buttonwidget(parent=cnt,
                            size=(b_width, b_height),
                            position=(btnh, btnv),
                            button_type='square',
                            color=b_color,
                            textcolor=b_textcolor,
                            on_activate_call=self._on_my_replay_rename_press,
                            text_scale=tscl,
                            label=ba.Lstr(resource=self._r +
                                          '.renameReplayButtonText'),
                            autoselect=True)
            btnv -= b_height + b_space_extra
            ba.buttonwidget(parent=cnt,
                            size=(b_width, b_height),
                            position=(btnh, btnv),
                            button_type='square',
                            color=b_color,
                            textcolor=b_textcolor,
                            on_activate_call=self._on_my_replay_delete_press,
                            text_scale=tscl,
                            label=ba.Lstr(resource=self._r +
                                          '.deleteReplayButtonText'),
                            autoselect=True)

            v -= sub_scroll_height + 23
            self._scrollwidget = scrlw = ba.scrollwidget(
                parent=cnt,
                position=(smlh, v),
                size=(sub_scroll_width, sub_scroll_height))
            ba.containerwidget(edit=cnt, selected_child=scrlw)
            self._columnwidget = ba.columnwidget(parent=scrlw,
                                                 left_border=10,
                                                 border=2,
                                                 margin=0)

            ba.widget(edit=scrlw,
                      autoselect=True,
                      left_widget=btn1,
                      up_widget=self._tab_row.tabs[tab_id].button)
            ba.widget(edit=self._tab_row.tabs[tab_id].button,
                      down_widget=scrlw)

            self._my_replay_selected = None
            self._refresh_my_replays()
Exemplo n.º 4
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.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.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.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.toolbars else self._scrollwidget)
        self._col = ba.columnwidget(parent=scrollwidget)

        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)
Exemplo n.º 5
0
    def __init__(self, textwidget: ba.Widget, label: str, max_chars: int):
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        self._target_text = textwidget
        self._width = 700
        self._height = 400
        uiscale = ba.app.ui.uiscale
        top_extra = 20 if uiscale is ba.UIScale.SMALL else 0
        super().__init__(root_widget=ba.containerwidget(
            parent=_ba.get_special_widget('overlay_stack'),
            size=(self._width, self._height + top_extra),
            transition='in_scale',
            scale_origin_stack_offset=self._target_text.
            get_screen_space_center(),
            scale=(2.0 if uiscale is ba.UIScale.SMALL else
                   1.5 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, 0) if uiscale is ba.UIScale.SMALL else (
                0, 0) if uiscale is ba.UIScale.MEDIUM else (0, 0)))
        self._done_button = ba.buttonwidget(parent=self._root_widget,
                                            position=(self._width - 200, 44),
                                            size=(140, 60),
                                            autoselect=True,
                                            label=ba.Lstr(resource='doneText'),
                                            on_activate_call=self._done)
        ba.containerwidget(edit=self._root_widget,
                           on_cancel_call=self._cancel,
                           start_button=self._done_button)

        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height - 41),
                      size=(0, 0),
                      scale=0.95,
                      text=label,
                      maxwidth=self._width - 140,
                      color=ba.app.ui.title_color,
                      h_align='center',
                      v_align='center')

        self._text_field = ba.textwidget(
            parent=self._root_widget,
            position=(70, self._height - 116),
            max_chars=max_chars,
            text=cast(str, ba.textwidget(query=self._target_text)),
            on_return_press_call=self._done,
            autoselect=True,
            size=(self._width - 140, 55),
            v_align='center',
            editable=True,
            maxwidth=self._width - 175,
            force_internal_editing=True,
            always_show_carat=True)

        self._shift_button = None
        self._double_press_shift = False
        self._num_mode_button = None
        self._emoji_button = None
        self._char_keys: List[ba.Widget] = []
        self._mode = 'normal'
        self._last_mode = 'normal'

        v = self._height - 180
        key_width = 46
        key_height = 46
        self._key_color_lit = (1.4, 1.2, 1.4)
        self._key_color = key_color = (0.69, 0.6, 0.74)
        self._key_color_dark = key_color_dark = (0.55, 0.55, 0.71)
        key_textcolor = (1, 1, 1)
        row_starts = (69, 95, 151)

        self._click_sound = ba.getsound('click01')

        # kill prev char keys
        for key in self._char_keys:
            key.delete()
        self._char_keys = []

        # dummy data just used for row/column lengths... we don't actually
        # set things until refresh
        chars: List[Tuple[str, ...]] = [
            ('q', 'u', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'),
            ('a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'),
            ('z', 'x', 'c', 'v', 'b', 'n', 'm')
        ]

        for row_num, row in enumerate(chars):
            h = row_starts[row_num]
            # shift key before row 3
            if row_num == 2:
                self._shift_button = ba.buttonwidget(
                    parent=self._root_widget,
                    position=(h - key_width * 2.0, v),
                    size=(key_width * 1.7, key_height),
                    autoselect=True,
                    textcolor=key_textcolor,
                    color=key_color_dark,
                    label=charstr(SpCh.SHIFT),
                    enable_sound=False,
                    extra_touch_border_scale=0.3,
                    button_type='square',
                )

            for _ in row:
                btn = ba.buttonwidget(
                    parent=self._root_widget,
                    position=(h, v),
                    size=(key_width, key_height),
                    autoselect=True,
                    enable_sound=False,
                    textcolor=key_textcolor,
                    color=key_color,
                    label='',
                    button_type='square',
                    extra_touch_border_scale=0.1,
                )
                self._char_keys.append(btn)
                h += key_width + 10

            # Add delete key at end of third row.
            if row_num == 2:
                ba.buttonwidget(parent=self._root_widget,
                                position=(h + 4, v),
                                size=(key_width * 1.8, key_height),
                                autoselect=True,
                                enable_sound=False,
                                repeat=True,
                                textcolor=key_textcolor,
                                color=key_color_dark,
                                label=charstr(SpCh.DELETE),
                                button_type='square',
                                on_activate_call=self._del)
            v -= (key_height + 9)
            # Do space bar and stuff.
            if row_num == 2:
                if self._num_mode_button is None:
                    self._num_mode_button = ba.buttonwidget(
                        parent=self._root_widget,
                        position=(112, v - 8),
                        size=(key_width * 2, key_height + 5),
                        enable_sound=False,
                        button_type='square',
                        extra_touch_border_scale=0.3,
                        autoselect=True,
                        textcolor=key_textcolor,
                        color=key_color_dark,
                        label='',
                    )
                if self._emoji_button is None:
                    self._emoji_button = ba.buttonwidget(
                        parent=self._root_widget,
                        position=(56, v - 8),
                        size=(key_width, key_height + 5),
                        autoselect=True,
                        enable_sound=False,
                        textcolor=key_textcolor,
                        color=key_color_dark,
                        label=charstr(SpCh.LOGO_FLAT),
                        extra_touch_border_scale=0.3,
                        button_type='square',
                    )
                btn1 = self._num_mode_button
                btn2 = ba.buttonwidget(parent=self._root_widget,
                                       position=(210, v - 12),
                                       size=(key_width * 6.1, key_height + 15),
                                       extra_touch_border_scale=0.3,
                                       enable_sound=False,
                                       autoselect=True,
                                       textcolor=key_textcolor,
                                       color=key_color_dark,
                                       label=ba.Lstr(resource='spaceKeyText'),
                                       on_activate_call=ba.Call(
                                           self._type_char, ' '))
                btn3 = self._emoji_button
                ba.widget(edit=btn1, right_widget=btn2, left_widget=btn3)
                ba.widget(edit=btn2,
                          left_widget=btn1,
                          right_widget=self._done_button)
                ba.widget(edit=btn3, left_widget=btn1)
                ba.widget(edit=self._done_button, left_widget=btn2)

        ba.containerwidget(edit=self._root_widget,
                           selected_child=self._char_keys[14])

        self._refresh()
Exemplo n.º 6
0
    def __init__(self,
                 gameclass: 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._gameclass = gameclass
        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 = gameclass.get_supported_maps(sessiontype)
        if not valid_maps:
            ba.screenmessage(ba.Lstr(resource='noValidMapsErrorText'))
            raise Exception('No valid maps')

        self._settings_defs = gameclass.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('exception 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] = {}

        width = 720 if ba.app.small_ui else 620
        x_inset = 50 if ba.app.small_ui else 0
        height = (365 if ba.app.small_ui else 460 if ba.app.med_ui 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 ba.app.small_ui else 0
        super().__init__(root_widget=ba.containerwidget(
            size=(width, height + top_extra),
            transition=transition,
            scale=(
                2.19 if ba.app.small_ui else 1.35 if ba.app.med_ui else 1.0),
            stack_offset=(0, -17) if ba.app.small_ui 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.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=gameclass.get_display_string(),
                      color=ba.app.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)
        self._subcontainer = cnt = ba.containerwidget(
            parent=self._scrollwidget,
            size=(scroll_width, scroll_height),
            background=False)

        # So selection loops through everything and doesn't get stuck in
        # sub-containers.
        ba.containerwidget(edit=self._scrollwidget,
                           claims_left_right=True,
                           claims_tab=True,
                           selection_loop_to_parent=True)
        ba.containerwidget(edit=cnt,
                           claims_left_right=True,
                           claims_tab=True,
                           selection_loop_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):
                # if 'choices' in setting:
                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)
Exemplo n.º 7
0
                def instantiate(self, scrollwidget: ba.Widget,
                                tab_button: ba.Widget) -> None:
                    """Create the store."""
                    # pylint: disable=too-many-locals
                    # pylint: disable=too-many-branches
                    # pylint: disable=too-many-nested-blocks
                    from bastd.ui.store import item as storeitemui
                    title_spacing = 40
                    button_border = 20
                    button_spacing = 4
                    boffs_h = 40
                    self._height = 80.0

                    # Calc total height.
                    for i, section in enumerate(self._sections):
                        if section['title'] != '':
                            assert self._height is not None
                            self._height += title_spacing
                        b_width, b_height = section['button_size']
                        b_column_count = int(
                            math.floor((self._width - boffs_h - 20) /
                                       (b_width + button_spacing)))
                        b_row_count = int(
                            math.ceil(
                                float(len(section['items'])) / b_column_count))
                        b_height_total = (
                            2 * button_border + b_row_count * b_height +
                            (b_row_count - 1) * section['v_spacing'])
                        self._height += b_height_total

                    assert self._height is not None
                    cnt2 = ba.containerwidget(parent=scrollwidget,
                                              scale=1.0,
                                              size=(self._width, self._height),
                                              background=False)
                    ba.containerwidget(edit=cnt2,
                                       claims_left_right=True,
                                       claims_tab=True,
                                       selection_loop_to_parent=True)
                    v = self._height - 20

                    if self._tab == 'characters':
                        txt = ba.Lstr(
                            resource='store.howToSwitchCharactersText',
                            subs=[
                                ('${SETTINGS}',
                                 ba.Lstr(
                                     resource='accountSettingsWindow.titleText'
                                 )),
                                ('${PLAYER_PROFILES}',
                                 ba.Lstr(
                                     resource='playerProfilesWindow.titleText')
                                 )
                            ])
                        ba.textwidget(parent=cnt2,
                                      text=txt,
                                      size=(0, 0),
                                      position=(self._width * 0.5,
                                                self._height - 28),
                                      h_align='center',
                                      v_align='center',
                                      color=(0.7, 1, 0.7, 0.4),
                                      scale=0.7,
                                      shadow=0,
                                      flatness=1.0,
                                      maxwidth=700,
                                      transition_delay=0.4)
                    elif self._tab == 'icons':
                        txt = ba.Lstr(
                            resource='store.howToUseIconsText',
                            subs=[
                                ('${SETTINGS}',
                                 ba.Lstr(resource='mainMenu.settingsText')),
                                ('${PLAYER_PROFILES}',
                                 ba.Lstr(
                                     resource='playerProfilesWindow.titleText')
                                 )
                            ])
                        ba.textwidget(parent=cnt2,
                                      text=txt,
                                      size=(0, 0),
                                      position=(self._width * 0.5,
                                                self._height - 28),
                                      h_align='center',
                                      v_align='center',
                                      color=(0.7, 1, 0.7, 0.4),
                                      scale=0.7,
                                      shadow=0,
                                      flatness=1.0,
                                      maxwidth=700,
                                      transition_delay=0.4)
                    elif self._tab == 'maps':
                        assert self._width is not None
                        assert self._height is not None
                        txt = ba.Lstr(resource='store.howToUseMapsText')
                        ba.textwidget(parent=cnt2,
                                      text=txt,
                                      size=(0, 0),
                                      position=(self._width * 0.5,
                                                self._height - 28),
                                      h_align='center',
                                      v_align='center',
                                      color=(0.7, 1, 0.7, 0.4),
                                      scale=0.7,
                                      shadow=0,
                                      flatness=1.0,
                                      maxwidth=700,
                                      transition_delay=0.4)

                    prev_row_buttons: Optional[List] = None
                    this_row_buttons = []

                    delay = 0.3
                    for section in self._sections:
                        if section['title'] != '':
                            ba.textwidget(
                                parent=cnt2,
                                position=(60, v - title_spacing * 0.8),
                                size=(0, 0),
                                scale=1.0,
                                transition_delay=delay,
                                color=(0.7, 0.9, 0.7, 1),
                                h_align="left",
                                v_align="center",
                                text=ba.Lstr(resource=section['title']),
                                maxwidth=self._width * 0.7)
                            v -= title_spacing
                        delay = max(0.100, delay - 0.100)
                        v -= button_border
                        b_width, b_height = section['button_size']
                        b_count = len(section['items'])
                        b_column_count = int(
                            math.floor((self._width - boffs_h - 20) /
                                       (b_width + button_spacing)))
                        col = 0
                        item: Dict[str, Any]
                        assert self._store_window.button_infos is not None
                        for i, item_name in enumerate(section['items']):
                            item = self._store_window.button_infos[
                                item_name] = {}
                            item['call'] = ba.WeakCall(self._store_window.buy,
                                                       item_name)
                            if 'x_offs' in section:
                                boffs_h2 = section['x_offs']
                            else:
                                boffs_h2 = 0

                            if 'y_offs' in section:
                                boffs_v2 = section['y_offs']
                            else:
                                boffs_v2 = 0
                            b_pos = (boffs_h + boffs_h2 +
                                     (b_width + button_spacing) * col,
                                     v - b_height + boffs_v2)
                            storeitemui.instantiate_store_item_display(
                                item_name,
                                item,
                                parent_widget=cnt2,
                                b_pos=b_pos,
                                boffs_h=boffs_h,
                                b_width=b_width,
                                b_height=b_height,
                                boffs_h2=boffs_h2,
                                boffs_v2=boffs_v2,
                                delay=delay)
                            btn = item['button']
                            delay = max(0.1, delay - 0.1)
                            this_row_buttons.append(btn)

                            # Wire this button to the equivalent in the
                            # previous row.
                            if prev_row_buttons is not None:
                                # pylint: disable=unsubscriptable-object
                                if len(prev_row_buttons) > col:
                                    ba.widget(edit=btn,
                                              up_widget=prev_row_buttons[col])
                                    ba.widget(edit=prev_row_buttons[col],
                                              down_widget=btn)

                                    # If we're the last button in our row,
                                    # wire any in the previous row past
                                    # our position to go to us if down is
                                    # pressed.
                                    if (col + 1 == b_column_count
                                            or i == b_count - 1):
                                        for b_prev in prev_row_buttons[col +
                                                                       1:]:
                                            ba.widget(edit=b_prev,
                                                      down_widget=btn)
                                else:
                                    ba.widget(edit=btn,
                                              up_widget=prev_row_buttons[-1])
                            else:
                                ba.widget(edit=btn, up_widget=tab_button)

                            col += 1
                            if col == b_column_count or i == b_count - 1:
                                prev_row_buttons = this_row_buttons
                                this_row_buttons = []
                                col = 0
                                v -= b_height
                                if i < b_count - 1:
                                    v -= section['v_spacing']

                        v -= button_border

                    # Set a timer to update these buttons periodically as long
                    # as we're alive (so if we buy one it will grey out, etc).
                    self._store_window.update_buttons_timer = ba.Timer(
                        0.5,
                        ba.WeakCall(self._store_window.update_buttons),
                        repeat=True,
                        timetype=ba.TimeType.REAL)

                    # Also update them immediately.
                    self._store_window.update_buttons()
Exemplo n.º 8
0
    def on_activate(
        self,
        parent_widget: ba.Widget,
        tab_button: ba.Widget,
        region_width: float,
        region_height: float,
        region_left: float,
        region_bottom: float,
    ) -> ba.Widget:
        c_width = region_width
        c_height = region_height - 20
        self._container = ba.containerwidget(
            parent=parent_widget,
            position=(region_left,
                      region_bottom + (region_height - c_height) * 0.5),
            size=(c_width, c_height),
            background=False,
            selection_loops_to_parent=True)
        v = c_height - 30
        self._join_text = ba.textwidget(
            parent=self._container,
            position=(c_width * 0.5 - 245, v - 13),
            color=(0.6, 1.0, 0.6),
            scale=1.3,
            size=(200, 30),
            maxwidth=250,
            h_align='left',
            v_align='center',
            click_activate=True,
            selectable=True,
            autoselect=True,
            on_activate_call=lambda: self._set_sub_tab(
                SubTabType.JOIN,
                region_width,
                region_height,
                playsound=True,
            ),
            text=ba.Lstr(resource='gatherWindow.'
                         'joinPublicPartyDescriptionText'))
        self._host_text = ba.textwidget(
            parent=self._container,
            position=(c_width * 0.5 + 45, v - 13),
            color=(0.6, 1.0, 0.6),
            scale=1.3,
            size=(200, 30),
            maxwidth=250,
            h_align='left',
            v_align='center',
            click_activate=True,
            selectable=True,
            autoselect=True,
            on_activate_call=lambda: self._set_sub_tab(
                SubTabType.HOST,
                region_width,
                region_height,
                playsound=True,
            ),
            text=ba.Lstr(resource='gatherWindow.'
                         'hostPublicPartyDescriptionText'))
        ba.widget(edit=self._join_text, up_widget=tab_button)
        ba.widget(edit=self._host_text,
                  left_widget=self._join_text,
                  up_widget=tab_button)
        ba.widget(edit=self._join_text, right_widget=self._host_text)

        # Attempt to fetch our local address so we have it for error messages.
        if self._local_address is None:
            AddrFetchThread(ba.WeakCall(self._fetch_local_addr_cb)).start()

        self._set_sub_tab(self._sub_tab, region_width, region_height)
        self._update_timer = ba.Timer(0.1,
                                      ba.WeakCall(self._update),
                                      repeat=True,
                                      timetype=ba.TimeType.REAL)
        return self._container
Exemplo n.º 9
0
    def _build_join_tab(self, region_width: float,
                        region_height: float) -> None:
        c_width = region_width
        c_height = region_height - 20
        sub_scroll_height = c_height - 125
        sub_scroll_width = 830
        v = c_height - 35
        v -= 60
        filter_txt = ba.Lstr(resource='filterText')
        self._filter_text = ba.textwidget(parent=self._container,
                                          text=self._filter_value,
                                          size=(350, 45),
                                          position=(290, v - 10),
                                          h_align='left',
                                          v_align='center',
                                          editable=True,
                                          description=filter_txt)
        ba.widget(edit=self._filter_text, up_widget=self._join_text)
        ba.textwidget(text=filter_txt,
                      parent=self._container,
                      size=(0, 0),
                      position=(270, v + 13),
                      maxwidth=150,
                      scale=0.8,
                      color=(0.5, 0.5, 0.5),
                      flatness=1.0,
                      shadow=0.0,
                      h_align='right',
                      v_align='center')

        ba.textwidget(text=ba.Lstr(resource='nameText'),
                      parent=self._container,
                      size=(0, 0),
                      position=(90, v - 8),
                      maxwidth=60,
                      scale=0.6,
                      color=(0.5, 0.5, 0.5),
                      flatness=1.0,
                      shadow=0.0,
                      h_align='center',
                      v_align='center')
        ba.textwidget(text=ba.Lstr(resource='gatherWindow.partySizeText'),
                      parent=self._container,
                      size=(0, 0),
                      position=(755, v - 8),
                      maxwidth=60,
                      scale=0.6,
                      color=(0.5, 0.5, 0.5),
                      flatness=1.0,
                      shadow=0.0,
                      h_align='center',
                      v_align='center')
        ba.textwidget(text=ba.Lstr(resource='gatherWindow.pingText'),
                      parent=self._container,
                      size=(0, 0),
                      position=(825, v - 8),
                      maxwidth=60,
                      scale=0.6,
                      color=(0.5, 0.5, 0.5),
                      flatness=1.0,
                      shadow=0.0,
                      h_align='center',
                      v_align='center')
        v -= sub_scroll_height + 23
        self._host_scrollwidget = scrollw = ba.scrollwidget(
            parent=self._container,
            simple_culling_v=10,
            position=((c_width - sub_scroll_width) * 0.5, v),
            size=(sub_scroll_width, sub_scroll_height),
            claims_up_down=False,
            claims_left_right=True,
            autoselect=True)
        self._join_list_column = ba.containerwidget(parent=scrollw,
                                                    background=False,
                                                    size=(400, 400),
                                                    claims_left_right=True)
        self._join_status_text = ba.textwidget(parent=self._container,
                                               text='',
                                               size=(0, 0),
                                               scale=0.9,
                                               flatness=1.0,
                                               shadow=0.0,
                                               h_align='center',
                                               v_align='top',
                                               maxwidth=c_width,
                                               color=(0.6, 0.6, 0.6),
                                               position=(c_width * 0.5,
                                                         c_height * 0.5))
Exemplo n.º 10
0
    def __init__(self, position: Tuple[float, float], scale: float = None):
        # pylint: disable=too-many-locals
        if scale is None:
            scale = (2.3
                     if ba.app.small_ui else 1.65 if ba.app.med_ui else 1.23)
        self._transitioning_out = False
        self._width = 450
        self._height = (300
                        if ba.app.small_ui else 370 if ba.app.med_ui 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')
Exemplo n.º 11
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
        appconfig = ba.app.config

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                index += 1

                if index >= count:
                    break
            if index >= count:
                break
        self._customize_button = btn = ba.buttonwidget(
            parent=self._subcontainer,
            size=(100, 30),
            position=(34 + h_offs_bottom, 50),
            text_scale=0.6,
            label=ba.Lstr(resource='customizeText'),
            on_activate_call=self._on_customize_press,
            color=(0.54, 0.52, 0.67),
            textcolor=(0.7, 0.65, 0.7),
            autoselect=True)
        ba.widget(edit=btn, show_buffer_top=22, show_buffer_bottom=28)
        self._restore_state()
Exemplo n.º 12
0
    def _update_for_league_rank_data(self, data: Optional[Dict[str,
                                                               Any]]) -> None:
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        if not self._root_widget:
            return
        accounts = ba.app.accounts
        in_top = (data is not None and data['rank'] is not None)
        eq_text = self._rdict.powerRankingPointsEqualsText
        pts_txt = self._rdict.powerRankingPointsText
        num_text = ba.Lstr(resource='numberText').evaluate()
        do_percent = False
        finished_season_unranked = False
        self._can_do_more_button = True
        extra_text = ''
        if _ba.get_account_state() != 'signed_in':
            status_text = '(' + ba.Lstr(
                resource='notSignedInText').evaluate() + ')'
        elif in_top:
            assert data is not None
            status_text = num_text.replace('${NUMBER}', str(data['rank']))
        elif data is not None:
            try:
                # handle old seasons where we didn't wind up ranked
                # at the end..
                if not data['scores']:
                    status_text = (
                        self._rdict.powerRankingFinishedSeasonUnrankedText)
                    extra_text = ''
                    finished_season_unranked = True
                    self._can_do_more_button = False
                else:
                    our_points = accounts.get_league_rank_points(data)
                    progress = float(our_points) / max(1,
                                                       data['scores'][-1][1])
                    status_text = str(int(progress * 100.0)) + '%'
                    extra_text = (
                        '\n' +
                        self._rdict.powerRankingPointsToRankedText.replace(
                            '${CURRENT}', str(our_points)).replace(
                                '${REMAINING}', str(data['scores'][-1][1])))
                    do_percent = True
            except Exception:
                ba.print_exception('Error updating power ranking.')
                status_text = self._rdict.powerRankingNotInTopText.replace(
                    '${NUMBER}', str(data['listSize']))
                extra_text = ''
        else:
            status_text = '-'

        self._season = data['s'] if data is not None else None

        v = self._subcontainerheight - 20
        popup_was_selected = False
        if self._season_popup_menu is not None:
            btn = self._season_popup_menu.get_button()
            assert self._subcontainer
            if self._subcontainer.get_selected_child() == btn:
                popup_was_selected = True
            btn.delete()
        season_choices = []
        season_choices_display = []
        did_first = False
        self._is_current_season = False
        if data is not None:
            # build our list of seasons we have available
            for ssn in data['sl']:
                season_choices.append(ssn)
                if ssn != 'a' and not did_first:
                    season_choices_display.append(
                        ba.Lstr(resource='league.currentSeasonText',
                                subs=[('${NUMBER}', ssn)]))
                    did_first = True
                    # if we either did not specify a season or specified the
                    # first, we're looking at the current..
                    if self._season in [ssn, None]:
                        self._is_current_season = True
                elif ssn == 'a':
                    season_choices_display.append(
                        ba.Lstr(resource='league.allTimeText'))
                else:
                    season_choices_display.append(
                        ba.Lstr(resource='league.seasonText',
                                subs=[('${NUMBER}', ssn)]))
            assert self._subcontainer
            self._season_popup_menu = popup_ui.PopupMenu(
                parent=self._subcontainer,
                position=(390, v - 45),
                width=150,
                button_size=(200, 50),
                choices=season_choices,
                on_value_change_call=ba.WeakCall(self._on_season_change),
                choices_display=season_choices_display,
                current_choice=self._season)
            if popup_was_selected:
                ba.containerwidget(
                    edit=self._subcontainer,
                    selected_child=self._season_popup_menu.get_button())
            ba.widget(edit=self._see_more_button, show_buffer_bottom=100)
            ba.widget(edit=self._season_popup_menu.get_button(),
                      up_widget=self._back_button)
            ba.widget(edit=self._back_button,
                      down_widget=self._power_ranking_achievements_button,
                      right_widget=self._season_popup_menu.get_button())

        ba.textwidget(edit=self._league_title_text,
                      text='' if self._season == 'a' else ba.Lstr(
                          resource='league.leagueText'))

        if data is None:
            lname = ''
            lnum = ''
            lcolor = (1, 1, 1)
            self._league_url_arg = ''
        elif self._season == 'a':
            lname = ba.Lstr(resource='league.allTimeText').evaluate()
            lnum = ''
            lcolor = (1, 1, 1)
            self._league_url_arg = ''
        else:
            lnum = ('[' + str(data['l']['i']) + ']') if data['l']['i2'] else ''
            lname = ba.Lstr(translate=('leagueNames',
                                       data['l']['n'])).evaluate()
            lcolor = data['l']['c']
            self._league_url_arg = (data['l']['n'] + '_' +
                                    str(data['l']['i'])).lower()

        to_end_string: Union[ba.Lstr, str]
        if data is None or self._season == 'a' or data['se'] is None:
            to_end_string = ''
            show_season_end = False
        else:
            show_season_end = True
            days_to_end = data['se'][0]
            minutes_to_end = data['se'][1]
            if days_to_end > 0:
                to_end_string = ba.Lstr(resource='league.seasonEndsDaysText',
                                        subs=[('${NUMBER}', str(days_to_end))])
            elif days_to_end == 0 and minutes_to_end >= 60:
                to_end_string = ba.Lstr(resource='league.seasonEndsHoursText',
                                        subs=[('${NUMBER}',
                                               str(minutes_to_end // 60))])
            elif days_to_end == 0 and minutes_to_end >= 0:
                to_end_string = ba.Lstr(
                    resource='league.seasonEndsMinutesText',
                    subs=[('${NUMBER}', str(minutes_to_end))])
            else:
                to_end_string = ba.Lstr(
                    resource='league.seasonEndedDaysAgoText',
                    subs=[('${NUMBER}', str(-(days_to_end + 1)))])

        ba.textwidget(edit=self._season_ends_text, text=to_end_string)
        ba.textwidget(edit=self._trophy_counts_reset_text,
                      text=ba.Lstr(resource='league.trophyCountsResetText')
                      if self._is_current_season and show_season_end else '')

        ba.textwidget(edit=self._league_text, text=lname, color=lcolor)
        l_text_width = min(
            self._league_text_maxwidth,
            _ba.get_string_width(lname, suppress_warning=True) *
            self._league_text_scale)
        ba.textwidget(
            edit=self._league_number_text,
            text=lnum,
            color=lcolor,
            position=(self._league_number_base_pos[0] + l_text_width * 0.5 + 8,
                      self._league_number_base_pos[1] + 10))
        ba.textwidget(
            edit=self._to_ranked_text,
            text=ba.Lstr(resource='coopSelectWindow.toRankedText').evaluate() +
            '' + extra_text if do_percent else '')

        ba.textwidget(
            edit=self._your_power_ranking_text,
            text=ba.Lstr(
                resource='rankText',
                fallback_resource='coopSelectWindow.yourPowerRankingText') if
            (not do_percent) else '')

        ba.textwidget(edit=self._power_ranking_rank_text,
                      position=(473, v - 70 - (170 if do_percent else 220)),
                      text=status_text,
                      big=(in_top or do_percent),
                      scale=3.0 if (in_top or do_percent) else
                      0.7 if finished_season_unranked else 1.0)

        if self._activity_mult_button is not None:
            if data is None or data['act'] is None:
                ba.buttonwidget(edit=self._activity_mult_button,
                                textcolor=(0.7, 0.7, 0.8, 0.5),
                                icon_color=(0.5, 0, 0.5, 0.3))
                ba.textwidget(edit=self._activity_mult_text, text='     -')
            else:
                ba.buttonwidget(edit=self._activity_mult_button,
                                textcolor=(0.7, 0.7, 0.8, 1.0),
                                icon_color=(0.5, 0, 0.5, 1.0))
                # pylint: disable=consider-using-f-string
                ba.textwidget(edit=self._activity_mult_text,
                              text='x ' + ('%.2f' % data['act']))

        have_pro = False if data is None else data['p']
        pro_mult = 1.0 + float(
            _ba.get_account_misc_read_val('proPowerRankingBoost', 0.0)) * 0.01
        # pylint: disable=consider-using-f-string
        ba.textwidget(edit=self._pro_mult_text,
                      text='     -' if
                      (data is None or not have_pro) else 'x ' +
                      ('%.2f' % pro_mult))
        ba.buttonwidget(edit=self._pro_mult_button,
                        textcolor=(0.7, 0.7, 0.8, (1.0 if have_pro else 0.5)),
                        icon_color=(0.5, 0, 0.5) if have_pro else
                        (0.5, 0, 0.5, 0.2))
        ba.buttonwidget(edit=self._power_ranking_achievements_button,
                        label=('' if data is None else
                               (str(data['a']) + ' ')) +
                        ba.Lstr(resource='achievementsText').evaluate())

        # for the achievement value, use the number they gave us for
        # non-current seasons; otherwise calc our own
        total_ach_value = 0
        for ach in ba.app.ach.achievements:
            if ach.complete:
                total_ach_value += ach.power_ranking_value
        if self._season != 'a' and not self._is_current_season:
            if data is not None and 'at' in data:
                total_ach_value = data['at']

        ba.textwidget(edit=self._power_ranking_achievement_total_text,
                      text='-' if data is None else
                      ('+ ' +
                       pts_txt.replace('${NUMBER}', str(total_ach_value))))

        total_trophies_count = (accounts.get_league_rank_points(
            data, 'trophyCount'))
        total_trophies_value = (accounts.get_league_rank_points(
            data, 'trophies'))
        ba.buttonwidget(edit=self._power_ranking_trophies_button,
                        label=('' if data is None else
                               (str(total_trophies_count) + ' ')) +
                        ba.Lstr(resource='trophiesText').evaluate())
        ba.textwidget(
            edit=self._power_ranking_trophies_total_text,
            text='-' if data is None else
            ('+ ' + pts_txt.replace('${NUMBER}', str(total_trophies_value))))

        ba.textwidget(
            edit=self._power_ranking_total_text,
            text='-' if data is None else eq_text.replace(
                '${NUMBER}', str(accounts.get_league_rank_points(data))))
        for widget in self._power_ranking_score_widgets:
            widget.delete()
        self._power_ranking_score_widgets = []

        scores = data['scores'] if data is not None else []
        tally_color = (0.5, 0.6, 0.8)
        w_parent = self._subcontainer
        v2 = self._power_ranking_score_v

        for score in scores:
            h2 = 680
            is_us = score[3]
            self._power_ranking_score_widgets.append(
                ba.textwidget(parent=w_parent,
                              position=(h2 - 20, v2),
                              size=(0, 0),
                              color=(1, 1, 1) if is_us else (0.6, 0.6, 0.7),
                              maxwidth=40,
                              flatness=1.0,
                              shadow=0.0,
                              text=num_text.replace('${NUMBER}',
                                                    str(score[0])),
                              h_align='right',
                              v_align='center',
                              scale=0.5))
            self._power_ranking_score_widgets.append(
                ba.textwidget(parent=w_parent,
                              position=(h2 + 20, v2),
                              size=(0, 0),
                              color=(1, 1, 1) if is_us else tally_color,
                              maxwidth=60,
                              text=str(score[1]),
                              flatness=1.0,
                              shadow=0.0,
                              h_align='center',
                              v_align='center',
                              scale=0.7))
            txt = ba.textwidget(parent=w_parent,
                                position=(h2 + 60, v2 - (28 * 0.5) / 0.9),
                                size=(210 / 0.9, 28),
                                color=(1, 1, 1) if is_us else (0.6, 0.6, 0.6),
                                maxwidth=210,
                                flatness=1.0,
                                shadow=0.0,
                                autoselect=True,
                                selectable=True,
                                click_activate=True,
                                text=score[2],
                                h_align='left',
                                v_align='center',
                                scale=0.9)
            self._power_ranking_score_widgets.append(txt)
            ba.textwidget(edit=txt,
                          on_activate_call=ba.Call(self._show_account_info,
                                                   score[4], txt))
            assert self._season_popup_menu is not None
            ba.widget(edit=txt,
                      left_widget=self._season_popup_menu.get_button())
            v2 -= 28
Exemplo n.º 13
0
    def __init__(self,
                 transition: str = 'in_right',
                 modal: bool = False,
                 origin_widget: ba.Widget = None):
        ba.set_analytics_screen('League Rank Window')

        self._league_rank_data: Optional[Dict[str, Any]] = None
        self._modal = modal

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

        uiscale = ba.app.ui.uiscale
        self._width = 1320 if uiscale is ba.UIScale.SMALL else 1120
        x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
        self._height = (657 if uiscale is ba.UIScale.SMALL else
                        710 if uiscale is ba.UIScale.MEDIUM else 800)
        self._r = 'coopSelectWindow'
        self._rdict = ba.app.lang.get_resource(self._r)
        top_extra = 20 if uiscale is ba.UIScale.SMALL else 0

        self._league_url_arg = ''

        self._is_current_season = False
        self._can_do_more_button = True

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

        self._back_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(75 + x_inset, self._height - 87 -
                      (4 if uiscale is ba.UIScale.SMALL else 0)),
            size=(120, 60),
            scale=1.2,
            autoselect=True,
            label=ba.Lstr(resource='doneText' if self._modal else 'backText'),
            button_type=None if self._modal else 'back',
            on_activate_call=self._back)

        self._title_text = ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height - 56),
            size=(0, 0),
            text=ba.Lstr(
                resource='league.leagueRankText',
                fallback_resource='coopSelectWindow.powerRankingText'),
            h_align='center',
            color=ba.app.ui.title_color,
            scale=1.4,
            maxwidth=600,
            v_align='center')

        ba.buttonwidget(edit=btn,
                        button_type='backSmall',
                        position=(75 + x_inset, self._height - 87 -
                                  (2 if uiscale is ba.UIScale.SMALL else 0)),
                        size=(60, 55),
                        label=ba.charstr(ba.SpecialChar.BACK))

        self._scroll_width = self._width - (130 + 2 * x_inset)
        self._scroll_height = self._height - 160
        self._scrollwidget = ba.scrollwidget(parent=self._root_widget,
                                             highlight=False,
                                             position=(65 + x_inset, 70),
                                             size=(self._scroll_width,
                                                   self._scroll_height),
                                             center_small_content=True)
        ba.widget(edit=self._scrollwidget, autoselect=True)
        ba.containerwidget(edit=self._scrollwidget, claims_left_right=True)
        ba.containerwidget(edit=self._root_widget,
                           cancel_button=self._back_button,
                           selected_child=self._back_button)

        self._last_power_ranking_query_time: Optional[float] = None
        self._doing_power_ranking_query = False

        self._subcontainer: Optional[ba.Widget] = None
        self._subcontainerwidth = 800
        self._subcontainerheight = 483
        self._power_ranking_score_widgets: List[ba.Widget] = []

        self._season_popup_menu: Optional[popup_ui.PopupMenu] = None
        self._requested_season: Optional[str] = None
        self._season: Optional[str] = None

        # take note of our account state; we'll refresh later if this changes
        self._account_state = _ba.get_account_state()

        self._refresh()
        self._restore_state()

        # if we've got cached power-ranking data already, display it
        info = ba.app.accounts.get_cached_league_rank_data()
        if info is not None:
            self._update_for_league_rank_data(info)

        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)
        self._update(show=(info is None))
Exemplo n.º 14
0
    def _refresh(self) -> None:
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        # pylint: disable=cyclic-import
        from bastd.ui import confirm

        account_state = _ba.get_v1_account_state()
        account_type = (_ba.get_v1_account_type()
                        if account_state == 'signed_in' else 'unknown')

        is_google = account_type == 'Google Play'

        show_local_signed_in_as = False
        local_signed_in_as_space = 50.0

        show_signed_in_as = self._signed_in
        signed_in_as_space = 95.0

        show_sign_in_benefits = not self._signed_in
        sign_in_benefits_space = 80.0

        show_signing_in_text = account_state == 'signing_in'
        signing_in_text_space = 80.0

        show_google_play_sign_in_button = (account_state == 'signed_out'
                                           and 'Google Play'
                                           in self._show_sign_in_buttons)
        show_game_circle_sign_in_button = (account_state == 'signed_out'
                                           and 'Game Circle'
                                           in self._show_sign_in_buttons)
        show_device_sign_in_button = (account_state == 'signed_out' and 'Local'
                                      in self._show_sign_in_buttons)
        show_v2_sign_in_button = (account_state == 'signed_out'
                                  and 'V2' in self._show_sign_in_buttons)
        sign_in_button_space = 70.0

        show_game_service_button = (self._signed_in and account_type
                                    in ['Game Center', 'Game Circle'])
        game_service_button_space = 60.0

        show_linked_accounts_text = (self._signed_in
                                     and _ba.get_v1_account_misc_read_val(
                                         'allowAccountLinking2', False))
        linked_accounts_text_space = 60.0

        show_achievements_button = (
            self._signed_in
            and account_type in ('Google Play', 'Alibaba', 'Local', 'OUYA'))
        achievements_button_space = 60.0

        show_achievements_text = (self._signed_in
                                  and not show_achievements_button)
        achievements_text_space = 27.0

        show_leaderboards_button = (self._signed_in and is_google)
        leaderboards_button_space = 60.0

        show_campaign_progress = self._signed_in
        campaign_progress_space = 27.0

        show_tickets = self._signed_in
        tickets_space = 27.0

        show_reset_progress_button = False
        reset_progress_button_space = 70.0

        show_player_profiles_button = self._signed_in
        player_profiles_button_space = 100.0

        show_link_accounts_button = (self._signed_in
                                     and _ba.get_v1_account_misc_read_val(
                                         'allowAccountLinking2', False))
        link_accounts_button_space = 70.0

        show_unlink_accounts_button = show_link_accounts_button
        unlink_accounts_button_space = 90.0

        show_sign_out_button = (self._signed_in and account_type
                                in ['Local', 'Google Play', 'V2'])
        sign_out_button_space = 70.0

        show_cancel_v2_sign_in_button = (
            account_state == 'signing_in'
            and ba.app.accounts_v2.have_primary_credentials())
        cancel_v2_sign_in_button_space = 70.0

        if self._subcontainer is not None:
            self._subcontainer.delete()
        self._sub_height = 60.0
        if show_local_signed_in_as:
            self._sub_height += local_signed_in_as_space
        if show_signed_in_as:
            self._sub_height += signed_in_as_space
        if show_signing_in_text:
            self._sub_height += signing_in_text_space
        if show_google_play_sign_in_button:
            self._sub_height += sign_in_button_space
        if show_game_circle_sign_in_button:
            self._sub_height += sign_in_button_space
        if show_device_sign_in_button:
            self._sub_height += sign_in_button_space
        if show_v2_sign_in_button:
            self._sub_height += sign_in_button_space
        if show_game_service_button:
            self._sub_height += game_service_button_space
        if show_linked_accounts_text:
            self._sub_height += linked_accounts_text_space
        if show_achievements_text:
            self._sub_height += achievements_text_space
        if show_achievements_button:
            self._sub_height += achievements_button_space
        if show_leaderboards_button:
            self._sub_height += leaderboards_button_space
        if show_campaign_progress:
            self._sub_height += campaign_progress_space
        if show_tickets:
            self._sub_height += tickets_space
        if show_sign_in_benefits:
            self._sub_height += sign_in_benefits_space
        if show_reset_progress_button:
            self._sub_height += reset_progress_button_space
        if show_player_profiles_button:
            self._sub_height += player_profiles_button_space
        if show_link_accounts_button:
            self._sub_height += link_accounts_button_space
        if show_unlink_accounts_button:
            self._sub_height += unlink_accounts_button_space
        if show_sign_out_button:
            self._sub_height += sign_out_button_space
        if show_cancel_v2_sign_in_button:
            self._sub_height += cancel_v2_sign_in_button_space
        self._subcontainer = ba.containerwidget(parent=self._scrollwidget,
                                                size=(self._sub_width,
                                                      self._sub_height),
                                                background=False,
                                                claims_left_right=True,
                                                claims_tab=True,
                                                selection_loops_to_parent=True)

        first_selectable = None
        v = self._sub_height - 10.0

        if show_local_signed_in_as:
            v -= local_signed_in_as_space * 0.6
            ba.textwidget(
                parent=self._subcontainer,
                position=(self._sub_width * 0.5, v),
                size=(0, 0),
                text=ba.Lstr(
                    resource='accountSettingsWindow.deviceSpecificAccountText',
                    subs=[('${NAME}', _ba.get_v1_account_display_string())]),
                scale=0.7,
                color=(0.5, 0.5, 0.6),
                maxwidth=self._sub_width * 0.9,
                flatness=1.0,
                h_align='center',
                v_align='center')
            v -= local_signed_in_as_space * 0.4

        self._account_name_text: Optional[ba.Widget]
        if show_signed_in_as:
            v -= signed_in_as_space * 0.2
            txt = ba.Lstr(
                resource='accountSettingsWindow.youAreSignedInAsText',
                fallback_resource='accountSettingsWindow.youAreLoggedInAsText')
            ba.textwidget(parent=self._subcontainer,
                          position=(self._sub_width * 0.5, v),
                          size=(0, 0),
                          text=txt,
                          scale=0.9,
                          color=ba.app.ui.title_color,
                          maxwidth=self._sub_width * 0.9,
                          h_align='center',
                          v_align='center')
            v -= signed_in_as_space * 0.4
            self._account_name_text = ba.textwidget(
                parent=self._subcontainer,
                position=(self._sub_width * 0.5, v),
                size=(0, 0),
                scale=1.5,
                maxwidth=self._sub_width * 0.9,
                res_scale=1.5,
                color=(1, 1, 1, 1),
                h_align='center',
                v_align='center')
            self._refresh_account_name_text()
            v -= signed_in_as_space * 0.4
        else:
            self._account_name_text = None

        if self._back_button is None:
            bbtn = _ba.get_special_widget('back_button')
        else:
            bbtn = self._back_button

        if show_sign_in_benefits:
            v -= sign_in_benefits_space
            app = ba.app
            extra: Optional[Union[str, ba.Lstr]]
            if (app.platform in ['mac', 'ios']
                    and app.subplatform == 'appstore'):
                extra = ba.Lstr(
                    value='\n${S}',
                    subs=[('${S}',
                           ba.Lstr(resource='signInWithGameCenterText'))])
            else:
                extra = ''

            ba.textwidget(parent=self._subcontainer,
                          position=(self._sub_width * 0.5,
                                    v + sign_in_benefits_space * 0.4),
                          size=(0, 0),
                          text=ba.Lstr(value='${A}${B}',
                                       subs=[('${A}',
                                              ba.Lstr(resource=self._r +
                                                      '.signInInfoText')),
                                             ('${B}', extra)]),
                          max_height=sign_in_benefits_space * 0.9,
                          scale=0.9,
                          color=(0.75, 0.7, 0.8),
                          maxwidth=self._sub_width * 0.8,
                          h_align='center',
                          v_align='center')

        if show_signing_in_text:
            v -= signing_in_text_space

            ba.textwidget(
                parent=self._subcontainer,
                position=(self._sub_width * 0.5,
                          v + signing_in_text_space * 0.5),
                size=(0, 0),
                text=ba.Lstr(resource='accountSettingsWindow.signingInText'),
                scale=0.9,
                color=(0, 1, 0),
                maxwidth=self._sub_width * 0.8,
                h_align='center',
                v_align='center')

        if show_google_play_sign_in_button:
            button_width = 350
            v -= sign_in_button_space
            self._sign_in_google_play_button = btn = ba.buttonwidget(
                parent=self._subcontainer,
                position=((self._sub_width - button_width) * 0.5, v - 20),
                autoselect=True,
                size=(button_width, 60),
                label=ba.Lstr(
                    value='${A}${B}',
                    subs=[('${A}',
                           ba.charstr(ba.SpecialChar.GOOGLE_PLAY_GAMES_LOGO)),
                          ('${B}',
                           ba.Lstr(resource=self._r +
                                   '.signInWithGooglePlayText'))]),
                on_activate_call=lambda: self._sign_in_press('Google Play'))
            if first_selectable is None:
                first_selectable = btn
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            ba.widget(edit=btn, left_widget=bbtn)
            ba.widget(edit=btn, show_buffer_bottom=40, show_buffer_top=100)
            self._sign_in_text = None

        if show_game_circle_sign_in_button:
            button_width = 350
            v -= sign_in_button_space
            self._sign_in_game_circle_button = btn = ba.buttonwidget(
                parent=self._subcontainer,
                position=((self._sub_width - button_width) * 0.5, v - 20),
                autoselect=True,
                size=(button_width, 60),
                label=ba.Lstr(value='${A}${B}',
                              subs=[('${A}',
                                     ba.charstr(
                                         ba.SpecialChar.GAME_CIRCLE_LOGO)),
                                    ('${B}',
                                     ba.Lstr(resource=self._r +
                                             '.signInWithGameCircleText'))]),
                on_activate_call=lambda: self._sign_in_press('Game Circle'))
            if first_selectable is None:
                first_selectable = btn
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            ba.widget(edit=btn, left_widget=bbtn)
            ba.widget(edit=btn, show_buffer_bottom=40, show_buffer_top=100)
            self._sign_in_text = None

        if show_v2_sign_in_button:
            button_width = 350
            v -= sign_in_button_space
            self._sign_in_v2_button = btn = ba.buttonwidget(
                parent=self._subcontainer,
                position=((self._sub_width - button_width) * 0.5, v - 20),
                autoselect=True,
                size=(button_width, 60),
                label='',
                on_activate_call=self._v2_sign_in_press)
            ba.textwidget(
                parent=self._subcontainer,
                draw_controller=btn,
                h_align='center',
                v_align='center',
                size=(0, 0),
                position=(self._sub_width * 0.5, v + 17),
                text=ba.Lstr(
                    value='${A}${B}',
                    subs=[('${A}', ba.charstr(ba.SpecialChar.V2_LOGO)),
                          ('${B}',
                           ba.Lstr(resource=self._r + '.signInWithV2Text'))]),
                maxwidth=button_width * 0.8,
                color=(0.75, 1.0, 0.7))
            ba.textwidget(parent=self._subcontainer,
                          draw_controller=btn,
                          h_align='center',
                          v_align='center',
                          size=(0, 0),
                          position=(self._sub_width * 0.5, v - 4),
                          text=ba.Lstr(resource=self._r +
                                       '.signInWithV2InfoText'),
                          flatness=1.0,
                          scale=0.57,
                          maxwidth=button_width * 0.9,
                          color=(0.55, 0.8, 0.5))
            if first_selectable is None:
                first_selectable = btn
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            ba.widget(edit=btn, left_widget=bbtn)
            ba.widget(edit=btn, show_buffer_bottom=40, show_buffer_top=100)
            self._sign_in_text = None

        if show_device_sign_in_button:
            button_width = 350
            v -= sign_in_button_space
            self._sign_in_device_button = btn = ba.buttonwidget(
                parent=self._subcontainer,
                position=((self._sub_width - button_width) * 0.5, v - 20),
                autoselect=True,
                size=(button_width, 60),
                label='',
                on_activate_call=lambda: self._sign_in_press('Local'))
            ba.textwidget(parent=self._subcontainer,
                          draw_controller=btn,
                          h_align='center',
                          v_align='center',
                          size=(0, 0),
                          position=(self._sub_width * 0.5, v + 17),
                          text=ba.Lstr(
                              value='${A}${B}',
                              subs=[('${A}',
                                     ba.charstr(ba.SpecialChar.LOCAL_ACCOUNT)),
                                    ('${B}',
                                     ba.Lstr(resource=self._r +
                                             '.signInWithDeviceText'))]),
                          maxwidth=button_width * 0.8,
                          color=(0.75, 1.0, 0.7))
            ba.textwidget(parent=self._subcontainer,
                          draw_controller=btn,
                          h_align='center',
                          v_align='center',
                          size=(0, 0),
                          position=(self._sub_width * 0.5, v - 4),
                          text=ba.Lstr(resource=self._r +
                                       '.signInWithDeviceInfoText'),
                          flatness=1.0,
                          scale=0.57,
                          maxwidth=button_width * 0.9,
                          color=(0.55, 0.8, 0.5))
            if first_selectable is None:
                first_selectable = btn
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            ba.widget(edit=btn, left_widget=bbtn)
            ba.widget(edit=btn, show_buffer_bottom=40, show_buffer_top=100)
            self._sign_in_text = None

        if show_player_profiles_button:
            button_width = 300
            v -= player_profiles_button_space
            self._player_profiles_button = btn = ba.buttonwidget(
                parent=self._subcontainer,
                position=((self._sub_width - button_width) * 0.5, v + 30),
                autoselect=True,
                size=(button_width, 60),
                label=ba.Lstr(resource='playerProfilesWindow.titleText'),
                color=(0.55, 0.5, 0.6),
                icon=ba.gettexture('cuteSpaz'),
                textcolor=(0.75, 0.7, 0.8),
                on_activate_call=self._player_profiles_press)
            if first_selectable is None:
                first_selectable = btn
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            ba.widget(edit=btn, left_widget=bbtn, show_buffer_bottom=0)

        # the button to go to OS-Specific leaderboards/high-score-lists/etc.
        if show_game_service_button:
            button_width = 300
            v -= game_service_button_space * 0.85
            account_type = _ba.get_v1_account_type()
            if account_type == 'Game Center':
                account_type_name = ba.Lstr(resource='gameCenterText')
            elif account_type == 'Game Circle':
                account_type_name = ba.Lstr(resource='gameCircleText')
            else:
                raise ValueError("unknown account type: '" +
                                 str(account_type) + "'")
            self._game_service_button = btn = ba.buttonwidget(
                parent=self._subcontainer,
                position=((self._sub_width - button_width) * 0.5, v),
                color=(0.55, 0.5, 0.6),
                textcolor=(0.75, 0.7, 0.8),
                autoselect=True,
                on_activate_call=_ba.show_online_score_ui,
                size=(button_width, 50),
                label=account_type_name)
            if first_selectable is None:
                first_selectable = btn
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            ba.widget(edit=btn, left_widget=bbtn)
            v -= game_service_button_space * 0.15
        else:
            self.game_service_button = None

        self._achievements_text: Optional[ba.Widget]
        if show_achievements_text:
            v -= achievements_text_space * 0.5
            self._achievements_text = ba.textwidget(
                parent=self._subcontainer,
                position=(self._sub_width * 0.5, v),
                size=(0, 0),
                scale=0.9,
                color=(0.75, 0.7, 0.8),
                maxwidth=self._sub_width * 0.8,
                h_align='center',
                v_align='center')
            v -= achievements_text_space * 0.5
        else:
            self._achievements_text = None

        self._achievements_button: Optional[ba.Widget]
        if show_achievements_button:
            button_width = 300
            v -= achievements_button_space * 0.85
            self._achievements_button = btn = ba.buttonwidget(
                parent=self._subcontainer,
                position=((self._sub_width - button_width) * 0.5, v),
                color=(0.55, 0.5, 0.6),
                textcolor=(0.75, 0.7, 0.8),
                autoselect=True,
                icon=ba.gettexture('googlePlayAchievementsIcon'
                                   if is_google else 'achievementsIcon'),
                icon_color=(0.8, 0.95, 0.7) if is_google else (0.85, 0.8, 0.9),
                on_activate_call=self._on_achievements_press,
                size=(button_width, 50),
                label='')
            if first_selectable is None:
                first_selectable = btn
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            ba.widget(edit=btn, left_widget=bbtn)
            v -= achievements_button_space * 0.15
        else:
            self._achievements_button = None

        if show_achievements_text or show_achievements_button:
            self._refresh_achievements()

        self._leaderboards_button: Optional[ba.Widget]
        if show_leaderboards_button:
            button_width = 300
            v -= leaderboards_button_space * 0.85
            self._leaderboards_button = btn = ba.buttonwidget(
                parent=self._subcontainer,
                position=((self._sub_width - button_width) * 0.5, v),
                color=(0.55, 0.5, 0.6),
                textcolor=(0.75, 0.7, 0.8),
                autoselect=True,
                icon=ba.gettexture('googlePlayLeaderboardsIcon'),
                icon_color=(0.8, 0.95, 0.7),
                on_activate_call=self._on_leaderboards_press,
                size=(button_width, 50),
                label=ba.Lstr(resource='leaderboardsText'))
            if first_selectable is None:
                first_selectable = btn
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            ba.widget(edit=btn, left_widget=bbtn)
            v -= leaderboards_button_space * 0.15
        else:
            self._leaderboards_button = None

        self._campaign_progress_text: Optional[ba.Widget]
        if show_campaign_progress:
            v -= campaign_progress_space * 0.5
            self._campaign_progress_text = ba.textwidget(
                parent=self._subcontainer,
                position=(self._sub_width * 0.5, v),
                size=(0, 0),
                scale=0.9,
                color=(0.75, 0.7, 0.8),
                maxwidth=self._sub_width * 0.8,
                h_align='center',
                v_align='center')
            v -= campaign_progress_space * 0.5
            self._refresh_campaign_progress_text()
        else:
            self._campaign_progress_text = None

        self._tickets_text: Optional[ba.Widget]
        if show_tickets:
            v -= tickets_space * 0.5
            self._tickets_text = ba.textwidget(parent=self._subcontainer,
                                               position=(self._sub_width * 0.5,
                                                         v),
                                               size=(0, 0),
                                               scale=0.9,
                                               color=(0.75, 0.7, 0.8),
                                               maxwidth=self._sub_width * 0.8,
                                               flatness=1.0,
                                               h_align='center',
                                               v_align='center')
            v -= tickets_space * 0.5
            self._refresh_tickets_text()

        else:
            self._tickets_text = None

        # bit of spacing before the reset/sign-out section
        v -= 5

        button_width = 250
        if show_reset_progress_button:
            confirm_text = (ba.Lstr(resource=self._r +
                                    '.resetProgressConfirmText')
                            if self._can_reset_achievements else ba.Lstr(
                                resource=self._r +
                                '.resetProgressConfirmNoAchievementsText'))
            v -= reset_progress_button_space
            self._reset_progress_button = btn = ba.buttonwidget(
                parent=self._subcontainer,
                position=((self._sub_width - button_width) * 0.5, v),
                color=(0.55, 0.5, 0.6),
                textcolor=(0.75, 0.7, 0.8),
                autoselect=True,
                size=(button_width, 60),
                label=ba.Lstr(resource=self._r + '.resetProgressText'),
                on_activate_call=lambda: confirm.ConfirmWindow(
                    text=confirm_text,
                    width=500,
                    height=200,
                    action=self._reset_progress))
            if first_selectable is None:
                first_selectable = btn
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            ba.widget(edit=btn, left_widget=bbtn)

        self._linked_accounts_text: Optional[ba.Widget]
        if show_linked_accounts_text:
            v -= linked_accounts_text_space * 0.8
            self._linked_accounts_text = ba.textwidget(
                parent=self._subcontainer,
                position=(self._sub_width * 0.5, v),
                size=(0, 0),
                scale=0.9,
                color=(0.75, 0.7, 0.8),
                maxwidth=self._sub_width * 0.95,
                h_align='center',
                v_align='center')
            v -= linked_accounts_text_space * 0.2
            self._update_linked_accounts_text()
        else:
            self._linked_accounts_text = None

        if show_link_accounts_button:
            v -= link_accounts_button_space
            self._link_accounts_button = btn = ba.buttonwidget(
                parent=self._subcontainer,
                position=((self._sub_width - button_width) * 0.5, v),
                autoselect=True,
                size=(button_width, 60),
                label='',
                color=(0.55, 0.5, 0.6),
                on_activate_call=self._link_accounts_press)
            ba.textwidget(parent=self._subcontainer,
                          draw_controller=btn,
                          h_align='center',
                          v_align='center',
                          size=(0, 0),
                          position=(self._sub_width * 0.5, v + 17 + 20),
                          text=ba.Lstr(resource=self._r + '.linkAccountsText'),
                          maxwidth=button_width * 0.8,
                          color=(0.75, 0.7, 0.8))
            ba.textwidget(parent=self._subcontainer,
                          draw_controller=btn,
                          h_align='center',
                          v_align='center',
                          size=(0, 0),
                          position=(self._sub_width * 0.5, v - 4 + 20),
                          text=ba.Lstr(resource=self._r +
                                       '.linkAccountsInfoText'),
                          flatness=1.0,
                          scale=0.5,
                          maxwidth=button_width * 0.8,
                          color=(0.75, 0.7, 0.8))
            if first_selectable is None:
                first_selectable = btn
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            ba.widget(edit=btn, left_widget=bbtn, show_buffer_bottom=50)

        self._unlink_accounts_button: Optional[ba.Widget]
        if show_unlink_accounts_button:
            v -= unlink_accounts_button_space
            self._unlink_accounts_button = btn = ba.buttonwidget(
                parent=self._subcontainer,
                position=((self._sub_width - button_width) * 0.5, v + 25),
                autoselect=True,
                size=(button_width, 60),
                label='',
                color=(0.55, 0.5, 0.6),
                on_activate_call=self._unlink_accounts_press)
            self._unlink_accounts_button_label = ba.textwidget(
                parent=self._subcontainer,
                draw_controller=btn,
                h_align='center',
                v_align='center',
                size=(0, 0),
                position=(self._sub_width * 0.5, v + 55),
                text=ba.Lstr(resource=self._r + '.unlinkAccountsText'),
                maxwidth=button_width * 0.8,
                color=(0.75, 0.7, 0.8))
            if first_selectable is None:
                first_selectable = btn
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            ba.widget(edit=btn, left_widget=bbtn, show_buffer_bottom=50)
            self._update_unlink_accounts_button()
        else:
            self._unlink_accounts_button = None

        if show_sign_out_button:
            v -= sign_out_button_space
            self._sign_out_button = btn = ba.buttonwidget(
                parent=self._subcontainer,
                position=((self._sub_width - button_width) * 0.5, v),
                size=(button_width, 60),
                label=ba.Lstr(resource=self._r + '.signOutText'),
                color=(0.55, 0.5, 0.6),
                textcolor=(0.75, 0.7, 0.8),
                autoselect=True,
                on_activate_call=self._sign_out_press)
            if first_selectable is None:
                first_selectable = btn
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            ba.widget(edit=btn, left_widget=bbtn, show_buffer_bottom=15)

        if show_cancel_v2_sign_in_button:
            v -= cancel_v2_sign_in_button_space
            self._cancel_v2_sign_in_button = btn = ba.buttonwidget(
                parent=self._subcontainer,
                position=((self._sub_width - button_width) * 0.5, v),
                size=(button_width, 60),
                label=ba.Lstr(resource='cancelText'),
                color=(0.55, 0.5, 0.6),
                textcolor=(0.75, 0.7, 0.8),
                autoselect=True,
                on_activate_call=self._cancel_v2_sign_in_press)
            if first_selectable is None:
                first_selectable = btn
            if ba.app.ui.use_toolbars:
                ba.widget(edit=btn,
                          right_widget=_ba.get_special_widget('party_button'))
            ba.widget(edit=btn, left_widget=bbtn, show_buffer_bottom=15)

        # Whatever the topmost selectable thing is, we want it to scroll all
        # the way up when we select it.
        if first_selectable is not None:
            ba.widget(edit=first_selectable,
                      up_widget=bbtn,
                      show_buffer_top=400)
            # (this should re-scroll us to the top..)
            ba.containerwidget(edit=self._subcontainer,
                               visible_child=first_selectable)
        self._needs_refresh = False
Exemplo n.º 15
0
    def __init__(self,
                 transition: str = 'in_right',
                 in_main_menu: bool = True,
                 selected_profile: str = None,
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        from ba.internal import ensure_have_account_player_profile
        self._in_main_menu = in_main_menu
        if self._in_main_menu:
            back_label = ba.Lstr(resource='backText')
        else:
            back_label = ba.Lstr(resource='doneText')
        self._width = 700.0 if ba.app.small_ui else 600.0
        x_inset = 50.0 if ba.app.small_ui else 0.0
        self._height = (360.0 if ba.app.small_ui else
                        385.0 if ba.app.med_ui else 410.0)

        # If we're being called up standalone, handle pause/resume ourself.
        if not self._in_main_menu:
            ba.app.pause()

        # 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 = 'playerProfilesWindow'

        # Ensure we've got an account-profile in cases where we're signed in.
        ensure_have_account_player_profile()

        top_extra = 20 if ba.app.small_ui else 0

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + top_extra),
            transition=transition,
            scale_origin_stack_offset=scale_origin,
            scale=(2.2 if ba.app.small_ui else 1.6 if ba.app.med_ui else 1.0),
            stack_offset=(0, -14) if ba.app.small_ui else (0, 0)))

        self._back_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(40 + x_inset, self._height - 59),
            size=(120, 60),
            scale=0.8,
            label=back_label,
            button_type='back' if self._in_main_menu else None,
            autoselect=True,
            on_activate_call=self._back)
        ba.containerwidget(edit=self._root_widget, cancel_button=btn)

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

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

        scroll_height = self._height - 140.0
        self._scroll_width = self._width - (188 + x_inset * 2)
        v = self._height - 84.0
        h = 50 + x_inset
        b_color = (0.6, 0.53, 0.63)

        scl = (1.055 if ba.app.small_ui else 1.18 if ba.app.med_ui else 1.3)
        v -= 70.0 * scl
        self._new_button = ba.buttonwidget(parent=self._root_widget,
                                           position=(h, v),
                                           size=(80, 66.0 * scl),
                                           on_activate_call=self._new_profile,
                                           color=b_color,
                                           button_type='square',
                                           autoselect=True,
                                           textcolor=(0.75, 0.7, 0.8),
                                           text_scale=0.7,
                                           label=ba.Lstr(resource=self._r +
                                                         '.newButtonText'))
        v -= 70.0 * scl
        self._edit_button = ba.buttonwidget(
            parent=self._root_widget,
            position=(h, v),
            size=(80, 66.0 * scl),
            on_activate_call=self._edit_profile,
            color=b_color,
            button_type='square',
            autoselect=True,
            textcolor=(0.75, 0.7, 0.8),
            text_scale=0.7,
            label=ba.Lstr(resource=self._r + '.editButtonText'))
        v -= 70.0 * scl
        self._delete_button = ba.buttonwidget(
            parent=self._root_widget,
            position=(h, v),
            size=(80, 66.0 * scl),
            on_activate_call=self._delete_profile,
            color=b_color,
            button_type='square',
            autoselect=True,
            textcolor=(0.75, 0.7, 0.8),
            text_scale=0.7,
            label=ba.Lstr(resource=self._r + '.deleteButtonText'))

        v = self._height - 87

        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height - 71),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r + '.explanationText'),
                      color=ba.app.infotextcolor,
                      maxwidth=self._width * 0.83,
                      scale=0.6,
                      h_align="center",
                      v_align="center")

        self._scrollwidget = ba.scrollwidget(parent=self._root_widget,
                                             highlight=False,
                                             position=(140 + x_inset,
                                                       v - scroll_height),
                                             size=(self._scroll_width,
                                                   scroll_height))
        ba.widget(edit=self._scrollwidget,
                  autoselect=True,
                  left_widget=self._new_button)
        ba.containerwidget(edit=self._root_widget,
                           selected_child=self._scrollwidget)
        self._columnwidget = ba.columnwidget(parent=self._scrollwidget)
        v -= 255
        self._profiles: Optional[Dict[str, Dict[str, Any]]] = None
        self._selected_profile = selected_profile
        self._profile_widgets: List[ba.Widget] = []
        self._refresh()
        self._restore_state()
Exemplo n.º 16
0
    def _build_host_tab(self, region_width: float,
                        region_height: float) -> None:
        c_width = region_width
        c_height = region_height - 20
        v = c_height - 35
        v -= 25
        is_public_enabled = _ba.get_public_party_enabled()
        v -= 30
        party_name_text = ba.Lstr(
            resource='gatherWindow.partyNameText',
            fallback_resource='editGameListWindow.nameText')
        ba.textwidget(parent=self._container,
                      size=(0, 0),
                      h_align='right',
                      v_align='center',
                      maxwidth=200,
                      scale=0.8,
                      color=ba.app.ui.infotextcolor,
                      position=(210, v - 9),
                      text=party_name_text)
        self._host_name_text = ba.textwidget(parent=self._container,
                                             editable=True,
                                             size=(535, 40),
                                             position=(230, v - 30),
                                             text=ba.app.config.get(
                                                 'Public Party Name', ''),
                                             maxwidth=494,
                                             shadow=0.3,
                                             flatness=1.0,
                                             description=party_name_text,
                                             autoselect=True,
                                             v_align='center',
                                             corner_scale=1.0)

        v -= 60
        ba.textwidget(parent=self._container,
                      size=(0, 0),
                      h_align='right',
                      v_align='center',
                      maxwidth=200,
                      scale=0.8,
                      color=ba.app.ui.infotextcolor,
                      position=(210, v - 9),
                      text=ba.Lstr(resource='maxPartySizeText',
                                   fallback_resource='maxConnectionsText'))
        self._host_max_party_size_value = ba.textwidget(
            parent=self._container,
            size=(0, 0),
            h_align='center',
            v_align='center',
            scale=1.2,
            color=(1, 1, 1),
            position=(240, v - 9),
            text=str(_ba.get_public_party_max_size()))
        btn1 = self._host_max_party_size_minus_button = (ba.buttonwidget(
            parent=self._container,
            size=(40, 40),
            on_activate_call=ba.WeakCall(
                self._on_max_public_party_size_minus_press),
            position=(280, v - 26),
            label='-',
            autoselect=True))
        btn2 = self._host_max_party_size_plus_button = (ba.buttonwidget(
            parent=self._container,
            size=(40, 40),
            on_activate_call=ba.WeakCall(
                self._on_max_public_party_size_plus_press),
            position=(350, v - 26),
            label='+',
            autoselect=True))
        v -= 50
        v -= 70
        if is_public_enabled:
            label = ba.Lstr(
                resource='gatherWindow.makePartyPrivateText',
                fallback_resource='gatherWindow.stopAdvertisingText')
        else:
            label = ba.Lstr(
                resource='gatherWindow.makePartyPublicText',
                fallback_resource='gatherWindow.startAdvertisingText')
        self._host_toggle_button = ba.buttonwidget(
            parent=self._container,
            label=label,
            size=(400, 80),
            on_activate_call=self._on_stop_advertising_press
            if is_public_enabled else self._on_start_advertizing_press,
            position=(c_width * 0.5 - 200, v),
            autoselect=True,
            up_widget=btn2)
        ba.widget(edit=self._host_name_text, down_widget=btn2)
        ba.widget(edit=btn2, up_widget=self._host_name_text)
        ba.widget(edit=btn1, up_widget=self._host_name_text)
        ba.widget(edit=self._join_text, down_widget=self._host_name_text)
        v -= 10
        self._host_status_text = ba.textwidget(
            parent=self._container,
            text=ba.Lstr(resource='gatherWindow.'
                         'partyStatusNotPublicText'),
            size=(0, 0),
            scale=0.7,
            flatness=1.0,
            shadow=0.0,
            h_align='center',
            v_align='top',
            maxwidth=c_width,
            color=(0.6, 0.6, 0.6),
            position=(c_width * 0.5, v))
        v -= 90
        ba.textwidget(
            parent=self._container,
            text=ba.Lstr(resource='gatherWindow.dedicatedServerInfoText'),
            size=(0, 0),
            scale=0.7,
            flatness=1.0,
            shadow=0.0,
            h_align='center',
            v_align='center',
            maxwidth=c_width * 0.9,
            color=ba.app.ui.infotextcolor,
            position=(c_width * 0.5, v))

        # If public sharing is already on,
        # launch a status-check immediately.
        if _ba.get_public_party_enabled():
            self._do_status_check()
Exemplo n.º 17
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
Exemplo n.º 18
0
    def update(self, index: int, party: PartyEntry, sub_scroll_width: float,
               sub_scroll_height: float, lineheight: float,
               columnwidget: ba.Widget, join_text: ba.Widget,
               filter_text: ba.Widget, existing_selection: Optional[Selection],
               tab: PublicGatherTab) -> None:
        """Update for the given data."""
        # pylint: disable=too-many-locals

        # Quick-out: if we've been marked clean for a certain index and
        # we're still at that index, we're done.
        if party.clean_display_index == index:
            return

        ping_good = _ba.get_account_misc_read_val('pingGood', 100)
        ping_med = _ba.get_account_misc_read_val('pingMed', 500)

        self._clear()
        hpos = 20
        vpos = sub_scroll_height - lineheight * index - 50
        self._name_widget = ba.textwidget(
            text=ba.Lstr(value=party.name),
            parent=columnwidget,
            size=(sub_scroll_width * 0.63, 20),
            position=(0 + hpos, 4 + vpos),
            selectable=True,
            on_select_call=ba.WeakCall(
                tab.set_public_party_selection,
                Selection(party.get_key(), SelectionComponent.NAME)),
            on_activate_call=ba.WeakCall(tab.on_public_party_activate, party),
            click_activate=True,
            maxwidth=sub_scroll_width * 0.45,
            corner_scale=1.4,
            autoselect=True,
            color=(1, 1, 1, 0.3 if party.ping is None else 1.0),
            h_align='left',
            v_align='center')
        ba.widget(edit=self._name_widget,
                  left_widget=join_text,
                  show_buffer_top=64.0,
                  show_buffer_bottom=64.0)
        if existing_selection == Selection(party.get_key(),
                                           SelectionComponent.NAME):
            ba.containerwidget(edit=columnwidget,
                               selected_child=self._name_widget)
        if party.stats_addr:
            url = party.stats_addr.replace(
                '${ACCOUNT}',
                _ba.get_account_misc_read_val_2('resolvedAccountID',
                                                'UNKNOWN'))
            self._stats_button = ba.buttonwidget(
                color=(0.3, 0.6, 0.94),
                textcolor=(1.0, 1.0, 1.0),
                label=ba.Lstr(resource='statsText'),
                parent=columnwidget,
                autoselect=True,
                on_activate_call=ba.Call(ba.open_url, url),
                on_select_call=ba.WeakCall(
                    tab.set_public_party_selection,
                    Selection(party.get_key(),
                              SelectionComponent.STATS_BUTTON)),
                size=(120, 40),
                position=(sub_scroll_width * 0.66 + hpos, 1 + vpos),
                scale=0.9)
            if existing_selection == Selection(
                    party.get_key(), SelectionComponent.STATS_BUTTON):
                ba.containerwidget(edit=columnwidget,
                                   selected_child=self._stats_button)

        self._size_widget = ba.textwidget(
            text=str(party.size) + '/' + str(party.size_max),
            parent=columnwidget,
            size=(0, 0),
            position=(sub_scroll_width * 0.86 + hpos, 20 + vpos),
            scale=0.7,
            color=(0.8, 0.8, 0.8),
            h_align='right',
            v_align='center')

        if index == 0:
            ba.widget(edit=self._name_widget, up_widget=filter_text)
            if self._stats_button:
                ba.widget(edit=self._stats_button, up_widget=filter_text)

        self._ping_widget = ba.textwidget(parent=columnwidget,
                                          size=(0, 0),
                                          position=(sub_scroll_width * 0.94 +
                                                    hpos, 20 + vpos),
                                          scale=0.7,
                                          h_align='right',
                                          v_align='center')
        if party.ping is None:
            ba.textwidget(edit=self._ping_widget,
                          text='-',
                          color=(0.5, 0.5, 0.5))
        else:
            ba.textwidget(edit=self._ping_widget,
                          text=str(int(party.ping)),
                          color=(0, 1, 0) if party.ping <= ping_good else
                          (1, 1, 0) if party.ping <= ping_med else (1, 0, 0))

        party.clean_display_index = index
Exemplo n.º 19
0
    def __init__(self,
                 transition: str = 'in_right',
                 modal: bool = False,
                 show_tab: str = None,
                 on_close_call: Callable[[], Any] = None,
                 back_location: str = None,
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        from bastd.ui import tabs
        from ba import SpecialChar

        app = ba.app

        ba.set_analytics_screen('Store Window')

        scale_origin: Optional[Tuple[float, float]]

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

        self.button_infos: Optional[Dict[str, Dict[str, Any]]] = None
        self.update_buttons_timer: Optional[ba.Timer] = None
        self._status_textwidget_update_timer = None

        self._back_location = back_location
        self._on_close_call = on_close_call
        self._show_tab = show_tab
        self._modal = modal
        self._width = 1240 if app.small_ui else 1040
        self._x_inset = x_inset = 100 if app.small_ui else 0
        self._height = (578 if app.small_ui else 645 if app.med_ui else 800)
        self._current_tab: Optional[str] = None
        extra_top = 30 if app.small_ui else 0

        self._request: Any = None
        self._r = 'store'
        self._last_buy_time: Optional[float] = None

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + extra_top),
            transition=transition,
            toolbar_visibility='menu_full',
            scale=1.3 if app.small_ui else 0.9 if app.med_ui else 0.8,
            scale_origin_stack_offset=scale_origin,
            stack_offset=(0,
                          -5) if app.small_ui else (0,
                                                    0) if app.med_ui else (0,
                                                                           0)))

        self._back_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(70 + x_inset, self._height - 74),
            size=(140, 60),
            scale=1.1,
            autoselect=True,
            label=ba.Lstr(resource='doneText' if self._modal else 'backText'),
            button_type=None if self._modal else 'back',
            on_activate_call=self._back)
        ba.containerwidget(edit=self._root_widget, cancel_button=btn)

        self._get_tickets_button = ba.buttonwidget(
            parent=self._root_widget,
            size=(210, 65),
            on_activate_call=self._on_get_more_tickets_press,
            autoselect=True,
            scale=0.9,
            text_scale=1.4,
            left_widget=self._back_button,
            color=(0.7, 0.5, 0.85),
            textcolor=(0.2, 1.0, 0.2),
            label=ba.Lstr(resource='getTicketsWindow.titleText'))

        # Move this dynamically to keep it out of the way of the party icon.
        self._update_get_tickets_button_pos()
        self._get_ticket_pos_update_timer = ba.Timer(
            1.0,
            ba.WeakCall(self._update_get_tickets_button_pos),
            repeat=True,
            timetype=ba.TimeType.REAL)
        ba.widget(edit=self._back_button,
                  right_widget=self._get_tickets_button)
        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()

        app = ba.app
        if app.platform in ['mac', 'ios'] and app.subplatform == 'appstore':
            ba.buttonwidget(
                parent=self._root_widget,
                position=(self._width * 0.5 - 70, 16),
                size=(230, 50),
                scale=0.65,
                on_activate_call=ba.WeakCall(self._restore_purchases),
                color=(0.35, 0.3, 0.4),
                selectable=False,
                textcolor=(0.55, 0.5, 0.6),
                label=ba.Lstr(
                    resource='getTicketsWindow.restorePurchasesText'))

        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height - 44),
                      size=(0, 0),
                      color=app.title_color,
                      scale=1.5,
                      h_align="center",
                      v_align="center",
                      text=ba.Lstr(resource='storeText'),
                      maxwidth=420)

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

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

        tabs_def = [
            ('extras', ba.Lstr(resource=self._r + '.extrasText')),
            ('maps', ba.Lstr(resource=self._r + '.mapsText')),
            ('minigames', ba.Lstr(resource=self._r + '.miniGamesText')),
            ('characters', ba.Lstr(resource=self._r + '.charactersText')),
            ('icons', ba.Lstr(resource=self._r + '.iconsText')),
        ]

        tab_results = tabs.create_tab_buttons(self._root_widget,
                                              tabs_def,
                                              pos=(tab_buffer_h * 0.5,
                                                   self._height - 130),
                                              size=(self._width - tab_buffer_h,
                                                    50),
                                              on_select_call=self._set_tab,
                                              return_extra_info=True)

        self._purchasable_count_widgets: Dict[str, Dict[str, Any]] = {}

        # Create our purchasable-items tags and have them update over time.
        for i, tab in enumerate(tabs_def):
            pos = tab_results['positions'][i]
            size = tab_results['sizes'][i]
            button = tab_results['buttons_indexed'][i]
            rad = 10
            center = (pos[0] + 0.1 * size[0], pos[1] + 0.9 * size[1])
            img = ba.imagewidget(parent=self._root_widget,
                                 position=(center[0] - rad * 1.04,
                                           center[1] - rad * 1.15),
                                 size=(rad * 2.2, rad * 2.2),
                                 texture=ba.gettexture('circleShadow'),
                                 color=(1, 0, 0))
            txt = ba.textwidget(parent=self._root_widget,
                                position=center,
                                size=(0, 0),
                                h_align='center',
                                v_align='center',
                                maxwidth=1.4 * rad,
                                scale=0.6,
                                shadow=1.0,
                                flatness=1.0)
            rad = 20
            sale_img = ba.imagewidget(parent=self._root_widget,
                                      position=(center[0] - rad,
                                                center[1] - rad),
                                      size=(rad * 2, rad * 2),
                                      draw_controller=button,
                                      texture=ba.gettexture('circleZigZag'),
                                      color=(0.5, 0, 1.0))
            sale_title_text = ba.textwidget(parent=self._root_widget,
                                            position=(center[0],
                                                      center[1] + 0.24 * rad),
                                            size=(0, 0),
                                            h_align='center',
                                            v_align='center',
                                            draw_controller=button,
                                            maxwidth=1.4 * rad,
                                            scale=0.6,
                                            shadow=0.0,
                                            flatness=1.0,
                                            color=(0, 1, 0))
            sale_time_text = ba.textwidget(parent=self._root_widget,
                                           position=(center[0],
                                                     center[1] - 0.29 * rad),
                                           size=(0, 0),
                                           h_align='center',
                                           v_align='center',
                                           draw_controller=button,
                                           maxwidth=1.4 * rad,
                                           scale=0.4,
                                           shadow=0.0,
                                           flatness=1.0,
                                           color=(0, 1, 0))
            self._purchasable_count_widgets[tab[0]] = {
                'img': img,
                'text': txt,
                'sale_img': sale_img,
                'sale_title_text': sale_title_text,
                'sale_time_text': sale_time_text
            }
        self._tab_update_timer = ba.Timer(1.0,
                                          ba.WeakCall(self._update_tabs),
                                          timetype=ba.TimeType.REAL,
                                          repeat=True)
        self._update_tabs()

        self._tab_buttons = tab_results['buttons']

        if self._get_tickets_button is not None:
            last_tab_button = self._tab_buttons[tabs_def[-1][0]]
            ba.widget(edit=self._get_tickets_button,
                      down_widget=last_tab_button)
            ba.widget(edit=last_tab_button,
                      up_widget=self._get_tickets_button,
                      right_widget=self._get_tickets_button)

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

        self._scrollwidget: Optional[ba.Widget] = None
        self._status_textwidget: Optional[ba.Widget] = None
        self._restore_state()
Exemplo n.º 20
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()

        # We can currently be used either for main menu duty or for selecting
        # playlists (should make this more elegant/general).
        self._is_main_menu = not ba.app.ui.selecting_private_party_playlist

        uiscale = ba.app.ui.uiscale
        width = 1000 if uiscale is ba.UIScale.SMALL else 800
        x_offs = 100 if uiscale is ba.UIScale.SMALL else 0
        height = 550
        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 uiscale is ba.UIScale.SMALL else
                   0.9 if uiscale is ba.UIScale.MEDIUM else 0.8),
            stack_offset=(0, 0) 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),
            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),
            # position=(width * 0.5, height -
            #           (101 if main_menu else 61)),
            size=(0, 0),
            text=ba.Lstr(resource=(
                self._r +
                '.titleText') if self._is_main_menu else 'playlistsText'),
            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 self._is_main_menu else 90)
        v -= 100
        clr = (0.6, 0.7, 0.6, 1.0)
        v -= 280 if self._is_main_menu else 180
        v += (30
              if ba.app.ui.use_toolbars and uiscale is ba.UIScale.SMALL else 0)
        hoffs = x_offs + 80 if self._is_main_menu else x_offs - 100
        scl = 1.13 if self._is_main_menu 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: Optional[ba.Widget] = None

        # Only show coop button in main-menu variant.
        if self._is_main_menu:
            self._coop_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)),
                size=(scl * button_width,
                      scl * (300 if self._is_main_menu 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 self._is_main_menu else 0.68
        hoffs += 440 if self._is_main_menu else 216
        v += 180 if self._is_main_menu else -68

        self._teams_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)),
            size=(scl * button_width,
                  scl * (300 if self._is_main_menu 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 self._is_main_menu else 300
        v -= 155 if self._is_main_menu else 0
        self._free_for_all_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)),
            size=(scl * button_width,
                  scl * (300 if self._is_main_menu 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
                               if self._is_main_menu else self._teams_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
                               if self._is_main_menu else self._teams_button)

        self._restore_state()
Exemplo n.º 21
0
    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 (getclass, have_pro,
                                 get_default_teams_playlist,
                                 get_default_free_for_all_playlist,
                                 filter_playlist)
        from ba.internal import get_map_class
        from bastd.ui.playlist import PlaylistTypeVars

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

        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__':
                if self._sessiontype is ba.FreeForAllSession:
                    plst = get_default_free_for_all_playlist()
                elif self._sessiontype is ba.DualTeamSession:
                    plst = get_default_teams_playlist()
                else:
                    raise Exception('unrecognized session-type: ' +
                                    str(self._sessiontype))
            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 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)
            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.
        scale = (1.69 if ba.app.small_ui else 1.1 if ba.app.med_ui 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_config_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 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.
        try:
            show_tutorial = ba.app.config['Show Tutorial']
        except Exception:
            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._play_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_play_press,
            autoselect=True,
            label=ba.Lstr(resource='playText'))

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

        ba.containerwidget(edit=self.root_widget,
                           start_button=self._play_button,
                           cancel_button=self._cancel_button,
                           selected_child=self._play_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()
Exemplo n.º 22
0
    def _refresh(self) -> None:
        from ba.deprecated import get_resource
        for widget in self._col.get_children():
            widget.delete()

        types = [
            'Menu',
            'CharSelect',
            'ToTheDeath',
            'Onslaught',
            'Keep Away',
            'Race',
            'Epic Race',
            'ForwardMarch',
            'FlagCatcher',
            'Survival',
            'Epic',
            'Hockey',
            'Football',
            'Flying',
            'Scary',
            'Marching',
            'GrandRomp',
            'Chosen One',
            'Scores',
            'Victory',
        ]
        # FIXME: We should probably convert this to use translations.
        type_names_translated = get_resource('soundtrackTypeNames')
        prev_type_button: Optional[ba.Widget] = None
        prev_test_button: Optional[ba.Widget] = None

        for index, song_type in enumerate(types):
            row = ba.rowwidget(parent=self._col, size=(self._width - 40, 40))
            ba.containerwidget(edit=row,
                               claims_left_right=True,
                               claims_tab=True,
                               selection_loop_to_parent=True)
            try:
                type_name = type_names_translated[song_type]
            except Exception:
                type_name = song_type
            ba.textwidget(parent=row,
                          size=(230, 25),
                          always_highlight=True,
                          text=type_name,
                          scale=0.7,
                          h_align='left',
                          v_align='center',
                          maxwidth=190)

            if song_type in self._soundtrack:
                entry = self._soundtrack[song_type]
            else:
                entry = None

            if entry is not None:
                # make sure they don't muck with this after it gets to us
                entry = copy.deepcopy(entry)

            icon_type = self._get_entry_button_display_icon_type(entry)
            self._song_type_buttons[song_type] = btn = ba.buttonwidget(
                parent=row,
                size=(230, 32),
                label=self._get_entry_button_display_name(entry),
                text_scale=0.6,
                on_activate_call=ba.Call(self._get_entry, song_type, entry,
                                         type_name),
                icon=(self._file_tex if icon_type == 'file' else
                      self._folder_tex if icon_type == 'folder' else None),
                icon_color=(1.1, 0.8, 0.2) if icon_type == 'folder' else
                (1, 1, 1),
                left_widget=self._text_field,
                iconscale=0.7,
                autoselect=True,
                up_widget=prev_type_button)
            if index == 0:
                ba.widget(edit=btn, up_widget=self._text_field)
            ba.widget(edit=btn, down_widget=btn)

            if (self._last_edited_song_type is not None
                    and song_type == self._last_edited_song_type):
                ba.containerwidget(edit=row,
                                   selected_child=btn,
                                   visible_child=btn)
                ba.containerwidget(edit=self._col,
                                   selected_child=row,
                                   visible_child=row)
                ba.containerwidget(edit=self._scrollwidget,
                                   selected_child=self._col,
                                   visible_child=self._col)
                ba.containerwidget(edit=self._root_widget,
                                   selected_child=self._scrollwidget,
                                   visible_child=self._scrollwidget)

            if prev_type_button is not None:
                ba.widget(edit=prev_type_button, down_widget=btn)
            prev_type_button = btn
            ba.textwidget(parent=row, size=(10, 32), text='')  # spacing
            btn = ba.buttonwidget(
                parent=row,
                size=(50, 32),
                label=ba.Lstr(resource=self._r + '.testText'),
                text_scale=0.6,
                on_activate_call=ba.Call(self._test, ba.MusicType(song_type)),
                up_widget=prev_test_button
                if prev_test_button is not None else self._text_field)
            if prev_test_button is not None:
                ba.widget(edit=prev_test_button, down_widget=btn)
            ba.widget(edit=btn, down_widget=btn, right_widget=btn)
            prev_test_button = btn
Exemplo n.º 23
0
    def _refresh(self, select_soundtrack: str = None) -> None:
        self._allow_changing_soundtracks = False
        old_selection = self._selected_soundtrack

        # If there was no prev selection, look in prefs.
        if old_selection is None:
            old_selection = ba.app.config.get('Soundtrack')
        old_selection_index = self._selected_soundtrack_index

        # Delete old.
        while self._soundtrack_widgets:
            self._soundtrack_widgets.pop().delete()

        self._soundtracks = ba.app.config.get('Soundtracks', {})
        assert self._soundtracks is not None
        items = list(self._soundtracks.items())
        items.sort(key=lambda x: x[0].lower())
        items = [('__default__', None)] + items  # default is always first
        index = 0
        for pname, _pval in items:
            assert pname is not None
            txtw = ba.textwidget(
                parent=self._col,
                size=(self._width - 40, 24),
                text=self._get_soundtrack_display_name(pname),
                h_align='left',
                v_align='center',
                maxwidth=self._width - 110,
                always_highlight=True,
                on_select_call=ba.WeakCall(self._select, pname, index),
                on_activate_call=self._edit_soundtrack_with_sound,
                selectable=True)
            if index == 0:
                ba.widget(edit=txtw, up_widget=self._back_button)
            self._soundtrack_widgets.append(txtw)

            # Select this one if the user requested it
            if select_soundtrack is not None:
                if pname == select_soundtrack:
                    ba.columnwidget(edit=self._col,
                                    selected_child=txtw,
                                    visible_child=txtw)
            else:
                # Select this one if it was previously selected.
                # Go by index if there's one.
                if old_selection_index is not None:
                    if index == old_selection_index:
                        ba.columnwidget(edit=self._col,
                                        selected_child=txtw,
                                        visible_child=txtw)
                else:  # Otherwise look by name.
                    if pname == old_selection:
                        ba.columnwidget(edit=self._col,
                                        selected_child=txtw,
                                        visible_child=txtw)
            index += 1

        # Explicitly run select callback on current one and re-enable
        # callbacks.

        # Eww need to run this in a timer so it happens after our select
        # callbacks. With a small-enough time sometimes it happens before
        # anyway. Ew. need a way to just schedule a callable i guess.
        ba.timer(0.1,
                 ba.WeakCall(self._set_allow_changing),
                 timetype=ba.TimeType.REAL)
Exemplo n.º 24
0
    def __init__(self,
                 existing_soundtrack: Optional[Union[str, Dict[str, Any]]],
                 transition: str = 'in_right'):
        # pylint: disable=too-many-statements
        bs_config = ba.app.config
        self._r = 'editSoundtrackWindow'
        self._folder_tex = ba.gettexture('folder')
        self._file_tex = ba.gettexture('file')
        self._width = 848 if ba.app.small_ui else 648
        x_inset = 100 if ba.app.small_ui else 0
        self._height = (395
                        if ba.app.small_ui else 450 if ba.app.med_ui else 560)
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height),
            transition=transition,
            scale=(2.08 if ba.app.small_ui else 1.5 if ba.app.med_ui else 1.0),
            stack_offset=(0, -48) if ba.app.small_ui else (
                0, 15) if ba.app.med_ui else (0, 0)))
        cancel_button = ba.buttonwidget(parent=self._root_widget,
                                        position=(38 + x_inset,
                                                  self._height - 60),
                                        size=(160, 60),
                                        autoselect=True,
                                        label=ba.Lstr(resource='cancelText'),
                                        scale=0.8)
        save_button = ba.buttonwidget(parent=self._root_widget,
                                      position=(self._width - (168 + x_inset),
                                                self._height - 60),
                                      autoselect=True,
                                      size=(160, 60),
                                      label=ba.Lstr(resource='saveText'),
                                      scale=0.8)
        ba.widget(edit=save_button, left_widget=cancel_button)
        ba.widget(edit=cancel_button, right_widget=save_button)
        ba.textwidget(
            parent=self._root_widget,
            position=(0, self._height - 50),
            size=(self._width, 25),
            text=ba.Lstr(resource=self._r +
                         ('.editSoundtrackText' if existing_soundtrack
                          is not None else '.newSoundtrackText')),
            color=ba.app.title_color,
            h_align='center',
            v_align='center',
            maxwidth=280)
        v = self._height - 110
        if 'Soundtracks' not in bs_config:
            bs_config['Soundtracks'] = {}

        self._soundtrack_name: Optional[str]
        self._existing_soundtrack_name: Optional[str]
        if existing_soundtrack is not None:
            # if they passed just a name, pull info from that soundtrack
            if isinstance(existing_soundtrack, str):
                self._soundtrack = copy.deepcopy(
                    bs_config['Soundtracks'][existing_soundtrack])
                self._soundtrack_name = existing_soundtrack
                self._existing_soundtrack_name = existing_soundtrack
                self._last_edited_song_type = None
            else:
                # otherwise they can pass info on an in-progress edit
                self._soundtrack = existing_soundtrack['soundtrack']
                self._soundtrack_name = existing_soundtrack['name']
                self._existing_soundtrack_name = (
                    existing_soundtrack['existing_name'])
                self._last_edited_song_type = (
                    existing_soundtrack['last_edited_song_type'])
        else:
            self._soundtrack_name = None
            self._existing_soundtrack_name = None
            self._soundtrack = {}
            self._last_edited_song_type = None

        ba.textwidget(parent=self._root_widget,
                      text=ba.Lstr(resource=self._r + '.nameText'),
                      maxwidth=80,
                      scale=0.8,
                      position=(105 + x_inset, v + 19),
                      color=(0.8, 0.8, 0.8, 0.5),
                      size=(0, 0),
                      h_align='right',
                      v_align='center')

        # if there's no initial value, find a good initial unused name
        if existing_soundtrack is None:
            i = 1
            st_name_text = ba.Lstr(resource=self._r +
                                   '.newSoundtrackNameText').evaluate()
            if '${COUNT}' not in st_name_text:
                # make sure we insert number *somewhere*
                st_name_text = st_name_text + ' ${COUNT}'
            while True:
                self._soundtrack_name = st_name_text.replace(
                    '${COUNT}', str(i))
                if self._soundtrack_name not in bs_config['Soundtracks']:
                    break
                i += 1

        self._text_field = ba.textwidget(
            parent=self._root_widget,
            position=(120 + x_inset, v - 5),
            size=(self._width - (160 + 2 * x_inset), 43),
            text=self._soundtrack_name,
            h_align='left',
            v_align='center',
            max_chars=32,
            autoselect=True,
            description=ba.Lstr(resource=self._r + '.nameText'),
            editable=True,
            padding=4,
            on_return_press_call=self._do_it_with_sound)

        scroll_height = self._height - 180
        self._scrollwidget = scrollwidget = ba.scrollwidget(
            parent=self._root_widget,
            highlight=False,
            position=(40 + x_inset, v - (scroll_height + 10)),
            size=(self._width - (80 + 2 * x_inset), scroll_height),
            simple_culling_v=10)
        ba.widget(edit=self._text_field, down_widget=self._scrollwidget)
        self._col = ba.columnwidget(parent=scrollwidget)

        ba.containerwidget(edit=self._scrollwidget,
                           claims_left_right=True,
                           claims_tab=True,
                           selection_loop_to_parent=True)
        ba.containerwidget(edit=self._col,
                           claims_left_right=True,
                           claims_tab=True,
                           selection_loop_to_parent=True)

        self._song_type_buttons: Dict[str, ba.Widget] = {}
        self._refresh()
        ba.buttonwidget(edit=cancel_button, on_activate_call=self._cancel)
        ba.containerwidget(edit=self._root_widget, cancel_button=cancel_button)
        ba.buttonwidget(edit=save_button, on_activate_call=self._do_it)
        ba.containerwidget(edit=self._root_widget, start_button=save_button)
        ba.widget(edit=self._text_field, up_widget=cancel_button)
        ba.widget(edit=cancel_button, down_widget=self._text_field)
Exemplo n.º 25
0
    def __init__(self, origin: Sequence[float] = (0, 0)):
        _ba.set_party_window_open(True)
        self._r = 'partyWindow'
        self._popup_type: Optional[str] = None
        self._popup_party_member_client_id: Optional[int] = None
        self._popup_party_member_is_host: Optional[bool] = None
        self._width = 500
        uiscale = ba.app.ui.uiscale
        self._height = (365 if uiscale is ba.UIScale.SMALL else
                        480 if uiscale is ba.UIScale.MEDIUM else 600)
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height),
            transition='in_scale',
            color=(0.40, 0.55, 0.20),
            parent=_ba.get_special_widget('overlay_stack'),
            on_outside_click_call=self.close_with_sound,
            scale_origin_stack_offset=origin,
            scale=(2.0 if uiscale is ba.UIScale.SMALL else
                   1.35 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -10) if uiscale is ba.UIScale.SMALL else (
                240, 0) if uiscale is ba.UIScale.MEDIUM else (330, 20)))

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

        self._menu_button = ba.buttonwidget(
            parent=self._root_widget,
            scale=0.7,
            position=(self._width - 60, self._height - 47),
            size=(50, 50),
            label='...',
            autoselect=True,
            button_type='square',
            on_activate_call=ba.WeakCall(self._on_menu_button_press),
            color=(0.55, 0.73, 0.25),
            iconscale=1.2)

        info = _ba.get_connection_to_host_info()
        if info.get('name', '') != '':
            title = ba.Lstr(value=info['name'])
        else:
            title = ba.Lstr(resource=self._r + '.titleText')

        self._title_text = ba.textwidget(parent=self._root_widget,
                                         scale=0.9,
                                         color=(0.5, 0.7, 0.5),
                                         text=title,
                                         size=(0, 0),
                                         position=(self._width * 0.5,
                                                   self._height - 29),
                                         maxwidth=self._width * 0.7,
                                         h_align='center',
                                         v_align='center')

        self._empty_str = ba.textwidget(parent=self._root_widget,
                                        scale=0.75,
                                        size=(0, 0),
                                        position=(self._width * 0.5,
                                                  self._height - 65),
                                        maxwidth=self._width * 0.85,
                                        h_align='center',
                                        v_align='center')

        self._scroll_width = self._width - 50
        self._scrollwidget = ba.scrollwidget(parent=self._root_widget,
                                             size=(self._scroll_width,
                                                   self._height - 200),
                                             position=(30, 80),
                                             color=(0.4, 0.6, 0.3))
        self._columnwidget = ba.columnwidget(parent=self._scrollwidget,
                                             border=2,
                                             margin=0)
        ba.widget(edit=self._menu_button, down_widget=self._columnwidget)

        self._muted_text = ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height * 0.5),
            size=(0, 0),
            h_align='center',
            v_align='center',
            text=ba.Lstr(resource='chatMutedText'))
        self._chat_texts: List[ba.Widget] = []

        # add all existing messages if chat is not muted
        if not ba.app.config.resolve('Chat Muted'):
            msgs = _ba.get_chat_messages()
            for msg in msgs:
                self._add_msg(msg)

        self._text_field = txt = ba.textwidget(
            parent=self._root_widget,
            editable=True,
            size=(530, 40),
            position=(44, 39),
            text='',
            maxwidth=494,
            shadow=0.3,
            flatness=1.0,
            description=ba.Lstr(resource=self._r + '.chatMessageText'),
            autoselect=True,
            v_align='center',
            corner_scale=0.7)

        ba.widget(edit=self._scrollwidget,
                  autoselect=True,
                  left_widget=self._cancel_button,
                  up_widget=self._cancel_button,
                  down_widget=self._text_field)
        ba.widget(edit=self._columnwidget,
                  autoselect=True,
                  up_widget=self._cancel_button,
                  down_widget=self._text_field)
        ba.containerwidget(edit=self._root_widget, selected_child=txt)
        btn = ba.buttonwidget(parent=self._root_widget,
                              size=(50, 35),
                              label=ba.Lstr(resource=self._r + '.sendText'),
                              button_type='square',
                              autoselect=True,
                              position=(self._width - 70, 35),
                              on_activate_call=self._send_chat_message)
        ba.textwidget(edit=txt, on_return_press_call=btn.activate)
        self._name_widgets: List[ba.Widget] = []
        self._roster: Optional[List[Dict[str, Any]]] = None
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      repeat=True,
                                      timetype=ba.TimeType.REAL)
        self._update()
Exemplo n.º 26
0
    def _rebuild_ui(self) -> None:
        from ba.internal import get_device_value
        for widget in self._root_widget.get_children():
            widget.delete()

        # Fill our temp config with present values.
        self._settings: Dict[str, int] = {}
        for button in [
                'buttonJump', 'buttonPunch', 'buttonBomb', 'buttonPickUp',
                'buttonStart', 'buttonStart2', 'buttonUp', 'buttonDown',
                'buttonLeft', 'buttonRight'
        ]:
            self._settings[button] = get_device_value(self._input, button)

        cancel_button = ba.buttonwidget(parent=self._root_widget,
                                        autoselect=True,
                                        position=(38, self._height - 85),
                                        size=(170, 60),
                                        label=ba.Lstr(resource='cancelText'),
                                        scale=0.9,
                                        on_activate_call=self._cancel)
        save_button = ba.buttonwidget(parent=self._root_widget,
                                      autoselect=True,
                                      position=(self._width - 190,
                                                self._height - 85),
                                      size=(180, 60),
                                      label=ba.Lstr(resource='saveText'),
                                      scale=0.9,
                                      text_scale=0.9,
                                      on_activate_call=self._save)
        ba.containerwidget(edit=self._root_widget,
                           cancel_button=cancel_button,
                           start_button=save_button)

        ba.widget(edit=cancel_button, right_widget=save_button)
        ba.widget(edit=save_button, left_widget=cancel_button)

        v = self._height - 74.0
        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, v + 15),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r + '.configuringText',
                                   subs=[('${DEVICE}', self._displayname)]),
                      color=ba.app.ui.title_color,
                      h_align='center',
                      v_align='center',
                      maxwidth=270,
                      scale=0.83)
        v -= 20

        if self._unique_id != '#1':
            v -= 20
            v -= self._spacing
            ba.textwidget(parent=self._root_widget,
                          position=(0, v + 19),
                          size=(self._width, 50),
                          text=ba.Lstr(resource=self._r +
                                       '.keyboard2NoteText'),
                          scale=0.7,
                          maxwidth=self._width * 0.75,
                          max_height=110,
                          color=ba.app.ui.infotextcolor,
                          h_align='center',
                          v_align='top')
            v -= 40
        v -= 10
        v -= self._spacing * 2.2
        v += 25
        v -= 42
        h_offs = 160
        dist = 70
        d_color = (0.4, 0.4, 0.8)
        self._capture_button(pos=(h_offs, v + 0.95 * dist),
                             color=d_color,
                             button='buttonUp',
                             texture=ba.gettexture('upButton'),
                             scale=1.0)
        self._capture_button(pos=(h_offs - 1.2 * dist, v),
                             color=d_color,
                             button='buttonLeft',
                             texture=ba.gettexture('leftButton'),
                             scale=1.0)
        self._capture_button(pos=(h_offs + 1.2 * dist, v),
                             color=d_color,
                             button='buttonRight',
                             texture=ba.gettexture('rightButton'),
                             scale=1.0)
        self._capture_button(pos=(h_offs, v - 0.95 * dist),
                             color=d_color,
                             button='buttonDown',
                             texture=ba.gettexture('downButton'),
                             scale=1.0)

        if self._unique_id == '#2':
            self._capture_button(pos=(self._width * 0.5, v + 0.1 * dist),
                                 color=(0.4, 0.4, 0.6),
                                 button='buttonStart',
                                 texture=ba.gettexture('startButton'),
                                 scale=0.8)

        h_offs = self._width - 160

        self._capture_button(pos=(h_offs, v + 0.95 * dist),
                             color=(0.6, 0.4, 0.8),
                             button='buttonPickUp',
                             texture=ba.gettexture('buttonPickUp'),
                             scale=1.0)
        self._capture_button(pos=(h_offs - 1.2 * dist, v),
                             color=(0.7, 0.5, 0.1),
                             button='buttonPunch',
                             texture=ba.gettexture('buttonPunch'),
                             scale=1.0)
        self._capture_button(pos=(h_offs + 1.2 * dist, v),
                             color=(0.5, 0.2, 0.1),
                             button='buttonBomb',
                             texture=ba.gettexture('buttonBomb'),
                             scale=1.0)
        self._capture_button(pos=(h_offs, v - 0.95 * dist),
                             color=(0.2, 0.5, 0.2),
                             button='buttonJump',
                             texture=ba.gettexture('buttonJump'),
                             scale=1.0)
Exemplo n.º 27
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.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.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.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)
Exemplo n.º 28
0
    def _refresh(self) -> None:
        # pylint: disable=too-many-locals
        from ba.internal import (PlayerProfilesChangedMessage,
                                 get_player_profile_colors,
                                 get_player_profile_icon)
        old_selection = self._selected_profile

        # Delete old.
        while self._profile_widgets:
            self._profile_widgets.pop().delete()
        try:
            self._profiles = ba.app.config['Player Profiles']
        except Exception:
            self._profiles = {}
        assert self._profiles is not None
        items = list(self._profiles.items())
        items.sort(key=lambda x: x[0].lower())
        index = 0
        account_name: Optional[str]
        if _ba.get_account_state() == 'signed_in':
            account_name = _ba.get_account_display_string()
        else:
            account_name = None
        widget_to_select = None
        for p_name, _ in items:
            if p_name == '__account__' and account_name is None:
                continue
            color, _highlight = get_player_profile_colors(p_name)
            scl = 1.1
            txtw = ba.textwidget(
                parent=self._columnwidget,
                position=(0, 32),
                size=((self._width - 40) / scl, 28),
                text=ba.Lstr(
                    value=account_name if p_name ==
                    '__account__' else get_player_profile_icon(p_name) +
                    p_name),
                h_align='left',
                v_align='center',
                on_select_call=ba.WeakCall(self._select, p_name, index),
                maxwidth=self._scroll_width * 0.92,
                corner_scale=scl,
                color=ba.safecolor(color, 0.4),
                always_highlight=True,
                on_activate_call=ba.Call(self._edit_button.activate),
                selectable=True)
            if index == 0:
                ba.widget(edit=txtw, up_widget=self._back_button)
            ba.widget(edit=txtw, show_buffer_top=40, show_buffer_bottom=40)
            self._profile_widgets.append(txtw)

            # Select/show this one if it was previously selected
            # (but defer till after this loop since our height is
            # still changing).
            if p_name == old_selection:
                widget_to_select = txtw

            index += 1

        if widget_to_select is not None:
            ba.columnwidget(edit=self._columnwidget,
                            selected_child=widget_to_select,
                            visible_child=widget_to_select)

        # If there's a team-chooser in existence, tell it the profile-list
        # has probably changed.
        session = _ba.get_foreground_host_session()
        if session is not None:
            session.handlemessage(PlayerProfilesChangedMessage())
Exemplo n.º 29
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()
Exemplo n.º 30
0
    def __init__(self,
                 transition: str = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-statements
        from bastd.ui import popup
        from bastd.ui.config import ConfigCheckBox, ConfigNumberEdit
        # if they provided an origin-widget, scale up from that
        scale_origin: Optional[Tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        h_offs = 0

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

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

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

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

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

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

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

        v -= spacing

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