mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-19 13:25:31 +08:00
adding tokens
This commit is contained in:
parent
cf5fe0fcd0
commit
9acbc2c94f
220
.efrocachemap
generated
220
.efrocachemap
generated
@ -1282,10 +1282,10 @@
|
|||||||
"build/assets/ba_data/textures/buttonPunch.ktx": "9de2058679dd2e55a9c180fafa810559",
|
"build/assets/ba_data/textures/buttonPunch.ktx": "9de2058679dd2e55a9c180fafa810559",
|
||||||
"build/assets/ba_data/textures/buttonPunch.pvr": "7b7ced951fcee4e572988f232d729ad6",
|
"build/assets/ba_data/textures/buttonPunch.pvr": "7b7ced951fcee4e572988f232d729ad6",
|
||||||
"build/assets/ba_data/textures/buttonPunch_preview.png": "e78d05abb78fef5fe18119c4f3fd1dbe",
|
"build/assets/ba_data/textures/buttonPunch_preview.png": "e78d05abb78fef5fe18119c4f3fd1dbe",
|
||||||
"build/assets/ba_data/textures/buttonSquare.dds": "2475ef6978210f993d7c61fc08a15c18",
|
"build/assets/ba_data/textures/buttonSquare.dds": "8b4091b6fc25d964059673062cc9faa6",
|
||||||
"build/assets/ba_data/textures/buttonSquare.ktx": "15794e5bb14980f49ee17a3bcfe7e9b3",
|
"build/assets/ba_data/textures/buttonSquare.ktx": "21fe9898e50c6d44151e059e0a4b94ea",
|
||||||
"build/assets/ba_data/textures/buttonSquare.pvr": "ef1c0a321975aa3a7cad6e4ec29c1196",
|
"build/assets/ba_data/textures/buttonSquare.pvr": "c454666fa706aed388e4ce366248b34d",
|
||||||
"build/assets/ba_data/textures/buttonSquare_preview.png": "d903b64a5f41bce2a64be077bcdfd4ba",
|
"build/assets/ba_data/textures/buttonSquare_preview.png": "e5dc8e92b0306b218be7b6c927aa4e06",
|
||||||
"build/assets/ba_data/textures/chTitleChar1.dds": "d8c615a51d900da15b8aba5ce35296bf",
|
"build/assets/ba_data/textures/chTitleChar1.dds": "d8c615a51d900da15b8aba5ce35296bf",
|
||||||
"build/assets/ba_data/textures/chTitleChar1.ktx": "44384ea28c9fe01440deb1fc80c7224a",
|
"build/assets/ba_data/textures/chTitleChar1.ktx": "44384ea28c9fe01440deb1fc80c7224a",
|
||||||
"build/assets/ba_data/textures/chTitleChar1.pvr": "304d7551786a2eca008bd2057996d05e",
|
"build/assets/ba_data/textures/chTitleChar1.pvr": "304d7551786a2eca008bd2057996d05e",
|
||||||
@ -1517,10 +1517,10 @@
|
|||||||
"build/assets/ba_data/textures/fontExtras.dds": "d2d20fdde7c6114925ba626ade35151f",
|
"build/assets/ba_data/textures/fontExtras.dds": "d2d20fdde7c6114925ba626ade35151f",
|
||||||
"build/assets/ba_data/textures/fontExtras.ktx": "2dde1a343493a9329792d7042116d301",
|
"build/assets/ba_data/textures/fontExtras.ktx": "2dde1a343493a9329792d7042116d301",
|
||||||
"build/assets/ba_data/textures/fontExtras.pvr": "80ab1f61fafba22ce0259177944beabf",
|
"build/assets/ba_data/textures/fontExtras.pvr": "80ab1f61fafba22ce0259177944beabf",
|
||||||
"build/assets/ba_data/textures/fontExtras2.dds": "18063a12912dadc9528afd90d1cf2369",
|
"build/assets/ba_data/textures/fontExtras2.dds": "56e365473f2babd5404a4ea63924c4ca",
|
||||||
"build/assets/ba_data/textures/fontExtras2.ktx": "36da7f6cfbfb8d32fb14371de0a8f660",
|
"build/assets/ba_data/textures/fontExtras2.ktx": "1de6da8081788bea25cfb0e8df0d16ca",
|
||||||
"build/assets/ba_data/textures/fontExtras2.pvr": "7a4e8e64ac05313b1782fb5b958150d0",
|
"build/assets/ba_data/textures/fontExtras2.pvr": "eb327acb727a626c5f46e2e281a0b789",
|
||||||
"build/assets/ba_data/textures/fontExtras2_preview.png": "f5bc05c8c34cb3ff7284e9edab7b8bcd",
|
"build/assets/ba_data/textures/fontExtras2_preview.png": "aa3ca66b5368da12eb70c21d73dc74b8",
|
||||||
"build/assets/ba_data/textures/fontExtras3.dds": "4fce73998583207fd7692a816e3d86b0",
|
"build/assets/ba_data/textures/fontExtras3.dds": "4fce73998583207fd7692a816e3d86b0",
|
||||||
"build/assets/ba_data/textures/fontExtras3.ktx": "13d61e663088bc97c1fa906a46ed5955",
|
"build/assets/ba_data/textures/fontExtras3.ktx": "13d61e663088bc97c1fa906a46ed5955",
|
||||||
"build/assets/ba_data/textures/fontExtras3.pvr": "56bac0d5f8672f36e1408a1e57cdd3d3",
|
"build/assets/ba_data/textures/fontExtras3.pvr": "56bac0d5f8672f36e1408a1e57cdd3d3",
|
||||||
@ -1626,6 +1626,10 @@
|
|||||||
"build/assets/ba_data/textures/glow.ktx": "fb924f8b6e5dc268f469fb5791cac131",
|
"build/assets/ba_data/textures/glow.ktx": "fb924f8b6e5dc268f469fb5791cac131",
|
||||||
"build/assets/ba_data/textures/glow.pvr": "7ef85fd8127acfb9dafdc75cdcb61a72",
|
"build/assets/ba_data/textures/glow.pvr": "7ef85fd8127acfb9dafdc75cdcb61a72",
|
||||||
"build/assets/ba_data/textures/glow_preview.png": "6f32a4134d5e2ee70d7f804c8fdae3b0",
|
"build/assets/ba_data/textures/glow_preview.png": "6f32a4134d5e2ee70d7f804c8fdae3b0",
|
||||||
|
"build/assets/ba_data/textures/goldPass.dds": "e39d1181ace28b2f3aa2f68b29cff597",
|
||||||
|
"build/assets/ba_data/textures/goldPass.ktx": "cb0ff1dc86be777325ba0d1b54d1f3ac",
|
||||||
|
"build/assets/ba_data/textures/goldPass.pvr": "d5e9e6dd71d571fad5898af6626cf343",
|
||||||
|
"build/assets/ba_data/textures/goldPass_preview.png": "81614ca81d55029721b7ceb3e21831ab",
|
||||||
"build/assets/ba_data/textures/googlePlayAchievementsIcon.dds": "f43d34da87ae80344c5f47e39dc53455",
|
"build/assets/ba_data/textures/googlePlayAchievementsIcon.dds": "f43d34da87ae80344c5f47e39dc53455",
|
||||||
"build/assets/ba_data/textures/googlePlayAchievementsIcon.ktx": "fb15945ffc91b8b513c41d122c371925",
|
"build/assets/ba_data/textures/googlePlayAchievementsIcon.ktx": "fb15945ffc91b8b513c41d122c371925",
|
||||||
"build/assets/ba_data/textures/googlePlayAchievementsIcon.pvr": "662e91f51ed4f6dac5695c099a0cecbc",
|
"build/assets/ba_data/textures/googlePlayAchievementsIcon.pvr": "662e91f51ed4f6dac5695c099a0cecbc",
|
||||||
@ -2410,6 +2414,22 @@
|
|||||||
"build/assets/ba_data/textures/tnt.ktx": "b65ce2a5713a00e37c50aa213b299d8e",
|
"build/assets/ba_data/textures/tnt.ktx": "b65ce2a5713a00e37c50aa213b299d8e",
|
||||||
"build/assets/ba_data/textures/tnt.pvr": "9688020124094656a932ef5d446e575a",
|
"build/assets/ba_data/textures/tnt.pvr": "9688020124094656a932ef5d446e575a",
|
||||||
"build/assets/ba_data/textures/tnt_preview.png": "37f907b09acbdc72d62e48311e28f439",
|
"build/assets/ba_data/textures/tnt_preview.png": "37f907b09acbdc72d62e48311e28f439",
|
||||||
|
"build/assets/ba_data/textures/tokens1.dds": "ac5dfc96143d1e8896b83ad5c2b5b707",
|
||||||
|
"build/assets/ba_data/textures/tokens1.ktx": "7eb2e53c71462087fbca6b1e4f428981",
|
||||||
|
"build/assets/ba_data/textures/tokens1.pvr": "2c5475ffef4c43ca3136056c0dabbb10",
|
||||||
|
"build/assets/ba_data/textures/tokens1_preview.png": "de5142cc0be755f2c61cbcd49c6b6c5b",
|
||||||
|
"build/assets/ba_data/textures/tokens2.dds": "5ecb1fa56e9f0cb2665cac9ed195541e",
|
||||||
|
"build/assets/ba_data/textures/tokens2.ktx": "6bbda19cf5c1ea432a5b58f7d5d04013",
|
||||||
|
"build/assets/ba_data/textures/tokens2.pvr": "011a96e01e39e84857e47a3da4a9ea62",
|
||||||
|
"build/assets/ba_data/textures/tokens2_preview.png": "213649d48adeded11c0125f209f43b3e",
|
||||||
|
"build/assets/ba_data/textures/tokens3.dds": "659d16c00046721e65040fd858b0036c",
|
||||||
|
"build/assets/ba_data/textures/tokens3.ktx": "8edee22873a572abcbb57d4a2c804164",
|
||||||
|
"build/assets/ba_data/textures/tokens3.pvr": "bf0463650ce22789b7196117c5a1114a",
|
||||||
|
"build/assets/ba_data/textures/tokens3_preview.png": "9d3e38908db44848152ce85cdaf63656",
|
||||||
|
"build/assets/ba_data/textures/tokens4.dds": "5b3c5f56f86e10b1e99b53b50d0d04f7",
|
||||||
|
"build/assets/ba_data/textures/tokens4.ktx": "f5288b1e86b2c5f8bdf7c185fda49dfd",
|
||||||
|
"build/assets/ba_data/textures/tokens4.pvr": "b2fc14fb36b6c67d64134a1d41104037",
|
||||||
|
"build/assets/ba_data/textures/tokens4_preview.png": "75dc96161bf8182f42124af24f418cf5",
|
||||||
"build/assets/ba_data/textures/touchArrows.dds": "08e1b07035b236cd9c94a33396624030",
|
"build/assets/ba_data/textures/touchArrows.dds": "08e1b07035b236cd9c94a33396624030",
|
||||||
"build/assets/ba_data/textures/touchArrows.ktx": "404024fec655041449ed6dca9ba8a35b",
|
"build/assets/ba_data/textures/touchArrows.ktx": "404024fec655041449ed6dca9ba8a35b",
|
||||||
"build/assets/ba_data/textures/touchArrows.pvr": "bce89715f94e530bc243a32e112f3391",
|
"build/assets/ba_data/textures/touchArrows.pvr": "bce89715f94e530bc243a32e112f3391",
|
||||||
@ -2478,14 +2498,18 @@
|
|||||||
"build/assets/ba_data/textures/white.ktx": "a948a0fcadd2c7ff5ade346dc0856b92",
|
"build/assets/ba_data/textures/white.ktx": "a948a0fcadd2c7ff5ade346dc0856b92",
|
||||||
"build/assets/ba_data/textures/white.pvr": "4281d8f181ccb325d77fabb5c8c87816",
|
"build/assets/ba_data/textures/white.pvr": "4281d8f181ccb325d77fabb5c8c87816",
|
||||||
"build/assets/ba_data/textures/white_preview.png": "39e65093bf4792cb696927a08909bb2c",
|
"build/assets/ba_data/textures/white_preview.png": "39e65093bf4792cb696927a08909bb2c",
|
||||||
"build/assets/ba_data/textures/windowHSmallVMed.dds": "ea2f027e5b201e53b30000dce19985d9",
|
"build/assets/ba_data/textures/windowBottomCap.dds": "d0daf8ff9d6b6d99ef24518e43cd4b0a",
|
||||||
"build/assets/ba_data/textures/windowHSmallVMed.ktx": "e0d2b9519570fd4bfc6792bebac4253c",
|
"build/assets/ba_data/textures/windowBottomCap.ktx": "a948f0953ccdf9a483d25c359a432804",
|
||||||
"build/assets/ba_data/textures/windowHSmallVMed.pvr": "352934e17d70bd1d2376c02f9d97b923",
|
"build/assets/ba_data/textures/windowBottomCap.pvr": "54a390728cca11339445de329b4f4bf5",
|
||||||
"build/assets/ba_data/textures/windowHSmallVMed_preview.png": "8f10851830b7e640d07bb26cac2e564b",
|
"build/assets/ba_data/textures/windowBottomCap_preview.png": "fdeb2221b9cfc1bc92805826033b6cee",
|
||||||
"build/assets/ba_data/textures/windowHSmallVSmall.dds": "1fdab760550124d83455a3b32a488abe",
|
"build/assets/ba_data/textures/windowHSmallVMed.dds": "c5720b09bef0d51afb4cb294ba516651",
|
||||||
"build/assets/ba_data/textures/windowHSmallVSmall.ktx": "c064b5bfab58e3526114c712d522b4e2",
|
"build/assets/ba_data/textures/windowHSmallVMed.ktx": "1d0977585e0ee8c9064a415b35c4b5e9",
|
||||||
"build/assets/ba_data/textures/windowHSmallVSmall.pvr": "b9eee1de93b19477409cdc04e91d76da",
|
"build/assets/ba_data/textures/windowHSmallVMed.pvr": "e6844e1d4d0b4161e1f4acb020cf4321",
|
||||||
"build/assets/ba_data/textures/windowHSmallVSmall_preview.png": "0a61e76caa8bc93e9deaa3369b712a18",
|
"build/assets/ba_data/textures/windowHSmallVMed_preview.png": "b9d66c1f932c2091b097e4007d1db82a",
|
||||||
|
"build/assets/ba_data/textures/windowHSmallVSmall.dds": "1d3c13f37c4b6f39a45adf20ebec4514",
|
||||||
|
"build/assets/ba_data/textures/windowHSmallVSmall.ktx": "120593e4ecb90079353d02cc8eecd41f",
|
||||||
|
"build/assets/ba_data/textures/windowHSmallVSmall.pvr": "d40c4924e93017e384e32bbe610fb4fc",
|
||||||
|
"build/assets/ba_data/textures/windowHSmallVSmall_preview.png": "b3db4b605a7937736a4f2e9c233a03fb",
|
||||||
"build/assets/ba_data/textures/wings.dds": "ed0aee36ae96b2c5c3e9ee03ef23c998",
|
"build/assets/ba_data/textures/wings.dds": "ed0aee36ae96b2c5c3e9ee03ef23c998",
|
||||||
"build/assets/ba_data/textures/wings.ktx": "127b7381b882448b80428c96c7483dbb",
|
"build/assets/ba_data/textures/wings.ktx": "127b7381b882448b80428c96c7483dbb",
|
||||||
"build/assets/ba_data/textures/wings.pvr": "3e07ec0f582d897c2b21395ae6c5aa3f",
|
"build/assets/ba_data/textures/wings.pvr": "3e07ec0f582d897c2b21395ae6c5aa3f",
|
||||||
@ -2572,13 +2596,13 @@
|
|||||||
"build/assets/pylib-android/_osx_support.py": "c0871f8d2b36955d67f0446bb9fa3827",
|
"build/assets/pylib-android/_osx_support.py": "c0871f8d2b36955d67f0446bb9fa3827",
|
||||||
"build/assets/pylib-android/_py_abc.py": "180d5cf138b011bd6a280c2f433bed47",
|
"build/assets/pylib-android/_py_abc.py": "180d5cf138b011bd6a280c2f433bed47",
|
||||||
"build/assets/pylib-android/_pydatetime.py": "af813d3d6cb8ccf3e90b76b91f5fa7f2",
|
"build/assets/pylib-android/_pydatetime.py": "af813d3d6cb8ccf3e90b76b91f5fa7f2",
|
||||||
"build/assets/pylib-android/_pydecimal.py": "4572eb8c67bcfbbcda7ed47055c6e6b5",
|
"build/assets/pylib-android/_pydecimal.py": "e58d83934dbffe094d2976a9e1132190",
|
||||||
"build/assets/pylib-android/_pyio.py": "618a6fa97c93e8c63c8e5cf3c283d5fe",
|
"build/assets/pylib-android/_pyio.py": "618a6fa97c93e8c63c8e5cf3c283d5fe",
|
||||||
"build/assets/pylib-android/_pylong.py": "e057ab3c9eea264704dff2af204884f8",
|
"build/assets/pylib-android/_pylong.py": "0ae926c324155186a115b54eb88d0526",
|
||||||
"build/assets/pylib-android/_sitebuiltins.py": "8b5e3f6e73917962fa014ad2c4a55e61",
|
"build/assets/pylib-android/_sitebuiltins.py": "8b5e3f6e73917962fa014ad2c4a55e61",
|
||||||
"build/assets/pylib-android/_strptime.py": "8c65b46a50f13ca2389b19b32b7f2996",
|
"build/assets/pylib-android/_strptime.py": "8c65b46a50f13ca2389b19b32b7f2996",
|
||||||
"build/assets/pylib-android/_sysconfigdata__linux_.py": "e112c946a141bcf18e0656a14a52ca71",
|
"build/assets/pylib-android/_sysconfigdata__linux_.py": "6c03d32177713f6abdf9e692aaa53ed6",
|
||||||
"build/assets/pylib-android/_sysconfigdata_d_linux_.py": "063295bed5c2c6f30d323abb2cf82fd9",
|
"build/assets/pylib-android/_sysconfigdata_d_linux_.py": "c37336d1880d691f3108e1cedf5e7355",
|
||||||
"build/assets/pylib-android/_threading_local.py": "4a9688e3987d7d692db46feb9214945e",
|
"build/assets/pylib-android/_threading_local.py": "4a9688e3987d7d692db46feb9214945e",
|
||||||
"build/assets/pylib-android/_weakrefset.py": "e4fa8532ace46dfbc35149c41ea497f7",
|
"build/assets/pylib-android/_weakrefset.py": "e4fa8532ace46dfbc35149c41ea497f7",
|
||||||
"build/assets/pylib-android/abc.py": "a0daa1ed187eee8690c1e8438b97da90",
|
"build/assets/pylib-android/abc.py": "a0daa1ed187eee8690c1e8438b97da90",
|
||||||
@ -2587,7 +2611,7 @@
|
|||||||
"build/assets/pylib-android/argparse.py": "479fa19b01a256e9162cfed4b3866708",
|
"build/assets/pylib-android/argparse.py": "479fa19b01a256e9162cfed4b3866708",
|
||||||
"build/assets/pylib-android/ast.py": "e59b9f09a7d1f8979b94f900a72f74c6",
|
"build/assets/pylib-android/ast.py": "e59b9f09a7d1f8979b94f900a72f74c6",
|
||||||
"build/assets/pylib-android/asyncio/__init__.py": "4a732a7b4c77634cab1909d8be43cb4c",
|
"build/assets/pylib-android/asyncio/__init__.py": "4a732a7b4c77634cab1909d8be43cb4c",
|
||||||
"build/assets/pylib-android/asyncio/__main__.py": "8e391b47f448ad922dc2614dbd93011e",
|
"build/assets/pylib-android/asyncio/__main__.py": "18122a137578030c2a458f7af9d93edd",
|
||||||
"build/assets/pylib-android/asyncio/base_events.py": "071d87caa982ce12333bf31b691dd0b0",
|
"build/assets/pylib-android/asyncio/base_events.py": "071d87caa982ce12333bf31b691dd0b0",
|
||||||
"build/assets/pylib-android/asyncio/base_futures.py": "5b4cefd0a571e9e8d913a052f2e0b15e",
|
"build/assets/pylib-android/asyncio/base_futures.py": "5b4cefd0a571e9e8d913a052f2e0b15e",
|
||||||
"build/assets/pylib-android/asyncio/base_subprocess.py": "8a805e04a2911b2d8e297f0029def4b1",
|
"build/assets/pylib-android/asyncio/base_subprocess.py": "8a805e04a2911b2d8e297f0029def4b1",
|
||||||
@ -2601,7 +2625,7 @@
|
|||||||
"build/assets/pylib-android/asyncio/locks.py": "1630852effc563876002c88455a2f7f4",
|
"build/assets/pylib-android/asyncio/locks.py": "1630852effc563876002c88455a2f7f4",
|
||||||
"build/assets/pylib-android/asyncio/log.py": "1e101049c5cd7ad159b63ef97fe8fb0b",
|
"build/assets/pylib-android/asyncio/log.py": "1e101049c5cd7ad159b63ef97fe8fb0b",
|
||||||
"build/assets/pylib-android/asyncio/mixins.py": "9be94c61811a65522320e29e3dec16b0",
|
"build/assets/pylib-android/asyncio/mixins.py": "9be94c61811a65522320e29e3dec16b0",
|
||||||
"build/assets/pylib-android/asyncio/proactor_events.py": "ff72970f982322a1141d710557847d4d",
|
"build/assets/pylib-android/asyncio/proactor_events.py": "97d197fadbae03691260f805ac1049e2",
|
||||||
"build/assets/pylib-android/asyncio/protocols.py": "b8aa105b79d24f88c7a2c2cdbc8e7814",
|
"build/assets/pylib-android/asyncio/protocols.py": "b8aa105b79d24f88c7a2c2cdbc8e7814",
|
||||||
"build/assets/pylib-android/asyncio/queues.py": "f63be54780730992e2377c51ac373126",
|
"build/assets/pylib-android/asyncio/queues.py": "f63be54780730992e2377c51ac373126",
|
||||||
"build/assets/pylib-android/asyncio/runners.py": "e523f1abdd9ab2cf2bc355acea052bd8",
|
"build/assets/pylib-android/asyncio/runners.py": "e523f1abdd9ab2cf2bc355acea052bd8",
|
||||||
@ -2619,8 +2643,8 @@
|
|||||||
"build/assets/pylib-android/asyncio/unix_events.py": "e5490096c3c8ce4d2537317c608862d9",
|
"build/assets/pylib-android/asyncio/unix_events.py": "e5490096c3c8ce4d2537317c608862d9",
|
||||||
"build/assets/pylib-android/asyncio/windows_events.py": "e70d58554906a59b6d823850aa6b8395",
|
"build/assets/pylib-android/asyncio/windows_events.py": "e70d58554906a59b6d823850aa6b8395",
|
||||||
"build/assets/pylib-android/asyncio/windows_utils.py": "4efbef16e6692c9424804d9bdc496761",
|
"build/assets/pylib-android/asyncio/windows_utils.py": "4efbef16e6692c9424804d9bdc496761",
|
||||||
"build/assets/pylib-android/base64.py": "00f5d31b06dd0f489d8b14b7bcf43db7",
|
"build/assets/pylib-android/base64.py": "b89a7dfe64760a2402b5bf255174969c",
|
||||||
"build/assets/pylib-android/bdb.py": "1e26c626405bfc06b1e7231183eb928a",
|
"build/assets/pylib-android/bdb.py": "e7f362c5918a54efc0085efc7bae3a8d",
|
||||||
"build/assets/pylib-android/bisect.py": "69d3166bd72a28217f1bffa40dc9c33b",
|
"build/assets/pylib-android/bisect.py": "69d3166bd72a28217f1bffa40dc9c33b",
|
||||||
"build/assets/pylib-android/bz2.py": "cd6a5f2491bc52afd8fc180097371473",
|
"build/assets/pylib-android/bz2.py": "cd6a5f2491bc52afd8fc180097371473",
|
||||||
"build/assets/pylib-android/cProfile.py": "bec17d6b102c0123c4b743ac685de752",
|
"build/assets/pylib-android/cProfile.py": "bec17d6b102c0123c4b743ac685de752",
|
||||||
@ -2648,7 +2672,7 @@
|
|||||||
"build/assets/pylib-android/copyreg.py": "de5fb1333a0e388e69749e78ed5e55ae",
|
"build/assets/pylib-android/copyreg.py": "de5fb1333a0e388e69749e78ed5e55ae",
|
||||||
"build/assets/pylib-android/crypt.py": "e12ad225ff7be254f543a48ed68b9465",
|
"build/assets/pylib-android/crypt.py": "e12ad225ff7be254f543a48ed68b9465",
|
||||||
"build/assets/pylib-android/csv.py": "a896b3c30246ae11b1633b402675b6b9",
|
"build/assets/pylib-android/csv.py": "a896b3c30246ae11b1633b402675b6b9",
|
||||||
"build/assets/pylib-android/ctypes/__init__.py": "235310a16d0c17607d86807724dfc51f",
|
"build/assets/pylib-android/ctypes/__init__.py": "53033669e712496a979fc62d320ff76b",
|
||||||
"build/assets/pylib-android/ctypes/_aix.py": "5fd9184c6794ee90ac1441f2c5fe7335",
|
"build/assets/pylib-android/ctypes/_aix.py": "5fd9184c6794ee90ac1441f2c5fe7335",
|
||||||
"build/assets/pylib-android/ctypes/_endian.py": "75edb1136e6c70ff5797b639d74d3a76",
|
"build/assets/pylib-android/ctypes/_endian.py": "75edb1136e6c70ff5797b639d74d3a76",
|
||||||
"build/assets/pylib-android/ctypes/macholib/__init__.py": "b2ee4220c9357720236e4da2f849f7da",
|
"build/assets/pylib-android/ctypes/macholib/__init__.py": "b2ee4220c9357720236e4da2f849f7da",
|
||||||
@ -2662,17 +2686,17 @@
|
|||||||
"build/assets/pylib-android/curses/has_key.py": "c74b8d6db329fbbd872b7b91bfa94624",
|
"build/assets/pylib-android/curses/has_key.py": "c74b8d6db329fbbd872b7b91bfa94624",
|
||||||
"build/assets/pylib-android/curses/panel.py": "8f36fdade9588f8a4362d2cc057a6eff",
|
"build/assets/pylib-android/curses/panel.py": "8f36fdade9588f8a4362d2cc057a6eff",
|
||||||
"build/assets/pylib-android/curses/textpad.py": "c53f9edcb5abba15eb755fdebef0eb19",
|
"build/assets/pylib-android/curses/textpad.py": "c53f9edcb5abba15eb755fdebef0eb19",
|
||||||
"build/assets/pylib-android/dataclasses.py": "52ef11127750fed81643fe829bc4c737",
|
"build/assets/pylib-android/dataclasses.py": "a57847f8c5f4dc7681d8a39a96bf399b",
|
||||||
"build/assets/pylib-android/datetime.py": "b4a98cc076882de0f4c5787b888b2eb6",
|
"build/assets/pylib-android/datetime.py": "b4a98cc076882de0f4c5787b888b2eb6",
|
||||||
"build/assets/pylib-android/decimal.py": "f57d255d45b5d1d7d8e13c41a283c3e4",
|
"build/assets/pylib-android/decimal.py": "bc71d12e6e91b709990e51c1e5c22a04",
|
||||||
"build/assets/pylib-android/difflib.py": "6b3c8fd541b2b8d0320727025cd25275",
|
"build/assets/pylib-android/difflib.py": "6b3c8fd541b2b8d0320727025cd25275",
|
||||||
"build/assets/pylib-android/dis.py": "a13ae44a4be77ce18f74d1e56659ea03",
|
"build/assets/pylib-android/dis.py": "a13ae44a4be77ce18f74d1e56659ea03",
|
||||||
"build/assets/pylib-android/doctest.py": "25cfaf6115c8d69f5e84c66ce4d51dae",
|
"build/assets/pylib-android/doctest.py": "d5799d14d763cb9788073a7d9fcb3cac",
|
||||||
"build/assets/pylib-android/email/__init__.py": "4ff603eeeb4ce0302c8bd1b220fc5e13",
|
"build/assets/pylib-android/email/__init__.py": "4ff603eeeb4ce0302c8bd1b220fc5e13",
|
||||||
"build/assets/pylib-android/email/_encoded_words.py": "d7b77501689dd1ce32da789b46264a6a",
|
"build/assets/pylib-android/email/_encoded_words.py": "d7b77501689dd1ce32da789b46264a6a",
|
||||||
"build/assets/pylib-android/email/_header_value_parser.py": "f472e3136172faada943c60181e886eb",
|
"build/assets/pylib-android/email/_header_value_parser.py": "ca9f4ed18429b711d22e25dc6117da3d",
|
||||||
"build/assets/pylib-android/email/_parseaddr.py": "a6d2999aeed17f060be8797e761a01aa",
|
"build/assets/pylib-android/email/_parseaddr.py": "a6d2999aeed17f060be8797e761a01aa",
|
||||||
"build/assets/pylib-android/email/_policybase.py": "09b0c21693ac080c52c52f5daab616aa",
|
"build/assets/pylib-android/email/_policybase.py": "b632710aafb0885a10b6ed8c7576e9cb",
|
||||||
"build/assets/pylib-android/email/base64mime.py": "d3e4fc07d04833487677dd2a888c3826",
|
"build/assets/pylib-android/email/base64mime.py": "d3e4fc07d04833487677dd2a888c3826",
|
||||||
"build/assets/pylib-android/email/charset.py": "8bcb2315a8340755057e66398e975542",
|
"build/assets/pylib-android/email/charset.py": "8bcb2315a8340755057e66398e975542",
|
||||||
"build/assets/pylib-android/email/contentmanager.py": "e88780ef1d37a11ff216060f740f2572",
|
"build/assets/pylib-android/email/contentmanager.py": "e88780ef1d37a11ff216060f740f2572",
|
||||||
@ -2683,7 +2707,7 @@
|
|||||||
"build/assets/pylib-android/email/header.py": "09923b7b77bf91bed41a71b6e3c6e4d9",
|
"build/assets/pylib-android/email/header.py": "09923b7b77bf91bed41a71b6e3c6e4d9",
|
||||||
"build/assets/pylib-android/email/headerregistry.py": "dfd48f9c41454d5bc2355cb1762fb869",
|
"build/assets/pylib-android/email/headerregistry.py": "dfd48f9c41454d5bc2355cb1762fb869",
|
||||||
"build/assets/pylib-android/email/iterators.py": "752ece28a18545e70fa67a7cf2fe3ef3",
|
"build/assets/pylib-android/email/iterators.py": "752ece28a18545e70fa67a7cf2fe3ef3",
|
||||||
"build/assets/pylib-android/email/message.py": "d35660dfc0ff8e0ed0125f0e465771b6",
|
"build/assets/pylib-android/email/message.py": "68764155da8820f7d4810b08b0fe7af0",
|
||||||
"build/assets/pylib-android/email/mime/__init__.py": "340c83beff7dcff8f5c7b87cd43cedaf",
|
"build/assets/pylib-android/email/mime/__init__.py": "340c83beff7dcff8f5c7b87cd43cedaf",
|
||||||
"build/assets/pylib-android/email/mime/application.py": "4ce678512f30cac9fd95993186d2eef7",
|
"build/assets/pylib-android/email/mime/application.py": "4ce678512f30cac9fd95993186d2eef7",
|
||||||
"build/assets/pylib-android/email/mime/audio.py": "4073e45bda9524e3cbe29374951fdc16",
|
"build/assets/pylib-android/email/mime/audio.py": "4073e45bda9524e3cbe29374951fdc16",
|
||||||
@ -2694,7 +2718,7 @@
|
|||||||
"build/assets/pylib-android/email/mime/nonmultipart.py": "a96d8d31156781a7511cec04e46a95f6",
|
"build/assets/pylib-android/email/mime/nonmultipart.py": "a96d8d31156781a7511cec04e46a95f6",
|
||||||
"build/assets/pylib-android/email/mime/text.py": "634e0b909f94788cf97fc8a0b914d12c",
|
"build/assets/pylib-android/email/mime/text.py": "634e0b909f94788cf97fc8a0b914d12c",
|
||||||
"build/assets/pylib-android/email/parser.py": "d78f74ba45a3618608cdc9ece2aa411a",
|
"build/assets/pylib-android/email/parser.py": "d78f74ba45a3618608cdc9ece2aa411a",
|
||||||
"build/assets/pylib-android/email/policy.py": "34946fe746ce5d39634d54f18716c8f3",
|
"build/assets/pylib-android/email/policy.py": "96ff779e28c2fa000dd84acced05650c",
|
||||||
"build/assets/pylib-android/email/quoprimime.py": "c5e54c3f0e70d55145517382d4455765",
|
"build/assets/pylib-android/email/quoprimime.py": "c5e54c3f0e70d55145517382d4455765",
|
||||||
"build/assets/pylib-android/email/utils.py": "05398f8a134b22fac6ab3a1d4b84fcb1",
|
"build/assets/pylib-android/email/utils.py": "05398f8a134b22fac6ab3a1d4b84fcb1",
|
||||||
"build/assets/pylib-android/encodings/__init__.py": "6a342ed3b218da63b7f7937beafcc20c",
|
"build/assets/pylib-android/encodings/__init__.py": "6a342ed3b218da63b7f7937beafcc20c",
|
||||||
@ -2825,7 +2849,7 @@
|
|||||||
"build/assets/pylib-android/fnmatch.py": "a1bc67633695d4defd4c0886428c5363",
|
"build/assets/pylib-android/fnmatch.py": "a1bc67633695d4defd4c0886428c5363",
|
||||||
"build/assets/pylib-android/fractions.py": "02689771b334f161f5bd4b052aaa3e33",
|
"build/assets/pylib-android/fractions.py": "02689771b334f161f5bd4b052aaa3e33",
|
||||||
"build/assets/pylib-android/ftplib.py": "84c6c5d111b887aa3986a02d164e4cdd",
|
"build/assets/pylib-android/ftplib.py": "84c6c5d111b887aa3986a02d164e4cdd",
|
||||||
"build/assets/pylib-android/functools.py": "a60c3a01c02be0f20a3e91de2b9e188f",
|
"build/assets/pylib-android/functools.py": "25c531165121ae37d026331f7364f379",
|
||||||
"build/assets/pylib-android/genericpath.py": "700f98a87ac51709fc817a23e48b52f3",
|
"build/assets/pylib-android/genericpath.py": "700f98a87ac51709fc817a23e48b52f3",
|
||||||
"build/assets/pylib-android/getopt.py": "2c02d59b410128b2ebff26e3030568a6",
|
"build/assets/pylib-android/getopt.py": "2c02d59b410128b2ebff26e3030568a6",
|
||||||
"build/assets/pylib-android/getpass.py": "c19e383e949c147a30ecc554b8598e91",
|
"build/assets/pylib-android/getpass.py": "c19e383e949c147a30ecc554b8598e91",
|
||||||
@ -2869,9 +2893,9 @@
|
|||||||
"build/assets/pylib-android/importlib/resources/simple.py": "16b97df12d2762e00bbb7ee6189750a2",
|
"build/assets/pylib-android/importlib/resources/simple.py": "16b97df12d2762e00bbb7ee6189750a2",
|
||||||
"build/assets/pylib-android/importlib/simple.py": "f34f28cd359ecaf9fd6cf18a4dca2c33",
|
"build/assets/pylib-android/importlib/simple.py": "f34f28cd359ecaf9fd6cf18a4dca2c33",
|
||||||
"build/assets/pylib-android/importlib/util.py": "8b414591277a59478a9acab9ef9c56e2",
|
"build/assets/pylib-android/importlib/util.py": "8b414591277a59478a9acab9ef9c56e2",
|
||||||
"build/assets/pylib-android/inspect.py": "1f9f508f836c6f55658d722e9383ada9",
|
"build/assets/pylib-android/inspect.py": "c3ef07d9f7ac90aad135a198faf2029b",
|
||||||
"build/assets/pylib-android/io.py": "4f501a9e8a4ff4c2ca8152b8f5634cb9",
|
"build/assets/pylib-android/io.py": "4f501a9e8a4ff4c2ca8152b8f5634cb9",
|
||||||
"build/assets/pylib-android/ipaddress.py": "f8aab9a66231645bc9bd92301f1c6ac0",
|
"build/assets/pylib-android/ipaddress.py": "523062c7debdcd4c554b3e7c7b3714b1",
|
||||||
"build/assets/pylib-android/json/__init__.py": "e8b000d2bf8c53b55a72bc3053800596",
|
"build/assets/pylib-android/json/__init__.py": "e8b000d2bf8c53b55a72bc3053800596",
|
||||||
"build/assets/pylib-android/json/decoder.py": "82a8faab8ae9599b2b5f58322b8055ee",
|
"build/assets/pylib-android/json/decoder.py": "82a8faab8ae9599b2b5f58322b8055ee",
|
||||||
"build/assets/pylib-android/json/encoder.py": "c85377b74511c6f463715e02118ca566",
|
"build/assets/pylib-android/json/encoder.py": "c85377b74511c6f463715e02118ca566",
|
||||||
@ -2879,9 +2903,9 @@
|
|||||||
"build/assets/pylib-android/json/tool.py": "a83b2c5dafa3adfd772a058cddbc0afc",
|
"build/assets/pylib-android/json/tool.py": "a83b2c5dafa3adfd772a058cddbc0afc",
|
||||||
"build/assets/pylib-android/keyword.py": "4132d92e0b8a50d8f7119ed5fabf1674",
|
"build/assets/pylib-android/keyword.py": "4132d92e0b8a50d8f7119ed5fabf1674",
|
||||||
"build/assets/pylib-android/linecache.py": "965977aa395c6db802aa732f30660097",
|
"build/assets/pylib-android/linecache.py": "965977aa395c6db802aa732f30660097",
|
||||||
"build/assets/pylib-android/locale.py": "7c90ef0f6f75d9a5ee9a709ca266a2e2",
|
"build/assets/pylib-android/locale.py": "b337ca2d5d86061fd6e0592125a87f50",
|
||||||
"build/assets/pylib-android/logging/__init__.py": "88f53a4eec4313c2e2ab9130250d3ab5",
|
"build/assets/pylib-android/logging/__init__.py": "88f53a4eec4313c2e2ab9130250d3ab5",
|
||||||
"build/assets/pylib-android/logging/config.py": "cc6d515fd6b7b16d8ab66fe934249f9b",
|
"build/assets/pylib-android/logging/config.py": "63b9328b44c899e6858af68fc65b7646",
|
||||||
"build/assets/pylib-android/logging/handlers.py": "0d0ca5db1f8e3588301a4cfbc4d6d365",
|
"build/assets/pylib-android/logging/handlers.py": "0d0ca5db1f8e3588301a4cfbc4d6d365",
|
||||||
"build/assets/pylib-android/lzma.py": "d7388640aa6af4c64fdc821471930f57",
|
"build/assets/pylib-android/lzma.py": "d7388640aa6af4c64fdc821471930f57",
|
||||||
"build/assets/pylib-android/mailbox.py": "7de36be1f3365d2202d1e6548c538360",
|
"build/assets/pylib-android/mailbox.py": "7de36be1f3365d2202d1e6548c538360",
|
||||||
@ -2890,23 +2914,23 @@
|
|||||||
"build/assets/pylib-android/modulefinder.py": "3fc074c018de1dd15ab2e309be199dea",
|
"build/assets/pylib-android/modulefinder.py": "3fc074c018de1dd15ab2e309be199dea",
|
||||||
"build/assets/pylib-android/netrc.py": "9dd6b80891863e23b5e0a57bb80c7346",
|
"build/assets/pylib-android/netrc.py": "9dd6b80891863e23b5e0a57bb80c7346",
|
||||||
"build/assets/pylib-android/nntplib.py": "4926aa991bd4b96b9318d6242135abf9",
|
"build/assets/pylib-android/nntplib.py": "4926aa991bd4b96b9318d6242135abf9",
|
||||||
"build/assets/pylib-android/ntpath.py": "1e3997be9aec964b4a3caa2ff7172c78",
|
"build/assets/pylib-android/ntpath.py": "9790c31a274924d4168d8fa1f396f9c0",
|
||||||
"build/assets/pylib-android/nturl2path.py": "937624c4b6f213b652addea66296ccc4",
|
"build/assets/pylib-android/nturl2path.py": "937624c4b6f213b652addea66296ccc4",
|
||||||
"build/assets/pylib-android/numbers.py": "bb9d88751c4f892d66e43961c521de7f",
|
"build/assets/pylib-android/numbers.py": "bb9d88751c4f892d66e43961c521de7f",
|
||||||
"build/assets/pylib-android/opcode.py": "27b5ed52b503d4cf1adb7d65116655c3",
|
"build/assets/pylib-android/opcode.py": "27b5ed52b503d4cf1adb7d65116655c3",
|
||||||
"build/assets/pylib-android/operator.py": "61e197bc43df97ec39ae3e5e59b11c19",
|
"build/assets/pylib-android/operator.py": "61e197bc43df97ec39ae3e5e59b11c19",
|
||||||
"build/assets/pylib-android/optparse.py": "5f65f891612b68c71a2846da86254285",
|
"build/assets/pylib-android/optparse.py": "5f65f891612b68c71a2846da86254285",
|
||||||
"build/assets/pylib-android/os.py": "1d20abe92b62ba9fc876be6714e29337",
|
"build/assets/pylib-android/os.py": "e9627e3183be83287f785cfa0878a820",
|
||||||
"build/assets/pylib-android/pathlib.py": "1bf23fd9f937bb58eec2a62a60d73280",
|
"build/assets/pylib-android/pathlib.py": "b6a1d7be62bb73cf45e43617f5270957",
|
||||||
"build/assets/pylib-android/pdb.py": "c62b3dff47478089a415ed83671a636c",
|
"build/assets/pylib-android/pdb.py": "c62b3dff47478089a415ed83671a636c",
|
||||||
"build/assets/pylib-android/pickle.py": "ec61f6c0d4bd9f21c664a3673d6ce158",
|
"build/assets/pylib-android/pickle.py": "ec61f6c0d4bd9f21c664a3673d6ce158",
|
||||||
"build/assets/pylib-android/pickletools.py": "e2cb81715625efdc409f8d34e36a9569",
|
"build/assets/pylib-android/pickletools.py": "e2cb81715625efdc409f8d34e36a9569",
|
||||||
"build/assets/pylib-android/pipes.py": "2dd796bdbb87982034234fec50d4526c",
|
"build/assets/pylib-android/pipes.py": "2dd796bdbb87982034234fec50d4526c",
|
||||||
"build/assets/pylib-android/pkgutil.py": "417ff74f276b7659b93ac5e8ee425f0f",
|
"build/assets/pylib-android/pkgutil.py": "417ff74f276b7659b93ac5e8ee425f0f",
|
||||||
"build/assets/pylib-android/platform.py": "d15e44b3dcd3271c78bcd4b0cd37dbbb",
|
"build/assets/pylib-android/platform.py": "263c9442b51433c6956a9e7a561d9b7e",
|
||||||
"build/assets/pylib-android/plistlib.py": "89a4be15fa63e930d5b5fc3f9c99c4f7",
|
"build/assets/pylib-android/plistlib.py": "89a4be15fa63e930d5b5fc3f9c99c4f7",
|
||||||
"build/assets/pylib-android/poplib.py": "8150e0a07082ec4dbb017c4bc7163d7d",
|
"build/assets/pylib-android/poplib.py": "8150e0a07082ec4dbb017c4bc7163d7d",
|
||||||
"build/assets/pylib-android/posixpath.py": "f7403faf74c3968010c45e204aad6415",
|
"build/assets/pylib-android/posixpath.py": "41b7b16fe21131e0012177f090aacc47",
|
||||||
"build/assets/pylib-android/pprint.py": "8a1792d9fe0cad9605a9deb9af479341",
|
"build/assets/pylib-android/pprint.py": "8a1792d9fe0cad9605a9deb9af479341",
|
||||||
"build/assets/pylib-android/profile.py": "8f26436d147cfd6d00d19592cf0d8c91",
|
"build/assets/pylib-android/profile.py": "8f26436d147cfd6d00d19592cf0d8c91",
|
||||||
"build/assets/pylib-android/pstats.py": "1eb59db1b83dd577c863d26ca04b3105",
|
"build/assets/pylib-android/pstats.py": "1eb59db1b83dd577c863d26ca04b3105",
|
||||||
@ -2930,17 +2954,17 @@
|
|||||||
"build/assets/pylib-android/selectors.py": "3c94b3b678c473543cdc7f1d2b20a6f6",
|
"build/assets/pylib-android/selectors.py": "3c94b3b678c473543cdc7f1d2b20a6f6",
|
||||||
"build/assets/pylib-android/shelve.py": "3e569c07c863ecbd7f35a6c382d1785a",
|
"build/assets/pylib-android/shelve.py": "3e569c07c863ecbd7f35a6c382d1785a",
|
||||||
"build/assets/pylib-android/shlex.py": "adb6b917c5d3adadbdcb77a9257595fd",
|
"build/assets/pylib-android/shlex.py": "adb6b917c5d3adadbdcb77a9257595fd",
|
||||||
"build/assets/pylib-android/shutil.py": "b24c18a65894e6860b16fb8462f9c1c5",
|
"build/assets/pylib-android/shutil.py": "b23c4712f744f3030ba1f87d1a2bf6a4",
|
||||||
"build/assets/pylib-android/signal.py": "6c286caa92d351510f74cb4e1b3661da",
|
"build/assets/pylib-android/signal.py": "6c286caa92d351510f74cb4e1b3661da",
|
||||||
"build/assets/pylib-android/site.py": "ddbf5304e85bedcc06f9a49b2e544e74",
|
"build/assets/pylib-android/site.py": "e1523c36412e4ec333acbd5b0d2d6ea2",
|
||||||
"build/assets/pylib-android/smtplib.py": "a8121c0c6888489f89cdb2d5b06638f7",
|
"build/assets/pylib-android/smtplib.py": "a8121c0c6888489f89cdb2d5b06638f7",
|
||||||
"build/assets/pylib-android/sndhdr.py": "6b62a34738529e39528c0cb498a23eee",
|
"build/assets/pylib-android/sndhdr.py": "6b62a34738529e39528c0cb498a23eee",
|
||||||
"build/assets/pylib-android/socket.py": "93b3814a3cd3753bfbb8caa1e37ea8dd",
|
"build/assets/pylib-android/socket.py": "e0463a87103f5d2e08f772b9a53ea816",
|
||||||
"build/assets/pylib-android/socketserver.py": "08d185dbe1e568e299133cc8dcb35940",
|
"build/assets/pylib-android/socketserver.py": "08d185dbe1e568e299133cc8dcb35940",
|
||||||
"build/assets/pylib-android/sqlite3/__init__.py": "e64822b75a1c8f1be3e23ed6923e12eb",
|
"build/assets/pylib-android/sqlite3/__init__.py": "e64822b75a1c8f1be3e23ed6923e12eb",
|
||||||
"build/assets/pylib-android/sqlite3/__main__.py": "52b4c89dbcbaab2bcbd71da0317fdf46",
|
"build/assets/pylib-android/sqlite3/__main__.py": "52b4c89dbcbaab2bcbd71da0317fdf46",
|
||||||
"build/assets/pylib-android/sqlite3/dbapi2.py": "b3b44b48fcb3999ca0269023c2fb7268",
|
"build/assets/pylib-android/sqlite3/dbapi2.py": "b3b44b48fcb3999ca0269023c2fb7268",
|
||||||
"build/assets/pylib-android/sqlite3/dump.py": "8d2085ec40031d544694759608e53178",
|
"build/assets/pylib-android/sqlite3/dump.py": "ac821eee63ad27947460c6aca84d4e8d",
|
||||||
"build/assets/pylib-android/sre_compile.py": "a1784e9ccbea7d9963cab75b536b40c8",
|
"build/assets/pylib-android/sre_compile.py": "a1784e9ccbea7d9963cab75b536b40c8",
|
||||||
"build/assets/pylib-android/sre_constants.py": "5c5be32a5334d9b0a848dad520746a63",
|
"build/assets/pylib-android/sre_constants.py": "5c5be32a5334d9b0a848dad520746a63",
|
||||||
"build/assets/pylib-android/sre_parse.py": "cca15b9ab31509e6642f9d2fd4fb9d91",
|
"build/assets/pylib-android/sre_parse.py": "cca15b9ab31509e6642f9d2fd4fb9d91",
|
||||||
@ -2955,8 +2979,8 @@
|
|||||||
"build/assets/pylib-android/symtable.py": "7808839ac346e577ef1ab623c324d9e1",
|
"build/assets/pylib-android/symtable.py": "7808839ac346e577ef1ab623c324d9e1",
|
||||||
"build/assets/pylib-android/sysconfig.py": "6c0114db24638ab125b9e933d44c79ef",
|
"build/assets/pylib-android/sysconfig.py": "6c0114db24638ab125b9e933d44c79ef",
|
||||||
"build/assets/pylib-android/tabnanny.py": "017f45469d744cc511654fe887bda204",
|
"build/assets/pylib-android/tabnanny.py": "017f45469d744cc511654fe887bda204",
|
||||||
"build/assets/pylib-android/tarfile.py": "43041075df31a5c8e7d8ea626391f185",
|
"build/assets/pylib-android/tarfile.py": "c895804e267dc809bf1fbd5e990078ba",
|
||||||
"build/assets/pylib-android/telnetlib.py": "1a746e1fc988b9f5c12b9fd5a97c00ea",
|
"build/assets/pylib-android/telnetlib.py": "0700ac21e04abde09aac1eb1e52ebbde",
|
||||||
"build/assets/pylib-android/tempfile.py": "916365f4533239ffe6d66440b0ead6ae",
|
"build/assets/pylib-android/tempfile.py": "916365f4533239ffe6d66440b0ead6ae",
|
||||||
"build/assets/pylib-android/textwrap.py": "3eb16a40553205dc96be5cb9039f3c8c",
|
"build/assets/pylib-android/textwrap.py": "3eb16a40553205dc96be5cb9039f3c8c",
|
||||||
"build/assets/pylib-android/this.py": "8b0a9a1fa0a45a37e6c656eca1922277",
|
"build/assets/pylib-android/this.py": "8b0a9a1fa0a45a37e6c656eca1922277",
|
||||||
@ -2968,21 +2992,21 @@
|
|||||||
"build/assets/pylib-android/tomllib/_parser.py": "f9a4dc92c44403f970e94c2e494a7358",
|
"build/assets/pylib-android/tomllib/_parser.py": "f9a4dc92c44403f970e94c2e494a7358",
|
||||||
"build/assets/pylib-android/tomllib/_re.py": "0e509117e16c41c491615e06bb98861d",
|
"build/assets/pylib-android/tomllib/_re.py": "0e509117e16c41c491615e06bb98861d",
|
||||||
"build/assets/pylib-android/tomllib/_types.py": "07be9616d6f5e401fd31fbeea619fc97",
|
"build/assets/pylib-android/tomllib/_types.py": "07be9616d6f5e401fd31fbeea619fc97",
|
||||||
"build/assets/pylib-android/trace.py": "e0015a322cf5fbb35310705e81953ab1",
|
"build/assets/pylib-android/trace.py": "3e0ba305fd653f127f2ddcc278abbbc4",
|
||||||
"build/assets/pylib-android/traceback.py": "84cbe40fcb14833ce4a1c0be22c4c9bc",
|
"build/assets/pylib-android/traceback.py": "84cbe40fcb14833ce4a1c0be22c4c9bc",
|
||||||
"build/assets/pylib-android/tracemalloc.py": "e4d10d2bee7773566e46797a939e5cbf",
|
"build/assets/pylib-android/tracemalloc.py": "e4d10d2bee7773566e46797a939e5cbf",
|
||||||
"build/assets/pylib-android/tty.py": "06d3dd054c50fbff2712f3a38cca880f",
|
"build/assets/pylib-android/tty.py": "06d3dd054c50fbff2712f3a38cca880f",
|
||||||
"build/assets/pylib-android/types.py": "134f86ee0d4879d294f95ea39c396027",
|
"build/assets/pylib-android/types.py": "134f86ee0d4879d294f95ea39c396027",
|
||||||
"build/assets/pylib-android/typing.py": "5780108232e902b6c03c9dede3203e15",
|
"build/assets/pylib-android/typing.py": "56bcd9a7595ef9b7f9332894b7ebc1a7",
|
||||||
"build/assets/pylib-android/urllib/__init__.py": "340c83beff7dcff8f5c7b87cd43cedaf",
|
"build/assets/pylib-android/urllib/__init__.py": "340c83beff7dcff8f5c7b87cd43cedaf",
|
||||||
"build/assets/pylib-android/urllib/error.py": "b7dde0483ff647eb87162d6e19c04fa0",
|
"build/assets/pylib-android/urllib/error.py": "b7dde0483ff647eb87162d6e19c04fa0",
|
||||||
"build/assets/pylib-android/urllib/parse.py": "9533d0e59e5ec79810be417dfc8b351a",
|
"build/assets/pylib-android/urllib/parse.py": "2b10efb06b24573929dafb6167b26099",
|
||||||
"build/assets/pylib-android/urllib/request.py": "bf59985a796494de7374fb909f32f933",
|
"build/assets/pylib-android/urllib/request.py": "bf59985a796494de7374fb909f32f933",
|
||||||
"build/assets/pylib-android/urllib/response.py": "c8537707a4b1e493c0ec4489ab523c93",
|
"build/assets/pylib-android/urllib/response.py": "c8537707a4b1e493c0ec4489ab523c93",
|
||||||
"build/assets/pylib-android/urllib/robotparser.py": "5a7616bdf398c166f953ad48c25506eb",
|
"build/assets/pylib-android/urllib/robotparser.py": "5a7616bdf398c166f953ad48c25506eb",
|
||||||
"build/assets/pylib-android/uu.py": "7cb795ca0c9e914550e6245dfe53c53e",
|
"build/assets/pylib-android/uu.py": "7cb795ca0c9e914550e6245dfe53c53e",
|
||||||
"build/assets/pylib-android/uuid.py": "fc298b89a3f1327be7808f0125c57866",
|
"build/assets/pylib-android/uuid.py": "fc298b89a3f1327be7808f0125c57866",
|
||||||
"build/assets/pylib-android/warnings.py": "0786f92f520b209fc88b9352fd7fc474",
|
"build/assets/pylib-android/warnings.py": "4deb449b93c3a0d8737555589f6f111c",
|
||||||
"build/assets/pylib-android/wave.py": "91c8be6651123c0d264fada07b63fd8e",
|
"build/assets/pylib-android/wave.py": "91c8be6651123c0d264fada07b63fd8e",
|
||||||
"build/assets/pylib-android/weakref.py": "dd14612f02ca8acd723f633b6fff0adf",
|
"build/assets/pylib-android/weakref.py": "dd14612f02ca8acd723f633b6fff0adf",
|
||||||
"build/assets/pylib-android/webbrowser.py": "45185d3143cc2513d3141e7cbfdafb1b",
|
"build/assets/pylib-android/webbrowser.py": "45185d3143cc2513d3141e7cbfdafb1b",
|
||||||
@ -2996,7 +3020,7 @@
|
|||||||
"build/assets/pylib-android/xml/dom/minidom.py": "3f4037810f081b078cc3fcab75bae3a0",
|
"build/assets/pylib-android/xml/dom/minidom.py": "3f4037810f081b078cc3fcab75bae3a0",
|
||||||
"build/assets/pylib-android/xml/dom/pulldom.py": "e133090081e446d69e5d1884f64fe1b6",
|
"build/assets/pylib-android/xml/dom/pulldom.py": "e133090081e446d69e5d1884f64fe1b6",
|
||||||
"build/assets/pylib-android/xml/dom/xmlbuilder.py": "610ebe0afcf5c7a72c6f708ae34e4f7e",
|
"build/assets/pylib-android/xml/dom/xmlbuilder.py": "610ebe0afcf5c7a72c6f708ae34e4f7e",
|
||||||
"build/assets/pylib-android/xml/etree/ElementInclude.py": "164c77dfb9abdf9c70def8812a00843a",
|
"build/assets/pylib-android/xml/etree/ElementInclude.py": "cdb7b9c55c44fbeb94bf96500b7bb5aa",
|
||||||
"build/assets/pylib-android/xml/etree/ElementPath.py": "fca9220534a8160762dee5e7da5f4144",
|
"build/assets/pylib-android/xml/etree/ElementPath.py": "fca9220534a8160762dee5e7da5f4144",
|
||||||
"build/assets/pylib-android/xml/etree/ElementTree.py": "dade97ab01bfa32bafca09daf7e7bbb2",
|
"build/assets/pylib-android/xml/etree/ElementTree.py": "dade97ab01bfa32bafca09daf7e7bbb2",
|
||||||
"build/assets/pylib-android/xml/etree/__init__.py": "82a62c7b190620aa1d3a40cc9ba829a5",
|
"build/assets/pylib-android/xml/etree/__init__.py": "82a62c7b190620aa1d3a40cc9ba829a5",
|
||||||
@ -4038,52 +4062,52 @@
|
|||||||
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
|
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
|
||||||
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
|
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
|
||||||
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
|
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
|
||||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "984af200e5e35417de6ace1da79c1351",
|
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "de1a31ddd37764c6a31c6c619a0069fe",
|
||||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "0902b446e625e001396b70ab1e567423",
|
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "1a4894c9eb324e6d2a442f72e5651c2c",
|
||||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "7e940b9dabe493f106c2e9d41fad32d2",
|
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "1999d90958ff312203a290aaff97a24f",
|
||||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "3492bf499cbf195e311ea7587d4247c4",
|
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "9a33cde90e447754e0b669f1e08948b2",
|
||||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "80ce3502f6ff6ae99d5a61cb746f476a",
|
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "c52c4b14e87cada2d2de8060caf64ec3",
|
||||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "08f433223f802b142a64a4d7e8ff129e",
|
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "4894e58ac2fa3cbff0c0542e33afd94e",
|
||||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "ee89411f673161492bf8762656c8308a",
|
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "eee4b5407e69075d925fad94de12c0b8",
|
||||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "bcb36f5a15e3fe28cbc5606b2196736d",
|
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "5d041c76ab815765179308a01b6a0028",
|
||||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "fb21bde8f575ef1aaabfee5bd2651571",
|
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "8ae3a85f68553255fa47a86e35cd41b0",
|
||||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "3c3ad695c496f35ca06b9b95d4ff1db7",
|
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "cd9dac595579b8e19f15eade2cf8155f",
|
||||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "f3ee8ad1b441c7788f2a76106a740f14",
|
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "1ab4f141dd2541ae40e886b5d448d86f",
|
||||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "b29045a9462537f4cc4a487a0d75abc3",
|
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "fb869f599357cb079851542411b2a852",
|
||||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "46c370f0616494816ea1ff73aa2b0d2f",
|
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "d06777b1f953c4f102d3ddb5b9d79337",
|
||||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "ffb4d1ab15033abbc9a7ccdf64493b25",
|
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "ac0582306bab0108da45dc53e0c544a7",
|
||||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "0a542a05b30e4f1d443e3e63be3406aa",
|
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "f847c697c1d541bbd1207355065fa988",
|
||||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "8711c3e818a759b050cab7dcff2e1147",
|
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "6edc275e5c427a04df8b02b115d2d832",
|
||||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "edb7277a16fb2847388b3c55447e5fbd",
|
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "473ef626512034b43a8fa54ad66af1ce",
|
||||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "8980b84f0c39fb6f8bead208e4b794de",
|
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "45f6a37d5e21b45542260f86b7c4784b",
|
||||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "109c5e9d5a415a0c5bb81ad076680174",
|
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "4d9922c7ba8e15e2059fcef7f87d195a",
|
||||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "49aa40bff81a8342ff16a41c143d7917",
|
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "fd57a5b64d0fc65bd04bbfdd4b63965d",
|
||||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "f231b10895bdcb542de87b887ca181fd",
|
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "fbfd42ab5d27e3ff921fa9cda02b2b45",
|
||||||
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "ae936a119668ede7b36f38c8672f4bf8",
|
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "abb5870a4b01cda2c9a958149f759325",
|
||||||
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "f231b10895bdcb542de87b887ca181fd",
|
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "fbfd42ab5d27e3ff921fa9cda02b2b45",
|
||||||
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "ae936a119668ede7b36f38c8672f4bf8",
|
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "abb5870a4b01cda2c9a958149f759325",
|
||||||
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "419b7edff05748a74370f29945bca90c",
|
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "1b51a49163d412cdd0b1441e3459e6c4",
|
||||||
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "1e75c6c1f0b0aae130bacfb8b65507cc",
|
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "4a39d8397fb76df3bafa366d8085d1cd",
|
||||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "419b7edff05748a74370f29945bca90c",
|
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "1b51a49163d412cdd0b1441e3459e6c4",
|
||||||
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "1e75c6c1f0b0aae130bacfb8b65507cc",
|
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "4a39d8397fb76df3bafa366d8085d1cd",
|
||||||
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "d965aa38a18627966633308f5a4e61b9",
|
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "c4ed230b63e7109de342e045733963e5",
|
||||||
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "5d12b05022f064c2aaf096c466da687c",
|
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "adb7ef762cb92b4c3bbe74a36e8ac6df",
|
||||||
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "d965aa38a18627966633308f5a4e61b9",
|
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "c4ed230b63e7109de342e045733963e5",
|
||||||
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "5d12b05022f064c2aaf096c466da687c",
|
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "adb7ef762cb92b4c3bbe74a36e8ac6df",
|
||||||
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "ff5b18144bf249558517bff7c97dc84f",
|
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "0863bb24d2a42598dd20e7b55beb1c02",
|
||||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "efffc4f330e77530accd9a9f82840a6c",
|
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "1805fd5900917411f0e8032bf3c4734c",
|
||||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "c20363fe2af3d54e666b1c8ee67f6b76",
|
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "3277c2f61c315e2ca7ed6776ba2363e2",
|
||||||
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "efffc4f330e77530accd9a9f82840a6c",
|
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "1805fd5900917411f0e8032bf3c4734c",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "54b1fb0ff0a189a59da87f3578a1119a",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "b639992e280ee3a73b764a3e3e58baec",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "c0e6444e540a2046b858fc4b4629f6b4",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "5ebaf4315d286080e5789939edfe43ce",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "b44c5bb764eb9a30c49d3dc36c54d784",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "be8f76ded92473fbab8b28018097456c",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "23afa2f159052928a16cc3e5bde1f864",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "dcab88e3c14c6f4c4a03dd8617328eaf",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "40437dd15a65d97481d88e245de923bf",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "bab18c50134744a7206ea1ded2d90ab2",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "4e7a439617c2ad9d6100a7ec6e593713",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "c6788ba7cd99fc29a0b6ca8351f412b4",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "a19afc6c611054e2c5df4dd3c07afed9",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "e61726c963e53ee7746ffbd7ed35c919",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "5156925d106a00a4602ef7204f70ab5a",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "841fbbd6b87ac5d50ccdda647d8ff909",
|
||||||
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
|
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
|
||||||
"src/assets/ba_data/python/babase/_mgen/enums.py": "5548f407d97e380069f6c596c4e36cd7",
|
"src/assets/ba_data/python/babase/_mgen/enums.py": "cb299985623bbcc86015cb103a424ae6",
|
||||||
"src/ballistica/base/mgen/pyembed/binding_base.inc": "efa61468cf098f77cc6a234461d8b86d",
|
"src/ballistica/base/mgen/pyembed/binding_base.inc": "efa61468cf098f77cc6a234461d8b86d",
|
||||||
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "97efb93f4bfd8e8b09f2db24398e29fc",
|
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "97efb93f4bfd8e8b09f2db24398e29fc",
|
||||||
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "3ceb412513963f0818ab39c58bf292e3",
|
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "3ceb412513963f0818ab39c58bf292e3",
|
||||||
|
|||||||
3
.idea/dictionaries/ericf.xml
generated
3
.idea/dictionaries/ericf.xml
generated
@ -1232,7 +1232,7 @@
|
|||||||
<w>getcollisionmesh</w>
|
<w>getcollisionmesh</w>
|
||||||
<w>getconf</w>
|
<w>getconf</w>
|
||||||
<w>getconfig</w>
|
<w>getconfig</w>
|
||||||
<w>getcurrency</w>
|
<w>gettickets</w>
|
||||||
<w>getcwd</w>
|
<w>getcwd</w>
|
||||||
<w>getdata</w>
|
<w>getdata</w>
|
||||||
<w>getenv</w>
|
<w>getenv</w>
|
||||||
@ -3082,7 +3082,6 @@
|
|||||||
<w>tournamentbutton</w>
|
<w>tournamentbutton</w>
|
||||||
<w>tournamententry</w>
|
<w>tournamententry</w>
|
||||||
<w>tournamentscores</w>
|
<w>tournamentscores</w>
|
||||||
<w>tpartial</w>
|
|
||||||
<w>tpath</w>
|
<w>tpath</w>
|
||||||
<w>tpathsegs</w>
|
<w>tpathsegs</w>
|
||||||
<w>tpexl</w>
|
<w>tpexl</w>
|
||||||
|
|||||||
25
CHANGELOG.md
25
CHANGELOG.md
@ -1,4 +1,4 @@
|
|||||||
### 1.7.36 (build 21911, api 8, 2024-07-05)
|
### 1.7.36 (build 21919, api 8, 2024-07-21)
|
||||||
- Wired up initial support for using asset-packages for bundled assets.
|
- Wired up initial support for using asset-packages for bundled assets.
|
||||||
- bacloud workspace commands are now a bit smarter; you can now do things like
|
- bacloud workspace commands are now a bit smarter; you can now do things like
|
||||||
`bacloud workspace put .` or even just `bacloud workspace put` and it will
|
`bacloud workspace put .` or even just `bacloud workspace put` and it will
|
||||||
@ -6,6 +6,29 @@
|
|||||||
as a second argument. Both `workspace get` and `workspace put` now also have
|
as a second argument. Both `workspace get` and `workspace put` now also have
|
||||||
an optional `--workspace` arg if you want to sync with a workspace different
|
an optional `--workspace` arg if you want to sync with a workspace different
|
||||||
than the local directory name.
|
than the local directory name.
|
||||||
|
- Cleaned up look and feel on horizontal scrollbars, especially when and how
|
||||||
|
they fade in and out.
|
||||||
|
- Fixed an issue where ConfigNumberEdit objects would draw incorrectly with
|
||||||
|
textscale set to non-1.0 values.
|
||||||
|
- Fixed a nasty bug with the new stdin handling from 1.7.35 which could cause
|
||||||
|
the stdin thread to spin at 100% cpu usage in some cases (such as when
|
||||||
|
launching the Mac build from the Finder and not a terminal).
|
||||||
|
- Added a `draw_controller_mult` arg to `bauiv1.imagewidget()` to control how
|
||||||
|
brightly the image pulses when its controller widget is selected (can prevent
|
||||||
|
brightly colored images from blowing out too much).
|
||||||
|
- The Mac version is now correctly rendering to a sRGB colorspace instead of P3.
|
||||||
|
This was causing some bright colors to render extra-eye-destroying bright.
|
||||||
|
- Fixed an issue with the Repeater() class which could cause key presses in UIs
|
||||||
|
to get lost if many were happening in short succession. An easy way to observe
|
||||||
|
this (at least on my machine) was to press left and right repeatedly in the
|
||||||
|
main menu - some presses would be lost and the selection would 'drift' one
|
||||||
|
direction.
|
||||||
|
- Replaced all `efro.call.tpartial` calls with Python's built in
|
||||||
|
`functools.partial`. Mypy's 1.11 update added full type checking for
|
||||||
|
`functools.partial` so there's no benefit to maintaining our own special
|
||||||
|
version anymore. This also applies to `ba*.Call` which is redundant in the
|
||||||
|
same way. Both `efro.call.tpartial` and `ba*.Call` will probably be marked
|
||||||
|
deprecated and go away at some point.
|
||||||
|
|
||||||
### 1.7.35 (build 21889, api 8, 2024-06-20)
|
### 1.7.35 (build 21889, api 8, 2024-06-20)
|
||||||
- Fixed an issue where the engine would block at exit on some version of Linux
|
- Fixed an issue where the engine would block at exit on some version of Linux
|
||||||
|
|||||||
1
ballisticakit-cmake/.idea/dictionaries/ericf.xml
generated
1
ballisticakit-cmake/.idea/dictionaries/ericf.xml
generated
@ -1807,7 +1807,6 @@
|
|||||||
<w>toucs</w>
|
<w>toucs</w>
|
||||||
<w>tournamentbutton</w>
|
<w>tournamentbutton</w>
|
||||||
<w>toutf</w>
|
<w>toutf</w>
|
||||||
<w>tpartial</w>
|
|
||||||
<w>tpath</w>
|
<w>tpath</w>
|
||||||
<w>tpathsegs</w>
|
<w>tpathsegs</w>
|
||||||
<w>tpexl</w>
|
<w>tpexl</w>
|
||||||
|
|||||||
@ -1,21 +1,21 @@
|
|||||||
cpplint==1.6.1
|
cpplint==1.6.1
|
||||||
dmgbuild==1.6.1
|
dmgbuild==1.6.1
|
||||||
filelock==3.15.4
|
filelock==3.15.4
|
||||||
furo==2024.5.6
|
furo==2024.7.18
|
||||||
mypy==1.10.1
|
mypy==1.11.0
|
||||||
pbxproj==4.2.0
|
pbxproj==4.2.0
|
||||||
pdoc==14.5.1
|
pdoc==14.5.1
|
||||||
pur==7.3.2
|
pur==7.3.2
|
||||||
pylint==3.2.5
|
pylint==3.2.6
|
||||||
pylsp-mypy==0.6.8
|
pylsp-mypy==0.6.8
|
||||||
pytest==8.2.2
|
pytest==8.3.1
|
||||||
python-daemon==3.0.1
|
python-daemon==3.0.1
|
||||||
python-lsp-black==2.0.0
|
python-lsp-black==2.0.0
|
||||||
python-lsp-server==1.11.0
|
python-lsp-server==1.11.0
|
||||||
requests==2.32.3
|
requests==2.32.3
|
||||||
Sphinx==7.3.7
|
Sphinx==7.4.7
|
||||||
tomlkit==0.12.5
|
tomlkit==0.13.0
|
||||||
types-certifi==2021.10.8.3
|
types-certifi==2021.10.8.3
|
||||||
types-filelock==3.2.7
|
types-filelock==3.2.7
|
||||||
types-requests==2.32.0.20240622
|
types-requests==2.32.0.20240712
|
||||||
typing_extensions==4.12.2
|
typing_extensions==4.12.2
|
||||||
|
|||||||
@ -1629,6 +1629,10 @@
|
|||||||
"ba_data/textures/glow.ktx",
|
"ba_data/textures/glow.ktx",
|
||||||
"ba_data/textures/glow.pvr",
|
"ba_data/textures/glow.pvr",
|
||||||
"ba_data/textures/glow_preview.png",
|
"ba_data/textures/glow_preview.png",
|
||||||
|
"ba_data/textures/goldPass.dds",
|
||||||
|
"ba_data/textures/goldPass.ktx",
|
||||||
|
"ba_data/textures/goldPass.pvr",
|
||||||
|
"ba_data/textures/goldPass_preview.png",
|
||||||
"ba_data/textures/googlePlayAchievementsIcon.dds",
|
"ba_data/textures/googlePlayAchievementsIcon.dds",
|
||||||
"ba_data/textures/googlePlayAchievementsIcon.ktx",
|
"ba_data/textures/googlePlayAchievementsIcon.ktx",
|
||||||
"ba_data/textures/googlePlayAchievementsIcon.pvr",
|
"ba_data/textures/googlePlayAchievementsIcon.pvr",
|
||||||
@ -2413,6 +2417,22 @@
|
|||||||
"ba_data/textures/tnt.ktx",
|
"ba_data/textures/tnt.ktx",
|
||||||
"ba_data/textures/tnt.pvr",
|
"ba_data/textures/tnt.pvr",
|
||||||
"ba_data/textures/tnt_preview.png",
|
"ba_data/textures/tnt_preview.png",
|
||||||
|
"ba_data/textures/tokens1.dds",
|
||||||
|
"ba_data/textures/tokens1.ktx",
|
||||||
|
"ba_data/textures/tokens1.pvr",
|
||||||
|
"ba_data/textures/tokens1_preview.png",
|
||||||
|
"ba_data/textures/tokens2.dds",
|
||||||
|
"ba_data/textures/tokens2.ktx",
|
||||||
|
"ba_data/textures/tokens2.pvr",
|
||||||
|
"ba_data/textures/tokens2_preview.png",
|
||||||
|
"ba_data/textures/tokens3.dds",
|
||||||
|
"ba_data/textures/tokens3.ktx",
|
||||||
|
"ba_data/textures/tokens3.pvr",
|
||||||
|
"ba_data/textures/tokens3_preview.png",
|
||||||
|
"ba_data/textures/tokens4.dds",
|
||||||
|
"ba_data/textures/tokens4.ktx",
|
||||||
|
"ba_data/textures/tokens4.pvr",
|
||||||
|
"ba_data/textures/tokens4_preview.png",
|
||||||
"ba_data/textures/touchArrows.dds",
|
"ba_data/textures/touchArrows.dds",
|
||||||
"ba_data/textures/touchArrows.ktx",
|
"ba_data/textures/touchArrows.ktx",
|
||||||
"ba_data/textures/touchArrows.pvr",
|
"ba_data/textures/touchArrows.pvr",
|
||||||
@ -2481,6 +2501,10 @@
|
|||||||
"ba_data/textures/white.ktx",
|
"ba_data/textures/white.ktx",
|
||||||
"ba_data/textures/white.pvr",
|
"ba_data/textures/white.pvr",
|
||||||
"ba_data/textures/white_preview.png",
|
"ba_data/textures/white_preview.png",
|
||||||
|
"ba_data/textures/windowBottomCap.dds",
|
||||||
|
"ba_data/textures/windowBottomCap.ktx",
|
||||||
|
"ba_data/textures/windowBottomCap.pvr",
|
||||||
|
"ba_data/textures/windowBottomCap_preview.png",
|
||||||
"ba_data/textures/windowHSmallVMed.dds",
|
"ba_data/textures/windowHSmallVMed.dds",
|
||||||
"ba_data/textures/windowHSmallVMed.ktx",
|
"ba_data/textures/windowHSmallVMed.ktx",
|
||||||
"ba_data/textures/windowHSmallVMed.pvr",
|
"ba_data/textures/windowHSmallVMed.pvr",
|
||||||
|
|||||||
@ -380,8 +380,9 @@
|
|||||||
"ba_data/python/bauiv1lib/__pycache__/discord.cpython-312.opt-1.pyc",
|
"ba_data/python/bauiv1lib/__pycache__/discord.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/bauiv1lib/__pycache__/feedback.cpython-312.opt-1.pyc",
|
"ba_data/python/bauiv1lib/__pycache__/feedback.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/bauiv1lib/__pycache__/fileselector.cpython-312.opt-1.pyc",
|
"ba_data/python/bauiv1lib/__pycache__/fileselector.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/bauiv1lib/__pycache__/getcurrency.cpython-312.opt-1.pyc",
|
|
||||||
"ba_data/python/bauiv1lib/__pycache__/getremote.cpython-312.opt-1.pyc",
|
"ba_data/python/bauiv1lib/__pycache__/getremote.cpython-312.opt-1.pyc",
|
||||||
|
"ba_data/python/bauiv1lib/__pycache__/gettickets.cpython-312.opt-1.pyc",
|
||||||
|
"ba_data/python/bauiv1lib/__pycache__/gettokens.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/bauiv1lib/__pycache__/helpui.cpython-312.opt-1.pyc",
|
"ba_data/python/bauiv1lib/__pycache__/helpui.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/bauiv1lib/__pycache__/iconpicker.cpython-312.opt-1.pyc",
|
"ba_data/python/bauiv1lib/__pycache__/iconpicker.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/bauiv1lib/__pycache__/kiosk.cpython-312.opt-1.pyc",
|
"ba_data/python/bauiv1lib/__pycache__/kiosk.cpython-312.opt-1.pyc",
|
||||||
@ -454,8 +455,9 @@
|
|||||||
"ba_data/python/bauiv1lib/gather/nearbytab.py",
|
"ba_data/python/bauiv1lib/gather/nearbytab.py",
|
||||||
"ba_data/python/bauiv1lib/gather/privatetab.py",
|
"ba_data/python/bauiv1lib/gather/privatetab.py",
|
||||||
"ba_data/python/bauiv1lib/gather/publictab.py",
|
"ba_data/python/bauiv1lib/gather/publictab.py",
|
||||||
"ba_data/python/bauiv1lib/getcurrency.py",
|
|
||||||
"ba_data/python/bauiv1lib/getremote.py",
|
"ba_data/python/bauiv1lib/getremote.py",
|
||||||
|
"ba_data/python/bauiv1lib/gettickets.py",
|
||||||
|
"ba_data/python/bauiv1lib/gettokens.py",
|
||||||
"ba_data/python/bauiv1lib/helpui.py",
|
"ba_data/python/bauiv1lib/helpui.py",
|
||||||
"ba_data/python/bauiv1lib/iconpicker.py",
|
"ba_data/python/bauiv1lib/iconpicker.py",
|
||||||
"ba_data/python/bauiv1lib/keyboard/__init__.py",
|
"ba_data/python/bauiv1lib/keyboard/__init__.py",
|
||||||
|
|||||||
@ -364,8 +364,9 @@ SCRIPT_TARGETS_PY_PUBLIC = \
|
|||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/gather/nearbytab.py \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/gather/nearbytab.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/gather/privatetab.py \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/gather/privatetab.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/gather/publictab.py \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/gather/publictab.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/getcurrency.py \
|
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/getremote.py \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/getremote.py \
|
||||||
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/gettickets.py \
|
||||||
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/gettokens.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/helpui.py \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/helpui.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/iconpicker.py \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/iconpicker.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/keyboard/__init__.py \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/keyboard/__init__.py \
|
||||||
@ -641,8 +642,9 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
|
|||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/gather/__pycache__/nearbytab.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/gather/__pycache__/nearbytab.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/gather/__pycache__/privatetab.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/gather/__pycache__/privatetab.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/gather/__pycache__/publictab.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/gather/__pycache__/publictab.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/getcurrency.cpython-312.opt-1.pyc \
|
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/getremote.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/getremote.cpython-312.opt-1.pyc \
|
||||||
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/gettickets.cpython-312.opt-1.pyc \
|
||||||
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/gettokens.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/helpui.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/helpui.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/iconpicker.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/iconpicker.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/keyboard/__pycache__/__init__.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bauiv1lib/keyboard/__pycache__/__init__.cpython-312.opt-1.pyc \
|
||||||
@ -5711,6 +5713,7 @@ TEX2D_DDS_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/gladiatorIcon.dds \
|
$(BUILD_DIR)/ba_data/textures/gladiatorIcon.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/gladiatorIconColorMask.dds \
|
$(BUILD_DIR)/ba_data/textures/gladiatorIconColorMask.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/glow.dds \
|
$(BUILD_DIR)/ba_data/textures/glow.dds \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/goldPass.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/googlePlayAchievementsIcon.dds \
|
$(BUILD_DIR)/ba_data/textures/googlePlayAchievementsIcon.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/googlePlayGamesIcon.dds \
|
$(BUILD_DIR)/ba_data/textures/googlePlayGamesIcon.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/googlePlayLeaderboardsIcon.dds \
|
$(BUILD_DIR)/ba_data/textures/googlePlayLeaderboardsIcon.dds \
|
||||||
@ -5907,6 +5910,10 @@ TEX2D_DDS_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/tipTopLevelColor.dds \
|
$(BUILD_DIR)/ba_data/textures/tipTopLevelColor.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/tipTopPreview.dds \
|
$(BUILD_DIR)/ba_data/textures/tipTopPreview.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/tnt.dds \
|
$(BUILD_DIR)/ba_data/textures/tnt.dds \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens1.dds \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens2.dds \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens3.dds \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens4.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/touchArrows.dds \
|
$(BUILD_DIR)/ba_data/textures/touchArrows.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/touchArrowsActions.dds \
|
$(BUILD_DIR)/ba_data/textures/touchArrowsActions.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/towerDLevelColor.dds \
|
$(BUILD_DIR)/ba_data/textures/towerDLevelColor.dds \
|
||||||
@ -5924,6 +5931,7 @@ TEX2D_DDS_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/warriorIcon.dds \
|
$(BUILD_DIR)/ba_data/textures/warriorIcon.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/warriorIconColorMask.dds \
|
$(BUILD_DIR)/ba_data/textures/warriorIconColorMask.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/white.dds \
|
$(BUILD_DIR)/ba_data/textures/white.dds \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/windowBottomCap.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/windowHSmallVMed.dds \
|
$(BUILD_DIR)/ba_data/textures/windowHSmallVMed.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/windowHSmallVSmall.dds \
|
$(BUILD_DIR)/ba_data/textures/windowHSmallVSmall.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/wings.dds \
|
$(BUILD_DIR)/ba_data/textures/wings.dds \
|
||||||
@ -6116,6 +6124,7 @@ TEX2D_PVR_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/gladiatorIcon.pvr \
|
$(BUILD_DIR)/ba_data/textures/gladiatorIcon.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/gladiatorIconColorMask.pvr \
|
$(BUILD_DIR)/ba_data/textures/gladiatorIconColorMask.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/glow.pvr \
|
$(BUILD_DIR)/ba_data/textures/glow.pvr \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/goldPass.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/googlePlayAchievementsIcon.pvr \
|
$(BUILD_DIR)/ba_data/textures/googlePlayAchievementsIcon.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/googlePlayGamesIcon.pvr \
|
$(BUILD_DIR)/ba_data/textures/googlePlayGamesIcon.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/googlePlayLeaderboardsIcon.pvr \
|
$(BUILD_DIR)/ba_data/textures/googlePlayLeaderboardsIcon.pvr \
|
||||||
@ -6312,6 +6321,10 @@ TEX2D_PVR_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/tipTopLevelColor.pvr \
|
$(BUILD_DIR)/ba_data/textures/tipTopLevelColor.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/tipTopPreview.pvr \
|
$(BUILD_DIR)/ba_data/textures/tipTopPreview.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/tnt.pvr \
|
$(BUILD_DIR)/ba_data/textures/tnt.pvr \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens1.pvr \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens2.pvr \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens3.pvr \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens4.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/touchArrows.pvr \
|
$(BUILD_DIR)/ba_data/textures/touchArrows.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/touchArrowsActions.pvr \
|
$(BUILD_DIR)/ba_data/textures/touchArrowsActions.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/towerDLevelColor.pvr \
|
$(BUILD_DIR)/ba_data/textures/towerDLevelColor.pvr \
|
||||||
@ -6329,6 +6342,7 @@ TEX2D_PVR_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/warriorIcon.pvr \
|
$(BUILD_DIR)/ba_data/textures/warriorIcon.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/warriorIconColorMask.pvr \
|
$(BUILD_DIR)/ba_data/textures/warriorIconColorMask.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/white.pvr \
|
$(BUILD_DIR)/ba_data/textures/white.pvr \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/windowBottomCap.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/windowHSmallVMed.pvr \
|
$(BUILD_DIR)/ba_data/textures/windowHSmallVMed.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/windowHSmallVSmall.pvr \
|
$(BUILD_DIR)/ba_data/textures/windowHSmallVSmall.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/wings.pvr \
|
$(BUILD_DIR)/ba_data/textures/wings.pvr \
|
||||||
@ -6521,6 +6535,7 @@ TEX2D_KTX_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/gladiatorIcon.ktx \
|
$(BUILD_DIR)/ba_data/textures/gladiatorIcon.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/gladiatorIconColorMask.ktx \
|
$(BUILD_DIR)/ba_data/textures/gladiatorIconColorMask.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/glow.ktx \
|
$(BUILD_DIR)/ba_data/textures/glow.ktx \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/goldPass.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/googlePlayAchievementsIcon.ktx \
|
$(BUILD_DIR)/ba_data/textures/googlePlayAchievementsIcon.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/googlePlayGamesIcon.ktx \
|
$(BUILD_DIR)/ba_data/textures/googlePlayGamesIcon.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/googlePlayLeaderboardsIcon.ktx \
|
$(BUILD_DIR)/ba_data/textures/googlePlayLeaderboardsIcon.ktx \
|
||||||
@ -6717,6 +6732,10 @@ TEX2D_KTX_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/tipTopLevelColor.ktx \
|
$(BUILD_DIR)/ba_data/textures/tipTopLevelColor.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/tipTopPreview.ktx \
|
$(BUILD_DIR)/ba_data/textures/tipTopPreview.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/tnt.ktx \
|
$(BUILD_DIR)/ba_data/textures/tnt.ktx \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens1.ktx \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens2.ktx \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens3.ktx \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens4.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/touchArrows.ktx \
|
$(BUILD_DIR)/ba_data/textures/touchArrows.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/touchArrowsActions.ktx \
|
$(BUILD_DIR)/ba_data/textures/touchArrowsActions.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/towerDLevelColor.ktx \
|
$(BUILD_DIR)/ba_data/textures/towerDLevelColor.ktx \
|
||||||
@ -6734,6 +6753,7 @@ TEX2D_KTX_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/warriorIcon.ktx \
|
$(BUILD_DIR)/ba_data/textures/warriorIcon.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/warriorIconColorMask.ktx \
|
$(BUILD_DIR)/ba_data/textures/warriorIconColorMask.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/white.ktx \
|
$(BUILD_DIR)/ba_data/textures/white.ktx \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/windowBottomCap.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/windowHSmallVMed.ktx \
|
$(BUILD_DIR)/ba_data/textures/windowHSmallVMed.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/windowHSmallVSmall.ktx \
|
$(BUILD_DIR)/ba_data/textures/windowHSmallVSmall.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/wings.ktx \
|
$(BUILD_DIR)/ba_data/textures/wings.ktx \
|
||||||
@ -6926,6 +6946,7 @@ TEX2D_PREVIEW_PNG_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/gladiatorIconColorMask_preview.png \
|
$(BUILD_DIR)/ba_data/textures/gladiatorIconColorMask_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/gladiatorIcon_preview.png \
|
$(BUILD_DIR)/ba_data/textures/gladiatorIcon_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/glow_preview.png \
|
$(BUILD_DIR)/ba_data/textures/glow_preview.png \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/goldPass_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/googlePlayAchievementsIcon_preview.png \
|
$(BUILD_DIR)/ba_data/textures/googlePlayAchievementsIcon_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/googlePlayGamesIcon_preview.png \
|
$(BUILD_DIR)/ba_data/textures/googlePlayGamesIcon_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/googlePlayLeaderboardsIcon_preview.png \
|
$(BUILD_DIR)/ba_data/textures/googlePlayLeaderboardsIcon_preview.png \
|
||||||
@ -7122,6 +7143,10 @@ TEX2D_PREVIEW_PNG_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/tipTopLevelColor_preview.png \
|
$(BUILD_DIR)/ba_data/textures/tipTopLevelColor_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/tipTopPreview_preview.png \
|
$(BUILD_DIR)/ba_data/textures/tipTopPreview_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/tnt_preview.png \
|
$(BUILD_DIR)/ba_data/textures/tnt_preview.png \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens1_preview.png \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens2_preview.png \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens3_preview.png \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/tokens4_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/touchArrowsActions_preview.png \
|
$(BUILD_DIR)/ba_data/textures/touchArrowsActions_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/touchArrows_preview.png \
|
$(BUILD_DIR)/ba_data/textures/touchArrows_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/towerDLevelColor_preview.png \
|
$(BUILD_DIR)/ba_data/textures/towerDLevelColor_preview.png \
|
||||||
@ -7139,6 +7164,7 @@ TEX2D_PREVIEW_PNG_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/warriorIconColorMask_preview.png \
|
$(BUILD_DIR)/ba_data/textures/warriorIconColorMask_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/warriorIcon_preview.png \
|
$(BUILD_DIR)/ba_data/textures/warriorIcon_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/white_preview.png \
|
$(BUILD_DIR)/ba_data/textures/white_preview.png \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/windowBottomCap_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/windowHSmallVMed_preview.png \
|
$(BUILD_DIR)/ba_data/textures/windowHSmallVMed_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/windowHSmallVSmall_preview.png \
|
$(BUILD_DIR)/ba_data/textures/windowHSmallVSmall_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/wings_preview.png \
|
$(BUILD_DIR)/ba_data/textures/wings_preview.png \
|
||||||
|
|||||||
@ -6,9 +6,9 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
|
from functools import partial
|
||||||
from typing import TYPE_CHECKING, assert_never
|
from typing import TYPE_CHECKING, assert_never
|
||||||
|
|
||||||
from efro.call import tpartial
|
|
||||||
from efro.error import CommunicationError
|
from efro.error import CommunicationError
|
||||||
from bacommon.login import LoginType
|
from bacommon.login import LoginType
|
||||||
import _babase
|
import _babase
|
||||||
@ -223,7 +223,7 @@ class AccountV2Subsystem:
|
|||||||
if service_str is not None:
|
if service_str is not None:
|
||||||
_babase.apptimer(
|
_babase.apptimer(
|
||||||
2.0,
|
2.0,
|
||||||
tpartial(
|
partial(
|
||||||
_babase.screenmessage,
|
_babase.screenmessage,
|
||||||
Lstr(
|
Lstr(
|
||||||
resource='notUsingAccountText',
|
resource='notUsingAccountText',
|
||||||
|
|||||||
@ -7,13 +7,11 @@ from __future__ import annotations
|
|||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
from functools import partial
|
||||||
from typing import TYPE_CHECKING, TypeVar, override
|
from typing import TYPE_CHECKING, TypeVar, override
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from threading import RLock
|
from threading import RLock
|
||||||
|
|
||||||
|
|
||||||
from efro.call import tpartial
|
|
||||||
|
|
||||||
import _babase
|
import _babase
|
||||||
from babase._language import LanguageSubsystem
|
from babase._language import LanguageSubsystem
|
||||||
from babase._plugin import PluginSubsystem
|
from babase._plugin import PluginSubsystem
|
||||||
@ -512,7 +510,7 @@ class App:
|
|||||||
|
|
||||||
# Do the actual work of calcing our app-mode/etc. in a bg thread
|
# Do the actual work of calcing our app-mode/etc. in a bg thread
|
||||||
# since it may block for a moment to load modules/etc.
|
# since it may block for a moment to load modules/etc.
|
||||||
self.threadpool_submit_no_wait(tpartial(self._set_intent, intent))
|
self.threadpool_submit_no_wait(partial(self._set_intent, intent))
|
||||||
|
|
||||||
def push_apply_app_config(self) -> None:
|
def push_apply_app_config(self) -> None:
|
||||||
"""Internal. Use app.config.apply() to apply app config changes."""
|
"""Internal. Use app.config.apply() to apply app config changes."""
|
||||||
@ -644,13 +642,13 @@ class App:
|
|||||||
# kick back to the logic thread to apply.
|
# kick back to the logic thread to apply.
|
||||||
mode = modetype()
|
mode = modetype()
|
||||||
_babase.pushcall(
|
_babase.pushcall(
|
||||||
tpartial(self._apply_intent, intent, mode),
|
partial(self._apply_intent, intent, mode),
|
||||||
from_other_thread=True,
|
from_other_thread=True,
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
logging.exception('Error setting app intent to %s.', intent)
|
logging.exception('Error setting app intent to %s.', intent)
|
||||||
_babase.pushcall(
|
_babase.pushcall(
|
||||||
tpartial(self._display_set_intent_error, intent),
|
partial(self._display_set_intent_error, intent),
|
||||||
from_other_thread=True,
|
from_other_thread=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -7,10 +7,10 @@ import gc
|
|||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
from functools import partial
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import TYPE_CHECKING, override
|
from typing import TYPE_CHECKING, override
|
||||||
|
|
||||||
from efro.call import tpartial
|
|
||||||
from efro.log import LogLevel
|
from efro.log import LogLevel
|
||||||
from efro.dataclassio import ioprepped, dataclass_to_json, dataclass_from_json
|
from efro.dataclassio import ioprepped, dataclass_to_json, dataclass_from_json
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ import _babase
|
|||||||
from babase._appsubsystem import AppSubsystem
|
from babase._appsubsystem import AppSubsystem
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, TextIO
|
from typing import Any, TextIO, Callable
|
||||||
|
|
||||||
import babase
|
import babase
|
||||||
|
|
||||||
@ -320,7 +320,7 @@ def dump_app_state(
|
|||||||
# We want this to work from any thread, so need to kick this part
|
# We want this to work from any thread, so need to kick this part
|
||||||
# over to the logic thread so timer works.
|
# over to the logic thread so timer works.
|
||||||
_babase.pushcall(
|
_babase.pushcall(
|
||||||
tpartial(_babase.apptimer, delay + 1.0, log_dumped_app_state),
|
partial(_babase.apptimer, delay + 1.0, log_dumped_app_state),
|
||||||
from_other_thread=True,
|
from_other_thread=True,
|
||||||
suppress_other_thread_warning=True,
|
suppress_other_thread_warning=True,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -15,8 +15,8 @@ from efro.terminal import Clr
|
|||||||
import _babase
|
import _babase
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
import functools
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from efro.call import Call as Call # 'as Call' so we re-export.
|
|
||||||
|
|
||||||
|
|
||||||
# Declare distinct types for different time measurements we use so the
|
# Declare distinct types for different time measurements we use so the
|
||||||
@ -166,7 +166,7 @@ class _WeakCall:
|
|||||||
if not self._did_invalid_call_warning:
|
if not self._did_invalid_call_warning:
|
||||||
logging.warning(
|
logging.warning(
|
||||||
'Warning: callable passed to babase.WeakCall() is not'
|
'Warning: callable passed to babase.WeakCall() is not'
|
||||||
' weak-referencable (%s); use babase.Call() instead'
|
' weak-referencable (%s); use functools.partial instead'
|
||||||
' to avoid this warning.',
|
' to avoid this warning.',
|
||||||
stack_info=True,
|
stack_info=True,
|
||||||
)
|
)
|
||||||
@ -199,9 +199,13 @@ class _Call:
|
|||||||
The callable is strong-referenced so it won't die until this
|
The callable is strong-referenced so it won't die until this
|
||||||
object does.
|
object does.
|
||||||
|
|
||||||
|
WARNING: This is exactly the same as Python's built in functools.partial().
|
||||||
|
Use functools.partial instead of this for new code, as this will probably
|
||||||
|
be deprecated at some point.
|
||||||
|
|
||||||
Note that a bound method (ex: ``myobj.dosomething``) contains a reference
|
Note that a bound method (ex: ``myobj.dosomething``) contains a reference
|
||||||
to ``self`` (``myobj`` in that case), so you will be keeping that object
|
to ``self`` (``myobj`` in that case), so you will be keeping that object
|
||||||
alive too. Use babase.WeakCall if you want to pass a method to callback
|
alive too. Use babase.WeakCall if you want to pass a method to a callback
|
||||||
without keeping its object alive.
|
without keeping its object alive.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -239,12 +243,16 @@ class _Call:
|
|||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
# Some interaction between our ballistica pylint plugin
|
# For type-checking, point at functools.partial which gives us full
|
||||||
# and this code is crashing starting on pylint 2.15.0.
|
# type checking on both positional and keyword arguments (as of mypy
|
||||||
# This seems to fix things for now.
|
# 1.11).
|
||||||
|
|
||||||
|
# Note: Something here is wonky with pylint, possibly related to our
|
||||||
|
# custom pylint plugin. Disabling all checks seems to fix it.
|
||||||
# pylint: disable=all
|
# pylint: disable=all
|
||||||
WeakCall = Call
|
|
||||||
Call = Call
|
WeakCall = functools.partial
|
||||||
|
Call = functools.partial
|
||||||
else:
|
else:
|
||||||
WeakCall = _WeakCall
|
WeakCall = _WeakCall
|
||||||
WeakCall.__name__ = 'WeakCall'
|
WeakCall.__name__ = 'WeakCall'
|
||||||
|
|||||||
@ -6,6 +6,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
from functools import partial
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import TYPE_CHECKING, final, override
|
from typing import TYPE_CHECKING, final, override
|
||||||
|
|
||||||
@ -162,8 +163,8 @@ class LoginAdapter:
|
|||||||
the adapter will attempt to sign in if possible. An exception will
|
the adapter will attempt to sign in if possible. An exception will
|
||||||
be returned if the sign-in attempt fails.
|
be returned if the sign-in attempt fails.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
assert _babase.in_logic_thread()
|
assert _babase.in_logic_thread()
|
||||||
from babase._general import Call
|
|
||||||
|
|
||||||
# Have been seeing multiple sign-in attempts come through
|
# Have been seeing multiple sign-in attempts come through
|
||||||
# nearly simultaneously which can be problematic server-side.
|
# nearly simultaneously which can be problematic server-side.
|
||||||
@ -185,7 +186,7 @@ class LoginAdapter:
|
|||||||
appnow,
|
appnow,
|
||||||
)
|
)
|
||||||
_babase.pushcall(
|
_babase.pushcall(
|
||||||
Call(
|
partial(
|
||||||
result_cb,
|
result_cb,
|
||||||
self,
|
self,
|
||||||
RuntimeError('sign_in called too soon after last.'),
|
RuntimeError('sign_in called too soon after last.'),
|
||||||
@ -215,7 +216,7 @@ class LoginAdapter:
|
|||||||
self.login_type.name,
|
self.login_type.name,
|
||||||
)
|
)
|
||||||
_babase.pushcall(
|
_babase.pushcall(
|
||||||
Call(
|
partial(
|
||||||
result_cb,
|
result_cb,
|
||||||
self,
|
self,
|
||||||
RuntimeError('fetch-sign-in-token failed.'),
|
RuntimeError('fetch-sign-in-token failed.'),
|
||||||
@ -245,7 +246,7 @@ class LoginAdapter:
|
|||||||
self.login_type.name,
|
self.login_type.name,
|
||||||
response,
|
response,
|
||||||
)
|
)
|
||||||
_babase.pushcall(Call(result_cb, self, response))
|
_babase.pushcall(partial(result_cb, self, response))
|
||||||
else:
|
else:
|
||||||
# This means our credentials were explicitly rejected.
|
# This means our credentials were explicitly rejected.
|
||||||
if response.credentials is None:
|
if response.credentials is None:
|
||||||
@ -262,7 +263,7 @@ class LoginAdapter:
|
|||||||
result2 = self.SignInResult(
|
result2 = self.SignInResult(
|
||||||
credentials=response.credentials
|
credentials=response.credentials
|
||||||
)
|
)
|
||||||
_babase.pushcall(Call(result_cb, self, result2))
|
_babase.pushcall(partial(result_cb, self, result2))
|
||||||
|
|
||||||
assert _babase.app.plus is not None
|
assert _babase.app.plus is not None
|
||||||
_babase.app.plus.cloud.send_message_cb(
|
_babase.app.plus.cloud.send_message_cb(
|
||||||
@ -293,10 +294,9 @@ class LoginAdapter:
|
|||||||
as needed. The provided completion_cb should then be called with
|
as needed. The provided completion_cb should then be called with
|
||||||
either a token or None if sign in failed or was cancelled.
|
either a token or None if sign in failed or was cancelled.
|
||||||
"""
|
"""
|
||||||
from babase._general import Call
|
|
||||||
|
|
||||||
# Default implementation simply fails immediately.
|
# Default implementation simply fails immediately.
|
||||||
_babase.pushcall(Call(completion_cb, None))
|
_babase.pushcall(partial(completion_cb, None))
|
||||||
|
|
||||||
def _update_implicit_login_state(self) -> None:
|
def _update_implicit_login_state(self) -> None:
|
||||||
# If we've received an implicit login state, schedule it to be
|
# If we've received an implicit login state, schedule it to be
|
||||||
@ -304,7 +304,6 @@ class LoginAdapter:
|
|||||||
# called so that account-client-v2 has had a chance to load
|
# called so that account-client-v2 has had a chance to load
|
||||||
# any existing state so it can properly respond to this.
|
# any existing state so it can properly respond to this.
|
||||||
if self._implicit_login_state_dirty and self._on_app_loading_called:
|
if self._implicit_login_state_dirty and self._on_app_loading_called:
|
||||||
from babase._general import Call
|
|
||||||
|
|
||||||
if DEBUG_LOG:
|
if DEBUG_LOG:
|
||||||
logging.debug(
|
logging.debug(
|
||||||
@ -315,7 +314,7 @@ class LoginAdapter:
|
|||||||
|
|
||||||
assert _babase.app.plus is not None
|
assert _babase.app.plus is not None
|
||||||
_babase.pushcall(
|
_babase.pushcall(
|
||||||
Call(
|
partial(
|
||||||
_babase.app.plus.accounts.on_implicit_login_state_changed,
|
_babase.app.plus.accounts.on_implicit_login_state_changed,
|
||||||
self.login_type,
|
self.login_type,
|
||||||
self._implicit_login_state,
|
self._implicit_login_state,
|
||||||
|
|||||||
@ -7,12 +7,12 @@ from __future__ import annotations
|
|||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
from threading import Thread
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from threading import Thread
|
||||||
|
from functools import partial
|
||||||
from typing import TYPE_CHECKING, TypeVar
|
from typing import TYPE_CHECKING, TypeVar
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
from efro.call import tpartial
|
|
||||||
import _babase
|
import _babase
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -116,7 +116,7 @@ class MetadataSubsystem:
|
|||||||
loading work happens, pass completion_cb_in_bg_thread=True.
|
loading work happens, pass completion_cb_in_bg_thread=True.
|
||||||
"""
|
"""
|
||||||
Thread(
|
Thread(
|
||||||
target=tpartial(
|
target=partial(
|
||||||
self._load_exported_classes,
|
self._load_exported_classes,
|
||||||
cls,
|
cls,
|
||||||
completion_cb,
|
completion_cb,
|
||||||
@ -145,7 +145,7 @@ class MetadataSubsystem:
|
|||||||
except Exception:
|
except Exception:
|
||||||
logging.exception('Error loading exported classes.')
|
logging.exception('Error loading exported classes.')
|
||||||
|
|
||||||
completion_call = tpartial(completion_cb, classes)
|
completion_call = partial(completion_cb, classes)
|
||||||
if completion_cb_in_bg_thread:
|
if completion_cb_in_bg_thread:
|
||||||
completion_call()
|
completion_call()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -9,9 +9,9 @@ import sys
|
|||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
from functools import partial
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from efro.call import tpartial
|
|
||||||
from efro.error import CleanError
|
from efro.error import CleanError
|
||||||
import _babase
|
import _babase
|
||||||
import bacommon.cloud
|
import bacommon.cloud
|
||||||
@ -118,7 +118,7 @@ class WorkspaceSubsystem:
|
|||||||
state.iteration += 1
|
state.iteration += 1
|
||||||
|
|
||||||
_babase.pushcall(
|
_babase.pushcall(
|
||||||
tpartial(
|
partial(
|
||||||
self._successmsg,
|
self._successmsg,
|
||||||
Lstr(
|
Lstr(
|
||||||
resource='activatedText',
|
resource='activatedText',
|
||||||
@ -130,7 +130,7 @@ class WorkspaceSubsystem:
|
|||||||
|
|
||||||
except _SkipSyncError:
|
except _SkipSyncError:
|
||||||
_babase.pushcall(
|
_babase.pushcall(
|
||||||
tpartial(
|
partial(
|
||||||
self._errmsg,
|
self._errmsg,
|
||||||
Lstr(
|
Lstr(
|
||||||
resource='workspaceSyncReuseText',
|
resource='workspaceSyncReuseText',
|
||||||
@ -145,7 +145,7 @@ class WorkspaceSubsystem:
|
|||||||
# be in wonky state.
|
# be in wonky state.
|
||||||
set_path = False
|
set_path = False
|
||||||
_babase.pushcall(
|
_babase.pushcall(
|
||||||
tpartial(self._errmsg, Lstr(value=str(exc))),
|
partial(self._errmsg, Lstr(value=str(exc))),
|
||||||
from_other_thread=True,
|
from_other_thread=True,
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
@ -153,7 +153,7 @@ class WorkspaceSubsystem:
|
|||||||
set_path = False
|
set_path = False
|
||||||
logging.exception("Error syncing workspace '%s'.", workspacename)
|
logging.exception("Error syncing workspace '%s'.", workspacename)
|
||||||
_babase.pushcall(
|
_babase.pushcall(
|
||||||
tpartial(
|
partial(
|
||||||
self._errmsg,
|
self._errmsg,
|
||||||
Lstr(
|
Lstr(
|
||||||
resource='workspaceSyncErrorText',
|
resource='workspaceSyncErrorText',
|
||||||
|
|||||||
@ -52,7 +52,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
# Build number and version of the ballistica binary we expect to be
|
# Build number and version of the ballistica binary we expect to be
|
||||||
# using.
|
# using.
|
||||||
TARGET_BALLISTICA_BUILD = 21911
|
TARGET_BALLISTICA_BUILD = 21919
|
||||||
TARGET_BALLISTICA_VERSION = '1.7.36'
|
TARGET_BALLISTICA_VERSION = '1.7.36'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -100,6 +100,15 @@ class CloudSubsystem(babase.AppSubsystem):
|
|||||||
],
|
],
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def send_message_cb(
|
||||||
|
self,
|
||||||
|
msg: bacommon.cloud.StoreQueryMessage,
|
||||||
|
on_response: Callable[
|
||||||
|
[bacommon.cloud.StoreQueryResponse | Exception], None
|
||||||
|
],
|
||||||
|
) -> None: ...
|
||||||
|
|
||||||
def send_message_cb(
|
def send_message_cb(
|
||||||
self,
|
self,
|
||||||
msg: Message,
|
msg: Message,
|
||||||
@ -194,6 +203,10 @@ def cloud_console_exec(code: str) -> None:
|
|||||||
except Exception:
|
except Exception:
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
# Note to self: Seems like we should just use
|
||||||
|
# logging.exception() here. Except currently that winds up
|
||||||
|
# triggering our cloud logging stuff so we'd probably want a
|
||||||
|
# specific logger or whatnot to avoid that.
|
||||||
apptime = babase.apptime()
|
apptime = babase.apptime()
|
||||||
print(f'Exec error at time {apptime:.2f}.', file=sys.stderr)
|
print(f'Exec error at time {apptime:.2f}.', file=sys.stderr)
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|||||||
@ -254,6 +254,11 @@ class PlusSubsystem(AppSubsystem):
|
|||||||
"""(internal)"""
|
"""(internal)"""
|
||||||
return _baplus.tournament_query(callback, args)
|
return _baplus.tournament_query(callback, args)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def supports_purchases() -> bool:
|
||||||
|
"""Does this platform support in-app-purchases?"""
|
||||||
|
return _baplus.supports_purchases()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def have_incentivized_ad() -> bool:
|
def have_incentivized_ad() -> bool:
|
||||||
"""Is an incentivized ad available?"""
|
"""Is an incentivized ad available?"""
|
||||||
|
|||||||
@ -119,10 +119,10 @@ class ConfigNumberEdit:
|
|||||||
|
|
||||||
self.nametext = bui.textwidget(
|
self.nametext = bui.textwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
position=position,
|
position=(position[0], position[1] + 12.0),
|
||||||
size=(100, 30),
|
size=(0, 0),
|
||||||
text=displayname,
|
text=displayname,
|
||||||
# maxwidth=160 + xoffset,
|
maxwidth=150 + xoffset,
|
||||||
color=(0.8, 0.8, 0.8, 1.0),
|
color=(0.8, 0.8, 0.8, 1.0),
|
||||||
h_align='left',
|
h_align='left',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
@ -130,8 +130,8 @@ class ConfigNumberEdit:
|
|||||||
)
|
)
|
||||||
self.valuetext = bui.textwidget(
|
self.valuetext = bui.textwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
position=(position[0] + 146 + xoffset, position[1]),
|
position=(position[0] + 216 + xoffset, position[1] + 12.0),
|
||||||
size=(60, 28),
|
size=(0, 0),
|
||||||
editable=False,
|
editable=False,
|
||||||
color=(0.3, 1.0, 0.3, 1.0),
|
color=(0.3, 1.0, 0.3, 1.0),
|
||||||
h_align='right',
|
h_align='right',
|
||||||
|
|||||||
@ -28,8 +28,10 @@ def wait_for_connectivity(
|
|||||||
assert plus is not None
|
assert plus is not None
|
||||||
|
|
||||||
# Quick-out: if we're already connected, don't bother with the UI.
|
# Quick-out: if we're already connected, don't bother with the UI.
|
||||||
|
# We do, however, push this call instead of calling it immediately
|
||||||
|
# so as to be consistent with the waiting path.
|
||||||
if plus.cloud.connected:
|
if plus.cloud.connected:
|
||||||
on_connected()
|
bui.pushcall(on_connected)
|
||||||
return
|
return
|
||||||
|
|
||||||
WaitForConnectivityWindow(on_connected=on_connected, on_cancel=on_cancel)
|
WaitForConnectivityWindow(on_connected=on_connected, on_cancel=on_cancel)
|
||||||
|
|||||||
@ -214,7 +214,7 @@ class ContinuesWindow(bui.Window):
|
|||||||
self._on_cancel()
|
self._on_cancel()
|
||||||
|
|
||||||
def _on_continue_press(self) -> None:
|
def _on_continue_press(self) -> None:
|
||||||
from bauiv1lib import getcurrency
|
from bauiv1lib import gettickets
|
||||||
|
|
||||||
plus = bui.app.plus
|
plus = bui.app.plus
|
||||||
assert plus is not None
|
assert plus is not None
|
||||||
@ -238,7 +238,7 @@ class ContinuesWindow(bui.Window):
|
|||||||
self._counting_down = False
|
self._counting_down = False
|
||||||
bui.textwidget(edit=self._counter_text, text='')
|
bui.textwidget(edit=self._counter_text, text='')
|
||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
getcurrency.show_get_tickets_prompt()
|
gettickets.show_get_tickets_prompt()
|
||||||
return
|
return
|
||||||
if not self._transitioning_out:
|
if not self._transitioning_out:
|
||||||
bui.getsound('swish').play()
|
bui.getsound('swish').play()
|
||||||
|
|||||||
@ -290,6 +290,7 @@ class TournamentButton:
|
|||||||
text='-',
|
text='-',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
maxwidth=170,
|
maxwidth=170,
|
||||||
|
glow_type='uniform',
|
||||||
scale=1.4,
|
scale=1.4,
|
||||||
color=value_color,
|
color=value_color,
|
||||||
flatness=1.0,
|
flatness=1.0,
|
||||||
|
|||||||
@ -20,7 +20,7 @@ from bacommon.net import (
|
|||||||
PrivatePartyConnectResult,
|
PrivatePartyConnectResult,
|
||||||
)
|
)
|
||||||
from bauiv1lib.gather import GatherTab
|
from bauiv1lib.gather import GatherTab
|
||||||
from bauiv1lib.getcurrency import GetCurrencyWindow, show_get_tickets_prompt
|
from bauiv1lib.gettickets import GetTicketsWindow, show_get_tickets_prompt
|
||||||
import bascenev1 as bs
|
import bascenev1 as bs
|
||||||
import bauiv1 as bui
|
import bauiv1 as bui
|
||||||
|
|
||||||
@ -487,7 +487,7 @@ class PrivateGatherTab(GatherTab):
|
|||||||
|
|
||||||
# Bring up get-tickets window and then kill ourself (we're on the
|
# Bring up get-tickets window and then kill ourself (we're on the
|
||||||
# overlay layer so we'd show up above it).
|
# overlay layer so we'd show up above it).
|
||||||
GetCurrencyWindow(modal=True, origin_widget=self._get_tickets_button)
|
GetTicketsWindow(modal=True, origin_widget=self._get_tickets_button)
|
||||||
|
|
||||||
def _build_host_tab(self) -> None:
|
def _build_host_tab(self) -> None:
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
|
|||||||
@ -14,8 +14,8 @@ if TYPE_CHECKING:
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
class GetCurrencyWindow(bui.Window):
|
class GetTicketsWindow(bui.Window):
|
||||||
"""Window for purchasing/acquiring currency."""
|
"""Window for purchasing/acquiring classic tickets."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -97,14 +97,42 @@ class GetCurrencyWindow(bui.Window):
|
|||||||
|
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
position=(self._width * 0.5, self._height - 55),
|
position=(self._width * 0.5 - 15, self._height - 47),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
color=bui.app.ui_v1.title_color,
|
color=bui.app.ui_v1.title_color,
|
||||||
scale=1.2,
|
scale=1.2,
|
||||||
h_align='center',
|
h_align='right',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
text=bui.Lstr(resource=self._r + '.titleText'),
|
text=bui.Lstr(resource=self._r + '.titleText'),
|
||||||
maxwidth=290,
|
# text='Testing really long text here blah blah',
|
||||||
|
maxwidth=260,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get Tokens button
|
||||||
|
bui.buttonwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(self._width * 0.5, self._height - 72),
|
||||||
|
color=(0.65, 0.5, 0.7),
|
||||||
|
textcolor=bui.app.ui_v1.title_color,
|
||||||
|
size=(190, 50),
|
||||||
|
autoselect=True,
|
||||||
|
label='Get Tokens',
|
||||||
|
on_activate_call=self._get_tokens_press,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 'New!' by tokens button
|
||||||
|
bui.textwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
text='New!',
|
||||||
|
position=(self._width * 0.5 + 25, self._height - 32),
|
||||||
|
size=(0, 0),
|
||||||
|
color=(1, 1, 0, 1.0),
|
||||||
|
rotate=22,
|
||||||
|
shadow=1.0,
|
||||||
|
maxwidth=150,
|
||||||
|
h_align='center',
|
||||||
|
v_align='center',
|
||||||
|
scale=0.7,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not modal:
|
if not modal:
|
||||||
@ -437,7 +465,7 @@ class GetCurrencyWindow(bui.Window):
|
|||||||
tc_y_offs = 0
|
tc_y_offs = 0
|
||||||
|
|
||||||
h = self._width - (185 + x_inset)
|
h = self._width - (185 + x_inset)
|
||||||
v = self._height - 95 + tc_y_offs
|
v = self._height - 105 + tc_y_offs
|
||||||
|
|
||||||
txt1 = (
|
txt1 = (
|
||||||
bui.Lstr(resource=self._r + '.youHaveText')
|
bui.Lstr(resource=self._r + '.youHaveText')
|
||||||
@ -733,6 +761,41 @@ class GetCurrencyWindow(bui.Window):
|
|||||||
else:
|
else:
|
||||||
plus.purchase(item)
|
plus.purchase(item)
|
||||||
|
|
||||||
|
def _get_tokens_press(self) -> None:
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
from bauiv1lib.gettokens import GetTokensWindow
|
||||||
|
|
||||||
|
# No-op if our underlying widget is dead or on its way out.
|
||||||
|
if not self._root_widget or self._root_widget.transitioning_out:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self._transitioning_out:
|
||||||
|
return
|
||||||
|
|
||||||
|
bui.containerwidget(edit=self._root_widget, transition='out_left')
|
||||||
|
|
||||||
|
# Note: Make sure we don't pass anything here that would
|
||||||
|
# capture 'self'. (a lambda would implicitly do this by capturing
|
||||||
|
# the stack frame).
|
||||||
|
restorecall = partial(
|
||||||
|
_restore_get_tickets_window,
|
||||||
|
self._modal,
|
||||||
|
self._from_modal_store,
|
||||||
|
self._store_back_location,
|
||||||
|
)
|
||||||
|
|
||||||
|
window = GetTokensWindow(
|
||||||
|
transition='in_right',
|
||||||
|
restore_previous_call=restorecall,
|
||||||
|
).get_root_widget()
|
||||||
|
if not self._modal and not self._from_modal_store:
|
||||||
|
assert bui.app.classic is not None
|
||||||
|
bui.app.ui_v1.set_main_menu_window(
|
||||||
|
window, from_window=self._root_widget
|
||||||
|
)
|
||||||
|
self._transitioning_out = True
|
||||||
|
|
||||||
def _back(self) -> None:
|
def _back(self) -> None:
|
||||||
from bauiv1lib.store import browser
|
from bauiv1lib.store import browser
|
||||||
|
|
||||||
@ -760,6 +823,27 @@ class GetCurrencyWindow(bui.Window):
|
|||||||
self._transitioning_out = True
|
self._transitioning_out = True
|
||||||
|
|
||||||
|
|
||||||
|
# A call we can bundle up and pass to windows we open; allows them to
|
||||||
|
# get back to us without having to explicitly know about us.
|
||||||
|
def _restore_get_tickets_window(
|
||||||
|
modal: bool,
|
||||||
|
from_modal_store: bool,
|
||||||
|
store_back_location: str | None,
|
||||||
|
from_window: bui.Widget,
|
||||||
|
) -> None:
|
||||||
|
restored = GetTicketsWindow(
|
||||||
|
transition='in_left',
|
||||||
|
modal=modal,
|
||||||
|
from_modal_store=from_modal_store,
|
||||||
|
store_back_location=store_back_location,
|
||||||
|
)
|
||||||
|
if not modal and not from_modal_store:
|
||||||
|
assert bui.app.classic is not None
|
||||||
|
bui.app.ui_v1.set_main_menu_window(
|
||||||
|
restored.get_root_widget(), from_window=from_window
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def show_get_tickets_prompt() -> None:
|
def show_get_tickets_prompt() -> None:
|
||||||
"""Show a 'not enough tickets' prompt with an option to purchase more.
|
"""Show a 'not enough tickets' prompt with an option to purchase more.
|
||||||
|
|
||||||
@ -769,6 +853,7 @@ def show_get_tickets_prompt() -> None:
|
|||||||
from bauiv1lib.confirm import ConfirmWindow
|
from bauiv1lib.confirm import ConfirmWindow
|
||||||
|
|
||||||
assert bui.app.classic is not None
|
assert bui.app.classic is not None
|
||||||
|
|
||||||
if bui.app.classic.allow_ticket_purchases:
|
if bui.app.classic.allow_ticket_purchases:
|
||||||
ConfirmWindow(
|
ConfirmWindow(
|
||||||
bui.Lstr(
|
bui.Lstr(
|
||||||
@ -777,7 +862,7 @@ def show_get_tickets_prompt() -> None:
|
|||||||
'You don\'t have enough tickets for this!',
|
'You don\'t have enough tickets for this!',
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
lambda: GetCurrencyWindow(modal=True),
|
lambda: GetTicketsWindow(modal=True),
|
||||||
ok_text=bui.Lstr(resource='getTicketsWindow.titleText'),
|
ok_text=bui.Lstr(resource='getTicketsWindow.titleText'),
|
||||||
width=460,
|
width=460,
|
||||||
height=130,
|
height=130,
|
||||||
618
src/assets/ba_data/python/bauiv1lib/gettokens.py
Normal file
618
src/assets/ba_data/python/bauiv1lib/gettokens.py
Normal file
@ -0,0 +1,618 @@
|
|||||||
|
# Released under the MIT License. See LICENSE for details.
|
||||||
|
#
|
||||||
|
"""UI functionality for purchasing/acquiring currency."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from enum import Enum
|
||||||
|
from functools import partial
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import TYPE_CHECKING, assert_never
|
||||||
|
|
||||||
|
import bacommon.cloud
|
||||||
|
|
||||||
|
import bauiv1 as bui
|
||||||
|
from bauiv1lib.connectivity import wait_for_connectivity
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from typing import Any, Callable
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class _ButtonDef:
|
||||||
|
itemid: str
|
||||||
|
width: float
|
||||||
|
color: tuple[float, float, float]
|
||||||
|
imgdefs: list[_ImgDef]
|
||||||
|
txtdefs: list[_TxtDef]
|
||||||
|
prepad: float = 0.0
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class _ImgDef:
|
||||||
|
tex: str
|
||||||
|
pos: tuple[float, float]
|
||||||
|
size: tuple[float, float]
|
||||||
|
color: tuple[float, float, float] = (1, 1, 1)
|
||||||
|
opacity: float = 1.0
|
||||||
|
draw_controller_mult: float | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class TextContents(Enum):
|
||||||
|
"""Some type of text to show."""
|
||||||
|
|
||||||
|
PRICE = 'price'
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class _TxtDef:
|
||||||
|
text: str | TextContents
|
||||||
|
pos: tuple[float, float]
|
||||||
|
maxwidth: float | None
|
||||||
|
scale: float = 1.0
|
||||||
|
color: tuple[float, float, float] = (1, 1, 1)
|
||||||
|
rotate: float | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class GetTokensWindow(bui.Window):
|
||||||
|
"""Window for purchasing/acquiring classic tickets."""
|
||||||
|
|
||||||
|
def __del__(self) -> None:
|
||||||
|
print('~GetTokensWindow()')
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
transition: str = 'in_right',
|
||||||
|
origin_widget: bui.Widget | None = None,
|
||||||
|
restore_previous_call: Callable[[bui.Widget], None] | None = None,
|
||||||
|
):
|
||||||
|
# pylint: disable=too-many-locals
|
||||||
|
|
||||||
|
bwidthstd = 170
|
||||||
|
bwidthwide = 300
|
||||||
|
ycolor = (0, 0, 0.3)
|
||||||
|
pcolor = (0, 0, 0.3)
|
||||||
|
pos1 = 65
|
||||||
|
pos2 = 34
|
||||||
|
titlescale = 0.9
|
||||||
|
pricescale = 0.65
|
||||||
|
bcapcol1 = (0.25, 0.13, 0.02)
|
||||||
|
self._buttondefs: list[_ButtonDef] = [
|
||||||
|
_ButtonDef(
|
||||||
|
itemid='tokens1',
|
||||||
|
width=bwidthstd,
|
||||||
|
color=ycolor,
|
||||||
|
imgdefs=[
|
||||||
|
_ImgDef(
|
||||||
|
'tokens1',
|
||||||
|
pos=(-3, 85),
|
||||||
|
size=(172, 172),
|
||||||
|
opacity=1.0,
|
||||||
|
draw_controller_mult=0.5,
|
||||||
|
),
|
||||||
|
_ImgDef(
|
||||||
|
'windowBottomCap',
|
||||||
|
pos=(1.5, 4),
|
||||||
|
size=(bwidthstd * 0.960, 100),
|
||||||
|
color=bcapcol1,
|
||||||
|
opacity=1.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
txtdefs=[
|
||||||
|
_TxtDef(
|
||||||
|
'50 Tokens',
|
||||||
|
pos=(bwidthstd * 0.5, pos1),
|
||||||
|
color=(1.1, 1.05, 1.0),
|
||||||
|
scale=titlescale,
|
||||||
|
maxwidth=bwidthstd * 0.9,
|
||||||
|
),
|
||||||
|
_TxtDef(
|
||||||
|
TextContents.PRICE,
|
||||||
|
pos=(bwidthstd * 0.5, pos2),
|
||||||
|
color=(1.1, 1.05, 1.0),
|
||||||
|
scale=pricescale,
|
||||||
|
maxwidth=bwidthstd * 0.9,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
_ButtonDef(
|
||||||
|
itemid='tokens2',
|
||||||
|
width=bwidthstd,
|
||||||
|
color=ycolor,
|
||||||
|
imgdefs=[
|
||||||
|
_ImgDef(
|
||||||
|
'tokens2',
|
||||||
|
pos=(-3, 85),
|
||||||
|
size=(172, 172),
|
||||||
|
opacity=1.0,
|
||||||
|
draw_controller_mult=0.5,
|
||||||
|
),
|
||||||
|
_ImgDef(
|
||||||
|
'windowBottomCap',
|
||||||
|
pos=(1.5, 4),
|
||||||
|
size=(bwidthstd * 0.960, 100),
|
||||||
|
color=bcapcol1,
|
||||||
|
opacity=1.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
txtdefs=[
|
||||||
|
_TxtDef(
|
||||||
|
'500 Tokens',
|
||||||
|
pos=(bwidthstd * 0.5, pos1),
|
||||||
|
color=(1.1, 1.05, 1.0),
|
||||||
|
scale=titlescale,
|
||||||
|
maxwidth=bwidthstd * 0.9,
|
||||||
|
),
|
||||||
|
_TxtDef(
|
||||||
|
TextContents.PRICE,
|
||||||
|
pos=(bwidthstd * 0.5, pos2),
|
||||||
|
color=(1.1, 1.05, 1.0),
|
||||||
|
scale=pricescale,
|
||||||
|
maxwidth=bwidthstd * 0.9,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
_ButtonDef(
|
||||||
|
itemid='tokens3',
|
||||||
|
width=bwidthstd,
|
||||||
|
color=ycolor,
|
||||||
|
imgdefs=[
|
||||||
|
_ImgDef(
|
||||||
|
'tokens3',
|
||||||
|
pos=(-3, 85),
|
||||||
|
size=(172, 172),
|
||||||
|
opacity=1.0,
|
||||||
|
draw_controller_mult=0.5,
|
||||||
|
),
|
||||||
|
_ImgDef(
|
||||||
|
'windowBottomCap',
|
||||||
|
pos=(1.5, 4),
|
||||||
|
size=(bwidthstd * 0.960, 100),
|
||||||
|
color=bcapcol1,
|
||||||
|
opacity=1.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
txtdefs=[
|
||||||
|
_TxtDef(
|
||||||
|
'1200 Tokens',
|
||||||
|
pos=(bwidthstd * 0.5, pos1),
|
||||||
|
color=(1.1, 1.05, 1.0),
|
||||||
|
scale=titlescale,
|
||||||
|
maxwidth=bwidthstd * 0.9,
|
||||||
|
),
|
||||||
|
_TxtDef(
|
||||||
|
TextContents.PRICE,
|
||||||
|
pos=(bwidthstd * 0.5, pos2),
|
||||||
|
color=(1.1, 1.05, 1.0),
|
||||||
|
scale=pricescale,
|
||||||
|
maxwidth=bwidthstd * 0.9,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
_ButtonDef(
|
||||||
|
itemid='tokens4',
|
||||||
|
width=bwidthstd,
|
||||||
|
color=ycolor,
|
||||||
|
imgdefs=[
|
||||||
|
_ImgDef(
|
||||||
|
'tokens4',
|
||||||
|
pos=(-3, 85),
|
||||||
|
size=(172, 172),
|
||||||
|
opacity=1.0,
|
||||||
|
draw_controller_mult=0.5,
|
||||||
|
),
|
||||||
|
_ImgDef(
|
||||||
|
'windowBottomCap',
|
||||||
|
pos=(1.5, 4),
|
||||||
|
size=(bwidthstd * 0.960, 100),
|
||||||
|
color=bcapcol1,
|
||||||
|
opacity=1.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
txtdefs=[
|
||||||
|
_TxtDef(
|
||||||
|
'2600 Tokens',
|
||||||
|
pos=(bwidthstd * 0.5, pos1),
|
||||||
|
color=(1.1, 1.05, 1.0),
|
||||||
|
scale=titlescale,
|
||||||
|
maxwidth=bwidthstd * 0.9,
|
||||||
|
),
|
||||||
|
_TxtDef(
|
||||||
|
TextContents.PRICE,
|
||||||
|
pos=(bwidthstd * 0.5, pos2),
|
||||||
|
color=(1.1, 1.05, 1.0),
|
||||||
|
scale=pricescale,
|
||||||
|
maxwidth=bwidthstd * 0.9,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
_ButtonDef(
|
||||||
|
itemid='gold_pass',
|
||||||
|
width=bwidthwide,
|
||||||
|
color=pcolor,
|
||||||
|
imgdefs=[
|
||||||
|
_ImgDef(
|
||||||
|
'goldPass',
|
||||||
|
pos=(-7, 102),
|
||||||
|
size=(312, 156),
|
||||||
|
draw_controller_mult=0.3,
|
||||||
|
),
|
||||||
|
_ImgDef(
|
||||||
|
'windowBottomCap',
|
||||||
|
pos=(8, 4),
|
||||||
|
size=(bwidthwide * 0.923, 116),
|
||||||
|
color=(0.25, 0.12, 0.15),
|
||||||
|
opacity=1.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
txtdefs=[
|
||||||
|
_TxtDef(
|
||||||
|
'Gold Pass',
|
||||||
|
pos=(bwidthwide * 0.5, pos1 + 27),
|
||||||
|
color=(1.1, 1.05, 1.0),
|
||||||
|
scale=titlescale,
|
||||||
|
maxwidth=bwidthwide * 0.8,
|
||||||
|
),
|
||||||
|
_TxtDef(
|
||||||
|
'Infinite tokens.',
|
||||||
|
pos=(bwidthwide * 0.5, pos1 + 6),
|
||||||
|
color=(1.1, 1.05, 1.0),
|
||||||
|
scale=0.4,
|
||||||
|
maxwidth=bwidthwide * 0.8,
|
||||||
|
),
|
||||||
|
_TxtDef(
|
||||||
|
'No ads.',
|
||||||
|
pos=(bwidthwide * 0.5, pos1 + 6 - 13 * 1),
|
||||||
|
color=(1.1, 1.05, 1.0),
|
||||||
|
scale=0.4,
|
||||||
|
maxwidth=bwidthwide * 0.8,
|
||||||
|
),
|
||||||
|
_TxtDef(
|
||||||
|
'Forever.',
|
||||||
|
pos=(bwidthwide * 0.5, pos1 + 6 - 13 * 2),
|
||||||
|
color=(1.1, 1.05, 1.0),
|
||||||
|
scale=0.4,
|
||||||
|
maxwidth=bwidthwide * 0.8,
|
||||||
|
),
|
||||||
|
_TxtDef(
|
||||||
|
TextContents.PRICE,
|
||||||
|
pos=(bwidthwide * 0.5, pos2 - 9),
|
||||||
|
color=(1.1, 1.05, 1.0),
|
||||||
|
scale=pricescale,
|
||||||
|
maxwidth=bwidthwide * 0.8,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
prepad=-8,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
self._transitioning_out = False
|
||||||
|
self._restore_previous_call = restore_previous_call
|
||||||
|
self._textcolor = (0.92, 0.92, 2.0)
|
||||||
|
|
||||||
|
# If they provided an origin-widget, scale up from that.
|
||||||
|
scale_origin: tuple[float, float] | None
|
||||||
|
if origin_widget is not None:
|
||||||
|
self._transition_out = 'out_scale'
|
||||||
|
scale_origin = origin_widget.get_screen_space_center()
|
||||||
|
transition = 'in_scale'
|
||||||
|
else:
|
||||||
|
self._transition_out = 'out_right'
|
||||||
|
scale_origin = None
|
||||||
|
|
||||||
|
uiscale = bui.app.ui_v1.uiscale
|
||||||
|
self._width = 1000.0 if uiscale is bui.UIScale.SMALL else 800.0
|
||||||
|
self._x_inset = 100.0 if uiscale is bui.UIScale.SMALL else 0.0
|
||||||
|
self._height = 480.0
|
||||||
|
|
||||||
|
self._r = 'getTokensWindow'
|
||||||
|
|
||||||
|
top_extra = 20 if uiscale is bui.UIScale.SMALL else 0
|
||||||
|
|
||||||
|
super().__init__(
|
||||||
|
root_widget=bui.containerwidget(
|
||||||
|
size=(self._width, self._height + top_extra),
|
||||||
|
transition=transition,
|
||||||
|
scale_origin_stack_offset=scale_origin,
|
||||||
|
color=(0.3, 0.23, 0.36),
|
||||||
|
scale=(
|
||||||
|
1.63
|
||||||
|
if uiscale is bui.UIScale.SMALL
|
||||||
|
else 1.2 if uiscale is bui.UIScale.MEDIUM else 1.0
|
||||||
|
),
|
||||||
|
stack_offset=(
|
||||||
|
(0, -3) if uiscale is bui.UIScale.SMALL else (0, 0)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self._back_button = btn = bui.buttonwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(45 + self._x_inset, self._height - 80),
|
||||||
|
size=(
|
||||||
|
(140, 60) if self._restore_previous_call is None else (60, 60)
|
||||||
|
),
|
||||||
|
scale=1.0,
|
||||||
|
autoselect=True,
|
||||||
|
label=(
|
||||||
|
bui.Lstr(resource='doneText')
|
||||||
|
if self._restore_previous_call is None
|
||||||
|
else bui.charstr(bui.SpecialChar.BACK)
|
||||||
|
),
|
||||||
|
button_type=(
|
||||||
|
'regular'
|
||||||
|
if self._restore_previous_call is None
|
||||||
|
else 'backSmall'
|
||||||
|
),
|
||||||
|
on_activate_call=self._back,
|
||||||
|
)
|
||||||
|
|
||||||
|
bui.containerwidget(edit=self._root_widget, cancel_button=btn)
|
||||||
|
|
||||||
|
bui.textwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(self._width * 0.5, self._height - 47),
|
||||||
|
size=(0, 0),
|
||||||
|
color=self._textcolor,
|
||||||
|
flatness=0.0,
|
||||||
|
shadow=1.0,
|
||||||
|
scale=1.2,
|
||||||
|
h_align='center',
|
||||||
|
v_align='center',
|
||||||
|
text='Get Tokens',
|
||||||
|
maxwidth=260,
|
||||||
|
)
|
||||||
|
|
||||||
|
self._status_text = bui.textwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(self._width * 0.5, self._height * 0.5),
|
||||||
|
h_align='center',
|
||||||
|
v_align='center',
|
||||||
|
color=(0.6, 0.6, 0.6),
|
||||||
|
scale=0.75,
|
||||||
|
text='Loading...',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get all textures used by our buttons preloading so hopefully
|
||||||
|
# they'll be in place by the time we show them.
|
||||||
|
for bdef in self._buttondefs:
|
||||||
|
for bimg in bdef.imgdefs:
|
||||||
|
bui.gettexture(bimg.tex)
|
||||||
|
|
||||||
|
# Wait for a master-server connection if need be. Otherwise we
|
||||||
|
# could error if called at the wrong time even with an internet
|
||||||
|
# connection, which is unintuitive.
|
||||||
|
wait_for_connectivity(
|
||||||
|
on_connected=bui.WeakCall(self._on_have_connectivity),
|
||||||
|
on_cancel=bui.WeakCall(self._back),
|
||||||
|
)
|
||||||
|
|
||||||
|
def _on_have_connectivity(self) -> None:
|
||||||
|
plus = bui.app.plus
|
||||||
|
assert plus is not None
|
||||||
|
|
||||||
|
# Sanity check; we need to be signed in. (we should not be
|
||||||
|
# allowed to get here if we aren't, but it could happen for
|
||||||
|
# fluke-ish reasons.)
|
||||||
|
if plus.accounts.primary is None:
|
||||||
|
bui.screenmessage(
|
||||||
|
bui.Lstr(resource='notSignedInErrorText'), color=(1, 0, 0)
|
||||||
|
)
|
||||||
|
bui.getsound('error').play()
|
||||||
|
self._back()
|
||||||
|
return
|
||||||
|
|
||||||
|
with plus.accounts.primary:
|
||||||
|
plus.cloud.send_message_cb(
|
||||||
|
bacommon.cloud.StoreQueryMessage(),
|
||||||
|
on_response=bui.WeakCall(self._on_store_query_response),
|
||||||
|
)
|
||||||
|
|
||||||
|
def _on_load_error(self) -> None:
|
||||||
|
bui.textwidget(
|
||||||
|
edit=self._status_text,
|
||||||
|
text=bui.Lstr(resource='internal.unavailableNoConnectionText'),
|
||||||
|
color=(1, 0, 0),
|
||||||
|
)
|
||||||
|
|
||||||
|
def _on_store_query_response(
|
||||||
|
self, response: bacommon.cloud.StoreQueryResponse | Exception
|
||||||
|
) -> None:
|
||||||
|
# pylint: disable=too-many-locals
|
||||||
|
|
||||||
|
plus = bui.app.plus
|
||||||
|
|
||||||
|
# If our message failed, just error and back out.
|
||||||
|
if isinstance(response, Exception):
|
||||||
|
logging.info('Store query failed.', exc_info=response)
|
||||||
|
|
||||||
|
bui.screenmessage(bui.Lstr(resource='errorText'), color=(1, 0, 0))
|
||||||
|
bui.getsound('error').play()
|
||||||
|
self._back()
|
||||||
|
return
|
||||||
|
|
||||||
|
bui.textwidget(edit=self._status_text, text='')
|
||||||
|
|
||||||
|
xinset = 40
|
||||||
|
|
||||||
|
scrollwidth = self._width - 2 * (self._x_inset + xinset)
|
||||||
|
scrollheight = 280
|
||||||
|
buttonpadding = -5
|
||||||
|
|
||||||
|
yoffs = 5
|
||||||
|
|
||||||
|
# We currently don't handle the zero-button case.
|
||||||
|
assert self._buttondefs
|
||||||
|
|
||||||
|
total_button_width = sum(
|
||||||
|
b.width + b.prepad for b in self._buttondefs
|
||||||
|
) + buttonpadding * (len(self._buttondefs) - 1)
|
||||||
|
|
||||||
|
h_scroll = bui.hscrollwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
size=(scrollwidth, scrollheight),
|
||||||
|
position=(self._x_inset + xinset, 45),
|
||||||
|
claims_left_right=True,
|
||||||
|
highlight=False,
|
||||||
|
border_opacity=0.25,
|
||||||
|
)
|
||||||
|
subcontainer = bui.containerwidget(
|
||||||
|
parent=h_scroll,
|
||||||
|
background=False,
|
||||||
|
size=(max(total_button_width, scrollwidth), scrollheight),
|
||||||
|
)
|
||||||
|
tinfobtn = bui.buttonwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
autoselect=True,
|
||||||
|
label='Learn More',
|
||||||
|
position=(self._width * 0.5 - 75, self._height * 0.703),
|
||||||
|
size=(180, 43),
|
||||||
|
scale=0.8,
|
||||||
|
color=(0.4, 0.25, 0.5),
|
||||||
|
textcolor=self._textcolor,
|
||||||
|
on_activate_call=partial(
|
||||||
|
self._on_learn_more_press, response.token_info_url
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
x = 0.0
|
||||||
|
bwidgets: list[bui.Widget] = []
|
||||||
|
for i, buttondef in enumerate(self._buttondefs):
|
||||||
|
|
||||||
|
price = None if plus is None else plus.get_price(buttondef.itemid)
|
||||||
|
|
||||||
|
x += buttondef.prepad
|
||||||
|
tdelay = 0.3 - i / len(self._buttondefs) * 0.25
|
||||||
|
btn = bui.buttonwidget(
|
||||||
|
autoselect=True,
|
||||||
|
label='',
|
||||||
|
color=buttondef.color,
|
||||||
|
transition_delay=tdelay,
|
||||||
|
up_widget=tinfobtn,
|
||||||
|
parent=subcontainer,
|
||||||
|
size=(buttondef.width, 275),
|
||||||
|
position=(x, -10 + yoffs),
|
||||||
|
button_type='square',
|
||||||
|
on_activate_call=partial(
|
||||||
|
self._purchase_press, buttondef.itemid
|
||||||
|
),
|
||||||
|
)
|
||||||
|
bwidgets.append(btn)
|
||||||
|
for imgdef in buttondef.imgdefs:
|
||||||
|
_img = bui.imagewidget(
|
||||||
|
parent=subcontainer,
|
||||||
|
size=imgdef.size,
|
||||||
|
position=(x + imgdef.pos[0], imgdef.pos[1] + yoffs),
|
||||||
|
draw_controller=btn,
|
||||||
|
draw_controller_mult=imgdef.draw_controller_mult,
|
||||||
|
color=imgdef.color,
|
||||||
|
texture=bui.gettexture(imgdef.tex),
|
||||||
|
transition_delay=tdelay,
|
||||||
|
opacity=imgdef.opacity,
|
||||||
|
)
|
||||||
|
for txtdef in buttondef.txtdefs:
|
||||||
|
txt: bui.Lstr | str
|
||||||
|
if isinstance(txtdef.text, TextContents):
|
||||||
|
if txtdef.text is TextContents.PRICE:
|
||||||
|
tcolor = (
|
||||||
|
(1, 1, 1, 0.5) if price is None else txtdef.color
|
||||||
|
)
|
||||||
|
txt = (
|
||||||
|
bui.Lstr(resource='unavailableText')
|
||||||
|
if price is None
|
||||||
|
else price
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Make sure we cover all cases.
|
||||||
|
assert_never(txtdef.text)
|
||||||
|
else:
|
||||||
|
tcolor = txtdef.color
|
||||||
|
txt = txtdef.text
|
||||||
|
_txt = bui.textwidget(
|
||||||
|
parent=subcontainer,
|
||||||
|
text=txt,
|
||||||
|
position=(x + txtdef.pos[0], txtdef.pos[1] + yoffs),
|
||||||
|
size=(0, 0),
|
||||||
|
scale=txtdef.scale,
|
||||||
|
h_align='center',
|
||||||
|
v_align='center',
|
||||||
|
draw_controller=btn,
|
||||||
|
color=tcolor,
|
||||||
|
transition_delay=tdelay,
|
||||||
|
flatness=0.0,
|
||||||
|
shadow=1.0,
|
||||||
|
rotate=txtdef.rotate,
|
||||||
|
maxwidth=txtdef.maxwidth,
|
||||||
|
)
|
||||||
|
x += buttondef.width + buttonpadding
|
||||||
|
bui.containerwidget(edit=subcontainer, visible_child=bwidgets[0])
|
||||||
|
|
||||||
|
_tinfotxt = bui.textwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(self._width * 0.5, self._height * 0.812),
|
||||||
|
color=self._textcolor,
|
||||||
|
shadow=1.0,
|
||||||
|
scale=0.7,
|
||||||
|
size=(0, 0),
|
||||||
|
h_align='center',
|
||||||
|
v_align='center',
|
||||||
|
text='BombSquad\'s shiny new currency.',
|
||||||
|
)
|
||||||
|
_tnumtxt = bui.textwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(self._width - self._x_inset - 120.0, self._height - 48),
|
||||||
|
color=(2.0, 0.7, 0.0),
|
||||||
|
shadow=1.0,
|
||||||
|
flatness=0.0,
|
||||||
|
size=(0, 0),
|
||||||
|
h_align='left',
|
||||||
|
v_align='center',
|
||||||
|
text=str(response.tokens),
|
||||||
|
)
|
||||||
|
_tlabeltxt = bui.textwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(self._width - self._x_inset - 123.0, self._height - 48),
|
||||||
|
size=(0, 0),
|
||||||
|
h_align='right',
|
||||||
|
v_align='center',
|
||||||
|
text=bui.charstr(bui.SpecialChar.TOKEN),
|
||||||
|
)
|
||||||
|
|
||||||
|
def _purchase_press(self, itemid: str) -> None:
|
||||||
|
plus = bui.app.plus
|
||||||
|
|
||||||
|
price = None if plus is None else plus.get_price(itemid)
|
||||||
|
|
||||||
|
if price is None:
|
||||||
|
if plus is not None and plus.supports_purchases():
|
||||||
|
# Looks like internet is down or something temporary.
|
||||||
|
errmsg = 'This purchase is not available.'
|
||||||
|
else:
|
||||||
|
# Looks like purchases will never work here.
|
||||||
|
errmsg = (
|
||||||
|
'Sorry, purchases are not available on this build.\n'
|
||||||
|
'As a fallback, sign in to this account on another'
|
||||||
|
' platform and make purchases from there.'
|
||||||
|
)
|
||||||
|
|
||||||
|
bui.screenmessage(errmsg, color=(1, 0.5, 0))
|
||||||
|
bui.getsound('error').play()
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f'WOULD PURCHASE {itemid}')
|
||||||
|
|
||||||
|
def _back(self) -> None:
|
||||||
|
|
||||||
|
# No-op if our underlying widget is dead or on its way out.
|
||||||
|
if not self._root_widget or self._root_widget.transitioning_out:
|
||||||
|
return
|
||||||
|
|
||||||
|
bui.containerwidget(
|
||||||
|
edit=self._root_widget, transition=self._transition_out
|
||||||
|
)
|
||||||
|
if self._restore_previous_call is not None:
|
||||||
|
self._restore_previous_call(self._root_widget)
|
||||||
|
|
||||||
|
def _on_learn_more_press(self, url: str) -> None:
|
||||||
|
bui.open_url(url)
|
||||||
@ -39,7 +39,8 @@ class MainMenuWindow(bui.Window):
|
|||||||
bui.set_analytics_screen('Main Menu')
|
bui.set_analytics_screen('Main Menu')
|
||||||
self._show_remote_app_info_on_first_launch()
|
self._show_remote_app_info_on_first_launch()
|
||||||
|
|
||||||
# Make a vanilla container; we'll modify it to our needs in refresh.
|
# Make a vanilla container; we'll modify it to our needs in
|
||||||
|
# refresh.
|
||||||
super().__init__(
|
super().__init__(
|
||||||
root_widget=bui.containerwidget(
|
root_widget=bui.containerwidget(
|
||||||
transition=transition,
|
transition=transition,
|
||||||
@ -91,7 +92,6 @@ class MainMenuWindow(bui.Window):
|
|||||||
0.27, bui.WeakCall(self._check_refresh), repeat=True
|
0.27, bui.WeakCall(self._check_refresh), repeat=True
|
||||||
)
|
)
|
||||||
|
|
||||||
# noinspection PyUnresolvedReferences
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _preload_modules() -> None:
|
def _preload_modules() -> None:
|
||||||
"""Preload modules we use; avoids hitches (called in bg thread)."""
|
"""Preload modules we use; avoids hitches (called in bg thread)."""
|
||||||
@ -162,8 +162,9 @@ class MainMenuWindow(bui.Window):
|
|||||||
if now < self._next_refresh_allow_time:
|
if now < self._next_refresh_allow_time:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Don't refresh for the first few seconds the game is up so we don't
|
# Don't refresh for the first few seconds the game is up so we
|
||||||
# interrupt the transition in.
|
# don't interrupt the transition in.
|
||||||
|
|
||||||
# bui.app.main_menu_window_refresh_check_count += 1
|
# bui.app.main_menu_window_refresh_check_count += 1
|
||||||
# if bui.app.main_menu_window_refresh_check_count < 4:
|
# if bui.app.main_menu_window_refresh_check_count < 4:
|
||||||
# return
|
# return
|
||||||
@ -413,8 +414,8 @@ class MainMenuWindow(bui.Window):
|
|||||||
else:
|
else:
|
||||||
self._quit_button = None
|
self._quit_button = None
|
||||||
|
|
||||||
# If we're not in-game, have no quit button, and this is android,
|
# If we're not in-game, have no quit button, and this is
|
||||||
# we want back presses to quit our activity.
|
# android, we want back presses to quit our activity.
|
||||||
if (
|
if (
|
||||||
not self._in_game
|
not self._in_game
|
||||||
and not self._have_quit_button
|
and not self._have_quit_button
|
||||||
@ -428,9 +429,9 @@ class MainMenuWindow(bui.Window):
|
|||||||
edit=self._root_widget, on_cancel_call=_do_quit
|
edit=self._root_widget, on_cancel_call=_do_quit
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add speed-up/slow-down buttons for replays.
|
# Add speed-up/slow-down buttons for replays. Ideally this
|
||||||
# (ideally this should be part of a fading-out playback bar like most
|
# should be part of a fading-out playback bar like most media
|
||||||
# media players but this works for now).
|
# players but this works for now.
|
||||||
if bs.is_in_replay():
|
if bs.is_in_replay():
|
||||||
b_size = 50.0
|
b_size = 50.0
|
||||||
b_buffer_1 = 50.0
|
b_buffer_1 = 50.0
|
||||||
@ -605,13 +606,13 @@ class MainMenuWindow(bui.Window):
|
|||||||
def _set_allow_time() -> None:
|
def _set_allow_time() -> None:
|
||||||
self._next_refresh_allow_time = bui.apptime() + 2.5
|
self._next_refresh_allow_time = bui.apptime() + 2.5
|
||||||
|
|
||||||
# Slight hack: widget transitions currently only progress when
|
# Slight hack: widget transitions currently only progress
|
||||||
# frames are being drawn, but this tends to get called before
|
# when frames are being drawn, but this tends to get called
|
||||||
# frame drawing even starts, meaning we don't know exactly how
|
# before frame drawing even starts, meaning we don't know
|
||||||
# long we should wait before refreshing to avoid interrupting
|
# exactly how long we should wait before refreshing to avoid
|
||||||
# the transition. To make things a bit better, let's do a
|
# interrupting the transition. To make things a bit better,
|
||||||
# redundant set of the time in a deferred call which hopefully
|
# let's do a redundant set of the time in a deferred call
|
||||||
# happens closer to actual frame draw times.
|
# which hopefully happens closer to actual frame draw times.
|
||||||
_set_allow_time()
|
_set_allow_time()
|
||||||
bui.pushcall(_set_allow_time)
|
bui.pushcall(_set_allow_time)
|
||||||
|
|
||||||
|
|||||||
@ -564,7 +564,7 @@ class PartyQueueWindow(bui.Window):
|
|||||||
def on_boost_press(self) -> None:
|
def on_boost_press(self) -> None:
|
||||||
"""Boost was pressed."""
|
"""Boost was pressed."""
|
||||||
from bauiv1lib import account
|
from bauiv1lib import account
|
||||||
from bauiv1lib import getcurrency
|
from bauiv1lib import gettickets
|
||||||
|
|
||||||
plus = bui.app.plus
|
plus = bui.app.plus
|
||||||
assert plus is not None
|
assert plus is not None
|
||||||
@ -575,7 +575,7 @@ class PartyQueueWindow(bui.Window):
|
|||||||
|
|
||||||
if plus.get_v1_account_ticket_count() < self._boost_tickets:
|
if plus.get_v1_account_ticket_count() < self._boost_tickets:
|
||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
getcurrency.show_get_tickets_prompt()
|
gettickets.show_get_tickets_prompt()
|
||||||
return
|
return
|
||||||
|
|
||||||
bui.getsound('laserReverse').play()
|
bui.getsound('laserReverse').play()
|
||||||
|
|||||||
@ -545,8 +545,6 @@ class EditProfileWindow(bui.Window):
|
|||||||
for n in [
|
for n in [
|
||||||
bui.SpecialChar.GOOGLE_PLAY_GAMES_LOGO,
|
bui.SpecialChar.GOOGLE_PLAY_GAMES_LOGO,
|
||||||
bui.SpecialChar.GAME_CENTER_LOGO,
|
bui.SpecialChar.GAME_CENTER_LOGO,
|
||||||
bui.SpecialChar.GAME_CIRCLE_LOGO,
|
|
||||||
bui.SpecialChar.OUYA_LOGO,
|
|
||||||
bui.SpecialChar.LOCAL_ACCOUNT,
|
bui.SpecialChar.LOCAL_ACCOUNT,
|
||||||
bui.SpecialChar.OCULUS_LOGO,
|
bui.SpecialChar.OCULUS_LOGO,
|
||||||
bui.SpecialChar.NVIDIA_LOGO,
|
bui.SpecialChar.NVIDIA_LOGO,
|
||||||
|
|||||||
@ -210,7 +210,7 @@ class ProfileUpgradeWindow(bui.Window):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _on_upgrade_press(self) -> None:
|
def _on_upgrade_press(self) -> None:
|
||||||
from bauiv1lib import getcurrency
|
from bauiv1lib import gettickets
|
||||||
|
|
||||||
if self._status is None:
|
if self._status is None:
|
||||||
plus = bui.app.plus
|
plus = bui.app.plus
|
||||||
@ -220,7 +220,7 @@ class ProfileUpgradeWindow(bui.Window):
|
|||||||
tickets = plus.get_v1_account_ticket_count()
|
tickets = plus.get_v1_account_ticket_count()
|
||||||
if tickets < self._cost:
|
if tickets < self._cost:
|
||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
getcurrency.show_get_tickets_prompt()
|
gettickets.show_get_tickets_prompt()
|
||||||
return
|
return
|
||||||
bui.screenmessage(
|
bui.screenmessage(
|
||||||
bui.Lstr(resource='purchasingText'), color=(0, 1, 0)
|
bui.Lstr(resource='purchasingText'), color=(0, 1, 0)
|
||||||
|
|||||||
@ -162,7 +162,7 @@ class PurchaseWindow(bui.Window):
|
|||||||
bui.containerwidget(edit=self._root_widget, transition='out_left')
|
bui.containerwidget(edit=self._root_widget, transition='out_left')
|
||||||
|
|
||||||
def _purchase(self) -> None:
|
def _purchase(self) -> None:
|
||||||
from bauiv1lib import getcurrency
|
from bauiv1lib import gettickets
|
||||||
|
|
||||||
plus = bui.app.plus
|
plus = bui.app.plus
|
||||||
assert plus is not None
|
assert plus is not None
|
||||||
@ -176,7 +176,7 @@ class PurchaseWindow(bui.Window):
|
|||||||
except Exception:
|
except Exception:
|
||||||
ticket_count = None
|
ticket_count = None
|
||||||
if ticket_count is not None and ticket_count < self._price:
|
if ticket_count is not None and ticket_count < self._price:
|
||||||
getcurrency.show_get_tickets_prompt()
|
gettickets.show_get_tickets_prompt()
|
||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@ -440,7 +440,7 @@ class SpecialOfferWindow(bui.Window):
|
|||||||
|
|
||||||
def _on_get_more_tickets_press(self) -> None:
|
def _on_get_more_tickets_press(self) -> None:
|
||||||
from bauiv1lib import account
|
from bauiv1lib import account
|
||||||
from bauiv1lib import getcurrency
|
from bauiv1lib import gettickets
|
||||||
|
|
||||||
plus = bui.app.plus
|
plus = bui.app.plus
|
||||||
assert plus is not None
|
assert plus is not None
|
||||||
@ -448,10 +448,10 @@ class SpecialOfferWindow(bui.Window):
|
|||||||
if plus.get_v1_account_state() != 'signed_in':
|
if plus.get_v1_account_state() != 'signed_in':
|
||||||
account.show_sign_in_prompt()
|
account.show_sign_in_prompt()
|
||||||
return
|
return
|
||||||
getcurrency.GetCurrencyWindow(modal=True).get_root_widget()
|
gettickets.GetTicketsWindow(modal=True).get_root_widget()
|
||||||
|
|
||||||
def _purchase(self) -> None:
|
def _purchase(self) -> None:
|
||||||
from bauiv1lib import getcurrency
|
from bauiv1lib import gettickets
|
||||||
from bauiv1lib import confirm
|
from bauiv1lib import confirm
|
||||||
|
|
||||||
plus = bui.app.plus
|
plus = bui.app.plus
|
||||||
@ -474,7 +474,7 @@ class SpecialOfferWindow(bui.Window):
|
|||||||
except Exception:
|
except Exception:
|
||||||
ticket_count = None
|
ticket_count = None
|
||||||
if ticket_count is not None and ticket_count < self._offer['price']:
|
if ticket_count is not None and ticket_count < self._offer['price']:
|
||||||
getcurrency.show_get_tickets_prompt()
|
gettickets.show_get_tickets_prompt()
|
||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@ -574,7 +574,7 @@ class StoreBrowserWindow(bui.Window):
|
|||||||
"""Attempt to purchase the provided item."""
|
"""Attempt to purchase the provided item."""
|
||||||
from bauiv1lib import account
|
from bauiv1lib import account
|
||||||
from bauiv1lib.confirm import ConfirmWindow
|
from bauiv1lib.confirm import ConfirmWindow
|
||||||
from bauiv1lib import getcurrency
|
from bauiv1lib import gettickets
|
||||||
|
|
||||||
assert bui.app.classic is not None
|
assert bui.app.classic is not None
|
||||||
store = bui.app.classic.store
|
store = bui.app.classic.store
|
||||||
@ -620,7 +620,7 @@ class StoreBrowserWindow(bui.Window):
|
|||||||
our_tickets = plus.get_v1_account_ticket_count()
|
our_tickets = plus.get_v1_account_ticket_count()
|
||||||
if price is not None and our_tickets < price:
|
if price is not None and our_tickets < price:
|
||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
getcurrency.show_get_tickets_prompt()
|
gettickets.show_get_tickets_prompt()
|
||||||
else:
|
else:
|
||||||
|
|
||||||
def do_it() -> None:
|
def do_it() -> None:
|
||||||
@ -1320,7 +1320,7 @@ class StoreBrowserWindow(bui.Window):
|
|||||||
def _on_get_more_tickets_press(self) -> None:
|
def _on_get_more_tickets_press(self) -> None:
|
||||||
# pylint: disable=cyclic-import
|
# pylint: disable=cyclic-import
|
||||||
from bauiv1lib.account import show_sign_in_prompt
|
from bauiv1lib.account import show_sign_in_prompt
|
||||||
from bauiv1lib.getcurrency import GetCurrencyWindow
|
from bauiv1lib.gettickets import GetTicketsWindow
|
||||||
|
|
||||||
# no-op if our underlying widget is dead or on its way out.
|
# no-op if our underlying widget is dead or on its way out.
|
||||||
if not self._root_widget or self._root_widget.transitioning_out:
|
if not self._root_widget or self._root_widget.transitioning_out:
|
||||||
@ -1334,7 +1334,7 @@ class StoreBrowserWindow(bui.Window):
|
|||||||
return
|
return
|
||||||
self._save_state()
|
self._save_state()
|
||||||
bui.containerwidget(edit=self._root_widget, transition='out_left')
|
bui.containerwidget(edit=self._root_widget, transition='out_left')
|
||||||
window = GetCurrencyWindow(
|
window = GetTicketsWindow(
|
||||||
from_modal_store=self._modal,
|
from_modal_store=self._modal,
|
||||||
store_back_location=self._back_location,
|
store_back_location=self._back_location,
|
||||||
).get_root_widget()
|
).get_root_widget()
|
||||||
@ -1391,7 +1391,7 @@ def _check_merch_availability_in_bg_thread() -> None:
|
|||||||
|
|
||||||
def _store_in_logic_thread() -> None:
|
def _store_in_logic_thread() -> None:
|
||||||
cfg = bui.app.config
|
cfg = bui.app.config
|
||||||
current: str | None = cfg.get(MERCH_LINK_KEY)
|
current = cfg.get(MERCH_LINK_KEY)
|
||||||
if not isinstance(current, str | None):
|
if not isinstance(current, str | None):
|
||||||
current = None
|
current = None
|
||||||
if current != response.url:
|
if current != response.url:
|
||||||
@ -1414,6 +1414,9 @@ def _check_merch_availability_in_bg_thread() -> None:
|
|||||||
# Slight hack; start checking merch availability in the bg (but only if
|
# Slight hack; start checking merch availability in the bg (but only if
|
||||||
# it looks like we've been imported for use in a running app; don't want
|
# it looks like we've been imported for use in a running app; don't want
|
||||||
# to do this during docs generation/etc.)
|
# to do this during docs generation/etc.)
|
||||||
|
|
||||||
|
# TODO: Should wire this up explicitly to app bootstrapping; not good to
|
||||||
|
# be kicking off work at module import time.
|
||||||
if (
|
if (
|
||||||
os.environ.get('BA_RUNNING_WITH_DUMMY_MODULES') != '1'
|
os.environ.get('BA_RUNNING_WITH_DUMMY_MODULES') != '1'
|
||||||
and bui.app.state is not bui.app.State.NOT_STARTED
|
and bui.app.state is not bui.app.State.NOT_STARTED
|
||||||
|
|||||||
@ -632,7 +632,7 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
bui.apptimer(0 if practice else 1.25, self._transition_out)
|
bui.apptimer(0 if practice else 1.25, self._transition_out)
|
||||||
|
|
||||||
def _on_pay_with_tickets_press(self) -> None:
|
def _on_pay_with_tickets_press(self) -> None:
|
||||||
from bauiv1lib import getcurrency
|
from bauiv1lib import gettickets
|
||||||
|
|
||||||
plus = bui.app.plus
|
plus = bui.app.plus
|
||||||
assert plus is not None
|
assert plus is not None
|
||||||
@ -675,7 +675,7 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
ticket_count = None
|
ticket_count = None
|
||||||
ticket_cost = self._purchase_price
|
ticket_cost = self._purchase_price
|
||||||
if ticket_count is not None and ticket_count < ticket_cost:
|
if ticket_count is not None and ticket_count < ticket_cost:
|
||||||
getcurrency.show_get_tickets_prompt()
|
gettickets.show_get_tickets_prompt()
|
||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
self._transition_out()
|
self._transition_out()
|
||||||
return
|
return
|
||||||
@ -781,7 +781,7 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
self._launch()
|
self._launch()
|
||||||
|
|
||||||
def _on_get_tickets_press(self) -> None:
|
def _on_get_tickets_press(self) -> None:
|
||||||
from bauiv1lib import getcurrency
|
from bauiv1lib import gettickets
|
||||||
|
|
||||||
# If we're already entering, ignore presses.
|
# If we're already entering, ignore presses.
|
||||||
if self._entering:
|
if self._entering:
|
||||||
@ -789,7 +789,7 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
|
|
||||||
# Bring up get-tickets window and then kill ourself (we're on the
|
# Bring up get-tickets window and then kill ourself (we're on the
|
||||||
# overlay layer so we'd show up above it).
|
# overlay layer so we'd show up above it).
|
||||||
getcurrency.GetCurrencyWindow(
|
gettickets.GetTicketsWindow(
|
||||||
modal=True, origin_widget=self._get_tickets_button
|
modal=True, origin_widget=self._get_tickets_button
|
||||||
)
|
)
|
||||||
self._transition_out()
|
self._transition_out()
|
||||||
|
|||||||
@ -148,5 +148,6 @@ void AppAdapter::NativeReviewRequest() {
|
|||||||
void AppAdapter::DoNativeReviewRequest() { FatalError("Fixme unimplemented."); }
|
void AppAdapter::DoNativeReviewRequest() { FatalError("Fixme unimplemented."); }
|
||||||
|
|
||||||
auto AppAdapter::ShouldSilenceAudioForInactive() -> bool const { return false; }
|
auto AppAdapter::ShouldSilenceAudioForInactive() -> bool const { return false; }
|
||||||
|
auto AppAdapter::SupportsPurchases() -> bool { return false; }
|
||||||
|
|
||||||
} // namespace ballistica::base
|
} // namespace ballistica::base
|
||||||
|
|||||||
@ -222,6 +222,8 @@ class AppAdapter {
|
|||||||
virtual void DoClipboardSetText(const std::string& text);
|
virtual void DoClipboardSetText(const std::string& text);
|
||||||
virtual auto DoClipboardGetText() -> std::string;
|
virtual auto DoClipboardGetText() -> std::string;
|
||||||
|
|
||||||
|
virtual auto SupportsPurchases() -> bool;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~AppAdapter();
|
virtual ~AppAdapter();
|
||||||
|
|
||||||
|
|||||||
@ -408,6 +408,7 @@ void AppAdapterSDL::HandleSDLEvent_(const SDL_Event& event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SDL_KEYDOWN: {
|
case SDL_KEYDOWN: {
|
||||||
|
// printf("KEYDOWN %d\n", static_cast<int>(event.key.keysym.sym));
|
||||||
if (!event.key.repeat) {
|
if (!event.key.repeat) {
|
||||||
g_base->input->PushKeyPressEvent(event.key.keysym);
|
g_base->input->PushKeyPressEvent(event.key.keysym);
|
||||||
}
|
}
|
||||||
@ -415,6 +416,7 @@ void AppAdapterSDL::HandleSDLEvent_(const SDL_Event& event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SDL_KEYUP: {
|
case SDL_KEYUP: {
|
||||||
|
// printf("KEYUP %d\n", static_cast<int>(event.key.keysym.sym));
|
||||||
g_base->input->PushKeyReleaseEvent(event.key.keysym);
|
g_base->input->PushKeyReleaseEvent(event.key.keysym);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1259,7 +1259,7 @@ void Assets::InitSpecialChars() {
|
|||||||
special_char_strings_[SpecialChar::kOuyaButtonU] = "\xee\x80\x9A";
|
special_char_strings_[SpecialChar::kOuyaButtonU] = "\xee\x80\x9A";
|
||||||
special_char_strings_[SpecialChar::kOuyaButtonY] = "\xee\x80\x9B";
|
special_char_strings_[SpecialChar::kOuyaButtonY] = "\xee\x80\x9B";
|
||||||
special_char_strings_[SpecialChar::kOuyaButtonA] = "\xee\x80\x9C";
|
special_char_strings_[SpecialChar::kOuyaButtonA] = "\xee\x80\x9C";
|
||||||
special_char_strings_[SpecialChar::kOuyaLogo] = "\xee\x80\x9D";
|
special_char_strings_[SpecialChar::kToken] = "\xee\x80\x9D";
|
||||||
special_char_strings_[SpecialChar::kLogo] = "\xee\x80\x9E";
|
special_char_strings_[SpecialChar::kLogo] = "\xee\x80\x9E";
|
||||||
special_char_strings_[SpecialChar::kTicket] = "\xee\x80\x9F";
|
special_char_strings_[SpecialChar::kTicket] = "\xee\x80\x9F";
|
||||||
special_char_strings_[SpecialChar::kGooglePlayGamesLogo] = "\xee\x80\xA0";
|
special_char_strings_[SpecialChar::kGooglePlayGamesLogo] = "\xee\x80\xA0";
|
||||||
|
|||||||
@ -54,8 +54,8 @@ TextGraphics::TextGraphics() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Shrink account logos and move them up a bit.
|
// Shrink account logos and move them up a bit.
|
||||||
if (index == 29 || index == 32 || index == 33 || index == 38
|
if (index == 32 || index == 33 || index == 38 || index == 40
|
||||||
|| index == 40 || index == 48 || index == 49) {
|
|| index == 48 || index == 49) {
|
||||||
g.pen_offset_y += 0.4f;
|
g.pen_offset_y += 0.4f;
|
||||||
extra_advance += 0.08f;
|
extra_advance += 0.08f;
|
||||||
g.x_size *= 0.55f;
|
g.x_size *= 0.55f;
|
||||||
|
|||||||
@ -347,6 +347,14 @@ int BasePlatform::SmartGetC_(FILE* stream) {
|
|||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Need to catch these error cases and bail, oherwise we'll spin
|
||||||
|
// forever getting the same thing. (Noticed this happening on Mac build
|
||||||
|
// where we get an immediate POLLNVAL if there's no terminal attached
|
||||||
|
// to stdin.
|
||||||
|
if (fds[0].revents & (POLLERR | POLLNVAL | POLLHUP)) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
if (fds[0].revents & POLLIN) {
|
if (fds[0].revents & POLLIN) {
|
||||||
// stdin is ready for reading.
|
// stdin is ready for reading.
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include "ballistica/shared/foundation/event_loop.h"
|
#include "ballistica/shared/foundation/event_loop.h"
|
||||||
|
|
||||||
namespace ballistica::base {
|
namespace ballistica::base {
|
||||||
|
|
||||||
Repeater::Repeater(seconds_t initial_delay, seconds_t repeat_delay,
|
Repeater::Repeater(seconds_t initial_delay, seconds_t repeat_delay,
|
||||||
Runnable* runnable)
|
Runnable* runnable)
|
||||||
: initial_delay_(initial_delay),
|
: initial_delay_(initial_delay),
|
||||||
@ -14,26 +15,29 @@ Repeater::Repeater(seconds_t initial_delay, seconds_t repeat_delay,
|
|||||||
assert(g_base->InLogicThread());
|
assert(g_base->InLogicThread());
|
||||||
assert(initial_delay >= 0.0);
|
assert(initial_delay >= 0.0);
|
||||||
assert(repeat_delay >= 0.0);
|
assert(repeat_delay >= 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Repeater::PostInit_() {
|
||||||
|
assert(g_base->InLogicThread());
|
||||||
|
|
||||||
// Let's go ahead and run our initial time in a deferred call;
|
// Let's go ahead and run our initial time in a deferred call;
|
||||||
// this is generally safer than running in the middle of whatever UI
|
// this is generally safer than running in the middle of whatever UI
|
||||||
// code set this up.
|
// code called us. Note that we use a strong ref here - if we use a
|
||||||
|
// weak ref then it is possible for our initial key press to get lost
|
||||||
|
// if the repeater gets canceled due to other keypresses/etc before
|
||||||
|
// the initial call runs.
|
||||||
|
|
||||||
|
auto strong_this = Object::Ref<Repeater>(this);
|
||||||
|
g_base->logic->event_loop()->PushCall(
|
||||||
|
[strong_this] { strong_this->runnable_->RunAndLogErrors(); });
|
||||||
|
|
||||||
auto weak_this = Object::WeakRef<Repeater>(this);
|
auto weak_this = Object::WeakRef<Repeater>(this);
|
||||||
g_base->logic->event_loop()->PushCall([weak_this] {
|
timer_ = DisplayTimer::New(weak_this->initial_delay_, false, [weak_this] {
|
||||||
if (weak_this.Exists()) {
|
|
||||||
weak_this->runnable_->RunAndLogErrors();
|
|
||||||
if (!weak_this.Exists()) {
|
|
||||||
// Runnable might have killed us.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Kick off our initial delay timer (generally the longer one).
|
|
||||||
weak_this->timer_ =
|
|
||||||
DisplayTimer::New(weak_this->initial_delay_, false, [weak_this] {
|
|
||||||
// Timer should not have fired if we died.
|
// Timer should not have fired if we died.
|
||||||
assert(weak_this.Exists());
|
assert(weak_this.Exists());
|
||||||
weak_this->runnable_->RunAndLogErrors();
|
weak_this->runnable_->RunAndLogErrors();
|
||||||
if (!weak_this.Exists()) {
|
if (!weak_this.Exists()) {
|
||||||
// Runnable might have killed us.
|
// Runnable we just ran might have killed us.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Kick off our repeat timer (generally the short one).
|
// Kick off our repeat timer (generally the short one).
|
||||||
@ -47,8 +51,6 @@ Repeater::Repeater(seconds_t initial_delay, seconds_t repeat_delay,
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater::~Repeater() { assert(g_base->InLogicThread()); }
|
Repeater::~Repeater() { assert(g_base->InLogicThread()); }
|
||||||
|
|
||||||
|
|||||||
@ -14,17 +14,22 @@ namespace ballistica::base {
|
|||||||
/// Uses display-time so emphasizes visual smoothness over accuracy.
|
/// Uses display-time so emphasizes visual smoothness over accuracy.
|
||||||
class Repeater : public Object {
|
class Repeater : public Object {
|
||||||
public:
|
public:
|
||||||
Repeater(seconds_t initial_delay, seconds_t repeat_delay, Runnable* runnable);
|
|
||||||
~Repeater();
|
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
static auto New(seconds_t initial_delay, seconds_t repeat_delay,
|
static auto New(seconds_t initial_delay, seconds_t repeat_delay,
|
||||||
const F& lambda) {
|
const F& lambda) {
|
||||||
return Object::New<Repeater>(initial_delay, repeat_delay,
|
auto&& rep = Object::New<Repeater>(initial_delay, repeat_delay,
|
||||||
NewLambdaRunnable<F>(lambda).Get());
|
NewLambdaRunnable<F>(lambda).Get());
|
||||||
|
// We need to run this bit *after* constructing our obj since it creates
|
||||||
|
// a strong ref.
|
||||||
|
rep->PostInit_();
|
||||||
|
return Object::Ref<Repeater>(rep);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class Object; // Allows our constructor to be private.
|
||||||
|
Repeater(seconds_t initial_delay, seconds_t repeat_delay, Runnable* runnable);
|
||||||
|
~Repeater();
|
||||||
|
void PostInit_();
|
||||||
seconds_t initial_delay_;
|
seconds_t initial_delay_;
|
||||||
seconds_t repeat_delay_;
|
seconds_t repeat_delay_;
|
||||||
Object::Ref<DisplayTimer> timer_;
|
Object::Ref<DisplayTimer> timer_;
|
||||||
|
|||||||
@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
|
|||||||
namespace ballistica {
|
namespace ballistica {
|
||||||
|
|
||||||
// These are set automatically via script; don't modify them here.
|
// These are set automatically via script; don't modify them here.
|
||||||
const int kEngineBuildNumber = 21911;
|
const int kEngineBuildNumber = 21919;
|
||||||
const char* kEngineVersion = "1.7.36";
|
const char* kEngineVersion = "1.7.36";
|
||||||
const int kEngineApiVersion = 8;
|
const int kEngineApiVersion = 8;
|
||||||
|
|
||||||
|
|||||||
@ -188,7 +188,7 @@ enum class SpecialChar : uint8_t {
|
|||||||
kOuyaButtonU,
|
kOuyaButtonU,
|
||||||
kOuyaButtonY,
|
kOuyaButtonY,
|
||||||
kOuyaButtonA,
|
kOuyaButtonA,
|
||||||
kOuyaLogo,
|
kToken,
|
||||||
kLogo,
|
kLogo,
|
||||||
kTicket,
|
kTicket,
|
||||||
kGooglePlayGamesLogo,
|
kGooglePlayGamesLogo,
|
||||||
|
|||||||
@ -704,6 +704,7 @@ static auto PyImageWidget(PyObject* self, PyObject* args,
|
|||||||
PyObject* tilt_scale_obj = Py_None;
|
PyObject* tilt_scale_obj = Py_None;
|
||||||
PyObject* mask_texture_obj = Py_None;
|
PyObject* mask_texture_obj = Py_None;
|
||||||
PyObject* radial_amount_obj = Py_None;
|
PyObject* radial_amount_obj = Py_None;
|
||||||
|
PyObject* draw_controller_mult_obj = Py_None;
|
||||||
|
|
||||||
static const char* kwlist[] = {"edit",
|
static const char* kwlist[] = {"edit",
|
||||||
"parent",
|
"parent",
|
||||||
@ -723,14 +724,16 @@ static auto PyImageWidget(PyObject* self, PyObject* args,
|
|||||||
"tilt_scale",
|
"tilt_scale",
|
||||||
"mask_texture",
|
"mask_texture",
|
||||||
"radial_amount",
|
"radial_amount",
|
||||||
|
"draw_controller_mult",
|
||||||
nullptr};
|
nullptr};
|
||||||
if (!PyArg_ParseTupleAndKeywords(
|
if (!PyArg_ParseTupleAndKeywords(
|
||||||
args, keywds, "|OOOOOOOOOOOOOOOOOO", const_cast<char**>(kwlist),
|
args, keywds, "|OOOOOOOOOOOOOOOOOOO", const_cast<char**>(kwlist),
|
||||||
&edit_obj, &parent_obj, &size_obj, &pos_obj, &color_obj, &texture_obj,
|
&edit_obj, &parent_obj, &size_obj, &pos_obj, &color_obj, &texture_obj,
|
||||||
&opacity_obj, &mesh_transparent_obj, &mesh_opaque_obj,
|
&opacity_obj, &mesh_transparent_obj, &mesh_opaque_obj,
|
||||||
&has_alpha_channel_obj, &tint_texture_obj, &tint_color_obj,
|
&has_alpha_channel_obj, &tint_texture_obj, &tint_color_obj,
|
||||||
&transition_delay_obj, &draw_controller_obj, &tint2_color_obj,
|
&transition_delay_obj, &draw_controller_obj, &tint2_color_obj,
|
||||||
&tilt_scale_obj, &mask_texture_obj, &radial_amount_obj))
|
&tilt_scale_obj, &mask_texture_obj, &radial_amount_obj,
|
||||||
|
&draw_controller_mult_obj))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (!g_base->CurrentContext().IsEmpty()) {
|
if (!g_base->CurrentContext().IsEmpty()) {
|
||||||
@ -831,6 +834,9 @@ static auto PyImageWidget(PyObject* self, PyObject* args,
|
|||||||
if (tilt_scale_obj != Py_None) {
|
if (tilt_scale_obj != Py_None) {
|
||||||
b->set_tilt_scale(Python::GetPyFloat(tilt_scale_obj));
|
b->set_tilt_scale(Python::GetPyFloat(tilt_scale_obj));
|
||||||
}
|
}
|
||||||
|
if (draw_controller_mult_obj != Py_None) {
|
||||||
|
b->set_draw_controller_mult(Python::GetPyFloat(draw_controller_mult_obj));
|
||||||
|
}
|
||||||
|
|
||||||
// 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) {
|
if (edit_obj == Py_None) {
|
||||||
@ -866,7 +872,8 @@ static PyMethodDef PyImageWidgetDef = {
|
|||||||
" tint2_color: Sequence[float] | None = None,\n"
|
" tint2_color: Sequence[float] | None = None,\n"
|
||||||
" tilt_scale: float | None = None,\n"
|
" tilt_scale: float | None = None,\n"
|
||||||
" mask_texture: bauiv1.Texture | None = None,\n"
|
" mask_texture: bauiv1.Texture | None = None,\n"
|
||||||
" radial_amount: float | None = None)\n"
|
" radial_amount: float | None = None,\n"
|
||||||
|
" draw_controller_mult: float | None = None)\n"
|
||||||
" -> bauiv1.Widget\n"
|
" -> bauiv1.Widget\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Create or edit an image widget.\n"
|
"Create or edit an image widget.\n"
|
||||||
@ -1816,7 +1823,7 @@ static auto PyHScrollWidget(PyObject* self, PyObject* args,
|
|||||||
if (c.size() != 3) {
|
if (c.size() != 3) {
|
||||||
throw Exception("Expected 3 floats for color.", PyExcType::kValue);
|
throw Exception("Expected 3 floats for color.", PyExcType::kValue);
|
||||||
}
|
}
|
||||||
widget->setColor(c[0], c[1], c[2]);
|
widget->SetColor(c[0], c[1], c[2]);
|
||||||
}
|
}
|
||||||
if (capture_arrows_obj != Py_None) {
|
if (capture_arrows_obj != Py_None) {
|
||||||
widget->set_capture_arrows(Python::GetPyBool(capture_arrows_obj));
|
widget->set_capture_arrows(Python::GetPyBool(capture_arrows_obj));
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "ballistica/base/graphics/component/empty_component.h"
|
#include "ballistica/base/graphics/component/empty_component.h"
|
||||||
#include "ballistica/base/graphics/component/simple_component.h"
|
#include "ballistica/base/graphics/component/simple_component.h"
|
||||||
#include "ballistica/base/support/app_timer.h"
|
#include "ballistica/base/support/app_timer.h"
|
||||||
|
#include "ballistica/shared/foundation/inline.h"
|
||||||
|
|
||||||
namespace ballistica::ui_v1 {
|
namespace ballistica::ui_v1 {
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ void HScrollWidget::OnTouchDelayTimerExpired() {
|
|||||||
touch_delay_timer_.Clear();
|
touch_delay_timer_.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HScrollWidget::ClampThumb(bool velocity_clamp, bool position_clamp) {
|
void HScrollWidget::ClampThumb_(bool velocity_clamp, bool position_clamp) {
|
||||||
BA_DEBUG_UI_READ_LOCK;
|
BA_DEBUG_UI_READ_LOCK;
|
||||||
bool is_scrolling = (touch_held_ || !has_momentum_);
|
bool is_scrolling = (touch_held_ || !has_momentum_);
|
||||||
float strong_force;
|
float strong_force;
|
||||||
@ -59,7 +60,7 @@ void HScrollWidget::ClampThumb(bool velocity_clamp, bool position_clamp) {
|
|||||||
|
|
||||||
if (velocity_clamp) {
|
if (velocity_clamp) {
|
||||||
if (child_offset_h_ < 0) {
|
if (child_offset_h_ < 0) {
|
||||||
// even in velocity case do some sane clamping
|
// Even in velocity case do some sane clamping.
|
||||||
float diff = child_offset_h_;
|
float diff = child_offset_h_;
|
||||||
inertia_scroll_rate_ +=
|
inertia_scroll_rate_ +=
|
||||||
diff * (is_scrolling ? strong_force : weak_force);
|
diff * (is_scrolling ? strong_force : weak_force);
|
||||||
@ -77,7 +78,7 @@ void HScrollWidget::ClampThumb(bool velocity_clamp, bool position_clamp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// hard clipping if we're dragging the scrollbar
|
// Hard clipping if we're dragging the scrollbar.
|
||||||
if (position_clamp) {
|
if (position_clamp) {
|
||||||
if (child_offset_h_smoothed_
|
if (child_offset_h_smoothed_
|
||||||
> child_w - (width() - 2 * (border_width_ + kHMargin))) {
|
> child_w - (width() - 2 * (border_width_ + kHMargin))) {
|
||||||
@ -111,17 +112,18 @@ auto HScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
if (i == widgets().end()) break;
|
if (i == widgets().end()) break;
|
||||||
float child_w = (**i).GetWidth();
|
float child_w = (**i).GetWidth();
|
||||||
|
|
||||||
// see where we'd have to scroll to get selection at left and right
|
// See where we'd have to scroll to get selection at left and right.
|
||||||
float child_offset_left =
|
float child_offset_left =
|
||||||
child_w - m.fval1 - (width() - 2 * (border_width_ + kHMargin));
|
child_w - m.fval1 - (width() - 2 * (border_width_ + kHMargin));
|
||||||
float child_offset_right = child_w - m.fval1 - m.fval3;
|
float child_offset_right = child_w - m.fval1 - m.fval3;
|
||||||
|
|
||||||
// if we're in the middle, dont do anything
|
// If we're in the middle, dont do anything.
|
||||||
if (child_offset_h_ > child_offset_left
|
if (child_offset_h_ > child_offset_left
|
||||||
&& child_offset_h_ < child_offset_right) {
|
&& child_offset_h_ < child_offset_right) {
|
||||||
} else {
|
} else {
|
||||||
float prev_child_offset = child_offset_h_;
|
float prev_child_offset = child_offset_h_;
|
||||||
// do whatever offset is less of a move
|
|
||||||
|
// Do whatever offset is less of a move.
|
||||||
if (std::abs(child_offset_left - child_offset_h_)
|
if (std::abs(child_offset_left - child_offset_h_)
|
||||||
< std::abs(child_offset_right - child_offset_h_)) {
|
< std::abs(child_offset_right - child_offset_h_)) {
|
||||||
child_offset_h_ = child_offset_left;
|
child_offset_h_ = child_offset_left;
|
||||||
@ -129,12 +131,13 @@ auto HScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
child_offset_h_ = child_offset_right;
|
child_offset_h_ = child_offset_right;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're moving left, stop at the end
|
// If we're moving left, stop at the end.
|
||||||
{
|
{
|
||||||
float max_val = child_w - (width() - 2 * (border_width_ + kHMargin));
|
float max_val = child_w - (width() - 2 * (border_width_ + kHMargin));
|
||||||
if (child_offset_h_ > max_val) child_offset_h_ = max_val;
|
if (child_offset_h_ > max_val) child_offset_h_ = max_val;
|
||||||
}
|
}
|
||||||
// if we're moving right, stop at the top
|
|
||||||
|
// If we're moving right, stop at the top.
|
||||||
{
|
{
|
||||||
if (child_offset_h_ < prev_child_offset) {
|
if (child_offset_h_ < prev_child_offset) {
|
||||||
if (child_offset_h_ < 0) child_offset_h_ = 0;
|
if (child_offset_h_ < 0) child_offset_h_ = 0;
|
||||||
@ -154,6 +157,7 @@ auto HScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case base::WidgetMessage::Type::kMouseMove: {
|
case base::WidgetMessage::Type::kMouseMove: {
|
||||||
|
last_mouse_move_time_ = g_base->logic->display_time();
|
||||||
float x = m.fval1;
|
float x = m.fval1;
|
||||||
float y = m.fval2;
|
float y = m.fval2;
|
||||||
bool claimed2 = (m.fval3 > 0.0f);
|
bool claimed2 = (m.fval3 > 0.0f);
|
||||||
@ -177,17 +181,17 @@ auto HScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
touch_x_ = x;
|
touch_x_ = x;
|
||||||
touch_y_ = y;
|
touch_y_ = y;
|
||||||
|
|
||||||
// if this is a new scroll-touch, see which direction the drag is
|
// If this is a new scroll-touch, see which direction the drag
|
||||||
// happening; if it's primarily vertical lets disown it so it can
|
// is happening; if it's primarily vertical lets disown it so it
|
||||||
// get handled by the scroll widget above us (presumably a vertical
|
// can get handled by the scroll widget above us (presumably a
|
||||||
// scroll widget)
|
// vertical scroll widget).
|
||||||
if (new_scroll_touch_) {
|
if (new_scroll_touch_) {
|
||||||
float x_diff = std::abs(touch_x_ - touch_start_x_);
|
float x_diff = std::abs(touch_x_ - touch_start_x_);
|
||||||
float y_diff = std::abs(touch_y_ - touch_start_y_);
|
float y_diff = std::abs(touch_y_ - touch_start_y_);
|
||||||
|
|
||||||
float dist = x_diff * x_diff + y_diff * y_diff;
|
float dist = x_diff * x_diff + y_diff * y_diff;
|
||||||
|
|
||||||
// if they're somehow equal, wait and look at the next one..
|
// If they're somehow equal, wait and look at the next one.
|
||||||
if (x_diff != y_diff && dist > 30.0f) {
|
if (x_diff != y_diff && dist > 30.0f) {
|
||||||
new_scroll_touch_ = false;
|
new_scroll_touch_ = false;
|
||||||
|
|
||||||
@ -200,8 +204,8 @@ auto HScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
|
|
||||||
// Handle generating delayed press/releases.
|
// Handle generating delayed press/releases.
|
||||||
if (static_cast<int>(m.type)) { // <- FIXME WHAT IS THIS FOR??
|
if (static_cast<int>(m.type)) { // <- FIXME WHAT IS THIS FOR??
|
||||||
// If we move more than a slight amount it means our touch isn't a
|
// If we move more than a slight amount it means our touch
|
||||||
// click.
|
// isn't a click.
|
||||||
if (!touch_is_scrolling_
|
if (!touch_is_scrolling_
|
||||||
&& ((std::abs(touch_x_ - touch_start_x_) > 10.0f)
|
&& ((std::abs(touch_x_ - touch_start_x_) > 10.0f)
|
||||||
|| (std::abs(touch_y_ - touch_start_y_) > 10.0f))) {
|
|| (std::abs(touch_y_ - touch_start_y_) > 10.0f))) {
|
||||||
@ -253,7 +257,7 @@ auto HScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
child_offset_h_ = thumb_click_start_child_offset_h_
|
child_offset_h_ = thumb_click_start_child_offset_h_
|
||||||
- rate * (x - thumb_click_start_h_);
|
- rate * (x - thumb_click_start_h_);
|
||||||
|
|
||||||
ClampThumb(false, true);
|
ClampThumb_(false, true);
|
||||||
|
|
||||||
MarkForUpdate();
|
MarkForUpdate();
|
||||||
}
|
}
|
||||||
@ -272,12 +276,12 @@ auto HScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
|
|
||||||
touch_held_ = false;
|
touch_held_ = false;
|
||||||
|
|
||||||
// If we moved at all, we mark it as claimed to keep
|
// If we moved at all, we mark it as claimed to keep sub-widgets
|
||||||
// sub-widgets from acting on it (since we used it for scrolling).
|
// from acting on it (since we used it for scrolling).
|
||||||
bool claimed2 = touch_is_scrolling_ || m_claimed;
|
bool claimed2 = touch_is_scrolling_ || m_claimed;
|
||||||
|
|
||||||
// If we're not claiming it and we haven't sent a mouse_down yet due
|
// If we're not claiming it and we haven't sent a mouse_down yet
|
||||||
// to our delay, send that first.
|
// due to our delay, send that first.
|
||||||
if (!claimed2 && !touch_down_sent_) {
|
if (!claimed2 && !touch_down_sent_) {
|
||||||
ContainerWidget::HandleMessage(base::WidgetMessage(
|
ContainerWidget::HandleMessage(base::WidgetMessage(
|
||||||
base::WidgetMessage::Type::kMouseDown, nullptr, m.fval1,
|
base::WidgetMessage::Type::kMouseDown, nullptr, m.fval1,
|
||||||
@ -294,9 +298,9 @@ auto HScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If coords are outside of our bounds, pass a mouse-up along for anyone
|
// If coords are outside of our bounds, pass a mouse-up along for
|
||||||
// tracking a drag, but mark it as claimed so it doesn't actually get
|
// anyone tracking a drag, but mark it as claimed so it doesn't
|
||||||
// acted on.
|
// actually get acted on.
|
||||||
float x = m.fval1;
|
float x = m.fval1;
|
||||||
float y = m.fval2;
|
float y = m.fval2;
|
||||||
if (!((y >= 0.0f) && (y < height()) && (x >= 0.0f) && (x < width()))) {
|
if (!((y >= 0.0f) && (y < height()) && (x >= 0.0f) && (x < width()))) {
|
||||||
@ -399,8 +403,8 @@ auto HScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
touch_down_x_ = x - child_offset_h_;
|
touch_down_x_ = x - child_offset_h_;
|
||||||
touch_is_scrolling_ = false;
|
touch_is_scrolling_ = false;
|
||||||
|
|
||||||
// If there's significant scrolling happening we never pass touches.
|
// If there's significant scrolling happening we never pass
|
||||||
// they're only used to scroll more/less.
|
// touches. they're only used to scroll more/less.
|
||||||
if (std::abs(inertia_scroll_rate_) > 0.05f) {
|
if (std::abs(inertia_scroll_rate_) > 0.05f) {
|
||||||
touch_is_scrolling_ = true;
|
touch_is_scrolling_ = true;
|
||||||
}
|
}
|
||||||
@ -441,7 +445,7 @@ auto HScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
smoothing_amount_ = 1.0f; // So we can see the transition.
|
smoothing_amount_ = 1.0f; // So we can see the transition.
|
||||||
child_offset_h_ -= (width() - 2 * (border_width_ + kHMargin));
|
child_offset_h_ -= (width() - 2 * (border_width_ + kHMargin));
|
||||||
MarkForUpdate();
|
MarkForUpdate();
|
||||||
ClampThumb(false, true);
|
ClampThumb_(false, true);
|
||||||
} else if (x >= sb_thumb_right - sb_thumb_width) {
|
} else if (x >= sb_thumb_right - sb_thumb_width) {
|
||||||
// On thumb.
|
// On thumb.
|
||||||
mouse_held_thumb_ = true;
|
mouse_held_thumb_ = true;
|
||||||
@ -452,7 +456,7 @@ auto HScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
smoothing_amount_ = 1.0f; // So we can see the transition.
|
smoothing_amount_ = 1.0f; // So we can see the transition.
|
||||||
child_offset_h_ += (width() - 2 * (border_width_ + kHMargin));
|
child_offset_h_ += (width() - 2 * (border_width_ + kHMargin));
|
||||||
MarkForUpdate();
|
MarkForUpdate();
|
||||||
ClampThumb(false, true);
|
ClampThumb_(false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -519,18 +523,20 @@ void HScrollWidget::UpdateLayout() {
|
|||||||
|
|
||||||
void HScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
void HScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
||||||
have_drawn_ = true;
|
have_drawn_ = true;
|
||||||
millisecs_t current_time = pass->frame_def()->display_time_millisecs();
|
auto* frame_def{pass->frame_def()};
|
||||||
|
millisecs_t current_time_ms = frame_def->display_time_millisecs();
|
||||||
float prev_child_offset_h_smoothed = child_offset_h_smoothed_;
|
float prev_child_offset_h_smoothed = child_offset_h_smoothed_;
|
||||||
|
|
||||||
// Ok, lets update our inertial scrolling during the opaque pass.
|
// Ok, lets update our inertial scrolling during the opaque pass. (we
|
||||||
// (we really should have some sort of update() function for this but widgets
|
// really should have some sort of update() function for this but widgets
|
||||||
// don't have that currently)
|
// don't have that currently)
|
||||||
if (!draw_transparent) {
|
if (!draw_transparent) {
|
||||||
// (skip huge differences)
|
// (skip huge differences)
|
||||||
if (current_time - inertia_scroll_update_time_ > 1000)
|
if (current_time_ms - inertia_scroll_update_time_ms_ > 1000) {
|
||||||
inertia_scroll_update_time_ = current_time - 1000;
|
inertia_scroll_update_time_ms_ = current_time_ms - 1000;
|
||||||
while (current_time - inertia_scroll_update_time_ > 5) {
|
}
|
||||||
inertia_scroll_update_time_ += 5;
|
while (current_time_ms - inertia_scroll_update_time_ms_ > 5) {
|
||||||
|
inertia_scroll_update_time_ms_ += 5;
|
||||||
|
|
||||||
if (touch_mode_) {
|
if (touch_mode_) {
|
||||||
if (touch_held_) {
|
if (touch_held_) {
|
||||||
@ -545,18 +551,20 @@ void HScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
inertia_scroll_rate_ *= 0.98f;
|
inertia_scroll_rate_ *= 0.98f;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClampThumb(true, mouse_held_thumb_);
|
ClampThumb_(true, mouse_held_thumb_);
|
||||||
child_offset_h_ += inertia_scroll_rate_;
|
child_offset_h_ += inertia_scroll_rate_;
|
||||||
|
|
||||||
if (!has_momentum_
|
if (!has_momentum_
|
||||||
&& (current_time - last_velocity_event_time_millisecs_ > 1000 / 30)) {
|
&& (current_time_ms - last_velocity_event_time_millisecs_
|
||||||
|
> 1000 / 30)) {
|
||||||
inertia_scroll_rate_ = 0;
|
inertia_scroll_rate_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lastly we apply smoothing so that if we're snapping to a specific place
|
// Lastly we apply smoothing so that if we're snapping to a specific
|
||||||
// we don't go instantly there we blend between smoothed and non-smoothed
|
// place we don't go instantly there we blend between smoothed and
|
||||||
// depending on whats driving us (we dont want to add smoothing on top of
|
// non-smoothed depending on whats driving us (we dont want to add
|
||||||
// inertial scrolling for example or it'll feel muddy)
|
// smoothing on top of inertial scrolling for example or it'll feel
|
||||||
|
// muddy)
|
||||||
float diff = child_offset_h_ - child_offset_h_smoothed_;
|
float diff = child_offset_h_ - child_offset_h_smoothed_;
|
||||||
if (std::abs(diff) < 1.0f)
|
if (std::abs(diff) < 1.0f)
|
||||||
child_offset_h_smoothed_ = child_offset_h_;
|
child_offset_h_smoothed_ = child_offset_h_;
|
||||||
@ -601,6 +609,7 @@ void HScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// scroll trough (depth 0.7f to 0.8f)
|
// scroll trough (depth 0.7f to 0.8f)
|
||||||
|
if (explicit_bool(false)) {
|
||||||
if (draw_transparent && border_opacity_ > 0.0f) {
|
if (draw_transparent && border_opacity_ > 0.0f) {
|
||||||
if (trough_dirty_) {
|
if (trough_dirty_) {
|
||||||
float b2 = b + 4;
|
float b2 = b + 4;
|
||||||
@ -635,24 +644,25 @@ void HScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
}
|
}
|
||||||
c.Submit();
|
c.Submit();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// scroll bars
|
// Scroll bars.
|
||||||
if (amount_visible_ > 0 && amount_visible_ < 1) {
|
if (amount_visible_ > 0.0f && amount_visible_ < 1.0f) {
|
||||||
// scroll thumb at depth 0.8f-0.9
|
// Scroll thumb at depth 0.8 - 0.9.
|
||||||
{
|
{
|
||||||
float sb_thumb_width = amount_visible_ * (width() - 2 * border_width_);
|
float sb_thumb_width = amount_visible_ * (width() - 2.0f * border_width_);
|
||||||
if (thumb_dirty_) {
|
if (thumb_dirty_) {
|
||||||
float sb_thumb_right =
|
float sb_thumb_right =
|
||||||
r - border_width_
|
r - border_width_
|
||||||
- ((width() - (border_width_ * 2) - sb_thumb_width)
|
- ((width() - (border_width_ * 2.0f) - sb_thumb_width)
|
||||||
* child_offset_h_smoothed_ / child_max_offset_);
|
* child_offset_h_smoothed_ / child_max_offset_);
|
||||||
float b2 = 4;
|
float b2 = 4.0f;
|
||||||
float t2 = b2 + scroll_bar_height_;
|
float t2 = b2 + scroll_bar_height_;
|
||||||
float r2 = sb_thumb_right;
|
float r2 = sb_thumb_right;
|
||||||
float l2 = r2 - sb_thumb_width;
|
float l2 = r2 - sb_thumb_width;
|
||||||
float b_border, t_border, l_border, r_border;
|
float b_border, t_border, l_border, r_border;
|
||||||
b_border = 6;
|
b_border = 6.0f;
|
||||||
t_border = 3;
|
t_border = 3.0f;
|
||||||
if (sb_thumb_width > 100) {
|
if (sb_thumb_width > 100) {
|
||||||
auto wd = r2 - l2;
|
auto wd = r2 - l2;
|
||||||
l_border = wd * 0.04f;
|
l_border = wd * 0.04f;
|
||||||
@ -679,25 +689,32 @@ void HScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
// c_scale = 1.25f;
|
// c_scale = 1.25f;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
float frame_duration = frame_def->display_time_elapsed();
|
||||||
|
|
||||||
bool smooth_diff =
|
bool smooth_diff =
|
||||||
(std::abs(child_offset_h_smoothed_ - child_offset_h_) > 0.01f);
|
(std::abs(child_offset_h_smoothed_ - child_offset_h_) > 0.01f);
|
||||||
if (touch_mode_) {
|
if (touch_mode_) {
|
||||||
if (smooth_diff || (touch_held_ && touch_is_scrolling_)
|
if (smooth_diff || (touch_held_ && touch_is_scrolling_)
|
||||||
|| std::abs(inertia_scroll_rate_) > 1.0f) {
|
|| std::abs(inertia_scroll_rate_) > 1.0f) {
|
||||||
touch_fade_ = std::min(1.5f, touch_fade_ + 0.02f);
|
last_scroll_bar_show_time_ = frame_def->display_time();
|
||||||
} else {
|
|
||||||
// FIXME: Shouldn't be frame based.
|
|
||||||
touch_fade_ = std::max(0.0f, touch_fade_ - 0.015f);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (smooth_diff || (touch_held_ && touch_is_scrolling_)
|
if (smooth_diff || (touch_held_ && touch_is_scrolling_)
|
||||||
|| std::abs(inertia_scroll_rate_) > 1.0f || mouse_over_) {
|
|| std::abs(inertia_scroll_rate_) > 1.0f
|
||||||
touch_fade_ = std::min(1.5f, touch_fade_ + 0.02f);
|
|| (mouse_over_
|
||||||
|
&& frame_def->display_time() - last_mouse_move_time_ < 0.1)) {
|
||||||
|
last_scroll_bar_show_time_ = frame_def->display_time();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fade in if we want to see the scrollbar. Start fading out a moment
|
||||||
|
// after we stop wanting to see it.
|
||||||
|
if (frame_def->display_time() - last_scroll_bar_show_time_ < 1.0) {
|
||||||
|
touch_fade_ = std::min(1.5f, touch_fade_ + 2.0f * frame_duration);
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Shouldn't be frame based.
|
touch_fade_ = std::max(0.0f, touch_fade_ - frame_duration);
|
||||||
touch_fade_ = std::max(0.0f, touch_fade_ - 0.015f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.SetColor(0, 0, 0, std::min(1.0f, 0.3f * touch_fade_));
|
c.SetColor(0, 0, 0, std::min(1.0f, 0.3f * touch_fade_));
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -722,7 +739,7 @@ void HScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// outline shadow (depth 0.9 to 1.0)
|
// Outline shadow (depth 0.9 to 1.0).
|
||||||
if (draw_transparent && border_opacity_ > 0.0f) {
|
if (draw_transparent && border_opacity_ > 0.0f) {
|
||||||
if (shadow_dirty_) {
|
if (shadow_dirty_) {
|
||||||
float r2 = l + width();
|
float r2 = l + width();
|
||||||
@ -754,12 +771,12 @@ void HScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
c.Submit();
|
c.Submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if selected, do glow at depth 0.9-1.0
|
// If selected, do glow at depth 0.9 - 1.0.
|
||||||
if (draw_transparent && IsHierarchySelected()
|
if (draw_transparent && IsHierarchySelected()
|
||||||
&& g_base->ui->ShouldHighlightWidgets() && highlight_
|
&& g_base->ui->ShouldHighlightWidgets() && highlight_
|
||||||
&& border_opacity_ > 0.0f) {
|
&& border_opacity_ > 0.0f) {
|
||||||
float m = 0.8f
|
float m = 0.8f
|
||||||
+ std::abs(sinf(static_cast<float>(current_time) * 0.006467f))
|
+ std::abs(sinf(static_cast<float>(current_time_ms) * 0.006467f))
|
||||||
* 0.2f * border_opacity_;
|
* 0.2f * border_opacity_;
|
||||||
|
|
||||||
if (glow_dirty_) {
|
if (glow_dirty_) {
|
||||||
|
|||||||
@ -33,7 +33,7 @@ class HScrollWidget : public ContainerWidget {
|
|||||||
MarkForUpdate();
|
MarkForUpdate();
|
||||||
}
|
}
|
||||||
void OnTouchDelayTimerExpired();
|
void OnTouchDelayTimerExpired();
|
||||||
void setColor(float r, float g, float b) {
|
void SetColor(float r, float g, float b) {
|
||||||
color_red_ = r;
|
color_red_ = r;
|
||||||
color_green_ = g;
|
color_green_ = g;
|
||||||
color_blue_ = b;
|
color_blue_ = b;
|
||||||
@ -47,39 +47,30 @@ class HScrollWidget : public ContainerWidget {
|
|||||||
void UpdateLayout() override;
|
void UpdateLayout() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ClampThumb(bool velocity_clamp, bool position_clamp);
|
void ClampThumb_(bool velocity_clamp, bool position_clamp);
|
||||||
|
|
||||||
bool touch_mode_{};
|
Object::Ref<base::AppTimer> touch_delay_timer_;
|
||||||
|
seconds_t last_scroll_bar_show_time_{};
|
||||||
|
seconds_t last_mouse_move_time_{};
|
||||||
float color_red_{0.55f};
|
float color_red_{0.55f};
|
||||||
float color_green_{0.47f};
|
float color_green_{0.47f};
|
||||||
float color_blue_{0.67f};
|
float color_blue_{0.67f};
|
||||||
bool has_momentum_{true};
|
|
||||||
bool trough_dirty_{true};
|
|
||||||
bool shadow_dirty_{true};
|
|
||||||
bool glow_dirty_{true};
|
|
||||||
bool thumb_dirty_{true};
|
|
||||||
millisecs_t last_velocity_event_time_millisecs_{};
|
|
||||||
float touch_fade_{};
|
float touch_fade_{};
|
||||||
bool center_small_content_{};
|
|
||||||
float center_offset_x_{};
|
float center_offset_x_{};
|
||||||
bool touch_held_{};
|
|
||||||
int touch_held_click_count_{};
|
|
||||||
float touch_down_x_{};
|
float touch_down_x_{};
|
||||||
float touch_x_{};
|
float touch_x_{};
|
||||||
float touch_y_{};
|
float touch_y_{};
|
||||||
float touch_start_x_{};
|
float touch_start_x_{};
|
||||||
float touch_start_y_{};
|
float touch_start_y_{};
|
||||||
bool touch_is_scrolling_{};
|
|
||||||
bool touch_down_sent_{};
|
|
||||||
bool touch_up_sent_{};
|
|
||||||
bool new_scroll_touch_{};
|
|
||||||
float trough_width_{};
|
float trough_width_{};
|
||||||
float trough_height_{};
|
float trough_height_{};
|
||||||
float trough_center_x_{};
|
float trough_center_x_{};
|
||||||
float trough_center_y_{};
|
float trough_center_y_{};
|
||||||
float thumb_width_{}, thumb_height_{}, thumb_center_x_{}, thumb_center_y_{};
|
float thumb_width_{};
|
||||||
|
float thumb_height_{};
|
||||||
|
float thumb_center_x_{};
|
||||||
|
float thumb_center_y_{};
|
||||||
float smoothing_amount_{1.0f};
|
float smoothing_amount_{1.0f};
|
||||||
bool highlight_{true};
|
|
||||||
float glow_width_{};
|
float glow_width_{};
|
||||||
float glow_height_{};
|
float glow_height_{};
|
||||||
float glow_center_x_{};
|
float glow_center_x_{};
|
||||||
@ -89,16 +80,8 @@ class HScrollWidget : public ContainerWidget {
|
|||||||
float outline_center_x_{};
|
float outline_center_x_{};
|
||||||
float outline_center_y_{};
|
float outline_center_y_{};
|
||||||
float border_opacity_{1.0f};
|
float border_opacity_{1.0f};
|
||||||
bool capture_arrows_{};
|
|
||||||
bool mouse_held_scroll_down_{};
|
|
||||||
bool mouse_held_scroll_up_{};
|
|
||||||
bool mouse_held_thumb_{};
|
|
||||||
float thumb_click_start_h_{};
|
float thumb_click_start_h_{};
|
||||||
float thumb_click_start_child_offset_h_{};
|
float thumb_click_start_child_offset_h_{};
|
||||||
bool mouse_held_page_down_{};
|
|
||||||
bool mouse_held_page_up_{};
|
|
||||||
bool mouse_over_thumb_{};
|
|
||||||
bool mouse_over_{};
|
|
||||||
float scroll_bar_height_{10.0f};
|
float scroll_bar_height_{10.0f};
|
||||||
float border_width_{2.0f};
|
float border_width_{2.0f};
|
||||||
float border_height_{2.0f};
|
float border_height_{2.0f};
|
||||||
@ -106,10 +89,32 @@ class HScrollWidget : public ContainerWidget {
|
|||||||
float child_offset_h_smoothed_{};
|
float child_offset_h_smoothed_{};
|
||||||
float child_max_offset_{};
|
float child_max_offset_{};
|
||||||
float amount_visible_{};
|
float amount_visible_{};
|
||||||
bool have_drawn_{};
|
|
||||||
millisecs_t inertia_scroll_update_time_{};
|
|
||||||
float inertia_scroll_rate_{};
|
float inertia_scroll_rate_{};
|
||||||
Object::Ref<base::AppTimer> touch_delay_timer_;
|
millisecs_t inertia_scroll_update_time_ms_{};
|
||||||
|
millisecs_t last_velocity_event_time_millisecs_{};
|
||||||
|
int touch_held_click_count_{};
|
||||||
|
bool touch_is_scrolling_{};
|
||||||
|
bool touch_down_sent_{};
|
||||||
|
bool touch_up_sent_{};
|
||||||
|
bool new_scroll_touch_{};
|
||||||
|
bool touch_held_{};
|
||||||
|
bool touch_mode_{};
|
||||||
|
bool has_momentum_{true};
|
||||||
|
bool trough_dirty_{true};
|
||||||
|
bool shadow_dirty_{true};
|
||||||
|
bool glow_dirty_{true};
|
||||||
|
bool thumb_dirty_{true};
|
||||||
|
bool center_small_content_{};
|
||||||
|
bool highlight_{true};
|
||||||
|
bool capture_arrows_{};
|
||||||
|
bool mouse_held_scroll_down_{};
|
||||||
|
bool mouse_held_scroll_up_{};
|
||||||
|
bool mouse_held_thumb_{};
|
||||||
|
bool mouse_held_page_down_{};
|
||||||
|
bool mouse_held_page_up_{};
|
||||||
|
bool mouse_over_thumb_{};
|
||||||
|
bool mouse_over_{};
|
||||||
|
bool have_drawn_{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ballistica::ui_v1
|
} // namespace ballistica::ui_v1
|
||||||
|
|||||||
@ -87,7 +87,9 @@ void ImageWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
// Draw brightness.
|
// Draw brightness.
|
||||||
float db = 1.0f;
|
float db = 1.0f;
|
||||||
if (Widget* draw_controller = draw_control_parent()) {
|
if (Widget* draw_controller = draw_control_parent()) {
|
||||||
db *= draw_controller->GetDrawBrightness(current_time);
|
db *= (draw_controller_mult_
|
||||||
|
* draw_controller->GetDrawBrightness(current_time))
|
||||||
|
+ (1.0f - draw_controller_mult_) * 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opaque portion may get drawn transparent or opaque depending on our
|
// Opaque portion may get drawn transparent or opaque depending on our
|
||||||
|
|||||||
@ -43,6 +43,9 @@ class ImageWidget : public Widget {
|
|||||||
tint2_color_green_ = g;
|
tint2_color_green_ = g;
|
||||||
tint2_color_blue_ = b;
|
tint2_color_blue_ = b;
|
||||||
}
|
}
|
||||||
|
void set_draw_controller_mult(float val) {
|
||||||
|
draw_controller_mult_ = std::max(0.0f, std::min(1.0f, val));
|
||||||
|
}
|
||||||
void set_opacity(float o) { opacity_ = o; }
|
void set_opacity(float o) { opacity_ = o; }
|
||||||
void SetTexture(base::TextureAsset* val) { texture_ = val; }
|
void SetTexture(base::TextureAsset* val) { texture_ = val; }
|
||||||
void SetTintTexture(base::TextureAsset* val) { tint_texture_ = val; }
|
void SetTintTexture(base::TextureAsset* val) { tint_texture_ = val; }
|
||||||
@ -89,6 +92,7 @@ class ImageWidget : public Widget {
|
|||||||
float tint2_color_green_{1.0f};
|
float tint2_color_green_{1.0f};
|
||||||
float tint2_color_blue_{1.0f};
|
float tint2_color_blue_{1.0f};
|
||||||
float opacity_{1.0f};
|
float opacity_{1.0f};
|
||||||
|
float draw_controller_mult_{1.0f};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ballistica::ui_v1
|
} // namespace ballistica::ui_v1
|
||||||
|
|||||||
@ -24,8 +24,8 @@ void ScrollWidget::OnTouchDelayTimerExpired() {
|
|||||||
if (touch_held_) {
|
if (touch_held_) {
|
||||||
// Pass a mouse-down event if we haven't moved.
|
// Pass a mouse-down event if we haven't moved.
|
||||||
if (!touch_is_scrolling_ && !touch_down_sent_) {
|
if (!touch_is_scrolling_ && !touch_down_sent_) {
|
||||||
// Gather up any user code triggered by this stuff and run it at the end
|
// Gather up any user code triggered by this stuff and run it at the
|
||||||
// before we return.
|
// end before we return.
|
||||||
base::UI::OperationContext ui_op_context;
|
base::UI::OperationContext ui_op_context;
|
||||||
|
|
||||||
ContainerWidget::HandleMessage(base::WidgetMessage(
|
ContainerWidget::HandleMessage(base::WidgetMessage(
|
||||||
@ -42,7 +42,7 @@ void ScrollWidget::OnTouchDelayTimerExpired() {
|
|||||||
touch_delay_timer_.Clear();
|
touch_delay_timer_.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScrollWidget::ClampThumb(bool velocity_clamp, bool position_clamp) {
|
void ScrollWidget::ClampThumb_(bool velocity_clamp, bool position_clamp) {
|
||||||
BA_DEBUG_UI_READ_LOCK;
|
BA_DEBUG_UI_READ_LOCK;
|
||||||
|
|
||||||
bool is_scrolling;
|
bool is_scrolling;
|
||||||
@ -118,7 +118,7 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
smoothing_amount_ = 1.0f; // So we can see the transition.
|
smoothing_amount_ = 1.0f; // So we can see the transition.
|
||||||
child_offset_v_ -= (60);
|
child_offset_v_ -= (60);
|
||||||
MarkForUpdate();
|
MarkForUpdate();
|
||||||
ClampThumb(false, true);
|
ClampThumb_(false, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
smoothing_amount_ = 1.0f; // So we can see the transition.
|
smoothing_amount_ = 1.0f; // So we can see the transition.
|
||||||
child_offset_v_ += (60);
|
child_offset_v_ += (60);
|
||||||
MarkForUpdate();
|
MarkForUpdate();
|
||||||
ClampThumb(false, true);
|
ClampThumb_(false, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -187,8 +187,8 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
if (ContainerWidget::HandleMessage(m)) {
|
if (ContainerWidget::HandleMessage(m)) {
|
||||||
claimed = true;
|
claimed = true;
|
||||||
|
|
||||||
// Keep track of the average scrolling going on. (only update when we
|
// Keep track of the average scrolling going on. (only update when
|
||||||
// get non-momentum events)
|
// we get non-momentum events)
|
||||||
if (std::abs(m.fval3) > 0.001f && !has_momentum_) {
|
if (std::abs(m.fval3) > 0.001f && !has_momentum_) {
|
||||||
float smoothing = 0.8f;
|
float smoothing = 0.8f;
|
||||||
avg_scroll_speed_h_ =
|
avg_scroll_speed_h_ =
|
||||||
@ -207,8 +207,8 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
float x = m.fval1;
|
float x = m.fval1;
|
||||||
float y = m.fval2;
|
float y = m.fval2;
|
||||||
|
|
||||||
// Keep track of the average scrolling going on. (only update when we get
|
// Keep track of the average scrolling going on. (only update when we
|
||||||
// non-momentum events).
|
// get non-momentum events).
|
||||||
if (std::abs(m.fval3) > 0.001f && !has_momentum_) {
|
if (std::abs(m.fval3) > 0.001f && !has_momentum_) {
|
||||||
float smoothing = 0.8f;
|
float smoothing = 0.8f;
|
||||||
avg_scroll_speed_v_ =
|
avg_scroll_speed_v_ =
|
||||||
@ -219,9 +219,9 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
smoothing * avg_scroll_speed_h_ + (1.0f - smoothing) * 0.0f;
|
smoothing * avg_scroll_speed_h_ + (1.0f - smoothing) * 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a child appears to be looking at horizontal scroll events and we're
|
// If a child appears to be looking at horizontal scroll events and
|
||||||
// scrolling more horizontally than vertically in general, ignore vertical
|
// we're scrolling more horizontally than vertically in general,
|
||||||
// scrolling (should probably make this less fuzzy).
|
// ignore vertical scrolling (should probably make this less fuzzy).
|
||||||
bool ignore_regular_scrolling = false;
|
bool ignore_regular_scrolling = false;
|
||||||
bool child_claimed_h_scroll_recently =
|
bool child_claimed_h_scroll_recently =
|
||||||
(g_core->GetAppTimeMillisecs() - last_sub_widget_h_scroll_claim_time_
|
(g_core->GetAppTimeMillisecs() - last_sub_widget_h_scroll_claim_time_
|
||||||
@ -301,8 +301,8 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
float y = m.fval2;
|
float y = m.fval2;
|
||||||
if ((x >= 0.0f) && (x < width() + right_overlap) && (y >= 0.0f)
|
if ((x >= 0.0f) && (x < width() + right_overlap) && (y >= 0.0f)
|
||||||
&& (y < height())) {
|
&& (y < height())) {
|
||||||
// On touch devices, touches begin scrolling, (and eventually can count
|
// On touch devices, touches begin scrolling, (and eventually can
|
||||||
// as clicks if they don't move).
|
// count as clicks if they don't move).
|
||||||
if (touch_mode_) {
|
if (touch_mode_) {
|
||||||
touch_held_ = true;
|
touch_held_ = true;
|
||||||
auto click_count = static_cast<int>(m.fval3);
|
auto click_count = static_cast<int>(m.fval3);
|
||||||
@ -318,8 +318,8 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
child_is_scrolling_ = false;
|
child_is_scrolling_ = false;
|
||||||
child_disowned_scroll_ = false;
|
child_disowned_scroll_ = false;
|
||||||
|
|
||||||
// If there's already significant scrolling happening, we handle all
|
// If there's already significant scrolling happening, we handle
|
||||||
// these ourself as scroll events.
|
// all these ourself as scroll events.
|
||||||
if (std::abs(inertia_scroll_rate_) > 0.05f) {
|
if (std::abs(inertia_scroll_rate_) > 0.05f) {
|
||||||
touch_is_scrolling_ = true;
|
touch_is_scrolling_ = true;
|
||||||
}
|
}
|
||||||
@ -361,19 +361,18 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
smoothing_amount_ = 1.0f;
|
smoothing_amount_ = 1.0f;
|
||||||
child_offset_v_ -= (height() - 2 * (border_height_ + V_MARGIN));
|
child_offset_v_ -= (height() - 2 * (border_height_ + V_MARGIN));
|
||||||
MarkForUpdate();
|
MarkForUpdate();
|
||||||
ClampThumb(false, true);
|
ClampThumb_(false, true);
|
||||||
} else if (y >= sb_thumb_top - sb_thumb_height) {
|
} else if (y >= sb_thumb_top - sb_thumb_height) {
|
||||||
// On thumb.
|
// On thumb.
|
||||||
mouse_held_thumb_ = true;
|
mouse_held_thumb_ = true;
|
||||||
thumb_click_start_v_ = y;
|
thumb_click_start_v_ = y;
|
||||||
thumb_click_start_child_offset_v_ = child_offset_v_;
|
thumb_click_start_child_offset_v_ = child_offset_v_;
|
||||||
} else if (y >= s_bottom) {
|
} else if (y >= s_bottom) {
|
||||||
// Below thumb (page down).
|
// Below thumb (page down). So we can see the transition.
|
||||||
// So we can see the transition.
|
|
||||||
smoothing_amount_ = 1.0f;
|
smoothing_amount_ = 1.0f;
|
||||||
child_offset_v_ += (height() - 2 * (border_height_ + V_MARGIN));
|
child_offset_v_ += (height() - 2 * (border_height_ + V_MARGIN));
|
||||||
MarkForUpdate();
|
MarkForUpdate();
|
||||||
ClampThumb(false, true);
|
ClampThumb_(false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -388,12 +387,13 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
float y = m.fval2;
|
float y = m.fval2;
|
||||||
bool was_claimed = (m.fval3 > 0.0f);
|
bool was_claimed = (m.fval3 > 0.0f);
|
||||||
|
|
||||||
// If coords are outside of our bounds we don't want to pass mouse-moved
|
// If coords are outside of our bounds we don't want to pass
|
||||||
// events through the standard container logic. (otherwise, if we mouse
|
// mouse-moved events through the standard container logic.
|
||||||
// down over a button that doesn't overlap the scroll area but overlaps
|
// (otherwise, if we mouse down over a button that doesn't overlap the
|
||||||
// some widget in the scroll area, the widget would claim the move and the
|
// scroll area but overlaps some widget in the scroll area, the widget
|
||||||
// button would lose its mouse-over-highlight; ew.) There may be some
|
// would claim the move and the button would lose its
|
||||||
// case where we *would* want to pass this though.
|
// mouse-over-highlight; ew.) There may be some case where we *would*
|
||||||
|
// want to pass this though.
|
||||||
if (!((x >= 0.0f) && (x < width() + right_overlap) && (y >= 0.0f)
|
if (!((x >= 0.0f) && (x < width() + right_overlap) && (y >= 0.0f)
|
||||||
&& (y < height()))) {
|
&& (y < height()))) {
|
||||||
pass = false;
|
pass = false;
|
||||||
@ -404,14 +404,15 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
} else {
|
} else {
|
||||||
if (touch_mode_) {
|
if (touch_mode_) {
|
||||||
if (touch_held_) {
|
if (touch_held_) {
|
||||||
// If we have a child claiming this scrolling action for themselves,
|
// If we have a child claiming this scrolling action for
|
||||||
// just keep passing them the events as long as they get claimed.
|
// themselves, just keep passing them the events as long as they
|
||||||
|
// get claimed.
|
||||||
if (child_is_scrolling_ && !child_disowned_scroll_) {
|
if (child_is_scrolling_ && !child_disowned_scroll_) {
|
||||||
bool move_claimed = ContainerWidget::HandleMessage(
|
bool move_claimed = ContainerWidget::HandleMessage(
|
||||||
base::WidgetMessage(base::WidgetMessage::Type::kMouseMove,
|
base::WidgetMessage(base::WidgetMessage::Type::kMouseMove,
|
||||||
nullptr, m.fval1, m.fval2, m.fval3));
|
nullptr, m.fval1, m.fval2, m.fval3));
|
||||||
// If they stopped claiming them, send a scroll-mouse-up to tie
|
// If they stopped claiming them, send a scroll-mouse-up to
|
||||||
// things up.
|
// tie things up.
|
||||||
if (!move_claimed) {
|
if (!move_claimed) {
|
||||||
ContainerWidget::HandleMessage(
|
ContainerWidget::HandleMessage(
|
||||||
base::WidgetMessage(base::WidgetMessage::Type::kMouseUp,
|
base::WidgetMessage(base::WidgetMessage::Type::kMouseUp,
|
||||||
@ -419,12 +420,13 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
child_disowned_scroll_ = true;
|
child_disowned_scroll_ = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If no child is scrolling; this touch motion is ours to handle.
|
// If no child is scrolling; this touch motion is ours to
|
||||||
|
// handle.
|
||||||
touch_x_ = x;
|
touch_x_ = x;
|
||||||
touch_y_ = y;
|
touch_y_ = y;
|
||||||
|
|
||||||
// If we move more than a slight amount it means our touch isn't a
|
// If we move more than a slight amount it means our touch
|
||||||
// click.
|
// isn't a click.
|
||||||
if (!touch_is_scrolling_
|
if (!touch_is_scrolling_
|
||||||
&& ((std::abs(touch_x_ - touch_start_x_) > 10.0f)
|
&& ((std::abs(touch_x_ - touch_start_x_) > 10.0f)
|
||||||
|| (std::abs(touch_y_ - touch_start_y_) > 10.0f))) {
|
|| (std::abs(touch_y_ - touch_start_y_) > 10.0f))) {
|
||||||
@ -476,7 +478,7 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
/ ((1.0f - ((s_top - s_bottom) / child_h)) * (s_top - s_bottom));
|
/ ((1.0f - ((s_top - s_bottom) / child_h)) * (s_top - s_bottom));
|
||||||
child_offset_v_ = thumb_click_start_child_offset_v_
|
child_offset_v_ = thumb_click_start_child_offset_v_
|
||||||
- rate * (y - thumb_click_start_v_);
|
- rate * (y - thumb_click_start_v_);
|
||||||
ClampThumb(false, true);
|
ClampThumb_(false, true);
|
||||||
MarkForUpdate();
|
MarkForUpdate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -491,8 +493,8 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
if (touch_held_) {
|
if (touch_held_) {
|
||||||
touch_held_ = false;
|
touch_held_ = false;
|
||||||
|
|
||||||
// If we moved at all, we mark it as claimed to keep
|
// If we moved at all, we mark it as claimed to keep sub-widgets
|
||||||
// sub-widgets from acting on it (since we used it for scrolling)
|
// from acting on it (since we used it for scrolling)
|
||||||
bool claimed2 = touch_is_scrolling_ || child_is_scrolling_;
|
bool claimed2 = touch_is_scrolling_ || child_is_scrolling_;
|
||||||
|
|
||||||
// if a child is still scrolling, send them a scroll-mouse-up
|
// if a child is still scrolling, send them a scroll-mouse-up
|
||||||
@ -502,8 +504,8 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
nullptr, m.fval1, m.fval2, false));
|
nullptr, m.fval1, m.fval2, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're not claiming it and we haven't sent a mouse_down yet due
|
// If we're not claiming it and we haven't sent a mouse_down yet
|
||||||
// to our delay, send that first..
|
// due to our delay, send that first..
|
||||||
if (!claimed2 && !touch_down_sent_) {
|
if (!claimed2 && !touch_down_sent_) {
|
||||||
ContainerWidget::HandleMessage(base::WidgetMessage(
|
ContainerWidget::HandleMessage(base::WidgetMessage(
|
||||||
base::WidgetMessage::Type::kMouseDown, nullptr, m.fval1,
|
base::WidgetMessage::Type::kMouseDown, nullptr, m.fval1,
|
||||||
@ -521,9 +523,9 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If coords are outside of our bounds, pass a mouse-up along for anyone
|
// If coords are outside of our bounds, pass a mouse-up along for
|
||||||
// tracking a drag, but mark it as claimed so it doesn't actually get
|
// anyone tracking a drag, but mark it as claimed so it doesn't
|
||||||
// acted on.
|
// actually get acted on.
|
||||||
float x = m.fval1;
|
float x = m.fval1;
|
||||||
float y = m.fval2;
|
float y = m.fval2;
|
||||||
if (!((x >= 0.0f) && (x < width() + right_overlap) && (y >= 0.0f)
|
if (!((x >= 0.0f) && (x < width() + right_overlap) && (y >= 0.0f)
|
||||||
@ -558,7 +560,7 @@ auto ScrollWidget::HandleMessage(const base::WidgetMessage& m) -> bool {
|
|||||||
void ScrollWidget::UpdateLayout() {
|
void ScrollWidget::UpdateLayout() {
|
||||||
BA_DEBUG_UI_READ_LOCK;
|
BA_DEBUG_UI_READ_LOCK;
|
||||||
|
|
||||||
// move everything based on our offset
|
// Move everything based on our offset.
|
||||||
auto i = widgets().begin();
|
auto i = widgets().begin();
|
||||||
if (i == widgets().end()) {
|
if (i == widgets().end()) {
|
||||||
amount_visible_ = 0;
|
amount_visible_ = 0;
|
||||||
@ -600,11 +602,11 @@ void ScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
millisecs_t current_time = pass->frame_def()->display_time_millisecs();
|
millisecs_t current_time = pass->frame_def()->display_time_millisecs();
|
||||||
float prev_child_offset_v_smoothed = child_offset_v_smoothed_;
|
float prev_child_offset_v_smoothed = child_offset_v_smoothed_;
|
||||||
|
|
||||||
// ok lets update our inertial scrolling during the opaque pass
|
// Ok, lets update our inertial scrolling during the opaque pass (we
|
||||||
// (we really should have some sort of update() function for this but widgets
|
// really should have some sort of update() function for this but widgets
|
||||||
// don't have that)
|
// don't have that).
|
||||||
if (!draw_transparent) {
|
if (!draw_transparent) {
|
||||||
// (skip huge differences)
|
// Skip huge differences.
|
||||||
if (current_time - inertia_scroll_update_time_ > 1000) {
|
if (current_time - inertia_scroll_update_time_ > 1000) {
|
||||||
inertia_scroll_update_time_ = current_time - 1000;
|
inertia_scroll_update_time_ = current_time - 1000;
|
||||||
}
|
}
|
||||||
@ -623,16 +625,17 @@ void ScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
} else {
|
} else {
|
||||||
inertia_scroll_rate_ *= 0.98f;
|
inertia_scroll_rate_ *= 0.98f;
|
||||||
}
|
}
|
||||||
ClampThumb(true, mouse_held_thumb_);
|
ClampThumb_(true, mouse_held_thumb_);
|
||||||
child_offset_v_ += inertia_scroll_rate_;
|
child_offset_v_ += inertia_scroll_rate_;
|
||||||
if (!has_momentum_
|
if (!has_momentum_
|
||||||
&& (current_time - last_velocity_event_time_millisecs_ > 1000 / 30))
|
&& (current_time - last_velocity_event_time_millisecs_ > 1000 / 30))
|
||||||
inertia_scroll_rate_ = 0;
|
inertia_scroll_rate_ = 0;
|
||||||
|
|
||||||
// lastly we apply smoothing so that if we're snapping to a specific place
|
// Lastly we apply smoothing so that if we're snapping to a specific
|
||||||
// we don't go instantly there we blend between smoothed and non-smoothed
|
// place we don't go instantly there we blend between smoothed and
|
||||||
// depending on whats driving us (we dont want to add smoothing on top of
|
// non-smoothed depending on whats driving us (we dont want to add
|
||||||
// inertial scrolling for example or it'll feel muddy)
|
// smoothing on top of inertial scrolling for example or it'll feel
|
||||||
|
// muddy).
|
||||||
float diff = child_offset_v_ - child_offset_v_smoothed_;
|
float diff = child_offset_v_ - child_offset_v_smoothed_;
|
||||||
if (std::abs(diff) < 1.0f) {
|
if (std::abs(diff) < 1.0f) {
|
||||||
child_offset_v_smoothed_ = child_offset_v_;
|
child_offset_v_smoothed_ = child_offset_v_;
|
||||||
@ -641,7 +644,8 @@ void ScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
}
|
}
|
||||||
smoothing_amount_ = std::max(0.0f, smoothing_amount_ - 0.005f);
|
smoothing_amount_ = std::max(0.0f, smoothing_amount_ - 0.005f);
|
||||||
}
|
}
|
||||||
// only re-layout our widgets if we've moved a significant amount
|
|
||||||
|
// Only re-layout our widgets if we've moved a significant amount.
|
||||||
if (std::abs(prev_child_offset_v_smoothed - child_offset_v_smoothed_)
|
if (std::abs(prev_child_offset_v_smoothed - child_offset_v_smoothed_)
|
||||||
> 0.01f) {
|
> 0.01f) {
|
||||||
MarkForUpdate();
|
MarkForUpdate();
|
||||||
@ -675,7 +679,7 @@ void ScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
1.0f);
|
1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// scroll trough (depth 0.7f to 0.8f)
|
// Scroll trough (depth 0.7 to 0.8).
|
||||||
if (draw_transparent) {
|
if (draw_transparent) {
|
||||||
if (trough_dirty_) {
|
if (trough_dirty_) {
|
||||||
float r2 = l + width();
|
float r2 = l + width();
|
||||||
@ -709,9 +713,9 @@ void ScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
c.Submit();
|
c.Submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// scroll bars
|
// Scroll bars.
|
||||||
if (amount_visible_ > 0 && amount_visible_ < 1) {
|
if (amount_visible_ > 0 && amount_visible_ < 1) {
|
||||||
// scroll thumb at depth 0.8f-0.9
|
// Scroll thumb at depth 0.8 - 0.9.
|
||||||
{
|
{
|
||||||
float sb_thumb_height = amount_visible_ * (height() - 2 * border_height_);
|
float sb_thumb_height = amount_visible_ * (height() - 2 * border_height_);
|
||||||
if (thumb_dirty_) {
|
if (thumb_dirty_) {
|
||||||
@ -777,7 +781,7 @@ void ScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// outline shadow (depth 0.9f to 1.0f)
|
// Outline shadow (depth 0.9 to 1.0).
|
||||||
if (draw_transparent) {
|
if (draw_transparent) {
|
||||||
if (shadow_dirty_) {
|
if (shadow_dirty_) {
|
||||||
float r2 = l + width();
|
float r2 = l + width();
|
||||||
@ -811,7 +815,7 @@ void ScrollWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if selected, do glow at depth 0.9f-1.0
|
// If selected, do glow at depth 0.9 - 1.0.
|
||||||
if (draw_transparent && IsHierarchySelected()
|
if (draw_transparent && IsHierarchySelected()
|
||||||
&& g_base->ui->ShouldHighlightWidgets() && highlight_) {
|
&& g_base->ui->ShouldHighlightWidgets() && highlight_) {
|
||||||
float m = 0.8f
|
float m = 0.8f
|
||||||
|
|||||||
@ -47,37 +47,33 @@ class ScrollWidget : public ContainerWidget {
|
|||||||
void UpdateLayout() override;
|
void UpdateLayout() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ClampThumb(bool velocity_clamp, bool position_clamp);
|
void ClampThumb_(bool velocity_clamp, bool position_clamp);
|
||||||
bool touch_mode_{};
|
|
||||||
|
Object::Ref<base::AppTimer> touch_delay_timer_;
|
||||||
|
millisecs_t last_sub_widget_h_scroll_claim_time_{};
|
||||||
|
millisecs_t last_velocity_event_time_millisecs_{};
|
||||||
|
millisecs_t inertia_scroll_update_time_{};
|
||||||
|
int touch_held_click_count_{};
|
||||||
float color_red_{0.55f};
|
float color_red_{0.55f};
|
||||||
float color_green_{0.47f};
|
float color_green_{0.47f};
|
||||||
float color_blue_{0.67f};
|
float color_blue_{0.67f};
|
||||||
bool has_momentum_{true};
|
|
||||||
bool trough_dirty_{true};
|
|
||||||
bool shadow_dirty_{true};
|
|
||||||
bool glow_dirty_{true};
|
|
||||||
bool thumb_dirty_{true};
|
|
||||||
millisecs_t last_sub_widget_h_scroll_claim_time_{};
|
|
||||||
millisecs_t last_velocity_event_time_millisecs_{};
|
|
||||||
float avg_scroll_speed_h_{};
|
float avg_scroll_speed_h_{};
|
||||||
float avg_scroll_speed_v_{};
|
float avg_scroll_speed_v_{};
|
||||||
bool center_small_content_{};
|
|
||||||
float center_offset_y_{};
|
float center_offset_y_{};
|
||||||
bool touch_held_{};
|
|
||||||
int touch_held_click_count_{};
|
|
||||||
float touch_down_y_{};
|
float touch_down_y_{};
|
||||||
float touch_x_{};
|
float touch_x_{};
|
||||||
float touch_y_{};
|
float touch_y_{};
|
||||||
float touch_start_x_{};
|
float touch_start_x_{};
|
||||||
float touch_start_y_{};
|
float touch_start_y_{};
|
||||||
bool touch_is_scrolling_{};
|
float trough_width_{};
|
||||||
bool touch_down_sent_{};
|
float trough_height_{};
|
||||||
bool touch_up_sent_{};
|
float trough_center_x_{};
|
||||||
float trough_width_{}, trough_height_{}, trough_center_x_{},
|
float trough_center_y_{};
|
||||||
trough_center_y_{};
|
float thumb_width_{};
|
||||||
float thumb_width_{}, thumb_height_{}, thumb_center_x_{}, thumb_center_y_{};
|
float thumb_height_{};
|
||||||
|
float thumb_center_x_{};
|
||||||
|
float thumb_center_y_{};
|
||||||
float smoothing_amount_{1.0f};
|
float smoothing_amount_{1.0f};
|
||||||
bool highlight_{true};
|
|
||||||
float glow_width_{};
|
float glow_width_{};
|
||||||
float glow_height_{};
|
float glow_height_{};
|
||||||
float glow_center_x_{};
|
float glow_center_x_{};
|
||||||
@ -87,15 +83,8 @@ class ScrollWidget : public ContainerWidget {
|
|||||||
float outline_center_x_{};
|
float outline_center_x_{};
|
||||||
float outline_center_y_{};
|
float outline_center_y_{};
|
||||||
float border_opacity_{1.0f};
|
float border_opacity_{1.0f};
|
||||||
bool capture_arrows_{false};
|
|
||||||
bool mouse_held_scroll_down_{};
|
|
||||||
bool mouse_held_scroll_up_{};
|
|
||||||
bool mouse_held_thumb_{};
|
|
||||||
float thumb_click_start_v_{};
|
float thumb_click_start_v_{};
|
||||||
float thumb_click_start_child_offset_v_{};
|
float thumb_click_start_child_offset_v_{};
|
||||||
bool mouse_held_page_down_{};
|
|
||||||
bool mouse_held_page_up_{};
|
|
||||||
bool mouse_over_thumb_{};
|
|
||||||
float scroll_bar_width_{10.0f};
|
float scroll_bar_width_{10.0f};
|
||||||
float border_width_{2.0f};
|
float border_width_{2.0f};
|
||||||
float border_height_{2.0f};
|
float border_height_{2.0f};
|
||||||
@ -103,13 +92,30 @@ class ScrollWidget : public ContainerWidget {
|
|||||||
float child_offset_v_smoothed_{};
|
float child_offset_v_smoothed_{};
|
||||||
float child_max_offset_{};
|
float child_max_offset_{};
|
||||||
float amount_visible_{};
|
float amount_visible_{};
|
||||||
|
float inertia_scroll_rate_{};
|
||||||
|
bool mouse_held_page_down_{};
|
||||||
|
bool mouse_held_page_up_{};
|
||||||
|
bool mouse_over_thumb_{};
|
||||||
|
bool touch_is_scrolling_{};
|
||||||
|
bool touch_down_sent_{};
|
||||||
|
bool touch_up_sent_{};
|
||||||
|
bool touch_mode_{};
|
||||||
|
bool has_momentum_{true};
|
||||||
|
bool trough_dirty_{true};
|
||||||
|
bool shadow_dirty_{true};
|
||||||
|
bool glow_dirty_{true};
|
||||||
|
bool thumb_dirty_{true};
|
||||||
|
bool center_small_content_{};
|
||||||
|
bool touch_held_{};
|
||||||
|
bool highlight_{true};
|
||||||
|
bool capture_arrows_{false};
|
||||||
|
bool mouse_held_scroll_down_{};
|
||||||
|
bool mouse_held_scroll_up_{};
|
||||||
|
bool mouse_held_thumb_{};
|
||||||
bool have_drawn_{};
|
bool have_drawn_{};
|
||||||
bool touch_down_passed_{};
|
bool touch_down_passed_{};
|
||||||
bool child_is_scrolling_{};
|
bool child_is_scrolling_{};
|
||||||
bool child_disowned_scroll_{};
|
bool child_disowned_scroll_{};
|
||||||
millisecs_t inertia_scroll_update_time_{};
|
|
||||||
float inertia_scroll_rate_{};
|
|
||||||
Object::Ref<base::AppTimer> touch_delay_timer_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ballistica::ui_v1
|
} // namespace ballistica::ui_v1
|
||||||
|
|||||||
@ -250,3 +250,39 @@ class ManageAccountResponse(Response):
|
|||||||
"""Here's that sign-in result you asked for, boss."""
|
"""Here's that sign-in result you asked for, boss."""
|
||||||
|
|
||||||
url: Annotated[str | None, IOAttrs('u')]
|
url: Annotated[str | None, IOAttrs('u')]
|
||||||
|
|
||||||
|
|
||||||
|
@ioprepped
|
||||||
|
@dataclass
|
||||||
|
class StoreQueryMessage(Message):
|
||||||
|
"""Message asking about purchasable stuff and store related state."""
|
||||||
|
|
||||||
|
@override
|
||||||
|
@classmethod
|
||||||
|
def get_response_types(cls) -> list[type[Response] | None]:
|
||||||
|
return [StoreQueryResponse]
|
||||||
|
|
||||||
|
|
||||||
|
@ioprepped
|
||||||
|
@dataclass
|
||||||
|
class StoreQueryResponse(Response):
|
||||||
|
"""Here's that store info you asked for, boss."""
|
||||||
|
|
||||||
|
class Result(Enum):
|
||||||
|
"""Our overall result."""
|
||||||
|
|
||||||
|
SUCCESS = 's'
|
||||||
|
ERROR = 'e'
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Purchase:
|
||||||
|
"""Info about a purchasable thing."""
|
||||||
|
|
||||||
|
purchaseid: Annotated[str, IOAttrs('id')]
|
||||||
|
|
||||||
|
# Overall result; all data is undefined if not SUCCESS.
|
||||||
|
result: Annotated[Result, IOAttrs('r')]
|
||||||
|
|
||||||
|
tokens: Annotated[int, IOAttrs('t')]
|
||||||
|
available_purchases: Annotated[list[Purchase], IOAttrs('p')]
|
||||||
|
token_info_url: Annotated[str, IOAttrs('tiu')]
|
||||||
|
|||||||
@ -30,6 +30,10 @@ class AssetsV1GlobalVals:
|
|||||||
str | None, IOAttrs('base_assets', store_default=False)
|
str | None, IOAttrs('base_assets', store_default=False)
|
||||||
] = None
|
] = None
|
||||||
|
|
||||||
|
base_assets_filter: Annotated[
|
||||||
|
str, IOAttrs('base_assets_filter', store_default=False)
|
||||||
|
] = ''
|
||||||
|
|
||||||
|
|
||||||
class AssetsV1PathValsTypeID(Enum):
|
class AssetsV1PathValsTypeID(Enum):
|
||||||
"""Types of vals we can store for paths."""
|
"""Types of vals we can store for paths."""
|
||||||
|
|||||||
@ -615,7 +615,7 @@ def cmake_prep_dir(dirname: str, verbose: bool = False) -> None:
|
|||||||
# ...or if homebrew SDL.h resolved path changes (happens for updates)
|
# ...or if homebrew SDL.h resolved path changes (happens for updates)
|
||||||
sdl_h_path = Path('/opt/homebrew/include/SDL2/SDL.h')
|
sdl_h_path = Path('/opt/homebrew/include/SDL2/SDL.h')
|
||||||
homebrew_sdl_h_resolved: str = (
|
homebrew_sdl_h_resolved: str = (
|
||||||
str(sdl_h_path.resolve()) if sdl_h_path.is_symlink() else ''
|
str(sdl_h_path.resolve()) if sdl_h_path.exists() else ''
|
||||||
)
|
)
|
||||||
entries.append(Entry('homebrew_sdl_h_resolved', homebrew_sdl_h_resolved))
|
entries.append(Entry('homebrew_sdl_h_resolved', homebrew_sdl_h_resolved))
|
||||||
|
|
||||||
|
|||||||
@ -4,328 +4,14 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, TypeVar, Generic, Callable, cast
|
|
||||||
import functools
|
import functools
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, overload
|
pass
|
||||||
|
|
||||||
CT = TypeVar('CT', bound=Callable)
|
# TODO: should deprecate tpartial since it nowadays simply wraps
|
||||||
|
# functools.partial (mypy added support for functools.partial in 1.11 so
|
||||||
|
# there's no benefit to rolling our own type-safe version anymore).
|
||||||
class _CallbackCall(Generic[CT]):
|
# Perhaps we can use Python 13's @warnings.deprecated() stuff for this.
|
||||||
"""Descriptor for exposing a call with a type defined by a TypeVar."""
|
|
||||||
|
|
||||||
def __get__(self, obj: Any, type_in: Any = None) -> CT:
|
|
||||||
return cast(CT, None)
|
|
||||||
|
|
||||||
|
|
||||||
class CallbackSet(Generic[CT]):
|
|
||||||
"""Wrangles callbacks for a particular event in a type-safe manner."""
|
|
||||||
|
|
||||||
# In the type-checker's eyes, our 'run' attr is a CallbackCall which
|
|
||||||
# returns a callable with the type we were created with. This lets us
|
|
||||||
# type-check our run calls. (Is there another way to expose a function
|
|
||||||
# with a signature defined by a generic?..)
|
|
||||||
# At runtime, run() simply passes its args verbatim to its registered
|
|
||||||
# callbacks; no types are checked.
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
run: _CallbackCall[CT] = _CallbackCall()
|
|
||||||
else:
|
|
||||||
|
|
||||||
def run(self, *args, **keywds):
|
|
||||||
"""Run all callbacks."""
|
|
||||||
print('HELLO FROM RUN', *args, **keywds)
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
print('CallbackSet()')
|
|
||||||
|
|
||||||
def __del__(self) -> None:
|
|
||||||
print('~CallbackSet()')
|
|
||||||
|
|
||||||
def add(self, call: CT) -> None:
|
|
||||||
"""Add a callback to be run."""
|
|
||||||
print('Would add call', call)
|
|
||||||
|
|
||||||
|
|
||||||
# Define Call() which can be used in type-checking call-wrappers that behave
|
|
||||||
# similarly to functools.partial (in that they take a callable and some
|
|
||||||
# positional arguments to be passed to it).
|
|
||||||
|
|
||||||
# In type-checking land, We define several different _CallXArg classes
|
|
||||||
# corresponding to different argument counts and define Call() as an
|
|
||||||
# overloaded function which returns one of them based on how many args are
|
|
||||||
# passed.
|
|
||||||
|
|
||||||
# To use this, simply assign your call type to this Call for type checking:
|
|
||||||
# Example:
|
|
||||||
# class _MyCallWrapper:
|
|
||||||
# <runtime class defined here>
|
|
||||||
# if TYPE_CHECKING:
|
|
||||||
# MyCallWrapper = efro.call.Call
|
|
||||||
# else:
|
|
||||||
# MyCallWrapper = _MyCallWrapper
|
|
||||||
|
|
||||||
# Note that this setup currently only works with positional arguments; if you
|
|
||||||
# would like to pass args via keyword you can wrap a lambda or local function
|
|
||||||
# which takes keyword args and converts to a call containing keywords.
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
In1T = TypeVar('In1T')
|
|
||||||
In2T = TypeVar('In2T')
|
|
||||||
In3T = TypeVar('In3T')
|
|
||||||
In4T = TypeVar('In4T')
|
|
||||||
In5T = TypeVar('In5T')
|
|
||||||
In6T = TypeVar('In6T')
|
|
||||||
In7T = TypeVar('In7T')
|
|
||||||
OutT = TypeVar('OutT')
|
|
||||||
|
|
||||||
class _CallNoArgs(Generic[OutT]):
|
|
||||||
"""Single argument variant of call wrapper."""
|
|
||||||
|
|
||||||
def __init__(self, _call: Callable[[], OutT]): ...
|
|
||||||
|
|
||||||
def __call__(self) -> OutT: ...
|
|
||||||
|
|
||||||
class _Call1Arg(Generic[In1T, OutT]):
|
|
||||||
"""Single argument variant of call wrapper."""
|
|
||||||
|
|
||||||
def __init__(self, _call: Callable[[In1T], OutT]): ...
|
|
||||||
|
|
||||||
def __call__(self, _arg1: In1T) -> OutT: ...
|
|
||||||
|
|
||||||
class _Call2Args(Generic[In1T, In2T, OutT]):
|
|
||||||
"""Two argument variant of call wrapper"""
|
|
||||||
|
|
||||||
def __init__(self, _call: Callable[[In1T, In2T], OutT]): ...
|
|
||||||
|
|
||||||
def __call__(self, _arg1: In1T, _arg2: In2T) -> OutT: ...
|
|
||||||
|
|
||||||
class _Call3Args(Generic[In1T, In2T, In3T, OutT]):
|
|
||||||
"""Three argument variant of call wrapper"""
|
|
||||||
|
|
||||||
def __init__(self, _call: Callable[[In1T, In2T, In3T], OutT]): ...
|
|
||||||
|
|
||||||
def __call__(self, _arg1: In1T, _arg2: In2T, _arg3: In3T) -> OutT: ...
|
|
||||||
|
|
||||||
class _Call4Args(Generic[In1T, In2T, In3T, In4T, OutT]):
|
|
||||||
"""Four argument variant of call wrapper"""
|
|
||||||
|
|
||||||
def __init__(self, _call: Callable[[In1T, In2T, In3T, In4T], OutT]): ...
|
|
||||||
|
|
||||||
def __call__(
|
|
||||||
self, _arg1: In1T, _arg2: In2T, _arg3: In3T, _arg4: In4T
|
|
||||||
) -> OutT: ...
|
|
||||||
|
|
||||||
class _Call5Args(Generic[In1T, In2T, In3T, In4T, In5T, OutT]):
|
|
||||||
"""Five argument variant of call wrapper"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self, _call: Callable[[In1T, In2T, In3T, In4T, In5T], OutT]
|
|
||||||
): ...
|
|
||||||
|
|
||||||
def __call__(
|
|
||||||
self,
|
|
||||||
_arg1: In1T,
|
|
||||||
_arg2: In2T,
|
|
||||||
_arg3: In3T,
|
|
||||||
_arg4: In4T,
|
|
||||||
_arg5: In5T,
|
|
||||||
) -> OutT: ...
|
|
||||||
|
|
||||||
class _Call6Args(Generic[In1T, In2T, In3T, In4T, In5T, In6T, OutT]):
|
|
||||||
"""Six argument variant of call wrapper"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self, _call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T], OutT]
|
|
||||||
): ...
|
|
||||||
|
|
||||||
def __call__(
|
|
||||||
self,
|
|
||||||
_arg1: In1T,
|
|
||||||
_arg2: In2T,
|
|
||||||
_arg3: In3T,
|
|
||||||
_arg4: In4T,
|
|
||||||
_arg5: In5T,
|
|
||||||
_arg6: In6T,
|
|
||||||
) -> OutT: ...
|
|
||||||
|
|
||||||
class _Call7Args(Generic[In1T, In2T, In3T, In4T, In5T, In6T, In7T, OutT]):
|
|
||||||
"""Seven argument variant of call wrapper"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
_call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T, In7T], OutT],
|
|
||||||
): ...
|
|
||||||
|
|
||||||
def __call__(
|
|
||||||
self,
|
|
||||||
_arg1: In1T,
|
|
||||||
_arg2: In2T,
|
|
||||||
_arg3: In3T,
|
|
||||||
_arg4: In4T,
|
|
||||||
_arg5: In5T,
|
|
||||||
_arg6: In6T,
|
|
||||||
_arg7: In7T,
|
|
||||||
) -> OutT: ...
|
|
||||||
|
|
||||||
# No arg call; no args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(call: Callable[[], OutT]) -> _CallNoArgs[OutT]: ...
|
|
||||||
|
|
||||||
# 1 arg call; 1 arg bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(call: Callable[[In1T], OutT], arg1: In1T) -> _CallNoArgs[OutT]: ...
|
|
||||||
|
|
||||||
# 1 arg call; no args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(call: Callable[[In1T], OutT]) -> _Call1Arg[In1T, OutT]: ...
|
|
||||||
|
|
||||||
# 2 arg call; 2 args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T], OutT], arg1: In1T, arg2: In2T
|
|
||||||
) -> _CallNoArgs[OutT]: ...
|
|
||||||
|
|
||||||
# 2 arg call; 1 arg bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T], OutT], arg1: In1T
|
|
||||||
) -> _Call1Arg[In2T, OutT]: ...
|
|
||||||
|
|
||||||
# 2 arg call; no args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T], OutT]
|
|
||||||
) -> _Call2Args[In1T, In2T, OutT]: ...
|
|
||||||
|
|
||||||
# 3 arg call; 3 args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T, In3T], OutT],
|
|
||||||
arg1: In1T,
|
|
||||||
arg2: In2T,
|
|
||||||
arg3: In3T,
|
|
||||||
) -> _CallNoArgs[OutT]: ...
|
|
||||||
|
|
||||||
# 3 arg call; 2 args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T, In3T], OutT], arg1: In1T, arg2: In2T
|
|
||||||
) -> _Call1Arg[In3T, OutT]: ...
|
|
||||||
|
|
||||||
# 3 arg call; 1 arg bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T, In3T], OutT], arg1: In1T
|
|
||||||
) -> _Call2Args[In2T, In3T, OutT]: ...
|
|
||||||
|
|
||||||
# 3 arg call; no args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T, In3T], OutT]
|
|
||||||
) -> _Call3Args[In1T, In2T, In3T, OutT]: ...
|
|
||||||
|
|
||||||
# 4 arg call; 4 args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T, In3T, In4T], OutT],
|
|
||||||
arg1: In1T,
|
|
||||||
arg2: In2T,
|
|
||||||
arg3: In3T,
|
|
||||||
arg4: In4T,
|
|
||||||
) -> _CallNoArgs[OutT]: ...
|
|
||||||
|
|
||||||
# 4 arg call; 3 args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T, In3T, In4T], OutT],
|
|
||||||
arg1: In1T,
|
|
||||||
arg2: In2T,
|
|
||||||
arg3: In3T,
|
|
||||||
) -> _Call1Arg[In4T, OutT]: ...
|
|
||||||
|
|
||||||
# 4 arg call; 2 args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T, In3T, In4T], OutT],
|
|
||||||
arg1: In1T,
|
|
||||||
arg2: In2T,
|
|
||||||
) -> _Call2Args[In3T, In4T, OutT]: ...
|
|
||||||
|
|
||||||
# 4 arg call; 1 arg bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T, In3T, In4T], OutT],
|
|
||||||
arg1: In1T,
|
|
||||||
) -> _Call3Args[In2T, In3T, In4T, OutT]: ...
|
|
||||||
|
|
||||||
# 4 arg call; no args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T, In3T, In4T], OutT],
|
|
||||||
) -> _Call4Args[In1T, In2T, In3T, In4T, OutT]: ...
|
|
||||||
|
|
||||||
# 5 arg call; 5 args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T, In3T, In4T, In5T], OutT],
|
|
||||||
arg1: In1T,
|
|
||||||
arg2: In2T,
|
|
||||||
arg3: In3T,
|
|
||||||
arg4: In4T,
|
|
||||||
arg5: In5T,
|
|
||||||
) -> _CallNoArgs[OutT]: ...
|
|
||||||
|
|
||||||
# 6 arg call; 6 args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T], OutT],
|
|
||||||
arg1: In1T,
|
|
||||||
arg2: In2T,
|
|
||||||
arg3: In3T,
|
|
||||||
arg4: In4T,
|
|
||||||
arg5: In5T,
|
|
||||||
arg6: In6T,
|
|
||||||
) -> _CallNoArgs[OutT]: ...
|
|
||||||
|
|
||||||
# 7 arg call; 7 args bundled.
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
@overload
|
|
||||||
def Call(
|
|
||||||
call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T, In7T], OutT],
|
|
||||||
arg1: In1T,
|
|
||||||
arg2: In2T,
|
|
||||||
arg3: In3T,
|
|
||||||
arg4: In4T,
|
|
||||||
arg5: In5T,
|
|
||||||
arg6: In6T,
|
|
||||||
arg7: In7T,
|
|
||||||
) -> _CallNoArgs[OutT]: ...
|
|
||||||
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
def Call(*_args: Any, **_keywds: Any) -> Any: ...
|
|
||||||
|
|
||||||
# (Type-safe Partial)
|
|
||||||
# A convenient wrapper around functools.partial which adds type-safety
|
|
||||||
# (though it does not support keyword arguments).
|
|
||||||
tpartial = Call
|
|
||||||
else:
|
|
||||||
tpartial = functools.partial
|
tpartial = functools.partial
|
||||||
|
|||||||
@ -54,15 +54,19 @@ class _Outputter:
|
|||||||
def run(self) -> Any:
|
def run(self) -> Any:
|
||||||
"""Do the thing."""
|
"""Do the thing."""
|
||||||
|
|
||||||
|
obj = self._obj
|
||||||
|
|
||||||
|
# mypy workaround - if we check 'obj' here it assumes the
|
||||||
|
# isinstance call below fails.
|
||||||
assert dataclasses.is_dataclass(self._obj)
|
assert dataclasses.is_dataclass(self._obj)
|
||||||
|
|
||||||
# For special extended data types, call their 'will_output' callback.
|
# For special extended data types, call their 'will_output' callback.
|
||||||
# FIXME - should probably move this into _process_dataclass so it
|
# FIXME - should probably move this into _process_dataclass so it
|
||||||
# can work on nested values.
|
# can work on nested values.
|
||||||
if isinstance(self._obj, IOExtendedData):
|
if isinstance(obj, IOExtendedData):
|
||||||
self._obj.will_output()
|
obj.will_output()
|
||||||
|
|
||||||
return self._process_dataclass(type(self._obj), self._obj, '')
|
return self._process_dataclass(type(obj), obj, '')
|
||||||
|
|
||||||
def soft_default_check(
|
def soft_default_check(
|
||||||
self, value: Any, anntype: Any, fieldpath: str
|
self, value: Any, anntype: Any, fieldpath: str
|
||||||
|
|||||||
@ -10,13 +10,13 @@ import logging
|
|||||||
import datetime
|
import datetime
|
||||||
import itertools
|
import itertools
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
from functools import partial
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from typing import TYPE_CHECKING, Annotated, override
|
from typing import TYPE_CHECKING, Annotated, override
|
||||||
from threading import Thread, current_thread, Lock
|
from threading import Thread, current_thread, Lock
|
||||||
|
|
||||||
from efro.util import utc_now
|
from efro.util import utc_now
|
||||||
from efro.call import tpartial
|
|
||||||
from efro.terminal import Clr
|
from efro.terminal import Clr
|
||||||
from efro.dataclassio import ioprepped, IOAttrs, dataclass_to_json
|
from efro.dataclassio import ioprepped, IOAttrs, dataclass_to_json
|
||||||
|
|
||||||
@ -178,7 +178,7 @@ class LogHandler(logging.Handler):
|
|||||||
# process cached entries at the same time to ensure there are no
|
# process cached entries at the same time to ensure there are no
|
||||||
# race conditions that could cause entries to be skipped/etc.
|
# race conditions that could cause entries to be skipped/etc.
|
||||||
self._event_loop.call_soon_threadsafe(
|
self._event_loop.call_soon_threadsafe(
|
||||||
tpartial(self._add_callback_in_thread, call, feed_existing_logs)
|
partial(self._add_callback_in_thread, call, feed_existing_logs)
|
||||||
)
|
)
|
||||||
|
|
||||||
def _add_callback_in_thread(
|
def _add_callback_in_thread(
|
||||||
@ -342,7 +342,7 @@ class LogHandler(logging.Handler):
|
|||||||
if __debug__:
|
if __debug__:
|
||||||
formattime = echotime = time.monotonic()
|
formattime = echotime = time.monotonic()
|
||||||
self._event_loop.call_soon_threadsafe(
|
self._event_loop.call_soon_threadsafe(
|
||||||
tpartial(
|
partial(
|
||||||
self._emit_in_thread,
|
self._emit_in_thread,
|
||||||
record.name,
|
record.name,
|
||||||
record.levelno,
|
record.levelno,
|
||||||
@ -395,7 +395,7 @@ class LogHandler(logging.Handler):
|
|||||||
echotime = time.monotonic()
|
echotime = time.monotonic()
|
||||||
|
|
||||||
self._event_loop.call_soon_threadsafe(
|
self._event_loop.call_soon_threadsafe(
|
||||||
tpartial(
|
partial(
|
||||||
self._emit_in_thread,
|
self._emit_in_thread,
|
||||||
record.name,
|
record.name,
|
||||||
record.levelno,
|
record.levelno,
|
||||||
@ -427,7 +427,7 @@ class LogHandler(logging.Handler):
|
|||||||
# the bg event loop thread we've already got.
|
# the bg event loop thread we've already got.
|
||||||
self._last_slow_emit_warning_time = now
|
self._last_slow_emit_warning_time = now
|
||||||
self._event_loop.call_soon_threadsafe(
|
self._event_loop.call_soon_threadsafe(
|
||||||
tpartial(
|
partial(
|
||||||
logging.warning,
|
logging.warning,
|
||||||
'efro.log.LogHandler emit took too long'
|
'efro.log.LogHandler emit took too long'
|
||||||
' (%.2fs total; %.2fs format, %.2fs echo,'
|
' (%.2fs total; %.2fs format, %.2fs echo,'
|
||||||
@ -477,7 +477,7 @@ class LogHandler(logging.Handler):
|
|||||||
# another thread for each character. Perhaps should do some sort
|
# another thread for each character. Perhaps should do some sort
|
||||||
# of basic accumulation here?
|
# of basic accumulation here?
|
||||||
self._event_loop.call_soon_threadsafe(
|
self._event_loop.call_soon_threadsafe(
|
||||||
tpartial(self._file_write_in_thread, name, output)
|
partial(self._file_write_in_thread, name, output)
|
||||||
)
|
)
|
||||||
|
|
||||||
def _file_write_in_thread(self, name: str, output: str) -> None:
|
def _file_write_in_thread(self, name: str, output: str) -> None:
|
||||||
@ -537,7 +537,7 @@ class LogHandler(logging.Handler):
|
|||||||
"""Send raw stdout/stderr flush to the logger to be collated."""
|
"""Send raw stdout/stderr flush to the logger to be collated."""
|
||||||
|
|
||||||
self._event_loop.call_soon_threadsafe(
|
self._event_loop.call_soon_threadsafe(
|
||||||
tpartial(self._file_flush_in_thread, name)
|
partial(self._file_flush_in_thread, name)
|
||||||
)
|
)
|
||||||
|
|
||||||
def _file_flush_in_thread(self, name: str) -> None:
|
def _file_flush_in_thread(self, name: str) -> None:
|
||||||
@ -739,11 +739,7 @@ def setup_logging(
|
|||||||
# Optionally intercept Python's stdout/stderr output and generate
|
# Optionally intercept Python's stdout/stderr output and generate
|
||||||
# log entries from it.
|
# log entries from it.
|
||||||
if log_stdout_stderr:
|
if log_stdout_stderr:
|
||||||
sys.stdout = FileLogEcho( # type: ignore
|
sys.stdout = FileLogEcho(sys.stdout, 'stdout', loghandler)
|
||||||
sys.stdout, 'stdout', loghandler
|
sys.stderr = FileLogEcho(sys.stderr, 'stderr', loghandler)
|
||||||
)
|
|
||||||
sys.stderr = FileLogEcho( # type: ignore
|
|
||||||
sys.stderr, 'stderr', loghandler
|
|
||||||
)
|
|
||||||
|
|
||||||
return loghandler
|
return loghandler
|
||||||
|
|||||||
@ -52,6 +52,9 @@ class MessageSender:
|
|||||||
def __init__(self, protocol: MessageProtocol) -> None:
|
def __init__(self, protocol: MessageProtocol) -> None:
|
||||||
self.protocol = protocol
|
self.protocol = protocol
|
||||||
self._send_raw_message_call: Callable[[Any, str], str] | None = None
|
self._send_raw_message_call: Callable[[Any, str], str] | None = None
|
||||||
|
self._send_raw_message_ex_call: (
|
||||||
|
Callable[[Any, str, Message], str] | None
|
||||||
|
) = None
|
||||||
self._send_async_raw_message_call: (
|
self._send_async_raw_message_call: (
|
||||||
Callable[[Any, str], Awaitable[str]] | None
|
Callable[[Any, str], Awaitable[str]] | None
|
||||||
) = None
|
) = None
|
||||||
@ -80,6 +83,19 @@ class MessageSender:
|
|||||||
self._send_raw_message_call = call
|
self._send_raw_message_call = call
|
||||||
return call
|
return call
|
||||||
|
|
||||||
|
def send_ex_method(
|
||||||
|
self, call: Callable[[Any, str, Message], str]
|
||||||
|
) -> Callable[[Any, str, Message], str]:
|
||||||
|
"""Function decorator for extended send method.
|
||||||
|
|
||||||
|
Version of send_method which is also is passed the original
|
||||||
|
unencoded message; can be useful for cases where metadata is sent
|
||||||
|
along with messages referring to their payloads/etc.
|
||||||
|
"""
|
||||||
|
assert self._send_raw_message_ex_call is None
|
||||||
|
self._send_raw_message_ex_call = call
|
||||||
|
return call
|
||||||
|
|
||||||
def send_async_method(
|
def send_async_method(
|
||||||
self, call: Callable[[Any, str], Awaitable[str]]
|
self, call: Callable[[Any, str], Awaitable[str]]
|
||||||
) -> Callable[[Any, str], Awaitable[str]]:
|
) -> Callable[[Any, str], Awaitable[str]]:
|
||||||
@ -200,11 +216,20 @@ class MessageSender:
|
|||||||
for when message sending and response handling need to happen
|
for when message sending and response handling need to happen
|
||||||
in different contexts/threads.
|
in different contexts/threads.
|
||||||
"""
|
"""
|
||||||
if self._send_raw_message_call is None:
|
if (
|
||||||
|
self._send_raw_message_call is None
|
||||||
|
and self._send_raw_message_ex_call is None
|
||||||
|
):
|
||||||
raise RuntimeError('send() is unimplemented for this type.')
|
raise RuntimeError('send() is unimplemented for this type.')
|
||||||
|
|
||||||
msg_encoded = self._encode_message(bound_obj, message)
|
msg_encoded = self._encode_message(bound_obj, message)
|
||||||
try:
|
try:
|
||||||
|
if self._send_raw_message_ex_call is not None:
|
||||||
|
response_encoded = self._send_raw_message_ex_call(
|
||||||
|
bound_obj, msg_encoded, message
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
assert self._send_raw_message_call is not None
|
||||||
response_encoded = self._send_raw_message_call(
|
response_encoded = self._send_raw_message_call(
|
||||||
bound_obj, msg_encoded
|
bound_obj, msg_encoded
|
||||||
)
|
)
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import asyncio
|
|||||||
import logging
|
import logging
|
||||||
import weakref
|
import weakref
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
from functools import partial
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from threading import current_thread
|
from threading import current_thread
|
||||||
@ -84,7 +85,6 @@ def ssl_stream_writer_underlying_transport_info(
|
|||||||
|
|
||||||
def ssl_stream_writer_force_close_check(writer: asyncio.StreamWriter) -> None:
|
def ssl_stream_writer_force_close_check(writer: asyncio.StreamWriter) -> None:
|
||||||
"""Ensure a writer is closed; hacky workaround for odd hang."""
|
"""Ensure a writer is closed; hacky workaround for odd hang."""
|
||||||
from efro.call import tpartial
|
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
# Disabling for now..
|
# Disabling for now..
|
||||||
@ -100,9 +100,8 @@ def ssl_stream_writer_force_close_check(writer: asyncio.StreamWriter) -> None:
|
|||||||
raw_transport = getattr(sslproto, '_transport', None)
|
raw_transport = getattr(sslproto, '_transport', None)
|
||||||
if raw_transport is not None:
|
if raw_transport is not None:
|
||||||
Thread(
|
Thread(
|
||||||
target=tpartial(
|
target=partial(
|
||||||
_do_writer_force_close_check,
|
_do_writer_force_close_check, weakref.ref(raw_transport)
|
||||||
weakref.ref(raw_transport),
|
|
||||||
),
|
),
|
||||||
daemon=True,
|
daemon=True,
|
||||||
).start()
|
).start()
|
||||||
|
|||||||
@ -72,6 +72,7 @@ def _default_color_enabled() -> bool:
|
|||||||
import platform
|
import platform
|
||||||
|
|
||||||
# If our stdout is not attached to a terminal, go with no-color.
|
# If our stdout is not attached to a terminal, go with no-color.
|
||||||
|
assert sys.__stdout__ is not None
|
||||||
if not sys.__stdout__.isatty():
|
if not sys.__stdout__.isatty():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import os
|
|||||||
import time
|
import time
|
||||||
import weakref
|
import weakref
|
||||||
import datetime
|
import datetime
|
||||||
import functools
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import TYPE_CHECKING, cast, TypeVar, Generic, overload
|
from typing import TYPE_CHECKING, cast, TypeVar, Generic, overload
|
||||||
|
|
||||||
@ -16,8 +15,6 @@ if TYPE_CHECKING:
|
|||||||
import asyncio
|
import asyncio
|
||||||
from typing import Any, Callable, Literal
|
from typing import Any, Callable, Literal
|
||||||
|
|
||||||
from efro.call import Call as Call # 'as Call' so we re-export.
|
|
||||||
|
|
||||||
T = TypeVar('T')
|
T = TypeVar('T')
|
||||||
ValT = TypeVar('ValT')
|
ValT = TypeVar('ValT')
|
||||||
ArgT = TypeVar('ArgT')
|
ArgT = TypeVar('ArgT')
|
||||||
@ -36,13 +33,6 @@ _g_empty_weak_ref = weakref.ref(_EmptyObj())
|
|||||||
assert _g_empty_weak_ref() is None
|
assert _g_empty_weak_ref() is None
|
||||||
|
|
||||||
|
|
||||||
# TODO: kill this and just use efro.call.tpartial
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
Call = Call
|
|
||||||
else:
|
|
||||||
Call = functools.partial
|
|
||||||
|
|
||||||
|
|
||||||
def explicit_bool(val: bool) -> bool:
|
def explicit_bool(val: bool) -> bool:
|
||||||
"""Return a non-inferable boolean value.
|
"""Return a non-inferable boolean value.
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ from efrotools.util import readfile, writefile, replace_exact
|
|||||||
|
|
||||||
# Python version we build here (not necessarily same as we use in repo).
|
# Python version we build here (not necessarily same as we use in repo).
|
||||||
PY_VER_ANDROID = '3.12'
|
PY_VER_ANDROID = '3.12'
|
||||||
PY_VER_EXACT_ANDROID = '3.12.3'
|
PY_VER_EXACT_ANDROID = '3.12.4'
|
||||||
PY_VER_APPLE = '3.12'
|
PY_VER_APPLE = '3.12'
|
||||||
PY_VER_EXACT_APPLE = '3.12.0'
|
PY_VER_EXACT_APPLE = '3.12.0'
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ VERSION_MIN_TVOS = '9.0'
|
|||||||
#
|
#
|
||||||
# For now will try to ride out this 3.0 LTS version as long as possible.
|
# For now will try to ride out this 3.0 LTS version as long as possible.
|
||||||
OPENSSL_VER_APPLE = '3.0.12-1'
|
OPENSSL_VER_APPLE = '3.0.12-1'
|
||||||
OPENSSL_VER_ANDROID = '3.0.13'
|
OPENSSL_VER_ANDROID = '3.0.14'
|
||||||
|
|
||||||
LIBFFI_VER_APPLE = '3.4.4-1'
|
LIBFFI_VER_APPLE = '3.4.4-1'
|
||||||
BZIP2_VER_APPLE = '1.0.8-1'
|
BZIP2_VER_APPLE = '1.0.8-1'
|
||||||
@ -46,15 +46,16 @@ XZ_VER_APPLE = '5.4.4-1'
|
|||||||
|
|
||||||
# Android repo doesn't seem to be getting updated much so manually
|
# Android repo doesn't seem to be getting updated much so manually
|
||||||
# bumping various versions to keep things up to date.
|
# bumping various versions to keep things up to date.
|
||||||
|
ANDROID_API_VER = 23
|
||||||
ZLIB_VER_ANDROID = '1.3.1'
|
ZLIB_VER_ANDROID = '1.3.1'
|
||||||
XZ_VER_ANDROID = '5.4.4'
|
XZ_VER_ANDROID = '5.6.2'
|
||||||
BZIP2_VER_ANDROID = '1.0.8'
|
BZIP2_VER_ANDROID = '1.0.8'
|
||||||
GDBM_VER_ANDROID = '1.23'
|
GDBM_VER_ANDROID = '1.23'
|
||||||
LIBFFI_VER_ANDROID = '3.4.6'
|
LIBFFI_VER_ANDROID = '3.4.6'
|
||||||
LIBUUID_VER_ANDROID = ('2.39', '2.39.3')
|
LIBUUID_VER_ANDROID = ('2.39', '2.39.3')
|
||||||
NCURSES_VER_ANDROID = '6.4'
|
NCURSES_VER_ANDROID = '6.4'
|
||||||
READLINE_VER_ANDROID = '8.2'
|
READLINE_VER_ANDROID = '8.2'
|
||||||
SQLITE_VER_ANDROID = ('2024', '3450200')
|
SQLITE_VER_ANDROID = ('2024', '3460000')
|
||||||
|
|
||||||
# Filenames we prune from Python lib dirs in source repo to cut down on
|
# Filenames we prune from Python lib dirs in source repo to cut down on
|
||||||
# size.
|
# size.
|
||||||
@ -349,7 +350,7 @@ def build_android(rootdir: str, arch: str, debug: bool = False) -> None:
|
|||||||
# Set specific OpenSSL version.
|
# Set specific OpenSSL version.
|
||||||
ftxt = replace_exact(
|
ftxt = replace_exact(
|
||||||
ftxt,
|
ftxt,
|
||||||
"source = 'https://www.openssl.org/source/openssl-3.0.7.tar.gz'",
|
"source = 'https://www.openssl.org/source/openssl-3.0.12.tar.gz'",
|
||||||
f"source = 'https://www.openssl.org/"
|
f"source = 'https://www.openssl.org/"
|
||||||
f"source/openssl-{OPENSSL_VER_ANDROID}.tar.gz'",
|
f"source/openssl-{OPENSSL_VER_ANDROID}.tar.gz'",
|
||||||
count=1,
|
count=1,
|
||||||
@ -358,7 +359,7 @@ def build_android(rootdir: str, arch: str, debug: bool = False) -> None:
|
|||||||
# Set specific ZLib version.
|
# Set specific ZLib version.
|
||||||
ftxt = replace_exact(
|
ftxt = replace_exact(
|
||||||
ftxt,
|
ftxt,
|
||||||
"source = 'https://www.zlib.net/zlib-1.2.13.tar.gz'",
|
"source = 'https://www.zlib.net/zlib-1.3.1.tar.gz'",
|
||||||
f"source = 'https://www.zlib.net/zlib-{ZLIB_VER_ANDROID}.tar.gz'",
|
f"source = 'https://www.zlib.net/zlib-{ZLIB_VER_ANDROID}.tar.gz'",
|
||||||
count=1,
|
count=1,
|
||||||
)
|
)
|
||||||
@ -366,7 +367,7 @@ def build_android(rootdir: str, arch: str, debug: bool = False) -> None:
|
|||||||
# Set specific XZ version.
|
# Set specific XZ version.
|
||||||
ftxt = replace_exact(
|
ftxt = replace_exact(
|
||||||
ftxt,
|
ftxt,
|
||||||
"source = 'https://tukaani.org/xz/xz-5.2.7.tar.xz'",
|
"source = 'https://tukaani.org/xz/xz-5.6.2.tar.xz'",
|
||||||
f"source = 'https://tukaani.org/xz/xz-{XZ_VER_ANDROID}.tar.xz'",
|
f"source = 'https://tukaani.org/xz/xz-{XZ_VER_ANDROID}.tar.xz'",
|
||||||
count=1,
|
count=1,
|
||||||
)
|
)
|
||||||
@ -402,7 +403,7 @@ def build_android(rootdir: str, arch: str, debug: bool = False) -> None:
|
|||||||
ftxt = replace_exact(
|
ftxt = replace_exact(
|
||||||
ftxt,
|
ftxt,
|
||||||
"source = 'https://mirrors.edge.kernel.org/pub/linux/utils/"
|
"source = 'https://mirrors.edge.kernel.org/pub/linux/utils/"
|
||||||
"util-linux/v2.38/util-linux-2.38.1.tar.xz'",
|
"util-linux/v2.39/util-linux-2.39.2.tar.xz'",
|
||||||
"source = 'https://mirrors.edge.kernel.org/pub/linux/utils/"
|
"source = 'https://mirrors.edge.kernel.org/pub/linux/utils/"
|
||||||
f'util-linux/v{LIBUUID_VER_ANDROID[0]}/'
|
f'util-linux/v{LIBUUID_VER_ANDROID[0]}/'
|
||||||
f"util-linux-{LIBUUID_VER_ANDROID[1]}.tar.xz'",
|
f"util-linux-{LIBUUID_VER_ANDROID[1]}.tar.xz'",
|
||||||
@ -412,7 +413,7 @@ def build_android(rootdir: str, arch: str, debug: bool = False) -> None:
|
|||||||
# Set specific NCurses version.
|
# Set specific NCurses version.
|
||||||
ftxt = replace_exact(
|
ftxt = replace_exact(
|
||||||
ftxt,
|
ftxt,
|
||||||
"source = 'https://ftp.gnu.org/gnu/ncurses/ncurses-6.3.tar.gz'",
|
"source = 'https://ftp.gnu.org/gnu/ncurses/ncurses-6.4.tar.gz'",
|
||||||
"source = 'https://ftp.gnu.org/gnu/ncurses/"
|
"source = 'https://ftp.gnu.org/gnu/ncurses/"
|
||||||
f"ncurses-{NCURSES_VER_ANDROID}.tar.gz'",
|
f"ncurses-{NCURSES_VER_ANDROID}.tar.gz'",
|
||||||
count=1,
|
count=1,
|
||||||
@ -430,7 +431,7 @@ def build_android(rootdir: str, arch: str, debug: bool = False) -> None:
|
|||||||
# Set specific SQLite version.
|
# Set specific SQLite version.
|
||||||
ftxt = replace_exact(
|
ftxt = replace_exact(
|
||||||
ftxt,
|
ftxt,
|
||||||
"source = 'https://sqlite.org/2022/sqlite-autoconf-3390400.tar.gz'",
|
"source = 'https://sqlite.org/2024/sqlite-autoconf-3460000.tar.gz'",
|
||||||
"source = 'https://sqlite.org/"
|
"source = 'https://sqlite.org/"
|
||||||
f'{SQLITE_VER_ANDROID[0]}/'
|
f'{SQLITE_VER_ANDROID[0]}/'
|
||||||
f"sqlite-autoconf-{SQLITE_VER_ANDROID[1]}.tar.gz'",
|
f"sqlite-autoconf-{SQLITE_VER_ANDROID[1]}.tar.gz'",
|
||||||
@ -449,12 +450,29 @@ def build_android(rootdir: str, arch: str, debug: bool = False) -> None:
|
|||||||
|
|
||||||
writefile('Android/build_deps.py', ftxt)
|
writefile('Android/build_deps.py', ftxt)
|
||||||
|
|
||||||
|
ftxt = readfile('Android/util.py')
|
||||||
|
|
||||||
|
ftxt = replace_exact(
|
||||||
|
ftxt,
|
||||||
|
"choices=range(30, 40), dest='android_api_level'",
|
||||||
|
"choices=range(23, 40), dest='android_api_level'",
|
||||||
|
)
|
||||||
|
writefile('Android/util.py', ftxt)
|
||||||
|
|
||||||
# Tweak some things in the base build script; grab the right version
|
# Tweak some things in the base build script; grab the right version
|
||||||
# of Python and also inject some code to modify bits of python
|
# of Python and also inject some code to modify bits of python
|
||||||
# after it is extracted.
|
# after it is extracted.
|
||||||
ftxt = readfile('build.sh')
|
ftxt = readfile('build.sh')
|
||||||
|
|
||||||
ftxt = replace_exact(ftxt, 'PYVER=3.11.0', f'PYVER={PY_VER_EXACT_ANDROID}')
|
# Repo has gone 30+, but we currently want our own which is lower.
|
||||||
|
ftxt = replace_exact(
|
||||||
|
ftxt,
|
||||||
|
'COMMON_ARGS="--arch ${ARCH:-arm} --api ${ANDROID_API:-30}"',
|
||||||
|
'COMMON_ARGS="--arch ${ARCH:-arm} --api ${ANDROID_API:-'
|
||||||
|
+ str(ANDROID_API_VER)
|
||||||
|
+ '}"',
|
||||||
|
)
|
||||||
|
ftxt = replace_exact(ftxt, 'PYVER=3.12.4', f'PYVER={PY_VER_EXACT_ANDROID}')
|
||||||
ftxt = replace_exact(
|
ftxt = replace_exact(
|
||||||
ftxt,
|
ftxt,
|
||||||
' popd\n',
|
' popd\n',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user