mirror of
https://git.lynn.is/Gwen/python-layout.git
synced 2024-01-13 01:31:55 +01:00
150 lines
5.4 KiB
Python
150 lines
5.4 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
|