almost final mac app store update build

This commit is contained in:
Eric 2023-11-13 15:43:54 -08:00
parent e6d3e7dff2
commit f06ad6b9ba
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
49 changed files with 499 additions and 480 deletions

100
.efrocachemap generated
View File

@ -421,7 +421,7 @@
"build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26",
"build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8",
"build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55",
"build/assets/ba_data/data/langdata.json": "dca47b4976752e76e852f7a4be2c7aa3",
"build/assets/ba_data/data/langdata.json": "02522e0d2593baf2e57a97fbfbfe3368",
"build/assets/ba_data/data/languages/arabic.json": "e0001d8542c904bc3c98a174f256efd9",
"build/assets/ba_data/data/languages/belarussian.json": "7fe38341815ca6ff4d95224196e7a67e",
"build/assets/ba_data/data/languages/chinese.json": "4e2f4f1f38216940953fcbee4da1563e",
@ -439,22 +439,22 @@
"build/assets/ba_data/data/languages/greek.json": "287c0ec437b38772284ef9d3e4fb2fc3",
"build/assets/ba_data/data/languages/hindi.json": "8ea0c58a44a24edb131d0e53b074d1f6",
"build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e",
"build/assets/ba_data/data/languages/indonesian.json": "ba39cade3c965b2ddbee122880b6f0db",
"build/assets/ba_data/data/languages/indonesian.json": "97657eb2ab75d821045387b6d7a2b52d",
"build/assets/ba_data/data/languages/italian.json": "cda5760f247500657722c279bc2f2bc7",
"build/assets/ba_data/data/languages/korean.json": "ca1122a9ee551da3f75ae632012bd0e2",
"build/assets/ba_data/data/languages/malay.json": "832562ce997fc70704b9234c95fb2e38",
"build/assets/ba_data/data/languages/persian.json": "4f448b29ba04f2b789329600cb7f9ab7",
"build/assets/ba_data/data/languages/polish.json": "8bb8f7baa5efcf6cdd627140d209c2b2",
"build/assets/ba_data/data/languages/portuguese.json": "7374b6a5cadcf573ee4ab4a5b4bc8c0a",
"build/assets/ba_data/data/languages/portuguese.json": "c738cc76396305060d4f94cb77db5bec",
"build/assets/ba_data/data/languages/romanian.json": "aeebdd54f65939c2facc6ac50c117826",
"build/assets/ba_data/data/languages/russian.json": "9e068a3afdec43b207c83aedfb812e82",
"build/assets/ba_data/data/languages/russian.json": "cdaac43afde13ab622babe403b9858a4",
"build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69",
"build/assets/ba_data/data/languages/slovak.json": "27962d53dc3f7dd4e877cd40faafeeef",
"build/assets/ba_data/data/languages/spanish.json": "f73b0d4d534f030f95c00385bb06cbc1",
"build/assets/ba_data/data/languages/swedish.json": "5142a96597d17d8344be96a603da64ac",
"build/assets/ba_data/data/languages/tamil.json": "b4de1a2851afe4869c82e9acd94cd89c",
"build/assets/ba_data/data/languages/thai.json": "33f63753c9af9a5b238d229a0bf23fbc",
"build/assets/ba_data/data/languages/turkish.json": "c3674336e746bf7b23617a6ff296c69a",
"build/assets/ba_data/data/languages/thai.json": "77755219bbf5fb7eea0d6b226684f403",
"build/assets/ba_data/data/languages/turkish.json": "326bcc54b69cb6a1bda4abb732f9f56f",
"build/assets/ba_data/data/languages/ukrainian.json": "e5c861187c4c6db37d1a033f4ef3dd5a",
"build/assets/ba_data/data/languages/venetian.json": "9fe1a58d9e5dfb00f31ce3b2eb9993f4",
"build/assets/ba_data/data/languages/vietnamese.json": "921cd1e50f60fe3e101f246e172750ba",
@ -4056,50 +4056,50 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "66647fb41b54b221cf4189161a696698",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "81a9bec829a30860a260df58c258b7d0",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "1930fa43a702b2fd3601b032afd9ad31",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "e9fdc1e724495d36a1ae9c1898b2dbeb",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "5cb78d708e8dc3911d1e5a345e535bd2",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "9aa815a258a476f02490cf58db28340a",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "dd932540bbef37a3e0580ef81206090c",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "d34c3fcf54ae4c362dafb442e5e2e57a",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "a74979683c4e58bfefde5235996551db",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "cbbecde45fb204a8f39cbf5448d248a2",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "37d71f1f72191bb29645146a5d7fdd09",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "10cb64bd655ad3ff562496bb66693dd6",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "7d9ab35e63602e682a533495022728d3",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "d98edee305c488c3a082ef98deae8a6c",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "a12f0a05ed17ef48554356b6087cdee0",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "de7e6c726c6ace4bba28f59a84cdf6b5",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "fd7b381ca67b31c088d4e98b6c0ddfe1",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "1d074c3b15b2bdf6c32e145ea83f1fa2",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "0b47cfab278418386ac29009402c9f59",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "213a68414bac47cbe051db9fbb0cbb43",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "a5e255155289f502a6662e5f9bb7819c",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "ae044789e56e5d2999f55e2f4eeb6a4d",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "a5e255155289f502a6662e5f9bb7819c",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "ae044789e56e5d2999f55e2f4eeb6a4d",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "48d81af91942519355b066d7bf8d3468",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "2c4f37722cb283a8405f35a0c9bbbfbb",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "48d81af91942519355b066d7bf8d3468",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "2c4f37722cb283a8405f35a0c9bbbfbb",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "09abcf532a2c0fba00e5e7860f495ba8",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "699291d36e42e3214946aab9798446ea",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "09abcf532a2c0fba00e5e7860f495ba8",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "699291d36e42e3214946aab9798446ea",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "ef1356360fb3701b0976a0ef37eae4bf",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "50cfe82580f1ef2698c5508f46bd2e4c",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "7b6afdb6b8d8722cbcee3bff944ec038",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "50cfe82580f1ef2698c5508f46bd2e4c",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "b29d085453e251a7e6866ac7efcd0513",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "e8da891dd0f5a441d781793f641f215d",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "982dc78eabf4eca6ccbfd3bf2537c706",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "d02505b956c8a0d5b2cb310408492df6",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "c95c26eed8a2c5e8573d35c58b2c99f2",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "d5a04d68e7818912b1f689fb1a3e8b53",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "b612531dedbb057f48868e43ce05636a",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "499914dfdd9a5fd051013ab5ae845f41",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "96ba5c40a9216f4efed502e29a0bc762",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "bbe152b83087e223b9f9f0336d4f03d3",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "c22b27747e16c1dfa7e7a43264555cd5",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "06b779dfd042cb832e4546b177b333a7",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "a18464f5e02af14e3b34ccb2154fb1de",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "56d0b3ff53e9d4ac46c8ef2aa4d729b6",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "7d00156ec8e56af0d8a39ea7eb20f6fd",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "b933746e1b64608aab7e6bf8ebf32a8d",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "824515c2fc33e06c7ecb866a2818a546",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "d0a8783b736e196cfaaefbb62271e337",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "741f777205eddf8a2500625e3ba18ee6",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "01697d3e58c63d3f23c74720f7738da6",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "a86b1855a709c6b654195a8a0e308057",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "9567d63a4c02d393a8110953f1c2e9b5",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "7199a245c7e946222125f0e8640285a0",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "a5e0788917285460f40d1beacabd0ca2",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "4cc6912cd58e026baa523d8081411506",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "754fed064c8a87448617ef7b9c3479cb",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "047c6dcda71e7c4e0c4ffa5f1aac5bfa",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "56976efa146ae9972dd6ba53ec75d451",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "dc8d1e0f82fe799cbbacfd89bbf04498",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "c6be3757c2ee85a7f4f8a66d327a24a0",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "dc8d1e0f82fe799cbbacfd89bbf04498",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "c6be3757c2ee85a7f4f8a66d327a24a0",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "859470a05f3d968031ae9843bdf818c3",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "bd8926fb9d12b7f4972870efea006d54",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "859470a05f3d968031ae9843bdf818c3",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "bd8926fb9d12b7f4972870efea006d54",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "11eeb74f8cb307ed673768c0629ca302",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "5f6ed20081020d554b1866389136b712",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "11eeb74f8cb307ed673768c0629ca302",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "5f6ed20081020d554b1866389136b712",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "d9407d62ab82cdf25e970e3fde8971fa",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "856a05aadbe4b75baee3048296aa8eef",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "c5eb4a9161b68775876c4d19bff1cc1b",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "856a05aadbe4b75baee3048296aa8eef",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "767e7b15de08ffe850d3bbc7def2fab2",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "d482806656749efd090c6c28c124eecf",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "07abac6aa3c528bd594bdf5b53e9c823",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "b16b8780811a583824491b80a45b839d",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "33806447e8ab2bd3a55509d8a5d8b64c",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "786967e43a719120d339de9cd791e58b",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "70162e33973c253efdc386e421c50ebe",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "4ab0adfd6cc8934f0340d4bb6c73b78d",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "28323912b56ec07701eda3d41a6a4101",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f",

View File

@ -1,4 +1,4 @@
### 1.7.28 (build 21585, api 8, 2023-11-10)
### 1.7.28 (build 21588, api 8, 2023-11-13)
- Turning off ticket continues on all platforms. I'll be moving the game towards
a new monetization scheme mostly based on cosmetics and this has always felt a
@ -209,6 +209,13 @@
- The V2 account id for the signed in account is now available at
`ba*.app.plus.accounts.primary.accountid` (alongside some other existing
account info).
- (build 21585) Fixed an issue where some navigation key presses were getting
incorrectly absorbed by text widgets. (Thanks for the heads-up Temp!)
- (build 21585) Fixed an issue where texture quality changes would not take
effect until next launch.
- Added a 'glow_type' arg to `bauiv1.textwidget()` to adjust the glow used when
the text is selected. The default is 'gradient' but there is now a 'uniform'
option which may look better in some circumstances.
### 1.7.27 (build 21282, api 8, 2023-08-30)

View File

@ -26,6 +26,11 @@ DEBUG_LOG = False
class CloudSubsystem(AppSubsystem):
"""Manages communication with cloud components."""
@property
def connected(self) -> bool:
"""Property equivalent of CloudSubsystem.is_connected()."""
return self.is_connected()
def is_connected(self) -> bool:
"""Return whether a connection to the cloud is present.

View File

@ -104,8 +104,8 @@ def show_user_scripts() -> None:
_error.print_exception('error writing about_this_folder stuff')
# On a few platforms we try to open the dir in the UI.
if app.classic is not None and app.classic.platform in ['mac', 'windows']:
# On platforms that support it, open the dir in the UI.
if _babase.supports_open_dir_externally():
_babase.open_dir_externally(env.python_directory_user)
# Otherwise we just print a pretty version of it.

View File

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

View File

@ -486,20 +486,21 @@ class AccountSettingsWindow(bui.Window):
self._account_name_what_is_text = bui.textwidget(
parent=self._subcontainer,
position=(0.0, self._account_name_what_is_y),
size=(200.0, 60),
size=(220.0, 60),
text=bui.Lstr(
value='${WHAT} -->',
subs=[('${WHAT}', bui.Lstr(resource='whatIsThisText'))],
),
scale=0.6,
color=(0.3, 0.7, 0.05),
maxwidth=200.0,
maxwidth=130.0,
h_align='right',
v_align='center',
autoselect=True,
selectable=True,
on_activate_call=show_what_is_v2_page,
click_activate=True,
glow_type='uniform',
)
if first_selectable is None:
first_selectable = self._account_name_what_is_text
@ -1281,11 +1282,21 @@ class AccountSettingsWindow(bui.Window):
show_what_is_v2_page()
def _on_manage_account_press(self) -> None:
bui.screenmessage(bui.Lstr(resource='oneMomentText'))
plus = bui.app.plus
assert plus is not None
# Preemptively fail if it looks like we won't be able to talk to
# the server anyway.
if not plus.cloud.connected:
bui.screenmessage(
bui.Lstr(resource='internal.unavailableNoConnectionText'),
color=(1, 0, 0),
)
bui.getsound('error').play()
return
bui.screenmessage(bui.Lstr(resource='oneMomentText'))
# We expect to have a v2 account signed in if we get here.
if plus.accounts.primary is None:
logging.exception(
@ -1445,7 +1456,7 @@ class AccountSettingsWindow(bui.Window):
swidth = bui.get_string_width(name_str, suppress_warning=True)
# Eww; number-fudging. Need to recalibrate this if
# account name scaling changes.
x = self._sub_width * 0.5 - swidth * 0.75 - 170
x = self._sub_width * 0.5 - swidth * 0.75 - 190
bui.textwidget(
edit=self._account_name_what_is_text,

View File

@ -142,6 +142,7 @@ class ManualGatherTab(GatherTab):
playsound=True,
),
text=bui.Lstr(resource='gatherWindow.manualJoinSectionText'),
glow_type='uniform',
)
self._favorites_text = bui.textwidget(
parent=self._container,
@ -162,6 +163,7 @@ class ManualGatherTab(GatherTab):
playsound=True,
),
text=bui.Lstr(resource='gatherWindow.favoritesText'),
glow_type='uniform',
)
bui.widget(edit=self._join_by_address_text, up_widget=tab_button)
bui.widget(
@ -316,7 +318,7 @@ class ManualGatherTab(GatherTab):
self._check_button = bui.textwidget(
parent=self._container,
size=(250, 60),
text=bui.Lstr(resource='gatherWindow.' 'showMyAddressText'),
text=bui.Lstr(resource='gatherWindow.showMyAddressText'),
v_align='center',
h_align='center',
click_activate=True,
@ -331,6 +333,7 @@ class ManualGatherTab(GatherTab):
self._container,
c_width,
),
glow_type='uniform',
)
bui.widget(edit=self._check_button, up_widget=btn)

View File

@ -120,6 +120,7 @@ class PrivateGatherTab(GatherTab):
playsound=True,
),
text=bui.Lstr(resource='gatherWindow.privatePartyJoinText'),
glow_type='uniform',
)
self._host_sub_tab_text = bui.textwidget(
parent=self._container,
@ -138,6 +139,7 @@ class PrivateGatherTab(GatherTab):
playsound=True,
),
text=bui.Lstr(resource='gatherWindow.privatePartyHostText'),
glow_type='uniform',
)
bui.widget(edit=self._join_sub_tab_text, up_widget=tab_button)
bui.widget(

View File

@ -114,7 +114,7 @@ class UIRow:
self._name_widget = bui.textwidget(
text=bui.Lstr(value=party.name),
parent=columnwidget,
size=(sub_scroll_width * 0.63, 20),
size=(sub_scroll_width * 0.46, 20),
position=(0 + hpos, 4 + vpos),
selectable=True,
on_select_call=bui.WeakCall(
@ -248,6 +248,7 @@ class AddrFetchThread(Thread):
self._call = call
def run(self) -> None:
sock: socket.socket | None = None
try:
# FIXME: Update this to work with IPv6 at some point.
import socket
@ -255,7 +256,6 @@ class AddrFetchThread(Thread):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.connect(('8.8.8.8', 80))
val = sock.getsockname()[0]
sock.close()
bui.pushcall(bui.Call(self._call, val), from_other_thread=True)
except Exception as exc:
from efro.error import is_udp_communication_error
@ -265,6 +265,9 @@ class AddrFetchThread(Thread):
pass
else:
logging.exception('Error in addr-fetch-thread')
finally:
if sock is not None:
sock.close()
class PingThread(Thread):
@ -432,6 +435,7 @@ class PublicGatherTab(GatherTab):
text=bui.Lstr(
resource='gatherWindow.' 'joinPublicPartyDescriptionText'
),
glow_type='uniform',
)
self._host_text = bui.textwidget(
parent=self._container,
@ -454,6 +458,7 @@ class PublicGatherTab(GatherTab):
text=bui.Lstr(
resource='gatherWindow.' 'hostPublicPartyDescriptionText'
),
glow_type='uniform',
)
bui.widget(edit=self._join_text, up_widget=tab_button)
bui.widget(

View File

@ -198,7 +198,7 @@ class PlaylistAddGameWindow(bui.Window):
txt = bui.textwidget(
parent=self._column,
position=(0, 0),
size=(self._width - 88, 24),
size=(self._scroll_width * 1.1, 24),
text=gametype.get_display_string(),
h_align='left',
v_align='center',

View File

@ -382,12 +382,12 @@ class ProfileBrowserWindow(bui.Window):
txtw = bui.textwidget(
parent=self._columnwidget,
position=(0, 32),
size=((self._width - 40) / scl, 28),
size=((self._width - 210) / scl, 28),
text=bui.Lstr(value=tval),
h_align='left',
v_align='center',
on_select_call=bui.WeakCall(self._select, p_name, index),
maxwidth=self._scroll_width * 0.92,
maxwidth=self._scroll_width * 0.86,
corner_scale=scl,
color=bui.safecolor(color, 0.4),
always_highlight=True,

View File

@ -90,6 +90,7 @@ class NetGraph;
class Networking;
class NetworkReader;
class NetworkWriter;
class NinePatchMesh;
class ObjectComponent;
class PythonClassUISound;
class PythonContextCall;

View File

@ -11,8 +11,7 @@ namespace ballistica::base {
// transform/scissor/etc state changes.
class EmptyComponent : public RenderComponent {
public:
explicit EmptyComponent(RenderPass* pass)
: RenderComponent(pass), transparent_(false) {}
explicit EmptyComponent(RenderPass* pass) : RenderComponent(pass) {}
void SetTransparent(bool val) {
EnsureConfiguring();
transparent_ = val;
@ -22,7 +21,7 @@ class EmptyComponent : public RenderComponent {
void WriteConfig() override { ConfigForEmpty(transparent_); }
private:
bool transparent_;
bool transparent_{};
};
} // namespace ballistica::base

View File

@ -113,6 +113,14 @@ class ObjectComponent : public RenderComponent {
void WriteConfig() override;
protected:
ReflectionType reflection_{ReflectionType::kNone};
LightShadowType light_shadow_{LightShadowType::kObject};
bool world_space_ : 1 {};
bool transparent_ : 1 {};
bool premultiplied_ : 1 {};
bool have_color_add_ : 1 {};
bool double_sided_ : 1 {};
bool do_colorize_2_ : 1 {};
float color_r_{1.0f};
float color_g_{1.0f};
float color_b_{1.0f};
@ -133,14 +141,6 @@ class ObjectComponent : public RenderComponent {
float reflection_scale_b_{1.0f};
Object::Ref<TextureAsset> texture_;
Object::Ref<TextureAsset> colorize_texture_;
ReflectionType reflection_{ReflectionType::kNone};
LightShadowType light_shadow_{LightShadowType::kObject};
bool world_space_{};
bool transparent_{};
bool premultiplied_{};
bool have_color_add_{};
bool double_sided_{};
bool do_colorize_2_{};
};
} // namespace ballistica::base

View File

@ -9,8 +9,7 @@ namespace ballistica::base {
class PostProcessComponent : public RenderComponent {
public:
explicit PostProcessComponent(RenderPass* pass)
: RenderComponent(pass), normal_distort_(0.0f), eyes_(false) {}
explicit PostProcessComponent(RenderPass* pass) : RenderComponent(pass) {}
void SetNormalDistort(float d) {
EnsureConfiguring();
normal_distort_ = d;
@ -22,8 +21,8 @@ class PostProcessComponent : public RenderComponent {
protected:
void WriteConfig() override;
bool eyes_;
float normal_distort_;
bool eyes_ : 1 {};
float normal_distort_{};
};
} // namespace ballistica::base

View File

@ -7,35 +7,10 @@
namespace ballistica::base {
// used for UI and overlays and things - no world tinting/etc is applied
/// Used for UI and overlays and things; no world tinting/etc is applied.
class SimpleComponent : public RenderComponent {
public:
explicit SimpleComponent(RenderPass* pass)
: RenderComponent(pass),
color_r_(1.0f),
color_g_(1.0f),
color_b_(1.0f),
color_a_(1.0f),
colorize_color_r_(1.0f),
colorize_color_g_(1.0f),
colorize_color_b_(1.0f),
colorize_color_a_(1.0f),
colorize_color2_r_(1.0f),
colorize_color2_g_(1.0f),
colorize_color2_b_(1.0f),
colorize_color2_a_(1.0f),
shadow_offset_x_(0.0f),
shadow_offset_y_(0.0f),
shadow_blur_(0.0f),
shadow_opacity_(0.0f),
glow_amount_(0.0f),
glow_blur_(0.0f),
flatness_(0.0f),
transparent_(false),
premultiplied_(false),
have_color_(false),
double_sided_(false),
do_colorize_2_(false) {}
explicit SimpleComponent(RenderPass* pass) : RenderComponent(pass) {}
void SetPremultiplied(bool val) {
EnsureConfiguring();
@ -56,16 +31,16 @@ class SimpleComponent : public RenderComponent {
EnsureConfiguring();
texture_ = t;
}
// used with colorize color 1 and 2
// red areas of the texture will get multiplied by colorize-color1
// and green areas by colorize-color2
/// Used with colorize color 1 and 2. Red areas of the texture will get
/// multiplied by colorize-color1 and green areas by colorize-color2.
void SetColorizeTexture(TextureAsset* t) {
EnsureConfiguring();
colorize_texture_ = t;
}
// Red multiplies source color, green adds colorize1-color, and blue adds
// white (currently requires colorize1 and colorize 2 to be set).
/// Red multiplies source color, green adds colorize1-color, and blue adds
/// white (currently requires colorize1 and colorize 2 to be set).
void SetMaskTexture(TextureAsset* t) {
EnsureConfiguring();
mask_texture_ = t;
@ -124,10 +99,10 @@ class SimpleComponent : public RenderComponent {
do_colorize_2_ = true;
}
void SetShadow(float offsetX, float offsetY, float blur, float opacity) {
void SetShadow(float offset_x, float offset_y, float blur, float opacity) {
EnsureConfiguring();
shadow_offset_x_ = offsetX;
shadow_offset_y_ = offsetY;
shadow_offset_x_ = offset_x;
shadow_offset_y_ = offset_y;
shadow_blur_ = blur;
shadow_opacity_ = opacity;
}
@ -147,23 +122,34 @@ class SimpleComponent : public RenderComponent {
void WriteConfig() override;
protected:
float color_r_, color_g_, color_b_, color_a_;
float colorize_color_r_, colorize_color_g_, colorize_color_b_,
colorize_color_a_;
float colorize_color2_r_, colorize_color2_g_, colorize_color2_b_,
colorize_color2_a_;
float shadow_offset_x_, shadow_offset_y_, shadow_blur_, shadow_opacity_;
float glow_amount_, glow_blur_;
float flatness_;
bool do_colorize_2_ : 1 {};
bool transparent_ : 1 {};
bool premultiplied_ : 1 {};
bool have_color_ : 1 {};
bool double_sided_ : 1 {};
float color_r_{1.0f};
float color_g_{1.0f};
float color_b_{1.0f};
float color_a_{1.0f};
float colorize_color_r_{1.0f};
float colorize_color_g_{1.0f};
float colorize_color_b_{1.0f};
float colorize_color_a_{1.0f};
float colorize_color2_r_{1.0f};
float colorize_color2_g_{1.0f};
float colorize_color2_b_{1.0f};
float colorize_color2_a_{1.0f};
float shadow_offset_x_{};
float shadow_offset_y_{};
float shadow_blur_{};
float shadow_opacity_{};
float glow_amount_{};
float glow_blur_{};
float flatness_{};
Object::Ref<TextureAsset> texture_;
Object::Ref<TextureAsset> colorize_texture_;
Object::Ref<TextureAsset> mask_texture_;
Object::Ref<TextureAsset> mask_uv2_texture_;
bool do_colorize_2_;
bool transparent_;
bool premultiplied_;
bool have_color_;
bool double_sided_;
};
} // namespace ballistica::base

View File

@ -9,13 +9,8 @@ namespace ballistica::base {
class SmokeComponent : public RenderComponent {
public:
explicit SmokeComponent(RenderPass* pass)
: RenderComponent(pass),
color_r_(1.0f),
color_g_(1.0f),
color_b_(1.0f),
color_a_(1.0f),
overlay_(false) {}
explicit SmokeComponent(RenderPass* pass) : RenderComponent(pass) {}
void SetColor(float r, float g, float b, float a = 1.0f) {
EnsureConfiguring();
color_r_ = r;
@ -23,6 +18,7 @@ class SmokeComponent : public RenderComponent {
color_b_ = b;
color_a_ = a;
}
void SetOverlay(bool overlay) {
EnsureConfiguring();
overlay_ = overlay;
@ -30,8 +26,12 @@ class SmokeComponent : public RenderComponent {
protected:
void WriteConfig() override;
float color_r_, color_g_, color_b_, color_a_;
bool overlay_;
bool overlay_ : 1 {};
float color_r_{1.0f};
float color_g_{1.0f};
float color_b_{1.0f};
float color_a_{1.0f};
};
} // namespace ballistica::base

View File

@ -37,9 +37,9 @@ class SpriteComponent : public RenderComponent {
protected:
void WriteConfig() override;
bool have_color_{};
bool camera_aligned_{};
bool overlay_{};
bool have_color_ : 1 {};
bool camera_aligned_ : 1 {};
bool overlay_ : 1 {};
uint8_t exponent_{1};
float color_r_{1.0f};
float color_g_{1.0f};

View File

@ -106,8 +106,6 @@ void Graphics::DoApplyAppConfig() {
show_fps_ = g_base->app_config->Resolve(AppConfig::BoolID::kShowFPS);
show_ping_ = g_base->app_config->Resolve(AppConfig::BoolID::kShowPing);
// tv_border_ =
// g_base->app_config->Resolve(AppConfig::BoolID::kEnableTVBorder);
bool disable_camera_shake =
g_base->app_config->Resolve(AppConfig::BoolID::kDisableCameraShake);
@ -133,6 +131,7 @@ void Graphics::UpdateInitialGraphicsSettingsSend_() {
// We need to send an initial graphics-settings to the server to kick
// things off, but we need a few things to be in place first.
auto app_config_ready = applied_app_config_;
// At some point we may want to wait to know our actual screen res before
// sending. This won't apply everywhere though since on some platforms the
// screen doesn't exist until we send this.
@ -149,7 +148,7 @@ void Graphics::UpdateInitialGraphicsSettingsSend_() {
// explicitly increment its refcount here in the logic thread now and
// then push a call back here to decrement it when we're done.
settings->ObjectIncrementStrongRefCount();
// auto* s = settings_.Get();
g_base->app_adapter->PushGraphicsContextCall([settings] {
assert(g_base->app_adapter->InGraphicsContext());
g_base->graphics_server->ApplySettings(settings->Get());
@ -466,9 +465,8 @@ void Graphics::DrawMiscOverlays(FrameDef* frame_def) {
if (now - it->second->LastUsedTime() > 1000) {
it = debug_graphs_.erase(it);
} else {
it->second->Draw(pass,
static_cast<double>(g_core->GetAppTimeMillisecs()),
50.0f, debug_graph_y, 500.0f, 100.0f);
it->second->Draw(pass, g_base->logic->display_time() * 1000.0, 50.0f,
debug_graph_y, 500.0f, 100.0f);
debug_graph_y += 110.0f;
++it;
@ -581,6 +579,9 @@ auto Graphics::GetGraphicsSettingsSnapshot() -> Snapshot<GraphicsSettings>* {
new_settings->index = next_settings_index_++;
settings_snapshot_ = Object::New<Snapshot<GraphicsSettings>>(new_settings);
graphics_settings_dirty_ = false;
// This can affect placeholder settings; keep those up to date.
UpdatePlaceholderSettings();
}
assert(settings_snapshot_.Exists());
return settings_snapshot_.Get();
@ -1618,7 +1619,6 @@ void Graphics::LanguageChanged() {
Log(LogLevel::kWarning,
"Graphics::LanguageChanged() called during draw; should not happen.");
}
screenmessages->ClearScreenMessageTranslations();
}
@ -1665,19 +1665,31 @@ auto Graphics::TextureQualityFromRequest(TextureQualityRequest request,
void Graphics::set_client_context(Snapshot<GraphicsClientContext>* context) {
assert(g_base->InLogicThread());
// Currently we only expect this to be set once. That will change
// once we support renderer swapping/etc.
// Currently we only expect this to be set once. That will change once we
// support renderer swapping/etc.
assert(!g_base->logic->graphics_ready());
assert(!client_context_snapshot_.Exists());
client_context_snapshot_ = context;
// Update our static placeholder value (we don't want to calc it dynamically
// since it can be accessed from other threads).
texture_quality_placeholder_ = TextureQualityFromRequest(
settings()->texture_quality, client_context()->auto_texture_quality);
// Placeholder settings are affected by client context, so update them
// when it changes.
UpdatePlaceholderSettings();
// Let the logic system know its free to proceed beyond bootstrapping.
g_base->logic->OnGraphicsReady();
}
// This call exists for the graphics-server to call when they've changed
void Graphics::UpdatePlaceholderSettings() {
assert(g_base->InLogicThread());
// Need both of these in place.
if (!settings_snapshot_.Exists() || !has_client_context()) {
return;
}
texture_quality_placeholder_ = TextureQualityFromRequest(
settings()->texture_quality, client_context()->auto_texture_quality);
}
} // namespace ballistica::base

View File

@ -320,6 +320,8 @@ class Graphics {
/// Called by the graphics-server when a new client context is ready.
void set_client_context(Snapshot<GraphicsClientContext>* context);
void UpdatePlaceholderSettings();
auto has_client_context() -> bool {
return client_context_snapshot_.Exists();
}

View File

@ -66,7 +66,8 @@ void GraphicsServer::ApplySettings(const GraphicsSettings* settings) {
// gathered for themself.
g_base->app_adapter->ApplyGraphicsSettings(settings);
// Lastly, if we've not yet sent a context to the client, do so.
// If we've not yet sent a context to the client, do so. At some point we
// may support re-sending this if there are settings that change.
if (client_context_ == nullptr) {
set_client_context(g_base->app_adapter->GetGraphicsClientContext());
}
@ -387,58 +388,6 @@ void GraphicsServer::UnloadRenderer() {
renderer_loaded_ = false;
}
// Given physical res, calculate virtual res.
// void GraphicsServer::CalcVirtualRes_(float* x, float* y) {
// float x_in = *x;
// float y_in = *y;
// if (*x / *y > static_cast<float>(kBaseVirtualResX)
// / static_cast<float>(kBaseVirtualResY)) {
// *y = kBaseVirtualResY;
// *x = *y * (x_in / y_in);
// } else {
// *x = kBaseVirtualResX;
// *y = *x * (y_in / x_in);
// }
// }
// void GraphicsServer::UpdateVirtualScreenRes_() {
// assert(g_base->app_adapter->InGraphicsContext());
// // In vr mode our virtual res is independent of our screen size.
// // (since it gets drawn to an overlay)
// if (g_core->IsVRMode()) {
// res_x_virtual_ = kBaseVirtualResX;
// res_y_virtual_ = kBaseVirtualResY;
// } else {
// res_x_virtual_ = res_x_;
// res_y_virtual_ = res_y_;
// CalcVirtualRes_(&res_x_virtual_, &res_y_virtual_);
// }
// }
// void GraphicsServer::SetScreenResolution(float h, float v) {
// assert(g_base->app_adapter->InGraphicsContext());
// // Ignore redundant sets.
// if (res_x_ == h && res_y_ == v) {
// return;
// }
// res_x_ = h;
// res_y_ = v;
// // UpdateVirtualScreenRes_();
// // Inform renderer of the change.
// if (renderer_) {
// renderer_->OnScreenSizeChange();
// }
// // Inform all logic thread bits of this change.
// g_base->logic->event_loop()->PushCall(
// [vx = res_x_virtual_, vy = res_y_virtual_, x = res_x_, y = res_y_] {
// g_base->graphics->SetScreenSize(vx, vy, x, y);
// });
// }
// FIXME: Shouldn't have android-specific code in here.
void GraphicsServer::HandlePushAndroidRes(const std::string& android_res) {
if (g_buildconfig.ostype_android()) {
@ -578,16 +527,6 @@ void GraphicsServer::PushReloadMediaCall() {
g_base->app_adapter->PushGraphicsContextCall([this] { ReloadMedia_(); });
}
// void GraphicsServer::PushSetScreenPixelScaleCall(float pixel_scale) {
// g_base->app_adapter->PushGraphicsContextCall([this, pixel_scale] {
// assert(g_base->app_adapter->InGraphicsContext());
// if (!renderer_) {
// return;
// }
// renderer_->set_pixel_scale(pixel_scale);
// });
// }
void GraphicsServer::PushComponentUnloadCall(
const std::vector<Object::Ref<Asset>*>& components) {
g_base->app_adapter->PushGraphicsContextCall([components] {

View File

@ -330,7 +330,6 @@ class GraphicsServer {
bool cam_orient_matrix_dirty_ : 1 {true};
bool shutting_down_ : 1 {};
bool shutdown_completed_ : 1 {};
Snapshot<GraphicsClientContext>* client_context_{};
float res_x_{};
float res_y_{};
float res_x_virtual_{};
@ -353,6 +352,7 @@ class GraphicsServer {
Vector3f cam_target_{0.0f, 0.0f, 0.0f};
Matrix44f light_shadow_projection_matrix_{kMatrix44fIdentity};
Matrix44f cam_orient_matrix_ = kMatrix44fIdentity;
Snapshot<GraphicsClientContext>* client_context_{};
std::vector<Matrix44f> model_view_stack_;
std::list<MeshData*> mesh_datas_;
Renderer* renderer_{};

View File

@ -48,42 +48,30 @@ auto InputDevice::GetPersistentIdentifier() const -> std::string {
InputDevice::~InputDevice() { assert(g_base->InLogicThread()); }
// Called to let the current host/client-session know that we'd like to control
// something please.
// Called to let the current host/client-session know that we'd like to
// control something please.
void InputDevice::RequestPlayer() {
assert(g_base->InLogicThread());
// Make note that we're being used in some way.
last_input_time_millisecs_ =
static_cast<millisecs_t>(g_base->logic->display_time() * 1000.0);
// Tracking down a bug.
BA_PRECONDITION_FATAL(delegate_.Exists());
delegate_->RequestPlayer();
}
// If we're attached to a remote player, ship completed packets every now and
// then.
void InputDevice::Update() {
// Tracking down a bug.
BA_PRECONDITION_FATAL(delegate_.Exists());
delegate_->Update();
}
// If we're attached to a remote player, ship completed packets every now
// and then.
void InputDevice::Update() { delegate_->Update(); }
auto InputDevice::AttachedToPlayer() const -> bool {
// Tracking down a bug.
BA_PRECONDITION_FATAL(delegate_.Exists());
return delegate_->AttachedToPlayer();
}
void InputDevice::DetachFromPlayer() {
// Tracking down a bug.
BA_PRECONDITION_FATAL(delegate_.Exists());
delegate_->DetachFromPlayer();
}
void InputDevice::DetachFromPlayer() { delegate_->DetachFromPlayer(); }
void InputDevice::UpdateLastInputTime() {
// Keep our own individual time, and also let
// the overall input system know something happened.
// Keep our own individual time, and also let the overall input system
// know something happened.
last_input_time_millisecs_ =
static_cast<millisecs_t>(g_base->logic->display_time() * 1000.0);
g_base->input->MarkInputActive();
@ -95,8 +83,6 @@ void InputDevice::InputCommand(InputType type, float value) {
// Make note that we're being used in some way.
UpdateLastInputTime();
// Tracking down a bug.
BA_PRECONDITION_FATAL(delegate_.Exists());
delegate_->InputCommand(type, value);
}

View File

@ -112,10 +112,11 @@ auto Input::GetNewNumberedIdentifier_(const std::string& name,
}
if (!in_use) {
// Ok so far its unused.. however input devices that provide non-empty
// identifiers (serial number, usb-id, etc) reserve their number for the
// duration of the game, so we need to check against all reserved numbers
// so we don't steal someones... (so that if they disconnect and reconnect
// they'll get the same number and thus the same name, etc)
// identifiers (serial number, usb-id, etc) reserve their number for
// the duration of the game, so we need to check against all reserved
// numbers so we don't steal someones... (so that if they disconnect
// and reconnect they'll get the same number and thus the same name,
// etc)
if (!identifier.empty()) {
auto i = reserved_identifiers_.find(name);
if (i != reserved_identifiers_.end()) {
@ -144,10 +145,6 @@ auto Input::GetNewNumberedIdentifier_(const std::string& name,
return full_id;
}
// void Input::CreateTouchInput() {
// assert(g_core->InMainThread());
// }
void Input::AnnounceConnects_() {
assert(g_base->InLogicThread());
@ -308,10 +305,10 @@ void Input::AddInputDevice(InputDevice* device, bool standard_message) {
}
// We also want to give this input-device as unique an identifier as
// possible. We ask it for its own string which hopefully includes a serial
// or something, but if it doesn't and thus matches an already-existing one,
// we tack an index on to it. that way we can at least uniquely address them
// based off how many are connected.
// possible. We ask it for its own string which hopefully includes a
// serial or something, but if it doesn't and thus matches an
// already-existing one, we tack an index on to it. that way we can at
// least uniquely address them based off how many are connected.
device->set_number(GetNewNumberedIdentifier_(device->GetRawDeviceName(),
device->GetDeviceIdentifier()));
@ -325,23 +322,11 @@ void Input::AddInputDevice(InputDevice* device, bool standard_message) {
device->UpdateMapping();
// Need to do this after updating controls, as some control settings can
// affect things we count (such as whether start activates default button).
// affect things we count (such as whether start activates default
// button).
UpdateInputDeviceCounts_();
}
if (g_buildconfig.ostype_macos()) {
// Special case: on mac, the first time a iOS/Mac controller is connected,
// let the user know they may want to enable them if they're currently set
// as ignored. (the default at the moment is to only use classic device
// support).
static bool printed_ios_mac_controller_warning = false;
if (!printed_ios_mac_controller_warning && ignore_mfi_controllers_
&& device->IsMFiController()) {
ScreenMessage(R"({"r":"macControllerSubsystemMFiNoteText"})", {1, 1, 0});
printed_ios_mac_controller_warning = true;
}
}
if (standard_message && !device->ShouldBeHiddenFromUser()) {
ShowStandardInputDeviceConnectedMessage_(device);
}
@ -362,16 +347,16 @@ void Input::RemoveInputDevice(InputDevice* input, bool standard_message) {
ShowStandardInputDeviceDisconnectedMessage_(input);
}
// Just look for it in our list.. if we find it, simply clear the ref
// (we need to keep the ref around so our list indices don't change).
// Just look for it in our list.. if we find it, simply clear the ref (we
// need to keep the ref around so our list indices don't change).
for (auto& input_device : input_devices_) {
if (input_device.Exists() && (input_device.Get() == input)) {
// Pull it off the list before killing it (in case it tries to trigger
// another kill itself).
auto device = Object::Ref<InputDevice>(input_device);
// Ok we cleared its slot in our vector; now we just have
// the local variable 'device' keeping it alive.
// Ok we cleared its slot in our vector; now we just have the local
// variable 'device' keeping it alive.
input_device.Clear();
// Tell it to detach from anything it is controlling.
@ -519,41 +504,7 @@ auto Input::GetConfigurableGamePads() -> std::vector<InputDevice*> {
auto Input::ShouldCompletelyIgnoreInputDevice(InputDevice* input_device)
-> bool {
if (g_buildconfig.ostype_macos()) {
if (ignore_mfi_controllers_ && input_device->IsMFiController()) {
return true;
}
}
return ignore_sdl_controllers_ && input_device->IsSDLController();
}
void Input::UpdateEnabledControllerSubsystems_() {
assert(g_base);
// First off, on mac, let's update whether we want to completely ignore
// either the classic or the iOS/Mac controller subsystems.
//
// UPDATE - these days we're mfi-only on our xcode builds (which should
// support older controllers too). So we don't need to touch ignore vals
// anywhere since we'll not get sdl ones on those builds.
// if (g_buildconfig.ostype_macos()) {
// std::string sys = g_base->app_config->Resolve(
// AppConfig::StringID::kMacControllerSubsystem);
// if (sys == "Classic") {
// ignore_mfi_controllers_ = true;
// ignore_sdl_controllers_ = false;
// } else if (sys == "MFi") {
// ignore_mfi_controllers_ = false;
// ignore_sdl_controllers_ = true;
// } else if (sys == "Both") {
// ignore_mfi_controllers_ = false;
// ignore_sdl_controllers_ = false;
// } else {
// BA_LOG_ONCE(LogLevel::kError,
// "Invalid mac-controller-subsystem value: '" + sys + "'");
// }
// }
return false;
}
void Input::OnAppStart() {
@ -577,8 +528,6 @@ void Input::OnAppShutdownComplete() { assert(g_base->InLogicThread()); }
void Input::DoApplyAppConfig() {
assert(g_base->InLogicThread());
UpdateEnabledControllerSubsystems_();
// It's technically possible that updating these controls will add or
// remove devices, thus changing the input_devices_ list, so lets work
// with a copy of it.
@ -612,10 +561,11 @@ void Input::StepDisplayTime() {
}
}
// We now need to update our input-device numbers dynamically since they're
// based on recently-active devices.
// ..we do this much more often for the first few seconds to keep
// controller-usage from being as annoying.
// We now need to update our input-device numbers dynamically since
// they're based on recently-active devices. We do this much more often
// for the first few seconds to keep controller-usage from being as
// annoying.
// millisecs_t incr = (real_time > 10000) ? 468 : 98;
// Update: don't remember why that was annoying; trying a single value for
// now.
@ -780,18 +730,18 @@ void Input::PushTextInputEvent(const std::string& text) {
return;
}
// Also ignore if there are any mod keys being held.
// We process some of our own keyboard shortcuts and don't
// want text input to come through at the same time.
// Also ignore if there are any mod keys being held. We process some of
// our own keyboard shortcuts and don't want text input to come through
// at the same time.
if (keys_held_.contains(SDLK_LCTRL) || keys_held_.contains(SDLK_RCTRL)
|| keys_held_.contains(SDLK_LALT) || keys_held_.contains(SDLK_RALT)
|| keys_held_.contains(SDLK_LGUI) || keys_held_.contains(SDLK_RGUI)) {
return;
}
// Ignore back-tick and tilde because we use that key to toggle the console.
// FIXME: Perhaps should allow typing it if some control-character is
// held?
// Ignore back-tick and tilde because we use that key to toggle the
// console. FIXME: Perhaps should allow typing it if some
// control-character is held?
if (text == "`" || text == "~") {
return;
}
@ -958,10 +908,9 @@ void Input::HandleKeyPress_(const SDL_Keysym& keysym) {
return;
}
// Nowadays we don't want the OS to deliver repeat events to us,
// so filter out any that we get and make noise that they should stop. We
// explicitly handle repeats for UI purposes at the InputDevice or Widget
// level now.
// Nowadays we don't want the OS to deliver repeat events to us, so filter
// out any that we get and make noise that they should stop. We explicitly
// handle repeats for UI purposes at the InputDevice or Widget level now.
if (keys_held_.find(keysym.sym) != keys_held_.end()) {
// Look out for several repeats coming in within the span of a few
// seconds and complain if it happens. This should allow for the random
@ -993,9 +942,9 @@ void Input::HandleKeyPress_(const SDL_Keysym& keysym) {
}
}
// Regardless of what else we do, keep track of mod key states.
// (for things like manual camera moves. For individual key presses
// ideally we should use the modifiers bundled with the key presses)
// Regardless of what else we do, keep track of mod key states. (for
// things like manual camera moves. For individual key presses ideally we
// should use the modifiers bundled with the key presses)
UpdateModKeyStates_(&keysym, true);
// Mobile-specific stuff.
@ -1317,9 +1266,9 @@ void Input::HandleMouseMotion_(const Vector2f& position) {
last_mouse_move_time_ = g_core->GetAppTimeSeconds();
mouse_move_count_++;
// If we have a touch-input in editing mode, pass along events to it.
// (it usually handles its own events but here we want it to play nice
// with stuff under it by blocking touches, etc)
// If we have a touch-input in editing mode, pass along events to it. (it
// usually handles its own events but here we want it to play nice with
// stuff under it by blocking touches, etc)
if (touch_input_ && touch_input_->editing()) {
touch_input_->HandleTouchMoved(reinterpret_cast<void*>(1), cursor_pos_x_,
cursor_pos_y_);

View File

@ -157,7 +157,6 @@ class Input {
void UpdateInputDeviceCounts_();
auto GetNewNumberedIdentifier_(const std::string& name,
const std::string& identifier) -> int;
void UpdateEnabledControllerSubsystems_();
void AnnounceConnects_();
void AnnounceDisconnects_();
void HandleKeyPressSimple_(int keycode);
@ -190,8 +189,6 @@ class Input {
bool have_button_using_inputs_ : 1 {};
bool have_start_activated_default_button_inputs_ : 1 {};
bool have_non_touch_inputs_ : 1 {};
bool ignore_mfi_controllers_ : 1 {};
bool ignore_sdl_controllers_ : 1 {};
millisecs_t input_idle_time_{};
millisecs_t last_get_local_active_input_device_count_check_time_{};
float cursor_pos_x_{};

View File

@ -93,6 +93,30 @@ void BasePlatformApple::LoginAdapterBackEndActiveChange(
#endif
}
auto BasePlatformApple::SupportsOpenDirExternally() -> bool {
#if BA_XCODE_BUILD && BA_OSTYPE_MACOS
return true;
#else
return BasePlatform::SupportsOpenDirExternally();
#endif
}
void BasePlatformApple::OpenDirExternally(const std::string& path) {
#if BA_OSTYPE_MACOS && BA_XCODE_BUILD
BallisticaKit::CocoaFromCpp::openDirExternally(path);
#else
BasePlatform::OpenDirExternally(path);
#endif
}
void BasePlatformApple::OpenFileExternally(const std::string& path) {
#if BA_OSTYPE_MACOS && BA_XCODE_BUILD
BallisticaKit::CocoaFromCpp::openFileExternally(path);
#else
BasePlatform::OpenFileExternally(path);
#endif
}
} // namespace ballistica::base
#endif // BA_OSTYPE_MACOS || BA_OSTYPE_IOS_TVOS

View File

@ -20,6 +20,9 @@ class BasePlatformApple : public BasePlatform {
int attempt_id) override;
void LoginAdapterBackEndActiveChange(const std::string& login_type,
bool active) override;
auto SupportsOpenDirExternally() -> bool override;
void OpenDirExternally(const std::string& path) override;
void OpenFileExternally(const std::string& path) override;
};
} // namespace ballistica::base

View File

@ -221,4 +221,14 @@ void BasePlatform::DoInvokeStringEditor(const std::string& title,
Log(LogLevel::kError, "FIXME: DoInvokeStringEditor() unimplemented");
}
auto BasePlatform::SupportsOpenDirExternally() -> bool { return false; }
void BasePlatform::OpenDirExternally(const std::string& path) {
Log(LogLevel::kError, "OpenDirExternally() unimplemented");
}
void BasePlatform::OpenFileExternally(const std::string& path) {
Log(LogLevel::kError, "OpenFileExternally() unimplemented");
}
} // namespace ballistica::base

View File

@ -98,6 +98,16 @@ class BasePlatform {
auto ran_base_post_init() const { return ran_base_post_init_; }
/// Do we support opening dirs exteranlly? (via finder, windows explorer,
/// etc.)
virtual auto SupportsOpenDirExternally() -> bool;
/// Open a directory using the system default method (Finder, etc.)
virtual void OpenDirExternally(const std::string& path);
/// Open a file using the system default method (in another app, etc.)
virtual void OpenFileExternally(const std::string& path);
protected:
/// Pop up a text edit dialog.
virtual void DoInvokeStringEditor(const std::string& title,

View File

@ -17,6 +17,26 @@ void BasePlatformLinux::DoOpenURL(const std::string& url) {
BasePlatform::DoOpenURL(url);
}
auto BasePlatformLinux::SupportsOpenDirExternally() -> bool { return true; }
void BasePlatformLinux::OpenDirExternally(const std::string& path) {
std::string cmd = std::string("xdg-open \"") + path + "\"";
int result = system(cmd.c_str());
if (result != 0) {
Log(LogLevel::kError, "Got return value " + std::to_string(result)
+ " on xdg-open cmd '" + cmd + "'");
}
}
void BasePlatformLinux::OpenFileExternally(const std::string& path) {
std::string cmd = std::string("xdg-open \"") + path + "\"";
int result = system(cmd.c_str());
if (result != 0) {
Log(LogLevel::kError, "Got return value " + std::to_string(result)
+ " on xdg-open cmd '" + cmd + "'");
}
}
} // namespace ballistica::base
#endif // BA_OSTYPE_LINUX

View File

@ -14,6 +14,9 @@ class BasePlatformLinux : public BasePlatform {
public:
BasePlatformLinux();
void DoOpenURL(const std::string& url) override;
auto SupportsOpenDirExternally() -> bool override;
void OpenDirExternally(const std::string& path) override;
void OpenFileExternally(const std::string& path) override;
};
} // namespace ballistica::base

View File

@ -15,6 +15,7 @@
#include "ballistica/base/logic/logic.h"
#include "ballistica/core/platform/windows/core_platform_windows.h"
#include "ballistica/shared/foundation/event_loop.h"
#include "ballistica/shared/generic/utils.h"
namespace ballistica::base {
@ -62,6 +63,30 @@ void BasePlatformWindows::SetupInterruptHandling() {
}
}
auto BasePlatformWindows::SupportsOpenDirExternally() -> bool { return true; }
void BasePlatformWindows::OpenDirExternally(const std::string& path) {
auto r = reinterpret_cast<intptr_t>(
ShellExecute(nullptr, _T("open"), _T("explorer.exe"),
core::CorePlatformWindows::UTF8Decode(path).c_str(), nullptr,
SW_SHOWNORMAL));
if (r <= 32) {
Log(LogLevel::kError, "Error " + std::to_string(r)
+ " on open_dir_externally for '" + path + "'");
}
}
void BasePlatformWindows::OpenFileExternally(const std::string& path) {
auto r = reinterpret_cast<intptr_t>(
ShellExecute(nullptr, _T("open"), _T("notepad.exe"),
core::CorePlatformWindows::UTF8Decode(path).c_str(), nullptr,
SW_SHOWNORMAL));
if (r <= 32) {
Log(LogLevel::kError, "Error " + std::to_string(r)
+ " on open_file_externally for '" + path + "'");
}
}
} // namespace ballistica::base
#endif // BA_OSTYPE_WINDOWS

View File

@ -16,6 +16,9 @@ class BasePlatformWindows : public BasePlatform {
BasePlatformWindows();
void DoOpenURL(const std::string& url) override;
void SetupInterruptHandling() override;
auto SupportsOpenDirExternally() -> bool override;
void OpenDirExternally(const std::string& path) override;
void OpenFileExternally(const std::string& path) override;
};
} // namespace ballistica::base

View File

@ -1395,6 +1395,31 @@ static PyMethodDef PyNativeStackTraceDef = {
"Only use them for debugging.",
};
// --------------------- supports_open_dir_externally --------------------------
static auto PySupportsOpenDirExternally(PyObject* self, PyObject* args,
PyObject* keywds) -> PyObject* {
BA_PYTHON_TRY;
if (g_base->platform->SupportsOpenDirExternally()) {
Py_RETURN_TRUE;
}
Py_RETURN_FALSE;
BA_PYTHON_CATCH;
}
static PyMethodDef PySupportsOpenDirExternallyDef = {
"supports_open_dir_externally", // name
(PyCFunction)PySupportsOpenDirExternally, // method
METH_NOARGS, // flags
"supports_open_dir_externally() -> bool\n"
"\n"
"(internal)\n"
"\n"
"Return whether the current app/platform supports opening dirs externally\n"
"(in the Mac Finder, Windows Explorer, etc.).",
};
// -------------------------- open_dir_externally ------------------------------
static auto PyOpenDirExternally(PyObject* self, PyObject* args,
@ -1406,7 +1431,7 @@ static auto PyOpenDirExternally(PyObject* self, PyObject* args,
const_cast<char**>(kwlist), &path)) {
return nullptr;
}
g_core->platform->OpenDirExternally(path);
g_base->platform->OpenDirExternally(path);
Py_RETURN_NONE;
BA_PYTHON_CATCH;
}
@ -1816,6 +1841,7 @@ auto PythonMethodsMisc::GetMethods() -> std::vector<PyMethodDef> {
PyGetSimpleSoundDef,
PyHasTouchScreenDef,
PyNativeStackTraceDef,
PySupportsOpenDirExternallyDef,
PyOpenDirExternallyDef,
PyFatalErrorDef,
PyDevConsoleAddButtonDef,

View File

@ -6,6 +6,7 @@
#include "ballistica/base/app_mode/app_mode.h"
#include "ballistica/base/audio/audio.h"
#include "ballistica/base/graphics/component/simple_component.h"
#include "ballistica/base/graphics/mesh/nine_patch_mesh.h"
#include "ballistica/base/graphics/text/text_graphics.h"
#include "ballistica/base/logic/logic.h"
#include "ballistica/base/platform/base_platform.h"

View File

@ -8,7 +8,6 @@
#include <utility>
#include <vector>
#include "ballistica/base/graphics/mesh/nine_patch_mesh.h"
#include "ballistica/base/graphics/renderer/renderer.h"
#include "ballistica/shared/foundation/object.h"
#include "ballistica/shared/python/python_ref.h"

View File

@ -25,13 +25,14 @@ namespace ballistica::core {
CorePlatformApple::CorePlatformApple() = default;
auto CorePlatformApple::GetDeviceV1AccountUUIDPrefix() -> std::string {
#if BA_OSTYPE_MACOS
return "m";
#elif BA_OSTYPE_IOS_TVOS
return "i";
#else
#error FIXME
#endif
if (g_buildconfig.ostype_macos()) {
return "m";
} else if (g_buildconfig.ostype_ios_tvos()) {
return "i";
} else {
FatalError("Unhandled V1 UUID case.");
return "";
}
}
auto CorePlatformApple::DoGetDeviceName() -> std::string {
@ -349,22 +350,6 @@ auto CorePlatformApple::IsOSPlayingMusic() -> bool {
#endif
}
void CorePlatformApple::OpenFileExternally(const std::string& path) {
#if BA_OSTYPE_MACOS && BA_XCODE_BUILD
BallisticaKit::CocoaFromCpp::openFileExternally(path);
#else
CorePlatform::OpenFileExternally(path);
#endif
}
void CorePlatformApple::OpenDirExternally(const std::string& path) {
#if BA_OSTYPE_MACOS && BA_XCODE_BUILD
BallisticaKit::CocoaFromCpp::openDirExternally(path);
#else
CorePlatform::OpenDirExternally(path);
#endif
}
void CorePlatformApple::MacMusicAppInit() {
#if BA_OSTYPE_MACOS && BA_XCODE_BUILD
BallisticaKit::CocoaFromCpp::macMusicAppInit();

View File

@ -44,10 +44,7 @@ class CorePlatformApple : public CorePlatform {
void ShowOnlineScoreUI(const std::string& show, const std::string& game,
const std::string& game_version) override;
void ResetAchievements() override;
// void GameCenterLogin() override;
auto IsOSPlayingMusic() -> bool override;
void OpenFileExternally(const std::string& path) override;
void OpenDirExternally(const std::string& path) override;
void MacMusicAppInit() override;
auto MacMusicAppGetVolume() -> int override;
void MacMusicAppSetVolume(int volume) override;

View File

@ -804,14 +804,6 @@ void CorePlatform::SignOutV1() {
Log(LogLevel::kError, "SignOutV1() unimplemented");
}
void CorePlatform::OpenFileExternally(const std::string& path) {
Log(LogLevel::kError, "OpenFileExternally() unimplemented");
}
void CorePlatform::OpenDirExternally(const std::string& path) {
Log(LogLevel::kError, "OpenDirExternally() unimplemented");
}
void CorePlatform::MacMusicAppInit() {
Log(LogLevel::kError, "MacMusicAppInit() unimplemented");
}

View File

@ -384,12 +384,6 @@ class CorePlatform {
/// Pass platform-specific misc-read-vals along to the OS (as a json string).
virtual void SetPlatformMiscReadVals(const std::string& vals);
/// Open a file using the system default method (in another app, etc.)
virtual void OpenFileExternally(const std::string& path);
/// Open a directory using the system default method (Finder, etc.)
virtual void OpenDirExternally(const std::string& path);
/// Set the name of the current thread (for debugging).
virtual void SetCurrentThreadName(const std::string& name);

View File

@ -100,24 +100,6 @@ auto CorePlatformLinux::GetDeviceUUIDInputs() -> std::list<std::string> {
bool CorePlatformLinux::DoHasTouchScreen() { return false; }
void CorePlatformLinux::OpenFileExternally(const std::string& path) {
std::string cmd = std::string("xdg-open \"") + path + "\"";
int result = system(cmd.c_str());
if (result != 0) {
Log(LogLevel::kError, "Got return value " + std::to_string(result)
+ " on xdg-open cmd '" + cmd + "'");
}
}
void CorePlatformLinux::OpenDirExternally(const std::string& path) {
std::string cmd = std::string("xdg-open \"") + path + "\"";
int result = system(cmd.c_str());
if (result != 0) {
Log(LogLevel::kError, "Got return value " + std::to_string(result)
+ " on xdg-open cmd '" + cmd + "'");
}
}
std::string CorePlatformLinux::GetPlatformName() { return "linux"; }
std::string CorePlatformLinux::GetSubplatformName() {

View File

@ -16,8 +16,6 @@ class CorePlatformLinux : public CorePlatform {
auto GetDeviceV1AccountUUIDPrefix() -> std::string override { return "l"; }
auto GenerateUUID() -> std::string override;
auto DoHasTouchScreen() -> bool override;
void OpenFileExternally(const std::string& path) override;
void OpenDirExternally(const std::string& path) override;
auto GetPlatformName() -> std::string override;
auto GetSubplatformName() -> std::string override;
auto GetDeviceUUIDInputs() -> std::list<std::string> override;

View File

@ -964,26 +964,6 @@ std::string CorePlatformWindows::GetCWD() {
return UTF8Encode(buffer);
}
void CorePlatformWindows::OpenFileExternally(const std::string& path) {
auto r = reinterpret_cast<intptr_t>(
ShellExecute(nullptr, _T("open"), _T("notepad.exe"),
UTF8Decode(path).c_str(), nullptr, SW_SHOWNORMAL));
if (r <= 32) {
Log(LogLevel::kError, "Error " + std::to_string(r)
+ " on open_file_externally for '" + path + "'");
}
}
void CorePlatformWindows::OpenDirExternally(const std::string& path) {
auto r = reinterpret_cast<intptr_t>(
ShellExecute(nullptr, _T("open"), _T("explorer.exe"),
UTF8Decode(path).c_str(), nullptr, SW_SHOWNORMAL));
if (r <= 32) {
Log(LogLevel::kError, "Error " + std::to_string(r)
+ " on open_dir_externally for '" + path + "'");
}
}
void CorePlatformWindows::Unlink(const char* path) { _unlink(path); }
void CorePlatformWindows::CloseSocket(int socket) { closesocket(socket); }

View File

@ -49,8 +49,6 @@ class CorePlatformWindows : public CorePlatform {
auto GetIsStdinATerminal() -> bool override;
auto GetOSVersionString() -> std::string override;
auto GetCWD() -> std::string override;
void OpenFileExternally(const std::string& path) override;
void OpenDirExternally(const std::string& path) override;
void Unlink(const char* path) override;
void CloseSocket(int socket) override;
auto GetBroadcastAddrs() -> std::vector<uint32_t> override;

View File

@ -5,6 +5,7 @@
#include "ballistica/base/assets/assets_server.h"
#include "ballistica/base/graphics/graphics.h"
#include "ballistica/base/graphics/support/net_graph.h"
#include "ballistica/base/logic/logic.h"
#include "ballistica/scene_v1/connection/connection_to_host.h"
#include "ballistica/scene_v1/support/scene_v1_app_mode.h"
@ -118,24 +119,27 @@ void ClientSessionNet::UpdateBuffering() {
set_consume_rate(new_consume_rate);
if (g_base->graphics->network_debug_info_display_enabled()) {
// Plug display time into these graphs to get smoother looking updates.
auto now_d = g_base->logic->display_time() * 1000.0;
if (auto* graph =
g_base->graphics->GetDebugGraph("1: packet delay", false)) {
graph->AddSample(now, current_delay_);
graph->AddSample(now_d, current_delay_);
}
if (auto* graph =
g_base->graphics->GetDebugGraph("2: max delay bucketed", false)) {
graph->AddSample(now, last_bucket_max_delay_);
graph->AddSample(now_d, last_bucket_max_delay_);
}
if (auto* graph =
g_base->graphics->GetDebugGraph("3: filtered delay", false)) {
graph->AddSample(now, max_delay_smoothed_);
graph->AddSample(now_d, max_delay_smoothed_);
}
if (auto* graph = g_base->graphics->GetDebugGraph("4: run rate", false)) {
graph->AddSample(now, new_consume_rate);
graph->AddSample(now_d, new_consume_rate);
}
if (auto* graph =
g_base->graphics->GetDebugGraph("5: time buffered", true)) {
graph->AddSample(now, base_time_buffered());
graph->AddSample(now_d, base_time_buffered());
}
}
}

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 = 21585;
const int kEngineBuildNumber = 21588;
const char* kEngineVersion = "1.7.28";
const int kEngineApiVersion = 8;

View File

@ -1868,6 +1868,7 @@ static auto PyTextWidget(PyObject* self, PyObject* args, PyObject* keywds)
PyObject* query_max_chars_obj = Py_None;
PyObject* query_description_obj = Py_None;
PyObject* adapter_finished_obj = Py_None;
PyObject* glow_type_obj = Py_None;
static const char* kwlist[] = {"edit",
"parent",
@ -1907,9 +1908,10 @@ static auto PyTextWidget(PyObject* self, PyObject* args, PyObject* keywds)
"query_max_chars",
"query_description",
"adapter_finished",
"glow_type",
nullptr};
if (!PyArg_ParseTupleAndKeywords(
args, keywds, "|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
args, keywds, "|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
const_cast<char**>(kwlist), &edit_obj, &parent_obj, &size_obj,
&pos_obj, &text_obj, &v_align_obj, &h_align_obj, &editable_obj,
&padding_obj, &on_return_press_call_obj, &on_activate_call_obj,
@ -1920,7 +1922,7 @@ static auto PyTextWidget(PyObject* self, PyObject* args, PyObject* keywds)
&shadow_obj, &autoselect_obj, &rotate_obj, &enabled_obj,
&force_internal_editing_obj, &always_show_carat_obj, &big_obj,
&extra_touch_border_scale_obj, &res_scale_obj, &query_max_chars_obj,
&query_description_obj, &adapter_finished_obj))
&query_description_obj, &adapter_finished_obj, &glow_type_obj))
return nullptr;
if (!g_base->CurrentContext().IsEmpty()) {
@ -2123,8 +2125,20 @@ static auto PyTextWidget(PyObject* self, PyObject* args, PyObject* keywds)
throw Exception("Unexpected value for adapter_finished");
}
}
if (glow_type_obj != Py_None) {
auto glow_type_s = Python::GetPyString(glow_type_obj);
TextWidget::GlowType glow_type;
if (glow_type_s == "uniform") {
glow_type = TextWidget::GlowType::kUniform;
} else if (glow_type_s == "gradient") {
glow_type = TextWidget::GlowType::kGradient;
} else {
throw Exception("Invalid glow_type: " + glow_type_s, PyExcType::kValue);
}
widget->set_glow_type(glow_type);
}
// if making a new widget add it at the end
// If making a new widget, add it at the end.
if (edit_obj == Py_None) {
g_ui_v1->AddWidget(widget.Get(), parent_widget);
}
@ -2175,7 +2189,8 @@ static PyMethodDef PyTextWidgetDef = {
" res_scale: float | None = None,"
" query_max_chars: bauiv1.Widget | None = None,\n"
" query_description: bauiv1.Widget | None = None,\n"
" adapter_finished: bool | None = None)\n"
" adapter_finished: bool | None = None,\n"
" glow_type: str | None = None)\n"
" -> bauiv1.Widget\n"
"\n"
"Create or edit a text widget.\n"
@ -2725,7 +2740,7 @@ static auto PyOpenFileExternally(PyObject* self, PyObject* args,
const_cast<char**>(kwlist), &path)) {
return nullptr;
}
g_core->platform->OpenFileExternally(path);
g_base->platform->OpenFileExternally(path);
Py_RETURN_NONE;
BA_PYTHON_CATCH;
}

View File

@ -6,6 +6,7 @@
#include "ballistica/base/audio/audio.h"
#include "ballistica/base/graphics/component/empty_component.h"
#include "ballistica/base/graphics/component/simple_component.h"
#include "ballistica/base/graphics/mesh/nine_patch_mesh.h"
#include "ballistica/base/graphics/text/text_graphics.h"
#include "ballistica/base/input/device/keyboard_input.h"
#include "ballistica/base/input/input.h"
@ -114,8 +115,9 @@ void TextWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
// another component at the end with the matching pop. This only works
// because the components in the middle wind up writing to the same draw
// list, but there is nothing checking or enforcing that so it would be
// easy to break. Should improve this somehow. (perhaps by using a single
// component and enforcing list uniformity between push/pop blocks?)
// easy to break. Should improve this somehow. (perhaps by using a
// single component and enforcing list uniformity between push/pop
// blocks?)
c.PushTransform();
// Move to middle, scale down, move back.
@ -159,34 +161,68 @@ void TextWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
}
if (highlight_dirty_) {
float l_border, r_border, b_border, t_border;
float l2 = bound_l;
float r2 = bound_r;
float t2 = bound_t;
float b2 = bound_b;
l_border = std::max(10.0f, (r2 - l2) * 0.05f);
r_border = 0;
b_border = std::max(16.0f, (t2 - b2) * 0.16f);
t_border = std::max(14.0f, (t2 - b2) * 0.14f);
highlight_width_ = r2 - l2 + l_border + r_border;
highlight_height_ = t2 - b2 + b_border + t_border;
highlight_center_x_ = l2 - l_border + highlight_width_ * 0.5f;
highlight_center_y_ = b2 - b_border + highlight_height_ * 0.5f;
if (glow_type_ == GlowType::kGradient) {
float l_border, r_border, b_border, t_border;
float l2 = bound_l;
float r2 = bound_r;
float t2 = bound_t;
float b2 = bound_b;
l_border = std::max(10.0f, (r2 - l2) * 0.05f);
r_border = 0;
b_border = std::max(16.0f, (t2 - b2) * 0.16f);
t_border = std::max(14.0f, (t2 - b2) * 0.14f);
highlight_width_ = r2 - l2 + l_border + r_border;
highlight_height_ = t2 - b2 + b_border + t_border;
highlight_center_x_ = l2 - l_border + highlight_width_ * 0.5f;
highlight_center_y_ = b2 - b_border + highlight_height_ * 0.5f;
highlight_mesh_.Clear();
} else {
assert(glow_type_ == GlowType::kUniform);
float corner_radius{30.0f};
float width{bound_r - bound_l};
float height{bound_t - bound_b};
float x_extend{12.0f};
float y_extend{6.0f};
float x_offset{0.0f};
float width_fin = width + x_extend * 2.0f;
float height_fin = height + y_extend * 2.0f;
float x_border = base::NinePatchMesh::BorderForRadius(
corner_radius, width_fin, height_fin);
float y_border = base::NinePatchMesh::BorderForRadius(
corner_radius, height_fin, width_fin);
highlight_mesh_ = Object::New<base::NinePatchMesh>(
-x_extend + x_offset, -y_extend, 0.0f, width_fin, height_fin,
x_border, y_border, x_border, y_border);
}
highlight_dirty_ = false;
}
base::SimpleComponent c(pass);
c.SetTransparent(true);
c.SetPremultiplied(true);
c.SetColor(0.25f * m, 0.3f * m, 0, 0.3f * m);
c.SetTexture(g_base->assets->SysTexture(base::SysTextureID::kGlow));
{
auto xf = c.ScopedTransform();
c.Translate(highlight_center_x_, highlight_center_y_, 0.1f);
c.Scale(highlight_width_, highlight_height_);
c.DrawMeshAsset(g_base->assets->SysMesh(base::SysMeshID::kImage4x1));
if (glow_type_ == GlowType::kGradient) {
base::SimpleComponent c(pass);
c.SetTransparent(true);
c.SetPremultiplied(true);
c.SetColor(0.25f * m, 0.3f * m, 0, 0.3f * m);
c.SetTexture(g_base->assets->SysTexture(base::SysTextureID::kGlow));
{
auto xf = c.ScopedTransform();
c.Translate(highlight_center_x_, highlight_center_y_, 0.1f);
c.Scale(highlight_width_, highlight_height_);
c.DrawMeshAsset(g_base->assets->SysMesh(base::SysMeshID::kImage4x1));
}
} else {
assert(glow_type_ == GlowType::kUniform);
base::SimpleComponent c(pass);
c.SetTransparent(true);
c.SetColor(0.9 * m, 1.0f * m, 0, 0.3f * m);
c.SetTexture(
g_base->assets->SysTexture(base::SysTextureID::kShadowSharp));
{
auto xf = c.ScopedTransform();
c.Translate(bound_l, bound_b, 0.1f);
c.DrawMesh(highlight_mesh_.Get());
}
}
c.Submit();
}
// Outline.
@ -660,7 +696,7 @@ auto TextWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
}
}
// If we're doing inline editing, handle some key events.
if (m.has_keysym && !ShouldUseStringEditor_()) {
if (editable() && m.has_keysym && !ShouldUseStringEditor_()) {
last_carat_change_time_millisecs_ =
static_cast<millisecs_t>(g_base->logic->display_time() * 1000.0);
text_group_dirty_ = true;

View File

@ -21,8 +21,9 @@ class TextWidget : public Widget {
void SetHeight(float heightIn);
auto GetWidth() -> float override;
auto GetHeight() -> float override;
enum class HAlign { kLeft, kCenter, kRight };
enum class VAlign { kTop, kCenter, kBottom };
enum class HAlign : uint8_t { kLeft, kCenter, kRight };
enum class VAlign : uint8_t { kTop, kCenter, kBottom };
enum class GlowType : uint8_t { kGradient, kUniform };
auto HandleMessage(const base::WidgetMessage& m) -> bool override;
auto IsSelectable() -> bool override {
return (enabled_ && (editable_ || selectable_));
@ -87,6 +88,13 @@ class TextWidget : public Widget {
void set_extra_touch_border_scale(float scale) {
extra_touch_border_scale_ = scale;
}
void set_glow_type(GlowType glow_type) {
if (glow_type == glow_type_) {
return;
}
glow_type_ = glow_type;
highlight_dirty_ = true;
}
private:
auto ScaleAdjustedX_(float x) -> float;
@ -101,18 +109,35 @@ class TextWidget : public Widget {
float max_height_scale);
void DoDrawText_(base::RenderPass* pass, float x_offset, float y_offset,
float max_width_scale, float max_height_scale);
HAlign alignment_h_{HAlign::kLeft};
VAlign alignment_v_{VAlign::kTop};
GlowType glow_type_{GlowType::kGradient};
bool enabled_ : 1 {true};
bool big_ : 1 {};
bool force_internal_editing_ : 1 {};
bool always_show_carat_ : 1 {};
bool highlight_dirty_ : 1 {true};
bool text_translation_dirty_ : 1 {true};
bool text_group_dirty_ : 1 {true};
bool outline_dirty_ : 1 {true};
bool click_activate_ : 1 {};
bool mouse_over_ : 1 {};
bool pressed_ : 1 {};
bool pressed_activate_ : 1 {};
bool always_highlight_ : 1 {};
bool editable_ : 1 {};
bool selectable_ : 1 {};
bool clear_pressed_ : 1 {};
bool clear_mouse_over_ : 1 {};
bool do_clear_button_ : 1 {true};
int carat_position_{9999};
int max_chars_{99999};
float res_scale_{1.0f};
bool enabled_{true};
millisecs_t birth_time_millisecs_{};
float transition_delay_{};
float max_width_{-1.0f};
float max_height_{-1.0f};
float extra_touch_border_scale_{1.0f};
Object::Ref<base::TextGroup> text_group_;
bool big_{};
bool force_internal_editing_{};
bool always_show_carat_{};
std::string description_{"Text"};
float highlight_width_{};
float highlight_height_{};
float highlight_center_x_{};
@ -124,42 +149,28 @@ class TextWidget : public Widget {
float text_width_{};
float text_height_{};
float rotate_{};
bool highlight_dirty_{true};
bool text_translation_dirty_{true};
bool text_group_dirty_{true};
bool outline_dirty_{true};
bool click_activate_{};
int max_chars_{99999};
float color_r_{1.0f};
float color_g_{1.0f};
float color_b_{1.0f};
float color_a_{1.0f};
bool mouse_over_{};
float flatness_{};
float shadow_{0.5f};
float padding_{};
bool pressed_{};
bool pressed_activate_{};
bool always_highlight_{};
int carat_position_{9999};
bool editable_{};
bool selectable_{};
float width_{50.0f};
float height_{30.0f};
bool clear_pressed_{};
bool clear_mouse_over_{};
bool do_clear_button_{true};
float center_scale_{1.0f};
std::string text_raw_;
std::string text_translated_;
HAlign alignment_h_{HAlign::kLeft};
VAlign alignment_v_{VAlign::kTop};
float flatness_{};
float shadow_{0.5f};
millisecs_t birth_time_millisecs_{};
millisecs_t last_activate_time_millisecs_{};
millisecs_t last_carat_change_time_millisecs_{};
std::string description_{"Text"};
Object::Ref<base::TextGroup> text_group_;
// We keep these at the bottom so they're torn down first.
Object::Ref<base::PythonContextCall> on_return_press_call_;
Object::Ref<base::PythonContextCall> on_activate_call_;
Object::Ref<base::NinePatchMesh> highlight_mesh_;
PythonRef string_edit_adapter_;
};