bastd.ui.settings.controls
Provides a top level control settings window.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Provides a top level control settings window.""" 4 5from __future__ import annotations 6 7from typing import TYPE_CHECKING 8 9import ba 10import ba.internal 11 12if TYPE_CHECKING: 13 pass 14 15 16class ControlsSettingsWindow(ba.Window): 17 """Top level control settings window.""" 18 19 def __init__( 20 self, 21 transition: str = 'in_right', 22 origin_widget: ba.Widget | None = None, 23 ): 24 # FIXME: should tidy up here. 25 # pylint: disable=too-many-statements 26 # pylint: disable=too-many-branches 27 # pylint: disable=too-many-locals 28 # pylint: disable=cyclic-import 29 from bastd.ui import popup as popup_ui 30 31 self._have_selected_child = False 32 33 scale_origin: tuple[float, float] | None 34 35 # If they provided an origin-widget, scale up from that. 36 if origin_widget is not None: 37 self._transition_out = 'out_scale' 38 scale_origin = origin_widget.get_screen_space_center() 39 transition = 'in_scale' 40 else: 41 self._transition_out = 'out_right' 42 scale_origin = None 43 44 self._r = 'configControllersWindow' 45 app = ba.app 46 47 # is_fire_tv = ba.internal.is_running_on_fire_tv() 48 49 spacing = 50.0 50 button_width = 350.0 51 width = 460.0 52 height = 130.0 53 54 space_height = spacing * 0.3 55 56 # FIXME: should create vis settings in platform for these, 57 # not hard code them here. 58 59 show_gamepads = False 60 platform = app.platform 61 subplatform = app.subplatform 62 non_vr_windows = platform == 'windows' and ( 63 subplatform != 'oculus' or not app.vr_mode 64 ) 65 if platform in ('linux', 'android', 'mac') or non_vr_windows: 66 show_gamepads = True 67 height += spacing 68 69 show_touch = False 70 if ba.internal.have_touchscreen_input(): 71 show_touch = True 72 height += spacing 73 74 show_space_1 = False 75 if show_gamepads or show_touch: 76 show_space_1 = True 77 height += space_height 78 79 show_keyboard = False 80 if ( 81 ba.internal.getinputdevice('Keyboard', '#1', doraise=False) 82 is not None 83 ): 84 show_keyboard = True 85 height += spacing 86 show_keyboard_p2 = False if app.vr_mode else show_keyboard 87 if show_keyboard_p2: 88 height += spacing 89 90 show_space_2 = False 91 if show_keyboard: 92 show_space_2 = True 93 height += space_height 94 95 if bool(True): 96 show_remote = True 97 height += spacing 98 else: 99 show_remote = False 100 101 # On windows (outside of oculus/vr), show an option to disable xinput. 102 show_xinput_toggle = False 103 if platform == 'windows' and not app.vr_mode: 104 show_xinput_toggle = True 105 106 # On mac builds, show an option to switch between generic and 107 # made-for-iOS/Mac systems 108 # (we can run into problems where devices register as one of each 109 # type otherwise).. 110 show_mac_controller_subsystem = False 111 if platform == 'mac' and ba.internal.is_xcode_build(): 112 show_mac_controller_subsystem = True 113 114 if show_mac_controller_subsystem: 115 height += spacing * 1.5 116 117 if show_xinput_toggle: 118 height += spacing 119 120 uiscale = ba.app.ui.uiscale 121 smallscale = 1.7 if show_keyboard else 2.2 122 super().__init__( 123 root_widget=ba.containerwidget( 124 size=(width, height), 125 transition=transition, 126 scale_origin_stack_offset=scale_origin, 127 stack_offset=( 128 (0, -10) if uiscale is ba.UIScale.SMALL else (0, 0) 129 ), 130 scale=( 131 smallscale 132 if uiscale is ba.UIScale.SMALL 133 else 1.5 134 if uiscale is ba.UIScale.MEDIUM 135 else 1.0 136 ), 137 ) 138 ) 139 self._back_button = btn = ba.buttonwidget( 140 parent=self._root_widget, 141 position=(35, height - 60), 142 size=(140, 65), 143 scale=0.8, 144 text_scale=1.2, 145 autoselect=True, 146 label=ba.Lstr(resource='backText'), 147 button_type='back', 148 on_activate_call=self._back, 149 ) 150 ba.containerwidget(edit=self._root_widget, cancel_button=btn) 151 152 # We need these vars to exist even if the buttons don't. 153 self._gamepads_button: ba.Widget | None = None 154 self._touch_button: ba.Widget | None = None 155 self._keyboard_button: ba.Widget | None = None 156 self._keyboard_2_button: ba.Widget | None = None 157 self._idevices_button: ba.Widget | None = None 158 159 ba.textwidget( 160 parent=self._root_widget, 161 position=(0, height - 49), 162 size=(width, 25), 163 text=ba.Lstr(resource=self._r + '.titleText'), 164 color=ba.app.ui.title_color, 165 h_align='center', 166 v_align='top', 167 ) 168 ba.buttonwidget( 169 edit=btn, 170 button_type='backSmall', 171 size=(60, 60), 172 label=ba.charstr(ba.SpecialChar.BACK), 173 ) 174 175 v = height - 75 176 v -= spacing 177 178 if show_touch: 179 self._touch_button = btn = ba.buttonwidget( 180 parent=self._root_widget, 181 position=((width - button_width) / 2, v), 182 size=(button_width, 43), 183 autoselect=True, 184 label=ba.Lstr(resource=self._r + '.configureTouchText'), 185 on_activate_call=self._do_touchscreen, 186 ) 187 if ba.app.ui.use_toolbars: 188 ba.widget( 189 edit=btn, 190 right_widget=ba.internal.get_special_widget('party_button'), 191 ) 192 if not self._have_selected_child: 193 ba.containerwidget( 194 edit=self._root_widget, selected_child=self._touch_button 195 ) 196 ba.widget( 197 edit=self._back_button, down_widget=self._touch_button 198 ) 199 self._have_selected_child = True 200 v -= spacing 201 202 if show_gamepads: 203 self._gamepads_button = btn = ba.buttonwidget( 204 parent=self._root_widget, 205 position=((width - button_width) / 2 - 7, v), 206 size=(button_width, 43), 207 autoselect=True, 208 label=ba.Lstr(resource=self._r + '.configureControllersText'), 209 on_activate_call=self._do_gamepads, 210 ) 211 if ba.app.ui.use_toolbars: 212 ba.widget( 213 edit=btn, 214 right_widget=ba.internal.get_special_widget('party_button'), 215 ) 216 if not self._have_selected_child: 217 ba.containerwidget( 218 edit=self._root_widget, selected_child=self._gamepads_button 219 ) 220 ba.widget( 221 edit=self._back_button, down_widget=self._gamepads_button 222 ) 223 self._have_selected_child = True 224 v -= spacing 225 else: 226 self._gamepads_button = None 227 228 if show_space_1: 229 v -= space_height 230 231 if show_keyboard: 232 self._keyboard_button = btn = ba.buttonwidget( 233 parent=self._root_widget, 234 position=((width - button_width) / 2 + 5, v), 235 size=(button_width, 43), 236 autoselect=True, 237 label=ba.Lstr(resource=self._r + '.configureKeyboardText'), 238 on_activate_call=self._config_keyboard, 239 ) 240 if ba.app.ui.use_toolbars: 241 ba.widget( 242 edit=btn, 243 right_widget=ba.internal.get_special_widget('party_button'), 244 ) 245 if not self._have_selected_child: 246 ba.containerwidget( 247 edit=self._root_widget, selected_child=self._keyboard_button 248 ) 249 ba.widget( 250 edit=self._back_button, down_widget=self._keyboard_button 251 ) 252 self._have_selected_child = True 253 v -= spacing 254 if show_keyboard_p2: 255 self._keyboard_2_button = ba.buttonwidget( 256 parent=self._root_widget, 257 position=((width - button_width) / 2 - 3, v), 258 size=(button_width, 43), 259 autoselect=True, 260 label=ba.Lstr(resource=self._r + '.configureKeyboard2Text'), 261 on_activate_call=self._config_keyboard2, 262 ) 263 v -= spacing 264 if show_space_2: 265 v -= space_height 266 if show_remote: 267 self._idevices_button = btn = ba.buttonwidget( 268 parent=self._root_widget, 269 position=((width - button_width) / 2 - 5, v), 270 size=(button_width, 43), 271 autoselect=True, 272 label=ba.Lstr(resource=self._r + '.configureMobileText'), 273 on_activate_call=self._do_mobile_devices, 274 ) 275 if ba.app.ui.use_toolbars: 276 ba.widget( 277 edit=btn, 278 right_widget=ba.internal.get_special_widget('party_button'), 279 ) 280 if not self._have_selected_child: 281 ba.containerwidget( 282 edit=self._root_widget, selected_child=self._idevices_button 283 ) 284 ba.widget( 285 edit=self._back_button, down_widget=self._idevices_button 286 ) 287 self._have_selected_child = True 288 v -= spacing 289 290 if show_xinput_toggle: 291 292 def do_toggle(value: bool) -> None: 293 ba.screenmessage( 294 ba.Lstr(resource='settingsWindowAdvanced.mustRestartText'), 295 color=(1, 1, 0), 296 ) 297 ba.playsound(ba.getsound('gunCocking')) 298 ba.internal.set_low_level_config_value( 299 'enablexinput', not value 300 ) 301 302 ba.checkboxwidget( 303 parent=self._root_widget, 304 position=(100, v + 3), 305 size=(120, 30), 306 value=( 307 not ba.internal.get_low_level_config_value( 308 'enablexinput', 1 309 ) 310 ), 311 maxwidth=200, 312 on_value_change_call=do_toggle, 313 text=ba.Lstr(resource='disableXInputText'), 314 autoselect=True, 315 ) 316 ba.textwidget( 317 parent=self._root_widget, 318 position=(width * 0.5, v - 5), 319 size=(0, 0), 320 text=ba.Lstr(resource='disableXInputDescriptionText'), 321 scale=0.5, 322 h_align='center', 323 v_align='center', 324 color=ba.app.ui.infotextcolor, 325 maxwidth=width * 0.8, 326 ) 327 v -= spacing 328 if show_mac_controller_subsystem: 329 popup_ui.PopupMenu( 330 parent=self._root_widget, 331 position=(260, v - 10), 332 width=160, 333 button_size=(150, 50), 334 scale=1.5, 335 choices=['Classic', 'MFi', 'Both'], 336 choices_display=[ 337 ba.Lstr(resource='macControllerSubsystemClassicText'), 338 ba.Lstr(resource='macControllerSubsystemMFiText'), 339 ba.Lstr(resource='macControllerSubsystemBothText'), 340 ], 341 current_choice=ba.app.config.resolve( 342 'Mac Controller Subsystem' 343 ), 344 on_value_change_call=self._set_mac_controller_subsystem, 345 ) 346 ba.textwidget( 347 parent=self._root_widget, 348 position=(245, v + 13), 349 size=(0, 0), 350 text=ba.Lstr(resource='macControllerSubsystemTitleText'), 351 scale=1.0, 352 h_align='right', 353 v_align='center', 354 color=ba.app.ui.infotextcolor, 355 maxwidth=180, 356 ) 357 ba.textwidget( 358 parent=self._root_widget, 359 position=(width * 0.5, v - 20), 360 size=(0, 0), 361 text=ba.Lstr(resource='macControllerSubsystemDescriptionText'), 362 scale=0.5, 363 h_align='center', 364 v_align='center', 365 color=ba.app.ui.infotextcolor, 366 maxwidth=width * 0.8, 367 ) 368 v -= spacing * 1.5 369 self._restore_state() 370 371 def _set_mac_controller_subsystem(self, val: str) -> None: 372 cfg = ba.app.config 373 cfg['Mac Controller Subsystem'] = val 374 cfg.apply_and_commit() 375 376 def _config_keyboard(self) -> None: 377 # pylint: disable=cyclic-import 378 from bastd.ui.settings.keyboard import ConfigKeyboardWindow 379 380 self._save_state() 381 ba.containerwidget(edit=self._root_widget, transition='out_left') 382 ba.app.ui.set_main_menu_window( 383 ConfigKeyboardWindow( 384 ba.internal.getinputdevice('Keyboard', '#1') 385 ).get_root_widget() 386 ) 387 388 def _config_keyboard2(self) -> None: 389 # pylint: disable=cyclic-import 390 from bastd.ui.settings.keyboard import ConfigKeyboardWindow 391 392 self._save_state() 393 ba.containerwidget(edit=self._root_widget, transition='out_left') 394 ba.app.ui.set_main_menu_window( 395 ConfigKeyboardWindow( 396 ba.internal.getinputdevice('Keyboard', '#2') 397 ).get_root_widget() 398 ) 399 400 def _do_mobile_devices(self) -> None: 401 # pylint: disable=cyclic-import 402 from bastd.ui.settings.remoteapp import RemoteAppSettingsWindow 403 404 self._save_state() 405 ba.containerwidget(edit=self._root_widget, transition='out_left') 406 ba.app.ui.set_main_menu_window( 407 RemoteAppSettingsWindow().get_root_widget() 408 ) 409 410 def _do_gamepads(self) -> None: 411 # pylint: disable=cyclic-import 412 from bastd.ui.settings.gamepadselect import GamepadSelectWindow 413 414 self._save_state() 415 ba.containerwidget(edit=self._root_widget, transition='out_left') 416 ba.app.ui.set_main_menu_window(GamepadSelectWindow().get_root_widget()) 417 418 def _do_touchscreen(self) -> None: 419 # pylint: disable=cyclic-import 420 from bastd.ui.settings.touchscreen import TouchscreenSettingsWindow 421 422 self._save_state() 423 ba.containerwidget(edit=self._root_widget, transition='out_left') 424 ba.app.ui.set_main_menu_window( 425 TouchscreenSettingsWindow().get_root_widget() 426 ) 427 428 def _save_state(self) -> None: 429 sel = self._root_widget.get_selected_child() 430 if sel == self._gamepads_button: 431 sel_name = 'GamePads' 432 elif sel == self._touch_button: 433 sel_name = 'Touch' 434 elif sel == self._keyboard_button: 435 sel_name = 'Keyboard' 436 elif sel == self._keyboard_2_button: 437 sel_name = 'Keyboard2' 438 elif sel == self._idevices_button: 439 sel_name = 'iDevices' 440 else: 441 sel_name = 'Back' 442 ba.app.ui.window_states[type(self)] = sel_name 443 444 def _restore_state(self) -> None: 445 sel_name = ba.app.ui.window_states.get(type(self)) 446 if sel_name == 'GamePads': 447 sel = self._gamepads_button 448 elif sel_name == 'Touch': 449 sel = self._touch_button 450 elif sel_name == 'Keyboard': 451 sel = self._keyboard_button 452 elif sel_name == 'Keyboard2': 453 sel = self._keyboard_2_button 454 elif sel_name == 'iDevices': 455 sel = self._idevices_button 456 elif sel_name == 'Back': 457 sel = self._back_button 458 else: 459 sel = ( 460 self._gamepads_button 461 if self._gamepads_button is not None 462 else self._back_button 463 ) 464 ba.containerwidget(edit=self._root_widget, selected_child=sel) 465 466 def _back(self) -> None: 467 # pylint: disable=cyclic-import 468 from bastd.ui.settings.allsettings import AllSettingsWindow 469 470 self._save_state() 471 ba.containerwidget( 472 edit=self._root_widget, transition=self._transition_out 473 ) 474 ba.app.ui.set_main_menu_window( 475 AllSettingsWindow(transition='in_left').get_root_widget() 476 )
class
ControlsSettingsWindow(ba.ui.Window):
17class ControlsSettingsWindow(ba.Window): 18 """Top level control settings window.""" 19 20 def __init__( 21 self, 22 transition: str = 'in_right', 23 origin_widget: ba.Widget | None = None, 24 ): 25 # FIXME: should tidy up here. 26 # pylint: disable=too-many-statements 27 # pylint: disable=too-many-branches 28 # pylint: disable=too-many-locals 29 # pylint: disable=cyclic-import 30 from bastd.ui import popup as popup_ui 31 32 self._have_selected_child = False 33 34 scale_origin: tuple[float, float] | None 35 36 # If they provided an origin-widget, scale up from that. 37 if origin_widget is not None: 38 self._transition_out = 'out_scale' 39 scale_origin = origin_widget.get_screen_space_center() 40 transition = 'in_scale' 41 else: 42 self._transition_out = 'out_right' 43 scale_origin = None 44 45 self._r = 'configControllersWindow' 46 app = ba.app 47 48 # is_fire_tv = ba.internal.is_running_on_fire_tv() 49 50 spacing = 50.0 51 button_width = 350.0 52 width = 460.0 53 height = 130.0 54 55 space_height = spacing * 0.3 56 57 # FIXME: should create vis settings in platform for these, 58 # not hard code them here. 59 60 show_gamepads = False 61 platform = app.platform 62 subplatform = app.subplatform 63 non_vr_windows = platform == 'windows' and ( 64 subplatform != 'oculus' or not app.vr_mode 65 ) 66 if platform in ('linux', 'android', 'mac') or non_vr_windows: 67 show_gamepads = True 68 height += spacing 69 70 show_touch = False 71 if ba.internal.have_touchscreen_input(): 72 show_touch = True 73 height += spacing 74 75 show_space_1 = False 76 if show_gamepads or show_touch: 77 show_space_1 = True 78 height += space_height 79 80 show_keyboard = False 81 if ( 82 ba.internal.getinputdevice('Keyboard', '#1', doraise=False) 83 is not None 84 ): 85 show_keyboard = True 86 height += spacing 87 show_keyboard_p2 = False if app.vr_mode else show_keyboard 88 if show_keyboard_p2: 89 height += spacing 90 91 show_space_2 = False 92 if show_keyboard: 93 show_space_2 = True 94 height += space_height 95 96 if bool(True): 97 show_remote = True 98 height += spacing 99 else: 100 show_remote = False 101 102 # On windows (outside of oculus/vr), show an option to disable xinput. 103 show_xinput_toggle = False 104 if platform == 'windows' and not app.vr_mode: 105 show_xinput_toggle = True 106 107 # On mac builds, show an option to switch between generic and 108 # made-for-iOS/Mac systems 109 # (we can run into problems where devices register as one of each 110 # type otherwise).. 111 show_mac_controller_subsystem = False 112 if platform == 'mac' and ba.internal.is_xcode_build(): 113 show_mac_controller_subsystem = True 114 115 if show_mac_controller_subsystem: 116 height += spacing * 1.5 117 118 if show_xinput_toggle: 119 height += spacing 120 121 uiscale = ba.app.ui.uiscale 122 smallscale = 1.7 if show_keyboard else 2.2 123 super().__init__( 124 root_widget=ba.containerwidget( 125 size=(width, height), 126 transition=transition, 127 scale_origin_stack_offset=scale_origin, 128 stack_offset=( 129 (0, -10) if uiscale is ba.UIScale.SMALL else (0, 0) 130 ), 131 scale=( 132 smallscale 133 if uiscale is ba.UIScale.SMALL 134 else 1.5 135 if uiscale is ba.UIScale.MEDIUM 136 else 1.0 137 ), 138 ) 139 ) 140 self._back_button = btn = ba.buttonwidget( 141 parent=self._root_widget, 142 position=(35, height - 60), 143 size=(140, 65), 144 scale=0.8, 145 text_scale=1.2, 146 autoselect=True, 147 label=ba.Lstr(resource='backText'), 148 button_type='back', 149 on_activate_call=self._back, 150 ) 151 ba.containerwidget(edit=self._root_widget, cancel_button=btn) 152 153 # We need these vars to exist even if the buttons don't. 154 self._gamepads_button: ba.Widget | None = None 155 self._touch_button: ba.Widget | None = None 156 self._keyboard_button: ba.Widget | None = None 157 self._keyboard_2_button: ba.Widget | None = None 158 self._idevices_button: ba.Widget | None = None 159 160 ba.textwidget( 161 parent=self._root_widget, 162 position=(0, height - 49), 163 size=(width, 25), 164 text=ba.Lstr(resource=self._r + '.titleText'), 165 color=ba.app.ui.title_color, 166 h_align='center', 167 v_align='top', 168 ) 169 ba.buttonwidget( 170 edit=btn, 171 button_type='backSmall', 172 size=(60, 60), 173 label=ba.charstr(ba.SpecialChar.BACK), 174 ) 175 176 v = height - 75 177 v -= spacing 178 179 if show_touch: 180 self._touch_button = btn = ba.buttonwidget( 181 parent=self._root_widget, 182 position=((width - button_width) / 2, v), 183 size=(button_width, 43), 184 autoselect=True, 185 label=ba.Lstr(resource=self._r + '.configureTouchText'), 186 on_activate_call=self._do_touchscreen, 187 ) 188 if ba.app.ui.use_toolbars: 189 ba.widget( 190 edit=btn, 191 right_widget=ba.internal.get_special_widget('party_button'), 192 ) 193 if not self._have_selected_child: 194 ba.containerwidget( 195 edit=self._root_widget, selected_child=self._touch_button 196 ) 197 ba.widget( 198 edit=self._back_button, down_widget=self._touch_button 199 ) 200 self._have_selected_child = True 201 v -= spacing 202 203 if show_gamepads: 204 self._gamepads_button = btn = ba.buttonwidget( 205 parent=self._root_widget, 206 position=((width - button_width) / 2 - 7, v), 207 size=(button_width, 43), 208 autoselect=True, 209 label=ba.Lstr(resource=self._r + '.configureControllersText'), 210 on_activate_call=self._do_gamepads, 211 ) 212 if ba.app.ui.use_toolbars: 213 ba.widget( 214 edit=btn, 215 right_widget=ba.internal.get_special_widget('party_button'), 216 ) 217 if not self._have_selected_child: 218 ba.containerwidget( 219 edit=self._root_widget, selected_child=self._gamepads_button 220 ) 221 ba.widget( 222 edit=self._back_button, down_widget=self._gamepads_button 223 ) 224 self._have_selected_child = True 225 v -= spacing 226 else: 227 self._gamepads_button = None 228 229 if show_space_1: 230 v -= space_height 231 232 if show_keyboard: 233 self._keyboard_button = btn = ba.buttonwidget( 234 parent=self._root_widget, 235 position=((width - button_width) / 2 + 5, v), 236 size=(button_width, 43), 237 autoselect=True, 238 label=ba.Lstr(resource=self._r + '.configureKeyboardText'), 239 on_activate_call=self._config_keyboard, 240 ) 241 if ba.app.ui.use_toolbars: 242 ba.widget( 243 edit=btn, 244 right_widget=ba.internal.get_special_widget('party_button'), 245 ) 246 if not self._have_selected_child: 247 ba.containerwidget( 248 edit=self._root_widget, selected_child=self._keyboard_button 249 ) 250 ba.widget( 251 edit=self._back_button, down_widget=self._keyboard_button 252 ) 253 self._have_selected_child = True 254 v -= spacing 255 if show_keyboard_p2: 256 self._keyboard_2_button = ba.buttonwidget( 257 parent=self._root_widget, 258 position=((width - button_width) / 2 - 3, v), 259 size=(button_width, 43), 260 autoselect=True, 261 label=ba.Lstr(resource=self._r + '.configureKeyboard2Text'), 262 on_activate_call=self._config_keyboard2, 263 ) 264 v -= spacing 265 if show_space_2: 266 v -= space_height 267 if show_remote: 268 self._idevices_button = btn = ba.buttonwidget( 269 parent=self._root_widget, 270 position=((width - button_width) / 2 - 5, v), 271 size=(button_width, 43), 272 autoselect=True, 273 label=ba.Lstr(resource=self._r + '.configureMobileText'), 274 on_activate_call=self._do_mobile_devices, 275 ) 276 if ba.app.ui.use_toolbars: 277 ba.widget( 278 edit=btn, 279 right_widget=ba.internal.get_special_widget('party_button'), 280 ) 281 if not self._have_selected_child: 282 ba.containerwidget( 283 edit=self._root_widget, selected_child=self._idevices_button 284 ) 285 ba.widget( 286 edit=self._back_button, down_widget=self._idevices_button 287 ) 288 self._have_selected_child = True 289 v -= spacing 290 291 if show_xinput_toggle: 292 293 def do_toggle(value: bool) -> None: 294 ba.screenmessage( 295 ba.Lstr(resource='settingsWindowAdvanced.mustRestartText'), 296 color=(1, 1, 0), 297 ) 298 ba.playsound(ba.getsound('gunCocking')) 299 ba.internal.set_low_level_config_value( 300 'enablexinput', not value 301 ) 302 303 ba.checkboxwidget( 304 parent=self._root_widget, 305 position=(100, v + 3), 306 size=(120, 30), 307 value=( 308 not ba.internal.get_low_level_config_value( 309 'enablexinput', 1 310 ) 311 ), 312 maxwidth=200, 313 on_value_change_call=do_toggle, 314 text=ba.Lstr(resource='disableXInputText'), 315 autoselect=True, 316 ) 317 ba.textwidget( 318 parent=self._root_widget, 319 position=(width * 0.5, v - 5), 320 size=(0, 0), 321 text=ba.Lstr(resource='disableXInputDescriptionText'), 322 scale=0.5, 323 h_align='center', 324 v_align='center', 325 color=ba.app.ui.infotextcolor, 326 maxwidth=width * 0.8, 327 ) 328 v -= spacing 329 if show_mac_controller_subsystem: 330 popup_ui.PopupMenu( 331 parent=self._root_widget, 332 position=(260, v - 10), 333 width=160, 334 button_size=(150, 50), 335 scale=1.5, 336 choices=['Classic', 'MFi', 'Both'], 337 choices_display=[ 338 ba.Lstr(resource='macControllerSubsystemClassicText'), 339 ba.Lstr(resource='macControllerSubsystemMFiText'), 340 ba.Lstr(resource='macControllerSubsystemBothText'), 341 ], 342 current_choice=ba.app.config.resolve( 343 'Mac Controller Subsystem' 344 ), 345 on_value_change_call=self._set_mac_controller_subsystem, 346 ) 347 ba.textwidget( 348 parent=self._root_widget, 349 position=(245, v + 13), 350 size=(0, 0), 351 text=ba.Lstr(resource='macControllerSubsystemTitleText'), 352 scale=1.0, 353 h_align='right', 354 v_align='center', 355 color=ba.app.ui.infotextcolor, 356 maxwidth=180, 357 ) 358 ba.textwidget( 359 parent=self._root_widget, 360 position=(width * 0.5, v - 20), 361 size=(0, 0), 362 text=ba.Lstr(resource='macControllerSubsystemDescriptionText'), 363 scale=0.5, 364 h_align='center', 365 v_align='center', 366 color=ba.app.ui.infotextcolor, 367 maxwidth=width * 0.8, 368 ) 369 v -= spacing * 1.5 370 self._restore_state() 371 372 def _set_mac_controller_subsystem(self, val: str) -> None: 373 cfg = ba.app.config 374 cfg['Mac Controller Subsystem'] = val 375 cfg.apply_and_commit() 376 377 def _config_keyboard(self) -> None: 378 # pylint: disable=cyclic-import 379 from bastd.ui.settings.keyboard import ConfigKeyboardWindow 380 381 self._save_state() 382 ba.containerwidget(edit=self._root_widget, transition='out_left') 383 ba.app.ui.set_main_menu_window( 384 ConfigKeyboardWindow( 385 ba.internal.getinputdevice('Keyboard', '#1') 386 ).get_root_widget() 387 ) 388 389 def _config_keyboard2(self) -> None: 390 # pylint: disable=cyclic-import 391 from bastd.ui.settings.keyboard import ConfigKeyboardWindow 392 393 self._save_state() 394 ba.containerwidget(edit=self._root_widget, transition='out_left') 395 ba.app.ui.set_main_menu_window( 396 ConfigKeyboardWindow( 397 ba.internal.getinputdevice('Keyboard', '#2') 398 ).get_root_widget() 399 ) 400 401 def _do_mobile_devices(self) -> None: 402 # pylint: disable=cyclic-import 403 from bastd.ui.settings.remoteapp import RemoteAppSettingsWindow 404 405 self._save_state() 406 ba.containerwidget(edit=self._root_widget, transition='out_left') 407 ba.app.ui.set_main_menu_window( 408 RemoteAppSettingsWindow().get_root_widget() 409 ) 410 411 def _do_gamepads(self) -> None: 412 # pylint: disable=cyclic-import 413 from bastd.ui.settings.gamepadselect import GamepadSelectWindow 414 415 self._save_state() 416 ba.containerwidget(edit=self._root_widget, transition='out_left') 417 ba.app.ui.set_main_menu_window(GamepadSelectWindow().get_root_widget()) 418 419 def _do_touchscreen(self) -> None: 420 # pylint: disable=cyclic-import 421 from bastd.ui.settings.touchscreen import TouchscreenSettingsWindow 422 423 self._save_state() 424 ba.containerwidget(edit=self._root_widget, transition='out_left') 425 ba.app.ui.set_main_menu_window( 426 TouchscreenSettingsWindow().get_root_widget() 427 ) 428 429 def _save_state(self) -> None: 430 sel = self._root_widget.get_selected_child() 431 if sel == self._gamepads_button: 432 sel_name = 'GamePads' 433 elif sel == self._touch_button: 434 sel_name = 'Touch' 435 elif sel == self._keyboard_button: 436 sel_name = 'Keyboard' 437 elif sel == self._keyboard_2_button: 438 sel_name = 'Keyboard2' 439 elif sel == self._idevices_button: 440 sel_name = 'iDevices' 441 else: 442 sel_name = 'Back' 443 ba.app.ui.window_states[type(self)] = sel_name 444 445 def _restore_state(self) -> None: 446 sel_name = ba.app.ui.window_states.get(type(self)) 447 if sel_name == 'GamePads': 448 sel = self._gamepads_button 449 elif sel_name == 'Touch': 450 sel = self._touch_button 451 elif sel_name == 'Keyboard': 452 sel = self._keyboard_button 453 elif sel_name == 'Keyboard2': 454 sel = self._keyboard_2_button 455 elif sel_name == 'iDevices': 456 sel = self._idevices_button 457 elif sel_name == 'Back': 458 sel = self._back_button 459 else: 460 sel = ( 461 self._gamepads_button 462 if self._gamepads_button is not None 463 else self._back_button 464 ) 465 ba.containerwidget(edit=self._root_widget, selected_child=sel) 466 467 def _back(self) -> None: 468 # pylint: disable=cyclic-import 469 from bastd.ui.settings.allsettings import AllSettingsWindow 470 471 self._save_state() 472 ba.containerwidget( 473 edit=self._root_widget, transition=self._transition_out 474 ) 475 ba.app.ui.set_main_menu_window( 476 AllSettingsWindow(transition='in_left').get_root_widget() 477 )
Top level control settings window.
ControlsSettingsWindow( transition: str = 'in_right', origin_widget: _ba.Widget | None = None)
20 def __init__( 21 self, 22 transition: str = 'in_right', 23 origin_widget: ba.Widget | None = None, 24 ): 25 # FIXME: should tidy up here. 26 # pylint: disable=too-many-statements 27 # pylint: disable=too-many-branches 28 # pylint: disable=too-many-locals 29 # pylint: disable=cyclic-import 30 from bastd.ui import popup as popup_ui 31 32 self._have_selected_child = False 33 34 scale_origin: tuple[float, float] | None 35 36 # If they provided an origin-widget, scale up from that. 37 if origin_widget is not None: 38 self._transition_out = 'out_scale' 39 scale_origin = origin_widget.get_screen_space_center() 40 transition = 'in_scale' 41 else: 42 self._transition_out = 'out_right' 43 scale_origin = None 44 45 self._r = 'configControllersWindow' 46 app = ba.app 47 48 # is_fire_tv = ba.internal.is_running_on_fire_tv() 49 50 spacing = 50.0 51 button_width = 350.0 52 width = 460.0 53 height = 130.0 54 55 space_height = spacing * 0.3 56 57 # FIXME: should create vis settings in platform for these, 58 # not hard code them here. 59 60 show_gamepads = False 61 platform = app.platform 62 subplatform = app.subplatform 63 non_vr_windows = platform == 'windows' and ( 64 subplatform != 'oculus' or not app.vr_mode 65 ) 66 if platform in ('linux', 'android', 'mac') or non_vr_windows: 67 show_gamepads = True 68 height += spacing 69 70 show_touch = False 71 if ba.internal.have_touchscreen_input(): 72 show_touch = True 73 height += spacing 74 75 show_space_1 = False 76 if show_gamepads or show_touch: 77 show_space_1 = True 78 height += space_height 79 80 show_keyboard = False 81 if ( 82 ba.internal.getinputdevice('Keyboard', '#1', doraise=False) 83 is not None 84 ): 85 show_keyboard = True 86 height += spacing 87 show_keyboard_p2 = False if app.vr_mode else show_keyboard 88 if show_keyboard_p2: 89 height += spacing 90 91 show_space_2 = False 92 if show_keyboard: 93 show_space_2 = True 94 height += space_height 95 96 if bool(True): 97 show_remote = True 98 height += spacing 99 else: 100 show_remote = False 101 102 # On windows (outside of oculus/vr), show an option to disable xinput. 103 show_xinput_toggle = False 104 if platform == 'windows' and not app.vr_mode: 105 show_xinput_toggle = True 106 107 # On mac builds, show an option to switch between generic and 108 # made-for-iOS/Mac systems 109 # (we can run into problems where devices register as one of each 110 # type otherwise).. 111 show_mac_controller_subsystem = False 112 if platform == 'mac' and ba.internal.is_xcode_build(): 113 show_mac_controller_subsystem = True 114 115 if show_mac_controller_subsystem: 116 height += spacing * 1.5 117 118 if show_xinput_toggle: 119 height += spacing 120 121 uiscale = ba.app.ui.uiscale 122 smallscale = 1.7 if show_keyboard else 2.2 123 super().__init__( 124 root_widget=ba.containerwidget( 125 size=(width, height), 126 transition=transition, 127 scale_origin_stack_offset=scale_origin, 128 stack_offset=( 129 (0, -10) if uiscale is ba.UIScale.SMALL else (0, 0) 130 ), 131 scale=( 132 smallscale 133 if uiscale is ba.UIScale.SMALL 134 else 1.5 135 if uiscale is ba.UIScale.MEDIUM 136 else 1.0 137 ), 138 ) 139 ) 140 self._back_button = btn = ba.buttonwidget( 141 parent=self._root_widget, 142 position=(35, height - 60), 143 size=(140, 65), 144 scale=0.8, 145 text_scale=1.2, 146 autoselect=True, 147 label=ba.Lstr(resource='backText'), 148 button_type='back', 149 on_activate_call=self._back, 150 ) 151 ba.containerwidget(edit=self._root_widget, cancel_button=btn) 152 153 # We need these vars to exist even if the buttons don't. 154 self._gamepads_button: ba.Widget | None = None 155 self._touch_button: ba.Widget | None = None 156 self._keyboard_button: ba.Widget | None = None 157 self._keyboard_2_button: ba.Widget | None = None 158 self._idevices_button: ba.Widget | None = None 159 160 ba.textwidget( 161 parent=self._root_widget, 162 position=(0, height - 49), 163 size=(width, 25), 164 text=ba.Lstr(resource=self._r + '.titleText'), 165 color=ba.app.ui.title_color, 166 h_align='center', 167 v_align='top', 168 ) 169 ba.buttonwidget( 170 edit=btn, 171 button_type='backSmall', 172 size=(60, 60), 173 label=ba.charstr(ba.SpecialChar.BACK), 174 ) 175 176 v = height - 75 177 v -= spacing 178 179 if show_touch: 180 self._touch_button = btn = ba.buttonwidget( 181 parent=self._root_widget, 182 position=((width - button_width) / 2, v), 183 size=(button_width, 43), 184 autoselect=True, 185 label=ba.Lstr(resource=self._r + '.configureTouchText'), 186 on_activate_call=self._do_touchscreen, 187 ) 188 if ba.app.ui.use_toolbars: 189 ba.widget( 190 edit=btn, 191 right_widget=ba.internal.get_special_widget('party_button'), 192 ) 193 if not self._have_selected_child: 194 ba.containerwidget( 195 edit=self._root_widget, selected_child=self._touch_button 196 ) 197 ba.widget( 198 edit=self._back_button, down_widget=self._touch_button 199 ) 200 self._have_selected_child = True 201 v -= spacing 202 203 if show_gamepads: 204 self._gamepads_button = btn = ba.buttonwidget( 205 parent=self._root_widget, 206 position=((width - button_width) / 2 - 7, v), 207 size=(button_width, 43), 208 autoselect=True, 209 label=ba.Lstr(resource=self._r + '.configureControllersText'), 210 on_activate_call=self._do_gamepads, 211 ) 212 if ba.app.ui.use_toolbars: 213 ba.widget( 214 edit=btn, 215 right_widget=ba.internal.get_special_widget('party_button'), 216 ) 217 if not self._have_selected_child: 218 ba.containerwidget( 219 edit=self._root_widget, selected_child=self._gamepads_button 220 ) 221 ba.widget( 222 edit=self._back_button, down_widget=self._gamepads_button 223 ) 224 self._have_selected_child = True 225 v -= spacing 226 else: 227 self._gamepads_button = None 228 229 if show_space_1: 230 v -= space_height 231 232 if show_keyboard: 233 self._keyboard_button = btn = ba.buttonwidget( 234 parent=self._root_widget, 235 position=((width - button_width) / 2 + 5, v), 236 size=(button_width, 43), 237 autoselect=True, 238 label=ba.Lstr(resource=self._r + '.configureKeyboardText'), 239 on_activate_call=self._config_keyboard, 240 ) 241 if ba.app.ui.use_toolbars: 242 ba.widget( 243 edit=btn, 244 right_widget=ba.internal.get_special_widget('party_button'), 245 ) 246 if not self._have_selected_child: 247 ba.containerwidget( 248 edit=self._root_widget, selected_child=self._keyboard_button 249 ) 250 ba.widget( 251 edit=self._back_button, down_widget=self._keyboard_button 252 ) 253 self._have_selected_child = True 254 v -= spacing 255 if show_keyboard_p2: 256 self._keyboard_2_button = ba.buttonwidget( 257 parent=self._root_widget, 258 position=((width - button_width) / 2 - 3, v), 259 size=(button_width, 43), 260 autoselect=True, 261 label=ba.Lstr(resource=self._r + '.configureKeyboard2Text'), 262 on_activate_call=self._config_keyboard2, 263 ) 264 v -= spacing 265 if show_space_2: 266 v -= space_height 267 if show_remote: 268 self._idevices_button = btn = ba.buttonwidget( 269 parent=self._root_widget, 270 position=((width - button_width) / 2 - 5, v), 271 size=(button_width, 43), 272 autoselect=True, 273 label=ba.Lstr(resource=self._r + '.configureMobileText'), 274 on_activate_call=self._do_mobile_devices, 275 ) 276 if ba.app.ui.use_toolbars: 277 ba.widget( 278 edit=btn, 279 right_widget=ba.internal.get_special_widget('party_button'), 280 ) 281 if not self._have_selected_child: 282 ba.containerwidget( 283 edit=self._root_widget, selected_child=self._idevices_button 284 ) 285 ba.widget( 286 edit=self._back_button, down_widget=self._idevices_button 287 ) 288 self._have_selected_child = True 289 v -= spacing 290 291 if show_xinput_toggle: 292 293 def do_toggle(value: bool) -> None: 294 ba.screenmessage( 295 ba.Lstr(resource='settingsWindowAdvanced.mustRestartText'), 296 color=(1, 1, 0), 297 ) 298 ba.playsound(ba.getsound('gunCocking')) 299 ba.internal.set_low_level_config_value( 300 'enablexinput', not value 301 ) 302 303 ba.checkboxwidget( 304 parent=self._root_widget, 305 position=(100, v + 3), 306 size=(120, 30), 307 value=( 308 not ba.internal.get_low_level_config_value( 309 'enablexinput', 1 310 ) 311 ), 312 maxwidth=200, 313 on_value_change_call=do_toggle, 314 text=ba.Lstr(resource='disableXInputText'), 315 autoselect=True, 316 ) 317 ba.textwidget( 318 parent=self._root_widget, 319 position=(width * 0.5, v - 5), 320 size=(0, 0), 321 text=ba.Lstr(resource='disableXInputDescriptionText'), 322 scale=0.5, 323 h_align='center', 324 v_align='center', 325 color=ba.app.ui.infotextcolor, 326 maxwidth=width * 0.8, 327 ) 328 v -= spacing 329 if show_mac_controller_subsystem: 330 popup_ui.PopupMenu( 331 parent=self._root_widget, 332 position=(260, v - 10), 333 width=160, 334 button_size=(150, 50), 335 scale=1.5, 336 choices=['Classic', 'MFi', 'Both'], 337 choices_display=[ 338 ba.Lstr(resource='macControllerSubsystemClassicText'), 339 ba.Lstr(resource='macControllerSubsystemMFiText'), 340 ba.Lstr(resource='macControllerSubsystemBothText'), 341 ], 342 current_choice=ba.app.config.resolve( 343 'Mac Controller Subsystem' 344 ), 345 on_value_change_call=self._set_mac_controller_subsystem, 346 ) 347 ba.textwidget( 348 parent=self._root_widget, 349 position=(245, v + 13), 350 size=(0, 0), 351 text=ba.Lstr(resource='macControllerSubsystemTitleText'), 352 scale=1.0, 353 h_align='right', 354 v_align='center', 355 color=ba.app.ui.infotextcolor, 356 maxwidth=180, 357 ) 358 ba.textwidget( 359 parent=self._root_widget, 360 position=(width * 0.5, v - 20), 361 size=(0, 0), 362 text=ba.Lstr(resource='macControllerSubsystemDescriptionText'), 363 scale=0.5, 364 h_align='center', 365 v_align='center', 366 color=ba.app.ui.infotextcolor, 367 maxwidth=width * 0.8, 368 ) 369 v -= spacing * 1.5 370 self._restore_state()
Inherited Members
- ba.ui.Window
- get_root_widget