Help us shape the future of Go! Take the 2026 Go Developer Survey

platinum

package module
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 19 Imported by: 0

README

mygo-platinum

English | 简体中文

verify Go Reference

A set of controls for MyGo's native UI in the style of the gray, beveled late-1990s "Platinum" desktop look — drawn pixel by pixel on the GPU, with no web view — and a "classic desktop" example that puts them to work. Try the desktop in the browser at mygo-platinum.firede.com.

The gallery of controls

More: page 2 (bevel buttons, toolbar, fields, status, rich text, pop-up windows), page 3 (lists, tables, layout), page 4 (dates, colors, sheet, ruler), page 5 (documents and navigation).

A tribute in style only. This project is not affiliated with, endorsed by or connected to Apple Inc. It uses none of Apple's fonts, icons, images or trademarks: its Latin bitmap faces, its icons and every picture in it were drawn for it, its East Asian glyphs come from the open Fusion Pixel Font, and its design specification (docs/spec.md) is written from scratch.

[!WARNING] An early, personal project. It was made for its author's own use and is shared as it is, with no promise of support. Its API may change in any 0.x release, and it is built on MyGo v0.7.1, itself young and changing. Pin a version, and expect to adapt.

What is in it

Control Function
Push button, default and cancel buttons Button
Check box (with a mixed state) Checkbox
Radio button and radio group Radio, RadioGroup
Slider (with tick marks) Slider
Progress bar, determinate and indeterminate ProgressBar
Disclosure triangle Disclosure
Group box and separator GroupBox, Separator
Tab control TabControl
Pop-up menu PopupMenu
Text field, password field, text area TextField, TextArea
List box (with icons, dimmed rows) ListBox
Scroll bar ScrollBar
Window frame: striped title bar, close, zoom and collapse boxes, resize corner, path menu Window
Menu bar, menus, submenus, keyboard equivalents MenuBar
Alert box, movable modal dialog Alert, Dialog
Text in the bitmap faces Label, TextIn, Paragraph
Bevel button, icon button, toggle, segmented control BevelButton, IconButton, Segmented
Toolbar with an overflow menu Toolbar
Little arrows, number field, search field Stepper, NumberField, SearchField
Chasing arrows, placard, window header, badge, tag, image well ChasingArrows, Placard, WindowHeader, Badge, Tag, ImageWell
Help balloon, context menu Balloon, ContextMenu
Tree view, sortable table, icon view TreeView, Table, IconView
Split, scroll view, utility window Split, SplitPercent, ScrollView, Window with Utility
Calendar, date picker, time field Calendar, DatePicker, TimeField
Combo box, color well and color picker Combobox, ColorWell
Spreadsheet sheet with formulas, formula bar Sheet, FormulaBar
Find and replace dialog, ruler FindReplace, Find, ReplaceAll, Ruler
Column view, document tabs, font picker, page setup ColumnView, DocumentTabs, FontPicker, PageSetup
Progress dialog, banner, toasts, empty state ProgressDialog, Banner, Toasts, EmptyState
Path pop-up, breadcrumb, pagination, card, status bar PathPopup, Breadcrumbs, Pagination, Card, StatusBar
Rich text: styles, four sizes, paragraph alignment; format bar RichTextArea, FormatBar, SizeMenu
Pop-up window docked at the bottom edge PopupWindow, SpringOpen
Open and save dialogs OpenDialog, SaveDialog
Zoom rectangles of a window opening ZoomRects
Mermaid diagram, laid out by limu diagram.View

Every control has its states (pressed, disabled, focused, default, checked, selected, and inactive in a window in the background), is operated from the keyboard, describes itself to screen readers through MyGo's accessibility support, and has a godoc example that compiles and runs. Those with a look of their own are drawn with an exported Draw… function too, for controls of your own that look like them.

The diagram package draws Mermaid diagrams in the look. limu lays a diagram out on whole pixels with the library's bitmap faces, and the package draws its boxes as the controls are drawn and its lines a pixel at a time.

sc, err := limu.Layout(src, diagram.Layout())
if err != nil {
	return err
}
diagram.View(c, sc)

Controls MyGo has too go by MyGo's names and take what MyGo's take — Button, Checkbox, Radio, Slider, Stepper, Segmented, Split, SplitPercent, TextArea, SearchField, Combobox, ColorWell, Calendar, Badge, Breadcrumbs, Table — and report what the user did as they do (Clicked, Changed, Submitted; OnChange on their elements). The others go by the names of the period:

This library MyGo's own
PopupMenu ui.Select
TabControl ui.Tabs
ListBox, TreeView ui.List, ui.Tree
IconView ui.GridView
TextField, NumberField, TimeField, DatePicker ui.TextInput, ui.NumberInput, ui.TimeInput, ui.DateInput
ProgressBar, ChasingArrows ui.Progress, ui.Spinner
GroupBox, Separator, Disclosure ui.Fieldset, ui.Divider, ui.Collapsible
Alert, Dialog ui.AlertDialog, ui.Modal
Balloon, ContextMenu Element.Tooltip, Element.ContextMenu
Toasts draws c.Toast in the look

Using it

It needs Go 1.27.3 or later and MyGo v0.7.1.

go get github.com/firede/mygo-platinum@v0.2.2
import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func (app *state) view(c *ui.Context) {
	pt.Use(c, app.theme) // nil for the default: gray with a lavender accent
	ui.Column(c).Fill().Padding(12).Gap(8).Children(func() {
		pt.Checkbox(c, &app.sound, "Play alert sounds")
		pt.Slider(c, &app.volume, 0, 100).Label("Volume")
		pt.PopupMenu(c, &app.sort, "Sort by:", []string{"Name", "Date", "Size"})
		ui.Row(c).Gap(10).Children(func() {
			pt.Button(c, "Cancel").Cancel()
			if pt.Button(c, "OK").Default().Clicked() {
				app.apply()
			}
		})
	})
}

Controls that take input return a *…Widget whose methods set them up (Default, Disabled, Width, Label…) and report what the user did (Clicked, Changed, Submitted, Activated); call the setters before the queries. Values are bound by pointer, as MyGo's own widgets bind them. Static controls (ProgressBar, GroupBox, Separator) return the ui.Element to lay out.

Six accents ship with it — Lavender, Graphite, Harbor, Moss, Ember and Orchid — set with Theme.Accent.

The classic desktop

The desktop example

examples/desktop is a whole desktop in one window: a menu bar with a clock and an application menu, icons that open and that drop on the Wastebasket, windows that move, resize, roll up, zoom and dock at the bottom as pop-up windows, a browser of its own little disk (as icons, buttons, a list or columns, with spring-loaded folders, Option-drag copies, Get Info, Duplicate, Put Away and a path menu in each window's title) with Find File, and applications built from the controls — Calculator, Jotter (a note pad), Scribe (a rich text editor with styles, sizes, a ruler, find and replace, and the standard open and save dialogs), Ledger (a spreadsheet), Puzzle, Alarm Clock, Controls (every control of the library, live, by the name of its function), and the Appearance, Date & Time, Language, Sound and Mouse control panels. All of its names and pictures are its own.

It speaks English, Simplified and Traditional Chinese, Japanese and Korean, the language of the system or the one its Language control panel chooses: its words, dates and times, and the forms of East Asian characters, drawn with the faces of platinum-fonts' cjk12. Its catalogs are in examples/desktop/locales.

Running the examples

go run ./examples/gallery                    # every control, in a window
go run ./examples/gallery -png gallery.png   # the same, rendered without one
go run ./examples/desktop                    # the classic desktop
go run ./examples/desktop -png desk.png -lang ja   # a picture of it, in Japanese
go run ./examples/diagrams                   # every type of diagram, in the look

./scripts/site.sh builds the desktop's web page, compiled to WebAssembly, into site/dist; ./scripts/deploy.sh builds it for its address and deploys it to Cloudflare, as wrangler.jsonc says, which publishing a release on GitHub does too.

Testing

./scripts/verify.sh

runs go vet, gofmt, the build, and every test: snapshots of every control in every state compared pixel by pixel with the golden images in testdata/golden (a test finds the package's controls and fails if one has no snapshots or no example of its own), examples that compile and run, checks of sizes and colors against docs/spec.md, interaction tests driven through MyGo's headless tester, audits of the keyboard focus, random input thrown at the examples, and smoke tests of the examples; then all the tests again at another moment and in another time zone, which must pass alike. Its last line is PASSED x/y.

  • After a deliberate change to how a control looks, look at the new image, then go test -update (in the package, or in ./examples/desktop) writes it.
  • After adding or renaming a test, go run ./internal/verify -write-manifest updates scripts/checks.txt, the list of checks verify.sh expects.
  • The gallery's golden images are in examples/gallery/testdata/golden; the pictures in docs are rendered at twice the scale, as go run ./examples/gallery -png docs/gallery-2@2x.png -scale 2 -page 2 and go run ./examples/desktop -png docs/desktop@2x.png -scale 2 (-lang zh-Hans for docs/desktop-zh-hans@2x.png).
  • After changing a catalog of examples/desktop/locales, go run github.com/egoist/mygo/cmd/mygo generate in examples/desktop writes its Go functions anew.

Notes

  • Pixels are DIPs: the controls are crisp at any whole scale of the display, and drawn blocks of 2×2 pixels on a 2× display.

  • Text is drawn with the bitmap faces of platinum-fonts: Platinum Sans Bold (SystemFont) and Platinum Sans Small (AppFont), which cover ASCII, common punctuation, every letter of Latin-1 (accented letters, Æ, Ð, Ø, Þ, Œ, ß) and the Central European letters most used (Ł, Ś, Č, Ő, Ą…).

  • East Asian text is drawn with a 12px face of platinum-fonts' cjk12, in the forms of the app's language, once the app chooses one:

    import "github.com/firede/platinum-fonts/cjk12/zhhans"
    
    pt.SetEastAsian(zhhans.Regular, zhhans.Bold)
    

    Characters no face draws — East Asian ones before that call, Greek, other accented letters — draw in the system's font on the same baseline, so any text can be typed.

  • The controls' own words — buttons, dialogs, labels and the names screen readers read — come in English, Simplified and Traditional Chinese, Japanese and Korean, in the language of the window; an app changes them with keys platinum.<key> of its catalogs. Calendars, date pickers and time fields write dates as the language does, and start weeks and count hours as the user's regional formats do, as MyGo's own controls do.

  • Every focus stop has a name for screen readers, Tab goes round every page and window without being trapped, and news the focus does not bring (a banner, what a search found) is read out; tests check all three.

License

MIT — see LICENSE. The faces come from platinum-fonts, whose glyph data is under the SIL Open Font License 1.1.

Documentation

Overview

Package platinum is a set of controls for MyGo's native UI in the manner of the late-1990s gray "Platinum" desktop look: beveled gray buttons, striped title bars, pop-up menus and the rest, drawn pixel by pixel on the GPU with no web view.

It is a tribute in style only. Its fonts, icons and drawings are its own, and it is not affiliated with or endorsed by Apple Inc.

Every control is drawn on a grid of whole DIPs, so it is crisp at any whole scale of the display, and its text is drawn with the bitmap faces of platinum-fonts (see Font, and SetEastAsian for East Asian scripts). Call Use at the top of a view to give the window its theme, as the package's example shows; every control has an example of its own.

Controls are built on MyGo's widget bases, so they take the keyboard focus, answer the keys their kind does and describe themselves to assistive technology. docs/spec.md gives the measurements and colors they are drawn with.

Conventions

Controls bind what they edit by pointer, as MyGo's widgets do: Checkbox(c, &app.on, …), ListBox(c, &app.chosen, …). Bind the app's state; a variable of the view works too, as the controls carry what the pointer does between frames.

Controls that take input return a *…Widget. Its setters (Default, Disabled, Width, Label, …) return it, to chain, and come first; its queries (Clicked, Changed, Submitted, Activated, …) report what the user did since the last frame, and come after. Element returns the control's ui.Element, for layout. Controls that only show something (ProgressBar, GroupBox, Separator, Placard, Badge, …) return their ui.Element. Dialogs and alerts show while a bool they are given is true, and return what the user chose.

Each control with a look of its own (not the dialogs made of others, as the file dialogs) has a Draw… function too, drawing it in a given state with a Pen, for controls of your own that look like it. A Pen draws on whole pixels of the grid; Font measures and draws the library's two faces.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{}
	render(func(c *ui.Context) {
		pt.Use(c, a.theme) // nil is the default theme
		ui.Column(c).Fill().Padding(12).Gap(8).Children(func() {
			pt.Checkbox(c, &a.sound, "Play sounds")
			if pt.Button(c, "OK").Default().Clicked() {
				fmt.Println("OK")
			}
		})
	})
}

Index

Examples

Constants

View Source
const (
	AlertIconSize = 32  // the icon of an alert
	AlertWidth    = 340 // the width of an alert box

)

Alert metrics, from docs/spec.md.

View Source
const (
	ButtonHeight   = 20 // the height of a push button
	ButtonMinWidth = 58 // the narrowest a push button gets
	ButtonPadding  = 12 // the room on each side of its label, at least
	DefaultRing    = 4  // how far a default button's ring reaches outside it
)

Push button metrics, from docs/spec.md.

View Source
const (
	CalendarCellW = 22 // the width of a day of a calendar
	CalendarCellH = 16 // its height

)

Calendar metrics, from docs/spec.md.

View Source
const (
	CalendarWidth  = 7*CalendarCellW + 2*calendarPad + 4
	CalendarHeight = calendarHeader + calendarDays + 6*CalendarCellH + calendarPad + 4
)

CalendarWidth and CalendarHeight are the size of a calendar.

View Source
const (
	CheckSize   = 12 // the box of a check box, and the circle of a radio button
	CheckHeight = 16 // the height of a check box or radio button with its label
	CheckGap    = 5  // between the box and the label
)

Check box and radio button metrics, from docs/spec.md.

View Source
const (
	ColorWellW = 44 // the width of a color well
	ColorWellH = 22 // its height

)

Color well metrics, from docs/spec.md.

View Source
const (
	FileListW   = 220
	FileListH   = 150
	FileButtonW = 100
)

The size of a file dialog's list, and the width of its buttons.

View Source
const (
	IconCellW = 84 // the width of an icon view's cell
	IconCellH = 64 // its height
)

Icon view metrics, from docs/spec.md.

View Source
const (
	SplitterWidth = 7  // the width of a splitter's divider
	SplitMin      = 40 // the least either pane keeps

)

Splitter metrics, from docs/spec.md.

View Source
const (
	MenuBarHeight       = 20 // the height of the menu bar
	MenuTitlePadding    = 9  // the room on each side of a menu's title
	MenuItemHeight      = 18 // the height of a menu item
	MenuSeparatorHeight = 8  // the height of a separator between items

)

Menu metrics, from docs/spec.md.

View Source
const (
	PopupHeight   = 20 // the height of a pop-up menu button
	PopupArrowBox = 18 // the width of the box holding its arrow

)

Pop-up menu metrics, from docs/spec.md.

View Source
const (
	ScrollBarWidth = 16 // the width of a vertical scroll bar, and the height of a horizontal one
	ScrollMinThumb = 16 // the shortest a thumb gets

)

Scroll bar metrics, from docs/spec.md.

View Source
const (
	SheetCellW    = 72 // the width of a column of a sheet
	SheetCellH    = 18 // the height of a row
	SheetRowHeadW = 32 // the width of the row numbers
)

Sheet metrics, from docs/spec.md.

View Source
const (
	SliderHeight   = 18 // the height of a horizontal slider
	SliderThumbW   = 11 // the width of its thumb
	SliderThumbH   = 16 // the height of its thumb
	SliderTrackH   = 6  // the height of its track
	SliderMinWidth = 60 // the narrowest a slider gets

)

Slider metrics, from docs/spec.md.

View Source
const (
	ChasingArrowsSize = 16 // the box of the chasing arrows
	PlacardHeight     = 16 // the height of a placard
	BadgeHeight       = 14 // the height of a badge or tag

)

Status control metrics, from docs/spec.md.

View Source
const (
	StepperWidth  = 13 // the width of the little arrows
	StepperHeight = 23 // their height
)

Little arrows metrics, from docs/spec.md.

View Source
const (
	TableHeaderHeight = 18 // the height of a table's column headers
	TableMinColumn    = 30 // the narrowest a column gets

)

Table metrics, from docs/spec.md.

View Source
const (
	TabHeight  = 22 // the height of an unselected tab
	TabRaise   = 2  // how much taller the selected tab is
	TabPadding = 12 // the room on each side of a tab's label

)

Tab control metrics, from docs/spec.md.

View Source
const (
	TextFieldHeight = 22 // the height of a text field

	TextLineHeight = 14 // the height of a line of a text area
)

Text field metrics, from docs/spec.md.

View Source
const (
	TitleBarHeight = 19 // the height of a window's title bar, its outline included
	FrameWidth     = 6  // the frame at a window's sides and bottom, outline included
	TitleBoxSize   = 11 // the close, zoom and collapse boxes
	GrowBoxSize    = 15 // the resize corner

)

Window frame metrics, from docs/spec.md.

View Source
const (
	UtilityBarHeight = 13 // the height of a utility window's title bar
	UtilityBoxSize   = 9  // its close box

)

Utility window metrics, from docs/spec.md.

View Source
const BannerHeight = 30

BannerHeight is the height of a banner.

View Source
const (
	BevelHeight = 22 // the height of a bevel button with a label alone

)

Bevel button metrics, from docs/spec.md.

View Source
const ColumnViewWidth = 140 // the width of each column of a column view

Column view metrics, from docs/spec.md.

View Source
const DisclosureSize = 12

DisclosureSize is the box of a disclosure triangle.

View Source
const FlashDuration = 130 * time.Millisecond

FlashDuration is how long a button shows pressed when the keyboard presses it.

View Source
const (
	GroupPadding = 12 // the room inside a group box around its content

)

Group box metrics, from docs/spec.md.

View Source
const Indeterminate = -1

Indeterminate is the value ProgressBar takes for work of unknown length.

View Source
const (
	ListRowHeight = 16 // the height of a row of a list box

)

List box metrics, from docs/spec.md.

View Source
const MaxScale = 4

MaxScale is the largest scale of rich text, as Scaled sets it.

View Source
const MenuFlash = 150 * time.Millisecond

MenuFlash is how long a chosen menu item blinks before its action runs, as the classic menus confirm a choice.

View Source
const (
	PopupTabHeight = 20 // the tab of a pop-up window, its outline included

)

Pop-up window metrics, from docs/spec.md.

View Source
const (
	ProgressHeight = 14 // the height of a progress bar

)

Progress bar metrics, from docs/spec.md.

View Source
const (
	RulerHeight = 22 // the height of a ruler

)

Ruler metrics, from docs/spec.md.

View Source
const SpringDelay = 500 * time.Millisecond

SpringDelay is how long a drag rests on a closed pop-up window's tab before SpringOpen opens it.

View Source
const (
	ToolbarHeight = 32 // the height of a toolbar

)
View Source
const (
	TreeIndent = 16 // how far each level of a tree view is indented

)

Tree view metrics, from docs/spec.md.

View Source
const WindowHeaderHeight = 18

WindowHeaderHeight is the height of a window header.

View Source
const ZoomDuration = 180 * time.Millisecond

ZoomDuration is how long zoom rectangles take to go from where a window comes from to where it opens.

Variables

View Source
var (
	IconBold = []string{
		"................",
		"................",
		"..#########.....",
		"...###...###....",
		"...###....###...",
		"...###....###...",
		"...###...###....",
		"...########.....",
		"...###....###...",
		"...###.....###..",
		"...###.....###..",
		"...###....###...",
		"..##########....",
		"................",
		"................",
		"................",
	}
	IconItalic = []string{
		"................",
		"................",
		"......#######...",
		".........##.....",
		".........##.....",
		"........##......",
		"........##......",
		".......##.......",
		".......##.......",
		"......##........",
		"......##........",
		".....##.........",
		"...#######......",
		"................",
		"................",
		"................",
	}
	IconUnderline = []string{
		"................",
		"................",
		"..####....####..",
		"...##......##...",
		"...##......##...",
		"...##......##...",
		"...##......##...",
		"...##......##...",
		"...##......##...",
		"....##....##....",
		".....######.....",
		"................",
		"..############..",
		"................",
		"................",
		"................",
	}
	IconAlign = [3][]string{
		{"................", "................", "..############..", "................", "..########......", "................", "..############..", "................", "..########......", "................", "..############..", "................", "..########......", "................", "................", "................"},
		{"................", "................", "..############..", "................", "....########....", "................", "..############..", "................", "....########....", "................", "..############..", "................", "....########....", "................", "................", "................"},
		{"................", "................", "..############..", "................", "......########..", "................", "..############..", "................", "......########..", "................", "..############..", "................", "......########..", "................", "................", "................"},
	}
)

The 16×16 icons of the format bar, as rows for DrawIcon, for toolbars of one's own.

View Source
var (
	White  = ui.RGB(0xFF, 0xFF, 0xFF)
	Gray1  = ui.RGB(0xEE, 0xEE, 0xEE) // inner highlights, menus
	Gray2  = ui.RGB(0xDD, 0xDD, 0xDD) // the face of windows and controls
	Gray3  = ui.RGB(0xCC, 0xCC, 0xCC) // pressed faces of small controls
	Gray4  = ui.RGB(0xBB, 0xBB, 0xBB) // tracks of scroll bars and sliders
	Gray5  = ui.RGB(0xAA, 0xAA, 0xAA) // inner shadows
	Gray6  = ui.RGB(0x99, 0x99, 0x99) // disabled frames
	Gray7  = ui.RGB(0x88, 0x88, 0x88) // outer shadows
	Gray8  = ui.RGB(0x77, 0x77, 0x77) // disabled text
	Gray9  = ui.RGB(0x66, 0x66, 0x66) // pressed faces of buttons
	Gray10 = ui.RGB(0x55, 0x55, 0x55) // bevel button outlines, zoom rectangles
	Gray11 = ui.RGB(0x44, 0x44, 0x44) // pressed shadows
	Gray12 = ui.RGB(0x22, 0x22, 0x22) // a gray of the color picker
	Black  = ui.RGB(0x00, 0x00, 0x00)
)

The gray ramp of the Platinum look. Every control is drawn from these twelve grays, black and white, and the theme's accent; docs/spec.md says which part of which control takes which.

View Source
var (
	Lavender = Accent{Name: "Lavender", Dark: ui.RGB(0x4C, 0x4C, 0xA8), Mid: ui.RGB(0x88, 0x88, 0xDD), Light: ui.RGB(0xCC, 0xCC, 0xFF)}
	Graphite = Accent{Name: "Graphite", Dark: ui.RGB(0x4A, 0x4A, 0x4A), Mid: ui.RGB(0x8C, 0x8C, 0x8C), Light: ui.RGB(0xCC, 0xCC, 0xCC)}
	Harbor   = Accent{Name: "Harbor", Dark: ui.RGB(0x1F, 0x5A, 0x8C), Mid: ui.RGB(0x5C, 0x99, 0xCC), Light: ui.RGB(0xBB, 0xDD, 0xFF)}
	Moss     = Accent{Name: "Moss", Dark: ui.RGB(0x3A, 0x6B, 0x2A), Mid: ui.RGB(0x77, 0xAA, 0x5E), Light: ui.RGB(0xCC, 0xEE, 0xBB)}
	Ember    = Accent{Name: "Ember", Dark: ui.RGB(0x99, 0x3D, 0x1F), Mid: ui.RGB(0xDD, 0x88, 0x55), Light: ui.RGB(0xFF, 0xDD, 0xBB)}
	Orchid   = Accent{Name: "Orchid", Dark: ui.RGB(0x7A, 0x2E, 0x7A), Mid: ui.RGB(0xBB, 0x77, 0xBB), Light: ui.RGB(0xEE, 0xCC, 0xEE)}
)

The accents that ship with the library.

View Source
var MacKeys = macKeyboard()

MacKeys is whether menus show the keys of shortcuts as a Mac's keyboard marks them, as ⌘N, or by their names, as Ctrl+N, as other systems do. It starts as the system's, in a browser the system the browser runs on; tests set it, to draw the same everywhere.

View Source
var Papers = []struct {
	Name string
	W, H float64
}{{"US Letter", 612, 792}, {"US Legal", 612, 1008}, {"A4", 595, 842}, {"A5", 420, 595}, {"Envelope #10", 297, 684}}

Papers are the sizes of paper a page setup dialog offers, in points.

Functions

func Alert

func Alert(c *ui.Context, open *bool, kind AlertKind, message, detail string, buttons ...string) int

Alert shows an alert box over the window while *open: an icon of kind, message in the bold face, detail under it in the regular face, and buttons along its bottom, the last one the default. It keeps the keyboard while it shows: Return and Enter press the default button, and Escape and Command-period a button named "Cancel". It returns the index of the button the user pressed, and closes, or -1.

The counterpart among MyGo's own controls is ui.AlertDialog.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{confirm: true}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		switch pt.Alert(c, &a.confirm, pt.AlertCaution,
			"Save changes to “Notes” before closing?", "Your changes will be lost if you don’t save them.",
			"Don’t Save", "Cancel", "Save") {
		case 0:
			fmt.Println("discarded")
		case 2:
			fmt.Println("saved")
		}
	})
}

func Badge

func Badge(c *ui.Context, text string) ui.Element

Badge builds a badge: a short text, as a count, inverted — white on black in a square box — as the classic desktop marks what is selected.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Row(c).Gap(6).Children(func() {
			pt.TextIn(c, "Mail", pt.AppFont, pt.Black)
			pt.Badge(c, "3")
		})
	})
}

func Balloon

func Balloon(c *ui.Context, anchor ui.Element, text string)

Balloon gives anchor a help balloon: a rounded white balloon with a tail pointing at it, holding text in the regular face, which shows as the pointer rests on anchor or the keyboard focus comes to it.

The counterpart among MyGo's own controls is Element.Tooltip.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		b := pt.Button(c, "Erase")
		pt.Balloon(c, b.Element(), "Erases the disk. You cannot undo it.")
	})
}
func Banner(c *ui.Context, open *bool, kind AlertKind, text string) ui.Element

Banner builds a notification band where it is laid out while *open — across the top of a window's content, as a rule, the content under it moved down: a raised panel as wide as its parent, with a small icon of kind, text and a close box that closes it, its text read out once by screen readers as it shows. It returns the band, or a nil Element while closed.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	shown := true
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Column(c).Fill().AlignItems(ui.Stretch).Children(func() {
			// Across the top of the content, which goes under it.
			pt.Banner(c, &shown, pt.AlertNote, "The disk was backed up.")
			pt.TextIn(c, "28 items", pt.AppFont, pt.Black)
		})
	})
	fmt.Println(shown)
}
Output:
true
func Breadcrumbs(c *ui.Context, path []string) int

Breadcrumbs builds a row of the folders of path, the outermost first, with arrows between them; a click on one, or Space or Return while it has the keyboard focus, goes there. It returns the index of the one chosen, or -1.

The counterpart among MyGo's own controls is ui.Breadcrumbs.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	path := []string{"Platinum Disk", "Documents", "Letters"}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		if i := pt.Breadcrumbs(c, path); i >= 0 {
			path = path[:i+1] // go up to the folder chosen
		}
	})
	fmt.Println(len(path))
}
Output:
3

func Card

func Card(c *ui.Context, fn func()) ui.Element

Card builds a raised panel that groups what fn builds, in a column: a black outline round a raised face, as a panel of a control panel.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Card(c, func() {
			pt.Label(c, "Backup")
			pt.TextIn(c, "Last backed up today.", pt.AppFont, pt.Black)
		})
	})
}

func ChasingArrows

func ChasingArrows(c *ui.Context) ui.Element

ChasingArrows builds the chasing arrows: two arrows running round a circle, which show that work of unknown length goes on, in less room than a progress bar.

The counterpart among MyGo's own controls is ui.Spinner.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.ChasingArrows(c).Label("Connecting")
		pt.Placard(c, "12 items")
		pt.Badge(c, "3")
		pt.Tag(c, "draft")
		pt.ImageWell(c, nil).Label("Picture")
	})
}

func ContextMenu

func ContextMenu(c *ui.Context, target ui.Element, items []MenuItem)

ContextMenu gives target a context menu of items, which opens at the pointer on a click of the secondary button, or a Control-click, and chooses as the menus of a menu bar do. Shift-F10 opens it from the keyboard while target has the focus.

The counterpart among MyGo's own controls is Element.ContextMenu.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		row := ui.Box(c).Size(200, 20).Focusable().Label("Row")
		pt.ContextMenu(c, row, []pt.MenuItem{{Title: "Rename", Action: func() { fmt.Println("rename") }}})
	})
}

func Dialog

func Dialog(c *ui.Context, open *bool, title string, width int, fn func())

Dialog shows a movable modal dialog over the window while *open: a window frame with a title bar, which the user drags, but no boxes, around the controls fn builds, in a column. It keeps the keyboard while it shows; Escape closes it, unless fn's buttons take it. It first shows centered, as wide as width.

The counterpart among MyGo's own controls is ui.Modal.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{find: true}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Dialog(c, &a.find, "Find", 320, func() {
			pt.TextField(c, &a.query).Width(280).Label("Find")
			if pt.Button(c, "Find").Default().Clicked() {
				fmt.Println("finding", a.query)
			}
		})
	})
}

func DrawAlertFrame

func DrawAlertFrame(pn Pen)

DrawAlertFrame draws the frame of an alert box filling pn's box: an outline and a thick, beveled border around a gray face.

func DrawAlertIcon

func DrawAlertIcon(pn Pen, kind AlertKind)

DrawAlertIcon draws the 32×32 icon of an alert of kind in pn's corner.

func DrawBalloon

func DrawBalloon(pn Pen)

DrawBalloon draws a help balloon filling pn's box, its tail at the top left, balloonTail tall.

func DrawBevelButton

func DrawBevelButton(pn Pen, s State, on bool)

DrawBevelButton draws the face of a bevel button filling pn's box, pushed in while pressed or on.

func DrawButton

func DrawButton(pn Pen, label string, s State)

DrawButton draws a push button with label filling pn's box, for controls of your own that look like one.

func DrawCalendar

func DrawCalendar(pn Pen, locale string, first time.Weekday, month, chosen, today time.Time, focused bool, a Accent)

DrawCalendar draws the calendar of month in pn's box, in the language of locale, its weeks starting on first, chosen highlighted and today outlined.

func DrawChasingArrows

func DrawChasingArrows(pn Pen, step int)

DrawChasingArrows draws the chasing arrows in pn's 16×16 corner, turned step eighths of a turn.

func DrawCheckbox

func DrawCheckbox(pn Pen, mark CheckMark, s State)

DrawCheckbox draws the box of a check box in pn's corner.

func DrawContentRing

func DrawContentRing(pn Pen)

DrawContentRing draws the sunken ring around a content box — a text field, list, tree, table or scroll view — just inside pn's box: Gray7 along the top and left, White along the bottom and right. The content's black outline goes inside it.

func DrawDefaultRing

func DrawDefaultRing(pn Pen, x, y, w, h int, s State)

DrawDefaultRing draws the ring of a default button around the w×h box at x, y of pn, DefaultRing pixels wide, in state s (normal, disabled or inactive).

func DrawDisclosure

func DrawDisclosure(pn Pen, open bool, s State)

DrawDisclosure draws a disclosure triangle in pn's 12×12 corner, pointing down when open.

func DrawFocusCircle

func DrawFocusCircle(pn Pen, c ui.Color)

DrawFocusCircle draws the focus ring of a radio button around pn's 12×12 circle: a ring two pixels wide, a pixel outside it.

func DrawFocusRing

func DrawFocusRing(pn Pen, r int, c ui.Color)

DrawFocusRing draws the ring of the keyboard focus around pn's box: two pixels of c, a pixel outside it, its corners cut by radius r.

func DrawGroupBox

func DrawGroupBox(pn Pen, title string, disabled bool)

DrawGroupBox draws the outline of a group box filling pn's box, its title on its top edge, dimmed when disabled.

func DrawGrowBox

func DrawGrowBox(pn Pen, active bool)

DrawGrowBox draws the resize corner of a window in pn's 15×15 corner.

func DrawIcon

func DrawIcon(pn Pen, rows []string, a Accent, inverted bool)

DrawIcon draws a small picture given as rows of '#' (black), 'o' (the accent's dark color), '+' (the accent's mid color), ':' (gray), 'w' (white) and other characters (nothing). Inverted, black and white swap, for an icon on a highlight.

func DrawIconView

func DrawIconView(pn Pen, items []IconItem, sel int, focused bool, a Accent)

DrawIconView draws the icons of an icon view in pn's box, icon sel selected.

func DrawLabelBox

func DrawLabelBox(pn Pen, face ui.Color)

DrawLabelBox draws the square box of a badge or tag filling pn's box: face inside a black outline.

func DrawListBox

func DrawListBox(pn Pen, items []string, top, sel int, focused, disabled bool, a Accent)

DrawListBox draws the rows of a list box from row top in pn's box, row sel highlighted: in the accent while the list has the keyboard focus, in gray otherwise.

func DrawMenuBar

func DrawMenuBar(pn Pen, menus []Menu, hl int, a Accent)

DrawMenuBar draws a menu bar filling pn's box, with the title of menu hl highlighted (-1 for none).

func DrawMenuItem

func DrawMenuItem(pn Pen, it MenuItem, highlighted bool, a Accent)

DrawMenuItem draws an item of a menu filling pn's box.

func DrawMenuPanel

func DrawMenuPanel(pn Pen, items []MenuItem, hl, w int, a Accent)

DrawMenuPanel draws a menu of items at the panel's corner of pn, with item hl highlighted (-1 for none), as wide as w.

func DrawPagePreview

func DrawPagePreview(pn Pen, st PageSetupState)

DrawPagePreview draws a picture of a page set up as st, centered in pn's box, with a shadow, its margins dotted and gray lines for its text.

func DrawPalette

func DrawPalette(pn Pen, chosen ui.Color)

DrawPalette draws the picker's palette in pn's box, the swatch of chosen, if any, outlined.

func DrawPlacard

func DrawPlacard(pn Pen)

DrawPlacard draws the panel of a placard filling pn's box: a raised band, with no outline.

func DrawPopupButton

func DrawPopupButton(pn Pen, text string, s State)

DrawPopupButton draws the button of a pop-up menu showing text, filling pn's box.

func DrawPopupWindow

func DrawPopupWindow(pn Pen, title string, tabW int, open, active, pressed bool)

DrawPopupWindow draws a pop-up window filling pn's box: its tab, tabW wide, with the title, and, while open, the window under it, its frame and the sunken edge of its content running off the bottom. The tab is pressed in while pressed; in the background, its title is gray.

func DrawProgress

func DrawProgress(pn Pen, f float64, a Accent)

DrawProgress draws a progress bar at f (0 to 1) of its length.

func DrawProgressIndeterminate

func DrawProgressIndeterminate(pn Pen, phase int, a Accent)

DrawProgressIndeterminate draws a progress bar of unknown length, its stripes moved by phase pixels.

func DrawRadio

func DrawRadio(pn Pen, on bool, s State)

DrawRadio draws the circle of a radio button in pn's corner.

func DrawRuler

func DrawRuler(pn Pen, left, right, first int)

DrawRuler draws a ruler filling pn's box, with its margin markers at left and right, and its first-line indent marker first in from left.

func DrawScrollBar

func DrawScrollBar(pn Pen, horizontal bool, value, visible, total float64, pressed ScrollPart, active bool, a Accent)

DrawScrollBar draws a scroll bar filling pn's box: its arrows, track and thumb for value, visible and total as ScrollBar takes them, the part pressed darkened. An inactive bar shows its track empty and its arrows dimmed.

func DrawScrollBarInactive

func DrawScrollBarInactive(pn Pen, horizontal bool)

DrawScrollBarInactive draws a scroll bar of a window in the background filling pn's box: its outline round a flat gray track, with no arrows or thumb.

func DrawSearchDecor

func DrawSearchDecor(pn Pen, clear, disabled bool)

DrawSearchDecor draws the magnifier and, when clear, the clear button of a search field filling pn's box.

func DrawSheet

func DrawSheet(pn Pen, st *SheetState, top, left, rows, cols int, focused bool, a Accent)

DrawSheet draws the cells of a sheet from row top and column left in pn's box, which holds its outline.

func DrawSlider

func DrawSlider(pn Pen, f float64, n int, s State, a Accent)

DrawSlider draws a horizontal slider at fraction f (0 to 1) of its track in pn's box, with n tick marks under it when n > 1.

func DrawSliderThumb

func DrawSliderThumb(pn Pen, s State, a Accent)

DrawSliderThumb draws the pointed thumb of a slider in pn's corner.

func DrawSmallAlertIcon

func DrawSmallAlertIcon(pn Pen, kind AlertKind)

DrawSmallAlertIcon draws the 16×16 icon of an alert of kind, as banners show it, in pn's corner.

func DrawSplitter

func DrawSplitter(pn Pen, vertical bool)

DrawSplitter draws the divider of a split filling pn's box: a raised bar with a grip of dots in its middle, across a vertical split if vertical.

func DrawStepper

func DrawStepper(pn Pen, pressed int, s State)

DrawStepper draws the little arrows in pn's 13×23 corner, the half pressed (1 up, -1 down) darkened, in state s (normal, disabled or inactive).

func DrawTab

func DrawTab(pn Pen, label string, selected bool, s State)

DrawTab draws a tab labeled label filling pn's box: its top corners rounded, its bottom open onto the pane when selected.

func DrawTabPane

func DrawTabPane(pn Pen, gapX, gapW int)

DrawTabPane draws the raised pane of a tab control filling pn's box, open under the selected tab, gapW wide from gapX.

func DrawTable

func DrawTable(pn Pen, st *TableState, cols []TableColumn, order []int, top int, cell func(row, col int) string, focused bool, a Accent)

DrawTable draws a table in pn's box: its headers and the rows of order from row top.

func DrawTextFrame

func DrawTextFrame(pn Pen, disabled bool)

DrawTextFrame draws the sunken white box of a text field or text area filling pn's box.

func DrawTimeField

func DrawTimeField(pn Pen, parts, seps []string, xs []int, seg int, focused, inactive bool, a Accent)

DrawTimeField draws a time field showing parts — the hours, minutes and half of the day if the time has one, in the order the language writes them, seps between them — from xs, part seg chosen while focused, in pn's box.

func DrawTitleBox

func DrawTitleBox(pn Pen, part WindowPart, pressed bool)

DrawTitleBox draws the close, zoom or collapse box of a title bar filling pn's square box: 11×11, or 9×9 in a utility window.

func DrawTree

func DrawTree(pn Pen, roots []*TreeNode, top int, sel *TreeNode, focused bool, a Accent)

DrawTree draws the rows of a tree view of roots — those open showing their children — from row top in pn's box, sel highlighted (in the accent while focused).

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	roots := []*pt.TreeNode{{Title: "Documents", Open: true, Children: []*pt.TreeNode{{Title: "Letters"}}}}
	render(func(c *ui.Context) {
		ui.Box(c).Size(160, 60).Draw(func(p *ui.Painter, r ui.Rect) {
			pt.DrawTree(pt.NewPen(p, r), roots, 0, roots[0].Children[0], true, pt.Lavender)
		})
	})
}

func DrawWell

func DrawWell(pn Pen)

DrawWell draws a sunken white well filling pn's box, as an image well's.

func DrawWindowFrame

func DrawWindowFrame(pn Pen, title string, opts WindowOptions, collapsed bool, pressed WindowPart)

DrawWindowFrame draws a window's frame filling pn's box: its outline, title bar with title, boxes and stripes, side frame and resize corner, with the box pressed darkened. The content goes inside, FrameWidth from the sides and bottom and TitleBarHeight from the top.

func DrawWindowHeader

func DrawWindowHeader(pn Pen, left, right string)

DrawWindowHeader draws a window header filling pn's box: Gray2, an etched line and a Black one at its bottom, left 8 from its left and right 8 from its right.

func DrawZoomRects

func DrawZoomRects(pn Pen, from, to ui.Rect, t float32)

DrawZoomRects draws the outlines of zoom rectangles at t (0 to 1) of the way from from to to: zoomSteps outlines, the newest t of the way, the others trailing behind it, in a gray that shows on light and dark.

func EditCommand

func EditCommand(c *ui.Context, cmd string) bool

EditCommand performs an edit command — "undo", "redo", "cut", "copy", "paste", "delete" or "selectAll" — on the text field or text area that has the keyboard focus in the window of c, as the items of an Edit menu do, and reports whether one had it.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Column(c).Fill().Children(func() {
			pt.MenuBar(c, []pt.Menu{{Title: "Edit", Items: []pt.MenuItem{
				{Title: "Copy", Key: ui.KeyC, Action: func() { pt.EditCommand(c, "copy") }},
				{Title: "Paste", Key: ui.KeyV, Action: func() { pt.EditCommand(c, "paste") }},
			}}})
		})
	})
}

func EmptyState

func EmptyState(c *ui.Context, text string) ui.Element

EmptyState builds what a list or a window shows while it has nothing to show: one line of gray text, centered in the room it is given.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Column(c).Fill().Children(func() { pt.EmptyState(c, "No messages") })
	})
}

func Find

func Find(text, query string, from int, o FindOptions) (int, int)

Find returns where the first match of query in text starts and ends, in runes, at or after from — wrapping round to the start — or -1, -1.

func FormatBar

func FormatBar(c *ui.Context, d *RichText) ui.Element

FormatBar builds a toolbar styling d: bold, italic and underline toggles showing the style of the selection, and the alignment of its lines.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	doc := pt.NewRichText("Minutes")
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Column(c).Fill().AlignItems(ui.Stretch).Children(func() {
			pt.FormatBar(c, doc) // bold, italic, underline and alignment
			pt.RichTextArea(c, doc).Label("Document").Element().Grow(1)
		})
	})
}

func FormulaBar

func FormulaBar(c *ui.Context, st *SheetState) ui.Element

FormulaBar builds the bar over a sheet that names its cursor's cell and shows the text typed in it — a formula where it has one — in a field that edits it: Return puts the text in the cell.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	sheet := pt.NewSheetState()
	sheet.Cells[pt.Cell{Col: 0, Row: 0}] = "=1+2"
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Column(c).Fill().AlignItems(ui.Stretch).Children(func() {
			pt.FormulaBar(c, sheet)
			pt.Sheet(c, sheet, 20, 6).Label("Sheet").Element().Grow(1)
		})
	})
	fmt.Println(sheet.Value(pt.Cell{Col: 0, Row: 0}))
}
Output:
3

func GroupBox

func GroupBox(c *ui.Context, title string, fn func()) ui.Element

GroupBox builds a box that groups related controls under title: an etched outline whose top edge the title interrupts. fn builds the controls inside, in a column. An empty title draws the outline alone.

The counterpart among MyGo's own controls is ui.Fieldset.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.GroupBox(c, "Sound", func() {
			pt.Checkbox(c, &a.sound, "Beep on errors")
			pt.Separator(c)
		})
	})
}

func ImageWell

func ImageWell(c *ui.Context, bmp *ui.Bitmap) ui.Element

ImageWell builds an image well: a sunken white square showing bmp centered, as a picture a document or a setting holds. Label it for assistive technology; size it with Size (48×48 by default).

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.ImageWell(c, nil).Label("Picture") // empty until a picture is dropped
	})
}

func Inset

func Inset(i, h, r int) int

Inset returns how far row i of a box h tall, with corners of radius r, starts in from its sides, for shapes of one's own rounded as the library's are.

func ItalicSlant

func ItalicSlant(f Font) int

ItalicSlant returns the room italic text of f takes beyond its glyphs' advances, at the end of each run: how far its top row leans right.

func Label

func Label(c *ui.Context, text string) ui.Element

Label builds a line of text in the bold face, sized to it.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Row(c).Gap(8).AlignItems(ui.Center).Children(func() {
			pt.Label(c, "Name:") // a label in the bold face, beside its field
			pt.TextIn(c, "Ada Lovelace", pt.AppFont, pt.Black)
		})
	})
}
func MenuBar(c *ui.Context, menus []Menu) ui.Element

MenuBar builds a menu bar of menus along the top of its parent, as wide as it: its menus open as the pointer presses their titles, and choose the item it is released over, or stay open after a click until an item is clicked. Ctrl-F2 opens the first menu from the keyboard; the arrows move through the menus and their items, Return chooses and Escape closes. Keyboard equivalents of the items work wherever the focus is.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Column(c).Fill().Children(func() {
			pt.MenuBar(c, []pt.Menu{
				{Title: "File", Items: []pt.MenuItem{
					{Title: "New", Key: ui.KeyN, Action: func() { fmt.Println("new") }},
					pt.SeparatorItem(),
					{Title: "Recent", Submenu: []pt.MenuItem{{Title: "Notes"}}},
					{Title: "Print…", Disabled: true},
				}},
			})
		})
	})
}

func PageSetup

func PageSetup(c *ui.Context, open *bool, st *PageSetupState) bool

PageSetup shows a page setup dialog while *open: the paper, the orientation as two bevel buttons of pictures, the scale and margins, and a picture of the page as chosen. It edits a copy of *st and reports whether OK put it in *st.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	open := true
	setup := pt.PageSetupState{Scale: 100, Margin: 36}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Box(c).Fill().Children(func() {
			if pt.PageSetup(c, &open, &setup) {
				// Lay the document out again for the paper chosen.
			}
		})
	})
	fmt.Println(pt.Papers[setup.Paper].Name)
}
Output:
US Letter

func Pagination

func Pagination(c *ui.Context, page *int, pages int) ui.Element

Pagination builds the arrows and the "Page n of m" between them that move *page (from 0) through pages pages; Left and Right do too while either arrow has the keyboard focus.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	page := 2
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Pagination(c, &page, 12)
	})
	fmt.Println(page)
}
Output:
2

func Paragraph

func Paragraph(c *ui.Context, text string, f Font, width int) ui.Element

Paragraph builds text that wraps at width pixels, in font f.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Paragraph(c, "The document could not be saved, because the disk is full.", pt.AppFont, 200)
	})
}

func PathPopup

func PathPopup(c *ui.Context, path []string) int

PathPopup builds a bevel button showing the last of path, a folder's name, whose menu lists the folders it is in, from it up to the outermost, as the path menu of a window's title. It returns the index in path of the folder chosen, or -1.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	path := []string{"Disk", "Documents", "Letters"}
	page := 0
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		if i := pt.PathPopup(c, path); i >= 0 {
			path = path[:i+1]
		}
		if i := pt.Breadcrumbs(c, path); i >= 0 {
			path = path[:i+1]
		}
		pt.Pagination(c, &page, 12)
		pt.Card(c, func() { pt.Label(c, "In a card") })
		pt.EmptyState(c, "No documents")
		pt.StatusBar(c, "3 items", "1.2 MB available")
	})
}

func Placard

func Placard(c *ui.Context, text string) ui.Element

Placard builds a placard: a small raised panel of text in the regular face, as the information along the bottom of a window, beside its horizontal scroll bar.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Placard(c, "12 words, 2 lines")
	})
}

func ProgressBar

func ProgressBar(c *ui.Context, value float64) ui.Element

ProgressBar builds a progress bar showing value, from 0 to 1, of work done: a sunken channel filled from the left with the accent. A negative value shows work of unknown length, as diagonal stripes moving along the bar.

The counterpart among MyGo's own controls is ui.Progress.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.ProgressBar(c, 0.4).Width(200)
		pt.ProgressBar(c, pt.Indeterminate).Width(200)
	})
}

func ProgressDialog

func ProgressDialog(c *ui.Context, open *bool, title, message string, value float64, detail string) bool

ProgressDialog shows a movable modal dialog of work in progress while *open: message over a progress bar of value (Indeterminate for work of unknown length) and detail under it, and a Cancel button that Escape and Command-period press too. It reports whether the user cancelled, which closes it.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	copying, done := true, true
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		if pt.ProgressDialog(c, &copying, "Copying", "Copying 12 items…", 0.4, "About a minute left") {
			fmt.Println("stopped")
		}
		pt.Banner(c, &done, pt.AlertNote, "The disk was backed up.")
	})
}

func RadioGroup

func RadioGroup(c *ui.Context, fn func()) ui.Element

RadioGroup lays out the radio buttons fn builds in a column, as one stop of Tab whose buttons the arrow keys move between and choose.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	size := 1
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.RadioGroup(c, func() {
			pt.Radio(c, &size, 0, "Small")
			pt.Radio(c, &size, 1, "Medium")
			pt.Radio(c, &size, 2, "Large")
		}).Label("Size")
	})
	fmt.Println(size)
}
Output:
1

func ReplaceAll

func ReplaceAll(text, query, with string, o FindOptions) (string, int)

ReplaceAll replaces every match of query in text with with, and returns the text and how many it replaced.

func Ruler

func Ruler(c *ui.Context, st *RulerState) ui.Element

Ruler builds a ruler over a document: a scale from the left margin, ticked every 9 pixels and numbered every 72 (an inch at 72 dpi), with markers of the left and right margins under it and of the first-line indent on it, which the pointer drags in steps of 9. The text between the margins is the document's width; the first line of each paragraph starts First further in.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	margins := &pt.RulerState{Left: 16, Right: 300}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Ruler(c, margins)
	})
}

func SaveDialog

func SaveDialog(c *ui.Context, open *bool, st *FileDialogState, roots []*TreeNode, prompt string) bool

SaveDialog shows a dialog choosing where to save while *open, as the classic desktop's standard one: as OpenDialog's, with the files dimmed and not to be chosen, and New Folder among the buttons (when st.NewFolder is set); under the list, the prompt and a field of the name, selected to type over; Cancel and Save at the bottom of the buttons. Saving over a file of the same name asks first. It reports whether the user saved, and closes: st.Path's last folder (or the desktop) and st.Name say where.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	docs := &pt.TreeNode{Title: "Documents", Children: []*pt.TreeNode{{Title: "Letter"}}}
	disk := &pt.TreeNode{Title: "Disk", Children: []*pt.TreeNode{docs}}
	open := true
	st := &pt.FileDialogState{Path: []*pt.TreeNode{disk, docs}, Name: "untitled"}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Box(c).Fill().Children(func() {
			if pt.SaveDialog(c, &open, st, []*pt.TreeNode{disk}, "Save as:") {
				// Write the document as st.Name in st.Path's last folder.
			}
		})
	})
	fmt.Println(open, st.Name, st.Path[len(st.Path)-1].Title)
}
Output:
true untitled Documents

func ScrollView

func ScrollView(c *ui.Context, st *ui.ScrollState, fn func()) ui.Element

ScrollView builds a box that scrolls what fn builds up and down, with a Platinum scroll bar at its right that follows it, kept in *st by the app. Give it a size, or let it grow.

The counterpart among MyGo's own controls is ui.Scroll.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	var st ui.ScrollState
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.ScrollView(c, &st, func() {
			for i := 1; i <= 40; i++ {
				pt.TextIn(c, fmt.Sprintf("Line %d", i), pt.AppFont, pt.Black)
			}
		}).Size(200, 120)
	})
}

func Separator

func Separator(c *ui.Context) ui.Element

Separator builds a horizontal etched line, for dividing a column of controls. Give it a width, or let it stretch across its column.

The counterpart among MyGo's own controls is ui.Divider.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Column(c).Gap(6).AlignItems(ui.Stretch).Children(func() {
			pt.Label(c, "Above")
			pt.Separator(c)
			pt.Label(c, "Below")
		})
	})
}

func SetClock

func SetClock(now func() time.Time) (previous func() time.Time)

SetClock makes every control take its time from now instead of the frame's — indeterminate progress bars and chasing arrows, caret blinks, menu and button flashes, calendars' today — for tests and screenshots that must come out the same whenever and wherever they run. Animations stand still at that moment. A nil now restores the frame's time. It returns the clock it replaces, to put back:

defer platinum.SetClock(platinum.SetClock(fixed))

func SetEastAsian

func SetEastAsian(regular, bold func() *bitmap.Face)

SetEastAsian makes the controls draw the characters of East Asian scripts, which the library's faces lack, with the 12px faces regular and bold return: those of a package of platinum-fonts' cjk12, whose forms are of the language the app shows. Bold draws them in the bold face, SystemFont, and in bold styled text. Characters neither face draws are drawn in the system's font, as they all are until SetEastAsian is called; nil functions return to it.

import "github.com/firede/platinum-fonts/cjk12/zhhans"

pt.SetEastAsian(zhhans.Regular, zhhans.Bold)

func Split

func Split(c *ui.Context, pos *float32, first, second func()) ui.Element

Split builds two panes side by side, first and second, with a divider between them that the pointer drags, or the arrows move while it has the keyboard focus. *pos is the first pane's width, kept by the app; with less room than that and the second pane's least, the first gives way, and *pos stays for when there is room again. Give the split a size, or let it grow.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{split: 120}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Split(c, &a.split, func() {
			pt.Label(c, "Folders")
		}, func() {
			pt.ScrollView(c, &a.scroll, func() {
				for i := 0; i < 30; i++ {
					pt.TextIn(c, fmt.Sprint("Line ", i), pt.AppFont, pt.Black)
				}
			}).Grow(1)
		}).Size(360, 200)
	})
}

func SplitPercent

func SplitPercent(c *ui.Context, p *float32, first, second func()) ui.Element

SplitPercent builds a Split with *p the percentage of the room the first pane takes, from 0 to 100, so that both panes grow and shrink with the split, in proportion.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	sidebar := float32(25) // a quarter of the room, however wide
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.SplitPercent(c, &sidebar, func() {
			pt.Label(c, "Folders")
		}, func() {
			pt.Label(c, "Files")
		}).Size(360, 200)
	})
}

func SplitVertical

func SplitVertical(c *ui.Context, pos *float32, first, second func()) ui.Element

SplitVertical builds a Split whose panes are stacked, *pos being the first one's height.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	height := float32(80)
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.SplitVertical(c, &height, func() {
			pt.Label(c, "Messages")
		}, func() {
			pt.Label(c, "Preview")
		}).Size(240, 200)
	})
}

func SplitVerticalPercent

func SplitVerticalPercent(c *ui.Context, p *float32, first, second func()) ui.Element

SplitVerticalPercent builds a SplitPercent whose panes are stacked.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	top := float32(60)
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.SplitVerticalPercent(c, &top, func() {
			pt.Label(c, "Messages")
		}, func() {
			pt.Label(c, "Preview")
		}).Size(240, 200)
	})
}

func SpringOpen

func SpringOpen[T any](c *ui.Context, w *PopupWindowWidget, st *PopupWindowState)

SpringOpen opens a closed pop-up window w when a drag of a T has rested on its tab for SpringDelay, as the classic pop-up windows sprang open under a drag, for what is dragged to be dropped in the window. Call it after PopupWindow, with its state.

func StatusBar

func StatusBar(c *ui.Context, texts ...string) ui.Element

StatusBar builds a row of placards along the bottom of a window, one for each of texts, the last one taking the room left.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Column(c).Fill().AlignItems(ui.Stretch).Children(func() {
			ui.Box(c).Grow(1)
			pt.StatusBar(c, "12 items", "3 selected", "48 MB available")
		})
	})
}

func Tag

func Tag(c *ui.Context, text string) ui.Element

Tag builds a tag: a short text in a light gray box with a black outline, as a keyword.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Row(c).Gap(4).Children(func() {
			pt.Tag(c, "draft")
			pt.Tag(c, "letters")
		})
	})
}

func TextIn

func TextIn(c *ui.Context, text string, f Font, ink ui.Color) ui.Element

TextIn builds a line of text in font f and color ink, sized to it. Made taller, as tall as a control beside it, it centers its capitals on its middle, as the control centers its own text.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.TextIn(c, "28 items, 3.2 MB available", pt.AppFont, pt.Gray9)
	})
}

func TimeField

func TimeField(c *ui.Context, t *time.Time, step int) ui.Element

TimeField builds a field of the time of day of *t, as "9:41 AM" or "21:41", in the hour cycle of the user's regional formats, with little arrows at its right. Its parts — hours, minutes, and AM or PM — are chosen one at a time, by a click or with Left and Right; Up, Down and the arrows step the part chosen (minutes by step), digits type it, and A and P set the half of the day.

The counterpart among MyGo's own controls is ui.TimeInput.

Example
package main

import (
	"fmt"
	"time"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	t := time.Date(2026, 10, 14, 9, 41, 0, 0, time.UTC)
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.TimeField(c, &t, 1).Label("Time")
	})
	fmt.Println(t.Format("3:04 PM"))
}
Output:
9:41 AM

func Toasts

func Toasts(c *ui.Context) ui.Element

Toasts builds the toasts of the window — what c.Toast, c.ToastAction and c.AddToast of MyGo show — in the Platinum look: small alert boxes at the bottom of the window, centered, the newest at the bottom, each with the small icon of its Type ("error" a stop, "caution" or "warning" a caution, else a note), its title and description, its action as a push button and a close box. They show and go without fading, as nothing of the look fades. Call it once in the view, wherever.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	saved := false
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		if !saved {
			saved = true
			c.Toast("Saved") // MyGo's toasts, in the Platinum look
		}
		pt.Toasts(c)
	})
}

func Toolbar

func Toolbar(c *ui.Context, items []ToolItem) ui.Element

Toolbar builds a row of bevel buttons along the top of a window, on a face with an etched line under it, one stop of Tab whose buttons the arrows move between. Items that do not fit go into a menu that a » button at its end opens.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

var boldIcon = []string{
	"######..",
	".##..##.",
	".#####..",
	".##..##.",
	"######..",
}

func main() {
	a := &app{}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Toolbar(c, []pt.ToolItem{
			{Label: "New", Action: func() { fmt.Println("new") }},
			{Separator: true},
			{Label: "Bold", Icon: boldIcon, IconOnly: true, On: &a.bold},
		})
	})
}

func ToolbarSeparator

func ToolbarSeparator(c *ui.Context) ui.Element

ToolbarSeparator builds an etched vertical line between groups of controls of a toolbar.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Row(c).Gap(4).Children(func() {
			pt.BevelButton(c, "Cut")
			pt.ToolbarSeparator(c)
			pt.BevelButton(c, "Paste")
		})
	})
}

func Use

func Use(c *ui.Context, th *Theme)

Use makes the window of c draw its Platinum controls with th, and sets the MyGo theme of the window to match (its background, text, selection and focus colors), so that MyGo's own elements sit well among them. Call it at the top of the view, every frame; a nil th is DefaultTheme.

func WindowHeader

func WindowHeader(c *ui.Context, left, right string) ui.Element

WindowHeader builds the band across the top of a window's content that tells about it, as a folder window's count of items and the room left: left at its left and right at its right, in the regular face.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Column(c).Fill().AlignItems(ui.Stretch).Children(func() {
			pt.WindowHeader(c, "4 items", "47.7 MB available")
		})
	})
}

func ZoomRects

func ZoomRects(c *ui.Context, from, to ui.Rect, start time.Time) bool

ZoomRects shows the outlines that grow from the box from, as the icon a window opens from, to the box to, where it opens, over ZoomDuration from start — the classic desktop's sign of where a window came from. It draws over the window, in its coordinates, and asks for frames until it is done; with the desktop asking for less motion, or the time frozen by SetClock, it shows nothing. It reports whether it is still going.

Example
package main

import (
	"time"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	opened := time.Date(2026, 10, 14, 9, 41, 0, 0, time.UTC) // when the window opened
	icon := ui.Rect{X: 600, Y: 40, W: 32, H: 32}
	window := ui.Rect{X: 40, Y: 40, W: 300, H: 200}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.ZoomRects(c, icon, window, opened)
	})
}

Types

type Accent

type Accent struct {
	// Name is what an appearance control panel calls it.
	Name string
	// Dark fills highlighted menu items and selected rows under white text,
	// and draws the focus ring.
	Dark ui.Color
	// Mid fills progress bars and slider thumbs.
	Mid ui.Color
	// Light highlights selected text under black text.
	Light ui.Color
}

Accent is a color variation: the color of highlighted menu items, selected rows, the keyboard focus, the filled part of progress bars and the thumbs of sliders.

func Accents

func Accents() []Accent

Accents lists the accents that ship with the library, Lavender first.

type AlertKind

type AlertKind int

AlertKind is the kind of news an alert brings, which its icon shows.

const (
	// AlertNote tells the user something.
	AlertNote AlertKind = iota
	// AlertCaution warns of what an action will do.
	AlertCaution
	// AlertStop says something went wrong.
	AlertStop
)

type Align

type Align uint8

Align is the alignment of the lines of rich text.

const (
	AlignLeft Align = iota
	AlignCenter
	AlignRight
)

The alignments of the lines of rich text.

type BevelButtonWidget

type BevelButtonWidget struct {
	// contains filtered or unexported fields
}

BevelButtonWidget is a bevel button being built.

func BevelButton

func BevelButton(c *ui.Context, label string) *BevelButtonWidget

BevelButton builds a bevel button: a square, beveled button that shows a label, an icon above or beside it (Icon), stays pressed in as a toggle (Toggle), or opens a menu (Menu). Space and Enter press it while it has the keyboard focus.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

var boldIcon = []string{
	"######..",
	".##..##.",
	".#####..",
	".##..##.",
	"######..",
}

func main() {
	a := &app{}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.BevelButton(c, "Bold").Icon(boldIcon).Toggle(&a.bold)
		pt.BevelButton(c, "Style").Menu([]pt.MenuItem{{Title: "Plain"}, {Title: "Bold"}})
		pt.IconButton(c, boldIcon, "Bold")
		pt.Segmented(c, &a.tab, "Left", "Center", "Right")
	})
}

func IconButton

func IconButton(c *ui.Context, icon []string, label string) *BevelButtonWidget

IconButton builds a bevel button showing icon alone, labeled label for assistive technology, as the buttons of a toolbar.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	page := []string{"######..", "#....##.", "#.....#.", "#######."}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		if pt.IconButton(c, page, "New Page").Clicked() {
			// Make a page.
		}
	})
}

func (*BevelButtonWidget) Clicked

func (b *BevelButtonWidget) Clicked() bool

Clicked reports whether the user clicked the button since the last frame. A toggle has turned over by then.

func (*BevelButtonWidget) Disabled

func (b *BevelButtonWidget) Disabled(d bool) *BevelButtonWidget

Disabled dims the button and makes it take no input while d is true.

func (*BevelButtonWidget) Element

func (b *BevelButtonWidget) Element() ui.Element

Element returns the button's element.

func (*BevelButtonWidget) Icon

func (b *BevelButtonWidget) Icon(rows []string) *BevelButtonWidget

Icon shows a small picture in the button, left of its label, given as rows for DrawIcon.

func (*BevelButtonWidget) Menu

func (b *BevelButtonWidget) Menu(items []MenuItem) *BevelButtonWidget

Menu makes the button open a menu of items below it as it is pressed, with a small arrow at its right.

func (*BevelButtonWidget) Size

func (b *BevelButtonWidget) Size(w, h int) *BevelButtonWidget

Size sets the button's size, which is otherwise as its content needs.

func (*BevelButtonWidget) Toggle

func (b *BevelButtonWidget) Toggle(on *bool) *BevelButtonWidget

Toggle makes the button stay pressed in while *on, and turn *on over as it is clicked.

type ButtonWidget

type ButtonWidget struct {
	// contains filtered or unexported fields
}

ButtonWidget is a push button being built; its methods set it up and ask what the user did to it. Set it up before asking.

func Button

func Button(c *ui.Context, label string) *ButtonWidget

Button builds a push button showing label: a rounded, beveled gray button that turns dark while pressed. Space and Enter press it while it has the keyboard focus.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Row(c).Gap(10).Children(func() {
			if pt.Button(c, "Cancel").Cancel().Clicked() {
				fmt.Println("cancelled")
			}
			if pt.Button(c, "Save").Default().Clicked() {
				fmt.Println("saved")
			}
		})
	})
}

func (*ButtonWidget) Cancel

func (b *ButtonWidget) Cancel() *ButtonWidget

Cancel makes Escape and Command-period press the button, as a dialog's Cancel button.

func (*ButtonWidget) Clicked

func (b *ButtonWidget) Clicked() bool

Clicked reports whether the user clicked the button since the last frame: a press and release inside it, Space or Enter while it has the focus, its keyboard equivalent when it is the default or cancel button, or assistive technology pressing it.

func (*ButtonWidget) Default

func (b *ButtonWidget) Default() *ButtonWidget

Default makes the button the default one of its window or dialog: it shows a thick ring around it, and Return and Enter press it wherever the keyboard focus is, unless the focused control takes them.

func (*ButtonWidget) Disabled

func (b *ButtonWidget) Disabled(d bool) *ButtonWidget

Disabled dims the button and makes it take no clicks or keys while d is true.

func (*ButtonWidget) Element

func (b *ButtonWidget) Element() ui.Element

Element returns the button's element, to lay it out or to ask more of it.

func (*ButtonWidget) Flash

func (b *ButtonWidget) Flash() *ButtonWidget

Flash shows the button pressed for a moment, as when its keyboard equivalent presses it: for a key of your own that stands for it.

func (*ButtonWidget) Width

func (b *ButtonWidget) Width(w int) *ButtonWidget

Width sets the width of the button, which is otherwise as wide as its label needs, and at least ButtonMinWidth.

type CalendarWidget

type CalendarWidget struct {
	// contains filtered or unexported fields
}

CalendarWidget is a calendar being built.

func Calendar

func Calendar(c *ui.Context, day *time.Time) *CalendarWidget

Calendar builds a month of days choosing *day: the month and year between arrows that turn the month, the initials of the weekdays, and the days in a grid of six weeks from the first day of the user's week, the chosen one highlighted and today outlined. A click chooses a day; with the keyboard focus, the arrows move the choice by a day or a week, and Page Up and Down by a month.

Example
package main

import (
	"fmt"
	"time"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	day := time.Date(2026, 10, 14, 0, 0, 0, 0, time.UTC)
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Calendar(c, &day).Label("Calendar")
	})
	fmt.Println(day.Format("Jan 2"))
}
Output:
Oct 14

func (*CalendarWidget) Changed

func (w *CalendarWidget) Changed() bool

Changed reports whether the user chose another day since the last frame.

func (*CalendarWidget) Element

func (w *CalendarWidget) Element() ui.Element

Element returns the calendar's element.

func (*CalendarWidget) Label

func (w *CalendarWidget) Label(s string) *CalendarWidget

Label names the calendar.

type Cell

type Cell struct{ Col, Row int }

Cell names a cell of a sheet, from 0, 0 at A1.

func ParseCell

func ParseCell(s string) (Cell, bool)

ParseCell reads a cell's name, as "B3".

func (Cell) String

func (c Cell) String() string

String returns the cell's name, as "B3".

type CheckMark

type CheckMark int

CheckMark is what a check box shows in its box.

const (
	CheckNone CheckMark = iota
	CheckOn
	CheckMixed
)

The marks of a check box: none, a cross, a dash.

type CheckboxWidget

type CheckboxWidget struct {
	// contains filtered or unexported fields
}

CheckboxWidget is a check box being built.

func Checkbox

func Checkbox(c *ui.Context, checked *bool, label string) *CheckboxWidget

Checkbox builds a check box that toggles *checked, labeled label: a small beveled box that shows a cross while checked. A click on the box or the label toggles it, as does Space while it has the keyboard focus.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Checkbox(c, &a.sound, "Play alert sounds")
		pt.Checkbox(c, &a.bold, "Some of them").Mixed()
	})
}

func (*CheckboxWidget) Changed

func (b *CheckboxWidget) Changed() bool

Changed reports whether the user toggled the box since the last frame.

func (*CheckboxWidget) Disabled

func (b *CheckboxWidget) Disabled(d bool) *CheckboxWidget

Disabled dims the check box and makes it take no input while d is true.

func (*CheckboxWidget) Element

func (b *CheckboxWidget) Element() ui.Element

Element returns the check box's element.

func (*CheckboxWidget) Mixed

func (b *CheckboxWidget) Mixed() *CheckboxWidget

Mixed shows the box partly checked, a dash in place of the cross, for a box over others of which some are checked.

type ColorWellWidget

type ColorWellWidget struct {
	// contains filtered or unexported fields
}

ColorWellWidget is a color well being built.

func ColorWell

func ColorWell(c *ui.Context, col *ui.Color) *ColorWellWidget

ColorWell builds a color well: a bevel button holding a swatch of *col. Clicking it, or Space, opens a color picker dialog — a palette, sliders of red, green and blue, and the new color beside the old — whose OK sets *col, and Cancel leaves it. Label names it, and titles the picker.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	col := pt.Lavender.Mid
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		if pt.ColorWell(c, &col).Label("Highlight color").Changed() {
			fmt.Println("now", col)
		}
	})
}

func (*ColorWellWidget) Changed

func (w *ColorWellWidget) Changed() bool

Changed reports whether the user chose another color since the last frame.

func (*ColorWellWidget) Disabled

func (w *ColorWellWidget) Disabled(d bool) *ColorWellWidget

Disabled dims the well and makes it take no input while d is true.

func (*ColorWellWidget) Element

func (w *ColorWellWidget) Element() ui.Element

Element returns the well's element.

func (*ColorWellWidget) Label

func (w *ColorWellWidget) Label(s string) *ColorWellWidget

Label names the well, as screen readers read it, and titles its color picker.

type ColumnViewWidget

type ColumnViewWidget struct {
	// contains filtered or unexported fields
}

ColumnViewWidget is a column view being built.

func ColumnView

func ColumnView(c *ui.Context, roots []*TreeNode, path *[]*TreeNode) *ColumnViewWidget

ColumnView builds a browser of a tree in columns, as a list of roots and, right of it, a list of the children of the item chosen in each column: *path holds the item chosen in each column, from the first. A click chooses an item; with the keyboard focus, Up and Down move in a column, Right goes into the item chosen, Left back to its column. A horizontal scroll bar under the columns scrolls them, the newest in view when the path changes; its arrows dim while they all fit. Give it a size.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	roots := []*pt.TreeNode{{Title: "Documents", Children: []*pt.TreeNode{{Title: "Letters"}}}, {Title: "Read Me"}}
	var path []*pt.TreeNode
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.ColumnView(c, roots, &path).Element().Size(420, 160).Label("Browser")
	})
}

func (*ColumnViewWidget) Changed

func (w *ColumnViewWidget) Changed() bool

Changed reports whether the user chose another item since the last frame.

func (*ColumnViewWidget) Element

func (w *ColumnViewWidget) Element() ui.Element

Element returns the column view's element, to size it.

func (*ColumnViewWidget) Label

Label names the column view.

func (*ColumnViewWidget) ScrollBarRoom

func (w *ColumnViewWidget) ScrollBarRoom(px int) *ColumnViewWidget

ScrollBarRoom leaves px pixels at the right of the horizontal scroll bar, as for the resize corner of the window it fills, and lays the bar over that window's lines at its left and bottom.

func (*ColumnViewWidget) Submitted

func (w *ColumnViewWidget) Submitted() bool

Submitted reports whether the user double-clicked an item, or chose one and pressed Return, since the last frame: the last of the path.

type ComboboxWidget

type ComboboxWidget struct {
	// contains filtered or unexported fields
}

ComboboxWidget is a combo box being built.

func Combobox

func Combobox(c *ui.Context, value *string, items []string) *ComboboxWidget

Combobox builds a text field editing *value with an arrow button at its right that opens a menu of items: those that start as the text does, or all of them while it is empty. Choosing one puts it in the field. Down opens the menu from the keyboard.

The counterpart among MyGo's own controls is ui.Combobox.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	font := ""
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Combobox(c, &font, []string{"Sans", "Serif", "Mono"}).Label("Font")
	})
}

func (*ComboboxWidget) Changed

func (w *ComboboxWidget) Changed() bool

Changed reports whether the text changed since the last frame.

func (*ComboboxWidget) Element

func (w *ComboboxWidget) Element() ui.Element

Element returns the combo box's element.

func (*ComboboxWidget) Label

func (w *ComboboxWidget) Label(l string) *ComboboxWidget

Label names the combo box for assistive technology and tests: the group, the field, and the button of its choices, as "<l> choices".

type DatePickerWidget

type DatePickerWidget struct {
	// contains filtered or unexported fields
}

DatePickerWidget is a date picker being built.

func DatePicker

func DatePicker(c *ui.Context, day *time.Time) *DatePickerWidget

DatePicker builds a pop-up button showing *day, which opens a calendar under it to choose another; choosing a day, Escape or a click elsewhere closes it. Space, Return and Down open it from the keyboard.

The counterpart among MyGo's own controls is ui.DateInput.

Example
package main

import (
	"fmt"
	"time"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	day := time.Date(2026, 10, 14, 0, 0, 0, 0, time.UTC)
	at := day
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		if pt.DatePicker(c, &day).Changed() {
			fmt.Println("due", day.Format("Jan 2"))
		}
		pt.Calendar(c, &day)
		pt.TimeField(c, &at, 5)
	})
}

func (*DatePickerWidget) Changed

func (w *DatePickerWidget) Changed() bool

Changed reports whether the user chose another day since the last frame.

func (*DatePickerWidget) Element

func (w *DatePickerWidget) Element() ui.Element

Element returns the picker's element.

type DisclosureWidget

type DisclosureWidget struct {
	// contains filtered or unexported fields
}

DisclosureWidget is a disclosure triangle being built.

func Disclosure

func Disclosure(c *ui.Context, open *bool, label string) *DisclosureWidget

Disclosure builds a disclosure triangle that shows and hides what it labels: it points right while *open is false and down while it is true, and a click, Space or Enter turns it. Left and Right close and open it too. Build what it shows after it, while *open.

The counterpart among MyGo's own controls is ui.Collapsible.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Disclosure(c, &a.details, "Details")
		if a.details {
			pt.TextIn(c, "More about it.", pt.AppFont, pt.Black)
		}
	})
}

func (*DisclosureWidget) Changed

func (d *DisclosureWidget) Changed() bool

Changed reports whether the user opened or closed the triangle since the last frame.

func (*DisclosureWidget) Disabled

func (d *DisclosureWidget) Disabled(dis bool) *DisclosureWidget

Disabled dims the triangle and makes it take no input while d is true.

func (*DisclosureWidget) Element

func (d *DisclosureWidget) Element() ui.Element

Element returns the triangle's element.

type DocumentTabsWidget

type DocumentTabsWidget struct {
	// contains filtered or unexported fields
}

DocumentTabsWidget is a row of document tabs being built.

func DocumentTabs

func DocumentTabs(c *ui.Context, selected *int, titles []string, fn func(i int)) *DocumentTabsWidget

DocumentTabs builds the tabs of the documents of a window, choosing *selected, over the pane fn builds for the document chosen. Command-W, while the tabs have the keyboard focus, and the Close item of a tab's context menu close a document: DocumentTabs reports the index of the one closed, or -1, for the app to remove it. The arrows move between the tabs.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	docs := []string{"Letter", "Notes"}
	sel := 0
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		tabs := pt.DocumentTabs(c, &sel, docs, func(i int) {
			pt.TextIn(c, "The text of "+docs[i], pt.AppFont, pt.Black)
		})
		if i := tabs.Closed(); i >= 0 {
			docs = append(docs[:i:i], docs[i+1:]...)
		}
	})
}

func (*DocumentTabsWidget) Changed

func (w *DocumentTabsWidget) Changed() bool

Changed reports whether the user chose another document since the last frame.

func (*DocumentTabsWidget) Closed

func (w *DocumentTabsWidget) Closed() int

Closed returns the index of the tab whose close box the user clicked since the last frame, or -1.

func (*DocumentTabsWidget) Element

func (w *DocumentTabsWidget) Element() ui.Element

Element returns the element of the tabs and their pane.

type FileDialogState

type FileDialogState struct {
	// Path holds the folders opened, from one of the roots in; empty, the
	// dialog shows the roots, as the desktop. The dialog finds them again
	// by title in the tree it is given each frame.
	Path []*TreeNode
	// Name is the name to save as.
	Name string
	// NewFolder, if set, makes a folder in the one shown (nil: the
	// desktop) for the save dialog's New Folder button, and returns its
	// title, for the dialog to go into it.
	NewFolder func(in *TreeNode) string
	// contains filtered or unexported fields
}

FileDialogState is where an open or save dialog is, kept by the app between showings: the folders from the outermost down to the one it shows, and the name typed to save as.

type FindAction

type FindAction int

FindAction is what the user asked of a find and replace dialog.

const (
	FindNone FindAction = iota
	FindNext
	ReplaceOne
	ReplaceEvery
)

The actions of a find and replace dialog.

func FindReplace

func FindReplace(c *ui.Context, open *bool, st *FindState) FindAction

FindReplace shows a find and replace dialog while *open: fields of what to find and what to replace it with, the options to match case and whole words, and the buttons Replace All, Replace and Find (the default). It returns what the user pressed, for the app to do it to its text, as with Find and ReplaceAll, and the select methods of its text area.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	text := "One cat, two cats."
	open := true
	st := &pt.FindState{Query: "cat", With: "dog"}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		area := pt.TextArea(c, &text)
		switch pt.FindReplace(c, &open, st) {
		case pt.FindNext:
			_, from := area.Selection()
			if a, b := pt.Find(text, st.Query, from, st.Options); a >= 0 {
				area.Select(a, b)
			}
		case pt.ReplaceEvery:
			var n int
			text, n = pt.ReplaceAll(text, st.Query, st.With, st.Options)
			st.Note = fmt.Sprint(n, " replaced")
		}
	})
	fmt.Println(pt.ReplaceAll(text, "cat", "dog", pt.FindOptions{WholeWord: true}))
}
Output:
One dog, two cats. 1

type FindOptions

type FindOptions struct {
	MatchCase, WholeWord bool
}

FindOptions says how Find matches.

type FindState

type FindState struct {
	Query, With string
	Options     FindOptions
	// Note is what the dialog says under its fields, as "3 replaced";
	// screen readers read it out when it shows.
	Note string
	// contains filtered or unexported fields
}

FindState is what a find and replace dialog edits, kept by the app.

type Font

type Font int

Font is one of the two bitmap faces of the library, from platinum-fonts: SystemFont, Platinum Sans Bold, for menus, buttons, labels and titles, and AppFont, Platinum Sans Small, for documents, lists and the names of icons. East Asian characters are drawn with the faces SetEastAsian gives, and other characters the faces lack in the system's font.

const (
	SystemFont Font = iota
	AppFont
)

The two faces of the library.

func (Font) Ascent

func (f Font) Ascent() int

Ascent returns the rows of the font above its baseline.

func (Font) CapHeight

func (f Font) CapHeight() int

CapHeight returns the height of the font's capitals.

func (Font) Has

func (f Font) Has(r rune) bool

Has reports whether the font's own face draws r; East Asian characters draw with the faces SetEastAsian gives, and others in the system's font, or as a box where it has none.

func (Font) Height

func (f Font) Height() int

Height returns the height of the font's lines, without leading.

func (Font) Measure

func (f Font) Measure(s string) int

Measure returns the width of s on one line, in pixels.

func (Font) MeasureStyled added in v0.2.0

func (f Font) MeasureStyled(s string, style TextStyle) int

MeasureStyled returns the width of s on one line in a style, as TextStyled draws it: bold glyphs, the room italic takes at the end of the run, and the scale; without the tracking after the last glyph, as Measure.

func (Font) Truncate

func (f Font) Truncate(s string, width int) string

Truncate returns s cut with an ellipsis to fit in width pixels, or s as it is when it fits.

type FontChoice

type FontChoice struct {
	Family                  string
	Size                    float64
	Bold, Italic, Underline bool
}

FontChoice is a font, size and style as a font picker chooses them.

type FontPickerWidget

type FontPickerWidget struct {
	// contains filtered or unexported fields
}

FontPickerWidget is a font picker being built.

func FontPicker

func FontPicker(c *ui.Context, ch *FontChoice, families []string) *FontPickerWidget

FontPicker builds a panel choosing a font, as a Format menu's dialog: a list of families, a list of sizes with a field for any other, the styles as check boxes, and a sample of the choice. families are the families the app has. The sample is drawn in the library's regular face, in the style chosen.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	choice := pt.FontChoice{Family: "Serif", Size: 12}
	page := pt.PageSetupState{Scale: 100, Margin: 36}
	setup := false
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.FontPicker(c, &choice, []string{"Sans", "Serif", "Mono"})
		if pt.PageSetup(c, &setup, &page) {
			fmt.Println("paper", pt.Papers[page.Paper].Name)
		}
	})
}

func (*FontPickerWidget) Changed

func (w *FontPickerWidget) Changed() bool

Changed reports whether the user changed the choice since the last frame.

func (*FontPickerWidget) Element

func (w *FontPickerWidget) Element() ui.Element

Element returns the picker's element.

type IconItem

type IconItem struct {
	Name string
	Icon *ui.Bitmap
}

IconItem is an item of an icon view: a name under a 32×32 picture.

type IconViewWidget

type IconViewWidget struct {
	// contains filtered or unexported fields
}

IconViewWidget is an icon view being built.

func IconView

func IconView(c *ui.Context, items []IconItem, selected *int) *IconViewWidget

IconView builds a grid of icons with their names under them, choosing *selected (-1 for none): a click chooses an icon, darkening it and inverting its name, and a double click activates it; with the keyboard focus, the arrows, Page Up and Down, Home and End move the choice into view and Return activates. A scroll bar at the right and the wheel scroll the icons when they do not all fit. Give it a size.

The counterpart among MyGo's own controls is ui.GridView.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{icons: []pt.IconItem{{Name: "Alpha"}, {Name: "Beta"}}, icon: -1}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		if pt.IconView(c, a.icons, &a.icon).Submitted() {
			fmt.Println("open", a.icons[a.icon].Name)
		}
	})
}

func (*IconViewWidget) Changed

func (w *IconViewWidget) Changed() bool

Changed reports whether the user chose another icon since the last frame.

func (*IconViewWidget) Element

func (w *IconViewWidget) Element() ui.Element

Element returns the icon view's element, to size it.

func (*IconViewWidget) Label

func (w *IconViewWidget) Label(s string) *IconViewWidget

Label names the icon view.

func (*IconViewWidget) Submitted

func (w *IconViewWidget) Submitted() bool

Submitted reports whether the user double-clicked an icon, or pressed Return, since the last frame, as MyGo's lists report it.

type ListBoxWidget

type ListBoxWidget struct {
	// contains filtered or unexported fields
}

ListBoxWidget is a list box being built.

func ListBox

func ListBox(c *ui.Context, selected *int, items []string) *ListBoxWidget

ListBox builds a list box of items choosing *selected (-1 for none): a white, sunken box of rows, the chosen one highlighted, with a scroll bar at its right when the rows do not all fit. A click chooses a row, and a double click activates it; with the keyboard focus, the arrows, Page Up and Down, Home and End move the choice, typing the start of an item chooses it, and Return activates it. Give it a size; its height in rows is its height divided by ListRowHeight.

The counterpart among MyGo's own controls is ui.List.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{}
	fonts := []string{"Sans", "Serif", "Mono"}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		lb := pt.ListBox(c, &a.font, fonts)
		lb.Element().Size(160, 96).Label("Fonts")
		if lb.Submitted() {
			fmt.Println("chose", fonts[a.font])
		}
	})
}

func (*ListBoxWidget) Arrows

func (w *ListBoxWidget) Arrows(rows []bool) *ListBoxWidget

Arrows draws an arrow at the right of the rows marked, as a column view marks the items that hold others.

func (*ListBoxWidget) Changed

func (w *ListBoxWidget) Changed() bool

Changed reports whether the user chose another row since the last frame.

func (*ListBoxWidget) Dim

func (w *ListBoxWidget) Dim(rows []bool) *ListBoxWidget

Dim draws the rows marked in Gray8 and keeps them from being chosen, as a save dialog shows the files it is not saving over.

func (*ListBoxWidget) Disabled

func (w *ListBoxWidget) Disabled(d bool) *ListBoxWidget

Disabled dims the list and makes it take no input while d is true.

func (*ListBoxWidget) Element

func (w *ListBoxWidget) Element() ui.Element

Element returns the list box's element, to size it.

func (*ListBoxWidget) FocusRing

func (w *ListBoxWidget) FocusRing(on bool) *ListBoxWidget

FocusRing(false) leaves the focus ring to what holds the list, as a column view draws one around all its columns.

func (*ListBoxWidget) Icons

func (w *ListBoxWidget) Icons(icons [][]string) *ListBoxWidget

Icons draws a small picture, at most 16×16 as rows for DrawIcon, at the left of each row, its text after it.

func (*ListBoxWidget) Label

func (w *ListBoxWidget) Label(s string) *ListBoxWidget

Label names the list box.

func (*ListBoxWidget) ScrollBarAlways

func (w *ListBoxWidget) ScrollBarAlways() *ListBoxWidget

ScrollBarAlways keeps the scroll bar at the list's right when its rows all fit too, as a flat track.

func (*ListBoxWidget) Submitted

func (w *ListBoxWidget) Submitted() bool

Submitted reports whether the user double-clicked a row, or pressed Return, since the last frame, as MyGo's lists report it.

type Menu struct {
	// Title is the menu's title on the bar.
	Title string
	// Icon shows a small picture in place of the title, given as rows of
	// '#' (black), 'o' (the accent's dark color), ':' (gray) and '.' or ' '
	// (nothing), at most 16 rows tall. Title still names it for assistive
	// technology.
	Icon []string
	// IconTitle shows the title beside the icon, as an application menu
	// shows the application's name.
	IconTitle bool
	// Right places the menu at the right end of the bar, after those
	// before it there, as the clock and the application menu; the last is
	// rightmost.
	Right bool
	// Items are the menu's items. A menu without items shows its title
	// alone and does not open, as a clock.
	Items []MenuItem
	// Action runs when the user clicks the title of a menu without items,
	// as a clock clicked to show the date.
	Action func()
}

Menu is a menu of a menu bar.

func SizeMenu

func SizeMenu(d *RichText) Menu

SizeMenu returns a Size menu for a document, to add to the menu bar: an item for each scale, named by its size in points (the App face is 11), the selection's checked.

type MenuItem struct {
	// Title is what the item says.
	Title string
	// Key, with Mods, is the item's keyboard equivalent, which chooses it
	// wherever the focus is; Mods of 0 is ui.Cmd. The menu shows it at the
	// item's right.
	Key  ui.Key
	Mods ui.Modifiers
	// Disabled dims the item, which the user cannot choose.
	Disabled bool
	// Checked shows a check mark before the title.
	Checked bool
	// Separator makes the item an etched line between groups of items.
	Separator bool
	// Submenu makes the item open a menu of its own, to its right.
	Submenu []MenuItem
	// Action runs when the user chooses the item, in a frame after the
	// one that built the menu: it should change the app's state, not
	// variables of the view that built it.
	Action func()
}

MenuItem is an item of a menu, or a separator.

func SeparatorItem

func SeparatorItem() MenuItem

SeparatorItem returns a separator, for a menu's list of items, as MyGo's menus have Separator; Separator draws one in a window.

type NumberFieldWidget

type NumberFieldWidget struct {
	// contains filtered or unexported fields
}

NumberFieldWidget is a number field being built.

func NumberField

func NumberField(c *ui.Context, value *float64, lo, hi, step float64, digits int) *NumberFieldWidget

NumberField builds a text field of a number between lo and hi with little arrows beside it stepping it by step. Typing changes the number once the text is a number; Return or leaving the field puts the text back in order. digits sets how many decimals it shows.

The counterpart among MyGo's own controls is ui.NumberInput.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{copies: 1}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.NumberField(c, &a.copies, 1, 99, 1, 0).Label("Copies")
		pt.Stepper(c, &a.volume, 0, 10, 1).Label("Level")
		pt.SearchField(c, &a.query).Width(160).Label("Search")
	})
}

func (*NumberFieldWidget) Changed

func (w *NumberFieldWidget) Changed() bool

Changed reports whether the user changed the number since the last frame.

func (*NumberFieldWidget) Element

func (w *NumberFieldWidget) Element() ui.Element

Element returns the field's element, its text field and arrows in a row.

func (*NumberFieldWidget) Label

Label names the field for assistive technology and tests: the group, the field, and its little arrows, as "Change <l>".

type PageSetupState

type PageSetupState struct {
	// Paper is an index of Papers; Landscape turns the page.
	Paper     int
	Landscape bool
	// Scale is the size of the printing, in percent; Margin the margin
	// around it, in points.
	Scale, Margin float64
}

PageSetupState is what a page setup dialog chooses, kept by the app.

type Pen

type Pen struct {
	P *ui.Painter
	// X and Y are the corner of the box on the window, and W and H its
	// size, in whole DIPs. The pen's coordinates start at the corner.
	X, Y, W, H int
	// contains filtered or unexported fields
}

Pen draws on whole pixels of the Platinum grid, one DIP each: it rounds the box it draws in to whole DIPs, so that every line it draws is one pixel wide at a scale of 1 and a whole block of pixels at any whole scale. Controls draw with it, and so can controls of your own.

func NewPen

func NewPen(p *ui.Painter, r ui.Rect) Pen

NewPen returns a pen drawing in r, rounded to whole DIPs.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	render(func(c *ui.Context) {
		ui.Box(c).Size(60, 24).Draw(func(p *ui.Painter, r ui.Rect) {
			pn := pt.NewPen(p, r)
			pt.DrawButton(pn, "Drawn", pt.StateNormal)
		})
	})
}

func (Pen) Bevel

func (pn Pen) Bevel(x, y, w, h int, tl, br ui.Color)

Bevel draws a ring one pixel wide just inside the w×h box at x, y: tl along its top and left edges, br along its bottom and right ones. The two corners where they meet, top right and bottom left, are left unpainted, for the face under them to show, as the Platinum bevels have them.

func (Pen) Bitmap

func (pn Pen) Bitmap(x, y int, rows []string, c ui.Color)

Bitmap draws a small picture given as rows of '#' (ink) and other characters (paper) with its corner at x, y.

func (Pen) Clip

func (pn Pen) Clip(x, y, w, h int, fn func())

Clip draws what fn draws within the w×h box at x, y only.

func (Pen) Dimmed

func (pn Pen) Dimmed(d bool) Pen

Dimmed returns the pen for drawing a control in a window in the background, while d: Black and the grays darker than Gray8 come out Gray8, and colors as a light gray of their lightness, as Platinum dims the controls of a window that is not in front.

func (Pen) Dot

func (pn Pen) Dot(x, y int, c ui.Color)

Dot fills the pixel at x, y.

func (Pen) Faded

func (pn Pen) Faded(f bool) Pen

Faded returns the pen for drawing an element that MyGo paints at half opacity, as it paints the elements it disables: it draws each color so that, half over the window's face (Gray2) beneath, it comes out as the color asked for. Colors lighter than the face can come out a little darker than asked: white comes out Gray1.

func (Pen) FillRound

func (pn Pen) FillRound(x, y, w, h, r int, c ui.Color)

FillRound fills the w×h box at x, y, its corners cut as RoundFrame cuts them.

func (Pen) Frame

func (pn Pen) Frame(x, y, w, h int, c ui.Color)

Frame outlines the w×h box at x, y with a line one pixel wide.

func (Pen) HLine

func (pn Pen) HLine(x, y, w int, c ui.Color)

HLine draws a line w pixels long rightward from x, y.

func (Pen) Pattern

func (pn Pen) Pattern(x, y, w, h int, pat [8]byte, fg, bg ui.Color)

Pattern fills the w×h box at x, y with an 8×8 pattern: bit 7-x of row y of pat paints fg, the others bg (unless bg is transparent). The pattern is anchored at the window's corner, so that neighbors line up.

func (Pen) Rect

func (pn Pen) Rect(x, y, w, h int, c ui.Color)

Rect fills w×h pixels at x, y.

func (Pen) RoundFrame

func (pn Pen) RoundFrame(x, y, w, h, r int, line, face ui.Color)

RoundFrame outlines the w×h box at x, y with a line one pixel wide whose corners are cut in steps of r pixels (0 to 4), and fills it with face unless face is transparent.

func (Pen) Sub

func (pn Pen) Sub(x, y, w, h int) Pen

Sub returns a pen drawing in the w×h box at x, y of this one.

func (Pen) Text

func (pn Pen) Text(x, y int, s string, f Font, c ui.Color) int

Text draws s with its cell's top at x, y, in c, and returns the x after it.

func (Pen) TextCentered

func (pn Pen) TextCentered(x, y, w, h int, s string, f Font, c ui.Color)

TextCentered draws s centered in the w×h box at x, y, its capitals centered on the box's middle.

func (Pen) TextMiddle

func (pn Pen) TextMiddle(x, y, h int, s string, f Font, c ui.Color) int

TextMiddle draws s from x, its capitals centered on the middle of the h pixels from y.

func (Pen) TextScaled

func (pn Pen) TextScaled(x, y int, s string, f Font, c ui.Color, k int) int

TextScaled draws s as Text does, each pixel of its glyphs a k×k block, for large type such as a clock's, and returns the x after it. Characters no face draws show as the face's box.

func (Pen) TextStyled

func (pn Pen) TextStyled(x, y int, s string, f Font, c ui.Color, style TextStyle) int

TextStyled draws s as Text does, in style: bold in the bold faces, each glyph drawn again a pixel to its right and a pixel wider, as classic bitmap text was made bold; italic slanted to the right, each pair of rows a pixel right of the pair below, with the slant's room added after the run, East Asian characters staying upright; underlined with a line a pixel under the baseline; and at the style's scale, each pixel of all that k by k. Characters no face draws are drawn upright in the system's font. It returns the x after it.

func (Pen) VLine

func (pn Pen) VLine(x, y, h int, c ui.Color)

VLine draws a line h pixels long downward from x, y.

type PopupMenuWidget

type PopupMenuWidget struct {
	// contains filtered or unexported fields
}

PopupMenuWidget is a pop-up menu being built.

func PopupMenu

func PopupMenu(c *ui.Context, selected *int, label string, items []string) *PopupMenuWidget

PopupMenu builds a pop-up menu choosing *selected, an index of items: a beveled button showing the item chosen, with an arrow box at its right. Pressing it shows the menu over it, the chosen item over the button; releasing over an item chooses it, and a click without a drag leaves the menu open for a second click. With the keyboard focus, Space, Return, Up and Down open it. An item "-" is a separator. A label, if not empty, shows before the button and names it.

The counterpart among MyGo's own controls is ui.Select.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		if pt.PopupMenu(c, &a.sort, "Sort by:", []string{"Name", "Date", "-", "Size"}).Changed() {
			fmt.Println("sorted")
		}
	})
}

func (*PopupMenuWidget) Changed

func (w *PopupMenuWidget) Changed() bool

Changed reports whether the user chose another item since the last frame.

func (*PopupMenuWidget) Disabled

func (w *PopupMenuWidget) Disabled(d bool) *PopupMenuWidget

Disabled dims the pop-up menu and makes it take no input while d is true.

func (*PopupMenuWidget) Element

func (w *PopupMenuWidget) Element() ui.Element

Element returns the pop-up menu's element.

type PopupWindowState

type PopupWindowState struct {
	// X places the window's left side in its parent; W is its width and
	// H its height when open, under its tab.
	X, W, H int
	// Open shows the window over the bottom of its parent, its tab on top;
	// closed, the tab alone sits on the bottom edge.
	Open bool
}

PopupWindowState is where a pop-up window is and whether it is open, which the app keeps.

type PopupWindowWidget

type PopupWindowWidget struct {
	// contains filtered or unexported fields
}

PopupWindowWidget is a pop-up window being built.

func PopupWindow(c *ui.Context, st *PopupWindowState, title string, opts WindowOptions, fn func()) *PopupWindowWidget

PopupWindow builds a window docked at the bottom of its parent, as the classic desktop's pop-up windows were: a tab showing title stands on the window's top edge, and the window rises from the bottom of the parent while st.Open, or hides, leaving the tab on the bottom edge. A click on the tab, or Space or Enter while it has the keyboard focus, opens and closes the window; dragging the tab sideways moves it; dragging it up tears the window off, which TornOff reports for the app to show it as a Window instead. Command-W closes it. Of opts, Active, Interactive and Dragging mean what they do for Window. Build it in a parent that positions absolutely, as Window.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	dock := pt.PopupWindowState{X: 40, W: 260, H: 160, Open: true}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Box(c).Fill().Children(func() {
			w := pt.PopupWindow(c, &dock, "Projects", pt.WindowOptions{Active: true}, func() {
				pt.EmptyState(c, "No projects")
			})
			if w.TornOff() {
				// Show it as a Window from now on.
			}
		})
	})
	fmt.Println(dock.Open)
}
Output:
true

func (*PopupWindowWidget) Activated

func (w *PopupWindowWidget) Activated() bool

Activated reports whether the user pressed the window since the last frame, which brings a window in the background to the front.

func (*PopupWindowWidget) Closed

func (w *PopupWindowWidget) Closed() bool

Closed reports whether the user pressed Command-W in the window since the last frame.

func (*PopupWindowWidget) Element

func (w *PopupWindowWidget) Element() ui.Element

Element returns the pop-up window's element.

func (*PopupWindowWidget) Tab

func (w *PopupWindowWidget) Tab() ui.Element

Tab returns the element of the window's tab, for the app to take drops on it (ui.Drop), as the classic pop-up windows took items dropped on their tabs.

func (*PopupWindowWidget) TornOff

func (w *PopupWindowWidget) TornOff() bool

TornOff reports whether the user dragged the tab up, tearing the window off the bottom edge, since the last frame.

type RadioWidget

type RadioWidget struct {
	// contains filtered or unexported fields
}

RadioWidget is a radio button being built.

func Radio

func Radio[T comparable](c *ui.Context, selected *T, value T, label string) *RadioWidget

Radio builds a radio button labeled label that sets *selected to value: a small beveled circle with a dot while *selected is value. Put the buttons of one choice in a RadioGroup, which makes them one stop of Tab that the arrows move within.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{size: "small"}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.RadioGroup(c, func() {
			pt.Radio(c, &a.size, "small", "Small")
			pt.Radio(c, &a.size, "large", "Large")
		})
	})
}

func (*RadioWidget) Changed

func (b *RadioWidget) Changed() bool

Changed reports whether the user chose the button since the last frame.

func (*RadioWidget) Disabled

func (b *RadioWidget) Disabled(d bool) *RadioWidget

Disabled dims the radio button and makes it take no input while d is true.

func (*RadioWidget) Element

func (b *RadioWidget) Element() ui.Element

Element returns the radio button's element.

type RichText

type RichText struct {
	// Text is the document's text. Setting it from outside keeps the
	// styles of the runes at the same places.
	Text string
	// contains filtered or unexported fields
}

RichText is a document of styled text, kept by the app: its text, the style of each of its runes, and the alignment of each of its paragraphs. A RichTextArea edits it, and a FormatBar and a SizeMenu style it.

func NewRichText

func NewRichText(text string) *RichText

NewRichText returns a document of text in the plain style.

func (*RichText) Align

func (d *RichText) Align() Align

Align returns the alignment the format bar shows: of the paragraph holding the caret, or the start of the selection.

func (*RichText) Aligns

func (d *RichText) Aligns() []Align

Aligns returns the alignment of each of the document's paragraphs, the lines between newlines, as for saving it with its runs.

func (*RichText) Runs

func (d *RichText) Runs() []Run

Runs returns the document as runs of one style each, as for saving it.

func (*RichText) SetAlign

func (d *RichText) SetAlign(align Align)

SetAlign aligns the paragraphs the selection touches, or the one holding the caret, as one edit to undo.

func (*RichText) SetAligns

func (d *RichText) SetAligns(aligns []Align)

SetAligns aligns the document's paragraphs, from the first; those it leaves out are aligned left.

func (*RichText) SetRuns

func (d *RichText) SetRuns(runs []Run)

SetRuns replaces the document with runs.

func (*RichText) SetSize

func (d *RichText) SetSize(k int)

SetSize scales the selection, or, with none, what is typed next, to k, from 1 to MaxScale.

Example
package main

import (
	"fmt"

	pt "github.com/firede/mygo-platinum"
)

func main() {
	doc := pt.NewRichText("Minutes\nWe met at noon.")
	doc.SetAligns([]pt.Align{pt.AlignCenter})
	// The menu bar of the app offers a Size menu for the document.
	sizes := pt.SizeMenu(doc)
	fmt.Println(sizes.Title, sizes.Items[1].Title, doc.Aligns())
}
Output:
Size 22 Point [1 0]

func (*RichText) Size

func (d *RichText) Size() int

Size returns the scale of the selection, where all of it has one, or 0; with no selection, the scale typing takes. See TextStyle.Scale.

func (*RichText) Style

func (d *RichText) Style() TextStyle

Style returns the style the format bar shows: the styles all of the selection has, at the scale Size reports (1 where it is mixed), or, with none, the style typing takes — that of the rune before the caret, unless the user chose another since the caret moved.

func (*RichText) Toggle

func (d *RichText) Toggle(s TextStyle)

Toggle turns style s on or off: over the selection — on, unless all of it has it already — or, with none, for what is typed next.

type RulerState

type RulerState struct {
	Left, Right int
	First       int
	// contains filtered or unexported fields
}

RulerState is the margins a ruler sets, in pixels from its left, and the first-line indent, from the left margin.

type Run

type Run struct {
	Text  string
	Style TextStyle
}

Run is a stretch of a document in one style.

type ScrollBarWidget

type ScrollBarWidget struct {
	// contains filtered or unexported fields
}

ScrollBarWidget is a scroll bar being built.

func ScrollBar

func ScrollBar(c *ui.Context, value *float64, visible, total float64) *ScrollBarWidget

ScrollBar builds a vertical scroll bar setting *value, the offset of the content in view, from 0 to total-visible: arrows at both ends step it, a click in the track pages it, and the thumb, as long as the part of the content in view is of the whole, drags it. With nothing to scroll, it shows an empty track. Its element is ScrollBarWidth wide; give it a height, or let it stretch.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	top := 0.0
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.ScrollBar(c, &top, 10, 100).Step(1).Element().Height(160).Label("Rows")
	})
}

func (*ScrollBarWidget) Changed

func (s *ScrollBarWidget) Changed() bool

Changed reports whether the user scrolled since the last frame.

func (*ScrollBarWidget) Element

func (s *ScrollBarWidget) Element() ui.Element

Element returns the scroll bar's element.

func (*ScrollBarWidget) Horizontal

func (s *ScrollBarWidget) Horizontal() *ScrollBarWidget

Horizontal makes the bar run left to right, ScrollBarWidth tall.

func (*ScrollBarWidget) Inactive

func (s *ScrollBarWidget) Inactive() *ScrollBarWidget

Inactive draws the bar as in a window in the background: a flat gray track, no thumb and no arrows. Bars in a Window in the background draw so of themselves.

func (*ScrollBarWidget) Label

func (s *ScrollBarWidget) Label(l string) *ScrollBarWidget

Label names the scroll bar.

func (*ScrollBarWidget) Step

func (s *ScrollBarWidget) Step(step float64) *ScrollBarWidget

Step sets how far the arrows move the content, 16 by default.

type ScrollPart

type ScrollPart int

ScrollPart is a part of a scroll bar.

const (
	ScrollNone ScrollPart = iota
	ScrollUpArrow
	ScrollDownArrow
	ScrollPageUp
	ScrollPageDown
	ScrollThumb
)

The parts of a scroll bar.

type SegmentedWidget

type SegmentedWidget struct {
	// contains filtered or unexported fields
}

SegmentedWidget is a segmented control being built.

func Segmented

func Segmented(c *ui.Context, selected *int, labels ...string) *SegmentedWidget

Segmented builds a row of bevel buttons joined into one control, of which one, *selected, is pressed in: a choice of a few views or modes. The arrows move the choice while it has the keyboard focus.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	align := 1
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Segmented(c, &align, "Left", "Center", "Right").Label("Alignment")
	})
	fmt.Println(align)
}
Output:
1

func (*SegmentedWidget) Changed

func (w *SegmentedWidget) Changed() bool

Changed reports whether the user chose another segment since the last frame.

func (*SegmentedWidget) Element

func (w *SegmentedWidget) Element() ui.Element

Element returns the control's element.

func (*SegmentedWidget) Label

func (w *SegmentedWidget) Label(s string) *SegmentedWidget

Label names the segmented control.

type SheetState

type SheetState struct {
	Cells map[Cell]string
	// Cursor is the cell chosen; Anchor the other corner of the range
	// selected with Shift.
	Cursor, Anchor Cell
	// Editing is the text being typed into the cursor's cell, while
	// IsEditing.
	Editing   string
	IsEditing bool
	// NoFocusRing draws no ring around the sheet while it has the keyboard
	// focus, as for a sheet that fills its window.
	NoFocusRing bool
	// contains filtered or unexported fields
}

SheetState is a sheet's cells and what the user does to them, kept by the app: the text of each cell as typed (numbers, text, or formulas beginning with "="), the cell chosen and the range selected, the cell being edited, and how far the sheet is scrolled.

func NewSheetState

func NewSheetState() *SheetState

NewSheetState returns an empty sheet.

func (*SheetState) Value

func (s *SheetState) Value(c Cell) string

Value returns what a cell shows: its number or text, or the result of its formula, or an error such as "#REF!".

type SheetWidget

type SheetWidget struct {
	// contains filtered or unexported fields
}

SheetWidget is a sheet being built.

func Sheet

func Sheet(c *ui.Context, st *SheetState, rows, cols int) *SheetWidget

Sheet builds a grid of cells of rows rows and cols columns, as a spreadsheet: lettered column headers, numbered rows, and the cells' values right-aligned when they are numbers. A click chooses a cell (Shift extends the range); with the keyboard focus, the arrows move the cursor (Shift extends), typing starts editing the cell, Return commits and moves down, Tab commits and moves right (from the last column, on to the next control; Shift-Tab back from the first), Escape cancels, Delete clears the range. Pair it with a FormulaBar to show and edit the cursor's text.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	st := pt.NewSheetState()
	st.Cells[pt.Cell{Col: 0, Row: 0}] = "12"
	st.Cells[pt.Cell{Col: 0, Row: 1}] = "=A1*2"
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Column(c).Fill().Children(func() {
			pt.FormulaBar(c, st)
			pt.Sheet(c, st, 100, 26).Element().Grow(1).FillWidth()
		})
	})
	fmt.Println(st.Value(pt.Cell{Col: 0, Row: 1}))
}
Output:
24

func (*SheetWidget) Changed

func (w *SheetWidget) Changed() bool

Changed reports whether the user changed a cell since the last frame.

func (*SheetWidget) Element

func (w *SheetWidget) Element() ui.Element

Element returns the sheet's element, to size it.

func (*SheetWidget) Label

func (w *SheetWidget) Label(s string) *SheetWidget

Label names the sheet.

type SliderWidget

type SliderWidget struct {
	// contains filtered or unexported fields
}

SliderWidget is a slider being built.

func Slider

func Slider(c *ui.Context, value *float64, lo, hi float64) *SliderWidget

Slider builds a horizontal slider setting *value between lo and hi: a sunken track and a pointed thumb that the pointer drags, and the arrows, Page Up and Down, Home and End move while it has the keyboard focus. Label it for assistive technology.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.Slider(c, &a.volume, 0, 100).Width(160).Ticks(5).Label("Volume")
	})
}

func (*SliderWidget) Changed

func (s *SliderWidget) Changed() bool

Changed reports whether the user moved the slider since the last frame.

func (*SliderWidget) Disabled

func (s *SliderWidget) Disabled(d bool) *SliderWidget

Disabled dims the slider and makes it take no input while d is true.

func (*SliderWidget) Element

func (s *SliderWidget) Element() ui.Element

Element returns the slider's element.

func (*SliderWidget) Label

func (s *SliderWidget) Label(l string) *SliderWidget

Label names the slider for assistive technology and tests.

func (*SliderWidget) Step

func (s *SliderWidget) Step(step float64) *SliderWidget

Step makes the slider move by step, as the keys do, and stop only on its multiples.

func (*SliderWidget) Ticks

func (s *SliderWidget) Ticks(n int) *SliderWidget

Ticks draws n tick marks under the track, evenly spaced from end to end.

func (*SliderWidget) Width

func (s *SliderWidget) Width(w int) *SliderWidget

Width sets the slider's width.

type State

type State int

State is how a control shows: normal, pressed or disabled.

const (
	StateNormal State = iota
	StatePressed
	StateDisabled
	// StateInactive is a control in a window in the background: its
	// outline and text gray, its bevels flat.
	StateInactive
)

The states a control draws in.

type StepperWidget

type StepperWidget struct {
	// contains filtered or unexported fields
}

StepperWidget is a pair of little arrows being built.

func Stepper

func Stepper(c *ui.Context, value *float64, lo, hi, step float64) *StepperWidget

Stepper builds the little arrows: two small beveled halves, up and down, that add step to *value and take it away, between lo and hi, again and again while held. Up and Down do the same while it has the keyboard focus. Label it for assistive technology.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	copies := 2.0
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Row(c).Gap(4).AlignItems(ui.Center).Children(func() {
			pt.TextIn(c, fmt.Sprint(copies), pt.AppFont, pt.Black)
			pt.Stepper(c, &copies, 1, 99, 1).Label("Copies")
		})
	})
	fmt.Println(copies)
}
Output:
2

func (*StepperWidget) Changed

func (s *StepperWidget) Changed() bool

Changed reports whether the user changed the value since the last frame.

func (*StepperWidget) Disabled

func (s *StepperWidget) Disabled(d bool) *StepperWidget

Disabled dims the arrows and makes them take no input while d is true.

func (*StepperWidget) Element

func (s *StepperWidget) Element() ui.Element

Element returns the arrows' element.

func (*StepperWidget) Label

func (s *StepperWidget) Label(l string) *StepperWidget

Label names the arrows for assistive technology and tests.

type TabControlWidget

type TabControlWidget struct {
	// contains filtered or unexported fields
}

TabControlWidget is a tab control being built.

func TabControl

func TabControl(c *ui.Context, selected *int, labels []string, fn func(i int)) *TabControlWidget

TabControl builds a tab control: a row of tabs labeled labels over a raised pane that shows the page of the tab chosen, *selected. fn builds that page, given its index. A click chooses a tab, and the arrows, Home and End move the choice while a tab has the keyboard focus.

The counterpart among MyGo's own controls is ui.Tabs.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.TabControl(c, &a.tab, []string{"General", "Sharing"}, func(i int) {
			pt.Label(c, []string{"General settings", "Who may connect"}[i])
		}).Element().Size(300, 120)
	})
}

func (*TabControlWidget) Changed

func (t *TabControlWidget) Changed() bool

Changed reports whether the user chose another tab since the last frame.

func (*TabControlWidget) Element

func (t *TabControlWidget) Element() ui.Element

Element returns the element holding the tabs and their pane.

type TableColumn

type TableColumn struct {
	Title string
	// Width is the column's width when the table first shows; the user
	// resizes it from there.
	Width int
	// Right aligns the column's cells at its right, as numbers.
	Right bool
	// Fixed keeps the user from sorting by the column.
	Fixed bool
	// Less, if set, orders rows a and b of the model by the column, for
	// cells whose text does not sort as their values do (as "2 K" and
	// "300 bytes"), or text to order as a language does (a collator of
	// golang.org/x/text/collate); otherwise cells sort as numbers where
	// both are, and as text otherwise, by code point.
	Less func(a, b int) bool
	// Icon, if set, gives a small picture (at most 16×16, as rows for
	// DrawIcon) for row r of the model, drawn at the left of its cell.
	Icon func(r int) []string
}

Column is a column of a table.

type TableState

type TableState struct {
	// Widths are the columns' widths; the table fills it from Column.Width.
	Widths []int
	// SortColumn sorts the rows by that column's cells (-1, or a Fixed
	// column, for the model's order); Descending turns the order over.
	SortColumn int
	Descending bool
	// Selected holds the rows selected, by their index in the model.
	Selected map[int]bool
	// ScrollBarAlways keeps the scroll bar when the rows fit too, as a
	// flat track.
	ScrollBarAlways bool
	// NoFocusRing draws no ring around the table while it has the keyboard
	// focus, as a list view filling a window draws none.
	NoFocusRing bool
	// contains filtered or unexported fields
}

TableState is what a table keeps between frames, held by the app: the widths of its columns, how its rows are sorted, which are selected, and how far it is scrolled.

func NewTableState

func NewTableState() *TableState

NewTableState returns the state of a table sorted by none of its columns.

type TableWidget

type TableWidget struct {
	// contains filtered or unexported fields
}

TableWidget is a table being built.

func Table

func Table(c *ui.Context, st *TableState, cols []TableColumn, rows int, cell func(row, col int) string) *TableWidget

Table builds a table of rows rows in columns, whose cells cell returns: column headers along its top, which sort the rows by their column as clicked (again to turn the order over) and resize it as their right edges are dragged, over rows that the pointer and the keyboard select — a click selects one, Shift extends the selection, Command adds or takes away a row. With the keyboard focus, Up and Down move the selection (Shift extends it), Command-A selects every row, Home and End go to the ends. Give it a size.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{table: pt.NewTableState()}
	rows := [][]string{{"Kiwi", "0.50"}, {"Fig", "2.50"}}
	cols := []pt.TableColumn{{Title: "Name", Width: 100}, {Title: "Price", Width: 60, Right: true}}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		t := pt.Table(c, a.table, cols, len(rows), func(r, col int) string { return rows[r][col] })
		t.Element().Size(200, 100).Label("Prices")
		if t.Changed() {
			fmt.Println(len(a.table.Selected), "selected")
		}
	})
}

func (*TableWidget) Changed

func (w *TableWidget) Changed() bool

Changed reports whether the user changed the selection since the last frame.

func (*TableWidget) Cursor

func (w *TableWidget) Cursor() int

Cursor returns the model index of the row the arrows last moved to or a click chose, or -1 with no rows.

func (*TableWidget) Element

func (w *TableWidget) Element() ui.Element

Element returns the table's element, to size it.

func (*TableWidget) Label

func (w *TableWidget) Label(s string) *TableWidget

Label names the table.

func (*TableWidget) Order

func (w *TableWidget) Order() []int

Order returns the rows of the model in the order they show.

func (*TableWidget) Sorted

func (w *TableWidget) Sorted() bool

Sorted reports whether the user sorted the rows anew since the last frame.

func (*TableWidget) Submitted

func (w *TableWidget) Submitted() bool

Submitted reports whether the user double-clicked a row, or pressed Return, with rows selected, since the last frame, as MyGo's tables report it.

type TextFieldWidget

type TextFieldWidget struct {
	// contains filtered or unexported fields
}

TextFieldWidget is a text field or text area being built.

func RichTextArea

func RichTextArea(c *ui.Context, d *RichText) *TextFieldWidget

RichTextArea builds a box editing a document of styled text, as TextArea edits plain text: what is typed takes the style the format bar shows, and the lines wrap, aligned, at the box's width. Command-B, -I and -U toggle bold, italic and underline; Command-Shift-. and -, make the text a size larger and smaller. Give it a size.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	doc := pt.NewRichText("")
	doc.SetRuns([]pt.Run{{Text: "Dear "}, {Text: "Ada", Style: pt.Bold}, {Text: ","}})
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Column(c).Fill().Children(func() {
			pt.FormatBar(c, doc)
			pt.RichTextArea(c, doc).Label("Letter").Element().Grow(1).FillWidth()
		})
	})
	fmt.Println(doc.Text, len(doc.Runs()))
}
Output:
Dear Ada, 3

func SearchField

func SearchField(c *ui.Context, value *string) *TextFieldWidget

SearchField builds a text field for searching: a magnifier at its left, and a button at its right, once there is text, that clears it, as Escape does.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	query := ""
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.SearchField(c, &query).Width(180).Label("Search")
	})
	fmt.Printf("%q\n", query)
}
Output:
""

func TextArea

func TextArea(c *ui.Context, value *string) *TextFieldWidget

TextArea builds a box editing *value on many lines, which wrap at its width, with a scroll bar at its right. It edits as TextField does, and Return starts a new line. Give it a size.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	notes := "Dear diary,\ntoday the controls lined up on whole pixels."
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.TextArea(c, &notes).Label("Notes").Element().Size(240, 80)
	})
	fmt.Println(len(notes) > 0)
}
Output:
true

func TextField

func TextField(c *ui.Context, value *string) *TextFieldWidget

TextField builds a field editing *value on one line: a white, sunken box with a caret, in the regular face. It takes the keys of editing: the arrows (with Shift to select, Option by words, Command to the ends), Delete, the clipboard's Command-X, C and V, Command-Z to undo and Command-Shift-Z to redo, and text from input methods. Return submits it.

The counterpart among MyGo's own controls is ui.TextInput.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		if pt.TextField(c, &a.name).Width(180).Placeholder("Name").Label("Name").Submitted() {
			fmt.Println("renamed to", a.name)
		}
		pt.TextField(c, &a.query).Width(180).Password().Label("Password")
		pt.TextArea(c, &a.note).Label("Note").Element().Size(300, 120)
	})
}

func (*TextFieldWidget) Changed

func (w *TextFieldWidget) Changed() bool

Changed reports whether the user changed the text since the last frame.

func (*TextFieldWidget) Disabled

func (w *TextFieldWidget) Disabled(d bool) *TextFieldWidget

Disabled dims the field and makes it take no input while d is true.

func (*TextFieldWidget) Document

func (w *TextFieldWidget) Document(left, width int) *TextFieldWidget

Document makes a text area the content of a document window: white to the window's edges, its scroll bar laid over the window's line at its right and the lines above and below it as a window's own scroll bar is, no ring or outline of its own, and no focus ring — the window shows where typing goes. Its text starts left pixels in and wraps at width (0: at the area's width), as a ruler's margins set them.

func (*TextFieldWidget) Element

func (w *TextFieldWidget) Element() ui.Element

Element returns the field's element.

func (*TextFieldWidget) Indent

func (w *TextFieldWidget) Indent(first int) *TextFieldWidget

Indent starts the first line of each paragraph of a text area first pixels further in, as a ruler's first-line indent sets it.

func (*TextFieldWidget) Label

func (w *TextFieldWidget) Label(s string) *TextFieldWidget

Label names the field for assistive technology and tests.

func (*TextFieldWidget) MaxLength

func (w *TextFieldWidget) MaxLength(n int) *TextFieldWidget

MaxLength keeps the text to n characters at most.

func (*TextFieldWidget) Password

func (w *TextFieldWidget) Password() *TextFieldWidget

Password shows the field's text as bullets, keeps it from being copied or cut by any means, and gives assistive technology bullets in place of the text.

func (*TextFieldWidget) Placeholder

func (w *TextFieldWidget) Placeholder(s string) *TextFieldWidget

Placeholder shows text in gray while the field is empty.

func (*TextFieldWidget) Select

func (w *TextFieldWidget) Select(a, b int) *TextFieldWidget

Select selects the runes from a to b of the text field or area, as a match found, and scrolls them into view.

func (*TextFieldWidget) Selection

func (w *TextFieldWidget) Selection() (int, int)

Selection returns the runes selected in the text field or area, from a to b; a equals b at the caret.

func (*TextFieldWidget) Submitted

func (w *TextFieldWidget) Submitted() bool

Submitted reports whether the user pressed Return in a text field since the last frame.

func (*TextFieldWidget) Width

func (w *TextFieldWidget) Width(px int) *TextFieldWidget

Width sets the field's width.

type TextStyle

type TextStyle uint8

TextStyle is the style of a run of rich text.

const (
	Bold TextStyle = 1 << iota
	Italic
	Underline
)

The styles of rich text, combined as bits, with a scale (see Scaled).

func (TextStyle) Scale

func (s TextStyle) Scale() int

Scale returns the size of text in style s, as a multiple of the face's: text at scale k draws each pixel of its glyphs as k by k, as a bitmap font was drawn at a size it had no bitmaps for.

func (TextStyle) Scaled

func (s TextStyle) Scaled(k int) TextStyle

Scaled returns s at scale k, from 1 to MaxScale.

type Theme

type Theme struct {
	Accent Accent
	// Background is the face of windows and dialogs.
	Background ui.Color
}

Theme is what a window's Platinum controls take their look from.

func DefaultTheme

func DefaultTheme() *Theme

DefaultTheme returns the theme controls use where Use set none: the gray ramp with the Lavender accent.

func ThemeOf

func ThemeOf(c *ui.Context) *Theme

ThemeOf returns the theme the window of c draws with.

type ToolItem

type ToolItem struct {
	// Label names the item; it shows beside the icon, or alone, unless
	// IconOnly. Icon is a small picture for DrawIcon.
	Label    string
	Icon     []string
	IconOnly bool
	// On makes the item a toggle, pressed in while *On.
	On       *bool
	Disabled bool
	// Action runs when the user clicks the item.
	Action func()
	// Separator makes the item an etched line between groups.
	Separator bool
}

ToolItem is an item of a toolbar: a bevel button, or a separator.

func FormatItems

func FormatItems(d *RichText) []ToolItem

FormatItems returns the items of a format bar, to put in a toolbar of one's own.

type TreeNode

type TreeNode struct {
	Title string
	// Icon is a small picture for DrawIcon, at most 12 rows tall.
	Icon []string
	// Children are the items inside it; it shows a disclosure triangle when
	// it has any.
	Children []*TreeNode
	// Open shows its children under it.
	Open bool
	// Data is anything the app keeps with the item.
	Data any
}

TreeNode is an item of a tree view, which may hold others.

func OpenDialog

func OpenDialog(c *ui.Context, open *bool, st *FileDialogState, roots []*TreeNode) *TreeNode

OpenDialog shows a dialog choosing a file to open while *open, as the classic desktop's standard one: a modal box with no title bar; the folder it shows as a path pop-up; a list of what is in it, each with a small icon, with a scroll bar; and beside it the disk's icon and name, Eject, Desktop, and Cancel and Open under a line. The files are a tree: roots are what is on the desktop, and an item whose Children is not nil is a folder, which opening goes into. It returns the file the user opened, and closes, or nil.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	docs := &pt.TreeNode{Title: "Documents", Children: []*pt.TreeNode{{Title: "Letter"}}}
	disk := &pt.TreeNode{Title: "Disk", Children: []*pt.TreeNode{docs}}
	open := true
	st := &pt.FileDialogState{}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Box(c).Fill().Children(func() {
			if f := pt.OpenDialog(c, &open, st, []*pt.TreeNode{disk}); f != nil {
				// Open f.
			}
		})
	})
	fmt.Println(open, len(st.Path))
}
Output:
true 0

type TreeViewWidget

type TreeViewWidget struct {
	// contains filtered or unexported fields
}

TreeViewWidget is a tree view being built.

func TreeView

func TreeView(c *ui.Context, roots []*TreeNode, selected **TreeNode) *TreeViewWidget

TreeView builds a list of roots and the items inside them, as an outline: a disclosure triangle opens and closes an item, its children indented under it. It chooses *selected. A click chooses a row, a click on its triangle opens or closes it, and a double click activates it; with the keyboard focus, Up and Down move the choice, Right opens the item chosen or goes into it, Left closes it or goes to its parent, typing the start of a title chooses it, and Return activates. Give it a size.

The counterpart among MyGo's own controls is ui.Tree.

Example
package main

import (
	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{folders: []*pt.TreeNode{
		{Title: "Documents", Open: true, Children: []*pt.TreeNode{{Title: "Letters"}}},
		{Title: "Pictures"},
	}}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		pt.TreeView(c, a.folders, &a.folder).Element().Size(200, 120).Label("Folders")
	})
}

func (*TreeViewWidget) Changed

func (w *TreeViewWidget) Changed() bool

Changed reports whether the user chose another item since the last frame.

func (*TreeViewWidget) Element

func (w *TreeViewWidget) Element() ui.Element

Element returns the tree view's element, to size it.

func (*TreeViewWidget) Label

func (w *TreeViewWidget) Label(s string) *TreeViewWidget

Label names the tree view.

func (*TreeViewWidget) Submitted

func (w *TreeViewWidget) Submitted() bool

Submitted reports whether the user double-clicked an item, or pressed Return, since the last frame, as MyGo's lists report it.

type WindowOptions

type WindowOptions struct {
	// NoClose, NoZoom and NoCollapse leave out the boxes of the title bar,
	// and NoGrow the resize corner.
	NoClose, NoZoom, NoCollapse, NoGrow bool
	// Active draws the window as the one in front: its title bar striped
	// and its boxes shown. A window in the background shows a plain title
	// bar and dimmed title.
	Active bool
	// ZoomTo is the box the zoom box zooms the window to, in its parent;
	// zero zooms to the window's own size.
	ZoomTo [4]int
	// Modal draws the frame of a movable modal dialog: no close box, no
	// zoom or collapse box, no resize corner, and a thicker border.
	Modal bool
	// Interactive lets the content of a window in the background take
	// clicks, as a floating palette's does; otherwise its first click only
	// brings it to the front.
	Interactive bool
	// Dragging says a drag is under way, which a window in the background
	// lets drop in its content while it keeps its look; the app knows its
	// drags (ui.Element.Dragging).
	Dragging bool
	// Utility draws the frame of a floating utility window, as an
	// inspector or a palette: a narrow title bar with a small close box and
	// its title in the regular face, and a thin frame.
	Utility bool
	// Path is the folders a folder window's folder is in, the outermost
	// first: a Command-press on the title shows the window's title and
	// them as a menu, to go to one, which PathChosen reports.
	Path []string
}

WindowOptions says which parts a window's frame has.

type WindowPart

type WindowPart int

WindowPart is a part of a window's frame.

const (
	PartNone WindowPart = iota
	PartTitle
	PartClose
	PartZoom
	PartCollapse
	PartGrow
	PartContent
)

The parts of a window frame, as WindowPartAt finds them.

func WindowPartAt

func WindowPartAt(x, y float32, w, h int, opts WindowOptions, collapsed bool) WindowPart

WindowPartAt returns the part of a window w×h (title bar included, or collapsed) at x, y from its corner.

type WindowState

type WindowState struct {
	// X and Y place the window's outline in its parent, and W and H size
	// it, title bar and frame included. An H of 0 makes it as tall as its
	// content.
	X, Y, W, H int
	// MinW and MinH are as small as the grow box makes it (120×80 if
	// zero).
	MinW, MinH int
	// Collapsed shows the title bar alone, as a window shade rolled up.
	Collapsed bool
	// Zoomed shows the window at its zoomed size; the zoom box toggles it
	// with the size the user gave it, which Unzoomed keeps.
	Zoomed   bool
	Unzoomed [4]int
}

WindowState is where a window is and how it shows, which the app keeps: the window moves and resizes it as the user drags it.

type WindowWidget

type WindowWidget struct {
	// contains filtered or unexported fields
}

WindowWidget is a window being built.

func Window

func Window(c *ui.Context, st *WindowState, title string, opts WindowOptions, fn func()) *WindowWidget

Window builds a window of the desktop inside its parent, placed where st says: an outlined frame with a striped title bar showing title, a close box at its left, zoom and collapse boxes at its right and a resize corner at the bottom right, around the content fn builds. Dragging the title bar moves the window, dragging the corner resizes it, double-clicking the title bar rolls it up, and the boxes act when released over. Put the window in a parent that positions absolutely, as a full-window Box, and build the windows back to front.

Example
package main

import (
	"fmt"

	"github.com/egoist/mygo/ui"
	pt "github.com/firede/mygo-platinum"
)

type app struct {
	theme                *pt.Theme
	sound, details, bold bool
	size                 string
	volume, copies       float64
	sort, tab, font      int
	name, query, note    string
	confirm, find        bool
	frame                pt.WindowState
	split                float32
	scroll               ui.ScrollState
	table                *pt.TableState
	folders              []*pt.TreeNode
	folder               *pt.TreeNode
	icons                []pt.IconItem
	icon                 int
}

func render(view func(c *ui.Context)) { ui.Render(view, 400, 300, 1) }

func main() {
	a := &app{frame: pt.WindowState{X: 20, Y: 20, W: 240, H: 160}}
	render(func(c *ui.Context) {
		pt.Use(c, nil)
		ui.Box(c).Fill().Children(func() {
			w := pt.Window(c, &a.frame, "Notes", pt.WindowOptions{Active: true}, func() {
				pt.Label(c, "Inside the window")
			})
			if w.Closed() {
				fmt.Println("closed")
			}
		})
	})
}

func (*WindowWidget) Activated

func (w *WindowWidget) Activated() bool

Activated reports whether the user pressed the window since the last frame, which brings a window in the background to the front.

func (*WindowWidget) Closed

func (w *WindowWidget) Closed() bool

Closed reports whether the user clicked the close box, or pressed Command-W in the window, since the last frame.

func (*WindowWidget) Element

func (w *WindowWidget) Element() ui.Element

Element returns the window's element.

func (*WindowWidget) PathChosen

func (w *WindowWidget) PathChosen() int

PathChosen returns the index in WindowOptions.Path of the folder the user chose from the title's path menu since the last frame, or -1.

Directories

Path Synopsis
Package diagram draws Mermaid diagrams in the Platinum look: laid out by limu on whole pixels, with the library's bitmap faces, and drawn with its Pen — boxes as its controls are drawn, lines and arrowheads a pixel at a time.
Package diagram draws Mermaid diagrams in the Platinum look: laid out by limu on whole pixels, with the library's bitmap faces, and drawn with its Pen — boxes as its controls are drawn, lines and arrowheads a pixel at a time.
examples
desktop command
Command desktop is a classic desktop built with the Platinum controls: a menu bar, icons, windows that move, resize and roll up, a browser of the desk's own little disk, and a few small applications — a calculator, a note pad, a text editor, a sliding puzzle, an alarm clock, a catalog of the library's controls, control panels and an about box.
Command desktop is a classic desktop built with the Platinum controls: a menu bar, icons, windows that move, resize and roll up, a browser of the desk's own little disk, and a few small applications — a calculator, a note pad, a text editor, a sliding puzzle, an alarm clock, a catalog of the library's controls, control panels and an about box.
diagrams command
Command diagrams shows every type of Mermaid diagram limu reads, drawn in the Platinum look by the diagram package: a list of the types, a pop-up menu of each type's examples, and the example's text beside its drawing, to edit.
Command diagrams shows every type of Mermaid diagram limu reads, drawn in the Platinum look by the diagram package: a list of the types, a pop-up menu of each type's examples, and the example's text beside its drawing, to edit.
gallery command
Command gallery shows every control of the Platinum library in a window, or, with -png, renders them to a PNG without one:
Command gallery shows every control of the Platinum library in a window, or, with -png, renders them to a PNG without one:
internal
verify command
Command verify runs every check of the repository and reports how many passed, as scripts/verify.sh shows them.
Command verify runs every check of the repository and reports how many passed, as scripts/verify.sh shows them.

Jump to

Keyboard shortcuts

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