ludic/packages/ludic.ui/node.ludic
Orkuncakilkaya 20d011f8e9 feat(lang): UI components as files - component Name { ... } beside Name.xml and Name.lss
The compiler turns a component declaration into:
- a record of its props and state;
- a constructor, a props setter, a model and a call;
- a class, registered with ludic.ui at start.

Its template and styles are read from beside it and compiled in, with @import inlined, and a
missing template fails the build.

In the runtime:
- each mounted instance keeps its own props and state, and `set` in a template writes the state;
- styles are scoped to the component;
- class, style and id on a component's tag land on its root, styled by the parent's sheet too;
- ui_reload re-reads a component's files from disk and keeps instances.

The package's own module is now ludic_ui, so a program may call a directory of its own ui.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 16:50:12 +03:00

80 lines
3 KiB
Text

# node.ludic - what a template becomes each frame, the view it reads, and the renderer seam
export property UiNode {
kind: int = 0
dir: int = 0
text: string = ""
key: string = ""
tag: string = "" # what it is called in the template, and what a selector names
id: string = ""
classes: []string = null
akeys: []string = null # its attributes, as text, for [attr=value] selectors
avals: []string = null
vals: []Val = null # the same, as values, applied after every rule
style: UiRule = null # its style="..." declarations
sheet: UiSheet = null # the stylesheets of the file it was written in
sheet2: UiSheet = null # a component's root: its user's sheet too, and their style="..."
style2: UiRule = null
env2: UiEnv = null
parent: UiNode = null
index: int = 0 # its place among its parent's children, for :first-child and the rest
src: string = "" # an <img>'s picture
size: float = 0.0
w: float = 0.0
h: float = 0.0
w_pct: float = 0.0 # a width or height as a percentage of the parent's room
h_pct: float = 0.0
pt: float = 0.0 # padding, top right bottom left
pr: float = 0.0
pb: float = 0.0
pl: float = 0.0
mt: float = 0.0 # margin
mr: float = 0.0
mb: float = 0.0
ml: float = 0.0
border: float = 0.0
border_c: int = -2
gap: float = 0.0
align: int = 0
justify: int = 0
talign: int = 0 # text-align
self: int = -1 # align-self; -1 takes the parent's align
grow: float = 0.0 # a share of the spare room along the parent's direction
wrap: bool = false # a row breaks into lines where it runs out of room
min_w: float = 0.0
max_w: float = 0.0 # 0 is no limit
min_h: float = 0.0
max_h: float = 0.0
hidden: bool = false # display: none, or hidden
pos: int = 0 # position: 0 static, 1 relative, 2 absolute, 3 fixed
top: float = -1000000.0 # the insets a positioned element is placed by (UI_AUTO: unset)
right: float = -1000000.0
bottom: float = -1000000.0
left: float = -1000000.0
z: int = 0
nowrap: bool = false # white-space: nowrap
ellipsis: bool = false # text-overflow: ellipsis
lines: []string = null # a wrapped text's lines
var_names: []string = null # its custom properties (--name), which its descendants inherit
var_vals: []string = null
fg: int = -1
bg: int = -2
alpha: float = 1.0
enabled: bool = true
act: UiAct = null # on-press, which the pointer and the renderer's button fire
on_names: []string = null # every on-* it answers
on_acts: []UiAct = null
native: UiNative = null
env: UiEnv = null
children: []UiNode = null
mw: float = 0.0
mh: float = 0.0
content_h: float = 0.0 # what a scroll box holds, however tall the box itself is
x: float = 0.0
y: float = 0.0
cw: float = 0.0
ch: float = 0.0
rsize: float = 0.0
rfg: int = 0
hovered: bool = false
}