mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-24 16:06:51 +08:00
Work on type-safe TabRow class
This commit is contained in:
parent
eba70f0c81
commit
981375f51e
@ -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/dd/d1/e12c5331256ecffcd7684d6d2963",
|
||||
"build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c5/35/8d811eec1a47f4e70d4b27eb3bf5",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6f/43/d0f61fb34a76e11b9ebd4334038d",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a4/56/614e09d8ab86355f0d65c1ce76fe",
|
||||
"build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f7/c5/f695953295c2d79dfb01555aea89",
|
||||
"build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/7b/19/ff1bba3a148b6e0f0823d7d7c7bf",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f7/dd/d5e4d872192060d46821d6911c13",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/64/58/962c2e707ee66d310848f375796a",
|
||||
"build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/db/58/65c487facba1de6ba8ce65f19f01",
|
||||
"build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/40/cb/afd71350fdc9827ca99baab73001",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/f2/05/e9252b68a96ee418da35dd4d2530",
|
||||
"build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/bb/a2/e1f5b3f561a08bb09cc3ffb2492f",
|
||||
"build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/81/be/dd6f786f096520a5450b96b0efd9",
|
||||
"build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/b0/14/defa61c54179e1810f8308cac55c",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/89/2d/9c41cd7bba801f79906a397f9b23",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/78/bb/4656448316b4b5ff7bc348ede9f2",
|
||||
"build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c0/e0/54ff7942beddb65315194b79da09",
|
||||
"build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/5b/52/1771901e2344bad49238986c80b2",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2d/d7/e1ffb234f71e715587456fc7cfd8",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/99/88/2ee8c18b63f64425516050c8a304",
|
||||
"build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/ac/a2/75427a8ecc1f19d402b58f9014e6",
|
||||
"build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d7/d4/4640f90f0ae2d2b98b8fbf099c2f",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/95/94/a110e7c8d338d5a6cefe2e975e8b",
|
||||
"build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/51/26/638d82bbf9acbfaffd8cfe780671",
|
||||
"build/prefab/lib/linux_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/66/c9/3b04209f599dea8b8ca4be7d3404",
|
||||
"build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0d/3b/b7b46c3131cff8a40dfaa001af38",
|
||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/57/40/0c1d88af3ce14e0f8870ab9ac7ad",
|
||||
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8a/72/02b4eddf662001f05f98288d4ad4",
|
||||
"build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fc/bc/51529aac7531d1a62cf13eb79153",
|
||||
"build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ea/7b/de9ce5284627cc77b2fffc354a66",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/96/00/78b64146e33ec35dcde9c278328a",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6d/25/0e5918fa1eb7285538d14051761c"
|
||||
"build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ac/e6/0e2476b60bfa7d3af4e9a2a6db1f",
|
||||
"build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f3/81/218f5899da12bcaf1128175e7ef0",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/84/14/923a2f78920255adffe574b613d6",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4e/f0/8e6fdd837a08e6daae5bd9e743dc"
|
||||
}
|
||||
13
.idea/dictionaries/ericf.xml
generated
13
.idea/dictionaries/ericf.xml
generated
@ -29,8 +29,8 @@
|
||||
<w>achname</w>
|
||||
<w>achs</w>
|
||||
<w>acinstance</w>
|
||||
<w>ack</w>
|
||||
<w>ack'ed</w>
|
||||
<w>ack</w>
|
||||
<w>acked</w>
|
||||
<w>acks</w>
|
||||
<w>acnt</w>
|
||||
@ -152,8 +152,8 @@
|
||||
<w>bacommon</w>
|
||||
<w>badguy</w>
|
||||
<w>bafoundation</w>
|
||||
<w>ballistica</w>
|
||||
<w>ballistica's</w>
|
||||
<w>ballistica</w>
|
||||
<w>ballisticacore</w>
|
||||
<w>ballisticacorecb</w>
|
||||
<w>bamaster</w>
|
||||
@ -800,8 +800,8 @@
|
||||
<w>gamedata</w>
|
||||
<w>gameinstance</w>
|
||||
<w>gamemap</w>
|
||||
<w>gamepad</w>
|
||||
<w>gamepad's</w>
|
||||
<w>gamepad</w>
|
||||
<w>gamepadadvanced</w>
|
||||
<w>gamepads</w>
|
||||
<w>gamepadselect</w>
|
||||
@ -1189,8 +1189,8 @@
|
||||
<w>lsqlite</w>
|
||||
<w>lssl</w>
|
||||
<w>lstart</w>
|
||||
<w>lstr</w>
|
||||
<w>lstr's</w>
|
||||
<w>lstr</w>
|
||||
<w>lstrs</w>
|
||||
<w>lsval</w>
|
||||
<w>ltex</w>
|
||||
@ -1823,8 +1823,8 @@
|
||||
<w>sessionname</w>
|
||||
<w>sessionplayer</w>
|
||||
<w>sessionplayers</w>
|
||||
<w>sessionteam</w>
|
||||
<w>sessionteam's</w>
|
||||
<w>sessionteam</w>
|
||||
<w>sessionteams</w>
|
||||
<w>sessiontype</w>
|
||||
<w>setactivity</w>
|
||||
@ -2009,6 +2009,7 @@
|
||||
<w>sysconfigdata</w>
|
||||
<w>sysctl</w>
|
||||
<w>syslogmodule</w>
|
||||
<w>tabdefs</w>
|
||||
<w>tabval</w>
|
||||
<w>tagargs</w>
|
||||
<w>tagversion</w>
|
||||
@ -2156,8 +2157,8 @@
|
||||
<w>txtw</w>
|
||||
<w>typeargs</w>
|
||||
<w>typecheck</w>
|
||||
<w>typechecker</w>
|
||||
<w>typechecker's</w>
|
||||
<w>typechecker</w>
|
||||
<w>typedval</w>
|
||||
<w>typeshed</w>
|
||||
<w>typestr</w>
|
||||
|
||||
@ -7,6 +7,14 @@ import random
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import _ba
|
||||
from ba._music import MusicSubsystem
|
||||
from ba._language import LanguageSubsystem
|
||||
from ba._ui import UISubsystem
|
||||
from ba._achievement import AchievementSubsystem
|
||||
from ba._plugin import PluginSubsystem
|
||||
from ba._account import AccountSubsystem
|
||||
from ba._meta import MetadataSubsystem
|
||||
from ba._ads import AdsSubsystem
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import ba
|
||||
@ -165,14 +173,6 @@ class App:
|
||||
the single shared instance.
|
||||
"""
|
||||
# pylint: disable=too-many-statements
|
||||
from ba._music import MusicSubsystem
|
||||
from ba._language import LanguageSubsystem
|
||||
from ba._ui import UISubsystem
|
||||
from ba._achievement import AchievementSubsystem
|
||||
from ba._plugin import PluginSubsystem
|
||||
from ba._account import AccountSubsystem
|
||||
from ba._meta import MetadataSubsystem
|
||||
from ba._ads import AdsSubsystem
|
||||
|
||||
# Config.
|
||||
self.config_file_healthy = False
|
||||
|
||||
@ -175,6 +175,7 @@ def print_live_object_warnings(when: Any,
|
||||
from ba._session import Session
|
||||
from ba._actor import Actor
|
||||
from ba._activity import Activity
|
||||
|
||||
sessions: List[ba.Session] = []
|
||||
activities: List[ba.Activity] = []
|
||||
actors: List[ba.Actor] = []
|
||||
|
||||
@ -4,7 +4,8 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, TypeVar, Generic
|
||||
|
||||
import ba
|
||||
|
||||
@ -12,6 +13,70 @@ if TYPE_CHECKING:
|
||||
from typing import Any, Callable, Dict, Tuple, List, Sequence, Optional
|
||||
|
||||
|
||||
@dataclass
|
||||
class Tab:
|
||||
"""Info for an individual tab in a TabRow"""
|
||||
button: ba.Widget
|
||||
position: Tuple[float, float]
|
||||
size: Tuple[float, float]
|
||||
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
class TabRow(Generic[T]):
|
||||
"""Encapsulates a row of tab-styled buttons.
|
||||
|
||||
Tabs are indexed by id which is an arbitrary user-provided type.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
parent: ba.Widget,
|
||||
tabdefs: List[Tuple[T, ba.Lstr]],
|
||||
pos: Tuple[float, float],
|
||||
size: Tuple[float, float],
|
||||
on_select_call: Callable[[T], None] = None) -> None:
|
||||
if not tabdefs:
|
||||
raise ValueError('At least one tab def is required')
|
||||
self.tabs: Dict[T, Tab] = {}
|
||||
tab_pos_v = pos[1]
|
||||
tab_button_width = float(size[0]) / len(tabdefs)
|
||||
tab_spacing = (250.0 - tab_button_width) * 0.06
|
||||
h = pos[0]
|
||||
for tab_id, tab_label in tabdefs:
|
||||
pos = (h + tab_spacing * 0.5, tab_pos_v)
|
||||
size = (tab_button_width - tab_spacing, 50.0)
|
||||
btn = ba.buttonwidget(parent=parent,
|
||||
position=pos,
|
||||
autoselect=True,
|
||||
button_type='tab',
|
||||
size=size,
|
||||
label=tab_label,
|
||||
enable_sound=False,
|
||||
on_activate_call=ba.Call(
|
||||
self._tick_and_call, on_select_call,
|
||||
tab_id))
|
||||
h += tab_button_width
|
||||
self.tabs[tab_id] = Tab(button=btn, position=pos, size=size)
|
||||
|
||||
def update_appearance(self, selected_tab_id: T) -> None:
|
||||
"""Update appearances to make the provided tab appear selected."""
|
||||
for tab_id, tab in self.tabs.items():
|
||||
if tab_id == selected_tab_id:
|
||||
ba.buttonwidget(edit=tab.button,
|
||||
color=(0.5, 0.4, 0.93),
|
||||
textcolor=(0.85, 0.75, 0.95)) # lit
|
||||
else:
|
||||
ba.buttonwidget(edit=tab.button,
|
||||
color=(0.52, 0.48, 0.63),
|
||||
textcolor=(0.65, 0.6, 0.7)) # unlit
|
||||
|
||||
def _tick_and_call(self, call: Optional[Callable], arg: Any) -> None:
|
||||
ba.playsound(ba.getsound('click01'))
|
||||
if call is not None:
|
||||
call(arg)
|
||||
|
||||
|
||||
def create_tab_buttons(parent_widget: ba.Widget,
|
||||
tabs: List[Tuple[str, ba.Lstr]],
|
||||
pos: Sequence[float],
|
||||
@ -25,7 +90,7 @@ def create_tab_buttons(parent_widget: ba.Widget,
|
||||
tab_buttons_indexed = []
|
||||
tab_button_width = float(size[0]) / len(tabs)
|
||||
|
||||
# add a bit more visual spacing as our buttons get narrower
|
||||
# Add a bit more visual spacing as our buttons get narrower.
|
||||
tab_spacing = (250.0 - tab_button_width) * 0.06
|
||||
positions = []
|
||||
sizes = []
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from enum import Enum
|
||||
from typing import TYPE_CHECKING, cast
|
||||
|
||||
import _ba
|
||||
@ -14,6 +15,12 @@ if TYPE_CHECKING:
|
||||
from typing import Any, Optional, Tuple, Dict
|
||||
|
||||
|
||||
class TabID(Enum):
|
||||
"""Our available tab types."""
|
||||
MY_REPLAYS = 'my_replays'
|
||||
TEST_TAB = 'test_tab'
|
||||
|
||||
|
||||
class WatchWindow(ba.Window):
|
||||
"""Window for watching replays."""
|
||||
|
||||
@ -22,7 +29,7 @@ class WatchWindow(ba.Window):
|
||||
origin_widget: ba.Widget = None):
|
||||
# pylint: disable=too-many-locals
|
||||
# pylint: disable=too-many-statements
|
||||
from bastd.ui import tabs
|
||||
from bastd.ui.tabs import TabRow
|
||||
ba.set_analytics_screen('Watch Window')
|
||||
scale_origin: Optional[Tuple[float, float]]
|
||||
if origin_widget is not None:
|
||||
@ -47,7 +54,7 @@ class WatchWindow(ba.Window):
|
||||
x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
|
||||
self._height = (578 if uiscale is ba.UIScale.SMALL else
|
||||
670 if uiscale is ba.UIScale.MEDIUM else 800)
|
||||
self._current_tab: Optional[str] = None
|
||||
self._current_tab: Optional[TabID] = None
|
||||
extra_top = 20 if uiscale is ba.UIScale.SMALL else 0
|
||||
|
||||
super().__init__(root_widget=ba.containerwidget(
|
||||
@ -90,32 +97,35 @@ class WatchWindow(ba.Window):
|
||||
text=ba.Lstr(resource=self._r + '.titleText'),
|
||||
maxwidth=400)
|
||||
|
||||
tabs_def = [('my_replays',
|
||||
ba.Lstr(resource=self._r + '.myReplaysText'))]
|
||||
tabdefs = [
|
||||
(TabID.MY_REPLAYS, ba.Lstr(resource=self._r + '.myReplaysText')),
|
||||
# (TabID.TEST_TAB, ba.Lstr(value='Testing')),
|
||||
]
|
||||
|
||||
scroll_buffer_h = 130 + 2 * x_inset
|
||||
tab_buffer_h = 750 + 2 * x_inset
|
||||
|
||||
self._tab_buttons = tabs.create_tab_buttons(
|
||||
self._root_widget,
|
||||
tabs_def,
|
||||
pos=(tab_buffer_h * 0.5, self._height - 130),
|
||||
size=(self._width - tab_buffer_h, 50),
|
||||
on_select_call=self._set_tab)
|
||||
self._tab_row = TabRow(self._root_widget,
|
||||
tabdefs,
|
||||
pos=(tab_buffer_h * 0.5, self._height - 130),
|
||||
size=(self._width - tab_buffer_h, 50),
|
||||
on_select_call=self._set_tab)
|
||||
|
||||
if ba.app.ui.use_toolbars:
|
||||
ba.widget(edit=self._tab_buttons[tabs_def[-1][0]],
|
||||
first_tab = self._tab_row.tabs[tabdefs[0][0]]
|
||||
last_tab = self._tab_row.tabs[tabdefs[-1][0]]
|
||||
ba.widget(edit=last_tab.button,
|
||||
right_widget=_ba.get_special_widget('party_button'))
|
||||
if uiscale is ba.UIScale.SMALL:
|
||||
bbtn = _ba.get_special_widget('back_button')
|
||||
ba.widget(edit=self._tab_buttons[tabs_def[0][0]],
|
||||
ba.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
|
||||
@ -131,21 +141,21 @@ class WatchWindow(ba.Window):
|
||||
|
||||
self._restore_state()
|
||||
|
||||
def _set_tab(self, tab: str) -> None:
|
||||
def _set_tab(self, tab_id: TabID) -> None:
|
||||
# pylint: disable=too-many-locals
|
||||
from bastd.ui import tabs
|
||||
|
||||
if self._current_tab == tab:
|
||||
if self._current_tab == tab_id:
|
||||
return
|
||||
self._current_tab = tab
|
||||
self._current_tab = tab_id
|
||||
|
||||
# We wanna preserve our current tab between runs.
|
||||
# Preserve our current tab between runs.
|
||||
cfg = ba.app.config
|
||||
cfg['Watch Tab'] = tab
|
||||
cfg['Watch Tab'] = tab_id.value
|
||||
cfg.commit()
|
||||
|
||||
# Update tab colors based on which is selected.
|
||||
tabs.update_tab_button_colors(self._tab_buttons, tab)
|
||||
# tabs.update_tab_button_colors(self._tab_buttons, tab)
|
||||
self._tab_row.update_appearance(tab_id)
|
||||
|
||||
if self._tab_container:
|
||||
self._tab_container.delete()
|
||||
@ -157,7 +167,7 @@ class WatchWindow(ba.Window):
|
||||
self._tab_data = {}
|
||||
|
||||
uiscale = ba.app.ui.uiscale
|
||||
if tab == 'my_replays':
|
||||
if tab_id is TabID.MY_REPLAYS:
|
||||
c_width = self._scroll_width
|
||||
c_height = self._scroll_height - 20
|
||||
sub_scroll_height = c_height - 63
|
||||
@ -212,7 +222,7 @@ class WatchWindow(ba.Window):
|
||||
text_scale=tscl,
|
||||
label=ba.Lstr(resource=self._r + '.watchReplayButtonText'),
|
||||
autoselect=True)
|
||||
ba.widget(edit=btn1, up_widget=self._tab_buttons[tab])
|
||||
ba.widget(edit=btn1, up_widget=self._tab_row.tabs[tab_id].button)
|
||||
if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
|
||||
ba.widget(edit=btn1,
|
||||
left_widget=_ba.get_special_widget('back_button'))
|
||||
@ -255,8 +265,9 @@ class WatchWindow(ba.Window):
|
||||
ba.widget(edit=scrlw,
|
||||
autoselect=True,
|
||||
left_widget=btn1,
|
||||
up_widget=self._tab_buttons[tab])
|
||||
ba.widget(edit=self._tab_buttons[tab], down_widget=scrlw)
|
||||
up_widget=self._tab_row.tabs[tab_id].button)
|
||||
ba.widget(edit=self._tab_row.tabs[tab_id].button,
|
||||
down_widget=scrlw)
|
||||
|
||||
self._my_replay_selected = None
|
||||
self._refresh_my_replays()
|
||||
@ -463,23 +474,28 @@ class WatchWindow(ba.Window):
|
||||
corner_scale=t_scale,
|
||||
maxwidth=(self._my_replays_scroll_width / t_scale) * 0.93)
|
||||
if i == 0:
|
||||
ba.widget(edit=txt, up_widget=self._tab_buttons['my_replays'])
|
||||
ba.widget(
|
||||
edit=txt,
|
||||
up_widget=self._tab_row.tabs[TabID.MY_REPLAYS].button)
|
||||
|
||||
def _save_state(self) -> None:
|
||||
try:
|
||||
sel = self._root_widget.get_selected_child()
|
||||
selected_tab_ids = [
|
||||
tab_id for tab_id, tab in self._tab_row.tabs.items()
|
||||
if sel == tab.button
|
||||
]
|
||||
if sel == self._back_button:
|
||||
sel_name = 'Back'
|
||||
elif sel in list(self._tab_buttons.values()):
|
||||
sel_name = 'Tab:' + list(self._tab_buttons.keys())[list(
|
||||
self._tab_buttons.values()).index(sel)]
|
||||
elif selected_tab_ids:
|
||||
assert len(selected_tab_ids) == 1
|
||||
sel_name = f'Tab:{selected_tab_ids[0].value}'
|
||||
elif sel == self._tab_container:
|
||||
sel_name = 'TabContainer'
|
||||
else:
|
||||
raise ValueError(f'unrecognized selection {sel}')
|
||||
ba.app.ui.window_states[self.__class__.__name__] = {
|
||||
'sel_name': sel_name,
|
||||
'tab': self._current_tab
|
||||
'sel_name': sel_name
|
||||
}
|
||||
except Exception:
|
||||
ba.print_exception(f'Error saving state for {self}.')
|
||||
@ -488,21 +504,28 @@ class WatchWindow(ba.Window):
|
||||
try:
|
||||
sel_name = ba.app.ui.window_states.get(self.__class__.__name__,
|
||||
{}).get('sel_name')
|
||||
current_tab = ba.app.config.get('Watch Tab')
|
||||
if current_tab is None or current_tab not in self._tab_buttons:
|
||||
current_tab = 'my_replays'
|
||||
assert isinstance(sel_name, (str, type(None)))
|
||||
try:
|
||||
current_tab = TabID(ba.app.config.get('Watch Tab'))
|
||||
except ValueError:
|
||||
current_tab = TabID.MY_REPLAYS
|
||||
self._set_tab(current_tab)
|
||||
|
||||
if sel_name == 'Back':
|
||||
sel = self._back_button
|
||||
elif sel_name == 'TabContainer':
|
||||
sel = self._tab_container
|
||||
elif isinstance(sel_name, str) and sel_name.startswith('Tab:'):
|
||||
sel = self._tab_buttons[sel_name.split(':')[-1]]
|
||||
try:
|
||||
sel_tab_id = TabID(sel_name.split(':')[-1])
|
||||
except ValueError:
|
||||
sel_tab_id = TabID.MY_REPLAYS
|
||||
sel = self._tab_row.tabs[sel_tab_id].button
|
||||
else:
|
||||
if self._tab_container is not None:
|
||||
sel = self._tab_container
|
||||
else:
|
||||
sel = self._tab_buttons[current_tab]
|
||||
sel = self._tab_row.tabs[current_tab].button
|
||||
ba.containerwidget(edit=self._root_widget, selected_child=sel)
|
||||
except Exception:
|
||||
ba.print_exception(f'Error restoring state for {self}.')
|
||||
|
||||
@ -814,6 +814,7 @@
|
||||
<w>sval</w>
|
||||
<w>symbolification</w>
|
||||
<w>syscalls</w>
|
||||
<w>tabdefs</w>
|
||||
<w>talloc</w>
|
||||
<w>tegra</w>
|
||||
<w>telefonaktiebolaget</w>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
|
||||
<h4><em>last updated on 2020-10-17 for Ballistica version 1.5.27 build 20223</em></h4>
|
||||
<h4><em>last updated on 2020-10-19 for Ballistica version 1.5.27 build 20224</em></h4>
|
||||
<p>This page documents the Python classes and functions in the 'ba' module,
|
||||
which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p>
|
||||
<hr>
|
||||
|
||||
@ -5,23 +5,15 @@
|
||||
#include <map>
|
||||
|
||||
#include "ballistica/app/app.h"
|
||||
#include "ballistica/app/app_config.h"
|
||||
#include "ballistica/app/app_globals.h"
|
||||
#include "ballistica/audio/audio.h"
|
||||
#include "ballistica/audio/audio_server.h"
|
||||
#include "ballistica/core/fatal_error.h"
|
||||
#include "ballistica/core/logging.h"
|
||||
#include "ballistica/core/thread.h"
|
||||
#include "ballistica/dynamics/bg/bg_dynamics.h"
|
||||
#include "ballistica/dynamics/bg/bg_dynamics_server.h"
|
||||
#include "ballistica/game/account.h"
|
||||
#include "ballistica/graphics/graphics.h"
|
||||
#include "ballistica/graphics/graphics_server.h"
|
||||
#include "ballistica/input/input.h"
|
||||
#include "ballistica/media/media.h"
|
||||
#include "ballistica/media/media_server.h"
|
||||
#include "ballistica/networking/network_write_module.h"
|
||||
#include "ballistica/networking/networking.h"
|
||||
#include "ballistica/platform/platform.h"
|
||||
#include "ballistica/python/python.h"
|
||||
#include "ballistica/scene/scene.h"
|
||||
@ -29,7 +21,7 @@
|
||||
namespace ballistica {
|
||||
|
||||
// These are set automatically via script; don't change here.
|
||||
const int kAppBuildNumber = 20223;
|
||||
const int kAppBuildNumber = 20224;
|
||||
const char* kAppVersion = "1.5.27";
|
||||
|
||||
// Our standalone globals.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user