DatumHueEnterprise v0.0.24datumhue.com
Contents

Theme and density

Color your widgets from the theme, pin a built-in theme or one of your own, and size your controls for a mouse or a finger.

Colors and sizes from the theme

A theme maps named tokens to colors and sizes. theme.token returns a color that follows the theme: give it to a widget and the widget repaints when the theme changes. theme.metric reads a size, such as a font size or a gap, as your app's theme and density set it. The Theme format lists every token.

Write a theme file

A theme file is KDL: a colors block of tokens and 0xRRGGBB colors, and a metrics block of sizes. Set only the tokens you change; those you leave out take the built-in dark theme's values.

themes/sunset.kdlkdl
colors {
    panel_background 0x3b2a3a
    surface_sunken 0x2a1e2a
    text_primary 0xf6e3d2
    text_secondary 0xd9b8a8
    accent_primary 0xf08a4b
    button_normal 0x553a52
    button_text 0xf6e3d2
}
metrics {
    border_radius 12
}

A theme can also define shader materials in a shaders block, and give them to kinds of widget in a widget_shaders block. A widget takes its surface from its own material, else from its theme's material for its kind, else from its background color. The Theme format describes both blocks.

Pin a theme

This program offers three themes, the built-in light and dark ones and the file above, and a switch for touch-sized controls.

theme.lualua
local theme = datumhue.theme
local ui = datumhue.ui

local themes = {
    theme.default_light(),
    theme.default_dark(),
    datumhue.args.dirs.themes:read("sunset.kdl"):theme(),
}
theme.pin(themes[3])

local panel = ui.root:panel({ width = 360, gap = 12 })
panel:label({ text = "Appearance", font_size = "1.5rem" })
panel:radio_group({
    options = { "Light", "Dark", "Sunset" },
    selected = 3,
    on_change = function(i)
        theme.pin(themes[i])
    end,
})
panel:checkbox({
    label = "Larger controls for touch",
    on_change = function(on)
        theme.density = on and "touch" or "standard"
    end,
})
local done = panel:button({ text = "Done" })
done.color = theme.token("accent_primary")
done:set_text_color(theme.token("panel_background"))

In this example: datumhue.theme datumhue.ui datumhue.theme.default_light datumhue.theme.default_dark datumhue.args Dir:read Bytes:theme datumhue.theme.pin datumhue.ui.root UiElement:panel UiElement:label UiElement:radio_group UiElement:checkbox datumhue.theme.density UiElement:button UiElement.color datumhue.theme.token UiElement:set_text_color

Run it with the themes folder granted to it:

sh
$ datumhue run theme.lua --dir themes:themes
  • Bytes:theme turns the file into a Theme, which theme.pin takes.
  • theme.pin applies a theme to your app until you pin another, or call theme.unpin to follow the theme of the app above yours again.
  • Done takes its fill and its label color from tokens, so it follows each theme you pick. Its border takes its fill's color. A button that keeps the theme's fill draws its border in button_border instead, so it stands out from the surface under it.

An app that pins no theme of its own follows the nearest app above it that does, and changes when that app's theme changes. A window manager can pin a theme on an app it manages, with theme.pin(dark, app). theme.current() returns the theme in effect.

The theme event tells your app the theme in effect as you subscribe, then each time it changes, by your own pin or by an app above yours. Widgets colored from tokens repaint on their own; listen for the event to redo what you colored from the theme yourself, such as a drawing. A theme file you read again is the same theme, even when the file changed: pinning it repaints your widgets but does not call the event's callback, so redo your drawing after that pin.

follow.lualua
local theme = datumhue.theme

datumhue.events.on("theme", function(e)
    print(e.theme.name)
end)
datumhue.time.after(0.2, function()
    theme.pin(theme.default_dark())
end)

In this example: datumhue.theme datumhue.events.on datumhue.time.after datumhue.theme.pin datumhue.theme.default_dark

  • The callback runs once right away, with the light theme, then once more after the pin, with the dark one.
  • e.theme is the handle theme.current() returns, so == compares it with a theme you hold.
  • Several pins in one frame tell the callback once, with the last.

Size controls for a mouse or a finger

Density sizes your app's controls for its pointer: "standard" for a mouse or a trackpad, and "touch" for fingers, with larger text, spacing and controls, and buttons at least 48 UI px tall. Set theme.density, and your widgets resize in place. Apps you start follow your density unless they set their own, as with themes. A workstation opened in a browser on a phone or a tablet starts at "touch".

  • The density event tells your app when its density changes, by its own write or by an app above it, so a layout that depends on it can rebuild.
  • Text sized in rem keeps its size at every density.
  • A metric your theme sets wins over the density's.
  • What you set on an element yourself stays yours through every theme and density change: sizes, padding, borders, corner rounding, gaps, colors and fonts, whether set when you make it or later with UiElement:update.
  • A scroll bar lies over the edge of the element it scrolls, on top of the element's padding and content. theme.metric("scrollbar_width") is how much of that edge it takes: pad the edge at least that much to keep what the element holds clear of the bar, and update that padding on the theme and density events, since a theme can set the metric too.

See also

Reference used on this page: datumhue.theme datumhue.ui datumhue.theme.default_light datumhue.theme.default_dark datumhue.args Dir:read Bytes:theme datumhue.theme.pin datumhue.ui.root UiElement:panel UiElement:label UiElement:radio_group UiElement:checkbox datumhue.theme.density UiElement:button UiElement.color datumhue.theme.token UiElement:set_text_color datumhue.events.on datumhue.time.after datumhue.theme.metric datumhue.theme.unpin datumhue.theme.current UiElement:update

datumhue.com

(c) 2026 Shuusei AB. Quote excerpts of this manual, with attribution to DatumHue, in your own documentation, tutorials, course materials, reviews, and other writing or video. Republishing it in whole or in substantial part needs written permission: support@datumhue.com.

Victor Mono is licensed under the SIL Open Font License 1.1
Copyright (c) 2024, Rune Bjørnerås (https://github.com/rubjo)

This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL


-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------

PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.

The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.

DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.

"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).

"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).

"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.

"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.

PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:

1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.

2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.

3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.

4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.

5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.

TERMINATION
This license becomes null and void if any of the above conditions are
not met.

DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Try

    ↑↓ selectEnter openTab filter

    Settings

    Theme
    Text
    Print

    Keyboard shortcuts

    / or Ctrl KSearch
    ↑ ↓ EnterPick a result
    TabNext result filter
    j kNext or previous entry
    [ ]Previous or next page
    yCopy a link to the current entry
    ?These shortcuts
    EscClose

    On this page