Draw a custom frame

A how-to guide: when no layout has the shape you want, draw the content yourself, cell by cell.

from sextile import Custom, OnOneFrame, Page, PageLayout, PageRequest, PageRouter, Sextile
from sextile.viewdata.canvas import Canvas
from sextile.viewdata.controls import Colour

router = PageRouter()

_SWATCHES = [Colour.RED, Colour.GREEN, Colour.YELLOW, Colour.CYAN, Colour.WHITE]


@router.page("5", name="palette", title="Colours")
async def palette(request: PageRequest) -> Page:
    def draw(canvas: Canvas, row: int) -> None:
        for offset, colour in enumerate(_SWATCHES):
            canvas.row(row + offset).text(colour.name, colour)

    return PageLayout(
        parts=[OnOneFrame(Custom(rows=len(_SWATCHES), draw=draw))],
    ).build(request)


app = Sextile(name="Palette", pages=[*router])
 COLOURS                              5a
  
 RED                                    
 GREEN                                  
 YELLOW                                 
 CYAN                                   
WHITE                                   
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
  
 0 index                                

A Custom part owns a stated number of rows and is handed the Canvas and the row it begins on. canvas.row(n) gives a writer for that row; .text(string, Colour.RED) appends text, spending a cell on a colour attribute where the colour changes. Reach for Custom only for a picture no layout has a shape for — a chart, a masthead, a grid — and prefer a layout otherwise.

For runs placed at positions with a checked fit, rather than a row at a time, use Compose a frame; for a sequence drawn its own way, a A custom part. The parts model is Layout, and the cost of the colour attribute a row spends is in Graphics.