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_for_league_rank_data(self, data: Optional[Dict[str, Any]]) -> None: # pylint: disable=too-many-statements # pylint: disable=too-many-branches # pylint: disable=too-many-locals from ba.internal import get_league_rank_points if not self._root_widget: return in_top = (data is not None and data['rank'] is not None) eq_text = self._rdict.powerRankingPointsEqualsText pts_txt = self._rdict.powerRankingPointsText num_text = ba.Lstr(resource='numberText').evaluate() do_percent = False finished_season_unranked = False self._can_do_more_button = True extra_text = '' if _ba.get_account_state() != 'signed_in': status_text = '(' + ba.Lstr( resource='notSignedInText').evaluate() + ')' elif in_top: assert data is not None status_text = num_text.replace('${NUMBER}', str(data['rank'])) elif data is not None: try: # handle old seasons where we didn't wind up ranked # at the end.. if not data['scores']: status_text = ( self._rdict.powerRankingFinishedSeasonUnrankedText) extra_text = '' finished_season_unranked = True self._can_do_more_button = False else: our_points = get_league_rank_points(data) progress = float(our_points) / max(1, data['scores'][-1][1]) status_text = str(int(progress * 100.0)) + '%' extra_text = ( '\n' + self._rdict.powerRankingPointsToRankedText.replace( '${CURRENT}', str(our_points)).replace( '${REMAINING}', str(data['scores'][-1][1]))) do_percent = True except Exception: ba.print_exception('error updating power ranking') status_text = self._rdict.powerRankingNotInTopText.replace( '${NUMBER}', str(data['listSize'])) extra_text = '' else: status_text = '-' self._season = data['s'] if data is not None else None v = self._subcontainerheight - 20 popup_was_selected = False if self._season_popup_menu is not None: btn = self._season_popup_menu.get_button() assert self._subcontainer if self._subcontainer.get_selected_child() == btn: popup_was_selected = True btn.delete() season_choices = [] season_choices_display = [] did_first = False self._is_current_season = False if data is not None: # build our list of seasons we have available for ssn in data['sl']: season_choices.append(ssn) if ssn != 'a' and not did_first: season_choices_display.append( ba.Lstr(resource='league.currentSeasonText', subs=[('${NUMBER}', ssn)])) did_first = True # if we either did not specify a season or specified the # first, we're looking at the current.. if self._season in [ssn, None]: self._is_current_season = True elif ssn == 'a': season_choices_display.append( ba.Lstr(resource='league.allTimeText')) else: season_choices_display.append( ba.Lstr(resource='league.seasonText', subs=[('${NUMBER}', ssn)])) assert self._subcontainer self._season_popup_menu = popup_ui.PopupMenu( parent=self._subcontainer, position=(390, v - 45), width=150, button_size=(200, 50), choices=season_choices, on_value_change_call=ba.WeakCall(self._on_season_change), choices_display=season_choices_display, current_choice=self._season) if popup_was_selected: ba.containerwidget( edit=self._subcontainer, selected_child=self._season_popup_menu.get_button()) ba.widget(edit=self._see_more_button, show_buffer_bottom=100) ba.widget(edit=self._season_popup_menu.get_button(), up_widget=self._back_button) ba.widget(edit=self._back_button, down_widget=self._power_ranking_achievements_button, right_widget=self._season_popup_menu.get_button()) ba.textwidget(edit=self._league_title_text, text='' if self._season == 'a' else ba.Lstr( resource='league.leagueText')) if data is None: lname = '' lnum = '' lcolor = (1, 1, 1) self._league_url_arg = '' elif self._season == 'a': lname = ba.Lstr(resource='league.allTimeText').evaluate() lnum = '' lcolor = (1, 1, 1) self._league_url_arg = '' else: lnum = ('[' + str(data['l']['i']) + ']') if data['l']['i2'] else '' lname = ba.Lstr(translate=('leagueNames', data['l']['n'])).evaluate() lcolor = data['l']['c'] self._league_url_arg = (data['l']['n'] + '_' + str(data['l']['i'])).lower() to_end_string: Union[ba.Lstr, str] if data is None or self._season == 'a' or data['se'] is None: to_end_string = '' show_season_end = False else: show_season_end = True days_to_end = data['se'][0] minutes_to_end = data['se'][1] if days_to_end > 0: to_end_string = ba.Lstr(resource='league.seasonEndsDaysText', subs=[('${NUMBER}', str(days_to_end))]) elif days_to_end == 0 and minutes_to_end >= 60: to_end_string = ba.Lstr(resource='league.seasonEndsHoursText', subs=[('${NUMBER}', str(minutes_to_end // 60))]) elif days_to_end == 0 and minutes_to_end >= 0: to_end_string = ba.Lstr( resource='league.seasonEndsMinutesText', subs=[('${NUMBER}', str(minutes_to_end))]) else: to_end_string = ba.Lstr( resource='league.seasonEndedDaysAgoText', subs=[('${NUMBER}', str(-(days_to_end + 1)))]) ba.textwidget(edit=self._season_ends_text, text=to_end_string) ba.textwidget(edit=self._trophy_counts_reset_text, text=ba.Lstr(resource='league.trophyCountsResetText') if self._is_current_season and show_season_end else '') ba.textwidget(edit=self._league_text, text=lname, color=lcolor) l_text_width = min( self._league_text_maxwidth, _ba.get_string_width(lname, suppress_warning=True) * self._league_text_scale) ba.textwidget( edit=self._league_number_text, text=lnum, color=lcolor, position=(self._league_number_base_pos[0] + l_text_width * 0.5 + 8, self._league_number_base_pos[1] + 10)) ba.textwidget( edit=self._to_ranked_text, text=ba.Lstr(resource='coopSelectWindow.toRankedText').evaluate() + '' + extra_text if do_percent else '') ba.textwidget( edit=self._your_power_ranking_text, text=ba.Lstr( resource='rankText', fallback_resource='coopSelectWindow.yourPowerRankingText') if (not do_percent) else '') ba.textwidget(edit=self._power_ranking_rank_text, position=(473, v - 70 - (170 if do_percent else 220)), text=status_text, big=(in_top or do_percent), scale=3.0 if (in_top or do_percent) else 0.7 if finished_season_unranked else 1.0) if self._activity_mult_button is not None: if data is None or data['act'] is None: ba.buttonwidget(edit=self._activity_mult_button, textcolor=(0.7, 0.7, 0.8, 0.5), icon_color=(0.5, 0, 0.5, 0.3)) ba.textwidget(edit=self._activity_mult_text, text=' -') else: ba.buttonwidget(edit=self._activity_mult_button, textcolor=(0.7, 0.7, 0.8, 1.0), icon_color=(0.5, 0, 0.5, 1.0)) ba.textwidget(edit=self._activity_mult_text, text='x ' + ('%.2f' % data['act'])) have_pro = False if data is None else data['p'] pro_mult = 1.0 + float( _ba.get_account_misc_read_val('proPowerRankingBoost', 0.0)) * 0.01 ba.textwidget(edit=self._pro_mult_text, text=' -' if (data is None or not have_pro) else 'x ' + ('%.2f' % pro_mult)) ba.buttonwidget(edit=self._pro_mult_button, textcolor=(0.7, 0.7, 0.8, (1.0 if have_pro else 0.5)), icon_color=(0.5, 0, 0.5) if have_pro else (0.5, 0, 0.5, 0.2)) ba.buttonwidget(edit=self._power_ranking_achievements_button, label=('' if data is None else (str(data['a']) + ' ')) + ba.Lstr(resource='achievementsText').evaluate()) # for the achievement value, use the number they gave us for # non-current seasons; otherwise calc our own total_ach_value = 0 for ach in ba.app.achievements: if ach.complete: total_ach_value += ach.power_ranking_value if self._season != 'a' and not self._is_current_season: if data is not None and 'at' in data: total_ach_value = data['at'] ba.textwidget(edit=self._power_ranking_achievement_total_text, text='-' if data is None else ('+ ' + pts_txt.replace('${NUMBER}', str(total_ach_value)))) total_trophies_count = (get_league_rank_points(data, 'trophyCount')) total_trophies_value = (get_league_rank_points(data, 'trophies')) ba.buttonwidget(edit=self._power_ranking_trophies_button, label=('' if data is None else (str(total_trophies_count) + ' ')) + ba.Lstr(resource='trophiesText').evaluate()) ba.textwidget( edit=self._power_ranking_trophies_total_text, text='-' if data is None else ('+ ' + pts_txt.replace('${NUMBER}', str(total_trophies_value)))) ba.textwidget(edit=self._power_ranking_total_text, text='-' if data is None else eq_text.replace( '${NUMBER}', str(get_league_rank_points(data)))) for widget in self._power_ranking_score_widgets: widget.delete() self._power_ranking_score_widgets = [] scores = data['scores'] if data is not None else [] tally_color = (0.5, 0.6, 0.8) w_parent = self._subcontainer v2 = self._power_ranking_score_v for score in scores: h2 = 680 is_us = score[3] self._power_ranking_score_widgets.append( ba.textwidget(parent=w_parent, position=(h2 - 20, v2), size=(0, 0), color=(1, 1, 1) if is_us else (0.6, 0.6, 0.7), maxwidth=40, flatness=1.0, shadow=0.0, text=num_text.replace('${NUMBER}', str(score[0])), h_align='right', v_align='center', scale=0.5)) self._power_ranking_score_widgets.append( ba.textwidget(parent=w_parent, position=(h2 + 20, v2), size=(0, 0), color=(1, 1, 1) if is_us else tally_color, maxwidth=60, text=str(score[1]), flatness=1.0, shadow=0.0, h_align='center', v_align='center', scale=0.7)) txt = ba.textwidget(parent=w_parent, position=(h2 + 60, v2 - (28 * 0.5) / 0.9), size=(210 / 0.9, 28), color=(1, 1, 1) if is_us else (0.6, 0.6, 0.6), maxwidth=210, flatness=1.0, shadow=0.0, autoselect=True, selectable=True, click_activate=True, text=score[2], h_align='left', v_align='center', scale=0.9) self._power_ranking_score_widgets.append(txt) ba.textwidget(edit=txt, on_activate_call=ba.Call(self._show_account_info, score[4], txt)) assert self._season_popup_menu is not None ba.widget(edit=txt, left_widget=self._season_popup_menu.get_button()) v2 -= 28
def __init__(self, transition: str = 'in_right', origin_widget: ba.Widget = None): # pylint: disable=too-many-locals # pylint: disable=too-many-branches # pylint: disable=too-many-statements from bastd.ui import popup from bastd.ui.config import ConfigCheckBox, ConfigNumberEdit # if they provided an origin-widget, scale up from that scale_origin: Optional[Tuple[float, float]] if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() transition = 'in_scale' else: self._transition_out = 'out_right' scale_origin = None self._r = 'graphicsSettingsWindow' app = ba.app spacing = 32 self._have_selected_child = False uiscale = app.ui.uiscale width = 450.0 height = 302.0 self._show_fullscreen = False fullscreen_spacing_top = spacing * 0.2 fullscreen_spacing = spacing * 1.2 if uiscale == ba.UIScale.LARGE and app.platform != 'android': self._show_fullscreen = True height += fullscreen_spacing + fullscreen_spacing_top show_gamma = False gamma_spacing = spacing * 1.3 if _ba.has_gamma_control(): show_gamma = True height += gamma_spacing show_vsync = False if app.platform == 'mac': show_vsync = True show_resolution = True if app.vr_mode: show_resolution = (app.platform == 'android' and app.subplatform == 'cardboard') uiscale = ba.app.ui.uiscale base_scale = (2.4 if uiscale is ba.UIScale.SMALL else 1.5 if uiscale is ba.UIScale.MEDIUM else 1.0) popup_menu_scale = base_scale * 1.2 v = height - 50 v -= spacing * 1.15 super().__init__(root_widget=ba.containerwidget( size=(width, height), transition=transition, scale_origin_stack_offset=scale_origin, scale=base_scale, stack_offset=(0, -30) if uiscale is ba.UIScale.SMALL else (0, 0))) btn = ba.buttonwidget(parent=self._root_widget, position=(35, height - 50), size=(120, 60), scale=0.8, text_scale=1.2, autoselect=True, label=ba.Lstr(resource='backText'), button_type='back', on_activate_call=self._back) ba.containerwidget(edit=self._root_widget, cancel_button=btn) ba.textwidget(parent=self._root_widget, position=(0, height - 44), size=(width, 25), text=ba.Lstr(resource=self._r + '.titleText'), color=ba.app.ui.title_color, h_align='center', v_align='top') ba.buttonwidget(edit=btn, button_type='backSmall', size=(60, 60), label=ba.charstr(ba.SpecialChar.BACK)) self._fullscreen_checkbox: Optional[ba.Widget] if self._show_fullscreen: v -= fullscreen_spacing_top self._fullscreen_checkbox = ConfigCheckBox( parent=self._root_widget, position=(100, v), maxwidth=200, size=(300, 30), configkey='Fullscreen', displayname=ba.Lstr(resource=self._r + ('.fullScreenCmdText' if app.platform == 'mac' else '.fullScreenCtrlText'))).widget if not self._have_selected_child: ba.containerwidget(edit=self._root_widget, selected_child=self._fullscreen_checkbox) self._have_selected_child = True v -= fullscreen_spacing else: self._fullscreen_checkbox = None self._gamma_controls: Optional[ConfigNumberEdit] if show_gamma: self._gamma_controls = gmc = ConfigNumberEdit( parent=self._root_widget, position=(90, v), configkey='Screen Gamma', displayname=ba.Lstr(resource=self._r + '.gammaText'), minval=0.1, maxval=2.0, increment=0.1, xoffset=-70, textscale=0.85) if ba.app.ui.use_toolbars: ba.widget(edit=gmc.plusbutton, right_widget=_ba.get_special_widget('party_button')) if not self._have_selected_child: ba.containerwidget(edit=self._root_widget, selected_child=gmc.minusbutton) self._have_selected_child = True v -= gamma_spacing else: self._gamma_controls = None self._selected_color = (0.5, 1, 0.5, 1) self._unselected_color = (0.7, 0.7, 0.7, 1) # quality ba.textwidget(parent=self._root_widget, position=(60, v), size=(160, 25), text=ba.Lstr(resource=self._r + '.visualsText'), color=ba.app.ui.heading_color, scale=0.65, maxwidth=150, h_align='center', v_align='center') popup.PopupMenu( parent=self._root_widget, position=(60, v - 50), width=150, scale=popup_menu_scale, choices=['Auto', 'Higher', 'High', 'Medium', 'Low'], choices_disabled=['Higher', 'High'] if _ba.get_max_graphics_quality() == 'Medium' else [], choices_display=[ ba.Lstr(resource='autoText'), ba.Lstr(resource=self._r + '.higherText'), ba.Lstr(resource=self._r + '.highText'), ba.Lstr(resource=self._r + '.mediumText'), ba.Lstr(resource=self._r + '.lowText') ], current_choice=ba.app.config.resolve('Graphics Quality'), on_value_change_call=self._set_quality) # texture controls ba.textwidget(parent=self._root_widget, position=(230, v), size=(160, 25), text=ba.Lstr(resource=self._r + '.texturesText'), color=ba.app.ui.heading_color, scale=0.65, maxwidth=150, h_align='center', v_align='center') textures_popup = popup.PopupMenu( parent=self._root_widget, position=(230, v - 50), width=150, scale=popup_menu_scale, choices=['Auto', 'High', 'Medium', 'Low'], choices_display=[ ba.Lstr(resource='autoText'), ba.Lstr(resource=self._r + '.highText'), ba.Lstr(resource=self._r + '.mediumText'), ba.Lstr(resource=self._r + '.lowText') ], current_choice=ba.app.config.resolve('Texture Quality'), on_value_change_call=self._set_textures) if ba.app.ui.use_toolbars: ba.widget(edit=textures_popup.get_button(), right_widget=_ba.get_special_widget('party_button')) v -= 80 h_offs = 0 if show_resolution: # resolution ba.textwidget(parent=self._root_widget, position=(h_offs + 60, v), size=(160, 25), text=ba.Lstr(resource=self._r + '.resolutionText'), color=ba.app.ui.heading_color, scale=0.65, maxwidth=150, h_align='center', v_align='center') # on standard android we have 'Auto', 'Native', and a few # HD standards if app.platform == 'android': # on cardboard/daydream android we have a few # render-target-scale options if app.subplatform == 'cardboard': current_res_cardboard = (str(min(100, max(10, int(round( ba.app.config.resolve('GVR Render Target Scale') * 100.0))))) + '%') # yapf: disable popup.PopupMenu( parent=self._root_widget, position=(h_offs + 60, v - 50), width=120, scale=popup_menu_scale, choices=['100%', '75%', '50%', '35%'], current_choice=current_res_cardboard, on_value_change_call=self._set_gvr_render_target_scale) else: native_res = _ba.get_display_resolution() assert native_res is not None choices = ['Auto', 'Native'] choices_display = [ ba.Lstr(resource='autoText'), ba.Lstr(resource='nativeText') ] for res in [1440, 1080, 960, 720, 480]: # nav bar is 72px so lets allow for that in what # choices we show if native_res[1] >= res - 72: res_str = str(res) + 'p' choices.append(res_str) choices_display.append(ba.Lstr(value=res_str)) current_res_android = ba.app.config.resolve( 'Resolution (Android)') popup.PopupMenu(parent=self._root_widget, position=(h_offs + 60, v - 50), width=120, scale=popup_menu_scale, choices=choices, choices_display=choices_display, current_choice=current_res_android, on_value_change_call=self._set_android_res) else: # if we're on a system that doesn't allow setting resolution, # set pixel-scale instead current_res = _ba.get_display_resolution() if current_res is None: current_res2 = (str(min(100, max(10, int(round( ba.app.config.resolve('Screen Pixel Scale') * 100.0))))) + '%') # yapf: disable popup.PopupMenu( parent=self._root_widget, position=(h_offs + 60, v - 50), width=120, scale=popup_menu_scale, choices=['100%', '88%', '75%', '63%', '50%'], current_choice=current_res2, on_value_change_call=self._set_pixel_scale) else: raise Exception('obsolete path; discrete resolutions' ' no longer supported') # vsync if show_vsync: ba.textwidget(parent=self._root_widget, position=(230, v), size=(160, 25), text=ba.Lstr(resource=self._r + '.verticalSyncText'), color=ba.app.ui.heading_color, scale=0.65, maxwidth=150, h_align='center', v_align='center') popup.PopupMenu( parent=self._root_widget, position=(230, v - 50), width=150, scale=popup_menu_scale, choices=['Auto', 'Always', 'Never'], choices_display=[ ba.Lstr(resource='autoText'), ba.Lstr(resource=self._r + '.alwaysText'), ba.Lstr(resource=self._r + '.neverText') ], current_choice=ba.app.config.resolve('Vertical Sync'), on_value_change_call=self._set_vsync) v -= 90 fpsc = ConfigCheckBox(parent=self._root_widget, position=(69, v - 6), size=(210, 30), scale=0.86, configkey='Show FPS', displayname=ba.Lstr(resource=self._r + '.showFPSText'), maxwidth=130) # (tv mode doesnt apply to vr) if not ba.app.vr_mode: tvc = ConfigCheckBox(parent=self._root_widget, position=(240, v - 6), size=(210, 30), scale=0.86, configkey='TV Border', displayname=ba.Lstr(resource=self._r + '.tvBorderText'), maxwidth=130) # grumble.. ba.widget(edit=fpsc.widget, right_widget=tvc.widget) try: pass except Exception: ba.print_exception('Exception wiring up graphics settings UI:') v -= spacing # make a timer to update our controls in case the config changes # under us self._update_timer = ba.Timer(0.25, ba.WeakCall(self._update_controls), repeat=True, timetype=ba.TimeType.REAL)
def __init__(self, transition: str = 'in_right', origin_widget: ba.Widget = None): # FIXME: should tidy up here. # pylint: disable=too-many-statements # pylint: disable=too-many-branches # pylint: disable=too-many-locals # pylint: disable=cyclic-import from bastd.ui import popup as popup_ui self._have_selected_child = False scale_origin: Optional[Tuple[float, float]] # If they provided an origin-widget, scale up from that. if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() transition = 'in_scale' else: self._transition_out = 'out_right' scale_origin = None self._r = 'configControllersWindow' app = ba.app is_fire_tv = _ba.is_running_on_fire_tv() spacing = 50.0 button_width = 350.0 width = 460.0 height = 135.0 space_height = spacing * 0.3 # FIXME: should create vis settings in platform for these, # not hard code them here.. show_gamepads = False platform = app.platform subplatform = app.subplatform non_vr_windows = (platform == 'windows' and (subplatform != 'oculus' or not app.vr_mode)) if platform in ('linux', 'android', 'mac') or non_vr_windows: show_gamepads = True height += spacing show_touch = False if _ba.have_touchscreen_input(): show_touch = True height += spacing show_space_1 = False if show_gamepads or show_touch: show_space_1 = True height += space_height show_keyboard = False if _ba.getinputdevice('Keyboard', '#1', doraise=False) is not None: show_keyboard = True height += spacing * 2 show_keyboard_p2 = False if app.vr_mode else show_keyboard if show_keyboard_p2: height += spacing show_space_2 = False if show_keyboard: show_space_2 = True height += space_height if bool(True): show_remote = True height += spacing else: show_remote = False show_ps3 = False if platform == 'mac': show_ps3 = True height += spacing show360 = False if platform == 'mac' or is_fire_tv: show360 = True height += spacing show_mac_wiimote = False if platform == 'mac': show_mac_wiimote = True height += spacing # on non-oculus-vr windows, show an option to disable xinput show_xinput_toggle = False if platform == 'windows' and (subplatform != 'oculus' or not app.vr_mode): show_xinput_toggle = True # on mac builds, show an option to switch between generic and # made-for-iOS/Mac systems # (we can run into problems where devices register as one of each # type otherwise).. show_mac_controller_subsystem = False if platform == 'mac': show_mac_controller_subsystem = True if show_mac_controller_subsystem: height += spacing if show_xinput_toggle: height += spacing super().__init__(root_widget=ba.containerwidget( size=(width, height), transition=transition, scale_origin_stack_offset=scale_origin, scale=(1.7 if show_keyboard else 2.2 ) if ba.app.small_ui else 1.5 if ba.app.med_ui else 1.0)) self._back_button = btn = ba.buttonwidget( parent=self._root_widget, position=(35, height - 60), size=(140, 65), scale=0.8, text_scale=1.2, autoselect=True, label=ba.Lstr(resource='backText'), button_type='back', on_activate_call=self._back) ba.containerwidget(edit=self._root_widget, cancel_button=btn) # need these vars to exist even if the buttons don't self._gamepads_button: Optional[ba.Widget] = None self._touch_button: Optional[ba.Widget] = None self._keyboard_button: Optional[ba.Widget] = None self._keyboard_2_button: Optional[ba.Widget] = None self._idevices_button: Optional[ba.Widget] = None self._ps3_button: Optional[ba.Widget] = None self._xbox_360_button: Optional[ba.Widget] = None self._wiimotes_button: Optional[ba.Widget] = None ba.textwidget(parent=self._root_widget, position=(0, height - 49), size=(width, 25), text=ba.Lstr(resource=self._r + '.titleText'), color=ba.app.title_color, h_align='center', v_align='top') ba.buttonwidget(edit=btn, button_type='backSmall', size=(60, 60), label=ba.charstr(ba.SpecialChar.BACK)) v = height - 75 v -= spacing if show_touch: self._touch_button = btn = ba.buttonwidget( parent=self._root_widget, position=((width - button_width) / 2, v), size=(button_width, 43), autoselect=True, label=ba.Lstr(resource=self._r + '.configureTouchText'), on_activate_call=self._do_touchscreen) if ba.app.toolbars: ba.widget(edit=btn, right_widget=_ba.get_special_widget('party_button')) if not self._have_selected_child: ba.containerwidget(edit=self._root_widget, selected_child=self._touch_button) ba.widget(edit=self._back_button, down_widget=self._touch_button) self._have_selected_child = True v -= spacing if show_gamepads: self._gamepads_button = btn = ba.buttonwidget( parent=self._root_widget, position=((width - button_width) / 2 - 7, v), size=(button_width, 43), autoselect=True, label=ba.Lstr(resource=self._r + '.configureControllersText'), on_activate_call=self._do_gamepads) if ba.app.toolbars: ba.widget(edit=btn, right_widget=_ba.get_special_widget('party_button')) if not self._have_selected_child: ba.containerwidget(edit=self._root_widget, selected_child=self._gamepads_button) ba.widget(edit=self._back_button, down_widget=self._gamepads_button) self._have_selected_child = True v -= spacing else: self._gamepads_button = None if show_space_1: v -= space_height if show_keyboard: self._keyboard_button = btn = ba.buttonwidget( parent=self._root_widget, position=((width - button_width) / 2 + 5, v), size=(button_width, 43), autoselect=True, label=ba.Lstr(resource=self._r + '.configureKeyboardText'), on_activate_call=self._config_keyboard) if ba.app.toolbars: ba.widget(edit=btn, right_widget=_ba.get_special_widget('party_button')) if not self._have_selected_child: ba.containerwidget(edit=self._root_widget, selected_child=self._keyboard_button) ba.widget(edit=self._back_button, down_widget=self._keyboard_button) self._have_selected_child = True v -= spacing if show_keyboard_p2: self._keyboard_2_button = ba.buttonwidget( parent=self._root_widget, position=((width - button_width) / 2 - 3, v), size=(button_width, 43), autoselect=True, label=ba.Lstr(resource=self._r + '.configureKeyboard2Text'), on_activate_call=self._config_keyboard2) v -= spacing if show_space_2: v -= space_height if show_remote: self._idevices_button = btn = ba.buttonwidget( parent=self._root_widget, position=((width - button_width) / 2 - 5, v), size=(button_width, 43), autoselect=True, label=ba.Lstr(resource=self._r + '.configureMobileText'), on_activate_call=self._do_mobile_devices) if ba.app.toolbars: ba.widget(edit=btn, right_widget=_ba.get_special_widget('party_button')) if not self._have_selected_child: ba.containerwidget(edit=self._root_widget, selected_child=self._idevices_button) ba.widget(edit=self._back_button, down_widget=self._idevices_button) self._have_selected_child = True v -= spacing if show_ps3: self._ps3_button = btn = ba.buttonwidget( parent=self._root_widget, position=((width - button_width) / 2 + 5, v), size=(button_width, 43), autoselect=True, label=ba.Lstr(resource=self._r + '.ps3Text'), on_activate_call=self._do_ps3_controllers) if ba.app.toolbars: ba.widget(edit=btn, right_widget=_ba.get_special_widget('party_button')) v -= spacing if show360: self._xbox_360_button = btn = ba.buttonwidget( parent=self._root_widget, position=((width - button_width) / 2 - 1, v), size=(button_width, 43), autoselect=True, label=ba.Lstr(resource=self._r + '.xbox360Text'), on_activate_call=self._do_360_controllers) if ba.app.toolbars: ba.widget(edit=btn, right_widget=_ba.get_special_widget('party_button')) v -= spacing if show_mac_wiimote: self._wiimotes_button = btn = ba.buttonwidget( parent=self._root_widget, position=((width - button_width) / 2 + 5, v), size=(button_width, 43), autoselect=True, label=ba.Lstr(resource=self._r + '.wiimotesText'), on_activate_call=self._do_wiimotes) if ba.app.toolbars: ba.widget(edit=btn, right_widget=_ba.get_special_widget('party_button')) v -= spacing if show_xinput_toggle: def do_toggle(value: bool) -> None: ba.screenmessage( ba.Lstr(resource='settingsWindowAdvanced.mustRestartText'), color=(1, 1, 0)) ba.playsound(ba.getsound('gunCocking')) _ba.set_low_level_config_value('enablexinput', not value) ba.checkboxwidget( parent=self._root_widget, position=(100, v + 3), size=(120, 30), value=(not _ba.get_low_level_config_value('enablexinput', 1)), maxwidth=200, on_value_change_call=do_toggle, text=ba.Lstr(resource='disableXInputText'), autoselect=True) ba.textwidget( parent=self._root_widget, position=(width * 0.5, v - 5), size=(0, 0), text=ba.Lstr(resource='disableXInputDescriptionText'), scale=0.5, h_align='center', v_align='center', color=ba.app.infotextcolor, maxwidth=width * 0.8) v -= spacing if show_mac_controller_subsystem: popup_ui.PopupMenu( parent=self._root_widget, position=(260, v - 10), width=160, button_size=(150, 50), scale=1.5, choices=['Classic', 'MFi', 'Both'], choices_display=[ ba.Lstr(resource='macControllerSubsystemClassicText'), ba.Lstr(resource='macControllerSubsystemMFiText'), ba.Lstr(resource='macControllerSubsystemBothText') ], current_choice=ba.app.config.resolve( 'Mac Controller Subsystem'), on_value_change_call=self._set_mac_controller_subsystem) ba.textwidget( parent=self._root_widget, position=(245, v + 13), size=(0, 0), text=ba.Lstr(resource='macControllerSubsystemTitleText'), scale=1.0, h_align='right', v_align='center', color=ba.app.infotextcolor, maxwidth=180) ba.textwidget( parent=self._root_widget, position=(width * 0.5, v - 20), size=(0, 0), text=ba.Lstr(resource='macControllerSubsystemDescriptionText'), scale=0.5, h_align='center', v_align='center', color=ba.app.infotextcolor, maxwidth=width * 0.8) v -= spacing self._restore_state()
def _rebuild(self) -> None: # pylint: disable=too-many-statements # pylint: disable=too-many-branches # pylint: disable=too-many-locals from bastd.ui.config import ConfigCheckBox from ba.modutils import show_user_scripts available_languages = ba.app.lang.available_languages # Don't rebuild if the menu is open or if our language and # language-list hasn't changed. # NOTE - although we now support widgets updating their own # translations, we still change the label formatting on the language # menu based on the language so still need this. ...however we could # make this more limited to it only rebuilds that one menu instead # of everything. if self._menu_open or (self._prev_lang == _ba.app.config.get( 'Lang', None) and self._prev_lang_list == available_languages): return self._prev_lang = _ba.app.config.get('Lang', None) self._prev_lang_list = available_languages # Clear out our sub-container. children = self._subcontainer.get_children() for child in children: child.delete() v = self._sub_height - 35 v -= self._spacing * 1.2 # Update our existing back button and title. if self._back_button is not None: ba.buttonwidget(edit=self._back_button, label=ba.Lstr(resource='backText')) ba.buttonwidget(edit=self._back_button, label=ba.charstr(ba.SpecialChar.BACK)) ba.textwidget(edit=self._title_text, text=ba.Lstr(resource=self._r + '.titleText')) this_button_width = 410 self._promo_code_button = ba.buttonwidget( parent=self._subcontainer, position=(self._sub_width / 2 - this_button_width / 2, v - 14), size=(this_button_width, 60), autoselect=True, label=ba.Lstr(resource=self._r + '.enterPromoCodeText'), text_scale=1.0, on_activate_call=self._on_promo_code_press) if self._back_button is not None: ba.widget(edit=self._promo_code_button, up_widget=self._back_button, left_widget=self._back_button) v -= self._extra_button_spacing * 0.8 ba.textwidget(parent=self._subcontainer, position=(200, v + 10), size=(0, 0), text=ba.Lstr(resource=self._r + '.languageText'), maxwidth=150, scale=0.95, color=ba.app.ui.title_color, h_align='right', v_align='center') languages = _ba.app.lang.available_languages cur_lang = _ba.app.config.get('Lang', None) if cur_lang is None: cur_lang = 'Auto' # We have a special dict of language names in that language # so we don't have to go digging through each full language. try: import json with open('ba_data/data/langdata.json', encoding='utf-8') as infile: lang_names_translated = (json.loads( infile.read())['lang_names_translated']) except Exception: ba.print_exception('Error reading lang data.') lang_names_translated = {} langs_translated = {} for lang in languages: langs_translated[lang] = lang_names_translated.get(lang, lang) langs_full = {} for lang in languages: lang_translated = ba.Lstr(translate=('languages', lang)).evaluate() if langs_translated[lang] == lang_translated: langs_full[lang] = lang_translated else: langs_full[lang] = (langs_translated[lang] + ' (' + lang_translated + ')') self._language_popup = popup_ui.PopupMenu( parent=self._subcontainer, position=(210, v - 19), width=150, opening_call=ba.WeakCall(self._on_menu_open), closing_call=ba.WeakCall(self._on_menu_close), autoselect=False, on_value_change_call=ba.WeakCall(self._on_menu_choice), choices=['Auto'] + languages, button_size=(250, 60), choices_display=([ ba.Lstr(value=(ba.Lstr(resource='autoText').evaluate() + ' (' + ba.Lstr(translate=('languages', ba.app.lang.default_language )).evaluate() + ')')) ] + [ba.Lstr(value=langs_full[l]) for l in languages]), current_choice=cur_lang) v -= self._spacing * 1.8 ba.textwidget(parent=self._subcontainer, position=(self._sub_width * 0.5, v + 10), size=(0, 0), text=ba.Lstr(resource=self._r + '.helpTranslateText', subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))]), maxwidth=self._sub_width * 0.9, max_height=55, flatness=1.0, scale=0.65, color=(0.4, 0.9, 0.4, 0.8), h_align='center', v_align='center') v -= self._spacing * 1.9 this_button_width = 410 self._translation_editor_button = ba.buttonwidget( parent=self._subcontainer, position=(self._sub_width / 2 - this_button_width / 2, v - 24), size=(this_button_width, 60), label=ba.Lstr(resource=self._r + '.translationEditorButtonText', subs=[('${APP_NAME}', ba.Lstr(resource='titleText')) ]), autoselect=True, on_activate_call=ba.Call( ba.open_url, 'https://legacy.ballistica.net/translate')) self._lang_status_text = ba.textwidget(parent=self._subcontainer, position=(self._sub_width * 0.5, v - 40), size=(0, 0), text='', flatness=1.0, scale=0.63, h_align='center', v_align='center', maxwidth=400.0) self._update_lang_status() v -= 40 lang_inform = _ba.get_v1_account_misc_val('langInform', False) self._language_inform_checkbox = cbw = ba.checkboxwidget( parent=self._subcontainer, position=(50, v - 50), size=(self._sub_width - 100, 30), autoselect=True, maxwidth=430, textcolor=(0.8, 0.8, 0.8), value=lang_inform, text=ba.Lstr(resource=self._r + '.translationInformMe'), on_value_change_call=ba.WeakCall( self._on_lang_inform_value_change)) ba.widget(edit=self._translation_editor_button, down_widget=cbw, up_widget=self._language_popup.get_button()) v -= self._spacing * 3.0 self._kick_idle_players_check_box = ConfigCheckBox( parent=self._subcontainer, position=(50, v), size=(self._sub_width - 100, 30), configkey='Kick Idle Players', displayname=ba.Lstr(resource=self._r + '.kickIdlePlayersText'), scale=1.0, maxwidth=430) v -= 42 self._disable_camera_shake_check_box = ConfigCheckBox( parent=self._subcontainer, position=(50, v), size=(self._sub_width - 100, 30), configkey='Disable Camera Shake', displayname=ba.Lstr(resource=self._r + '.disableCameraShakeText'), scale=1.0, maxwidth=430) self._disable_gyro_check_box: Optional[ConfigCheckBox] = None if self._show_disable_gyro: v -= 42 self._disable_gyro_check_box = ConfigCheckBox( parent=self._subcontainer, position=(50, v), size=(self._sub_width - 100, 30), configkey='Disable Camera Gyro', displayname=ba.Lstr(resource=self._r + '.disableCameraGyroscopeMotionText'), scale=1.0, maxwidth=430) self._always_use_internal_keyboard_check_box: Optional[ConfigCheckBox] if self._show_always_use_internal_keyboard: v -= 42 self._always_use_internal_keyboard_check_box = ConfigCheckBox( parent=self._subcontainer, position=(50, v), size=(self._sub_width - 100, 30), configkey='Always Use Internal Keyboard', autoselect=True, displayname=ba.Lstr(resource=self._r + '.alwaysUseInternalKeyboardText'), scale=1.0, maxwidth=430) ba.textwidget( parent=self._subcontainer, position=(90, v - 10), size=(0, 0), text=ba.Lstr(resource=self._r + '.alwaysUseInternalKeyboardDescriptionText'), maxwidth=400, flatness=1.0, scale=0.65, color=(0.4, 0.9, 0.4, 0.8), h_align='left', v_align='center') v -= 20 else: self._always_use_internal_keyboard_check_box = None v -= self._spacing * 2.1 this_button_width = 410 self._show_user_mods_button = ba.buttonwidget( parent=self._subcontainer, position=(self._sub_width / 2 - this_button_width / 2, v - 10), size=(this_button_width, 60), autoselect=True, label=ba.Lstr(resource=self._r + '.showUserModsText'), text_scale=1.0, on_activate_call=show_user_scripts) if self._show_always_use_internal_keyboard: assert self._always_use_internal_keyboard_check_box is not None ba.widget(edit=self._always_use_internal_keyboard_check_box.widget, down_widget=self._show_user_mods_button) ba.widget( edit=self._show_user_mods_button, up_widget=self._always_use_internal_keyboard_check_box.widget) else: ba.widget(edit=self._show_user_mods_button, up_widget=self._kick_idle_players_check_box.widget) ba.widget(edit=self._kick_idle_players_check_box.widget, down_widget=self._show_user_mods_button) v -= self._spacing * 2.0 self._modding_guide_button = ba.buttonwidget( parent=self._subcontainer, position=(self._sub_width / 2 - this_button_width / 2, v - 10), size=(this_button_width, 60), autoselect=True, label=ba.Lstr(resource=self._r + '.moddingGuideText'), text_scale=1.0, on_activate_call=ba.Call( ba.open_url, 'http://www.froemling.net/docs/bombsquad-modding-guide')) v -= self._spacing * 2.0 self._plugins_button = ba.buttonwidget( parent=self._subcontainer, position=(self._sub_width / 2 - this_button_width / 2, v - 10), size=(this_button_width, 60), autoselect=True, label=ba.Lstr(resource='pluginsText'), text_scale=1.0, on_activate_call=self._on_plugins_button_press) v -= self._spacing * 0.6 self._vr_test_button: Optional[ba.Widget] if self._do_vr_test_button: v -= self._extra_button_spacing self._vr_test_button = ba.buttonwidget( parent=self._subcontainer, position=(self._sub_width / 2 - this_button_width / 2, v - 14), size=(this_button_width, 60), autoselect=True, label=ba.Lstr(resource=self._r + '.vrTestingText'), text_scale=1.0, on_activate_call=self._on_vr_test_press) else: self._vr_test_button = None self._net_test_button: Optional[ba.Widget] if self._do_net_test_button: v -= self._extra_button_spacing self._net_test_button = ba.buttonwidget( parent=self._subcontainer, position=(self._sub_width / 2 - this_button_width / 2, v - 14), size=(this_button_width, 60), autoselect=True, label=ba.Lstr(resource=self._r + '.netTestingText'), text_scale=1.0, on_activate_call=self._on_net_test_press) else: self._net_test_button = None v -= 70 self._benchmarks_button = ba.buttonwidget( parent=self._subcontainer, position=(self._sub_width / 2 - this_button_width / 2, v - 14), size=(this_button_width, 60), autoselect=True, label=ba.Lstr(resource=self._r + '.benchmarksText'), text_scale=1.0, on_activate_call=self._on_benchmark_press) for child in self._subcontainer.get_children(): ba.widget(edit=child, show_buffer_bottom=30, show_buffer_top=20) if ba.app.ui.use_toolbars: pbtn = _ba.get_special_widget('party_button') ba.widget(edit=self._scrollwidget, right_widget=pbtn) if self._back_button is None: ba.widget(edit=self._scrollwidget, left_widget=_ba.get_special_widget('back_button')) self._restore_state()
def __init__(self, transition: str = 'in_right', origin_widget: ba.Widget = None): # pylint: disable=too-many-statements # pylint: disable=too-many-locals # pylint: disable=cyclic-import from ba.internal import have_music_player, music_volume_changed from bastd.ui import popup as popup_ui from bastd.ui import config as cfgui # 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 = 'audioSettingsWindow' spacing = 50.0 width = 460.0 height = 210.0 # Update: hard-coding head-relative audio to true now, so not showing # options. # show_vr_head_relative_audio = True if ba.app.vr_mode else False show_vr_head_relative_audio = False if show_vr_head_relative_audio: height += 70 show_soundtracks = False if have_music_player(): show_soundtracks = True height += spacing * 2.0 base_scale = (2.05 if ba.app.small_ui else 1.6 if ba.app.med_ui else 1.0) popup_menu_scale = base_scale * 1.2 super().__init__(root_widget=ba.containerwidget( size=(width, height), transition=transition, scale=base_scale, scale_origin_stack_offset=scale_origin, stack_offset=(0, -20) if ba.app.small_ui else (0, 0))) self._back_button = back_button = btn = ba.buttonwidget( parent=self._root_widget, position=(35, height - 55), size=(120, 60), scale=0.8, text_scale=1.2, label=ba.Lstr(resource='backText'), button_type='back', on_activate_call=self._back, autoselect=True) ba.containerwidget(edit=self._root_widget, cancel_button=btn) v = height - 60 v -= spacing * 1.0 ba.textwidget(parent=self._root_widget, position=(width * 0.5, height - 32), size=(0, 0), text=ba.Lstr(resource=self._r + '.titleText'), color=ba.app.title_color, maxwidth=180, h_align="center", v_align="center") ba.buttonwidget(edit=self._back_button, button_type='backSmall', size=(60, 60), label=ba.charstr(ba.SpecialChar.BACK)) self._sound_volume_numedit = svne = cfgui.ConfigNumberEdit( parent=self._root_widget, position=(40, v), xoffset=10, configkey="Sound Volume", displayname=ba.Lstr(resource=self._r + '.soundVolumeText'), minval=0.0, maxval=1.0, increment=0.1) if ba.app.toolbars: ba.widget(edit=svne.plusbutton, right_widget=_ba.get_special_widget('party_button')) v -= spacing self._music_volume_numedit = cfgui.ConfigNumberEdit( parent=self._root_widget, position=(40, v), xoffset=10, configkey="Music Volume", displayname=ba.Lstr(resource=self._r + '.musicVolumeText'), minval=0.0, maxval=1.0, increment=0.1, callback=music_volume_changed, changesound=False) v -= 0.5 * spacing self._vr_head_relative_audio_button: Optional[ba.Widget] if show_vr_head_relative_audio: v -= 40 ba.textwidget(parent=self._root_widget, position=(40, v + 24), size=(0, 0), text=ba.Lstr(resource=self._r + '.headRelativeVRAudioText'), color=(0.8, 0.8, 0.8), maxwidth=230, h_align="left", v_align="center") popup = popup_ui.PopupMenu( parent=self._root_widget, position=(290, v), width=120, button_size=(135, 50), scale=popup_menu_scale, choices=['Auto', 'On', 'Off'], choices_display=[ ba.Lstr(resource='autoText'), ba.Lstr(resource='onText'), ba.Lstr(resource='offText') ], current_choice=ba.app.config.resolve('VR Head Relative Audio'), on_value_change_call=self._set_vr_head_relative_audio) self._vr_head_relative_audio_button = popup.get_button() ba.textwidget(parent=self._root_widget, position=(width * 0.5, v - 11), size=(0, 0), text=ba.Lstr(resource=self._r + '.headRelativeVRAudioInfoText'), scale=0.5, color=(0.7, 0.8, 0.7), maxwidth=400, flatness=1.0, h_align="center", v_align="center") v -= 30 else: self._vr_head_relative_audio_button = None self._soundtrack_button: Optional[ba.Widget] if show_soundtracks: v -= 1.2 * spacing self._soundtrack_button = ba.buttonwidget( parent=self._root_widget, position=((width - 310) / 2, v), size=(310, 50), autoselect=True, label=ba.Lstr(resource=self._r + '.soundtrackButtonText'), on_activate_call=self._do_soundtracks) v -= spacing * 0.5 ba.textwidget(parent=self._root_widget, position=(0, v), size=(width, 20), text=ba.Lstr(resource=self._r + '.soundtrackDescriptionText'), flatness=1.0, h_align='center', scale=0.5, color=(0.7, 0.8, 0.7, 1.0), maxwidth=400) else: self._soundtrack_button = None # tweak a few navigation bits try: ba.widget(edit=back_button, down_widget=svne.minusbutton) except Exception: ba.print_exception('error wiring AudioSettingsWindow') self._restore_state()