Skip to content

A small declarative MicroPython GUI library for display drivers based on the FrameBuffer interface

License

Notifications You must be signed in to change notification settings

submer-crypto/decal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

decal

A small declarative MicroPython GUI library for display drivers based on the FrameBuffer interface.

The library is inspired by HTML and CSS layout and rendering.

Usage

There are two elements for layout control, block and inline. The children of a block element are laid out vertically while the children of a inline element are laid out horizontally.

Furthermore there are two content elements, text and bitmap. The text element renders text strings while the bitmap element renders BitMap objects containing monochrome pixel data. The text element is assumed by default if a string is encountered, usually there is no need to use it explicitly.

import framebuf
from decal import (
    ComputedStyle,
    Color,
    Align,
    BoxSizing,
    Percentage,
    BitMap,
    Viewport,
    Position,
    Dimensions,
    draw,
    block,
    inline)

# Font structure specifying font width and height.
# Required for calculating position when laying out text.
class font8x8:
    @staticmethod
    def width(text):
        return len(text) * 6

    @staticmethod
    def height(text):
        return 8

# Additional characters not contained in the the default character set.
# The bits in a byte are vertically mapped with bit 0 being nearest the top.
# Similar to definition of framebuf.MONO_VLSB format.
FONT_8_DEGREE = BitMap(bytes([0x00, 0x00, 0x00, 0x06, 0x09, 0x09, 0x06, 0x00]))
FONT_8_LEFT_TRIANGLE = BitMap(bytes([0x00, 0x08, 0x1c, 0x3e, 0x7f, 0x7f, 0x7f, 0x7f]))

# Structure for organizing styling.
class menu_style:
    root = ComputedStyle.shorthand(
        padding_top=2
    )

    item_selected = ComputedStyle.shorthand(
        background_color=Color.WHITE,
        foreground_color=Color.BLACK,
        padding=2,
        width=Percentage(100),
        box_sizing=BoxSizing.BORDER,
        font=font8x8
    )

    item_default = ComputedStyle.shorthand(
        padding=2,
        width=Percentage(100),
        box_sizing=BoxSizing.BORDER,
        font=font8x8
    )

    item_text_selected = ComputedStyle.shorthand(
        foreground_color=Color.BLACK,
        align=Align.END,
        font=font8x8
    )

    item_text_default = ComputedStyle.shorthand(
        align=Align.END,
        font=font8x8
    )

# The actual UI elements to be rendered.
element = block(menu_style.root, [
    inline(menu_style.item_default, [
        'Temperature',
        inline(menu_style.item_text_default, ['25', FONT_8_DEGREE, 'C'])
    ]),
    inline(menu_style.item_selected, [
        'Amperage',
        inline(menu_style.item_text_selected, ['5A'])
    ]),
    inline(menu_style.item_default, ['Settings']),
    inline(menu_style.item_default, ['Firmware']),
    inline(menu_style.item_default, [FONT_8_LEFT_TRIANGLE, ' Back'])
])

# The global viewport used to lay out the individual UI elements.
# The viewport itself is only a container and not rendered to the frame buffer.
viewport = Viewport(Position(0, 0), Dimensions(128, 64), [element])
viewport.layout()

# Built-in MicroPython frame buffer.
frame_buffer = framebuf.FrameBuffer(bytearray(1024), 128, 64, framebuf.MONO_VLSB)

# Call draw to actually draw the UI elements to frame buffer.
draw(viewport, frame_buffer)

The above example will draw the following UI on a monochrome 128 x 64 pixel screen.

UI

About

A small declarative MicroPython GUI library for display drivers based on the FrameBuffer interface

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published