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