Source code for todays_paper_web.widgets.core.line

from typing import Optional

import webcolors
from PIL import Image, ImageDraw
from pydantic import Field

from todays_paper_web.widgets import registerView, View
from todays_paper_web.widgets.params import Color
from todays_paper_web.widgets.view import ViewParams


[docs] class LineParams(ViewParams): # x/y (the line's own start point, defaulting to 0) come from # ViewParams - the same attributes a parent container reads to # position this element are what render() below uses as its start # coordinate, which is why the two never disagree with each other. x2: Optional[int] = Field( None, description="The line's end x coordinate; defaults to `x` (a zero-length line)." ) y2: Optional[int] = Field(None, description="The line's end y coordinate; defaults to `y`.") width: int = Field(1, description="Stroke thickness in pixels.") color: Color = Field( default_factory=lambda: webcolors.name_to_rgb("black"), description="Line color." )
@registerView("line") class LineView(View): Params = LineParams def render(self): x1 = self.params.x or 0 y1 = self.params.y or 0 x2 = self.params.x2 if self.params.x2 is not None else x1 y2 = self.params.y2 if self.params.y2 is not None else y1 width = max(abs(x2 - x1), self.params.width) height = max(abs(y2 - y1), self.params.width) img = Image.new("RGBA", (width, height), (0, 0, 0, 0)) draw = ImageDraw.Draw(img) color = (self.params.color.red, self.params.color.green, self.params.color.blue, 255) dx = abs(x2 - x1) dy = abs(y2 - y1) draw.line((0, 0, dx, dy), fill=color, width=self.params.width) return img