Skip to content

Tiri GUI API

Paul Manias edited this page Apr 9, 2026 · 2 revisions

The GUI API provides shared helpers, theme state, sizing defaults and colour utilities that sit underneath the widget modules in scripts/gui/.

Load it with:

import 'gui'

This page documents the current public surface of scripts/gui.tiri as of 2026-04-09.

Overview

When imported, gui initialises these publicly accessible fields:

Field Description
theme The default theme name, read from user:config/style.cfg when available.
palette The selected palette family name.
paletteTheme Either light or dark.
style Refers to the default theme, initialised from gui.themes[gui.theme]. Prefer gui.getTheme() for the active theme.
fonts Shared font presets used by the GUI modules.
iconThemes Named presets for styling icons.
sizing Sizing recommendations for the layout of widgets and pages.
interface Base interface settings such as default font size and icon size.

Colour Types

The API provides immutable colour tables that are backed by metatable functionality.

RGB colours

Create RGB values in the sRGB colourspace with either:

rgb = gui.srgb(255, 128, 64, 255)
rgb = gui.nrgb(1.0, 0.5, 0.25, 1.0)
  • gui.srgb(R, G, B, A, KV) accepts 8-bit channel values and stores them internally as normalised 0..1 values.
  • gui.nrgb(R, G, B, A, KV) accepts normalised channel values directly.
  • KV is an optional table that is merged into the returned table before the metatable is applied.
  • tostring(rgb) returns an SVG/CSS-style rgb(...) string, including alpha when present.

Available methods:

  • rgb:interpolate(New, Ratio) returns a new RGB colour between rgb and New.
  • rgb:toHSV() converts to an HSV colour table.
  • rgb:brightness() returns the maximum RGB channel value, equivalent to the V component in HSV.
  • rgb:withAlpha(Alpha) returns a copy with alpha multiplied by Alpha.
  • rgb:linearise() converts to linear sRGB.
  • rgb:toHSL() returns { h, s, l }.
  • rgb:luminance() returns WCAG relative luminance in the range 0..1.
  • rgb:toDisplayP3() returns a Display P3 { r, g, b } table.
  • rgb:toOKLab() returns { okl, oka, okb, a }.
  • rgb:toOKLCH() returns { okl, okc, okh, a } and formats as oklch(...) when converted to string.

Note: The sRGB colour values are unclamped in order to support extended colourspaces like Display P3. Clients are expected to clamp values to the 0 - 1.0 range when strict sRGB values are required.

HSV colours

Create HSV values with:

hsv = gui.hsv(210, 0.5, 0.75, 1.0)
  • gui.hsv(H, S, V, A) creates an immutable HSV table.
  • tostring(hsv) returns an hsv(...) string.

Available methods:

  • hsv:interpolate(New, Ratio) returns a new HSV colour between hsv and New.
  • hsv:toRGB() converts to an RGB colour table.

Parsing colour strings

gui.strToRGB(Value) parses a CSS colour string using the vector painter parser and returns an RGB table.

gui.strToRGB('#336699')
gui.strToRGB('rgb(51 102 153 / 0.5)')
gui.strToRGB('oklch(0.653 0.135 242.687)')

Theme And Style State

Themes are layered on top of named palettes.

Palettes

gui.palettes contains named palette families such as ocean, orangeApples, greenland, sunrise and candyfloss.

Each palette family is required to define light and dark variants of the palette.

Each light or dark palette entry must contain these CSS colour fields:

Field Description
bkgd The standard background colour for large amounts of text (documents & code). In a light theme it should be near-white.
inverse The inverse light value of bkgd (or must contrast significantly). Useful for heavy contrast against bkgd, e.g. stroking menu borders.
prime Prime (primary) should have a strong chroma and is used for drawing attention, like for highlighting and selection.
contrast Complements prime and should be of a strongly contrasting hue.
neutral Default background colour for undefined areas (e.g. window background).
mid Separates an area from bkgd without drawing attention. E.g. scrollbar and slider tracks.
text Default colour for text drawn over bkgd.
altText The default colour for text drawn over 'prime' when highlighted or selected. Can be same as 'text'

These palette values are used to build the actual theme tables.

Themes

gui.themes.light and gui.themes.dark are the current resolved themes. Each contains sections used by the widget modules:

  • page
  • widget
  • input
  • window
  • button
  • menubar
  • menu
  • dropdown
  • slider
  • toolbar
  • desktop

All colour fields are fill values, so plain colours, gradients and pattern references are permitted.

Accessors

gui.getTheme()

gui.getTheme(Object)

Returns the active theme table. Themes are tracked at the VectorScene level, so the theme returned depends on the type of Object supplied:

  • If Object is a VectorViewport, the nearest parent scene is used.
  • If Object is a VectorScene, that scene is used directly.
  • If Object is nil, the current global default theme is returned.

Note: To get the theme for a window, access its theme field directly, which is set at window creation time.

gui.setTheme()

gui.setTheme(Object, Theme)

Sets the active theme and returns the resolved theme table.

  • Passing nil for Object changes the global default theme.
  • Passing a viewport or scene applies the theme to that scene state only.
  • If Theme is not already loaded, gui.setTheme() looks for config:themes/<Theme>.tiri.
  • If the custom theme cannot be found, the theme falls back to light.

Fonts, Icons And Sizing

Fonts

gui.fonts provides shared font presets for common GUI roles: default, window, button, filesys, icon, menu, page, titlebar, small, large, input, widget, label. Each preset can define the following field values:

Field Description
face The font family name. Multiple families separated by commas is permitted.
style The font style, e.g. Medium, Italic, Bold, Bold Italic.
size The font size in pixels. May also be a percentage string,

Font sizes may be declared as percentages inside gui.tiri, but after initialisation they are converted to numeric sizes based on gui.interface.fontSize.

gui.getFontHeight()

gui.getFontHeight(Font)

For a given preset from gui.fonts, returns the font's recommended line spacing and height in pixels.

line_spacing, height = gui.getFontHeight(gui.fonts.window)

gui.rgbToIconTheme()

gui.rgbToIconTheme(Value)

Returns either pearl or carbon based on the brightness of the colour supplied. Value may be an RGB table or a string that gui.strToRGB() can parse.

Sizing

The gui.sizing table currently exposes:

gui.sizing = {
   widget = {
      width       = 160, -- Minimum recommended width for buttons, comboboxes, etc.
      gap         = 6, -- Pixel gap between widgets in a layout
      margin      = 6, -- Margins applicable to inner text and icons within widgets
      strokeWidth = 2  -- Standard width of strokes used for widget borders
   },
   page = {
      strokeWidth = 2
   }
}

These are shared defaults used by the widget modules and by helper functions such as gui.separator().

gui.pixel()

gui.pixel(Value)

Converts a size string into pixels. Supported units are: px, in, mm, pt, dp

Examples:

gui.pixel('16px')  -- 16
gui.pixel('12pt')  -- converted using gui.interface.dpi
gui.pixel('24dp')  -- density-independent pixels at 160 DPI baseline

Scene And Vector Helpers

gui.forVector()

gui.forVector(Vector, Function)

Walks a vector tree depth-first, visiting the supplied vector, then its children and siblings. Function is called as:

gui.forVector(viewport, function(Vector)
   print(Vector)
end)

gui.applyFill()

gui.applyFill(Vector, Fill)

Recursively applies Fill to every vector in the tree whose fill is not none. If a vector has a stroke, the stroke is also updated to match.

gui.simpleGradient()

gradient = gui.simpleGradient(Scene, Name, Colours, X1, Y1, X2, Y2, Units, IgnoreClashes)

Creates and registers a linear VectorGradient in Scene.

  • Colours is an array of RGB tables. Each item may also include an explicit offset.
  • Units defaults to boundingbox.
  • If IgnoreClashes is true and a definition with Name already exists, the function returns nil instead of failing.

The result can be used as url(#Name).

Example:

gui.simpleGradient(scene, 'accent_fill', {
   gui.strToRGB('oklch(0.653 0.135 242.687)'),
   gui.strToRGB('oklch(0.631 0.194 29.442)')
}, 0, 0, 1, 0)

gui.createIcon()

Info = gui.createIcon(Scene, Path, Size, Theme, Name)

Builds an icon pattern from an SVG resource and registers it in Scene.

  • Path is an icon path relative to the icons: volume unless it already starts with icons:.
  • Size defaults to 16.
  • Theme may be either a theme name from gui.iconThemes or a custom theme table.
  • Name defaults to the icon path, or to a derived theme/path name when a built-in icon theme name is used.

The returned table contains: name, theme, size, path, fill

Use fill as the vector fill reference:

icon = gui.createIcon(scene, 'items/help', 20, 'pearl')
viewport.new('VectorRectangle', { width=20, height=20, fill=icon.fill })

gui.separator()

Thickness = gui.separator(Viewport, Orientation, Pos, MarginA, MarginB)

Draws a horizontal or vertical separator line using the current window stroke colour.

  • Set Orientation to H (horizontal) or V (vertical).
  • Pos is the horizontal or vertical coordinate. Providing a negative position, including negative zero, is treated as an offset from the far edge.
  • MarginA and MarginB are optional offsets for either side of the separator.
  • Pos, MarginA and MarginB may be numeric values or proportional values such as 100%.
  • The return value is the width of the separator.

Clone this wiki locally