gather window is now screen-size-responsive

This commit is contained in:
Eric Froemling 2025-01-22 14:18:55 -08:00
parent b634f4e14f
commit 34ed3be00c
No known key found for this signature in database
10 changed files with 221 additions and 216 deletions

34
.efrocachemap generated
View File

@ -432,7 +432,7 @@
"build/assets/ba_data/audio/zoeOw.ogg": "b2d705c31c9dcc1efdc71394764c3beb", "build/assets/ba_data/audio/zoeOw.ogg": "b2d705c31c9dcc1efdc71394764c3beb",
"build/assets/ba_data/audio/zoePickup01.ogg": "e9366dc2d2b8ab8b0c4e2c14c02d0789", "build/assets/ba_data/audio/zoePickup01.ogg": "e9366dc2d2b8ab8b0c4e2c14c02d0789",
"build/assets/ba_data/audio/zoeScream01.ogg": "903e0e45ee9b3373e9d9ce20c814374e", "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/arabic.json": "32b9849fb8389b8c7798f0b744620318",
"build/assets/ba_data/data/languages/belarussian.json": "009b452aa308bf2b2f7e92d9b78ba5ff", "build/assets/ba_data/data/languages/belarussian.json": "009b452aa308bf2b2f7e92d9b78ba5ff",
"build/assets/ba_data/data/languages/chinese.json": "5363a79f843e6be7ef47a840f47cc17d", "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/russian.json": "780d1857df77ef59104d5dac75415bd6",
"build/assets/ba_data/data/languages/serbian.json": "623fa4129a1154c2f32ed7867e56ff6a", "build/assets/ba_data/data/languages/serbian.json": "623fa4129a1154c2f32ed7867e56ff6a",
"build/assets/ba_data/data/languages/slovak.json": "c11c29708b3742cdc2a92b4fa0d6d29f", "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/swedish.json": "3b179e7333183c70adb0811246b09959",
"build/assets/ba_data/data/languages/tamil.json": "ead39b864228696a9b0d19344bc4b5ec", "build/assets/ba_data/data/languages/tamil.json": "ead39b864228696a9b0d19344bc4b5ec",
"build/assets/ba_data/data/languages/thai.json": "383540a1e9c7c131ac579f51afc87471", "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/ukrainian.json": "0db55824759119aca74d2ee8ffe6daae",
"build/assets/ba_data/data/languages/venetian.json": "acea003316bef657925d776dd460e713", "build/assets/ba_data/data/languages/venetian.json": "acea003316bef657925d776dd460e713",
"build/assets/ba_data/data/languages/vietnamese.json": "017d8aa346d0c23a229a8a9acccf79a1", "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_gui/release/ballisticakit": "af6b01b85380b1a9874f8d7e7db435e4",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "23039996985b4aa93dff5aaf41067ea4", "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/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_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/mac_arm64_server/release/dist/ballisticakit_headless": "ee6d0760189953307799b7e06858aa87",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "89e6739f26b419ed71548fbba21f476f", "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "372d0ad3ef2bcd7f8fa93b9d83e2a300",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "3ef2b3179c424dfa97f4e50250cccc57", "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "e6f8c4f279931182f28722a33b9e3fc0",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "9b2170e71927e097b3e92a8ad993c81f", "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "8e28d37c93494d05479d3132a6525967",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "4bd75394e66b2eba2ec35d1d6119fd7a", "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/debug/libballisticaplus.a": "4d70703c4eba1a402fbc2d997d84aa93",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "bb64e2182b1a533679f93c5997f14584", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "bb64e2182b1a533679f93c5997f14584",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "4d70703c4eba1a402fbc2d997d84aa93", "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_gui/release/libballisticaplus.a": "116b500c2d57caf06619408b2176e83b",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "e3e9d9c7a94f8cd22939839fd8fbc178", "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "e3e9d9c7a94f8cd22939839fd8fbc178",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "116b500c2d57caf06619408b2176e83b", "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.lib": "3f2dddebc7313756f2f6ee83c377f265",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "a168a3ab32ab82e1775d2ac33f4ee859", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "d4a5d87e4ae724ae5e49cec56cb17a58",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "3023cfdf99e6a1af1c5daacd0a5ef93d", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "72d5ac0df3f03d2fceb5f015e9071ca3",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "4b2dad34e4edf32a00d6c32e7ed703e2", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "12b693aea7eb0a3d501bea4ae7de75e1",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "c1d35a57b5c9a84c4da24eaf5bdf210f", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "091f0ff2326739346407622d4d8cc449",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "49080baa202c08e0da85e8562ff7d889", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "4ad50d22cac50a74f4953abf24016088",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "04a2c999f64cde37a786fffec1b53e34", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "0be3a0c54d84379972bacc70f0c16887",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "af531d6fb63cd54cd02dd5a756fd167b", "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/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "794d258d59fd17a61752843a9a0551ad", "src/assets/ba_data/python/babase/_mgen/enums.py": "794d258d59fd17a61752843a9a0551ad",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "06042d31df0ff9af96b99477162e2a91", "src/ballistica/base/mgen/pyembed/binding_base.inc": "06042d31df0ff9af96b99477162e2a91",

View File

@ -89,7 +89,7 @@ class AccountSettingsWindow(bui.MainWindow):
self._scroll_width = target_width self._scroll_width = target_width
self._scroll_height = target_height - 33 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_button = None
self._sign_in_text = None self._sign_in_text = None
@ -174,7 +174,10 @@ class AccountSettingsWindow(bui.MainWindow):
parent=self._root_widget, parent=self._root_widget,
highlight=False, highlight=False,
size=(self._scroll_width, self._scroll_height), 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, claims_left_right=True,
selection_loops_to_parent=True, selection_loops_to_parent=True,
border_opacity=0.4, border_opacity=0.4,

View File

@ -55,7 +55,7 @@ class AchievementsWindow(bui.MainWindow):
scroll_width = target_width scroll_width = target_width
scroll_height = target_height - 25 scroll_height = target_height - 25
scroll_y = yoffs - 54 - scroll_height scroll_bottom = yoffs - 54 - scroll_height
super().__init__( super().__init__(
root_widget=bui.containerwidget( root_widget=bui.containerwidget(
@ -121,7 +121,7 @@ class AchievementsWindow(bui.MainWindow):
self._scrollwidget = bui.scrollwidget( self._scrollwidget = bui.scrollwidget(
parent=self._root_widget, parent=self._root_widget,
size=(scroll_width, scroll_height), 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, capture_arrows=True,
simple_culling_v=10, simple_culling_v=10,
border_opacity=0.4, border_opacity=0.4,

View File

@ -88,39 +88,56 @@ class GatherWindow(bui.MainWindow):
bui.set_analytics_screen('Gather Window') bui.set_analytics_screen('Gather Window')
uiscale = bui.app.ui_v1.uiscale uiscale = bui.app.ui_v1.uiscale
self._width = 1640 if uiscale is bui.UIScale.SMALL else 1040 self._width = (
x_offs = 200 if uiscale is bui.UIScale.SMALL else 0 1640
y_offs = -65 if uiscale is bui.UIScale.SMALL else 0
self._height = (
650
if uiscale is bui.UIScale.SMALL 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 self._current_tab: GatherWindow.TabID | None = None
extra_top = 20 if uiscale is bui.UIScale.SMALL else 0
self._r = 'gatherWindow' 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__( super().__init__(
root_widget=bui.containerwidget( root_widget=bui.containerwidget(
size=(self._width, self._height + extra_top), size=(self._width, self._height),
toolbar_visibility=( toolbar_visibility=(
'menu_tokens' 'menu_tokens'
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 'menu_full' else 'menu_full'
), ),
scale=( scale=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)
),
), ),
transition=transition, transition=transition,
origin_widget=origin_widget, 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: if uiscale is bui.UIScale.SMALL:
@ -131,46 +148,35 @@ class GatherWindow(bui.MainWindow):
else: else:
self._back_button = btn = bui.buttonwidget( self._back_button = btn = bui.buttonwidget(
parent=self._root_widget, parent=self._root_widget,
position=(70 + x_offs, self._height - 74 + y_offs), position=(70, yoffs - 43),
size=(140, 60), size=(60, 60),
scale=1.1, scale=1.1,
autoselect=True, autoselect=True,
label=bui.Lstr(resource='backText'), label=bui.charstr(bui.SpecialChar.BACK),
button_type='back', button_type='backSmall',
on_activate_call=self.main_window_back, on_activate_call=self.main_window_back,
) )
bui.containerwidget(edit=self._root_widget, cancel_button=btn) 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( bui.textwidget(
parent=self._root_widget, 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), size=(0, 0),
color=bui.app.ui_v1.title_color, color=bui.app.ui_v1.title_color,
scale=( scale=1.0,
1.5
if not condensed
else 1.0 if uiscale is bui.UIScale.MEDIUM else 1.0
),
h_align='center', h_align='center',
v_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, 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. # Build up the set of tabs we want.
tabdefs: list[tuple[GatherWindow.TabID, bui.Lstr]] = [ tabdefs: list[tuple[GatherWindow.TabID, bui.Lstr]] = [
(self.TabID.ABOUT, bui.Lstr(resource=f'{self._r}.aboutText')) (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')) (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 tab_inset = 100.0
# save a bit of space. tab_inset_extra_r = 150 if uiscale is bui.UIScale.SMALL else 0
tabs_top_extra = 42 if condensed else 0
self._tab_row = TabRow( self._tab_row = TabRow(
self._root_widget, self._root_widget,
tabdefs, tabdefs,
size=(self._scroll_width - 2.0 * tab_inset - tab_inset_extra_r, 50),
pos=( pos=(
tab_buffer_h * 0.5, self._scroll_left + tab_inset,
self._height - 130 + tabs_top_extra + y_offs, self._scroll_bottom + self._scroll_height,
), ),
size=(self._width - tab_buffer_h, 50),
on_select_call=bui.WeakCall(self._set_tab), on_select_call=bui.WeakCall(self._set_tab),
) )
@ -220,45 +225,26 @@ class GatherWindow(bui.MainWindow):
if tabtype is not None: if tabtype is not None:
self._tabs[tab_id] = tabtype(self) self._tabs[tab_id] = tabtype(self)
# Eww; tokens meter may or may not be here; should be smarter
# about this.
bui.widget( bui.widget(
edit=self._tab_row.tabs[tabdefs[-1][0]].button, 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: if uiscale is bui.UIScale.SMALL:
bui.widget( bui.widget(
edit=self._tab_row.tabs[tabdefs[0][0]].button, edit=self._tab_row.tabs[tabdefs[0][0]].button,
left_widget=bui.get_special_widget('back_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. # Not actually using a scroll widget anymore; just an image.
bui.imagewidget( bui.imagewidget(
parent=self._root_widget, parent=self._root_widget,
size=(self._scroll_width, self._scroll_height),
position=( position=(
self._scroll_left - buffer_h, self._width * 0.5 - self._scroll_width * 0.5,
self._scroll_bottom - buffer_v, self._scroll_bottom,
),
size=(
self._scroll_width + 2 * buffer_h,
self._scroll_height + 2 * buffer_v,
), ),
texture=bui.gettexture('scrollWidget'), texture=bui.gettexture('scrollWidget'),
mesh_transparent=bui.getmesh('softEdgeOutside'), mesh_transparent=bui.getmesh('softEdgeOutside'),

View File

@ -162,7 +162,8 @@ class UIRow:
Selection(party.get_key(), SelectionComponent.STATS_BUTTON), Selection(party.get_key(), SelectionComponent.STATS_BUTTON),
), ),
size=(120, 40), 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, scale=0.9,
) )
if existing_selection == Selection( if existing_selection == Selection(
@ -176,7 +177,8 @@ class UIRow:
text=str(party.size) + '/' + str(party.size_max), text=str(party.size) + '/' + str(party.size_max),
parent=columnwidget, parent=columnwidget,
size=(0, 0), 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, scale=0.7,
color=(0.8, 0.8, 0.8), color=(0.8, 0.8, 0.8),
h_align='right', h_align='right',
@ -191,7 +193,8 @@ class UIRow:
self._ping_widget = bui.textwidget( self._ping_widget = bui.textwidget(
parent=columnwidget, parent=columnwidget,
size=(0, 0), 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, scale=0.7,
h_align='right', h_align='right',
v_align='center', 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_value: bui.Widget | None = None
self._host_max_party_size_minus_button: 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._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._host_status_text: bui.Widget | None = None
self._signed_in = False self._signed_in = False
self._ui_rows: list[UIRow] = [] self._ui_rows: list[UIRow] = []
@ -474,7 +478,8 @@ class PublicGatherTab(GatherTab):
) )
bui.widget(edit=self._join_text, right_widget=self._host_text) 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: if self._local_address is None:
AddrFetchThread(bui.WeakCall(self._fetch_local_addr_cb)).start() AddrFetchThread(bui.WeakCall(self._fetch_local_addr_cb)).start()
@ -491,9 +496,9 @@ class PublicGatherTab(GatherTab):
@override @override
def save_state(self) -> None: def save_state(self) -> None:
# Save off a small number of parties with the lowest ping; we'll # Save off a small number of parties with the lowest ping; we'll
# display these immediately when our UI comes back up which should # display these immediately when our UI comes back up which
# be enough to make things feel nice and crisp while we do a full # should be enough to make things feel nice and crisp while we
# server re-query or whatnot. # do a full server re-query or whatnot.
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.window_states[type(self)] = State( bui.app.ui_v1.window_states[type(self)] = State(
sub_tab=self._sub_tab, sub_tab=self._sub_tab,
@ -523,7 +528,7 @@ class PublicGatherTab(GatherTab):
self._next_entry_index = state.next_entry_index 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_server_list_response = state.have_server_list_response
self._have_valid_server_list = state.have_valid_server_list self._have_valid_server_list = state.have_valid_server_list
self._filter_value = state.filter_value self._filter_value = state.filter_value
@ -539,9 +544,8 @@ class PublicGatherTab(GatherTab):
if playsound: if playsound:
bui.getsound('click01').play() bui.getsound('click01').play()
# Reset our selection. # Reset our selection (prevents selecting something way down the
# (prevents selecting something way down the list if we switched away # list if we switched away and came back).
# and came back)
self._selection = None self._selection = None
self._have_user_selected_row = False self._have_user_selected_row = False
@ -579,7 +583,9 @@ class PublicGatherTab(GatherTab):
c_width = region_width c_width = region_width
c_height = region_height - 20 c_height = region_height - 20
sub_scroll_height = c_height - 125 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 = c_height - 35
v -= 60 v -= 60
filter_txt = bui.Lstr(resource='filterText') filter_txt = bui.Lstr(resource='filterText')
@ -726,6 +732,9 @@ class PublicGatherTab(GatherTab):
) )
v -= 30 v -= 30
# Nudge party name and size values to be mostly centered.
xoffs = region_width * 0.5 - 500
party_name_text = bui.Lstr( party_name_text = bui.Lstr(
resource='gatherWindow.partyNameText', resource='gatherWindow.partyNameText',
fallback_resource='editGameListWindow.nameText', fallback_resource='editGameListWindow.nameText',
@ -739,14 +748,14 @@ class PublicGatherTab(GatherTab):
maxwidth=200, maxwidth=200,
scale=0.8, scale=0.8,
color=bui.app.ui_v1.infotextcolor, color=bui.app.ui_v1.infotextcolor,
position=(210, v - 9), position=(210 + xoffs, v - 9),
text=party_name_text, text=party_name_text,
) )
self._host_name_text = bui.textwidget( self._host_name_text = bui.textwidget(
parent=self._container, parent=self._container,
editable=True, editable=True,
size=(535, 40), size=(535, 40),
position=(230, v - 30), position=(230 + xoffs, v - 30),
text=bui.app.config.get('Public Party Name', ''), text=bui.app.config.get('Public Party Name', ''),
maxwidth=494, maxwidth=494,
shadow=0.3, shadow=0.3,
@ -766,7 +775,7 @@ class PublicGatherTab(GatherTab):
maxwidth=200, maxwidth=200,
scale=0.8, scale=0.8,
color=bui.app.ui_v1.infotextcolor, color=bui.app.ui_v1.infotextcolor,
position=(210, v - 9), position=(210 + xoffs, v - 9),
text=bui.Lstr( text=bui.Lstr(
resource='maxPartySizeText', resource='maxPartySizeText',
fallback_resource='maxConnectionsText', fallback_resource='maxConnectionsText',
@ -779,7 +788,7 @@ class PublicGatherTab(GatherTab):
v_align='center', v_align='center',
scale=1.2, scale=1.2,
color=(1, 1, 1), color=(1, 1, 1),
position=(240, v - 9), position=(240 + xoffs, v - 9),
text=str(bs.get_public_party_max_size()), text=str(bs.get_public_party_max_size()),
) )
btn1 = self._host_max_party_size_minus_button = bui.buttonwidget( btn1 = self._host_max_party_size_minus_button = bui.buttonwidget(
@ -788,7 +797,7 @@ class PublicGatherTab(GatherTab):
on_activate_call=bui.WeakCall( on_activate_call=bui.WeakCall(
self._on_max_public_party_size_minus_press self._on_max_public_party_size_minus_press
), ),
position=(280, v - 26), position=(280 + xoffs, v - 26),
label='-', label='-',
autoselect=True, autoselect=True,
) )
@ -798,7 +807,7 @@ class PublicGatherTab(GatherTab):
on_activate_call=bui.WeakCall( on_activate_call=bui.WeakCall(
self._on_max_public_party_size_plus_press self._on_max_public_party_size_plus_press
), ),
position=(350, v - 26), position=(350 + xoffs, v - 26),
label='+', label='+',
autoselect=True, autoselect=True,
) )
@ -859,8 +868,8 @@ class PublicGatherTab(GatherTab):
position=(c_width * 0.5, v), position=(c_width * 0.5, v),
) )
# If public sharing is already on, # If public sharing is already on, launch a status-check
# launch a status-check immediately. # immediately.
if bs.get_public_party_enabled(): if bs.get_public_party_enabled():
self._do_status_check() self._do_status_check()
@ -884,9 +893,9 @@ class PublicGatherTab(GatherTab):
self._pending_party_infos += parties_in self._pending_party_infos += parties_in
# To avoid causing a stutter here, we do most processing of # To avoid causing a stutter here, we do most processing of
# these entries incrementally in our _update() method. # these entries incrementally in our _update() method. The one
# The one thing we do here is prune parties not contained in # thing we do here is prune parties not contained in this
# this result. # result.
for partyval in list(self._parties.values()): for partyval in list(self._parties.values()):
partyval.claimed = False partyval.claimed = False
for party_in in parties_in: 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._parties_sorted = [p for p in self._parties_sorted if p[1].claimed]
self._party_lists_dirty = True self._party_lists_dirty = True
# self._update_server_list()
if DEBUG_PROCESSING: if DEBUG_PROCESSING:
print( print(
f'Handled public party query results in ' f'Handled public party query results in '
@ -926,10 +934,10 @@ class PublicGatherTab(GatherTab):
self._filter_value = filter_value self._filter_value = filter_value
self._party_lists_dirty = True self._party_lists_dirty = True
# Also wipe out party clean-row states. # Also wipe out party clean-row states (otherwise if
# (otherwise if a party disappears from a row due to # a party disappears from a row due to filtering and
# filtering and then reappears on that same row when # then reappears on that same row when the filter is
# the filter is removed it may not update) # removed it may not update).
for party in self._parties.values(): for party in self._parties.values():
party.clean_display_index = None party.clean_display_index = None
@ -965,9 +973,9 @@ class PublicGatherTab(GatherTab):
) )
bui.spinnerwidget(edit=self._join_status_spinner, visible=False) bui.spinnerwidget(edit=self._join_status_spinner, visible=False)
else: else:
# If we have a valid list, show no status; just the list. # If we have a valid list, show no status; just the
# Otherwise show either 'loading...' or 'error' depending # list. Otherwise show either 'loading...' or 'error'
# on whether this is our first go-round. # depending on whether this is our first go-round.
if self._have_valid_server_list: if self._have_valid_server_list:
bui.textwidget(edit=self._join_status_text, text='') bui.textwidget(edit=self._join_status_text, text='')
bui.spinnerwidget( bui.spinnerwidget(
@ -985,19 +993,6 @@ class PublicGatherTab(GatherTab):
else: else:
# Show our loading spinner. # Show our loading spinner.
bui.textwidget(edit=self._join_status_text, text='') 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( bui.spinnerwidget(
edit=self._join_status_spinner, visible=True edit=self._join_status_spinner, visible=True
) )
@ -1037,7 +1032,8 @@ class PublicGatherTab(GatherTab):
) )
return return
sub_scroll_width = 830 assert self._join_sub_scroll_width is not None
sub_scroll_width = self._join_sub_scroll_width
lineheight = 42 lineheight = 42
sub_scroll_height = lineheight * len(self._parties_displayed) + 50 sub_scroll_height = lineheight * len(self._parties_displayed) + 50
bui.containerwidget( bui.containerwidget(
@ -1045,27 +1041,27 @@ class PublicGatherTab(GatherTab):
) )
# Any time our height changes, reset the refresh back to the top # Any time our height changes, reset the refresh back to the top
# so we don't see ugly empty spaces appearing during initial list # so we don't see ugly empty spaces appearing during initial
# filling. # list filling.
if sub_scroll_height != self._last_sub_scroll_height: if sub_scroll_height != self._last_sub_scroll_height:
self._refresh_ui_row = 0 self._refresh_ui_row = 0
self._last_sub_scroll_height = sub_scroll_height self._last_sub_scroll_height = sub_scroll_height
# Also note that we need to redisplay everything since its pos # Also note that we need to redisplay everything since its
# will have changed.. :( # pos will have changed.. :(
for party in self._parties.values(): for party in self._parties.values():
party.clean_display_index = None party.clean_display_index = None
# Ew; this rebuilding generates deferred selection callbacks # Ew; this rebuilding generates deferred selection callbacks so
# so we need to push deferred notices so we know to ignore them. # we need to push deferred notices so we know to ignore them.
def refresh_on() -> None: def refresh_on() -> None:
self._refreshing_list = True self._refreshing_list = True
bui.pushcall(refresh_on) bui.pushcall(refresh_on)
# Ok, now here's the deal: we want to avoid creating/updating this # Ok, now here's the deal: we want to avoid creating/updating
# entire list at one time because it will lead to hitches. So we # this entire list at one time because it will lead to hitches.
# refresh individual rows quickly in a loop. # So we refresh individual rows quickly in a loop.
rowcount = min(12, len(self._parties_displayed)) rowcount = min(12, len(self._parties_displayed))
party_vals_displayed = list(self._parties_displayed.values()) party_vals_displayed = list(self._parties_displayed.values())
@ -1075,9 +1071,10 @@ class PublicGatherTab(GatherTab):
self._ui_rows.append(UIRow()) self._ui_rows.append(UIRow())
refresh_row = len(self._ui_rows) - 1 refresh_row = len(self._ui_rows) - 1
# For the first few seconds after getting our first server-list, # For the first few seconds after getting our first
# refresh only the top section of the list; this allows the lowest # server-list, refresh only the top section of the list;
# ping servers to show up more quickly. # this allows the lowest ping servers to show up more
# quickly.
if self._first_valid_server_list_time is not None: if self._first_valid_server_list_time is not None:
if time.time() - self._first_valid_server_list_time < 4.0: if time.time() - self._first_valid_server_list_time < 4.0:
if refresh_row > 40: if refresh_row > 40:
@ -1107,7 +1104,8 @@ class PublicGatherTab(GatherTab):
def _process_pending_party_infos(self) -> None: def _process_pending_party_infos(self) -> None:
starttime = time.time() 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 chunksize = 30
parties_in = self._pending_party_infos[:chunksize] parties_in = self._pending_party_infos[:chunksize]
self._pending_party_infos = self._pending_party_infos[chunksize:] self._pending_party_infos = self._pending_party_infos[chunksize:]
@ -1191,16 +1189,16 @@ class PublicGatherTab(GatherTab):
else: else:
self._parties_displayed = dict(self._parties_sorted) self._parties_displayed = dict(self._parties_sorted)
# Any time our selection disappears from the displayed list, go back to # Any time our selection disappears from the displayed list, go
# auto-selecting the top entry. # back to auto-selecting the top entry.
if ( if (
self._selection is not None self._selection is not None
and self._selection.entry_key not in self._parties_displayed and self._selection.entry_key not in self._parties_displayed
): ):
self._have_user_selected_row = False self._have_user_selected_row = False
# Whenever the user hasn't selected something, keep the first visible # Whenever the user hasn't selected something, keep the first
# row selected. # visible row selected.
if not self._have_user_selected_row and self._parties_displayed: if not self._have_user_selected_row and self._parties_displayed:
firstpartykey = next(iter(self._parties_displayed)) firstpartykey = next(iter(self._parties_displayed))
self._selection = Selection(firstpartykey, SelectionComponent.NAME) self._selection = Selection(firstpartykey, SelectionComponent.NAME)
@ -1252,8 +1250,8 @@ class PublicGatherTab(GatherTab):
party.next_ping_time <= now party.next_ping_time <= now
and bui.app.classic.ping_thread_count < 15 and bui.app.classic.ping_thread_count < 15
): ):
# Crank the interval up for high-latency or non-responding # Crank the interval up for high-latency or
# parties to save us some useless work. # non-responding parties to save us some useless work.
mult = 1 mult = 1
if party.ping_responses == 0: if party.ping_responses == 0:
if party.ping_attempts > 4: if party.ping_attempts > 4:
@ -1283,16 +1281,16 @@ class PublicGatherTab(GatherTab):
def _ping_callback( def _ping_callback(
self, address: str, port: int | None, result: float | None self, address: str, port: int | None, result: float | None
) -> None: ) -> None:
# Look for a widget corresponding to this target. # Look for a widget corresponding to this target. If we find
# If we find one, update our list. # one, update our list.
party_key = f'{address}_{port}' party_key = f'{address}_{port}'
party = self._parties.get(party_key) party = self._parties.get(party_key)
if party is not None: if party is not None:
if result is not None: if result is not None:
party.ping_responses += 1 party.ping_responses += 1
# We now smooth ping a bit to reduce jumping around in the list # We now smooth ping a bit to reduce jumping around in the
# (only where pings are relatively good). # list (only where pings are relatively good).
current_ping = party.ping current_ping = party.ping
if current_ping is not None and result is not None and result < 150: if current_ping is not None and result is not None and result < 150:
smoothing = 0.7 smoothing = 0.7
@ -1419,8 +1417,8 @@ class PublicGatherTab(GatherTab):
bui.getsound('shieldUp').play() bui.getsound('shieldUp').play()
bs.set_public_party_enabled(True) bs.set_public_party_enabled(True)
# In GUI builds we want to authenticate clients only when hosting # In GUI builds we want to authenticate clients only when
# public parties. # hosting public parties.
bs.set_authenticate_clients(True) bs.set_authenticate_clients(True)
self._do_status_check() self._do_status_check()
@ -1436,8 +1434,8 @@ class PublicGatherTab(GatherTab):
def _on_stop_advertising_press(self) -> None: def _on_stop_advertising_press(self) -> None:
bs.set_public_party_enabled(False) bs.set_public_party_enabled(False)
# In GUI builds we want to authenticate clients only when hosting # In GUI builds we want to authenticate clients only when
# public parties. # hosting public parties.
bs.set_authenticate_clients(False) bs.set_authenticate_clients(False)
bui.getsound('shieldDown').play() bui.getsound('shieldDown').play()
text = self._host_status_text text = self._host_status_text

View File

@ -58,7 +58,7 @@ class HelpWindow(bui.MainWindow):
scroll_width = target_width scroll_width = target_width
scroll_height = target_height - 36 scroll_height = target_height - 36
scroll_y = yoffs - 64 - scroll_height scroll_bottom = yoffs - 64 - scroll_height
super().__init__( super().__init__(
root_widget=bui.containerwidget( root_widget=bui.containerwidget(
@ -114,7 +114,7 @@ class HelpWindow(bui.MainWindow):
self._scrollwidget = bui.scrollwidget( self._scrollwidget = bui.scrollwidget(
parent=self._root_widget, parent=self._root_widget,
size=(scroll_width, scroll_height), 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, simple_culling_v=100.0,
capture_arrows=True, capture_arrows=True,
border_opacity=0.4, border_opacity=0.4,

View File

@ -346,7 +346,7 @@ class InboxWindow(bui.MainWindow):
scroll_width = target_width scroll_width = target_width
scroll_height = target_height - 31 scroll_height = target_height - 31
scroll_y = yoffs - 59 - scroll_height scroll_bottom = yoffs - 59 - scroll_height
super().__init__( super().__init__(
root_widget=bui.containerwidget( root_widget=bui.containerwidget(
@ -420,7 +420,7 @@ class InboxWindow(bui.MainWindow):
self._scrollwidget = bui.scrollwidget( self._scrollwidget = bui.scrollwidget(
parent=self._root_widget, parent=self._root_widget,
size=(scroll_width, scroll_height), 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, capture_arrows=True,
simple_culling_v=200, simple_culling_v=200,
claims_left_right=True, claims_left_right=True,

View File

@ -84,7 +84,7 @@ class PlaylistBrowserWindow(bui.MainWindow):
self._scroll_width = target_width self._scroll_width = target_width
self._scroll_height = target_height - 31 self._scroll_height = target_height - 31
scroll_y = yoffs - 60 - self._scroll_height scroll_bottom = yoffs - 60 - self._scroll_height
super().__init__( super().__init__(
root_widget=bui.containerwidget( root_widget=bui.containerwidget(
@ -145,7 +145,10 @@ class PlaylistBrowserWindow(bui.MainWindow):
parent=self._root_widget, parent=self._root_widget,
highlight=False, highlight=False,
size=(self._scroll_width, self._scroll_height), 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, border_opacity=0.4,
center_small_content_horizontally=True, center_small_content_horizontally=True,
) )

View File

@ -70,7 +70,7 @@ class AdvancedSettingsWindow(bui.MainWindow):
self._scroll_width = target_width self._scroll_width = target_width
self._scroll_height = target_height - 25 self._scroll_height = target_height - 25
scroll_y = yoffs - 56 - self._scroll_height scroll_bottom = yoffs - 56 - self._scroll_height
super().__init__( super().__init__(
root_widget=bui.containerwidget( root_widget=bui.containerwidget(
@ -162,7 +162,10 @@ class AdvancedSettingsWindow(bui.MainWindow):
self._scrollwidget = bui.scrollwidget( self._scrollwidget = bui.scrollwidget(
parent=self._root_widget, parent=self._root_widget,
size=(self._scroll_width, self._scroll_height), 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, simple_culling_v=20.0,
highlight=False, highlight=False,
center_small_content_horizontally=True, center_small_content_horizontally=True,

View File

@ -45,36 +45,49 @@ class WatchWindow(bui.MainWindow):
self._r = 'watchWindow' self._r = 'watchWindow'
uiscale = bui.app.ui_v1.uiscale uiscale = bui.app.ui_v1.uiscale
self._width = 1440 if uiscale is bui.UIScale.SMALL else 1040 self._width = 1440 if uiscale is bui.UIScale.SMALL else 1040
x_inset = 200 if uiscale is bui.UIScale.SMALL else 0
self._height = ( self._height = (
570 900
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 670 if uiscale is bui.UIScale.MEDIUM else 800 else 670 if uiscale is bui.UIScale.MEDIUM else 800
) )
self._current_tab: WatchWindow.TabID | None = None 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__( super().__init__(
root_widget=bui.containerwidget( root_widget=bui.containerwidget(
size=(self._width, self._height + extra_top), size=(self._width, self._height),
toolbar_visibility=( toolbar_visibility=(
'menu_minimal' 'menu_minimal'
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 'menu_full' else 'menu_full'
), ),
scale=( scale=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)
),
), ),
transition=transition, transition=transition,
origin_widget=origin_widget, 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: if uiscale is bui.UIScale.SMALL:
@ -86,7 +99,7 @@ class WatchWindow(bui.MainWindow):
self._back_button = btn = bui.buttonwidget( self._back_button = btn = bui.buttonwidget(
parent=self._root_widget, parent=self._root_widget,
autoselect=True, autoselect=True,
position=(70 + x_inset, self._height - 74), position=(70, self.yoffs - 50),
size=(60, 60), size=(60, 60),
scale=1.1, scale=1.1,
label=bui.charstr(bui.SpecialChar.BACK), label=bui.charstr(bui.SpecialChar.BACK),
@ -99,11 +112,11 @@ class WatchWindow(bui.MainWindow):
parent=self._root_widget, parent=self._root_widget,
position=( position=(
self._width * 0.5, 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), size=(0, 0),
color=bui.app.ui_v1.title_color, 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', h_align='center',
v_align='center', v_align='center',
text=( text=(
@ -119,17 +132,19 @@ class WatchWindow(bui.MainWindow):
self.TabID.MY_REPLAYS, self.TabID.MY_REPLAYS,
bui.Lstr(resource=f'{self._r}.myReplaysText'), bui.Lstr(resource=f'{self._r}.myReplaysText'),
), ),
# (self.TabID.TEST_TAB, bui.Lstr(value='Testing')),
] ]
scroll_buffer_h = 130 + 2 * x_inset tab_bar_width = 200.0 * len(tabdefs)
tab_buffer_h = 750 + 2 * x_inset tab_bar_inset = (self._scroll_width - tab_bar_width) * 0.5
self._tab_row = TabRow( self._tab_row = TabRow(
self._root_widget, self._root_widget,
tabdefs, tabdefs,
pos=(tab_buffer_h * 0.5, self._height - 130), pos=(
size=(self._width - tab_buffer_h, 50), 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, on_select_call=self._set_tab,
) )
@ -143,20 +158,13 @@ class WatchWindow(bui.MainWindow):
bbtn = bui.get_special_widget('back_button') bbtn = bui.get_special_widget('back_button')
bui.widget(edit=first_tab.button, up_widget=bbtn, left_widget=bbtn) 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. # 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( bui.imagewidget(
parent=self._root_widget, parent=self._root_widget,
position=(scroll_left - buffer_h, scroll_bottom - buffer_v), size=(self._scroll_width, self._scroll_height),
size=( position=(
self._scroll_width + 2 * buffer_h, self._width * 0.5 - self._scroll_width * 0.5,
self._scroll_height + 2 * buffer_v, self._scroll_y,
), ),
texture=bui.gettexture('scrollWidget'), texture=bui.gettexture('scrollWidget'),
mesh_transparent=bui.getmesh('softEdgeOutside'), mesh_transparent=bui.getmesh('softEdgeOutside'),
@ -199,7 +207,7 @@ class WatchWindow(bui.MainWindow):
if self._tab_container: if self._tab_container:
self._tab_container.delete() self._tab_container.delete()
scroll_left = (self._width - self._scroll_width) * 0.5 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 # A place where tabs can store data to get cleared when
# switching to a different tab # 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_width = 140 if uiscale is bui.UIScale.SMALL else 178
b_height = ( b_height = (
107 110
if uiscale is bui.UIScale.SMALL 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 = ( b_space_extra = (
0 0
@ -264,14 +272,18 @@ class WatchWindow(bui.MainWindow):
btnv = ( btnv = (
c_height c_height
- ( - (
48 40
if uiscale is bui.UIScale.SMALL 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 - b_height
) )
btnh = 40 if uiscale is bui.UIScale.SMALL else 40 # Roughly center buttons and scroll-widget in the middle.
smlh = 190 if uiscale is bui.UIScale.SMALL else 225 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 tscl = 1.0 if uiscale is bui.UIScale.SMALL else 1.2
self._my_replays_watch_replay_button = btn1 = bui.buttonwidget( self._my_replays_watch_replay_button = btn1 = bui.buttonwidget(
parent=cnt, parent=cnt,