main-windows can now auto-refresh for screen size changes

This commit is contained in:
Eric Froemling 2025-01-21 13:54:59 -08:00
parent 81339dd31b
commit ac13f28d90
No known key found for this signature in database
29 changed files with 244 additions and 125 deletions

84
.efrocachemap generated
View File

@ -432,7 +432,7 @@
"build/assets/ba_data/audio/zoeOw.ogg": "b2d705c31c9dcc1efdc71394764c3beb",
"build/assets/ba_data/audio/zoePickup01.ogg": "e9366dc2d2b8ab8b0c4e2c14c02d0789",
"build/assets/ba_data/audio/zoeScream01.ogg": "903e0e45ee9b3373e9d9ce20c814374e",
"build/assets/ba_data/data/langdata.json": "cd059a1e20ac384f763c6386038837d8",
"build/assets/ba_data/data/langdata.json": "bf0ed9fa002ad530d64ba801b617a527",
"build/assets/ba_data/data/languages/arabic.json": "32b9849fb8389b8c7798f0b744620318",
"build/assets/ba_data/data/languages/belarussian.json": "009b452aa308bf2b2f7e92d9b78ba5ff",
"build/assets/ba_data/data/languages/chinese.json": "5363a79f843e6be7ef47a840f47cc17d",
@ -441,17 +441,17 @@
"build/assets/ba_data/data/languages/czech.json": "3418bee44e69be13b7f72996abe96921",
"build/assets/ba_data/data/languages/danish.json": "8e57db30c5250df2abff14a822f83ea7",
"build/assets/ba_data/data/languages/dutch.json": "4ba5bbcc0fecddd0aac6ee2c165d1e40",
"build/assets/ba_data/data/languages/english.json": "5506f0629e42604eb62c92bed4551d3b",
"build/assets/ba_data/data/languages/english.json": "856ba013c0680d69038988df7f04caa1",
"build/assets/ba_data/data/languages/esperanto.json": "0e397cfa5f3fb8cef5f4a64f21cda880",
"build/assets/ba_data/data/languages/filipino.json": "1894fc331dcad7ce9cf4c180843f548f",
"build/assets/ba_data/data/languages/french.json": "6d20655730b1017ef187fd828b91d43c",
"build/assets/ba_data/data/languages/german.json": "bc656f1ada467161c23546f48d0dacc5",
"build/assets/ba_data/data/languages/gibberish.json": "85b93e21e4969e2e3eceb26f1f66237c",
"build/assets/ba_data/data/languages/gibberish.json": "e6c107495d2788f8a2f876986ca1af35",
"build/assets/ba_data/data/languages/greek.json": "d28d1092fbb00ed857cbd53124c0dc78",
"build/assets/ba_data/data/languages/hindi.json": "567e6976b3c72f891431ad7fcc62ab16",
"build/assets/ba_data/data/languages/hungarian.json": "af801baffb2c06460635dfb04c34bb3e",
"build/assets/ba_data/data/languages/indonesian.json": "607ba358179185f032096ea1978e4448",
"build/assets/ba_data/data/languages/italian.json": "254d4d3962fda17fe127636fa6221851",
"build/assets/ba_data/data/languages/italian.json": "8ed7e5b3a277ed1576af100fc944ef7e",
"build/assets/ba_data/data/languages/korean.json": "360760d72832863e1a3451b0a514cb08",
"build/assets/ba_data/data/languages/malay.json": "0212e18e54efa202c17505376e5b82fb",
"build/assets/ba_data/data/languages/persian.json": "517217e679c768fff4ffec7f8000ab77",
@ -462,7 +462,7 @@
"build/assets/ba_data/data/languages/russian.json": "70cd57440e4cbb49f2fa0c79dedcafbe",
"build/assets/ba_data/data/languages/serbian.json": "623fa4129a1154c2f32ed7867e56ff6a",
"build/assets/ba_data/data/languages/slovak.json": "c11c29708b3742cdc2a92b4fa0d6d29f",
"build/assets/ba_data/data/languages/spanish.json": "8c319f6e50275fb0a22d5f1bd4b7f1e0",
"build/assets/ba_data/data/languages/spanish.json": "5bc22761e8a37cbdf38d4bced753b6ba",
"build/assets/ba_data/data/languages/swedish.json": "3b179e7333183c70adb0811246b09959",
"build/assets/ba_data/data/languages/tamil.json": "ead39b864228696a9b0d19344bc4b5ec",
"build/assets/ba_data/data/languages/thai.json": "383540a1e9c7c131ac579f51afc87471",
@ -4174,46 +4174,46 @@
"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": "490075b1f0f409dac071e27dc3a5396a",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "60efb54d98253d7d97021efc3dbcbd59",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "9c6eb8e03faf95e6902adb8bfde24a8b",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "bd670699053a1e0d474ee345f4edd656",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "3741d31a0f0dd0422a85f04e0ff0fa3f",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "32c46e38a916c8176322a910efcbcb3b",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "fd8708e164382c48edfbf9c7544a6e38",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "bc05c6a771e4defb28cdb7ca0561a689",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "99ec5b6f6cf2d0f925cb06ce7f8ab805",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "f4f245a47dc0279051dadd007959b689",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "28245a834bb409b6f11e90458c1624e2",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "1aa5230ba881011366f1d9fb9a895d3d",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "1e72ce51c2c2d2f1f2550a52ac3fc344",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "ecc96fe59adc13ea67e1d2e50b253b7a",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "aa0a5767a0eea6d4723ff54cc43cd81c",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "44091a64667a2c06f548a29805890321",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "7497894d2943b75b6ac830cdba8481af",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "273a6f64cac5a233694223b85cd0f22b",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "7497894d2943b75b6ac830cdba8481af",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "273a6f64cac5a233694223b85cd0f22b",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "6f4d0f923e186f013e20d894ce3cf5f0",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "f9866ec5b496b5565cad36eebb695507",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "6f4d0f923e186f013e20d894ce3cf5f0",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "f9866ec5b496b5565cad36eebb695507",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "55a2b0c2d1db4d70627c901471d05fc7",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "7e071962108a8d1727525fb331b70ee4",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "55a2b0c2d1db4d70627c901471d05fc7",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "7e071962108a8d1727525fb331b70ee4",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "ed2d35d12c3abb5113b4725c25076532",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "bfa9e7ac4d012d9d3556fd1401055a14",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "a4dd8c160b5cde72d93b7627950ea755",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "5a730a358d15ddb2f18cd58505941409",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "5db366eeb98b8366ef8f1878f22c0e95",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "b368c2712eb5b1296cac5a35b2ef910e",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "37677230e1b27a733c90552eaa227691",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "efffad67c4056754c29d88010c239175",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "677778a5f7114170c50602335fc3ddf1",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "8887729af3137c9709ee10b70f353786",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "2f9c170609a70d52d3bca2a1fcfe31d6",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "97220018e9d2fb42421d3fb2d7d98d47",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "22e38fabd263a4e639c69c901408e56d",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "9ce287d7714226daa851880f79c38d05",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "a53442bb694a34052bc5de9cc8a27f59",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "69b314b2d8528d226ef1b40f5b02e711",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "251b40efe83b7dfa917be97f86c73f48",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "008d0196de947e99620005d158880336",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "f0f93e610bb29895fd523899269add39",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "36a30c52a024f465d9c40f5fc42323e1",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "d7ebdc77b3ebd9e4f8a03bce5937202c",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "acb0ab12e1883cd54a6384a8ef6aacb5",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "fe4557d5dc57a3bb3281db2ab745fa5b",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "9c2829fc79d58705520f8d73d411afb4",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "4d70703c4eba1a402fbc2d997d84aa93",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "bb64e2182b1a533679f93c5997f14584",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "4d70703c4eba1a402fbc2d997d84aa93",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "bb64e2182b1a533679f93c5997f14584",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "1d25993b7cd4676d3884781b002edf53",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "ab6f04d0fb73d88ccbd3c65e73ead01f",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "1d25993b7cd4676d3884781b002edf53",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "ab6f04d0fb73d88ccbd3c65e73ead01f",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "e3e9d9c7a94f8cd22939839fd8fbc178",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "116b500c2d57caf06619408b2176e83b",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "e3e9d9c7a94f8cd22939839fd8fbc178",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "116b500c2d57caf06619408b2176e83b",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "654d386245b885f38515f9f9bf7eb501",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "b06edc326b9d47403f2aae52ff26f86c",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "8c6ec7bf96e5139b6252b2a36d63f504",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "4c9c1cc618d134b7da3391562195c034",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "f6debb77214ad953cdb673353cbfd546",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "ff57a7ec1f61492e3af985c49641d4b2",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "c06d91baebd97c6182f0d8ac9c09eacc",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "03a045a22e9eb41e9d6cd6f029aa99b6",
"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",
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "2d228e7c5578261d394f9c407f4becb1",
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "152bd413bf5823d163aa6ca931971f10",
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "8ab156122cde23d9718923abe1b4ae5b",
"src/ballistica/core/mgen/pyembed/binding_core.inc": "217c84a30f866aaca3a4373e82af7db2",
"src/ballistica/core/mgen/pyembed/env.inc": "f015d726b44d2922112fc14d9f146d8b",

View File

@ -1,4 +1,4 @@
### 1.7.37 (build 22222, api 9, 2025-01-20)
### 1.7.37 (build 22226, api 9, 2025-01-21)
- 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.
@ -191,6 +191,12 @@
in various places.
- Tournament now award chests instead of tickets.
- Tournaments are now free to enter if you are running this build or newer.
- (build 22225) Added `babase.get_virtual_screen_size()` to get the current
virtual screen size, and added a `refresh_on_screen_size_changes` arg to the
`MainWindow` class. This can be used to fit windows to the exact screen size,
which is especially useful at the small ui-scale. Generally medium and large
ui-scale windows don't fill the entire screen and can simply stay within the
virtual safe area and don't need to refresh.
### 1.7.36 (build 21944, api 8, 2024-07-26)
- Wired up Tokens, BombSquad's new purchasable currency. The first thing these

View File

@ -1,6 +1,6 @@
cpplint==2.0.0
dmgbuild==1.6.4
filelock==3.16.1
filelock==3.17.0
furo==2024.8.6
mypy==1.14.1
pbxproj==4.2.1

View File

@ -604,8 +604,8 @@ class App:
def set_ui_scale(self, scale: babase.UIScale) -> None:
"""Change ui-scale on the fly.
Currently this is mainly for debugging and will not
be called as part of normal app operation.
Currently this is mainly for debugging and will not be called as
part of normal app operation.
"""
assert _babase.in_logic_thread()
@ -618,10 +618,25 @@ class App:
assert self._subsystem_registration_ended
for subsystem in self._subsystems:
try:
subsystem.on_screen_change()
subsystem.on_ui_scale_change()
except Exception:
logging.exception(
'Error in on_screen_change() for subsystem %s.', subsystem
'Error in on_ui_scale_change() for subsystem %s.', subsystem
)
def on_screen_size_change(self) -> None:
"""Screen size has changed."""
# Inform all app subsystems in the same order they were inited.
# Operate on a copy of the list here because this can be called
# while subsystems are still being added.
for subsystem in self._subsystems.copy():
try:
subsystem.on_screen_size_change()
except Exception:
logging.exception(
'Error in on_screen_size_change() for subsystem %s.',
subsystem,
)
def _set_intent(self, intent: AppIntent) -> None:

View File

@ -54,8 +54,17 @@ class AppSubsystem:
def do_apply_app_config(self) -> None:
"""Called when the app config should be applied."""
def on_screen_change(self) -> None:
"""Called when screen dimensions or ui-scale changes."""
def on_ui_scale_change(self) -> None:
"""Called when screen ui-scale changes.
Will not be called for the initial ui scale.
"""
def on_screen_size_change(self) -> None:
"""Called when the screen size changes.
Will not be called for the initial screen size.
"""
def reset(self) -> None:
"""Reset the subsystem to a default state.

View File

@ -123,24 +123,19 @@ class DevConsoleTabUI(DevConsoleTab):
xoffs = -375
self.text(
'Make sure all interactive UI fits in the'
' virtual bounds at all UI-scales (not counting things'
' that follow screen edges).\n'
'Note that some elements may not reflect UI-scale changes'
' until recreated.',
'Make sure all UIs either fit in the virtual safe area'
' or dynamically respond to screen size changes.',
scale=0.6,
pos=(xoffs + 15, 70),
# h_anchor='left',
h_align='left',
v_align='center',
)
ui_overlay = _babase.get_draw_ui_bounds()
self.button(
'Virtual Bounds ON' if ui_overlay else 'Virtual Bounds OFF',
'Virtual Safe Area ON' if ui_overlay else 'Virtual Safe Area OFF',
pos=(xoffs + 10, 10),
size=(200, 30),
# h_anchor='left',
label_scale=0.6,
call=self.toggle_ui_overlay,
style='bright' if ui_overlay else 'normal',
@ -149,7 +144,6 @@ class DevConsoleTabUI(DevConsoleTab):
self.text(
'UI-Scale',
pos=(xoffs + x - 5, 15),
# h_anchor='left',
h_align='right',
v_align='none',
scale=0.6,
@ -161,7 +155,6 @@ class DevConsoleTabUI(DevConsoleTab):
scale.name.capitalize(),
pos=(xoffs + x, 10),
size=(bwidth, 30),
# h_anchor='left',
label_scale=0.6,
call=partial(_babase.app.set_ui_scale, scale),
style=(

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 = 22222
TARGET_BALLISTICA_BUILD = 22226
TARGET_BALLISTICA_VERSION = '1.7.37'

View File

@ -4,6 +4,7 @@
from __future__ import annotations
import time
import logging
import inspect
import weakref
@ -85,6 +86,10 @@ class UIV1AppSubsystem(babase.AppSubsystem):
self.heading_color = (0.72, 0.7, 0.75)
self.infotextcolor = (0.7, 0.9, 0.7)
self._last_win_recreate_size: tuple[float, float] | None = None
self._last_screen_size_win_recreate_time: float | None = None
self._screen_size_win_recreate_timer: babase.AppTimer | None = None
# Elements in our root UI will call anything here when
# activated.
self.root_ui_calls: dict[
@ -394,12 +399,12 @@ class UIV1AppSubsystem(babase.AppSubsystem):
)
@override
def on_screen_change(self) -> None:
def on_ui_scale_change(self) -> None:
# Update our stored UIScale.
self._update_ui_scale()
# Update native bits (allow root widget to rebuild itself/etc.)
_bauiv1.on_screen_change()
_bauiv1.on_ui_scale_change()
# Lastly, if we have a main window, recreate it to pick up the
# new UIScale/etc.
@ -408,3 +413,57 @@ class UIV1AppSubsystem(babase.AppSubsystem):
winstate = self.save_main_window_state(mainwindow)
self.clear_main_window(transition='instant')
self.restore_main_window_state(winstate)
# Store the size we created this for to avoid redundant
# future recreates.
self._last_win_recreate_size = babase.get_virtual_screen_size()
@override
def on_screen_size_change(self) -> None:
# Recreating a MainWindow is a kinda heavy thing and it doesn't
# seem like we should be doing it at 120hz during a live window
# resize, so let's limit the max rate we do it.
now = time.monotonic()
# 4 refreshes per second seems reasonable.
interval = 0.25
# If there is a timer set already, do nothing.
if self._screen_size_win_recreate_timer is not None:
return
# Ok; there's no timer. Schedule one.
till_update = (
0.0
if self._last_screen_size_win_recreate_time is None
else max(
0.0, self._last_screen_size_win_recreate_time + interval - now
)
)
self._screen_size_win_recreate_timer = babase.AppTimer(
till_update, self._do_screen_size_win_recreate
)
def _do_screen_size_win_recreate(self) -> None:
self._last_screen_size_win_recreate_time = time.monotonic()
self._screen_size_win_recreate_timer = None
# Avoid recreating if we're already at this size. This prevents
# a redundant recreate when ui scale changes.
virtual_screen_size = babase.get_virtual_screen_size()
if virtual_screen_size == self._last_win_recreate_size:
return
mainwindow = self.get_main_window()
if (
mainwindow is not None
and mainwindow.refreshes_on_screen_size_changes
):
winstate = self.save_main_window_state(mainwindow)
self.clear_main_window(transition='instant')
self.restore_main_window_state(winstate)
# Store the size we created this for to avoid redundant
# future recreates.
self._last_win_recreate_size = virtual_screen_size

View File

@ -58,9 +58,11 @@ class MainWindow(Window):
def __init__(
self,
root_widget: bauiv1.Widget,
*,
transition: str | None,
origin_widget: bauiv1.Widget | None,
cleanupcheck: bool = True,
refresh_on_screen_size_changes: bool = False,
):
"""Create a MainWindow given a root widget and transition info.
@ -72,6 +74,12 @@ class MainWindow(Window):
self.main_window_is_top_level: bool = False
# Windows that size tailor themselves to exact screen dimensions
# can pass True for this. Generally this only applies to small
# ui scale and at larger scales windows simply fit in the
# virtual safe area.
self.refreshes_on_screen_size_changes = refresh_on_screen_size_changes
# Windows can be flagged as auxiliary when not related to the
# main UI task at hand. UI code may choose to handle auxiliary
# windows in special ways, such as by implicitly replacing

View File

@ -36,11 +36,8 @@ class AchievementsWindow(bui.MainWindow):
)
# Do some fancy math to fill all available screen area up to the
# size of our backing container.
#
# TODO: We need an auto-refresh mechanism for cases where screen
# size changes under us. Currently one must navigate out and
# back in to properly reflect such changes.
# size of our backing container. This lets us fit to the exact
# screen shape at small ui scale.
screensize = bui.get_virtual_screen_size()
scale = (
2.3
@ -72,6 +69,8 @@ class AchievementsWindow(bui.MainWindow):
),
transition=transition,
origin_widget=origin_widget,
# We're affected by screen size only at small ui-scale.
refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL,
)
if uiscale is bui.UIScale.SMALL:

View File

@ -327,11 +327,8 @@ class InboxWindow(bui.MainWindow):
)
# Do some fancy math to fill all available screen area up to the
# size of our backing container.
#
# TODO: We need an auto-refresh mechanism for cases where screen
# size changes under us. Currently one must navigate out and
# back in to properly reflect such changes.
# size of our backing container. This lets us fit to the exact
# screen shape at small ui scale.
screensize = bui.get_virtual_screen_size()
scale = (
1.74
@ -361,6 +358,8 @@ class InboxWindow(bui.MainWindow):
),
transition=transition,
origin_widget=origin_widget,
# We're affected by screen size only at small ui-scale.
refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL,
)
if uiscale is bui.UIScale.SMALL:

View File

@ -65,11 +65,8 @@ class PlaylistBrowserWindow(bui.MainWindow):
)
# Do some fancy math to fill all available screen area up to the
# size of our backing container.
#
# TODO: We need an auto-refresh mechanism for cases where screen
# size changes under us. Currently one must navigate out and
# back in to properly reflect such changes.
# size of our backing container. This lets us fit to the exact
# screen shape at small ui scale.
screensize = bui.get_virtual_screen_size()
scale = (
1.85
@ -104,6 +101,8 @@ class PlaylistBrowserWindow(bui.MainWindow):
),
transition=transition,
origin_widget=origin_widget,
# We're affected by screen size only at small ui-scale.
refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL,
)
self._back_button: bui.Widget | None

View File

@ -50,11 +50,8 @@ class AdvancedSettingsWindow(bui.MainWindow):
self._menu_open = False
# Do some fancy math to fill all available screen area up to the
# size of our backing container.
#
# TODO: We need an auto-refresh mechanism for cases where screen
# size changes under us. Currently one must navigate out and
# back in to properly reflect such changes.
# size of our backing container. This lets us fit to the exact
# screen shape at small ui scale.
screensize = bui.get_virtual_screen_size()
scale = (
2.04
@ -87,6 +84,8 @@ class AdvancedSettingsWindow(bui.MainWindow):
),
transition=transition,
origin_widget=origin_widget,
# We're affected by screen size only at small ui-scale.
refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL,
)
self._prev_lang = ''

View File

@ -507,13 +507,13 @@ auto BaseFeatureSet::HavePlus() -> bool {
return plus_soft_ != nullptr;
}
void BaseFeatureSet::set_plus(PlusSoftInterface* plus) {
void BaseFeatureSet::SetPlus(PlusSoftInterface* plus) {
assert(plus_soft_ == nullptr);
plus_soft_ = plus;
}
/// Access the plus feature-set. Will throw an exception if not present.
auto BaseFeatureSet::plus() -> PlusSoftInterface* {
auto BaseFeatureSet::Plus() -> PlusSoftInterface* {
if (!plus_soft_ && !tried_importing_plus_) {
python->SoftImportPlus();
// Important to set this *after* import attempt, or a second import
@ -615,7 +615,7 @@ auto BaseFeatureSet::FeatureSetFromData(PyObject* obj)
auto BaseFeatureSet::IsUnmodifiedBlessedBuild() -> bool {
// If we've got plus present, ask them. Otherwise assume no.
if (HavePlus()) {
return plus()->IsUnmodifiedBlessedBuild();
return Plus()->IsUnmodifiedBlessedBuild();
}
return false;
}
@ -731,7 +731,7 @@ void BaseFeatureSet::DoV1CloudLog(const std::string& msg) {
if (g_core == nullptr) {
logsuffix = msg;
}
plus()->DirectSendV1CloudLogs(logprefix, logsuffix, false, nullptr);
Plus()->DirectSendV1CloudLogs(logprefix, logsuffix, false, nullptr);
}
void BaseFeatureSet::PushDevConsolePrintCall(const std::string& msg,

View File

@ -686,9 +686,9 @@ class BaseFeatureSet : public FeatureSetNativeComponent,
auto HavePlus() -> bool;
/// Access the plus feature-set. Will throw an exception if not present.
auto plus() -> PlusSoftInterface*;
auto Plus() -> PlusSoftInterface*;
void set_plus(PlusSoftInterface* plus);
void SetPlus(PlusSoftInterface* plus);
/// Try to load the classic feature-set and return whether it is available.
auto HaveClassic() -> bool;

View File

@ -70,7 +70,7 @@ void Logic::OnAppStart() {
g_base->ui->OnAppStart();
g_base->app_mode()->OnAppStart();
if (g_base->HavePlus()) {
g_base->plus()->OnAppStart();
g_base->Plus()->OnAppStart();
}
g_base->python->OnAppStart();
@ -191,7 +191,7 @@ void Logic::OnAppSuspend() {
// Note: keep these in opposite order of OnAppStart.
g_base->python->OnAppSuspend();
if (g_base->HavePlus()) {
g_base->plus()->OnAppSuspend();
g_base->Plus()->OnAppSuspend();
}
g_base->app_mode()->OnAppSuspend();
g_base->ui->OnAppSuspend();
@ -215,7 +215,7 @@ void Logic::OnAppUnsuspend() {
g_base->ui->OnAppUnsuspend();
g_base->app_mode()->OnAppUnsuspend();
if (g_base->HavePlus()) {
g_base->plus()->OnAppUnsuspend();
g_base->Plus()->OnAppUnsuspend();
}
g_base->python->OnAppUnsuspend();
}
@ -247,7 +247,7 @@ void Logic::OnAppShutdown() {
// should be registered as shutdown-tasks
g_base->python->OnAppShutdown();
if (g_base->HavePlus()) {
g_base->plus()->OnAppShutdown();
g_base->Plus()->OnAppShutdown();
}
g_base->app_mode()->OnAppShutdown();
g_base->ui->OnAppShutdown();
@ -280,7 +280,7 @@ void Logic::OnAppShutdownComplete() {
// should be registered as shutdown-tasks.
g_base->python->OnAppShutdownComplete();
if (g_base->HavePlus()) {
g_base->plus()->OnAppShutdownComplete();
g_base->Plus()->OnAppShutdownComplete();
}
g_base->app_mode()->OnAppShutdownComplete();
g_base->ui->OnAppShutdownComplete();
@ -307,7 +307,7 @@ void Logic::DoApplyAppConfig() {
g_base->ui->DoApplyAppConfig();
g_base->app_mode()->DoApplyAppConfig();
if (g_base->HavePlus()) {
g_base->plus()->DoApplyAppConfig();
g_base->Plus()->DoApplyAppConfig();
}
g_base->python->DoApplyAppConfig();
@ -323,6 +323,7 @@ void Logic::OnScreenSizeChange(float virtual_width, float virtual_height,
assert(g_base->InLogicThread());
// Inform all subsystems.
//
// Note: keep these in the same order as OnAppStart.
g_base->app_adapter->OnScreenSizeChange();
g_base->platform->OnScreenSizeChange();
@ -333,7 +334,7 @@ void Logic::OnScreenSizeChange(float virtual_width, float virtual_height,
g_core->platform->OnScreenSizeChange();
g_base->app_mode()->OnScreenSizeChange();
if (g_base->HavePlus()) {
g_base->plus()->OnScreenSizeChange();
g_base->Plus()->OnScreenSizeChange();
}
g_base->python->OnScreenSizeChange();
}
@ -363,7 +364,7 @@ void Logic::StepDisplayTime_() {
g_core->platform->StepDisplayTime();
g_base->app_mode()->StepDisplayTime();
if (g_base->HavePlus()) {
g_base->plus()->StepDisplayTime();
g_base->Plus()->StepDisplayTime();
}
g_base->python->StepDisplayTime();

View File

@ -155,7 +155,35 @@ void BasePython::OnAppShutdownComplete() {
void BasePython::DoApplyAppConfig() { assert(g_base->InLogicThread()); }
void BasePython::OnScreenSizeChange() { assert(g_base->InLogicThread()); }
void BasePython::OnScreenSizeChange() {
assert(g_base->InLogicThread());
float screen_res_x{g_base->graphics->screen_virtual_width()};
float screen_res_y{g_base->graphics->screen_virtual_height()};
// This call runs for all screen sizes including the initial one. However
// we only want to inform the Python layer of *changes*, so we only store
// the initial one and don't pass it on.
if (last_screen_res_x_ < 0.0) {
last_screen_res_x_ = screen_res_x;
last_screen_res_y_ = g_base->graphics->screen_virtual_height();
return;
}
// Ignore any redundant values that might come through.
if (last_screen_res_x_ == screen_res_x
&& last_screen_res_y_ == screen_res_y) {
return;
}
// Aight; we got a fresh, non-initial value. Store it and inform Python.
last_screen_res_x_ = screen_res_x;
last_screen_res_y_ = screen_res_y;
g_base->python->objs()
.Get(BasePython::ObjID::kAppOnScreenSizeChangeCall)
.Call();
}
void BasePython::StepDisplayTime() { assert(g_base->InLogicThread()); }

View File

@ -118,6 +118,7 @@ class BasePython {
kGetV2AccountIdCall,
kAppOnNativeActiveChangedCall,
kCopyDevConsoleHistoryCall,
kAppOnScreenSizeChangeCall,
kLast // Sentinel; must be at end.
};
@ -183,6 +184,8 @@ class BasePython {
private:
std::set<std::string> do_once_locations_;
PythonObjectSet<ObjID> objs_;
float last_screen_res_x_{-1.0f};
float last_screen_res_y_{-1.0f};
};
} // namespace ballistica::base

View File

@ -1307,7 +1307,7 @@ void ClassicAppMode::SetPublicPartyEnabled(bool val) {
return;
}
public_party_enabled_ = val;
g_base->plus()->PushPublicPartyState();
g_base->Plus()->PushPublicPartyState();
}
void ClassicAppMode::SetPublicPartySize(int count) {
@ -1320,7 +1320,7 @@ void ClassicAppMode::SetPublicPartySize(int count) {
// Push our new state to the server *ONLY* if public-party is turned on
// (wasteful otherwise).
if (public_party_enabled_) {
g_base->plus()->PushPublicPartyState();
g_base->Plus()->PushPublicPartyState();
}
}
@ -1334,7 +1334,7 @@ void ClassicAppMode::SetPublicPartyQueueEnabled(bool enabled) {
// Push our new state to the server *ONLY* if public-party is turned on
// (wasteful otherwise).
if (public_party_enabled_) {
g_base->plus()->PushPublicPartyState();
g_base->Plus()->PushPublicPartyState();
}
}
@ -1348,7 +1348,7 @@ void ClassicAppMode::SetPublicPartyMaxSize(int count) {
// Push our new state to the server *ONLY* if public-party is turned on
// (wasteful otherwise).
if (public_party_enabled_) {
g_base->plus()->PushPublicPartyState();
g_base->Plus()->PushPublicPartyState();
}
}
@ -1362,7 +1362,7 @@ void ClassicAppMode::SetPublicPartyName(const std::string& name) {
// Push our new state to the server *ONLY* if public-party is turned on
// (wasteful otherwise).
if (public_party_enabled_) {
g_base->plus()->PushPublicPartyState();
g_base->Plus()->PushPublicPartyState();
}
}
@ -1376,7 +1376,7 @@ void ClassicAppMode::SetPublicPartyStatsURL(const std::string& url) {
// Push our new state to the server *ONLY* if public-party is turned on
// (wasteful otherwise).
if (public_party_enabled_) {
g_base->plus()->PushPublicPartyState();
g_base->Plus()->PushPublicPartyState();
}
}
@ -1390,7 +1390,7 @@ void ClassicAppMode::SetPublicPartyPlayerCount(int count) {
// Push our new state to the server *ONLY* if public-party is turned on
// (wasteful otherwise).
if (public_party_enabled_) {
g_base->plus()->PushPublicPartyState();
g_base->Plus()->PushPublicPartyState();
}
}

View File

@ -195,7 +195,7 @@ void V1Account::SetLogin(V1AccountType account_type, V1LoginState login_state,
}
if (call_login_did_change) {
// Inform a few subsystems of the change.
g_base->plus()->V1LoginDidChange();
g_base->Plus()->V1LoginDidChange();
g_core->platform->V1LoginDidChange();
}
}

View File

@ -444,7 +444,7 @@ void ConnectionToClient::HandleMessagePacket(
if (!token_.empty()) {
// Kick off a query to the master-server for this client's info.
// FIXME: we need to add retries for this in case of failure.
g_base->plus()->ClientInfoQuery(
g_base->Plus()->ClientInfoQuery(
token_, our_handshake_player_spec_str_ + our_handshake_salt_,
peer_hash_, build_number_);
}

View File

@ -202,7 +202,7 @@ void ConnectionToHost::HandleGamePacket(const std::vector<uint8_t>& data) {
set_peer_spec(PlayerSpec(string_buffer.data()));
}
peer_hash_ = g_base->plus()->CalcV1PeerHash(peer_hash_input_);
peer_hash_ = g_base->Plus()->CalcV1PeerHash(peer_hash_input_);
set_can_communicate(true);
appmode->LaunchClientSession();
@ -227,7 +227,7 @@ void ConnectionToHost::HandleGamePacket(const std::vector<uint8_t>& data) {
JsonDict dict;
dict.AddNumber("b", kEngineBuildNumber);
g_base->plus()->V1SetClientInfo(&dict);
g_base->Plus()->V1SetClientInfo(&dict);
// Pass the hash we generated from their handshake; they can use
// this to make sure we're who we say we are.

View File

@ -1367,7 +1367,7 @@ static auto PyGetGameRoster(PyObject* self, PyObject* args, PyObject* keywds)
// Let's also include a public account-id if we have one.
std::string account_id;
if (clientid == -1) {
account_id = g_base->plus()->GetPublicV1AccountID();
account_id = g_base->Plus()->GetPublicV1AccountID();
} else {
if (auto* appmode = classic::ClassicAppMode::GetActiveOrWarn()) {
auto client2 =

View File

@ -244,10 +244,10 @@ void SceneV1InputDeviceDelegate::InvalidateConnectionToHost() {
auto SceneV1InputDeviceDelegate::GetPublicV1AccountID() const -> std::string {
assert(g_base->InLogicThread());
// This default implementation assumes the device is local
// so just returns the locally signed in account's public id.
// This default implementation assumes the device is local so just returns
// the locally signed in account's public id.
return g_base->plus()->GetPublicV1AccountID();
return g_base->Plus()->GetPublicV1AccountID();
}
auto SceneV1InputDeviceDelegate::GetPlayerProfiles() const -> PyObject* {

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

View File

@ -2752,23 +2752,23 @@ static PyMethodDef PyIsAvailableDef = {
"(internal)",
};
// --------------------------- on_screen_change --------------------------------
// --------------------------- on_ui_scale_change ------------------------------
static auto PyOnScreenChange(PyObject* self) -> PyObject* {
static auto PyOnUIScaleChange(PyObject* self) -> PyObject* {
BA_PYTHON_TRY;
BA_PRECONDITION(g_base->InLogicThread());
g_ui_v1->OnScreenChange();
g_ui_v1->OnUIScaleChange();
Py_RETURN_NONE;
BA_PYTHON_CATCH;
}
static PyMethodDef PyOnScreenChangeDef = {
"on_screen_change", // name
(PyCFunction)PyOnScreenChange, // method
METH_NOARGS, // flags
static PyMethodDef PyOnUIScaleChangeDef = {
"on_ui_scale_change", // name
(PyCFunction)PyOnUIScaleChange, // method
METH_NOARGS, // flags
"on_screen_change() -> None\n"
"on_ui_scale_change() -> None\n"
"\n"
"(internal)",
};
@ -2844,7 +2844,7 @@ auto PythonMethodsUIV1::GetMethods() -> std::vector<PyMethodDef> {
PyGetQRCodeTextureDef,
PyGetMeshDef,
PyIsAvailableDef,
PyOnScreenChangeDef,
PyOnUIScaleChangeDef,
PyRootUIPauseUpdatesDef,
PyRootUIResumeUpdatesDef};
}

View File

@ -223,7 +223,7 @@ void UIV1FeatureSet::OnScreenSizeChange() {
}
}
void UIV1FeatureSet::OnScreenChange() {
void UIV1FeatureSet::OnUIScaleChange() {
// This gets called by the Python layer when UIScale or window size
// changes.
assert(g_base->InLogicThread());

View File

@ -121,7 +121,7 @@ class UIV1FeatureSet : public FeatureSetNativeComponent,
void DeleteWidget(Widget* widget);
void OnScreenSizeChange() override;
void OnScreenChange();
void OnUIScaleChange();
void OnLanguageChange() override;
auto GetRootWidget() -> ui_v1::Widget* override;

View File

@ -20,4 +20,5 @@ values = [
app.on_native_shutdown_complete, # kAppOnNativeShutdownCompleteCall
app.on_native_active_changed, # kAppOnNativeActiveChangedCall
app.devconsole.do_refresh_tab, # kAppDevConsoleDoRefreshTabCall
app.on_screen_size_change, # kAppOnScreenSizeChangeCall
]