mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-19 21:37:57 +08:00
almost final mac app store update build
This commit is contained in:
parent
e6d3e7dff2
commit
f06ad6b9ba
100
.efrocachemap
generated
100
.efrocachemap
generated
@ -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",
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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'
|
||||
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -90,6 +90,7 @@ class NetGraph;
|
||||
class Networking;
|
||||
class NetworkReader;
|
||||
class NetworkWriter;
|
||||
class NinePatchMesh;
|
||||
class ObjectComponent;
|
||||
class PythonClassUISound;
|
||||
class PythonContextCall;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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};
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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] {
|
||||
|
||||
@ -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_{};
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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_);
|
||||
|
||||
@ -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_{};
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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); }
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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_;
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user