mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-19 21:37:57 +08:00
Added a filter option to the public-party gather tab (and more general cleanup)
This commit is contained in:
parent
e2126fa0f7
commit
d3ec602329
@ -420,20 +420,20 @@
|
||||
"assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/04/0a/c4f7d2794b018593ab0b2bcb07f0",
|
||||
"assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/06/4d/18777c9a2eb2207a2891a2837a70",
|
||||
"assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/81/90/23ab1ecc8c55267bd904a9c05344",
|
||||
"assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/48/27/1b912861ed8d8795add395df41b6",
|
||||
"assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/05/20/767f42e4f0f289389cbdfb61eb10",
|
||||
"assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/de/25/74be4875c2a0e22b813a4e1a103b",
|
||||
"assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/49/5f/b29bb65369040892fe6601801637",
|
||||
"assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/c3/3f/c37ac3c65ac65f171af9313a502a",
|
||||
"assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/5a/9e/e8cad6f08b2b19803ab20fdc80d0",
|
||||
"assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/c1/2b/54aeb92c709c4af443f4a9013b3d",
|
||||
"assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/69/cc/f8bdd1e83162481c6bf2a78cb5e0",
|
||||
"assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/7c/b5/ddf2aedf7a7821b134d3663ae320",
|
||||
"assets/build/ba_data/data/languages/croatian.json": "https://files.ballistica.net/cache/ba1/56/02/c22deb7174aabdcbffe1da23e484",
|
||||
"assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/97/6c/61de67c477c98b7c4fddd22e6ae0",
|
||||
"assets/build/ba_data/data/languages/danish.json": "https://files.ballistica.net/cache/ba1/3f/46/e4da3c1d2b0ebf916df55c608b28",
|
||||
"assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/d1/07/37b7adc3dbec7328d26c5325f212",
|
||||
"assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/d4/5b/fbd64cf1846340db0606824568c2",
|
||||
"assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/3b/0d/eb66b073295cacde00e5d054dbae",
|
||||
"assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/6e/fd/685a4e1da031474d47a1d9eb2731",
|
||||
"assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/e3/6d/63e78b12ae9d99e0929671f52c12",
|
||||
"assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/3f/62/4eedf8cfad2e5f7ff2136ec19277",
|
||||
"assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/97/3a/b6746b7f89af424584c794c4d11f",
|
||||
"assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/93/31/66df9784a606600b7933bcb8ffa1",
|
||||
"assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/a4/2c/8c43b338be2367441b87378e19c1",
|
||||
"assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/d5/19/5e450e35b83fe68722330d03b896",
|
||||
"assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/87/2d/027aa239eb66ea8f496562f4fd83",
|
||||
@ -442,12 +442,12 @@
|
||||
"assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/0a/84/bbb6ed2abf66509406f534cbbb52",
|
||||
"assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/1e/67/f8d1d6579698c10af9da2ecb62d9",
|
||||
"assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/88/4b/6745a1a58220772e259f0de51196",
|
||||
"assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/42/b5/7612cce15fe4555889585108b3ef",
|
||||
"assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/59/49/d75f2b9916541bd2be8c49a5171f",
|
||||
"assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/44/3c/7cc06ca8d5475e1687d0ed05bdbf",
|
||||
"assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/d4/bb/69c09648f60e36f35bd38be20cf8",
|
||||
"assets/build/ba_data/data/languages/serbian.json": "https://files.ballistica.net/cache/ba1/e7/d8/ace32888249fc8b8cca0e2edb48b",
|
||||
"assets/build/ba_data/data/languages/slovak.json": "https://files.ballistica.net/cache/ba1/b7/0a/fab820b96e7aa587ee56427ecdc2",
|
||||
"assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/32/0e/ac0b8dcef065d7934a6bc30d7560",
|
||||
"assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/2a/35/eab086a95c41287fa0a856e59fb6",
|
||||
"assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/50/9f/be006ba19be6a69a57837eb6dca0",
|
||||
"assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/9a/8a/f7b2521c1904ffc83262dff1e11b",
|
||||
"assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/26/62/a072404c02c576a5c3f09059b582",
|
||||
@ -3932,24 +3932,24 @@
|
||||
"assets/build/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/b5/85/f8b6d0558ddb87267f34254b1450",
|
||||
"assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e",
|
||||
"assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f",
|
||||
"build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/57/c4/65b46cdf99edf156347ed3381223",
|
||||
"build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/24/06/49b1e54e764a57c0c925cd48d71e",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b1/e9/12e2965cd54d3cbc02f795222441",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/94/e8/4b12bc80273d1527e2a8210cf090",
|
||||
"build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b3/f2/25d7adfb561752522269fe0677e7",
|
||||
"build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/e4/37/aa7613de3f87a18a5f981f73786a",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/de/7a/54548afb27b6027ff7c10c41838f",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6b/f3/8e66e8bfdc5ca8fbe5b61838c7b8",
|
||||
"build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a0/af/d65a065f6da183970c71c2f479d7",
|
||||
"build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/38/bc/dc1d1354f9a81f9e0120a3de63a7",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/da/9a/0c9617ad9d98f912db70b91dfd20",
|
||||
"build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/53/28/8e4c340f2accc1cf3dfb600a2981",
|
||||
"build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/29/71/f22b8e8297b5fcda6a055501dd9a",
|
||||
"build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/e3/4b/cd188b8da52207463fdeb6176704",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/10/52/435cd568d1690c023b8c1aebafff",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6d/b7/57677f9d991f046f6b784bdd6321",
|
||||
"build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/0c/77/4c9ff1fa0630936563f0f7c9fee4",
|
||||
"build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/80/25/43012563e7b0db4a76c431fcbb40",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b3/e5/e2da42b1e5a6031487333c72da70",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e1/89/0491751bb4d33a3d3ffc758a6b20",
|
||||
"build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/3a/c5/623f2be3c9f061941c0ed1543588",
|
||||
"build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/47/54/9f7775a0cdf008be499e80d62a8f",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/2b/29/060806ab4ed3b47f3890b14a36e9",
|
||||
"build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/e4/7e/943f5f6a581e4fccfe763b20fd30",
|
||||
"build/prefab/lib/linux_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/80/d2/d1c6766cf07f4c4828bbd5899f79",
|
||||
"build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/de/49/2cfc34ac856737d903954db5571b",
|
||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/17/9a/fa66aafdf31fc9bdd92ce382c619",
|
||||
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/86/de/7d9c9a2b7bba34c630130ed759c9",
|
||||
"build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7c/71/59aa912540741d36fca95baf0cdf",
|
||||
"build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f7/0e/da229849278095b6dcf26432909a",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/58/e2/e78c6993c58dae2a94aa1c36139b",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8b/28/742e9c33d64ceeb5e1ff87da5577"
|
||||
"build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/11/ca/ef8dc06a074606894db186954d49",
|
||||
"build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/24/4d/f64b747dbea2588e6ffe8d3e24e8",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/35/5f/e588c08ae05abeb233bb803c695b",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c6/a4/77a6648afb78e6b452bcccad2c8e"
|
||||
}
|
||||
13
.idea/dictionaries/ericf.xml
generated
13
.idea/dictionaries/ericf.xml
generated
@ -30,8 +30,8 @@
|
||||
<w>achname</w>
|
||||
<w>achs</w>
|
||||
<w>acinstance</w>
|
||||
<w>ack</w>
|
||||
<w>ack'ed</w>
|
||||
<w>ack</w>
|
||||
<w>acked</w>
|
||||
<w>acks</w>
|
||||
<w>acnt</w>
|
||||
@ -153,8 +153,8 @@
|
||||
<w>bacommon</w>
|
||||
<w>badguy</w>
|
||||
<w>bafoundation</w>
|
||||
<w>ballistica</w>
|
||||
<w>ballistica's</w>
|
||||
<w>ballistica</w>
|
||||
<w>ballisticacore</w>
|
||||
<w>ballisticacorecb</w>
|
||||
<w>bamaster</w>
|
||||
@ -703,6 +703,7 @@
|
||||
<w>filterlines</w>
|
||||
<w>filterpath</w>
|
||||
<w>filterpaths</w>
|
||||
<w>filterval</w>
|
||||
<w>finalhash</w>
|
||||
<w>finalmaterials</w>
|
||||
<w>finfo</w>
|
||||
@ -801,8 +802,8 @@
|
||||
<w>gamedata</w>
|
||||
<w>gameinstance</w>
|
||||
<w>gamemap</w>
|
||||
<w>gamepad</w>
|
||||
<w>gamepad's</w>
|
||||
<w>gamepad</w>
|
||||
<w>gamepadadvanced</w>
|
||||
<w>gamepads</w>
|
||||
<w>gamepadselect</w>
|
||||
@ -1191,8 +1192,8 @@
|
||||
<w>lsqlite</w>
|
||||
<w>lssl</w>
|
||||
<w>lstart</w>
|
||||
<w>lstr</w>
|
||||
<w>lstr's</w>
|
||||
<w>lstr</w>
|
||||
<w>lstrs</w>
|
||||
<w>lsval</w>
|
||||
<w>ltex</w>
|
||||
@ -1828,8 +1829,8 @@
|
||||
<w>sessionname</w>
|
||||
<w>sessionplayer</w>
|
||||
<w>sessionplayers</w>
|
||||
<w>sessionteam</w>
|
||||
<w>sessionteam's</w>
|
||||
<w>sessionteam</w>
|
||||
<w>sessionteams</w>
|
||||
<w>sessiontype</w>
|
||||
<w>setactivity</w>
|
||||
@ -2164,8 +2165,8 @@
|
||||
<w>txtw</w>
|
||||
<w>typeargs</w>
|
||||
<w>typecheck</w>
|
||||
<w>typechecker</w>
|
||||
<w>typechecker's</w>
|
||||
<w>typechecker</w>
|
||||
<w>typedval</w>
|
||||
<w>typeshed</w>
|
||||
<w>typestr</w>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
### 1.5.27 (20224)
|
||||
### 1.5.27 (20231)
|
||||
- Language functionality has been consolidated into a LanguageSubsystem object at ba.app.lang
|
||||
- ba.get_valid_languages() is now an attr: ba.app.lang.available_languages
|
||||
- Achievement functionality has been consolidated into an AchievementSubsystem object at ba.app.ach
|
||||
@ -9,6 +9,8 @@
|
||||
- Revamped tab-button functionality into a cleaner type-safe class (bastd.ui.tabs.TabRow)
|
||||
- Split Gather-Window tabs out into individual classes for future improvements (bastd.ui.gather.*)
|
||||
- Added the ability to disable ticket-purchasing UIs for builds (ba.app.allow_ticket_purchases)
|
||||
- Reworked the public party gather section to perform better; it should no longer have to rebuild the list from scratch each time the UI is visited.
|
||||
- Added a filter option to the public party list (sorry it has taken so long).
|
||||
|
||||
### 1.5.26 (20217)
|
||||
- Simplified licensing header on python scripts.
|
||||
|
||||
@ -27,7 +27,7 @@ The Ballistica project is the foundation for the next generation of [BombSquad](
|
||||
* A: No, BombSquad is still BombSquad. 'Ballistica' is simply the new name for the engine/app-framework. This way it can also be used for other game/app projects without causing confusion (though that is mostly theoretical at this point). As a modder, the biggest changes you will notice is 'ba' prefixes in the API instead of 'bs' and naming that follows Python PEP8 standards (underscores and lowercase instead of camel-case). So `bs.playSound(mySound)` in the old system might look like `ba.playsound(my_sound)` in the new. You may also see the word 'BallisticaCore' show up various places, which in actual releases gets replaced by 'BombSquad'.
|
||||
|
||||
* **Q: Does this mean BombSquad is open source?**
|
||||
* A: Yes and no. All code contained in this repo is MIT licensed and free for use anywhere. This includes game scripts, pipeline tools, etc. Over time I hope to expand this to include at least some of the binary engine sources. Anything not directly contained in this repository, however, even if automatically downloaded by build scripts, is still proprietary and cannot be redistributed without explicit consent. This includes assets and game binaries. So in a nutshell: create and share mods to your heart's content, but please don't distribute your own complete copies of the game without permission. Please email support@froemling.net if you have any questions about this.
|
||||
* A: Yes and no. All code contained in this repo is MIT licensed and free for use anywhere. This includes game scripts, pipeline tools, and most of the binary engine sources. Anything not directly contained in this repository, however, even if automatically downloaded by build scripts, is still proprietary and cannot be redistributed without explicit consent. This includes assets and game libraries/binaries. So in a nutshell: create and share mods to your heart's content, but please don't distribute your own complete copies of the game without permission. Please email support@froemling.net if you have any questions about this.
|
||||
|
||||
* **Q: Will my existing BombSquad 1.4.x mods still work?**
|
||||
* A: Not 'out of the box'. All mods will need to be explicitly updated to work with the new ballistica apis in 1.5+. This may or may not be a significant amount of work depending on the mod. I would highly suggest tinkering around with some of the new features in 1.5 such as type-safe Python and dynamic assets before attempting to port any old mods, as some things are done significantly differently now. You may also want to consider simply sticking with 1.4 builds for a while longer, especially for server duties, since they will remain fully compatible with clients running 1.5. The new ballistica APIs may be changing significantly for at least a while as the dust settles, but they will be worth switching to in the end, I promise!
|
||||
|
||||
@ -2622,6 +2622,7 @@ def hscrollwidget(edit: ba.Widget = None,
|
||||
border_opacity: float = None,
|
||||
simple_culling_h: float = None,
|
||||
claims_left_right: bool = None,
|
||||
claims_up_down: bool = None,
|
||||
claims_tab: bool = None) -> ba.Widget:
|
||||
"""hscrollwidget(edit: ba.Widget = None, parent: ba.Widget = None,
|
||||
size: Sequence[float] = None, position: Sequence[float] = None,
|
||||
@ -2632,6 +2633,7 @@ def hscrollwidget(edit: ba.Widget = None,
|
||||
highlight: bool = None, border_opacity: float = None,
|
||||
simple_culling_h: float = None,
|
||||
claims_left_right: bool = None,
|
||||
claims_up_down: bool = None,
|
||||
claims_tab: bool = None) -> ba.Widget
|
||||
|
||||
Create or edit a horizontal scroll widget.
|
||||
@ -3388,6 +3390,7 @@ def scrollwidget(edit: ba.Widget = None,
|
||||
simple_culling_v: float = None,
|
||||
selection_loops_to_parent: bool = None,
|
||||
claims_left_right: bool = None,
|
||||
claims_up_down: bool = None,
|
||||
claims_tab: bool = None,
|
||||
autoselect: bool = None) -> ba.Widget:
|
||||
"""scrollwidget(edit: ba.Widget = None, parent: ba.Widget = None,
|
||||
@ -3399,6 +3402,7 @@ def scrollwidget(edit: ba.Widget = None,
|
||||
simple_culling_v: float = None,
|
||||
selection_loops_to_parent: bool = None,
|
||||
claims_left_right: bool = None,
|
||||
claims_up_down: bool = None,
|
||||
claims_tab: bool = None,
|
||||
autoselect: bool = None) -> ba.Widget
|
||||
|
||||
|
||||
@ -45,6 +45,7 @@ class MainMenuActivity(ba.Activity[ba.Player, ba.Team]):
|
||||
|
||||
if not ba.app.toolbar_test:
|
||||
color = ((1.0, 1.0, 1.0, 1.0) if vr_mode else (0.5, 0.6, 0.5, 0.6))
|
||||
|
||||
# FIXME: Need a node attr for vr-specific-scale.
|
||||
scale = (0.9 if
|
||||
(app.ui.uiscale is ba.UIScale.SMALL or vr_mode) else 0.7)
|
||||
|
||||
@ -20,6 +20,7 @@ if TYPE_CHECKING:
|
||||
from typing import Callable, Any, Optional, Dict, Union, Tuple, List
|
||||
from bastd.ui.gather import GatherWindow
|
||||
|
||||
# Print a bit of info about pings, queries, etc.
|
||||
DEBUG_SERVER_COMMUNICATION = False
|
||||
|
||||
|
||||
@ -58,6 +59,7 @@ class State:
|
||||
sub_tab: SubTabType = SubTabType.JOIN
|
||||
parties: Optional[List[PartyEntry]] = None
|
||||
next_entry_index: int = 0
|
||||
filter_value: str = ''
|
||||
|
||||
|
||||
class SelectionComponent(Enum):
|
||||
@ -186,6 +188,7 @@ class PublicGatherTab(GatherTab):
|
||||
self._container: Optional[ba.Widget] = None
|
||||
self._join_text: Optional[ba.Widget] = None
|
||||
self._host_text: Optional[ba.Widget] = None
|
||||
self._filter_text: Optional[ba.Widget] = None
|
||||
self._local_address: Optional[str] = None
|
||||
self._last_connect_attempt_time: Optional[float] = None
|
||||
self._sub_tab: SubTabType = SubTabType.JOIN
|
||||
@ -207,7 +210,8 @@ class PublicGatherTab(GatherTab):
|
||||
self._first_server_list_rebuild_time: Optional[float] = None
|
||||
self._next_entry_index = 0
|
||||
self._have_valid_server_list = False
|
||||
self._built_join_list = False
|
||||
self._server_list_dirty = True
|
||||
self._filter_value = ''
|
||||
|
||||
def on_activate(
|
||||
self,
|
||||
@ -278,7 +282,6 @@ class PublicGatherTab(GatherTab):
|
||||
if self._local_address is None:
|
||||
AddrFetchThread(ba.WeakCall(self._fetch_local_addr_cb)).start()
|
||||
|
||||
assert self._sub_tab is not None
|
||||
self._set_sub_tab(self._sub_tab, region_width, region_height)
|
||||
self._update_timer = ba.Timer(0.2,
|
||||
ba.WeakCall(self._update),
|
||||
@ -292,13 +295,15 @@ class PublicGatherTab(GatherTab):
|
||||
|
||||
def save_state(self) -> None:
|
||||
|
||||
# Save off a small number of parties with the lowest ping; this
|
||||
# should be most of the ones that matter and will keep things
|
||||
# a reasonable size.
|
||||
# Save off a small number of parties with the lowest ping; we'll
|
||||
# display these immediately when our UI comes back up which should
|
||||
# be enough to make things feel nice and crisp while we do a full
|
||||
# server re-query or whatnot.
|
||||
ba.app.ui.window_states[self.__class__.__name__] = State(
|
||||
sub_tab=self._sub_tab,
|
||||
parties=[copy.copy(p) for p in self._get_ordered_parties()[:20]],
|
||||
next_entry_index=self._next_entry_index)
|
||||
parties=[copy.copy(p) for p in self._get_ordered_parties()[:40]],
|
||||
next_entry_index=self._next_entry_index,
|
||||
filter_value=self._filter_value)
|
||||
|
||||
def restore_state(self) -> None:
|
||||
state = ba.app.ui.window_states.get(self.__class__.__name__)
|
||||
@ -307,7 +312,7 @@ class PublicGatherTab(GatherTab):
|
||||
assert isinstance(state, State)
|
||||
self._sub_tab = state.sub_tab
|
||||
|
||||
# Restore the parties we stored...
|
||||
# Restore the parties we stored.
|
||||
if state.parties:
|
||||
self._parties = {
|
||||
f'{p.address}_{p.port}': copy.copy(p)
|
||||
@ -315,6 +320,7 @@ class PublicGatherTab(GatherTab):
|
||||
}
|
||||
self._next_entry_index = state.next_entry_index
|
||||
self._have_valid_server_list = True
|
||||
self._filter_value = state.filter_value
|
||||
|
||||
def _set_sub_tab(self,
|
||||
value: SubTabType,
|
||||
@ -346,16 +352,9 @@ class PublicGatherTab(GatherTab):
|
||||
if widget and widget not in {self._host_text, self._join_text}:
|
||||
widget.delete()
|
||||
|
||||
c_width = region_width
|
||||
c_height = region_height - 20
|
||||
sub_scroll_height = c_height - 90
|
||||
sub_scroll_width = 830
|
||||
v = c_height - 35
|
||||
v -= 25
|
||||
if value is SubTabType.JOIN:
|
||||
self._build_join_tab(v, sub_scroll_width, sub_scroll_height,
|
||||
c_width, c_height)
|
||||
self._built_join_list = False
|
||||
self._build_join_tab(region_width, region_height)
|
||||
self._server_list_dirty = True
|
||||
|
||||
# If we've not yet successfully fetched a server list,
|
||||
# force an attempt now and show the user a 'loading...' status.
|
||||
@ -372,12 +371,36 @@ class PublicGatherTab(GatherTab):
|
||||
ba.textwidget(edit=self._join_status_text, text=join_status_str)
|
||||
|
||||
if value is SubTabType.HOST:
|
||||
self._build_host_tab(v, sub_scroll_width, sub_scroll_height,
|
||||
c_width, c_height)
|
||||
self._build_host_tab(region_width, region_height)
|
||||
|
||||
def _build_join_tab(self, region_width: float,
|
||||
region_height: float) -> None:
|
||||
c_width = region_width
|
||||
c_height = region_height - 20
|
||||
sub_scroll_height = c_height - 125
|
||||
sub_scroll_width = 830
|
||||
v = c_height - 35
|
||||
v -= 60
|
||||
self._filter_text = ba.textwidget(parent=self._container,
|
||||
text=self._filter_value,
|
||||
size=(350, 45),
|
||||
position=(290, v - 10),
|
||||
h_align='left',
|
||||
v_align='center',
|
||||
editable=True)
|
||||
ba.widget(edit=self._filter_text, up_widget=self._join_text)
|
||||
ba.textwidget(text=ba.Lstr(resource='filterText'),
|
||||
parent=self._container,
|
||||
size=(0, 0),
|
||||
position=(270, v + 15),
|
||||
maxwidth=100,
|
||||
scale=0.8,
|
||||
color=(0.5, 0.5, 0.5),
|
||||
flatness=1.0,
|
||||
shadow=0.0,
|
||||
h_align='right',
|
||||
v_align='center')
|
||||
|
||||
def _build_join_tab(self, v: float, sub_scroll_width: float,
|
||||
sub_scroll_height: float, c_width: float,
|
||||
c_height: float) -> None:
|
||||
ba.textwidget(text=ba.Lstr(resource='nameText'),
|
||||
parent=self._container,
|
||||
size=(0, 0),
|
||||
@ -412,19 +435,18 @@ class PublicGatherTab(GatherTab):
|
||||
h_align='center',
|
||||
v_align='center')
|
||||
v -= sub_scroll_height + 23
|
||||
|
||||
self._host_scrollwidget = scrollw = ba.scrollwidget(
|
||||
parent=self._container,
|
||||
simple_culling_v=10,
|
||||
position=((c_width - sub_scroll_width) * 0.5, v),
|
||||
size=(sub_scroll_width, sub_scroll_height),
|
||||
claims_up_down=False,
|
||||
claims_left_right=True,
|
||||
autoselect=True)
|
||||
self._join_list_column = ba.containerwidget(parent=scrollw,
|
||||
background=False,
|
||||
size=(400, 400),
|
||||
claims_left_right=True)
|
||||
|
||||
self._join_status_text = ba.textwidget(parent=self._container,
|
||||
text='',
|
||||
size=(0, 0),
|
||||
@ -438,10 +460,12 @@ class PublicGatherTab(GatherTab):
|
||||
position=(c_width * 0.5,
|
||||
c_height * 0.5))
|
||||
|
||||
def _build_host_tab(self, v: float, sub_scroll_width: float,
|
||||
sub_scroll_height: float, c_width: float,
|
||||
c_height: float) -> None:
|
||||
del sub_scroll_width, sub_scroll_height, c_height # Unused.
|
||||
def _build_host_tab(self, region_width: float,
|
||||
region_height: float) -> None:
|
||||
c_width = region_width
|
||||
c_height = region_height - 20
|
||||
v = c_height - 35
|
||||
v -= 25
|
||||
is_public_enabled = _ba.get_public_party_enabled()
|
||||
v -= 30
|
||||
party_name_text = ba.Lstr(
|
||||
@ -584,7 +608,7 @@ class PublicGatherTab(GatherTab):
|
||||
since_first = cur_time - self._first_server_list_rebuild_time
|
||||
wait_time = (1.0 if since_first < 2.0 else
|
||||
2.5 if since_first < 10.0 else 5.0)
|
||||
if (self._built_join_list
|
||||
if (not self._server_list_dirty
|
||||
and self._last_server_list_update_time is not None
|
||||
and cur_time - self._last_server_list_update_time < wait_time):
|
||||
return
|
||||
@ -595,7 +619,7 @@ class PublicGatherTab(GatherTab):
|
||||
return
|
||||
|
||||
self._last_server_list_update_time = cur_time
|
||||
self._built_join_list = True
|
||||
self._server_list_dirty = False
|
||||
|
||||
with ba.Context('ui'):
|
||||
|
||||
@ -605,6 +629,14 @@ class PublicGatherTab(GatherTab):
|
||||
|
||||
ordered_parties = self._get_ordered_parties()
|
||||
|
||||
# If we've got a filter, filter them.
|
||||
if self._filter_value:
|
||||
# Let's do case-insensitive searching.
|
||||
filterval = self._filter_value.lower()
|
||||
ordered_parties = [
|
||||
p for p in ordered_parties if filterval in p.name.lower()
|
||||
]
|
||||
|
||||
sub_scroll_width = 830
|
||||
lineheight = 42
|
||||
sub_scroll_height = lineheight * len(ordered_parties) + 50
|
||||
@ -699,10 +731,10 @@ class PublicGatherTab(GatherTab):
|
||||
if first:
|
||||
if party.stats_button:
|
||||
ba.widget(edit=party.stats_button,
|
||||
up_widget=self._join_text)
|
||||
up_widget=self._filter_text)
|
||||
if party.name_widget:
|
||||
ba.widget(edit=party.name_widget,
|
||||
up_widget=self._join_text)
|
||||
up_widget=self._filter_text)
|
||||
first = False
|
||||
|
||||
party.size_widget = ba.textwidget(
|
||||
@ -820,54 +852,70 @@ class PublicGatherTab(GatherTab):
|
||||
_ba.set_public_party_name(name)
|
||||
|
||||
if self._sub_tab is SubTabType.JOIN:
|
||||
now = ba.time(ba.TimeType.REAL)
|
||||
|
||||
# Fire off a new public-party query periodically.
|
||||
if (self._last_server_list_query_time is None
|
||||
or now - self._last_server_list_query_time > 0.001 *
|
||||
_ba.get_account_misc_read_val('pubPartyRefreshMS', 10000)):
|
||||
self._last_server_list_query_time = now
|
||||
# If our filter value has changed, refresh the list
|
||||
# using the new one.
|
||||
text = self._filter_text
|
||||
if text:
|
||||
filter_value = cast(str, ba.textwidget(query=text))
|
||||
if filter_value != self._filter_value:
|
||||
self._filter_value = filter_value
|
||||
self._server_list_dirty = True
|
||||
self._update_server_list()
|
||||
|
||||
self._query_party_list_periodically()
|
||||
self._ping_parties_periodically()
|
||||
|
||||
def _query_party_list_periodically(self) -> None:
|
||||
now = ba.time(ba.TimeType.REAL)
|
||||
|
||||
# Fire off a new public-party query periodically.
|
||||
if (self._last_server_list_query_time is None
|
||||
or now - self._last_server_list_query_time > 0.001 *
|
||||
_ba.get_account_misc_read_val('pubPartyRefreshMS', 10000)):
|
||||
self._last_server_list_query_time = now
|
||||
if DEBUG_SERVER_COMMUNICATION:
|
||||
print('REQUESTING SERVER LIST')
|
||||
_ba.add_transaction(
|
||||
{
|
||||
'type': 'PUBLIC_PARTY_QUERY',
|
||||
'proto': ba.app.protocol_version,
|
||||
'lang': ba.app.lang.language
|
||||
},
|
||||
callback=ba.WeakCall(self._on_public_party_query_result))
|
||||
_ba.run_transactions()
|
||||
|
||||
def _ping_parties_periodically(self) -> None:
|
||||
now = ba.time(ba.TimeType.REAL)
|
||||
|
||||
# Go through our existing public party entries firing off pings
|
||||
# for any that have timed out.
|
||||
for party in list(self._parties.values()):
|
||||
if party.next_ping_time <= now and ba.app.ping_thread_count < 15:
|
||||
|
||||
# Crank the interval up for high-latency or non-responding
|
||||
# parties to save us some useless work.
|
||||
mult = 1
|
||||
if party.ping_responses == 0:
|
||||
if party.ping_attempts > 4:
|
||||
mult = 10
|
||||
elif party.ping_attempts > 2:
|
||||
mult = 5
|
||||
if party.ping is not None:
|
||||
mult = (10 if party.ping > 300 else
|
||||
5 if party.ping > 150 else 2)
|
||||
|
||||
interval = party.ping_interval * mult
|
||||
if DEBUG_SERVER_COMMUNICATION:
|
||||
print('REQUESTING SERVER LIST')
|
||||
_ba.add_transaction(
|
||||
{
|
||||
'type': 'PUBLIC_PARTY_QUERY',
|
||||
'proto': ba.app.protocol_version,
|
||||
'lang': ba.app.lang.language
|
||||
},
|
||||
callback=ba.WeakCall(self._on_public_party_query_result))
|
||||
_ba.run_transactions()
|
||||
print(f'pinging #{party.index} cur={party.ping} '
|
||||
f'interval={interval} '
|
||||
f'({party.ping_responses}/{party.ping_attempts})')
|
||||
|
||||
# Go through our existing public party entries firing off pings
|
||||
# for any that have timed out.
|
||||
for party in list(self._parties.values()):
|
||||
if (party.next_ping_time <= now
|
||||
and ba.app.ping_thread_count < 15):
|
||||
party.next_ping_time = now + party.ping_interval * mult
|
||||
party.ping_attempts += 1
|
||||
|
||||
# Crank the interval up for high-latency or non-responding
|
||||
# parties to save us some useless work.
|
||||
mult = 1
|
||||
if party.ping_responses == 0:
|
||||
if party.ping_attempts > 4:
|
||||
mult = 10
|
||||
elif party.ping_attempts > 2:
|
||||
mult = 5
|
||||
if party.ping is not None:
|
||||
mult = (10 if party.ping > 300 else
|
||||
5 if party.ping > 150 else 2)
|
||||
|
||||
interval = party.ping_interval * mult
|
||||
if DEBUG_SERVER_COMMUNICATION:
|
||||
print(
|
||||
f'pinging #{party.index} cur={party.ping} '
|
||||
f'interval={interval} '
|
||||
f'({party.ping_responses}/{party.ping_attempts})')
|
||||
|
||||
party.next_ping_time = now + party.ping_interval * mult
|
||||
party.ping_attempts += 1
|
||||
|
||||
PingThread(party.address, party.port,
|
||||
ba.WeakCall(self._ping_callback)).start()
|
||||
PingThread(party.address, party.port,
|
||||
ba.WeakCall(self._ping_callback)).start()
|
||||
|
||||
def _ping_callback(self, address: str, port: Optional[int],
|
||||
result: Optional[int]) -> None:
|
||||
|
||||
@ -38,8 +38,11 @@ class MainMenuWindow(ba.Window):
|
||||
toolbar_visibility='menu_minimal_no_back' if self.
|
||||
_in_game else 'menu_minimal_no_back'))
|
||||
|
||||
# Grab this stuff in case it changes.
|
||||
self._is_demo = ba.app.demo_mode
|
||||
self._is_arcade = ba.app.arcade_mode
|
||||
self._is_iircade = ba.app.iircade_mode
|
||||
|
||||
self._tdelay = 0.0
|
||||
self._t_delay_inc = 0.02
|
||||
self._t_delay_play = 1.7
|
||||
@ -179,7 +182,7 @@ class MainMenuWindow(ba.Window):
|
||||
|
||||
self._have_settings_button = (
|
||||
(not self._in_game or not app.toolbar_test)
|
||||
and not (self._is_demo or self._is_arcade))
|
||||
and not (self._is_demo or self._is_arcade or self._is_iircade))
|
||||
|
||||
self._input_device = input_device = _ba.get_ui_input_device()
|
||||
self._input_player = input_device.player if input_device else None
|
||||
@ -436,7 +439,9 @@ class MainMenuWindow(ba.Window):
|
||||
account_type_icon_color = (1.0, 1.0, 1.0)
|
||||
account_type_call = self._show_account_window
|
||||
account_type_enable_button_sound = True
|
||||
b_count = 4 # play, help, credits, settings
|
||||
b_count = 3 # play, help, credits
|
||||
if self._have_settings_button:
|
||||
b_count += 1
|
||||
if enable_account_button:
|
||||
b_count += 1
|
||||
if self._have_quit_button:
|
||||
|
||||
@ -209,15 +209,6 @@ class AllSettingsWindow(ba.Window):
|
||||
# pylint: disable=cyclic-import
|
||||
from bastd.ui.settings.controls import ControlsSettingsWindow
|
||||
self._save_state()
|
||||
|
||||
# Disallow this on iircade.
|
||||
if ba.app.iircade_mode:
|
||||
ba.playsound(ba.getsound('error'))
|
||||
ba.screenmessage(
|
||||
ba.Lstr(resource='getTicketsWindow.unavailableText'),
|
||||
color=(1, 0, 0))
|
||||
return
|
||||
|
||||
ba.containerwidget(edit=self._root_widget, transition='out_left')
|
||||
ba.app.ui.set_main_menu_window(
|
||||
ControlsSettingsWindow(
|
||||
@ -227,15 +218,6 @@ class AllSettingsWindow(ba.Window):
|
||||
# pylint: disable=cyclic-import
|
||||
from bastd.ui.settings.graphics import GraphicsSettingsWindow
|
||||
self._save_state()
|
||||
|
||||
# Disallow this on iircade.
|
||||
if ba.app.iircade_mode:
|
||||
ba.playsound(ba.getsound('error'))
|
||||
ba.screenmessage(
|
||||
ba.Lstr(resource='getTicketsWindow.unavailableText'),
|
||||
color=(1, 0, 0))
|
||||
return
|
||||
|
||||
ba.containerwidget(edit=self._root_widget, transition='out_left')
|
||||
ba.app.ui.set_main_menu_window(
|
||||
GraphicsSettingsWindow(
|
||||
|
||||
@ -13,8 +13,8 @@
|
||||
<w>ack'ed</w>
|
||||
<w>acked</w>
|
||||
<w>acks</w>
|
||||
<w>aclass</w>
|
||||
<w>aclass's</w>
|
||||
<w>aclass</w>
|
||||
<w>activityplayer</w>
|
||||
<w>addrs</w>
|
||||
<w>adjoint</w>
|
||||
@ -146,8 +146,8 @@
|
||||
<w>cmath</w>
|
||||
<w>cmds</w>
|
||||
<w>cmdvals</w>
|
||||
<w>codewarrior</w>
|
||||
<w>codewarrior's</w>
|
||||
<w>codewarrior</w>
|
||||
<w>cofnodes</w>
|
||||
<w>collapseable</w>
|
||||
<w>collidable</w>
|
||||
@ -287,6 +287,7 @@
|
||||
<w>fffffffffifff</w>
|
||||
<w>fgets</w>
|
||||
<w>fifteenbits</w>
|
||||
<w>filterval</w>
|
||||
<w>finishedptr</w>
|
||||
<w>fjco</w>
|
||||
<w>fjcoiwef</w>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
|
||||
<h4><em>last updated on 2020-10-27 for Ballistica version 1.5.27 build 20228</em></h4>
|
||||
<h4><em>last updated on 2020-10-29 for Ballistica version 1.5.27 build 20230</em></h4>
|
||||
<p>This page documents the Python classes and functions in the 'ba' module,
|
||||
which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p>
|
||||
<hr>
|
||||
@ -6760,6 +6760,7 @@ in the background if necessary.</p>
|
||||
highlight: bool = None, border_opacity: float = None,
|
||||
simple_culling_h: float = None,
|
||||
claims_left_right: bool = None,
|
||||
claims_up_down: bool = None,
|
||||
claims_tab: bool = None) -> <a href="#class_ba_Widget">ba.Widget</a></span></p>
|
||||
|
||||
<p>Create or edit a horizontal scroll widget.</p>
|
||||
@ -7036,6 +7037,7 @@ Currently the 'clients' option only works for transient messages.</p>
|
||||
simple_culling_v: float = None,
|
||||
selection_loops_to_parent: bool = None,
|
||||
claims_left_right: bool = None,
|
||||
claims_up_down: bool = None,
|
||||
claims_tab: bool = None,
|
||||
autoselect: bool = None) -> <a href="#class_ba_Widget">ba.Widget</a></span></p>
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
namespace ballistica {
|
||||
|
||||
// These are set automatically via script; don't change here.
|
||||
const int kAppBuildNumber = 20229;
|
||||
const int kAppBuildNumber = 20232;
|
||||
const char* kAppVersion = "1.5.27";
|
||||
|
||||
// Our standalone globals.
|
||||
|
||||
@ -1179,6 +1179,7 @@ auto PyScrollWidget(PyObject* self, PyObject* args, PyObject* keywds)
|
||||
PyObject* simple_culling_v_obj{Py_None};
|
||||
PyObject* selection_loops_to_parent_obj{Py_None};
|
||||
PyObject* claims_left_right_obj{Py_None};
|
||||
PyObject* claims_up_down_obj{Py_None};
|
||||
PyObject* claims_tab_obj{Py_None};
|
||||
PyObject* autoselect_obj{Py_None};
|
||||
|
||||
@ -1197,18 +1198,19 @@ auto PyScrollWidget(PyObject* self, PyObject* args, PyObject* keywds)
|
||||
"simple_culling_v",
|
||||
"selection_loops_to_parent",
|
||||
"claims_left_right",
|
||||
"claims_up_down",
|
||||
"claims_tab",
|
||||
"autoselect",
|
||||
nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, keywds, "|OOOOOOOOOOOOOOOOO", const_cast<char**>(kwlist),
|
||||
args, keywds, "|OOOOOOOOOOOOOOOOOO", const_cast<char**>(kwlist),
|
||||
&edit_obj, &parent_obj, &size_obj, &pos_obj, &background_obj,
|
||||
&selected_child_obj, &capture_arrows_obj, &on_select_call_obj,
|
||||
¢er_small_content_obj, &color_obj, &highlight_obj,
|
||||
&border_opacity_obj, &simple_culling_v_obj,
|
||||
&selection_loops_to_parent_obj, &claims_left_right_obj,
|
||||
&claims_tab_obj, &autoselect_obj))
|
||||
&claims_up_down_obj, &claims_tab_obj, &autoselect_obj))
|
||||
return nullptr;
|
||||
|
||||
if (!g_game->IsInUIContext()) {
|
||||
@ -1287,6 +1289,9 @@ auto PyScrollWidget(PyObject* self, PyObject* args, PyObject* keywds)
|
||||
if (claims_left_right_obj != Py_None) {
|
||||
widget->set_claims_left_right(Python::GetPyBool(claims_left_right_obj));
|
||||
}
|
||||
if (claims_up_down_obj != Py_None) {
|
||||
widget->set_claims_up_down(Python::GetPyBool(claims_up_down_obj));
|
||||
}
|
||||
if (claims_tab_obj != Py_None) {
|
||||
widget->set_claims_tab(Python::GetPyBool(claims_tab_obj));
|
||||
}
|
||||
@ -1324,6 +1329,7 @@ auto PyHScrollWidget(PyObject* self, PyObject* args, PyObject* keywds)
|
||||
PyObject* border_opacity_obj = Py_None;
|
||||
PyObject* simple_culling_h_obj = Py_None;
|
||||
PyObject* claims_left_right_obj = Py_None;
|
||||
PyObject* claims_up_down_obj = Py_None;
|
||||
PyObject* claims_tab_obj = Py_None;
|
||||
PyObject* autoselect_obj = Py_None;
|
||||
|
||||
@ -1341,6 +1347,7 @@ auto PyHScrollWidget(PyObject* self, PyObject* args, PyObject* keywds)
|
||||
"border_opacity",
|
||||
"simple_culling_h",
|
||||
"claims_left_right",
|
||||
"claims_up_down",
|
||||
"claims_tab",
|
||||
"autoselect",
|
||||
nullptr};
|
||||
@ -1351,7 +1358,7 @@ auto PyHScrollWidget(PyObject* self, PyObject* args, PyObject* keywds)
|
||||
&selected_child_obj, &capture_arrows_obj, &on_select_call_obj,
|
||||
¢er_small_content_obj, &color_obj, &highlight_obj,
|
||||
&border_opacity_obj, &simple_culling_h_obj, &claims_left_right_obj,
|
||||
&claims_tab_obj, &autoselect_obj))
|
||||
&claims_up_down_obj, &claims_tab_obj, &autoselect_obj))
|
||||
return nullptr;
|
||||
|
||||
if (!g_game->IsInUIContext()) {
|
||||
@ -1425,6 +1432,9 @@ auto PyHScrollWidget(PyObject* self, PyObject* args, PyObject* keywds)
|
||||
if (claims_left_right_obj != Py_None) {
|
||||
widget->set_claims_left_right(Python::GetPyBool(claims_left_right_obj));
|
||||
}
|
||||
if (claims_up_down_obj != Py_None) {
|
||||
widget->set_claims_up_down(Python::GetPyBool(claims_up_down_obj));
|
||||
}
|
||||
if (claims_tab_obj != Py_None) {
|
||||
widget->set_claims_tab(Python::GetPyBool(claims_tab_obj));
|
||||
}
|
||||
@ -2643,6 +2653,7 @@ PyMethodDef PythonMethodsUI::methods_def[] = {
|
||||
" simple_culling_v: float = None,\n"
|
||||
" selection_loops_to_parent: bool = None,\n"
|
||||
" claims_left_right: bool = None,\n"
|
||||
" claims_up_down: bool = None,\n"
|
||||
" claims_tab: bool = None,\n"
|
||||
" autoselect: bool = None) -> ba.Widget\n"
|
||||
"\n"
|
||||
@ -2665,6 +2676,7 @@ PyMethodDef PythonMethodsUI::methods_def[] = {
|
||||
" highlight: bool = None, border_opacity: float = None,\n"
|
||||
" simple_culling_h: float = None,\n"
|
||||
" claims_left_right: bool = None,\n"
|
||||
" claims_up_down: bool = None,\n"
|
||||
" claims_tab: bool = None) -> ba.Widget\n"
|
||||
"\n"
|
||||
"Create or edit a horizontal scroll widget.\n"
|
||||
|
||||
@ -301,6 +301,7 @@ void TextWidget::Draw(RenderPass* pass, bool draw_transparent) {
|
||||
if (text_group_dirty_) {
|
||||
text_group_->SetText(text_translated_, align_h, align_v, big_, res_scale_);
|
||||
text_width_ = g_text_graphics->GetStringWidth(text_translated_, big_);
|
||||
|
||||
// FIXME: doesnt support big.
|
||||
text_height_ = g_text_graphics->GetStringHeight(text_translated_);
|
||||
text_group_dirty_ = false;
|
||||
@ -334,7 +335,9 @@ void TextWidget::Draw(RenderPass* pass, bool draw_transparent) {
|
||||
for (int e = 0; e < elem_count; e++) {
|
||||
// Gracefully skip unloaded textures..
|
||||
TextureData* t2 = text_group_->GetElementTexture(e);
|
||||
if (!t2->preloaded()) continue;
|
||||
if (!t2->preloaded()) {
|
||||
continue;
|
||||
}
|
||||
c.SetTexture(t2);
|
||||
c.SetMaskUV2Texture(text_group_->GetElementMaskUV2Texture(e));
|
||||
c.SetShadow(-0.004f * text_group_->GetElementUScale(e),
|
||||
@ -607,23 +610,22 @@ auto TextWidget::HandleMessage(const WidgetMessage& m) -> bool {
|
||||
return false;
|
||||
case SDLK_RETURN:
|
||||
case SDLK_KP_ENTER:
|
||||
|
||||
#if BA_OSTYPE_IOS_TVOS || BA_OSTYPE_ANDROID
|
||||
// On iOS, return currently just deselects us.
|
||||
g_audio->PlaySound(g_media->GetSound(SystemSoundID::kSwish));
|
||||
parent_widget()->SelectWidget(nullptr);
|
||||
return true;
|
||||
#else
|
||||
if (on_return_press_call_.exists()) {
|
||||
claimed = true;
|
||||
if (g_buildconfig.ostype_ios_tvos() || g_buildconfig.ostype_android()) {
|
||||
// On mobile, return currently just deselects us.
|
||||
g_audio->PlaySound(g_media->GetSound(SystemSoundID::kSwish));
|
||||
parent_widget()->SelectWidget(nullptr);
|
||||
return true;
|
||||
} else {
|
||||
if (on_return_press_call_.exists()) {
|
||||
// Call this in the next cycle (don't wanna risk mucking with UI
|
||||
// from within a UI loop)
|
||||
g_game->PushPythonWeakCall(
|
||||
Object::WeakRef<PythonContextCall>(on_return_press_call_));
|
||||
claimed = true;
|
||||
if (on_return_press_call_.exists()) {
|
||||
// Call this in the next cycle (don't wanna risk mucking with UI
|
||||
// from within a UI loop)
|
||||
g_game->PushPythonWeakCall(
|
||||
Object::WeakRef<PythonContextCall>(on_return_press_call_));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // BA_OSTYPE_IOS_TVOS
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
if (editable()) {
|
||||
|
||||
@ -33,7 +33,7 @@ PIP_REQUIREMENTS = [
|
||||
PipRequirement(modulename='mypy', minversion=[0, 790]),
|
||||
PipRequirement(modulename='yapf', minversion=[0, 30, 0]),
|
||||
PipRequirement(modulename='cpplint', minversion=[1, 5, 4]),
|
||||
PipRequirement(modulename='pytest', minversion=[6, 1, 1]),
|
||||
PipRequirement(modulename='pytest', minversion=[6, 1, 2]),
|
||||
PipRequirement(modulename='typing_extensions'),
|
||||
PipRequirement(modulename='pytz'),
|
||||
PipRequirement(modulename='yaml', pipname='PyYAML'),
|
||||
@ -739,41 +739,54 @@ def cmake_prep_dir(dirname: str) -> None:
|
||||
else:
|
||||
versions = {}
|
||||
|
||||
# Get version of installed cmake.
|
||||
# Start fresh if cmake version changes.
|
||||
cmake_ver_output = subprocess.run(['cmake', '--version'],
|
||||
check=True,
|
||||
capture_output=True).stdout.decode()
|
||||
cmake_ver = cmake_ver_output.splitlines()[0].split('cmake version ')[1]
|
||||
|
||||
cmake_ver_existing = versions.get('cmake')
|
||||
cmake_ver_existing = versions.get('cmake_version')
|
||||
assert isinstance(cmake_ver_existing, (str, type(None)))
|
||||
|
||||
# Get specific version of our target python.
|
||||
# ...or if python's version changes.
|
||||
python_ver_output = subprocess.run([f'python{PYVER}', '--version'],
|
||||
check=True,
|
||||
capture_output=True).stdout.decode()
|
||||
python_ver = python_ver_output.splitlines()[0].split('Python ')[1]
|
||||
|
||||
python_ver_existing = versions.get('python')
|
||||
python_ver_existing = versions.get('python_version')
|
||||
assert isinstance(python_ver_existing, (str, type(None)))
|
||||
|
||||
# If they don't match, blow away the dir and write the current version.
|
||||
if cmake_ver_existing != cmake_ver or python_ver_existing != python_ver:
|
||||
if (cmake_ver_existing != cmake_ver
|
||||
and cmake_ver_existing is not None):
|
||||
# ...or if the actual location of python on disk changes.
|
||||
python_path = os.path.realpath(
|
||||
subprocess.run(['which', f'python{PYVER}'],
|
||||
check=True,
|
||||
capture_output=True).stdout.decode())
|
||||
python_path_existing = versions.get('python_path')
|
||||
assert isinstance(python_path_existing, (str, type(None)))
|
||||
|
||||
# Blow away and start from scratch if any vals differ from existing.
|
||||
if (cmake_ver_existing != cmake_ver or python_ver_existing != python_ver
|
||||
or python_path != python_path_existing):
|
||||
if (cmake_ver_existing is not None
|
||||
and cmake_ver_existing != cmake_ver):
|
||||
print(f'{Clr.BLU}CMake version changed from {cmake_ver_existing}'
|
||||
f' to {cmake_ver}; clearing existing build at'
|
||||
f' "{dirname}".{Clr.RST}')
|
||||
if (python_ver_existing != python_ver
|
||||
and python_ver_existing is not None):
|
||||
if (python_ver_existing is not None
|
||||
and python_ver_existing != python_ver):
|
||||
print(f'{Clr.BLU}Python version changed from {python_ver_existing}'
|
||||
f' to {python_ver}; clearing existing build at'
|
||||
f' "{dirname}".{Clr.RST}')
|
||||
if (python_path_existing is not None
|
||||
and python_path_existing != python_path):
|
||||
print(f'{Clr.BLU}Python path changed from {python_path_existing}'
|
||||
f' to {python_path}; clearing existing build at'
|
||||
f' "{dirname}".{Clr.RST}')
|
||||
subprocess.run(['rm', '-rf', dirname], check=True)
|
||||
os.makedirs(dirname, exist_ok=True)
|
||||
with open(verfilename, 'w') as outfile:
|
||||
outfile.write(
|
||||
json.dumps({
|
||||
'cmake': cmake_ver,
|
||||
'python': python_ver
|
||||
'cmake_version': cmake_ver,
|
||||
'python_version': python_ver,
|
||||
'python_path': python_path
|
||||
}))
|
||||
|
||||
@ -733,7 +733,6 @@ def cmake_prep_dir() -> None:
|
||||
"""
|
||||
from efro.error import CleanError
|
||||
import batools.build
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
raise CleanError('Expected 1 arg (dir name)')
|
||||
dirname = sys.argv[2]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user