From 05f09c94de721692df045048ac9e18d16315f383 Mon Sep 17 00:00:00 2001 From: Eric Froemling Date: Thu, 19 Dec 2024 06:02:48 -0800 Subject: [PATCH] starting to wire up chests gui --- .efrocachemap | 74 ++-- CHANGELOG.md | 2 +- .../ba_data/python/baclassic/_appmode.py | 28 +- src/assets/ba_data/python/baenv.py | 2 +- .../ba_data/python/bauiv1/_appsubsystem.py | 2 +- src/assets/ba_data/python/bauiv1/_hooks.py | 12 +- .../python/methods/python_methods_classic.cc | 24 +- .../classic/support/classic_app_mode.cc | 31 ++ .../classic/support/classic_app_mode.h | 8 + src/ballistica/shared/ballistica.cc | 2 +- src/ballistica/ui_v1/python/ui_v1_python.h | 2 +- src/ballistica/ui_v1/widget/root_widget.cc | 315 ++++++++++-------- src/ballistica/ui_v1/widget/root_widget.h | 101 +++--- src/ballistica/ui_v1/widget/widget.h | 2 +- src/meta/bauiv1meta/pyembed/binding_ui_v1.py | 2 +- 15 files changed, 373 insertions(+), 234 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 9ce7928f..b26183bb 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4103,42 +4103,42 @@ "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": "1c6d09241842fc53d62646cc662b5788", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "cdd335f35c449a6ef92a6a30c16a0085", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "cf604039da1f3d28d6bc1ea7c7b5be6f", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "ead609fc3fa3645e6233f29da0129fa0", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "a7ecf0c835d4601e392351722af45e91", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "0435e351e411ad582efa9edb4cbfacae", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "77d0eafc54b09616dfde834ace398af4", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "cde652ed341ef18534373d6a084c73e4", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "ed5c1f1fc1b27c337d3d7ab52ea6f80d", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "4b4455542be4cc68a2faa77e08856546", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "16038e4aee7fad2ef7d7dfaa20fc1e77", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "9791d3a106473204df3c075912b88627", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "9579daa473553d9b3184e8d6e2449d1a", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "1bd63a757fc1936048baabb67cd78ae0", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "5788412d3b6f5b40094f7f1e7871ed5e", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "2d852ebf53692fac186e851864d30ecf", - "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "8e0d4fe40c9d3f78dc353b855c36033d", - "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "7a523edeaea9e8e222e3d9daafd53d3a", - "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "8e0d4fe40c9d3f78dc353b855c36033d", - "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "7a523edeaea9e8e222e3d9daafd53d3a", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "3cdfe757d64213164f3cc1fb3d660f54", - "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "15740f71e03465f7341f6ecd83165f07", - "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "3cdfe757d64213164f3cc1fb3d660f54", - "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "15740f71e03465f7341f6ecd83165f07", - "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "3516e46d80d01cab8b93d3c50a5947bc", - "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "b57964942b8ca52efdf51582adc26aee", - "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "3516e46d80d01cab8b93d3c50a5947bc", - "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "b57964942b8ca52efdf51582adc26aee", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "fb8b453ef08c338a3021c409c9b92cd7", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "2e37c8cc89e0c7d3921de1dac2fa9248", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "d49436a80df5bc4620a5fac8ce8dd905", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "7fbe2f445f79975909484da424f50fff", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "93a68477b999f022cdfeaf8bb358c9a7", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "e75d0ea19ce9a2012da65bba6d391fb7", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "87ab5928f2703ff308f976c162d4f6e4", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "d950ed6388747fce98c7c8c8d412d103", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "50d25937dea753465f4c37093252a506", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "9379bbb7a0e05265618072ce54b5150b", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "31d6adcaabf9c6626bba3840cad8e887", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "b9eac18a217bc7688b2d9144b2d712f6", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "e89c0ffde5d3e39aeb585544de2b5020", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "a265586bc3c0a3190ca43cd66bb786d1", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "bd5776295818b26d4933e0c95de5ccf5", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "202c243dea911c748673edebd01a6d27", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "80b9857bec34269d850fc0a196628ff1", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "1bf73ae24f6a33a1d8bffb901e655072", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "f81be586ef989a7a70d7d6db66e6d333", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "989eaa1a362d5584bca1c703f1fb297a", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "fc585782cef6148c70914988a0a6c4d6", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "7c51de6bbecaf69f9c447819891537ad", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "7eaae5174e50c2007af260ae6ca1db4c", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "daa74a12e1655dc73603dfcc7c14029f", + "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "144b0407bc4aa4fd889adeb9938f7c83", + "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "b546945362b7e71974acaf41ddd52c6e", + "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "144b0407bc4aa4fd889adeb9938f7c83", + "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "b546945362b7e71974acaf41ddd52c6e", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "f7a4426a032132569d5d61addd25932f", + "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "a8d2a7566260465abe9dd3cb75dcffc5", + "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "f7a4426a032132569d5d61addd25932f", + "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "a8d2a7566260465abe9dd3cb75dcffc5", + "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "f052e79cad083c718834345ef01015ca", + "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "5484ab93d479f69111fb2a83cafbf269", + "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "f052e79cad083c718834345ef01015ca", + "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "5484ab93d479f69111fb2a83cafbf269", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "cec1716fa0fd08cfb444b12fc3a1d90b", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "3a4f575fe91ac1944e6d5a2935b2e18d", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "48ef32642a8de1aabb0533ce692f5344", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "06af8dc996eaa17fc01b3ddbaef704ad", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "45437fa0d848b76b77aeae9bf3792389", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "9b32bec0aff1d5b2a56b2548d33ae9f8", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "9bb774ea2805698e5fa47cf0e8367f8a", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "57c81da4ae274d0694e470c61da13967", "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", @@ -4149,5 +4149,5 @@ "src/ballistica/core/mgen/python_modules_monolithic.h": "fb967ed1c7db0c77d8deb4f00a7103c5", "src/ballistica/scene_v1/mgen/pyembed/binding_scene_v1.inc": "24319dcd493e3d0271dd9e1b67839844", "src/ballistica/template_fs/mgen/pyembed/binding_template_fs.inc": "4957085dad60cc136fc513215ffeaf78", - "src/ballistica/ui_v1/mgen/pyembed/binding_ui_v1.inc": "04770b89b892d9891b29064685a89287" + "src/ballistica/ui_v1/mgen/pyembed/binding_ui_v1.inc": "615ea6d085d5e568cf8a065266b458f8" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index d3d042d2..650e3ba0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.37 (build 22138, api 9, 2024-12-19) +### 1.7.37 (build 22139, api 9, 2024-12-19) - Bumping api version to 9. As you'll see below, there's some UI changes that will require a bit of work for any UI mods to adapt to. If your mods don't touch UI stuff at all you can simply bump your api version and call it a day. diff --git a/src/assets/ba_data/python/baclassic/_appmode.py b/src/assets/ba_data/python/baclassic/_appmode.py index a2262305..e9ff509d 100644 --- a/src/assets/ba_data/python/baclassic/_appmode.py +++ b/src/assets/ba_data/python/baclassic/_appmode.py @@ -104,6 +104,9 @@ class ClassicAppMode(babase.AppMode): ui.root_ui_calls[ui.RootUIElement.ACHIEVEMENTS_BUTTON] = ( self._root_ui_achievements_press ) + ui.root_ui_calls[ui.RootUIElement.CHEST_SLOT_0] = partial( + self._root_ui_chest_slot_pressed, 0 + ) ui.root_ui_calls[ui.RootUIElement.CHEST_SLOT_1] = partial( self._root_ui_chest_slot_pressed, 1 ) @@ -113,9 +116,6 @@ class ClassicAppMode(babase.AppMode): ui.root_ui_calls[ui.RootUIElement.CHEST_SLOT_3] = partial( self._root_ui_chest_slot_pressed, 3 ) - ui.root_ui_calls[ui.RootUIElement.CHEST_SLOT_4] = partial( - self._root_ui_chest_slot_pressed, 4 - ) # We want to be informed when primary account changes. self._on_primary_account_changed_callback = ( @@ -189,6 +189,10 @@ class ClassicAppMode(babase.AppMode): xp_text='-', inbox_count_text='', gold_pass=False, + chest_0_appearance='', + chest_1_appearance='', + chest_2_appearance='', + chest_3_appearance='', ) else: @@ -210,6 +214,12 @@ class ClassicAppMode(babase.AppMode): ibc = str(val.inbox_count) if val.inbox_count_is_max: ibc += '+' + + chest0 = val.chests.get('0') + chest1 = val.chests.get('1') + chest2 = val.chests.get('2') + chest3 = val.chests.get('3') + _baclassic.set_root_ui_values( tickets_text=str(val.tickets), tokens_text=str(val.tokens), @@ -224,6 +234,18 @@ class ClassicAppMode(babase.AppMode): xp_text=f'{val.xp}/{val.xpmax}', inbox_count_text=ibc, gold_pass=val.gold_pass, + chest_0_appearance=( + '' if chest0 is None else chest0.appearance.value + ), + chest_1_appearance=( + '' if chest1 is None else chest1.appearance.value + ), + chest_2_appearance=( + '' if chest2 is None else chest2.appearance.value + ), + chest_3_appearance=( + '' if chest3 is None else chest3.appearance.value + ), ) def _root_ui_menu_press(self) -> None: diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index df422a85..27a7bd5e 100644 --- a/src/assets/ba_data/python/baenv.py +++ b/src/assets/ba_data/python/baenv.py @@ -53,7 +53,7 @@ if TYPE_CHECKING: # Build number and version of the ballistica binary we expect to be # using. -TARGET_BALLISTICA_BUILD = 22138 +TARGET_BALLISTICA_BUILD = 22139 TARGET_BALLISTICA_VERSION = '1.7.37' diff --git a/src/assets/ba_data/python/bauiv1/_appsubsystem.py b/src/assets/ba_data/python/bauiv1/_appsubsystem.py index 36bc7749..4ee01016 100644 --- a/src/assets/ba_data/python/bauiv1/_appsubsystem.py +++ b/src/assets/ba_data/python/bauiv1/_appsubsystem.py @@ -52,10 +52,10 @@ class UIV1AppSubsystem(babase.AppSubsystem): TOKENS_METER = 'tokens_meter' TROPHY_METER = 'trophy_meter' LEVEL_METER = 'level_meter' + CHEST_SLOT_0 = 'chest_slot_0' CHEST_SLOT_1 = 'chest_slot_1' CHEST_SLOT_2 = 'chest_slot_2' CHEST_SLOT_3 = 'chest_slot_3' - CHEST_SLOT_4 = 'chest_slot_4' def __init__(self) -> None: from bauiv1._uitypes import MainWindow diff --git a/src/assets/ba_data/python/bauiv1/_hooks.py b/src/assets/ba_data/python/bauiv1/_hooks.py index 979f43fe..7cf00e17 100644 --- a/src/assets/ba_data/python/bauiv1/_hooks.py +++ b/src/assets/ba_data/python/bauiv1/_hooks.py @@ -63,6 +63,12 @@ def root_ui_store_button_press() -> None: _root_ui_button_press(UIV1AppSubsystem.RootUIElement.STORE_BUTTON) +def root_ui_chest_slot_0_press() -> None: + from bauiv1._appsubsystem import UIV1AppSubsystem + + _root_ui_button_press(UIV1AppSubsystem.RootUIElement.CHEST_SLOT_0) + + def root_ui_chest_slot_1_press() -> None: from bauiv1._appsubsystem import UIV1AppSubsystem @@ -81,12 +87,6 @@ def root_ui_chest_slot_3_press() -> None: _root_ui_button_press(UIV1AppSubsystem.RootUIElement.CHEST_SLOT_3) -def root_ui_chest_slot_4_press() -> None: - from bauiv1._appsubsystem import UIV1AppSubsystem - - _root_ui_button_press(UIV1AppSubsystem.RootUIElement.CHEST_SLOT_4) - - def root_ui_inventory_button_press() -> None: from bauiv1._appsubsystem import UIV1AppSubsystem diff --git a/src/ballistica/classic/python/methods/python_methods_classic.cc b/src/ballistica/classic/python/methods/python_methods_classic.cc index bca26086..7d87408f 100644 --- a/src/ballistica/classic/python/methods/python_methods_classic.cc +++ b/src/ballistica/classic/python/methods/python_methods_classic.cc @@ -303,6 +303,10 @@ static auto PySetRootUIValues(PyObject* self, PyObject* args, PyObject* keywds) const char* level_text; const char* xp_text; const char* inbox_count_text; + const char* chest_0_appearance; + const char* chest_1_appearance; + const char* chest_2_appearance; + const char* chest_3_appearance; int gold_pass{}; static const char* kwlist[] = {"tickets_text", @@ -314,12 +318,17 @@ static auto PySetRootUIValues(PyObject* self, PyObject* args, PyObject* keywds) "xp_text", "inbox_count_text", "gold_pass", + "chest_0_appearance", + "chest_1_appearance", + "chest_2_appearance", + "chest_3_appearance", nullptr}; if (!PyArg_ParseTupleAndKeywords( - args, keywds, "ssssssssp", const_cast(kwlist), &tickets_text, - &tokens_text, &league_rank_text, &league_type, + args, keywds, "sssssssspssss", const_cast(kwlist), + &tickets_text, &tokens_text, &league_rank_text, &league_type, &achievements_percent_text, &level_text, &xp_text, &inbox_count_text, - &gold_pass)) { + &gold_pass, &chest_0_appearance, &chest_1_appearance, + &chest_2_appearance, &chest_3_appearance)) { return nullptr; } BA_PRECONDITION(g_base->InLogicThread()); @@ -337,6 +346,8 @@ static auto PySetRootUIValues(PyObject* self, PyObject* args, PyObject* keywds) appmode->SetRootUIXPText(xp_text); appmode->SetRootUIInboxCountText(inbox_count_text); appmode->SetRootUIGoldPass(gold_pass); + appmode->SetRootUIChests(chest_0_appearance, chest_1_appearance, + chest_2_appearance, chest_3_appearance); Py_RETURN_NONE; BA_PYTHON_CATCH; @@ -347,7 +358,8 @@ static PyMethodDef PySetRootUIValuesDef = { (PyCFunction)PySetRootUIValues, // method METH_VARARGS | METH_KEYWORDS, // flags - "set_root_ui_values(tickets_text: str,\n" + "set_root_ui_values(*,\n" + " tickets_text: str,\n" " tokens_text: str,\n" " league_rank_text: str,\n" " league_type: str,\n" @@ -356,6 +368,10 @@ static PyMethodDef PySetRootUIValuesDef = { " xp_text: str,\n" " inbox_count_text: str,\n" " gold_pass: bool,\n" + " chest_0_appearance: str,\n" + " chest_1_appearance: str,\n" + " chest_2_appearance: str,\n" + " chest_3_appearance: str,\n" ") -> None\n" "\n" "(internal)", diff --git a/src/ballistica/classic/support/classic_app_mode.cc b/src/ballistica/classic/support/classic_app_mode.cc index ab6b2778..5d9be9d5 100644 --- a/src/ballistica/classic/support/classic_app_mode.cc +++ b/src/ballistica/classic/support/classic_app_mode.cc @@ -158,6 +158,9 @@ void ClassicAppMode::Reset_() { root_widget->SetLevelText(root_ui_level_text_); root_widget->SetXPText(root_ui_xp_text_); root_widget->SetInboxCountText(root_ui_inbox_count_text_); + root_widget->SetChests( + root_ui_chest_0_appearance_, root_ui_chest_1_appearance_, + root_ui_chest_2_appearance_, root_ui_chest_3_appearance_); } } @@ -1696,6 +1699,34 @@ void ClassicAppMode::SetRootUIGoldPass(bool enabled) { } } +void ClassicAppMode::SetRootUIChests(const std::string& chest_0_appearance, + const std::string& chest_1_appearance, + const std::string& chest_2_appearance, + const std::string& chest_3_appearance) { + BA_PRECONDITION(g_base->InLogicThread()); + if (chest_0_appearance == root_ui_chest_0_appearance_ + && chest_1_appearance == root_ui_chest_1_appearance_ + && chest_2_appearance == root_ui_chest_2_appearance_ + && chest_3_appearance == root_ui_chest_3_appearance_) { + return; + } + + // Store the values. + root_ui_chest_0_appearance_ = chest_0_appearance; + root_ui_chest_1_appearance_ = chest_1_appearance; + root_ui_chest_2_appearance_ = chest_2_appearance; + root_ui_chest_3_appearance_ = chest_3_appearance; + + // Apply it to any existing UI. + if (uiv1_) { + if (auto* root_widget = uiv1_->root_widget()) { + root_widget->SetChests( + root_ui_chest_0_appearance_, root_ui_chest_1_appearance_, + root_ui_chest_2_appearance_, root_ui_chest_3_appearance_); + } + } +} + auto ClassicAppMode::GetBottomLeftEdgeHeight() -> float { assert(g_base->InLogicThread()); if (uiv1_) { diff --git a/src/ballistica/classic/support/classic_app_mode.h b/src/ballistica/classic/support/classic_app_mode.h index 3a14956a..805c5a23 100644 --- a/src/ballistica/classic/support/classic_app_mode.h +++ b/src/ballistica/classic/support/classic_app_mode.h @@ -224,6 +224,10 @@ class ClassicAppMode : public base::AppMode { void SetRootUIXPText(const std::string text); void SetRootUIInboxCountText(const std::string text); void SetRootUIGoldPass(bool enabled); + void SetRootUIChests(const std::string& chest_0_appearance, + const std::string& chest_1_appearance, + const std::string& chest_2_appearance, + const std::string& chest_3_appearance); private: ClassicAppMode(); @@ -241,6 +245,10 @@ class ClassicAppMode : public base::AppMode { // forward declarations of their template params. std::map scan_results_; std::mutex scan_results_mutex_; + std::string root_ui_chest_0_appearance_; + std::string root_ui_chest_1_appearance_; + std::string root_ui_chest_2_appearance_; + std::string root_ui_chest_3_appearance_; uint32_t next_scan_query_id_{}; int scan_socket_{-1}; int host_protocol_version_{-1}; diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index ab2e3f7b..c2ce720b 100644 --- a/src/ballistica/shared/ballistica.cc +++ b/src/ballistica/shared/ballistica.cc @@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int { namespace ballistica { // These are set automatically via script; don't modify them here. -const int kEngineBuildNumber = 22138; +const int kEngineBuildNumber = 22139; const char* kEngineVersion = "1.7.37"; const int kEngineApiVersion = 9; diff --git a/src/ballistica/ui_v1/python/ui_v1_python.h b/src/ballistica/ui_v1/python/ui_v1_python.h index 8d9578d2..5f165f28 100644 --- a/src/ballistica/ui_v1/python/ui_v1_python.h +++ b/src/ballistica/ui_v1/python/ui_v1_python.h @@ -36,10 +36,10 @@ class UIV1Python { kRootUISettingsButtonPressCall, kRootUIAchievementsButtonPressCall, kRootUIStoreButtonPressCall, + kRootUIChestSlot0PressCall, kRootUIChestSlot1PressCall, kRootUIChestSlot2PressCall, kRootUIChestSlot3PressCall, - kRootUIChestSlot4PressCall, kRootUIInventoryButtonPressCall, kRootUITrophyMeterPressCall, kRootUILevelIconPressCall, diff --git a/src/ballistica/ui_v1/widget/root_widget.cc b/src/ballistica/ui_v1/widget/root_widget.cc index 45aa5097..5ab188d8 100644 --- a/src/ballistica/ui_v1/widget/root_widget.cc +++ b/src/ballistica/ui_v1/widget/root_widget.cc @@ -4,6 +4,7 @@ #include #include +#include #include "ballistica/base/app_mode/app_mode.h" #include "ballistica/base/assets/assets.h" @@ -27,12 +28,12 @@ static const float kBotLeftColorB{0.8f}; static const bool kShowLevels{false}; // For defining toolbar buttons. -struct RootWidget::ButtonDef { +struct RootWidget::ButtonDef_ { std::string label; std::string img; std::string mesh_transparent; std::string mesh_opaque; - VAlign v_align{VAlign::kTop}; + VAlign_ v_align{VAlign_::kTop}; UIV1Python::ObjID call{UIV1Python::ObjID::kEmptyCall}; uint32_t visibility_mask{}; bool selectable{true}; @@ -59,10 +60,10 @@ struct RootWidget::ButtonDef { float post_buffer{0.0f}; }; -struct RootWidget::Button { +struct RootWidget::Button_ { Object::Ref widget; float h_align{}; - VAlign v_align{VAlign::kTop}; + VAlign_ v_align{VAlign_::kTop}; float x{}; // user provided x float y{}; // user provided y float y_offs_small{}; // user provided y offset for small uiscale @@ -86,8 +87,8 @@ struct RootWidget::Button { }; // For adding text label decorations to buttons. -struct RootWidget::TextDef { - Button* button{}; +struct RootWidget::TextDef_ { + Button_* button{}; float x{}; float y{}; float width{-1.0f}; @@ -103,16 +104,16 @@ struct RootWidget::TextDef { std::string text; }; -struct RootWidget::Text { - Button* button{}; +struct RootWidget::Text_ { + Button_* button{}; Object::Ref widget; float x{}; float y{}; bool visible{true}; }; -struct RootWidget::ImageDef { - Button* button{}; +struct RootWidget::ImageDef_ { + Button_* button{}; float x{}; float y{}; float width{32.0f}; @@ -125,8 +126,8 @@ struct RootWidget::ImageDef { std::string img; }; -struct RootWidget::Image { - Button* button{}; +struct RootWidget::Image_ { + Button_* button{}; Object::Ref widget; float x{}; float y{}; @@ -144,18 +145,18 @@ RootWidget::RootWidget() { RootWidget::~RootWidget() = default; -void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, +void RootWidget::AddMeter_(MeterType_ type, float h_align, float r, float g, float b, bool plus, const std::string& s) { float y_offs_small{7.0f}; - float width = (type == MeterType::kTrophy) ? 80.0f : 110.0f; + float width = (type == MeterType_::kTrophy) ? 80.0f : 110.0f; width = 110.0f; // Bar. { - ButtonDef bd; + ButtonDef_ bd; bd.h_align = h_align; - bd.v_align = VAlign::kTop; + bd.v_align = VAlign_::kTop; bd.width = width; bd.height = 36.0f; bd.y = -36.0f + 10.0f - y_offs_small; @@ -170,7 +171,7 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, bd.depth_min = 0.3f; - if (type == MeterType::kLevel && !kShowLevels) { + if (type == MeterType_::kLevel && !kShowLevels) { // Keep levels hidden always. } else { bd.visibility_mask = @@ -181,14 +182,14 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, bd.allow_in_game = false; // Show some in store mode. - if (type == MeterType::kLevel || type == MeterType::kTickets) { + if (type == MeterType_::kLevel || type == MeterType_::kTickets) { bd.visibility_mask |= static_cast(Widget::ToolbarVisibility::kMenuStore) | static_cast( Widget::ToolbarVisibility::kMenuStoreNoBack); } // Show some in get-tokens/tokens mode - if (type == MeterType::kTokens) { + if (type == MeterType_::kTokens) { bd.visibility_mask |= static_cast(Widget::ToolbarVisibility::kGetTokens) | static_cast(Widget::ToolbarVisibility::kMenuTokens); @@ -197,16 +198,16 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, // Adjust buffer between neighbors. switch (type) { - case MeterType::kLevel: + case MeterType_::kLevel: bd.pre_buffer = 50.0f; break; - case MeterType::kTrophy: + case MeterType_::kTrophy: bd.pre_buffer = 50.0f; break; - case MeterType::kTickets: + case MeterType_::kTickets: bd.pre_buffer = 50.0f; break; - case MeterType::kTokens: + case MeterType_::kTokens: bd.pre_buffer = 50.0f; break; default: @@ -215,16 +216,16 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, // Extend button target areas to cover where icon will go. switch (type) { - case MeterType::kLevel: + case MeterType_::kLevel: bd.target_extra_left = 40.0f; break; - case MeterType::kTrophy: + case MeterType_::kTrophy: bd.target_extra_left = 40.0f; break; - case MeterType::kTickets: + case MeterType_::kTickets: bd.target_extra_right = 40.0f; break; - case MeterType::kTokens: + case MeterType_::kTokens: bd.target_extra_right = 40.0f; break; default: @@ -232,39 +233,39 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, } switch (type) { - case MeterType::kLevel: + case MeterType_::kLevel: bd.call = UIV1Python::ObjID::kRootUILevelIconPressCall; break; - case MeterType::kTrophy: + case MeterType_::kTrophy: bd.call = UIV1Python::ObjID::kRootUITrophyMeterPressCall; break; - case MeterType::kTokens: + case MeterType_::kTokens: bd.call = UIV1Python::ObjID::kRootUITokensMeterPressCall; break; - case MeterType::kTickets: + case MeterType_::kTickets: bd.call = UIV1Python::ObjID::kRootUITicketIconPressCall; break; default: break; } - Button* btn = AddButton_(bd); + Button_* btn = AddButton_(bd); // Store the bar button in some cases. switch (type) { - case MeterType::kLevel: + case MeterType_::kLevel: level_meter_button_ = btn; top_left_buttons_.push_back(btn); break; - case MeterType::kTrophy: + case MeterType_::kTrophy: trophy_meter_button_ = btn; top_left_buttons_.push_back(btn); break; - case MeterType::kTickets: + case MeterType_::kTickets: tickets_meter_button_ = btn; top_right_buttons_.push_back(btn); break; - case MeterType::kTokens: + case MeterType_::kTokens: tokens_meter_button_ = btn; top_right_buttons_.push_back(btn); break; @@ -274,7 +275,7 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, // Bar value text. { - TextDef td; + TextDef_ td; td.button = btn; td.width = bd.width * 0.7f; td.text = s; @@ -284,16 +285,16 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, td.depth_min = 0.3f; auto* text = AddText_(td); switch (type) { - case MeterType::kTickets: + case MeterType_::kTickets: tickets_meter_text_ = text; break; - case MeterType::kTokens: + case MeterType_::kTokens: tokens_meter_text_ = text; break; - case MeterType::kTrophy: + case MeterType_::kTrophy: league_rank_text_ = text; break; - case MeterType::kLevel: + case MeterType_::kLevel: xp_text_ = text; break; default: @@ -303,9 +304,9 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, // Icon on side. { - ImageDef imgd; + ImageDef_ imgd; imgd.button = btn; - if (type == MeterType::kLevel || type == MeterType::kTrophy) { + if (type == MeterType_::kLevel || type == MeterType_::kTrophy) { imgd.x = -0.5 * width - 10.0f; } else { imgd.x = 0.5 * width + 10.0f; @@ -315,16 +316,16 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, imgd.width = 54.0f; imgd.height = 54.0f; switch (type) { - case MeterType::kLevel: + case MeterType_::kLevel: imgd.img = "levelIcon"; break; - case MeterType::kTrophy: + case MeterType_::kTrophy: imgd.img = "trophy"; break; - case MeterType::kTokens: + case MeterType_::kTokens: imgd.img = "coin"; break; - case MeterType::kTickets: + case MeterType_::kTickets: imgd.img = "tickets"; break; default: @@ -333,15 +334,15 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, imgd.depth_min = 0.3f; auto* img = AddImage_(imgd); switch (type) { - case MeterType::kTrophy: + case MeterType_::kTrophy: trophy_icon_ = img; default: break; } // Level num. - if (type == MeterType::kLevel) { - TextDef td; + if (type == MeterType_::kLevel) { + TextDef_ td; td.button = btn; td.width = imgd.width * 0.8f; td.text = "12"; @@ -361,9 +362,9 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, // Plus button. if (plus) { - ButtonDef bd; + ButtonDef_ bd; bd.h_align = h_align; - bd.v_align = VAlign::kTop; + bd.v_align = VAlign_::kTop; bd.width = bd.height = 45.0f; // bd.x = x - 68; bd.y = -36.0f + 11.0f - y_offs_small; @@ -375,7 +376,7 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, bd.color_b = 0.55f; bd.depth_min = 0.3f; switch (type) { - case MeterType::kTokens: + case MeterType_::kTokens: bd.call = UIV1Python::ObjID::kRootUIGetTokensButtonPressCall; break; default: @@ -387,13 +388,13 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, | static_cast(Widget::ToolbarVisibility::kMenuFullRoot)); // Show some in store mode. - if (type == MeterType::kLevel || type == MeterType::kTickets) { + if (type == MeterType_::kLevel || type == MeterType_::kTickets) { bd.visibility_mask |= static_cast(Widget::ToolbarVisibility::kMenuStore) | static_cast(Widget::ToolbarVisibility::kMenuStoreNoBack); } // Show some in tokens mode. - if (type == MeterType::kTokens) { + if (type == MeterType_::kTokens) { bd.visibility_mask |= static_cast(Widget::ToolbarVisibility::kMenuTokens); } @@ -401,8 +402,8 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, bd.pre_buffer = -10.0f; bd.allow_in_game = false; - Button* btn = AddButton_(bd); - if (type == MeterType::kTokens) { + Button_* btn = AddButton_(bd); + if (type == MeterType_::kTokens) { get_tokens_button_ = btn; } top_right_buttons_.push_back(btn); @@ -412,9 +413,9 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g, void RootWidget::Setup() { // Back button. { - ButtonDef bd; + ButtonDef_ bd; bd.h_align = 0.0f; - bd.v_align = VAlign::kTop; + bd.v_align = VAlign_::kTop; bd.width = bd.height = 140.0f; bd.color_r = 0.7f; bd.color_g = 0.4f; @@ -429,11 +430,11 @@ void RootWidget::Setup() { | static_cast(Widget::ToolbarVisibility::kGetTokens) | static_cast(Widget::ToolbarVisibility::kMenuTokens)); bd.pre_buffer = -30.0f; - Button* b = back_button_ = AddButton_(bd); + Button_* b = back_button_ = AddButton_(bd); top_left_buttons_.push_back(b); { - TextDef td; + TextDef_ td; td.button = b; td.x = 5.0f; td.y = 3.0f; @@ -449,9 +450,9 @@ void RootWidget::Setup() { // Top bar backing (currency only). if (explicit_bool(false)) { - ButtonDef bd; + ButtonDef_ bd; bd.h_align = 0.5f; - bd.v_align = VAlign::kTop; + bd.v_align = VAlign_::kTop; bd.width = 370.0f; bd.height = 90.0f; bd.x = 256.0f; @@ -472,9 +473,9 @@ void RootWidget::Setup() { // Top bar backing. if (explicit_bool(false)) { - ButtonDef bd; + ButtonDef_ bd; bd.h_align = 0.5f; - bd.v_align = VAlign::kTop; + bd.v_align = VAlign_::kTop; bd.width = 850.0f; bd.height = 90.0f; bd.x = 0.0f; @@ -498,9 +499,9 @@ void RootWidget::Setup() { // Account Button { - ButtonDef bd; + ButtonDef_ bd; bd.h_align = 0.0f; - bd.v_align = VAlign::kTop; + bd.v_align = VAlign_::kTop; bd.width = 160.0f; bd.height = 60.0f; bd.depth_min = 0.3f; @@ -518,12 +519,12 @@ void RootWidget::Setup() { bd.allow_in_game = false; - Button* b = account_button_ = AddButton_(bd); + Button_* b = account_button_ = AddButton_(bd); top_left_buttons_.push_back(b); // Player name. { - TextDef td; + TextDef_ td; td.button = b; td.y = 0.0f; td.width = bd.width * 0.8f; @@ -537,15 +538,15 @@ void RootWidget::Setup() { account_name_text_ = AddText_(td); } } - AddMeter_(MeterType::kLevel, 0.0f, 1.0f, 1.0f, 1.0f, false, ""); - AddMeter_(MeterType::kTrophy, 0.0f, 1.0f, 1.0f, 1.0f, false, ""); + AddMeter_(MeterType_::kLevel, 0.0f, 1.0f, 1.0f, 1.0f, false, ""); + AddMeter_(MeterType_::kTrophy, 0.0f, 1.0f, 1.0f, 1.0f, false, ""); // Menu button (only shows up when we're not in a menu). // FIXME - this should never be visible on TV or VR UI modes { - ButtonDef b; + ButtonDef_ b; b.h_align = 1.0f; - b.v_align = VAlign::kTop; + b.v_align = VAlign_::kTop; b.width = b.height = 65.0f; // b.x = -36.0f; b.y = b.height * -0.48f; @@ -573,9 +574,9 @@ void RootWidget::Setup() { // Squad button. { - ButtonDef b; + ButtonDef_ b; b.h_align = 1.0f; - b.v_align = VAlign::kTop; + b.v_align = VAlign_::kTop; b.width = b.height = 70.0f; b.y = b.height * -0.41f; b.img = "usersButton"; @@ -598,7 +599,7 @@ void RootWidget::Setup() { top_right_buttons_.push_back(squad_button_); { - TextDef td; + TextDef_ td; td.button = squad_button_; td.width = 70.0f; td.text = "0"; @@ -616,14 +617,14 @@ void RootWidget::Setup() { } } - AddMeter_(MeterType::kTokens, 1.0f, 1.0f, 1.0f, 1.0f, true, ""); - AddMeter_(MeterType::kTickets, 1.0f, 1.0f, 1.0f, 1.0f, false, ""); + AddMeter_(MeterType_::kTokens, 1.0f, 1.0f, 1.0f, 1.0f, true, ""); + AddMeter_(MeterType_::kTickets, 1.0f, 1.0f, 1.0f, 1.0f, false, ""); // Inbox button. { - ButtonDef b; + ButtonDef_ b; b.h_align = 0.0f; - b.v_align = VAlign::kBottom; + b.v_align = VAlign_::kBottom; b.width = b.height = 60.0f; // b.x = bx; b.y = b.height * 0.5f + 2.0f; @@ -644,7 +645,7 @@ void RootWidget::Setup() { // Inbox count circle backing. { - ImageDef imgd; + ImageDef_ imgd; imgd.button = inbox_button_; imgd.x = 18.0f; imgd.y = 24.0f; @@ -660,7 +661,7 @@ void RootWidget::Setup() { } // Inbox count number. { - TextDef td; + TextDef_ td; td.button = inbox_button_; td.width = 24.0f; td.text = "2"; @@ -679,9 +680,9 @@ void RootWidget::Setup() { // Achievements button. if (explicit_bool(true)) { - ButtonDef b; + ButtonDef_ b; b.h_align = 0.0f; - b.v_align = VAlign::kBottom; + b.v_align = VAlign_::kBottom; b.width = b.height = 60.0f; b.y = b.height * 0.5f + 2.0f; b.color_r = kBotLeftColorR; @@ -701,7 +702,7 @@ void RootWidget::Setup() { auto centerx = -1.5f; auto centery = 8.0f; { - TextDef td; + TextDef_ td; td.button = achievements_button_; td.width = 26.0f; td.text = ""; @@ -720,9 +721,9 @@ void RootWidget::Setup() { // Leaderboards button. if (explicit_bool(false)) { - ButtonDef b; + ButtonDef_ b; b.h_align = 0.0f; - b.v_align = VAlign::kBottom; + b.v_align = VAlign_::kBottom; b.width = b.height = 60.0f; // b.x = bx; b.y = b.height * 0.5f + 2.0f; @@ -740,9 +741,9 @@ void RootWidget::Setup() { // Settings button. { - ButtonDef b; + ButtonDef_ b; b.h_align = 0.0f; - b.v_align = VAlign::kBottom; + b.v_align = VAlign_::kBottom; b.width = b.height = 60.0f; // b.x = bx; b.y = b.height * 0.58f - 2.0f; @@ -779,9 +780,9 @@ void RootWidget::Setup() { // Bar backing. { - ButtonDef bd; + ButtonDef_ bd; bd.h_align = 0.5f; - bd.v_align = VAlign::kBottom; + bd.v_align = VAlign_::kBottom; bd.width = 500.0f; bd.height = 100.0f; bd.x = 0.0f; @@ -801,51 +802,50 @@ void RootWidget::Setup() { | static_cast(Widget::ToolbarVisibility::kMenuFullNoBack) | static_cast(Widget::ToolbarVisibility::kMenuFullRoot)); bd.allow_in_game = false; - AddButton_(bd); + chest_backing_ = AddButton_(bd); } - ButtonDef b; + ButtonDef_ b; b.h_align = 0.5f; - b.v_align = VAlign::kBottom; - b.width = b.height = 110.0f; - b.x = 0.0f; - b.y = b.height * 0.4f; - b.img = "chestIcon"; + b.v_align = VAlign_::kBottom; b.depth_min = 0.3f; b.visibility_mask = (static_cast(Widget::ToolbarVisibility::kMenuFull) | static_cast(Widget::ToolbarVisibility::kMenuFullNoBack) | static_cast(Widget::ToolbarVisibility::kMenuFullRoot)); float spacing = 120.0f; - b.x = -1.5f * spacing; - b.call = UIV1Python::ObjID::kRootUIChestSlot1PressCall; b.allow_in_game = false; - AddButton_(b); - b.y = b.height * 0.4f; - b.x = 0.5f * spacing; + b.y = 44.0f; b.img = "chestIconEmpty"; b.width = b.height = 80.0f; b.color_r = backing_cover_r; b.color_g = backing_cover_g; b.color_b = backing_cover_b; b.opacity = 1.0f; - b.call = UIV1Python::ObjID::kRootUIChestSlot2PressCall; + + b.call = UIV1Python::ObjID::kRootUIChestSlot0PressCall; + b.x = -1.5f * spacing; + chest_0_button_ = AddButton_(b); + + b.call = UIV1Python::ObjID::kRootUIChestSlot1PressCall; b.x = -0.5f * spacing; - AddButton_(b); + chest_1_button_ = AddButton_(b); + b.x = 0.5f * spacing; - b.call = UIV1Python::ObjID::kRootUIChestSlot3PressCall; - AddButton_(b); + b.call = UIV1Python::ObjID::kRootUIChestSlot2PressCall; + chest_2_button_ = AddButton_(b); + b.x = 1.5f * spacing; - b.call = UIV1Python::ObjID::kRootUIChestSlot4PressCall; - AddButton_(b); + b.call = UIV1Python::ObjID::kRootUIChestSlot3PressCall; + chest_3_button_ = AddButton_(b); } // Inventory button. { - ButtonDef b; + ButtonDef_ b; b.h_align = 1.0f; - b.v_align = VAlign::kBottom; + b.v_align = VAlign_::kBottom; b.width = b.height = 135.0f; // b.x = -80.0f; b.y = b.height * 0.45f; @@ -864,9 +864,9 @@ void RootWidget::Setup() { // Store button. { - ButtonDef b; + ButtonDef_ b; b.h_align = 1.0f; - b.v_align = VAlign::kBottom; + b.v_align = VAlign_::kBottom; b.width = b.height = 85.0f; // b.x = -206.0f; b.y = b.height * 0.5f; @@ -901,10 +901,10 @@ void RootWidget::Draw(base::RenderPass* pass, bool transparent) { ContainerWidget::Draw(pass, transparent); } -auto RootWidget::AddButton_(const ButtonDef& def) -> RootWidget::Button* { +auto RootWidget::AddButton_(const ButtonDef_& def) -> RootWidget::Button_* { base::ScopedSetContext ssc(nullptr); buttons_.emplace_back(); - Button& b(buttons_.back()); + Button_& b(buttons_.back()); b.x = b.x_smoothed = b.x_target = def.x; b.y = b.y_smoothed = b.y_target = def.y; b.y_offs_small = def.y_offs_small; @@ -935,8 +935,8 @@ auto RootWidget::AddButton_(const ButtonDef& def) -> RootWidget::Button* { // Make sure up/down moves focus into the main stack. assert(screen_stack_widget_ != nullptr); - assert(b.v_align != VAlign::kCenter); - if (b.v_align == VAlign::kTop) { + assert(b.v_align != VAlign_::kCenter); + if (b.v_align == VAlign_::kTop) { b.widget->SetDownWidget(screen_stack_widget_); } else { b.widget->SetUpWidget(screen_stack_widget_); @@ -965,10 +965,10 @@ auto RootWidget::AddButton_(const ButtonDef& def) -> RootWidget::Button* { return &b; } -auto RootWidget::AddText_(const TextDef& def) -> RootWidget::Text* { +auto RootWidget::AddText_(const TextDef_& def) -> RootWidget::Text_* { base::ScopedSetContext ssc(nullptr); texts_.emplace_back(); - Text& t(texts_.back()); + Text_& t(texts_.back()); t.button = def.button; t.widget = Object::New(); t.widget->SetWidth(0.0f); @@ -990,10 +990,10 @@ auto RootWidget::AddText_(const TextDef& def) -> RootWidget::Text* { return &t; } -auto RootWidget::AddImage_(const ImageDef& def) -> RootWidget::Image* { +auto RootWidget::AddImage_(const ImageDef_& def) -> RootWidget::Image_* { base::ScopedSetContext ssc(nullptr); images_.emplace_back(); - Image& img(images_.back()); + Image_& img(images_.back()); img.button = def.button; img.widget = Object::New(); img.widget->set_width(def.width); @@ -1044,7 +1044,7 @@ void RootWidget::StepChildWidgets_(float dt) { bool is_small{g_base->ui->scale() == UIScale::kSmall}; // Update enabled-state for all buttons. - for (Button& b : buttons_) { + for (Button_& b : buttons_) { bool enable_button = static_cast(static_cast(toolbar_visibility_) & static_cast(b.visibility_mask)); @@ -1128,12 +1128,12 @@ void RootWidget::StepChildWidgets_(float dt) { // Go through our buttons updating their target points and smooth values. // If everything has arrived at its target point, mark us as not dirty. bool have_dirty = false; - for (Button& b : buttons_) { + for (Button_& b : buttons_) { // Update our target position. b.x_target = b.x; b.y_target = b.y + (is_small ? b.y_offs_small : 0.0f); float disable_offset = b.disable_offset_scale * 110.0f - * ((b.v_align == VAlign::kTop) ? 1.0f : -1.0f); + * ((b.v_align == VAlign_::kTop) ? 1.0f : -1.0f); // Can turn this down to debug visibility. if (explicit_bool(false)) { @@ -1183,14 +1183,14 @@ void RootWidget::StepChildWidgets_(float dt) { x = width() * b.h_align + base_scale_ * (b.x_smoothed - b.width * b.scale * 0.5f); switch (b.v_align) { - case VAlign::kTop: + case VAlign_::kTop: y = height() + base_scale_ * (b.y_smoothed - b.height * b.scale * 0.5f); break; - case VAlign::kCenter: + case VAlign_::kCenter: y = height() * 0.5f + base_scale_ * (b.y_smoothed - b.height * b.scale * 0.5f); break; - case VAlign::kBottom: + case VAlign_::kBottom: y = base_scale_ * (b.y_smoothed - b.height * b.scale * 0.5f); break; } @@ -1202,9 +1202,9 @@ void RootWidget::StepChildWidgets_(float dt) { b.widget->set_scale(b.scale * base_scale_); } - for (Text& t : texts_) { + for (Text_& t : texts_) { // Move the text widget to wherever its target button is (plus offset). - Button* b = t.button; + Button_* b = t.button; float x = b->widget->tx() + base_scale_ * b->scale * (b->width * 0.5f + t.x); float y = @@ -1214,9 +1214,9 @@ void RootWidget::StepChildWidgets_(float dt) { t.widget->set_visible_in_container(!b->fully_offscreen && t.visible); } - for (Image& img : images_) { + for (Image_& img : images_) { // Move the image widget to wherever its target button is (plus offset). - Button* b = img.button; + Button_* b = img.button; float x = b->widget->tx() + base_scale_ * b->scale * (b->width * 0.5f + img.x); float y = @@ -1385,6 +1385,7 @@ void RootWidget::SetTokensMeterText(const std::string& val, bool gold_pass) { assert(get_tokens_button_); if (gold_pass) { get_tokens_button_->force_hide = true; + // Use the infinity symbol if we have full unicode support. tokens_meter_text_->widget->SetText( g_buildconfig.enable_os_font_rendering() ? "\xE2\x88\x9E" : "inf"); @@ -1394,7 +1395,8 @@ void RootWidget::SetTokensMeterText(const std::string& val, bool gold_pass) { tokens_meter_text_->widget->SetText(val); tokens_meter_text_->widget->set_color(1.0f, 1.0f, 1.0f, 1.0f); } - MarkForUpdate(); + // May need to animate in/out. + child_widgets_dirty_ = true; } void RootWidget::SetLeagueRankText(const std::string& val) { @@ -1438,6 +1440,55 @@ void RootWidget::SetXPText(const std::string& val) { xp_text_->widget->SetText(val); } +void RootWidget::SetChests(const std::string& chest_0_appearance, + const std::string& chest_1_appearance, + const std::string& chest_2_appearance, + const std::string& chest_3_appearance) { + std::vector> pairs = { + {chest_0_appearance, chest_0_button_}, + {chest_1_appearance, chest_1_button_}, + {chest_2_appearance, chest_2_button_}, + {chest_3_appearance, chest_3_button_}, + }; + + auto have_chests{false}; + for (const auto& [appearance, b] : pairs) { + if (appearance != "") { + have_chests = true; + } + } + + for (const auto& [appearance, b] : pairs) { + assert(b); + if (appearance == "") { + b->widget->set_color(0.473f, 0.44f, 0.583f); + b->widget->set_opacity(0.5f); + b->width = b->height = 80.0f; + b->y = have_chests ? 44.0f : 0.0f; + { + base::Assets::AssetListLock lock; + b->widget->SetTexture( + g_base->assets->GetTexture("chestIconEmpty").get()); + } + } else { + have_chests = true; + b->widget->set_color(1.0f, 1.0f, 1.0f); + b->widget->set_opacity(1.0f); + b->width = b->height = 110.0f; + b->y = 44.0f; + { + base::Assets::AssetListLock lock; + b->widget->SetTexture(g_base->assets->GetTexture("chestIcon").get()); + } + } + } + assert(chest_backing_); + chest_backing_->y = have_chests ? 41.0f : -10.0f; + chest_backing_->widget->set_opacity(have_chests ? 1.0f : 0.5f); + + child_widgets_dirty_ = true; +} + void RootWidget::SetInboxCountText(const std::string& val) { assert(inbox_count_text_); diff --git a/src/ballistica/ui_v1/widget/root_widget.h b/src/ballistica/ui_v1/widget/root_widget.h index a8ba6b7a..ec3ad660 100644 --- a/src/ballistica/ui_v1/widget/root_widget.h +++ b/src/ballistica/ui_v1/widget/root_widget.h @@ -47,66 +47,77 @@ class RootWidget : public ContainerWidget { void SetLevelText(const std::string& val); void SetXPText(const std::string& val); void SetInboxCountText(const std::string& val); + void SetChests(const std::string& chest_0_appearance, + const std::string& chest_1_appearance, + const std::string& chest_2_appearance, + const std::string& chest_3_appearance); auto bottom_left_height() const { return bottom_left_height_; } private: + struct ButtonDef_; + struct Button_; + struct TextDef_; + struct ImageDef_; + struct Text_; + struct Image_; + enum class MeterType_ { kLevel, kTrophy, kTickets, kTokens }; + enum class VAlign_ { kTop, kCenter, kBottom }; + void UpdateTokensMeterText_(); - struct ButtonDef; - struct Button; - struct TextDef; - struct ImageDef; - struct Text; - struct Image; - enum class MeterType { kLevel, kTrophy, kTickets, kTokens }; - enum class VAlign { kTop, kCenter, kBottom }; void UpdateForFocusedWindow_(Widget* widget); - auto AddButton_(const ButtonDef& def) -> Button*; - auto AddText_(const TextDef& def) -> Text*; - auto AddImage_(const ImageDef& def) -> Image*; + auto AddButton_(const ButtonDef_& def) -> Button_*; + auto AddText_(const TextDef_& def) -> Text_*; + auto AddImage_(const ImageDef_& def) -> Image_*; void StepChildWidgets_(float dt); - void AddMeter_(MeterType type, float h_align, float r, float g, float b, + void AddMeter_(MeterType_ type, float h_align, float r, float g, float b, bool plus, const std::string& s); - ToolbarVisibility toolbar_visibility_{ToolbarVisibility::kInGame}; + + std::list buttons_; + std::list texts_; + std::list images_; + std::vector top_left_buttons_; + std::vector top_right_buttons_; + std::vector bottom_left_buttons_; + std::vector bottom_right_buttons_; StackWidget* screen_stack_widget_{}; StackWidget* overlay_stack_widget_{}; + Button_* back_button_{}; + Button_* account_button_{}; + Button_* achievements_button_{}; + Button_* inbox_button_{}; + Button_* tickets_meter_button_{}; + Button_* tokens_meter_button_{}; + Button_* trophy_meter_button_{}; + Button_* settings_button_{}; + Button_* store_button_{}; + Button_* get_tokens_button_{}; + Button_* inventory_button_{}; + Button_* menu_button_{}; + Button_* squad_button_{}; + Button_* level_meter_button_{}; + Button_* chest_0_button_{}; + Button_* chest_1_button_{}; + Button_* chest_2_button_{}; + Button_* chest_3_button_{}; + Button_* chest_backing_{}; + Image_* trophy_icon_{}; + Image_* inbox_count_backing_{}; + Text_* squad_size_text_{}; + Text_* account_name_text_{}; + Text_* tickets_meter_text_{}; + Text_* tokens_meter_text_{}; + Text_* league_rank_text_{}; + Text_* achievement_percent_text_{}; + Text_* level_text_{}; + Text_* xp_text_{}; + Text_* inbox_count_text_{}; float base_scale_{1.0f}; float bottom_left_height_{}; millisecs_t update_time_{}; - std::list