62 lines
2.2 KiB
Python
62 lines
2.2 KiB
Python
import numpy as np
|
|
from PIL import Image
|
|
|
|
from pyWebLayout.core.base import Renderable, Queriable
|
|
from pyWebLayout.style.layout import Alignment
|
|
|
|
class Box(Renderable, Queriable):
|
|
|
|
def __init__(self,origin, size, callback = None, sheet : Image = None, mode: bool = None, halign=Alignment.CENTER, valign = Alignment.CENTER):
|
|
self._origin = np.array(origin)
|
|
self._size = np.array(size)
|
|
self._end = self._origin + self._size
|
|
self._callback = callback
|
|
self._sheet : Image = sheet
|
|
if self._sheet == None:
|
|
self._mode = mode
|
|
else:
|
|
self._mode = sheet.mode
|
|
self._halign = halign
|
|
self._valign = valign
|
|
|
|
def in_shape(self, point):
|
|
|
|
return np.all((point >= self._origin) & (point < self._end), axis=-1)
|
|
|
|
def render(self) -> Image:
|
|
# Create a new image canvas
|
|
if self._sheet is not None:
|
|
canvas = Image.new(self._sheet.mode, tuple(self._size))
|
|
else:
|
|
# Default to RGBA if no sheet is provided
|
|
canvas = Image.new(self._mode if self._mode else 'RGBA', tuple(self._size))
|
|
|
|
# Check if there's content to render
|
|
if hasattr(self, '_content') and self._content is not None:
|
|
content_render = self._content.render()
|
|
|
|
# Calculate positioning based on alignment
|
|
content_width, content_height = content_render.size
|
|
box_width, box_height = self._size
|
|
|
|
# Horizontal alignment
|
|
if self._halign == Alignment.LEFT:
|
|
x_offset = 0
|
|
elif self._halign == Alignment.RIGHT:
|
|
x_offset = box_width - content_width
|
|
else: # CENTER is default
|
|
x_offset = (box_width - content_width) // 2
|
|
|
|
# Vertical alignment
|
|
if self._valign == Alignment.TOP:
|
|
y_offset = 0
|
|
elif self._valign == Alignment.BOTTOM:
|
|
y_offset = box_height - content_height
|
|
else: # CENTER is default
|
|
y_offset = (box_height - content_height) // 2
|
|
|
|
# Paste the content onto the canvas
|
|
canvas.paste(content_render, (x_offset, y_offset))
|
|
|
|
return canvas
|