diff --git a/.efrocachemap b/.efrocachemap index 209822f2..ae335fa3 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4096,26 +4096,26 @@ "build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599", - "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "b4a141253c7e65acf25669015d739dc8", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "66dd516f011240f4bd89d960747f5306", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "7467a00e52c02904d385a9f03cb938c1", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "bff07f7aaba6de3994093450f6b7652e", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "e4264a74c5197c903ced0f9fad9f358f", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "0b2b7ffdcba7fce08115d60f46907dd3", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "2b6bedf49d78797be81a3a91a40faea4", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "8a83499d274108ac181c8709cfecebcc", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "ac51052669f94969d50c32c3bb5faa39", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "0de05110dc0d73c578f1ee90098d062f", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "29536a3ccaa1373662a9ad61d15ea311", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "56d6bd161d82ff248b1389c83dbc1a9e", - "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "8cfafd625e0744cc1cd6a825d4192d6b", - "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "5673525e6591eed323a574dbc4e053cd", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "fef949796918e90da2c867d212923fc5", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "2c5b61d0105dc5c2c0d69fee4de0b3bb", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "27084c4785c00b0b47348a7ea2121df4", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "b474ebbbd3498bfbbf7ade35bf4e3273", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "9d364f0f8023699a7f4c14ee4f1f80a2", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "e8b7846713d5aca5a9a472652b49bced", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "fdb570ca6bdd3b6d99ce8c8d253fb2e3", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "5d4acb829768fdbeabe94131d0483a6a", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "b6627d26b51b581205ce26e493bd190c", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "cbb7d5c3650237e6b442fb2ebda46f1c", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "b8b599bf7db21492c4a45e80978b5949", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "0d90cea395d9aaaabcd158663225a3dd", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "1564bba0949d9e1aa65f1389cd03c96e", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "2613a1072975508a5123ccd847b6a1c9", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "941b27dafbe60f4a4225ecc2998ce4f6", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "5e95b9923453b0f4b78f9e2a7258c3d5", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "810852a17cf44c522740628fa24f71e8", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "13008f16f21abcfb24262ce2842718dc", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "9af0b5d3b404bd6a00e7405ec28d2f86", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "9316ea6bb849e1f2420fa738ebd51be0", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "5c25ed8b51702160adf7f94975333690", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "32cb3de3deccb042d6bc23f9051605db", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "980fabe1caa650ad63e0dfad15aeb681", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "8fa7fd27a3f1cbca84c1e22e899ea82f", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "58b9330de90f5e7dd2f448252a1e5c62", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "ad8711189edb9ac148010d4cb976fedf", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "73ad3303fe1a82005918fbc5dae3446c", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "fa659b5d6119acba6570c92ce4d35ae2", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "73ad3303fe1a82005918fbc5dae3446c", @@ -4132,14 +4132,14 @@ "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "3e5c5fd0a09f55ba7b05ce1e2ec7171e", "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "1659535e95e3047fda529543e265ac97", "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "3e5c5fd0a09f55ba7b05ce1e2ec7171e", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "8f7ffb5997d1601d57d71af95584d719", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "cacccdf999c17e285edfb89a830f2286", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "c39508091d106d9fb77fd676a14ae4b1", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "584298e65be570d131f7543744c28b47", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "79a0e0beb67caef006d3ef5d3afa3fae", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "a5520e9b3ba6556412381d179a9e3884", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "5ad1b6928cdb9fb4e0c29f399785f535", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "504cfbf0d946547c3c26bda13afe0833", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "5be7c79fcb8dfefc17234f63094dae1a", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "c61e76677707094a5c476d4bf3b35027", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "1cce083c5562eebc8bab6ecf8154223a", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "2d5421108b9066f34c049fce5f0dec2c", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "149d53a2414c3731e595f5d93dc966cd", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "c88b477490ed0e3cf5712cbef3efbe66", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "241bef769bc25143b622da29cd2e7b9d", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "64483ffc9564a7e3f782c26637b0bd4f", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/enums.py": "cb299985623bbcc86015cb103a424ae6", "src/ballistica/base/mgen/pyembed/binding_base.inc": "efa61468cf098f77cc6a234461d8b86d", diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f1675c1..80fbfb26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.37 (build 21980, api 9, 2024-09-03) +### 1.7.37 (build 21982, api 9, 2024-09-03) - Bumping api version to 9. As you'll see below, there's some UI changes that will require a bit of work for any UI mods to adapt to. If your mods don't touch UI stuff at all you can simply bump your api version and call it a day. diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index 504da6c9..42621884 100644 --- a/src/assets/ba_data/python/baenv.py +++ b/src/assets/ba_data/python/baenv.py @@ -52,7 +52,7 @@ if TYPE_CHECKING: # Build number and version of the ballistica binary we expect to be # using. -TARGET_BALLISTICA_BUILD = 21980 +TARGET_BALLISTICA_BUILD = 21982 TARGET_BALLISTICA_VERSION = '1.7.37' diff --git a/src/assets/ba_data/python/bauiv1/_appsubsystem.py b/src/assets/ba_data/python/bauiv1/_appsubsystem.py index d9fc8d41..2e9a5aaa 100644 --- a/src/assets/ba_data/python/bauiv1/_appsubsystem.py +++ b/src/assets/ba_data/python/bauiv1/_appsubsystem.py @@ -346,13 +346,13 @@ class UIV1AppSubsystem(babase.AppSubsystem): """Return whether a main menu window is present.""" return bool(self._main_window_widget) - def clear_main_window(self) -> None: + def clear_main_window(self, transition: str | None = None) -> None: """Clear any existing main window.""" from bauiv1._uitypes import MainWindow main_window = self._main_window() if main_window: - main_window.main_window_close() + main_window.main_window_close(transition=transition) else: # Fallback; if we have a widget but no window, nuke the widget. if self._main_window_widget: diff --git a/src/assets/ba_data/python/bauiv1/_uitypes.py b/src/assets/ba_data/python/bauiv1/_uitypes.py index 2743bde3..69cc8b04 100644 --- a/src/assets/ba_data/python/bauiv1/_uitypes.py +++ b/src/assets/ba_data/python/bauiv1/_uitypes.py @@ -136,7 +136,9 @@ class MainWindow(Window): self.main_window_close() - def main_window_replace(self, new_window: MainWindow) -> None: + def main_window_replace( + self, new_window: MainWindow, back_state: MainWindowState | None = None + ) -> None: """Replace ourself with a new MainWindow.""" # Users should always check main_window_has_control() *before* @@ -161,7 +163,9 @@ class MainWindow(Window): logging.exception('Error in on_main_window_close() for %s.', self) _bauiv1.containerwidget(edit=self._root_widget, transition=transition) - babase.app.ui_v1.set_main_window(new_window, from_window=self) + babase.app.ui_v1.set_main_window( + new_window, from_window=self, back_state=back_state + ) def on_main_window_close(self) -> None: """Called before transitioning out a main window. diff --git a/src/assets/ba_data/python/bauiv1lib/gather/privatetab.py b/src/assets/ba_data/python/bauiv1lib/gather/privatetab.py index 8681fa12..65854a1a 100644 --- a/src/assets/ba_data/python/bauiv1lib/gather/privatetab.py +++ b/src/assets/ba_data/python/bauiv1lib/gather/privatetab.py @@ -921,9 +921,6 @@ class PrivateGatherTab(GatherTab): ) def _playlist_press(self) -> None: - # if bool(True): - # bui.screenmessage('UNDER CONSTRUCTION') - # return assert self._host_playlist_button is not None self._state.playlist_select_context = PlaylistSelectContext() diff --git a/src/assets/ba_data/python/bauiv1lib/settings/gamepad.py b/src/assets/ba_data/python/bauiv1lib/settings/gamepad.py index 1a0cba67..6b43edc7 100644 --- a/src/assets/ba_data/python/bauiv1lib/settings/gamepad.py +++ b/src/assets/ba_data/python/bauiv1lib/settings/gamepad.py @@ -24,20 +24,20 @@ class GamepadSettingsWindow(bui.MainWindow): def __init__( self, - gamepad: bs.InputDevice, - is_main_menu: bool = True, + inputdevice: bs.InputDevice, + modal: bool = False, transition: str = 'in_right', transition_out: str = 'out_right', origin_widget: bui.Widget | None = None, settings: dict | None = None, ): - self._input = gamepad + self._inputdevice = inputdevice # If our input-device went away, just return an empty zombie. - if not self._input: + if not self._inputdevice: return - self._name = self._input.name + self._name = self._inputdevice.name self._r = 'configGamepadWindow' self._transition_out = transition_out @@ -45,7 +45,7 @@ class GamepadSettingsWindow(bui.MainWindow): # We're a secondary gamepad if supplied with settings. self._is_secondary = settings is not None self._ext = '_B' if self._is_secondary else '' - self._is_main_menu = is_main_menu + self._modal = modal self._displayname = self._name self._width = 700 if self._is_secondary else 730 self._height = 440 if self._is_secondary else 450 @@ -63,7 +63,6 @@ class GamepadSettingsWindow(bui.MainWindow): stack_offset=( (-20, -16) if uiscale is bui.UIScale.SMALL else (0, 0) ), - transition=transition, ), transition=transition, origin_widget=origin_widget, @@ -72,6 +71,7 @@ class GamepadSettingsWindow(bui.MainWindow): self._settings: dict[str, int] = {} if not self._is_secondary: self._get_config_mapping() + # Don't ask to config joysticks while we're in here. self._rebuild_ui() @@ -137,7 +137,7 @@ class GamepadSettingsWindow(bui.MainWindow): ]: assert bui.app.classic is not None val = bui.app.classic.get_input_device_mapped_value( - self._input, button, default + self._inputdevice, button, default ) if val != -1: self._settings[button] = val @@ -419,7 +419,7 @@ class GamepadSettingsWindow(bui.MainWindow): def get_input(self) -> bs.InputDevice: """(internal)""" - return self._input + return self._inputdevice def _do_advanced(self) -> None: # pylint: disable=cyclic-import @@ -535,8 +535,8 @@ class GamepadSettingsWindow(bui.MainWindow): def show_secondary_editor(self) -> None: """(internal)""" GamepadSettingsWindow( - self._input, - is_main_menu=False, + self._inputdevice, + modal=True, settings=self._settings, transition='in_scale', transition_out='out_scale', @@ -562,16 +562,16 @@ class GamepadSettingsWindow(bui.MainWindow): assert isinstance(sval2, (int, type(None))) if sval1 is not None and sval2 is not None: return ( - self._input.get_axis_name(sval1) + self._inputdevice.get_axis_name(sval1) + ' / ' - + self._input.get_axis_name(sval2) + + self._inputdevice.get_axis_name(sval2) ) return bui.Lstr(resource=f'{self._r}.unsetText') # If they're looking for triggers. if control in ['triggerRun1' + self._ext, 'triggerRun2' + self._ext]: if control in self._settings: - return self._input.get_axis_name(self._settings[control]) + return self._inputdevice.get_axis_name(self._settings[control]) return bui.Lstr(resource=f'{self._r}.unsetText') # Dead-zone. @@ -592,7 +592,9 @@ class GamepadSettingsWindow(bui.MainWindow): # If *any* dpad buttons are assigned, show only button assignments. if any(b in self._settings for b in dpad_buttons): if control in self._settings: - return self._input.get_button_name(self._settings[control]) + return self._inputdevice.get_button_name( + self._settings[control] + ) return bui.Lstr(resource=f'{self._r}.unsetText') # No dpad buttons - show the dpad number for all 4. @@ -617,7 +619,7 @@ class GamepadSettingsWindow(bui.MainWindow): # Other buttons. if control in self._settings: - return self._input.get_button_name(self._settings[control]) + return self._inputdevice.get_button_name(self._settings[control]) return bui.Lstr(resource=f'{self._r}.unsetText') def _gamepad_event( @@ -694,7 +696,7 @@ class GamepadSettingsWindow(bui.MainWindow): # Now launch the up/down listener. AwaitGamepadInputWindow( - self._input, + self._inputdevice, 'analogStickUD' + ext, self._gamepad_event, bui.Lstr(resource=f'{self._r}.pressUpDownText'), @@ -783,7 +785,7 @@ class GamepadSettingsWindow(bui.MainWindow): edit=btn, on_activate_call=bui.Call( AwaitGamepadInputWindow, - self._input, + self._inputdevice, button, self._gamepad_event, message, @@ -795,16 +797,16 @@ class GamepadSettingsWindow(bui.MainWindow): return btn def _cancel(self) -> None: - # from bauiv1lib.settings.controls import ControlsSettingsWindow # no-op if our underlying widget is dead or on its way out. if not self._root_widget or self._root_widget.transitioning_out: return - bui.containerwidget( - edit=self._root_widget, transition=self._transition_out - ) - if self._is_main_menu: + if self._modal: + bui.containerwidget( + edit=self._root_widget, transition=self._transition_out + ) + else: self.main_window_back() # assert bui.app.classic is not None # bui.app.ui_v1.set_main_window( @@ -899,18 +901,20 @@ class GamepadSettingsWindow(bui.MainWindow): if not self._root_widget or self._root_widget.transitioning_out: return - bui.containerwidget( - edit=self._root_widget, transition=self._transition_out - ) - # If we're a secondary editor we just go away (we were editing our # parent's settings dict). if self._is_secondary: + assert self._modal + bui.containerwidget( + edit=self._root_widget, transition=self._transition_out + ) return assert self._settings is not None - if self._input: - dst = classic.get_input_device_config(self._input, default=True) + if self._inputdevice: + dst = classic.get_input_device_config( + self._inputdevice, default=True + ) dst2: dict[str, Any] = dst[0][dst[1]] dst2.clear() @@ -921,7 +925,7 @@ class GamepadSettingsWindow(bui.MainWindow): # If we're allowed to phone home, send this config so we can # generate more defaults in the future. - inputhash = classic.get_input_device_map_hash(self._input) + inputhash = classic.get_input_device_map_hash(self._inputdevice) classic.master_server_v1_post( 'controllerConfig', { @@ -938,15 +942,13 @@ class GamepadSettingsWindow(bui.MainWindow): else: bui.getsound('error').play() - if self._is_main_menu: - from bauiv1lib.settings.controls import ControlsSettingsWindow - - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - ControlsSettingsWindow(transition='in_left'), - from_window=self, - is_back=True, + if self._modal: + bui.containerwidget( + edit=self._root_widget, transition=self._transition_out ) + else: + assert self.main_window_has_control() + self.main_window_back() class AwaitGamepadInputWindow(bui.Window): diff --git a/src/assets/ba_data/python/bauiv1lib/settings/gamepadselect.py b/src/assets/ba_data/python/bauiv1lib/settings/gamepadselect.py index 9040c81d..382e353e 100644 --- a/src/assets/ba_data/python/bauiv1lib/settings/gamepadselect.py +++ b/src/assets/ba_data/python/bauiv1lib/settings/gamepadselect.py @@ -4,7 +4,6 @@ from __future__ import annotations -import logging from typing import TYPE_CHECKING, override import bascenev1 as bs @@ -14,107 +13,6 @@ if TYPE_CHECKING: from typing import Any -def gamepad_configure_callback(event: dict[str, Any]) -> None: - """Respond to a gamepad button press during config selection.""" - from bauiv1lib.settings.gamepad import GamepadSettingsWindow - - # Ignore all but button-presses. - if event['type'] not in ['BUTTONDOWN', 'HATMOTION']: - return - bs.release_gamepad_input() - - if bool(True): - bui.screenmessage('UNDER CONSTRUCTION') - return - - assert bui.app.classic is not None - try: - bui.app.ui_v1.clear_main_window() - except Exception: - logging.exception('Error transitioning out main_menu_window.') - bui.getsound('activateBeep').play() - bui.getsound('swish').play() - device = event['input_device'] - assert isinstance(device, bs.InputDevice) - if device.allows_configuring: - bui.app.ui_v1.set_main_window( - GamepadSettingsWindow(device), from_window=None - ) - else: - width = 700 - height = 200 - button_width = 80 - uiscale = bui.app.ui_v1.uiscale - - class _Window(bui.MainWindow): - def __init__(self) -> None: - super().__init__( - root_widget=bui.containerwidget( - scale=( - 1.7 - if uiscale is bui.UIScale.SMALL - else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0 - ), - size=(width, height), - ), - transition='in_right', - origin_widget=None, - ) - - win = _Window() - dlg = win.get_root_widget() - - bui.app.ui_v1.set_main_window(win, from_window=None) - - if device.allows_configuring_in_system_settings: - msg = bui.Lstr( - resource='configureDeviceInSystemSettingsText', - subs=[('${DEVICE}', device.name)], - ) - elif device.is_controller_app: - msg = bui.Lstr( - resource='bsRemoteConfigureInAppText', - subs=[('${REMOTE_APP_NAME}', bui.get_remote_app_name())], - ) - else: - msg = bui.Lstr( - resource='cantConfigureDeviceText', - subs=[('${DEVICE}', device.name)], - ) - bui.textwidget( - parent=dlg, - position=(0, height - 80), - size=(width, 25), - text=msg, - scale=0.8, - h_align='center', - v_align='top', - ) - - def _ok() -> None: - from bauiv1lib.settings import controls - - # no-op if our underlying widget is dead or on its way out. - if not dlg or dlg.transitioning_out: - return - - bui.containerwidget(edit=dlg, transition='out_right') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - controls.ControlsSettingsWindow(transition='in_left'), - from_window=win, - is_back=True, - ) - - bui.buttonwidget( - parent=dlg, - position=((width - button_width) / 2, 20), - size=(button_width, 60), - label=bui.Lstr(resource='okText'), - on_activate_call=_ok, - ) - - class GamepadSelectWindow(bui.MainWindow): """Window for selecting a gamepad to configure.""" @@ -155,8 +53,8 @@ class GamepadSelectWindow(bui.MainWindow): on_activate_call=self.main_window_back, ) - # Let's not have anything selected by default; its misleading looking - # for the controller getting configured. + # Let's not have anything selected by default; its misleading + # looking for the controller getting configured. bui.containerwidget( edit=self._root_widget, cancel_button=btn, @@ -207,7 +105,10 @@ class GamepadSelectWindow(bui.MainWindow): v_align='top', ) - bs.capture_gamepad_input(gamepad_configure_callback) + bs.capture_gamepad_input(bui.WeakCall(self.gamepad_configure_callback)) + + def __del__(self) -> None: + bs.release_gamepad_input() @override def get_main_window_state(self) -> bui.MainWindowState: @@ -219,6 +120,102 @@ class GamepadSelectWindow(bui.MainWindow): ) ) - @override - def on_main_window_close(self) -> None: + def gamepad_configure_callback(self, event: dict[str, Any]) -> None: + """Respond to a gamepad button press during config selection.""" + from bauiv1lib.settings.gamepad import GamepadSettingsWindow + + if not self.main_window_has_control(): + return + + # Ignore all but button-presses. + if event['type'] not in ['BUTTONDOWN', 'HATMOTION']: + return bs.release_gamepad_input() + + assert bui.app.classic is not None + + bui.getsound('activateBeep').play() + bui.getsound('swish').play() + device = event['input_device'] + assert isinstance(device, bs.InputDevice) + + # No matter where we redirect to, we want their back + # functionality to skip over us and go to our parent. + assert self.main_window_back_state is not None + back_state = self.main_window_back_state + + if device.allows_configuring: + self.main_window_replace( + GamepadSettingsWindow(device), back_state=back_state + ) + else: + self.main_window_replace( + _NotConfigurableWindow(device), back_state=back_state + ) + + +class _NotConfigurableWindow(bui.MainWindow): + + def __init__(self, device: bs.InputDevice) -> None: + width = 700 + height = 200 + button_width = 80 + uiscale = bui.app.ui_v1.uiscale + super().__init__( + root_widget=bui.containerwidget( + scale=( + 1.7 + if uiscale is bui.UIScale.SMALL + else (1.4 if uiscale is bui.UIScale.MEDIUM else 1.0) + ), + size=(width, height), + ), + transition='in_right', + origin_widget=None, + ) + if device.allows_configuring_in_system_settings: + msg = bui.Lstr( + resource='configureDeviceInSystemSettingsText', + subs=[('${DEVICE}', device.name)], + ) + elif device.is_controller_app: + msg = bui.Lstr( + resource='bsRemoteConfigureInAppText', + subs=[ + ( + '${REMOTE_APP_NAME}', + bui.get_remote_app_name(), + ) + ], + ) + else: + msg = bui.Lstr( + resource='cantConfigureDeviceText', + subs=[('${DEVICE}', device.name)], + ) + bui.textwidget( + parent=self._root_widget, + position=(0, height - 80), + size=(width, 25), + text=msg, + scale=0.8, + h_align='center', + v_align='top', + ) + + btn = bui.buttonwidget( + parent=self._root_widget, + position=((width - button_width) / 2, 20), + size=(button_width, 60), + label=bui.Lstr(resource='okText'), + on_activate_call=self.main_window_back, + ) + bui.containerwidget(edit=self._root_widget, cancel_button=btn) + + # def _ok(self) -> None: + + # # Back would take us to the gamepad-select window. We want to go + # # past that. + # assert self.main_window_back_state is not None + # self.main_window_back_state = self.main_window_back_state.parent + # self.main_window_back() diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index 61464f5a..c32fa644 100644 --- a/src/ballistica/shared/ballistica.cc +++ b/src/ballistica/shared/ballistica.cc @@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int { namespace ballistica { // These are set automatically via script; don't modify them here. -const int kEngineBuildNumber = 21980; +const int kEngineBuildNumber = 21982; const char* kEngineVersion = "1.7.37"; const int kEngineApiVersion = 9;