optimized line rendering and updated render_lines API

This commit is contained in:
Will McGugan
2022-06-15 17:13:56 +01:00
parent 5edefcf29f
commit b0079fce56
9 changed files with 116 additions and 89 deletions

84
poetry.lock generated
View File

@@ -345,7 +345,7 @@ mkdocs = ">=1.1"
[[package]]
name = "mkdocs-material"
version = "8.3.3"
version = "8.3.5"
description = "Documentation that simply works"
category = "dev"
optional = false
@@ -391,7 +391,7 @@ python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"]
[[package]]
name = "mkdocstrings-python"
version = "0.7.0"
version = "0.7.1"
description = "A Python handler for mkdocstrings."
category = "dev"
optional = false
@@ -658,16 +658,21 @@ version = "12.4.4"
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
category = "main"
optional = false
python-versions = ">=3.6.3,<4.0.0"
python-versions = "^3.6.3"
develop = true
[package.dependencies]
commonmark = ">=0.9.0,<0.10.0"
pygments = ">=2.6.0,<3.0.0"
typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""}
commonmark = "^0.9.0"
pygments = "^2.6.0"
typing-extensions = {version = ">=4.0.0, <5.0", markers = "python_version < \"3.9\""}
[package.extras]
jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"]
[package.source]
type = "directory"
url = "../rich"
[[package]]
name = "six"
version = "1.16.0"
@@ -740,7 +745,7 @@ testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)",
[[package]]
name = "watchdog"
version = "2.1.8"
version = "2.1.9"
description = "Filesystem events monitoring"
category = "dev"
optional = false
@@ -777,7 +782,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
[metadata]
lock-version = "1.1"
python-versions = "^3.7"
content-hash = "378a60041202d505cba26ea7084886fe1b01090a0035253b100593b559aed090"
content-hash = "4aeef009c7c1f6a34d0dd1c3c16647b53a339f5963dcbe31eef43bb9dac270ab"
[metadata.files]
aiohttp = [
@@ -1122,8 +1127,8 @@ mkdocs-autorefs = [
{file = "mkdocs_autorefs-0.4.1-py3-none-any.whl", hash = "sha256:a2248a9501b29dc0cc8ba4c09f4f47ff121945f6ce33d760f145d6f89d313f5b"},
]
mkdocs-material = [
{file = "mkdocs-material-8.3.3.tar.gz", hash = "sha256:3dd30af894f6d5da3d8a2f8ffc04c90c4d0f1be013e654ec45f608373c131542"},
{file = "mkdocs_material-8.3.3-py2.py3-none-any.whl", hash = "sha256:4f9564af58f9c96f25c263cb705a40a82c833cb10c2626d6db6ddadedaa5b6c3"},
{file = "mkdocs-material-8.3.5.tar.gz", hash = "sha256:0d7ae82b28fa57a2ad9a4eeb5fd01704cb8fe963eb20c56a68afdd735e52b432"},
{file = "mkdocs_material-8.3.5-py2.py3-none-any.whl", hash = "sha256:9190aef365bd6ed43b27f47d1de956d9e67b61f4b9edb444563337ef717cacd3"},
]
mkdocs-material-extensions = [
{file = "mkdocs-material-extensions-1.0.3.tar.gz", hash = "sha256:bfd24dfdef7b41c312ede42648f9eb83476ea168ec163b613f9abd12bbfddba2"},
@@ -1134,8 +1139,8 @@ mkdocstrings = [
{file = "mkdocstrings-0.19.0.tar.gz", hash = "sha256:efa34a67bad11229d532d89f6836a8a215937548623b64f3698a1df62e01cc3e"},
]
mkdocstrings-python = [
{file = "mkdocstrings-python-0.7.0.tar.gz", hash = "sha256:e54c67890e8bb7dc4604360c8ef5dd214b23b6924de7706f461e3c998d4ea061"},
{file = "mkdocstrings_python-0.7.0-py3-none-any.whl", hash = "sha256:6964bd92f106766e771ac6cd5bc02643a960602b4d921b95362e31d491e9a6db"},
{file = "mkdocstrings-python-0.7.1.tar.gz", hash = "sha256:c334b382dca202dfa37071c182418a6df5818356a95d54362a2b24822ca3af71"},
{file = "mkdocstrings_python-0.7.1-py3-none-any.whl", hash = "sha256:a22060bfa374697678e9af4e62b020d990dad2711c98f7a9fac5c0345bef93c7"},
]
msgpack = [
{file = "msgpack-1.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4ab251d229d10498e9a2f3b1e68ef64cb393394ec477e3370c457f9430ce9250"},
@@ -1381,10 +1386,7 @@ pyyaml-env-tag = [
{file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"},
{file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"},
]
rich = [
{file = "rich-12.4.4-py3-none-any.whl", hash = "sha256:d2bbd99c320a2532ac71ff6a3164867884357da3e3301f0240090c5d2fdac7ec"},
{file = "rich-12.4.4.tar.gz", hash = "sha256:4c586de507202505346f3e32d1363eb9ed6932f0c2f63184dea88983ff4971e2"},
]
rich = []
six = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
@@ -1474,31 +1476,31 @@ virtualenv = [
{file = "virtualenv-20.14.1.tar.gz", hash = "sha256:ef589a79795589aada0c1c5b319486797c03b67ac3984c48c669c0e4f50df3a5"},
]
watchdog = [
{file = "watchdog-2.1.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:676263bee67b165f16b05abc52acc7a94feac5b5ab2449b491f1a97638a79277"},
{file = "watchdog-2.1.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:aa68d2d9a89d686fae99d28a6edf3b18595e78f5adf4f5c18fbfda549ac0f20c"},
{file = "watchdog-2.1.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5e2e51c53666850c3ecffe9d265fc5d7351db644de17b15e9c685dd3cdcd6f97"},
{file = "watchdog-2.1.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7721ac736170b191c50806f43357407138c6748e4eb3e69b071397f7f7aaeedd"},
{file = "watchdog-2.1.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ce7376aed3da5fd777483fe5ebc8475a440c6d18f23998024f832134b2938e7b"},
{file = "watchdog-2.1.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f9ee4c6bf3a1b2ed6be90a2d78f3f4bbd8105b6390c04a86eb48ed67bbfa0b0b"},
{file = "watchdog-2.1.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:68dbe75e0fa1ba4d73ab3f8e67b21770fbed0651d32ce515cd38919a26873266"},
{file = "watchdog-2.1.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0c520009b8cce79099237d810aaa19bc920941c268578436b62013b2f0102320"},
{file = "watchdog-2.1.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:efcc8cbc1b43902571b3dce7ef53003f5b97fe4f275fe0489565fc6e2ebe3314"},
{file = "watchdog-2.1.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:746e4c197ec1083581bb1f64d07d1136accf03437badb5ff8fcb862565c193b2"},
{file = "watchdog-2.1.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ae17b6be788fb8e4d8753d8d599de948f0275a232416e16436363c682c6f850"},
{file = "watchdog-2.1.8-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ddde157dc1447d8130cb5b8df102fad845916fe4335e3d3c3f44c16565becbb7"},
{file = "watchdog-2.1.8-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4978db33fc0934c92013ee163a9db158ec216099b69fce5aec790aba704da412"},
{file = "watchdog-2.1.8-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b962de4d7d92ff78fb2dbc6a0cb292a679dea879a0eb5568911484d56545b153"},
{file = "watchdog-2.1.8-py3-none-manylinux2014_aarch64.whl", hash = "sha256:1e5d0fdfaa265c29dc12621913a76ae99656cf7587d03950dfeb3595e5a26102"},
{file = "watchdog-2.1.8-py3-none-manylinux2014_armv7l.whl", hash = "sha256:036ed15f7cd656351bf4e17244447be0a09a61aaa92014332d50719fc5973bc0"},
{file = "watchdog-2.1.8-py3-none-manylinux2014_i686.whl", hash = "sha256:2962628a8777650703e8f6f2593065884c602df7bae95759b2df267bd89b2ef5"},
{file = "watchdog-2.1.8-py3-none-manylinux2014_ppc64.whl", hash = "sha256:156ec3a94695ea68cfb83454b98754af6e276031ba1ae7ae724dc6bf8973b92a"},
{file = "watchdog-2.1.8-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:47598fe6713fc1fee86b1ca85c9cbe77e9b72d002d6adeab9c3b608f8a5ead10"},
{file = "watchdog-2.1.8-py3-none-manylinux2014_s390x.whl", hash = "sha256:fed4de6e45a4f16e4046ea00917b4fe1700b97244e5d114f594b4a1b9de6bed8"},
{file = "watchdog-2.1.8-py3-none-manylinux2014_x86_64.whl", hash = "sha256:24dedcc3ce75e150f2a1d704661f6879764461a481ba15a57dc80543de46021c"},
{file = "watchdog-2.1.8-py3-none-win32.whl", hash = "sha256:6ddf67bc9f413791072e3afb466e46cc72c6799ba73dea18439b412e8f2e3257"},
{file = "watchdog-2.1.8-py3-none-win_amd64.whl", hash = "sha256:88ef3e8640ef0a64b7ad7394b0f23384f58ac19dd759da7eaa9bc04b2898943f"},
{file = "watchdog-2.1.8-py3-none-win_ia64.whl", hash = "sha256:0fb60c7d31474b21acba54079ce9ff0136411183e9a591369417cddb1d7d00d7"},
{file = "watchdog-2.1.8.tar.gz", hash = "sha256:6d03149126864abd32715d4e9267d2754cede25a69052901399356ad3bc5ecff"},
{file = "watchdog-2.1.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a735a990a1095f75ca4f36ea2ef2752c99e6ee997c46b0de507ba40a09bf7330"},
{file = "watchdog-2.1.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b17d302850c8d412784d9246cfe8d7e3af6bcd45f958abb2d08a6f8bedf695d"},
{file = "watchdog-2.1.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee3e38a6cc050a8830089f79cbec8a3878ec2fe5160cdb2dc8ccb6def8552658"},
{file = "watchdog-2.1.9-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64a27aed691408a6abd83394b38503e8176f69031ca25d64131d8d640a307591"},
{file = "watchdog-2.1.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:195fc70c6e41237362ba720e9aaf394f8178bfc7fa68207f112d108edef1af33"},
{file = "watchdog-2.1.9-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bfc4d351e6348d6ec51df007432e6fe80adb53fd41183716017026af03427846"},
{file = "watchdog-2.1.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8250546a98388cbc00c3ee3cc5cf96799b5a595270dfcfa855491a64b86ef8c3"},
{file = "watchdog-2.1.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:117ffc6ec261639a0209a3252546b12800670d4bf5f84fbd355957a0595fe654"},
{file = "watchdog-2.1.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:97f9752208f5154e9e7b76acc8c4f5a58801b338de2af14e7e181ee3b28a5d39"},
{file = "watchdog-2.1.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:247dcf1df956daa24828bfea5a138d0e7a7c98b1a47cf1fa5b0c3c16241fcbb7"},
{file = "watchdog-2.1.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:226b3c6c468ce72051a4c15a4cc2ef317c32590d82ba0b330403cafd98a62cfd"},
{file = "watchdog-2.1.9-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d9820fe47c20c13e3c9dd544d3706a2a26c02b2b43c993b62fcd8011bcc0adb3"},
{file = "watchdog-2.1.9-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:70af927aa1613ded6a68089a9262a009fbdf819f46d09c1a908d4b36e1ba2b2d"},
{file = "watchdog-2.1.9-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ed80a1628cee19f5cfc6bb74e173f1b4189eb532e705e2a13e3250312a62e0c9"},
{file = "watchdog-2.1.9-py3-none-manylinux2014_aarch64.whl", hash = "sha256:9f05a5f7c12452f6a27203f76779ae3f46fa30f1dd833037ea8cbc2887c60213"},
{file = "watchdog-2.1.9-py3-none-manylinux2014_armv7l.whl", hash = "sha256:255bb5758f7e89b1a13c05a5bceccec2219f8995a3a4c4d6968fe1de6a3b2892"},
{file = "watchdog-2.1.9-py3-none-manylinux2014_i686.whl", hash = "sha256:d3dda00aca282b26194bdd0adec21e4c21e916956d972369359ba63ade616153"},
{file = "watchdog-2.1.9-py3-none-manylinux2014_ppc64.whl", hash = "sha256:186f6c55abc5e03872ae14c2f294a153ec7292f807af99f57611acc8caa75306"},
{file = "watchdog-2.1.9-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:083171652584e1b8829581f965b9b7723ca5f9a2cd7e20271edf264cfd7c1412"},
{file = "watchdog-2.1.9-py3-none-manylinux2014_s390x.whl", hash = "sha256:b530ae007a5f5d50b7fbba96634c7ee21abec70dc3e7f0233339c81943848dc1"},
{file = "watchdog-2.1.9-py3-none-manylinux2014_x86_64.whl", hash = "sha256:4f4e1c4aa54fb86316a62a87b3378c025e228178d55481d30d857c6c438897d6"},
{file = "watchdog-2.1.9-py3-none-win32.whl", hash = "sha256:5952135968519e2447a01875a6f5fc8c03190b24d14ee52b0f4b1682259520b1"},
{file = "watchdog-2.1.9-py3-none-win_amd64.whl", hash = "sha256:7a833211f49143c3d336729b0020ffd1274078e94b0ae42e22f596999f50279c"},
{file = "watchdog-2.1.9-py3-none-win_ia64.whl", hash = "sha256:ad576a565260d8f99d97f2e64b0f97a48228317095908568a9d5c786c829d428"},
{file = "watchdog-2.1.9.tar.gz", hash = "sha256:43ce20ebb36a51f21fa376f76d1d4692452b2527ccd601950d69ed36b9e21609"},
]
yarl = [
{file = "yarl-1.7.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95"},

View File

@@ -22,8 +22,8 @@ textual = "textual.cli.cli:run"
[tool.poetry.dependencies]
python = "^3.7"
rich = "^12.4.3"
#rich = {path="../rich", develop=true}
#rich = "^12.4.3"
rich = {path="../rich", develop=true}
click = "8.1.2"
importlib-metadata = "^4.11.3"
typing-extensions = { version = "^4.0.0", python = "<3.8" }

View File

@@ -174,3 +174,6 @@ if __name__ == "__main__":
from textual.css.scalar import Scalar
print(Scalar.resolve_dimension.cache_info())
from rich.style import Style
print(Style.__add__.cache_info())

View File

@@ -21,10 +21,14 @@ class TableApp(App):
def on_mount(self):
self.bind("d", "toggle_dark")
self.bind("z", "toggle_zebra")
def action_toggle_dark(self) -> None:
self.app.dark = not self.app.dark
def action_toggle_zebra(self) -> None:
self.table.zebra_stripes = not self.table.zebra_stripes
app = TableApp()
if __name__ == "__main__":

View File

@@ -445,7 +445,8 @@ class Compositor:
x -= region.x
y -= region.y
lines = widget.render_lines((y, y + 1), (0, region.width))
# lines = widget.render_lines((y, y + 1), (0, region.width))
lines = widget.render_lines(Region(0, y, region.width, 1))
if not lines:
return Style.null()
@@ -546,8 +547,7 @@ class Compositor:
continue
if region in clip:
yield region, clip, widget.render_lines(
(0, region.height),
(0, region.width),
Region(0, 0, region.width, region.height)
)
elif overlaps(clip, region):
clipped_region = intersection(region, clip)
@@ -556,10 +556,8 @@ class Compositor:
new_x, new_y, new_width, new_height = clipped_region
delta_x = new_x - region.x
delta_y = new_y - region.y
crop_x = delta_x + new_width
lines = widget.render_lines(
(delta_y, delta_y + new_height),
(delta_x, crop_x),
Region(delta_x, delta_y, new_width, new_height)
)
yield region, clip, lines

View File

@@ -151,7 +151,7 @@ class App(Generic[ReturnType], DOMNode):
self.console = Console(
file=(open(os.devnull, "wt") if self.is_headless else sys.__stdout__),
markup=True,
markup=False,
highlight=False,
emoji=False,
)

View File

@@ -1,11 +1,9 @@
from __future__ import annotations
from rich.console import RenderableType
from rich.segment import Segment
from rich.style import Style
from .geometry import Size
from ._types import Lines
from .widget import Widget

View File

@@ -877,21 +877,26 @@ class Widget(DOMNode):
self._dirty_regions.clear()
def _crop_lines(self, lines: Lines, x1, x2) -> Lines:
if (x1, x2) != (0, self.size.width):
lines = [line_crop(line, x1, x2, self.size.width) for line in lines]
width = self.size.width
if (x1, x2) != (0, width):
lines = [line_crop(line, x1, x2, width) for line in lines]
return lines
def render_lines(
self, line_range: tuple[int, int], column_range: tuple[int, int]
) -> Lines:
"""Get segment lines to render the widget."""
def render_lines(self, crop: Region) -> Lines:
"""Render the widget in to lines.
Args:
crop (Region): Region within visible area to.
Returns:
Lines: A list of list of segments
"""
if self._dirty_regions:
self._render_lines()
y1, y2 = line_range
x1, y1, x2, y2 = crop.corners
lines = self._render_cache.lines[y1:y2]
if column_range is not None:
lines = self._crop_lines(lines, *column_range)
lines = self._crop_lines(lines, x1, x2)
return lines
def get_style_at(self, x: int, y: int) -> Style:

View File

@@ -1,8 +1,9 @@
from __future__ import annotations
from dataclasses import dataclass
from dataclasses import dataclass, field
from typing import ClassVar, Generic, TypeVar, cast
from rich.console import RenderableType
from rich.padding import Padding
from rich.segment import Segment
from rich.style import Style
@@ -11,8 +12,9 @@ from rich.text import Text, TextType
from .._lru_cache import LRUCache
from .._segment_tools import line_crop
from .._types import Lines
from ..geometry import Size
from ..geometry import Region, Size
from ..reactive import Reactive
from .._profile import timer
from ..scroll_view import ScrollView
from ..widget import Widget
@@ -27,6 +29,13 @@ class Column:
index: int = 0
@dataclass
class Row:
index: int
height: int = 1
cell_renderables: list[RenderableType] = field(default_factory=list)
@dataclass
class Cell:
value: object
@@ -62,6 +71,10 @@ class DataTable(ScrollView, Generic[CellType]):
background: $primary 10%;
}
.-dark-mode DataTable > .datatable--even-row {
background: $primary 15%;
}
DataTable > .datatable--highlight {
background: $secondary;
color: $text-secondary;
@@ -84,16 +97,19 @@ class DataTable(ScrollView, Generic[CellType]):
) -> None:
super().__init__(name=name, id=id, classes=classes)
self.columns: list[Column] = []
self.rows: dict[int, Row] = {}
self.data: dict[int, list[CellType]] = {}
self.row_count = 0
self._cells: dict[int, list[Cell]] = {}
self.line_contents: list[str] = []
self._cells: dict[int, list[Cell]] = {}
self._cell_render_cache: dict[tuple[int, int], Lines] = LRUCache(10000)
show_header = Reactive(True)
fixed_rows = Reactive(1)
fixed_columns = Reactive(1)
zebra_stripes = Reactive(False)
def _update_dimensions(self) -> None:
max_width = sum(column.width for column in self.columns)
@@ -105,8 +121,17 @@ class DataTable(ScrollView, Generic[CellType]):
self._update_dimensions()
self.refresh()
def add_row(self, *cells: CellType) -> None:
self.data[self.row_count] = list(cells)
def add_row(self, *cells: CellType, height: int = 1) -> None:
row_index = self.row_count
self.data[row_index] = list(cells)
self.rows[row_index] = Row(
row_index,
height=height,
cell_renderables=[
Text.from_markup(cell) if isinstance(cell, str) else cell
for cell in cells
],
)
self.row_count += 1
self._update_dimensions()
self.refresh()
@@ -122,7 +147,7 @@ class DataTable(ScrollView, Generic[CellType]):
if data is None:
return [Text() for column in self.columns]
else:
return data
return self.rows[data_offset].cell_renderables
def _render_cell(self, y: int, column: Column) -> Lines:
@@ -151,6 +176,8 @@ class DataTable(ScrollView, Generic[CellType]):
rendered_width += column.width
cell_segments.append(lines[0])
base_style = self.rich_style
fixed_style = self.component_styles[
"datatable--fixed"
].node.rich_style + Style.from_meta({"fixed": True})
@@ -165,37 +192,31 @@ class DataTable(ScrollView, Generic[CellType]):
line: list[Segment] = sum(cell_segments, start=[])
row_style = Style()
row_style = base_style
if y == 0:
segments = fixed + line_crop(line, x1 + fixed_width, x2, width)
line = Segment.adjust_line_length(segments, width)
else:
component_row_style = (
"datatable--odd-row" if y % 2 else "datatable--even-row"
)
row_style += self.component_styles[component_row_style].node.rich_style
if self.zebra_stripes:
component_row_style = (
"datatable--odd-row" if y % 2 else "datatable--even-row"
)
row_style = self.component_styles[component_row_style].node.rich_style
line = list(Segment.apply_style(line, row_style))
segments = fixed + line_crop(line, x1 + fixed_width, x2, width)
line = Segment.adjust_line_length(segments, width)
line = Segment.adjust_line_length(segments, width, style=base_style)
if y == 0 and self.show_header:
line = list(Segment.apply_style(line, header_style))
return line
def render_lines(
self, line_range: tuple[int, int], column_range: tuple[int, int]
) -> Lines:
scroll_x, scroll_y = self.scroll_offset
y1, y2 = line_range
y1 += scroll_y
y2 += scroll_y
@timer("render_lines")
def render_lines(self, crop: Region) -> Lines:
x1, x2 = column_range
x1 += scroll_x
x2 += scroll_x
scroll_x, scroll_y = self.scroll_offset
x1, y1, x2, y2 = crop.translate(scroll_x, scroll_y).corners
fixed_lines = [self._render_line(y, x1, x2) for y in range(0, self.fixed_rows)]
lines = [self._render_line(y, x1, x2) for y in range(y1, y2)]
@@ -204,10 +225,6 @@ class DataTable(ScrollView, Generic[CellType]):
if y - scroll_y == 0:
lines[0] = fixed_line
(base_background, base_color), (background, color) = self.colors
style = Style.from_color(color.rich_color, background.rich_color)
lines = [list(Segment.apply_style(line, style)) for line in lines]
return lines
def on_mouse_move(self, event):