polishing and toolbar-related fixes

This commit is contained in:
Eric 2024-10-04 14:39:50 -07:00
parent 29433b24b5
commit 3b6d44f5c0
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
35 changed files with 310 additions and 192 deletions

88
.efrocachemap generated
View File

@ -4096,50 +4096,50 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599", "build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "5dc626488240419a7fccd2e11e4e4fdc", "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "0b91292430d8deb60fea29ea3cbd08c4",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "9ee005e3df40528efc090d879917bec2", "build/prefab/full/linux_arm64_gui/release/ballisticakit": "5de7507d5eecd943a259306e4a88e31f",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "d554d33e3923e544b9b31dcc261230fb", "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "b784c5218097a3cc9cb1fb128252745f",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "764db7c11f7448c2c1dde96d7ec799b5", "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "fe567c99090f94f169a09a8a49f072c6",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "dd6fe4f7cc89a93a50a9693587bf511a", "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "a1718fa31093008d7e06df5437ad094e",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "cf203b66bb7bd718dbcb43c19d2c45bd", "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "8b8a7d3a484d4bca1946d479be3dfa0b",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "317ec48fe589393847a7b0c0a6d602d1", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "f55dda6ac5c57e950fd6caca43723e04",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "59dd77ef407875ff7af0628e05a45ae7", "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "d7cf60f2dd71b8ea6e44e86384897542",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "c3f17815f34c6947eda16fdb850ed64c", "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "34bffdb7d43d4a918f03d7adc3185572",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "6169a8b0c55aec2aa8e2ebd618d379a2", "build/prefab/full/mac_arm64_gui/release/ballisticakit": "e1eaf4393ae32874fc7ed09eb9e87071",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "a1596b9b8425ab0a8531c7f1f4acf3b8", "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "76fb2324412f05f62d6664c0fbaaa6ff",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "e674b261174e9b06a34f90c626856aa6", "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "45fdd4c09007e601a74e8be5705c64f5",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "d14b5f0693440239fd056d831441a53a", "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "36dcd45c4503216ab4c213ed92386c31",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "3584cd1db78d6b68c8436eaa86bc6d21", "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "bf22c964c56cd8593c17504ab19ec152",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "b7242358f3d1bb04a414e4b7dfbc4311", "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "da9177bfef989af57ce047267e7fdf23",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "11fe178ab9c93eb0f5d32a27895ea811", "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "f5fd6eada12cf3de3735b80d6a707240",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "413f092eb584ba15edc1a1b48a63d760", "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "60fd3eb460320f3246001ba9b57b0c65",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "35b37b4a67815a91df7b77ea2fac9f26", "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "7bdf4ca50de9ff62bc6cbd86a07ca68d",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "102b5af73a4ebce8ac475ed960ead4b4", "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "daa2b20a69b554f619de0b1e3f8083fc",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "f46a78e101f8c2c73654dfc982295748", "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "facbfecf157677de9756cc02833fbaea",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "0b5f8bdbe8221c4642d9f7f8584645ce", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "f731b23639b0b152109c3a367ab19340",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "e94dd06863796f17b9cfcbb5f79edd32", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "af1fa785407814fb7cab31dc95b6246d",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "0b5f8bdbe8221c4642d9f7f8584645ce", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "f731b23639b0b152109c3a367ab19340",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "e94dd06863796f17b9cfcbb5f79edd32", "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "af1fa785407814fb7cab31dc95b6246d",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "0248b884a4670bd63fc68faeb93db160", "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "1eff75bbcdce0ff611678ce79ba0ac18",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "2a5be1c7afca637bab7638d938d1b5b4", "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "af504ed9b0990fdbc5441b40f925890a",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "0248b884a4670bd63fc68faeb93db160", "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "1eff75bbcdce0ff611678ce79ba0ac18",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "2a5be1c7afca637bab7638d938d1b5b4", "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "af504ed9b0990fdbc5441b40f925890a",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "1f25c914affb8b1944a6eb10b4db2947", "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "2c88978e61c4a37606c4964ab0e62561",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "b7cc7b32cc752d76d01d802977bd7abb", "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "0422ad13cbb5234fecfc14f7573ba020",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "1f25c914affb8b1944a6eb10b4db2947", "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "2c88978e61c4a37606c4964ab0e62561",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "b7cc7b32cc752d76d01d802977bd7abb", "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "0422ad13cbb5234fecfc14f7573ba020",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "cc0bf2777f9e63f2917cf43a9f522876", "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "412efbbf3d7d9c85398c43303b03466e",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "381953df0ba482ef485e4da3fd8e9e69", "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "82b3e97e5f7620294eede876424e0c75",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "3b706f71d9a4fd3e5e5ecae88c6087ee", "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "dc201ad653d7098266caa12bcd038c30",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "381953df0ba482ef485e4da3fd8e9e69", "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "82b3e97e5f7620294eede876424e0c75",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "1706a7dc691b033e20d3861e9b16861d", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "5d5a32f8689888afe15b4bf082e3a21e",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "259cbea25d8aa9d53e61f2f1c7af2ff6", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "d7267b05c7f8f62786f2f7990b0bf5fa",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "fd51dd1b9a75c053ba91ed521fd72fe1", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "7a2710912719f036223e55afe427676f",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "3bb33d27b717ab731f43f44c443d1504", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "e2ccdb0ee72f166b12dc33002b169f4c",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "930c75164e229b2f9e3aa042100b1911", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "8c7c457e748d8fcf3a067197ba1745fd",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "329d5a560c7dd3a9bef54ec9db9aaf27", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "9b8e2960261083daaf8b4a283531a8bb",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "51175094ecad6e8bea39103bb927e449", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "47bfa200bb3a75e5cd94c4bcddb74a68",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "abf57a7d6c2df8bc3829060039bf7c19", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "6b865403653c3d080088e4e3cdba6f45",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "794d258d59fd17a61752843a9a0551ad", "src/assets/ba_data/python/babase/_mgen/enums.py": "794d258d59fd17a61752843a9a0551ad",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "efa61468cf098f77cc6a234461d8b86d", "src/ballistica/base/mgen/pyembed/binding_base.inc": "efa61468cf098f77cc6a234461d8b86d",

View File

@ -1,4 +1,4 @@
### 1.7.37 (build 22021, api 9, 2024-09-30) ### 1.7.37 (build 22024, api 9, 2024-10-04)
- Bumping api version to 9. As you'll see below, there's some UI changes that - 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 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. touch UI stuff at all you can simply bump your api version and call it a day.

View File

@ -64,11 +64,11 @@ class AccountV2Subsystem:
def have_primary_credentials(self) -> bool: def have_primary_credentials(self) -> bool:
"""Are credentials currently set for the primary app account? """Are credentials currently set for the primary app account?
Note that this does not mean these credentials are currently valid; Note that this does not mean these credentials have been checked
only that they exist. If/when credentials are validated, the 'primary' for validity; only that they exist. If/when credentials are
account handle will be set. validated, the 'primary' account handle will be set.
""" """
raise NotImplementedError('This should be overridden.') raise NotImplementedError()
@property @property
def primary(self) -> AccountV2Handle | None: def primary(self) -> AccountV2Handle | None:
@ -105,9 +105,9 @@ class AccountV2Subsystem:
on_completed=self._on_set_active_workspace_completed, on_completed=self._on_set_active_workspace_completed,
) )
else: else:
# Don't activate workspaces if we've already told the game # Don't activate workspaces if we've already told the
# that initial-log-in is done or if we've already kicked # game that initial-log-in is done or if we've already
# off a workspace load. # kicked off a workspace load.
_babase.screenmessage( _babase.screenmessage(
f'\'{account.workspacename}\'' f'\'{account.workspacename}\''
f' will be activated at next app launch.', f' will be activated at next app launch.',
@ -264,11 +264,11 @@ class AccountV2Subsystem:
def do_get_primary(self) -> AccountV2Handle | None: def do_get_primary(self) -> AccountV2Handle | None:
"""Internal - should be overridden by subclass.""" """Internal - should be overridden by subclass."""
raise NotImplementedError('This should be overridden.') raise NotImplementedError()
def set_primary_credentials(self, credentials: str | None) -> None: def set_primary_credentials(self, credentials: str | None) -> None:
"""Set credentials for the primary app account.""" """Set credentials for the primary app account."""
raise NotImplementedError('This should be overridden.') raise NotImplementedError()
def _update_auto_sign_in(self) -> None: def _update_auto_sign_in(self) -> None:
plus = _babase.app.plus plus = _babase.app.plus

View File

@ -54,7 +54,7 @@ class AppMode:
"""Called when the mode is being deactivated.""" """Called when the mode is being deactivated."""
def on_app_active_changed(self) -> None: def on_app_active_changed(self) -> None:
"""Called when babase.app.active changes. """Called when ba*.app.active changes while this mode is active.
The app-mode may want to take action such as pausing a running The app-mode may want to take action such as pausing a running
game in such cases. game in such cases.

View File

@ -115,7 +115,7 @@ def handle_v1_cloud_log() -> None:
'userRanCommands': _babase.has_user_run_commands(), 'userRanCommands': _babase.has_user_run_commands(),
'time': _babase.apptime(), 'time': _babase.apptime(),
'userModded': _babase.workspaces_in_use(), 'userModded': _babase.workspaces_in_use(),
'newsShow': plus.get_news_show(), 'newsShow': plus.get_classic_news_show(),
} }
def response(data: Any) -> None: def response(data: Any) -> None:

View File

@ -176,7 +176,9 @@ class AccountV1Subsystem:
else {} else {}
) )
for item_name, item in list(store_items.items()): for item_name, item in list(store_items.items()):
if item_name.startswith('icons.') and plus.get_purchased(item_name): if item_name.startswith(
'icons.'
) and plus.get_v1_account_product_purchased(item_name):
icons.append(item['icon']) icons.append(item['icon'])
return icons return icons
@ -230,9 +232,9 @@ class AccountV1Subsystem:
# Check our tickets-based pro upgrade and our two real-IAP based # Check our tickets-based pro upgrade and our two real-IAP based
# upgrades. Also always unlock this stuff in ballistica-core builds. # upgrades. Also always unlock this stuff in ballistica-core builds.
return bool( return bool(
plus.get_purchased('upgrades.pro') plus.get_v1_account_product_purchased('upgrades.pro')
or plus.get_purchased('static.pro') or plus.get_v1_account_product_purchased('static.pro')
or plus.get_purchased('static.pro_sale') or plus.get_v1_account_product_purchased('static.pro_sale')
or 'ballistica' + 'kit' == babase.appname() or 'ballistica' + 'kit' == babase.appname()
) )

View File

@ -15,7 +15,6 @@ from babase import (
AppIntentDefault, AppIntentDefault,
invoke_main_menu, invoke_main_menu,
screenmessage, screenmessage,
# in_main_menu,
) )
import _baclassic import _baclassic

View File

@ -446,8 +446,9 @@ class StoreSubsystem:
'price.' + item, None 'price.' + item, None
) )
if ticket_cost is not None: if ticket_cost is not None:
if our_tickets >= ticket_cost and not plus.get_purchased( if (
item our_tickets >= ticket_cost
and not plus.get_v1_account_product_purchased(item)
): ):
count += 1 count += 1
return count return count
@ -522,7 +523,7 @@ class StoreSubsystem:
for section in store_layout[tab]: for section in store_layout[tab]:
for item in section['items']: for item in section['items']:
if item in sales_raw: if item in sales_raw:
if not plus.get_purchased(item): if not plus.get_v1_account_product_purchased(item):
to_end = ( to_end = (
datetime.datetime.fromtimestamp( datetime.datetime.fromtimestamp(
sales_raw[item]['e'], datetime.UTC sales_raw[item]['e'], datetime.UTC
@ -550,7 +551,10 @@ class StoreSubsystem:
if babase.app.env.gui: if babase.app.env.gui:
for map_section in self.get_store_layout()['maps']: for map_section in self.get_store_layout()['maps']:
for mapitem in map_section['items']: for mapitem in map_section['items']:
if plus is None or not plus.get_purchased(mapitem): if (
plus is None
or not plus.get_v1_account_product_purchased(mapitem)
):
m_info = self.get_store_item(mapitem) m_info = self.get_store_item(mapitem)
unowned_maps.add(m_info['map_type'].name) unowned_maps.add(m_info['map_type'].name)
return sorted(unowned_maps) return sorted(unowned_maps)
@ -563,7 +567,10 @@ class StoreSubsystem:
if babase.app.env.gui: if babase.app.env.gui:
for section in self.get_store_layout()['minigames']: for section in self.get_store_layout()['minigames']:
for mname in section['items']: for mname in section['items']:
if plus is None or not plus.get_purchased(mname): if (
plus is None
or not plus.get_v1_account_product_purchased(mname)
):
m_info = self.get_store_item(mname) m_info = self.get_store_item(mname)
unowned_games.add(m_info['gametype']) unowned_games.add(m_info['gametype'])
return unowned_games return unowned_games

View File

@ -52,7 +52,7 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be # Build number and version of the ballistica binary we expect to be
# using. # using.
TARGET_BALLISTICA_BUILD = 22021 TARGET_BALLISTICA_BUILD = 22024
TARGET_BALLISTICA_VERSION = '1.7.37' TARGET_BALLISTICA_VERSION = '1.7.37'

View File

@ -40,7 +40,6 @@ class PlusAppSubsystem(AppSubsystem):
_baplus.on_app_loading() _baplus.on_app_loading()
self.accounts.on_app_loading() self.accounts.on_app_loading()
# noinspection PyUnresolvedReferences
@staticmethod @staticmethod
def add_v1_account_transaction( def add_v1_account_transaction(
transaction: dict, callback: Callable | None = None transaction: dict, callback: Callable | None = None
@ -66,9 +65,9 @@ class PlusAppSubsystem(AppSubsystem):
return _baplus.get_master_server_address(source, version) return _baplus.get_master_server_address(source, version)
@staticmethod @staticmethod
def get_news_show() -> str: def get_classic_news_show() -> str:
"""(internal)""" """(internal)"""
return _baplus.get_news_show() return _baplus.get_classic_news_show()
@staticmethod @staticmethod
def get_price(item: str) -> str | None: def get_price(item: str) -> str | None:
@ -76,14 +75,14 @@ class PlusAppSubsystem(AppSubsystem):
return _baplus.get_price(item) return _baplus.get_price(item)
@staticmethod @staticmethod
def get_purchased(item: str) -> bool: def get_v1_account_product_purchased(item: str) -> bool:
"""(internal)""" """(internal)"""
return _baplus.get_purchased(item) return _baplus.get_v1_account_product_purchased(item)
@staticmethod @staticmethod
def get_purchases_state() -> int: def get_v1_account_product_purchases_state() -> int:
"""(internal)""" """(internal)"""
return _baplus.get_purchases_state() return _baplus.get_v1_account_product_purchases_state()
@staticmethod @staticmethod
def get_v1_account_display_string(full: bool = True) -> str: def get_v1_account_display_string(full: bool = True) -> str:
@ -129,7 +128,7 @@ class PlusAppSubsystem(AppSubsystem):
def get_v1_account_ticket_count() -> int: def get_v1_account_ticket_count() -> int:
"""(internal) """(internal)
Returns the number of tickets for the current account. Return the number of tickets for the current account.
""" """
return _baplus.get_v1_account_ticket_count() return _baplus.get_v1_account_ticket_count()

View File

@ -14,7 +14,7 @@ def get_appearances(include_locked: bool = False) -> list[str]:
assert plus is not None assert plus is not None
assert bs.app.classic is not None assert bs.app.classic is not None
get_purchased = plus.get_purchased get_purchased = plus.get_v1_account_product_purchased
disallowed = [] disallowed = []
if not include_locked: if not include_locked:
# Hmm yeah this'll be tough to hack... # Hmm yeah this'll be tough to hack...

View File

@ -199,8 +199,7 @@ class MainWindow(Window):
def get_main_window_state(self) -> MainWindowState: def get_main_window_state(self) -> MainWindowState:
"""Return a WindowState to recreate this window, if supported.""" """Return a WindowState to recreate this window, if supported."""
# TODO - change to NotImplementedError when moved to MainWindow. raise NotImplementedError()
raise RuntimeError('FIXME NOT IMPLEMENTED')
class MainWindowState: class MainWindowState:

View File

@ -910,7 +910,7 @@ class CoopBrowserWindow(bui.MainWindow):
# Show easter-egg-hunt either if its easter or we own it. # Show easter-egg-hunt either if its easter or we own it.
if plus.get_v1_account_misc_read_val( if plus.get_v1_account_misc_read_val(
'easter', False 'easter', False
) or plus.get_purchased('games.easter_egg_hunt'): ) or plus.get_v1_account_product_purchased('games.easter_egg_hunt'):
items = [ items = [
'Challenges:Easter Egg Hunt', 'Challenges:Easter Egg Hunt',
'Challenges:Pro Easter Egg Hunt', 'Challenges:Pro Easter Egg Hunt',
@ -1089,8 +1089,9 @@ class CoopBrowserWindow(bui.MainWindow):
else: else:
required_purchase = None required_purchase = None
if required_purchase is not None and not plus.get_purchased( if (
required_purchase required_purchase is not None
and not plus.get_v1_account_product_purchased(required_purchase)
): ):
if plus.get_v1_account_state() != 'signed_in': if plus.get_v1_account_state() != 'signed_in':
show_sign_in_prompt() show_sign_in_prompt()

View File

@ -243,7 +243,9 @@ class GameButton:
) )
or ( or (
game in ('Challenges:Meteor Shower',) game in ('Challenges:Meteor Shower',)
and not plus.get_purchased('games.meteor_shower') and not plus.get_v1_account_product_purchased(
'games.meteor_shower'
)
) )
or ( or (
game game
@ -251,15 +253,21 @@ class GameButton:
'Challenges:Target Practice', 'Challenges:Target Practice',
'Challenges:Target Practice B', 'Challenges:Target Practice B',
) )
and not plus.get_purchased('games.target_practice') and not plus.get_v1_account_product_purchased(
'games.target_practice'
)
) )
or ( or (
game in ('Challenges:Ninja Fight',) game in ('Challenges:Ninja Fight',)
and not plus.get_purchased('games.ninja_fight') and not plus.get_v1_account_product_purchased(
'games.ninja_fight'
)
) )
or ( or (
game in ('Challenges:Pro Ninja Fight',) game in ('Challenges:Pro Ninja Fight',)
and not plus.get_purchased('games.ninja_fight') and not plus.get_v1_account_product_purchased(
'games.ninja_fight'
)
) )
or ( or (
game game
@ -267,7 +275,9 @@ class GameButton:
'Challenges:Easter Egg Hunt', 'Challenges:Easter Egg Hunt',
'Challenges:Pro Easter Egg Hunt', 'Challenges:Pro Easter Egg Hunt',
) )
and not plus.get_purchased('games.easter_egg_hunt') and not plus.get_v1_account_product_purchased(
'games.easter_egg_hunt'
)
) )
): ):
unlocked = False unlocked = False

View File

@ -393,9 +393,10 @@ class LeagueRankButton:
def _default_on_activate_call(self) -> None: def _default_on_activate_call(self) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.league.rankwindow import LeagueRankWindow # from bauiv1lib.league.rankwindow import LeagueRankWindow
LeagueRankWindow(modal=True, origin_widget=self._button) raise RuntimeError()
# LeagueRankWindow(modal=True, origin_widget=self._button)
def set_position(self, position: tuple[float, float]) -> None: def set_position(self, position: tuple[float, float]) -> None:
"""Set the button's position.""" """Set the button's position."""

View File

@ -7,7 +7,7 @@ from __future__ import annotations
import copy import copy
import logging import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, override
from bauiv1lib.popup import PopupMenu from bauiv1lib.popup import PopupMenu
import bauiv1 as bui import bauiv1 as bui
@ -23,7 +23,6 @@ class LeagueRankWindow(bui.MainWindow):
self, self,
transition: str | None = 'in_right', transition: str | None = 'in_right',
origin_widget: bui.Widget | None = None, origin_widget: bui.Widget | None = None,
modal: bool = False,
): ):
# pylint: disable=too-many-statements # pylint: disable=too-many-statements
plus = bui.app.plus plus = bui.app.plus
@ -32,7 +31,6 @@ class LeagueRankWindow(bui.MainWindow):
bui.set_analytics_screen('League Rank Window') bui.set_analytics_screen('League Rank Window')
self._league_rank_data: dict[str, Any] | None = None self._league_rank_data: dict[str, Any] | None = None
self._modal = modal
self._power_ranking_achievements_button: bui.Widget | None = None self._power_ranking_achievements_button: bui.Widget | None = None
self._pro_mult_button: bui.Widget | None = None self._pro_mult_button: bui.Widget | None = None
@ -46,12 +44,6 @@ class LeagueRankWindow(bui.MainWindow):
self._to_ranked_text: bui.Widget | None = None self._to_ranked_text: bui.Widget | None = None
self._trophy_counts_reset_text: bui.Widget | None = None self._trophy_counts_reset_text: bui.Widget | None = None
# Need to handle transitioning out ourself for modal case
if origin_widget is not None:
self._transition_out = 'out_scale'
else:
self._transition_out = 'out_right'
assert bui.app.classic is not None assert bui.app.classic is not None
uiscale = bui.app.ui_v1.uiscale uiscale = bui.app.ui_v1.uiscale
self._width = 1490 if uiscale is bui.UIScale.SMALL else 1120 self._width = 1490 if uiscale is bui.UIScale.SMALL else 1120
@ -98,7 +90,7 @@ class LeagueRankWindow(bui.MainWindow):
if uiscale is bui.UIScale.SMALL: if uiscale is bui.UIScale.SMALL:
self._back_button = bui.get_special_widget('back_button') self._back_button = bui.get_special_widget('back_button')
bui.containerwidget( bui.containerwidget(
edit=self._root_widget, on_cancel_call=self._back edit=self._root_widget, on_cancel_call=self.main_window_back
) )
else: else:
self._back_button = btn = bui.buttonwidget( self._back_button = btn = bui.buttonwidget(
@ -107,11 +99,9 @@ class LeagueRankWindow(bui.MainWindow):
size=(120, 60), size=(120, 60),
scale=1.2, scale=1.2,
autoselect=True, autoselect=True,
label=bui.Lstr( label=bui.Lstr(resource='backText'),
resource='doneText' if self._modal else 'backText' button_type='back',
), on_activate_call=self.main_window_back,
button_type=None if self._modal else 'back',
on_activate_call=self._back,
) )
bui.buttonwidget( bui.buttonwidget(
edit=btn, edit=btn,
@ -185,6 +175,20 @@ class LeagueRankWindow(bui.MainWindow):
) )
self._update(show=info is None) self._update(show=info is None)
@override
def get_main_window_state(self) -> bui.MainWindowState:
# Support recreating our window for back/refresh purposes.
cls = type(self)
return bui.BasicMainWindowState(
create_call=lambda transition, origin_widget: cls(
transition=transition, origin_widget=origin_widget
)
)
@override
def on_main_window_close(self) -> None:
self._save_state()
def _on_achievements_press(self) -> None: def _on_achievements_press(self) -> None:
from bauiv1lib.achievements import AchievementsWindow from bauiv1lib.achievements import AchievementsWindow
@ -1163,17 +1167,3 @@ class LeagueRankWindow(bui.MainWindow):
def _save_state(self) -> None: def _save_state(self) -> None:
pass pass
def _back(self) -> 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
self._save_state()
if self._modal:
bui.containerwidget(
edit=self._root_widget, transition=self._transition_out
)
else:
self.main_window_back()

View File

@ -155,7 +155,7 @@ class PurchaseWindow(bui.Window):
if bui.app.classic.accounts.have_pro(): if bui.app.classic.accounts.have_pro():
can_die = True can_die = True
else: else:
if plus.get_purchased(self._items[0]): if plus.get_v1_account_product_purchased(self._items[0]):
can_die = True can_die = True
if can_die: if can_die:

View File

@ -6,7 +6,7 @@ from __future__ import annotations
import time import time
import logging import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, override
import bauiv1 as bui import bauiv1 as bui
@ -164,6 +164,25 @@ class SendInfoWindow(bui.MainWindow):
selected_child=self._text_field, selected_child=self._text_field,
) )
@override
def get_main_window_state(self) -> bui.MainWindowState:
# Support recreating our window for back/refresh purposes.
cls = type(self)
assert not self._modal
# Pull stuff out of self here; if we do it in the lambda we'll
# keep self alive which we don't want.
legacy_code_mode = self._legacy_code_mode
return bui.BasicMainWindowState(
create_call=lambda transition, origin_widget: cls(
legacy_code_mode=legacy_code_mode,
transition=transition,
origin_widget=origin_widget,
)
)
def _do_back(self) -> None: def _do_back(self) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import

View File

@ -6,7 +6,7 @@
from __future__ import annotations from __future__ import annotations
import logging import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, override
from bauiv1lib.popup import PopupMenuWindow from bauiv1lib.popup import PopupMenuWindow
import bascenev1 as bs import bascenev1 as bs
@ -14,6 +14,7 @@ import bauiv1 as bui
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Callable from typing import Any, Callable
from bauiv1lib.popup import PopupWindow from bauiv1lib.popup import PopupWindow
@ -27,7 +28,7 @@ class GamepadSettingsWindow(bui.MainWindow):
inputdevice: bs.InputDevice, inputdevice: bs.InputDevice,
*, *,
modal: bool = False, modal: bool = False,
transition: str = 'in_right', transition: str | None = 'in_right',
transition_out: str = 'out_right', transition_out: str = 'out_right',
origin_widget: bui.Widget | None = None, origin_widget: bui.Widget | None = None,
settings: dict | None = None, settings: dict | None = None,
@ -76,6 +77,26 @@ class GamepadSettingsWindow(bui.MainWindow):
# Don't ask to config joysticks while we're in here. # Don't ask to config joysticks while we're in here.
self._rebuild_ui() self._rebuild_ui()
@override
def get_main_window_state(self) -> bui.MainWindowState:
# Support recreating our window for back/refresh purposes.
cls = type(self)
# Pull stuff out of self here; if we do it in the lambda we keep
# self alive which we don't want.
assert not self._is_secondary
assert not self._modal
inputdevice = self._inputdevice
return bui.BasicMainWindowState(
create_call=lambda transition, origin_widget: cls(
inputdevice=inputdevice,
transition=transition,
origin_widget=origin_widget,
)
)
def _get_config_mapping(self, default: bool = False) -> None: def _get_config_mapping(self, default: bool = False) -> None:
for button in [ for button in [
'buttonJump', 'buttonJump',

View File

@ -156,7 +156,12 @@ class GamepadSelectWindow(bui.MainWindow):
class _NotConfigurableWindow(bui.MainWindow): class _NotConfigurableWindow(bui.MainWindow):
def __init__(self, device: bs.InputDevice) -> None: def __init__(
self,
device: bs.InputDevice,
transition: str | None = 'in_right',
origin_widget: bui.Widget | None = None,
) -> None:
width = 700 width = 700
height = 200 height = 200
button_width = 80 button_width = 80
@ -170,9 +175,11 @@ class _NotConfigurableWindow(bui.MainWindow):
), ),
size=(width, height), size=(width, height),
), ),
transition='in_right', transition=transition,
origin_widget=None, origin_widget=origin_widget,
) )
self.device = device
if device.allows_configuring_in_system_settings: if device.allows_configuring_in_system_settings:
msg = bui.Lstr( msg = bui.Lstr(
resource='configureDeviceInSystemSettingsText', resource='configureDeviceInSystemSettingsText',
@ -212,10 +219,19 @@ class _NotConfigurableWindow(bui.MainWindow):
) )
bui.containerwidget(edit=self._root_widget, cancel_button=btn) bui.containerwidget(edit=self._root_widget, cancel_button=btn)
# def _ok(self) -> None: @override
def get_main_window_state(self) -> bui.MainWindowState:
# Support recreating our window for back/refresh purposes.
cls = type(self)
# # Back would take us to the gamepad-select window. We want to go # Pull stuff out of self here; if we do it in the lambda we'll
# # past that. # keep self alive which we don't want.
# assert self.main_window_back_state is not None device = self.device
# self.main_window_back_state = self.main_window_back_state.parent
# self.main_window_back() return bui.BasicMainWindowState(
create_call=lambda transition, origin_widget: cls(
device=device,
transition=transition,
origin_widget=origin_widget,
)
)

View File

@ -5,7 +5,7 @@
from __future__ import annotations from __future__ import annotations
import copy import copy
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, override
import bauiv1 as bui import bauiv1 as bui
@ -90,6 +90,27 @@ class MacMusicAppPlaylistSelectWindow(bui.MainWindow):
edit=self._root_widget, selected_child=self._scrollwidget edit=self._root_widget, selected_child=self._scrollwidget
) )
@override
def get_main_window_state(self) -> bui.MainWindowState:
# Support recreating our window for back/refresh purposes.
cls = type(self)
# Pull stuff out of self here; if we do it in the lambda we wind
# up keeping self alive which we don't want.
callback = self._callback
existing_playlist = self._existing_playlist
existing_entry = self._existing_entry
return bui.BasicMainWindowState(
create_call=lambda transition, origin_widget: cls(
callback=callback,
existing_playlist=existing_playlist,
existing_entry=existing_entry,
transition=transition,
origin_widget=origin_widget,
)
)
def _playlists_cb(self, playlists: list[str]) -> None: def _playlists_cb(self, playlists: list[str]) -> None:
if self._column: if self._column:
for widget in self._column.get_children(): for widget in self._column.get_children():

View File

@ -621,7 +621,7 @@ class StoreBrowserWindow(bui.MainWindow):
assert bui.app.classic is not None assert bui.app.classic is not None
purchased = bui.app.classic.accounts.have_pro() purchased = bui.app.classic.accounts.have_pro()
else: else:
purchased = plus.get_purchased(b_type) purchased = plus.get_v1_account_product_purchased(b_type)
sale_opacity = 0.0 sale_opacity = 0.0
sale_title_text: str | bui.Lstr = '' sale_title_text: str | bui.Lstr = ''

View File

@ -283,7 +283,7 @@ class StoreButton:
# Look at the current set of sales; filter any with time # Look at the current set of sales; filter any with time
# remaining that we don't own. # remaining that we don't own.
for sale_item, sale_info in list(sales_raw.items()): for sale_item, sale_info in list(sales_raw.items()):
if not plus.get_purchased(sale_item): if not plus.get_v1_account_product_purchased(sale_item):
to_end = ( to_end = (
datetime.datetime.fromtimestamp( datetime.datetime.fromtimestamp(
sale_info['e'], datetime.UTC sale_info['e'], datetime.UTC

View File

@ -742,7 +742,7 @@ class TournamentEntryWindow(PopupWindow):
# This should have awarded us the tournament_entry_ad purchase; # This should have awarded us the tournament_entry_ad purchase;
# make sure that's present. # make sure that's present.
# (otherwise the server will ignore our tournament entry anyway) # (otherwise the server will ignore our tournament entry anyway)
if not plus.get_purchased('tournament_entry_ad'): if not plus.get_v1_account_product_purchased('tournament_entry_ad'):
print('no tournament_entry_ad purchase present in _on_ad_complete') print('no tournament_entry_ad purchase present in _on_ad_complete')
bui.screenmessage(bui.Lstr(resource='errorText'), color=(1, 0, 0)) bui.screenmessage(bui.Lstr(resource='errorText'), color=(1, 0, 0))
bui.getsound('error').play() bui.getsound('error').play()
@ -781,7 +781,7 @@ class TournamentEntryWindow(PopupWindow):
# the tournament. # the tournament.
if (bui.apptime() - self._last_ticket_press_time < 6.0) and ( if (bui.apptime() - self._last_ticket_press_time < 6.0) and (
plus.have_outstanding_v1_account_transactions() plus.have_outstanding_v1_account_transactions()
or plus.get_purchased(self._purchase_name) or plus.get_v1_account_product_purchased(self._purchase_name)
or self._entering or self._entering
): ):
bui.getsound('error').play() bui.getsound('error').play()

View File

@ -3,8 +3,6 @@
#ifndef BALLISTICA_BASE_APP_MODE_EMPTY_APP_MODE_H_ #ifndef BALLISTICA_BASE_APP_MODE_EMPTY_APP_MODE_H_
#define BALLISTICA_BASE_APP_MODE_EMPTY_APP_MODE_H_ #define BALLISTICA_BASE_APP_MODE_EMPTY_APP_MODE_H_
#include <vector>
#include "ballistica/base/app_mode/app_mode.h" #include "ballistica/base/app_mode/app_mode.h"
#include "ballistica/shared/foundation/object.h" #include "ballistica/shared/foundation/object.h"
@ -23,6 +21,7 @@ class EmptyAppMode : public AppMode {
private: private:
void Reset_(); void Reset_();
Object::Ref<TextGroup> hello_text_group_; Object::Ref<TextGroup> hello_text_group_;
int reset_count_{}; int reset_count_{};
bool hello_mode_{}; bool hello_mode_{};

View File

@ -821,6 +821,8 @@ class BaseFeatureSet : public FeatureSetNativeComponent,
auto app_active() -> bool const { return app_active_; } auto app_active() -> bool const { return app_active_; }
/// Reset the engine to a default state. App-modes generally call this
/// when activating.
void Reset(); void Reset();
private: private:

View File

@ -14,6 +14,7 @@
#include "ballistica/base/ui/dev_console.h" #include "ballistica/base/ui/dev_console.h"
#include "ballistica/base/ui/ui_delegate.h" #include "ballistica/base/ui/ui_delegate.h"
#include "ballistica/shared/foundation/event_loop.h" #include "ballistica/shared/foundation/event_loop.h"
#include "ballistica/shared/foundation/macros.h"
#include "ballistica/shared/generic/utils.h" #include "ballistica/shared/generic/utils.h"
namespace ballistica::base { namespace ballistica::base {
@ -214,9 +215,9 @@ void UI::ActivatePartyIcon() {
} }
} }
void UI::SetPartyIconNumber(int val) { void UI::SetSquadSizeLabel(int val) {
if (auto* ui_delegate = g_base->ui->delegate()) { if (auto* ui_delegate = g_base->ui->delegate()) {
ui_delegate->SetPartyIconNumber(val); ui_delegate->SetSquadSizeLabel(val);
} }
} }
@ -248,12 +249,6 @@ auto UI::HandleMouseDown(int button, float x, float y, bool double_click)
handled = dev_console_->HandleMouseDown(button, x, y); handled = dev_console_->HandleMouseDown(button, x, y);
} }
// if (!handled) {
// if (auto* ui_delegate = g_base->ui->delegate()) {
// handled = ui_delegate->HandleLegacyRootUIMouseDown(x, y);
// }
// }
if (!handled) { if (!handled) {
handled = SendWidgetMessage(WidgetMessage( handled = SendWidgetMessage(WidgetMessage(
WidgetMessage::Type::kMouseDown, nullptr, x, y, double_click ? 2 : 1)); WidgetMessage::Type::kMouseDown, nullptr, x, y, double_click ? 2 : 1));
@ -280,10 +275,6 @@ void UI::HandleMouseUp(int button, float x, float y) {
} }
} }
} }
// if (auto* ui_delegate = g_base->ui->delegate()) {
// ui_delegate->HandleLegacyRootUIMouseUp(x, y);
// }
} }
auto UI::UIHasDirectKeyboardInput() const -> bool { auto UI::UIHasDirectKeyboardInput() const -> bool {
@ -352,10 +343,9 @@ void UI::SetUIInputDevice(InputDevice* input_device) {
void UI::Reset() { void UI::Reset() {
assert(g_base->InLogicThread()); assert(g_base->InLogicThread());
// Reset and then deactivate any current delegate. // Deactivate any current delegate.
if (auto* ui_delegate = g_base->ui->delegate()) { if (auto* ui_delegate = g_base->ui->delegate()) {
ui_delegate->Reset(); SetUIDelegate(nullptr);
g_base->ui->SetUIDelegate(nullptr);
} }
} }
@ -366,10 +356,6 @@ auto UI::ShouldHighlightWidgets() const -> bool {
return g_base->input->have_non_touch_inputs() && MainMenuVisible(); return g_base->input->have_non_touch_inputs() && MainMenuVisible();
} }
auto UI::ShouldShowButtonShortcuts() const -> bool {
return g_base->input->have_non_touch_inputs();
}
auto UI::SendWidgetMessage(const WidgetMessage& m) -> bool { auto UI::SendWidgetMessage(const WidgetMessage& m) -> bool {
OperationContext operation_context; OperationContext operation_context;
@ -595,8 +581,17 @@ void UI::ShowURL(const std::string& url) {
void UI::SetUIDelegate(base::UIDelegateInterface* delegate) { void UI::SetUIDelegate(base::UIDelegateInterface* delegate) {
assert(g_base->InLogicThread()); assert(g_base->InLogicThread());
if (delegate == delegate_) { // We should always be either setting or clearing delegate; never setting
return; // redundantly.
if (delegate_) {
if (delegate) {
FatalError(
"Can\'t set UI Delegate when one is already set. Reset base first.");
}
} else {
if (!delegate) {
FatalError("Can\'t clear UI Delegate when already cleared.");
}
} }
try { try {
@ -610,8 +605,8 @@ void UI::SetUIDelegate(base::UIDelegateInterface* delegate) {
delegate_->OnActivate(); delegate_->OnActivate();
// Inform them that a few things changed, since they might have since // Inform them that a few things changed, since they might have since
// the last time they were active (these callbacks only go to the *active* // the last time they were active (these callbacks only go to the
// ui delegate). // *active* ui delegate).
delegate_->DoApplyAppConfig(); delegate_->DoApplyAppConfig();
delegate_->OnScreenSizeChange(); delegate_->OnScreenSizeChange();
delegate_->OnLanguageChange(); delegate_->OnLanguageChange();
@ -629,8 +624,8 @@ void UI::PushDevConsolePrintCall(const std::string& msg) {
if (g_core->HeadlessMode()) { if (g_core->HeadlessMode()) {
return; return;
} }
// If our event loop AND console are up and running, ship it off to // If our event loop AND console are up and running, ship it off to be
// be printed. Otherwise store it for the console to grab when it's ready. // printed. Otherwise store it for the console to grab when it's ready.
if (auto* event_loop = g_base->logic->event_loop()) { if (auto* event_loop = g_base->logic->event_loop()) {
if (dev_console_ != nullptr) { if (dev_console_ != nullptr) {
event_loop->PushCall([this, msg] { dev_console_->Print(msg); }); event_loop->PushCall([this, msg] { dev_console_->Print(msg); });
@ -662,9 +657,11 @@ void UI::PushUIOperationRunnable(Runnable* runnable) {
if (operation_context_ != nullptr) { if (operation_context_ != nullptr) {
// Once we're finishing the context, nothing else should be adding calls // Once we're finishing the context, nothing else should be adding calls
// to it. UPDATE - this is actually ok. Things like widget-select // to it.
// commands can happen as part of user callbacks which themselves add //
// additional callbacks to the current ui-operation. // UPDATE - this is actually ok. Things like widget-select commands can
// happen as part of user callbacks which themselves add additional
// callbacks to the current ui-operation.
// //
// if (operation_context_->ran_finish()) { // if (operation_context_->ran_finish()) {
// auto trace = g_core->platform->GetNativeStackTrace(); // auto trace = g_core->platform->GetNativeStackTrace();

View File

@ -42,8 +42,8 @@ class UI {
void LanguageChanged(); void LanguageChanged();
/// Reset all UI to a default state. Generally should be called when /// Reset all UI to a default state. Note that this includes deactivating
/// switching app-modes or when resetting things within an app mode. /// any current UI Delegate.
void Reset(); void Reset();
void SetUIDelegate(base::UIDelegateInterface* delegate); void SetUIDelegate(base::UIDelegateInterface* delegate);
@ -59,7 +59,8 @@ class UI {
auto PartyIconVisible() -> bool; auto PartyIconVisible() -> bool;
auto PartyWindowOpen() -> bool; auto PartyWindowOpen() -> bool;
void ActivatePartyIcon(); void ActivatePartyIcon();
void SetPartyIconNumber(int val);
void SetSquadSizeLabel(int val);
auto HandleMouseDown(int button, float x, float y, bool double_click) -> bool; auto HandleMouseDown(int button, float x, float y, bool double_click) -> bool;
void HandleMouseUp(int button, float x, float y); void HandleMouseUp(int button, float x, float y);
@ -109,10 +110,6 @@ class UI {
/// present. /// present.
auto ShouldHighlightWidgets() const -> bool; auto ShouldHighlightWidgets() const -> bool;
/// Return whether currently selected widget should show button shortcuts.
/// These generally only get shown if a joystick of some form is present.
auto ShouldShowButtonShortcuts() const -> bool;
/// Get overall ui scale for the app. /// Get overall ui scale for the app.
auto scale() const { return scale_; } auto scale() const { return scale_; }
@ -140,9 +137,9 @@ class UI {
auto ran_finish() const { return ran_finish_; } auto ran_finish() const { return ran_finish_; }
private: private:
bool ran_finish_{};
OperationContext* parent_{};
std::vector<Runnable*> runnables_; std::vector<Runnable*> runnables_;
OperationContext* parent_{};
bool ran_finish_{};
}; };
private: private:
@ -151,18 +148,18 @@ class UI {
auto InDevConsoleButton_(float x, float y) const -> bool; auto InDevConsoleButton_(float x, float y) const -> bool;
void DrawDevConsoleButton_(FrameDef* frame_def); void DrawDevConsoleButton_(FrameDef* frame_def);
Object::Ref<TextGroup> dev_console_button_txt_;
Object::WeakRef<InputDevice> ui_input_device_;
OperationContext* operation_context_{}; OperationContext* operation_context_{};
base::UIDelegateInterface* delegate_{}; base::UIDelegateInterface* delegate_{};
DevConsole* dev_console_{}; DevConsole* dev_console_{};
std::string dev_console_startup_messages_; std::string dev_console_startup_messages_;
Object::WeakRef<InputDevice> ui_input_device_;
millisecs_t last_input_device_use_time_{}; millisecs_t last_input_device_use_time_{};
millisecs_t last_widget_input_reject_err_sound_time_{}; millisecs_t last_widget_input_reject_err_sound_time_{};
UIScale scale_{UIScale::kLarge}; UIScale scale_{UIScale::kLarge};
bool force_scale_{}; bool force_scale_{};
bool show_dev_console_button_{}; bool show_dev_console_button_{};
bool dev_console_button_pressed_{}; bool dev_console_button_pressed_{};
Object::Ref<TextGroup> dev_console_button_txt_;
}; };
} // namespace ballistica::base } // namespace ballistica::base

View File

@ -16,7 +16,7 @@ namespace ballistica::base {
class UIDelegateInterface { class UIDelegateInterface {
public: public:
virtual void Reset() = 0; // virtual void Reset() = 0;
/// Called when this delegate is becoming the active one. /// Called when this delegate is becoming the active one.
virtual void OnActivate() = 0; virtual void OnActivate() = 0;
@ -40,7 +40,7 @@ class UIDelegateInterface {
virtual auto PartyWindowOpen() -> bool = 0; virtual auto PartyWindowOpen() -> bool = 0;
virtual auto GetRootWidget() -> ui_v1::Widget* = 0; virtual auto GetRootWidget() -> ui_v1::Widget* = 0;
virtual auto SendWidgetMessage(const WidgetMessage& m) -> int = 0; virtual auto SendWidgetMessage(const WidgetMessage& m) -> int = 0;
virtual void SetPartyIconNumber(int num) = 0; virtual void SetSquadSizeLabel(int num) = 0;
/// Should return true if this app mode can confirm quitting the app. /// Should return true if this app mode can confirm quitting the app.
virtual auto HasQuitConfirmDialog() -> bool = 0; virtual auto HasQuitConfirmDialog() -> bool = 0;

View File

@ -89,8 +89,8 @@ void ClassicAppMode::OnActivate() {
Reset_(); Reset_();
// To set initial states, explicitly fire some of our 'On-Foo-Changed' // Explicitly fire some of our 'On-Foo-Changed' callbacks to set initial
// callbacks. // states.
DoApplyAppConfig(); DoApplyAppConfig();
LanguageChanged(); LanguageChanged();
OnGameRosterChanged_(); OnGameRosterChanged_();
@ -453,7 +453,7 @@ void ClassicAppMode::SetGameRoster(cJSON* r) {
void ClassicAppMode::OnGameRosterChanged_() { void ClassicAppMode::OnGameRosterChanged_() {
assert(g_base->InLogicThread()); assert(g_base->InLogicThread());
g_base->ui->SetPartyIconNumber(GetPartySize()); g_base->ui->SetSquadSizeLabel(GetPartySize());
} }
auto ClassicAppMode::GetPartySize() const -> int { auto ClassicAppMode::GetPartySize() const -> int {

View File

@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
namespace ballistica { namespace ballistica {
// These are set automatically via script; don't modify them here. // These are set automatically via script; don't modify them here.
const int kEngineBuildNumber = 22021; const int kEngineBuildNumber = 22024;
const char* kEngineVersion = "1.7.37"; const char* kEngineVersion = "1.7.37";
const int kEngineApiVersion = 9; const int kEngineApiVersion = 9;

View File

@ -79,8 +79,16 @@ bool UIV1FeatureSet::PartyIconVisible() {
// Currently this is always visible. // Currently this is always visible.
return true; return true;
} }
void UIV1FeatureSet::SetAccountState(bool signed_in, const std::string& name) {
// Store the value and plug it in if we've got a live widget.
account_signed_in_ = signed_in;
account_name_ = name;
if (auto* r = root_widget()) {
root_widget_->SetAccountState(signed_in, name);
}
}
void UIV1FeatureSet::SetPartyIconNumber(int num) { void UIV1FeatureSet::SetSquadSizeLabel(int num) {
// Store the value and plug it in if we've got a live widget. // Store the value and plug it in if we've got a live widget.
party_icon_number_ = num; party_icon_number_ = num;
if (auto* r = root_widget()) { if (auto* r = root_widget()) {
@ -147,12 +155,8 @@ void UIV1FeatureSet::Draw(base::FrameDef* frame_def) {
} }
} }
void UIV1FeatureSet::OnActivate() { assert(g_base->InLogicThread()); } void UIV1FeatureSet::OnActivate() {
void UIV1FeatureSet::OnDeactivate() { assert(g_base->InLogicThread()); } assert(g_base->InLogicThread());
void UIV1FeatureSet::Reset() {
root_widget_.Clear();
screen_root_widget_.Clear();
// (Re)create our screen-root widget. // (Re)create our screen-root widget.
auto sw(Object::New<StackWidget>()); auto sw(Object::New<StackWidget>());
@ -181,10 +185,23 @@ void UIV1FeatureSet::Reset() {
// Plug in current values for everything. // Plug in current values for everything.
rw->SetSquadSizeLabel(party_icon_number_); rw->SetSquadSizeLabel(party_icon_number_);
rw->SetAccountState(account_signed_in_, account_name_);
sw->GlobalSelect(); sw->GlobalSelect();
} }
void UIV1FeatureSet::OnDeactivate() {
assert(g_base->InLogicThread());
root_widget_.Clear();
screen_root_widget_.Clear();
}
// void UIV1FeatureSet::Reset() {
// printf("UIV1::Reset()\n");
// }
void UIV1FeatureSet::AddWidget(Widget* w, ContainerWidget* parent) { void UIV1FeatureSet::AddWidget(Widget* w, ContainerWidget* parent) {
assert(g_base->InLogicThread()); assert(g_base->InLogicThread());

View File

@ -87,7 +87,9 @@ class UIV1FeatureSet : public FeatureSetNativeComponent,
auto PartyIconVisible() -> bool override; auto PartyIconVisible() -> bool override;
void ActivatePartyIcon() override; void ActivatePartyIcon() override;
void Draw(base::FrameDef* frame_def) override; void Draw(base::FrameDef* frame_def) override;
void SetPartyIconNumber(int num) override;
void SetSquadSizeLabel(int num) override;
void SetAccountState(bool signed_in, const std::string& name);
UIV1Python* const python; UIV1Python* const python;
@ -109,7 +111,7 @@ class UIV1FeatureSet : public FeatureSetNativeComponent,
// Return the absolute root widget; this includes persistent UI bits such // Return the absolute root widget; this includes persistent UI bits such
// as the top/bottom bars // as the top/bottom bars
auto root_widget() -> ui_v1::RootWidget* { return root_widget_.Get(); } auto root_widget() -> ui_v1::RootWidget* { return root_widget_.Get(); }
void Reset() override; // void Reset() override;
// Add a widget to a container. If a parent is provided, the widget is // Add a widget to a container. If a parent is provided, the widget is
// added to it; otherwise it is added to the root widget. // added to it; otherwise it is added to the root widget.
@ -142,6 +144,8 @@ class UIV1FeatureSet : public FeatureSetNativeComponent,
int party_icon_number_{}; int party_icon_number_{};
bool always_use_internal_on_screen_keyboard_{}; bool always_use_internal_on_screen_keyboard_{};
bool party_window_open_{}; bool party_window_open_{};
bool account_signed_in_{};
std::string account_name_{};
}; };
} // namespace ballistica::ui_v1 } // namespace ballistica::ui_v1

View File

@ -494,7 +494,7 @@ void RootWidget::Setup() {
td.color_g = 0.8f; td.color_g = 0.8f;
td.color_b = 0.8f; td.color_b = 0.8f;
td.shadow = 1.0f; td.shadow = 1.0f;
AddText_(td); account_name_text_ = AddText_(td);
} }
} }
AddMeter_(MeterType::kLevel, 0.0f, 1.0f, 1.0f, 1.0f, false, "456/1000"); AddMeter_(MeterType::kLevel, 0.0f, 1.0f, 1.0f, 1.0f, false, "456/1000");
@ -1262,6 +1262,21 @@ auto RootWidget::GetSpecialWidget(const std::string& s) const -> Widget* {
return nullptr; return nullptr;
} }
void RootWidget::SetAccountState(bool signed_in, const std::string& name) {
if (account_name_text_) {
auto* w{account_name_text_->widget.Get()};
assert(w);
if (signed_in) {
w->SetText(name);
w->set_color(0.0f, 1.0f, 0.0f, 1.0f);
} else {
w->SetText("NOT SIGNED IN");
w->set_color(1.0f, 0.2f, 0.2f, 1.0f);
}
}
}
void RootWidget::SetSquadSizeLabel(int val) { void RootWidget::SetSquadSizeLabel(int val) {
if (squad_size_text_) { if (squad_size_text_) {
auto* w{squad_size_text_->widget.Get()}; auto* w{squad_size_text_->widget.Get()};

View File

@ -36,6 +36,7 @@ class RootWidget : public ContainerWidget {
void UpdateLayout() override; void UpdateLayout() override;
void SetSquadSizeLabel(int val); void SetSquadSizeLabel(int val);
void SetAccountState(bool signed_in, const std::string& name);
private: private:
struct ButtonDef; struct ButtonDef;
@ -84,6 +85,7 @@ class RootWidget : public ContainerWidget {
Button* level_meter_button_{}; Button* level_meter_button_{};
Button* trophy_icon_{}; Button* trophy_icon_{};
Text* squad_size_text_{}; Text* squad_size_text_{};
Text* account_name_text_{};
}; };
} // namespace ballistica::ui_v1 } // namespace ballistica::ui_v1