mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
70 lines
2.1 KiB
Python
70 lines
2.1 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Iterable, TYPE_CHECKING
|
|
|
|
from ..geometry import Offset, Region, Size, Spacing, SpacingDimensions
|
|
from ..layout import Layout, WidgetPlacement
|
|
from .._loop import loop_last
|
|
|
|
if TYPE_CHECKING:
|
|
from ..widget import Widget
|
|
from ..view import View
|
|
|
|
|
|
class VerticalLayout(Layout):
|
|
def __init__(
|
|
self,
|
|
*,
|
|
auto_width: bool = False,
|
|
z: int = 0,
|
|
gutter: SpacingDimensions = (0, 0, 0, 0)
|
|
):
|
|
self.auto_width = auto_width
|
|
self.z = z
|
|
self.gutter = Spacing.unpack(gutter)
|
|
self._widgets: list[Widget] = []
|
|
self._max_widget_width = 0
|
|
super().__init__()
|
|
|
|
def add(self, widget: Widget) -> None:
|
|
self._widgets.append(widget)
|
|
self._max_widget_width = max(widget.app.measure(widget), self._max_widget_width)
|
|
|
|
def clear(self) -> None:
|
|
del self._widgets[:]
|
|
self._max_widget_width = 0
|
|
|
|
def get_widgets(self) -> Iterable[Widget]:
|
|
return self._widgets
|
|
|
|
def arrange(
|
|
self, view: View, size: Size, scroll: Offset
|
|
) -> Iterable[WidgetPlacement]:
|
|
index = 0
|
|
width, _height = size
|
|
gutter = self.gutter
|
|
x, y = self.gutter.top_left
|
|
render_width = (
|
|
max(width, self._max_widget_width)
|
|
if self.auto_width
|
|
else width - gutter.width
|
|
)
|
|
|
|
total_width = render_width
|
|
|
|
gutter_height = max(gutter.top, gutter.bottom)
|
|
|
|
for last, widget in loop_last(self._widgets):
|
|
if (
|
|
not widget.render_cache
|
|
or widget.render_cache.size.width != render_width
|
|
):
|
|
widget.render_lines_free(render_width)
|
|
assert widget.render_cache is not None
|
|
render_height = widget.render_cache.size.height
|
|
region = Region(x, y, render_width, render_height)
|
|
yield WidgetPlacement(region, widget, (self.z, index))
|
|
y += render_height + (gutter.bottom if last else gutter_height)
|
|
|
|
yield WidgetPlacement(Region(0, 0, total_width + gutter.width, y))
|