tooey

package module
v0.0.0-...-020cec0 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2023 License: MIT Imports: 11 Imported by: 0

README

Tooey

example workflow Go Coverage Go Report Card

Tooey is a cross-platform and customizable terminal dashboard and widget library built on top of tcell (formerly termbox-go pre-fork). This project started as a fork of the fantastic termui but then turned into a ground-up rewrite.

See FORK.MD for details of the original fork and README.md

Features

  • 24bit colors enabled by TCell
    • Requires your $TERM to end in -truecolor Tcell Docs
    • Falls back to 256 color otherwise
  • Flex-inspired layout engine with Container
  • Several premade widgets for common use cases
  • Easily create custom widgets by extending Element
  • Position widgets either in containers with flex-like layout or with absolute coordinates
  • Keyboard, mouse, and terminal resizing events < UNDER REWORK >
  • Colors, Styling, Theming < UNDER REWORK >

Installation

go mod init

go get github.com/asciifaceman/tooey

go mod tidy after first reference

Hello World

package main

import (
	"log"

	"github.com/asciifaceman/tooey"
	"github.com/asciifaceman/tooey/widgets"
)

func main() {
	if err := tooey.Init(); err != nil {
		log.Fatalf("failed to initialize tooey: %v", err)
	}
	defer tooey.Close()

	p := widgets.NewText()
	p.SetTheme(themes.ThemeRetroTerminalOrange)
	p.Title.Content = "Text Title"
	p.Content = "Hello World!"
	p.SetRect(0, 0, 25, 5)

	tooey.Render(p)

	time.Sleep(time.Duration(time.Second * 5)) // events returning soon
}

Widgets

Run an example with go run _examples/{example}.go or run each example consecutively with make run-examples.

Documentation

License

MIT

Authors

Documentation

Overview

package tooey is a library for creating terminal user interfaces (TUIs) using widgets.

Index

Constants

View Source
const (
	ColorClear   tcell.Color = tcell.ColorDefault
	ColorBlack   tcell.Color = tcell.ColorBlack
	ColorRed     tcell.Color = tcell.ColorRed
	ColorGreen   tcell.Color = tcell.ColorGreen
	ColorYellow  tcell.Color = tcell.ColorYellow
	ColorBlue    tcell.Color = tcell.ColorBlue
	ColorMagenta tcell.Color = tcell.ColorDarkMagenta
	ColorCyan    tcell.Color = tcell.ColorLightCyan
	ColorWhite   tcell.Color = tcell.ColorWhite
)

Basic terminal colors

View Source
const (
	DOT      = '•'
	ELLIPSES = '…'

	UP_ARROW   = '▲'
	DOWN_ARROW = '▼'

	COLLAPSED = '+'
	EXPANDED  = '−'
)
View Source
const (
	TOP_LEFT     = '┌'
	TOP_RIGHT    = '┐'
	BOTTOM_LEFT  = '└'
	BOTTOM_RIGHT = '┘'

	VERTICAL_LINE   = '│'
	HORIZONTAL_LINE = '─'

	VERTICAL_LEFT   = '┤'
	VERTICAL_RIGHT  = '├'
	HORIZONTAL_UP   = '┴'
	HORIZONTAL_DOWN = '┬'

	QUOTA_LEFT  = '«'
	QUOTA_RIGHT = '»'

	VERTICAL_DASH   = '┊'
	HORIZONTAL_DASH = '┈'
)
View Source
const (
	DefaultULCorner = tcell.RuneULCorner
	DefaultURCorner = tcell.RuneURCorner
	DefaultLLCorner = tcell.RuneLLCorner
	DefaultLRCorner = tcell.RuneLRCorner
	DefaultHLine    = tcell.RuneHLine
	DefaultVLine    = tcell.RuneVLine
)

Variables

View Source
var (
	BARS = [...]rune{' ', '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'}

	SHADED_BLOCKS = [...]rune{' ', '░', '▒', '▓', '█'}

	IRREGULAR_BLOCKS = [...]rune{
		' ', '▘', '▝', '▀', '▖', '▌', '▞', '▛',
		'▗', '▚', '▐', '▜', '▄', '▙', '▟', '█',
	}

	BRAILLE_OFFSET = '\u2800'
	BRAILLE        = [4][2]rune{
		{'\u0001', '\u0008'},
		{'\u0002', '\u0010'},
		{'\u0004', '\u0020'},
		{'\u0040', '\u0080'},
	}

	DOUBLE_BRAILLE = map[[2]int]rune{
		{0, 0}: '⣀',
		{0, 1}: '⡠',
		{0, 2}: '⡐',
		{0, 3}: '⡈',

		{1, 0}: '⢄',
		{1, 1}: '⠤',
		{1, 2}: '⠔',
		{1, 3}: '⠌',

		{2, 0}: '⢂',
		{2, 1}: '⠢',
		{2, 2}: '⠒',
		{2, 3}: '⠊',

		{3, 0}: '⢁',
		{3, 1}: '⠡',
		{3, 2}: '⠑',
		{3, 3}: '⠉',
	}

	SINGLE_BRAILLE_LEFT  = [4]rune{'\u2840', '⠄', '⠂', '⠁'}
	SINGLE_BRAILLE_RIGHT = [4]rune{'\u2880', '⠠', '⠐', '⠈'}
)
View Source
var CornersOnlyBorderChars = &Chars{
	HLine:    ' ',
	VLine:    ' ',
	ULCorner: '◤',
	URCorner: '◥',
	LLCorner: '◣',
	LRCorner: '◢',
}

CornersOnlyBorderChars will only render corners with triangle ascii

View Source
var DefaultStylized = &Chars{
	HLine:    DefaultHLine,
	VLine:    DefaultVLine,
	ULCorner: '╒',
	URCorner: DefaultURCorner,
	LLCorner: DefaultLLCorner,
	LRCorner: DefaultLRCorner,
}
View Source
var DefaultTheme = &Theme{
	Default: StyleDefault,
	Element: StyleClear,
	Border:  StyleDefault,
	Title:   StyleDefault,
	Text:    StyleDefault,
	Chars:   NewDefaultChars(),
}

DefaultTheme is a basic white foreground and black background for all elements

View Source
var DoubleBarBorderChars = &Chars{
	HLine:    '═',
	VLine:    '║',
	ULCorner: '╔',
	URCorner: '╗',
	LLCorner: '╚',
	LRCorner: '╝',
}

DoubleBarBorder is like the Default border but with double bars for more dramatic effect // rune(2550)

View Source
var RoundedBarBorderChars = &Chars{
	HLine:    DefaultHLine,
	VLine:    DefaultVLine,
	ULCorner: '╭',
	URCorner: '╮',
	LLCorner: '╰',
	LRCorner: '╯',
}

RoundedBarBorderChars is like the Default border but the corners are rounded

View Source
var StyleClassicTerminal = Style{
	Style: tcell.StyleDefault.Foreground(tcell.ColorLightGreen).Background(tcell.ColorBlack),
	Align: AlignFull,
}

StyleClassicTerminal is a classic green-on-black terminal styling

View Source
var StyleClear = Style{
	Style: tcell.StyleDefault,
}

StyleClear represents an empty Style, with no colors or modifiers

View Source
var StyleDefault = Style{
	Style: tcell.StyleDefault.Foreground(ColorWhite).Background(ColorBlack),
	Align: AlignFull,
}

StyleDefault represents a simple white on black default

Functions

func AbsInt

func AbsInt(x int) int

func CheckWhichPositionHasFewest

func CheckWhichPositionHasFewest(positions []int) int

CheckWhichPositionHasFewest returns index of the position with the lowest count

func Clear

func Clear()

Clear the global screen

func Close

func Close()

Close is refactor of close

func ContainsNonWhitespace

func ContainsNonWhitespace(slice []rune) bool

ContainsNonWhitespace returns true if a given rune slice has any non-whitespace runes

func CountWhiteSpace

func CountWhiteSpace(slice []rune) int

CountWhiteSpace returns a count of the number of space characters in a []rune

func CountWordsInRuneSlice

func CountWordsInRuneSlice(slice []rune) int

CountWordsInRuneSlice counts how many blocks of non-whitespace characters are inside the rune

This can be used to traverse whitespace between the left and right boundaries use count-1 for right bound to prevent traversing outside of the word bounds

func DrawableDimensions

func DrawableDimensions() (int, int)

DrawableDimensions is the same as TerminalDimensions -1 to represent visibly drawable space in most terminals

func FloorFloat64

func FloorFloat64(x float64) float64

func GetMaxFloat64From2dSlice

func GetMaxFloat64From2dSlice(slices [][]float64) (float64, error)

func GetMaxFloat64FromSlice

func GetMaxFloat64FromSlice(slice []float64) (float64, error)

func GetMaxIntFromSlice

func GetMaxIntFromSlice(slice []int) (int, error)

func GetRootScreen

func GetRootScreen() tcell.Screen

GetRootScreen returns the root screen tooey writes to

func Init

func Init() error

Init initializes the screen and sets default styling

func InitSim

func InitSim() error

InitSim is just to support testing

func InterfaceSlice

func InterfaceSlice(slice interface{}) []interface{}

InterfaceSlice takes an []interface{} represented as an interface{} and converts it https://stackoverflow.com/questions/12753805/type-converting-slices-of-interfaces-in-go

func MaxFloat64

func MaxFloat64(x, y float64) float64

func MaxInt

func MaxInt(x, y int) int

func MinFloat64

func MinFloat64(x, y float64) float64

func MinInt

func MinInt(x, y int) int

func NormalizeLeftWhitespace

func NormalizeLeftWhitespace(slice []rune) []rune

func PollEvents

func PollEvents() tcell.Event

PollEvents returns a poll of events for the root screen

func Render

func Render(items ...Drawable)

Render locks and draws the passed Drawables

func RoundFloat64

func RoundFloat64(x float64) float64

func ShiftRuneSliceLeft

func ShiftRuneSliceLeft(slice []rune) []rune

ShiftRuneSliceLeft takes a []rune and shifts everything left, wrapping the right most character back to the right most position

func ShiftRuneSliceRight

func ShiftRuneSliceRight(slice []rune) []rune

ShiftRuneSliceRight takes a []rune and shifts everything right, wrapping the right most character back to the left most position

func ShiftRuneWhitespaceToLeft

func ShiftRuneWhitespaceToLeft(slice []rune) []rune

ShiftRuneWhitespaceToLeft takes a []rune and moves all whitespace to the left

func ShiftRuneWhitespaceToRight

func ShiftRuneWhitespaceToRight(slice []rune) []rune

ShiftRuneWhitespaceToRight takes a []rune and moves all whitespace to the right

func SpreadWhitespaceAcrossSliceInterior

func SpreadWhitespaceAcrossSliceInterior(slice []rune) []rune
SpreadWhitespaceAcrossSliceInterior takes a []rune

and attempts to distribute it's whitespace across the width of the slice interior but not at the outside edges

Take the string "abc def gh ij "

"abc_def___gh_ij___" would try to make "abc___def__gh___ij" "__abc_def___gh_ij" would try to make "abc__def__gh___ij"

func SumFloat64Slice

func SumFloat64Slice(data []float64) float64

func SumIntSlice

func SumIntSlice(slice []int) int

func Sync

func Sync()

Sync ...

func TerminalDimensions

func TerminalDimensions() (int, int)

Terminal dimensions returns an aggregate dimension for the terminal but it often is clipped on the right and buttom Use DrawableDimensions to get visible terminal dimensions

func TrimString

func TrimString(s string, w int) string

TrimString trims a string to a max length and adds '…' to the end if it was trimmed.

Types

type Alignment

type Alignment uint

Alignment provides a mechanism for Styles to control alignment of certain elements Not widely employed but can be at the widget level

const (
	AlignLeft Alignment = iota
	AlignCenter
	AlignRight
	AlignFull
)

type Border

type Border struct {
	Enabled bool
	Theme   *Theme
	Chars   *Chars

	Left   bool
	Top    bool
	Right  bool
	Bottom bool
}

Border contains the definition and drawing logic of an element border

func NewDefaultBorder

func NewDefaultBorder(theme *Theme) *Border

NewDefaultBorder returns a border with the default character set

func (*Border) Draw

func (b *Border) Draw(s tcell.Screen, rect *Rectangle)

Draw the borders for the given rect to the given tcell.Screen

func (*Border) SetChars

func (b *Border) SetChars(chars *Chars)

SetChars sets the char map for borders

type Chars

type Chars struct {
	HLine    rune
	VLine    rune
	ULCorner rune
	URCorner rune
	LLCorner rune
	LRCorner rune
}

Chars is to enable theming border characters

func NewDefaultChars

func NewDefaultChars() *Chars

NewDefaultChars returns the default character set for borders

type Color

type Color tcell.Color

Color is an integer from -1 to 255 -1 = ColorClear 0-255 = Xterm colors

func SelectColor

func SelectColor(colors []Color, index int) Color

type Container

type Container struct {
	Element
	Direction FlexDirection
	Children  []ContainerChild
	Theme     *Theme
}

Container is an element that holds other elements within

func NewContainer

func NewContainer(theme *Theme) *Container

NewContainer returns a new default configuration Container

A theme can be passed at this time or nil for defaults or to configure later

func (*Container) Draw

func (c *Container) Draw(s tcell.Screen)

Draw draws the row or col flex and their children

func (*Container) DrawFlexColumn

func (c *Container) DrawFlexColumn(s tcell.Screen)

DrawFlexColumn will draw the contents as a flexible column

func (*Container) DrawFlexRow

func (c *Container) DrawFlexRow(s tcell.Screen)

DrawFlexRow will draw the contents as a flexible row

func (*Container) RecursiveWrap

func (c *Container) RecursiveWrap(child ContainerChild)

RecursiveWrap wraps a tree of children

func (*Container) Wrap

func (c *Container) Wrap(children ...interface{})

Wrap embeds the given objects within the container using a top-level container that will fill it's available space

type ContainerChild

type ContainerChild struct {
	Drawable bool
	Contents interface{}
	Grow     float64
}

ContainerChild which represents a member of the flex Grow is added up then divided by the total grow to find the ratio of space each child will consume

func NewFlexChild

func NewFlexChild(grow float64, i ...interface{}) ContainerChild

NewFlexChild produces a ContainerChild which can be Wrapped

type Drawable

type Drawable interface {
	GetRect() image.Rectangle
	GetInnerRect() image.Rectangle
	// SetRect x1, y1, x2, y2
	SetRect(int, int, int, int)
	Draw(tcell.Screen)
	SetTheme(*Theme)
	sync.Locker
}

Drawable represents a renderable item

type Element

type Element struct {
	Rectangle
	Theme  *Theme
	Border *Border
	Title  *Title
}

Element is the base drawable struct inherited by most widgets Element manages size, positin, inner drawable space All other ui elements will inherit

func NewElement

func NewElement(theme *Theme) *Element

NewElement returns a stable empty Element ready to be modified

func (*Element) Draw

func (e *Element) Draw(s tcell.Screen)

Draw call on the element to write to the tcell.Screen

func (*Element) SetBorderCharacters

func (e *Element) SetBorderCharacters(chars *Chars)

SetBorderCharacters allows you to set the border characters for an element without touching the theme

func (*Element) SetTheme

func (e *Element) SetTheme(theme *Theme)

SetTheme will set the theme of the element

type FlexDirection

type FlexDirection uint
const (
	FlexColumn        FlexDirection = iota
	FlexColumnReverse               // NOT IMPLEMENTED
	FlexRow
	FlexRowReverse // NOT IMPLEMENTED
)

type Padding

type Padding struct {
	Left   int
	Top    int
	Right  int
	Bottom int
}

Padding provides an inset from an outer edge

func NewDefaultPadding

func NewDefaultPadding() *Padding

NewDefaultPadding returns a global padding of 1 all around which can account for a basic border

func NewPadding

func NewPadding() *Padding

NewPadding returns an empty padding

func NewTitlePadding

func NewTitlePadding() *Padding

NewTitlePadding returns a left & right padding of 2 to give the title more room to breathe

type Rectangle

type Rectangle struct {
	image.Rectangle
	// Padding should only affect objects within a rectangle
	// not the outer bounds of the rectangle
	Padding *Padding

	sync.Mutex
}

Rectangle is a convenience extension of the stdlib image.Rectangle

func NewRectangle

func NewRectangle(padding *Padding) Rectangle

func (*Rectangle) DrawableHeight

func (r *Rectangle) DrawableHeight() int

DrawableHeight returns the max height of the rectangle minux padding

func (*Rectangle) DrawableWidth

func (r *Rectangle) DrawableWidth() int

DrawableWidth returns the max width of the rectangle minus padding

func (*Rectangle) GetInnerRect

func (r *Rectangle) GetInnerRect() image.Rectangle

GetInnerRect returns the bounds of the inner padded rectangle

func (*Rectangle) GetRect

func (r *Rectangle) GetRect() image.Rectangle

GetRect returns the current underlying image.Rectangle

func (*Rectangle) InnerX1

func (r *Rectangle) InnerX1() int

InnerX1 returns X1 with padding

func (*Rectangle) InnerX2

func (r *Rectangle) InnerX2() int

InnerX2 returns X2 with padding

func (*Rectangle) InnerY1

func (r *Rectangle) InnerY1() int

InnerY1 returns Y1 with padding

func (*Rectangle) InnerY2

func (r *Rectangle) InnerY2() int

InnerY2 returns Y2 with padding

func (*Rectangle) SetRect

func (r *Rectangle) SetRect(x1 int, y1 int, x2 int, y2 int)

SetRect defines the boundaries of the rectangle

func (*Rectangle) X1

func (r *Rectangle) X1() int

X1 returns the rectangle's Min.X point

func (*Rectangle) X2

func (r *Rectangle) X2() int

X2 returns the rectangle's Max.X point

func (*Rectangle) Y1

func (r *Rectangle) Y1() int

Y1 returns the rectangle's Min.Y point

func (*Rectangle) Y2

func (r *Rectangle) Y2() int

Y2 returns the rectangle's Max.Y point

func (*Rectangle) ZeroSize

func (r *Rectangle) ZeroSize() bool

ZeroSize returns true if the rectangle has no size

type Style

type Style struct {
	tcell.Style
	Align Alignment
}

Style represents the style of one terminal cell

func SelectStyle

func SelectStyle(styles []Style, index int) Style

type Theme

type Theme struct {
	Default Style
	Element Style
	Border  Style
	Title   Style
	Text    Style
	Chars   *Chars
}

Theme is a bundle of Styles for different elements, subelements, and widgets If Inherit is true in the theme, then when a theme is set it will propagate the Default down to the others

type Title

type Title struct {
	Content string
	Padding *Padding
	Theme   *Theme
}

Title represents a rendered title in the header of an Element

func NewTitle

func NewTitle(theme *Theme) *Title

NewTitle returns a basic empty title

func (*Title) Draw

func (t *Title) Draw(s tcell.Screen, rect *Rectangle)

Draw the title

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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