diff --git a/.efrocachemap b/.efrocachemap index 527065e0..ada7d9de 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -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/5a/0e/c0d740728ec6a91c4058db0de580", - "build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/b2/5e/fd7b9b92e62dd673b3f0b8bde257", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1c/cf/0bcbafccaf1e7cc3e7f2e0fb1a51", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/39/82/ed8272b0ef178a7d625227729b93", - "build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/1b/34/79ba915806f7984d2821c16e61aa", - "build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/0d/80/f7277f55432bb4685f0605169d16", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9c/d2/f2d25f1ede5d806a553ce1da129a", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1b/42/b968b868eedd97b7be64a1728bfe", - "build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/79/99/e8fa8f51f33ca94705a4eca05673", - "build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/2d/dd/3deb44f89955ba8ffdd9ff1fec30", - "build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/cb/57/dd199c247cbd2a9651da09eaafcf", - "build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/85/a7/968e92f45eb512b0a6546fe64157", + "build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/5d/5f/7e353ad61a992fd31b1c27918e89", + "build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/61/77/65d2fd041d9f8fea8d7e4733a5ec", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/70/6c/a1111ede41bda66b5c4dda4162cb", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f6/24/3d45f90a537c7f19496b8dd8101c", + "build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/01/b9/a4862fd7ac4b9bc46109bf0f3fb5", + "build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/70/58/4b5840cd26a0853197fa63c39f26", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/93/de/4dc052ed052de5353044adaf3b56", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f9/5c/69ff3f14bb37bd82956088c16872", + "build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/5c/4d/acecaaafada62747b7beb884348b", + "build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/08/81/f3cfc8bb76bc05b0ee53ccd47b67", + "build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/45/9b/635f9392ba5c0561949e519ec8c3", + "build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/5f/f2/4136816295eca8ffefabc60a8b6e", "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/de/16/c12809a8a4754329e6da3c1586ec", - "build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/71/51/edcfb82938dcd3410f2d31547db6", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/73/77/b5c1338380f41d341a799921fe69", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0d/5c/c180e7a4d28600125e8dc2b1fbcc" + "build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/43/1d/ee9ee9bf897787f0b469853bb426", + "build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/98/d2/7a106e580aa03db5c9f91ccd8bc8", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/38/28/2cbd3a1eeec91e71ff8f4a048d73", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/25/4d/c9b30b84774de5ee5eed1927d6b1" } \ No newline at end of file diff --git a/assets/src/ba_data/python/_ba.py b/assets/src/ba_data/python/_ba.py index cb7afb6b..0640f6fe 100644 --- a/assets/src/ba_data/python/_ba.py +++ b/assets/src/ba_data/python/_ba.py @@ -3388,7 +3388,8 @@ def scrollwidget(edit: ba.Widget = None, simple_culling_v: float = None, selection_loops_to_parent: bool = None, claims_left_right: bool = None, - claims_tab: bool = None) -> ba.Widget: + claims_tab: bool = None, + autoselect: bool = None) -> ba.Widget: """scrollwidget(edit: ba.Widget = None, parent: ba.Widget = None, size: Sequence[float] = None, position: Sequence[float] = None, background: bool = None, selected_child: ba.Widget = None, @@ -3398,7 +3399,8 @@ def scrollwidget(edit: ba.Widget = None, simple_culling_v: float = None, selection_loops_to_parent: bool = None, claims_left_right: bool = None, - claims_tab: bool = None) -> ba.Widget + claims_tab: bool = None, + autoselect: bool = None) -> ba.Widget Create or edit a scroll widget. diff --git a/assets/src/ba_data/python/bastd/ui/gather/__init__.py b/assets/src/ba_data/python/bastd/ui/gather/__init__.py index 46e0b0ca..253c0629 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/__init__.py +++ b/assets/src/ba_data/python/bastd/ui/gather/__init__.py @@ -89,11 +89,16 @@ class GatherWindow(ba.Window): size=(60, 60), label=ba.charstr(ba.SpecialChar.BACK)) + condensed = uiscale is not ba.UIScale.LARGE + t_offs_y = (0 if not condensed else + 25 if uiscale is ba.UIScale.MEDIUM else 17) ba.textwidget(parent=self._root_widget, - position=(self._width * 0.5, self._height - 42), + position=(self._width * 0.5, + self._height - 42 + t_offs_y), size=(0, 0), color=ba.app.ui.title_color, - scale=1.5, + scale=(1.5 if not condensed else + 1.0 if uiscale is ba.UIScale.MEDIUM else 0.6), h_align='center', v_align='center', text=ba.Lstr(resource=self._r + '.titleText'), @@ -103,7 +108,7 @@ class GatherWindow(ba.Window): subplatform = ba.app.subplatform scroll_buffer_h = 130 + 2 * x_offs - tab_buffer_h = 250 + 2 * x_offs + tab_buffer_h = ((320 if condensed else 250) + 2 * x_offs) # Build up the set of tabs we want. tabdefs: List[Tuple[GatherWindow.TabID, ba.Lstr]] = [ @@ -120,9 +125,13 @@ class GatherWindow(ba.Window): tabdefs.append( (self.TabID.MANUAL, ba.Lstr(resource=self._r + '.manualText'))) + # On small UI, push our tabs up closer to the top of the screen to + # save a bit of space. + tabs_top_extra = 42 if condensed else 0 self._tab_row = TabRow(self._root_widget, tabdefs, - pos=(tab_buffer_h * 0.5, self._height - 130), + pos=(tab_buffer_h * 0.5, + self._height - 130 + tabs_top_extra), size=(self._width - tab_buffer_h, 50), on_select_call=self._set_tab) @@ -148,10 +157,11 @@ class GatherWindow(ba.Window): left_widget=_ba.get_special_widget('back_button')) self._scroll_width = self._width - scroll_buffer_h - self._scroll_height = self._height - 180.0 + self._scroll_height = self._height - 180.0 + tabs_top_extra self._scroll_left = (self._width - self._scroll_width) * 0.5 - self._scroll_bottom = self._height - self._scroll_height - 79 - 48 + self._scroll_bottom = (self._height - self._scroll_height - 79 - 48 + + tabs_top_extra) buffer_h = 10 buffer_v = 4 diff --git a/assets/src/ba_data/python/bastd/ui/gather/abouttab.py b/assets/src/ba_data/python/bastd/ui/gather/abouttab.py index 7fd1975b..de0a16b6 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/abouttab.py +++ b/assets/src/ba_data/python/bastd/ui/gather/abouttab.py @@ -31,11 +31,11 @@ class AboutGatherTab(GatherTab): region_left: float, region_bottom: float, ) -> ba.Widget: - message = ba.Lstr(resource='gatherWindow.aboutDescriptionText', - subs=[('${PARTY}', - ba.charstr(ba.SpecialChar.PARTY_ICON)), - ('${BUTTON}', - ba.charstr(ba.SpecialChar.TOP_BUTTON))]) + message = ba.Lstr( + resource='gatherWindow.aboutDescriptionText', + subs=[('${PARTY}', ba.charstr(ba.SpecialChar.PARTY_ICON)), + ('${BUTTON}', ba.charstr(ba.SpecialChar.TOP_BUTTON))], + ) # Let's not talk about sharing in vr-mode; its tricky to fit more # than one head in a VR-headset ;-) diff --git a/assets/src/ba_data/python/bastd/ui/gather/publictab.py b/assets/src/ba_data/python/bastd/ui/gather/publictab.py index da07f0e9..94e7bd19 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/publictab.py +++ b/assets/src/ba_data/python/bastd/ui/gather/publictab.py @@ -179,10 +179,10 @@ class PublicGatherTab(GatherTab): self._join_text: Optional[ba.Widget] = None self._host_text: Optional[ba.Widget] = None self._local_address: Optional[str] = None - self._last_public_party_connect_attempt_time: Optional[float] = None + self._last_connect_attempt_time: Optional[float] = None self._sub_tab: SubTabType = SubTabType.JOIN self._selection: Optional[Selection] = None - self._refreshing_public_party_list = False + self._refreshing_list = False self._update_timer: Optional[ba.Timer] = None self._host_scrollwidget: Optional[ba.Widget] = None self._host_name_text: Optional[ba.Widget] = None @@ -195,9 +195,9 @@ class PublicGatherTab(GatherTab): self._host_max_party_size_plus_button: (Optional[ba.Widget]) = None self._host_status_text: Optional[ba.Widget] = None self._public_parties: Dict[str, PartyEntry] = {} - self._last_public_party_list_rebuild_time: Optional[float] = None - self._first_public_party_list_rebuild_time: Optional[float] = None - self._next_public_party_entry_index = 0 + self._last_list_rebuild_time: Optional[float] = None + self._first_list_rebuild_time: Optional[float] = None + self._next_entry_index = 0 def on_activate( self, @@ -329,7 +329,7 @@ class PublicGatherTab(GatherTab): edit=self._host_text, color=active_color if value is SubTabType.HOST else inactive_color) - # Clear anything in existence in our sub-tabs. + # Clear anything existing in the old sub-tab. for widget in self._container.get_children(): if widget and widget not in {self._host_text, self._join_text}: widget.delete() @@ -356,8 +356,8 @@ class PublicGatherTab(GatherTab): # Reset our list of public parties. self._public_parties = {} - self._last_public_party_list_rebuild_time = 0 - self._first_public_party_list_rebuild_time = None + self._last_list_rebuild_time = 0 + self._first_list_rebuild_time = None ba.textwidget(text=ba.Lstr(resource='nameText'), parent=self._container, size=(0, 0), @@ -397,13 +397,13 @@ class PublicGatherTab(GatherTab): parent=self._container, simple_culling_v=10, position=((c_width - sub_scroll_width) * 0.5, v), - size=(sub_scroll_width, sub_scroll_height)) - ba.widget(edit=scrollw, autoselect=True) - colw = self._host_columnwidget = ba.containerwidget(parent=scrollw, - background=False, - size=(400, 400)) - ba.containerwidget(edit=scrollw, claims_left_right=True) - ba.containerwidget(edit=colw, claims_left_right=True) + size=(sub_scroll_width, sub_scroll_height), + claims_left_right=True, + autoselect=True) + self._host_columnwidget = ba.containerwidget(parent=scrollw, + background=False, + size=(400, 400), + claims_left_right=True) self._join_status_text = ba.textwidget( parent=self._container, @@ -550,18 +550,18 @@ class PublicGatherTab(GatherTab): # pylint: disable=too-many-locals # pylint: disable=too-many-statements cur_time = ba.time(ba.TimeType.REAL) - if self._first_public_party_list_rebuild_time is None: - self._first_public_party_list_rebuild_time = cur_time + if self._first_list_rebuild_time is None: + self._first_list_rebuild_time = cur_time # Update faster for the first few seconds; # then ease off to keep the list from jumping around. - since_first = cur_time - self._first_public_party_list_rebuild_time + since_first = cur_time - self._first_list_rebuild_time wait_time = (1.0 if since_first < 2.0 else 2.5 if since_first < 10.0 else 5.0) - assert self._last_public_party_list_rebuild_time is not None - if cur_time - self._last_public_party_list_rebuild_time < wait_time: + assert self._last_list_rebuild_time is not None + if cur_time - self._last_list_rebuild_time < wait_time: return - self._last_public_party_list_rebuild_time = cur_time + self._last_list_rebuild_time = cur_time # First off, check for the existence of our column widget; # if we don't have this, we're done. @@ -594,7 +594,7 @@ class PublicGatherTab(GatherTab): # Ew; this rebuilding generates deferred selection callbacks # so we need to generated deferred ignore notices for ourself. def refresh_on() -> None: - self._refreshing_public_party_list = True + self._refreshing_list = True ba.pushcall(refresh_on) @@ -701,7 +701,7 @@ class PublicGatherTab(GatherTab): # So our selection callbacks can start firing.. def refresh_off() -> None: - self._refreshing_public_party_list = False + self._refreshing_list = False ba.pushcall(refresh_off) @@ -745,8 +745,8 @@ class PublicGatherTab(GatherTab): next_ping_time=ba.time(ba.TimeType.REAL) + 0.001 * party_in['pd'], ping=None, - index=self._next_public_party_entry_index) - self._next_public_party_entry_index += 1 + index=self._next_entry_index) + self._next_entry_index += 1 assert isinstance(party.address, str) assert isinstance(party.next_ping_time, float) @@ -968,13 +968,13 @@ class PublicGatherTab(GatherTab): # Rate limit this a bit. now = time.time() - last_connect_time = self._last_public_party_connect_attempt_time + last_connect_time = self._last_connect_attempt_time if last_connect_time is None or now - last_connect_time > 2.0: _ba.connect_to_party(address, port=port) - self._last_public_party_connect_attempt_time = now + self._last_connect_attempt_time = now def _set_public_party_selection(self, sel: Selection) -> None: - if self._refreshing_public_party_list: + if self._refreshing_list: return self._selection = sel diff --git a/docs/ba_module.md b/docs/ba_module.md index c47b585d..b9bf5a21 100644 --- a/docs/ba_module.md +++ b/docs/ba_module.md @@ -1,5 +1,5 @@ -
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 let me know. Happy modding!
Create or edit a scroll widget.
diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 9fa746e4..65f019ce 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -21,7 +21,7 @@ namespace ballistica { // These are set automatically via script; don't change here. -const int kAppBuildNumber = 20227; +const int kAppBuildNumber = 20228; const char* kAppVersion = "1.5.27"; // Our standalone globals. diff --git a/src/ballistica/python/methods/python_methods_ui.cc b/src/ballistica/python/methods/python_methods_ui.cc index 02686359..b1f032de 100644 --- a/src/ballistica/python/methods/python_methods_ui.cc +++ b/src/ballistica/python/methods/python_methods_ui.cc @@ -1180,6 +1180,7 @@ auto PyScrollWidget(PyObject* self, PyObject* args, PyObject* keywds) PyObject* selection_loops_to_parent_obj{Py_None}; PyObject* claims_left_right_obj{Py_None}; PyObject* claims_tab_obj{Py_None}; + PyObject* autoselect_obj{Py_None}; static const char* kwlist[] = {"edit", "parent", @@ -1197,16 +1198,17 @@ auto PyScrollWidget(PyObject* self, PyObject* args, PyObject* keywds) "selection_loops_to_parent", "claims_left_right", "claims_tab", + "autoselect", nullptr}; if (!PyArg_ParseTupleAndKeywords( - args, keywds, "|OOOOOOOOOOOOOOOO", const_cast