Exemple #1
0
 def _playlists_cb(self, playlists: List[str]) -> None:
     if self._column:
         for widget in self._column.get_children():
             widget.delete()
         for playlist in playlists:
             txt = ba.textwidget(parent=self._column,
                                 size=(self._width - 80, 30),
                                 text=playlist,
                                 v_align='center',
                                 maxwidth=self._width - 110,
                                 selectable=True,
                                 on_activate_call=ba.Call(
                                     self._sel, playlist),
                                 click_activate=True)
             if playlist == self._existing_playlist:
                 ba.columnwidget(edit=self._column,
                                 selected_child=txt,
                                 visible_child=txt)
Exemple #2
0
    def __init__(self, callback: Callable[[Any], Any],
                 existing_playlist: Optional[str], existing_entry: Any):
        from ba.internal import get_music_player, MacMusicAppMusicPlayer
        self._r = 'editSoundtrackWindow'
        self._callback = callback
        self._existing_playlist = existing_playlist
        self._existing_entry = copy.deepcopy(existing_entry)
        self._width = 520.0
        self._height = 520.0
        self._spacing = 45.0
        v = self._height - 90.0
        v -= self._spacing * 1.0
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height), transition='in_right'))
        btn = ba.buttonwidget(parent=self._root_widget,
                              position=(35, self._height - 65),
                              size=(130, 50),
                              label=ba.Lstr(resource='cancelText'),
                              on_activate_call=self._back)
        ba.containerwidget(edit=self._root_widget, cancel_button=btn)
        ba.textwidget(parent=self._root_widget,
                      position=(20, self._height - 54),
                      size=(self._width, 25),
                      text=ba.Lstr(resource=self._r + '.selectAPlaylistText'),
                      color=ba.app.title_color,
                      h_align="center",
                      v_align="center",
                      maxwidth=200)
        self._scrollwidget = ba.scrollwidget(parent=self._root_widget,
                                             position=(40, v - 340),
                                             size=(self._width - 80, 400))
        self._column = ba.columnwidget(parent=self._scrollwidget)

        # 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=self._column,
                           claims_left_right=True,
                           claims_tab=True,
                           selection_loop_to_parent=True)

        ba.textwidget(parent=self._column,
                      size=(self._width - 80, 22),
                      text=ba.Lstr(resource=self._r + '.fetchingITunesText'),
                      color=(0.6, 0.9, 0.6, 1.0),
                      scale=0.8)
        musicplayer = get_music_player()
        assert isinstance(musicplayer, MacMusicAppMusicPlayer)
        musicplayer.get_playlists(self._playlists_cb)
        ba.containerwidget(edit=self._root_widget,
                           selected_child=self._scrollwidget)
    def _refresh(self, select_get_more_games_button: bool = False) -> None:
        from ba.internal import get_game_types

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

        self._column = ba.columnwidget(parent=self._scrollwidget,
                                       border=2,
                                       margin=0)

        gametypes = [
            gt for gt in get_game_types() if gt.supports_session_type(
                self._editcontroller.get_session_type())
        ]

        # Sort in the current language.
        gametypes.sort(key=lambda g: g.get_display_string().evaluate())

        for i, gametype in enumerate(gametypes):

            def _doit() -> None:
                if self._select_button:
                    ba.timer(0.1,
                             self._select_button.activate,
                             timetype=ba.TimeType.REAL)

            txt = ba.textwidget(parent=self._column,
                                position=(0, 0),
                                size=(self._width - 88, 24),
                                text=gametype.get_display_string(),
                                h_align='left',
                                v_align='center',
                                color=(0.8, 0.8, 0.8, 1.0),
                                maxwidth=self._scroll_width * 0.8,
                                on_select_call=ba.Call(
                                    self._set_selected_game_type, gametype),
                                always_highlight=True,
                                selectable=True,
                                on_activate_call=_doit)
            if i == 0:
                ba.widget(edit=txt, up_widget=self._back_button)

        self._get_more_games_button = ba.buttonwidget(
            parent=self._column,
            autoselect=True,
            label=ba.Lstr(resource=self._r + '.getMoreGamesText'),
            color=(0.54, 0.52, 0.67),
            textcolor=(0.7, 0.65, 0.7),
            on_activate_call=self._on_get_more_games_press,
            size=(178, 50))
        if select_get_more_games_button:
            ba.containerwidget(edit=self._column,
                               selected_child=self._get_more_games_button,
                               visible_child=self._get_more_games_button)
Exemple #4
0
 def _playlists_cb(self, playlists: List[str]) -> None:
     if self._column:
         for widget in self._column.get_children():
             widget.delete()
         for i, playlist in enumerate(playlists):
             txt = ba.textwidget(parent=self._column,
                                 size=(self._width - 80, 30),
                                 text=playlist,
                                 v_align='center',
                                 maxwidth=self._width - 110,
                                 selectable=True,
                                 on_activate_call=ba.Call(
                                     self._sel, playlist),
                                 click_activate=True)
             ba.widget(edit=txt, show_buffer_top=40, show_buffer_bottom=40)
             if playlist == self._existing_playlist:
                 ba.columnwidget(edit=self._column,
                                 selected_child=txt,
                                 visible_child=txt)
             if i == len(playlists) - 1:
                 ba.widget(edit=txt, down_widget=txt)
Exemple #5
0
    def _refresh(self) -> None:
        from ba.internal import getclass

        # Need to grab this here as rebuilding the list will
        # change it otherwise.
        old_selection_index = self._editcontroller.get_selected_index()

        while self._list_widgets:
            self._list_widgets.pop().delete()
        for index, pentry in enumerate(self._editcontroller.get_playlist()):

            try:
                cls = getclass(pentry['type'], subclassof=ba.GameActivity)
                desc = cls.get_settings_display_string(pentry)
            except Exception:
                ba.print_exception()
                desc = "(invalid: '" + pentry['type'] + "')"

            txtw = ba.textwidget(parent=self._columnwidget,
                                 size=(self._width - 80, 30),
                                 on_select_call=ba.Call(self._select, index),
                                 always_highlight=True,
                                 color=(0.8, 0.8, 0.8, 1.0),
                                 padding=0,
                                 maxwidth=self._scroll_width * 0.93,
                                 text=desc,
                                 on_activate_call=self._edit_button.activate,
                                 v_align='center',
                                 selectable=True)
            ba.widget(edit=txtw, show_buffer_top=50, show_buffer_bottom=50)

            # Wanna be able to jump up to the text field from the top one.
            if index == 0:
                ba.widget(edit=txtw, up_widget=self._text_field)
            self._list_widgets.append(txtw)
            if old_selection_index == index:
                ba.columnwidget(edit=self._columnwidget,
                                selected_child=txtw,
                                visible_child=txtw)
    def __init__(self, tab: GatherTab, scrollwidget: ba.Widget,
                 tab_button: ba.Widget, width: float):
        self._tab = weakref.ref(tab)
        self._scrollwidget = scrollwidget
        self._tab_button = tab_button
        self._columnwidget = ba.columnwidget(parent=self._scrollwidget,
                                             border=2,
                                             margin=0,
                                             left_border=10)
        ba.widget(edit=self._columnwidget, up_widget=tab_button)
        self._width = width
        self._last_selected_host: Optional[Dict[str, Any]] = None

        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self.update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)
        # Go ahead and run a few *almost* immediately so we don't
        # have to wait a second.
        self.update()
        ba.timer(0.25, ba.WeakCall(self.update), timetype=ba.TimeType.REAL)
Exemple #7
0
    def __init__(self,
                 position: Tuple[float, float],
                 choices: Sequence[str],
                 current_choice: str,
                 delegate: Any = None,
                 width: float = 230.0,
                 maxwidth: float = None,
                 scale: float = 1.0,
                 choices_disabled: Sequence[str] = None,
                 choices_display: Sequence[ba.Lstr] = None):
        # FIXME: Clean up a bit.
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        if choices_disabled is None:
            choices_disabled = []
        if choices_display is None:
            choices_display = []

        # FIXME: For the moment we base our width on these strings so
        #  we need to flatten them.
        choices_display_fin: List[str] = []
        for choice_display in choices_display:
            choices_display_fin.append(choice_display.evaluate())

        if maxwidth is None:
            maxwidth = width * 1.5

        self._transitioning_out = False
        self._choices = list(choices)
        self._choices_display = list(choices_display_fin)
        self._current_choice = current_choice
        self._choices_disabled = list(choices_disabled)
        self._done_building = False
        if not choices:
            raise Exception('Must pass at least one choice')
        self._width = width
        self._scale = scale
        if len(choices) > 8:
            self._height = 280
            self._use_scroll = True
        else:
            self._height = 20 + len(choices) * 33
            self._use_scroll = False
        self._delegate = None  # don't want this stuff called just yet..

        # extend width to fit our longest string (or our max-width)
        for index, choice in enumerate(choices):
            if len(choices_display_fin) == len(choices):
                choice_display_name = choices_display_fin[index]
            else:
                choice_display_name = choice
            if self._use_scroll:
                self._width = max(
                    self._width,
                    min(
                        maxwidth,
                        _ba.get_string_width(choice_display_name,
                                             suppress_warning=True)) + 75)
            else:
                self._width = max(
                    self._width,
                    min(
                        maxwidth,
                        _ba.get_string_width(choice_display_name,
                                             suppress_warning=True)) + 60)

        # init parent class - this will rescale and reposition things as
        # needed and create our root widget
        PopupWindow.__init__(self,
                             position,
                             size=(self._width, self._height),
                             scale=self._scale)

        if self._use_scroll:
            self._scrollwidget = ba.scrollwidget(parent=self.root_widget,
                                                 position=(20, 20),
                                                 highlight=False,
                                                 color=(0.35, 0.55, 0.15),
                                                 size=(self._width - 40,
                                                       self._height - 40))
            self._columnwidget = ba.columnwidget(parent=self._scrollwidget)
        else:
            self._offset_widget = ba.containerwidget(parent=self.root_widget,
                                                     position=(30, 15),
                                                     size=(self._width - 40,
                                                           self._height),
                                                     background=False)
            self._columnwidget = ba.columnwidget(parent=self._offset_widget)
        for index, choice in enumerate(choices):
            if len(choices_display_fin) == len(choices):
                choice_display_name = choices_display_fin[index]
            else:
                choice_display_name = choice
            inactive = (choice in self._choices_disabled)
            wdg = ba.textwidget(parent=self._columnwidget,
                                size=(self._width - 40, 28),
                                on_select_call=ba.Call(self._select, index),
                                click_activate=True,
                                color=(0.5, 0.5, 0.5, 0.5) if inactive else
                                ((0.5, 1, 0.5,
                                  1) if choice == self._current_choice else
                                 (0.8, 0.8, 0.8, 1.0)),
                                padding=0,
                                maxwidth=maxwidth,
                                text=choice_display_name,
                                on_activate_call=self._activate,
                                v_align='center',
                                selectable=(not inactive))
            if choice == self._current_choice:
                ba.containerwidget(edit=self._columnwidget,
                                   selected_child=wdg,
                                   visible_child=wdg)

        # ok from now on our delegate can be called
        self._delegate = weakref.ref(delegate)
        self._done_building = True
Exemple #8
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()
Exemple #9
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)
Exemple #10
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)
Exemple #11
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()
Exemple #12
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())
Exemple #13
0
    def __init__(self,
                 sessiontype: Type[ba.Session],
                 transition: str = 'in_right',
                 select_playlist: str = None,
                 origin_widget: ba.Widget = None):
        # Yes this needs tidying.
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        # pylint: disable=cyclic-import
        from bastd.ui import playlist
        scale_origin: Optional[Tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None

        self._sessiontype = sessiontype
        self._pvars = playlist.PlaylistTypeVars(sessiontype)
        self._max_playlists = 30
        self._r = 'gameListWindow'
        self._width = 750.0 if ba.app.small_ui else 650.0
        x_inset = 50.0 if ba.app.small_ui else 0.0
        self._height = (380.0 if ba.app.small_ui else
                        420.0 if ba.app.med_ui else 500.0)
        top_extra = 20.0 if ba.app.small_ui else 0.0

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

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

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

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

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

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

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

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

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

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

        h = 145

        try:
            self._do_randomize_val = ba.app.config[self._pvars.config_name +
                                                   ' Playlist Randomize']
        except Exception:
            self._do_randomize_val = 0

        h += 210

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

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

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

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

        self._refresh(select_playlist=select_playlist)

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

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

        # Keep our lock images up to date/etc.
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)
        self._update()
Exemple #14
0
    def __init__(self,
                 editcontroller: PlaylistEditController,
                 transition: str = 'in_right'):
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        prev_selection: Optional[str]
        self._editcontroller = editcontroller
        self._r = 'editGameListWindow'
        prev_selection = self._editcontroller.get_edit_ui_selection()

        uiscale = ba.app.ui.uiscale
        self._width = 770 if uiscale is ba.UIScale.SMALL else 670
        x_inset = 50 if uiscale is ba.UIScale.SMALL else 0
        self._height = (400 if uiscale is ba.UIScale.SMALL else
                        470 if uiscale is ba.UIScale.MEDIUM else 540)

        top_extra = 20 if uiscale is ba.UIScale.SMALL else 0
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + top_extra),
            transition=transition,
            scale=(2.0 if uiscale is ba.UIScale.SMALL else
                   1.3 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -16) if uiscale is ba.UIScale.SMALL else (0, 0)))
        cancel_button = ba.buttonwidget(parent=self._root_widget,
                                        position=(35 + x_inset,
                                                  self._height - 60),
                                        scale=0.8,
                                        size=(175, 60),
                                        autoselect=True,
                                        label=ba.Lstr(resource='cancelText'),
                                        text_scale=1.2)
        save_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(self._width - (195 + x_inset), self._height - 60),
            scale=0.8,
            size=(190, 60),
            autoselect=True,
            left_widget=cancel_button,
            label=ba.Lstr(resource='saveText'),
            text_scale=1.2)

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

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

        ba.textwidget(parent=self._root_widget,
                      position=(-10, self._height - 50),
                      size=(self._width, 25),
                      text=ba.Lstr(resource=self._r + '.titleText'),
                      color=ba.app.ui.title_color,
                      scale=1.05,
                      h_align='center',
                      v_align='center',
                      maxwidth=270)

        v = self._height - 115.0

        self._scroll_width = self._width - (205 + 2 * x_inset)

        ba.textwidget(parent=self._root_widget,
                      text=ba.Lstr(resource=self._r + '.listNameText'),
                      position=(196 + x_inset, v + 31),
                      maxwidth=150,
                      color=(0.8, 0.8, 0.8, 0.5),
                      size=(0, 0),
                      scale=0.75,
                      h_align='right',
                      v_align='center')

        self._text_field = ba.textwidget(
            parent=self._root_widget,
            position=(210 + x_inset, v + 7),
            size=(self._scroll_width - 53, 43),
            text=self._editcontroller.getname(),
            h_align='left',
            v_align='center',
            max_chars=40,
            autoselect=True,
            color=(0.9, 0.9, 0.9, 1.0),
            description=ba.Lstr(resource=self._r + '.listNameText'),
            editable=True,
            padding=4,
            on_return_press_call=self._save_press_with_sound)
        ba.widget(edit=cancel_button, down_widget=self._text_field)

        self._list_widgets: list[ba.Widget] = []

        h = 40 + x_inset
        v = self._height - 172.0

        b_color = (0.6, 0.53, 0.63)
        b_textcolor = (0.75, 0.7, 0.8)

        v -= 2.0
        v += 63

        scl = (1.03 if uiscale is ba.UIScale.SMALL else
               1.36 if uiscale is ba.UIScale.MEDIUM else 1.74)
        v -= 63.0 * scl

        add_game_button = ba.buttonwidget(
            parent=self._root_widget,
            position=(h, v),
            size=(110, 61.0 * scl),
            on_activate_call=self._add,
            on_select_call=ba.Call(self._set_ui_selection, 'add_button'),
            autoselect=True,
            button_type='square',
            color=b_color,
            textcolor=b_textcolor,
            text_scale=0.8,
            label=ba.Lstr(resource=self._r + '.addGameText'))
        ba.widget(edit=add_game_button, up_widget=self._text_field)
        v -= 63.0 * scl

        self._edit_button = edit_game_button = ba.buttonwidget(
            parent=self._root_widget,
            position=(h, v),
            size=(110, 61.0 * scl),
            on_activate_call=self._edit,
            on_select_call=ba.Call(self._set_ui_selection, 'editButton'),
            autoselect=True,
            button_type='square',
            color=b_color,
            textcolor=b_textcolor,
            text_scale=0.8,
            label=ba.Lstr(resource=self._r + '.editGameText'))
        v -= 63.0 * scl

        remove_game_button = ba.buttonwidget(parent=self._root_widget,
                                             position=(h, v),
                                             size=(110, 61.0 * scl),
                                             text_scale=0.8,
                                             on_activate_call=self._remove,
                                             autoselect=True,
                                             button_type='square',
                                             color=b_color,
                                             textcolor=b_textcolor,
                                             label=ba.Lstr(resource=self._r +
                                                           '.removeGameText'))
        v -= 40
        h += 9
        ba.buttonwidget(parent=self._root_widget,
                        position=(h, v),
                        size=(42, 35),
                        on_activate_call=self._move_up,
                        label=ba.charstr(ba.SpecialChar.UP_ARROW),
                        button_type='square',
                        color=b_color,
                        textcolor=b_textcolor,
                        autoselect=True,
                        repeat=True)
        h += 52
        ba.buttonwidget(parent=self._root_widget,
                        position=(h, v),
                        size=(42, 35),
                        on_activate_call=self._move_down,
                        autoselect=True,
                        button_type='square',
                        color=b_color,
                        textcolor=b_textcolor,
                        label=ba.charstr(ba.SpecialChar.DOWN_ARROW),
                        repeat=True)

        v = self._height - 100
        scroll_height = self._height - 155
        scrollwidget = ba.scrollwidget(
            parent=self._root_widget,
            position=(160 + x_inset, v - scroll_height),
            highlight=False,
            on_select_call=ba.Call(self._set_ui_selection, 'gameList'),
            size=(self._scroll_width, (scroll_height - 15)))
        ba.widget(edit=scrollwidget,
                  left_widget=add_game_button,
                  right_widget=scrollwidget)
        self._columnwidget = ba.columnwidget(parent=scrollwidget,
                                             border=2,
                                             margin=0)
        ba.widget(edit=self._columnwidget, up_widget=self._text_field)

        for button in [add_game_button, edit_game_button, remove_game_button]:
            ba.widget(edit=button,
                      left_widget=button,
                      right_widget=scrollwidget)

        self._refresh()

        ba.buttonwidget(edit=cancel_button, on_activate_call=self._cancel)
        ba.containerwidget(edit=self._root_widget,
                           cancel_button=cancel_button,
                           selected_child=scrollwidget)

        ba.buttonwidget(edit=save_button, on_activate_call=self._save_press)
        ba.containerwidget(edit=self._root_widget, start_button=save_button)

        if prev_selection == 'add_button':
            ba.containerwidget(edit=self._root_widget,
                               selected_child=add_game_button)
        elif prev_selection == 'editButton':
            ba.containerwidget(edit=self._root_widget,
                               selected_child=edit_game_button)
        elif prev_selection == 'gameList':
            ba.containerwidget(edit=self._root_widget,
                               selected_child=scrollwidget)
Exemple #15
0
    def __init__(self,
                 transition: str = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-locals
        app = ba.app

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

        uiscale = ba.app.ui.uiscale
        self._width = 870.0 if uiscale is ba.UIScale.SMALL else 670.0
        x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
        self._height = (390.0 if uiscale is ba.UIScale.SMALL else
                        450.0 if uiscale is ba.UIScale.MEDIUM else 520.0)
        top_extra = 10 if uiscale is ba.UIScale.SMALL else 0
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + top_extra),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(2.06 if uiscale is ba.UIScale.SMALL else
                   1.4 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -25) if uiscale is ba.UIScale.SMALL else (0, 0)))

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

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

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

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

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

        if ba.app.metascan is None:
            ba.screenmessage('Still scanning plugins; please try again.',
                             color=(1, 0, 0))
            ba.playsound(ba.getsound('error'))
        pluglist = ba.app.potential_plugins
        plugstates: Dict[str, Dict] = ba.app.config.setdefault('Plugins', {})
        assert isinstance(plugstates, dict)
        for i, availplug in enumerate(pluglist):
            active = availplug.class_path in ba.app.active_plugins

            plugstate = plugstates.setdefault(availplug.class_path, {})
            checked = plugstate.get('enabled', False)
            assert isinstance(checked, bool)
            check = ba.checkboxwidget(
                parent=self._subcontainer,
                text=availplug.display_name,
                value=checked,
                maxwidth=self._scroll_width - 100,
                size=(self._scroll_width - 40, 50),
                on_value_change_call=ba.Call(self._check_value_changed,
                                             availplug),
                textcolor=((0.8, 0.3, 0.3) if not availplug.available else
                           (0, 1, 0) if active else (0.6, 0.6, 0.6)))

            # Make sure we scroll all the way to the end when using
            # keyboard/button nav.
            ba.widget(edit=check, show_buffer_top=40, show_buffer_bottom=40)

            # Keep last from looping to back button when down is pressed.
            if i == len(pluglist) - 1:
                ba.widget(edit=check, down_widget=check)
        ba.containerwidget(edit=self._root_widget,
                           selected_child=self._scrollwidget)

        self._restore_state()
    def __init__(self, origin_widget: ba.Widget = None):
        scale_origin: Optional[tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None
            transition = 'in_right'
        bg_color = (0.4, 0.4, 0.5)
        self._width = 540
        self._height = 350
        self._scroll_width = 400
        self._scroll_height = 200
        uiscale = ba.app.ui.uiscale
        base_scale = (2.0 if uiscale is ba.UIScale.SMALL else
                      1.6 if uiscale is ba.UIScale.MEDIUM else 1.1)
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height),
            transition=transition,
            scale=base_scale,
            scale_origin_stack_offset=scale_origin,
            stack_offset=(0, -10) if uiscale is ba.UIScale.SMALL else (0, 0)))
        self._cancel_button = ba.buttonwidget(parent=self._root_widget,
                                              position=(30, self._height - 50),
                                              size=(50, 50),
                                              scale=0.7,
                                              label='',
                                              color=bg_color,
                                              on_activate_call=self._cancel,
                                              autoselect=True,
                                              icon=ba.gettexture('crossOut'),
                                              iconscale=1.2)
        ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height * 0.88),
            size=(0, 0),
            text=ba.Lstr(
                resource='accountSettingsWindow.unlinkAccountsInstructionsText'
            ),
            maxwidth=self._width * 0.7,
            color=ba.app.ui.infotextcolor,
            h_align='center',
            v_align='center')
        ba.containerwidget(edit=self._root_widget,
                           cancel_button=self._cancel_button)

        self._scrollwidget = ba.scrollwidget(
            parent=self._root_widget,
            highlight=False,
            position=((self._width - self._scroll_width) * 0.5,
                      self._height - 85 - self._scroll_height),
            size=(self._scroll_width, self._scroll_height))
        ba.containerwidget(edit=self._scrollwidget, claims_left_right=True)
        self._columnwidget = ba.columnwidget(parent=self._scrollwidget,
                                             border=2,
                                             margin=0,
                                             left_border=10)

        our_login_id = _ba.get_public_login_id()
        if our_login_id is None:
            entries = []
        else:
            account_infos = _ba.get_account_misc_read_val_2(
                'linkedAccounts2', [])
            entries = [{
                'name': ai['d'],
                'id': ai['id']
            } for ai in account_infos if ai['id'] != our_login_id]

        # (avoid getting our selection stuck on an empty column widget)
        if not entries:
            ba.containerwidget(edit=self._scrollwidget, selectable=False)
        for i, entry in enumerate(entries):
            txt = ba.textwidget(parent=self._columnwidget,
                                selectable=True,
                                text=entry['name'],
                                size=(self._scroll_width - 30, 30),
                                autoselect=True,
                                click_activate=True,
                                on_activate_call=ba.Call(
                                    self._on_entry_selected, entry))
            ba.widget(edit=txt, left_widget=self._cancel_button)
            if i == 0:
                ba.widget(edit=txt, up_widget=self._cancel_button)
Exemple #17
0
    def __init__(self, transition: str = 'in_right'):
        self._width = 820
        self._height = 500
        self._printed_lines: list[str] = []
        uiscale = ba.app.ui.uiscale
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height),
            scale=(1.56 if uiscale is ba.UIScale.SMALL else
                   1.2 if uiscale is ba.UIScale.MEDIUM else 0.8),
            stack_offset=(0.0, -7 if uiscale is ba.UIScale.SMALL else 0.0),
            transition=transition))
        self._done_button = ba.buttonwidget(parent=self._root_widget,
                                            position=(40, self._height - 77),
                                            size=(120, 60),
                                            scale=0.8,
                                            autoselect=True,
                                            label=ba.Lstr(resource='doneText'),
                                            on_activate_call=self._done)

        self._copy_button = ba.buttonwidget(parent=self._root_widget,
                                            position=(self._width - 200,
                                                      self._height - 77),
                                            size=(100, 60),
                                            scale=0.8,
                                            autoselect=True,
                                            label=ba.Lstr(resource='copyText'),
                                            on_activate_call=self._copy)

        self._settings_button = ba.buttonwidget(
            parent=self._root_widget,
            position=(self._width - 100, self._height - 77),
            size=(60, 60),
            scale=0.8,
            autoselect=True,
            label=ba.Lstr(value='...'),
            on_activate_call=self._show_val_testing)

        twidth = self._width - 450
        ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height - 55),
            size=(0, 0),
            text=ba.Lstr(resource='settingsWindowAdvanced.netTestingText'),
            color=(0.8, 0.8, 0.8, 1.0),
            h_align='center',
            v_align='center',
            maxwidth=twidth)

        self._scroll = ba.scrollwidget(parent=self._root_widget,
                                       position=(50, 50),
                                       size=(self._width - 100,
                                             self._height - 140),
                                       capture_arrows=True,
                                       autoselect=True)
        self._rows = ba.columnwidget(parent=self._scroll)

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

        # Now kick off the tests.
        # Pass a weak-ref to this window so we don't keep it alive
        # if we back out before it completes. Also set is as daemon
        # so it doesn't keep the app running if the user is trying to quit.
        Thread(
            daemon=True,
            target=ba.Call(_run_diagnostics, weakref.ref(self)),
        ).start()
    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()
Exemple #19
0
    def _refresh(self, select_playlist: str = None) -> None:
        old_selection = self._selected_playlist_name

        # If there was no prev selection, look in prefs.
        if old_selection is None:
            try:
                old_selection = ba.app.config[self._pvars.config_name +
                                              ' Playlist Selection']
            except Exception:
                pass

        old_selection_index = self._selected_playlist_index

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

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

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

        items.sort(key=lambda x: x[0].lower())

        items = [['__default__', None]] + items  # Default is always first.
        index = 0
        for pname, _ in items:
            assert pname is not None
            txtw = ba.textwidget(
                parent=self._columnwidget,
                size=(self._width - 40, 30),
                maxwidth=self._width - 110,
                text=self._get_playlist_display_name(pname),
                h_align='left',
                v_align='center',
                color=(0.6, 0.6, 0.7, 1.0) if pname == '__default__' else
                (0.85, 0.85, 0.85, 1),
                always_highlight=True,
                on_select_call=ba.Call(self._select, pname, index),
                on_activate_call=ba.Call(self._edit_button.activate),
                selectable=True)
            ba.widget(edit=txtw, show_buffer_top=50, show_buffer_bottom=50)

            # Hitting up from top widget should jump to 'back'
            if index == 0:
                ba.widget(edit=txtw, up_widget=self._back_button)

            self._playlist_widgets.append(txtw)

            # Select this one if the user requested it.
            if select_playlist is not None:
                if pname == select_playlist:
                    ba.columnwidget(edit=self._columnwidget,
                                    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._columnwidget,
                                        selected_child=txtw,
                                        visible_child=txtw)
                else:  # Otherwise look by name.
                    if pname == old_selection:
                        ba.columnwidget(edit=self._columnwidget,
                                        selected_child=txtw,
                                        visible_child=txtw)

            index += 1
Exemple #20
0
    def _build_favorites_tab(self, region_height: float) -> None:

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

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

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

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

        v = c_height - 30

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

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

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

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

        self._favorite_selected = None
        self._refresh_favorites()
Exemple #21
0
    def __init__(self,
                 existing_soundtrack: Optional[Union[str, Dict[str, Any]]],
                 transition: str = 'in_right'):
        # pylint: disable=too-many-statements
        appconfig = ba.app.config
        self._r = 'editSoundtrackWindow'
        self._folder_tex = ba.gettexture('folder')
        self._file_tex = ba.gettexture('file')
        uiscale = ba.app.ui.uiscale
        self._width = 848 if uiscale is ba.UIScale.SMALL else 648
        x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
        self._height = (395 if uiscale is ba.UIScale.SMALL else
                        450 if uiscale is ba.UIScale.MEDIUM else 560)
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height),
            transition=transition,
            scale=(2.08 if uiscale is ba.UIScale.SMALL else
                   1.5 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -48) if uiscale is ba.UIScale.SMALL else (
                0, 15) if uiscale is ba.UIScale.MEDIUM 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.ui.title_color,
            h_align='center',
            v_align='center',
            maxwidth=280)
        v = self._height - 110
        if 'Soundtracks' not in appconfig:
            appconfig['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(
                    appconfig['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 appconfig['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,
            claims_left_right=True,
            claims_tab=True,
            selection_loops_to_parent=True)
        ba.widget(edit=self._text_field, down_widget=self._scrollwidget)
        self._col = ba.columnwidget(parent=scrollwidget,
                                    claims_left_right=True,
                                    claims_tab=True,
                                    selection_loops_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)
    def _build_saved_party_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
        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)
        scroll_buffer_h = 130 + 2 * x_inset
        tab_buffer_h = 750 + 2 * x_inset
        self._scroll_width = self._width - scroll_buffer_h
        self._scroll_height = self._height - 180
        x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
        
        if True:
            c_width = self._scroll_width
            c_height = self._scroll_height - 20
            sub_scroll_height = c_height - 63
            self._my_parties_scroll_width = sub_scroll_width = (
                680 if uiscale is ba.UIScale.SMALL else 640)

           

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

            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_saved_party_connect_button = btn1 = ba.buttonwidget(
                parent=self._container,
                size=(b_width, b_height),
                position=(btnh, btnv),
                button_type='square',
                color=b_color,
                textcolor=b_textcolor,
                on_activate_call=self._on_my_saved_party_press,
                text_scale=tscl,
                label="Connect",
                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=self._container,
                            size=(b_width, b_height),
                            position=(btnh, btnv),
                            button_type='square',
                            color=b_color,
                            textcolor=b_textcolor,
                            on_activate_call=self._on_my_saved_party_rename_press,
                            text_scale=tscl,
                            label="Rename",
                            autoselect=True)
            btnv -= b_height + b_space_extra
            ba.buttonwidget(parent=self._container,
                            size=(b_width, b_height),
                            position=(btnh, btnv),
                            button_type='square',
                            color=b_color,
                            textcolor=b_textcolor,
                            on_activate_call=self._on_my_saved_party_delete_press,
                            text_scale=tscl,
                            label="Delete",
                            autoselect=True)

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

            
            self._my_saved_party_selected = None
            self._refresh_my_saved_parties()