Table of Contents
User Interface
The system pyssel/ui is the user interface toolkit, as Godot's controls
are: a user interface is scene nodes, saved and laid out like any scene,
drawn with the colours, fonts and style boxes of themes. What is here is
the control, which fills a rectangle, the layout that places controls,
the containers that lay them out, themes, the input that reaches
controls, from the pointer and the keyboard, and the widgets of a menu
screen or a settings form: panels, labels, buttons, check boxes,
sliders, progress bars, scroll bars, line edits and text edits. This page
says what every control has; Containers,
Widgets, Themes, Control Input and
Popups, Menus and Dialogs the rest. Panels draw
backgrounds:
(asdf:load-system :pyssel/ui)
(defpackage #:panels
(:use #:cl)
(:local-nicknames (#:sc #:pyssel/scene) (#:s2d #:pyssel/scene-2d) (#:ui #:pyssel/ui)))
(in-package #:panels)
(defun card (color &key (radius 6))
(make-instance 'ui:flat-style-box :background-color color :corner-radius radius))
(defun make-screen ()
(let ((screen (make-instance 'ui:panel
:name "screen" :preset :full-rect
:theme (make-instance 'ui:theme
:style-boxes `((ui:panel :panel
,(card '(0.25 0.3 0.4)))))))
(badge (make-instance 'ui:panel :preset :bottom-right :preset-margin 8
:custom-minimum-width 60 :custom-minimum-height 24)))
(setf (ui:control-style-box screen :panel) (card '(0.1 0.1 0.12) :radius 0)
(ui:control-style-box badge :panel) (card '(0.3 0.6 0.3)))
(sc:add-child screen (make-instance 'ui:panel :preset :top-wide :preset-margin 8
:custom-minimum-height 32))
(sc:add-child screen (make-instance 'ui:panel :preset :center
:custom-minimum-width 200
:custom-minimum-height 120))
(sc:add-child screen badge)
screen))
(defvar *tree* (s2d:run (make-screen) :title "Panels" :width 480 :height 320))
A bar runs along the top, a box sits in the centre and a badge in the
bottom right corner. Resize the window and each keeps its place. The bar
and the box draw the theme's style box for panels; the screen and the
badge have their own. The theme is the screen's, a resource it holds,
and *tree* the REPL's way in. Change the theme from the REPL, on the
tree's thread, and the bar and the box follow at the next frame:
(defun screen (tree)
(sc:find-node (sc:tree-root tree) "screen"))
(sc:call-in-tree *tree*
(lambda ()
(setf (ui:style-box-background-color
(ui:theme-style-box (ui:control-theme (screen *tree*)) 'ui:panel :panel))
'(0.5 0.3 0.2))))
- Controls:
control-x,control-y,control-widthandcontrol-heightare a control's rectangle in its parent's coordinates, as laid out; it and its children draw from its top left. Setting them moves or resizes it at once.offsets-for-positiongives the offsets that would put its top left at a point of its parent, keeping its size, as Godot'sset_positionworks them out, to set through an editor's history;anchoring-sizeis the size its anchors are fractions of, its parent's, as Godot'sget_parent_anchorable_rect. - Anchors and offsets place a control in its parent control, or in
the window if its parent is not a control: each edge is anchored at a
fraction of the parent's width or height,
control-anchor-leftand the rest, and sitscontrol-offset-leftand the rest units from there.set-layout-preset, or:presetand:preset-marginwhen making one, sets them for a corner, the middle of a side, the centre, a whole side or the whole parent. - Rotation, scale and pivot: as Godot's, a control and its children
are turned by
control-rotation, clockwise in radians, and stretched bycontrol-scale, agm:vec2, aboutcontrol-pivot-offset, a point from its top left in its own units: T(position) T(pivot) R S T(-pivot). They are saved with a scene, the pointer reaches a control through them, and a turned control's clip is the box around it. A scale of 0 is taken as 0.00001, as Godot's. A container sets its children's rotation back to 0 and their scale to 1 by 1 as it places them, as Godot'sfit_child_in_rectdoes, so the inspector shows those three of a container's child but does not edit them;res:property-read-only-psays so of an object's property, as Godot's_validate_propertymarks one read only. - Minimum sizes: a control is never laid out smaller than
control-minimum-size, the larger of itscontrol-custom-minimum-widthand-heightand what its content needs, which its class'scontrol-content-minimum-sizemethod says. Where its anchors give it less room, it grows ascontrol-grow-horizontaland-verticalsay. A class whose content changes size callsupdate-minimum-size. - Layout runs before each frame is drawn, after the tree's
processing, and only for what asked for it: a property that places or
sizes a control, a minimum size, a container's children, a theme, or
the window's size. It finds minimum sizes bottom-up and rectangles
top-down, emits
resizedfrom a control whose size changed, and allocates nothing in steady state. It runs in every mode, so the editor shows a game's user interface laid out. - Drawing: a control draws in its
s2d:drawmethod, as any canvas item does, from the pixel nearest its top left, so that its edges are sharp even where its rectangle falls between pixels. It is drawn again when its size, its theme items or a theme changes. - Text painters: a control draws its text with one of pyssel/2d's
painters, as
control-text-paintersays::inherit, the default, as the nearest control or viewport above it says,viewport-text-painterfor a viewport, popups' too, or:rasterwhere none does;:raster, glyphs hinted to the display's pixels, the crispest for small upright text;:sdf, from multi-channel distance fields; or:slug, from the glyphs' curves. The last two stay sharp as a transform scales or turns the text, but are softer than raster text at small sizes. So(setf (control-text-painter hud) :sdf)draws a whole screen's text from distance fields, and one label below it may still say:raster. Text whose fields are still being made is drawn rasterized meanwhile.control-effective-text-paintersays which painter a control draws with, anddraw-control-textdraws a layout as a control draws its text, for controls of one's own: each keeps its text's layout in atext-block, whichmake-text-blockmakes andtext-block-forlays out, again only as the text, its font or its width changes, and into the layout it keeps, so that a short line laid out again allocates nothing.control-text-fontis the font a control draws its text in. - Errors in a control's
control-content-minimum-sizeorplace-childrenstop that control, as an error in a callback stops a node, until code is redefined. An error in itsdrawkeeps what it drew before, as for any canvas item; an error there while it behaves, or in itsgui-input, stops it too, so that it takes no input. A game's control draws while its tree is edited, as every canvas item does, but takes no input then: the pointer passes over it. A control's setters declare their values' types, as an alignment's(member ...)orp2d:color, so a wrong value is refused as atype-error; whatmake-instanceis given is checked by the property metaclass, in words read from the property's type (see Scene Tree).
Getting started
The core
Drawing
Scenes
User interface
Games and the editor
- Playing a Game
- Projects
- The Editor
- The File System Dock
- The Script Screen
- The REPL
- The Debugger
- Lisp Text
- Code Services
- Project Manager
- Undo and Redo
- Exporting
The project