Skip to content

Layout and MainWindow

oldmangan edited this page Oct 6, 2026 · 3 revisions

Layout arranges cells in flexbox rows and columns; widgets mount into cells. MainWindow is a Layout bound to the page's #maindiv, and is the base class of every wapyt app.

MainWindow

from wapyt import CellConfig, LayoutConfig, MainWindow

APP_ENTRYPOINT = "Inventory"

class Inventory(MainWindow):
    layout_config = LayoutConfig(rows=[
        CellConfig(id="header", height="auto"),
        CellConfig(id="body", grow=1, cols=[
            CellConfig(id="nav", width="220px", header="Categories", collapsible=True),
            CellConfig(id="items", width="100%"),
        ]),
    ])

    def load_ui(self):
        self.set_theme("dark")
        self.tree = self.add_tree("nav", TreeConfig(...))
        self.table = self.add_datatable("items", DataTableConfig(...))
  • Implement load_ui() only. The LoadUICaller metaclass calls it after construction; an __init__ that also calls it builds the UI twice.
  • Without a class-level layout_config, MainWindow has two rows: mainwindow_header (height="auto") and mainwindow (grow=1).
  • set_theme("dark" | "light") sets data-wapyt-theme on <html>.
  • Declare APP_ENTRYPOINT (see Getting Started).

Cells

CellConfig field Meaning
id What every add_* helper and cell method takes
rows / cols Nested cells, stacked or side by side
width / height "100%" fill the remaining space · "auto" size to content · "220px", "30%", 220 fixed
grow / shrink Flex grow and shrink for cells without a size
min_size / max_size Limits along the parent's axis (also the limits of a splitter drag)
resizable A drag handle between this cell and its neighbour; see Resizable cells
header Title bar text
collapsible / collapsed / hidden Initial state
html Static markup
css Extra class names

LayoutConfig takes rows or cols, plus gap, css and borderless.

Cells get min-width: 0; min-height: 0, so a wide table or terminal scrolls inside its cell instead of pushing the layout wider. They are border-box, so width=240 is exactly 240px including the border (since #35; before, sized cells were 2px wider than declared).

Mounting

Helper Returns
add_layout(id, layout_config) nested Layout; its helpers take its cell ids
add_toolbar (defaults to mainwindow_header) · add_tree · add_datatable · add_form · add_tabwidget · add_sidebar · add_chat · add_terminal · add_cardpanel · add_resourceboard · add_progressbar · add_pagination the widget
attach_html(id, html) raw markup (escape any data in it)
attach(id, component) a JS component
get_cell(id) the cell, for Widget(cfg, container=cell)

The id is always an existing cell id.

Cell operations

collapse, expand, toggle, hide, show, is_visible, remove_cell, detach, progress_show(id, text) / progress_hide(id), resize(id). Layout events: after_add, after_remove, after_show, after_hide, before_remove.

Resizable cells

LayoutConfig(cols=[
    CellConfig(id="side", width=240, resizable=True, min_size=160, max_size=400),
    CellConfig(id="main"),
])
layout.on_resize(lambda e: prefs.save(e["id"], e["size"]))
layout.set_size("side", prefs.get("side", 240))      # restore

resizable=True puts a drag handle between the cell and its next sibling (its previous one if it is last). Added in #35.

  • Adding a handle moves nothing: it sits inside the gap between the cells. A line shows on hover, keyboard focus and drag.
  • What a drag changes: a cell with a size gets a new pixel size, and a cell that fills the remaining space keeps filling. Two fill cells trade their share, so their ratio survives a window resize.
  • Limits: min_size / max_size, and never under 48px.
  • Keyboard: the handle is a focusable role="separator". Arrow keys move it 10px (Shift: 50px), Home / End go to the limits, and Enter or a double-click puts both cells back to how they were configured.
  • A hidden neighbour hides the handle. Dragging works across iframes and terminals, and a Terminal refits itself as its cell changes.
Method
on_resize(handler) After a drag, a key press or a reset: {id, size, sibling, sibling_size} in px, the cells before and after the handle
set_size(id, size) Fix a cell's size (px or any CSS size), e.g. one saved from on_resize
get_size(id) A cell's size in px along its parent's axis

Clone this wiki locally