diff --git a/.efrocachemap b/.efrocachemap index 5c07cf41..62c55b86 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -432,7 +432,7 @@ "build/assets/ba_data/audio/zoeOw.ogg": "b2d705c31c9dcc1efdc71394764c3beb", "build/assets/ba_data/audio/zoePickup01.ogg": "e9366dc2d2b8ab8b0c4e2c14c02d0789", "build/assets/ba_data/audio/zoeScream01.ogg": "903e0e45ee9b3373e9d9ce20c814374e", - "build/assets/ba_data/data/langdata.json": "637e524f148eedb5a773a5d3529c2f51", + "build/assets/ba_data/data/langdata.json": "bb872f4df766a9cb353677300055066b", "build/assets/ba_data/data/languages/arabic.json": "32b9849fb8389b8c7798f0b744620318", "build/assets/ba_data/data/languages/belarussian.json": "009b452aa308bf2b2f7e92d9b78ba5ff", "build/assets/ba_data/data/languages/chinese.json": "5363a79f843e6be7ef47a840f47cc17d", @@ -462,11 +462,11 @@ "build/assets/ba_data/data/languages/russian.json": "780d1857df77ef59104d5dac75415bd6", "build/assets/ba_data/data/languages/serbian.json": "623fa4129a1154c2f32ed7867e56ff6a", "build/assets/ba_data/data/languages/slovak.json": "c11c29708b3742cdc2a92b4fa0d6d29f", - "build/assets/ba_data/data/languages/spanish.json": "5bc22761e8a37cbdf38d4bced753b6ba", + "build/assets/ba_data/data/languages/spanish.json": "ccb08a06f13d56c5d0b752a03c49865e", "build/assets/ba_data/data/languages/swedish.json": "3b179e7333183c70adb0811246b09959", "build/assets/ba_data/data/languages/tamil.json": "ead39b864228696a9b0d19344bc4b5ec", "build/assets/ba_data/data/languages/thai.json": "383540a1e9c7c131ac579f51afc87471", - "build/assets/ba_data/data/languages/turkish.json": "8a406f0fd91b55e3f8e57cd92aea5a52", + "build/assets/ba_data/data/languages/turkish.json": "f4c3e07275180114d951c002be5ef101", "build/assets/ba_data/data/languages/ukrainian.json": "0db55824759119aca74d2ee8ffe6daae", "build/assets/ba_data/data/languages/venetian.json": "acea003316bef657925d776dd460e713", "build/assets/ba_data/data/languages/vietnamese.json": "017d8aa346d0c23a229a8a9acccf79a1", @@ -4182,14 +4182,14 @@ "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "af6b01b85380b1a9874f8d7e7db435e4", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "23039996985b4aa93dff5aaf41067ea4", "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "56775e7415d62ea2d92ac73c6eb944a4", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "43417f65a4b03d86a0dd149975d79a4f", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "03bf4a2e606ee1fd85b3ba9839da87e6", "build/prefab/full/mac_arm64_gui/release/ballisticakit": "10fc3f2ecef4e957b26d1ec82b441255", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "551815823c8fc7bdb730d23ce32dfac1", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "b33d1932f2beb9b3d2769c8f4e35dcad", "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "ee6d0760189953307799b7e06858aa87", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "89e6739f26b419ed71548fbba21f476f", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "3ef2b3179c424dfa97f4e50250cccc57", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "9b2170e71927e097b3e92a8ad993c81f", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "4bd75394e66b2eba2ec35d1d6119fd7a", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "372d0ad3ef2bcd7f8fa93b9d83e2a300", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "e6f8c4f279931182f28722a33b9e3fc0", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "8e28d37c93494d05479d3132a6525967", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "e0db14d2a7df35e29fc4cdfe9c6c42d6", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "4d70703c4eba1a402fbc2d997d84aa93", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "bb64e2182b1a533679f93c5997f14584", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "4d70703c4eba1a402fbc2d997d84aa93", @@ -4202,14 +4202,14 @@ "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "116b500c2d57caf06619408b2176e83b", "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "e3e9d9c7a94f8cd22939839fd8fbc178", "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "116b500c2d57caf06619408b2176e83b", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "def3aafdaa027b8311290549d5466a03", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "a168a3ab32ab82e1775d2ac33f4ee859", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "3023cfdf99e6a1af1c5daacd0a5ef93d", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "4b2dad34e4edf32a00d6c32e7ed703e2", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "c1d35a57b5c9a84c4da24eaf5bdf210f", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "49080baa202c08e0da85e8562ff7d889", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "04a2c999f64cde37a786fffec1b53e34", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "af531d6fb63cd54cd02dd5a756fd167b", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "3f2dddebc7313756f2f6ee83c377f265", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "d4a5d87e4ae724ae5e49cec56cb17a58", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "72d5ac0df3f03d2fceb5f015e9071ca3", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "12b693aea7eb0a3d501bea4ae7de75e1", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "091f0ff2326739346407622d4d8cc449", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "4ad50d22cac50a74f4953abf24016088", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "0be3a0c54d84379972bacc70f0c16887", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "cf56d84fe7f9a4bd8bf93172b561c5c0", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/enums.py": "794d258d59fd17a61752843a9a0551ad", "src/ballistica/base/mgen/pyembed/binding_base.inc": "06042d31df0ff9af96b99477162e2a91", diff --git a/src/assets/ba_data/python/bauiv1lib/account/settings.py b/src/assets/ba_data/python/bauiv1lib/account/settings.py index cae1dccb..0a81d02f 100644 --- a/src/assets/ba_data/python/bauiv1lib/account/settings.py +++ b/src/assets/ba_data/python/bauiv1lib/account/settings.py @@ -89,7 +89,7 @@ class AccountSettingsWindow(bui.MainWindow): self._scroll_width = target_width self._scroll_height = target_height - 33 - scroll_y = yoffs - 61 - self._scroll_height + scroll_bottom = yoffs - 61 - self._scroll_height self._sign_in_button = None self._sign_in_text = None @@ -174,7 +174,10 @@ class AccountSettingsWindow(bui.MainWindow): parent=self._root_widget, highlight=False, size=(self._scroll_width, self._scroll_height), - position=(self._width * 0.5 - self._scroll_width * 0.5, scroll_y), + position=( + self._width * 0.5 - self._scroll_width * 0.5, + scroll_bottom, + ), claims_left_right=True, selection_loops_to_parent=True, border_opacity=0.4, diff --git a/src/assets/ba_data/python/bauiv1lib/achievements.py b/src/assets/ba_data/python/bauiv1lib/achievements.py index 1e239650..97d8e53f 100644 --- a/src/assets/ba_data/python/bauiv1lib/achievements.py +++ b/src/assets/ba_data/python/bauiv1lib/achievements.py @@ -55,7 +55,7 @@ class AchievementsWindow(bui.MainWindow): scroll_width = target_width scroll_height = target_height - 25 - scroll_y = yoffs - 54 - scroll_height + scroll_bottom = yoffs - 54 - scroll_height super().__init__( root_widget=bui.containerwidget( @@ -121,7 +121,7 @@ class AchievementsWindow(bui.MainWindow): self._scrollwidget = bui.scrollwidget( parent=self._root_widget, size=(scroll_width, scroll_height), - position=(self._width * 0.5 - scroll_width * 0.5, scroll_y), + position=(self._width * 0.5 - scroll_width * 0.5, scroll_bottom), capture_arrows=True, simple_culling_v=10, border_opacity=0.4, diff --git a/src/assets/ba_data/python/bauiv1lib/gather/__init__.py b/src/assets/ba_data/python/bauiv1lib/gather/__init__.py index 6e3cbe00..ed81395f 100644 --- a/src/assets/ba_data/python/bauiv1lib/gather/__init__.py +++ b/src/assets/ba_data/python/bauiv1lib/gather/__init__.py @@ -88,39 +88,56 @@ class GatherWindow(bui.MainWindow): bui.set_analytics_screen('Gather Window') uiscale = bui.app.ui_v1.uiscale - self._width = 1640 if uiscale is bui.UIScale.SMALL else 1040 - x_offs = 200 if uiscale is bui.UIScale.SMALL else 0 - y_offs = -65 if uiscale is bui.UIScale.SMALL else 0 - self._height = ( - 650 + self._width = ( + 1640 if uiscale is bui.UIScale.SMALL - else 680 if uiscale is bui.UIScale.MEDIUM else 800 + else 1100 if uiscale is bui.UIScale.MEDIUM else 1200 + ) + self._height = ( + 1000 + if uiscale is bui.UIScale.SMALL + else 730 if uiscale is bui.UIScale.MEDIUM else 900 ) self._current_tab: GatherWindow.TabID | None = None - extra_top = 20 if uiscale is bui.UIScale.SMALL else 0 self._r = 'gatherWindow' + # Do some fancy math to fill all available screen area up to the + # size of our backing container. This lets us fit to the exact + # screen shape at small ui scale. + screensize = bui.get_virtual_screen_size() + scale = ( + 1.15 + if uiscale is bui.UIScale.SMALL + else 0.88 if uiscale is bui.UIScale.MEDIUM else 0.66 + ) + # Calc screen size in our local container space and clamp to a + # bit smaller than our container size. + target_width = min(self._width - 130, screensize[0] / scale) + target_height = min(self._height - 130, screensize[1] / scale) + + # To get top/left coords, go to the center of our window and + # offset by half the width/height of our target area. + yoffs = 0.5 * self._height + 0.5 * target_height + 30.0 + + self._scroll_width = target_width + self._scroll_height = target_height - 57 + self._scroll_bottom = yoffs - 90 - self._scroll_height + self._scroll_left = (self._width - self._scroll_width) * 0.5 + super().__init__( root_widget=bui.containerwidget( - size=(self._width, self._height + extra_top), + size=(self._width, self._height), toolbar_visibility=( 'menu_tokens' if uiscale is bui.UIScale.SMALL else 'menu_full' ), - scale=( - 1.15 - if uiscale is bui.UIScale.SMALL - else 0.95 if uiscale is bui.UIScale.MEDIUM else 0.7 - ), - stack_offset=( - (0, 0) - if uiscale is bui.UIScale.SMALL - else (0, 0) if uiscale is bui.UIScale.MEDIUM else (0, 0) - ), + scale=scale, ), transition=transition, origin_widget=origin_widget, + # We're affected by screen size only at small ui-scale. + refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL, ) if uiscale is bui.UIScale.SMALL: @@ -131,46 +148,35 @@ class GatherWindow(bui.MainWindow): else: self._back_button = btn = bui.buttonwidget( parent=self._root_widget, - position=(70 + x_offs, self._height - 74 + y_offs), - size=(140, 60), + position=(70, yoffs - 43), + size=(60, 60), scale=1.1, autoselect=True, - label=bui.Lstr(resource='backText'), - button_type='back', + label=bui.charstr(bui.SpecialChar.BACK), + button_type='backSmall', on_activate_call=self.main_window_back, ) bui.containerwidget(edit=self._root_widget, cancel_button=btn) - bui.buttonwidget( - edit=btn, - button_type='backSmall', - position=(70 + x_offs, self._height - 78), - size=(60, 60), - label=bui.charstr(bui.SpecialChar.BACK), - ) - condensed = uiscale is not bui.UIScale.LARGE - t_offs_y = ( - 0 if not condensed else 25 if uiscale is bui.UIScale.MEDIUM else 33 - ) bui.textwidget( parent=self._root_widget, - position=(self._width * 0.5, self._height - 42 + t_offs_y + y_offs), + position=( + self._width * 0.5, + yoffs - (53 if uiscale is bui.UIScale.SMALL else 4), + ), size=(0, 0), color=bui.app.ui_v1.title_color, - scale=( - 1.5 - if not condensed - else 1.0 if uiscale is bui.UIScale.MEDIUM else 1.0 - ), + scale=1.0, h_align='center', v_align='center', - text=bui.Lstr(resource=f'{self._r}.titleText'), + text=( + '' + if uiscale is bui.UIScale.SMALL + else bui.Lstr(resource=f'{self._r}.titleText') + ), maxwidth=320, ) - scroll_buffer_h = 130 + 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, bui.Lstr]] = [ (self.TabID.ABOUT, bui.Lstr(resource=f'{self._r}.aboutText')) @@ -192,17 +198,16 @@ class GatherWindow(bui.MainWindow): (self.TabID.MANUAL, bui.Lstr(resource=f'{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 + tab_inset = 100.0 + tab_inset_extra_r = 150 if uiscale is bui.UIScale.SMALL else 0 self._tab_row = TabRow( self._root_widget, tabdefs, + size=(self._scroll_width - 2.0 * tab_inset - tab_inset_extra_r, 50), pos=( - tab_buffer_h * 0.5, - self._height - 130 + tabs_top_extra + y_offs, + self._scroll_left + tab_inset, + self._scroll_bottom + self._scroll_height, ), - size=(self._width - tab_buffer_h, 50), on_select_call=bui.WeakCall(self._set_tab), ) @@ -220,45 +225,26 @@ class GatherWindow(bui.MainWindow): if tabtype is not None: self._tabs[tab_id] = tabtype(self) + # Eww; tokens meter may or may not be here; should be smarter + # about this. bui.widget( edit=self._tab_row.tabs[tabdefs[-1][0]].button, - right_widget=bui.get_special_widget('squad_button'), + right_widget=bui.get_special_widget('tokens_meter'), ) if uiscale is bui.UIScale.SMALL: bui.widget( edit=self._tab_row.tabs[tabdefs[0][0]].button, left_widget=bui.get_special_widget('back_button'), + up_widget=bui.get_special_widget('back_button'), ) - self._scroll_width = self._width - scroll_buffer_h - self._scroll_height = ( - self._height - - (270.0 if uiscale is bui.UIScale.SMALL else 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 - + tabs_top_extra - + y_offs - ) - buffer_h = 10 - buffer_v = 4 - # Not actually using a scroll widget anymore; just an image. bui.imagewidget( parent=self._root_widget, + size=(self._scroll_width, self._scroll_height), position=( - self._scroll_left - buffer_h, - self._scroll_bottom - buffer_v, - ), - size=( - self._scroll_width + 2 * buffer_h, - self._scroll_height + 2 * buffer_v, + self._width * 0.5 - self._scroll_width * 0.5, + self._scroll_bottom, ), texture=bui.gettexture('scrollWidget'), mesh_transparent=bui.getmesh('softEdgeOutside'), diff --git a/src/assets/ba_data/python/bauiv1lib/gather/publictab.py b/src/assets/ba_data/python/bauiv1lib/gather/publictab.py index adaf2ec5..1526a63f 100644 --- a/src/assets/ba_data/python/bauiv1lib/gather/publictab.py +++ b/src/assets/ba_data/python/bauiv1lib/gather/publictab.py @@ -162,7 +162,8 @@ class UIRow: Selection(party.get_key(), SelectionComponent.STATS_BUTTON), ), size=(120, 40), - position=(sub_scroll_width * 0.66 + hpos, 1 + vpos), + # position=(sub_scroll_width * 0.66 + hpos, 1 + vpos), + position=(sub_scroll_width - 270.0, 1 + vpos), scale=0.9, ) if existing_selection == Selection( @@ -176,7 +177,8 @@ class UIRow: text=str(party.size) + '/' + str(party.size_max), parent=columnwidget, size=(0, 0), - position=(sub_scroll_width * 0.86 + hpos, 20 + vpos), + # position=(sub_scroll_width * 0.86 + hpos, 20 + vpos), + position=(sub_scroll_width - 100, 20 + vpos), scale=0.7, color=(0.8, 0.8, 0.8), h_align='right', @@ -191,7 +193,8 @@ class UIRow: self._ping_widget = bui.textwidget( parent=columnwidget, size=(0, 0), - position=(sub_scroll_width * 0.94 + hpos, 20 + vpos), + # position=(sub_scroll_width * 0.94 + hpos, 20 + vpos), + position=(sub_scroll_width - 30.0, 20 + vpos), scale=0.7, h_align='right', v_align='center', @@ -372,6 +375,7 @@ class PublicGatherTab(GatherTab): self._host_max_party_size_value: bui.Widget | None = None self._host_max_party_size_minus_button: bui.Widget | None = None self._host_max_party_size_plus_button: bui.Widget | None = None + self._join_sub_scroll_width: float | None = None self._host_status_text: bui.Widget | None = None self._signed_in = False self._ui_rows: list[UIRow] = [] @@ -474,7 +478,8 @@ class PublicGatherTab(GatherTab): ) bui.widget(edit=self._join_text, right_widget=self._host_text) - # Attempt to fetch our local address so we have it for error messages. + # Attempt to fetch our local address so we have it for error + # messages. if self._local_address is None: AddrFetchThread(bui.WeakCall(self._fetch_local_addr_cb)).start() @@ -491,9 +496,9 @@ class PublicGatherTab(GatherTab): @override def save_state(self) -> None: # 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. + # 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. assert bui.app.classic is not None bui.app.ui_v1.window_states[type(self)] = State( sub_tab=self._sub_tab, @@ -523,7 +528,7 @@ class PublicGatherTab(GatherTab): self._next_entry_index = state.next_entry_index - # FIXME: should save/restore these too?.. + # FIXME: should save/restore these too? self._have_server_list_response = state.have_server_list_response self._have_valid_server_list = state.have_valid_server_list self._filter_value = state.filter_value @@ -539,9 +544,8 @@ class PublicGatherTab(GatherTab): if playsound: bui.getsound('click01').play() - # Reset our selection. - # (prevents selecting something way down the list if we switched away - # and came back) + # Reset our selection (prevents selecting something way down the + # list if we switched away and came back). self._selection = None self._have_user_selected_row = False @@ -579,7 +583,9 @@ class PublicGatherTab(GatherTab): c_width = region_width c_height = region_height - 20 sub_scroll_height = c_height - 125 - sub_scroll_width = 830 + self._join_sub_scroll_width = sub_scroll_width = min( + 1200, region_width - 80 + ) v = c_height - 35 v -= 60 filter_txt = bui.Lstr(resource='filterText') @@ -726,6 +732,9 @@ class PublicGatherTab(GatherTab): ) v -= 30 + # Nudge party name and size values to be mostly centered. + xoffs = region_width * 0.5 - 500 + party_name_text = bui.Lstr( resource='gatherWindow.partyNameText', fallback_resource='editGameListWindow.nameText', @@ -739,14 +748,14 @@ class PublicGatherTab(GatherTab): maxwidth=200, scale=0.8, color=bui.app.ui_v1.infotextcolor, - position=(210, v - 9), + position=(210 + xoffs, v - 9), text=party_name_text, ) self._host_name_text = bui.textwidget( parent=self._container, editable=True, size=(535, 40), - position=(230, v - 30), + position=(230 + xoffs, v - 30), text=bui.app.config.get('Public Party Name', ''), maxwidth=494, shadow=0.3, @@ -766,7 +775,7 @@ class PublicGatherTab(GatherTab): maxwidth=200, scale=0.8, color=bui.app.ui_v1.infotextcolor, - position=(210, v - 9), + position=(210 + xoffs, v - 9), text=bui.Lstr( resource='maxPartySizeText', fallback_resource='maxConnectionsText', @@ -779,7 +788,7 @@ class PublicGatherTab(GatherTab): v_align='center', scale=1.2, color=(1, 1, 1), - position=(240, v - 9), + position=(240 + xoffs, v - 9), text=str(bs.get_public_party_max_size()), ) btn1 = self._host_max_party_size_minus_button = bui.buttonwidget( @@ -788,7 +797,7 @@ class PublicGatherTab(GatherTab): on_activate_call=bui.WeakCall( self._on_max_public_party_size_minus_press ), - position=(280, v - 26), + position=(280 + xoffs, v - 26), label='-', autoselect=True, ) @@ -798,7 +807,7 @@ class PublicGatherTab(GatherTab): on_activate_call=bui.WeakCall( self._on_max_public_party_size_plus_press ), - position=(350, v - 26), + position=(350 + xoffs, v - 26), label='+', autoselect=True, ) @@ -859,8 +868,8 @@ class PublicGatherTab(GatherTab): position=(c_width * 0.5, v), ) - # If public sharing is already on, - # launch a status-check immediately. + # If public sharing is already on, launch a status-check + # immediately. if bs.get_public_party_enabled(): self._do_status_check() @@ -884,9 +893,9 @@ class PublicGatherTab(GatherTab): self._pending_party_infos += parties_in # To avoid causing a stutter here, we do most processing of - # these entries incrementally in our _update() method. - # The one thing we do here is prune parties not contained in - # this result. + # these entries incrementally in our _update() method. The one + # thing we do here is prune parties not contained in this + # result. for partyval in list(self._parties.values()): partyval.claimed = False for party_in in parties_in: @@ -904,7 +913,6 @@ class PublicGatherTab(GatherTab): self._parties_sorted = [p for p in self._parties_sorted if p[1].claimed] self._party_lists_dirty = True - # self._update_server_list() if DEBUG_PROCESSING: print( f'Handled public party query results in ' @@ -926,10 +934,10 @@ class PublicGatherTab(GatherTab): self._filter_value = filter_value self._party_lists_dirty = True - # Also wipe out party clean-row states. - # (otherwise if a party disappears from a row due to - # filtering and then reappears on that same row when - # the filter is removed it may not update) + # Also wipe out party clean-row states (otherwise if + # a party disappears from a row due to filtering and + # then reappears on that same row when the filter is + # removed it may not update). for party in self._parties.values(): party.clean_display_index = None @@ -965,9 +973,9 @@ class PublicGatherTab(GatherTab): ) bui.spinnerwidget(edit=self._join_status_spinner, visible=False) else: - # If we have a valid list, show no status; just the list. - # Otherwise show either 'loading...' or 'error' depending - # on whether this is our first go-round. + # If we have a valid list, show no status; just the + # list. Otherwise show either 'loading...' or 'error' + # depending on whether this is our first go-round. if self._have_valid_server_list: bui.textwidget(edit=self._join_status_text, text='') bui.spinnerwidget( @@ -985,19 +993,6 @@ class PublicGatherTab(GatherTab): else: # Show our loading spinner. bui.textwidget(edit=self._join_status_text, text='') - # bui.textwidget( - # edit=self._join_status_text, - # text=bui.Lstr( - # value='${A}...', - # subs=[ - # ( - # '${A}', - # - # bui.Lstr(resource='store.loadingText'), - # ) - # ], - # ), - # ) bui.spinnerwidget( edit=self._join_status_spinner, visible=True ) @@ -1037,7 +1032,8 @@ class PublicGatherTab(GatherTab): ) return - sub_scroll_width = 830 + assert self._join_sub_scroll_width is not None + sub_scroll_width = self._join_sub_scroll_width lineheight = 42 sub_scroll_height = lineheight * len(self._parties_displayed) + 50 bui.containerwidget( @@ -1045,27 +1041,27 @@ class PublicGatherTab(GatherTab): ) # Any time our height changes, reset the refresh back to the top - # so we don't see ugly empty spaces appearing during initial list - # filling. + # so we don't see ugly empty spaces appearing during initial + # list filling. if sub_scroll_height != self._last_sub_scroll_height: self._refresh_ui_row = 0 self._last_sub_scroll_height = sub_scroll_height - # Also note that we need to redisplay everything since its pos - # will have changed.. :( + # Also note that we need to redisplay everything since its + # pos will have changed.. :( for party in self._parties.values(): party.clean_display_index = None - # Ew; this rebuilding generates deferred selection callbacks - # so we need to push deferred notices so we know to ignore them. + # Ew; this rebuilding generates deferred selection callbacks so + # we need to push deferred notices so we know to ignore them. def refresh_on() -> None: self._refreshing_list = True bui.pushcall(refresh_on) - # Ok, now here's the deal: we want to avoid creating/updating this - # entire list at one time because it will lead to hitches. So we - # refresh individual rows quickly in a loop. + # Ok, now here's the deal: we want to avoid creating/updating + # this entire list at one time because it will lead to hitches. + # So we refresh individual rows quickly in a loop. rowcount = min(12, len(self._parties_displayed)) party_vals_displayed = list(self._parties_displayed.values()) @@ -1075,9 +1071,10 @@ class PublicGatherTab(GatherTab): self._ui_rows.append(UIRow()) refresh_row = len(self._ui_rows) - 1 - # For the first few seconds after getting our first server-list, - # refresh only the top section of the list; this allows the lowest - # ping servers to show up more quickly. + # For the first few seconds after getting our first + # server-list, refresh only the top section of the list; + # this allows the lowest ping servers to show up more + # quickly. if self._first_valid_server_list_time is not None: if time.time() - self._first_valid_server_list_time < 4.0: if refresh_row > 40: @@ -1107,7 +1104,8 @@ class PublicGatherTab(GatherTab): def _process_pending_party_infos(self) -> None: starttime = time.time() - # We want to do this in small enough pieces to not cause UI hitches. + # We want to do this in small enough pieces to not cause UI + # hitches. chunksize = 30 parties_in = self._pending_party_infos[:chunksize] self._pending_party_infos = self._pending_party_infos[chunksize:] @@ -1191,16 +1189,16 @@ class PublicGatherTab(GatherTab): else: self._parties_displayed = dict(self._parties_sorted) - # Any time our selection disappears from the displayed list, go back to - # auto-selecting the top entry. + # Any time our selection disappears from the displayed list, go + # back to auto-selecting the top entry. if ( self._selection is not None and self._selection.entry_key not in self._parties_displayed ): self._have_user_selected_row = False - # Whenever the user hasn't selected something, keep the first visible - # row selected. + # Whenever the user hasn't selected something, keep the first + # visible row selected. if not self._have_user_selected_row and self._parties_displayed: firstpartykey = next(iter(self._parties_displayed)) self._selection = Selection(firstpartykey, SelectionComponent.NAME) @@ -1252,8 +1250,8 @@ class PublicGatherTab(GatherTab): party.next_ping_time <= now and bui.app.classic.ping_thread_count < 15 ): - # Crank the interval up for high-latency or non-responding - # parties to save us some useless work. + # 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: @@ -1283,16 +1281,16 @@ class PublicGatherTab(GatherTab): def _ping_callback( self, address: str, port: int | None, result: float | None ) -> None: - # Look for a widget corresponding to this target. - # If we find one, update our list. + # Look for a widget corresponding to this target. If we find + # one, update our list. party_key = f'{address}_{port}' party = self._parties.get(party_key) if party is not None: if result is not None: party.ping_responses += 1 - # We now smooth ping a bit to reduce jumping around in the list - # (only where pings are relatively good). + # We now smooth ping a bit to reduce jumping around in the + # list (only where pings are relatively good). current_ping = party.ping if current_ping is not None and result is not None and result < 150: smoothing = 0.7 @@ -1419,8 +1417,8 @@ class PublicGatherTab(GatherTab): bui.getsound('shieldUp').play() bs.set_public_party_enabled(True) - # In GUI builds we want to authenticate clients only when hosting - # public parties. + # In GUI builds we want to authenticate clients only when + # hosting public parties. bs.set_authenticate_clients(True) self._do_status_check() @@ -1436,8 +1434,8 @@ class PublicGatherTab(GatherTab): def _on_stop_advertising_press(self) -> None: bs.set_public_party_enabled(False) - # In GUI builds we want to authenticate clients only when hosting - # public parties. + # In GUI builds we want to authenticate clients only when + # hosting public parties. bs.set_authenticate_clients(False) bui.getsound('shieldDown').play() text = self._host_status_text diff --git a/src/assets/ba_data/python/bauiv1lib/help.py b/src/assets/ba_data/python/bauiv1lib/help.py index 12142234..61ef485a 100644 --- a/src/assets/ba_data/python/bauiv1lib/help.py +++ b/src/assets/ba_data/python/bauiv1lib/help.py @@ -58,7 +58,7 @@ class HelpWindow(bui.MainWindow): scroll_width = target_width scroll_height = target_height - 36 - scroll_y = yoffs - 64 - scroll_height + scroll_bottom = yoffs - 64 - scroll_height super().__init__( root_widget=bui.containerwidget( @@ -114,7 +114,7 @@ class HelpWindow(bui.MainWindow): self._scrollwidget = bui.scrollwidget( parent=self._root_widget, size=(scroll_width, scroll_height), - position=(width * 0.5 - scroll_width * 0.5, scroll_y), + position=(width * 0.5 - scroll_width * 0.5, scroll_bottom), simple_culling_v=100.0, capture_arrows=True, border_opacity=0.4, diff --git a/src/assets/ba_data/python/bauiv1lib/inbox.py b/src/assets/ba_data/python/bauiv1lib/inbox.py index f3e1daf7..9d498853 100644 --- a/src/assets/ba_data/python/bauiv1lib/inbox.py +++ b/src/assets/ba_data/python/bauiv1lib/inbox.py @@ -346,7 +346,7 @@ class InboxWindow(bui.MainWindow): scroll_width = target_width scroll_height = target_height - 31 - scroll_y = yoffs - 59 - scroll_height + scroll_bottom = yoffs - 59 - scroll_height super().__init__( root_widget=bui.containerwidget( @@ -420,7 +420,7 @@ class InboxWindow(bui.MainWindow): self._scrollwidget = bui.scrollwidget( parent=self._root_widget, size=(scroll_width, scroll_height), - position=(self._width * 0.5 - scroll_width * 0.5, scroll_y), + position=(self._width * 0.5 - scroll_width * 0.5, scroll_bottom), capture_arrows=True, simple_culling_v=200, claims_left_right=True, diff --git a/src/assets/ba_data/python/bauiv1lib/playlist/browser.py b/src/assets/ba_data/python/bauiv1lib/playlist/browser.py index 6bd66fc0..36b9aef9 100644 --- a/src/assets/ba_data/python/bauiv1lib/playlist/browser.py +++ b/src/assets/ba_data/python/bauiv1lib/playlist/browser.py @@ -84,7 +84,7 @@ class PlaylistBrowserWindow(bui.MainWindow): self._scroll_width = target_width self._scroll_height = target_height - 31 - scroll_y = yoffs - 60 - self._scroll_height + scroll_bottom = yoffs - 60 - self._scroll_height super().__init__( root_widget=bui.containerwidget( @@ -145,7 +145,10 @@ class PlaylistBrowserWindow(bui.MainWindow): parent=self._root_widget, highlight=False, size=(self._scroll_width, self._scroll_height), - position=(self._width * 0.5 - self._scroll_width * 0.5, scroll_y), + position=( + self._width * 0.5 - self._scroll_width * 0.5, + scroll_bottom, + ), border_opacity=0.4, center_small_content_horizontally=True, ) diff --git a/src/assets/ba_data/python/bauiv1lib/settings/advanced.py b/src/assets/ba_data/python/bauiv1lib/settings/advanced.py index e7eb2b07..ae079d50 100644 --- a/src/assets/ba_data/python/bauiv1lib/settings/advanced.py +++ b/src/assets/ba_data/python/bauiv1lib/settings/advanced.py @@ -70,7 +70,7 @@ class AdvancedSettingsWindow(bui.MainWindow): self._scroll_width = target_width self._scroll_height = target_height - 25 - scroll_y = yoffs - 56 - self._scroll_height + scroll_bottom = yoffs - 56 - self._scroll_height super().__init__( root_widget=bui.containerwidget( @@ -162,7 +162,10 @@ class AdvancedSettingsWindow(bui.MainWindow): self._scrollwidget = bui.scrollwidget( parent=self._root_widget, size=(self._scroll_width, self._scroll_height), - position=(self._width * 0.5 - self._scroll_width * 0.5, scroll_y), + position=( + self._width * 0.5 - self._scroll_width * 0.5, + scroll_bottom, + ), simple_culling_v=20.0, highlight=False, center_small_content_horizontally=True, diff --git a/src/assets/ba_data/python/bauiv1lib/watch.py b/src/assets/ba_data/python/bauiv1lib/watch.py index 05948678..7cd51758 100644 --- a/src/assets/ba_data/python/bauiv1lib/watch.py +++ b/src/assets/ba_data/python/bauiv1lib/watch.py @@ -45,36 +45,49 @@ class WatchWindow(bui.MainWindow): self._r = 'watchWindow' uiscale = bui.app.ui_v1.uiscale self._width = 1440 if uiscale is bui.UIScale.SMALL else 1040 - x_inset = 200 if uiscale is bui.UIScale.SMALL else 0 self._height = ( - 570 + 900 if uiscale is bui.UIScale.SMALL else 670 if uiscale is bui.UIScale.MEDIUM else 800 ) self._current_tab: WatchWindow.TabID | None = None - extra_top = 20 if uiscale is bui.UIScale.SMALL else 0 + + # Do some fancy math to fill all available screen area up to the + # size of our backing container. This lets us fit to the exact + # screen shape at small ui scale. + screensize = bui.get_virtual_screen_size() + scale = ( + 1.32 + if uiscale is bui.UIScale.SMALL + else 0.85 if uiscale is bui.UIScale.MEDIUM else 0.65 + ) + # Calc screen size in our local container space and clamp to a + # bit smaller than our container size. + target_width = min(self._width - 120, screensize[0] / scale) + target_height = min(self._height - 120, screensize[1] / scale) + + # To get top/left coords, go to the center of our window and + # offset by half the width/height of our target area. + self.yoffs = 0.5 * self._height + 0.5 * target_height + 30.0 + + self._scroll_width = target_width + self._scroll_height = target_height - 60 + self._scroll_y = self.yoffs - 90 - self._scroll_height super().__init__( root_widget=bui.containerwidget( - size=(self._width, self._height + extra_top), + size=(self._width, self._height), toolbar_visibility=( 'menu_minimal' if uiscale is bui.UIScale.SMALL else 'menu_full' ), - scale=( - 1.32 - if uiscale is bui.UIScale.SMALL - else 0.85 if uiscale is bui.UIScale.MEDIUM else 0.65 - ), - stack_offset=( - (0, 30) - if uiscale is bui.UIScale.SMALL - else (0, 0) if uiscale is bui.UIScale.MEDIUM else (0, 0) - ), + scale=scale, ), transition=transition, origin_widget=origin_widget, + # We're affected by screen size only at small ui-scale. + refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL, ) if uiscale is bui.UIScale.SMALL: @@ -86,7 +99,7 @@ class WatchWindow(bui.MainWindow): self._back_button = btn = bui.buttonwidget( parent=self._root_widget, autoselect=True, - position=(70 + x_inset, self._height - 74), + position=(70, self.yoffs - 50), size=(60, 60), scale=1.1, label=bui.charstr(bui.SpecialChar.BACK), @@ -99,11 +112,11 @@ class WatchWindow(bui.MainWindow): parent=self._root_widget, position=( self._width * 0.5, - self._height - (65 if uiscale is bui.UIScale.SMALL else 38), + self.yoffs - (44 if uiscale is bui.UIScale.SMALL else 10), ), size=(0, 0), color=bui.app.ui_v1.title_color, - scale=0.7 if uiscale is bui.UIScale.SMALL else 1.5, + scale=0.6 if uiscale is bui.UIScale.SMALL else 1.5, h_align='center', v_align='center', text=( @@ -119,17 +132,19 @@ class WatchWindow(bui.MainWindow): self.TabID.MY_REPLAYS, bui.Lstr(resource=f'{self._r}.myReplaysText'), ), - # (self.TabID.TEST_TAB, bui.Lstr(value='Testing')), ] - scroll_buffer_h = 130 + 2 * x_inset - tab_buffer_h = 750 + 2 * x_inset + tab_bar_width = 200.0 * len(tabdefs) + tab_bar_inset = (self._scroll_width - tab_bar_width) * 0.5 self._tab_row = TabRow( self._root_widget, tabdefs, - pos=(tab_buffer_h * 0.5, self._height - 130), - size=(self._width - tab_buffer_h, 50), + pos=( + self._width * 0.5 - self._scroll_width * 0.5 + tab_bar_inset, + self._scroll_y + self._scroll_height, + ), + size=(self._scroll_width - 2.0 * tab_bar_inset, 50), on_select_call=self._set_tab, ) @@ -143,20 +158,13 @@ class WatchWindow(bui.MainWindow): bbtn = bui.get_special_widget('back_button') bui.widget(edit=first_tab.button, up_widget=bbtn, left_widget=bbtn) - self._scroll_width = self._width - scroll_buffer_h - self._scroll_height = self._height - 180 - # Not actually using a scroll widget anymore; just an image. - scroll_left = (self._width - self._scroll_width) * 0.5 - scroll_bottom = self._height - self._scroll_height - 79 - 48 - buffer_h = 10 - buffer_v = 4 bui.imagewidget( parent=self._root_widget, - position=(scroll_left - buffer_h, scroll_bottom - buffer_v), - size=( - self._scroll_width + 2 * buffer_h, - self._scroll_height + 2 * buffer_v, + size=(self._scroll_width, self._scroll_height), + position=( + self._width * 0.5 - self._scroll_width * 0.5, + self._scroll_y, ), texture=bui.gettexture('scrollWidget'), mesh_transparent=bui.getmesh('softEdgeOutside'), @@ -199,7 +207,7 @@ class WatchWindow(bui.MainWindow): if self._tab_container: self._tab_container.delete() scroll_left = (self._width - self._scroll_width) * 0.5 - scroll_bottom = self._height - self._scroll_height - 79 - 48 + scroll_bottom = self._scroll_y # A place where tabs can store data to get cleared when # switching to a different tab @@ -249,9 +257,9 @@ class WatchWindow(bui.MainWindow): b_width = 140 if uiscale is bui.UIScale.SMALL else 178 b_height = ( - 107 + 110 if uiscale is bui.UIScale.SMALL - else 142 if uiscale is bui.UIScale.MEDIUM else 190 + else 142 if uiscale is bui.UIScale.MEDIUM else 180 ) b_space_extra = ( 0 @@ -264,14 +272,18 @@ class WatchWindow(bui.MainWindow): btnv = ( c_height - ( - 48 + 40 if uiscale is bui.UIScale.SMALL - else 45 if uiscale is bui.UIScale.MEDIUM else 40 + else 40 if uiscale is bui.UIScale.MEDIUM else 40 ) - b_height ) - btnh = 40 if uiscale is bui.UIScale.SMALL else 40 - smlh = 190 if uiscale is bui.UIScale.SMALL else 225 + # Roughly center buttons and scroll-widget in the middle. + xextra = ( + self._scroll_width - (sub_scroll_width + b_width) + ) * 0.5 - 50.0 + btnh = (40 if uiscale is bui.UIScale.SMALL else 40) + xextra + smlh = (190 if uiscale is bui.UIScale.SMALL else 225) + xextra tscl = 1.0 if uiscale is bui.UIScale.SMALL else 1.2 self._my_replays_watch_replay_button = btn1 = bui.buttonwidget( parent=cnt,