from PIL import ImageDraw from . import Layout, BoxTitleAnchor class Box(Layout): def __init__( self, title=None, title_font=None, title_color=None, title_anchor=BoxTitleAnchor.LEFT, title_position=0, title_padding=0, content=None, **kwargs ): super().__init__(**kwargs) self.title = title self.title_font = title_font self.title_color = title_color self.title_anchor = title_anchor self.title_position = title_position self.title_padding = title_padding self.content = content def children(self): if self.content is not None: return [self.content] else: return [] def get_title_font(self): if self.title_font is not None: return self.title_font else: return self.get_font() def get_title_color(self): if self.title_color is not None: return self.title_color else: return self.get_fg_color() def get_min_inner_width(self, max_height=None): if self.content is None: return 0 else: return self.content.get_min_outer_width(max_height) def get_min_inner_height(self, max_width=None): if self.content is None: return 0 else: return self.content.get_min_outer_height(max_width) def get_ideal_inner_dimensions(self, min_width=None, min_height=None, available_width=None, available_height=None): if self.content is None: return 0, 0 else: return self.content.get_ideal_outer_dimensions(min_width, min_height, available_width, available_height) def render_content(self, rect): if self.content is None: return self.make_canvas() else: return self.content.render(rect) def title_pos(self, rect): left, top, right, bottom = self.get_title_font().getbbox(self.title) height = bottom - top width = right - left border_radius = self.get_border_radius() available_width = rect[2] - rect[0] + 1 - border_radius[1] - border_radius[0] pos_x = rect[0] + border_radius[0] + self.title_position if self.title_anchor == BoxTitleAnchor.LEFT: pos_x += 0 elif self.title_anchor == BoxTitleAnchor.CENTER: pos_x += (available_width - width) / 2 elif self.title_anchor == BoxTitleAnchor.RIGHT: pos_x += available_width - width pos_y = rect[1] - height / 2 return (pos_x, pos_y), (left - self.title_padding, top, right + self.title_padding, bottom) def modify_border_mask(self, border_mask, rect): if self.title is None: return (x, y), (left, top, right, bottom) = self.title_pos(rect) d = ImageDraw.Draw(border_mask) d.rectangle((x + left, y + top, x + right, y + bottom), fill=0) def render_after_border(self, image, rect): if self.title is None: return (x, y), _ = self.title_pos(rect) d = ImageDraw.Draw(image) d.text((x, y), self.title, font=self.get_title_font(), fill=self.get_title_color())