mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Adding some additional parameters for customising tabs
This commit is contained in:
@@ -16,15 +16,23 @@ class PanelWidget(Widget):
|
||||
class BasicApp(App):
|
||||
"""Sandbox application used for testing/development by Textual developers"""
|
||||
|
||||
def on_load(self):
|
||||
"""Bind keys here."""
|
||||
self.bind("tab", "toggle_class('#sidebar', '-active')")
|
||||
self.bind("a", "toggle_class('#header', '-visible')")
|
||||
self.bind("c", "toggle_class('#content', '-content-visible')")
|
||||
self.bind("d", "toggle_class('#footer', 'dim')")
|
||||
|
||||
def on_key(self, event: events.Key) -> None:
|
||||
tab_keys = {
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.tabs = Tabs(
|
||||
[
|
||||
Tab("One", name="one"),
|
||||
Tab("Two", name="two"),
|
||||
Tab("Three", name="three"),
|
||||
Tab("Four", name="four"),
|
||||
Tab("Five", name="five"),
|
||||
Tab("Six", name="six"),
|
||||
Tab("SixHundred", name="seven"),
|
||||
Tab("Eight", name="eight"),
|
||||
],
|
||||
active_tab="three",
|
||||
tab_padding=1,
|
||||
)
|
||||
self.tab_keys = {
|
||||
"1": "one",
|
||||
"2": "two",
|
||||
"3": "three",
|
||||
@@ -34,22 +42,18 @@ class BasicApp(App):
|
||||
"7": "seven",
|
||||
"8": "eight",
|
||||
}
|
||||
self.tabs.active_tab_name = tab_keys.get(event.key, "one")
|
||||
|
||||
def on_load(self):
|
||||
"""Bind keys here."""
|
||||
self.bind("tab", "toggle_class('#sidebar', '-active')")
|
||||
self.bind("a", "toggle_class('#header', '-visible')")
|
||||
self.bind("c", "toggle_class('#content', '-content-visible')")
|
||||
self.bind("d", "toggle_class('#footer', 'dim')")
|
||||
|
||||
def on_key(self, event: events.Key) -> None:
|
||||
self.tabs.active_tab_name = self.tab_keys.get(event.key, "one")
|
||||
|
||||
def on_mount(self):
|
||||
self.tabs = Tabs(
|
||||
[
|
||||
Tab("One", name="one"),
|
||||
Tab("Two", name="two"),
|
||||
Tab("Three", name="three"),
|
||||
Tab("Four", name="four"),
|
||||
Tab("Five", name="five"),
|
||||
Tab("Six", name="six"),
|
||||
Tab("Seven", name="seven"),
|
||||
Tab("Eight", name="eight"),
|
||||
],
|
||||
active_tab="three",
|
||||
)
|
||||
"""Build layout here."""
|
||||
self.mount(
|
||||
header=self.tabs,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* CSS file for dev_sandbox.py */
|
||||
|
||||
$text: #f0f0f0;
|
||||
$primary: #021720;
|
||||
$primary: #262626;
|
||||
$secondary:#95d52a;
|
||||
$background: #262626;
|
||||
|
||||
|
||||
@@ -32,11 +32,13 @@ class TabHeadersRenderable:
|
||||
active_tab_name: str | None = None,
|
||||
width: int | None = None,
|
||||
tab_padding: int | None = None,
|
||||
inactive_tab_opacity: float = 0.5,
|
||||
):
|
||||
self.tabs = {tab.name: tab for tab in tabs}
|
||||
self.active_tab_name = active_tab_name or next(iter(self.tabs))
|
||||
self.width = width
|
||||
self.tab_padding = tab_padding
|
||||
self.inactive_tab_opacity = inactive_tab_opacity
|
||||
|
||||
self._range_cache: dict[str, tuple[int, int]] = {}
|
||||
|
||||
@@ -70,20 +72,22 @@ class TabHeadersRenderable:
|
||||
end="",
|
||||
style=Style(
|
||||
color="#f0f0f0",
|
||||
bgcolor="#021720",
|
||||
bgcolor="#262626",
|
||||
meta={"@click": f"activate_tab('{tab.name}')"},
|
||||
),
|
||||
)
|
||||
|
||||
# Cache and move to next label
|
||||
len_label = len(tab.label)
|
||||
len_label = cell_len(tab.label)
|
||||
self._range_cache[tab.name] = (char_index, char_index + len_label)
|
||||
char_index += len_label + label_pad * 2
|
||||
|
||||
if tab.name == self.active_tab_name:
|
||||
yield tab_content
|
||||
else:
|
||||
dimmed_tab_content = Opacity(tab_content, opacity=0.5)
|
||||
dimmed_tab_content = Opacity(
|
||||
tab_content, opacity=self.inactive_tab_opacity
|
||||
)
|
||||
segments = list(console.render(dimmed_tab_content))
|
||||
yield from segments
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ from __future__ import annotations
|
||||
|
||||
from rich.console import Console, ConsoleOptions, RenderableType, RenderResult
|
||||
from rich.segment import Segment
|
||||
from rich.style import StyleType
|
||||
|
||||
from textual import log
|
||||
from textual.reactive import Reactive
|
||||
from textual.renderables._tab_headers import TabHeadersRenderable, Tab
|
||||
from textual.renderables.underline_bar import UnderlineBar
|
||||
@@ -15,11 +15,17 @@ class TabsRenderable:
|
||||
self,
|
||||
tabs: list[Tab],
|
||||
active_tab_name: str,
|
||||
tab_padding: int | None = None,
|
||||
bar_offset: float = 0.0,
|
||||
active_bar_style: StyleType,
|
||||
inactive_bar_style: StyleType,
|
||||
inactive_text_opacity: float,
|
||||
tab_padding: int | None,
|
||||
bar_offset: float,
|
||||
):
|
||||
self.tabs = tabs
|
||||
self.active_tab_name = active_tab_name
|
||||
self.active_bar_style = active_bar_style
|
||||
self.inactive_bar_style = inactive_bar_style
|
||||
self.inactive_text_opacity = inactive_text_opacity
|
||||
self.tab_padding = tab_padding
|
||||
self.bar_offset = bar_offset
|
||||
|
||||
@@ -30,6 +36,7 @@ class TabsRenderable:
|
||||
self.tabs,
|
||||
active_tab_name=self.active_tab_name,
|
||||
tab_padding=self.tab_padding,
|
||||
inactive_tab_opacity=self.inactive_text_opacity,
|
||||
)
|
||||
yield from console.render(headers)
|
||||
yield Segment.line()
|
||||
@@ -50,13 +57,14 @@ class TabsRenderable:
|
||||
|
||||
underline = UnderlineBar(
|
||||
highlight_range=(bar_start, bar_end),
|
||||
highlight_style="#95d52a",
|
||||
highlight_style=self.active_bar_style,
|
||||
background_style=self.inactive_bar_style,
|
||||
)
|
||||
yield from console.render(underline)
|
||||
|
||||
|
||||
class Tabs(Widget):
|
||||
"""Widget for displaying tab headers"""
|
||||
"""Horizontal tabs"""
|
||||
|
||||
active_tab_name: Reactive[str] = Reactive("")
|
||||
bar_offset: Reactive[float] = Reactive(0.0)
|
||||
@@ -65,13 +73,20 @@ class Tabs(Widget):
|
||||
self,
|
||||
tabs: list[Tab],
|
||||
active_tab: str | None = None,
|
||||
active_bar_style: StyleType = "#1BB152",
|
||||
inactive_bar_style: StyleType = "#455058",
|
||||
tab_padding: int | None = None,
|
||||
inactive_text_opacity: float = 0.5,
|
||||
) -> None:
|
||||
super().__init__()
|
||||
self.tabs = tabs
|
||||
|
||||
self.active_tab_name = active_tab or tabs[0].name
|
||||
# TODO: Handle empty tabs
|
||||
self.active_tab_name = active_tab or tabs[0]
|
||||
self.active_bar_style = active_bar_style
|
||||
self.inactive_bar_style = inactive_bar_style
|
||||
self.bar_offset = float(self.get_tab_index(active_tab) or 0)
|
||||
self.inactive_text_opacity = inactive_text_opacity
|
||||
|
||||
self._used = False
|
||||
self.tab_padding = tab_padding
|
||||
@@ -81,7 +96,6 @@ class Tabs(Widget):
|
||||
|
||||
def watch_active_tab_name(self, tab_name: str) -> None:
|
||||
target_tab_index = self.get_tab_index(tab_name)
|
||||
log("bar_offset", self.bar_offset)
|
||||
self.animate(
|
||||
"bar_offset", float(target_tab_index), easing="out_cubic", duration=0.3
|
||||
)
|
||||
@@ -98,5 +112,8 @@ class Tabs(Widget):
|
||||
self.tabs,
|
||||
tab_padding=self.tab_padding,
|
||||
active_tab_name=self.active_tab_name,
|
||||
active_bar_style=self.active_bar_style,
|
||||
inactive_bar_style=self.inactive_bar_style,
|
||||
bar_offset=self.bar_offset,
|
||||
inactive_text_opacity=self.inactive_text_opacity,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user