bauiv1lib.settings.gamepadselect

Settings UI related to gamepad functionality.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Settings UI related to gamepad functionality."""
  4
  5from __future__ import annotations
  6
  7import logging
  8from typing import TYPE_CHECKING
  9
 10import bascenev1 as bs
 11import bauiv1 as bui
 12
 13if TYPE_CHECKING:
 14    from typing import Any
 15
 16
 17def gamepad_configure_callback(event: dict[str, Any]) -> None:
 18    """Respond to a gamepad button press during config selection."""
 19    from bauiv1lib.settings import gamepad
 20
 21    # Ignore all but button-presses.
 22    if event['type'] not in ['BUTTONDOWN', 'HATMOTION']:
 23        return
 24    bs.release_gamepad_input()
 25    assert bui.app.classic is not None
 26    try:
 27        bui.app.ui_v1.clear_main_menu_window(transition='out_left')
 28    except Exception:
 29        logging.exception('Error transitioning out main_menu_window.')
 30    bui.getsound('activateBeep').play()
 31    bui.getsound('swish').play()
 32    device = event['input_device']
 33    assert isinstance(device, bs.InputDevice)
 34    if device.allows_configuring:
 35        bui.app.ui_v1.set_main_menu_window(
 36            gamepad.GamepadSettingsWindow(device).get_root_widget(),
 37            from_window=None,
 38        )
 39    else:
 40        width = 700
 41        height = 200
 42        button_width = 80
 43        uiscale = bui.app.ui_v1.uiscale
 44        dlg = bui.containerwidget(
 45            scale=(
 46                1.7
 47                if uiscale is bui.UIScale.SMALL
 48                else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0
 49            ),
 50            size=(width, height),
 51            transition='in_right',
 52        )
 53        bui.app.ui_v1.set_main_menu_window(dlg, from_window=None)
 54
 55        if device.allows_configuring_in_system_settings:
 56            msg = bui.Lstr(
 57                resource='configureDeviceInSystemSettingsText',
 58                subs=[('${DEVICE}', device.name)],
 59            )
 60        elif device.is_controller_app:
 61            msg = bui.Lstr(
 62                resource='bsRemoteConfigureInAppText',
 63                subs=[('${REMOTE_APP_NAME}', bui.get_remote_app_name())],
 64            )
 65        else:
 66            msg = bui.Lstr(
 67                resource='cantConfigureDeviceText',
 68                subs=[('${DEVICE}', device.name)],
 69            )
 70        bui.textwidget(
 71            parent=dlg,
 72            position=(0, height - 80),
 73            size=(width, 25),
 74            text=msg,
 75            scale=0.8,
 76            h_align='center',
 77            v_align='top',
 78        )
 79
 80        def _ok() -> None:
 81            from bauiv1lib.settings import controls
 82
 83            # no-op if our underlying widget is dead or on its way out.
 84            if not dlg or dlg.transitioning_out:
 85                return
 86
 87            bui.containerwidget(edit=dlg, transition='out_right')
 88            assert bui.app.classic is not None
 89            bui.app.ui_v1.set_main_menu_window(
 90                controls.ControlsSettingsWindow(
 91                    transition='in_left'
 92                ).get_root_widget(),
 93                from_window=dlg,
 94            )
 95
 96        bui.buttonwidget(
 97            parent=dlg,
 98            position=((width - button_width) / 2, 20),
 99            size=(button_width, 60),
100            label=bui.Lstr(resource='okText'),
101            on_activate_call=_ok,
102        )
103
104
105class GamepadSelectWindow(bui.Window):
106    """Window for selecting a gamepad to configure."""
107
108    def __init__(self) -> None:
109        from typing import cast
110
111        width = 480
112        height = 170
113        spacing = 40
114        self._r = 'configGamepadSelectWindow'
115
116        assert bui.app.classic is not None
117        uiscale = bui.app.ui_v1.uiscale
118        super().__init__(
119            root_widget=bui.containerwidget(
120                scale=(
121                    2.3
122                    if uiscale is bui.UIScale.SMALL
123                    else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
124                ),
125                size=(width, height),
126                transition='in_right',
127            )
128        )
129
130        btn = bui.buttonwidget(
131            parent=self._root_widget,
132            position=(20, height - 60),
133            size=(130, 60),
134            label=bui.Lstr(resource='backText'),
135            button_type='back',
136            scale=0.8,
137            on_activate_call=self._back,
138        )
139        # Let's not have anything selected by default; its misleading looking
140        # for the controller getting configured.
141        bui.containerwidget(
142            edit=self._root_widget,
143            cancel_button=btn,
144            selected_child=cast(bui.Widget, 0),
145        )
146        bui.textwidget(
147            parent=self._root_widget,
148            position=(20, height - 50),
149            size=(width, 25),
150            text=bui.Lstr(resource=self._r + '.titleText'),
151            maxwidth=250,
152            color=bui.app.ui_v1.title_color,
153            h_align='center',
154            v_align='center',
155        )
156
157        bui.buttonwidget(
158            edit=btn,
159            button_type='backSmall',
160            size=(60, 60),
161            label=bui.charstr(bui.SpecialChar.BACK),
162        )
163
164        v: float = height - 60
165        v -= spacing
166        bui.textwidget(
167            parent=self._root_widget,
168            position=(15, v),
169            size=(width - 30, 30),
170            scale=0.8,
171            text=bui.Lstr(resource=self._r + '.pressAnyButtonText'),
172            maxwidth=width * 0.95,
173            color=bui.app.ui_v1.infotextcolor,
174            h_align='center',
175            v_align='top',
176        )
177        v -= spacing * 1.24
178        if bui.app.classic.platform == 'android':
179            bui.textwidget(
180                parent=self._root_widget,
181                position=(15, v),
182                size=(width - 30, 30),
183                scale=0.46,
184                text=bui.Lstr(resource=self._r + '.androidNoteText'),
185                maxwidth=width * 0.95,
186                color=(0.7, 0.9, 0.7, 0.5),
187                h_align='center',
188                v_align='top',
189            )
190
191        bs.capture_gamepad_input(gamepad_configure_callback)
192
193    def _back(self) -> None:
194        from bauiv1lib.settings import controls
195
196        # no-op if our underlying widget is dead or on its way out.
197        if not self._root_widget or self._root_widget.transitioning_out:
198            return
199
200        bs.release_gamepad_input()
201        bui.containerwidget(edit=self._root_widget, transition='out_right')
202        assert bui.app.classic is not None
203        bui.app.ui_v1.set_main_menu_window(
204            controls.ControlsSettingsWindow(
205                transition='in_left'
206            ).get_root_widget(),
207            from_window=self._root_widget,
208        )
def gamepad_configure_callback(event: dict[str, typing.Any]) -> None:
 18def gamepad_configure_callback(event: dict[str, Any]) -> None:
 19    """Respond to a gamepad button press during config selection."""
 20    from bauiv1lib.settings import gamepad
 21
 22    # Ignore all but button-presses.
 23    if event['type'] not in ['BUTTONDOWN', 'HATMOTION']:
 24        return
 25    bs.release_gamepad_input()
 26    assert bui.app.classic is not None
 27    try:
 28        bui.app.ui_v1.clear_main_menu_window(transition='out_left')
 29    except Exception:
 30        logging.exception('Error transitioning out main_menu_window.')
 31    bui.getsound('activateBeep').play()
 32    bui.getsound('swish').play()
 33    device = event['input_device']
 34    assert isinstance(device, bs.InputDevice)
 35    if device.allows_configuring:
 36        bui.app.ui_v1.set_main_menu_window(
 37            gamepad.GamepadSettingsWindow(device).get_root_widget(),
 38            from_window=None,
 39        )
 40    else:
 41        width = 700
 42        height = 200
 43        button_width = 80
 44        uiscale = bui.app.ui_v1.uiscale
 45        dlg = bui.containerwidget(
 46            scale=(
 47                1.7
 48                if uiscale is bui.UIScale.SMALL
 49                else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0
 50            ),
 51            size=(width, height),
 52            transition='in_right',
 53        )
 54        bui.app.ui_v1.set_main_menu_window(dlg, from_window=None)
 55
 56        if device.allows_configuring_in_system_settings:
 57            msg = bui.Lstr(
 58                resource='configureDeviceInSystemSettingsText',
 59                subs=[('${DEVICE}', device.name)],
 60            )
 61        elif device.is_controller_app:
 62            msg = bui.Lstr(
 63                resource='bsRemoteConfigureInAppText',
 64                subs=[('${REMOTE_APP_NAME}', bui.get_remote_app_name())],
 65            )
 66        else:
 67            msg = bui.Lstr(
 68                resource='cantConfigureDeviceText',
 69                subs=[('${DEVICE}', device.name)],
 70            )
 71        bui.textwidget(
 72            parent=dlg,
 73            position=(0, height - 80),
 74            size=(width, 25),
 75            text=msg,
 76            scale=0.8,
 77            h_align='center',
 78            v_align='top',
 79        )
 80
 81        def _ok() -> None:
 82            from bauiv1lib.settings import controls
 83
 84            # no-op if our underlying widget is dead or on its way out.
 85            if not dlg or dlg.transitioning_out:
 86                return
 87
 88            bui.containerwidget(edit=dlg, transition='out_right')
 89            assert bui.app.classic is not None
 90            bui.app.ui_v1.set_main_menu_window(
 91                controls.ControlsSettingsWindow(
 92                    transition='in_left'
 93                ).get_root_widget(),
 94                from_window=dlg,
 95            )
 96
 97        bui.buttonwidget(
 98            parent=dlg,
 99            position=((width - button_width) / 2, 20),
100            size=(button_width, 60),
101            label=bui.Lstr(resource='okText'),
102            on_activate_call=_ok,
103        )

Respond to a gamepad button press during config selection.

class GamepadSelectWindow(bauiv1._uitypes.Window):
106class GamepadSelectWindow(bui.Window):
107    """Window for selecting a gamepad to configure."""
108
109    def __init__(self) -> None:
110        from typing import cast
111
112        width = 480
113        height = 170
114        spacing = 40
115        self._r = 'configGamepadSelectWindow'
116
117        assert bui.app.classic is not None
118        uiscale = bui.app.ui_v1.uiscale
119        super().__init__(
120            root_widget=bui.containerwidget(
121                scale=(
122                    2.3
123                    if uiscale is bui.UIScale.SMALL
124                    else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
125                ),
126                size=(width, height),
127                transition='in_right',
128            )
129        )
130
131        btn = bui.buttonwidget(
132            parent=self._root_widget,
133            position=(20, height - 60),
134            size=(130, 60),
135            label=bui.Lstr(resource='backText'),
136            button_type='back',
137            scale=0.8,
138            on_activate_call=self._back,
139        )
140        # Let's not have anything selected by default; its misleading looking
141        # for the controller getting configured.
142        bui.containerwidget(
143            edit=self._root_widget,
144            cancel_button=btn,
145            selected_child=cast(bui.Widget, 0),
146        )
147        bui.textwidget(
148            parent=self._root_widget,
149            position=(20, height - 50),
150            size=(width, 25),
151            text=bui.Lstr(resource=self._r + '.titleText'),
152            maxwidth=250,
153            color=bui.app.ui_v1.title_color,
154            h_align='center',
155            v_align='center',
156        )
157
158        bui.buttonwidget(
159            edit=btn,
160            button_type='backSmall',
161            size=(60, 60),
162            label=bui.charstr(bui.SpecialChar.BACK),
163        )
164
165        v: float = height - 60
166        v -= spacing
167        bui.textwidget(
168            parent=self._root_widget,
169            position=(15, v),
170            size=(width - 30, 30),
171            scale=0.8,
172            text=bui.Lstr(resource=self._r + '.pressAnyButtonText'),
173            maxwidth=width * 0.95,
174            color=bui.app.ui_v1.infotextcolor,
175            h_align='center',
176            v_align='top',
177        )
178        v -= spacing * 1.24
179        if bui.app.classic.platform == 'android':
180            bui.textwidget(
181                parent=self._root_widget,
182                position=(15, v),
183                size=(width - 30, 30),
184                scale=0.46,
185                text=bui.Lstr(resource=self._r + '.androidNoteText'),
186                maxwidth=width * 0.95,
187                color=(0.7, 0.9, 0.7, 0.5),
188                h_align='center',
189                v_align='top',
190            )
191
192        bs.capture_gamepad_input(gamepad_configure_callback)
193
194    def _back(self) -> None:
195        from bauiv1lib.settings import controls
196
197        # no-op if our underlying widget is dead or on its way out.
198        if not self._root_widget or self._root_widget.transitioning_out:
199            return
200
201        bs.release_gamepad_input()
202        bui.containerwidget(edit=self._root_widget, transition='out_right')
203        assert bui.app.classic is not None
204        bui.app.ui_v1.set_main_menu_window(
205            controls.ControlsSettingsWindow(
206                transition='in_left'
207            ).get_root_widget(),
208            from_window=self._root_widget,
209        )

Window for selecting a gamepad to configure.

Inherited Members
bauiv1._uitypes.Window
get_root_widget