Builtin Library
README.md
viewport
The size the engine draws at — read it, and change it while the engine runs.
Everything a screen is laid out against comes from this one number pair: the
pixels getViewportSize() reports, the logical points ui.screenSize()
reports over them, each camera's aspect, and the raster a capture encodes.
Until an engine can be told to draw at another size, a layout can be proven at
exactly one shape per boot, and the second shape has to be read off a picture
taken at the first.
- size — what the engine is drawing at right now, in pixels and in the logical points a UI screen is laid out in, with the factor between them and the largest surface this device will draw.
- setSize: draw at another size for the rest of the call. The surface is
resized and every reader of it follows within a frame, so the UI tree is
rebuilt at the new shape rather than scaled from the old one; the call
returns the
sizereading at that shape, and the surface goes back to the size it had before when the call ends.
Why a resized capture is not this
capture { width, height } re-runs layout at the size it encodes, so a shot
comes back looking like a genuine render of the other shape. It is not one. The
widget tree was built one frame earlier from the live screen size, so every
absolute number in it — font sizes, padding, a fixed maxWidth — was computed
against the old short edge, and any branch the tree took on the live size (a
one-column portrait layout against a two-column landscape one) is the branch
the old size chose. setSize changes the size the tree is built from, which is
the half a resized capture cannot reach.
Who honours the size
A headless engine and a browser canvas own the surface they draw into, so the
size is honoured exactly; a browser page that lays its canvas out at a new size
meanwhile ends the hold with its own size. Where an OS window owns it, the
window manager is asked and has the last word: a tiled or maximized window
keeps the size it has. Either way size afterwards reports what was realized.
A size larger than the device draws is refused at the call, naming the bound.
Held for the call
A size is held for the call (the task) that asked for it. When that call ends, however it ends, the surface goes back to the size it had before, so the window or browser canvas a person is looking at is handed back as it was and no check leaves it at a shape nobody asked it to keep.
Two spaces, one surface
size reports the surface in pixels and in the logical points a widget is
positioned in, plus the ratio between them. The logical canvas is normalised to
about 1280 points wide, so a resize to a size of the SAME aspect moves the ratio
and leaves the logical shape where it was, while a resize that changes the
aspect changes the logical shape too. Both are real resizes; the second is the
one an orientation branch reacts to.
sceneWidth/sceneHeight is the rect the 3D scene is drawn into. It is the
whole surface in a runtime window, a browser canvas and a headless engine, and
the editor's viewport panel — smaller than the surface — in an editor layout.
Checking a layout at two shapes
In one execute, so the readings are taken while the size is held:
local viewport = require("@builtin::tools.viewport.setSize")
local portrait = viewport.setSize(1080, 1440) -- waits until drawn there
local hud = ui.getLayoutInfo("hud-root") -- measured at portrait
local landscape = viewport.setSize(1920, 1080) -- same call, same tree
local hudWide = ui.getLayoutInfo("hud-root")
return { portrait = portrait, hud = hud, landscape = landscape, hudWide = hudWide }
setSize returns once the surface reports the size, with the reading size
gives there. A capture taken in the same call encodes that shape. When the
call returns the surface goes back to the size it had before the first
setSize.