fluo

package module
v0.23.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 0 Imported by: 0

README

fluo

A retained-mode GUI toolkit for Go with its own OpenGL renderer and a classic Windows-2000 look. fluo gives a Go program a themed widget tree — layout, input routing, and data binding — over a thin OpenGL 3.3 backend. No browser engine, no native OS toolkit underneath.

Controls draw themselves from swappable design tokens, so restyling an app is a data change. Each package stands on its own, so you can pull in just the renderer or the whole stack.

Features

  • A complete control set: buttons, checkboxes, radio groups, toggle switches, text boxes, sliders, progress bars, combo boxes, tooltips, list/tree/tab views, expanders, menus, modal dialogs, toasts, and a virtualized data grid. Layout panels (stack, grid, dock, wrap, canvas), a draggable split panel, and a custom title bar for undecorated windows come with it.
  • A text box that scales from a one-line field to a small code editor: word wrap, a line-number gutter, Tab-to-indent with block indent/outdent, word-wise motion, double-click-word and triple-click-line selection, and IME input.
  • Classic Windows-2000 chrome: four-tone raised and sunken bevels, square corners, gradient title bars. The classic themes don't reach for soft effects, but the primitives are there — DrawShadow, DrawBackdropBlur, and an AcrylicSurface control built on them.
  • Light and dark themes, both driven entirely by design tokens. Roll your own by copying one and changing a few colors.
  • One- and two-way data binding between typed properties and controls, plus observable-list collection binding.
  • Virtualized list and data-grid views for large data sets.

Requirements

  • Go 1.23
  • A C compiler — the go-gl/glfw and go-gl/gl bindings use cgo
  • An OpenGL 3.3 core-profile driver

Install

go get github.com/0xdreadnaught/fluo

Quickstart

package main

import (
	"log"

	"github.com/0xdreadnaught/fluo/app"
	"github.com/0xdreadnaught/fluo/controls"
	"github.com/0xdreadnaught/fluo/core"
	"github.com/0xdreadnaught/fluo/render"
	"github.com/0xdreadnaught/fluo/text"

	"golang.org/x/image/font/gofont/goregular"
)

func main() {
	font, _ := text.Load(goregular.TTF)
	root := controls.NewTextBlock(text.NewFace(font, 16), "Hello, fluo!")

	log.Fatal(app.Run(app.Config{Title: "hello", Width: 320, Height: 200}, func(c *app.Ctx) {
		c.Input.SetRoot(root)
		core.MeasureWidget(root, c.Size)
		core.ArrangeWidget(root, render.Rect{W: c.Size.W, H: c.Size.H})
		core.RenderWidget(root, c.R)
	}))
}

examples/counter shows the same thing with a proper one-time root guard and a data-bound label.

Architecture

fluo is layered bottom to top; each layer depends only on the ones below it.

Package Role
render, render/gl Renderer interface and geometry, implemented on OpenGL 3.3
text Font loading and glyph rasterization
core Widget/Element layout engine (Measure/Arrange/Render) and Property[T]
input Hit-testing, event bubbling, capture, focus
theme Color, metric, and typography tokens (Light(), Dark())
controls The built-in widget set
bind One- and two-way binding
anim, timers Tween animation and the frame-tick timer service
app glfw window host and embeddable surface

Examples

Run any of them with go run, e.g. go run ./cmd/fluo-gallery.

Documentation

go doc ./<package> covers each package. Longer guides — controls, data binding, theming, and the renderer — live in docs/wiki.

Status

v0.15.1. Every layer is implemented, tested (headless layout and binding tests plus GL golden images that auto-skip without a GPU), and exercised together by the gallery. Known gaps:

  • The custom title bar covers Windows and Linux. There's no native macOS integration.
  • No accessibility (screen-reader) hooks yet.

See CHANGELOG.md and ROADMAP.md for the full history.

License

MIT

Documentation

Overview

Package fluo is the module root for github.com/0xdreadnaught/fluo, a retained-mode, classic Windows-styled GUI toolkit for OpenGL apps in Go. It declares no exported symbols of its own — every usable package lives in a subdirectory (render, text, core, input, theme, controls, bind, anim, timers, app) — this file exists solely to give `go doc .`/pkg.go.dev a landing-page overview, quickstart, and architecture map for the module as a whole.

Quickstart

A minimal program: load a font, build one widget, and drive it from app.Run's per-frame callback.

font, _ := text.Load(goregular.TTF)
root := controls.NewTextBlock(text.NewFace(font, 16), "Hello, fluo!")

log.Fatal(app.Run(app.Config{Title: "hello", Width: 320, Height: 200}, func(c *app.Ctx) {
	c.Input.SetRoot(root)
	core.MeasureWidget(root, c.Size)
	core.ArrangeWidget(root, render.Rect{W: c.Size.W, H: c.Size.H})
	core.RenderWidget(root, c.R)
}))

See examples/counter, examples/form, and examples/todo for complete, runnable programs, and cmd/fluo-gallery for every control composed together.

Architecture

fluo is layered bottom to top; each layer only depends on the ones below it:

render    — the Renderer interface and geometry primitives (Color/
            Point/Size/Rect); render/gl implements it on OpenGL 3.3.
text      — font loading, grayscale glyph rasterization into a
            coverage atlas, and single-line layout, on top of render.
core      — the Widget/Element layout engine (Measure/Arrange/Render)
            and the reactive Property[T].
input     — hit-testing, event bubbling, capture, and focus over a
            core.Widget tree.
theme     — the color/metric/typography token model (Light/Dark).
controls  — the built-in widget set, styled from theme and wired to
            input.
bind      — one-way/two-way binding between core.Property[T]/
            bind.List[T] and controls.
anim/     — easing/Tween animation and the frame-tick timer service
timers      controls use for caret blink, tooltip dwell, and
            cross-fades.
app       — Run/Surface, the glfw window host (or embeddable surface)
            that ties every layer above together into a running
            program.

go doc on any of the above (e.g. `go doc ./controls`) gives a one-paragraph summary of its role and key types.

Directories

Path Synopsis
Package anim provides easing functions and a frame-driven Tween that interpolates a normalized progress value 0→1 over a duration, using a timers.Queue as its clock.
Package anim provides easing functions and a frame-driven Tween that interpolates a normalized progress value 0→1 over a duration, using a timers.Queue as its clock.
Package app provides fluo's desktop window host: Run opens a GLFW window with an OpenGL 3.3 core context, wires up render/gl's Renderer, and drives a frame(*Ctx) callback every vsync until the window closes.
Package app provides fluo's desktop window host: Run opens a GLFW window with an OpenGL 3.3 core context, wires up render/gl's Renderer, and drives a frame(*Ctx) callback every vsync until the window closes.
Package bind connects core.Property[T] values to controls: one-way binding pushes a property's value into a control on every change, and two-way binding additionally OWNS a control's OnChanged slot so user edits flow back into the property.
Package bind connects core.Property[T] values to controls: one-way binding pushes a property's value into a control on every change, and two-way binding additionally OWNS a control's OnChanged slot so user edits flow back into the property.
cmd
fluo-demo command
Command fluo-demo is a minimal demo host exercising every fluo primitive: rounded rects, stroke, shadow, SDF text, and a manually hand-rolled hover/press-reactive button (this becomes controls.Button in Phase 5).
Command fluo-demo is a minimal demo host exercising every fluo primitive: rounded rects, stroke, shadow, SDF text, and a manually hand-rolled hover/press-reactive button (this becomes controls.Button in Phase 5).
fluo-editor command
Command fluo-editor is a standalone code-editor demo built on fluo's multi-line TextBox: a monospace editor with a line-number gutter, word-wrap OFF (long lines scroll horizontally), tab-to-indent, mouse-wheel scrolling, and a live Ln/Col status.
Command fluo-editor is a standalone code-editor demo built on fluo's multi-line TextBox: a monospace editor with a line-number gutter, word-wrap OFF (long lines scroll horizontally), tab-to-indent, mouse-wheel scrolling, and a live Ln/Col status.
fluo-gallery command
Command fluo-gallery is the widget gallery: it grows a page per control as phases land.
Command fluo-gallery is the widget gallery: it grows a page per control as phases land.
Package controls provides fluo's built-in widget set, all styled from theme.Active() rather than hard-coded values.
Package controls provides fluo's built-in widget set, all styled from theme.Active() rather than hard-coded values.
Package core is fluo's layout engine and widget foundation.
Package core is fluo's layout engine and widget foundation.
examples
counter command
Command counter is fluo's smallest example: a Button increments a core.Property[int], and a TextBlock shows the current count via bind.OneWay.
Command counter is fluo's smallest example: a Button increments a core.Property[int], and a TextBlock shows the current count via bind.OneWay.
form command
Command form demonstrates binding several controls to one small model: a TextBox, CheckBox, and Slider each two-way bound to a field of model, and a TextBlock one-way bound to all three, echoing the combined state on every change.
Command form demonstrates binding several controls to one small model: a TextBox, CheckBox, and Slider each two-way bound to a field of model, and a TextBlock one-way bound to all three, echoing the combined state on every change.
todo command
Command todo demonstrates list binding: a TextBox + "Add" Button append to a bind.List[string], a ListView renders it, and a TextBlock tracks the item count — all driven off the same List, with no manual widget rebuilding.
Command todo demonstrates list binding: a TextBox + "Add" Button append to a bind.List[string], a ListView renders it, and a TextBlock tracks the item count — all driven off the same List, with no manual widget rebuilding.
Package input turns raw pointer/keyboard/wheel events into dispatch against a core.Widget tree.
Package input turns raw pointer/keyboard/wheel events into dispatch against a core.Widget tree.
Package render defines fluo's abstract 2D drawing surface: the Renderer interface (FillRect/FillRoundedRect/StrokeRoundedRect/DrawShadow/ DrawBackdropBlur/DrawQuad/DrawGlyphs plus texture management and clip push/pop) and the plain-data geometry types every other package builds on — Point, Size, Rect (with Thickness-based Inset), and Color (0..1 float components, with RGB/RGBA byte-based constructors).
Package render defines fluo's abstract 2D drawing surface: the Renderer interface (FillRect/FillRoundedRect/StrokeRoundedRect/DrawShadow/ DrawBackdropBlur/DrawQuad/DrawGlyphs plus texture management and clip push/pop) and the plain-data geometry types every other package builds on — Point, Size, Rect (with Thickness-based Inset), and Color (0..1 float components, with RGB/RGBA byte-based constructors).
gl
Package gl implements render.Renderer on top of OpenGL 3.3 core.
Package gl implements render.Renderer on top of OpenGL 3.3 core.
gl/gltest
Package gltest is a golden-image test harness for OpenGL rendering code.
Package gltest is a golden-image test harness for OpenGL rendering code.
Package text provides pure-Go font loading, glyph rasterization, and single-line text layout, built on golang.org/x/image/font/sfnt.
Package text provides pure-Go font loading, glyph rasterization, and single-line text layout, built on golang.org/x/image/font/sfnt.
Package theme holds fluo's classic Windows-2000-inspired design tokens.
Package theme holds fluo's classic Windows-2000-inspired design tokens.
Package timers provides a frame-driven timer service: Queue holds a set of pending Timer callbacks, and the host calls Advance(now) once per frame to fire whichever are due, in due-time order.
Package timers provides a frame-driven timer service: Queue holds a set of pending Timer callbacks, and the host calls Advance(now) once per frame to fire whichever are due, in due-time order.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL