Combining tab headers and underline bars, no functionality yet

This commit is contained in:
Darren Burns
2022-02-14 14:48:13 +00:00
parent 0bd324b147
commit c30d1b9795
5 changed files with 110 additions and 31 deletions

View File

@@ -2,7 +2,9 @@ from rich.console import RenderableType
from rich.panel import Panel
from textual.app import App
from textual.renderables._tab_headers import Tab
from textual.widget import Widget
from textual.widgets.tabs import Tabs
class PanelWidget(Widget):
@@ -23,7 +25,16 @@ class BasicApp(App):
def on_mount(self):
"""Build layout here."""
self.mount(
header=Widget(),
header=Tabs(
[
Tab("One", active=True),
Tab("Two"),
Tab("Three"),
Tab("Four"),
Tab("Five"),
Tab("Six"),
]
),
content=PanelWidget(),
footer=Widget(),
sidebar=Widget(),

View File

@@ -22,7 +22,7 @@ Widget:hover {
#sidebar {
text: $primary-style;
dock: side;
width: 30;
width: 24;
offset-x: -100%;
transition: $animation;
border-right: outer $secondary;
@@ -34,8 +34,7 @@ Widget:hover {
#header {
text: $text on $primary;
height: 3;
border-bottom: hkey $secondary;
height: 2;
}
#header.-visible {
@@ -44,7 +43,6 @@ Widget:hover {
#content {
text: $text on $background;
offset-y: -3;
}
#content.-content-visible {
@@ -54,7 +52,6 @@ Widget:hover {
#footer {
opacity: 1;
text: $text on $primary;
height: 3;
border-top: hkey $secondary;
}

View File

@@ -1,45 +1,87 @@
from __future__ import annotations
from dataclasses import dataclass
from rich.cells import cell_len
from rich.console import Console, ConsoleOptions, RenderResult
from rich.padding import Padding
from rich.style import Style
from rich.text import Text
from textual import log
from textual._loop import loop_first
from textual.renderables.opacity import Opacity
class TabHeader:
def __init__(self, headers: list[str], *, width: int | None = None):
self.headers = headers
@dataclass
class Tab:
title: str
active: bool = False
key: str | None = None
def __post_init__(self):
if self.key is None:
self.key = self.title
def __str__(self):
return self.title
class TabHeadersRenderable:
def __init__(
self,
tabs: list[Tab],
*,
width: int | None = None,
tab_padding: int = 1,
):
self.tabs = tabs
self.width = width
self.tab_padding = tab_padding
def action_highlight(self):
log("highlighted!")
def __rich_console__(
self, console: Console, options: ConsoleOptions
) -> RenderResult:
width = self.width or options.max_width
headers = self.headers
free_space = width - sum(cell_len(header) for header in headers)
space_per_gap = free_space // (len(headers) + 1)
tabs = self.tabs
padding_len = self.tab_padding * len(tabs)
total_len = sum(cell_len(header.title) for header in tabs) + padding_len
free_space = width - total_len
space_per_gap = free_space // (len(tabs) + 1)
gap = Text(" " * space_per_gap, end="")
pad = Text(" ", end="")
for is_first, header in loop_first(headers):
lpad = rpad = Text(" " * self.tab_padding, end="")
for is_first, tab in loop_first(tabs):
if is_first:
yield gap
yield pad
yield Text(header, end="")
yield pad
yield lpad
tab_content = Text(
tab.title, end="", style=Style(meta={"@click": "highlight"})
)
yield tab_content
# if tab.active:
# yield tab_content
# else:
# dimmed_tab_content = Opacity(tab_content, opacity=.2)
# yield from console.render(dimmed_tab_content)
yield rpad
yield gap
if __name__ == "__main__":
console = Console()
header = TabHeader(
headers=[
"One",
"Two",
"Three",
h = TabHeadersRenderable(
[
Tab("One"),
Tab("Two"),
Tab("Three"),
]
)
console.print(header)
console.print(h)

View File

@@ -3,16 +3,15 @@ from __future__ import annotations
from datetime import datetime
from logging import getLogger
from rich.console import Console, ConsoleOptions, RenderableType
from rich.console import RenderableType
from rich.panel import Panel
from rich.repr import rich_repr, Result
from rich.repr import Result
from rich.style import StyleType
from rich.table import Table
from rich.text import TextType
from .. import events
from ..widget import Widget
from ..reactive import watch, Reactive
from ..widget import Widget
log = getLogger("rich")

View File

@@ -1,5 +1,35 @@
from rich.console import Console, ConsoleOptions, RenderableType
from __future__ import annotations
from rich.console import Console, ConsoleOptions, RenderableType, RenderResult
from rich.segment import Segment
from textual import log
from textual.renderables._tab_headers import TabHeadersRenderable, Tab
from textual.renderables.underline_bar import UnderlineBar
from textual.widget import Widget
class Tabs:
pass
class TabsRenderable:
def __init__(self, headers: list[Tab]):
self.headers = headers
def __rich_console__(
self, console: Console, options: ConsoleOptions
) -> RenderResult:
headers = TabHeadersRenderable(tabs=self.headers)
underline = UnderlineBar(highlight_range=(19, 26), highlight_style="#95d52a")
yield from console.render(headers)
yield Segment.line()
yield from console.render(underline)
class Tabs(Widget):
def __init__(self, headers: list[Tab]):
self.headers = headers
super().__init__()
def action_highlight(self, header: str):
log(f"action_header_clicked {header}")
def render(self) -> RenderableType:
return TabsRenderable(self.headers)