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