Skip to main content

Py5 Layout

Py5 Layout is a library that extends Py5 with a python based markup language. Styles are mirrored from CSS. The library is compatible with your normal python workflow/libraries. You can use logic defined in python to control the layout and the styles.

Example:

import py5
from py5_layout import Py5Layout, Div, Style
from math import sin, cos
from time import time
width_ = 500
height_ = 500
layout = None
def setup():
    global width_, height_, layout
    py5.size(width_, height_)
    layout = Py5Layout(style=Style(background_color=(255,255,255), width="100%", height="100%"), width=width_, height=height_)

count = 0
def draw():
    global count, last_print_time
    count += 1
    with layout:
        with Div(style=Style(background_color=(127*sin(count/10), 0, 127*cos(count/10)), width=count//2, height="50%")):
            with Div(style=Style(background_color=(0,255,0))):
                Div(style=Style(background_color=(255,0,0)))

py5.run_sketch()

This creates the following animated layout:

animated layout

Installation

Install the library:

pip install py5-layout

Follow instructions to install Java 17 from py5's website here

Usage

In this library, the with statement is used to create a hierarchical layout context, where each nested with block defines a child node within its parent container.

from py5_layout import *

layout = None
def setup():
    py5.size(500, 500)
    global layout
    layout = Py5Layout(style=Style(background_color=(255,255,255), width="100%", height="100%"), width=width_, height=height_)
def draw():
    with layout:
        with Div(style=Style(background_color="red", width="100%", height="100%")):
            with Div(style=Style(background_color="green")):
                Div(style=Style(background_color="blue"))

is equivalent to:

<div style="background-color: red; width: 100%; height: 100%;">
  <div style="background-color: green;">
    <div style="background-color: blue;"></div>
  </div>
</div>

You can use python logic to control the layout and styles.

from py5_layout import *
count = 0
layout = None
def setup():
    global layout
    layout = Py5Layout(style=Style(background_color=(255,255,255), width="100%", height="100%"), width=width_, height=height_)
def draw():
    global count
    count += 1
    show_green = count % 50 < 25
    with layout:
        with Div(style=Style(background_color="red", width=f"{count%100}%", height="100%")):
            if show_green:
                with Div(style=Style(background_color="green")):
                    Div(style=Style(background_color="blue"))

You can also embed custom animations and renderings into the layout. See the custom sketch example

import py5
from py5_layout import Py5Layout, Div, Style, Text, Element
from math import sin, cos
from time import time
width_ = 500
height_ = 500
layout = None
last_print_time = 0

class CustomSketch(Element):
    def __init__(self, circle_radius: int, circle_color: tuple, **kwargs):
        super().__init__(**kwargs)
        self.circle_radius = circle_radius
        self.circle_color = circle_color

    def draw(self):
        with self.canvas(set_origin=False, clip=True):
            py5.fill(*self.circle_color)
            py5.circle(py5.mouse_x, py5.mouse_y, self.circle_radius)


def setup():
    global width_, height_, layout
    py5.size(width_, height_)
    layout = Py5Layout(style=Style(background_color=(255,255,255), width="100%", height="100%"), width=width_, height=height_)

count = 0
def draw():
    py5.no_stroke()
    global count, last_print_time
    count += 1
    with layout:
        CustomSketch(circle_radius=100,
                        circle_color=(255,0,0),
                        style=Style(background_color=(255,255,255),flex=1), width=width_, height=height_)
        with Div(style=Style(background_color="cyan", width="100%", height="50%", justify_content="center", align_items="center", align_content="center", font_size=40), name="div2"):
            Text("Woah look at that circle go!!!!")
py5.run_sketch()

this renders the following: custom sketch

Reference

  • Div: A container element that can contain other elements.
  • Text: A text element that can be used to display text.
  • Style: A style object that can be used to style the layout.
  • Py5Layout: The main layout object that can be used to create the layout.
  • Element: The base class for all elements.

Style Reference

Style closely follows React Native's style system. Since the py5-layout uses Yoga.

GlobalType = Literal["inherit", "initial"]
AlignType = Literal["auto", "flex-start", "center", "flex-end", "stretch", "baseline", "space-between", "space-around"]
JustifyType = Literal["flex-start", "center", "flex-end", "space-between", "space-around", "space-evenly"]
PositionMarginType = str | float | Literal["auto"]
SizeType = float | str | Literal["auto"]
MaxSizeType = float | str | Literal["none"]
MinSizeType = float | str | Literal["auto"]
PaddingType = float | str
ColorType = str | Tuple | int | float

class Style():
    align_content: AlignType | GlobalType = field(default="auto", metadata=gen_metadata(inherited=False))
    align_items: AlignType | GlobalType = field(default="auto", metadata=gen_metadata(inherited=False))
    align_self: AlignType | GlobalType = field(default="auto", metadata=gen_metadata(inherited=False))
    all: Any = NotImplemented
    # Animation properties are not included and there is no current plan to include them
    background_attachment = NotImplemented
    background_blend_mode = NotImplemented
    background_clip = NotImplemented
    background_color: ColorType = field(default="transparent", metadata=gen_metadata(inherited=False))
    background_image: str = NotImplemented
    background_origin = NotImplemented
    background_position = NotImplemented
    background_repeat = NotImplemented
    background_size = NotImplemented
    border: str = NotImplemented
    border_bottom: str = NotImplemented
    border_bottom_color: str = NotImplemented
    border_bottom_left_radius: str = NotImplemented
    border_bottom_right_radius: str = NotImplemented
    border_bottom_style: str = NotImplemented
    border_bottom_width: str = NotImplemented
    border_collapse: str = NotImplemented
    border_color: str = NotImplemented
    border_image = NotImplemented
    border_image_outset = NotImplemented
    border_image_repeat = NotImplemented
    border_image_slice = NotImplemented
    border_image_source = NotImplemented
    border_image_width = NotImplemented
    border_left: str = NotImplemented
    border_left_color: str = NotImplemented
    border_left_style: str = NotImplemented
    border_left_width: str = NotImplemented
    border_radius: str = NotImplemented
    border_right_color: str = NotImplemented
    border_right: str = NotImplemented
    border_right_style: str = NotImplemented
    border_right_width: str = NotImplemented
    border_top_color: str = NotImplemented
    border_top: str = NotImplemented
    border_top_left_radius: str = NotImplemented
    border_top_right_radius: str = NotImplemented
    border_top_style: str = NotImplemented
    border_top_width: str = NotImplemented
    border_style: str = NotImplemented
    border_spacing: str = NotImplemented
    border_width: int | str | Tuple = NotImplemented
    bottom: PositionMarginType = field(default="auto", metadata=gen_metadata(inherited=False))
    box_shadow = NotImplemented
    box_sizing = NotImplemented
    color: ColorType = field(default=(0,0,0), metadata=gen_metadata(inherited=True))
    column_gap = NotImplemented
    direction: Literal["ltr", "rtl", "inherit", "initial"] = field(default="ltr", metadata=gen_metadata(inherited=True))
    display: Literal["flex", "none"] = field(default="flex", metadata=gen_metadata(inherited=False))
    filter = NotImplemented
    flex: int = field(default=0, metadata=gen_metadata(inherited=False))
    flex_basis: str = NotImplemented
    flex_direction: Literal["row", "row-reverse", "column", "column-reverse"] = field(default="column", metadata=gen_metadata(inherited=False))
    flex_grow: float = field(default=0, metadata=gen_metadata(inherited=False))
    flex_shrink: float = field(default=0, metadata=gen_metadata(inherited=False))
    flex_wrap: Literal["nowrap", "wrap", "wrap-reverse"] = field(default="nowrap", metadata=gen_metadata(inherited=False))
    font_family: str = field(default="Serif", metadata=gen_metadata(inherited=True))
    font_size: int | str = field(default=16, metadata=gen_metadata(inherited=True))
    font_style: str = field(default="normal", metadata=gen_metadata(inherited=True))
    font_variant = NotImplemented
    font_weight = NotImplemented
    height: SizeType = field(default="auto", metadata=gen_metadata(inherited=False))
    hyphens = NotImplemented
    isolation = NotImplemented
    justify_content: JustifyType | GlobalType = field(default="flex-start", metadata=gen_metadata(inherited=False))
    left: PositionMarginType = field(default="auto", metadata=gen_metadata(inherited=False))
    letter_spacing = NotImplemented
    line_height: float | str = field(default=1.2, metadata=gen_metadata(inherited=True))
    margin_bottom: PositionMarginType = field(default="auto", metadata=gen_metadata(inherited=False))
    margin_left: PositionMarginType = field(default="auto", metadata=gen_metadata(inherited=False))
    margin_right: PositionMarginType = field(default="auto", metadata=gen_metadata(inherited=False))
    margin_top: PositionMarginType = field(default="auto", metadata=gen_metadata(inherited=False))
    max_height: MaxSizeType = field(default="none", metadata=gen_metadata(inherited=False))
    max_width: MaxSizeType = field(default="none", metadata=gen_metadata(inherited=False))
    min_height: MinSizeType = field(default="auto", metadata=gen_metadata(inherited=False))
    min_width: MinSizeType = field(default="auto", metadata=gen_metadata(inherited=False))
    mix_blend_mode = NotImplemented
    object_fit = NotImplemented
    outline_color = NotImplemented
    outline_offset = NotImplemented
    outline_style = NotImplemented
    outline_width = NotImplemented
    overflow = NotImplemented
    padding_bottom: PaddingType = field(default=0, metadata=gen_metadata(inherited=False))
    padding_left: PaddingType = field(default=0, metadata=gen_metadata(inherited=False))
    padding_right: PaddingType = field(default=0, metadata=gen_metadata(inherited=False))
    padding_top: PaddingType = field(default=0, metadata=gen_metadata(inherited=False))
    pointer_events = NotImplemented
    position: Literal["static", "relative", "absolute"] = field(default="static", metadata=gen_metadata(inherited=False))
    resize = NotImplemented
    right: PositionMarginType = field(default="auto", metadata=gen_metadata(inherited=False))
    scroll_behavior = NotImplemented
    text_align: Literal["left", "center", "right"] = field(default="left", metadata=gen_metadata(inherited=True))
    text_decoration = NotImplemented
    text_decoration_color = NotImplemented
    text_decoration_line = NotImplemented
    text_decoration_style = NotImplemented
    text_transform = NotImplemented
    text_shadow_color = NotImplemented
    text_shadow_offset = NotImplemented
    text_shadow_radius = NotImplemented
    top: PositionMarginType = field(default="auto", metadata=gen_metadata(inherited=False))
    # Transform properties are not included and there is no current plan to include them
    unicode_bidi: str = NotImplemented
    user_select = NotImplemented
    vertical_align = NotImplemented
    visibility = NotImplemented
    width: SizeType = field(default="auto", metadata=gen_metadata(inherited=False))
    z_index: str = NotImplemented

coming soon

  • Button
  • Switch
  • Slider
  • Checkbox

Todo:

  • Style inheritance
  • Style Merging
  • Text element
  • color keyword arguments (black, white, red, green, blue, etc.)
  • hover, focus, etc. pseudo-classes
  • Button element
  • rem, em, vw, vh, etc. units
  • CSS Classes and ids
  • CSS Files
  • CSS Variables
  • Style type checking

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py5_layout-0.1.0.tar.gz (15.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py5_layout-0.1.0-py3-none-any.whl (18.0 kB view details)

Uploaded Python 3

File details

Details for the file py5_layout-0.1.0.tar.gz.

File metadata

  • Download URL: py5_layout-0.1.0.tar.gz
  • Upload date:
  • Size: 15.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.3 CPython/3.10.8 Darwin/24.5.0

File hashes

Hashes for py5_layout-0.1.0.tar.gz
Algorithm Hash digest
SHA256 04aad84ff54260223949c5f1d31694513f4f4519d708c0f65c6c977025107172
MD5 19bc893de97736272f5a7ed127e04706
BLAKE2b-256 b04981c8ee1745dc65666c4e8c156873c859b0f6df44ecdb617bd5fd32939fd4

See more details on using hashes here.

File details

Details for the file py5_layout-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: py5_layout-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 18.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.3 CPython/3.10.8 Darwin/24.5.0

File hashes

Hashes for py5_layout-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6cbfec13fcf78a8130b91a59000f27c3b49635dedab141fee59622a309ec1578
MD5 5f9a3f0b82a50495582cd0c6678b0590
BLAKE2b-256 4fa1130dfb63ab1943fa8d9d5c15ce36e2ab560410a6bcded8b71e8427be6b63

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page