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