mirror of
https://github.com/hypervortex/VH-Bombsquad-Modded-Server-Files
synced 2026-08-15 13:04:50 +00:00
485 lines
16 KiB
Python
485 lines
16 KiB
Python
|
|
# Released under the MIT License. See LICENSE for details.
|
||
|
|
#
|
||
|
|
"""Provides UI for graphics settings."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from typing import TYPE_CHECKING
|
||
|
|
|
||
|
|
import ba
|
||
|
|
import ba.internal
|
||
|
|
|
||
|
|
if TYPE_CHECKING:
|
||
|
|
pass
|
||
|
|
|
||
|
|
|
||
|
|
class GraphicsSettingsWindow(ba.Window):
|
||
|
|
"""Window for graphics settings."""
|
||
|
|
|
||
|
|
def __init__(
|
||
|
|
self,
|
||
|
|
transition: str = 'in_right',
|
||
|
|
origin_widget: ba.Widget | None = 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: tuple[float, float] | None
|
||
|
|
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.internal.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: ba.Widget | None
|
||
|
|
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: ConfigNumberEdit | None
|
||
|
|
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.internal.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.internal.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.internal.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.internal.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.internal.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 _back(self) -> None:
|
||
|
|
from bastd.ui.settings import allsettings
|
||
|
|
|
||
|
|
ba.containerwidget(
|
||
|
|
edit=self._root_widget, transition=self._transition_out
|
||
|
|
)
|
||
|
|
ba.app.ui.set_main_menu_window(
|
||
|
|
allsettings.AllSettingsWindow(
|
||
|
|
transition='in_left'
|
||
|
|
).get_root_widget()
|
||
|
|
)
|
||
|
|
|
||
|
|
def _set_quality(self, quality: str) -> None:
|
||
|
|
cfg = ba.app.config
|
||
|
|
cfg['Graphics Quality'] = quality
|
||
|
|
cfg.apply_and_commit()
|
||
|
|
|
||
|
|
def _set_textures(self, val: str) -> None:
|
||
|
|
cfg = ba.app.config
|
||
|
|
cfg['Texture Quality'] = val
|
||
|
|
cfg.apply_and_commit()
|
||
|
|
|
||
|
|
def _set_android_res(self, val: str) -> None:
|
||
|
|
cfg = ba.app.config
|
||
|
|
cfg['Resolution (Android)'] = val
|
||
|
|
cfg.apply_and_commit()
|
||
|
|
|
||
|
|
def _set_pixel_scale(self, res: str) -> None:
|
||
|
|
cfg = ba.app.config
|
||
|
|
cfg['Screen Pixel Scale'] = float(res[:-1]) / 100.0
|
||
|
|
cfg.apply_and_commit()
|
||
|
|
|
||
|
|
def _set_gvr_render_target_scale(self, res: str) -> None:
|
||
|
|
cfg = ba.app.config
|
||
|
|
cfg['GVR Render Target Scale'] = float(res[:-1]) / 100.0
|
||
|
|
cfg.apply_and_commit()
|
||
|
|
|
||
|
|
def _set_vsync(self, val: str) -> None:
|
||
|
|
cfg = ba.app.config
|
||
|
|
cfg['Vertical Sync'] = val
|
||
|
|
cfg.apply_and_commit()
|
||
|
|
|
||
|
|
def _update_controls(self) -> None:
|
||
|
|
if self._show_fullscreen:
|
||
|
|
ba.checkboxwidget(
|
||
|
|
edit=self._fullscreen_checkbox,
|
||
|
|
value=ba.app.config.resolve('Fullscreen'),
|
||
|
|
)
|