mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
box model fixes and tests
This commit is contained in:
@@ -10,27 +10,27 @@ Widget {
|
||||
}
|
||||
|
||||
#thing {
|
||||
|
||||
width: auto;
|
||||
height: auto;
|
||||
|
||||
height: 10;
|
||||
background:magenta;
|
||||
margin: 3;
|
||||
padding: 1;
|
||||
border: solid white;
|
||||
box-sizing: content-box;
|
||||
/* border: solid white; */
|
||||
padding: 1;
|
||||
border: solid white;
|
||||
box-sizing: border-box;
|
||||
border: solid white;
|
||||
align-horizontal: center;
|
||||
}
|
||||
|
||||
|
||||
#thing2 {
|
||||
width: auto;
|
||||
height: 10;
|
||||
/* border: solid white; */
|
||||
outline: heavy blue;
|
||||
|
||||
border: solid white;
|
||||
/* outline: heavy blue; */
|
||||
|
||||
padding: 1 2;
|
||||
box-sizing: content-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
max-height: 100vh;
|
||||
|
||||
background:green;
|
||||
align-horizontal: center;
|
||||
@@ -39,8 +39,7 @@ Widget {
|
||||
|
||||
|
||||
#thing3 {
|
||||
width: 20;
|
||||
height: 10;
|
||||
|
||||
margin: 1;
|
||||
background:blue;
|
||||
align-horizontal: center;
|
||||
|
||||
@@ -201,7 +201,8 @@ Warning {
|
||||
|
||||
Success {
|
||||
max-width: 80;
|
||||
height:3;
|
||||
height:3;
|
||||
box-sizing: border-box;
|
||||
background: $success-lighten-3;
|
||||
color: $text-success-lighten-3-fade-1;
|
||||
border-top: hkey $success;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from __future__ import annotations
|
||||
from operator import is_
|
||||
|
||||
|
||||
from typing import Callable, NamedTuple, TYPE_CHECKING
|
||||
@@ -18,8 +19,8 @@ def get_box_model(
|
||||
styles: StylesBase,
|
||||
container_size: Size,
|
||||
parent_size: Size,
|
||||
get_auto_width: Callable[[Size, Size, Spacing], int],
|
||||
get_auto_height: Callable[[Size, Size, Spacing], int],
|
||||
get_content_width: Callable[[Size, Size], int],
|
||||
get_content_height: Callable[[Size, Size], int],
|
||||
) -> BoxModel:
|
||||
"""Resolve the box model for this Styles.
|
||||
|
||||
@@ -36,23 +37,30 @@ def get_box_model(
|
||||
|
||||
has_rule = styles.has_rule
|
||||
width, height = container_size
|
||||
is_content_box = styles.box_sizing == "content-box"
|
||||
gutter = styles.padding + styles.border.spacing
|
||||
|
||||
gutter = Spacing(0, 0, 0, 0)
|
||||
if styles.box_sizing == "content-box":
|
||||
if has_rule("padding"):
|
||||
gutter += styles.padding
|
||||
gutter += styles.border.spacing
|
||||
|
||||
else: # border-box
|
||||
gutter -= styles.border.spacing
|
||||
|
||||
if has_rule("width"):
|
||||
if styles.width.is_auto:
|
||||
width = get_auto_width(container_size, parent_size, gutter)
|
||||
else:
|
||||
width = styles.width.resolve_dimension(container_size, parent_size)
|
||||
if not has_rule("width") or styles.width.is_auto:
|
||||
# When width is auto, we want enough space to always fit the content
|
||||
width = get_content_width(container_size, parent_size)
|
||||
if not is_content_box:
|
||||
# If box sizing is border box we want to enlarge the width so that it
|
||||
# can accommodate padding + border
|
||||
width += gutter.width
|
||||
else:
|
||||
width = max(0, width - styles.margin.width)
|
||||
width = styles.width.resolve_dimension(container_size, parent_size)
|
||||
|
||||
if not has_rule("height") or styles.height.is_auto:
|
||||
height = get_content_height(container_size, parent_size)
|
||||
if not is_content_box:
|
||||
height += gutter.height
|
||||
else:
|
||||
height = styles.height.resolve_dimension(container_size, parent_size)
|
||||
|
||||
if is_content_box:
|
||||
gutter_width, gutter_height = gutter.totals
|
||||
width += gutter_width
|
||||
height += gutter_height
|
||||
|
||||
if has_rule("min_width"):
|
||||
min_width = styles.min_width.resolve_dimension(container_size, parent_size)
|
||||
@@ -62,23 +70,15 @@ def get_box_model(
|
||||
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:
|
||||
height = get_auto_height(container_size, parent_size, gutter)
|
||||
else:
|
||||
height = styles.height.resolve_dimension(container_size, parent_size)
|
||||
else:
|
||||
height = max(0, height - styles.margin.height)
|
||||
|
||||
if has_rule("min_height"):
|
||||
min_height = styles.min_height.resolve_dimension(container_size, parent_size)
|
||||
height = max(height, min_height)
|
||||
|
||||
if has_rule("max_height"):
|
||||
max_height = styles.max_height.resolve_dimension(container_size, parent_size)
|
||||
height = min(width, max_height)
|
||||
height = min(height, max_height)
|
||||
|
||||
size = Size(width, height) + gutter.totals
|
||||
margin = styles.margin if has_rule("margin") else Spacing(0, 0, 0, 0)
|
||||
size = Size(width, height)
|
||||
margin = styles.margin
|
||||
|
||||
return BoxModel(size, margin)
|
||||
|
||||
@@ -8,7 +8,6 @@ when setting and getting.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
from tkinter.tix import AUTO
|
||||
|
||||
from typing import Iterable, NamedTuple, TYPE_CHECKING, cast
|
||||
|
||||
|
||||
@@ -34,9 +34,10 @@ class HorizontalLayout(Layout):
|
||||
max((box1.margin.right, box2.margin.left))
|
||||
for box1, box2 in zip(box_models, box_models[1:])
|
||||
]
|
||||
margins.append(box_models[-1].margin.right)
|
||||
if box_models:
|
||||
margins.append(box_models[-1].margin.right)
|
||||
|
||||
x = box_models[0].margin.left
|
||||
x = box_models[0].margin.left if box_models else 0
|
||||
|
||||
for widget, box_model, margin in zip(parent.children, box_models, margins):
|
||||
content_width, content_height = box_model.size
|
||||
@@ -47,7 +48,7 @@ class HorizontalLayout(Layout):
|
||||
x += region.width + margin
|
||||
max_width = x
|
||||
|
||||
max_width += margins[-1]
|
||||
max_width += margins[-1] if margins else 0
|
||||
|
||||
total_region = Region(0, 0, max_width, max_height)
|
||||
add_placement(WidgetPlacement(total_region, None, 0))
|
||||
|
||||
@@ -35,9 +35,10 @@ class VerticalLayout(Layout):
|
||||
max((box1.margin.bottom, box2.margin.top))
|
||||
for box1, box2 in zip(box_models, box_models[1:])
|
||||
]
|
||||
margins.append(box_models[-1].margin.bottom)
|
||||
if box_models:
|
||||
margins.append(box_models[-1].margin.bottom)
|
||||
|
||||
y = box_models[0].margin.top
|
||||
y = box_models[0].margin.top if box_models else 0
|
||||
|
||||
for widget, box_model, margin in zip(parent.children, box_models, margins):
|
||||
content_width, content_height = box_model.size
|
||||
@@ -48,7 +49,7 @@ class VerticalLayout(Layout):
|
||||
y += region.height + margin
|
||||
max_height = y
|
||||
|
||||
max_height += margins[-1]
|
||||
max_height += margins[-1] if margins else 0
|
||||
|
||||
total_region = Region(0, 0, max_width, max_height)
|
||||
add_placement(WidgetPlacement(total_region, None, 0))
|
||||
|
||||
@@ -131,7 +131,8 @@ class Screen(Widget):
|
||||
)
|
||||
)
|
||||
except Exception as error:
|
||||
self.app.panic(error)
|
||||
self.app.on_exception(error)
|
||||
return
|
||||
self.app.refresh()
|
||||
self._dirty_widgets.clear()
|
||||
|
||||
|
||||
@@ -115,21 +115,16 @@ class Widget(DOMNode):
|
||||
self.get_content_width,
|
||||
self.get_content_height,
|
||||
)
|
||||
self.log(self, self.styles.padding, self.styles.border.spacing)
|
||||
return box_model
|
||||
|
||||
def get_content_width(
|
||||
self, container_size: Size, parent_size: Size, gutter: Spacing
|
||||
) -> int:
|
||||
def get_content_width(self, container_size: Size, parent_size: Size) -> int:
|
||||
console = self.app.console
|
||||
renderable = self.render()
|
||||
measurement = Measurement.get(console, console.options, renderable)
|
||||
return measurement.maximum
|
||||
|
||||
def get_content_height(
|
||||
self, container_size: Size, parent_size: Size, gutter: Spacing
|
||||
) -> int:
|
||||
return container_size.height - gutter.height
|
||||
def get_content_height(self, container_size: Size, parent_size: Size) -> int:
|
||||
return container_size.height
|
||||
|
||||
async def watch_scroll_x(self, new_value: float) -> None:
|
||||
self.horizontal_scrollbar.position = int(new_value)
|
||||
|
||||
Reference in New Issue
Block a user