11from __future__ import annotations
22
33from fractions import Fraction
4- from typing import Callable , NamedTuple
4+ from typing import NamedTuple
55
6- from .css .styles import StylesBase
7- from .geometry import Size , Spacing
6+ from .geometry import Spacing
87
98
109class BoxModel (NamedTuple ):
@@ -14,119 +13,3 @@ class BoxModel(NamedTuple):
1413 width : Fraction
1514 height : Fraction
1615 margin : Spacing # Additional margin
17-
18-
19- def get_box_model (
20- styles : StylesBase ,
21- container : Size ,
22- viewport : Size ,
23- width_fraction : Fraction ,
24- height_fraction : Fraction ,
25- get_content_width : Callable [[Size , Size ], int ],
26- get_content_height : Callable [[Size , Size , int ], int ],
27- ) -> BoxModel :
28- """Resolve the box model for this Styles.
29-
30- Args:
31- styles: Styles object.
32- container: The size of the widget container.
33- viewport: The viewport size.
34- width_fraction: A fraction used for 1 `fr` unit on the width dimension.
35- height_fraction: A fraction used for 1 `fr` unit on the height dimension.
36- get_content_width: A callable which accepts container size and parent size and returns a width.
37- get_content_height: A callable which accepts container size and parent size and returns a height.
38-
39- Returns:
40- A tuple with the size of the content area and margin.
41- """
42- _content_width , _content_height = container
43- content_width = Fraction (_content_width )
44- content_height = Fraction (_content_height )
45- is_border_box = styles .box_sizing == "border-box"
46- gutter = styles .gutter
47- margin = styles .margin
48-
49- is_auto_width = styles .width and styles .width .is_auto
50- is_auto_height = styles .height and styles .height .is_auto
51-
52- # Container minus padding and border
53- content_container = container - gutter .totals
54- # The container including the content
55- sizing_container = content_container if is_border_box else container
56-
57- if styles .width is None :
58- # No width specified, fill available space
59- content_width = Fraction (content_container .width - margin .width )
60- elif is_auto_width :
61- # When width is auto, we want enough space to always fit the content
62- content_width = Fraction (
63- get_content_width (content_container - styles .margin .totals , viewport )
64- )
65- if styles .scrollbar_gutter == "stable" and styles .overflow_x == "auto" :
66- content_width += styles .scrollbar_size_vertical
67- else :
68- # An explicit width
69- styles_width = styles .width
70- content_width = styles_width .resolve (
71- sizing_container - styles .margin .totals , viewport , width_fraction
72- )
73- if is_border_box and styles_width .excludes_border :
74- content_width -= gutter .width
75-
76- if styles .min_width is not None :
77- # Restrict to minimum width, if set
78- min_width = styles .min_width .resolve (
79- content_container , viewport , width_fraction
80- )
81- content_width = max (content_width , min_width )
82-
83- if styles .max_width is not None :
84- # Restrict to maximum width, if set
85- max_width = styles .max_width .resolve (
86- content_container , viewport , width_fraction
87- )
88- if is_border_box :
89- max_width -= gutter .width
90- content_width = min (content_width , max_width )
91-
92- content_width = max (Fraction (0 ), content_width )
93-
94- if styles .height is None :
95- # No height specified, fill the available space
96- content_height = Fraction (content_container .height - margin .height )
97- elif is_auto_height :
98- # Calculate dimensions based on content
99- content_height = Fraction (
100- get_content_height (content_container , viewport , int (content_width ))
101- )
102- if styles .scrollbar_gutter == "stable" and styles .overflow_y == "auto" :
103- content_height += styles .scrollbar_size_horizontal
104- else :
105- styles_height = styles .height
106- # Explicit height set
107- content_height = styles_height .resolve (
108- sizing_container - styles .margin .totals , viewport , height_fraction
109- )
110- if is_border_box and styles_height .excludes_border :
111- content_height -= gutter .height
112-
113- if styles .min_height is not None :
114- # Restrict to minimum height, if set
115- min_height = styles .min_height .resolve (
116- content_container , viewport , height_fraction
117- )
118- content_height = max (content_height , min_height )
119-
120- if styles .max_height is not None :
121- # Restrict maximum height, if set
122- max_height = styles .max_height .resolve (
123- content_container , viewport , height_fraction
124- )
125- content_height = min (content_height , max_height )
126-
127- content_height = max (Fraction (0 ), content_height )
128-
129- model = BoxModel (
130- content_width + gutter .width , content_height + gutter .height , margin
131- )
132- return model
0 commit comments