more ui polishing

This commit is contained in:
Eric Froemling 2024-12-28 15:25:56 -08:00
parent 2a69a937d0
commit 68be5d3b31
No known key found for this signature in database
38 changed files with 438 additions and 1083 deletions

48
.efrocachemap generated
View File

@ -4103,22 +4103,22 @@
"build/assets/windows/Win32/ucrtbased.dll": "bfd1180c269d3950b76f35a63655e9e1",
"build/assets/windows/Win32/vc_redist.x86.exe": "15a5f1f876503885adbdf5b3989b3718",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "831d5f904fef843b966d8e7660c8c310",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "2cbfc93f4523729dee68b1db2cf09c10",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "64a2a607a99a8a89df83e95441bc9361",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "a0fac95c32f3b78e268ce11634728436",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "f706f7873d2b6954b08fe481b1e13704",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "9f9becc6d5ce6960210c65fc1004c8d6",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "fceb974dfa1ed9e6eed0b28658d80d6e",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "ed386560c3fc4de94119b47eda30e723",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "780ab5c3146085919b070198aa752f0b",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "c14f0240b1fd17be3f52823e37e2c2af",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "b630856a0a5153a2766772d4c6d6657f",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "ebdc492db21008db802180853df82f25",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "7220f0036f22a8107110b1c02ebbdc6e",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "167a2273b849e53d77b0f03814c7c5b0",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "628ac9a71589d60aa1db1cede931f4a2",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "d1091a830960c56677c1a1141a543ce8",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "aaaf15a8a3968a5f9c99d242f5384857",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "9864117215a88d0434d153e3840323fc",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "6bfaafce85f68dbd631a6bf5d71be6c7",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "1b3a9671e0ec25d4d4f4312939e45f2a",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "85facaa825957bfdb3971220033b77c8",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "3ac89f516eca7a337b351aad780e5fec",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "6b7fa3e1615f004d7db2624174406baf",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "3277dcd7907ae9cdb9d71a6ab55203eb",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "b88dc886212e085e2c3f2c60497b6e9e",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "0ca8ee17ea6c20b955f09e06586dd03e",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "d2e0005fbeb6cfb7029d2587befbd703",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "4badd0d286f63a16886876c161c562be",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "1a7c38b236a5fe16c685c15527f658bd",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "2f4f2de5d326cceed8bef59f7d53eaa9",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "9e555dd5536b24e2f369261022e6301b",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "0875d9be5d271563bee284cbe052aa87",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "33a0ae6f1ea5a0b0c60055ce01478488",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "aad882eaf2230b89973e2cf4f13c9759",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "33a0ae6f1ea5a0b0c60055ce01478488",
@ -4131,14 +4131,14 @@
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "ae4e3f563892f6b9311c4b7284f28c11",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "01dab862a43d9e7c4ee4e49212442d42",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "ae4e3f563892f6b9311c4b7284f28c11",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "e6486a7303980b5cdb1b3c66039d6943",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "99daefc8faf688a6d981c814047ea7c9",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "c3c45e8b50ebf18228b420740230ae4e",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "86cca50b63553ed472aa26f24e377676",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "f626c31a39d7da50d5b7fd9651c88b19",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "d8befd638527cc591c18dd805999fc1b",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "577626c543f72d9d9cdd08bb2278718f",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "e190ceb6cd33b3281eaf52c40e5b2c13",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "4db5845cd1089bf9591c52f4feca4455",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "38ab6b8b4bfceae47d27c218556d770f",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "8764576e60e3fcd114bdd910736fc972",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "95f6af857196b71243ab71fd6ddc0da5",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "baa253ffc6a9d7be71b64c75b8e17498",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "473ac21b2510149bd46849f21d5f3420",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "1cf5b56cfa597ad908caa117247a031f",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "f51e076eede86d41e3853673dcfa5ea6",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "794d258d59fd17a61752843a9a0551ad",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "06042d31df0ff9af96b99477162e2a91",

View File

@ -1,4 +1,4 @@
### 1.7.37 (build 22146, api 9, 2024-12-25)
### 1.7.37 (build 22147, api 9, 2024-12-28)
- 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.

View File

@ -420,11 +420,13 @@
"ba_data/python/bauiv1lib/account/__pycache__/__init__.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/account/__pycache__/link.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/account/__pycache__/settings.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/account/__pycache__/signin.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/account/__pycache__/unlink.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/account/__pycache__/v2proxy.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/account/__pycache__/viewer.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/account/link.py",
"ba_data/python/bauiv1lib/account/settings.py",
"ba_data/python/bauiv1lib/account/signin.py",
"ba_data/python/bauiv1lib/account/unlink.py",
"ba_data/python/bauiv1lib/account/v2proxy.py",
"ba_data/python/bauiv1lib/account/viewer.py",
@ -476,9 +478,7 @@
"ba_data/python/bauiv1lib/kiosk.py",
"ba_data/python/bauiv1lib/league/__init__.py",
"ba_data/python/bauiv1lib/league/__pycache__/__init__.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/league/__pycache__/rankbutton.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/league/__pycache__/rankwindow.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/league/rankbutton.py",
"ba_data/python/bauiv1lib/league/rankwindow.py",
"ba_data/python/bauiv1lib/mainmenu.py",
"ba_data/python/bauiv1lib/party.py",
@ -570,10 +570,8 @@
"ba_data/python/bauiv1lib/store/__init__.py",
"ba_data/python/bauiv1lib/store/__pycache__/__init__.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/store/__pycache__/browser.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/store/__pycache__/button.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/store/__pycache__/item.cpython-312.opt-1.pyc",
"ba_data/python/bauiv1lib/store/browser.py",
"ba_data/python/bauiv1lib/store/button.py",
"ba_data/python/bauiv1lib/store/item.py",
"ba_data/python/bauiv1lib/tabs.py",
"ba_data/python/bauiv1lib/teamnamescolors.py",

View File

@ -341,6 +341,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/__init__.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/link.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/settings.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/signin.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/unlink.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/v2proxy.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/viewer.py \
@ -378,7 +379,6 @@ SCRIPT_TARGETS_PY_PUBLIC = \
$(BUILD_DIR)/ba_data/python/bauiv1lib/keyboard/englishkeyboard.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/kiosk.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/league/__init__.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/league/rankbutton.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/league/rankwindow.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/mainmenu.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/party.py \
@ -432,7 +432,6 @@ SCRIPT_TARGETS_PY_PUBLIC = \
$(BUILD_DIR)/ba_data/python/bauiv1lib/soundtrack/macmusicapp.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/store/__init__.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/store/browser.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/store/button.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/store/item.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/tabs.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/teamnamescolors.py \
@ -622,6 +621,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/__pycache__/__init__.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/__pycache__/link.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/__pycache__/settings.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/__pycache__/signin.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/__pycache__/unlink.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/__pycache__/v2proxy.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/account/__pycache__/viewer.cpython-312.opt-1.pyc \
@ -659,7 +659,6 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
$(BUILD_DIR)/ba_data/python/bauiv1lib/keyboard/__pycache__/englishkeyboard.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/kiosk.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/league/__pycache__/__init__.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/league/__pycache__/rankbutton.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/league/__pycache__/rankwindow.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/mainmenu.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/party.cpython-312.opt-1.pyc \
@ -713,7 +712,6 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
$(BUILD_DIR)/ba_data/python/bauiv1lib/soundtrack/__pycache__/macmusicapp.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/store/__pycache__/__init__.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/store/__pycache__/browser.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/store/__pycache__/button.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/store/__pycache__/item.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/tabs.cpython-312.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/teamnamescolors.cpython-312.opt-1.pyc \

View File

@ -175,7 +175,7 @@ from babase._general import (
get_type_name,
)
from babase._language import Lstr, LanguageSubsystem
from babase._logging import balog, lifecyclelog
from babase._logging import balog, applog, lifecyclelog
from babase._login import LoginAdapter, LoginInfo
from babase._mgen.enums import (
@ -214,6 +214,7 @@ __all__ = [
'AppIntentExec',
'AppMode',
'app_instance_uuid',
'applog',
'appname',
'appnameupper',
'AppModeSelector',

View File

@ -25,7 +25,7 @@ from babase._appintent import AppIntentDefault, AppIntentExec
from babase._stringedit import StringEditSubsystem
from babase._devconsole import DevConsoleSubsystem
from babase._appconfig import AppConfig
from babase._logging import lifecyclelog
from babase._logging import lifecyclelog, applog
if TYPE_CHECKING:
import asyncio
@ -909,6 +909,7 @@ class App:
# Entering shutdown state:
if self.state is not self.State.SHUTTING_DOWN:
self.state = self.State.SHUTTING_DOWN
applog.info('Shutting down...')
lifecyclelog.info('app-state is now %s', self.state.name)
self._on_shutting_down()

View File

@ -8,4 +8,5 @@ import logging
# Our standard set of loggers.
balog = logging.getLogger('ba')
applog = logging.getLogger('ba.app')
lifecyclelog = logging.getLogger('ba.lifecycle')

View File

@ -11,6 +11,8 @@ from typing import TYPE_CHECKING, override
from bacommon.app import AppExperience
import babase
import bauiv1
from bauiv1lib.connectivity import wait_for_connectivity
from bauiv1lib.account.signin import show_sign_in_prompt
import _baclassic
@ -429,17 +431,26 @@ class ClassicAppMode(babase.AppMode):
def _root_ui_achievements_press(self) -> None:
from bauiv1lib.achievements import AchievementsWindow
self._auxiliary_window_nav(
win_type=AchievementsWindow,
win_create_call=lambda: AchievementsWindow(
origin_widget=bauiv1.get_special_widget('achievements_button')
),
if not self._ensure_signed_in_v1():
return
wait_for_connectivity(
on_connected=lambda: self._auxiliary_window_nav(
win_type=AchievementsWindow,
win_create_call=lambda: AchievementsWindow(
origin_widget=bauiv1.get_special_widget(
'achievements_button'
)
),
)
)
def _root_ui_inbox_press(self) -> None:
from bauiv1lib.connectivity import wait_for_connectivity
from bauiv1lib.inbox import InboxWindow
if not self._ensure_signed_in():
return
wait_for_connectivity(
on_connected=lambda: self._auxiliary_window_nav(
win_type=InboxWindow,
@ -452,11 +463,16 @@ class ClassicAppMode(babase.AppMode):
def _root_ui_store_press(self) -> None:
from bauiv1lib.store.browser import StoreBrowserWindow
self._auxiliary_window_nav(
win_type=StoreBrowserWindow,
win_create_call=lambda: StoreBrowserWindow(
origin_widget=bauiv1.get_special_widget('store_button')
),
if not self._ensure_signed_in_v1():
return
wait_for_connectivity(
on_connected=lambda: self._auxiliary_window_nav(
win_type=StoreBrowserWindow,
win_create_call=lambda: StoreBrowserWindow(
origin_widget=bauiv1.get_special_widget('store_button')
),
)
)
def _root_ui_tickets_meter_press(self) -> None:
@ -474,13 +490,9 @@ class ClassicAppMode(babase.AppMode):
)
def _root_ui_trophy_meter_press(self) -> None:
from bauiv1lib.account import show_sign_in_prompt
from bauiv1lib.league.rankwindow import LeagueRankWindow
plus = bauiv1.app.plus
assert plus is not None
if plus.get_v1_account_state() != 'signed_in':
show_sign_in_prompt()
if not self._ensure_signed_in_v1():
return
self._auxiliary_window_nav(
@ -500,6 +512,9 @@ class ClassicAppMode(babase.AppMode):
def _root_ui_inventory_press(self) -> None:
from bauiv1lib.inventory import InventoryWindow
if not self._ensure_signed_in_v1():
return
self._auxiliary_window_nav(
win_type=InventoryWindow,
win_create_call=lambda: InventoryWindow(
@ -507,9 +522,36 @@ class ClassicAppMode(babase.AppMode):
),
)
def _ensure_signed_in(self) -> bool:
"""Make sure we're signed in (requiring modern v2 accounts)."""
plus = bauiv1.app.plus
if plus is None:
bauiv1.screenmessage('This requires plus.', color=(1, 0, 0))
bauiv1.getsound('error').play()
return False
if plus.accounts.primary is None:
show_sign_in_prompt()
return False
return True
def _ensure_signed_in_v1(self) -> bool:
"""Make sure we're signed in (allowing legacy v1-only accounts)."""
plus = bauiv1.app.plus
if plus is None:
bauiv1.screenmessage('This requires plus.', color=(1, 0, 0))
bauiv1.getsound('error').play()
return False
if plus.get_v1_account_state() != 'signed_in':
show_sign_in_prompt()
return False
return True
def _root_ui_get_tokens_press(self) -> None:
from bauiv1lib.gettokens import GetTokensWindow
if not self._ensure_signed_in():
return
self._auxiliary_window_nav(
win_type=GetTokensWindow,
win_create_call=lambda: GetTokensWindow(
@ -524,7 +566,6 @@ class ClassicAppMode(babase.AppMode):
ChestWindow2,
ChestWindow3,
)
from bauiv1lib.connectivity import wait_for_connectivity
widgetid: Literal[
'chest_0_button',

View File

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

View File

@ -19,9 +19,6 @@ from bascenev1lib.actor.zoomtext import ZoomText
if TYPE_CHECKING:
from typing import Any, Sequence
from bauiv1lib.store.button import StoreButton
from bauiv1lib.league.rankbutton import LeagueRankButton
class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
"""Score screen showing the results of a cooperative game."""
@ -105,10 +102,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
# Ui bits.
self._corner_button_offs: tuple[float, float] | None = None
self._league_rank_button: LeagueRankButton | None = None
self._store_button_instance: StoreButton | None = None
self._restart_button: bui.Widget | None = None
self._update_corner_button_positions_timer: bui.AppTimer | None = None
self._next_level_error: bs.Actor | None = None
# Score/gameplay bits.
@ -207,11 +201,6 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
)
def _ui_menu(self) -> None:
# from bauiv1lib import specialoffer
# if specialoffer.show_offer():
# return
bui.containerwidget(edit=self._root_ui, transition='out_left')
with self.context:
bs.timer(0.1, bs.Call(bs.WeakCall(self.session.end)))
@ -219,11 +208,6 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
def _ui_restart(self) -> None:
from bauiv1lib.tournamententry import TournamentEntryWindow
# from bauiv1lib import specialoffer
# if specialoffer.show_offer():
# return
# If we're in a tournament and it looks like there's no time left,
# disallow.
if self.session.tournament_id is not None:
@ -270,10 +254,6 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
self.end({'outcome': 'restart'})
def _ui_next(self) -> None:
# from bauiv1lib.specialoffer import show_offer
# if show_offer():
# return
# If we didn't just complete this level but are choosing to play the
# next one, set it as current (this won't happen otherwise).
@ -333,6 +313,12 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
)
def _should_show_worlds_best_button(self) -> bool:
# Old high score lists webpage for tourneys seems broken
# (looking at meteor shower at least).
if self.session.tournament_id is not None:
return False
# Link is too complicated to display with no browser.
return bui.is_browser_likely_available()
@ -349,8 +335,8 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
def show_ui(self) -> None:
"""Show the UI for restarting, playing the next Level, etc."""
# pylint: disable=too-many-locals
from bauiv1lib.store.button import StoreButton
from bauiv1lib.league.rankbutton import LeagueRankButton
# pylint: disable=too-many-statements
# pylint: disable=too-many-branches
assert bui.app.classic is not None
@ -420,38 +406,83 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
if not show_next_button:
h_offs += 70
menu_button = bui.buttonwidget(
parent=rootc,
autoselect=True,
position=(h_offs - 130 - 60, v_offs),
size=(110, 85),
label='',
on_activate_call=bui.WeakCall(self._ui_menu),
)
bui.imagewidget(
parent=rootc,
draw_controller=menu_button,
position=(h_offs - 130 - 60 + 22, v_offs + 14),
size=(60, 60),
texture=self._menu_icon_texture,
opacity=0.8,
)
self._restart_button = restart_button = bui.buttonwidget(
parent=rootc,
autoselect=True,
position=(h_offs - 60, v_offs),
size=(110, 85),
label='',
on_activate_call=bui.WeakCall(self._ui_restart),
)
bui.imagewidget(
parent=rootc,
draw_controller=restart_button,
position=(h_offs - 60 + 19, v_offs + 7),
size=(70, 70),
texture=self._replay_icon_texture,
opacity=0.8,
)
# Due to virtual-bounds changes, have to squish buttons a bit to
# avoid overlapping with tips at bottom. Could look nicer to
# rework things in the middle to get more space, but would
# rather not touch this old code more than necessary.
small_buttons = True
if small_buttons:
menu_button = bui.buttonwidget(
parent=rootc,
autoselect=True,
position=(h_offs - 130 - 45, v_offs + 40),
size=(100, 50),
label='',
button_type='square',
on_activate_call=bui.WeakCall(self._ui_menu),
)
bui.imagewidget(
parent=rootc,
draw_controller=menu_button,
position=(h_offs - 130 - 60 + 43, v_offs + 43),
size=(45, 45),
texture=self._menu_icon_texture,
opacity=0.8,
)
else:
menu_button = bui.buttonwidget(
parent=rootc,
autoselect=True,
position=(h_offs - 130 - 60, v_offs),
size=(110, 85),
label='',
on_activate_call=bui.WeakCall(self._ui_menu),
)
bui.imagewidget(
parent=rootc,
draw_controller=menu_button,
position=(h_offs - 130 - 60 + 22, v_offs + 14),
size=(60, 60),
texture=self._menu_icon_texture,
opacity=0.8,
)
if small_buttons:
self._restart_button = restart_button = bui.buttonwidget(
parent=rootc,
autoselect=True,
position=(h_offs - 60, v_offs + 40),
size=(100, 50),
label='',
button_type='square',
on_activate_call=bui.WeakCall(self._ui_restart),
)
bui.imagewidget(
parent=rootc,
draw_controller=restart_button,
position=(h_offs - 60 + 25, v_offs + 42),
size=(47, 47),
texture=self._replay_icon_texture,
opacity=0.8,
)
else:
self._restart_button = restart_button = bui.buttonwidget(
parent=rootc,
autoselect=True,
position=(h_offs - 60, v_offs),
size=(110, 85),
label='',
on_activate_call=bui.WeakCall(self._ui_restart),
)
bui.imagewidget(
parent=rootc,
draw_controller=restart_button,
position=(h_offs - 60 + 19, v_offs + 7),
size=(70, 70),
texture=self._replay_icon_texture,
opacity=0.8,
)
next_button: bui.Widget | None = None
@ -468,24 +499,46 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
button_sound = False
image_opacity = 0.2
color = (0.3, 0.3, 0.3)
next_button = bui.buttonwidget(
parent=rootc,
autoselect=True,
position=(h_offs + 130 - 60, v_offs),
size=(110, 85),
label='',
on_activate_call=call,
color=color,
enable_sound=button_sound,
)
bui.imagewidget(
parent=rootc,
draw_controller=next_button,
position=(h_offs + 130 - 60 + 12, v_offs + 5),
size=(80, 80),
texture=self._next_level_icon_texture,
opacity=image_opacity,
)
if small_buttons:
next_button = bui.buttonwidget(
parent=rootc,
autoselect=True,
position=(h_offs + 130 - 75, v_offs + 40),
size=(100, 50),
label='',
button_type='square',
on_activate_call=call,
color=color,
enable_sound=button_sound,
)
bui.imagewidget(
parent=rootc,
draw_controller=next_button,
position=(h_offs + 130 - 60 + 12, v_offs + 40),
size=(50, 50),
texture=self._next_level_icon_texture,
opacity=image_opacity,
)
else:
next_button = bui.buttonwidget(
parent=rootc,
autoselect=True,
position=(h_offs + 130 - 60, v_offs),
size=(110, 85),
label='',
on_activate_call=call,
color=color,
enable_sound=button_sound,
)
bui.imagewidget(
parent=rootc,
draw_controller=next_button,
position=(h_offs + 130 - 60 + 12, v_offs + 5),
size=(80, 80),
texture=self._next_level_icon_texture,
opacity=image_opacity,
)
x_offs_extra = 0 if show_next_button else -100
self._corner_button_offs = (
@ -493,33 +546,6 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
v_offs + 519.0,
)
if env.demo or env.arcade:
self._league_rank_button = None
self._store_button_instance = None
else:
self._league_rank_button = LeagueRankButton(
parent=rootc,
position=(h_offs + 300 + x_offs_extra, v_offs + 519),
size=(100, 60),
scale=0.9,
color=(0.4, 0.4, 0.9),
textcolor=(0.9, 0.9, 2.0),
transition_delay=0.0,
smooth_update_delay=5.0,
)
self._store_button_instance = StoreButton(
parent=rootc,
position=(h_offs + 400 + x_offs_extra, v_offs + 519),
show_tickets=True,
sale_scale=0.85,
size=(100, 60),
scale=0.9,
button_type='square',
color=(0.35, 0.25, 0.45),
textcolor=(0.9, 0.7, 1.0),
transition_delay=0.0,
)
bui.containerwidget(
edit=rootc,
selected_child=(
@ -530,25 +556,12 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
on_cancel_call=menu_button.activate,
)
self._update_corner_button_positions()
self._update_corner_button_positions_timer = bui.AppTimer(
1.0, bui.WeakCall(self._update_corner_button_positions), repeat=True
)
def _update_corner_button_positions(self) -> None:
assert self._corner_button_offs is not None
pos_x = self._corner_button_offs[0]
pos_y = self._corner_button_offs[1]
if self._league_rank_button is not None:
self._league_rank_button.set_position((pos_x, pos_y))
if self._store_button_instance is not None:
self._store_button_instance.set_position((pos_x + 100, pos_y))
def _player_press(self) -> None:
# (Only for headless builds).
# If this activity is a good 'end point', ask server-mode just once if
# it wants to do anything special like switch sessions or kill the app.
# If this activity is a good 'end point', ask server-mode just
# once if it wants to do anything special like switch sessions
# or kill the app.
if (
self._allow_server_transition
and bs.app.classic is not None
@ -715,7 +728,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
color=(0.5, 1, 0.5, 1),
h_align='center',
scale=0.4,
position=(0, 255),
position=(0, 260),
jitter=1.0,
).autoretain()
Text(

View File

@ -162,40 +162,6 @@ class UIV1AppSubsystem(babase.AppSubsystem):
# checks.
self.upkeeptimer = babase.AppTimer(2.6543, ui_upkeep, repeat=True)
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
)
if back_state is None:
raise RuntimeError(
f'Main window {main_window} provides no back-state;'
f' cannot use auto-back.'
)
# Valid states should have values here.
assert back_state.is_top_level is not None
assert back_state.is_auxiliary is not None
assert back_state.window_type is not None
backwin = back_state.create_window(transition='in_left')
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."""
return self._main_window()
@ -211,11 +177,14 @@ class UIV1AppSubsystem(babase.AppSubsystem):
back_state: MainWindowState | None = None,
suppress_warning: bool = False,
) -> None:
"""Set the current 'main' window, replacing any existing.
"""Set the current 'main' window.
Generally this should not be called directly; The high level
MainWindow methods main_window_replace() and main_window_back()
should be used when possible for navigation.
should be used whenever possible to implement navigation.
The caller is responsible for cleaning up any previous main
window.
"""
# pylint: disable=too-many-locals
# pylint: disable=too-many-branches

View File

@ -46,7 +46,14 @@ class Window:
class MainWindow(Window):
"""A special window that can be used as a main window."""
"""A special type of window that can be set as 'main'.
The UI system has at most one main window at any given time.
MainWindows support high level functionality such as saving and
restoring states, allowing them to be automatically recreated when
navigating back from other locations or when something like ui-scale
changes.
"""
def __init__(
self,
@ -146,11 +153,33 @@ class MainWindow(Window):
if not self.main_window_has_control():
return
uiv1 = babase.app.ui_v1
# Get the 'back' window coming in.
if not self.main_window_is_top_level:
# Get the 'back' window coming in.
babase.app.ui_v1.auto_set_back_window(self)
back_state = self.main_window_back_state
if back_state is None:
raise RuntimeError(
f'Main window {self} provides no back-state.'
)
# Valid states should have values here.
assert back_state.is_top_level is not None
assert back_state.is_auxiliary is not None
assert back_state.window_type is not None
backwin = back_state.create_window(transition='in_left')
uiv1.set_main_window(
backwin,
from_window=self,
is_back=True,
back_state=back_state,
suppress_warning=True,
)
# Transition ourself out.
self.main_window_close()
def main_window_replace(
@ -203,7 +232,7 @@ class MainWindow(Window):
class MainWindowState:
"""Persistent state for a specific main-window and its ancestors.
"""Persistent state for a specific MainWindow.
This allows MainWindows to be automatically recreated for back-button
purposes, when switching app-modes, etc.

View File

@ -1,21 +1,3 @@
# Released under the MIT License. See LICENSE for details.
#
"""UI functionality related to accounts."""
from __future__ import annotations
import bauiv1 as bui
def show_sign_in_prompt() -> None:
"""Bring up a prompt telling the user they must sign in."""
from bauiv1lib.confirm import ConfirmWindow
from bauiv1lib.account.settings import AccountSettingsWindow
ConfirmWindow(
bui.Lstr(resource='notSignedInErrorText'),
lambda: AccountSettingsWindow(modal=True, close_once_signed_in=True),
ok_text=bui.Lstr(resource='accountSettingsWindow.signInText'),
width=460,
height=130,
)

View File

@ -105,13 +105,13 @@ class AccountLinkWindow(bui.Window):
)
def _generate_press(self) -> None:
from bauiv1lib import account
from bauiv1lib.account.signin import show_sign_in_prompt
plus = bui.app.plus
assert plus is not None
if plus.get_v1_account_state() != 'signed_in':
account.show_sign_in_prompt()
show_sign_in_prompt()
return
bui.screenmessage(
bui.Lstr(resource='gatherWindow.requestingAPromoCodeText'),

View File

@ -28,7 +28,6 @@ class AccountSettingsWindow(bui.MainWindow):
def __init__(
self,
transition: str | None = 'in_right',
modal: bool = False,
origin_widget: bui.Widget | None = None,
close_once_signed_in: bool = False,
):
@ -49,7 +48,6 @@ class AccountSettingsWindow(bui.MainWindow):
self._explicitly_signed_out_of_gpgs = False
self._r = 'accountSettingsWindow'
self._modal = modal
self._needs_refresh = False
self._v1_signed_in = plus.get_v1_account_state() == 'signed_in'
self._v1_account_state_num = plus.get_v1_account_state_num()
@ -129,22 +127,17 @@ class AccountSettingsWindow(bui.MainWindow):
scale=0.8,
text_scale=1.2,
autoselect=True,
label=bui.Lstr(
resource='cancelText' if self._modal else 'backText'
),
button_type='regular' if self._modal else 'back',
on_activate_call=(
self._modal_close if self._modal else self.main_window_back
),
label=bui.Lstr(resource='backText'),
button_type='back',
on_activate_call=self.main_window_back,
)
bui.containerwidget(edit=self._root_widget, cancel_button=btn)
if not self._modal:
bui.buttonwidget(
edit=btn,
button_type='backSmall',
size=(60, 56),
label=bui.charstr(bui.SpecialChar.BACK),
)
bui.buttonwidget(
edit=btn,
button_type='backSmall',
size=(60, 56),
label=bui.charstr(bui.SpecialChar.BACK),
)
titleyoffs = -9 if uiscale is bui.UIScale.SMALL else 0
titlescale = 0.7 if uiscale is bui.UIScale.SMALL else 1.0
@ -176,18 +169,6 @@ class AccountSettingsWindow(bui.MainWindow):
self._refresh()
self._restore_state()
def _modal_close(self) -> None:
assert 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=('out_right'),
)
@override
def get_main_window_state(self) -> bui.MainWindowState:
# Support recreating our window for back/refresh purposes.

View File

@ -0,0 +1,51 @@
# Released under the MIT License. See LICENSE for details.
#
"""UI functionality related to accounts."""
from __future__ import annotations
import bauiv1 as bui
def show_sign_in_prompt() -> None:
"""Bring up a prompt telling the user they must sign in."""
from bauiv1lib.confirm import ConfirmWindow
ConfirmWindow(
bui.Lstr(resource='notSignedInErrorText'),
_show_account_settings,
ok_text=bui.Lstr(resource='accountSettingsWindow.signInText'),
width=460,
height=130,
)
def _show_account_settings() -> None:
from bauiv1lib.account.settings import AccountSettingsWindow
# NOTE TO USERS: The code below is not the proper way to do things;
# whenever possible one should use a MainWindow's
# main_window_replace() or main_window_back() methods. We just need
# to do things a bit more manually in this case.
prev_main_window = bui.app.ui_v1.get_main_window()
# Special-case: If it seems we're already in the account window, do
# nothing.
if isinstance(prev_main_window, AccountSettingsWindow):
return
# Set our new main window.
bui.app.ui_v1.set_main_window(
AccountSettingsWindow(
close_once_signed_in=True,
origin_widget=bui.get_special_widget('account_button'),
),
from_window=False,
is_auxiliary=True,
suppress_warning=True,
)
# Transition out any previous main window.
if prev_main_window is not None:
prev_main_window.main_window_close()

View File

@ -34,9 +34,9 @@ class V2ProxySignInWindow(bui.Window):
origin_widget.get_screen_space_center()
),
scale=(
1.25
1.16
if uiscale is bui.UIScale.SMALL
else 1.05 if uiscale is bui.UIScale.MEDIUM else 0.9
else 1.0 if uiscale is bui.UIScale.MEDIUM else 0.9
),
)
)

View File

@ -193,7 +193,7 @@ class CharacterPicker(PopupWindow):
bui.widget(edit=btn, show_buffer_top=30, show_buffer_bottom=30)
def _on_store_press(self) -> None:
from bauiv1lib.account import show_sign_in_prompt
from bauiv1lib.account.signin import show_sign_in_prompt
plus = bui.app.plus
assert plus is not None

View File

@ -1032,7 +1032,7 @@ class CoopBrowserWindow(bui.MainWindow):
# pylint: disable=cyclic-import
from bauiv1lib.confirm import ConfirmWindow
from bauiv1lib.purchase import PurchaseWindow
from bauiv1lib.account import show_sign_in_prompt
from bauiv1lib.account.signin import show_sign_in_prompt
plus = bui.app.plus
assert plus is not None
@ -1106,7 +1106,7 @@ class CoopBrowserWindow(bui.MainWindow):
def run_tournament(self, tournament_button: TournamentButton) -> None:
"""Run the provided tournament game."""
from bauiv1lib.account import show_sign_in_prompt
from bauiv1lib.account.signin import show_sign_in_prompt
from bauiv1lib.tournamententry import TournamentEntryWindow
plus = bui.app.plus

View File

@ -200,7 +200,7 @@ class AboutGatherTab(GatherTab):
return scroll_widget
def _invite_to_try_press(self) -> None:
from bauiv1lib.account import show_sign_in_prompt
from bauiv1lib.account.signin import show_sign_in_prompt
from bauiv1lib.appinvite import handle_app_invites_press
plus = bui.app.plus

View File

@ -1375,7 +1375,7 @@ class PublicGatherTab(GatherTab):
)
def _on_start_advertizing_press(self) -> None:
from bauiv1lib.account import show_sign_in_prompt
from bauiv1lib.account.signin import show_sign_in_prompt
plus = bui.app.plus
assert plus is not None

View File

@ -171,7 +171,7 @@ class IconPicker(PopupWindow):
bui.widget(edit=btn, show_buffer_top=30, show_buffer_bottom=30)
def _on_store_press(self) -> None:
from bauiv1lib.account import show_sign_in_prompt
from bauiv1lib.account.signin import show_sign_in_prompt
plus = bui.app.plus
assert plus is not None

View File

@ -1,424 +0,0 @@
# Released under the MIT License. See LICENSE for details.
#
"""Provides a button showing league rank."""
from __future__ import annotations
import logging
from typing import TYPE_CHECKING
import bauiv1 as bui
if TYPE_CHECKING:
from typing import Any, Callable
class LeagueRankButton:
"""Button showing league rank."""
def __init__(
self,
parent: bui.Widget,
position: tuple[float, float],
size: tuple[float, float],
scale: float,
*,
on_activate_call: Callable[[], Any] | None = None,
transition_delay: float | None = None,
color: tuple[float, float, float] | None = None,
textcolor: tuple[float, float, float] | None = None,
smooth_update_delay: float | None = None,
):
if on_activate_call is None:
on_activate_call = bui.WeakCall(self._default_on_activate_call)
self._on_activate_call = on_activate_call
if smooth_update_delay is None:
smooth_update_delay = 1.0
self._smooth_update_delay = smooth_update_delay
self._size = size
self._scale = scale
if color is None:
color = (0.5, 0.6, 0.5)
if textcolor is None:
textcolor = (1, 1, 1)
self._color = color
self._textcolor = textcolor
self._header_color = (0.8, 0.8, 2.0)
self._parent = parent
self._position: tuple[float, float] = (0.0, 0.0)
self._button = bui.buttonwidget(
parent=parent,
size=size,
label='',
button_type='square',
scale=scale,
autoselect=True,
on_activate_call=self._on_activate,
transition_delay=transition_delay,
color=color,
)
self._title_text = bui.textwidget(
parent=parent,
size=(0, 0),
draw_controller=self._button,
h_align='center',
v_align='center',
maxwidth=size[0] * scale * 0.85,
text=bui.Lstr(
resource='league.leagueRankText',
fallback_resource='coopSelectWindow.powerRankingText',
),
color=self._header_color,
flatness=1.0,
shadow=1.0,
scale=scale * 0.5,
transition_delay=transition_delay,
)
self._value_text = bui.textwidget(
parent=parent,
size=(0, 0),
h_align='center',
v_align='center',
maxwidth=size[0] * scale * 0.85,
text='-',
draw_controller=self._button,
big=True,
scale=scale,
transition_delay=transition_delay,
color=textcolor,
)
plus = bui.app.plus
assert plus is not None
self._smooth_percent: float | None = None
self._percent: int | None = None
self._smooth_rank: float | None = None
self._rank: int | None = None
self._ticking_sound: bui.Sound | None = None
self._smooth_increase_speed = 1.0
self._league: str | None = None
self._improvement_text: str | None = None
self._smooth_update_timer: bui.AppTimer | None = None
# Take note of our account state; we'll refresh later if this changes.
self._account_state_num = plus.get_v1_account_state_num()
self._last_power_ranking_query_time: float | None = None
self._doing_power_ranking_query = False
self.set_position(position)
self._bg_flash = False
self._update_timer = bui.AppTimer(
1.0, bui.WeakCall(self._update), repeat=True
)
self._update()
# If we've got cached power-ranking data already, apply it.
assert bui.app.classic is not None
data = bui.app.classic.accounts.get_cached_league_rank_data()
if data is not None:
self._update_for_league_rank_data(data)
def _on_activate(self) -> None:
bui.increment_analytics_count('League rank button press')
self._on_activate_call()
def __del__(self) -> None:
if self._ticking_sound is not None:
self._ticking_sound.stop()
self._ticking_sound = None
def _start_smooth_update(self) -> None:
self._smooth_update_timer = bui.AppTimer(
0.05, bui.WeakCall(self._smooth_update), repeat=True
)
def _smooth_update(self) -> None:
# pylint: disable=too-many-branches
# pylint: disable=too-many-statements
try:
if not self._button:
return
if self._ticking_sound is None:
self._ticking_sound = bui.getsound('scoreIncrease')
self._ticking_sound.play()
self._bg_flash = not self._bg_flash
color_used = (
(self._color[0] * 2, self._color[1] * 2, self._color[2] * 2)
if self._bg_flash
else self._color
)
textcolor_used = (1, 1, 1) if self._bg_flash else self._textcolor
header_color_used = (
(1, 1, 1) if self._bg_flash else self._header_color
)
if self._rank is not None:
assert self._smooth_rank is not None
self._smooth_rank -= 1.0 * self._smooth_increase_speed
finished = int(self._smooth_rank) <= self._rank
elif self._smooth_percent is not None:
self._smooth_percent += 1.0 * self._smooth_increase_speed
assert self._percent is not None
finished = int(self._smooth_percent) >= self._percent
else:
finished = True
if finished:
if self._rank is not None:
self._smooth_rank = float(self._rank)
elif self._percent is not None:
self._smooth_percent = float(self._percent)
color_used = self._color
textcolor_used = self._textcolor
self._smooth_update_timer = None
if self._ticking_sound is not None:
self._ticking_sound.stop()
self._ticking_sound = None
bui.getsound('cashRegister2').play()
assert self._improvement_text is not None
diff_text = bui.textwidget(
parent=self._parent,
size=(0, 0),
h_align='center',
v_align='center',
text='+' + self._improvement_text + '!',
position=(
self._position[0] + self._size[0] * 0.5 * self._scale,
self._position[1] + self._size[1] * -0.2 * self._scale,
),
color=(0, 1, 0),
flatness=1.0,
shadow=0.0,
scale=self._scale * 0.7,
)
def safe_delete(widget: bui.Widget) -> None:
if widget:
widget.delete()
bui.apptimer(2.0, bui.Call(safe_delete, diff_text))
status_text: str | bui.Lstr
if self._rank is not None:
assert self._smooth_rank is not None
status_text = bui.Lstr(
resource='numberText',
subs=[('${NUMBER}', str(int(self._smooth_rank)))],
)
elif self._smooth_percent is not None:
status_text = str(int(self._smooth_percent)) + '%'
else:
status_text = '-'
bui.textwidget(
edit=self._value_text, text=status_text, color=textcolor_used
)
bui.textwidget(edit=self._title_text, color=header_color_used)
bui.buttonwidget(edit=self._button, color=color_used)
except Exception:
logging.exception('Error doing smooth update.')
self._smooth_update_timer = None
def _update_for_league_rank_data(self, data: dict[str, Any] | None) -> None:
# pylint: disable=too-many-branches
# pylint: disable=too-many-statements
plus = bui.app.plus
assert plus is not None
# If our button has died, ignore.
if not self._button:
return
status_text: str | bui.Lstr
in_top = data is not None and data['rank'] is not None
do_percent = False
if data is None or plus.get_v1_account_state() != 'signed_in':
self._percent = self._rank = None
status_text = '-'
elif in_top:
self._percent = None
self._rank = data['rank']
prev_league = self._league
self._league = data['l']
# If this is the first set, league has changed, or rank has gotten
# worse, snap the smooth value immediately.
assert self._rank is not None
if (
self._smooth_rank is None
or prev_league != self._league
or self._rank > int(self._smooth_rank)
):
self._smooth_rank = float(self._rank)
status_text = bui.Lstr(
resource='numberText',
subs=[('${NUMBER}', str(int(self._smooth_rank)))],
)
else:
try:
if not data['scores'] or data['scores'][-1][1] <= 0:
self._percent = self._rank = None
status_text = '-'
else:
assert bui.app.classic is not None
our_points = (
bui.app.classic.accounts.get_league_rank_points(data)
)
progress = float(our_points) / data['scores'][-1][1]
self._percent = int(progress * 100.0)
self._rank = None
do_percent = True
prev_league = self._league
self._league = data['l']
# If this is the first set, league has changed, or percent
# has decreased, snap the smooth value immediately.
if (
self._smooth_percent is None
or prev_league != self._league
or self._percent < int(self._smooth_percent)
):
self._smooth_percent = float(self._percent)
status_text = str(int(self._smooth_percent)) + '%'
except Exception:
logging.exception('Error updating power ranking.')
self._percent = self._rank = None
status_text = '-'
# If we're doing a smooth update, set a timer.
if (
self._rank is not None
and self._smooth_rank is not None
and int(self._smooth_rank) != self._rank
):
self._improvement_text = str(
-(int(self._rank) - int(self._smooth_rank))
)
diff = abs(self._rank - self._smooth_rank)
if diff > 100:
self._smooth_increase_speed = diff / 80.0
elif diff > 50:
self._smooth_increase_speed = diff / 70.0
elif diff > 25:
self._smooth_increase_speed = diff / 55.0
else:
self._smooth_increase_speed = diff / 40.0
self._smooth_increase_speed = max(0.4, self._smooth_increase_speed)
bui.apptimer(
self._smooth_update_delay,
bui.WeakCall(self._start_smooth_update),
)
if (
self._percent is not None
and self._smooth_percent is not None
and int(self._smooth_percent) != self._percent
):
self._improvement_text = str(
(int(self._percent) - int(self._smooth_percent))
)
self._smooth_increase_speed = 0.3
bui.apptimer(
self._smooth_update_delay,
bui.WeakCall(self._start_smooth_update),
)
if do_percent:
bui.textwidget(
edit=self._title_text,
text=bui.Lstr(resource='coopSelectWindow.toRankedText'),
)
else:
try:
assert data is not None
txt = bui.Lstr(
resource='league.leagueFullText',
subs=[
(
'${NAME}',
bui.Lstr(translate=('leagueNames', data['l']['n'])),
),
],
)
t_color = data['l']['c']
except Exception:
txt = bui.Lstr(
resource='league.leagueRankText',
fallback_resource='coopSelectWindow.powerRankingText',
)
assert bui.app.classic is not None
t_color = bui.app.ui_v1.title_color
bui.textwidget(edit=self._title_text, text=txt, color=t_color)
bui.textwidget(edit=self._value_text, text=status_text)
def _on_power_ranking_query_response(
self, data: dict[str, Any] | None
) -> None:
self._doing_power_ranking_query = False
assert bui.app.classic is not None
bui.app.classic.accounts.cache_league_rank_data(data)
self._update_for_league_rank_data(data)
def _update(self) -> None:
cur_time = bui.apptime()
plus = bui.app.plus
assert plus is not None
# If our account state has changed, refresh our UI.
account_state_num = plus.get_v1_account_state_num()
if account_state_num != self._account_state_num:
self._account_state_num = account_state_num
# And power ranking too...
if not self._doing_power_ranking_query:
self._last_power_ranking_query_time = None
# Send off a new power-ranking query if its been
# long enough or whatnot.
if not self._doing_power_ranking_query and (
self._last_power_ranking_query_time is None
or cur_time - self._last_power_ranking_query_time > 30.0
):
self._last_power_ranking_query_time = cur_time
self._doing_power_ranking_query = True
plus.power_ranking_query(
callback=bui.WeakCall(self._on_power_ranking_query_response)
)
def _default_on_activate_call(self) -> None:
# pylint: disable=cyclic-import
# from bauiv1lib.league.rankwindow import LeagueRankWindow
raise RuntimeError()
# LeagueRankWindow(modal=True, origin_widget=self._button)
def set_position(self, position: tuple[float, float]) -> None:
"""Set the button's position."""
self._position = position
if not self._button:
return
bui.buttonwidget(edit=self._button, position=self._position)
bui.textwidget(
edit=self._title_text,
position=(
self._position[0] + self._size[0] * 0.5 * self._scale,
self._position[1] + self._size[1] * 0.82 * self._scale,
),
)
bui.textwidget(
edit=self._value_text,
position=(
self._position[0] + self._size[0] * 0.5 * self._scale,
self._position[1] + self._size[1] * 0.36 * self._scale,
),
)
def get_button(self) -> bui.Widget:
"""Return the underlying button bui.Widget>"""
return self._button

View File

@ -83,7 +83,6 @@ class MainMenuWindow(bui.MainWindow):
# pylint: disable=cyclic-import
import bauiv1lib.getremote as _unused
import bauiv1lib.confirm as _unused2
import bauiv1lib.store.button as _unused3
import bauiv1lib.account.settings as _unused5
import bauiv1lib.store.browser as _unused6
import bauiv1lib.credits as _unused7
@ -153,30 +152,31 @@ class MainMenuWindow(bui.MainWindow):
uiscale = app.ui_v1.uiscale
# Temp note about UI changes.
bui.textwidget(
parent=self._root_widget,
position=(
(-400, 400)
if uiscale is bui.UIScale.LARGE
else (
(-270, 320)
if uiscale is bui.UIScale.MEDIUM
else (-280, 280)
)
),
size=(0, 0),
scale=0.4,
flatness=1.0,
text=(
'WARNING: This build contains a revamped UI\n'
'which is still a work-in-progress. A number\n'
'of features are not currently functional or\n'
'contain bugs. To go back to the stable legacy UI,\n'
'grab version 1.7.36 from ballistica.net'
),
h_align='left',
v_align='top',
)
if bool(False):
bui.textwidget(
parent=self._root_widget,
position=(
(-400, 400)
if uiscale is bui.UIScale.LARGE
else (
(-270, 320)
if uiscale is bui.UIScale.MEDIUM
else (-280, 280)
)
),
size=(0, 0),
scale=0.4,
flatness=1.0,
text=(
'WARNING: This build contains a revamped UI\n'
'which is still a work-in-progress. A number\n'
'of features are not currently functional or\n'
'contain bugs. To go back to the stable legacy UI,\n'
'grab version 1.7.36 from ballistica.net'
),
h_align='left',
v_align='top',
)
self._have_quit_button = app.classic.platform in (
'windows',

View File

@ -566,7 +566,7 @@ class PartyQueueWindow(bui.Window):
def on_boost_press(self) -> None:
"""Boost was pressed."""
from bauiv1lib import account
from bauiv1lib.account.signin import show_sign_in_prompt
# from bauiv1lib import gettickets
@ -574,7 +574,7 @@ class PartyQueueWindow(bui.Window):
assert plus is not None
if plus.get_v1_account_state() != 'signed_in':
account.show_sign_in_prompt()
show_sign_in_prompt()
return
if plus.get_v1_account_ticket_count() < self._boost_tickets:

View File

@ -572,7 +572,7 @@ class PlayWindow(bui.MainWindow):
def _coop(self) -> None:
# pylint: disable=cyclic-import
from bauiv1lib.account import show_sign_in_prompt
from bauiv1lib.account.signin import show_sign_in_prompt
from bauiv1lib.coop.browser import CoopBrowserWindow
# no-op if we're not currently in control.

View File

@ -255,7 +255,7 @@ class PlaylistAddGameWindow(bui.MainWindow):
)
def _on_get_more_games_press(self) -> None:
from bauiv1lib.account import show_sign_in_prompt
from bauiv1lib.account.signin import show_sign_in_prompt
from bauiv1lib.store.browser import StoreBrowserWindow
# No-op if we're not in control.
@ -271,17 +271,12 @@ class PlaylistAddGameWindow(bui.MainWindow):
self.main_window_replace(
StoreBrowserWindow(
# modal=True,
show_tab=StoreBrowserWindow.TabID.MINIGAMES,
# on_close_call=self._on_store_close,
origin_widget=self._get_more_games_button,
minimal_toolbars=True,
)
)
# def _on_store_close(self) -> None:
# self._refresh(select_get_more_games_button=True)
def _add(self) -> None:
bui.lock_all_input() # Make sure no more commands happen.
bui.apptimer(0.1, bui.unlock_all_input)

View File

@ -283,7 +283,7 @@ class PlaylistMapSelectWindow(bui.MainWindow):
)
def _on_store_press(self) -> None:
from bauiv1lib import account
from bauiv1lib.account.signin import show_sign_in_prompt
from bauiv1lib.store.browser import StoreBrowserWindow
# No-op if we're not in control.
@ -294,7 +294,7 @@ class PlaylistMapSelectWindow(bui.MainWindow):
assert plus is not None
if plus.get_v1_account_state() != 'signed_in':
account.show_sign_in_prompt()
show_sign_in_prompt()
return
self._selected_get_more_maps = True

View File

@ -432,7 +432,7 @@ class PlayOptionsWindow(PopupWindow):
self._update()
def _custom_colors_names_press(self) -> None:
from bauiv1lib.account import show_sign_in_prompt
from bauiv1lib.account.signin import show_sign_in_prompt
from bauiv1lib.teamnamescolors import TeamNamesColorsWindow
from bauiv1lib.purchase import PurchaseWindow

View File

@ -550,7 +550,7 @@ class EditProfileWindow(
def upgrade_profile(self) -> None:
"""Attempt to upgrade the profile to global."""
from bauiv1lib import account
from bauiv1lib.account.signin import show_sign_in_prompt
from bauiv1lib.profile import upgrade as pupgrade
new_name = self.getname().strip()
@ -566,7 +566,7 @@ class EditProfileWindow(
assert plus is not None
if plus.get_v1_account_state() != 'signed_in':
account.show_sign_in_prompt()
show_sign_in_prompt()
return
pupgrade.ProfileUpgradeWindow(self)

View File

@ -53,24 +53,52 @@ class ResourceTypeInfoWindow(PopupWindow):
iconscale=1.2,
)
yoffs = self._height - 150
if resource_type == 'tickets':
rdesc = 'Will describe tickets.'
rdesc = (
'Use tickets to unlock characters, maps,\n'
'minigames, and more in the store.\n'
'\n'
'Earn tickets by completing achievements or\n'
'by opening chests won in the game.'
)
texname = 'tickets'
elif resource_type == 'tokens':
rdesc = 'Will describe tokens.'
rdesc = (
'Tokens can be used to speed up chest unlocks\n'
'and skip other waits.\n'
'\n'
'You can buy packs of tokens or buy a Gold Pass\n'
'to get infinite tokens forever.\n'
)
texname = 'coin'
elif resource_type == 'trophies':
rdesc = 'Will show trophies & league rankings.'
rdesc = 'TODO: Will show trophies & league rankings.'
texname = 'crossOut'
elif resource_type == 'xp':
rdesc = 'Will describe xp/levels.'
rdesc = 'TODO: Will describe xp/levels.'
texname = 'crossOut'
else:
assert_never(resource_type)
imgsize = 100.0
bui.imagewidget(
parent=self.root_widget,
position=(self._width * 0.5 - imgsize * 0.5, yoffs + 5.0),
size=(imgsize, imgsize),
texture=bui.gettexture(texname),
)
bui.textwidget(
parent=self.root_widget,
h_align='center',
v_align='center',
v_align='top',
size=(0, 0),
position=(self._width * 0.5, self._height * 0.5),
text=(f'UNDER CONSTRUCTION.\n({rdesc})'),
maxwidth=self._width * 0.8,
position=(self._width * 0.5, yoffs - 5.0),
text=rdesc,
scale=0.8,
)
def _on_cancel_press(self) -> None:

View File

@ -787,13 +787,13 @@ class AdvancedSettingsWindow(bui.MainWindow):
def _on_friend_promo_code_press(self) -> None:
from bauiv1lib import appinvite
from bauiv1lib import account
from bauiv1lib.account.signin import show_sign_in_prompt
plus = bui.app.plus
assert plus is not None
if plus.get_v1_account_state() != 'signed_in':
account.show_sign_in_prompt()
show_sign_in_prompt()
return
appinvite.handle_app_invites_press()

View File

@ -281,12 +281,12 @@ class StoreBrowserWindow(bui.MainWindow):
self._restore_state()
def _restore_purchases(self) -> None:
from bauiv1lib import account
from bauiv1lib.account.signin import show_sign_in_prompt
plus = bui.app.plus
assert plus is not None
if plus.accounts.primary is None:
account.show_sign_in_prompt()
show_sign_in_prompt()
else:
plus.restore_purchases()
@ -490,7 +490,7 @@ class StoreBrowserWindow(bui.MainWindow):
def buy(self, item: str) -> None:
"""Attempt to purchase the provided item."""
from bauiv1lib import account
from bauiv1lib.account.signin import show_sign_in_prompt
from bauiv1lib.confirm import ConfirmWindow
assert bui.app.classic is not None
@ -509,7 +509,7 @@ class StoreBrowserWindow(bui.MainWindow):
bui.getsound('error').play()
else:
if plus.get_v1_account_state() != 'signed_in':
account.show_sign_in_prompt()
show_sign_in_prompt()
else:
self._last_buy_time = curtime

View File

@ -1,329 +0,0 @@
# Released under the MIT License. See LICENSE for details.
#
"""UI functionality for a button leading to the store."""
from __future__ import annotations
import logging
from typing import TYPE_CHECKING
from efro.util import utc_now
import bauiv1 as bui
if TYPE_CHECKING:
from typing import Any, Sequence, Callable
class StoreButton:
"""A button leading to the store."""
def __init__(
self,
parent: bui.Widget,
position: Sequence[float],
size: Sequence[float],
scale: float,
*,
on_activate_call: Callable[[], Any] | None = None,
transition_delay: float | None = None,
color: Sequence[float] | None = None,
textcolor: Sequence[float] | None = None,
show_tickets: bool = False,
button_type: str | None = None,
sale_scale: float = 1.0,
):
self._position = position
self._size = size
self._scale = scale
if on_activate_call is None:
on_activate_call = bui.WeakCall(self._default_on_activate_call)
self._on_activate_call = on_activate_call
self._button = bui.buttonwidget(
parent=parent,
size=size,
label='' if show_tickets else bui.Lstr(resource='storeText'),
scale=scale,
autoselect=True,
on_activate_call=self._on_activate,
transition_delay=transition_delay,
color=color,
button_type=button_type,
)
self._title_text: bui.Widget | None
self._ticket_text: bui.Widget | None
if show_tickets:
self._title_text = bui.textwidget(
parent=parent,
position=(
position[0] + size[0] * 0.5 * scale,
position[1] + size[1] * 0.65 * scale,
),
size=(0, 0),
h_align='center',
v_align='center',
maxwidth=size[0] * scale * 0.65,
text=bui.Lstr(resource='storeText'),
draw_controller=self._button,
scale=scale,
transition_delay=transition_delay,
color=textcolor,
)
self._ticket_text = bui.textwidget(
parent=parent,
size=(0, 0),
h_align='center',
v_align='center',
maxwidth=size[0] * scale * 0.85,
text='',
color=(0.2, 1.0, 0.2),
flatness=1.0,
shadow=0.0,
scale=scale * 0.6,
transition_delay=transition_delay,
)
else:
self._title_text = None
self._ticket_text = None
self._circle_rad = 12 * scale
self._circle_center = (0.0, 0.0)
self._sale_circle_center = (0.0, 0.0)
self._available_purchase_backing = bui.imagewidget(
parent=parent,
color=(1, 0, 0),
draw_controller=self._button,
size=(2.2 * self._circle_rad, 2.2 * self._circle_rad),
texture=bui.gettexture('circleShadow'),
transition_delay=transition_delay,
)
self._available_purchase_text = bui.textwidget(
parent=parent,
size=(0, 0),
h_align='center',
v_align='center',
text='',
draw_controller=self._button,
color=(1, 1, 1),
flatness=1.0,
shadow=1.0,
scale=0.6 * scale,
maxwidth=self._circle_rad * 1.4,
transition_delay=transition_delay,
)
self._sale_circle_rad = 18 * scale * sale_scale
self._sale_backing = bui.imagewidget(
parent=parent,
color=(0.5, 0, 1.0),
draw_controller=self._button,
size=(2 * self._sale_circle_rad, 2 * self._sale_circle_rad),
texture=bui.gettexture('circleZigZag'),
transition_delay=transition_delay,
)
self._sale_title_text = bui.textwidget(
parent=parent,
size=(0, 0),
h_align='center',
v_align='center',
draw_controller=self._button,
color=(0, 1, 0),
flatness=1.0,
shadow=0.0,
scale=0.5 * scale * sale_scale,
maxwidth=self._sale_circle_rad * 1.5,
transition_delay=transition_delay,
)
self._sale_time_text = bui.textwidget(
parent=parent,
size=(0, 0),
h_align='center',
v_align='center',
draw_controller=self._button,
color=(0, 1, 0),
flatness=1.0,
shadow=0.0,
scale=0.4 * scale * sale_scale,
maxwidth=self._sale_circle_rad * 1.5,
transition_delay=transition_delay,
)
self.set_position(position)
self._update_timer = bui.AppTimer(
1.0, bui.WeakCall(self._update), repeat=True
)
self._update()
def _on_activate(self) -> None:
bui.increment_analytics_count('Store button press')
self._on_activate_call()
def set_position(self, position: Sequence[float]) -> None:
"""Set the button position."""
self._position = position
self._circle_center = (
position[0] + 0.1 * self._size[0] * self._scale,
position[1] + self._size[1] * self._scale * 0.8,
)
self._sale_circle_center = (
position[0] + 0.07 * self._size[0] * self._scale,
position[1] + self._size[1] * self._scale * 0.8,
)
if not self._button:
return
bui.buttonwidget(edit=self._button, position=self._position)
if self._title_text is not None:
bui.textwidget(
edit=self._title_text,
position=(
self._position[0] + self._size[0] * 0.5 * self._scale,
self._position[1] + self._size[1] * 0.65 * self._scale,
),
)
if self._ticket_text is not None:
bui.textwidget(
edit=self._ticket_text,
position=(
position[0] + self._size[0] * 0.5 * self._scale,
position[1] + self._size[1] * 0.28 * self._scale,
),
size=(0, 0),
)
bui.imagewidget(
edit=self._available_purchase_backing,
position=(
self._circle_center[0] - self._circle_rad * 1.02,
self._circle_center[1] - self._circle_rad * 1.13,
),
)
bui.textwidget(
edit=self._available_purchase_text, position=self._circle_center
)
bui.imagewidget(
edit=self._sale_backing,
position=(
self._sale_circle_center[0] - self._sale_circle_rad,
self._sale_circle_center[1] - self._sale_circle_rad,
),
)
bui.textwidget(
edit=self._sale_title_text,
position=(
self._sale_circle_center[0],
self._sale_circle_center[1] + self._sale_circle_rad * 0.3,
),
)
bui.textwidget(
edit=self._sale_time_text,
position=(
self._sale_circle_center[0],
self._sale_circle_center[1] - self._sale_circle_rad * 0.3,
),
)
def _default_on_activate_call(self) -> None:
# pylint: disable=cyclic-import
from bauiv1lib.account import show_sign_in_prompt
# from bauiv1lib.store.browser import StoreBrowserWindow
plus = bui.app.plus
assert plus is not None
if plus.get_v1_account_state() != 'signed_in':
show_sign_in_prompt()
return
raise RuntimeError('no longer wired up')
# StoreBrowserWindow(modal=True, origin_widget=self._button)
def get_button(self) -> bui.Widget:
"""Return the underlying button widget."""
return self._button
def _update(self) -> None:
# pylint: disable=too-many-branches
# pylint: disable=cyclic-import
from babase import SpecialChar
plus = bui.app.plus
assert plus is not None
assert bui.app.classic is not None
store = bui.app.classic.store
if not self._button:
return # Our instance may outlive our UI objects.
if self._ticket_text is not None:
if plus.get_v1_account_state() == 'signed_in':
sval = bui.charstr(SpecialChar.TICKET) + str(
plus.get_v1_account_ticket_count()
)
else:
sval = '-'
bui.textwidget(edit=self._ticket_text, text=sval)
available_purchases = store.get_available_purchase_count()
# Old pro sale stuff..
sale_time = store.get_available_sale_time('extras')
# ..also look for new style sales.
if sale_time is None:
import datetime
sales_raw = plus.get_v1_account_misc_read_val('sales', {})
sale_times = []
try:
# Look at the current set of sales; filter any with time
# remaining that we don't own.
for sale_item, sale_info in list(sales_raw.items()):
if not plus.get_v1_account_product_purchased(sale_item):
to_end = (
datetime.datetime.fromtimestamp(
sale_info['e'], datetime.UTC
)
- utc_now()
).total_seconds()
if to_end > 0:
sale_times.append(to_end)
except Exception:
logging.exception('Error parsing sales.')
if sale_times:
sale_time = int(min(sale_times) * 1000)
if sale_time is not None:
bui.textwidget(
edit=self._sale_title_text,
text=bui.Lstr(resource='store.saleText'),
)
bui.textwidget(
edit=self._sale_time_text,
text=bui.timestring(sale_time / 1000.0, centi=False),
)
bui.imagewidget(edit=self._sale_backing, opacity=1.0)
bui.imagewidget(edit=self._available_purchase_backing, opacity=1.0)
bui.textwidget(edit=self._available_purchase_text, text='')
bui.imagewidget(edit=self._available_purchase_backing, opacity=0.0)
else:
bui.imagewidget(edit=self._sale_backing, opacity=0.0)
bui.textwidget(edit=self._sale_time_text, text='')
bui.textwidget(edit=self._sale_title_text, text='')
if available_purchases > 0:
bui.textwidget(
edit=self._available_purchase_text,
text=str(available_purchases),
)
bui.imagewidget(
edit=self._available_purchase_backing, opacity=1.0
)
else:
bui.textwidget(edit=self._available_purchase_text, text='')
bui.imagewidget(
edit=self._available_purchase_backing, opacity=0.0
)

View File

@ -206,7 +206,7 @@ void BaseFeatureSet::StartApp() {
called_start_app_ = true;
assert(!app_started_); // Shouldn't be possible.
LogVersionInfo_();
LogStartupMessage_();
g_core->Log(LogName::kBaLifecycle, LogLevel::kInfo,
"start-app begin (main thread)");
@ -420,7 +420,7 @@ void BaseFeatureSet::OnAppShutdownComplete() {
}
}
void BaseFeatureSet::LogVersionInfo_() {
void BaseFeatureSet::LogStartupMessage_() {
char buffer[256];
if (g_buildconfig.headless_build()) {
snprintf(buffer, sizeof(buffer),

View File

@ -828,7 +828,7 @@ class BaseFeatureSet : public FeatureSetNativeComponent,
private:
BaseFeatureSet();
void LogVersionInfo_();
void LogStartupMessage_();
void PrintContextNonLogicThread_();
void PrintContextForCallableLabel_(const char* label);
void PrintContextUnavailable_();

View File

@ -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 = 22146;
const int kEngineBuildNumber = 22147;
const char* kEngineVersion = "1.7.37";
const int kEngineApiVersion = 9;

View File

@ -3,7 +3,6 @@
#include "ballistica/ui_v1/widget/root_widget.h"
#include <algorithm>
#include <cstdio>
#include <string>
#include <vector>
@ -1457,30 +1456,51 @@ void RootWidget::SetXPText(const std::string& val) {
}
void RootWidget::SetHaveLiveValues(bool have_live_values) {
auto cval{have_live_values ? 1.0f : 0.4f};
auto oval{have_live_values ? 1.0f : 0.2f};
// auto cval{have_live_values ? 1.0f : 0.4f};
auto oval{have_live_values ? 1.0f : 0.4f};
auto oval2{have_live_values ? 1.0f : 0.4f};
assert(tickets_meter_text_);
assert(tickets_meter_icon_);
tickets_meter_text_->widget->set_color(1.0f, 1.0f, 1.0f, oval);
tickets_meter_icon_->widget->set_color(cval, cval, cval);
// tickets_meter_icon_->widget->set_color(cval, cval, cval);
tickets_meter_icon_->widget->set_opacity(oval2);
assert(tokens_meter_text_);
assert(tokens_meter_icon_);
tokens_meter_text_->widget->set_color(1.0f, 1.0f, 1.0f, oval);
tokens_meter_icon_->widget->set_color(cval, cval, cval);
// tokens_meter_icon_->widget->set_color(cval, cval, cval);
tokens_meter_icon_->widget->set_opacity(oval2);
assert(inbox_button_);
inbox_button_->widget->set_opacity(oval2);
assert(achievements_button_);
achievements_button_->widget->set_opacity(oval2);
assert(achievement_percent_text_);
achievement_percent_text_->widget->set_color(1.0f, 1.0f, 1.0f, oval);
assert(store_button_);
store_button_->widget->set_opacity(oval2);
assert(inventory_button_);
inventory_button_->widget->set_opacity(oval2);
assert(get_tokens_button_);
get_tokens_button_->widget->set_opacity(oval2);
assert(league_rank_text_);
league_rank_text_->widget->set_color(1.0f, 1.0f, 1.0f, oval);
// Note: We are currently driving trophy icon color based on league and
// opacity here based on connectivity. This keeps logic simple but is a
// bit different than other icons where we only drive color and keep
// opacity at 1.0.
assert(tickets_meter_button_);
tickets_meter_button_->widget->set_opacity(oval2);
assert(tokens_meter_button_);
tokens_meter_button_->widget->set_opacity(oval2);
assert(trophy_meter_button_);
trophy_meter_button_->widget->set_opacity(oval2);
assert(trophy_icon_);
trophy_icon_->widget->set_opacity(oval2);