bauiv1lib.tabs
UI functionality for creating tab style buttons.
1# Released under the MIT License. See LICENSE for details. 2# 3"""UI functionality for creating tab style buttons.""" 4 5from __future__ import annotations 6 7from dataclasses import dataclass 8from typing import TYPE_CHECKING, TypeVar, Generic 9 10import bauiv1 as bui 11 12if TYPE_CHECKING: 13 from typing import Any, Callable 14 15 16@dataclass 17class Tab: 18 """Info for an individual tab in a TabRow""" 19 20 button: bui.Widget 21 position: tuple[float, float] 22 size: tuple[float, float] 23 24 25T = TypeVar('T') 26 27 28class TabRow(Generic[T]): 29 """Encapsulates a row of tab-styled buttons. 30 31 Tabs are indexed by id which is an arbitrary user-provided type. 32 """ 33 34 def __init__( 35 self, 36 parent: bui.Widget, 37 tabdefs: list[tuple[T, bui.Lstr]], 38 pos: tuple[float, float], 39 size: tuple[float, float], 40 on_select_call: Callable[[T], None] | None = None, 41 ) -> None: 42 if not tabdefs: 43 raise ValueError('At least one tab def is required') 44 self.tabs: dict[T, Tab] = {} 45 tab_pos_v = pos[1] 46 tab_button_width = float(size[0]) / len(tabdefs) 47 tab_spacing = (250.0 - tab_button_width) * 0.06 48 h = pos[0] 49 for tab_id, tab_label in tabdefs: 50 pos = (h + tab_spacing * 0.5, tab_pos_v) 51 size = (tab_button_width - tab_spacing, 50.0) 52 btn = bui.buttonwidget( 53 parent=parent, 54 position=pos, 55 autoselect=True, 56 button_type='tab', 57 size=size, 58 label=tab_label, 59 enable_sound=False, 60 on_activate_call=bui.Call( 61 self._tick_and_call, on_select_call, tab_id 62 ), 63 ) 64 h += tab_button_width 65 self.tabs[tab_id] = Tab(button=btn, position=pos, size=size) 66 67 def update_appearance(self, selected_tab_id: T) -> None: 68 """Update appearances to make the provided tab appear selected.""" 69 for tab_id, tab in self.tabs.items(): 70 if tab_id == selected_tab_id: 71 bui.buttonwidget( 72 edit=tab.button, 73 color=(0.5, 0.4, 0.93), 74 textcolor=(0.85, 0.75, 0.95), 75 ) # lit 76 else: 77 bui.buttonwidget( 78 edit=tab.button, 79 color=(0.52, 0.48, 0.63), 80 textcolor=(0.65, 0.6, 0.7), 81 ) # unlit 82 83 def _tick_and_call( 84 self, call: Callable[[Any], None] | None, arg: Any 85 ) -> None: 86 bui.getsound('click01').play() 87 if call is not None: 88 call(arg)
@dataclass
class
Tab:
17@dataclass 18class Tab: 19 """Info for an individual tab in a TabRow""" 20 21 button: bui.Widget 22 position: tuple[float, float] 23 size: tuple[float, float]
Info for an individual tab in a TabRow
class
TabRow(typing.Generic[~T]):
29class TabRow(Generic[T]): 30 """Encapsulates a row of tab-styled buttons. 31 32 Tabs are indexed by id which is an arbitrary user-provided type. 33 """ 34 35 def __init__( 36 self, 37 parent: bui.Widget, 38 tabdefs: list[tuple[T, bui.Lstr]], 39 pos: tuple[float, float], 40 size: tuple[float, float], 41 on_select_call: Callable[[T], None] | None = None, 42 ) -> None: 43 if not tabdefs: 44 raise ValueError('At least one tab def is required') 45 self.tabs: dict[T, Tab] = {} 46 tab_pos_v = pos[1] 47 tab_button_width = float(size[0]) / len(tabdefs) 48 tab_spacing = (250.0 - tab_button_width) * 0.06 49 h = pos[0] 50 for tab_id, tab_label in tabdefs: 51 pos = (h + tab_spacing * 0.5, tab_pos_v) 52 size = (tab_button_width - tab_spacing, 50.0) 53 btn = bui.buttonwidget( 54 parent=parent, 55 position=pos, 56 autoselect=True, 57 button_type='tab', 58 size=size, 59 label=tab_label, 60 enable_sound=False, 61 on_activate_call=bui.Call( 62 self._tick_and_call, on_select_call, tab_id 63 ), 64 ) 65 h += tab_button_width 66 self.tabs[tab_id] = Tab(button=btn, position=pos, size=size) 67 68 def update_appearance(self, selected_tab_id: T) -> None: 69 """Update appearances to make the provided tab appear selected.""" 70 for tab_id, tab in self.tabs.items(): 71 if tab_id == selected_tab_id: 72 bui.buttonwidget( 73 edit=tab.button, 74 color=(0.5, 0.4, 0.93), 75 textcolor=(0.85, 0.75, 0.95), 76 ) # lit 77 else: 78 bui.buttonwidget( 79 edit=tab.button, 80 color=(0.52, 0.48, 0.63), 81 textcolor=(0.65, 0.6, 0.7), 82 ) # unlit 83 84 def _tick_and_call( 85 self, call: Callable[[Any], None] | None, arg: Any 86 ) -> None: 87 bui.getsound('click01').play() 88 if call is not None: 89 call(arg)
Encapsulates a row of tab-styled buttons.
Tabs are indexed by id which is an arbitrary user-provided type.
TabRow( parent: _bauiv1.Widget, tabdefs: list[tuple[~T, babase.Lstr]], pos: tuple[float, float], size: tuple[float, float], on_select_call: Optional[Callable[[~T], NoneType]] = None)
35 def __init__( 36 self, 37 parent: bui.Widget, 38 tabdefs: list[tuple[T, bui.Lstr]], 39 pos: tuple[float, float], 40 size: tuple[float, float], 41 on_select_call: Callable[[T], None] | None = None, 42 ) -> None: 43 if not tabdefs: 44 raise ValueError('At least one tab def is required') 45 self.tabs: dict[T, Tab] = {} 46 tab_pos_v = pos[1] 47 tab_button_width = float(size[0]) / len(tabdefs) 48 tab_spacing = (250.0 - tab_button_width) * 0.06 49 h = pos[0] 50 for tab_id, tab_label in tabdefs: 51 pos = (h + tab_spacing * 0.5, tab_pos_v) 52 size = (tab_button_width - tab_spacing, 50.0) 53 btn = bui.buttonwidget( 54 parent=parent, 55 position=pos, 56 autoselect=True, 57 button_type='tab', 58 size=size, 59 label=tab_label, 60 enable_sound=False, 61 on_activate_call=bui.Call( 62 self._tick_and_call, on_select_call, tab_id 63 ), 64 ) 65 h += tab_button_width 66 self.tabs[tab_id] = Tab(button=btn, position=pos, size=size)
tabs: dict[~T, Tab]
def
update_appearance(self, selected_tab_id: ~T) -> None:
68 def update_appearance(self, selected_tab_id: T) -> None: 69 """Update appearances to make the provided tab appear selected.""" 70 for tab_id, tab in self.tabs.items(): 71 if tab_id == selected_tab_id: 72 bui.buttonwidget( 73 edit=tab.button, 74 color=(0.5, 0.4, 0.93), 75 textcolor=(0.85, 0.75, 0.95), 76 ) # lit 77 else: 78 bui.buttonwidget( 79 edit=tab.button, 80 color=(0.52, 0.48, 0.63), 81 textcolor=(0.65, 0.6, 0.7), 82 ) # unlit
Update appearances to make the provided tab appear selected.