Add horizontal layout

This commit is contained in:
Darren Burns
2022-01-27 13:07:12 +00:00
parent df0965f162
commit b0c9b83bf4
4 changed files with 55 additions and 3 deletions

View File

@@ -1,5 +1,6 @@
import sys import sys
from .horizontal import HorizontalLayout
from ..layout import Layout from ..layout import Layout
from ..layouts.dock import DockLayout from ..layouts.dock import DockLayout
from ..layouts.grid import GridLayout from ..layouts.grid import GridLayout
@@ -10,8 +11,13 @@ if sys.version_info >= (3, 8):
else: else:
from typing_extensions import Literal from typing_extensions import Literal
LayoutName = Literal["dock", "grid", "vertical"] LayoutName = Literal["dock", "grid", "vertical", "horizontal"]
LAYOUT_MAP = {"dock": DockLayout, "grid": GridLayout, "vertical": VerticalLayout} LAYOUT_MAP = {
"dock": DockLayout,
"grid": GridLayout,
"vertical": VerticalLayout,
"horizontal": HorizontalLayout,
}
class MissingLayout(Exception): class MissingLayout(Exception):

View File

@@ -0,0 +1,45 @@
from __future__ import annotations
from typing import Iterable
from textual._loop import loop_last
from textual.css.styles import Styles
from textual.geometry import SpacingDimensions, Spacing, Size, Offset, Region
from textual.layout import Layout, WidgetPlacement
from textual.view import View
from textual.widget import Widget
class HorizontalLayout(Layout):
def __init__(
self,
*,
z: int = 0,
gutter: SpacingDimensions = (0, 0, 0, 0),
):
self.z = z
self.gutter = Spacing.unpack(gutter)
self._max_widget_width = 0
super().__init__()
def get_widgets(self, view: View) -> Iterable[Widget]:
return view.children
def arrange(
self, view: View, size: Size, scroll: Offset
) -> Iterable[WidgetPlacement]:
width, height = size
gutter = self.gutter
gutter_width = max(gutter.right, gutter.left)
x, y = self.gutter.top_left
for last, widget in loop_last(view.children):
styles: Styles = widget.styles
render_height = styles.height if styles else height
if styles.width:
render_width = int(styles.width.resolve_dimension(size, view.app.size))
else:
render_width = width
region = Region(x, y, render_width, render_height)
yield WidgetPlacement(region, widget, self.z)
x += render_width + (gutter.right if last else gutter_width)

View File

@@ -2,7 +2,6 @@ from __future__ import annotations
from typing import Iterable, TYPE_CHECKING from typing import Iterable, TYPE_CHECKING
from textual import log
from ..css.styles import Styles from ..css.styles import Styles
from ..geometry import Offset, Region, Size, Spacing, SpacingDimensions from ..geometry import Offset, Region, Size, Spacing, SpacingDimensions
from ..layout import Layout, WidgetPlacement from ..layout import Layout, WidgetPlacement

View File

@@ -2,6 +2,7 @@ import pytest
from textual.layouts.dock import DockLayout from textual.layouts.dock import DockLayout
from textual.layouts.grid import GridLayout from textual.layouts.grid import GridLayout
from textual.layouts.horizontal import HorizontalLayout
from textual.layouts.vertical import VerticalLayout from textual.layouts.vertical import VerticalLayout
from textual.view import View from textual.view import View
@@ -10,6 +11,7 @@ from textual.view import View
["dock", DockLayout], ["dock", DockLayout],
["grid", GridLayout], ["grid", GridLayout],
["vertical", VerticalLayout], ["vertical", VerticalLayout],
["horizontal", HorizontalLayout],
]) ])
def test_view_layout_get_and_set(layout_name, layout_type): def test_view_layout_get_and_set(layout_name, layout_type):
view = View() view = View()