diff --git a/.efrocachemap b/.efrocachemap index d46eace5..424f0f95 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": "a0e1890fc3d156a1d480e7cbba7295bd", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "2ea3ddfd5280b5fa721a82286767208a", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "f9860dbec27801cf8b24c3b42e0b62bd", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "a53de05a4a3c3c2e766f488b0b53230d", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "43485a1c27605267ee83d27961b61017", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "65fe6d346dfd844925a07278a73bbb39", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "bc277e964bc08d0bd086f836732901f8", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "738e76cf0dc643a016f16f94503767db", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "949fd54340bc597c19ada580f59c30a9", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "f0f1037044f841e6817e970ba67f3c02", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "3990893e788968fe74e98aa419f28397", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "0c5fbd4cd45f944f02d7482e08d4b5d5", - "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "c39bcf72ef41865429f3df1d3ad586d0", - "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "37cb193fec5c61443fafa24d3ae96447", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "e454f30500a3ef2c0e4248388338db89", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "ddb81916ad653ccb38be9ffc9f98e7f3", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "18766baaa9e1a23e785aceb9f6be0d3a", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "b687f66795a831f0dfd7e15aa7a908b2", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "146168838c8e9cdbd5c016772b68e91a", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "f0ee92768afe3211aeab356539d58876", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "fa2f9a37401974a330f6406bfdde195a", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "ec0ca83cb8d63837d86024926a9f5792", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "22e11f5d894e02b521f1c77a3b1d14ad", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "803d4449de9e62bc33d62edaccb3a40c", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "5ee49f99993e6f690c955bf4e22ea232", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "f6882aef1cf0c4ab6a4d71b19e048ea3", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "2de6855febbe3fefbd1a696e54ff198c", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "76fff0d53458ff9308ee9050bfe42321", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "4b0f3502089e9a7ea6ea2db0c44ecee9", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "d426ae451363579868ed80e070ee1a7d", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "147e64e814f72846d5f78944df85f879", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "0e28cef28d1097cd61c1faa2f18b900d", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "213712de0e2e9c5fcbaf9b2cebd92ff7", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "34122e2302160ce65f4ac624e6b40876", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "09f8466080d70d84c15d697a659c6561", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "ad91f8448f3106a7d81f2615ab82d71c", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "6a369680967a22140b9a5d3dd65cfd65", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "eb2ccde783e4e7abaf40a76ed0be4a0c", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "112881e2d4429018dc5487a979d53a80", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "04b1f16241efd35e95ff544de09f3444", "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": "07c51c6015b17d6ad2e32ac6bad9aaee", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "d9dc89c65a1f5ae3a0a4e25636129bb7", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "8afac2e5edb1586137c60ce1d4829d0a", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "c9bfc854e52b6d2270d748ce80f45342", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "ec65affda58721c395d5188810195443", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "e16447cfaffecc545ae970aff2f09d16", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "1f5ba81d75d56eb680bb7f3aefaae5b6", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "44bc0d1aab93081db335ebd837f44632", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "599167b1b452e9a060475c059ebb742e", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "4495e25c4e6e286ebe0ac547c3c785e5", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "ee961522b1a726d982df90d35178f4df", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "de121ab71098df1ff6a9b72b46c30401", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "6319a5f16af08ad8cd396472e623b4e1", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "1464b16e286fc6379aa6e9d8d7b7ddaa", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "64c3bce65d48d16c7b0f5f59105a8856", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "a10c2110bb0155790ddc49a44388ba4c", "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 c993e272..662d8848 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.37 (build 21985, api 9, 2024-09-03) +### 1.7.37 (build 21986, api 9, 2024-09-04) - 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/baclassic/_appmode.py b/src/assets/ba_data/python/baclassic/_appmode.py index 0bfed722..1208b9e3 100644 --- a/src/assets/ba_data/python/baclassic/_appmode.py +++ b/src/assets/ba_data/python/baclassic/_appmode.py @@ -135,14 +135,19 @@ class ClassicAppMode(AppMode): # Blow away the window stack and build a fresh one. ui.clear_main_window() + back_state = ( + MainMenuWindow.do_get_main_window_state() + if in_main_menu() + else InGameMenuWindow.do_get_main_window_state() + ) + # set_main_window() needs this to be set. + back_state.is_top_level = True + ui.set_main_window( window, from_window=False, # Disable from-check. - back_state=( - MainMenuWindow.do_get_main_window_state() - if in_main_menu() - else InGameMenuWindow.do_get_main_window_state() - ), + back_state=back_state, + suppress_warning=True, ) def _root_ui_menu_press(self) -> None: diff --git a/src/assets/ba_data/python/baclassic/_appsubsystem.py b/src/assets/ba_data/python/baclassic/_appsubsystem.py index 4fe3637c..e10c5dfd 100644 --- a/src/assets/ba_data/python/baclassic/_appsubsystem.py +++ b/src/assets/ba_data/python/baclassic/_appsubsystem.py @@ -735,15 +735,30 @@ class ClassicAppSubsystem(babase.AppSubsystem): def profile_browser_window( self, transition: str = 'in_right', - in_main_menu: bool = True, - selected_profile: str | None = None, origin_widget: bauiv1.Widget | None = None, + # in_main_menu: bool = True, + selected_profile: str | None = None, ) -> None: """(internal)""" from bauiv1lib.profile.browser import ProfileBrowserWindow - ProfileBrowserWindow( - transition, in_main_menu, selected_profile, origin_widget + main_window = babase.app.ui_v1.get_main_window() + if main_window is not None: + logging.warning( + 'profile_browser_window()' + ' called with existing main window; should not happen.' + ) + return + + babase.app.ui_v1.set_main_window( + ProfileBrowserWindow( + transition=transition, + selected_profile=selected_profile, + origin_widget=origin_widget, + minimal_toolbar=True, + ), + is_top_level=True, + suppress_warning=True, ) def preload_map_preview_media(self) -> None: @@ -799,9 +814,7 @@ class ClassicAppSubsystem(babase.AppSubsystem): bauiv1.getsound('swish').play() babase.app.ui_v1.set_main_window( - InGameMenuWindow(), - from_window=False, # Disable check here. - is_top_level=True, + InGameMenuWindow(), is_top_level=True, suppress_warning=True ) def invoke_main_menu_ui(self) -> None: @@ -896,8 +909,8 @@ class ClassicAppSubsystem(babase.AppSubsystem): app.ui_v1.set_main_window( MainMenuWindow(transition=None), - from_window=False, # Disable check. is_top_level=True, + suppress_warning=True, ) # attempt to show any pending offers immediately. diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index f2c1fae8..e2830cd1 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 = 21985 +TARGET_BALLISTICA_BUILD = 21986 TARGET_BALLISTICA_VERSION = '1.7.37' diff --git a/src/assets/ba_data/python/bascenev1/_lobby.py b/src/assets/ba_data/python/bascenev1/_lobby.py index 001aa2d0..467cbeb8 100644 --- a/src/assets/ba_data/python/bascenev1/_lobby.py +++ b/src/assets/ba_data/python/bascenev1/_lobby.py @@ -588,10 +588,16 @@ class Chooser: # Handle '_edit' as a special case. if profilename == '_edit' and ready: with babase.ContextRef.empty(): - classic.profile_browser_window(in_main_menu=False) + # if bool(True): + # babase.screenmessage('UNDER CONSTRUCTION') + # return - # Give their input-device UI ownership too - # (prevent someone else from snatching it in crowded games) + classic.profile_browser_window( + # in_main_menu=False + ) + + # Give their input-device UI ownership too (prevent + # someone else from snatching it in crowded games). babase.set_ui_input_device(self._sessionplayer.inputdevice.id) return diff --git a/src/assets/ba_data/python/bauiv1/_appsubsystem.py b/src/assets/ba_data/python/bauiv1/_appsubsystem.py index 2e9a5aaa..a5491755 100644 --- a/src/assets/ba_data/python/bauiv1/_appsubsystem.py +++ b/src/assets/ba_data/python/bauiv1/_appsubsystem.py @@ -7,6 +7,7 @@ from __future__ import annotations import logging import inspect import weakref +import warnings from enum import Enum from typing import TYPE_CHECKING, override @@ -162,10 +163,16 @@ class UIV1AppSubsystem(babase.AppSubsystem): # FIXME: Can probably kill this if we do immediate UI death checks. self.upkeeptimer = babase.AppTimer(2.6543, ui_upkeep, repeat=True) - def do_main_window_back(self, from_window: MainWindow) -> None: + def auto_set_back_window(self, from_window: MainWindow) -> None: """Sets the main menu window automatically from a parent WindowState.""" main_window = self._main_window() + + # This should never get called for top-level main-windows. + assert ( + main_window is None or main_window.main_window_is_top_level is False + ) + back_state = ( None if main_window is None else main_window.main_window_back_state ) @@ -175,8 +182,17 @@ class UIV1AppSubsystem(babase.AppSubsystem): f' cannot use auto-back.' ) backwin = back_state.create_window(transition='in_left') - backwin.main_window_back_state = back_state.parent - self.set_main_window(backwin, from_window=from_window, is_back=True) + + # Properly created state should have a value here. + assert back_state.is_top_level is not None + + self.set_main_window( + backwin, + from_window=from_window, + is_back=True, + back_state=back_state, + suppress_warning=True, + ) def get_main_window(self) -> bauiv1.MainWindow | None: """Return main window, if any.""" @@ -189,6 +205,7 @@ class UIV1AppSubsystem(babase.AppSubsystem): is_back: bool = False, is_top_level: bool = False, back_state: MainWindowState | None = None, + suppress_warning: bool = False, ) -> None: """Set the current 'main' window, replacing any existing. @@ -201,7 +218,17 @@ class UIV1AppSubsystem(babase.AppSubsystem): # pylint: disable=too-many-statements from bauiv1._uitypes import MainWindow - from_window_widget: bauiv1.Widget | None + # Encourage migration to the new higher level nav calls. + if not suppress_warning: + warnings.warn( + 'set_main_window() should usually not be called directly;' + ' use the main_window_replace() or main_window_back()' + ' methods on MainWindow objects for navigation instead.' + ' If you truly need to use set_main_window(),' + ' pass suppress_warning=True to silence this warning.', + DeprecationWarning, + stacklevel=2, + ) # We used to accept Widgets but now want MainWindows. if not isinstance(window, MainWindow): @@ -213,7 +240,8 @@ class UIV1AppSubsystem(babase.AppSubsystem): window_widget = window.get_root_widget() if isinstance(from_window, MainWindow): - from_window_widget = from_window.get_root_widget() + # from_window_widget = from_window.get_root_widget() + pass else: if from_window is not None and not isinstance(from_window, bool): raise RuntimeError( @@ -222,110 +250,93 @@ class UIV1AppSubsystem(babase.AppSubsystem): f' You passed a {type(from_window)}.', ) - from_window_widget = None + existing = self._main_window() - existing = self._main_window_widget - - try: - if isinstance(from_window, bool): - # For default val True we warn that the arg wasn't - # passed. False can be explicitly passed to disable this - # check. - if from_window is True: - caller_frame = inspect.stack()[1] - caller_filename = caller_frame.filename - caller_line_number = caller_frame.lineno - logging.warning( - 'set_main_window() should be passed a' - " 'from_window' value to help ensure proper UI behavior" - ' (%s line %i).', - caller_filename, - caller_line_number, - ) - else: - # For everything else, warn if what they passed wasn't - # the previous main menu widget. - if from_window_widget is not existing: - caller_frame = inspect.stack()[1] - caller_filename = caller_frame.filename - caller_line_number = caller_frame.lineno - logging.warning( - "set_main_window() was passed 'from_window' %s" - ' but existing main-menu-window is %s. (%s line %i).', - from_window_widget, - existing, - caller_filename, - caller_line_number, - ) - except Exception: - # Prevent any bugs in these checks from causing problems. - logging.exception('Error checking from_window') - - # Once the above code leads to us fixing all leftover window - # bugs at the source, we can kill the code below. - - # Let's grab the location where we were called from to report if - # we have to force-kill the existing window (which normally - # should not happen). - frameline = None - try: - frame = inspect.currentframe() - if frame is not None: - frame = frame.f_back - if frame is not None: - frameinfo = inspect.getframeinfo(frame) - frameline = f'{frameinfo.filename} {frameinfo.lineno}' - except Exception: - logging.exception('Error calcing line for set_main_window') - - # NOTE: disabling this for now since hopefully our new system - # will be bulletproof enough to avoid this. Can turn it back on - # if that's not the case. - - # With our legacy main-menu system, the caller is responsible - # for clearing out the old main menu window when assigning the - # new. However there are corner cases where that doesn't happen - # and we get old windows stuck under the new main one. So let's - # guard against that. However, we can't simply delete the - # existing main window when a new one is assigned because the - # user may transition the old out *after* the assignment. Sigh. - # So, as a happy medium, let's check in on the old after a short - # bit of time and kill it if its still alive. That will be a bit - # ugly on screen but at least should un-break things. - def _delay_kill() -> None: - import time - - if existing: - print( - f'Killing old main_menu_window' - f' when called at: {frameline} t={time.time():.3f}' + # If they passed a back-state, make sure it is fully filled out. + if back_state is not None: + if back_state.is_top_level is None: + raise RuntimeError( + 'back_state.is_top_level has not been set.' + ' Make sure to only pass fully-filled-out MainWindowStates.' ) - existing.delete() - - if bool(False): - babase.apptimer(1.0, _delay_kill) + # If a top-level main-window is being set, complain if there already + # is a main-window. + if is_top_level: + if existing: + logging.warning( + 'set_main_window() called with top-level window %s' + ' but found existing main-window %s.', + window, + existing, + ) + else: + # In other cases, sanity-check that the window ordering this + # switch is the one we're switching away from. + try: + if isinstance(from_window, bool): + # For default val True we warn that the arg wasn't + # passed. False can be explicitly passed to disable this + # check. + if from_window is True: + caller_frame = inspect.stack()[1] + caller_filename = caller_frame.filename + caller_line_number = caller_frame.lineno + logging.warning( + 'set_main_window() should be passed a' + " 'from_window' value to help ensure proper" + ' UI behavior (%s line %i).', + caller_filename, + caller_line_number, + ) + else: + # For everything else, warn if what they passed wasn't + # the previous main menu widget. + if from_window is not existing: + caller_frame = inspect.stack()[1] + caller_filename = caller_frame.filename + caller_line_number = caller_frame.lineno + logging.warning( + "set_main_window() was passed 'from_window' %s" + ' but existing main-menu-window is %s.' + ' (%s line %i).', + from_window, + existing, + caller_filename, + caller_line_number, + ) + except Exception: + # Prevent any bugs in these checks from causing problems. + logging.exception('Error checking from_window') if is_back: - pass + # is_top_level should never be True here (only applies forward). + assert not is_top_level + # Always should have back_state in this case. + assert back_state is not None + assert back_state.is_top_level is not None + window.main_window_back_state = back_state.parent + window.main_window_is_top_level = back_state.is_top_level else: + # Store if the window is top-level so we won't complain later if + # we go back from it and there's nowhere to go to. + window.main_window_is_top_level = is_top_level + # When navigating forward, generate a back-window-state from # the outgoing window. if is_top_level: # Top level windows don't have or expect anywhere to # go back to. - # - # self._main_window_back_state = None window.main_window_back_state = None elif back_state is not None: window.main_window_back_state = back_state else: oldwin = self._main_window() if oldwin is None: - # We currenty only hold weak refs to windows so - # that they are free to die on their own, but we - # expect the main menu window to keep itself - # alive as long as its the main one. Holler if - # that seems to not be happening. + # We currenty only hold weak refs to windows so that + # they are free to die on their own, but we expect + # the main menu window to keep itself alive as long + # as its the main one. Holler if that seems to not + # be happening. logging.warning( 'set_main_window: No old MainWindow found' ' and is_top_level is False;' @@ -335,8 +346,9 @@ class UIV1AppSubsystem(babase.AppSubsystem): else: oldwinstate = oldwin.get_main_window_state() - # Store our previous back state on this new one. + # Store some common window stuff on its state. oldwinstate.parent = oldwin.main_window_back_state + oldwinstate.is_top_level = oldwin.main_window_is_top_level window.main_window_back_state = oldwinstate self._main_window = window_weakref diff --git a/src/assets/ba_data/python/bauiv1/_uitypes.py b/src/assets/ba_data/python/bauiv1/_uitypes.py index 69cc8b04..b1aca134 100644 --- a/src/assets/ba_data/python/bauiv1/_uitypes.py +++ b/src/assets/ba_data/python/bauiv1/_uitypes.py @@ -63,6 +63,8 @@ class MainWindow(Window): # A back-state supplied by the ui system. self.main_window_back_state: MainWindowState | None = None + self.main_window_is_top_level: bool = False + self._main_window_transition = transition self._main_window_origin_widget = origin_widget super().__init__(root_widget, cleanupcheck) @@ -131,8 +133,10 @@ class MainWindow(Window): if not self.main_window_has_control(): return - # Get the 'back' window coming in. - babase.app.ui_v1.do_main_window_back(self) + if not self.main_window_is_top_level: + + # Get the 'back' window coming in. + babase.app.ui_v1.auto_set_back_window(self) self.main_window_close() @@ -164,7 +168,10 @@ class MainWindow(Window): _bauiv1.containerwidget(edit=self._root_widget, transition=transition) babase.app.ui_v1.set_main_window( - new_window, from_window=self, back_state=back_state + new_window, + from_window=self, + back_state=back_state, + suppress_warning=True, ) def on_main_window_close(self) -> None: @@ -186,9 +193,10 @@ class MainWindowState: purposes, when switching app-modes, etc. """ - def __init__(self, parent: MainWindowState | None = None) -> None: + def __init__(self) -> None: # The window that back/cancel navigation should take us to. - self.parent = parent + self.parent: MainWindowState | None = None + self.is_top_level: bool | None = None def create_window( self, diff --git a/src/assets/ba_data/python/bauiv1lib/characterpicker.py b/src/assets/ba_data/python/bauiv1lib/characterpicker.py index b914f9af..1e16f45f 100644 --- a/src/assets/ba_data/python/bauiv1lib/characterpicker.py +++ b/src/assets/ba_data/python/bauiv1lib/characterpicker.py @@ -14,6 +14,18 @@ if TYPE_CHECKING: from typing import Any, Sequence +class CharacterPickerDelegate: + """Delegate for character-picker.""" + + def on_character_picker_pick(self, character: str) -> None: + """Called when a character is selected.""" + raise NotImplementedError() + + def on_character_picker_get_more_press(self) -> None: + """Called when the 'get more characters' button is pressed.""" + raise NotImplementedError() + + class CharacterPicker(PopupWindow): """Popup window for selecting characters.""" @@ -21,7 +33,7 @@ class CharacterPicker(PopupWindow): self, parent: bui.Widget, position: tuple[float, float] = (0.0, 0.0), - delegate: Any = None, + delegate: CharacterPickerDelegate | None = None, scale: float | None = None, offset: tuple[float, float] = (0.0, 0.0), tint_color: Sequence[float] = (1.0, 1.0, 1.0), @@ -191,10 +203,14 @@ class CharacterPicker(PopupWindow): show_sign_in_prompt() return - bui.screenmessage('UNDER CONSTRUCTION') - return + if self._delegate is not None: + self._delegate.on_character_picker_get_more_press() + + self._transition_out() + + # bui.screenmessage('UNDER CONSTRUCTION') + # return - # self._transition_out() # StoreBrowserWindow( # modal=True, # show_tab=StoreBrowserWindow.TabID.CHARACTERS, diff --git a/src/assets/ba_data/python/bauiv1lib/play.py b/src/assets/ba_data/python/bauiv1lib/play.py index 5548c67c..97ab6396 100644 --- a/src/assets/ba_data/python/bauiv1lib/play.py +++ b/src/assets/ba_data/python/bauiv1lib/play.py @@ -580,11 +580,9 @@ class PlayWindow(bui.MainWindow): if plus.get_v1_account_state() != 'signed_in': show_sign_in_prompt() return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - CoopBrowserWindow(origin_widget=self._coop_button), from_window=self + + self.main_window_replace( + CoopBrowserWindow(origin_widget=self._coop_button) ) def _team_tourney(self) -> None: @@ -595,8 +593,6 @@ class PlayWindow(bui.MainWindow): if not self.main_window_has_control(): return - self._save_state() - self.main_window_replace( PlaylistBrowserWindow( origin_widget=self._teams_button, @@ -613,16 +609,12 @@ class PlayWindow(bui.MainWindow): if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( + self.main_window_replace( PlaylistBrowserWindow( origin_widget=self._free_for_all_button, sessiontype=bs.FreeForAllSession, playlist_select_context=self._playlist_select_context, - ), - from_window=self, + ) ) def _draw_dude( diff --git a/src/assets/ba_data/python/bauiv1lib/profile/browser.py b/src/assets/ba_data/python/bauiv1lib/profile/browser.py index 95464e03..5cc6ad19 100644 --- a/src/assets/ba_data/python/bauiv1lib/profile/browser.py +++ b/src/assets/ba_data/python/bauiv1lib/profile/browser.py @@ -20,16 +20,13 @@ class ProfileBrowserWindow(bui.MainWindow): def __init__( self, transition: str | None = 'in_right', - in_main_menu: bool = True, + # in_main_menu: bool = True, selected_profile: str | None = None, origin_widget: bui.Widget | None = None, + minimal_toolbar: bool = False, ): - # pylint: disable=too-many-statements - self._in_main_menu = in_main_menu - if self._in_main_menu: - back_label = bui.Lstr(resource='backText') - else: - back_label = bui.Lstr(resource='doneText') + self._minimal_toolbar = minimal_toolbar + back_label = bui.Lstr(resource='backText') assert bui.app.classic is not None uiscale = bui.app.ui_v1.uiscale self._width = 800.0 if uiscale is bui.UIScale.SMALL else 600.0 @@ -40,11 +37,6 @@ class ProfileBrowserWindow(bui.MainWindow): else 385.0 if uiscale is bui.UIScale.MEDIUM else 410.0 ) - # If we're being called up standalone, handle pause/resume ourself. - if not self._in_main_menu: - assert bui.app.classic is not None - bui.app.classic.pause() - # Need to handle out-transitions ourself for modal mode. if origin_widget is not None: self._transition_out = 'out_scale' @@ -64,7 +56,7 @@ class ProfileBrowserWindow(bui.MainWindow): size=(self._width, self._height + top_extra), toolbar_visibility=( 'menu_minimal' - if uiscale is bui.UIScale.SMALL + if (uiscale is bui.UIScale.SMALL or minimal_toolbar) else 'menu_full' ), scale=( @@ -83,7 +75,7 @@ class ProfileBrowserWindow(bui.MainWindow): if bui.app.ui_v1.uiscale is bui.UIScale.SMALL: self._back_button = bui.get_special_widget('back_button') bui.containerwidget( - edit=self._root_widget, on_cancel_call=self._back + edit=self._root_widget, on_cancel_call=self.main_window_back ) else: self._back_button = btn = bui.buttonwidget( @@ -92,18 +84,17 @@ class ProfileBrowserWindow(bui.MainWindow): size=(120, 60), scale=0.8, label=back_label, - button_type='back' if self._in_main_menu else None, + button_type='back', autoselect=True, - on_activate_call=self._back, + on_activate_call=self.main_window_back, ) bui.containerwidget(edit=self._root_widget, cancel_button=btn) - if self._in_main_menu: - bui.buttonwidget( - edit=btn, - button_type='backSmall', - size=(60, 60), - label=bui.charstr(bui.SpecialChar.BACK), - ) + bui.buttonwidget( + edit=btn, + button_type='backSmall', + size=(60, 60), + label=bui.charstr(bui.SpecialChar.BACK), + ) bui.textwidget( parent=self._root_widget, @@ -212,9 +203,14 @@ class ProfileBrowserWindow(bui.MainWindow): def get_main_window_state(self) -> bui.MainWindowState: # Support recreating our window for back/refresh purposes. cls = type(self) + + minimal_toolbar = self._minimal_toolbar + return bui.BasicMainWindowState( create_call=lambda transition, origin_widget: cls( - transition=transition, origin_widget=origin_widget + transition=transition, + origin_widget=origin_widget, + minimal_toolbar=minimal_toolbar, ) ) @@ -227,10 +223,14 @@ class ProfileBrowserWindow(bui.MainWindow): from bauiv1lib.profile.edit import EditProfileWindow from bauiv1lib.purchase import PurchaseWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # No-op if we're not the in-control main window. + if not self.main_window_has_control(): return + # 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 + plus = bui.app.plus assert plus is not None @@ -266,14 +266,14 @@ class ProfileBrowserWindow(bui.MainWindow): bui.getsound('error').play() return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - bui.app.ui_v1.set_main_window( - EditProfileWindow( - existing_profile=None, in_main_menu=self._in_main_menu - ), - from_window=self if self._in_main_menu else False, - ) + self.main_window_replace(EditProfileWindow(existing_profile=None)) + + # self._save_state() + # bui.containerwidget(edit=self._root_widget, transition='out_left') + # bui.app.ui_v1.set_main_window( + # EditProfileWindow(existing_profile=None), + # from_window=self if self._in_main_menu else False, + # ) def _delete_profile(self) -> None: # pylint: disable=cyclic-import @@ -321,8 +321,8 @@ class ProfileBrowserWindow(bui.MainWindow): # pylint: disable=cyclic-import from bauiv1lib.profile.edit import EditProfileWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return if self._selected_profile is None: @@ -331,49 +331,13 @@ class ProfileBrowserWindow(bui.MainWindow): bui.Lstr(resource='nothingIsSelectedErrorText'), color=(1, 0, 0) ) return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - EditProfileWindow( - self._selected_profile, in_main_menu=self._in_main_menu - ), - from_window=self if self._in_main_menu else False, - ) + + self.main_window_replace(EditProfileWindow(self._selected_profile)) def _select(self, name: str, index: int) -> None: del index # Unused. self._selected_profile = name - def _back(self) -> None: - # pylint: disable=cyclic-import - - if self._in_main_menu: - self.main_window_back() - return - - # 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 - - assert bui.app.classic is not None - - self._save_state() - bui.containerwidget( - edit=self._root_widget, transition=self._transition_out - ) - # if self._in_main_menu: - # assert bui.app.classic is not None - # bui.app.ui_v1.set_main_window( - # AccountSettingsWindow(transition='in_left'), - # from_window=self, - # is_back=True, - # ) - - # # If we're being called up standalone, handle pause/resume ourself. - # else: - bui.app.classic.resume() - def _refresh(self) -> None: # pylint: disable=too-many-locals # pylint: disable=too-many-statements diff --git a/src/assets/ba_data/python/bauiv1lib/sendinfo.py b/src/assets/ba_data/python/bauiv1lib/sendinfo.py index 97899259..f742a4c2 100644 --- a/src/assets/ba_data/python/bauiv1lib/sendinfo.py +++ b/src/assets/ba_data/python/bauiv1lib/sendinfo.py @@ -26,8 +26,6 @@ class SendInfoWindow(bui.MainWindow): ): self._legacy_code_mode = legacy_code_mode - # scale_origin: tuple[float, float] | None - # Need to wrangle our own transition-out in modal mode. if origin_widget is not None: self._transition_out = 'out_scale' @@ -173,7 +171,7 @@ class SendInfoWindow(bui.MainWindow): self.main_window_back() return - # from bauiv1lib.settings.advanced import AdvancedSettingsWindow + # Handle modal case: # no-op if our underlying widget is dead or on its way out. if not self._root_widget or self._root_widget.transitioning_out: @@ -182,40 +180,33 @@ class SendInfoWindow(bui.MainWindow): bui.containerwidget( edit=self._root_widget, transition=self._transition_out ) - # if not self._modal: - # assert bui.app.classic is not None - # bui.app.ui_v1.set_main_window( - # AdvancedSettingsWindow(transition='in_left'), - # from_window=self, - # is_back=True, - # ) def _activate_enter_button(self) -> None: self._enter_button.activate() def _do_enter(self) -> None: # pylint: disable=cyclic-import - from bauiv1lib.settings.advanced import AdvancedSettingsWindow + # from bauiv1lib.settings.advanced import AdvancedSettingsWindow plus = bui.app.plus assert plus is not None - # 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 not self._modal: - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - AdvancedSettingsWindow(transition='in_left'), from_window=self - ) - description: Any = bui.textwidget(query=self._text_field) assert isinstance(description, str) + if self._modal: + # 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 + ) + else: + # no-op if we're not in control. + if not self.main_window_has_control(): + return + self.main_window_back() + # Used for things like unlocking shared playlists or linking # accounts: talk directly to V1 server via transactions. if self._legacy_code_mode: diff --git a/src/assets/ba_data/python/bauiv1lib/settings/advanced.py b/src/assets/ba_data/python/bauiv1lib/settings/advanced.py index 4ea22b36..d3915c32 100644 --- a/src/assets/ba_data/python/bauiv1lib/settings/advanced.py +++ b/src/assets/ba_data/python/bauiv1lib/settings/advanced.py @@ -721,32 +721,20 @@ class AdvancedSettingsWindow(bui.MainWindow): def _on_vr_test_press(self) -> None: from bauiv1lib.settings.vrtesting import VRTestingWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - VRTestingWindow(transition='in_right'), from_window=self - ) + self.main_window_replace(VRTestingWindow(transition='in_right')) def _on_net_test_press(self) -> None: - plus = bui.app.plus - assert plus is not None from bauiv1lib.settings.nettesting import NetTestingWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - NetTestingWindow(transition='in_right'), from_window=self - ) + self.main_window_replace(NetTestingWindow(transition='in_right')) def _on_friend_promo_code_press(self) -> None: from bauiv1lib import appinvite @@ -763,64 +751,46 @@ class AdvancedSettingsWindow(bui.MainWindow): def _on_plugins_button_press(self) -> None: from bauiv1lib.settings.plugins import PluginWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - PluginWindow(origin_widget=self._plugins_button), from_window=self + self.main_window_replace( + PluginWindow(origin_widget=self._plugins_button) ) def _on_dev_tools_button_press(self) -> None: # pylint: disable=cyclic-import from bauiv1lib.settings.devtools import DevToolsWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - DevToolsWindow(origin_widget=self._dev_tools_button), - from_window=self, + self.main_window_replace( + DevToolsWindow(origin_widget=self._dev_tools_button) ) def _on_send_info_press(self) -> None: from bauiv1lib.sendinfo import SendInfoWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - plus = bui.app.plus - assert plus is not None - - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - SendInfoWindow(origin_widget=self._send_info_button), - from_window=self, + self.main_window_replace( + SendInfoWindow(origin_widget=self._send_info_button) ) def _on_benchmark_press(self) -> None: from bauiv1lib.benchmarks import BenchmarksAndStressTestsWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - BenchmarksAndStressTestsWindow(transition='in_right'), - from_window=self, + self.main_window_replace( + BenchmarksAndStressTestsWindow(transition='in_right') ) def _save_state(self) -> None: @@ -975,21 +945,3 @@ class AdvancedSettingsWindow(bui.MainWindow): self._complete_langs_list = None self._complete_langs_error = True bui.apptimer(0.001, bui.WeakCall(self._update_lang_status)) - - # def _do_back(self) -> None: - # from bauiv1lib.settings.allsettings import AllSettingsWindow - - # # 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 - - # self._save_state() - # bui.containerwidget( - # edit=self._root_widget, transition=self._transition_out - # ) - # assert bui.app.classic is not None - # bui.app.ui_v1.set_main_window( - # AllSettingsWindow(transition='in_left'), - # from_window=self, - # is_back=True, - # ) diff --git a/src/assets/ba_data/python/bauiv1lib/settings/allsettings.py b/src/assets/ba_data/python/bauiv1lib/settings/allsettings.py index 11df974d..9c7c81a3 100644 --- a/src/assets/ba_data/python/bauiv1lib/settings/allsettings.py +++ b/src/assets/ba_data/python/bauiv1lib/settings/allsettings.py @@ -240,64 +240,48 @@ class AllSettingsWindow(bui.MainWindow): # pylint: disable=cyclic-import 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: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - ControlsSettingsWindow(origin_widget=self._controllers_button), - from_window=self, + self.main_window_replace( + ControlsSettingsWindow(origin_widget=self._controllers_button) ) def _do_graphics(self) -> None: # pylint: disable=cyclic-import from bauiv1lib.settings.graphics import GraphicsSettingsWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - GraphicsSettingsWindow(origin_widget=self._graphics_button), - from_window=self, + self.main_window_replace( + GraphicsSettingsWindow(origin_widget=self._graphics_button) ) def _do_audio(self) -> None: # pylint: disable=cyclic-import from bauiv1lib.settings.audio import AudioSettingsWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - AudioSettingsWindow(origin_widget=self._audio_button), - from_window=self, + self.main_window_replace( + AudioSettingsWindow(origin_widget=self._audio_button) ) def _do_advanced(self) -> None: # pylint: disable=cyclic-import from bauiv1lib.settings.advanced import AdvancedSettingsWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - AdvancedSettingsWindow(origin_widget=self._advanced_button), - from_window=self, + self.main_window_replace( + AdvancedSettingsWindow(origin_widget=self._advanced_button) ) def _save_state(self) -> None: diff --git a/src/assets/ba_data/python/bauiv1lib/settings/audio.py b/src/assets/ba_data/python/bauiv1lib/settings/audio.py index 71d242a9..323bb270 100644 --- a/src/assets/ba_data/python/bauiv1lib/settings/audio.py +++ b/src/assets/ba_data/python/bauiv1lib/settings/audio.py @@ -65,9 +65,7 @@ class AudioSettingsWindow(bui.MainWindow): (0, -20) if uiscale is bui.UIScale.SMALL else (0, 0) ), toolbar_visibility=( - 'menu_minimal' - if uiscale is bui.UIScale.SMALL - else 'menu_full' + None if uiscale is bui.UIScale.SMALL else 'menu_full' ), ), transition=transition, @@ -241,14 +239,14 @@ class AudioSettingsWindow(bui.MainWindow): def _do_soundtracks(self) -> None: # pylint: disable=cyclic-import - from bauiv1lib.soundtrack import browser as stb + from bauiv1lib.soundtrack.browser import SoundtrackBrowserWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - # We require disk access for soundtracks; - # if we don't have it, request it. + # We require disk access for soundtracks; request it if we don't + # have it. if not bui.have_permission(bui.Permission.STORAGE): bui.getsound('ding').play() bui.screenmessage( @@ -260,12 +258,8 @@ class AudioSettingsWindow(bui.MainWindow): ) return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - stb.SoundtrackBrowserWindow(origin_widget=self._soundtrack_button), - from_window=self, + self.main_window_replace( + SoundtrackBrowserWindow(origin_widget=self._soundtrack_button) ) def _save_state(self) -> None: diff --git a/src/assets/ba_data/python/bauiv1lib/settings/controls.py b/src/assets/ba_data/python/bauiv1lib/settings/controls.py index a28fa89e..591d0b81 100644 --- a/src/assets/ba_data/python/bauiv1lib/settings/controls.py +++ b/src/assets/ba_data/python/bauiv1lib/settings/controls.py @@ -6,7 +6,6 @@ from __future__ import annotations from typing import override -from bauiv1lib.popup import PopupMenu import bascenev1 as bs import bauiv1 as bui @@ -88,19 +87,6 @@ class ControlsSettingsWindow(bui.MainWindow): if platform == 'windows' and not app.env.vr: show_xinput_toggle = True - # On mac builds, show an option to switch between generic and - # made-for-iOS/Mac systems - # (we can run into problems where devices register as one of each - # type otherwise).. - # UPDATE: We always use the apple system these days (which should - # support older controllers). So no need for a switch. - show_mac_controller_subsystem = False - # if platform == 'mac' and bui.is_xcode_build(): - # show_mac_controller_subsystem = True - - if show_mac_controller_subsystem: - height += spacing * 1.5 - if show_xinput_toggle: height += spacing @@ -339,48 +325,6 @@ class ControlsSettingsWindow(bui.MainWindow): ) v -= spacing - if show_mac_controller_subsystem: - PopupMenu( - parent=self._root_widget, - position=(260, v - 10), - width=160, - button_size=(150, 50), - scale=1.5, - choices=['Classic', 'MFi', 'Both'], - choices_display=[ - bui.Lstr(resource='macControllerSubsystemClassicText'), - bui.Lstr(resource='macControllerSubsystemMFiText'), - bui.Lstr(resource='macControllerSubsystemBothText'), - ], - current_choice=bui.app.config.resolve( - 'Mac Controller Subsystem' - ), - on_value_change_call=self._set_mac_controller_subsystem, - ) - bui.textwidget( - parent=self._root_widget, - position=(245, v + 13), - size=(0, 0), - text=bui.Lstr(resource='macControllerSubsystemTitleText'), - scale=1.0, - h_align='right', - v_align='center', - color=bui.app.ui_v1.infotextcolor, - maxwidth=180, - ) - bui.textwidget( - parent=self._root_widget, - position=(width * 0.5, v - 20), - size=(0, 0), - text=bui.Lstr(resource='macControllerSubsystemDescriptionText'), - scale=0.5, - h_align='center', - v_align='center', - color=bui.app.ui_v1.infotextcolor, - maxwidth=width * 0.8, - ) - v -= spacing * 1.5 - self._restore_state() @override @@ -406,76 +350,55 @@ class ControlsSettingsWindow(bui.MainWindow): # pylint: disable=cyclic-import from bauiv1lib.settings.keyboard import ConfigKeyboardWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - ConfigKeyboardWindow(bs.getinputdevice('Keyboard', '#1')), - from_window=self, + self.main_window_replace( + ConfigKeyboardWindow(bs.getinputdevice('Keyboard', '#1')) ) def _config_keyboard2(self) -> None: # pylint: disable=cyclic-import from bauiv1lib.settings.keyboard import ConfigKeyboardWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - ConfigKeyboardWindow(bs.getinputdevice('Keyboard', '#2')), - from_window=self, + self.main_window_replace( + ConfigKeyboardWindow(bs.getinputdevice('Keyboard', '#2')) ) def _do_mobile_devices(self) -> None: # pylint: disable=cyclic-import from bauiv1lib.settings.remoteapp import RemoteAppSettingsWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - RemoteAppSettingsWindow(), from_window=self - ) + self.main_window_replace(RemoteAppSettingsWindow()) def _do_gamepads(self) -> None: # pylint: disable=cyclic-import from bauiv1lib.settings.gamepadselect import GamepadSelectWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window(GamepadSelectWindow(), from_window=self) + self.main_window_replace(GamepadSelectWindow()) def _do_touchscreen(self) -> None: # pylint: disable=cyclic-import from bauiv1lib.settings.touchscreen import TouchscreenSettingsWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we're not in control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - TouchscreenSettingsWindow(), from_window=self - ) + self.main_window_replace(TouchscreenSettingsWindow()) def _save_state(self) -> None: sel = self._root_widget.get_selected_child() @@ -516,22 +439,3 @@ class ControlsSettingsWindow(bui.MainWindow): else self._back_button ) bui.containerwidget(edit=self._root_widget, selected_child=sel) - - # def _back(self) -> None: - # # pylint: disable=cyclic-import - # from bauiv1lib.settings.allsettings import AllSettingsWindow - - # # 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 - - # self._save_state() - # bui.containerwidget( - # edit=self._root_widget, transition=self._transition_out - # ) - # assert bui.app.classic is not None - # bui.app.ui_v1.set_main_window( - # AllSettingsWindow(transition='in_left'), - # from_window=self, - # is_back=True, - # ) diff --git a/src/assets/ba_data/python/bauiv1lib/settings/graphics.py b/src/assets/ba_data/python/bauiv1lib/settings/graphics.py index 3088476d..a295f192 100644 --- a/src/assets/ba_data/python/bauiv1lib/settings/graphics.py +++ b/src/assets/ba_data/python/bauiv1lib/settings/graphics.py @@ -78,9 +78,7 @@ class GraphicsSettingsWindow(bui.MainWindow): (0, -10) if uiscale is bui.UIScale.SMALL else (0, 0) ), toolbar_visibility=( - 'menu_minimal' - if uiscale is bui.UIScale.SMALL - else 'menu_full' + None if uiscale is bui.UIScale.SMALL else 'menu_full' ), ), transition=transition, @@ -90,7 +88,6 @@ class GraphicsSettingsWindow(bui.MainWindow): back_button = bui.buttonwidget( parent=self._root_widget, position=(35, height - 50), - # size=(120, 60), size=(60, 60), scale=0.8, text_scale=1.2, diff --git a/src/assets/ba_data/python/bauiv1lib/settings/plugins.py b/src/assets/ba_data/python/bauiv1lib/settings/plugins.py index d5f4fd81..6c12907d 100644 --- a/src/assets/ba_data/python/bauiv1lib/settings/plugins.py +++ b/src/assets/ba_data/python/bauiv1lib/settings/plugins.py @@ -235,16 +235,11 @@ class PluginWindow(bui.MainWindow): # pylint: disable=cyclic-import from bauiv1lib.settings.pluginsettings import PluginSettingsWindow - # no-op if our underlying widget is dead or on its way out. - if not self._root_widget or self._root_widget.transitioning_out: + # no-op if we don't have control. + if not self.main_window_has_control(): return - self._save_state() - bui.containerwidget(edit=self._root_widget, transition='out_left') - assert bui.app.classic is not None - bui.app.ui_v1.set_main_window( - PluginSettingsWindow(transition='in_right'), from_window=self - ) + self.main_window_replace(PluginSettingsWindow(transition='in_right')) def _show_category_options(self) -> None: uiscale = bui.app.ui_v1.uiscale diff --git a/src/assets/ba_data/python/bauiv1lib/store/browser.py b/src/assets/ba_data/python/bauiv1lib/store/browser.py index 74d4a60d..17a36740 100644 --- a/src/assets/ba_data/python/bauiv1lib/store/browser.py +++ b/src/assets/ba_data/python/bauiv1lib/store/browser.py @@ -41,11 +41,11 @@ class StoreBrowserWindow(bui.MainWindow): def __init__( self, transition: str | None = 'in_right', + origin_widget: bui.Widget | None = None, # modal: bool = False, show_tab: StoreBrowserWindow.TabID | None = None, # on_close_call: Callable[[], Any] | None = None, # back_location: str | None = None, - origin_widget: bui.Widget | None = None, minimal_toolbars: bool = False, ): # pylint: disable=too-many-statements diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index 9086c601..8fee7684 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 = 21985; +const int kEngineBuildNumber = 21986; const char* kEngineVersion = "1.7.37"; const int kEngineApiVersion = 9; diff --git a/src/ballistica/ui_v1/widget/root_widget.cc b/src/ballistica/ui_v1/widget/root_widget.cc index ef24309c..8028d82d 100644 --- a/src/ballistica/ui_v1/widget/root_widget.cc +++ b/src/ballistica/ui_v1/widget/root_widget.cc @@ -16,13 +16,16 @@ namespace ballistica::ui_v1 { // Color we mult toolbars by in medium and large ui modes (in small mode we // keep them more the normal window color since everything overlaps). -#define TOOLBAR_COLOR_R 0.75f -#define TOOLBAR_COLOR_G 0.85f -#define TOOLBAR_COLOR_B 0.85f +#define TOOLBAR_COLOR_R 1.0f +#define TOOLBAR_COLOR_G 1.0f +#define TOOLBAR_COLOR_B 1.0f +// #define TOOLBAR_COLOR_R 0.75f +// #define TOOLBAR_COLOR_G 0.85f +// #define TOOLBAR_COLOR_B 0.85f -#define TOOLBAR_BACK_COLOR_R 0.8f -#define TOOLBAR_BACK_COLOR_G 0.8f -#define TOOLBAR_BACK_COLOR_B 0.8f +#define TOOLBAR_BACK_COLOR_R 1.0f +#define TOOLBAR_BACK_COLOR_G 1.0f +#define TOOLBAR_BACK_COLOR_B 1.0f // Opacity in med/large. #define TOOLBAR_OPACITY 1.0f @@ -469,9 +472,9 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, bd.color_g = 0.35f; bd.color_b = 0.55f; if (g_base->ui->scale() != UIScale::kSmall) { - bd.color_r *= TOOLBAR_COLOR_R; - bd.color_g *= TOOLBAR_COLOR_G; - bd.color_b *= TOOLBAR_COLOR_B; + // bd.color_r *= TOOLBAR_COLOR_R; + // bd.color_g *= TOOLBAR_COLOR_G; + // bd.color_b *= TOOLBAR_COLOR_B; } bd.depth_min = 0.3f; switch (type) { @@ -662,9 +665,9 @@ void RootWidget::Setup() { bd.color_b = 0.73f; bd.call = UIV1Python::ObjID::kRootUIAccountButtonPressCall; if (g_base->ui->scale() != UIScale::kSmall) { - bd.color_r *= TOOLBAR_COLOR_R; - bd.color_g *= TOOLBAR_COLOR_G; - bd.color_b *= TOOLBAR_COLOR_B; + // bd.color_r *= TOOLBAR_COLOR_R; + // bd.color_g *= TOOLBAR_COLOR_G; + // bd.color_b *= TOOLBAR_COLOR_B; } bd.pre_buffer = 10.0f; bd.visibility_mask = @@ -1056,10 +1059,11 @@ void RootWidget::Setup() { b.color_g = backing_cover_g; b.color_b = backing_cover_b; b.opacity = 1.0f; - b.call = UIV1Python::ObjID::kRootUIChestSlot3PressCall; + b.call = UIV1Python::ObjID::kRootUIChestSlot2PressCall; b.x = -0.5f * spacing; AddButton_(b); b.x = 0.5f * spacing; + b.call = UIV1Python::ObjID::kRootUIChestSlot3PressCall; AddButton_(b); b.x = 1.5f * spacing; b.call = UIV1Python::ObjID::kRootUIChestSlot4PressCall;