bastd.ui.settings.graphics
Provides UI for graphics settings.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Provides UI for graphics settings.""" 4 5from __future__ import annotations 6 7from typing import TYPE_CHECKING 8 9import _ba 10import ba 11 12if TYPE_CHECKING: 13 pass 14 15 16class GraphicsSettingsWindow(ba.Window): 17 """Window for graphics settings.""" 18 19 def __init__(self, 20 transition: str = 'in_right', 21 origin_widget: ba.Widget | None = None): 22 # pylint: disable=too-many-locals 23 # pylint: disable=too-many-branches 24 # pylint: disable=too-many-statements 25 from bastd.ui import popup 26 from bastd.ui.config import ConfigCheckBox, ConfigNumberEdit 27 # if they provided an origin-widget, scale up from that 28 scale_origin: tuple[float, float] | None 29 if origin_widget is not None: 30 self._transition_out = 'out_scale' 31 scale_origin = origin_widget.get_screen_space_center() 32 transition = 'in_scale' 33 else: 34 self._transition_out = 'out_right' 35 scale_origin = None 36 37 self._r = 'graphicsSettingsWindow' 38 app = ba.app 39 40 spacing = 32 41 self._have_selected_child = False 42 uiscale = app.ui.uiscale 43 width = 450.0 44 height = 302.0 45 46 self._show_fullscreen = False 47 fullscreen_spacing_top = spacing * 0.2 48 fullscreen_spacing = spacing * 1.2 49 if uiscale == ba.UIScale.LARGE and app.platform != 'android': 50 self._show_fullscreen = True 51 height += fullscreen_spacing + fullscreen_spacing_top 52 53 show_gamma = False 54 gamma_spacing = spacing * 1.3 55 if _ba.has_gamma_control(): 56 show_gamma = True 57 height += gamma_spacing 58 59 show_vsync = False 60 if app.platform == 'mac': 61 show_vsync = True 62 63 show_resolution = True 64 if app.vr_mode: 65 show_resolution = (app.platform == 'android' 66 and app.subplatform == 'cardboard') 67 68 uiscale = ba.app.ui.uiscale 69 base_scale = (2.4 if uiscale is ba.UIScale.SMALL else 70 1.5 if uiscale is ba.UIScale.MEDIUM else 1.0) 71 popup_menu_scale = base_scale * 1.2 72 v = height - 50 73 v -= spacing * 1.15 74 super().__init__(root_widget=ba.containerwidget( 75 size=(width, height), 76 transition=transition, 77 scale_origin_stack_offset=scale_origin, 78 scale=base_scale, 79 stack_offset=(0, -30) if uiscale is ba.UIScale.SMALL else (0, 0))) 80 81 btn = ba.buttonwidget(parent=self._root_widget, 82 position=(35, height - 50), 83 size=(120, 60), 84 scale=0.8, 85 text_scale=1.2, 86 autoselect=True, 87 label=ba.Lstr(resource='backText'), 88 button_type='back', 89 on_activate_call=self._back) 90 91 ba.containerwidget(edit=self._root_widget, cancel_button=btn) 92 93 ba.textwidget(parent=self._root_widget, 94 position=(0, height - 44), 95 size=(width, 25), 96 text=ba.Lstr(resource=self._r + '.titleText'), 97 color=ba.app.ui.title_color, 98 h_align='center', 99 v_align='top') 100 101 ba.buttonwidget(edit=btn, 102 button_type='backSmall', 103 size=(60, 60), 104 label=ba.charstr(ba.SpecialChar.BACK)) 105 106 self._fullscreen_checkbox: ba.Widget | None 107 if self._show_fullscreen: 108 v -= fullscreen_spacing_top 109 self._fullscreen_checkbox = ConfigCheckBox( 110 parent=self._root_widget, 111 position=(100, v), 112 maxwidth=200, 113 size=(300, 30), 114 configkey='Fullscreen', 115 displayname=ba.Lstr(resource=self._r + 116 ('.fullScreenCmdText' if app.platform == 117 'mac' else '.fullScreenCtrlText'))).widget 118 if not self._have_selected_child: 119 ba.containerwidget(edit=self._root_widget, 120 selected_child=self._fullscreen_checkbox) 121 self._have_selected_child = True 122 v -= fullscreen_spacing 123 else: 124 self._fullscreen_checkbox = None 125 126 self._gamma_controls: ConfigNumberEdit | None 127 if show_gamma: 128 self._gamma_controls = gmc = ConfigNumberEdit( 129 parent=self._root_widget, 130 position=(90, v), 131 configkey='Screen Gamma', 132 displayname=ba.Lstr(resource=self._r + '.gammaText'), 133 minval=0.1, 134 maxval=2.0, 135 increment=0.1, 136 xoffset=-70, 137 textscale=0.85) 138 if ba.app.ui.use_toolbars: 139 ba.widget(edit=gmc.plusbutton, 140 right_widget=_ba.get_special_widget('party_button')) 141 if not self._have_selected_child: 142 ba.containerwidget(edit=self._root_widget, 143 selected_child=gmc.minusbutton) 144 self._have_selected_child = True 145 v -= gamma_spacing 146 else: 147 self._gamma_controls = None 148 149 self._selected_color = (0.5, 1, 0.5, 1) 150 self._unselected_color = (0.7, 0.7, 0.7, 1) 151 152 # quality 153 ba.textwidget(parent=self._root_widget, 154 position=(60, v), 155 size=(160, 25), 156 text=ba.Lstr(resource=self._r + '.visualsText'), 157 color=ba.app.ui.heading_color, 158 scale=0.65, 159 maxwidth=150, 160 h_align='center', 161 v_align='center') 162 popup.PopupMenu( 163 parent=self._root_widget, 164 position=(60, v - 50), 165 width=150, 166 scale=popup_menu_scale, 167 choices=['Auto', 'Higher', 'High', 'Medium', 'Low'], 168 choices_disabled=['Higher', 'High'] 169 if _ba.get_max_graphics_quality() == 'Medium' else [], 170 choices_display=[ 171 ba.Lstr(resource='autoText'), 172 ba.Lstr(resource=self._r + '.higherText'), 173 ba.Lstr(resource=self._r + '.highText'), 174 ba.Lstr(resource=self._r + '.mediumText'), 175 ba.Lstr(resource=self._r + '.lowText') 176 ], 177 current_choice=ba.app.config.resolve('Graphics Quality'), 178 on_value_change_call=self._set_quality) 179 180 # texture controls 181 ba.textwidget(parent=self._root_widget, 182 position=(230, v), 183 size=(160, 25), 184 text=ba.Lstr(resource=self._r + '.texturesText'), 185 color=ba.app.ui.heading_color, 186 scale=0.65, 187 maxwidth=150, 188 h_align='center', 189 v_align='center') 190 textures_popup = popup.PopupMenu( 191 parent=self._root_widget, 192 position=(230, v - 50), 193 width=150, 194 scale=popup_menu_scale, 195 choices=['Auto', 'High', 'Medium', 'Low'], 196 choices_display=[ 197 ba.Lstr(resource='autoText'), 198 ba.Lstr(resource=self._r + '.highText'), 199 ba.Lstr(resource=self._r + '.mediumText'), 200 ba.Lstr(resource=self._r + '.lowText') 201 ], 202 current_choice=ba.app.config.resolve('Texture Quality'), 203 on_value_change_call=self._set_textures) 204 if ba.app.ui.use_toolbars: 205 ba.widget(edit=textures_popup.get_button(), 206 right_widget=_ba.get_special_widget('party_button')) 207 v -= 80 208 209 h_offs = 0 210 211 if show_resolution: 212 # resolution 213 ba.textwidget(parent=self._root_widget, 214 position=(h_offs + 60, v), 215 size=(160, 25), 216 text=ba.Lstr(resource=self._r + '.resolutionText'), 217 color=ba.app.ui.heading_color, 218 scale=0.65, 219 maxwidth=150, 220 h_align='center', 221 v_align='center') 222 223 # on standard android we have 'Auto', 'Native', and a few 224 # HD standards 225 if app.platform == 'android': 226 # on cardboard/daydream android we have a few 227 # render-target-scale options 228 if app.subplatform == 'cardboard': 229 current_res_cardboard = (str(min(100, max(10, int(round( 230 ba.app.config.resolve('GVR Render Target Scale') 231 * 100.0))))) + '%') # yapf: disable 232 popup.PopupMenu( 233 parent=self._root_widget, 234 position=(h_offs + 60, v - 50), 235 width=120, 236 scale=popup_menu_scale, 237 choices=['100%', '75%', '50%', '35%'], 238 current_choice=current_res_cardboard, 239 on_value_change_call=self._set_gvr_render_target_scale) 240 else: 241 native_res = _ba.get_display_resolution() 242 assert native_res is not None 243 choices = ['Auto', 'Native'] 244 choices_display = [ 245 ba.Lstr(resource='autoText'), 246 ba.Lstr(resource='nativeText') 247 ] 248 for res in [1440, 1080, 960, 720, 480]: 249 # nav bar is 72px so lets allow for that in what 250 # choices we show 251 if native_res[1] >= res - 72: 252 res_str = str(res) + 'p' 253 choices.append(res_str) 254 choices_display.append(ba.Lstr(value=res_str)) 255 current_res_android = ba.app.config.resolve( 256 'Resolution (Android)') 257 popup.PopupMenu(parent=self._root_widget, 258 position=(h_offs + 60, v - 50), 259 width=120, 260 scale=popup_menu_scale, 261 choices=choices, 262 choices_display=choices_display, 263 current_choice=current_res_android, 264 on_value_change_call=self._set_android_res) 265 else: 266 # if we're on a system that doesn't allow setting resolution, 267 # set pixel-scale instead 268 current_res = _ba.get_display_resolution() 269 if current_res is None: 270 current_res2 = (str(min(100, max(10, int(round( 271 ba.app.config.resolve('Screen Pixel Scale') 272 * 100.0))))) + '%') # yapf: disable 273 popup.PopupMenu( 274 parent=self._root_widget, 275 position=(h_offs + 60, v - 50), 276 width=120, 277 scale=popup_menu_scale, 278 choices=['100%', '88%', '75%', '63%', '50%'], 279 current_choice=current_res2, 280 on_value_change_call=self._set_pixel_scale) 281 else: 282 raise Exception('obsolete path; discrete resolutions' 283 ' no longer supported') 284 285 # vsync 286 if show_vsync: 287 ba.textwidget(parent=self._root_widget, 288 position=(230, v), 289 size=(160, 25), 290 text=ba.Lstr(resource=self._r + '.verticalSyncText'), 291 color=ba.app.ui.heading_color, 292 scale=0.65, 293 maxwidth=150, 294 h_align='center', 295 v_align='center') 296 297 popup.PopupMenu( 298 parent=self._root_widget, 299 position=(230, v - 50), 300 width=150, 301 scale=popup_menu_scale, 302 choices=['Auto', 'Always', 'Never'], 303 choices_display=[ 304 ba.Lstr(resource='autoText'), 305 ba.Lstr(resource=self._r + '.alwaysText'), 306 ba.Lstr(resource=self._r + '.neverText') 307 ], 308 current_choice=ba.app.config.resolve('Vertical Sync'), 309 on_value_change_call=self._set_vsync) 310 311 v -= 90 312 fpsc = ConfigCheckBox(parent=self._root_widget, 313 position=(69, v - 6), 314 size=(210, 30), 315 scale=0.86, 316 configkey='Show FPS', 317 displayname=ba.Lstr(resource=self._r + 318 '.showFPSText'), 319 maxwidth=130) 320 321 # (tv mode doesnt apply to vr) 322 if not ba.app.vr_mode: 323 tvc = ConfigCheckBox(parent=self._root_widget, 324 position=(240, v - 6), 325 size=(210, 30), 326 scale=0.86, 327 configkey='TV Border', 328 displayname=ba.Lstr(resource=self._r + 329 '.tvBorderText'), 330 maxwidth=130) 331 # grumble.. 332 ba.widget(edit=fpsc.widget, right_widget=tvc.widget) 333 try: 334 pass 335 336 except Exception: 337 ba.print_exception('Exception wiring up graphics settings UI:') 338 339 v -= spacing 340 341 # make a timer to update our controls in case the config changes 342 # under us 343 self._update_timer = ba.Timer(0.25, 344 ba.WeakCall(self._update_controls), 345 repeat=True, 346 timetype=ba.TimeType.REAL) 347 348 def _back(self) -> None: 349 from bastd.ui.settings import allsettings 350 ba.containerwidget(edit=self._root_widget, 351 transition=self._transition_out) 352 ba.app.ui.set_main_menu_window( 353 allsettings.AllSettingsWindow( 354 transition='in_left').get_root_widget()) 355 356 def _set_quality(self, quality: str) -> None: 357 cfg = ba.app.config 358 cfg['Graphics Quality'] = quality 359 cfg.apply_and_commit() 360 361 def _set_textures(self, val: str) -> None: 362 cfg = ba.app.config 363 cfg['Texture Quality'] = val 364 cfg.apply_and_commit() 365 366 def _set_android_res(self, val: str) -> None: 367 cfg = ba.app.config 368 cfg['Resolution (Android)'] = val 369 cfg.apply_and_commit() 370 371 def _set_pixel_scale(self, res: str) -> None: 372 cfg = ba.app.config 373 cfg['Screen Pixel Scale'] = float(res[:-1]) / 100.0 374 cfg.apply_and_commit() 375 376 def _set_gvr_render_target_scale(self, res: str) -> None: 377 cfg = ba.app.config 378 cfg['GVR Render Target Scale'] = float(res[:-1]) / 100.0 379 cfg.apply_and_commit() 380 381 def _set_vsync(self, val: str) -> None: 382 cfg = ba.app.config 383 cfg['Vertical Sync'] = val 384 cfg.apply_and_commit() 385 386 def _update_controls(self) -> None: 387 if self._show_fullscreen: 388 ba.checkboxwidget(edit=self._fullscreen_checkbox, 389 value=ba.app.config.resolve('Fullscreen'))
class
GraphicsSettingsWindow(ba.ui.Window):
17class GraphicsSettingsWindow(ba.Window): 18 """Window for graphics settings.""" 19 20 def __init__(self, 21 transition: str = 'in_right', 22 origin_widget: ba.Widget | None = None): 23 # pylint: disable=too-many-locals 24 # pylint: disable=too-many-branches 25 # pylint: disable=too-many-statements 26 from bastd.ui import popup 27 from bastd.ui.config import ConfigCheckBox, ConfigNumberEdit 28 # if they provided an origin-widget, scale up from that 29 scale_origin: tuple[float, float] | None 30 if origin_widget is not None: 31 self._transition_out = 'out_scale' 32 scale_origin = origin_widget.get_screen_space_center() 33 transition = 'in_scale' 34 else: 35 self._transition_out = 'out_right' 36 scale_origin = None 37 38 self._r = 'graphicsSettingsWindow' 39 app = ba.app 40 41 spacing = 32 42 self._have_selected_child = False 43 uiscale = app.ui.uiscale 44 width = 450.0 45 height = 302.0 46 47 self._show_fullscreen = False 48 fullscreen_spacing_top = spacing * 0.2 49 fullscreen_spacing = spacing * 1.2 50 if uiscale == ba.UIScale.LARGE and app.platform != 'android': 51 self._show_fullscreen = True 52 height += fullscreen_spacing + fullscreen_spacing_top 53 54 show_gamma = False 55 gamma_spacing = spacing * 1.3 56 if _ba.has_gamma_control(): 57 show_gamma = True 58 height += gamma_spacing 59 60 show_vsync = False 61 if app.platform == 'mac': 62 show_vsync = True 63 64 show_resolution = True 65 if app.vr_mode: 66 show_resolution = (app.platform == 'android' 67 and app.subplatform == 'cardboard') 68 69 uiscale = ba.app.ui.uiscale 70 base_scale = (2.4 if uiscale is ba.UIScale.SMALL else 71 1.5 if uiscale is ba.UIScale.MEDIUM else 1.0) 72 popup_menu_scale = base_scale * 1.2 73 v = height - 50 74 v -= spacing * 1.15 75 super().__init__(root_widget=ba.containerwidget( 76 size=(width, height), 77 transition=transition, 78 scale_origin_stack_offset=scale_origin, 79 scale=base_scale, 80 stack_offset=(0, -30) if uiscale is ba.UIScale.SMALL else (0, 0))) 81 82 btn = ba.buttonwidget(parent=self._root_widget, 83 position=(35, height - 50), 84 size=(120, 60), 85 scale=0.8, 86 text_scale=1.2, 87 autoselect=True, 88 label=ba.Lstr(resource='backText'), 89 button_type='back', 90 on_activate_call=self._back) 91 92 ba.containerwidget(edit=self._root_widget, cancel_button=btn) 93 94 ba.textwidget(parent=self._root_widget, 95 position=(0, height - 44), 96 size=(width, 25), 97 text=ba.Lstr(resource=self._r + '.titleText'), 98 color=ba.app.ui.title_color, 99 h_align='center', 100 v_align='top') 101 102 ba.buttonwidget(edit=btn, 103 button_type='backSmall', 104 size=(60, 60), 105 label=ba.charstr(ba.SpecialChar.BACK)) 106 107 self._fullscreen_checkbox: ba.Widget | None 108 if self._show_fullscreen: 109 v -= fullscreen_spacing_top 110 self._fullscreen_checkbox = ConfigCheckBox( 111 parent=self._root_widget, 112 position=(100, v), 113 maxwidth=200, 114 size=(300, 30), 115 configkey='Fullscreen', 116 displayname=ba.Lstr(resource=self._r + 117 ('.fullScreenCmdText' if app.platform == 118 'mac' else '.fullScreenCtrlText'))).widget 119 if not self._have_selected_child: 120 ba.containerwidget(edit=self._root_widget, 121 selected_child=self._fullscreen_checkbox) 122 self._have_selected_child = True 123 v -= fullscreen_spacing 124 else: 125 self._fullscreen_checkbox = None 126 127 self._gamma_controls: ConfigNumberEdit | None 128 if show_gamma: 129 self._gamma_controls = gmc = ConfigNumberEdit( 130 parent=self._root_widget, 131 position=(90, v), 132 configkey='Screen Gamma', 133 displayname=ba.Lstr(resource=self._r + '.gammaText'), 134 minval=0.1, 135 maxval=2.0, 136 increment=0.1, 137 xoffset=-70, 138 textscale=0.85) 139 if ba.app.ui.use_toolbars: 140 ba.widget(edit=gmc.plusbutton, 141 right_widget=_ba.get_special_widget('party_button')) 142 if not self._have_selected_child: 143 ba.containerwidget(edit=self._root_widget, 144 selected_child=gmc.minusbutton) 145 self._have_selected_child = True 146 v -= gamma_spacing 147 else: 148 self._gamma_controls = None 149 150 self._selected_color = (0.5, 1, 0.5, 1) 151 self._unselected_color = (0.7, 0.7, 0.7, 1) 152 153 # quality 154 ba.textwidget(parent=self._root_widget, 155 position=(60, v), 156 size=(160, 25), 157 text=ba.Lstr(resource=self._r + '.visualsText'), 158 color=ba.app.ui.heading_color, 159 scale=0.65, 160 maxwidth=150, 161 h_align='center', 162 v_align='center') 163 popup.PopupMenu( 164 parent=self._root_widget, 165 position=(60, v - 50), 166 width=150, 167 scale=popup_menu_scale, 168 choices=['Auto', 'Higher', 'High', 'Medium', 'Low'], 169 choices_disabled=['Higher', 'High'] 170 if _ba.get_max_graphics_quality() == 'Medium' else [], 171 choices_display=[ 172 ba.Lstr(resource='autoText'), 173 ba.Lstr(resource=self._r + '.higherText'), 174 ba.Lstr(resource=self._r + '.highText'), 175 ba.Lstr(resource=self._r + '.mediumText'), 176 ba.Lstr(resource=self._r + '.lowText') 177 ], 178 current_choice=ba.app.config.resolve('Graphics Quality'), 179 on_value_change_call=self._set_quality) 180 181 # texture controls 182 ba.textwidget(parent=self._root_widget, 183 position=(230, v), 184 size=(160, 25), 185 text=ba.Lstr(resource=self._r + '.texturesText'), 186 color=ba.app.ui.heading_color, 187 scale=0.65, 188 maxwidth=150, 189 h_align='center', 190 v_align='center') 191 textures_popup = popup.PopupMenu( 192 parent=self._root_widget, 193 position=(230, v - 50), 194 width=150, 195 scale=popup_menu_scale, 196 choices=['Auto', 'High', 'Medium', 'Low'], 197 choices_display=[ 198 ba.Lstr(resource='autoText'), 199 ba.Lstr(resource=self._r + '.highText'), 200 ba.Lstr(resource=self._r + '.mediumText'), 201 ba.Lstr(resource=self._r + '.lowText') 202 ], 203 current_choice=ba.app.config.resolve('Texture Quality'), 204 on_value_change_call=self._set_textures) 205 if ba.app.ui.use_toolbars: 206 ba.widget(edit=textures_popup.get_button(), 207 right_widget=_ba.get_special_widget('party_button')) 208 v -= 80 209 210 h_offs = 0 211 212 if show_resolution: 213 # resolution 214 ba.textwidget(parent=self._root_widget, 215 position=(h_offs + 60, v), 216 size=(160, 25), 217 text=ba.Lstr(resource=self._r + '.resolutionText'), 218 color=ba.app.ui.heading_color, 219 scale=0.65, 220 maxwidth=150, 221 h_align='center', 222 v_align='center') 223 224 # on standard android we have 'Auto', 'Native', and a few 225 # HD standards 226 if app.platform == 'android': 227 # on cardboard/daydream android we have a few 228 # render-target-scale options 229 if app.subplatform == 'cardboard': 230 current_res_cardboard = (str(min(100, max(10, int(round( 231 ba.app.config.resolve('GVR Render Target Scale') 232 * 100.0))))) + '%') # yapf: disable 233 popup.PopupMenu( 234 parent=self._root_widget, 235 position=(h_offs + 60, v - 50), 236 width=120, 237 scale=popup_menu_scale, 238 choices=['100%', '75%', '50%', '35%'], 239 current_choice=current_res_cardboard, 240 on_value_change_call=self._set_gvr_render_target_scale) 241 else: 242 native_res = _ba.get_display_resolution() 243 assert native_res is not None 244 choices = ['Auto', 'Native'] 245 choices_display = [ 246 ba.Lstr(resource='autoText'), 247 ba.Lstr(resource='nativeText') 248 ] 249 for res in [1440, 1080, 960, 720, 480]: 250 # nav bar is 72px so lets allow for that in what 251 # choices we show 252 if native_res[1] >= res - 72: 253 res_str = str(res) + 'p' 254 choices.append(res_str) 255 choices_display.append(ba.Lstr(value=res_str)) 256 current_res_android = ba.app.config.resolve( 257 'Resolution (Android)') 258 popup.PopupMenu(parent=self._root_widget, 259 position=(h_offs + 60, v - 50), 260 width=120, 261 scale=popup_menu_scale, 262 choices=choices, 263 choices_display=choices_display, 264 current_choice=current_res_android, 265 on_value_change_call=self._set_android_res) 266 else: 267 # if we're on a system that doesn't allow setting resolution, 268 # set pixel-scale instead 269 current_res = _ba.get_display_resolution() 270 if current_res is None: 271 current_res2 = (str(min(100, max(10, int(round( 272 ba.app.config.resolve('Screen Pixel Scale') 273 * 100.0))))) + '%') # yapf: disable 274 popup.PopupMenu( 275 parent=self._root_widget, 276 position=(h_offs + 60, v - 50), 277 width=120, 278 scale=popup_menu_scale, 279 choices=['100%', '88%', '75%', '63%', '50%'], 280 current_choice=current_res2, 281 on_value_change_call=self._set_pixel_scale) 282 else: 283 raise Exception('obsolete path; discrete resolutions' 284 ' no longer supported') 285 286 # vsync 287 if show_vsync: 288 ba.textwidget(parent=self._root_widget, 289 position=(230, v), 290 size=(160, 25), 291 text=ba.Lstr(resource=self._r + '.verticalSyncText'), 292 color=ba.app.ui.heading_color, 293 scale=0.65, 294 maxwidth=150, 295 h_align='center', 296 v_align='center') 297 298 popup.PopupMenu( 299 parent=self._root_widget, 300 position=(230, v - 50), 301 width=150, 302 scale=popup_menu_scale, 303 choices=['Auto', 'Always', 'Never'], 304 choices_display=[ 305 ba.Lstr(resource='autoText'), 306 ba.Lstr(resource=self._r + '.alwaysText'), 307 ba.Lstr(resource=self._r + '.neverText') 308 ], 309 current_choice=ba.app.config.resolve('Vertical Sync'), 310 on_value_change_call=self._set_vsync) 311 312 v -= 90 313 fpsc = ConfigCheckBox(parent=self._root_widget, 314 position=(69, v - 6), 315 size=(210, 30), 316 scale=0.86, 317 configkey='Show FPS', 318 displayname=ba.Lstr(resource=self._r + 319 '.showFPSText'), 320 maxwidth=130) 321 322 # (tv mode doesnt apply to vr) 323 if not ba.app.vr_mode: 324 tvc = ConfigCheckBox(parent=self._root_widget, 325 position=(240, v - 6), 326 size=(210, 30), 327 scale=0.86, 328 configkey='TV Border', 329 displayname=ba.Lstr(resource=self._r + 330 '.tvBorderText'), 331 maxwidth=130) 332 # grumble.. 333 ba.widget(edit=fpsc.widget, right_widget=tvc.widget) 334 try: 335 pass 336 337 except Exception: 338 ba.print_exception('Exception wiring up graphics settings UI:') 339 340 v -= spacing 341 342 # make a timer to update our controls in case the config changes 343 # under us 344 self._update_timer = ba.Timer(0.25, 345 ba.WeakCall(self._update_controls), 346 repeat=True, 347 timetype=ba.TimeType.REAL) 348 349 def _back(self) -> None: 350 from bastd.ui.settings import allsettings 351 ba.containerwidget(edit=self._root_widget, 352 transition=self._transition_out) 353 ba.app.ui.set_main_menu_window( 354 allsettings.AllSettingsWindow( 355 transition='in_left').get_root_widget()) 356 357 def _set_quality(self, quality: str) -> None: 358 cfg = ba.app.config 359 cfg['Graphics Quality'] = quality 360 cfg.apply_and_commit() 361 362 def _set_textures(self, val: str) -> None: 363 cfg = ba.app.config 364 cfg['Texture Quality'] = val 365 cfg.apply_and_commit() 366 367 def _set_android_res(self, val: str) -> None: 368 cfg = ba.app.config 369 cfg['Resolution (Android)'] = val 370 cfg.apply_and_commit() 371 372 def _set_pixel_scale(self, res: str) -> None: 373 cfg = ba.app.config 374 cfg['Screen Pixel Scale'] = float(res[:-1]) / 100.0 375 cfg.apply_and_commit() 376 377 def _set_gvr_render_target_scale(self, res: str) -> None: 378 cfg = ba.app.config 379 cfg['GVR Render Target Scale'] = float(res[:-1]) / 100.0 380 cfg.apply_and_commit() 381 382 def _set_vsync(self, val: str) -> None: 383 cfg = ba.app.config 384 cfg['Vertical Sync'] = val 385 cfg.apply_and_commit() 386 387 def _update_controls(self) -> None: 388 if self._show_fullscreen: 389 ba.checkboxwidget(edit=self._fullscreen_checkbox, 390 value=ba.app.config.resolve('Fullscreen'))
Window for graphics settings.
GraphicsSettingsWindow( transition: str = 'in_right', origin_widget: _ba.Widget | None = None)
20 def __init__(self, 21 transition: str = 'in_right', 22 origin_widget: ba.Widget | None = None): 23 # pylint: disable=too-many-locals 24 # pylint: disable=too-many-branches 25 # pylint: disable=too-many-statements 26 from bastd.ui import popup 27 from bastd.ui.config import ConfigCheckBox, ConfigNumberEdit 28 # if they provided an origin-widget, scale up from that 29 scale_origin: tuple[float, float] | None 30 if origin_widget is not None: 31 self._transition_out = 'out_scale' 32 scale_origin = origin_widget.get_screen_space_center() 33 transition = 'in_scale' 34 else: 35 self._transition_out = 'out_right' 36 scale_origin = None 37 38 self._r = 'graphicsSettingsWindow' 39 app = ba.app 40 41 spacing = 32 42 self._have_selected_child = False 43 uiscale = app.ui.uiscale 44 width = 450.0 45 height = 302.0 46 47 self._show_fullscreen = False 48 fullscreen_spacing_top = spacing * 0.2 49 fullscreen_spacing = spacing * 1.2 50 if uiscale == ba.UIScale.LARGE and app.platform != 'android': 51 self._show_fullscreen = True 52 height += fullscreen_spacing + fullscreen_spacing_top 53 54 show_gamma = False 55 gamma_spacing = spacing * 1.3 56 if _ba.has_gamma_control(): 57 show_gamma = True 58 height += gamma_spacing 59 60 show_vsync = False 61 if app.platform == 'mac': 62 show_vsync = True 63 64 show_resolution = True 65 if app.vr_mode: 66 show_resolution = (app.platform == 'android' 67 and app.subplatform == 'cardboard') 68 69 uiscale = ba.app.ui.uiscale 70 base_scale = (2.4 if uiscale is ba.UIScale.SMALL else 71 1.5 if uiscale is ba.UIScale.MEDIUM else 1.0) 72 popup_menu_scale = base_scale * 1.2 73 v = height - 50 74 v -= spacing * 1.15 75 super().__init__(root_widget=ba.containerwidget( 76 size=(width, height), 77 transition=transition, 78 scale_origin_stack_offset=scale_origin, 79 scale=base_scale, 80 stack_offset=(0, -30) if uiscale is ba.UIScale.SMALL else (0, 0))) 81 82 btn = ba.buttonwidget(parent=self._root_widget, 83 position=(35, height - 50), 84 size=(120, 60), 85 scale=0.8, 86 text_scale=1.2, 87 autoselect=True, 88 label=ba.Lstr(resource='backText'), 89 button_type='back', 90 on_activate_call=self._back) 91 92 ba.containerwidget(edit=self._root_widget, cancel_button=btn) 93 94 ba.textwidget(parent=self._root_widget, 95 position=(0, height - 44), 96 size=(width, 25), 97 text=ba.Lstr(resource=self._r + '.titleText'), 98 color=ba.app.ui.title_color, 99 h_align='center', 100 v_align='top') 101 102 ba.buttonwidget(edit=btn, 103 button_type='backSmall', 104 size=(60, 60), 105 label=ba.charstr(ba.SpecialChar.BACK)) 106 107 self._fullscreen_checkbox: ba.Widget | None 108 if self._show_fullscreen: 109 v -= fullscreen_spacing_top 110 self._fullscreen_checkbox = ConfigCheckBox( 111 parent=self._root_widget, 112 position=(100, v), 113 maxwidth=200, 114 size=(300, 30), 115 configkey='Fullscreen', 116 displayname=ba.Lstr(resource=self._r + 117 ('.fullScreenCmdText' if app.platform == 118 'mac' else '.fullScreenCtrlText'))).widget 119 if not self._have_selected_child: 120 ba.containerwidget(edit=self._root_widget, 121 selected_child=self._fullscreen_checkbox) 122 self._have_selected_child = True 123 v -= fullscreen_spacing 124 else: 125 self._fullscreen_checkbox = None 126 127 self._gamma_controls: ConfigNumberEdit | None 128 if show_gamma: 129 self._gamma_controls = gmc = ConfigNumberEdit( 130 parent=self._root_widget, 131 position=(90, v), 132 configkey='Screen Gamma', 133 displayname=ba.Lstr(resource=self._r + '.gammaText'), 134 minval=0.1, 135 maxval=2.0, 136 increment=0.1, 137 xoffset=-70, 138 textscale=0.85) 139 if ba.app.ui.use_toolbars: 140 ba.widget(edit=gmc.plusbutton, 141 right_widget=_ba.get_special_widget('party_button')) 142 if not self._have_selected_child: 143 ba.containerwidget(edit=self._root_widget, 144 selected_child=gmc.minusbutton) 145 self._have_selected_child = True 146 v -= gamma_spacing 147 else: 148 self._gamma_controls = None 149 150 self._selected_color = (0.5, 1, 0.5, 1) 151 self._unselected_color = (0.7, 0.7, 0.7, 1) 152 153 # quality 154 ba.textwidget(parent=self._root_widget, 155 position=(60, v), 156 size=(160, 25), 157 text=ba.Lstr(resource=self._r + '.visualsText'), 158 color=ba.app.ui.heading_color, 159 scale=0.65, 160 maxwidth=150, 161 h_align='center', 162 v_align='center') 163 popup.PopupMenu( 164 parent=self._root_widget, 165 position=(60, v - 50), 166 width=150, 167 scale=popup_menu_scale, 168 choices=['Auto', 'Higher', 'High', 'Medium', 'Low'], 169 choices_disabled=['Higher', 'High'] 170 if _ba.get_max_graphics_quality() == 'Medium' else [], 171 choices_display=[ 172 ba.Lstr(resource='autoText'), 173 ba.Lstr(resource=self._r + '.higherText'), 174 ba.Lstr(resource=self._r + '.highText'), 175 ba.Lstr(resource=self._r + '.mediumText'), 176 ba.Lstr(resource=self._r + '.lowText') 177 ], 178 current_choice=ba.app.config.resolve('Graphics Quality'), 179 on_value_change_call=self._set_quality) 180 181 # texture controls 182 ba.textwidget(parent=self._root_widget, 183 position=(230, v), 184 size=(160, 25), 185 text=ba.Lstr(resource=self._r + '.texturesText'), 186 color=ba.app.ui.heading_color, 187 scale=0.65, 188 maxwidth=150, 189 h_align='center', 190 v_align='center') 191 textures_popup = popup.PopupMenu( 192 parent=self._root_widget, 193 position=(230, v - 50), 194 width=150, 195 scale=popup_menu_scale, 196 choices=['Auto', 'High', 'Medium', 'Low'], 197 choices_display=[ 198 ba.Lstr(resource='autoText'), 199 ba.Lstr(resource=self._r + '.highText'), 200 ba.Lstr(resource=self._r + '.mediumText'), 201 ba.Lstr(resource=self._r + '.lowText') 202 ], 203 current_choice=ba.app.config.resolve('Texture Quality'), 204 on_value_change_call=self._set_textures) 205 if ba.app.ui.use_toolbars: 206 ba.widget(edit=textures_popup.get_button(), 207 right_widget=_ba.get_special_widget('party_button')) 208 v -= 80 209 210 h_offs = 0 211 212 if show_resolution: 213 # resolution 214 ba.textwidget(parent=self._root_widget, 215 position=(h_offs + 60, v), 216 size=(160, 25), 217 text=ba.Lstr(resource=self._r + '.resolutionText'), 218 color=ba.app.ui.heading_color, 219 scale=0.65, 220 maxwidth=150, 221 h_align='center', 222 v_align='center') 223 224 # on standard android we have 'Auto', 'Native', and a few 225 # HD standards 226 if app.platform == 'android': 227 # on cardboard/daydream android we have a few 228 # render-target-scale options 229 if app.subplatform == 'cardboard': 230 current_res_cardboard = (str(min(100, max(10, int(round( 231 ba.app.config.resolve('GVR Render Target Scale') 232 * 100.0))))) + '%') # yapf: disable 233 popup.PopupMenu( 234 parent=self._root_widget, 235 position=(h_offs + 60, v - 50), 236 width=120, 237 scale=popup_menu_scale, 238 choices=['100%', '75%', '50%', '35%'], 239 current_choice=current_res_cardboard, 240 on_value_change_call=self._set_gvr_render_target_scale) 241 else: 242 native_res = _ba.get_display_resolution() 243 assert native_res is not None 244 choices = ['Auto', 'Native'] 245 choices_display = [ 246 ba.Lstr(resource='autoText'), 247 ba.Lstr(resource='nativeText') 248 ] 249 for res in [1440, 1080, 960, 720, 480]: 250 # nav bar is 72px so lets allow for that in what 251 # choices we show 252 if native_res[1] >= res - 72: 253 res_str = str(res) + 'p' 254 choices.append(res_str) 255 choices_display.append(ba.Lstr(value=res_str)) 256 current_res_android = ba.app.config.resolve( 257 'Resolution (Android)') 258 popup.PopupMenu(parent=self._root_widget, 259 position=(h_offs + 60, v - 50), 260 width=120, 261 scale=popup_menu_scale, 262 choices=choices, 263 choices_display=choices_display, 264 current_choice=current_res_android, 265 on_value_change_call=self._set_android_res) 266 else: 267 # if we're on a system that doesn't allow setting resolution, 268 # set pixel-scale instead 269 current_res = _ba.get_display_resolution() 270 if current_res is None: 271 current_res2 = (str(min(100, max(10, int(round( 272 ba.app.config.resolve('Screen Pixel Scale') 273 * 100.0))))) + '%') # yapf: disable 274 popup.PopupMenu( 275 parent=self._root_widget, 276 position=(h_offs + 60, v - 50), 277 width=120, 278 scale=popup_menu_scale, 279 choices=['100%', '88%', '75%', '63%', '50%'], 280 current_choice=current_res2, 281 on_value_change_call=self._set_pixel_scale) 282 else: 283 raise Exception('obsolete path; discrete resolutions' 284 ' no longer supported') 285 286 # vsync 287 if show_vsync: 288 ba.textwidget(parent=self._root_widget, 289 position=(230, v), 290 size=(160, 25), 291 text=ba.Lstr(resource=self._r + '.verticalSyncText'), 292 color=ba.app.ui.heading_color, 293 scale=0.65, 294 maxwidth=150, 295 h_align='center', 296 v_align='center') 297 298 popup.PopupMenu( 299 parent=self._root_widget, 300 position=(230, v - 50), 301 width=150, 302 scale=popup_menu_scale, 303 choices=['Auto', 'Always', 'Never'], 304 choices_display=[ 305 ba.Lstr(resource='autoText'), 306 ba.Lstr(resource=self._r + '.alwaysText'), 307 ba.Lstr(resource=self._r + '.neverText') 308 ], 309 current_choice=ba.app.config.resolve('Vertical Sync'), 310 on_value_change_call=self._set_vsync) 311 312 v -= 90 313 fpsc = ConfigCheckBox(parent=self._root_widget, 314 position=(69, v - 6), 315 size=(210, 30), 316 scale=0.86, 317 configkey='Show FPS', 318 displayname=ba.Lstr(resource=self._r + 319 '.showFPSText'), 320 maxwidth=130) 321 322 # (tv mode doesnt apply to vr) 323 if not ba.app.vr_mode: 324 tvc = ConfigCheckBox(parent=self._root_widget, 325 position=(240, v - 6), 326 size=(210, 30), 327 scale=0.86, 328 configkey='TV Border', 329 displayname=ba.Lstr(resource=self._r + 330 '.tvBorderText'), 331 maxwidth=130) 332 # grumble.. 333 ba.widget(edit=fpsc.widget, right_widget=tvc.widget) 334 try: 335 pass 336 337 except Exception: 338 ba.print_exception('Exception wiring up graphics settings UI:') 339 340 v -= spacing 341 342 # make a timer to update our controls in case the config changes 343 # under us 344 self._update_timer = ba.Timer(0.25, 345 ba.WeakCall(self._update_controls), 346 repeat=True, 347 timetype=ba.TimeType.REAL)
Inherited Members
- ba.ui.Window
- get_root_widget