bauiv1lib.settings.gamepadadvanced
UI functionality related to advanced gamepad configuring.
1# Released under the MIT License. See LICENSE for details. 2# 3"""UI functionality related to advanced gamepad configuring.""" 4 5from __future__ import annotations 6 7from typing import TYPE_CHECKING 8 9import bauiv1 as bui 10 11if TYPE_CHECKING: 12 from typing import Any 13 from bauiv1lib.settings.gamepad import ( 14 GamepadSettingsWindow, 15 AwaitGamepadInputWindow, 16 ) 17 18 19class GamepadAdvancedSettingsWindow(bui.Window): 20 """Window for advanced gamepad configuration.""" 21 22 def __init__(self, parent_window: GamepadSettingsWindow): 23 # pylint: disable=too-many-statements 24 # pylint: disable=too-many-locals 25 self._parent_window = parent_window 26 27 app = bui.app 28 29 self._r = parent_window.get_r() 30 assert bui.app.classic is not None 31 uiscale = bui.app.ui_v1.uiscale 32 self._width = 900 if uiscale is bui.UIScale.SMALL else 700 33 self._x_inset = x_inset = 100 if uiscale is bui.UIScale.SMALL else 0 34 self._height = 402 if uiscale is bui.UIScale.SMALL else 512 35 self._textwidgets: dict[str, bui.Widget] = {} 36 advb = parent_window.get_advanced_button() 37 super().__init__( 38 root_widget=bui.containerwidget( 39 transition='in_scale', 40 size=(self._width, self._height), 41 scale=1.06 42 * ( 43 1.6 44 if uiscale is bui.UIScale.SMALL 45 else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0 46 ), 47 stack_offset=( 48 (0, -25) if uiscale is bui.UIScale.SMALL else (0, 0) 49 ), 50 scale_origin_stack_offset=(advb.get_screen_space_center()), 51 ) 52 ) 53 54 bui.textwidget( 55 parent=self._root_widget, 56 position=( 57 self._width * 0.5, 58 self._height - (40 if uiscale is bui.UIScale.SMALL else 34), 59 ), 60 size=(0, 0), 61 text=bui.Lstr(resource=f'{self._r}.advancedTitleText'), 62 maxwidth=320, 63 color=bui.app.ui_v1.title_color, 64 h_align='center', 65 v_align='center', 66 ) 67 68 back_button = btn = bui.buttonwidget( 69 parent=self._root_widget, 70 autoselect=True, 71 position=( 72 self._width - (176 + x_inset), 73 self._height - (60 if uiscale is bui.UIScale.SMALL else 55), 74 ), 75 size=(120, 48), 76 text_scale=0.8, 77 label=bui.Lstr(resource='doneText'), 78 on_activate_call=self._done, 79 ) 80 bui.containerwidget( 81 edit=self._root_widget, 82 start_button=btn, 83 on_cancel_call=btn.activate, 84 ) 85 86 self._scroll_width = self._width - (100 + 2 * x_inset) 87 self._scroll_height = self._height - 110 88 self._sub_width = self._scroll_width - 20 89 self._sub_height = ( 90 940 if self._parent_window.get_is_secondary() else 1040 91 ) 92 if app.env.vr: 93 self._sub_height += 50 94 self._scrollwidget = bui.scrollwidget( 95 parent=self._root_widget, 96 position=( 97 (self._width - self._scroll_width) * 0.5, 98 self._height - 65 - self._scroll_height, 99 ), 100 size=(self._scroll_width, self._scroll_height), 101 claims_left_right=True, 102 claims_tab=True, 103 selection_loops_to_parent=True, 104 ) 105 self._subcontainer = bui.containerwidget( 106 parent=self._scrollwidget, 107 size=(self._sub_width, self._sub_height), 108 background=False, 109 claims_left_right=True, 110 claims_tab=True, 111 selection_loops_to_parent=True, 112 ) 113 bui.containerwidget( 114 edit=self._root_widget, selected_child=self._scrollwidget 115 ) 116 117 h = 30 118 v = self._sub_height - 10 119 120 h2 = h + 12 121 122 # don't allow secondary joysticks to handle unassigned buttons 123 if not self._parent_window.get_is_secondary(): 124 v -= 40 125 cb1 = bui.checkboxwidget( 126 parent=self._subcontainer, 127 position=(h + 70, v), 128 size=(500, 30), 129 text=bui.Lstr(resource=f'{self._r}.unassignedButtonsRunText'), 130 textcolor=(0.8, 0.8, 0.8), 131 maxwidth=330, 132 scale=1.0, 133 on_value_change_call=( 134 self._parent_window.set_unassigned_buttons_run_value 135 ), 136 autoselect=True, 137 value=self._parent_window.get_unassigned_buttons_run_value(), 138 ) 139 bui.widget(edit=cb1, up_widget=back_button) 140 v -= 60 141 capb = self._capture_button( 142 pos=(h2, v), 143 name=bui.Lstr(resource=f'{self._r}.runButton1Text'), 144 control='buttonRun1' + self._parent_window.get_ext(), 145 ) 146 if self._parent_window.get_is_secondary(): 147 for widget in capb: 148 bui.widget(edit=widget, up_widget=back_button) 149 v -= 42 150 self._capture_button( 151 pos=(h2, v), 152 name=bui.Lstr(resource=f'{self._r}.runButton2Text'), 153 control='buttonRun2' + self._parent_window.get_ext(), 154 ) 155 bui.textwidget( 156 parent=self._subcontainer, 157 position=(self._sub_width * 0.5, v - 24), 158 size=(0, 0), 159 text=bui.Lstr(resource=f'{self._r}.runTriggerDescriptionText'), 160 color=(0.7, 1, 0.7, 0.6), 161 maxwidth=self._sub_width * 0.8, 162 scale=0.7, 163 h_align='center', 164 v_align='center', 165 ) 166 167 v -= 85 168 169 self._capture_button( 170 pos=(h2, v), 171 name=bui.Lstr(resource=f'{self._r}.runTrigger1Text'), 172 control='triggerRun1' + self._parent_window.get_ext(), 173 message=bui.Lstr(resource=f'{self._r}.pressAnyAnalogTriggerText'), 174 ) 175 v -= 42 176 self._capture_button( 177 pos=(h2, v), 178 name=bui.Lstr(resource=f'{self._r}.runTrigger2Text'), 179 control='triggerRun2' + self._parent_window.get_ext(), 180 message=bui.Lstr(resource=f'{self._r}.pressAnyAnalogTriggerText'), 181 ) 182 183 # in vr mode, allow assigning a reset-view button 184 if app.env.vr: 185 v -= 50 186 self._capture_button( 187 pos=(h2, v), 188 name=bui.Lstr(resource=f'{self._r}.vrReorientButtonText'), 189 control='buttonVRReorient' + self._parent_window.get_ext(), 190 ) 191 192 v -= 60 193 self._capture_button( 194 pos=(h2, v), 195 name=bui.Lstr(resource=f'{self._r}.extraStartButtonText'), 196 control='buttonStart2' + self._parent_window.get_ext(), 197 ) 198 v -= 60 199 self._capture_button( 200 pos=(h2, v), 201 name=bui.Lstr(resource=f'{self._r}.ignoredButton1Text'), 202 control='buttonIgnored' + self._parent_window.get_ext(), 203 ) 204 v -= 42 205 self._capture_button( 206 pos=(h2, v), 207 name=bui.Lstr(resource=f'{self._r}.ignoredButton2Text'), 208 control='buttonIgnored2' + self._parent_window.get_ext(), 209 ) 210 v -= 42 211 self._capture_button( 212 pos=(h2, v), 213 name=bui.Lstr(resource=f'{self._r}.ignoredButton3Text'), 214 control='buttonIgnored3' + self._parent_window.get_ext(), 215 ) 216 v -= 42 217 self._capture_button( 218 pos=(h2, v), 219 name=bui.Lstr(resource=f'{self._r}.ignoredButton4Text'), 220 control='buttonIgnored4' + self._parent_window.get_ext(), 221 ) 222 bui.textwidget( 223 parent=self._subcontainer, 224 position=(self._sub_width * 0.5, v - 14), 225 size=(0, 0), 226 text=bui.Lstr(resource=f'{self._r}.ignoredButtonDescriptionText'), 227 color=(0.7, 1, 0.7, 0.6), 228 scale=0.8, 229 maxwidth=self._sub_width * 0.8, 230 h_align='center', 231 v_align='center', 232 ) 233 234 v -= 80 235 pwin = self._parent_window 236 bui.checkboxwidget( 237 parent=self._subcontainer, 238 autoselect=True, 239 position=(h + 50, v), 240 size=(400, 30), 241 text=bui.Lstr( 242 resource=f'{self._r}.startButtonActivatesDefaultText' 243 ), 244 textcolor=(0.8, 0.8, 0.8), 245 maxwidth=450, 246 scale=0.9, 247 on_value_change_call=( 248 pwin.set_start_button_activates_default_widget_value 249 ), 250 value=pwin.get_start_button_activates_default_widget_value(), 251 ) 252 bui.textwidget( 253 parent=self._subcontainer, 254 position=(self._sub_width * 0.5, v - 12), 255 size=(0, 0), 256 text=bui.Lstr( 257 resource=f'{self._r}.startButtonActivatesDefaultDescriptionText' 258 ), 259 color=(0.7, 1, 0.7, 0.6), 260 maxwidth=self._sub_width * 0.8, 261 scale=0.7, 262 h_align='center', 263 v_align='center', 264 ) 265 266 v -= 80 267 bui.checkboxwidget( 268 parent=self._subcontainer, 269 autoselect=True, 270 position=(h + 50, v), 271 size=(400, 30), 272 text=bui.Lstr(resource=f'{self._r}.uiOnlyText'), 273 textcolor=(0.8, 0.8, 0.8), 274 maxwidth=450, 275 scale=0.9, 276 on_value_change_call=self._parent_window.set_ui_only_value, 277 value=self._parent_window.get_ui_only_value(), 278 ) 279 bui.textwidget( 280 parent=self._subcontainer, 281 position=(self._sub_width * 0.5, v - 12), 282 size=(0, 0), 283 text=bui.Lstr(resource=f'{self._r}.uiOnlyDescriptionText'), 284 color=(0.7, 1, 0.7, 0.6), 285 maxwidth=self._sub_width * 0.8, 286 scale=0.7, 287 h_align='center', 288 v_align='center', 289 ) 290 291 v -= 80 292 bui.checkboxwidget( 293 parent=self._subcontainer, 294 autoselect=True, 295 position=(h + 50, v), 296 size=(400, 30), 297 text=bui.Lstr(resource=f'{self._r}.ignoreCompletelyText'), 298 textcolor=(0.8, 0.8, 0.8), 299 maxwidth=450, 300 scale=0.9, 301 on_value_change_call=pwin.set_ignore_completely_value, 302 value=self._parent_window.get_ignore_completely_value(), 303 ) 304 bui.textwidget( 305 parent=self._subcontainer, 306 position=(self._sub_width * 0.5, v - 12), 307 size=(0, 0), 308 text=bui.Lstr( 309 resource=f'{self._r}.ignoreCompletelyDescriptionText' 310 ), 311 color=(0.7, 1, 0.7, 0.6), 312 maxwidth=self._sub_width * 0.8, 313 scale=0.7, 314 h_align='center', 315 v_align='center', 316 ) 317 318 v -= 80 319 320 cb1 = bui.checkboxwidget( 321 parent=self._subcontainer, 322 autoselect=True, 323 position=(h + 50, v), 324 size=(400, 30), 325 text=bui.Lstr(resource=f'{self._r}.autoRecalibrateText'), 326 textcolor=(0.8, 0.8, 0.8), 327 maxwidth=450, 328 scale=0.9, 329 on_value_change_call=pwin.set_auto_recalibrate_analog_stick_value, 330 value=self._parent_window.get_auto_recalibrate_analog_stick_value(), 331 ) 332 bui.textwidget( 333 parent=self._subcontainer, 334 position=(self._sub_width * 0.5, v - 12), 335 size=(0, 0), 336 text=bui.Lstr(resource=f'{self._r}.autoRecalibrateDescriptionText'), 337 color=(0.7, 1, 0.7, 0.6), 338 maxwidth=self._sub_width * 0.8, 339 scale=0.7, 340 h_align='center', 341 v_align='center', 342 ) 343 v -= 80 344 345 buttons = self._config_value_editor( 346 bui.Lstr(resource=f'{self._r}.analogStickDeadZoneText'), 347 control=('analogStickDeadZone' + self._parent_window.get_ext()), 348 position=(h + 40, v), 349 min_val=0, 350 max_val=10.0, 351 increment=0.1, 352 x_offset=100, 353 ) 354 bui.widget(edit=buttons[0], left_widget=cb1, up_widget=cb1) 355 bui.widget(edit=cb1, right_widget=buttons[0], down_widget=buttons[0]) 356 357 bui.textwidget( 358 parent=self._subcontainer, 359 position=(self._sub_width * 0.5, v - 12), 360 size=(0, 0), 361 text=bui.Lstr( 362 resource=f'{self._r}.analogStickDeadZoneDescriptionText' 363 ), 364 color=(0.7, 1, 0.7, 0.6), 365 maxwidth=self._sub_width * 0.8, 366 scale=0.7, 367 h_align='center', 368 v_align='center', 369 ) 370 v -= 100 371 372 # child joysticks cant have child joysticks.. that's just 373 # crazy talk 374 if not self._parent_window.get_is_secondary(): 375 bui.buttonwidget( 376 parent=self._subcontainer, 377 autoselect=True, 378 label=bui.Lstr(resource=f'{self._r}.twoInOneSetupText'), 379 position=(40, v), 380 size=(self._sub_width - 80, 50), 381 on_activate_call=self._parent_window.show_secondary_editor, 382 up_widget=buttons[0], 383 ) 384 385 # set a bigger bottom show-buffer for the widgets we just made 386 # so we can see the text below them when navigating with 387 # a gamepad 388 for child in self._subcontainer.get_children(): 389 bui.widget(edit=child, show_buffer_bottom=30, show_buffer_top=30) 390 391 def _capture_button( 392 self, 393 pos: tuple[float, float], 394 name: bui.Lstr, 395 control: str, 396 message: bui.Lstr | None = None, 397 ) -> tuple[bui.Widget, bui.Widget]: 398 if message is None: 399 message = bui.Lstr( 400 resource=self._parent_window.get_r() + '.pressAnyButtonText' 401 ) 402 btn = bui.buttonwidget( 403 parent=self._subcontainer, 404 autoselect=True, 405 position=(pos[0], pos[1]), 406 label=name, 407 size=(250, 60), 408 scale=0.7, 409 ) 410 btn2 = bui.buttonwidget( 411 parent=self._subcontainer, 412 autoselect=True, 413 position=(pos[0] + 400, pos[1] + 2), 414 left_widget=btn, 415 color=(0.45, 0.4, 0.5), 416 textcolor=(0.65, 0.6, 0.7), 417 label=bui.Lstr(resource=f'{self._r}.clearText'), 418 size=(110, 50), 419 scale=0.7, 420 on_activate_call=bui.Call(self._clear_control, control), 421 ) 422 bui.widget(edit=btn, right_widget=btn2) 423 424 # make this in a timer so that it shows up on top of all 425 # other buttons 426 427 def doit() -> None: 428 from bauiv1lib.settings.gamepad import AwaitGamepadInputWindow 429 430 txt = bui.textwidget( 431 parent=self._subcontainer, 432 position=(pos[0] + 285, pos[1] + 20), 433 color=(1, 1, 1, 0.3), 434 size=(0, 0), 435 h_align='center', 436 v_align='center', 437 scale=0.7, 438 text=self._parent_window.get_control_value_name(control), 439 maxwidth=200, 440 ) 441 self._textwidgets[control] = txt 442 bui.buttonwidget( 443 edit=btn, 444 on_activate_call=bui.Call( 445 AwaitGamepadInputWindow, 446 self._parent_window.get_input(), 447 control, 448 self._gamepad_event, 449 message, 450 ), 451 ) 452 453 bui.pushcall(doit) 454 return btn, btn2 455 456 def _inc( 457 self, control: str, min_val: float, max_val: float, inc: float 458 ) -> None: 459 val = self._parent_window.get_settings().get(control, 1.0) 460 val = min(max_val, max(min_val, val + inc)) 461 if abs(1.0 - val) < 0.001: 462 if control in self._parent_window.get_settings(): 463 del self._parent_window.get_settings()[control] 464 else: 465 self._parent_window.get_settings()[control] = round(val, 1) 466 bui.textwidget( 467 edit=self._textwidgets[control], 468 text=self._parent_window.get_control_value_name(control), 469 ) 470 471 def _config_value_editor( 472 self, 473 name: bui.Lstr, 474 control: str, 475 position: tuple[float, float], 476 *, 477 min_val: float = 0.0, 478 max_val: float = 100.0, 479 increment: float = 1.0, 480 change_sound: bool = True, 481 x_offset: float = 0.0, 482 displayname: bui.Lstr | None = None, 483 ) -> tuple[bui.Widget, bui.Widget]: 484 if displayname is None: 485 displayname = name 486 bui.textwidget( 487 parent=self._subcontainer, 488 position=position, 489 size=(100, 30), 490 text=displayname, 491 color=(0.8, 0.8, 0.8, 1.0), 492 h_align='left', 493 v_align='center', 494 scale=1.0, 495 maxwidth=280, 496 ) 497 self._textwidgets[control] = bui.textwidget( 498 parent=self._subcontainer, 499 position=(246.0 + x_offset, position[1]), 500 size=(60, 28), 501 editable=False, 502 color=(0.3, 1.0, 0.3, 1.0), 503 h_align='right', 504 v_align='center', 505 text=self._parent_window.get_control_value_name(control), 506 padding=2, 507 ) 508 btn = bui.buttonwidget( 509 parent=self._subcontainer, 510 autoselect=True, 511 position=(330 + x_offset, position[1] + 4), 512 size=(28, 28), 513 label='-', 514 on_activate_call=bui.Call( 515 self._inc, control, min_val, max_val, -increment 516 ), 517 repeat=True, 518 enable_sound=(change_sound is True), 519 ) 520 btn2 = bui.buttonwidget( 521 parent=self._subcontainer, 522 autoselect=True, 523 position=(380 + x_offset, position[1] + 4), 524 size=(28, 28), 525 label='+', 526 on_activate_call=bui.Call( 527 self._inc, control, min_val, max_val, increment 528 ), 529 repeat=True, 530 enable_sound=(change_sound is True), 531 ) 532 return btn, btn2 533 534 def _clear_control(self, control: str) -> None: 535 if control in self._parent_window.get_settings(): 536 del self._parent_window.get_settings()[control] 537 bui.textwidget( 538 edit=self._textwidgets[control], 539 text=self._parent_window.get_control_value_name(control), 540 ) 541 542 def _gamepad_event( 543 self, 544 control: str, 545 event: dict[str, Any], 546 dialog: AwaitGamepadInputWindow, 547 ) -> None: 548 ext = self._parent_window.get_ext() 549 if control in ['triggerRun1' + ext, 'triggerRun2' + ext]: 550 if event['type'] == 'AXISMOTION': 551 # ignore small values or else we might get triggered 552 # by noise 553 if abs(event['value']) > 0.5: 554 self._parent_window.get_settings()[control] = event['axis'] 555 # update the button's text widget 556 if self._textwidgets[control]: 557 bui.textwidget( 558 edit=self._textwidgets[control], 559 text=self._parent_window.get_control_value_name( 560 control 561 ), 562 ) 563 bui.getsound('gunCocking').play() 564 dialog.die() 565 else: 566 if event['type'] == 'BUTTONDOWN': 567 value = event['button'] 568 self._parent_window.get_settings()[control] = value 569 # update the button's text widget 570 if self._textwidgets[control]: 571 bui.textwidget( 572 edit=self._textwidgets[control], 573 text=self._parent_window.get_control_value_name( 574 control 575 ), 576 ) 577 bui.getsound('gunCocking').play() 578 dialog.die() 579 580 def _done(self) -> None: 581 bui.containerwidget(edit=self._root_widget, transition='out_scale')
class
GamepadAdvancedSettingsWindow(bauiv1._uitypes.Window):
20class GamepadAdvancedSettingsWindow(bui.Window): 21 """Window for advanced gamepad configuration.""" 22 23 def __init__(self, parent_window: GamepadSettingsWindow): 24 # pylint: disable=too-many-statements 25 # pylint: disable=too-many-locals 26 self._parent_window = parent_window 27 28 app = bui.app 29 30 self._r = parent_window.get_r() 31 assert bui.app.classic is not None 32 uiscale = bui.app.ui_v1.uiscale 33 self._width = 900 if uiscale is bui.UIScale.SMALL else 700 34 self._x_inset = x_inset = 100 if uiscale is bui.UIScale.SMALL else 0 35 self._height = 402 if uiscale is bui.UIScale.SMALL else 512 36 self._textwidgets: dict[str, bui.Widget] = {} 37 advb = parent_window.get_advanced_button() 38 super().__init__( 39 root_widget=bui.containerwidget( 40 transition='in_scale', 41 size=(self._width, self._height), 42 scale=1.06 43 * ( 44 1.6 45 if uiscale is bui.UIScale.SMALL 46 else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0 47 ), 48 stack_offset=( 49 (0, -25) if uiscale is bui.UIScale.SMALL else (0, 0) 50 ), 51 scale_origin_stack_offset=(advb.get_screen_space_center()), 52 ) 53 ) 54 55 bui.textwidget( 56 parent=self._root_widget, 57 position=( 58 self._width * 0.5, 59 self._height - (40 if uiscale is bui.UIScale.SMALL else 34), 60 ), 61 size=(0, 0), 62 text=bui.Lstr(resource=f'{self._r}.advancedTitleText'), 63 maxwidth=320, 64 color=bui.app.ui_v1.title_color, 65 h_align='center', 66 v_align='center', 67 ) 68 69 back_button = btn = bui.buttonwidget( 70 parent=self._root_widget, 71 autoselect=True, 72 position=( 73 self._width - (176 + x_inset), 74 self._height - (60 if uiscale is bui.UIScale.SMALL else 55), 75 ), 76 size=(120, 48), 77 text_scale=0.8, 78 label=bui.Lstr(resource='doneText'), 79 on_activate_call=self._done, 80 ) 81 bui.containerwidget( 82 edit=self._root_widget, 83 start_button=btn, 84 on_cancel_call=btn.activate, 85 ) 86 87 self._scroll_width = self._width - (100 + 2 * x_inset) 88 self._scroll_height = self._height - 110 89 self._sub_width = self._scroll_width - 20 90 self._sub_height = ( 91 940 if self._parent_window.get_is_secondary() else 1040 92 ) 93 if app.env.vr: 94 self._sub_height += 50 95 self._scrollwidget = bui.scrollwidget( 96 parent=self._root_widget, 97 position=( 98 (self._width - self._scroll_width) * 0.5, 99 self._height - 65 - self._scroll_height, 100 ), 101 size=(self._scroll_width, self._scroll_height), 102 claims_left_right=True, 103 claims_tab=True, 104 selection_loops_to_parent=True, 105 ) 106 self._subcontainer = bui.containerwidget( 107 parent=self._scrollwidget, 108 size=(self._sub_width, self._sub_height), 109 background=False, 110 claims_left_right=True, 111 claims_tab=True, 112 selection_loops_to_parent=True, 113 ) 114 bui.containerwidget( 115 edit=self._root_widget, selected_child=self._scrollwidget 116 ) 117 118 h = 30 119 v = self._sub_height - 10 120 121 h2 = h + 12 122 123 # don't allow secondary joysticks to handle unassigned buttons 124 if not self._parent_window.get_is_secondary(): 125 v -= 40 126 cb1 = bui.checkboxwidget( 127 parent=self._subcontainer, 128 position=(h + 70, v), 129 size=(500, 30), 130 text=bui.Lstr(resource=f'{self._r}.unassignedButtonsRunText'), 131 textcolor=(0.8, 0.8, 0.8), 132 maxwidth=330, 133 scale=1.0, 134 on_value_change_call=( 135 self._parent_window.set_unassigned_buttons_run_value 136 ), 137 autoselect=True, 138 value=self._parent_window.get_unassigned_buttons_run_value(), 139 ) 140 bui.widget(edit=cb1, up_widget=back_button) 141 v -= 60 142 capb = self._capture_button( 143 pos=(h2, v), 144 name=bui.Lstr(resource=f'{self._r}.runButton1Text'), 145 control='buttonRun1' + self._parent_window.get_ext(), 146 ) 147 if self._parent_window.get_is_secondary(): 148 for widget in capb: 149 bui.widget(edit=widget, up_widget=back_button) 150 v -= 42 151 self._capture_button( 152 pos=(h2, v), 153 name=bui.Lstr(resource=f'{self._r}.runButton2Text'), 154 control='buttonRun2' + self._parent_window.get_ext(), 155 ) 156 bui.textwidget( 157 parent=self._subcontainer, 158 position=(self._sub_width * 0.5, v - 24), 159 size=(0, 0), 160 text=bui.Lstr(resource=f'{self._r}.runTriggerDescriptionText'), 161 color=(0.7, 1, 0.7, 0.6), 162 maxwidth=self._sub_width * 0.8, 163 scale=0.7, 164 h_align='center', 165 v_align='center', 166 ) 167 168 v -= 85 169 170 self._capture_button( 171 pos=(h2, v), 172 name=bui.Lstr(resource=f'{self._r}.runTrigger1Text'), 173 control='triggerRun1' + self._parent_window.get_ext(), 174 message=bui.Lstr(resource=f'{self._r}.pressAnyAnalogTriggerText'), 175 ) 176 v -= 42 177 self._capture_button( 178 pos=(h2, v), 179 name=bui.Lstr(resource=f'{self._r}.runTrigger2Text'), 180 control='triggerRun2' + self._parent_window.get_ext(), 181 message=bui.Lstr(resource=f'{self._r}.pressAnyAnalogTriggerText'), 182 ) 183 184 # in vr mode, allow assigning a reset-view button 185 if app.env.vr: 186 v -= 50 187 self._capture_button( 188 pos=(h2, v), 189 name=bui.Lstr(resource=f'{self._r}.vrReorientButtonText'), 190 control='buttonVRReorient' + self._parent_window.get_ext(), 191 ) 192 193 v -= 60 194 self._capture_button( 195 pos=(h2, v), 196 name=bui.Lstr(resource=f'{self._r}.extraStartButtonText'), 197 control='buttonStart2' + self._parent_window.get_ext(), 198 ) 199 v -= 60 200 self._capture_button( 201 pos=(h2, v), 202 name=bui.Lstr(resource=f'{self._r}.ignoredButton1Text'), 203 control='buttonIgnored' + self._parent_window.get_ext(), 204 ) 205 v -= 42 206 self._capture_button( 207 pos=(h2, v), 208 name=bui.Lstr(resource=f'{self._r}.ignoredButton2Text'), 209 control='buttonIgnored2' + self._parent_window.get_ext(), 210 ) 211 v -= 42 212 self._capture_button( 213 pos=(h2, v), 214 name=bui.Lstr(resource=f'{self._r}.ignoredButton3Text'), 215 control='buttonIgnored3' + self._parent_window.get_ext(), 216 ) 217 v -= 42 218 self._capture_button( 219 pos=(h2, v), 220 name=bui.Lstr(resource=f'{self._r}.ignoredButton4Text'), 221 control='buttonIgnored4' + self._parent_window.get_ext(), 222 ) 223 bui.textwidget( 224 parent=self._subcontainer, 225 position=(self._sub_width * 0.5, v - 14), 226 size=(0, 0), 227 text=bui.Lstr(resource=f'{self._r}.ignoredButtonDescriptionText'), 228 color=(0.7, 1, 0.7, 0.6), 229 scale=0.8, 230 maxwidth=self._sub_width * 0.8, 231 h_align='center', 232 v_align='center', 233 ) 234 235 v -= 80 236 pwin = self._parent_window 237 bui.checkboxwidget( 238 parent=self._subcontainer, 239 autoselect=True, 240 position=(h + 50, v), 241 size=(400, 30), 242 text=bui.Lstr( 243 resource=f'{self._r}.startButtonActivatesDefaultText' 244 ), 245 textcolor=(0.8, 0.8, 0.8), 246 maxwidth=450, 247 scale=0.9, 248 on_value_change_call=( 249 pwin.set_start_button_activates_default_widget_value 250 ), 251 value=pwin.get_start_button_activates_default_widget_value(), 252 ) 253 bui.textwidget( 254 parent=self._subcontainer, 255 position=(self._sub_width * 0.5, v - 12), 256 size=(0, 0), 257 text=bui.Lstr( 258 resource=f'{self._r}.startButtonActivatesDefaultDescriptionText' 259 ), 260 color=(0.7, 1, 0.7, 0.6), 261 maxwidth=self._sub_width * 0.8, 262 scale=0.7, 263 h_align='center', 264 v_align='center', 265 ) 266 267 v -= 80 268 bui.checkboxwidget( 269 parent=self._subcontainer, 270 autoselect=True, 271 position=(h + 50, v), 272 size=(400, 30), 273 text=bui.Lstr(resource=f'{self._r}.uiOnlyText'), 274 textcolor=(0.8, 0.8, 0.8), 275 maxwidth=450, 276 scale=0.9, 277 on_value_change_call=self._parent_window.set_ui_only_value, 278 value=self._parent_window.get_ui_only_value(), 279 ) 280 bui.textwidget( 281 parent=self._subcontainer, 282 position=(self._sub_width * 0.5, v - 12), 283 size=(0, 0), 284 text=bui.Lstr(resource=f'{self._r}.uiOnlyDescriptionText'), 285 color=(0.7, 1, 0.7, 0.6), 286 maxwidth=self._sub_width * 0.8, 287 scale=0.7, 288 h_align='center', 289 v_align='center', 290 ) 291 292 v -= 80 293 bui.checkboxwidget( 294 parent=self._subcontainer, 295 autoselect=True, 296 position=(h + 50, v), 297 size=(400, 30), 298 text=bui.Lstr(resource=f'{self._r}.ignoreCompletelyText'), 299 textcolor=(0.8, 0.8, 0.8), 300 maxwidth=450, 301 scale=0.9, 302 on_value_change_call=pwin.set_ignore_completely_value, 303 value=self._parent_window.get_ignore_completely_value(), 304 ) 305 bui.textwidget( 306 parent=self._subcontainer, 307 position=(self._sub_width * 0.5, v - 12), 308 size=(0, 0), 309 text=bui.Lstr( 310 resource=f'{self._r}.ignoreCompletelyDescriptionText' 311 ), 312 color=(0.7, 1, 0.7, 0.6), 313 maxwidth=self._sub_width * 0.8, 314 scale=0.7, 315 h_align='center', 316 v_align='center', 317 ) 318 319 v -= 80 320 321 cb1 = bui.checkboxwidget( 322 parent=self._subcontainer, 323 autoselect=True, 324 position=(h + 50, v), 325 size=(400, 30), 326 text=bui.Lstr(resource=f'{self._r}.autoRecalibrateText'), 327 textcolor=(0.8, 0.8, 0.8), 328 maxwidth=450, 329 scale=0.9, 330 on_value_change_call=pwin.set_auto_recalibrate_analog_stick_value, 331 value=self._parent_window.get_auto_recalibrate_analog_stick_value(), 332 ) 333 bui.textwidget( 334 parent=self._subcontainer, 335 position=(self._sub_width * 0.5, v - 12), 336 size=(0, 0), 337 text=bui.Lstr(resource=f'{self._r}.autoRecalibrateDescriptionText'), 338 color=(0.7, 1, 0.7, 0.6), 339 maxwidth=self._sub_width * 0.8, 340 scale=0.7, 341 h_align='center', 342 v_align='center', 343 ) 344 v -= 80 345 346 buttons = self._config_value_editor( 347 bui.Lstr(resource=f'{self._r}.analogStickDeadZoneText'), 348 control=('analogStickDeadZone' + self._parent_window.get_ext()), 349 position=(h + 40, v), 350 min_val=0, 351 max_val=10.0, 352 increment=0.1, 353 x_offset=100, 354 ) 355 bui.widget(edit=buttons[0], left_widget=cb1, up_widget=cb1) 356 bui.widget(edit=cb1, right_widget=buttons[0], down_widget=buttons[0]) 357 358 bui.textwidget( 359 parent=self._subcontainer, 360 position=(self._sub_width * 0.5, v - 12), 361 size=(0, 0), 362 text=bui.Lstr( 363 resource=f'{self._r}.analogStickDeadZoneDescriptionText' 364 ), 365 color=(0.7, 1, 0.7, 0.6), 366 maxwidth=self._sub_width * 0.8, 367 scale=0.7, 368 h_align='center', 369 v_align='center', 370 ) 371 v -= 100 372 373 # child joysticks cant have child joysticks.. that's just 374 # crazy talk 375 if not self._parent_window.get_is_secondary(): 376 bui.buttonwidget( 377 parent=self._subcontainer, 378 autoselect=True, 379 label=bui.Lstr(resource=f'{self._r}.twoInOneSetupText'), 380 position=(40, v), 381 size=(self._sub_width - 80, 50), 382 on_activate_call=self._parent_window.show_secondary_editor, 383 up_widget=buttons[0], 384 ) 385 386 # set a bigger bottom show-buffer for the widgets we just made 387 # so we can see the text below them when navigating with 388 # a gamepad 389 for child in self._subcontainer.get_children(): 390 bui.widget(edit=child, show_buffer_bottom=30, show_buffer_top=30) 391 392 def _capture_button( 393 self, 394 pos: tuple[float, float], 395 name: bui.Lstr, 396 control: str, 397 message: bui.Lstr | None = None, 398 ) -> tuple[bui.Widget, bui.Widget]: 399 if message is None: 400 message = bui.Lstr( 401 resource=self._parent_window.get_r() + '.pressAnyButtonText' 402 ) 403 btn = bui.buttonwidget( 404 parent=self._subcontainer, 405 autoselect=True, 406 position=(pos[0], pos[1]), 407 label=name, 408 size=(250, 60), 409 scale=0.7, 410 ) 411 btn2 = bui.buttonwidget( 412 parent=self._subcontainer, 413 autoselect=True, 414 position=(pos[0] + 400, pos[1] + 2), 415 left_widget=btn, 416 color=(0.45, 0.4, 0.5), 417 textcolor=(0.65, 0.6, 0.7), 418 label=bui.Lstr(resource=f'{self._r}.clearText'), 419 size=(110, 50), 420 scale=0.7, 421 on_activate_call=bui.Call(self._clear_control, control), 422 ) 423 bui.widget(edit=btn, right_widget=btn2) 424 425 # make this in a timer so that it shows up on top of all 426 # other buttons 427 428 def doit() -> None: 429 from bauiv1lib.settings.gamepad import AwaitGamepadInputWindow 430 431 txt = bui.textwidget( 432 parent=self._subcontainer, 433 position=(pos[0] + 285, pos[1] + 20), 434 color=(1, 1, 1, 0.3), 435 size=(0, 0), 436 h_align='center', 437 v_align='center', 438 scale=0.7, 439 text=self._parent_window.get_control_value_name(control), 440 maxwidth=200, 441 ) 442 self._textwidgets[control] = txt 443 bui.buttonwidget( 444 edit=btn, 445 on_activate_call=bui.Call( 446 AwaitGamepadInputWindow, 447 self._parent_window.get_input(), 448 control, 449 self._gamepad_event, 450 message, 451 ), 452 ) 453 454 bui.pushcall(doit) 455 return btn, btn2 456 457 def _inc( 458 self, control: str, min_val: float, max_val: float, inc: float 459 ) -> None: 460 val = self._parent_window.get_settings().get(control, 1.0) 461 val = min(max_val, max(min_val, val + inc)) 462 if abs(1.0 - val) < 0.001: 463 if control in self._parent_window.get_settings(): 464 del self._parent_window.get_settings()[control] 465 else: 466 self._parent_window.get_settings()[control] = round(val, 1) 467 bui.textwidget( 468 edit=self._textwidgets[control], 469 text=self._parent_window.get_control_value_name(control), 470 ) 471 472 def _config_value_editor( 473 self, 474 name: bui.Lstr, 475 control: str, 476 position: tuple[float, float], 477 *, 478 min_val: float = 0.0, 479 max_val: float = 100.0, 480 increment: float = 1.0, 481 change_sound: bool = True, 482 x_offset: float = 0.0, 483 displayname: bui.Lstr | None = None, 484 ) -> tuple[bui.Widget, bui.Widget]: 485 if displayname is None: 486 displayname = name 487 bui.textwidget( 488 parent=self._subcontainer, 489 position=position, 490 size=(100, 30), 491 text=displayname, 492 color=(0.8, 0.8, 0.8, 1.0), 493 h_align='left', 494 v_align='center', 495 scale=1.0, 496 maxwidth=280, 497 ) 498 self._textwidgets[control] = bui.textwidget( 499 parent=self._subcontainer, 500 position=(246.0 + x_offset, position[1]), 501 size=(60, 28), 502 editable=False, 503 color=(0.3, 1.0, 0.3, 1.0), 504 h_align='right', 505 v_align='center', 506 text=self._parent_window.get_control_value_name(control), 507 padding=2, 508 ) 509 btn = bui.buttonwidget( 510 parent=self._subcontainer, 511 autoselect=True, 512 position=(330 + x_offset, position[1] + 4), 513 size=(28, 28), 514 label='-', 515 on_activate_call=bui.Call( 516 self._inc, control, min_val, max_val, -increment 517 ), 518 repeat=True, 519 enable_sound=(change_sound is True), 520 ) 521 btn2 = bui.buttonwidget( 522 parent=self._subcontainer, 523 autoselect=True, 524 position=(380 + x_offset, position[1] + 4), 525 size=(28, 28), 526 label='+', 527 on_activate_call=bui.Call( 528 self._inc, control, min_val, max_val, increment 529 ), 530 repeat=True, 531 enable_sound=(change_sound is True), 532 ) 533 return btn, btn2 534 535 def _clear_control(self, control: str) -> None: 536 if control in self._parent_window.get_settings(): 537 del self._parent_window.get_settings()[control] 538 bui.textwidget( 539 edit=self._textwidgets[control], 540 text=self._parent_window.get_control_value_name(control), 541 ) 542 543 def _gamepad_event( 544 self, 545 control: str, 546 event: dict[str, Any], 547 dialog: AwaitGamepadInputWindow, 548 ) -> None: 549 ext = self._parent_window.get_ext() 550 if control in ['triggerRun1' + ext, 'triggerRun2' + ext]: 551 if event['type'] == 'AXISMOTION': 552 # ignore small values or else we might get triggered 553 # by noise 554 if abs(event['value']) > 0.5: 555 self._parent_window.get_settings()[control] = event['axis'] 556 # update the button's text widget 557 if self._textwidgets[control]: 558 bui.textwidget( 559 edit=self._textwidgets[control], 560 text=self._parent_window.get_control_value_name( 561 control 562 ), 563 ) 564 bui.getsound('gunCocking').play() 565 dialog.die() 566 else: 567 if event['type'] == 'BUTTONDOWN': 568 value = event['button'] 569 self._parent_window.get_settings()[control] = value 570 # update the button's text widget 571 if self._textwidgets[control]: 572 bui.textwidget( 573 edit=self._textwidgets[control], 574 text=self._parent_window.get_control_value_name( 575 control 576 ), 577 ) 578 bui.getsound('gunCocking').play() 579 dialog.die() 580 581 def _done(self) -> None: 582 bui.containerwidget(edit=self._root_widget, transition='out_scale')
Window for advanced gamepad configuration.
GamepadAdvancedSettingsWindow(parent_window: bauiv1lib.settings.gamepad.GamepadSettingsWindow)
23 def __init__(self, parent_window: GamepadSettingsWindow): 24 # pylint: disable=too-many-statements 25 # pylint: disable=too-many-locals 26 self._parent_window = parent_window 27 28 app = bui.app 29 30 self._r = parent_window.get_r() 31 assert bui.app.classic is not None 32 uiscale = bui.app.ui_v1.uiscale 33 self._width = 900 if uiscale is bui.UIScale.SMALL else 700 34 self._x_inset = x_inset = 100 if uiscale is bui.UIScale.SMALL else 0 35 self._height = 402 if uiscale is bui.UIScale.SMALL else 512 36 self._textwidgets: dict[str, bui.Widget] = {} 37 advb = parent_window.get_advanced_button() 38 super().__init__( 39 root_widget=bui.containerwidget( 40 transition='in_scale', 41 size=(self._width, self._height), 42 scale=1.06 43 * ( 44 1.6 45 if uiscale is bui.UIScale.SMALL 46 else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0 47 ), 48 stack_offset=( 49 (0, -25) if uiscale is bui.UIScale.SMALL else (0, 0) 50 ), 51 scale_origin_stack_offset=(advb.get_screen_space_center()), 52 ) 53 ) 54 55 bui.textwidget( 56 parent=self._root_widget, 57 position=( 58 self._width * 0.5, 59 self._height - (40 if uiscale is bui.UIScale.SMALL else 34), 60 ), 61 size=(0, 0), 62 text=bui.Lstr(resource=f'{self._r}.advancedTitleText'), 63 maxwidth=320, 64 color=bui.app.ui_v1.title_color, 65 h_align='center', 66 v_align='center', 67 ) 68 69 back_button = btn = bui.buttonwidget( 70 parent=self._root_widget, 71 autoselect=True, 72 position=( 73 self._width - (176 + x_inset), 74 self._height - (60 if uiscale is bui.UIScale.SMALL else 55), 75 ), 76 size=(120, 48), 77 text_scale=0.8, 78 label=bui.Lstr(resource='doneText'), 79 on_activate_call=self._done, 80 ) 81 bui.containerwidget( 82 edit=self._root_widget, 83 start_button=btn, 84 on_cancel_call=btn.activate, 85 ) 86 87 self._scroll_width = self._width - (100 + 2 * x_inset) 88 self._scroll_height = self._height - 110 89 self._sub_width = self._scroll_width - 20 90 self._sub_height = ( 91 940 if self._parent_window.get_is_secondary() else 1040 92 ) 93 if app.env.vr: 94 self._sub_height += 50 95 self._scrollwidget = bui.scrollwidget( 96 parent=self._root_widget, 97 position=( 98 (self._width - self._scroll_width) * 0.5, 99 self._height - 65 - self._scroll_height, 100 ), 101 size=(self._scroll_width, self._scroll_height), 102 claims_left_right=True, 103 claims_tab=True, 104 selection_loops_to_parent=True, 105 ) 106 self._subcontainer = bui.containerwidget( 107 parent=self._scrollwidget, 108 size=(self._sub_width, self._sub_height), 109 background=False, 110 claims_left_right=True, 111 claims_tab=True, 112 selection_loops_to_parent=True, 113 ) 114 bui.containerwidget( 115 edit=self._root_widget, selected_child=self._scrollwidget 116 ) 117 118 h = 30 119 v = self._sub_height - 10 120 121 h2 = h + 12 122 123 # don't allow secondary joysticks to handle unassigned buttons 124 if not self._parent_window.get_is_secondary(): 125 v -= 40 126 cb1 = bui.checkboxwidget( 127 parent=self._subcontainer, 128 position=(h + 70, v), 129 size=(500, 30), 130 text=bui.Lstr(resource=f'{self._r}.unassignedButtonsRunText'), 131 textcolor=(0.8, 0.8, 0.8), 132 maxwidth=330, 133 scale=1.0, 134 on_value_change_call=( 135 self._parent_window.set_unassigned_buttons_run_value 136 ), 137 autoselect=True, 138 value=self._parent_window.get_unassigned_buttons_run_value(), 139 ) 140 bui.widget(edit=cb1, up_widget=back_button) 141 v -= 60 142 capb = self._capture_button( 143 pos=(h2, v), 144 name=bui.Lstr(resource=f'{self._r}.runButton1Text'), 145 control='buttonRun1' + self._parent_window.get_ext(), 146 ) 147 if self._parent_window.get_is_secondary(): 148 for widget in capb: 149 bui.widget(edit=widget, up_widget=back_button) 150 v -= 42 151 self._capture_button( 152 pos=(h2, v), 153 name=bui.Lstr(resource=f'{self._r}.runButton2Text'), 154 control='buttonRun2' + self._parent_window.get_ext(), 155 ) 156 bui.textwidget( 157 parent=self._subcontainer, 158 position=(self._sub_width * 0.5, v - 24), 159 size=(0, 0), 160 text=bui.Lstr(resource=f'{self._r}.runTriggerDescriptionText'), 161 color=(0.7, 1, 0.7, 0.6), 162 maxwidth=self._sub_width * 0.8, 163 scale=0.7, 164 h_align='center', 165 v_align='center', 166 ) 167 168 v -= 85 169 170 self._capture_button( 171 pos=(h2, v), 172 name=bui.Lstr(resource=f'{self._r}.runTrigger1Text'), 173 control='triggerRun1' + self._parent_window.get_ext(), 174 message=bui.Lstr(resource=f'{self._r}.pressAnyAnalogTriggerText'), 175 ) 176 v -= 42 177 self._capture_button( 178 pos=(h2, v), 179 name=bui.Lstr(resource=f'{self._r}.runTrigger2Text'), 180 control='triggerRun2' + self._parent_window.get_ext(), 181 message=bui.Lstr(resource=f'{self._r}.pressAnyAnalogTriggerText'), 182 ) 183 184 # in vr mode, allow assigning a reset-view button 185 if app.env.vr: 186 v -= 50 187 self._capture_button( 188 pos=(h2, v), 189 name=bui.Lstr(resource=f'{self._r}.vrReorientButtonText'), 190 control='buttonVRReorient' + self._parent_window.get_ext(), 191 ) 192 193 v -= 60 194 self._capture_button( 195 pos=(h2, v), 196 name=bui.Lstr(resource=f'{self._r}.extraStartButtonText'), 197 control='buttonStart2' + self._parent_window.get_ext(), 198 ) 199 v -= 60 200 self._capture_button( 201 pos=(h2, v), 202 name=bui.Lstr(resource=f'{self._r}.ignoredButton1Text'), 203 control='buttonIgnored' + self._parent_window.get_ext(), 204 ) 205 v -= 42 206 self._capture_button( 207 pos=(h2, v), 208 name=bui.Lstr(resource=f'{self._r}.ignoredButton2Text'), 209 control='buttonIgnored2' + self._parent_window.get_ext(), 210 ) 211 v -= 42 212 self._capture_button( 213 pos=(h2, v), 214 name=bui.Lstr(resource=f'{self._r}.ignoredButton3Text'), 215 control='buttonIgnored3' + self._parent_window.get_ext(), 216 ) 217 v -= 42 218 self._capture_button( 219 pos=(h2, v), 220 name=bui.Lstr(resource=f'{self._r}.ignoredButton4Text'), 221 control='buttonIgnored4' + self._parent_window.get_ext(), 222 ) 223 bui.textwidget( 224 parent=self._subcontainer, 225 position=(self._sub_width * 0.5, v - 14), 226 size=(0, 0), 227 text=bui.Lstr(resource=f'{self._r}.ignoredButtonDescriptionText'), 228 color=(0.7, 1, 0.7, 0.6), 229 scale=0.8, 230 maxwidth=self._sub_width * 0.8, 231 h_align='center', 232 v_align='center', 233 ) 234 235 v -= 80 236 pwin = self._parent_window 237 bui.checkboxwidget( 238 parent=self._subcontainer, 239 autoselect=True, 240 position=(h + 50, v), 241 size=(400, 30), 242 text=bui.Lstr( 243 resource=f'{self._r}.startButtonActivatesDefaultText' 244 ), 245 textcolor=(0.8, 0.8, 0.8), 246 maxwidth=450, 247 scale=0.9, 248 on_value_change_call=( 249 pwin.set_start_button_activates_default_widget_value 250 ), 251 value=pwin.get_start_button_activates_default_widget_value(), 252 ) 253 bui.textwidget( 254 parent=self._subcontainer, 255 position=(self._sub_width * 0.5, v - 12), 256 size=(0, 0), 257 text=bui.Lstr( 258 resource=f'{self._r}.startButtonActivatesDefaultDescriptionText' 259 ), 260 color=(0.7, 1, 0.7, 0.6), 261 maxwidth=self._sub_width * 0.8, 262 scale=0.7, 263 h_align='center', 264 v_align='center', 265 ) 266 267 v -= 80 268 bui.checkboxwidget( 269 parent=self._subcontainer, 270 autoselect=True, 271 position=(h + 50, v), 272 size=(400, 30), 273 text=bui.Lstr(resource=f'{self._r}.uiOnlyText'), 274 textcolor=(0.8, 0.8, 0.8), 275 maxwidth=450, 276 scale=0.9, 277 on_value_change_call=self._parent_window.set_ui_only_value, 278 value=self._parent_window.get_ui_only_value(), 279 ) 280 bui.textwidget( 281 parent=self._subcontainer, 282 position=(self._sub_width * 0.5, v - 12), 283 size=(0, 0), 284 text=bui.Lstr(resource=f'{self._r}.uiOnlyDescriptionText'), 285 color=(0.7, 1, 0.7, 0.6), 286 maxwidth=self._sub_width * 0.8, 287 scale=0.7, 288 h_align='center', 289 v_align='center', 290 ) 291 292 v -= 80 293 bui.checkboxwidget( 294 parent=self._subcontainer, 295 autoselect=True, 296 position=(h + 50, v), 297 size=(400, 30), 298 text=bui.Lstr(resource=f'{self._r}.ignoreCompletelyText'), 299 textcolor=(0.8, 0.8, 0.8), 300 maxwidth=450, 301 scale=0.9, 302 on_value_change_call=pwin.set_ignore_completely_value, 303 value=self._parent_window.get_ignore_completely_value(), 304 ) 305 bui.textwidget( 306 parent=self._subcontainer, 307 position=(self._sub_width * 0.5, v - 12), 308 size=(0, 0), 309 text=bui.Lstr( 310 resource=f'{self._r}.ignoreCompletelyDescriptionText' 311 ), 312 color=(0.7, 1, 0.7, 0.6), 313 maxwidth=self._sub_width * 0.8, 314 scale=0.7, 315 h_align='center', 316 v_align='center', 317 ) 318 319 v -= 80 320 321 cb1 = bui.checkboxwidget( 322 parent=self._subcontainer, 323 autoselect=True, 324 position=(h + 50, v), 325 size=(400, 30), 326 text=bui.Lstr(resource=f'{self._r}.autoRecalibrateText'), 327 textcolor=(0.8, 0.8, 0.8), 328 maxwidth=450, 329 scale=0.9, 330 on_value_change_call=pwin.set_auto_recalibrate_analog_stick_value, 331 value=self._parent_window.get_auto_recalibrate_analog_stick_value(), 332 ) 333 bui.textwidget( 334 parent=self._subcontainer, 335 position=(self._sub_width * 0.5, v - 12), 336 size=(0, 0), 337 text=bui.Lstr(resource=f'{self._r}.autoRecalibrateDescriptionText'), 338 color=(0.7, 1, 0.7, 0.6), 339 maxwidth=self._sub_width * 0.8, 340 scale=0.7, 341 h_align='center', 342 v_align='center', 343 ) 344 v -= 80 345 346 buttons = self._config_value_editor( 347 bui.Lstr(resource=f'{self._r}.analogStickDeadZoneText'), 348 control=('analogStickDeadZone' + self._parent_window.get_ext()), 349 position=(h + 40, v), 350 min_val=0, 351 max_val=10.0, 352 increment=0.1, 353 x_offset=100, 354 ) 355 bui.widget(edit=buttons[0], left_widget=cb1, up_widget=cb1) 356 bui.widget(edit=cb1, right_widget=buttons[0], down_widget=buttons[0]) 357 358 bui.textwidget( 359 parent=self._subcontainer, 360 position=(self._sub_width * 0.5, v - 12), 361 size=(0, 0), 362 text=bui.Lstr( 363 resource=f'{self._r}.analogStickDeadZoneDescriptionText' 364 ), 365 color=(0.7, 1, 0.7, 0.6), 366 maxwidth=self._sub_width * 0.8, 367 scale=0.7, 368 h_align='center', 369 v_align='center', 370 ) 371 v -= 100 372 373 # child joysticks cant have child joysticks.. that's just 374 # crazy talk 375 if not self._parent_window.get_is_secondary(): 376 bui.buttonwidget( 377 parent=self._subcontainer, 378 autoselect=True, 379 label=bui.Lstr(resource=f'{self._r}.twoInOneSetupText'), 380 position=(40, v), 381 size=(self._sub_width - 80, 50), 382 on_activate_call=self._parent_window.show_secondary_editor, 383 up_widget=buttons[0], 384 ) 385 386 # set a bigger bottom show-buffer for the widgets we just made 387 # so we can see the text below them when navigating with 388 # a gamepad 389 for child in self._subcontainer.get_children(): 390 bui.widget(edit=child, show_buffer_bottom=30, show_buffer_top=30)