def __init__(self) -> None: self._width = 650 self._height = 380 self._spacing = 40 self._r = 'configTouchscreenWindow' _ba.set_touchscreen_editing(True) uiscale = ba.app.ui.uiscale super().__init__(root_widget=ba.containerwidget( size=(self._width, self._height), transition='in_right', scale=(1.9 if uiscale is ba.UIScale.SMALL else 1.55 if uiscale is ba.UIScale.MEDIUM else 1.2))) btn = ba.buttonwidget(parent=self._root_widget, position=(55, self._height - 60), size=(120, 60), label=ba.Lstr(resource='backText'), button_type='back', scale=0.8, on_activate_call=self._back) ba.containerwidget(edit=self._root_widget, cancel_button=btn) ba.textwidget(parent=self._root_widget, position=(25, self._height - 50), size=(self._width, 25), text=ba.Lstr(resource=self._r + '.titleText'), color=ba.app.ui.title_color, maxwidth=280, h_align='center', v_align='center') ba.buttonwidget(edit=btn, button_type='backSmall', size=(60, 60), label=ba.charstr(ba.SpecialChar.BACK)) self._scroll_width = self._width - 100 self._scroll_height = self._height - 110 self._sub_width = self._scroll_width - 20 self._sub_height = 360 self._scrollwidget = ba.scrollwidget( parent=self._root_widget, position=((self._width - self._scroll_width) * 0.5, self._height - 65 - self._scroll_height), size=(self._scroll_width, self._scroll_height), claims_left_right=True, claims_tab=True, selection_loops_to_parent=True) self._subcontainer = ba.containerwidget(parent=self._scrollwidget, size=(self._sub_width, self._sub_height), background=False, claims_left_right=True, claims_tab=True, selection_loops_to_parent=True) self._build_gui()
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 on_activate( self, parent_widget: ba.Widget, tab_button: ba.Widget, region_width: float, region_height: float, region_left: float, region_bottom: float, ) -> ba.Widget: c_width = region_width c_height = region_height - 20 sub_scroll_height = c_height - 85 sub_scroll_width = 650 self._container = ba.containerwidget( parent=parent_widget, position=(region_left, region_bottom + (region_height - c_height) * 0.5), size=(c_width, c_height), background=False, selection_loops_to_parent=True) v = c_height - 30 ba.textwidget(parent=self._container, position=(c_width * 0.5, v - 3), color=(0.6, 1.0, 0.6), scale=1.3, size=(0, 0), maxwidth=c_width * 0.9, h_align='center', v_align='center', text=ba.Lstr(resource='gatherWindow.' 'localNetworkDescriptionText')) v -= 15 v -= sub_scroll_height + 23 scrollw = ba.scrollwidget(parent=self._container, position=((region_width - sub_scroll_width) * 0.5, v), size=(sub_scroll_width, sub_scroll_height)) self._net_scanner = NetScanner(self, scrollw, tab_button, width=sub_scroll_width) ba.widget(edit=scrollw, autoselect=True, up_widget=tab_button) return self._container
def __init__(self, title: ba.Lstr, entries: List[Dict[str, Any]], transition: str = 'in_right'): self._width = 600 self._height = 324 if ba.app.small_ui else 400 self._entries = copy.deepcopy(entries) super().__init__(root_widget=ba.containerwidget( size=(self._width, self._height), transition=transition, scale=(2.5 if ba.app.small_ui else 1.2 if ba.app.med_ui else 1.0), stack_offset=(0, -28) if ba.app.small_ui else (0, 0))) self._back_button = btn = ba.buttonwidget( parent=self._root_widget, autoselect=True, position=(65, self._height - 59), size=(130, 60), scale=0.8, text_scale=1.2, label=ba.Lstr(resource='backText'), button_type='back', on_activate_call=self._do_back) ba.textwidget(parent=self._root_widget, position=(self._width * 0.5, self._height - 35), size=(0, 0), color=ba.app.title_color, h_align='center', v_align='center', maxwidth=245, text=title) 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 - 75), size=(0, 0), color=ba.app.infotextcolor, h_align='center', v_align='center', maxwidth=self._width * 0.75, text=ba.Lstr(resource='settingsWindowAdvanced.forTestingText')) ba.containerwidget(edit=self._root_widget, cancel_button=btn) self._scroll_width = self._width - 130 self._scroll_height = self._height - 140 self._scrollwidget = ba.scrollwidget( parent=self._root_widget, size=(self._scroll_width, self._scroll_height), highlight=False, position=((self._width - self._scroll_width) * 0.5, 40)) ba.containerwidget(edit=self._scrollwidget, claims_left_right=True) self._spacing = 50 self._sub_width = self._scroll_width * 0.95 self._sub_height = 50 + len(self._entries) * self._spacing + 60 self._subcontainer = ba.containerwidget(parent=self._scrollwidget, size=(self._sub_width, self._sub_height), background=False) h = 230 v = self._sub_height - 48 for i, entry in enumerate(self._entries): entry_name = entry['name'] # if we haven't yet, record the default value for this name so # we can reset if we want.. if entry_name not in ba.app.value_test_defaults: ba.app.value_test_defaults[entry_name] = ( _ba.value_test(entry_name)) ba.textwidget(parent=self._subcontainer, position=(h, v), size=(0, 0), h_align='right', v_align='center', maxwidth=200, text=entry['label']) btn = ba.buttonwidget(parent=self._subcontainer, position=(h + 20, v - 19), size=(40, 40), autoselect=True, repeat=True, left_widget=self._back_button, button_type='square', label='-', on_activate_call=ba.Call( self._on_minus_press, entry['name'])) if i == 0: ba.widget(edit=btn, up_widget=self._back_button) ba.widget(edit=btn, show_buffer_top=20, show_buffer_bottom=20) entry['widget'] = ba.textwidget( parent=self._subcontainer, position=(h + 100, v), size=(0, 0), h_align='center', v_align='center', maxwidth=60, text=str(round(_ba.value_test(entry_name), 4))) btn = ba.buttonwidget(parent=self._subcontainer, position=(h + 140, v - 19), size=(40, 40), autoselect=True, repeat=True, button_type='square', label='+', on_activate_call=ba.Call( self._on_plus_press, entry['name'])) if i == 0: ba.widget(edit=btn, up_widget=self._back_button) v -= self._spacing v -= 35 b_reset = ba.buttonwidget( parent=self._subcontainer, autoselect=True, size=(200, 50), position=(self._sub_width * 0.5 - 100, v), label=ba.Lstr(resource='settingsWindowAdvanced.resetText'), right_widget=btn, on_activate_call=self._on_reset_press) ba.widget(edit=b_reset, show_buffer_top=20, show_buffer_bottom=20)
def __init__(self, gametype: type[ba.GameActivity], sessiontype: type[ba.Session], config: dict[str, Any], edit_info: dict[str, Any], completion_call: Callable[[Optional[dict[str, Any]]], Any], transition: str = 'in_right'): from ba.internal import get_filtered_map_name self._gametype = gametype self._sessiontype = sessiontype self._config = config self._completion_call = completion_call self._edit_info = edit_info self._maps: list[tuple[str, ba.Texture]] = [] try: self._previous_map = get_filtered_map_name( config['settings']['map']) except Exception: self._previous_map = '' uiscale = ba.app.ui.uiscale width = 715 if uiscale is ba.UIScale.SMALL else 615 x_inset = 50 if uiscale is ba.UIScale.SMALL else 0 height = (400 if uiscale is ba.UIScale.SMALL else 480 if uiscale is ba.UIScale.MEDIUM else 600) top_extra = 20 if uiscale is ba.UIScale.SMALL else 0 super().__init__(root_widget=ba.containerwidget( size=(width, height + top_extra), transition=transition, scale=(2.17 if uiscale is ba.UIScale.SMALL else 1.3 if uiscale is ba.UIScale.MEDIUM else 1.0), stack_offset=(0, -27) if uiscale is ba.UIScale.SMALL else (0, 0))) self._cancel_button = btn = ba.buttonwidget( parent=self._root_widget, position=(38 + x_inset, height - 67), size=(140, 50), scale=0.9, text_scale=1.0, autoselect=True, label=ba.Lstr(resource='cancelText'), on_activate_call=self._cancel) ba.containerwidget(edit=self._root_widget, cancel_button=btn) ba.textwidget(parent=self._root_widget, position=(width * 0.5, height - 46), size=(0, 0), maxwidth=260, scale=1.1, text=ba.Lstr(resource='mapSelectTitleText', subs=[('${GAME}', self._gametype.get_display_string()) ]), color=ba.app.ui.title_color, h_align='center', v_align='center') v = height - 70 self._scroll_width = width - (80 + 2 * x_inset) self._scroll_height = height - 140 self._scrollwidget = ba.scrollwidget( parent=self._root_widget, position=(40 + x_inset, v - self._scroll_height), size=(self._scroll_width, self._scroll_height)) ba.containerwidget(edit=self._root_widget, selected_child=self._scrollwidget) ba.containerwidget(edit=self._scrollwidget, claims_left_right=True) self._subcontainer: Optional[ba.Widget] = None self._refresh()
def __init__(self, tournament_id: str, tournament_activity: ba.GameActivity = None, position: Tuple[float, float] = (0.0, 0.0), scale: float = None, offset: Tuple[float, float] = (0.0, 0.0), tint_color: Sequence[float] = (1.0, 1.0, 1.0), tint2_color: Sequence[float] = (1.0, 1.0, 1.0), selected_character: str = None, on_close_call: Callable[[], Any] = None): del tournament_activity # unused arg del tint_color # unused arg del tint2_color # unused arg del selected_character # unused arg self._tournament_id = tournament_id self._subcontainer: Optional[ba.Widget] = None self._on_close_call = on_close_call uiscale = ba.app.ui.uiscale if scale is None: scale = (2.3 if uiscale is ba.UIScale.SMALL else 1.65 if uiscale is ba.UIScale.MEDIUM else 1.23) self._transitioning_out = False self._width = 400 self._height = (300 if uiscale is ba.UIScale.SMALL else 370 if uiscale is ba.UIScale.MEDIUM else 450) bg_color = (0.5, 0.4, 0.6) # creates our _root_widget super().__init__(position=position, size=(self._width, self._height), scale=scale, bg_color=bg_color, offset=offset) # app = ba.app self._cancel_button = ba.buttonwidget( parent=self.root_widget, position=(50, self._height - 30), size=(50, 50), scale=0.5, label='', color=bg_color, on_activate_call=self._on_cancel_press, autoselect=True, icon=ba.gettexture('crossOut'), iconscale=1.2) self._title_text = ba.textwidget( parent=self.root_widget, position=(self._width * 0.5, self._height - 20), size=(0, 0), h_align='center', v_align='center', scale=0.6, text=ba.Lstr(resource='tournamentStandingsText'), maxwidth=200, color=(1, 1, 1, 0.4)) self._scrollwidget = ba.scrollwidget(parent=self.root_widget, size=(self._width - 60, self._height - 70), position=(30, 30), highlight=False, simple_culling_v=10) ba.widget(edit=self._scrollwidget, autoselect=True) self._loading_text = ba.textwidget( parent=self._scrollwidget, scale=0.5, text=ba.Lstr(value='${A}...', subs=[('${A}', ba.Lstr(resource='loadingText'))]), size=(self._width - 60, 100), h_align='center', v_align='center') ba.containerwidget(edit=self.root_widget, cancel_button=self._cancel_button) _ba.tournament_query(args={ 'tournamentIDs': [tournament_id], 'numScores': 50, 'source': 'scores window' }, callback=ba.WeakCall( self._on_tournament_query_response))
def __init__(self, gametype: Type[ba.GameActivity], sessiontype: Type[ba.Session], config: Optional[Dict[str, Any]], completion_call: Callable[[Optional[Dict[str, Any]]], Any], default_selection: str = None, transition: str = 'in_right', edit_info: Dict[str, Any] = None): # pylint: disable=too-many-branches # pylint: disable=too-many-statements # pylint: disable=too-many-locals from ba.internal import (get_unowned_maps, get_filtered_map_name, get_map_class, get_map_display_string) self._gametype = gametype self._sessiontype = sessiontype # If we're within an editing session we get passed edit_info # (returning from map selection window, etc). if edit_info is not None: self._edit_info = edit_info # ..otherwise determine whether we're adding or editing a game based # on whether an existing config was passed to us. else: if config is None: self._edit_info = {'editType': 'add'} else: self._edit_info = {'editType': 'edit'} self._r = 'gameSettingsWindow' valid_maps = gametype.get_supported_maps(sessiontype) if not valid_maps: ba.screenmessage(ba.Lstr(resource='noValidMapsErrorText')) raise Exception('No valid maps') self._settings_defs = gametype.get_available_settings(sessiontype) self._completion_call = completion_call # To start with, pick a random map out of the ones we own. unowned_maps = get_unowned_maps() valid_maps_owned = [m for m in valid_maps if m not in unowned_maps] if valid_maps_owned: self._map = valid_maps[random.randrange(len(valid_maps_owned))] # Hmmm.. we own none of these maps.. just pick a random un-owned one # I guess.. should this ever happen? else: self._map = valid_maps[random.randrange(len(valid_maps))] is_add = (self._edit_info['editType'] == 'add') # If there's a valid map name in the existing config, use that. try: if (config is not None and 'settings' in config and 'map' in config['settings']): filtered_map_name = get_filtered_map_name( config['settings']['map']) if filtered_map_name in valid_maps: self._map = filtered_map_name except Exception: ba.print_exception('Error getting map for editor.') if config is not None and 'settings' in config: self._settings = config['settings'] else: self._settings = {} self._choice_selections: Dict[str, int] = {} uiscale = ba.app.ui.uiscale width = 720 if uiscale is ba.UIScale.SMALL else 620 x_inset = 50 if uiscale is ba.UIScale.SMALL else 0 height = (365 if uiscale is ba.UIScale.SMALL else 460 if uiscale is ba.UIScale.MEDIUM else 550) spacing = 52 y_extra = 15 y_extra2 = 21 map_tex_name = (get_map_class(self._map).get_preview_texture_name()) if map_tex_name is None: raise Exception('no map preview tex found for' + self._map) map_tex = ba.gettexture(map_tex_name) top_extra = 20 if uiscale is ba.UIScale.SMALL else 0 super().__init__(root_widget=ba.containerwidget( size=(width, height + top_extra), transition=transition, scale=(2.19 if uiscale is ba.UIScale.SMALL else 1.35 if uiscale is ba.UIScale.MEDIUM else 1.0), stack_offset=(0, -17) if uiscale is ba.UIScale.SMALL else (0, 0))) btn = ba.buttonwidget( parent=self._root_widget, position=(45 + x_inset, height - 82 + y_extra2), size=(180, 70) if is_add else (180, 65), label=ba.Lstr(resource='backText') if is_add else ba.Lstr( resource='cancelText'), button_type='back' if is_add else None, autoselect=True, scale=0.75, text_scale=1.3, on_activate_call=ba.Call(self._cancel)) ba.containerwidget(edit=self._root_widget, cancel_button=btn) add_button = ba.buttonwidget( parent=self._root_widget, position=(width - (193 + x_inset), height - 82 + y_extra2), size=(200, 65), scale=0.75, text_scale=1.3, label=ba.Lstr(resource=self._r + '.addGameText') if is_add else ba.Lstr( resource='doneText')) if ba.app.ui.use_toolbars: pbtn = _ba.get_special_widget('party_button') ba.widget(edit=add_button, right_widget=pbtn, up_widget=pbtn) ba.textwidget(parent=self._root_widget, position=(-8, height - 70 + y_extra2), size=(width, 25), text=gametype.get_display_string(), color=ba.app.ui.title_color, maxwidth=235, scale=1.1, h_align='center', v_align='center') map_height = 100 scroll_height = map_height + 10 # map select and margin # Calc our total height we'll need scroll_height += spacing * len(self._settings_defs) scroll_width = width - (86 + 2 * x_inset) self._scrollwidget = ba.scrollwidget(parent=self._root_widget, position=(44 + x_inset, 35 + y_extra), size=(scroll_width, height - 116), highlight=False, claims_left_right=True, claims_tab=True, selection_loops_to_parent=True) self._subcontainer = ba.containerwidget(parent=self._scrollwidget, size=(scroll_width, scroll_height), background=False, claims_left_right=True, claims_tab=True, selection_loops_to_parent=True) v = scroll_height - 5 h = -40 # Keep track of all the selectable widgets we make so we can wire # them up conveniently. widget_column: List[List[ba.Widget]] = [] # Map select button. ba.textwidget(parent=self._subcontainer, position=(h + 49, v - 63), size=(100, 30), maxwidth=110, text=ba.Lstr(resource='mapText'), h_align='left', color=(0.8, 0.8, 0.8, 1.0), v_align='center') ba.imagewidget( parent=self._subcontainer, size=(256 * 0.7, 125 * 0.7), position=(h + 261 - 128 + 128.0 * 0.56, v - 90), texture=map_tex, model_opaque=ba.getmodel('level_select_button_opaque'), model_transparent=ba.getmodel('level_select_button_transparent'), mask_texture=ba.gettexture('mapPreviewMask')) map_button = btn = ba.buttonwidget( parent=self._subcontainer, size=(140, 60), position=(h + 448, v - 72), on_activate_call=ba.Call(self._select_map), scale=0.7, label=ba.Lstr(resource='mapSelectText')) widget_column.append([btn]) ba.textwidget(parent=self._subcontainer, position=(h + 363 - 123, v - 114), size=(100, 30), flatness=1.0, shadow=1.0, scale=0.55, maxwidth=256 * 0.7 * 0.8, text=get_map_display_string(self._map), h_align='center', color=(0.6, 1.0, 0.6, 1.0), v_align='center') v -= map_height for setting in self._settings_defs: value = setting.default value_type = type(value) # Now, if there's an existing value for it in the config, # override with that. try: if (config is not None and 'settings' in config and setting.name in config['settings']): value = value_type(config['settings'][setting.name]) except Exception: ba.print_exception() # Shove the starting value in there to start. self._settings[setting.name] = value name_translated = self._get_localized_setting_name(setting.name) mw1 = 280 mw2 = 70 # Handle types with choices specially: if isinstance(setting, ba.ChoiceSetting): for choice in setting.choices: if len(choice) != 2: raise ValueError( "Expected 2-member tuples for 'choices'; got: " + repr(choice)) if not isinstance(choice[0], str): raise TypeError( 'First value for choice tuple must be a str; got: ' + repr(choice)) if not isinstance(choice[1], value_type): raise TypeError( 'Choice type does not match default value; choice:' + repr(choice) + '; setting:' + repr(setting)) if value_type not in (int, float): raise TypeError( 'Choice type setting must have int or float default; ' 'got: ' + repr(setting)) # Start at the choice corresponding to the default if possible. self._choice_selections[setting.name] = 0 for index, choice in enumerate(setting.choices): if choice[1] == value: self._choice_selections[setting.name] = index break v -= spacing ba.textwidget(parent=self._subcontainer, position=(h + 50, v), size=(100, 30), maxwidth=mw1, text=name_translated, h_align='left', color=(0.8, 0.8, 0.8, 1.0), v_align='center') txt = ba.textwidget( parent=self._subcontainer, position=(h + 509 - 95, v), size=(0, 28), text=self._get_localized_setting_name(setting.choices[ self._choice_selections[setting.name]][0]), editable=False, color=(0.6, 1.0, 0.6, 1.0), maxwidth=mw2, h_align='right', v_align='center', padding=2) btn1 = ba.buttonwidget(parent=self._subcontainer, position=(h + 509 - 50 - 1, v), size=(28, 28), label='<', autoselect=True, on_activate_call=ba.Call( self._choice_inc, setting.name, txt, setting, -1), repeat=True) btn2 = ba.buttonwidget(parent=self._subcontainer, position=(h + 509 + 5, v), size=(28, 28), label='>', autoselect=True, on_activate_call=ba.Call( self._choice_inc, setting.name, txt, setting, 1), repeat=True) widget_column.append([btn1, btn2]) elif isinstance(setting, (ba.IntSetting, ba.FloatSetting)): v -= spacing min_value = setting.min_value max_value = setting.max_value increment = setting.increment ba.textwidget(parent=self._subcontainer, position=(h + 50, v), size=(100, 30), text=name_translated, h_align='left', color=(0.8, 0.8, 0.8, 1.0), v_align='center', maxwidth=mw1) txt = ba.textwidget(parent=self._subcontainer, position=(h + 509 - 95, v), size=(0, 28), text=str(value), editable=False, color=(0.6, 1.0, 0.6, 1.0), maxwidth=mw2, h_align='right', v_align='center', padding=2) btn1 = ba.buttonwidget(parent=self._subcontainer, position=(h + 509 - 50 - 1, v), size=(28, 28), label='-', autoselect=True, on_activate_call=ba.Call( self._inc, txt, min_value, max_value, -increment, value_type, setting.name), repeat=True) btn2 = ba.buttonwidget(parent=self._subcontainer, position=(h + 509 + 5, v), size=(28, 28), label='+', autoselect=True, on_activate_call=ba.Call( self._inc, txt, min_value, max_value, increment, value_type, setting.name), repeat=True) widget_column.append([btn1, btn2]) elif value_type == bool: v -= spacing ba.textwidget(parent=self._subcontainer, position=(h + 50, v), size=(100, 30), text=name_translated, h_align='left', color=(0.8, 0.8, 0.8, 1.0), v_align='center', maxwidth=mw1) txt = ba.textwidget( parent=self._subcontainer, position=(h + 509 - 95, v), size=(0, 28), text=ba.Lstr(resource='onText') if value else ba.Lstr( resource='offText'), editable=False, color=(0.6, 1.0, 0.6, 1.0), maxwidth=mw2, h_align='right', v_align='center', padding=2) cbw = ba.checkboxwidget(parent=self._subcontainer, text='', position=(h + 505 - 50 - 5, v - 2), size=(200, 30), autoselect=True, textcolor=(0.8, 0.8, 0.8), value=value, on_value_change_call=ba.Call( self._check_value_change, setting.name, txt)) widget_column.append([cbw]) else: raise Exception() # Ok now wire up the column. try: # pylint: disable=unsubscriptable-object prev_widgets: Optional[List[ba.Widget]] = None for cwdg in widget_column: if prev_widgets is not None: # Wire our rightmost to their rightmost. ba.widget(edit=prev_widgets[-1], down_widget=cwdg[-1]) ba.widget(cwdg[-1], up_widget=prev_widgets[-1]) # Wire our leftmost to their leftmost. ba.widget(edit=prev_widgets[0], down_widget=cwdg[0]) ba.widget(cwdg[0], up_widget=prev_widgets[0]) prev_widgets = cwdg except Exception: ba.print_exception( 'Error wiring up game-settings-select widget column.') ba.buttonwidget(edit=add_button, on_activate_call=ba.Call(self._add)) ba.containerwidget(edit=self._root_widget, selected_child=add_button, start_button=add_button) if default_selection == 'map': ba.containerwidget(edit=self._root_widget, selected_child=self._scrollwidget) ba.containerwidget(edit=self._subcontainer, selected_child=map_button)
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 _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 __init__(self, transition: str = 'in_right', modal: bool = False, origin_widget: ba.Widget = None, close_once_signed_in: bool = False): # pylint: disable=too-many-statements self._sign_in_game_circle_button: Optional[ba.Widget] = None self._sign_in_v2_button: Optional[ba.Widget] = None self._sign_in_device_button: Optional[ba.Widget] = None self._close_once_signed_in = close_once_signed_in ba.set_analytics_screen('Account Window') # If they provided an origin-widget, scale up from that. scale_origin: Optional[tuple[float, float]] if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() transition = 'in_scale' else: self._transition_out = 'out_right' scale_origin = None self._r = 'accountSettingsWindow' self._modal = modal self._needs_refresh = False self._signed_in = (_ba.get_v1_account_state() == 'signed_in') self._account_state_num = _ba.get_v1_account_state_num() self._show_linked = (self._signed_in and _ba.get_v1_account_misc_read_val( 'allowAccountLinking2', False)) self._check_sign_in_timer = ba.Timer(1.0, ba.WeakCall(self._update), timetype=ba.TimeType.REAL, repeat=True) # Currently we can only reset achievements on game-center. account_type: Optional[str] if self._signed_in: account_type = _ba.get_v1_account_type() else: account_type = None self._can_reset_achievements = (account_type == 'Game Center') app = ba.app uiscale = app.ui.uiscale self._width = 760 if uiscale is ba.UIScale.SMALL else 660 x_offs = 50 if uiscale is ba.UIScale.SMALL else 0 self._height = (390 if uiscale is ba.UIScale.SMALL else 430 if uiscale is ba.UIScale.MEDIUM else 490) self._sign_in_button = None self._sign_in_text = None self._scroll_width = self._width - (100 + x_offs * 2) self._scroll_height = self._height - 120 self._sub_width = self._scroll_width - 20 # Determine which sign-in/sign-out buttons we should show. self._show_sign_in_buttons: list[str] = [] if app.platform == 'android' and app.subplatform == 'google': self._show_sign_in_buttons.append('Google Play') elif app.platform == 'android' and app.subplatform == 'amazon': self._show_sign_in_buttons.append('Game Circle') # Local accounts are generally always available with a few key # exceptions. self._show_sign_in_buttons.append('Local') # Ditto with shiny new V2 ones. if bool(True): self._show_sign_in_buttons.append('V2') top_extra = 15 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.09 if uiscale is ba.UIScale.SMALL else 1.4 if uiscale is ba.UIScale.MEDIUM else 1.0), stack_offset=(0, -19) if uiscale is ba.UIScale.SMALL else (0, 0))) if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars: self._back_button = None ba.containerwidget(edit=self._root_widget, on_cancel_call=self._back) else: self._back_button = btn = ba.buttonwidget( parent=self._root_widget, position=(51 + x_offs, self._height - 62), size=(120, 60), scale=0.8, text_scale=1.2, autoselect=True, label=ba.Lstr( resource='doneText' if self._modal else 'backText'), button_type='regular' if self._modal else 'back', on_activate_call=self._back) ba.containerwidget(edit=self._root_widget, cancel_button=btn) if not self._modal: ba.buttonwidget(edit=btn, button_type='backSmall', size=(60, 56), label=ba.charstr(ba.SpecialChar.BACK)) ba.textwidget(parent=self._root_widget, position=(self._width * 0.5, self._height - 41), size=(0, 0), text=ba.Lstr(resource=self._r + '.titleText'), color=ba.app.ui.title_color, maxwidth=self._width - 340, h_align='center', v_align='center') self._scrollwidget = ba.scrollwidget( parent=self._root_widget, highlight=False, position=((self._width - self._scroll_width) * 0.5, self._height - 65 - self._scroll_height), size=(self._scroll_width, self._scroll_height), claims_left_right=True, claims_tab=True, selection_loops_to_parent=True) self._subcontainer: Optional[ba.Widget] = None self._refresh() self._restore_state()
def __init__(self, position: Tuple[float, float], data: Dict[str, Any], scale: float = None): from ba.deprecated import get_resource self._data = data uiscale = ba.app.ui.uiscale if scale is None: scale = (2.3 if uiscale is ba.UIScale.SMALL else 1.65 if uiscale is ba.UIScale.MEDIUM else 1.23) self._transitioning_out = False self._width = 300 self._height = 300 bg_color = (0.5, 0.4, 0.6) popup.PopupWindow.__init__(self, position=position, size=(self._width, self._height), scale=scale, bg_color=bg_color) self._cancel_button = ba.buttonwidget( parent=self.root_widget, position=(50, self._height - 30), size=(50, 50), scale=0.5, label='', color=bg_color, on_activate_call=self._on_cancel_press, autoselect=True, icon=ba.gettexture('crossOut'), iconscale=1.2) self._title_text = ba.textwidget(parent=self.root_widget, position=(self._width * 0.5, self._height - 20), size=(0, 0), h_align='center', v_align='center', scale=0.6, text=ba.Lstr(resource='trophiesText'), maxwidth=200, color=(1, 1, 1, 0.4)) self._scrollwidget = ba.scrollwidget(parent=self.root_widget, size=(self._width - 60, self._height - 70), position=(30, 30), capture_arrows=True) ba.widget(edit=self._scrollwidget, autoselect=True) ba.containerwidget(edit=self.root_widget, cancel_button=self._cancel_button) incr = 31 sub_width = self._width - 90 trophy_types = [['0a'], ['0b'], ['1'], ['2'], ['3'], ['4']] sub_height = 40 + len(trophy_types) * incr eq_text = get_resource('coopSelectWindow.powerRankingPointsEqualsText') self._subcontainer = ba.containerwidget(parent=self._scrollwidget, size=(sub_width, sub_height), background=False) total_pts = 0 multi_txt = get_resource('coopSelectWindow.powerRankingPointsMultText') total_pts += self._create_trophy_type_widgets(eq_text, incr, multi_txt, sub_height, sub_width, trophy_types) ba.textwidget(parent=self._subcontainer, position=(sub_width * 1.0, sub_height - 20 - incr * len(trophy_types)), maxwidth=sub_width * 0.5, scale=0.7, color=(0.7, 0.8, 1.0), flatness=1.0, shadow=0.0, text=get_resource('coopSelectWindow.totalText') + ' ' + eq_text.replace('${NUMBER}', str(total_pts)), size=(0, 0), h_align='right', v_align='center')
def __init__(self, editcontroller: PlaylistEditController, transition: str = 'in_right'): self._editcontroller = editcontroller self._r = 'addGameWindow' uiscale = ba.app.ui.uiscale self._width = 750 if uiscale is ba.UIScale.SMALL else 650 x_inset = 50 if uiscale is ba.UIScale.SMALL else 0 self._height = (346 if uiscale is ba.UIScale.SMALL else 380 if uiscale is ba.UIScale.MEDIUM else 440) top_extra = 30 if uiscale is ba.UIScale.SMALL else 20 self._scroll_width = 210 super().__init__(root_widget=ba.containerwidget( size=(self._width, self._height + top_extra), transition=transition, scale=(2.17 if uiscale is ba.UIScale.SMALL else 1.5 if uiscale is ba.UIScale.MEDIUM else 1.0), stack_offset=(0, 1) if uiscale is ba.UIScale.SMALL else (0, 0))) self._back_button = ba.buttonwidget(parent=self._root_widget, position=(58 + x_inset, self._height - 53), size=(165, 70), scale=0.75, text_scale=1.2, label=ba.Lstr(resource='backText'), autoselect=True, button_type='back', on_activate_call=self._back) self._select_button = select_button = ba.buttonwidget( parent=self._root_widget, position=(self._width - (172 + x_inset), self._height - 50), autoselect=True, size=(160, 60), scale=0.75, text_scale=1.2, label=ba.Lstr(resource='selectText'), on_activate_call=self._add) if ba.app.ui.use_toolbars: ba.widget(edit=select_button, right_widget=_ba.get_special_widget('party_button')) ba.textwidget(parent=self._root_widget, position=(self._width * 0.5, self._height - 28), size=(0, 0), scale=1.0, text=ba.Lstr(resource=self._r + '.titleText'), h_align='center', color=ba.app.ui.title_color, maxwidth=250, v_align='center') v = self._height - 64 self._selected_title_text = ba.textwidget( parent=self._root_widget, position=(x_inset + self._scroll_width + 50 + 30, v - 15), size=(0, 0), scale=1.0, color=(0.7, 1.0, 0.7, 1.0), maxwidth=self._width - self._scroll_width - 150 - x_inset * 2, h_align='left', v_align='center') v -= 30 self._selected_description_text = ba.textwidget( parent=self._root_widget, position=(x_inset + self._scroll_width + 50 + 30, v), size=(0, 0), scale=0.7, color=(0.5, 0.8, 0.5, 1.0), maxwidth=self._width - self._scroll_width - 150 - x_inset * 2, h_align='left') scroll_height = self._height - 100 v = self._height - 60 self._scrollwidget = ba.scrollwidget(parent=self._root_widget, position=(x_inset + 61, v - scroll_height), size=(self._scroll_width, scroll_height), highlight=False) ba.widget(edit=self._scrollwidget, up_widget=self._back_button, left_widget=self._back_button, right_widget=select_button) self._column: Optional[ba.Widget] = None v -= 35 ba.containerwidget(edit=self._root_widget, cancel_button=self._back_button, start_button=select_button) self._selected_game_type: Optional[type[ba.GameActivity]] = None ba.containerwidget(edit=self._root_widget, selected_child=self._scrollwidget) self._refresh()
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, parent_window: gpsui.GamepadSettingsWindow): # pylint: disable=too-many-statements self._parent_window = parent_window app = ba.app self._r = parent_window.get_r() uiscale = ba.app.ui.uiscale self._width = 900 if uiscale is ba.UIScale.SMALL else 700 self._x_inset = x_inset = 100 if uiscale is ba.UIScale.SMALL else 0 self._height = 402 if uiscale is ba.UIScale.SMALL else 512 self._textwidgets: dict[str, ba.Widget] = {} super().__init__(root_widget=ba.containerwidget( transition='in_scale', size=(self._width, self._height), scale=1.06 * (1.85 if uiscale is ba.UIScale.SMALL else 1.35 if uiscale is ba.UIScale.MEDIUM else 1.0), stack_offset=(0, -25) if uiscale is ba.UIScale.SMALL else (0, 0), scale_origin_stack_offset=(parent_window.get_advanced_button(). get_screen_space_center()))) ba.textwidget(parent=self._root_widget, position=(self._width * 0.5, self._height - (40 if uiscale is ba.UIScale.SMALL else 34)), size=(0, 0), text=ba.Lstr(resource=self._r + '.advancedTitleText'), maxwidth=320, color=ba.app.ui.title_color, h_align='center', v_align='center') back_button = btn = ba.buttonwidget( parent=self._root_widget, autoselect=True, position=(self._width - (176 + x_inset), self._height - (60 if uiscale is ba.UIScale.SMALL else 55)), size=(120, 48), text_scale=0.8, label=ba.Lstr(resource='doneText'), on_activate_call=self._done) ba.containerwidget(edit=self._root_widget, start_button=btn, on_cancel_call=btn.activate) self._scroll_width = self._width - (100 + 2 * x_inset) self._scroll_height = self._height - 110 self._sub_width = self._scroll_width - 20 self._sub_height = (940 if self._parent_window.get_is_secondary() else 1040) if app.vr_mode: self._sub_height += 50 self._scrollwidget = ba.scrollwidget( parent=self._root_widget, position=((self._width - self._scroll_width) * 0.5, self._height - 65 - self._scroll_height), size=(self._scroll_width, self._scroll_height), claims_left_right=True, claims_tab=True, selection_loops_to_parent=True) self._subcontainer = ba.containerwidget(parent=self._scrollwidget, size=(self._sub_width, self._sub_height), background=False, claims_left_right=True, claims_tab=True, selection_loops_to_parent=True) ba.containerwidget(edit=self._root_widget, selected_child=self._scrollwidget) h = 30 v = self._sub_height - 10 h2 = h + 12 # don't allow secondary joysticks to handle unassigned buttons if not self._parent_window.get_is_secondary(): v -= 40 cb1 = ba.checkboxwidget( parent=self._subcontainer, position=(h + 70, v), size=(500, 30), text=ba.Lstr(resource=self._r + '.unassignedButtonsRunText'), textcolor=(0.8, 0.8, 0.8), maxwidth=330, scale=1.0, on_value_change_call=self._parent_window. set_unassigned_buttons_run_value, autoselect=True, value=self._parent_window.get_unassigned_buttons_run_value()) ba.widget(edit=cb1, up_widget=back_button) v -= 60 capb = self._capture_button( pos=(h2, v), name=ba.Lstr(resource=self._r + '.runButton1Text'), control='buttonRun1' + self._parent_window.get_ext()) if self._parent_window.get_is_secondary(): for widget in capb: ba.widget(edit=widget, up_widget=back_button) v -= 42 self._capture_button( pos=(h2, v), name=ba.Lstr(resource=self._r + '.runButton2Text'), control='buttonRun2' + self._parent_window.get_ext()) ba.textwidget(parent=self._subcontainer, position=(self._sub_width * 0.5, v - 24), size=(0, 0), text=ba.Lstr(resource=self._r + '.runTriggerDescriptionText'), color=(0.7, 1, 0.7, 0.6), maxwidth=self._sub_width * 0.8, scale=0.7, h_align='center', v_align='center') v -= 85 self._capture_button( pos=(h2, v), name=ba.Lstr(resource=self._r + '.runTrigger1Text'), control='triggerRun1' + self._parent_window.get_ext(), message=ba.Lstr(resource=self._r + '.pressAnyAnalogTriggerText')) v -= 42 self._capture_button( pos=(h2, v), name=ba.Lstr(resource=self._r + '.runTrigger2Text'), control='triggerRun2' + self._parent_window.get_ext(), message=ba.Lstr(resource=self._r + '.pressAnyAnalogTriggerText')) # in vr mode, allow assigning a reset-view button if app.vr_mode: v -= 50 self._capture_button( pos=(h2, v), name=ba.Lstr(resource=self._r + '.vrReorientButtonText'), control='buttonVRReorient' + self._parent_window.get_ext()) v -= 60 self._capture_button( pos=(h2, v), name=ba.Lstr(resource=self._r + '.extraStartButtonText'), control='buttonStart2' + self._parent_window.get_ext()) v -= 60 self._capture_button( pos=(h2, v), name=ba.Lstr(resource=self._r + '.ignoredButton1Text'), control='buttonIgnored' + self._parent_window.get_ext()) v -= 42 self._capture_button( pos=(h2, v), name=ba.Lstr(resource=self._r + '.ignoredButton2Text'), control='buttonIgnored2' + self._parent_window.get_ext()) v -= 42 self._capture_button( pos=(h2, v), name=ba.Lstr(resource=self._r + '.ignoredButton3Text'), control='buttonIgnored3' + self._parent_window.get_ext()) v -= 42 self._capture_button( pos=(h2, v), name=ba.Lstr(resource=self._r + '.ignoredButton4Text'), control='buttonIgnored4' + self._parent_window.get_ext()) ba.textwidget(parent=self._subcontainer, position=(self._sub_width * 0.5, v - 14), size=(0, 0), text=ba.Lstr(resource=self._r + '.ignoredButtonDescriptionText'), color=(0.7, 1, 0.7, 0.6), scale=0.8, maxwidth=self._sub_width * 0.8, h_align='center', v_align='center') v -= 80 ba.checkboxwidget(parent=self._subcontainer, autoselect=True, position=(h + 50, v), size=(400, 30), text=ba.Lstr(resource=self._r + '.startButtonActivatesDefaultText'), textcolor=(0.8, 0.8, 0.8), maxwidth=450, scale=0.9, on_value_change_call=self._parent_window. set_start_button_activates_default_widget_value, value=self._parent_window. get_start_button_activates_default_widget_value()) ba.textwidget( parent=self._subcontainer, position=(self._sub_width * 0.5, v - 12), size=(0, 0), text=ba.Lstr(resource=self._r + '.startButtonActivatesDefaultDescriptionText'), color=(0.7, 1, 0.7, 0.6), maxwidth=self._sub_width * 0.8, scale=0.7, h_align='center', v_align='center') v -= 80 ba.checkboxwidget( parent=self._subcontainer, autoselect=True, position=(h + 50, v), size=(400, 30), text=ba.Lstr(resource=self._r + '.uiOnlyText'), textcolor=(0.8, 0.8, 0.8), maxwidth=450, scale=0.9, on_value_change_call=self._parent_window.set_ui_only_value, value=self._parent_window.get_ui_only_value()) ba.textwidget(parent=self._subcontainer, position=(self._sub_width * 0.5, v - 12), size=(0, 0), text=ba.Lstr(resource=self._r + '.uiOnlyDescriptionText'), color=(0.7, 1, 0.7, 0.6), maxwidth=self._sub_width * 0.8, scale=0.7, h_align='center', v_align='center') v -= 80 ba.checkboxwidget( parent=self._subcontainer, autoselect=True, position=(h + 50, v), size=(400, 30), text=ba.Lstr(resource=self._r + '.ignoreCompletelyText'), textcolor=(0.8, 0.8, 0.8), maxwidth=450, scale=0.9, on_value_change_call=self._parent_window. set_ignore_completely_value, value=self._parent_window.get_ignore_completely_value()) ba.textwidget(parent=self._subcontainer, position=(self._sub_width * 0.5, v - 12), size=(0, 0), text=ba.Lstr(resource=self._r + '.ignoreCompletelyDescriptionText'), color=(0.7, 1, 0.7, 0.6), maxwidth=self._sub_width * 0.8, scale=0.7, h_align='center', v_align='center') v -= 80 cb1 = ba.checkboxwidget( parent=self._subcontainer, autoselect=True, position=(h + 50, v), size=(400, 30), text=ba.Lstr(resource=self._r + '.autoRecalibrateText'), textcolor=(0.8, 0.8, 0.8), maxwidth=450, scale=0.9, on_value_change_call=self._parent_window. set_auto_recalibrate_analog_stick_value, value=self._parent_window.get_auto_recalibrate_analog_stick_value( )) ba.textwidget(parent=self._subcontainer, position=(self._sub_width * 0.5, v - 12), size=(0, 0), text=ba.Lstr(resource=self._r + '.autoRecalibrateDescriptionText'), color=(0.7, 1, 0.7, 0.6), maxwidth=self._sub_width * 0.8, scale=0.7, h_align='center', v_align='center') v -= 80 buttons = self._config_value_editor( ba.Lstr(resource=self._r + '.analogStickDeadZoneText'), control=('analogStickDeadZone' + self._parent_window.get_ext()), position=(h + 40, v), min_val=0, max_val=10.0, increment=0.1, x_offset=100) ba.widget(edit=buttons[0], left_widget=cb1, up_widget=cb1) ba.widget(edit=cb1, right_widget=buttons[0], down_widget=buttons[0]) ba.textwidget(parent=self._subcontainer, position=(self._sub_width * 0.5, v - 12), size=(0, 0), text=ba.Lstr(resource=self._r + '.analogStickDeadZoneDescriptionText'), color=(0.7, 1, 0.7, 0.6), maxwidth=self._sub_width * 0.8, scale=0.7, h_align='center', v_align='center') v -= 100 # child joysticks cant have child joysticks.. that's just # crazy talk if not self._parent_window.get_is_secondary(): ba.buttonwidget( parent=self._subcontainer, autoselect=True, label=ba.Lstr(resource=self._r + '.twoInOneSetupText'), position=(40, v), size=(self._sub_width - 80, 50), on_activate_call=self._parent_window.show_secondary_editor, up_widget=buttons[0]) # set a bigger bottom show-buffer for the widgets we just made # so we can see the text below them when navigating with # a gamepad for child in self._subcontainer.get_children(): ba.widget(edit=child, show_buffer_bottom=30, show_buffer_top=30)
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 _refresh(self, file_names: List[str], error: Optional[str]) -> None: # pylint: disable=too-many-statements # pylint: disable=too-many-branches # pylint: disable=too-many-locals if not self._root_widget: return scrollwidget_selected = (self._scrollwidget is None or self._root_widget.get_selected_child() == self._scrollwidget) in_top_folder = (self._path == self._base_path) hide_top_folder = in_top_folder and self._show_base_path is False if hide_top_folder: folder_name = '' elif self._path == '/': folder_name = '/' else: assert self._path is not None folder_name = os.path.basename(self._path) b_color = (0.6, 0.53, 0.63) b_color_disabled = (0.65, 0.65, 0.65) if len(self._recent_paths) < 2: ba.buttonwidget(edit=self._back_button, color=b_color_disabled, textcolor=(0.5, 0.5, 0.5)) else: ba.buttonwidget(edit=self._back_button, color=b_color, textcolor=(0.75, 0.7, 0.8)) max_str_width = 300.0 str_width = min( max_str_width, _ba.get_string_width(folder_name, suppress_warning=True)) ba.textwidget(edit=self._path_text, text=folder_name, maxwidth=max_str_width) ba.imagewidget(edit=self._folder_icon, position=(self._folder_center - str_width * 0.5 - 40, self._height - 117), opacity=0.0 if hide_top_folder else 1.0) if self._scrollwidget is not None: self._scrollwidget.delete() if self._use_folder_button is not None: self._use_folder_button.delete() ba.widget(edit=self._cancel_button, right_widget=self._back_button) self._scrollwidget = ba.scrollwidget( parent=self._root_widget, position=((self._width - self._scroll_width) * 0.5, self._height - self._scroll_height - 119), size=(self._scroll_width, self._scroll_height)) if scrollwidget_selected: ba.containerwidget(edit=self._root_widget, selected_child=self._scrollwidget) # show error case.. if error is not None: self._subcontainer = ba.containerwidget(parent=self._scrollwidget, size=(self._scroll_width, self._scroll_height), background=False) ba.textwidget(parent=self._subcontainer, color=(1, 1, 0, 1), text=error, maxwidth=self._scroll_width * 0.9, position=(self._scroll_width * 0.48, self._scroll_height * 0.57), size=(0, 0), h_align='center', v_align='center') else: file_names = [f for f in file_names if not f.startswith('.')] file_names.sort(key=lambda x: x[0].lower()) entries = file_names entry_height = 35 folder_entry_height = 100 show_folder_entry = False show_use_folder_button = (self._allow_folders and not in_top_folder) self._subcontainerheight = entry_height * len(entries) + ( folder_entry_height if show_folder_entry else 0) v = self._subcontainerheight - (folder_entry_height if show_folder_entry else 0) self._subcontainer = ba.containerwidget( parent=self._scrollwidget, size=(self._scroll_width, self._subcontainerheight), background=False) ba.containerwidget(edit=self._scrollwidget, claims_left_right=False, claims_tab=False) ba.containerwidget(edit=self._subcontainer, claims_left_right=False, claims_tab=False, selection_loops=False, print_list_exit_instructions=False) ba.widget(edit=self._subcontainer, up_widget=self._back_button) if show_use_folder_button: self._use_folder_button = btn = ba.buttonwidget( parent=self._root_widget, position=(self._width - self._button_width - 35 - self._x_inset, self._height - 67), size=(self._button_width, 50), label=ba.Lstr(resource=self._r + '.useThisFolderButtonText'), on_activate_call=self._on_folder_entry_activated) ba.widget(edit=btn, left_widget=self._cancel_button, down_widget=self._scrollwidget) ba.widget(edit=self._cancel_button, right_widget=btn) ba.containerwidget(edit=self._root_widget, start_button=btn) folder_icon_size = 35 for num, entry in enumerate(entries): cnt = ba.containerwidget( parent=self._subcontainer, position=(0, v - entry_height), size=(self._scroll_width, entry_height), root_selectable=True, background=False, click_activate=True, on_activate_call=ba.Call(self._on_entry_activated, entry)) if num == 0: ba.widget(edit=cnt, up_widget=self._back_button) is_valid_file_path = self._is_valid_file_path(entry) assert self._path is not None is_dir = os.path.isdir(self._path + '/' + entry) if is_dir: ba.imagewidget(parent=cnt, size=(folder_icon_size, folder_icon_size), position=(10, 0.5 * entry_height - folder_icon_size * 0.5), draw_controller=cnt, texture=self._folder_tex, color=self._folder_color) else: ba.imagewidget(parent=cnt, size=(folder_icon_size, folder_icon_size), position=(10, 0.5 * entry_height - folder_icon_size * 0.5), opacity=1.0 if is_valid_file_path else 0.5, draw_controller=cnt, texture=self._file_tex, color=self._file_color) ba.textwidget(parent=cnt, draw_controller=cnt, text=entry, h_align='left', v_align='center', position=(10 + folder_icon_size * 1.05, entry_height * 0.5), size=(0, 0), maxwidth=self._scroll_width * 0.93 - 50, color=(1, 1, 1, 1) if (is_valid_file_path or is_dir) else (0.5, 0.5, 0.5, 1)) v -= entry_height
def __init__(self, position: Tuple[float, float], scale: float = None): # pylint: disable=too-many-locals if scale is None: scale = (2.3 if ba.app.small_ui else 1.65 if ba.app.med_ui else 1.23) self._transitioning_out = False self._width = 450 self._height = (300 if ba.app.small_ui else 370 if ba.app.med_ui else 450) bg_color = (0.5, 0.4, 0.6) # creates our _root_widget popup.PopupWindow.__init__(self, position=position, size=(self._width, self._height), scale=scale, bg_color=bg_color) self._cancel_button = ba.buttonwidget( parent=self.root_widget, position=(50, self._height - 30), size=(50, 50), scale=0.5, label='', color=bg_color, on_activate_call=self._on_cancel_press, autoselect=True, icon=ba.gettexture('crossOut'), iconscale=1.2) achievements = ba.app.achievements num_complete = len([a for a in achievements if a.complete]) txt_final = ba.Lstr( resource='accountSettingsWindow.achievementProgressText', subs=[('${COUNT}', str(num_complete)), ('${TOTAL}', str(len(achievements)))]) self._title_text = ba.textwidget(parent=self.root_widget, position=(self._width * 0.5, self._height - 20), size=(0, 0), h_align='center', v_align='center', scale=0.6, text=txt_final, maxwidth=200, color=(1, 1, 1, 0.4)) self._scrollwidget = ba.scrollwidget(parent=self.root_widget, size=(self._width - 60, self._height - 70), position=(30, 30), capture_arrows=True, simple_culling_v=10) ba.widget(edit=self._scrollwidget, autoselect=True) ba.containerwidget(edit=self.root_widget, cancel_button=self._cancel_button) incr = 36 sub_width = self._width - 90 sub_height = 40 + len(achievements) * incr eq_rsrc = 'coopSelectWindow.powerRankingPointsEqualsText' pts_rsrc = 'coopSelectWindow.powerRankingPointsText' self._subcontainer = ba.containerwidget(parent=self._scrollwidget, size=(sub_width, sub_height), background=False) total_pts = 0 for i, ach in enumerate(achievements): complete = ach.complete ba.textwidget(parent=self._subcontainer, position=(sub_width * 0.08 - 5, sub_height - 20 - incr * i), maxwidth=20, scale=0.5, color=(0.6, 0.6, 0.7) if complete else (0.6, 0.6, 0.7, 0.2), flatness=1.0, shadow=0.0, text=str(i + 1), size=(0, 0), h_align='right', v_align='center') ba.imagewidget(parent=self._subcontainer, position=(sub_width * 0.10 + 1, sub_height - 20 - incr * i - 9) if complete else (sub_width * 0.10 - 4, sub_height - 20 - incr * i - 14), size=(18, 18) if complete else (27, 27), opacity=1.0 if complete else 0.3, color=ach.get_icon_color(complete)[:3], texture=ach.get_icon_texture(complete)) if complete: ba.imagewidget(parent=self._subcontainer, position=(sub_width * 0.10 - 4, sub_height - 25 - incr * i - 9), size=(28, 28), color=(2, 1.4, 0), texture=ba.gettexture('achievementOutline')) ba.textwidget(parent=self._subcontainer, position=(sub_width * 0.19, sub_height - 19 - incr * i + 3), maxwidth=sub_width * 0.62, scale=0.6, flatness=1.0, shadow=0.0, color=(1, 1, 1) if complete else (1, 1, 1, 0.2), text=ach.display_name, size=(0, 0), h_align='left', v_align='center') ba.textwidget(parent=self._subcontainer, position=(sub_width * 0.19, sub_height - 19 - incr * i - 10), maxwidth=sub_width * 0.62, scale=0.4, flatness=1.0, shadow=0.0, color=(0.83, 0.8, 0.85) if complete else (0.8, 0.8, 0.8, 0.2), text=ach.description_full_complete if complete else ach.description_full, size=(0, 0), h_align='left', v_align='center') pts = ach.power_ranking_value ba.textwidget(parent=self._subcontainer, position=(sub_width * 0.92, sub_height - 20 - incr * i), maxwidth=sub_width * 0.15, color=(0.7, 0.8, 1.0) if complete else (0.9, 0.9, 1.0, 0.3), flatness=1.0, shadow=0.0, scale=0.6, text=ba.Lstr(resource=pts_rsrc, subs=[('${NUMBER}', str(pts))]), size=(0, 0), h_align='center', v_align='center') if complete: total_pts += pts ba.textwidget(parent=self._subcontainer, position=(sub_width * 1.0, sub_height - 20 - incr * len(achievements)), maxwidth=sub_width * 0.5, scale=0.7, color=(0.7, 0.8, 1.0), flatness=1.0, shadow=0.0, text=ba.Lstr( value='${A} ${B}', subs=[ ('${A}', ba.Lstr(resource='coopSelectWindow.totalText')), ('${B}', ba.Lstr(resource=eq_rsrc, subs=[('${NUMBER}', str(total_pts))])) ]), size=(0, 0), h_align='right', v_align='center')
def __init__(self, transition: str = 'in_right', modal: bool = False, origin_widget: ba.Widget = None): from ba.internal import get_cached_league_rank_data from ba.deprecated import get_resource ba.set_analytics_screen('League Rank Window') self._league_rank_data: Optional[Dict[str, Any]] = None self._modal = modal # If they provided an origin-widget, scale up from that. scale_origin: Optional[Tuple[float, float]] if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() transition = 'in_scale' else: self._transition_out = 'out_right' scale_origin = None self._width = 1320 if ba.app.small_ui else 1120 x_inset = 100 if ba.app.small_ui else 0 self._height = (657 if ba.app.small_ui else 710 if ba.app.med_ui else 800) self._r = 'coopSelectWindow' self._rdict = get_resource(self._r) top_extra = 20 if ba.app.small_ui else 0 self._league_url_arg = '' self._is_current_season = False self._can_do_more_button = True super().__init__(root_widget=ba.containerwidget( size=(self._width, self._height + top_extra), stack_offset=(0, -15) if ba.app.small_ui else ( 0, 10) if ba.app.med_ui else (0, 0), transition=transition, scale_origin_stack_offset=scale_origin, scale=( 1.2 if ba.app.small_ui else 0.93 if ba.app.med_ui else 0.8))) self._back_button = btn = ba.buttonwidget( parent=self._root_widget, position=(75 + x_inset, self._height - 87 - (4 if ba.app.small_ui else 0)), size=(120, 60), scale=1.2, autoselect=True, label=ba.Lstr(resource='doneText' if self._modal else 'backText'), button_type=None if self._modal else 'back', on_activate_call=self._back) self._title_text = ba.textwidget( parent=self._root_widget, position=(self._width * 0.5, self._height - 56), size=(0, 0), text=ba.Lstr( resource='league.leagueRankText', fallback_resource='coopSelectWindow.powerRankingText'), h_align="center", color=ba.app.title_color, scale=1.4, maxwidth=600, v_align="center") ba.buttonwidget(edit=btn, button_type='backSmall', position=(75 + x_inset, self._height - 87 - (2 if ba.app.small_ui else 0)), size=(60, 55), label=ba.charstr(ba.SpecialChar.BACK)) self._scroll_width = self._width - (130 + 2 * x_inset) self._scroll_height = self._height - 160 self._scrollwidget = ba.scrollwidget(parent=self._root_widget, highlight=False, position=(65 + x_inset, 70), size=(self._scroll_width, self._scroll_height), center_small_content=True) ba.widget(edit=self._scrollwidget, autoselect=True) ba.containerwidget(edit=self._scrollwidget, claims_left_right=True) ba.containerwidget(edit=self._root_widget, cancel_button=self._back_button, selected_child=self._back_button) self._last_power_ranking_query_time: Optional[float] = None self._doing_power_ranking_query = False self._subcontainer: Optional[ba.Widget] = None self._subcontainerwidth = 800 self._subcontainerheight = 483 self._power_ranking_score_widgets: List[ba.Widget] = [] self._season_popup_menu: Optional[popup_ui.PopupMenu] = None self._requested_season: Optional[str] = None self._season: Optional[str] = None # take note of our account state; we'll refresh later if this changes self._account_state = _ba.get_account_state() self._refresh() self._restore_state() # if we've got cached power-ranking data already, display it info = get_cached_league_rank_data() if info is not None: self._update_for_league_rank_data(info) self._update_timer = ba.Timer(1.0, ba.WeakCall(self._update), timetype=ba.TimeType.REAL, repeat=True) self._update(show=(info is None))
def __init__(self, sessiontype: Type[ba.Session], transition: Optional[str] = 'in_right', origin_widget: ba.Widget = None): # pylint: disable=too-many-statements # pylint: disable=cyclic-import from bastd.ui.playlist import PlaylistTypeVars # If they provided an origin-widget, scale up from that. scale_origin: Optional[Tuple[float, float]] if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() transition = 'in_scale' else: self._transition_out = 'out_right' scale_origin = None # Store state for when we exit the next game. if issubclass(sessiontype, ba.DualTeamSession): ba.app.main_window = 'Team Game Select' ba.set_analytics_screen('Teams Window') elif issubclass(sessiontype, ba.FreeForAllSession): ba.app.main_window = 'Free-for-All Game Select' ba.set_analytics_screen('FreeForAll Window') else: raise TypeError(f'Invalid sessiontype: {sessiontype}.') self._pvars = PlaylistTypeVars(sessiontype) self._sessiontype = sessiontype self._customize_button: Optional[ba.Widget] = None self._sub_width: Optional[float] = None self._sub_height: Optional[float] = None # On new installations, go ahead and create a few playlists # besides the hard-coded default one: if not _ba.get_account_misc_val('madeStandardPlaylists', False): _ba.add_transaction({ 'type': 'ADD_PLAYLIST', 'playlistType': 'Free-for-All', 'playlistName': ba.Lstr( resource='singleGamePlaylistNameText').evaluate().replace( '${GAME}', ba.Lstr(translate=('gameNames', 'Death Match')).evaluate()), 'playlist': [ { 'type': 'bs_death_match.DeathMatchGame', 'settings': { 'Epic Mode': False, 'Kills to Win Per Player': 10, 'Respawn Times': 1.0, 'Time Limit': 300, 'map': 'Doom Shroom' } }, { 'type': 'bs_death_match.DeathMatchGame', 'settings': { 'Epic Mode': False, 'Kills to Win Per Player': 10, 'Respawn Times': 1.0, 'Time Limit': 300, 'map': 'Crag Castle' } }, ] }) _ba.add_transaction({ 'type': 'ADD_PLAYLIST', 'playlistType': 'Team Tournament', 'playlistName': ba.Lstr( resource='singleGamePlaylistNameText').evaluate().replace( '${GAME}', ba.Lstr(translate=('gameNames', 'Capture the Flag')).evaluate()), 'playlist': [ { 'type': 'bs_capture_the_flag.CTFGame', 'settings': { 'map': 'Bridgit', 'Score to Win': 3, 'Flag Idle Return Time': 30, 'Flag Touch Return Time': 0, 'Respawn Times': 1.0, 'Time Limit': 600, 'Epic Mode': False } }, { 'type': 'bs_capture_the_flag.CTFGame', 'settings': { 'map': 'Roundabout', 'Score to Win': 2, 'Flag Idle Return Time': 30, 'Flag Touch Return Time': 0, 'Respawn Times': 1.0, 'Time Limit': 600, 'Epic Mode': False } }, { 'type': 'bs_capture_the_flag.CTFGame', 'settings': { 'map': 'Tip Top', 'Score to Win': 2, 'Flag Idle Return Time': 30, 'Flag Touch Return Time': 3, 'Respawn Times': 1.0, 'Time Limit': 300, 'Epic Mode': False } }, ] }) _ba.add_transaction({ 'type': 'ADD_PLAYLIST', 'playlistType': 'Team Tournament', 'playlistName': ba.Lstr(translate=('playlistNames', 'Just Sports')).evaluate(), 'playlist': [ { 'type': 'bs_hockey.HockeyGame', 'settings': { 'Time Limit': 0, 'map': 'Hockey Stadium', 'Score to Win': 1, 'Respawn Times': 1.0 } }, { 'type': 'bs_football.FootballTeamGame', 'settings': { 'Time Limit': 0, 'map': 'Football Stadium', 'Score to Win': 21, 'Respawn Times': 1.0 } }, ] }) _ba.add_transaction({ 'type': 'ADD_PLAYLIST', 'playlistType': 'Free-for-All', 'playlistName': ba.Lstr(translate=('playlistNames', 'Just Epic')).evaluate(), 'playlist': [{ 'type': 'bs_elimination.EliminationGame', 'settings': { 'Time Limit': 120, 'map': 'Tip Top', 'Respawn Times': 1.0, 'Lives Per Player': 1, 'Epic Mode': 1 } }] }) _ba.add_transaction({ 'type': 'SET_MISC_VAL', 'name': 'madeStandardPlaylists', 'value': True }) _ba.run_transactions() # Get the current selection (if any). self._selected_playlist = ba.app.config.get(self._pvars.config_name + ' Playlist Selection') uiscale = ba.app.uiscale self._width = 900 if uiscale is ba.UIScale.SMALL else 800 x_inset = 50 if uiscale is ba.UIScale.SMALL else 0 self._height = (480 if uiscale is ba.UIScale.SMALL else 510 if uiscale is ba.UIScale.MEDIUM else 580) top_extra = 20 if uiscale is ba.UIScale.SMALL else 0 super().__init__(root_widget=ba.containerwidget( size=(self._width, self._height + top_extra), transition=transition, toolbar_visibility='menu_full', scale_origin_stack_offset=scale_origin, scale=(1.69 if uiscale is ba.UIScale.SMALL else 1.05 if uiscale is ba.UIScale.MEDIUM else 0.9), stack_offset=(0, -26) if uiscale is ba.UIScale.SMALL else (0, 0))) self._back_button: Optional[ba.Widget] = ba.buttonwidget( parent=self._root_widget, position=(59 + x_inset, self._height - 70), size=(120, 60), scale=1.0, on_activate_call=self._on_back_press, autoselect=True, label=ba.Lstr(resource='backText'), button_type='back') ba.containerwidget(edit=self._root_widget, cancel_button=self._back_button) txt = self._title_text = ba.textwidget( parent=self._root_widget, position=(self._width * 0.5, self._height - 41), size=(0, 0), text=self._pvars.window_title_name, scale=1.3, res_scale=1.5, color=ba.app.heading_color, h_align='center', v_align='center') if uiscale is ba.UIScale.SMALL and ba.app.toolbars: ba.textwidget(edit=txt, text='') ba.buttonwidget(edit=self._back_button, button_type='backSmall', size=(60, 54), position=(59 + x_inset, self._height - 67), label=ba.charstr(ba.SpecialChar.BACK)) if uiscale is ba.UIScale.SMALL and ba.app.toolbars: self._back_button.delete() self._back_button = None ba.containerwidget(edit=self._root_widget, on_cancel_call=self._on_back_press) scroll_offs = 33 else: scroll_offs = 0 self._scroll_width = self._width - (100 + 2 * x_inset) self._scroll_height = self._height - ( 146 if uiscale is ba.UIScale.SMALL and ba.app.toolbars else 136) self._scrollwidget = ba.scrollwidget( parent=self._root_widget, highlight=False, size=(self._scroll_width, self._scroll_height), position=((self._width - self._scroll_width) * 0.5, 65 + scroll_offs)) ba.containerwidget(edit=self._scrollwidget, claims_left_right=True) self._subcontainer: Optional[ba.Widget] = None self._config_name_full = self._pvars.config_name + ' Playlists' self._last_config = None # Update now and once per second. # (this should do our initial refresh) self._update() self._update_timer = ba.Timer(1.0, ba.WeakCall(self._update), timetype=ba.TimeType.REAL, repeat=True)
def __init__(self, main_menu: bool = False, origin_widget: ba.Widget = None): # pylint: disable=too-many-statements # pylint: disable=too-many-locals from ba.internal import get_remote_app_name from ba.deprecated import get_resource ba.set_analytics_screen('Help Window') # If they provided an origin-widget, scale up from that. scale_origin: Optional[Tuple[float, float]] if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() transition = 'in_scale' else: self._transition_out = 'out_right' scale_origin = None transition = 'in_right' self._r = 'helpWindow' self._main_menu = main_menu width = 950 if ba.app.small_ui else 750 x_offs = 100 if ba.app.small_ui else 0 height = 460 if ba.app.small_ui else 530 if ba.app.med_ui else 600 super().__init__(root_widget=ba.containerwidget( size=(width, height), transition=transition, toolbar_visibility='menu_minimal', scale_origin_stack_offset=scale_origin, scale=( 1.77 if ba.app.small_ui else 1.25 if ba.app.med_ui else 1.0), stack_offset=(0, -30) if ba.app.small_ui else ( 0, 15) if ba.app.med_ui else (0, 0))) ba.textwidget(parent=self._root_widget, position=(0, height - (50 if ba.app.small_ui else 45)), size=(width, 25), text=ba.Lstr(resource=self._r + '.titleText', subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))]), color=ba.app.title_color, h_align='center', v_align='top') self._scrollwidget = ba.scrollwidget( parent=self._root_widget, position=(44 + x_offs, 55 if ba.app.small_ui else 55), simple_culling_v=100.0, size=(width - (88 + 2 * x_offs), height - 120 + (5 if ba.app.small_ui else 0)), capture_arrows=True) if ba.app.toolbars: ba.widget(edit=self._scrollwidget, right_widget=_ba.get_special_widget('party_button')) ba.containerwidget(edit=self._root_widget, selected_child=self._scrollwidget) # ugly: create this last so it gets first dibs at touch events (since # we have it close to the scroll widget) if ba.app.small_ui and ba.app.toolbars: ba.containerwidget(edit=self._root_widget, on_cancel_call=self._close) ba.widget(edit=self._scrollwidget, left_widget=_ba.get_special_widget('back_button')) else: btn = ba.buttonwidget( parent=self._root_widget, position=(x_offs + (40 + 0 if ba.app.small_ui else 70), height - (59 if ba.app.small_ui else 50)), size=(140, 60), scale=0.7 if ba.app.small_ui else 0.8, label=ba.Lstr( resource='backText') if self._main_menu else 'Close', button_type='back' if self._main_menu else None, extra_touch_border_scale=2.0, autoselect=True, on_activate_call=self._close) ba.containerwidget(edit=self._root_widget, cancel_button=btn) if self._main_menu: ba.buttonwidget(edit=btn, button_type='backSmall', size=(60, 55), label=ba.charstr(ba.SpecialChar.BACK)) # interface_type = ba.app.interface_type self._sub_width = 660 self._sub_height = 1590 + get_resource( self._r + '.someDaysExtraSpace') + get_resource( self._r + '.orPunchingSomethingExtraSpace') self._subcontainer = ba.containerwidget(parent=self._scrollwidget, size=(self._sub_width, self._sub_height), background=False, claims_left_right=False, claims_tab=False) spacing = 1.0 h = self._sub_width * 0.5 v = self._sub_height - 55 logo_tex = ba.gettexture('logo') icon_buffer = 1.1 header = (0.7, 1.0, 0.7, 1.0) header2 = (0.8, 0.8, 1.0, 1.0) paragraph = (0.8, 0.8, 1.0, 1.0) txt = ba.Lstr(resource=self._r + '.welcomeText', subs=[('${APP_NAME}', ba.Lstr(resource='titleText')) ]).evaluate() txt_scale = 1.4 txt_maxwidth = 480 ba.textwidget(parent=self._subcontainer, position=(h, v), size=(0, 0), scale=txt_scale, flatness=0.5, res_scale=1.5, text=txt, h_align='center', color=header, v_align='center', maxwidth=txt_maxwidth) txt_width = min( txt_maxwidth, _ba.get_string_width(txt, suppress_warning=True) * txt_scale) icon_size = 70 hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer) ba.imagewidget(parent=self._subcontainer, size=(icon_size, icon_size), position=(hval2 - 0.5 * icon_size, v - 0.45 * icon_size), texture=logo_tex) force_test = False app = ba.app if (app.platform == 'android' and app.subplatform == 'alibaba') or force_test: v -= 120.0 txtv = ( '\xe8\xbf\x99\xe6\x98\xaf\xe4\xb8\x80\xe4\xb8\xaa\xe5\x8f\xaf' '\xe4\xbb\xa5\xe5\x92\x8c\xe5\xae\xb6\xe4\xba\xba\xe6\x9c\x8b' '\xe5\x8f\x8b\xe4\xb8\x80\xe8\xb5\xb7\xe7\x8e\xa9\xe7\x9a\x84' '\xe6\xb8\xb8\xe6\x88\x8f,\xe5\x90\x8c\xe6\x97\xb6\xe6\x94\xaf' '\xe6\x8c\x81\xe8\x81\x94 \xe2\x80\xa8\xe7\xbd\x91\xe5\xaf\xb9' '\xe6\x88\x98\xe3\x80\x82\n' '\xe5\xa6\x82\xe6\xb2\xa1\xe6\x9c\x89\xe6\xb8\xb8\xe6\x88\x8f' '\xe6\x89\x8b\xe6\x9f\x84,\xe5\x8f\xaf\xe4\xbb\xa5\xe4\xbd\xbf' '\xe7\x94\xa8\xe7\xa7\xbb\xe5\x8a\xa8\xe8\xae\xbe\xe5\xa4\x87' '\xe6\x89\xab\xe7\xa0\x81\xe4\xb8\x8b\xe8\xbd\xbd\xe2\x80\x9c' '\xe9\x98\xbf\xe9\x87\x8c\xc2' '\xa0TV\xc2\xa0\xe5\x8a\xa9\xe6\x89' '\x8b\xe2\x80\x9d\xe7\x94\xa8 \xe6\x9d\xa5\xe4\xbb\xa3\xe6\x9b' '\xbf\xe5\xa4\x96\xe8\xae\xbe\xe3\x80\x82\n' '\xe6\x9c\x80\xe5\xa4\x9a\xe6\x94\xaf\xe6\x8c\x81\xe6\x8e\xa5' '\xe5\x85\xa5\xc2\xa08\xc2\xa0\xe4\xb8\xaa\xe5\xa4\x96\xe8' '\xae\xbe') ba.textwidget(parent=self._subcontainer, size=(0, 0), h_align='center', v_align='center', maxwidth=self._sub_width * 0.9, position=(self._sub_width * 0.5, v - 180), text=txtv) ba.imagewidget(parent=self._subcontainer, position=(self._sub_width - 320, v - 120), size=(200, 200), texture=ba.gettexture('aliControllerQR')) ba.imagewidget(parent=self._subcontainer, position=(90, v - 130), size=(210, 210), texture=ba.gettexture('multiplayerExamples')) v -= 120.0 else: v -= spacing * 50.0 txt = ba.Lstr(resource=self._r + '.someDaysText').evaluate() ba.textwidget(parent=self._subcontainer, position=(h, v), size=(0, 0), scale=1.2, maxwidth=self._sub_width * 0.9, text=txt, h_align='center', color=paragraph, v_align='center', flatness=1.0) v -= (spacing * 25.0 + get_resource(self._r + '.someDaysExtraSpace')) txt_scale = 0.66 txt = ba.Lstr(resource=self._r + '.orPunchingSomethingText').evaluate() ba.textwidget(parent=self._subcontainer, position=(h, v), size=(0, 0), scale=txt_scale, maxwidth=self._sub_width * 0.9, text=txt, h_align='center', color=paragraph, v_align='center', flatness=1.0) v -= (spacing * 27.0 + get_resource(self._r + '.orPunchingSomethingExtraSpace')) txt_scale = 1.0 txt = ba.Lstr(resource=self._r + '.canHelpText', subs=[('${APP_NAME}', ba.Lstr(resource='titleText')) ]).evaluate() ba.textwidget(parent=self._subcontainer, position=(h, v), size=(0, 0), scale=txt_scale, flatness=1.0, text=txt, h_align='center', color=paragraph, v_align='center') v -= spacing * 70.0 txt_scale = 1.0 txt = ba.Lstr(resource=self._r + '.toGetTheMostText').evaluate() ba.textwidget(parent=self._subcontainer, position=(h, v), size=(0, 0), scale=txt_scale, maxwidth=self._sub_width * 0.9, text=txt, h_align='center', color=header, v_align='center', flatness=1.0) v -= spacing * 40.0 txt_scale = 0.74 txt = ba.Lstr(resource=self._r + '.friendsText').evaluate() hval2 = h - 220 ba.textwidget(parent=self._subcontainer, position=(hval2, v), size=(0, 0), scale=txt_scale, maxwidth=100, text=txt, h_align='right', color=header, v_align='center', flatness=1.0) txt = ba.Lstr(resource=self._r + '.friendsGoodText', subs=[('${APP_NAME}', ba.Lstr(resource='titleText')) ]).evaluate() txt_scale = 0.7 ba.textwidget(parent=self._subcontainer, position=(hval2 + 10, v + 8), size=(0, 0), scale=txt_scale, maxwidth=500, text=txt, h_align='left', color=paragraph, flatness=1.0) app = ba.app v -= spacing * 45.0 txt = (ba.Lstr(resource=self._r + '.devicesText').evaluate() if app.vr_mode else ba.Lstr(resource=self._r + '.controllersText').evaluate()) txt_scale = 0.74 hval2 = h - 220 ba.textwidget(parent=self._subcontainer, position=(hval2, v), size=(0, 0), scale=txt_scale, maxwidth=100, text=txt, h_align='right', color=header, v_align='center', flatness=1.0) txt_scale = 0.7 if not app.vr_mode: txt = ba.Lstr(resource=self._r + '.controllersInfoText', subs=[('${APP_NAME}', ba.Lstr(resource='titleText')), ('${REMOTE_APP_NAME}', get_remote_app_name())]).evaluate() else: txt = ba.Lstr(resource=self._r + '.devicesInfoText', subs=[('${APP_NAME}', ba.Lstr(resource='titleText')) ]).evaluate() ba.textwidget(parent=self._subcontainer, position=(hval2 + 10, v + 8), size=(0, 0), scale=txt_scale, maxwidth=500, max_height=105, text=txt, h_align='left', color=paragraph, flatness=1.0) v -= spacing * 150.0 txt = ba.Lstr(resource=self._r + '.controlsText').evaluate() txt_scale = 1.4 txt_maxwidth = 480 ba.textwidget(parent=self._subcontainer, position=(h, v), size=(0, 0), scale=txt_scale, flatness=0.5, text=txt, h_align='center', color=header, v_align='center', res_scale=1.5, maxwidth=txt_maxwidth) txt_width = min( txt_maxwidth, _ba.get_string_width(txt, suppress_warning=True) * txt_scale) icon_size = 70 hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer) ba.imagewidget(parent=self._subcontainer, size=(icon_size, icon_size), position=(hval2 - 0.5 * icon_size, v - 0.45 * icon_size), texture=logo_tex) v -= spacing * 45.0 txt_scale = 0.7 txt = ba.Lstr(resource=self._r + '.controlsSubtitleText', subs=[('${APP_NAME}', ba.Lstr(resource='titleText')) ]).evaluate() ba.textwidget(parent=self._subcontainer, position=(h, v), size=(0, 0), scale=txt_scale, maxwidth=self._sub_width * 0.9, flatness=1.0, text=txt, h_align='center', color=paragraph, v_align='center') v -= spacing * 160.0 sep = 70 icon_size = 100 # icon_size_2 = 30 hval2 = h - sep vval2 = v ba.imagewidget(parent=self._subcontainer, size=(icon_size, icon_size), position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size), texture=ba.gettexture('buttonPunch'), color=(1, 0.7, 0.3)) txt_scale = get_resource(self._r + '.punchInfoTextScale') txt = ba.Lstr(resource=self._r + '.punchInfoText').evaluate() ba.textwidget(parent=self._subcontainer, position=(h - sep - 185 + 70, v + 120), size=(0, 0), scale=txt_scale, flatness=1.0, text=txt, h_align='center', color=(1, 0.7, 0.3, 1.0), v_align='top') hval2 = h + sep vval2 = v ba.imagewidget(parent=self._subcontainer, size=(icon_size, icon_size), position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size), texture=ba.gettexture('buttonBomb'), color=(1, 0.3, 0.3)) txt = ba.Lstr(resource=self._r + '.bombInfoText').evaluate() txt_scale = get_resource(self._r + '.bombInfoTextScale') ba.textwidget(parent=self._subcontainer, position=(h + sep + 50 + 60, v - 35), size=(0, 0), scale=txt_scale, flatness=1.0, maxwidth=270, text=txt, h_align='center', color=(1, 0.3, 0.3, 1.0), v_align='top') hval2 = h vval2 = v + sep ba.imagewidget(parent=self._subcontainer, size=(icon_size, icon_size), position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size), texture=ba.gettexture('buttonPickUp'), color=(0.5, 0.5, 1)) txtl = ba.Lstr(resource=self._r + '.pickUpInfoText') txt_scale = get_resource(self._r + '.pickUpInfoTextScale') ba.textwidget(parent=self._subcontainer, position=(h + 60 + 120, v + sep + 50), size=(0, 0), scale=txt_scale, flatness=1.0, text=txtl, h_align='center', color=(0.5, 0.5, 1, 1.0), v_align='top') hval2 = h vval2 = v - sep ba.imagewidget(parent=self._subcontainer, size=(icon_size, icon_size), position=(hval2 - 0.5 * icon_size, vval2 - 0.5 * icon_size), texture=ba.gettexture('buttonJump'), color=(0.4, 1, 0.4)) txt = ba.Lstr(resource=self._r + '.jumpInfoText').evaluate() txt_scale = get_resource(self._r + '.jumpInfoTextScale') ba.textwidget(parent=self._subcontainer, position=(h - 250 + 75, v - sep - 15 + 30), size=(0, 0), scale=txt_scale, flatness=1.0, text=txt, h_align='center', color=(0.4, 1, 0.4, 1.0), v_align='top') txt = ba.Lstr(resource=self._r + '.runInfoText').evaluate() txt_scale = get_resource(self._r + '.runInfoTextScale') ba.textwidget(parent=self._subcontainer, position=(h, v - sep - 100), size=(0, 0), scale=txt_scale, maxwidth=self._sub_width * 0.93, flatness=1.0, text=txt, h_align='center', color=(0.7, 0.7, 1.0, 1.0), v_align='center') v -= spacing * 280.0 txt = ba.Lstr(resource=self._r + '.powerupsText').evaluate() txt_scale = 1.4 txt_maxwidth = 480 ba.textwidget(parent=self._subcontainer, position=(h, v), size=(0, 0), scale=txt_scale, flatness=0.5, text=txt, h_align='center', color=header, v_align='center', maxwidth=txt_maxwidth) txt_width = min( txt_maxwidth, _ba.get_string_width(txt, suppress_warning=True) * txt_scale) icon_size = 70 hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer) ba.imagewidget(parent=self._subcontainer, size=(icon_size, icon_size), position=(hval2 - 0.5 * icon_size, v - 0.45 * icon_size), texture=logo_tex) v -= spacing * 50.0 txt_scale = get_resource(self._r + '.powerupsSubtitleTextScale') txt = ba.Lstr(resource=self._r + '.powerupsSubtitleText').evaluate() ba.textwidget(parent=self._subcontainer, position=(h, v), size=(0, 0), scale=txt_scale, maxwidth=self._sub_width * 0.9, text=txt, h_align='center', color=paragraph, v_align='center', flatness=1.0) v -= spacing * 1.0 mm1 = -270 mm2 = -215 mm3 = 0 icon_size = 50 shadow_size = 80 shadow_offs_x = 3 shadow_offs_y = -4 t_big = 1.1 t_small = 0.65 shadow_tex = ba.gettexture('shadowSharp') for tex in [ 'powerupPunch', 'powerupShield', 'powerupBomb', 'powerupHealth', 'powerupIceBombs', 'powerupImpactBombs', 'powerupStickyBombs', 'powerupLandMines', 'powerupCurse' ]: name = ba.Lstr(resource=self._r + '.' + tex + 'NameText') desc = ba.Lstr(resource=self._r + '.' + tex + 'DescriptionText') v -= spacing * 60.0 ba.imagewidget( parent=self._subcontainer, size=(shadow_size, shadow_size), position=(h + mm1 + shadow_offs_x - 0.5 * shadow_size, v + shadow_offs_y - 0.5 * shadow_size), texture=shadow_tex, color=(0, 0, 0), opacity=0.5) ba.imagewidget(parent=self._subcontainer, size=(icon_size, icon_size), position=(h + mm1 - 0.5 * icon_size, v - 0.5 * icon_size), texture=ba.gettexture(tex)) txt_scale = t_big txtl = name ba.textwidget(parent=self._subcontainer, position=(h + mm2, v + 3), size=(0, 0), scale=txt_scale, maxwidth=200, flatness=1.0, text=txtl, h_align='left', color=header2, v_align='center') txt_scale = t_small txtl = desc ba.textwidget(parent=self._subcontainer, position=(h + mm3, v), size=(0, 0), scale=txt_scale, maxwidth=300, flatness=1.0, text=txtl, h_align='left', color=paragraph, v_align='center', res_scale=0.5)
def _build_join_tab(self, region_width: float, region_height: float) -> None: c_width = region_width c_height = region_height - 20 sub_scroll_height = c_height - 125 sub_scroll_width = 830 v = c_height - 35 v -= 60 filter_txt = ba.Lstr(resource='filterText') self._filter_text = ba.textwidget(parent=self._container, text=self._filter_value, size=(350, 45), position=(290, v - 10), h_align='left', v_align='center', editable=True, description=filter_txt) ba.widget(edit=self._filter_text, up_widget=self._join_text) ba.textwidget(text=filter_txt, parent=self._container, size=(0, 0), position=(270, v + 13), maxwidth=150, scale=0.8, color=(0.5, 0.5, 0.5), flatness=1.0, shadow=0.0, h_align='right', v_align='center') ba.textwidget(text=ba.Lstr(resource='nameText'), parent=self._container, size=(0, 0), position=(90, v - 8), maxwidth=60, scale=0.6, color=(0.5, 0.5, 0.5), flatness=1.0, shadow=0.0, h_align='center', v_align='center') ba.textwidget(text=ba.Lstr(resource='gatherWindow.partySizeText'), parent=self._container, size=(0, 0), position=(755, v - 8), maxwidth=60, scale=0.6, color=(0.5, 0.5, 0.5), flatness=1.0, shadow=0.0, h_align='center', v_align='center') ba.textwidget(text=ba.Lstr(resource='gatherWindow.pingText'), parent=self._container, size=(0, 0), position=(825, v - 8), maxwidth=60, scale=0.6, color=(0.5, 0.5, 0.5), flatness=1.0, shadow=0.0, h_align='center', v_align='center') v -= sub_scroll_height + 23 self._host_scrollwidget = scrollw = ba.scrollwidget( parent=self._container, simple_culling_v=10, position=((c_width - sub_scroll_width) * 0.5, v), size=(sub_scroll_width, sub_scroll_height), claims_up_down=False, claims_left_right=True, autoselect=True) self._join_list_column = ba.containerwidget(parent=scrollw, background=False, size=(400, 400), claims_left_right=True) self._join_status_text = ba.textwidget(parent=self._container, text='', size=(0, 0), scale=0.9, flatness=1.0, shadow=0.0, h_align='center', v_align='top', maxwidth=c_width, color=(0.6, 0.6, 0.6), position=(c_width * 0.5, c_height * 0.5))
def __init__(self, account_id: str, profile_id: str = None, position: Tuple[float, float] = (0.0, 0.0), scale: float = None, offset: Tuple[float, float] = (0.0, 0.0)): from ba.internal import is_browser_likely_available, master_server_get self._account_id = account_id self._profile_id = profile_id uiscale = ba.app.uiscale if scale is None: scale = (2.6 if uiscale is ba.UIScale.SMALL else 1.8 if uiscale is ba.UIScale.MEDIUM else 1.4) self._transitioning_out = False self._width = 400 self._height = (300 if uiscale is ba.UIScale.SMALL else 400 if uiscale is ba.UIScale.MEDIUM else 450) self._subcontainer: Optional[ba.Widget] = None bg_color = (0.5, 0.4, 0.6) # Creates our _root_widget. popup.PopupWindow.__init__(self, position=position, size=(self._width, self._height), scale=scale, bg_color=bg_color, offset=offset) self._cancel_button = ba.buttonwidget( parent=self.root_widget, position=(50, self._height - 30), size=(50, 50), scale=0.5, label='', color=bg_color, on_activate_call=self._on_cancel_press, autoselect=True, icon=ba.gettexture('crossOut'), iconscale=1.2) self._title_text = ba.textwidget( parent=self.root_widget, position=(self._width * 0.5, self._height - 20), size=(0, 0), h_align='center', v_align='center', scale=0.6, text=ba.Lstr(resource='playerInfoText'), maxwidth=200, color=(0.7, 0.7, 0.7, 0.7)) self._scrollwidget = ba.scrollwidget(parent=self.root_widget, size=(self._width - 60, self._height - 70), position=(30, 30), capture_arrows=True, simple_culling_v=10) ba.widget(edit=self._scrollwidget, autoselect=True) self._loading_text = ba.textwidget( parent=self._scrollwidget, scale=0.5, text=ba.Lstr(value='${A}...', subs=[('${A}', ba.Lstr(resource='loadingText'))]), size=(self._width - 60, 100), h_align='center', v_align='center') # In cases where the user most likely has a browser/email, lets # offer a 'report this user' button. if (is_browser_likely_available() and _ba.get_account_misc_read_val( 'showAccountExtrasMenu', False)): self._extras_menu_button = ba.buttonwidget( parent=self.root_widget, size=(20, 20), position=(self._width - 60, self._height - 30), autoselect=True, label='...', button_type='square', color=(0.64, 0.52, 0.69), textcolor=(0.57, 0.47, 0.57), on_activate_call=self._on_extras_menu_press) ba.containerwidget(edit=self.root_widget, cancel_button=self._cancel_button) master_server_get('bsAccountInfo', { 'buildNumber': ba.app.build_number, 'accountID': self._account_id, 'profileID': self._profile_id }, callback=ba.WeakCall(self._on_query_response))
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 __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 __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'): # pylint: disable=too-many-statements # pylint: disable=cyclic-import from bastd.ui import popup uiscale = ba.app.ui.uiscale self._width = width = 580 self._height = height = (350 if uiscale is ba.UIScale.SMALL else 420 if uiscale is ba.UIScale.MEDIUM else 520) self._scroll_width = self._width - 100 self._scroll_height = self._height - 120 self._sub_width = self._scroll_width * 0.95 self._sub_height = 520 self._stress_test_game_type = 'Random' self._stress_test_playlist = '__default__' self._stress_test_player_count = 8 self._stress_test_round_duration = 30 self._r = 'debugWindow' uiscale = ba.app.ui.uiscale super().__init__(root_widget=ba.containerwidget( size=(width, height), transition=transition, scale=(2.35 if uiscale is ba.UIScale.SMALL else 1.55 if uiscale is ba.UIScale.MEDIUM else 1.0), stack_offset=(0, -30) if uiscale is ba.UIScale.SMALL else (0, 0))) self._done_button = btn = ba.buttonwidget( parent=self._root_widget, position=(40, height - 67), size=(120, 60), scale=0.8, autoselect=True, label=ba.Lstr(resource='doneText'), on_activate_call=self._done) ba.containerwidget(edit=self._root_widget, cancel_button=btn) ba.textwidget(parent=self._root_widget, position=(0, height - 60), size=(width, 30), text=ba.Lstr(resource=self._r + '.titleText'), h_align='center', color=ba.app.ui.title_color, v_align='center', maxwidth=260) self._scrollwidget = ba.scrollwidget( parent=self._root_widget, highlight=False, size=(self._scroll_width, self._scroll_height), position=((self._width - self._scroll_width) * 0.5, 50)) ba.containerwidget(edit=self._scrollwidget, claims_left_right=True) self._subcontainer = ba.containerwidget(parent=self._scrollwidget, size=(self._sub_width, self._sub_height), background=False) v = self._sub_height - 70 button_width = 300 btn = ba.buttonwidget( parent=self._subcontainer, position=((self._sub_width - button_width) * 0.5, v), size=(button_width, 60), autoselect=True, label=ba.Lstr(resource=self._r + '.runCPUBenchmarkText'), on_activate_call=self._run_cpu_benchmark_pressed) ba.widget(edit=btn, up_widget=self._done_button, left_widget=self._done_button) v -= 60 ba.buttonwidget(parent=self._subcontainer, position=((self._sub_width - button_width) * 0.5, v), size=(button_width, 60), autoselect=True, label=ba.Lstr(resource=self._r + '.runGPUBenchmarkText'), on_activate_call=self._run_gpu_benchmark_pressed) v -= 60 ba.buttonwidget( parent=self._subcontainer, position=((self._sub_width - button_width) * 0.5, v), size=(button_width, 60), autoselect=True, label=ba.Lstr(resource=self._r + '.runMediaReloadBenchmarkText'), on_activate_call=self._run_media_reload_benchmark_pressed) v -= 60 ba.textwidget(parent=self._subcontainer, position=(self._sub_width * 0.5, v + 22), size=(0, 0), text=ba.Lstr(resource=self._r + '.stressTestTitleText'), maxwidth=200, color=ba.app.ui.heading_color, scale=0.85, h_align='center', v_align='center') v -= 45 x_offs = 165 ba.textwidget(parent=self._subcontainer, position=(x_offs - 10, v + 22), size=(0, 0), text=ba.Lstr(resource=self._r + '.stressTestPlaylistTypeText'), maxwidth=130, color=ba.app.ui.heading_color, scale=0.65, h_align='right', v_align='center') popup.PopupMenu( parent=self._subcontainer, position=(x_offs, v), width=150, choices=['Random', 'Teams', 'Free-For-All'], choices_display=[ ba.Lstr(resource=a) for a in [ 'randomText', 'playModes.teamsText', 'playModes.freeForAllText' ] ], current_choice='Auto', on_value_change_call=self._stress_test_game_type_selected) v -= 46 ba.textwidget(parent=self._subcontainer, position=(x_offs - 10, v + 22), size=(0, 0), text=ba.Lstr(resource=self._r + '.stressTestPlaylistNameText'), maxwidth=130, color=ba.app.ui.heading_color, scale=0.65, h_align='right', v_align='center') self._stress_test_playlist_name_field = ba.textwidget( parent=self._subcontainer, position=(x_offs + 5, v - 5), size=(250, 46), text=self._stress_test_playlist, h_align='left', v_align='center', autoselect=True, color=(0.9, 0.9, 0.9, 1.0), description=ba.Lstr(resource=self._r + '.stressTestPlaylistDescriptionText'), editable=True, padding=4) v -= 29 x_sub = 60 # Player count. ba.textwidget(parent=self._subcontainer, position=(x_offs - 10, v), size=(0, 0), text=ba.Lstr(resource=self._r + '.stressTestPlayerCountText'), color=(0.8, 0.8, 0.8, 1.0), h_align='right', v_align='center', scale=0.65, maxwidth=130) self._stress_test_player_count_text = ba.textwidget( parent=self._subcontainer, position=(246 - x_sub, v - 14), size=(60, 28), editable=False, color=(0.3, 1.0, 0.3, 1.0), h_align='right', v_align='center', text=str(self._stress_test_player_count), padding=2) ba.buttonwidget(parent=self._subcontainer, position=(330 - x_sub, v - 11), size=(28, 28), label='-', autoselect=True, on_activate_call=ba.Call( self._stress_test_player_count_decrement), repeat=True, enable_sound=True) ba.buttonwidget(parent=self._subcontainer, position=(380 - x_sub, v - 11), size=(28, 28), label='+', autoselect=True, on_activate_call=ba.Call( self._stress_test_player_count_increment), repeat=True, enable_sound=True) v -= 42 # Round duration. ba.textwidget(parent=self._subcontainer, position=(x_offs - 10, v), size=(0, 0), text=ba.Lstr(resource=self._r + '.stressTestRoundDurationText'), color=(0.8, 0.8, 0.8, 1.0), h_align='right', v_align='center', scale=0.65, maxwidth=130) self._stress_test_round_duration_text = ba.textwidget( parent=self._subcontainer, position=(246 - x_sub, v - 14), size=(60, 28), editable=False, color=(0.3, 1.0, 0.3, 1.0), h_align='right', v_align='center', text=str(self._stress_test_round_duration), padding=2) ba.buttonwidget(parent=self._subcontainer, position=(330 - x_sub, v - 11), size=(28, 28), label='-', autoselect=True, on_activate_call=ba.Call( self._stress_test_round_duration_decrement), repeat=True, enable_sound=True) ba.buttonwidget(parent=self._subcontainer, position=(380 - x_sub, v - 11), size=(28, 28), label='+', autoselect=True, on_activate_call=ba.Call( self._stress_test_round_duration_increment), repeat=True, enable_sound=True) v -= 82 btn = ba.buttonwidget( parent=self._subcontainer, position=((self._sub_width - button_width) * 0.5, v), size=(button_width, 60), autoselect=True, label=ba.Lstr(resource=self._r + '.runStressTestText'), on_activate_call=self._stress_test_pressed) ba.widget(btn, show_buffer_bottom=50)
def _update(self) -> None: # pylint: disable=too-many-locals # pylint: disable=too-many-branches # pylint: disable=too-many-statements # pylint: disable=too-many-nested-blocks # update muted state if ba.app.config.resolve('Chat Muted'): ba.textwidget(edit=self._muted_text, color=(1, 1, 1, 0.3)) # clear any chat texts we're showing if self._chat_texts: while self._chat_texts: first = self._chat_texts.pop() first.delete() else: ba.textwidget(edit=self._muted_text, color=(1, 1, 1, 0.0)) # update roster section roster = _ba.get_game_roster() if roster != self._roster: self._roster = roster # clear out old for widget in self._name_widgets: widget.delete() self._name_widgets = [] if not self._roster: top_section_height = 60 ba.textwidget(edit=self._empty_str, text=ba.Lstr(resource=self._r + '.emptyText')) ba.scrollwidget(edit=self._scrollwidget, size=(self._width - 50, self._height - top_section_height - 110), position=(30, 80)) else: columns = 1 if len( self._roster) == 1 else 2 if len(self._roster) == 2 else 3 rows = int(math.ceil(float(len(self._roster)) / columns)) c_width = (self._width * 0.9) / max(3, columns) c_width_total = c_width * columns c_height = 24 c_height_total = c_height * rows for y in range(rows): for x in range(columns): index = y * columns + x if index < len(self._roster): t_scale = 0.65 pos = (self._width * 0.53 - c_width_total * 0.5 + c_width * x - 23, self._height - 65 - c_height * y - 15) # if there are players present for this client, use # their names as a display string instead of the # client spec-string try: if self._roster[index]['players']: # if there's just one, use the full name; # otherwise combine short names if len(self._roster[index] ['players']) == 1: p_str = self._roster[index]['players'][ 0]['name_full'] else: p_str = ('/'.join([ entry['name'] for entry in self._roster[index]['players'] ])) if len(p_str) > 25: p_str = p_str[:25] + '...' else: p_str = self._roster[index][ 'display_string'] except Exception: ba.print_exception( 'Error calcing client name str.') p_str = '???' widget = ba.textwidget(parent=self._root_widget, position=(pos[0], pos[1]), scale=t_scale, size=(c_width * 0.85, 30), maxwidth=c_width * 0.85, color=(1, 1, 1) if index == 0 else (1, 1, 1), selectable=True, autoselect=True, click_activate=True, text=ba.Lstr(value=p_str), h_align='left', v_align='center') self._name_widgets.append(widget) # in newer versions client_id will be present and # we can use that to determine who the host is. # in older versions we assume the first client is # host if self._roster[index]['client_id'] is not None: is_host = self._roster[index][ 'client_id'] == -1 else: is_host = (index == 0) # FIXME: Should pass client_id to these sort of # calls; not spec-string (perhaps should wait till # client_id is more readily available though). ba.textwidget(edit=widget, on_activate_call=ba.Call( self._on_party_member_press, self._roster[index]['client_id'], is_host, widget)) pos = (self._width * 0.53 - c_width_total * 0.5 + c_width * x, self._height - 65 - c_height * y) # Make the assumption that the first roster # entry is the server. # FIXME: Shouldn't do this. if is_host: twd = min( c_width * 0.85, _ba.get_string_width( p_str, suppress_warning=True) * t_scale) self._name_widgets.append( ba.textwidget( parent=self._root_widget, position=(pos[0] + twd + 1, pos[1] - 0.5), size=(0, 0), h_align='left', v_align='center', maxwidth=c_width * 0.96 - twd, color=(0.1, 1, 0.1, 0.5), text=ba.Lstr(resource=self._r + '.hostText'), scale=0.4, shadow=0.1, flatness=1.0)) ba.textwidget(edit=self._empty_str, text='') ba.scrollwidget(edit=self._scrollwidget, size=(self._width - 50, max(100, self._height - 139 - c_height_total)), position=(30, 80))
def _set_tab(self, tab: str) -> None: from bastd.ui import tabs if self._current_tab == tab: return self._current_tab = tab # We wanna preserve our current tab between runs. cfg = ba.app.config cfg['Store Tab'] = tab cfg.commit() # Update tab colors based on which is selected. tabs.update_tab_button_colors(self._tab_buttons, tab) # (Re)create scroll widget. if self._scrollwidget: self._scrollwidget.delete() self._scrollwidget = ba.scrollwidget( parent=self._root_widget, highlight=False, position=((self._width - self._scroll_width) * 0.5, self._height - self._scroll_height - 79 - 48), size=(self._scroll_width, self._scroll_height)) # NOTE: this stuff is modified by the _Store class. # Should maybe clean that up. self.button_infos = {} self.update_buttons_timer = None # So we can still select root level widgets with controllers. ba.containerwidget(edit=self._scrollwidget, claims_left_right=True, claims_tab=True, selection_loop_to_parent=True) # Show status over top. if self._status_textwidget: self._status_textwidget.delete() self._status_textwidget = ba.textwidget( parent=self._root_widget, position=(self._width * 0.5, self._height * 0.5), size=(0, 0), color=(1, 0.7, 1, 0.5), h_align='center', v_align='center', text=ba.Lstr(resource=self._r + '.loadingText'), maxwidth=self._scroll_width * 0.9) class _Request: def __init__(self, window: StoreBrowserWindow): self._window = weakref.ref(window) data = {'tab': tab} ba.timer(0.1, ba.WeakCall(self._on_response, data), timetype=ba.TimeType.REAL) def _on_response(self, data: Optional[Dict[str, Any]]) -> None: # FIXME: clean this up. # pylint: disable=protected-access window = self._window() if window is not None and (window._request is self): window._request = None # noinspection PyProtectedMember window._on_response(data) # Kick off a server request. self._request = _Request(self)
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()