box model py

This commit is contained in:
Will McGugan
2022-04-20 14:21:04 +01:00
parent 66ec130726
commit 7f85fc6795

76
src/textual/_box_model.py Normal file
View File

@@ -0,0 +1,76 @@
from __future__ import annotations
from typing import Callable, TYPE_CHECKING
from .geometry import Size, Spacing
from .css.styles import StylesBase
def get_box_model(
styles: StylesBase,
container_size: Size,
parent_size: Size,
get_auto_width: Callable[[Size, Size], int],
get_auto_height: Callable[[Size, Size], int],
) -> tuple[Size, Spacing]:
"""Resolve the box model for this Styles.
Args:
container_size (Size): The size of the widget container.
parent_size (Size): The size widget's parent.
Returns:
tuple[Size, Spacing]: A tuple with the size of the content area and margin.
"""
has_rule = styles.has_rule
width, height = container_size
extra = Size(0, 0)
if styles.box_sizing == "content-box":
if has_rule("padding"):
extra += styles.padding.totals
extra += styles.border.spacing.totals
else: # border-box
extra -= styles.border.spacing.totals
if has_rule("width"):
if styles.width.is_auto:
# extra_width = styles.padding.width + styles.border.spacing.width
width = get_auto_width(container_size, parent_size)
else:
width = styles.width.resolve_dimension(container_size, parent_size)
else:
width = max(0, width - styles.margin.width)
if styles.min_width:
min_width = styles.min_width.resolve_dimension(container_size, parent_size)
width = max(width, min_width)
if styles.max_width:
max_width = styles.max_width.resolve_dimension(container_size, parent_size)
width = min(width, max_width)
if has_rule("height"):
if styles.height.is_auto:
extra_height = styles.padding.height + styles.border.spacing.height
height = get_auto_height(container_size, parent_size) + extra_height
else:
height = styles.height.resolve_dimension(container_size, parent_size)
else:
height = max(0, height - styles.margin.height)
if styles.min_height:
min_height = styles.min_height.resolve_dimension(container_size, parent_size)
height = max(height, min_height)
if styles.max_height:
max_height = styles.max_height.resolve_dimension(container_size, parent_size)
height = min(width, max_height)
size = Size(width, height) + extra
margin = styles.margin if has_rule("margin") else Spacing(0, 0, 0, 0)
return size, margin