mirror of
https://git.lynn.is/Gwen/python-layout.git
synced 2024-01-13 01:31:55 +01:00
150 lines
5.5 KiB
Python
150 lines
5.5 KiB
Python
from . import Layout
|
|
from PIL import ImageDraw
|
|
|
|
from .internal.helpers import min_with_none, max_with_none
|
|
|
|
|
|
class Container(Layout):
|
|
def __init__(
|
|
self,
|
|
|
|
contents=None,
|
|
|
|
**kwargs
|
|
):
|
|
super().__init__(**kwargs)
|
|
if contents is None:
|
|
contents = []
|
|
self._contents = contents
|
|
|
|
def _children(self):
|
|
return self._contents
|
|
|
|
def get_min_inner_width(self, max_height=None):
|
|
min_width = 0
|
|
for c in self._contents:
|
|
width = c.get_min_outer_width(max_height)
|
|
if c._left is not None:
|
|
width += c._left
|
|
if c._right is not None:
|
|
width += c._right
|
|
min_width = max(min_width, width)
|
|
if self._min_width is not None:
|
|
min_width = max(min_width, self._min_width)
|
|
return min_width
|
|
|
|
def get_min_inner_height(self, max_width=None):
|
|
min_height_automatic = 0
|
|
min_height_absolute = 0
|
|
for c in self._contents:
|
|
height = c.get_min_outer_height(max_width)
|
|
if c._top is None and c._bottom is None and c._left is None and c._right is None:
|
|
min_height_automatic += height
|
|
else:
|
|
if c._top is not None:
|
|
height += c._top
|
|
if c._bottom is not None:
|
|
height += c._bottom
|
|
min_height_absolute = max(min_height_absolute, height)
|
|
min_height = max(min_height_automatic, min_height_absolute)
|
|
if self._min_height is not None:
|
|
min_height = max(min_height, self._min_height)
|
|
return min_height
|
|
|
|
def get_ideal_inner_dimensions(self, min_width=None, min_height=None, available_width=None, available_height=None):
|
|
width, height_automatic, height_absolute = 0, 0, 0
|
|
|
|
for c in self._contents:
|
|
w, h = c.get_ideal_outer_dimensions(min_width, min_height, available_width, available_height)
|
|
if c._left is not None:
|
|
w += c._left
|
|
if c._right is not None:
|
|
w += c._right
|
|
if c._top is not None:
|
|
h += c._top
|
|
if c._bottom is not None:
|
|
h += c._bottom
|
|
width = max(width, w)
|
|
if c._top is None and c._bottom is None and c._left is None and c._right is None:
|
|
height_automatic += h
|
|
else:
|
|
height_absolute = max(height_absolute, h)
|
|
height = max(height_automatic, height_absolute)
|
|
if self._width is not None:
|
|
width = self._width
|
|
if self._height is not None:
|
|
height = self._height
|
|
return width, height
|
|
|
|
def render_content(self, rect):
|
|
image = self.make_canvas()
|
|
x1, y1, x2, y2 = rect
|
|
automatic_y = 0
|
|
for c in self._contents:
|
|
soft_max_width, soft_max_height = x2 - x1 + 1, y2 - y1 + 1
|
|
|
|
is_absolute = not (c._top is None and c._bottom is None and c._left is None and c._right is None)
|
|
|
|
if c._left is not None:
|
|
soft_max_width -= c._left
|
|
if c._right is not None:
|
|
soft_max_width -= c._right
|
|
if c._top is not None:
|
|
soft_max_height -= c._top
|
|
if c._bottom is not None:
|
|
soft_max_height -= c._bottom
|
|
|
|
hard_max_width, hard_max_height = c._max_width, c._max_height
|
|
if c._left is not None and c._right is not None:
|
|
hard_max_width = min_with_none(hard_max_width, x2 - x1 + 1 - c._left - c._right)
|
|
if c._top is not None and c._bottom is not None:
|
|
hard_max_height = min_with_none(hard_max_height, y2 - y1 + 1 - c._top - c._bottom)
|
|
|
|
width, height = c.get_ideal_outer_dimensions(available_width=soft_max_width, available_height=soft_max_height)
|
|
|
|
if c._left is not None and c._right is not None:
|
|
width = (x2 - c._right) - (x1 + c._left) + 1
|
|
if c._top is not None and c._bottom is not None:
|
|
height = (y2 - c._bottom) - (y1 + c._top) + 1
|
|
|
|
min_width, min_height = c.get_min_outer_width(hard_max_height), c.get_min_outer_height(hard_max_width)
|
|
width = max_with_none(width, min_width)
|
|
height = max_with_none(height, min_height)
|
|
|
|
width = min_with_none(width, hard_max_width)
|
|
height = min_with_none(height, hard_max_height)
|
|
|
|
if is_absolute:
|
|
if c._left is None:
|
|
if c._right is None:
|
|
cx1 = x1
|
|
cx2 = cx1 + width - 1
|
|
else:
|
|
cx2 = x2 - c._right
|
|
cx1 = cx2 - width + 1
|
|
else:
|
|
cx1 = x1 + c._left
|
|
cx2 = cx1 + width - 1
|
|
|
|
if c._top is None:
|
|
if c._bottom is None:
|
|
cy1 = y1
|
|
cy2 = cy1 + height - 1
|
|
else:
|
|
cy2 = y2 - c._bottom
|
|
cy1 = cy2 - height + 1
|
|
else:
|
|
cy1 = y1 + c._top
|
|
cy2 = cy1 + height - 1
|
|
else:
|
|
cx1 = x1
|
|
cx2 = cx1 + width - 1
|
|
cy1 = y1 + automatic_y
|
|
cy2 = cy1 + height - 1
|
|
|
|
automatic_y += height
|
|
|
|
content_image = c.render((cx1, cy1, cx2, cy2))
|
|
image.alpha_composite(content_image)
|
|
return image
|