bauiv1lib.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 override 8 9import bascenev1 as bs 10import bauiv1 as bui 11 12 13class ControlsSettingsWindow(bui.MainWindow): 14 """Top level control settings window.""" 15 16 def __init__( 17 self, 18 transition: str | None = 'in_right', 19 origin_widget: bui.Widget | None = None, 20 ): 21 # FIXME: should tidy up here. 22 # pylint: disable=too-many-statements 23 # pylint: disable=too-many-branches 24 # pylint: disable=too-many-locals 25 # pylint: disable=cyclic-import 26 27 self._have_selected_child = False 28 29 self._r = 'configControllersWindow' 30 uiscale = bui.app.ui_v1.uiscale 31 app = bui.app 32 assert app.classic is not None 33 34 spacing = 50.0 35 button_width = 350.0 36 width = 800.0 if uiscale is bui.UIScale.SMALL else 460.0 37 height = 300 if uiscale is bui.UIScale.SMALL else 130.0 38 39 yoffs = -60 if uiscale is bui.UIScale.SMALL else 0 40 space_height = spacing * 0.3 41 42 # FIXME: should create vis settings under platform or 43 # app-adapter to determine whether to show this stuff; not hard 44 # code it. 45 46 show_gamepads = False 47 platform = app.classic.platform 48 subplatform = app.classic.subplatform 49 non_vr_windows = platform == 'windows' and ( 50 subplatform != 'oculus' or not app.env.vr 51 ) 52 if platform in ('linux', 'android', 'mac') or non_vr_windows: 53 show_gamepads = True 54 height += spacing 55 56 show_touch = False 57 if bs.have_touchscreen_input(): 58 show_touch = True 59 height += spacing 60 61 show_space_1 = False 62 if show_gamepads or show_touch: 63 show_space_1 = True 64 height += space_height 65 66 show_keyboard = False 67 if bs.getinputdevice('Keyboard', '#1', doraise=False) is not None: 68 show_keyboard = True 69 height += spacing 70 show_keyboard_p2 = False if app.env.vr else show_keyboard 71 if show_keyboard_p2: 72 height += spacing 73 74 show_space_2 = False 75 if show_keyboard: 76 show_space_2 = True 77 height += space_height 78 79 if bool(True): 80 show_remote = True 81 height += spacing 82 else: 83 show_remote = False 84 85 # On windows (outside of oculus/vr), show an option to disable xinput. 86 show_xinput_toggle = False 87 if platform == 'windows' and not app.env.vr: 88 show_xinput_toggle = True 89 90 if show_xinput_toggle: 91 height += spacing 92 93 assert bui.app.classic is not None 94 smallscale = 1.7 95 super().__init__( 96 root_widget=bui.containerwidget( 97 size=(width, height), 98 stack_offset=( 99 (0, -10) if uiscale is bui.UIScale.SMALL else (0, 0) 100 ), 101 scale=( 102 smallscale 103 if uiscale is bui.UIScale.SMALL 104 else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0 105 ), 106 toolbar_visibility=( 107 'menu_minimal' 108 if uiscale is bui.UIScale.SMALL 109 else 'menu_full' 110 ), 111 ), 112 transition=transition, 113 origin_widget=origin_widget, 114 ) 115 116 self._back_button: bui.Widget | None 117 if uiscale is bui.UIScale.SMALL: 118 bui.containerwidget( 119 edit=self._root_widget, on_cancel_call=self.main_window_back 120 ) 121 self._back_button = None 122 else: 123 self._back_button = btn = bui.buttonwidget( 124 parent=self._root_widget, 125 position=(35, height - 60), 126 size=(140, 65), 127 scale=0.8, 128 text_scale=1.2, 129 autoselect=True, 130 label=bui.Lstr(resource='backText'), 131 button_type='back', 132 on_activate_call=self.main_window_back, 133 ) 134 bui.containerwidget(edit=self._root_widget, cancel_button=btn) 135 bui.buttonwidget( 136 edit=btn, 137 button_type='backSmall', 138 size=(60, 60), 139 label=bui.charstr(bui.SpecialChar.BACK), 140 ) 141 142 # We need these vars to exist even if the buttons don't. 143 self._gamepads_button: bui.Widget | None = None 144 self._touch_button: bui.Widget | None = None 145 self._keyboard_button: bui.Widget | None = None 146 self._keyboard_2_button: bui.Widget | None = None 147 self._idevices_button: bui.Widget | None = None 148 149 bui.textwidget( 150 parent=self._root_widget, 151 position=(0, height - 49 + yoffs), 152 size=(width, 25), 153 text=bui.Lstr(resource=f'{self._r}.titleText'), 154 color=bui.app.ui_v1.title_color, 155 h_align='center', 156 v_align='top', 157 ) 158 159 v = height - 75 + yoffs 160 v -= spacing 161 162 if show_touch: 163 self._touch_button = btn = bui.buttonwidget( 164 parent=self._root_widget, 165 position=((width - button_width) / 2, v), 166 size=(button_width, 43), 167 autoselect=True, 168 label=bui.Lstr(resource=f'{self._r}.configureTouchText'), 169 on_activate_call=self._do_touchscreen, 170 ) 171 bui.widget( 172 edit=btn, 173 right_widget=bui.get_special_widget('squad_button'), 174 ) 175 if not self._have_selected_child: 176 bui.containerwidget( 177 edit=self._root_widget, selected_child=self._touch_button 178 ) 179 if self._back_button is not None: 180 bui.widget( 181 edit=self._back_button, down_widget=self._touch_button 182 ) 183 self._have_selected_child = True 184 v -= spacing 185 186 if show_gamepads: 187 self._gamepads_button = btn = bui.buttonwidget( 188 parent=self._root_widget, 189 position=((width - button_width) / 2 - 7, v), 190 size=(button_width, 43), 191 autoselect=True, 192 label=bui.Lstr(resource=f'{self._r}.configureControllersText'), 193 on_activate_call=self._do_gamepads, 194 ) 195 bui.widget( 196 edit=btn, 197 right_widget=bui.get_special_widget('squad_button'), 198 ) 199 if not self._have_selected_child: 200 bui.containerwidget( 201 edit=self._root_widget, selected_child=self._gamepads_button 202 ) 203 if self._back_button is not None: 204 bui.widget( 205 edit=self._back_button, 206 down_widget=self._gamepads_button, 207 ) 208 self._have_selected_child = True 209 v -= spacing 210 else: 211 self._gamepads_button = None 212 213 if show_space_1: 214 v -= space_height 215 216 if show_keyboard: 217 self._keyboard_button = btn = bui.buttonwidget( 218 parent=self._root_widget, 219 position=((width - button_width) / 2 - 5, v), 220 size=(button_width, 43), 221 autoselect=True, 222 label=bui.Lstr(resource=f'{self._r}.configureKeyboardText'), 223 on_activate_call=self._config_keyboard, 224 ) 225 bui.widget( 226 edit=self._keyboard_button, left_widget=self._keyboard_button 227 ) 228 bui.widget( 229 edit=btn, 230 right_widget=bui.get_special_widget('squad_button'), 231 ) 232 if not self._have_selected_child: 233 bui.containerwidget( 234 edit=self._root_widget, selected_child=self._keyboard_button 235 ) 236 if self._back_button is not None: 237 bui.widget( 238 edit=self._back_button, 239 down_widget=self._keyboard_button, 240 ) 241 self._have_selected_child = True 242 v -= spacing 243 if show_keyboard_p2: 244 self._keyboard_2_button = bui.buttonwidget( 245 parent=self._root_widget, 246 position=((width - button_width) / 2 - 3, v), 247 size=(button_width, 43), 248 autoselect=True, 249 label=bui.Lstr(resource=f'{self._r}.configureKeyboard2Text'), 250 on_activate_call=self._config_keyboard2, 251 ) 252 v -= spacing 253 bui.widget( 254 edit=self._keyboard_2_button, 255 left_widget=self._keyboard_2_button, 256 ) 257 if show_space_2: 258 v -= space_height 259 if show_remote: 260 self._idevices_button = btn = bui.buttonwidget( 261 parent=self._root_widget, 262 position=((width - button_width) / 2 - 5, v), 263 size=(button_width, 43), 264 autoselect=True, 265 label=bui.Lstr(resource=f'{self._r}.configureMobileText'), 266 on_activate_call=self._do_mobile_devices, 267 ) 268 bui.widget( 269 edit=self._idevices_button, left_widget=self._idevices_button 270 ) 271 bui.widget( 272 edit=btn, 273 right_widget=bui.get_special_widget('squad_button'), 274 ) 275 if not self._have_selected_child: 276 bui.containerwidget( 277 edit=self._root_widget, selected_child=self._idevices_button 278 ) 279 if self._back_button is not None: 280 bui.widget( 281 edit=self._back_button, 282 down_widget=self._idevices_button, 283 ) 284 self._have_selected_child = True 285 v -= spacing 286 287 if show_xinput_toggle: 288 289 def do_toggle(value: bool) -> None: 290 bui.screenmessage( 291 bui.Lstr(resource='settingsWindowAdvanced.mustRestartText'), 292 color=(1, 1, 0), 293 ) 294 bui.getsound('gunCocking').play() 295 bui.set_low_level_config_value('enablexinput', not value) 296 297 xinput_checkbox = bui.checkboxwidget( 298 parent=self._root_widget, 299 position=(100, v + 3), 300 size=(120, 30), 301 value=(not bui.get_low_level_config_value('enablexinput', 1)), 302 maxwidth=200, 303 on_value_change_call=do_toggle, 304 text=bui.Lstr(resource='disableXInputText'), 305 autoselect=True, 306 ) 307 bui.textwidget( 308 parent=self._root_widget, 309 position=(width * 0.5, v - 5), 310 size=(0, 0), 311 text=bui.Lstr(resource='disableXInputDescriptionText'), 312 scale=0.5, 313 h_align='center', 314 v_align='center', 315 color=bui.app.ui_v1.infotextcolor, 316 maxwidth=width * 0.8, 317 ) 318 bui.widget( 319 edit=xinput_checkbox, 320 left_widget=xinput_checkbox, 321 right_widget=xinput_checkbox, 322 ) 323 v -= spacing 324 325 self._restore_state() 326 327 @override 328 def get_main_window_state(self) -> bui.MainWindowState: 329 # Support recreating our window for back/refresh purposes. 330 cls = type(self) 331 return bui.BasicMainWindowState( 332 create_call=lambda transition, origin_widget: cls( 333 transition=transition, origin_widget=origin_widget 334 ) 335 ) 336 337 @override 338 def on_main_window_close(self) -> None: 339 self._save_state() 340 341 def _set_mac_controller_subsystem(self, val: str) -> None: 342 cfg = bui.app.config 343 cfg['Mac Controller Subsystem'] = val 344 cfg.apply_and_commit() 345 346 def _config_keyboard(self) -> None: 347 # pylint: disable=cyclic-import 348 from bauiv1lib.settings.keyboard import ConfigKeyboardWindow 349 350 # no-op if we're not in control. 351 if not self.main_window_has_control(): 352 return 353 354 self.main_window_replace( 355 ConfigKeyboardWindow(bs.getinputdevice('Keyboard', '#1')) 356 ) 357 358 def _config_keyboard2(self) -> None: 359 # pylint: disable=cyclic-import 360 from bauiv1lib.settings.keyboard import ConfigKeyboardWindow 361 362 # no-op if we're not in control. 363 if not self.main_window_has_control(): 364 return 365 366 self.main_window_replace( 367 ConfigKeyboardWindow(bs.getinputdevice('Keyboard', '#2')) 368 ) 369 370 def _do_mobile_devices(self) -> None: 371 # pylint: disable=cyclic-import 372 from bauiv1lib.settings.remoteapp import RemoteAppSettingsWindow 373 374 # no-op if we're not in control. 375 if not self.main_window_has_control(): 376 return 377 378 self.main_window_replace(RemoteAppSettingsWindow()) 379 380 def _do_gamepads(self) -> None: 381 # pylint: disable=cyclic-import 382 from bauiv1lib.settings.gamepadselect import GamepadSelectWindow 383 384 # no-op if we're not in control. 385 if not self.main_window_has_control(): 386 return 387 388 self.main_window_replace(GamepadSelectWindow()) 389 390 def _do_touchscreen(self) -> None: 391 # pylint: disable=cyclic-import 392 from bauiv1lib.settings.touchscreen import TouchscreenSettingsWindow 393 394 # no-op if we're not in control. 395 if not self.main_window_has_control(): 396 return 397 398 self.main_window_replace(TouchscreenSettingsWindow()) 399 400 def _save_state(self) -> None: 401 sel = self._root_widget.get_selected_child() 402 if sel == self._gamepads_button: 403 sel_name = 'GamePads' 404 elif sel == self._touch_button: 405 sel_name = 'Touch' 406 elif sel == self._keyboard_button: 407 sel_name = 'Keyboard' 408 elif sel == self._keyboard_2_button: 409 sel_name = 'Keyboard2' 410 elif sel == self._idevices_button: 411 sel_name = 'iDevices' 412 else: 413 sel_name = 'Back' 414 assert bui.app.classic is not None 415 bui.app.ui_v1.window_states[type(self)] = sel_name 416 417 def _restore_state(self) -> None: 418 assert bui.app.classic is not None 419 sel_name = bui.app.ui_v1.window_states.get(type(self)) 420 if sel_name == 'GamePads': 421 sel = self._gamepads_button 422 elif sel_name == 'Touch': 423 sel = self._touch_button 424 elif sel_name == 'Keyboard': 425 sel = self._keyboard_button 426 elif sel_name == 'Keyboard2': 427 sel = self._keyboard_2_button 428 elif sel_name == 'iDevices': 429 sel = self._idevices_button 430 elif sel_name == 'Back': 431 sel = self._back_button 432 else: 433 sel = ( 434 self._gamepads_button 435 if self._gamepads_button is not None 436 else self._back_button 437 ) 438 bui.containerwidget(edit=self._root_widget, selected_child=sel)
class
ControlsSettingsWindow(bauiv1._uitypes.MainWindow):
14class ControlsSettingsWindow(bui.MainWindow): 15 """Top level control settings window.""" 16 17 def __init__( 18 self, 19 transition: str | None = 'in_right', 20 origin_widget: bui.Widget | None = None, 21 ): 22 # FIXME: should tidy up here. 23 # pylint: disable=too-many-statements 24 # pylint: disable=too-many-branches 25 # pylint: disable=too-many-locals 26 # pylint: disable=cyclic-import 27 28 self._have_selected_child = False 29 30 self._r = 'configControllersWindow' 31 uiscale = bui.app.ui_v1.uiscale 32 app = bui.app 33 assert app.classic is not None 34 35 spacing = 50.0 36 button_width = 350.0 37 width = 800.0 if uiscale is bui.UIScale.SMALL else 460.0 38 height = 300 if uiscale is bui.UIScale.SMALL else 130.0 39 40 yoffs = -60 if uiscale is bui.UIScale.SMALL else 0 41 space_height = spacing * 0.3 42 43 # FIXME: should create vis settings under platform or 44 # app-adapter to determine whether to show this stuff; not hard 45 # code it. 46 47 show_gamepads = False 48 platform = app.classic.platform 49 subplatform = app.classic.subplatform 50 non_vr_windows = platform == 'windows' and ( 51 subplatform != 'oculus' or not app.env.vr 52 ) 53 if platform in ('linux', 'android', 'mac') or non_vr_windows: 54 show_gamepads = True 55 height += spacing 56 57 show_touch = False 58 if bs.have_touchscreen_input(): 59 show_touch = True 60 height += spacing 61 62 show_space_1 = False 63 if show_gamepads or show_touch: 64 show_space_1 = True 65 height += space_height 66 67 show_keyboard = False 68 if bs.getinputdevice('Keyboard', '#1', doraise=False) is not None: 69 show_keyboard = True 70 height += spacing 71 show_keyboard_p2 = False if app.env.vr else show_keyboard 72 if show_keyboard_p2: 73 height += spacing 74 75 show_space_2 = False 76 if show_keyboard: 77 show_space_2 = True 78 height += space_height 79 80 if bool(True): 81 show_remote = True 82 height += spacing 83 else: 84 show_remote = False 85 86 # On windows (outside of oculus/vr), show an option to disable xinput. 87 show_xinput_toggle = False 88 if platform == 'windows' and not app.env.vr: 89 show_xinput_toggle = True 90 91 if show_xinput_toggle: 92 height += spacing 93 94 assert bui.app.classic is not None 95 smallscale = 1.7 96 super().__init__( 97 root_widget=bui.containerwidget( 98 size=(width, height), 99 stack_offset=( 100 (0, -10) if uiscale is bui.UIScale.SMALL else (0, 0) 101 ), 102 scale=( 103 smallscale 104 if uiscale is bui.UIScale.SMALL 105 else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0 106 ), 107 toolbar_visibility=( 108 'menu_minimal' 109 if uiscale is bui.UIScale.SMALL 110 else 'menu_full' 111 ), 112 ), 113 transition=transition, 114 origin_widget=origin_widget, 115 ) 116 117 self._back_button: bui.Widget | None 118 if uiscale is bui.UIScale.SMALL: 119 bui.containerwidget( 120 edit=self._root_widget, on_cancel_call=self.main_window_back 121 ) 122 self._back_button = None 123 else: 124 self._back_button = btn = bui.buttonwidget( 125 parent=self._root_widget, 126 position=(35, height - 60), 127 size=(140, 65), 128 scale=0.8, 129 text_scale=1.2, 130 autoselect=True, 131 label=bui.Lstr(resource='backText'), 132 button_type='back', 133 on_activate_call=self.main_window_back, 134 ) 135 bui.containerwidget(edit=self._root_widget, cancel_button=btn) 136 bui.buttonwidget( 137 edit=btn, 138 button_type='backSmall', 139 size=(60, 60), 140 label=bui.charstr(bui.SpecialChar.BACK), 141 ) 142 143 # We need these vars to exist even if the buttons don't. 144 self._gamepads_button: bui.Widget | None = None 145 self._touch_button: bui.Widget | None = None 146 self._keyboard_button: bui.Widget | None = None 147 self._keyboard_2_button: bui.Widget | None = None 148 self._idevices_button: bui.Widget | None = None 149 150 bui.textwidget( 151 parent=self._root_widget, 152 position=(0, height - 49 + yoffs), 153 size=(width, 25), 154 text=bui.Lstr(resource=f'{self._r}.titleText'), 155 color=bui.app.ui_v1.title_color, 156 h_align='center', 157 v_align='top', 158 ) 159 160 v = height - 75 + yoffs 161 v -= spacing 162 163 if show_touch: 164 self._touch_button = btn = bui.buttonwidget( 165 parent=self._root_widget, 166 position=((width - button_width) / 2, v), 167 size=(button_width, 43), 168 autoselect=True, 169 label=bui.Lstr(resource=f'{self._r}.configureTouchText'), 170 on_activate_call=self._do_touchscreen, 171 ) 172 bui.widget( 173 edit=btn, 174 right_widget=bui.get_special_widget('squad_button'), 175 ) 176 if not self._have_selected_child: 177 bui.containerwidget( 178 edit=self._root_widget, selected_child=self._touch_button 179 ) 180 if self._back_button is not None: 181 bui.widget( 182 edit=self._back_button, down_widget=self._touch_button 183 ) 184 self._have_selected_child = True 185 v -= spacing 186 187 if show_gamepads: 188 self._gamepads_button = btn = bui.buttonwidget( 189 parent=self._root_widget, 190 position=((width - button_width) / 2 - 7, v), 191 size=(button_width, 43), 192 autoselect=True, 193 label=bui.Lstr(resource=f'{self._r}.configureControllersText'), 194 on_activate_call=self._do_gamepads, 195 ) 196 bui.widget( 197 edit=btn, 198 right_widget=bui.get_special_widget('squad_button'), 199 ) 200 if not self._have_selected_child: 201 bui.containerwidget( 202 edit=self._root_widget, selected_child=self._gamepads_button 203 ) 204 if self._back_button is not None: 205 bui.widget( 206 edit=self._back_button, 207 down_widget=self._gamepads_button, 208 ) 209 self._have_selected_child = True 210 v -= spacing 211 else: 212 self._gamepads_button = None 213 214 if show_space_1: 215 v -= space_height 216 217 if show_keyboard: 218 self._keyboard_button = btn = bui.buttonwidget( 219 parent=self._root_widget, 220 position=((width - button_width) / 2 - 5, v), 221 size=(button_width, 43), 222 autoselect=True, 223 label=bui.Lstr(resource=f'{self._r}.configureKeyboardText'), 224 on_activate_call=self._config_keyboard, 225 ) 226 bui.widget( 227 edit=self._keyboard_button, left_widget=self._keyboard_button 228 ) 229 bui.widget( 230 edit=btn, 231 right_widget=bui.get_special_widget('squad_button'), 232 ) 233 if not self._have_selected_child: 234 bui.containerwidget( 235 edit=self._root_widget, selected_child=self._keyboard_button 236 ) 237 if self._back_button is not None: 238 bui.widget( 239 edit=self._back_button, 240 down_widget=self._keyboard_button, 241 ) 242 self._have_selected_child = True 243 v -= spacing 244 if show_keyboard_p2: 245 self._keyboard_2_button = bui.buttonwidget( 246 parent=self._root_widget, 247 position=((width - button_width) / 2 - 3, v), 248 size=(button_width, 43), 249 autoselect=True, 250 label=bui.Lstr(resource=f'{self._r}.configureKeyboard2Text'), 251 on_activate_call=self._config_keyboard2, 252 ) 253 v -= spacing 254 bui.widget( 255 edit=self._keyboard_2_button, 256 left_widget=self._keyboard_2_button, 257 ) 258 if show_space_2: 259 v -= space_height 260 if show_remote: 261 self._idevices_button = btn = bui.buttonwidget( 262 parent=self._root_widget, 263 position=((width - button_width) / 2 - 5, v), 264 size=(button_width, 43), 265 autoselect=True, 266 label=bui.Lstr(resource=f'{self._r}.configureMobileText'), 267 on_activate_call=self._do_mobile_devices, 268 ) 269 bui.widget( 270 edit=self._idevices_button, left_widget=self._idevices_button 271 ) 272 bui.widget( 273 edit=btn, 274 right_widget=bui.get_special_widget('squad_button'), 275 ) 276 if not self._have_selected_child: 277 bui.containerwidget( 278 edit=self._root_widget, selected_child=self._idevices_button 279 ) 280 if self._back_button is not None: 281 bui.widget( 282 edit=self._back_button, 283 down_widget=self._idevices_button, 284 ) 285 self._have_selected_child = True 286 v -= spacing 287 288 if show_xinput_toggle: 289 290 def do_toggle(value: bool) -> None: 291 bui.screenmessage( 292 bui.Lstr(resource='settingsWindowAdvanced.mustRestartText'), 293 color=(1, 1, 0), 294 ) 295 bui.getsound('gunCocking').play() 296 bui.set_low_level_config_value('enablexinput', not value) 297 298 xinput_checkbox = bui.checkboxwidget( 299 parent=self._root_widget, 300 position=(100, v + 3), 301 size=(120, 30), 302 value=(not bui.get_low_level_config_value('enablexinput', 1)), 303 maxwidth=200, 304 on_value_change_call=do_toggle, 305 text=bui.Lstr(resource='disableXInputText'), 306 autoselect=True, 307 ) 308 bui.textwidget( 309 parent=self._root_widget, 310 position=(width * 0.5, v - 5), 311 size=(0, 0), 312 text=bui.Lstr(resource='disableXInputDescriptionText'), 313 scale=0.5, 314 h_align='center', 315 v_align='center', 316 color=bui.app.ui_v1.infotextcolor, 317 maxwidth=width * 0.8, 318 ) 319 bui.widget( 320 edit=xinput_checkbox, 321 left_widget=xinput_checkbox, 322 right_widget=xinput_checkbox, 323 ) 324 v -= spacing 325 326 self._restore_state() 327 328 @override 329 def get_main_window_state(self) -> bui.MainWindowState: 330 # Support recreating our window for back/refresh purposes. 331 cls = type(self) 332 return bui.BasicMainWindowState( 333 create_call=lambda transition, origin_widget: cls( 334 transition=transition, origin_widget=origin_widget 335 ) 336 ) 337 338 @override 339 def on_main_window_close(self) -> None: 340 self._save_state() 341 342 def _set_mac_controller_subsystem(self, val: str) -> None: 343 cfg = bui.app.config 344 cfg['Mac Controller Subsystem'] = val 345 cfg.apply_and_commit() 346 347 def _config_keyboard(self) -> None: 348 # pylint: disable=cyclic-import 349 from bauiv1lib.settings.keyboard import ConfigKeyboardWindow 350 351 # no-op if we're not in control. 352 if not self.main_window_has_control(): 353 return 354 355 self.main_window_replace( 356 ConfigKeyboardWindow(bs.getinputdevice('Keyboard', '#1')) 357 ) 358 359 def _config_keyboard2(self) -> None: 360 # pylint: disable=cyclic-import 361 from bauiv1lib.settings.keyboard import ConfigKeyboardWindow 362 363 # no-op if we're not in control. 364 if not self.main_window_has_control(): 365 return 366 367 self.main_window_replace( 368 ConfigKeyboardWindow(bs.getinputdevice('Keyboard', '#2')) 369 ) 370 371 def _do_mobile_devices(self) -> None: 372 # pylint: disable=cyclic-import 373 from bauiv1lib.settings.remoteapp import RemoteAppSettingsWindow 374 375 # no-op if we're not in control. 376 if not self.main_window_has_control(): 377 return 378 379 self.main_window_replace(RemoteAppSettingsWindow()) 380 381 def _do_gamepads(self) -> None: 382 # pylint: disable=cyclic-import 383 from bauiv1lib.settings.gamepadselect import GamepadSelectWindow 384 385 # no-op if we're not in control. 386 if not self.main_window_has_control(): 387 return 388 389 self.main_window_replace(GamepadSelectWindow()) 390 391 def _do_touchscreen(self) -> None: 392 # pylint: disable=cyclic-import 393 from bauiv1lib.settings.touchscreen import TouchscreenSettingsWindow 394 395 # no-op if we're not in control. 396 if not self.main_window_has_control(): 397 return 398 399 self.main_window_replace(TouchscreenSettingsWindow()) 400 401 def _save_state(self) -> None: 402 sel = self._root_widget.get_selected_child() 403 if sel == self._gamepads_button: 404 sel_name = 'GamePads' 405 elif sel == self._touch_button: 406 sel_name = 'Touch' 407 elif sel == self._keyboard_button: 408 sel_name = 'Keyboard' 409 elif sel == self._keyboard_2_button: 410 sel_name = 'Keyboard2' 411 elif sel == self._idevices_button: 412 sel_name = 'iDevices' 413 else: 414 sel_name = 'Back' 415 assert bui.app.classic is not None 416 bui.app.ui_v1.window_states[type(self)] = sel_name 417 418 def _restore_state(self) -> None: 419 assert bui.app.classic is not None 420 sel_name = bui.app.ui_v1.window_states.get(type(self)) 421 if sel_name == 'GamePads': 422 sel = self._gamepads_button 423 elif sel_name == 'Touch': 424 sel = self._touch_button 425 elif sel_name == 'Keyboard': 426 sel = self._keyboard_button 427 elif sel_name == 'Keyboard2': 428 sel = self._keyboard_2_button 429 elif sel_name == 'iDevices': 430 sel = self._idevices_button 431 elif sel_name == 'Back': 432 sel = self._back_button 433 else: 434 sel = ( 435 self._gamepads_button 436 if self._gamepads_button is not None 437 else self._back_button 438 ) 439 bui.containerwidget(edit=self._root_widget, selected_child=sel)
Top level control settings window.
ControlsSettingsWindow( transition: str | None = 'in_right', origin_widget: _bauiv1.Widget | None = None)
17 def __init__( 18 self, 19 transition: str | None = 'in_right', 20 origin_widget: bui.Widget | None = None, 21 ): 22 # FIXME: should tidy up here. 23 # pylint: disable=too-many-statements 24 # pylint: disable=too-many-branches 25 # pylint: disable=too-many-locals 26 # pylint: disable=cyclic-import 27 28 self._have_selected_child = False 29 30 self._r = 'configControllersWindow' 31 uiscale = bui.app.ui_v1.uiscale 32 app = bui.app 33 assert app.classic is not None 34 35 spacing = 50.0 36 button_width = 350.0 37 width = 800.0 if uiscale is bui.UIScale.SMALL else 460.0 38 height = 300 if uiscale is bui.UIScale.SMALL else 130.0 39 40 yoffs = -60 if uiscale is bui.UIScale.SMALL else 0 41 space_height = spacing * 0.3 42 43 # FIXME: should create vis settings under platform or 44 # app-adapter to determine whether to show this stuff; not hard 45 # code it. 46 47 show_gamepads = False 48 platform = app.classic.platform 49 subplatform = app.classic.subplatform 50 non_vr_windows = platform == 'windows' and ( 51 subplatform != 'oculus' or not app.env.vr 52 ) 53 if platform in ('linux', 'android', 'mac') or non_vr_windows: 54 show_gamepads = True 55 height += spacing 56 57 show_touch = False 58 if bs.have_touchscreen_input(): 59 show_touch = True 60 height += spacing 61 62 show_space_1 = False 63 if show_gamepads or show_touch: 64 show_space_1 = True 65 height += space_height 66 67 show_keyboard = False 68 if bs.getinputdevice('Keyboard', '#1', doraise=False) is not None: 69 show_keyboard = True 70 height += spacing 71 show_keyboard_p2 = False if app.env.vr else show_keyboard 72 if show_keyboard_p2: 73 height += spacing 74 75 show_space_2 = False 76 if show_keyboard: 77 show_space_2 = True 78 height += space_height 79 80 if bool(True): 81 show_remote = True 82 height += spacing 83 else: 84 show_remote = False 85 86 # On windows (outside of oculus/vr), show an option to disable xinput. 87 show_xinput_toggle = False 88 if platform == 'windows' and not app.env.vr: 89 show_xinput_toggle = True 90 91 if show_xinput_toggle: 92 height += spacing 93 94 assert bui.app.classic is not None 95 smallscale = 1.7 96 super().__init__( 97 root_widget=bui.containerwidget( 98 size=(width, height), 99 stack_offset=( 100 (0, -10) if uiscale is bui.UIScale.SMALL else (0, 0) 101 ), 102 scale=( 103 smallscale 104 if uiscale is bui.UIScale.SMALL 105 else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0 106 ), 107 toolbar_visibility=( 108 'menu_minimal' 109 if uiscale is bui.UIScale.SMALL 110 else 'menu_full' 111 ), 112 ), 113 transition=transition, 114 origin_widget=origin_widget, 115 ) 116 117 self._back_button: bui.Widget | None 118 if uiscale is bui.UIScale.SMALL: 119 bui.containerwidget( 120 edit=self._root_widget, on_cancel_call=self.main_window_back 121 ) 122 self._back_button = None 123 else: 124 self._back_button = btn = bui.buttonwidget( 125 parent=self._root_widget, 126 position=(35, height - 60), 127 size=(140, 65), 128 scale=0.8, 129 text_scale=1.2, 130 autoselect=True, 131 label=bui.Lstr(resource='backText'), 132 button_type='back', 133 on_activate_call=self.main_window_back, 134 ) 135 bui.containerwidget(edit=self._root_widget, cancel_button=btn) 136 bui.buttonwidget( 137 edit=btn, 138 button_type='backSmall', 139 size=(60, 60), 140 label=bui.charstr(bui.SpecialChar.BACK), 141 ) 142 143 # We need these vars to exist even if the buttons don't. 144 self._gamepads_button: bui.Widget | None = None 145 self._touch_button: bui.Widget | None = None 146 self._keyboard_button: bui.Widget | None = None 147 self._keyboard_2_button: bui.Widget | None = None 148 self._idevices_button: bui.Widget | None = None 149 150 bui.textwidget( 151 parent=self._root_widget, 152 position=(0, height - 49 + yoffs), 153 size=(width, 25), 154 text=bui.Lstr(resource=f'{self._r}.titleText'), 155 color=bui.app.ui_v1.title_color, 156 h_align='center', 157 v_align='top', 158 ) 159 160 v = height - 75 + yoffs 161 v -= spacing 162 163 if show_touch: 164 self._touch_button = btn = bui.buttonwidget( 165 parent=self._root_widget, 166 position=((width - button_width) / 2, v), 167 size=(button_width, 43), 168 autoselect=True, 169 label=bui.Lstr(resource=f'{self._r}.configureTouchText'), 170 on_activate_call=self._do_touchscreen, 171 ) 172 bui.widget( 173 edit=btn, 174 right_widget=bui.get_special_widget('squad_button'), 175 ) 176 if not self._have_selected_child: 177 bui.containerwidget( 178 edit=self._root_widget, selected_child=self._touch_button 179 ) 180 if self._back_button is not None: 181 bui.widget( 182 edit=self._back_button, down_widget=self._touch_button 183 ) 184 self._have_selected_child = True 185 v -= spacing 186 187 if show_gamepads: 188 self._gamepads_button = btn = bui.buttonwidget( 189 parent=self._root_widget, 190 position=((width - button_width) / 2 - 7, v), 191 size=(button_width, 43), 192 autoselect=True, 193 label=bui.Lstr(resource=f'{self._r}.configureControllersText'), 194 on_activate_call=self._do_gamepads, 195 ) 196 bui.widget( 197 edit=btn, 198 right_widget=bui.get_special_widget('squad_button'), 199 ) 200 if not self._have_selected_child: 201 bui.containerwidget( 202 edit=self._root_widget, selected_child=self._gamepads_button 203 ) 204 if self._back_button is not None: 205 bui.widget( 206 edit=self._back_button, 207 down_widget=self._gamepads_button, 208 ) 209 self._have_selected_child = True 210 v -= spacing 211 else: 212 self._gamepads_button = None 213 214 if show_space_1: 215 v -= space_height 216 217 if show_keyboard: 218 self._keyboard_button = btn = bui.buttonwidget( 219 parent=self._root_widget, 220 position=((width - button_width) / 2 - 5, v), 221 size=(button_width, 43), 222 autoselect=True, 223 label=bui.Lstr(resource=f'{self._r}.configureKeyboardText'), 224 on_activate_call=self._config_keyboard, 225 ) 226 bui.widget( 227 edit=self._keyboard_button, left_widget=self._keyboard_button 228 ) 229 bui.widget( 230 edit=btn, 231 right_widget=bui.get_special_widget('squad_button'), 232 ) 233 if not self._have_selected_child: 234 bui.containerwidget( 235 edit=self._root_widget, selected_child=self._keyboard_button 236 ) 237 if self._back_button is not None: 238 bui.widget( 239 edit=self._back_button, 240 down_widget=self._keyboard_button, 241 ) 242 self._have_selected_child = True 243 v -= spacing 244 if show_keyboard_p2: 245 self._keyboard_2_button = bui.buttonwidget( 246 parent=self._root_widget, 247 position=((width - button_width) / 2 - 3, v), 248 size=(button_width, 43), 249 autoselect=True, 250 label=bui.Lstr(resource=f'{self._r}.configureKeyboard2Text'), 251 on_activate_call=self._config_keyboard2, 252 ) 253 v -= spacing 254 bui.widget( 255 edit=self._keyboard_2_button, 256 left_widget=self._keyboard_2_button, 257 ) 258 if show_space_2: 259 v -= space_height 260 if show_remote: 261 self._idevices_button = btn = bui.buttonwidget( 262 parent=self._root_widget, 263 position=((width - button_width) / 2 - 5, v), 264 size=(button_width, 43), 265 autoselect=True, 266 label=bui.Lstr(resource=f'{self._r}.configureMobileText'), 267 on_activate_call=self._do_mobile_devices, 268 ) 269 bui.widget( 270 edit=self._idevices_button, left_widget=self._idevices_button 271 ) 272 bui.widget( 273 edit=btn, 274 right_widget=bui.get_special_widget('squad_button'), 275 ) 276 if not self._have_selected_child: 277 bui.containerwidget( 278 edit=self._root_widget, selected_child=self._idevices_button 279 ) 280 if self._back_button is not None: 281 bui.widget( 282 edit=self._back_button, 283 down_widget=self._idevices_button, 284 ) 285 self._have_selected_child = True 286 v -= spacing 287 288 if show_xinput_toggle: 289 290 def do_toggle(value: bool) -> None: 291 bui.screenmessage( 292 bui.Lstr(resource='settingsWindowAdvanced.mustRestartText'), 293 color=(1, 1, 0), 294 ) 295 bui.getsound('gunCocking').play() 296 bui.set_low_level_config_value('enablexinput', not value) 297 298 xinput_checkbox = bui.checkboxwidget( 299 parent=self._root_widget, 300 position=(100, v + 3), 301 size=(120, 30), 302 value=(not bui.get_low_level_config_value('enablexinput', 1)), 303 maxwidth=200, 304 on_value_change_call=do_toggle, 305 text=bui.Lstr(resource='disableXInputText'), 306 autoselect=True, 307 ) 308 bui.textwidget( 309 parent=self._root_widget, 310 position=(width * 0.5, v - 5), 311 size=(0, 0), 312 text=bui.Lstr(resource='disableXInputDescriptionText'), 313 scale=0.5, 314 h_align='center', 315 v_align='center', 316 color=bui.app.ui_v1.infotextcolor, 317 maxwidth=width * 0.8, 318 ) 319 bui.widget( 320 edit=xinput_checkbox, 321 left_widget=xinput_checkbox, 322 right_widget=xinput_checkbox, 323 ) 324 v -= spacing 325 326 self._restore_state()
Create a MainWindow given a root widget and transition info.
Automatically handles in and out transitions on the provided widget, so there is no need to set transitions when creating it.
328 @override 329 def get_main_window_state(self) -> bui.MainWindowState: 330 # Support recreating our window for back/refresh purposes. 331 cls = type(self) 332 return bui.BasicMainWindowState( 333 create_call=lambda transition, origin_widget: cls( 334 transition=transition, origin_widget=origin_widget 335 ) 336 )
Return a WindowState to recreate this window, if supported.
@override
def
on_main_window_close(self) -> None:
Called before transitioning out a main window.
A good opportunity to save window state/etc.
Inherited Members
- bauiv1._uitypes.MainWindow
- main_window_back_state
- main_window_is_top_level
- main_window_close
- main_window_has_control
- main_window_back
- main_window_replace
- bauiv1._uitypes.Window
- get_root_widget