termui

package module
v0.0.0-...-55f372f Latest Latest
Warning

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

Go to latest
Published: Feb 5, 2017 License: MIT Imports: 6 Imported by: 0

README

Introduction

TermUI is a styleable UI lib for console applications. It consists of two parts:

  1. the elements which are the controls which build the UI
  2. the css part which allows theming of the elements in a css like manner.

Elements

For now there are only a few elements:

  • Text is for basic text output
  • Border draws a border around a given child
  • TextBorder like a border but it also draws some text on the top left corner of the border.
  • TextBox allows the user to enter text.
  • StackPanel stacks multiple children vertical or horizontal
  • Grid a table like layout for multiple children

Example

package main

import (
    "github.com/boombuler/termui"
    "github.com/nsf/termbox-go"
)

func main() {
    vPanel := termui.NewStackPanel(termui.Vertical) // create a new panel
    vPanel.AddChild(
        termui.NewText("Hello"),                    // static text "Hello"
        termui.NewTextBox(),                        // and a textbox
        termui.NewText("World"),                    // static text "World"
        termui.NewTextBox(),                        // and another textbox
    )

    termui.Start(vPanel)                            // Start the ui rendering.
    go func() {                                     // Start a message loop for unhandled events.
        for ev := range termui.Events {
            if ev.Type == termbox.EventKey {
                if ev.Key == termbox.KeyEsc {       // If the user press `Esc`:
                    termui.Stop()                   // Stop the UI
                }
            }
        }
    }()

    termui.Wait()                                   // Wait for the ui lib to finish.
}

Styles

The style system is a css like engine. As in browsers there are three possible style sources:

  1. UserAgent: The default style for an element. Should be used if you write new elements for this lib.
  2. Designer: The Program specific style. Should be used to set the default style of your program.
  3. User: The User specific style of an element. Can be used to let the user theme the application.

Generating styles

Program style can be pre-parsed and generated via go generate. To enable this feature first run: go install github.com/boombuler/termui/css/termcssgen

After doing this you create a css file with the default style of your program:

package main

//go:generate termcssgen -i=style.css -o=style_gen.go -p=main -m=getDefaultStyle

import (
    "github.com/boombuler/termui/css"
)

func main() {
    css.SetDesignerStyles(getDefaultStyle())
    // add more program code here...
}

to generate the go file with the compiled style you just need to invoke go generate

Userdefined styles

It is also possible to load a style at runtime for example:

package main

import (
    "github.com/boombuler/termui"
    "github.com/boombuler/termui/css"
    "github.com/boombuler/termui/css/parser"
    "github.com/nsf/termbox-go"
)

func main() {
    vPanel := termui.NewStackPanel(termui.Vertical) // create a new panel
    vPanel.AddChild(
        termui.NewText("Hello"),                    // static text "Hello"
        termui.NewTextBox(),                        // and a textbox
        termui.NewText("World"),                    // static text "World"
        termui.NewTextBox(),                        // and another textbox
    )

    styledef := `
text {
  background: red;
  color: black;
}

stackpanel > * {
  gravity: right;
}

textbox:focused {
  background: magenta;
  color: black;
}`
    if parsedStyle, err := parser.Parse([]byte(styledef)); err != nil {
        panic(err)
    } else {
        css.SetUserStyles(parsedStyle)
    }

    termui.Start(vPanel)                       // Start the ui rendering.
    go func() {                                // Start a message loop for unhandled events.
        for ev := range termui.Events {
            if ev.Type == termbox.EventKey {
                if ev.Key == termbox.KeyEsc {  // If the user press `Esc`:
                    termui.Stop()              // Stop the UI
                }
            }
        }
    }()

    termui.Wait()                              // Wait for the ui lib to finish.
}

Todo

  • Examples and documentation
  • Mouse support
  • Grid
    • Fix ColumnSpan and RowSpan to work with auto-width columns
  • More Elements.
    • WrapPanel
    • Button
    • TabControl
  • Modal Dialogs

Documentation

Index

Constants

View Source
const (
	// GridSizeAuto is a Grid Size that takes only that much space as needed
	GridSizeAuto int = 0
	// GridSizeAuto defines a Grid Size that takes as that much space as available after layout all others.
	// The total width is distributed between all rows / columns with Star definitions
	// For example you can have one column with 1*GridSizeStar and one with 2*GridSizeStar. In this case
	// the second column will be twice as wide as the first one.
	GridSizeStar int = -1
)

Variables

View Source
var (
	// BackgroundProperty is a css property for the background color.
	BackgroundProperty = NewAttributeProperty("background", css.PropertyBehaviorInherit)
	// ForegroundProperty is a css property for the foreground color
	ForegroundProperty = NewAttributeProperty("color", css.PropertyBehaviorInherit)
	// GravityProperty is a css property for the gravity.
	GravityProperty = NewGravityProperty("gravity", css.PropertyBehaviorDefault)
)
View Source
var (

	// Events can be used to recieve unhandled termbox events.
	Events <-chan termbox.Event
)
View Source
var MarginProperty = NewThicknessProperty("margin")

Functions

func ArrangeChild

func ArrangeChild(e Element, finalWidth, finalHeight int)

ArrangeChild arranges the child and takes margin in account

func MeasureChild

func MeasureChild(e Element, availableWidth, availableHeight int) (int, int)

MeasureChild measures the child and takes margin in account

func SetBody

func SetBody(e Element)

SetBody replaces the root element with the new body.

func SetFocus

func SetFocus(e FocusElement)

func Start

func Start(body Element)

Start the UI with the given element as root.

func Stop

func Stop()

Stop shutsdown the UI.

func Update

func Update()

Update tells the UI to update measurement and render again.

func Wait

func Wait()

Wait for the UI to finish.

Types

type AttributePropertyDefinition

type AttributePropertyDefinition struct {
	*css.Property
}

AttributePropertyDefinition is a typesafe encapsulation of a css property for termbox.Attributes values.

func NewAttributeProperty

func NewAttributeProperty(name string, b css.PropertyBehavior) *AttributePropertyDefinition

NewAttributeProperty creates a new AttributePropertyDefinition

func (*AttributePropertyDefinition) FromInt

func (a *AttributePropertyDefinition) FromInt(i int) (interface{}, error)

FromInt converts an integer to a termbox attribute.

func (*AttributePropertyDefinition) FromStrings

func (a *AttributePropertyDefinition) FromStrings(s ...string) (interface{}, error)

FromStrings converts strings to a termbox attribute.

func (*AttributePropertyDefinition) Get

func (a *AttributePropertyDefinition) Get(e Element) termbox.Attribute

Get returns the value of the property for the given element.

type BaseElement

type BaseElement struct {
	css.IDAndClasses
	// contains filtered or unexported fields
}

BaseElement helps implementing the Element interface for ui elements. It handles classes, the ID and also the parent element.

func (*BaseElement) Parent

func (be *BaseElement) Parent() css.Styleable

Parent returns the parent of the element

func (*BaseElement) SetParent

func (be *BaseElement) SetParent(e Element)

SetParent sets the parent element of this element

type Border

type Border struct {
	BaseElement
	// contains filtered or unexported fields
}

Border draws a border around a given child element

func NewBorder

func NewBorder(child Element) *Border

NewBorder creates a new border element with the given child

func (*Border) Arrange

func (b *Border) Arrange(finalWidth, finalHeight int)

Arrange sets the final size for the Element end tells it to Arrange itself

func (*Border) Children

func (b *Border) Children() []css.Styleable

Children returns all nested child elements of the border.

func (*Border) Height

func (b *Border) Height() int

Height returns the height of the border.

func (*Border) Measure

func (b *Border) Measure(availableWidth, availableHeight int) (width int, height int)

Measure gets the "wanted" size of the element based on the available size.

func (*Border) Name

func (b *Border) Name() string

Name returns the constant name of the border element for css styling.

func (*Border) Render

func (b *Border) Render(r Renderer)

Render renders the element on the given Renderer

func (*Border) Width

func (b *Border) Width() int

Width returns the width of the border.

type Element

type Element interface {
	css.Styleable
	// Measure gets the "wanted" size of the element based on the available size
	Measure(availableWidth, availableHeight int) (width int, height int)
	// Arrange sets the final size for the Element end tells it to Arrange itself
	Arrange(finalWidth, finalHeight int)
	// Render renders the element on the given Renderer
	Render(fn Renderer)
	// Width returns the width of the border
	Width() int
	// Height returns the height of the element
	Height() int

	// SetParent sets the parent element of this element
	SetParent(e Element)
}

Element must be implemented by any UI element.

type ElementCollection

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

func (*ElementCollection) Add

func (c *ElementCollection) Add(e ...Element)

func (*ElementCollection) At

func (c *ElementCollection) At(i int) Element

func (*ElementCollection) Clear

func (c *ElementCollection) Clear()

func (*ElementCollection) IndexOf

func (c *ElementCollection) IndexOf(e Element) int

func (*ElementCollection) Items

func (c *ElementCollection) Items() []Element

func (*ElementCollection) Len

func (c *ElementCollection) Len() int

func (*ElementCollection) Remove

func (c *ElementCollection) Remove(e Element)

func (*ElementCollection) RemoveAt

func (c *ElementCollection) RemoveAt(i int)

type FocusElement

type FocusElement interface {
	KeyHandler
	// SetFocused is called by the ui system to indicate that the element has the focus.
	SetFocused(v bool)
}

FocusElement is an element which can get the input focus.

type Gravity

type Gravity byte

Gravity defines the horizontal and vertical orientation of an element.

const (
	// NoGravity -> element is centered horizontal and vertical
	NoGravity Gravity = 0
	// Top pulls the element to the top
	Top Gravity = 1 << iota
	// Left pulls the element to the left
	Left
	// Right pulls the element to the right
	Right
	// Bottom pulls the element to the top bottom
	Bottom
)

type GravityPropertyDefinition

type GravityPropertyDefinition struct {
	*css.Property
}

GravityPropertyDefinition is a typesafe encapsulation of a css property for Gravity values.

func NewGravityProperty

func NewGravityProperty(name string, b css.PropertyBehavior) *GravityPropertyDefinition

NewGravityProperty creates a new GravityPropertyDefinition

func (*GravityPropertyDefinition) FromInt

func (gp *GravityPropertyDefinition) FromInt(i int) (interface{}, error)

FromInt converts an integer to a gravity value.

func (GravityPropertyDefinition) FromStrings

func (gp GravityPropertyDefinition) FromStrings(s ...string) (interface{}, error)

FromStrings converts strings to a gravity value.

func (*GravityPropertyDefinition) Get

Get returns the value of the property for the given element.

type Grid

type Grid struct {
	BaseElement

	// ColumnDefinitions contains the the column sizes for the grid
	ColumnDefinitions []int
	// RowDefinitions contains the the row sizes for the grid
	RowDefinitions []int
	// contains filtered or unexported fields
}

Grid renders its children in a table like layout

func NewGrid

func NewGrid(colDefinitions, rowDefinitions []int) *Grid

NewGrid returns a new Grid.

func (*Grid) AddChild

func (g *Grid) AddChild(e Element, pos GridPosition)

func (*Grid) Arrange

func (g *Grid) Arrange(finalWidth, finalHeight int)

Arrange sets the final size for the Element end tells it to Arrange itself

func (*Grid) Children

func (g *Grid) Children() []css.Styleable

Children returns all nested elements.

func (*Grid) Height

func (g *Grid) Height() int

Height returns the height of the element

func (*Grid) Measure

func (g *Grid) Measure(availableWidth, availableHeight int) (width int, height int)

Measure gets the "wanted" size of the element based on the available size

func (*Grid) Name

func (g *Grid) Name() string

Name returns the constant name of the grid for css styling.

func (*Grid) Render

func (g *Grid) Render(r Renderer)

Render renders the element on the given Renderer

func (*Grid) Width

func (g *Grid) Width() int

Width returns the width of the border

type GridPosition

type GridPosition struct {
	// Column contains the column of the element
	Column int
	// Row contains the row of element
	Row int
	// ColumnSpan of the element. Auto-Width columns doesn't take spanned elements into account
	ColumnSpan int
	// RowSpan of the element. Auto-Height rows doesn't take spanned elements into account
	RowSpan int
}

GridPosition defines the location of an element within a grid

type KeyHandler

type KeyHandler interface {
	Element
	// HandleKey is called by the ui system if the element is asked to process a key. It should return true if the key
	// was successfully handled and should not be processed by other elements.
	HandleKey(k termbox.Key, ch rune) bool
}

type Orientation

type Orientation int
const (
	// Vertical orientation
	Vertical Orientation = iota
	// Horizontal orientation
	Horizontal
)

type Renderer

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

Renderer helps drawing an element

func (Renderer) RenderChild

func (r Renderer) RenderChild(e Element, width, height, xOffset, yOffset int)

RenderChild draws the given child.

func (Renderer) Set

func (r Renderer) Set(x, y int, ch rune)

Set the given rune at a relative x and y position

func (Renderer) SetAttr

func (r Renderer) SetAttr(x, y int, ch rune, attr termbox.Attribute)

SetAttr sets the given rune at a relative x and y position and applys the attribute to the foreground. This can be used to invert or underline a cell.

type StackPanel

type StackPanel struct {
	BaseElement
	// contains filtered or unexported fields
}

StackPanel is an UI element which stacks multiple elements in vertical order.

func NewStackPanel

func NewStackPanel(o Orientation) *StackPanel

NewStackPanel creates a new StackPanel

func (*StackPanel) AddChild

func (v *StackPanel) AddChild(e ...Element)

AddChild adds the given children to the StackPanel

func (*StackPanel) Arrange

func (v *StackPanel) Arrange(finalWidth, finalHeight int)

Arrange sets the final size for the Element end tells it to Arrange itself

func (*StackPanel) Children

func (v *StackPanel) Children() []css.Styleable

Children returns all nested elements.

func (*StackPanel) Height

func (v *StackPanel) Height() int

Height returns the height of the StackPanel.

func (*StackPanel) Measure

func (v *StackPanel) Measure(availableWidth, availableHeight int) (width int, height int)

Measure gets the "wanted" size of the element based on the available size

func (*StackPanel) Name

func (v *StackPanel) Name() string

Name returns the constant name of the StackPanel for css styling.

func (*StackPanel) Render

func (v *StackPanel) Render(rn Renderer)

Render renders the element on the given Renderer

func (*StackPanel) Width

func (v *StackPanel) Width() int

Width returns the width of the StackPanel

type Text

type Text struct {
	BaseElement
	// contains filtered or unexported fields
}

Text is an element which simply draws a static text.

func NewText

func NewText(txt string) *Text

NewText creates a new Text element.

func (*Text) Arrange

func (t *Text) Arrange(finalWidth, finalHeight int)

Arrange sets the final size for the Element end tells it to Arrange itself

func (*Text) Children

func (t *Text) Children() []css.Styleable

Children returns all nested elements.

func (*Text) Height

func (t *Text) Height() int

Height returns the height of the text.

func (*Text) Measure

func (t *Text) Measure(availableWidth, availableHeight int) (width int, height int)

Measure gets the "wanted" size of the element based on the available size

func (*Text) Name

func (t *Text) Name() string

Name returns the constant name of the text element for css styling.

func (*Text) Render

func (t *Text) Render(rn Renderer)

Render renders the element on the given Renderer

func (*Text) SetText

func (t *Text) SetText(txt string)

SetText replaces the the text of the text element.

func (*Text) Text

func (t *Text) Text() string

Text returns the current text of the element.

func (*Text) Width

func (t *Text) Width() int

Width returns the width of the text

type TextBorder

type TextBorder struct {
	*Border
	// contains filtered or unexported fields
}

TextBorder is a border with a text on the top left corner

func NewTextBorder

func NewTextBorder(txt string, child Element) *TextBorder

NewTextBorder creates a new TextBorder with a given text and child

func (*TextBorder) Render

func (b *TextBorder) Render(rn Renderer)

Render renders the element on the given Renderer

func (*TextBorder) SetText

func (b *TextBorder) SetText(txt string)

SetText sets the text on the border

func (*TextBorder) Text

func (b *TextBorder) Text() string

Text returns the current text value

type TextBox

type TextBox struct {
	BaseElement
	// contains filtered or unexported fields
}

TextBox is an UI element which can be used to query text input from the user.

func NewTextBox

func NewTextBox() *TextBox

NewTextBox creates a new textbox element.

func (*TextBox) Arrange

func (tb *TextBox) Arrange(finalWidth, finalHeight int)

Arrange sets the final size for the Element end tells it to Arrange itself

func (*TextBox) Children

func (tb *TextBox) Children() []css.Styleable

Children returns all nested elements.

func (*TextBox) DeleteRuneBackward

func (tb *TextBox) DeleteRuneBackward()

DeleteRuneBackward deletes the rune before the current cursor position

func (*TextBox) DeleteRuneForward

func (tb *TextBox) DeleteRuneForward()

DeleteRuneForward deletes the rune which is at the current cursor position

func (*TextBox) DeleteTheRestOfTheLine

func (tb *TextBox) DeleteTheRestOfTheLine()

DeleteTheRestOfTheLine removes all text from the current position to the end of the text.

func (*TextBox) HandleKey

func (tb *TextBox) HandleKey(k termbox.Key, ch rune) bool

HandleKey is called by the ui system if the element is asked to process a key.

func (*TextBox) Height

func (tb *TextBox) Height() int

Height returns the height of the textbox.

func (*TextBox) InsertRune

func (tb *TextBox) InsertRune(r rune)

InsertRune inserts the rune at the current cursor position

func (*TextBox) Measure

func (tb *TextBox) Measure(availableWidth, availableHeight int) (width int, height int)

Measure gets the "wanted" size of the element based on the available size

func (*TextBox) MoveCursorOneRuneBackward

func (tb *TextBox) MoveCursorOneRuneBackward()

MoveCursorOneRuneBackward moves the cursor one rune to the left.

func (*TextBox) MoveCursorOneRuneForward

func (tb *TextBox) MoveCursorOneRuneForward()

MoveCursorOneRuneForward moves the cursor one rune to the right

func (*TextBox) MoveCursorToBeginningOfTheLine

func (tb *TextBox) MoveCursorToBeginningOfTheLine()

MoveCursorToBeginningOfTheLine moves the cursor to the beginning of the text.

func (*TextBox) MoveCursorToEndOfTheLine

func (tb *TextBox) MoveCursorToEndOfTheLine()

MoveCursorToEndOfTheLine moves the cursor to the end of the line

func (*TextBox) Name

func (tb *TextBox) Name() string

Name returns the constant name of the textbox for css styling.

func (*TextBox) Render

func (tb *TextBox) Render(fn Renderer)

Render renders the element on the given Renderer

func (*TextBox) SetFocused

func (tb *TextBox) SetFocused(v bool)

SetFocused is called by the ui system to indicate that the element has the focus.

func (*TextBox) SetText

func (tb *TextBox) SetText(s string)

SetText sets the text of the textbox and moves the cursor to the end.

func (*TextBox) Text

func (tb *TextBox) Text() string

Text returns the current text of the textbox

func (*TextBox) Width

func (tb *TextBox) Width() int

Width returns the width of the textbox

type Thickness

type Thickness struct {
	Top, Right, Bottom, Left int
}

type ThicknessPropertyDefinition

type ThicknessPropertyDefinition struct {
	Property *css.Property
	// contains filtered or unexported fields
}

func NewThicknessProperty

func NewThicknessProperty(name string) *ThicknessPropertyDefinition

func (*ThicknessPropertyDefinition) Get

type WrapPanel

type WrapPanel struct {
	BaseElement
	// contains filtered or unexported fields
}

func NewWrapPanel

func NewWrapPanel(o Orientation) *WrapPanel

func (*WrapPanel) Add

func (v *WrapPanel) Add(e ...Element)

func (*WrapPanel) Arrange

func (v *WrapPanel) Arrange(finalWidth, finalHeight int)

Arrange sets the final size for the Element end tells it to Arrange itself

func (*WrapPanel) Children

func (v *WrapPanel) Children() []css.Styleable

Children returns all nested elements.

func (*WrapPanel) Clear

func (v *WrapPanel) Clear()

func (*WrapPanel) Height

func (v *WrapPanel) Height() int

Height returns the height of the WrapPanel.

func (*WrapPanel) Len

func (v *WrapPanel) Len() int

func (*WrapPanel) Measure

func (v *WrapPanel) Measure(availableWidth, availableHeight int) (width int, height int)

Measure gets the "wanted" size of the element based on the available size

func (*WrapPanel) Name

func (v *WrapPanel) Name() string

Name returns the constant name of the WrapPanel for css styling.

func (*WrapPanel) Remove

func (v *WrapPanel) Remove(e Element)

func (*WrapPanel) Render

func (v *WrapPanel) Render(rn Renderer)

Render renders the element on the given Renderer

func (*WrapPanel) Width

func (v *WrapPanel) Width() int

Width returns the width of the WrapPanel

Jump to

Keyboard shortcuts

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