ui

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2023 License: MPL-2.0 Imports: 9 Imported by: 10

Documentation

Overview

Package ui contains the interface types that a UI library needs to implement in order for vidar to be able to use it to draw windows with.

Index

Constants

View Source
const ErrUnfocused = constant.Error("no vidar window is focused")

Variables

View Source
var ErrFull = errors.New("ui element cannot add any more content")

Functions

This section is empty.

Types

type Alignment

type Alignment int

Alignment is a way to align items in the UI.

const (
	AlignmentInvalid Alignment = iota
	AlignCenter
	AlignLeft
	AlignRight
	AlignTop
	AlignBottom
)

type Box added in v0.7.0

type Box struct {
	Vertical   Range
	Horizontal Range
}

Box is a box of vertical and horizontal elements.

type Clipboard

type Clipboard interface {
	// Primary is the primary clipboard, usually ctrl+c/ctrl+v. A UI library may
	// choose to implement extra methods with the same type signature for other
	// forms of copy paste (e.g. X11 highlight/middle-click) to bind to.
	Primary(context.Context) ([]rune, error)
	SetPrimary(context.Context, []rune) error
}

Clipboard represents a clipboard to use for copying/pasting text. It's up to the UI library to choose whether or not to implement Secondary, Tertiary, etc methods; the only required methods are Primary.

type Count

type Count int

Count is a type which is used to count numbers of things in UI components. For example, this is used in some places to represent a number of pixels.

Negative Count values have special meaning. Check the constants for details.

const (
	// Enlarge represents a count that should consume all available space around
	// it.
	Enlarge Count = -1
)

type Creator

type Creator interface {
	// Start enqueues f on the Creator's global synchronization goroutine -
	// usually known as the UI goroutine. It returns after f has been queued
	// but does not wait for it to run.
	//
	// Some UI libraries may not have a built-in concept of a UI goroutine,
	// in which case it's expected that they have some other method of
	// queuing up these functions to run serially.
	//
	// All logic in the passed in function should be run before a UI update is
	// drawn. This means that resetting a UI element and then adding new
	// elements to it should not result in flicker when all of the update calls
	// are called in Start.
	Start(context.Context, func(context.Context))

	// Run runs f as if it were run by Start(f), then waits for it to finish
	// before returning. If Run is called from the synchronization goroutine, it
	// will simply run f in place rather than enqueing it first.
	Run(context.Context, func(context.Context))

	// State returns the current state of the world, as the Creator
	// understands it.
	State(context.Context) (State, error)

	// Clipboard returns a type to access this UI library's clipboard.
	Clipboard(context.Context) (Clipboard, error)

	// Window creates a new window.
	Window(_ context.Context, title string, _ ...WindowOpt) (Window, error)

	// KeyName returns the name for a key code. It seems these codes _can_ vary
	// between UI libraries, so we just require Creator implementations to
	// translate for us.
	//
	// The returned key name should always be lower-case.
	KeyName(context.Context, input.Key) string

	// Layout creates a new layout.
	Layout(context.Context, ...LayoutOpt) (Layout, error)

	// Image creates a new image element (canvas, texture, something like that)
	// to be displayed as an element in the UI.
	//
	// Since not all UIs can display images (e.g. CLI libraries), errors from
	// this will generally be logged but not prevent normal operation.
	Image(context.Context, image.Image) (any, error)

	// TextBox creates a new text box - a place to display text and accept user
	// input.
	TextBox(context.Context, ...TextBoxOpt) (TextBox, error)

	// Label creates a new label - basically a TextBox without any user
	// interaction.
	Label(context.Context) (Label, error)

	// Quit closes all windows, shuts down all UI goroutines, and
	// returns from all calls to Wait.
	Quit(context.Context) error
}

Creator is a type which can create user interface elements. The underlying implementation is up to the UI library which is in use, but it must keep track of some amount of its state - see the State method and the docs on its return type.

type Direction

type Direction int

Direction is a direction in the UI.

const (
	DirectionInvalid Direction = iota
	Up
	Right
	Down
	Left
)

type KeyHandler

type KeyHandler interface {
	// KeyDown should be called when a key is pressed by the user.
	KeyDown(context.Context, input.Key)

	// KeyUp should be called when a key is released by the user.
	KeyUp(context.Context, input.Key)

	// CharInput should be called when a character is processed as system
	// text input.
	CharInput(context.Context, rune)
}

KeyHandler is a type which handles keyboard input. Vidar implements this internally, passing along events to the input.Handler attached to the focused element.

type Label

type Label interface {
	// SetText changes the contents of the label to the passed in slice of Span
	// values.
	SetText(context.Context, ...Span) error
}

Label is a type which displays spans of text to a user.

type Layout

type Layout interface {
	// Add adds element to the Layout's children.
	//
	// If Layout already has the maximum number of elements, the returned error
	// should wrap ErrFull to indicate to callers that they can stop adding
	// elements.
	Add(_ context.Context, element any) error

	// Remove removes element from the Layout's children.
	Remove(_ context.Context, element any) error

	// Swap swaps the placement of a and b in the layout.
	Swap(_ context.Context, a, b any) error

	// Empty removes all children from the Layout.
	Empty(context.Context)
}

Layout is a type which can apply a structured layout to its child elements.

type LayoutOpt

type LayoutOpt func(LayoutPrefs) error

LayoutOpt is an option function for constructing a Layout.

func LayoutAlignment

func LayoutAlignment(a Alignment) LayoutOpt

LayoutAlignment informs the Layout to align elements according to a.

func LayoutLinear

func LayoutLinear(d Direction) LayoutOpt

LayoutLinear informs the Layout constructor that it should construct a layout that adds elements linearly in a specific direction. For example, LayoutLinear(Right) would lay elements out from left to right.

func LayoutMax

func LayoutMax(max Count) LayoutOpt

LayoutMax informs the Layout about a maximum number of elements.

func LayoutNamer

func LayoutNamer(n Namer) LayoutOpt

LayoutNamer informs the Layout to use n to find the name of elements if needed.

func LayoutTabs

func LayoutTabs() LayoutOpt

LayoutTabs informs the Layout constructor that it should construct a layout that tracks 'tabs' (or buffers).

type LayoutPrefs

type LayoutPrefs interface {
	// Direction indicates the direction that a layout should add elements
	// in. This indicates that the layout should add elements linearly.
	//
	// For example, Direction(Right) means that elements should be added
	// from left to right.
	Direction(Direction) error

	// Tabs indicates that child elements should be displayed maximized
	// within the Layout, and that the user can switch between child
	// elements using something like a tab bar or buffer switching.
	//
	// It is up to the UI library in question how these tabs/buffers are
	// displayed to the user.
	Tabs() error

	// Align indicates the alignment of child elements.
	Align(Alignment) error

	// Namer provides a Namer to the Layout which will find the name of elements
	// added to the layout (e.g. for tabs to display).
	Namer(Namer) error

	// Max sets the maxiumum number of elements to display. Layouts should
	// return ErrFull when they can no longer display elements, so that logic
	// which adds elements can return early.
	//
	// A Max of 0 (the default) means that the layout can contain infinite
	// elements and should expand to fit its contents.
	//
	// A Max of Enlarge means that it should always fill all available space.
	Max(Count) error
}

LayoutPrefs is a type which informs a UI library about preferences vidar has for a Layout it creates.

Many of these methods are used to tell the Layout how it should organize children, and therefor are contradictory. If methods are called which contradict one another, an error should be returned by the contradictory method.

type NamedConstructor

type NamedConstructor struct {
	// Name must be the name of the Creator that would be returned.
	Name string

	// Construct must initalize the Creator, including starting
	// any UI goroutines that need to be running.
	Construct func(context.Context, pref.Preferences) (Creator, error)
}

NamedConstructor is a type that must be used to wrap up a UI library's Creator constructor with its name. This is done so that plugins that are disabled by the user can be bound to vidar without being initialized.

type Namer

type Namer interface {
	Name(context.Context, any) (string, error)
}

type Range

type Range struct {
	Start, End Count
}

Range is a range of elements, e.g. lines or pixels.

type ScrollType

type ScrollType int

ScrollType indicates a type of scrolling to perform.

const (
	// Show means to just scroll enough to show the requested position. If the
	// position is already being shown, the view shouldn't scroll at all.
	Show ScrollType = iota

	// Top means to put the position at the top of the view (with a reasonable
	// buffer).
	Top

	// CenterY means to center the position vertically in the view.
	CenterY

	// Bottom means to put the position at the bottom of the view (with a
	// reasonable buffer).
	Bottom
)

type Size

type Size struct {
	Width, Height int
}

type Span

type Span struct {
	Style      font.Style
	Weight     font.Weight
	Foreground color.Color
	Background color.Color
	Runes      []rune
}

Span is a block of text with a style and/or color applied to it. UI implementations are not required to support all features of a Span.

type State

type State interface {
	// Focused returns the window that is focused, if any. If no window is
	// focused, it should return ErrUnfocused.
	Focused(context.Context) (Window, error)

	// Wait will block until there are no more windows that the UI library knows
	// about.
	//
	// Vidar will call this method last in the main() function, so if a UI
	// library needs access to specifically the main goroutine, this is how it
	// should take control.
	//
	// The first call to Creator.Window will happen in a separate goroutine
	// kicked off before this is called, so if control must be handed off before
	// the window is created, the Creator implementation must implement its own
	// synchronization to ensure the Window call blocks until Wait is called.
	Wait(context.Context) error
}

State is a little bit of state that the UI library (or the wrapper around the UI library) needs to keep track of for vidar.

type TextBox

type TextBox interface {
	Label

	// Visible reports the box of visible characters. This box measures
	// horizontal positions according to the font's character width (max width
	// for non-monospace fonts), not including tab characters.
	Visible(context.Context) Box

	// Scroll scrolls the view to display the requested position.
	Scroll(context.Context, ScrollType, int) error

	// SetSelections updates the positions of all selections. The primary
	// selection should be displayed more brightly than the others.
	SetSelections(_ context.Context, primary caret.Selection, secondary ...caret.Selection) error
}

TextBox is a type of text container which tracks carets for user input.

type TextBoxOpt

type TextBoxOpt func(TextBoxPrefs) error

TextBoxOpt is an option function for constructing text boxes.

func TextBoxLineNum

func TextBoxLineNum() TextBoxOpt

TextBoxLineNum returns an option function to turn line numbers on.

func TextBoxSize

func TextBoxSize(lines, cols Range) TextBoxOpt

TextBoxSize returns an option function to set the size of the text box.

type TextBoxPrefs

type TextBoxPrefs interface {
	// ContentSize is used to request a box of a specific size. For each range,
	// Start will be the minimum number of lines and End will be the maximum.
	ContentSize(lines, cols Range) error

	// LineNum is used to request a box with line numbers.
	LineNum() error
}

TextBoxPrefs is a type which informs a UI library about preferences vidar has for a TextBox it creates.

type Window

type Window interface {
	// SetIcon sets the window's icon. Vidar will use Creator.Image() to
	// construct an image first, then pass that to this method.
	SetIcon(context.Context, any) error

	// FocusedElement should return the UI element that currently has focus,
	// if any. If the window doesn't currently have focus, it should return
	// an error.
	FocusedElement(context.Context) (any, error)

	// FocusElement gives focus to an element in the Window. It errors if the
	// passed in element is either not focusable or not a child of the window.
	FocusElement(context.Context, any) error

	// SetChild sets the child element that the Window contains. If multiple
	// children are desired, this should be some type of layout container.
	SetChild(_ context.Context, element any) error

	// RemoveChild removes the child element that the Window contains.
	RemoveChild(context.Context) error

	// Close closes the Window.
	Close(context.Context) error
}

Window represents a single window in the ui.

type WindowOpt

type WindowOpt func(WindowPrefs) error

WindowOpt is a single option passed in when creating a window.

func WindowKeyHandler

func WindowKeyHandler(k KeyHandler) WindowOpt

WindowKeyHandler returns a WindowOpt that passes k to the window preferences during window creation.

func WindowSize

func WindowSize(s Size) WindowOpt

WindowSize returns a WindowOpt that passes s to the window preferences during window creation.

type WindowPrefs

type WindowPrefs interface {
	// Size tells the UI library what the size of the window should be.
	// Errors may be returned when the size is invalid, e.g. when s.Width or
	// s.Height is negative.
	Size(Size) error

	// KeyHandler tells the window where it should send its keyboard input.
	KeyHandler(KeyHandler)
}

WindowPrefs is a type which informs a UI library about some window preferences that vidar may need to set.

Keeping this an interface type allows plugins to define custom preferences - for example, if a UI library has additional preferences that it can support, it can provide its own ops which make use of methods that this interface doesn't directly require.

Jump to

Keyboard shortcuts

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