tinytui

package module
v0.0.0-...-4072897 Latest Latest
Warning

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

Go to latest
Published: May 24, 2025 License: BSD-3-Clause Imports: 10 Imported by: 0

README

TinyTUI

A lightweight Terminal User Interface (TUI) library for Go applications, built on top of tcell. TinyTUI provides a component-based architecture for building interactive terminal applications with minimal dependencies.

Features

  • Component-Based Architecture: Modular design with reusable UI components
  • Flexible Layout System: Arrange components using horizontal and vertical layouts with various sizing options
  • Event Handling: Process keyboard input, handle focus navigation, and dispatch commands
  • Modern Theming: Three built-in themes including Tokyo Night + KDE Sweet inspired design
  • Rich Component Library:
    • Text display with optional wrapping and alignment
    • Text input fields with cursor navigation and editing
    • Grid for data display with selection and interaction
    • Custom sprite rendering for graphics
    • Panes with optional borders and titles
  • Command Pattern: Decouple UI events from application logic
  • Focus Management: Tab navigation and Alt+Number quick access to panes
  • Thread-Safe: Proper synchronization for concurrent operations

Installation

go get github.com/LixenWraith/tinytui

Quick Start

package main

import (
	"github.com/LixenWraith/tinytui"
)

func main() {
	// Create application
	app := tinytui.NewApplication()

	// Create components
	header := tinytui.NewText("TinyTUI Example")
	header.SetAlignment(tinytui.AlignTextCenter)

	input := tinytui.NewTextInput()
	input.SetText("Enter text")

	button := tinytui.NewGrid()
	button.SetCells([][]string{{" Submit "}})
	button.SetCellSize(10, 1)
	button.SetOnSelect(func(r, c int, i string) {
		// Handle button click
	})

	// Create panes and set content
	headerPane := tinytui.NewPane()
	headerPane.SetChild(header)

	inputPane := tinytui.NewPane()
	inputPane.SetTitle("Input")
	inputPane.SetChild(input)

	buttonPane := tinytui.NewPane()
	buttonPane.SetChild(button)

	// Create layout and arrange panes
	layout := tinytui.NewLayout(tinytui.Vertical)
	layout.AddPane(headerPane, tinytui.Size{FixedSize: 1})
	layout.AddPane(inputPane, tinytui.Size{Proportion: 1})
	layout.AddPane(buttonPane, tinytui.Size{FixedSize: 1})

	// Set application layout
	app.SetLayout(layout)

	// Set initial focus
	app.Dispatch(&tinytui.FocusCommand{Target: input})

	// Run application
	if err := app.Run(); err != nil {
		panic(err)
	}
}

Core Concepts

Application

The Application is the root object that manages the screen, event loop, and component hierarchy. It handles focus management, command dispatch, and rendering.

app := tinytui.NewApplication()
app.SetScreenMode(tinytui.ScreenAlternate) // Use alternate screen buffer
app.SetTheme("tokyo-sweet")                // Use modern Tokyo Night + KDE Sweet theme
app.SetLayout(mainLayout)                  // Set root layout
app.Run()                                  // Start event loop
Components

Components are UI elements that implement the Component interface. TinyTUI provides several built-in components:

  • Text: Display non-editable text content
  • TextInput: Single-line text entry field
  • Grid: 2D grid of selectable and potentially interactive cells
  • Sprite: Display character-based graphics

Components share common behavior through the BaseComponent struct, which provides default implementations for visibility, focus, and state management.

Panes and Layouts

Panes are containers that hold a single child (Component or Layout) and provide borders, titles, and navigation indices. Layouts arrange multiple panes in a horizontal or vertical orientation with flexible sizing options.

// Create a pane with a border and title
pane := tinytui.NewPane()
pane.SetTitle("My Component")
pane.SetBorder(tinytui.BorderSingle, tinytui.DefaultPaneBorderStyle())
pane.SetChild(component)

// Create a vertical layout with multiple panes
layout := tinytui.NewLayout(tinytui.Vertical)
layout.SetGap(1) // Set gap between panes
layout.AddPane(pane1, tinytui.Size{FixedSize: 3})           // Fixed height of 3
layout.AddPane(pane2, tinytui.Size{Proportion: 1})          // Proportion of remaining space
layout.AddPane(pane3, tinytui.Size{FixedSize: 5})           // Fixed height of 5
Event Handling

TinyTUI uses an event-driven architecture for handling user input:

  1. Event Dispatch: The application dispatches tcell events to components
  2. Focus Handling: Focused components get first opportunity to handle events
  3. Command Pattern: Components can issue commands to be executed by the application
  4. Key Binding: Register handlers for specific keys globally
// Add component event handler
myGrid.SetOnSelect(func(row, col int, item string) {
    // Handle selection
})

// Register global key handler
app.RegisterRuneHandler('q', 0, func() bool {
    app.Stop()
    return true
})

// Dispatch a command
app.Dispatch(&tinytui.FocusCommand{Target: myInput})
Styling and Theming

TinyTUI provides a comprehensive theming system with three built-in themes:

  1. Default: Modern light theme with improved contrast
  2. Turbo: Classic Turbo Vision-inspired blue theme
  3. Tokyo Sweet: Modern dark theme inspired by Tokyo Night and KDE Sweet
// Use built-in themes
app.SetTheme("tokyo-sweet")    // Modern dark theme (default)
app.SetTheme("default")        // Light theme
app.SetTheme("turbo")          // Classic blue theme

// Create custom styles
style := tinytui.DefaultStyle.Foreground(tinytui.ColorRed).Bold(true)
myText.SetStyle(style)

Component Reference

Text
text := tinytui.NewText("Hello, World!")
text.SetContent("New content")              // Update text
text.SetAlignment(tinytui.AlignTextCenter)  // Set text alignment
text.SetWrap(true)                          // Enable text wrapping
text.SetStyle(myStyle)                      // Set text style
TextInput
input := tinytui.NewTextInput()
input.SetText("Initial value")              // Set text content
input.SetMasked(true, '*')                  // Password masking
input.SetMaxLength(10)                      // Limit input length
input.SetOnChange(func(text string) {       // Text change handler
    // Handle text change
})
input.SetOnSubmit(func(text string) {       // Enter key handler
    // Handle submission
})
Grid
grid := tinytui.NewGrid()
grid.SetCells([][]string{                   // Set grid cell content
    {"Row 1, Col 1", "Row 1, Col 2"},
    {"Row 2, Col 1", "Row 2, Col 2"},
})
grid.SetCellSize(15, 1)                     // Set cell size
grid.SetSelectionMode(tinytui.MultiSelect)  // Enable multi-selection
grid.SetIndicator('>', true)                // Set selection indicator
grid.SetOnChange(func(row, col int, item string) {
    // Handle selection change
})
grid.SetOnSelect(func(row, col int, item string) {
    // Handle cell activation (Enter/Space key)
})
Sprite
sprite := tinytui.NewSprite(nil)
sprite.Resize(10, 5)                         // Set sprite dimensions
sprite.SetCellsFromStrings([]string{         // Set sprite content
    "╔════╗",
    "║ICON║",
    "╚════╝",
}, myStyle)

Layout System

TinyTUI's layout system arranges panes in horizontal or vertical orientations with flexible sizing:

  • Fixed Size: Allocate a specific number of rows or columns
  • Proportional: Allocate a proportion of the remaining space
  • Gap: Set spacing between panes
  • Alignment: Control alignment along main and cross axes
// Create a horizontal layout with different sizing options
layout := tinytui.NewLayout(tinytui.Horizontal)
layout.SetGap(1)
layout.SetMainAxisAlignment(tinytui.AlignCenter)
layout.SetCrossAxisAlignment(tinytui.AlignStretch)
layout.AddPane(pane1, tinytui.Size{FixedSize: 20})         // Fixed width of 20
layout.AddPane(pane2, tinytui.Size{Proportion: 2})         // 2/3 of remaining width
layout.AddPane(pane3, tinytui.Size{Proportion: 1})         // 1/3 of remaining width

Advanced Usage

Navigation Indices

Panes can be assigned navigation indices (1-10) to allow quick access with Alt+Number keys:

// Navigation indices are automatically assigned to focusable panes
app.SetShowPaneIndices(true)  // Show indices in pane borders
Command Pattern

Commands allow decoupling UI events from application logic:

// Create a custom command
type MyCommand struct {
    Param string
}

func (c *MyCommand) Execute(app *Application) {
    // Command implementation
}

// Dispatch the command
app.Dispatch(&MyCommand{Param: "value"})
Custom Components

Create custom components by implementing the Component interface or embedding BaseComponent:

type MyComponent struct {
    tinytui.BaseComponent
    // Custom fields
}

func NewMyComponent() *MyComponent {
    return &MyComponent{
        BaseComponent: tinytui.NewBaseComponent(),
    }
}

// Implement Component interface methods
func (m *MyComponent) Draw(screen tcell.Screen) {
    // Drawing logic
}

func (m *MyComponent) HandleEvent(event tcell.Event) bool {
    // Event handling logic
    return false
}

Thread Safety

TinyTUI is designed with thread safety in mind:

  • Theme manager uses RWMutex for concurrent access
  • Application state changes are serialized through the command pattern
  • Event dispatch happens in the main event loop
  • Components should only be modified through commands or in event handlers

Performance Considerations

  • Maximum FPS can be configured via app.SetMaxFPS(fps)
  • Dirty flag system ensures only changed components are redrawn
  • Layout calculations are cached until dimensions change
  • Wide character support with proper width calculations

Dependencies

License

BSD-3-Clause

Documentation

Overview

application.go

base_component.go

base_theme.go

component.go

cursor.go

draw.go

event.go

grid.go

layout.go

pane.go

sprite.go

style.go

text.go

textinput.go

theme.go

theme_default.go

theme_tokyosweet.go

theme_turbo.go

types.go

Index

Constants

View Source
const (
	// Single line box drawing
	RuneULCorner rune = tcell.RuneULCorner // Upper left corner '┌'
	RuneURCorner rune = tcell.RuneURCorner // Upper right corner '┐'
	RuneLLCorner rune = tcell.RuneLLCorner // Lower left corner '└'
	RuneLRCorner rune = tcell.RuneLRCorner // Lower right corner '┘'
	RuneHLine    rune = tcell.RuneHLine    // Horizontal line '─'
	RuneVLine    rune = tcell.RuneVLine    // Vertical line '│'

	// Double line box drawing
	RuneDoubleULCorner rune = '╔' // Upper left corner
	RuneDoubleURCorner rune = '╗' // Upper right corner
	RuneDoubleLLCorner rune = '╚' // Lower left corner
	RuneDoubleLRCorner rune = '╝' // Lower right corner
	RuneDoubleHLine    rune = '═' // Horizontal line
	RuneDoubleVLine    rune = '║' // Vertical line

	// Block elements
	RuneBlock          rune = '█' // tcell.RuneBlock
	RuneUpperHalfBlock rune = '▀' // Top horizontal line
	RuneLowerHalfBlock rune = '▄' // Bottom horizontal line
)

Box-drawing runes (using tcell constants where available)

Variables

View Source
var DefaultStyle = Style{/* contains filtered or unexported fields */}

DefaultStyle represents the base style with default terminal colors and no attributes. It serves as a starting point for creating custom styles.

Functions

func DefaultCellHeight

func DefaultCellHeight() int

func DefaultCellWidth

func DefaultCellWidth() int

func DefaultPadding

func DefaultPadding() int

func DrawBox

func DrawBox(screen tcell.Screen, x, y, width, height int, style Style)

DrawBox draws a box with single-line borders using the specified style. Requires a minimum size of 1x1. Performs bounds checking.

func DrawDoubleBox

func DrawDoubleBox(screen tcell.Screen, x, y, width, height int, style Style)

DrawDoubleBox draws a box with double-line borders using the specified style. Requires a minimum size of 1x1. Performs bounds checking.

func DrawSolidBox

func DrawSolidBox(screen tcell.Screen, x, y, width, height int, style Style)

DrawSolidBox draws a box using block elements for a solid appearance. Handles smaller sizes gracefully. Performs bounds checking.

func DrawText

func DrawText(screen tcell.Screen, x, y int, style Style, text string)

DrawText draws a string at the specified position using the given style. Handles wide characters and clips text at the screen boundary.

func Fill

func Fill(screen tcell.Screen, x, y, width, height int, char rune, style Style)

Fill fills a rectangular area on the screen with a given rune and style. Performs bounds checking against the screen dimensions.

func RegisterTheme

func RegisterTheme(theme Theme)

RegisterTheme adds a new theme implementation to the manager. If it's the first theme registered, it automatically becomes the current global theme.

func SetTheme

func SetTheme(name ThemeName) bool

SetTheme changes the globally active theme to the one identified by `name`. Returns true if the theme was found and successfully set, false otherwise. Notifies all registered subscribers about the theme change. Note: This changes the *global* theme; individual Application instances might use app.SetTheme later.

func SubscribeThemeChange

func SubscribeThemeChange(callback func(Theme))

SubscribeThemeChange registers a callback function to be executed whenever the global theme changes via SetTheme. The callback is also executed immediately with the current theme upon successful registration.

Types

type AddPaneCommand

type AddPaneCommand struct {
	Pane *Pane
	Size Size
}

AddPaneCommand requests adding a pane. The Layout.AddPane method itself now dispatches the RecalculateNavIndicesCommand.

func (*AddPaneCommand) Execute

func (c *AddPaneCommand) Execute(app *Application)

type Alignment

type Alignment int

Alignment defines how items are positioned within a container or along a layout axis. Used primarily for Layout's CrossAxisAlignment, potentially MainAxisAlignment in future.

const (
	// AlignStart aligns items to the beginning of the axis (Top for Vertical, Left for Horizontal).
	AlignStart Alignment = iota
	// AlignCenter centers items within the available space on the axis. (Layout support may be partial).
	AlignCenter
	// AlignEnd aligns items to the end of the axis (Bottom for Vertical, Right for Horizontal). (Layout support may be partial).
	AlignEnd
	// AlignStretch expands items to fill the available space on the relevant axis (default for Layout's cross axis).
	AlignStretch
)

type AlignmentText

type AlignmentText int

AlignmentText defines horizontal text alignment options within the component's bounds.

const (
	AlignTextLeft   AlignmentText = iota // Align text to the left edge (default).
	AlignTextCenter                      // Center text horizontally.
	AlignTextRight                       // Align text to the right edge.
)

type Application

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

Application manages the screen, event loop, layout, focus, and drawing.

func NewApplication

func NewApplication() *Application

NewApplication creates a new application with default settings. Initializes the theme from the current global theme.

func (*Application) Dispatch

func (app *Application) Dispatch(cmd Command)

Dispatch sends a command to be executed asynchronously by the application's main loop. This is the safe way for components or other goroutines to modify application state or trigger actions.

func (*Application) GetCursorManager

func (app *Application) GetCursorManager() *CursorManager

GetCursorManager returns the application's cursor manager instance. Used by input components to request cursor visibility and position.

func (*Application) GetFocusedComponent

func (app *Application) GetFocusedComponent() Component

GetFocusedComponent returns the currently focused component, or nil if none.

func (*Application) GetLayout

func (app *Application) GetLayout() *Layout

GetLayout returns the application's root layout.

func (*Application) GetTheme

func (app *Application) GetTheme() Theme

GetTheme returns the application's current theme. It returns the theme specifically set on the Application instance.

func (*Application) IsShowPaneIndicesEnabled

func (app *Application) IsShowPaneIndicesEnabled() bool

IsShowPaneIndicesEnabled returns whether pane indices should be shown. Used by Pane during drawing.

func (*Application) ProcessEvent

func (app *Application) ProcessEvent(ev tcell.Event)

ProcessEvent handles incoming tcell events. Updated Alt+Num logic.

func (*Application) QueueRedraw

func (app *Application) QueueRedraw()

QueueRedraw requests a redraw on the next cycle of the event loop. It's buffered (size 1), so multiple calls between draw cycles result in only one redraw.

func (*Application) RegisterKeyHandler

func (app *Application) RegisterKeyHandler(key tcell.Key, mod tcell.ModMask, handler func() bool)

RegisterKeyHandler registers a handler function for a specific key (non-rune) and modifier combination. The handler function should return true if the event was handled, false otherwise.

func (*Application) RegisterRuneHandler

func (app *Application) RegisterRuneHandler(r rune, mod tcell.ModMask, handler func() bool)

RegisterRuneHandler registers a handler function for a specific rune and modifier combination. The handler function should return true if the event was handled, false otherwise. Handlers are checked in the order they are registered.

func (*Application) Run

func (app *Application) Run() error

Run initializes the screen, starts the event loop, and handles drawing and events. Returns an error if initialization fails.

func (*Application) SetClearScreenOnExit

func (app *Application) SetClearScreenOnExit(clear bool)

SetClearScreenOnExit sets whether the screen should be cleared when the application exits.

func (*Application) SetFocus

func (app *Application) SetFocus(component Component)

SetFocus changes the focused component, handling blur/focus events.

func (*Application) SetLayout

func (app *Application) SetLayout(layout *Layout)

SetLayout sets the application's root layout. Associates the layout, applies theme, and relies on layout.SetApplication to trigger the initial navigation index assignment.

func (*Application) SetMaxFPS

func (app *Application) SetMaxFPS(fps int)

SetMaxFPS sets the maximum frames per second for redraws. Affects how often dirty component checks and redraws occur via the frame timer.

func (*Application) SetScreenMode

func (app *Application) SetScreenMode(mode ScreenMode)

SetScreenMode sets the desired screen mode (Normal, Fullscreen, Alternate).

func (*Application) SetShowPaneIndices

func (app *Application) SetShowPaneIndices(show bool)

SetShowPaneIndices sets whether pane indices (Alt+Number hints) should be shown in pane borders.

func (*Application) SetTheme

func (app *Application) SetTheme(theme Theme)

SetTheme sets the application theme and notifies components recursively.

func (*Application) Stop

func (app *Application) Stop()

Stop signals the application to gracefully terminate the main loop. Idempotent.

func (*Application) StopChan

func (app *Application) StopChan() <-chan struct{}

StopChan returns the channel that is closed when the application stops. Can be used in select statements by goroutines to react to application shutdown.

type AttrMask

type AttrMask = tcell.AttrMask

AttrMask is an alias for tcell.AttrMask, representing a bitmask of text attributes.

const (
	AttrNone      AttrMask = 0                       // No attributes.
	AttrBold      AttrMask = tcell.AttrBold          // Bold text.
	AttrBlink     AttrMask = tcell.AttrBlink         // Blinking text (terminal support varies).
	AttrReverse   AttrMask = tcell.AttrReverse       // Reverse video (swap foreground/background).
	AttrUnderline AttrMask = tcell.AttrUnderline     // Underlined text.
	AttrDim       AttrMask = tcell.AttrDim           // Dim/faint text (terminal support varies).
	AttrItalic    AttrMask = tcell.AttrItalic        // Italic text (terminal support varies).
	AttrStrike    AttrMask = tcell.AttrStrikeThrough // Strikethrough text (terminal support varies).
)

Text Attributes (mapping directly to tcell constants)

type BaseComponent

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

BaseComponent provides default implementations for common Component methods. Concrete components should embed this struct to inherit baseline behavior.

func NewBaseComponent

func NewBaseComponent() BaseComponent

NewBaseComponent creates a new BaseComponent with sensible defaults.

func (*BaseComponent) App

func (b *BaseComponent) App() *Application

App returns the application instance the component belongs to, or nil if not set.

func (*BaseComponent) Blur

func (b *BaseComponent) Blur()

Blur is called by the application when the component loses input focus. Marks the component dirty.

func (*BaseComponent) ClearDirty

func (b *BaseComponent) ClearDirty()

ClearDirty marks the component as clean (no redraw needed for itself). This is typically called by the application's drawing logic after the component has been drawn.

func (*BaseComponent) Draw

func (b *BaseComponent) Draw(screen tcell.Screen)

Draw provides a default drawing implementation. Base implementation does nothing, as base components have no visual representation. Concrete components override this to draw their content onto the screen.

func (*BaseComponent) Focus

func (b *BaseComponent) Focus()

Focus is called by the application when the component gains input focus. Marks the component dirty.

func (*BaseComponent) Focusable

func (b *BaseComponent) Focusable() bool

Focusable returns whether the component can receive input focus. Default implementation: focusable only if visible. Concrete components (like TextInput, Grid) override this with more specific logic.

func (*BaseComponent) GetRect

func (b *BaseComponent) GetRect() (x, y, width, height int)

GetRect returns the component's current position and size.

func (*BaseComponent) GetState

func (b *BaseComponent) GetState() State

GetState returns the component's current interaction state.

func (*BaseComponent) HandleEvent

func (b *BaseComponent) HandleEvent(event tcell.Event) bool

HandleEvent provides a default event handler implementation. Base implementation does nothing and indicates the event was not handled. Concrete components override this to process specific events (e.g., key presses).

func (*BaseComponent) IsDirty

func (b *BaseComponent) IsDirty() bool

IsDirty returns whether the component is flagged as needing a redraw. This checks the component's own flag, not its children. Containers override this.

func (*BaseComponent) IsFocused

func (b *BaseComponent) IsFocused() bool

IsFocused returns whether the component currently has input focus.

func (*BaseComponent) IsVisible

func (b *BaseComponent) IsVisible() bool

IsVisible returns whether the component is currently set to be visible.

func (*BaseComponent) MarkDirty

func (b *BaseComponent) MarkDirty()

MarkDirty flags the component as needing a redraw in the next draw cycle. It also queues a redraw request with the application if the component is part of one.

func (*BaseComponent) SetApplication

func (b *BaseComponent) SetApplication(app *Application)

SetApplication sets the application instance the component belongs to. This is typically called by the parent container (Pane or Layout) during setup.

func (*BaseComponent) SetRect

func (b *BaseComponent) SetRect(x, y, width, height int)

SetRect sets the component's position and size. Marks the component as dirty if the rectangle changes.

func (*BaseComponent) SetState

func (b *BaseComponent) SetState(state State)

SetState sets the component's interaction state (Normal, Selected, Interacted). Marks the component dirty if the state changes, as appearance might depend on state.

func (*BaseComponent) SetVisible

func (b *BaseComponent) SetVisible(visible bool)

SetVisible sets the component's visibility state. If hiding a focused component, it dispatches a command to find a new focus target.

type BaseTheme

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

BaseTheme provides a common implementation foundation for the Theme interface, reducing boilerplate code in concrete theme definitions.

func (*BaseTheme) DefaultBorderType

func (t *BaseTheme) DefaultBorderType() Border

DefaultBorderType returns the theme's preferred default border type for panes.

func (*BaseTheme) DefaultCellHeight

func (t *BaseTheme) DefaultCellHeight() int

DefaultCellHeight returns the theme's preferred default height for grid cells.

func (*BaseTheme) DefaultCellWidth

func (t *BaseTheme) DefaultCellWidth() int

DefaultCellWidth returns the theme's preferred default width for grid cells.

func (*BaseTheme) DefaultPadding

func (t *BaseTheme) DefaultPadding() int

DefaultPadding returns the theme's preferred default padding for widgets.

func (*BaseTheme) FocusedBorderType

func (t *BaseTheme) FocusedBorderType() Border

FocusedBorderType returns the theme's preferred border type for focused panes.

func (*BaseTheme) GridFocusedInteractedStyle

func (t *BaseTheme) GridFocusedInteractedStyle() Style

GridFocusedInteractedStyle returns the style for interacted grid cells when the grid has focus.

func (*BaseTheme) GridFocusedSelectedStyle

func (t *BaseTheme) GridFocusedSelectedStyle() Style

GridFocusedSelectedStyle returns the style for selected grid cells when the grid has focus.

func (*BaseTheme) GridFocusedStyle

func (t *BaseTheme) GridFocusedStyle() Style

GridFocusedStyle returns the style for normal grid cells when the grid has focus.

func (*BaseTheme) GridInteractedStyle

func (t *BaseTheme) GridInteractedStyle() Style

GridInteractedStyle returns the style for interacted, unfocused grid cells.

func (*BaseTheme) GridSelectedStyle

func (t *BaseTheme) GridSelectedStyle() Style

GridSelectedStyle returns the style for selected, unfocused grid cells.

func (*BaseTheme) GridStyle

func (t *BaseTheme) GridStyle() Style

GridStyle returns the style for normal, unfocused grid cells.

func (*BaseTheme) IndicatorColor

func (t *BaseTheme) IndicatorColor() Color

IndicatorColor returns the theme's preferred color for selection indicators.

func (*BaseTheme) Name

func (t *BaseTheme) Name() ThemeName

Name returns the theme's identifier.

func (*BaseTheme) PaneBorderStyle

func (t *BaseTheme) PaneBorderStyle() Style

PaneBorderStyle returns the style for unfocused pane borders.

func (*BaseTheme) PaneFocusBorderStyle

func (t *BaseTheme) PaneFocusBorderStyle() Style

PaneFocusBorderStyle returns the style for focused pane borders.

func (*BaseTheme) PaneStyle

func (t *BaseTheme) PaneStyle() Style

PaneStyle returns the style for pane content areas (background).

func (*BaseTheme) TextSelectedStyle

func (t *BaseTheme) TextSelectedStyle() Style

TextSelectedStyle returns the style for selected text elements.

func (*BaseTheme) TextStyle

func (t *BaseTheme) TextStyle() Style

TextStyle returns the default style for text elements.

type Border

type Border int

Border defines the visual style of a Pane's border line/characters.

const (
	// BorderNone indicates no border should be drawn around the pane. Content fills the entire pane rectangle.
	BorderNone Border = iota
	// BorderSingle draws a border using single-line box drawing characters ('┌', '─', '┐', etc.).
	BorderSingle
	// BorderDouble draws a border using double-line box drawing characters ('╔', '═', '╗', etc.).
	BorderDouble
	// BorderSolid draws a border using solid block characters ('▀', '█', '▄', etc.).
	BorderSolid
)

func DefaultBorderType

func DefaultBorderType() Border

func FocusedBorderType

func FocusedBorderType() Border

type Color

type Color = tcell.Color

Color is an alias for tcell.Color, representing a terminal color. Use the ColorX constants for predefined colors.

const (
	ColorDefault Color = tcell.ColorDefault // Default terminal foreground/background

	// Basic ANSI Colors (0-7)
	ColorBlack  Color = tcell.ColorBlack  // 0
	ColorMaroon Color = tcell.ColorMaroon // 1 (Dark Red)
	ColorGreen  Color = tcell.ColorGreen  // 2 (Dark Green)
	ColorOlive  Color = tcell.ColorOlive  // 3 (Dark Yellow / Brown)
	ColorNavy   Color = tcell.ColorNavy   // 4 (Dark Blue)
	ColorPurple Color = tcell.ColorPurple // 5 (Dark Magenta)
	ColorTeal   Color = tcell.ColorTeal   // 6 (Dark Cyan)
	ColorSilver Color = tcell.ColorSilver // 7 (Light Gray)

	// Bright ANSI Colors (8-15)
	ColorGray    Color = tcell.ColorGray    // 8 (Dark Gray)
	ColorRed     Color = tcell.ColorRed     // 9 (Bright Red, often same as DarkRed in practice)
	ColorLime    Color = tcell.ColorLime    // 10 (Bright Green)
	ColorYellow  Color = tcell.ColorYellow  // 11 (Bright Yellow)
	ColorBlue    Color = tcell.ColorBlue    // 12 (Bright Blue)
	ColorFuchsia Color = tcell.ColorFuchsia // 13 (Bright Magenta)
	ColorAqua    Color = tcell.ColorAqua    // 14 (Bright Cyan)
	ColorWhite   Color = tcell.ColorWhite   // 15 (Bright White)

	// Explicit Dark Aliases (often map to 0-7 range)
	ColorDarkRed     Color = tcell.ColorDarkRed       // Usually same as ColorMaroon
	ColorDarkGreen   Color = tcell.ColorDarkGreen     // Usually same as ColorGreen
	ColorDarkYellow  Color = tcell.ColorDarkGoldenrod // Or Olive
	ColorDarkBlue    Color = tcell.ColorDarkBlue      // Usually same as ColorNavy
	ColorDarkMagenta Color = tcell.ColorDarkMagenta   // Usually same as ColorPurple
	ColorDarkCyan    Color = tcell.ColorDarkCyan      // Usually same as ColorTeal
	ColorDarkGray    Color = tcell.ColorDarkGray      // Usually same as ColorGray
	ColorLightGray   Color = tcell.ColorLightGray     // Usually same as ColorSilver

	// Explicit Light Aliases (often map to 8-15 range)
	ColorLightRed     Color = tcell.ColorOrangeRed   // No LightRed, Usually same as ColorRed
	ColorLightGreen   Color = tcell.ColorLightGreen  // Usually same as ColorLime
	ColorLightYellow  Color = tcell.ColorLightYellow // Usually same as ColorYellow
	ColorLightBlue    Color = tcell.ColorLightBlue   // Usually same as ColorBlue
	ColorLightMagenta Color = tcell.ColorFuchsia     // No LightMagenta, Usually same as ColorFuchsia
	ColorLightCyan    Color = tcell.ColorLightCyan   // Usually same as ColorAqua

	// Other common names (check tcell definitions)
	ColorDarkGoldenrod Color = tcell.ColorDarkGoldenrod
	ColorDarkSlateGray Color = tcell.ColorDarkSlateGray
)

Predefined Colors (mapping directly to tcell constants for convenience and familiarity)

func DefaultIndicatorColor

func DefaultIndicatorColor() Color

type Command

type Command interface {
	Execute(app *Application)
}

Command defines the interface for actions executed by the Application.

type Component

type Component interface {
	// Draw renders the component onto the screen within its allocated rectangle.
	// Implementations should respect the component's visibility and bounds.
	Draw(screen tcell.Screen)

	// SetRect informs the component of its allocated position and size (x, y, width, height).
	// Components should mark themselves dirty if the rectangle changes.
	SetRect(x, y, width, height int)

	// GetRect returns the component's current position and size.
	GetRect() (x, y, width, height int)

	// HandleEvent processes a terminal event (e.g., key press, mouse event).
	// Returns true if the event was handled by this component, false otherwise,
	// allowing the event to potentially bubble up or be handled globally.
	HandleEvent(event tcell.Event) bool

	// Focus is called by the application when the component gains input focus.
	// Implementations should update internal state and mark dirty if appearance changes.
	Focus()

	// Blur is called by the application when the component loses input focus.
	// Implementations should update internal state and mark dirty if appearance changes.
	Blur()

	// IsFocused returns true if the component currently has input focus.
	IsFocused() bool

	// Focusable returns true if the component is capable of receiving input focus
	// (e.g., interactive elements like TextInput, Grid). Non-focusable components
	// are skipped during focus cycling (Tab/Shift+Tab).
	Focusable() bool

	// IsVisible returns true if the component should be drawn and considered for layout/focus.
	IsVisible() bool

	// SetVisible sets the visibility state of the component.
	// Hidden components are not drawn and cannot be focused. Hiding a focused
	// component should trigger focus loss handling in the application.
	SetVisible(visible bool)

	// SetState sets the interaction state of the component (Normal, Selected, Interacted).
	// Used for visual feedback (e.g., highlighting selected grid cells).
	SetState(state State)

	// GetState returns the current interaction state of the component.
	GetState() State

	// SetApplication links the component to its parent application instance.
	// This allows components to dispatch commands or access application-level resources
	// like the theme or cursor manager. Usually called by the parent container.
	SetApplication(app *Application)

	// App returns the parent application instance, or nil if not set.
	App() *Application

	// MarkDirty flags the component as needing a redraw in the next draw cycle.
	// Implementations should ideally also notify the application via App().QueueRedraw()
	// to ensure the draw cycle runs.
	MarkDirty()

	// IsDirty returns true if the component has been flagged as needing a redraw.
	// Containers should override this to check their children recursively.
	IsDirty() bool

	// ClearDirty resets the dirty flag. Called by the application after drawing.
	// Containers should override this to clear flags recursively.
	ClearDirty()
}

Component is the fundamental interface for all visual elements within a Pane. It defines methods for drawing, geometry management, event handling, focus, visibility, and state.

type CursorManager

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

CursorManager handles the visibility, position, and blinking of the terminal cursor, typically controlled by input components like TextInput. It ensures only one cursor is active and manages its blinking cycle independently.

func NewCursorManager

func NewCursorManager(app *Application, screen tcell.Screen, rate time.Duration) *CursorManager

NewCursorManager creates and starts a cursor manager associated with an application and screen.

func (*CursorManager) Draw

func (cm *CursorManager) Draw()

Draw renders the cursor on the screen based on the current frame's request and blink state. This is called by the Application *after* all components have been drawn.

func (*CursorManager) IsCursorRequested

func (cm *CursorManager) IsCursorRequested() bool

IsCursorRequested returns whether a cursor position was requested in the current frame. (Used internally or for debugging).

func (*CursorManager) Request

func (cm *CursorManager) Request(x, y int)

Request sets the desired cursor position for the *current* draw frame. This should be called only once per frame, typically by the focused input component during its Draw() method. If called multiple times, the last call wins.

func (*CursorManager) ResetForFrame

func (cm *CursorManager) ResetForFrame()

ResetForFrame clears the cursor request state at the beginning of a draw cycle. This is called by the Application before drawing components to ensure no stale request persists.

func (*CursorManager) SetBlinkRate

func (cm *CursorManager) SetBlinkRate(rate time.Duration)

SetBlinkRate changes the cursor blink rate dynamically. Note: Dynamically changing the rate while running requires careful handling of the timer and goroutine restart. This implementation assumes it's called infrequently or when the application is stable.

func (*CursorManager) Stop

func (cm *CursorManager) Stop()

Stop halts the blinking timer goroutine and cleans up associated resources. Should be called when the application shuts down.

type FindNextFocusCommand

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

FindNextFocusCommand requests the application find a suitable component to focus. This is typically dispatched when the currently focused component is about to be hidden or removed, ensuring focus doesn't get lost.

func (*FindNextFocusCommand) Execute

func (c *FindNextFocusCommand) Execute(app *Application)

Execute implements the Command interface.

type FocusCommand

type FocusCommand struct {
	Target Component // The component to receive focus.
}

FocusCommand requests focus to be set on the target component.

func (*FocusCommand) Execute

func (c *FocusCommand) Execute(app *Application)

Execute implements the Command interface.

type Grid

type Grid struct {
	BaseComponent
	// contains filtered or unexported fields
}

Grid displays a 2D grid of selectable and potentially interactive cells.

func NewGrid

func NewGrid() *Grid

NewGrid creates a new grid component, initializing styles from the current theme.

func (*Grid) ApplyTheme

func (g *Grid) ApplyTheme(theme Theme)

ApplyTheme updates the grid's styles based on the provided theme. Implements ThemedComponent.

func (*Grid) ClearInteractions

func (g *Grid) ClearInteractions()

ClearInteractions resets the interaction state for all cells.

func (*Grid) Draw

func (g *Grid) Draw(screen tcell.Screen)

Draw renders the grid component onto the screen.

func (*Grid) Focusable

func (g *Grid) Focusable() bool

Focusable returns true if the grid is visible and contains selectable cells.

func (*Grid) GetInteractedCells

func (g *Grid) GetInteractedCells() [][2]int

GetInteractedCells returns a slice of [row, col] pairs for all interacted cells. Returns an empty slice if no cells are interacted.

func (*Grid) GetSelectedCell

func (g *Grid) GetSelectedCell() (row, col int, content string)

GetSelectedCell returns the currently selected cell's row, column, and content. Returns -1, -1, "" if nothing is selected or grid is empty.

func (*Grid) HandleEvent

func (g *Grid) HandleEvent(event tcell.Event) bool

HandleEvent processes keyboard events for grid navigation and interaction.

func (*Grid) IsCellInteracted

func (g *Grid) IsCellInteracted(row, col int) bool

IsCellInteracted checks if a specific cell is marked as interacted.

func (*Grid) SetAutoWidth

func (g *Grid) SetAutoWidth(auto bool)

SetAutoWidth enables or disables automatic cell width calculation based on content.

func (*Grid) SetCellInteracted

func (g *Grid) SetCellInteracted(row, col int, interacted bool)

SetCellInteracted explicitly sets the interaction state of a cell. Respects the SelectionMode (clears others if SingleSelect).

func (*Grid) SetCellSize

func (g *Grid) SetCellSize(width, height int)

SetCellSize sets the fixed size (width, height) of each cell. Disables autoWidth if width is set.

func (*Grid) SetCells

func (g *Grid) SetCells(cells [][]string)

SetCells updates the grid's content. Resets scroll and potentially selection. Ensures the resulting grid data is rectangular by padding shorter rows.

func (*Grid) SetContent

func (g *Grid) SetContent(content string)

SetContent implements TextUpdater by parsing a string into cells. Expects newline ('\n') for row separation and tab ('\t') for column separation.

func (*Grid) SetIndicator

func (g *Grid) SetIndicator(char rune, show bool)

SetIndicator configures the selection indicator character and visibility.

func (*Grid) SetOnChange

func (g *Grid) SetOnChange(handler func(row, col int, item string))

SetOnChange sets the callback function triggered when the selected cell changes.

func (*Grid) SetOnSelect

func (g *Grid) SetOnSelect(handler func(row, col int, item string))

SetOnSelect sets the callback function triggered when a cell is "activated" (e.g., Enter/Space).

func (*Grid) SetPadding

func (g *Grid) SetPadding(padding int)

SetPadding sets the internal padding (space on left/right) within cells.

func (*Grid) SetSelectionMode

func (g *Grid) SetSelectionMode(mode SelectionMode)

SetSelectionMode sets whether single or multiple cells can be interacted with.

type KeyHandler

type KeyHandler func() bool

KeyHandler defines the function signature for handling registered key events (non-rune or specific runes). It should return true if the key event was handled (consumed), false otherwise.

type KeyModCombo

type KeyModCombo struct {
	Key tcell.Key     // The specific key (e.g., tcell.KeyEnter, tcell.KeyTab).
	Mod tcell.ModMask // The modifier mask (e.g., tcell.ModAlt, tcell.ModCtrl).
}

KeyModCombo represents a non-rune key + modifier combination used for keybindings.

type Layout

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

Layout organizes Panes on screen, arranging them horizontally or vertically according to size constraints and alignment rules.

func NewLayout

func NewLayout(orientation Orientation) *Layout

NewLayout creates a new layout with the specified orientation. Initializes background style from the current theme.

func (*Layout) AddPane

func (l *Layout) AddPane(pane *Pane, size Size) int

AddPane adds a pane to the layout. Triggers layout calculation and navigation index recalculation via command.

func (*Layout) ApplyThemeRecursively

func (l *Layout) ApplyThemeRecursively(theme Theme)

ApplyThemeRecursively applies the theme to the layout itself and propagates it to all child panes.

func (*Layout) ClearAllDirtyFlags

func (l *Layout) ClearAllDirtyFlags()

ClearAllDirtyFlags recursively clears the dirty flag for all descendant panes and components. Called by the application after a successful draw cycle.

func (*Layout) ContainsFocus

func (l *Layout) ContainsFocus(focused Component) bool

ContainsFocus checks recursively if this layout or any of its descendant panes/layouts contain the specified focused component.

func (*Layout) Draw

func (l *Layout) Draw(screen tcell.Screen)

Draw draws the layout background and its active panes.

func (*Layout) GetAllFocusableComponents

func (l *Layout) GetAllFocusableComponents() []Component

GetAllFocusableComponents returns a slice of all focusable components found recursively within this layout's active panes, in the order they appear.

func (*Layout) GetPaneByNavIndex

func (l *Layout) GetPaneByNavIndex(navIndex int) *Pane

GetPaneByNavIndex returns the first pane matching the user navigation index (1-10). Iterates in slot order to ensure Alt+1 targets the *first* eligible pane.

func (*Layout) GetPaneBySlotIndex

func (l *Layout) GetPaneBySlotIndex(slotIndex int) *Pane

GetPaneBySlotIndex returns the pane at the specified internal slot index (0-9).

func (*Layout) GetRect

func (l *Layout) GetRect() (x, y, width, height int)

GetRect returns the layout's current allocated position and size.

func (*Layout) HasDirtyComponents

func (l *Layout) HasDirtyComponents() bool

HasDirtyComponents checks if the layout itself or any of its descendant panes or components are marked as dirty (need redrawing).

func (*Layout) RemovePane

func (l *Layout) RemovePane(index int)

RemovePane removes a pane from the layout by slot index. Triggers layout calculation and navigation index recalculation via command.

func (*Layout) SetApplication

func (l *Layout) SetApplication(app *Application)

SetApplication associates the layout with an application instance. Propagates app reference, sets slot indices for direct children, and triggers initial nav index assignment if this is the root layout.

func (*Layout) SetCrossAxisAlignment

func (l *Layout) SetCrossAxisAlignment(align Alignment)

SetCrossAxisAlignment sets the alignment of panes along the axis perpendicular to the orientation. Affects pane size and position along the cross axis (e.g., Stretch, Start, Center).

func (*Layout) SetGap

func (l *Layout) SetGap(gap int)

SetGap sets the spacing (in cells) between panes in the layout.

func (*Layout) SetMainAxisAlignment

func (l *Layout) SetMainAxisAlignment(align Alignment)

SetMainAxisAlignment sets the alignment of panes along the main axis (Vertical/Horizontal). Affects where panes start if there's extra space along the main axis.

func (*Layout) SetRect

func (l *Layout) SetRect(x, y, width, height int)

SetRect sets the layout's allocated position and size on the screen. Triggers recalculation of child pane positions and sizes if the rectangle changes.

func (*Layout) SetStyle

func (l *Layout) SetStyle(style Style)

SetStyle explicitly sets the background style used for the layout's own area (filling gaps). Consider using themes instead for consistent styling.

type Orientation

type Orientation int

Orientation specifies the direction children are arranged within a Layout.

const (
	// Horizontal arranges child panes side-by-side, left-to-right.
	Horizontal Orientation = iota
	// Vertical arranges child panes one above the other, top-to-bottom.
	Vertical
)

type Pane

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

Pane acts as a container for a single child (which can be a Component or another Layout). It manages the child's position relative to the pane's border and can draw the border, title, and user-facing index indicator.

func NewPane

func NewPane() *Pane

NewPane creates a new pane, initializing styles and border from the current theme.

func NewWrapperPane

func NewWrapperPane(child Component) *Pane

In your main file or a helpers file, if not in tinytui package:

func (*Pane) ApplyThemeRecursively

func (p *Pane) ApplyThemeRecursively(theme Theme)

ApplyThemeRecursively applies the theme to the pane itself and its child. This updates the pane's styles based on the theme and propagates the theme down.

func (*Pane) ClearDirtyFlags

func (p *Pane) ClearDirtyFlags()

ClearDirtyFlags clears the dirty flag for this pane and its child (recursively). Called by the layout/application after drawing.

func (*Pane) ContainsFocus

func (p *Pane) ContainsFocus(focused Component) bool

ContainsFocus checks recursively if this pane or its child contains the specified focused component.

func (*Pane) Draw

func (p *Pane) Draw(screen tcell.Screen, hasFocus bool)

Draw renders the pane. Signature changed back.

func (*Pane) GetChildComponent

func (p *Pane) GetChildComponent() Component

GetChildComponent returns the pane's child if it's a Component, otherwise nil.

func (*Pane) GetChildLayout

func (p *Pane) GetChildLayout() *Layout

GetChildLayout returns the pane's child if it's a Layout, otherwise nil.

func (*Pane) GetFirstFocusableComponent

func (p *Pane) GetFirstFocusableComponent() Component

GetFirstFocusableComponent finds and returns the first focusable component encountered within this pane's child hierarchy (depth-first). Returns nil if none found.

func (*Pane) GetFocusableComponents

func (p *Pane) GetFocusableComponents() []Component

GetFocusableComponents returns a slice of all focusable components within this pane's child hierarchy. The order depends on the child type (single component or layout's traversal order).

func (*Pane) GetNavIndex

func (p *Pane) GetNavIndex() int

GetNavIndex returns the pane's user-facing navigation index (1-10), or 0 if none.

func (*Pane) GetSlotIndex

func (p *Pane) GetSlotIndex() int

GetSlotIndex returns the pane's internal slot index (0-9), or 0 if not set.

func (*Pane) HasFocusableChild

func (p *Pane) HasFocusableChild() bool

HasFocusableChild checks if the pane's child (recursively) contains any focusable component. Used by Draw to determine if the index indicator should potentially be shown.

func (*Pane) IsDirty

func (p *Pane) IsDirty() bool

IsDirty returns true if the pane itself (border, title, style) or its child (recursively) needs redrawing.

func (*Pane) SetApplication

func (p *Pane) SetApplication(app *Application)

SetApplication associates the pane with an application instance and propagates it to the child.

func (*Pane) SetBorder

func (p *Pane) SetBorder(border Border, style Style)

SetBorder allows explicitly setting the pane's default (unfocused) border type and style. Note: This overrides the theme's DefaultBorderType and PaneBorderStyle for this pane. The theme's *focused* border type/style might still apply when focused.

func (*Pane) SetChild

func (p *Pane) SetChild(child interface{})

SetChild sets the pane's content (a Component or another Layout). Validates the child type and propagates application/theme settings.

func (*Pane) SetFocusBorderStyle

func (p *Pane) SetFocusBorderStyle(style Style)

SetFocusBorderStyle allows explicitly setting the focused border style. Note: This overrides the theme's PaneFocusBorderStyle for this pane.

func (*Pane) SetNavIndex

func (p *Pane) SetNavIndex(ni int)

SetNavIndex sets the pane's user-facing navigation index (1-10), or 0 if not navigable. Called dynamically by Layout.assignNavigationIndices.

func (*Pane) SetRect

func (p *Pane) SetRect(x, y, width, height int)

SetRect sets the pane's outer position and size (including any border area). It recalculates and sets the inner rectangle for the child component/layout.

func (*Pane) SetStyle

func (p *Pane) SetStyle(style Style)

SetStyle sets the background style for the pane's content area (inside the border). Note: This overrides the theme's PaneStyle for this specific pane.

func (*Pane) SetTitle

func (p *Pane) SetTitle(title string)

SetTitle sets the text displayed in the top border of the pane.

type PaneInfo

type PaneInfo struct {
	Pane   *Pane
	Size   Size // How the pane should be sized (Fixed or Proportional)
	Active bool // Is this slot in the 'panes' array currently occupied?
}

PaneInfo stores a reference to a Pane and its associated layout constraints (Size).

type RecalculateNavIndicesCommand

type RecalculateNavIndicesCommand struct{}

RecalculateNavIndicesCommand signals the application to recalculate and assign navigation indices to the top-level panes in the root layout.

func (*RecalculateNavIndicesCommand) Execute

func (c *RecalculateNavIndicesCommand) Execute(app *Application)

Execute implements the Command interface.

type Rect

type Rect struct {
	X      int
	Y      int
	Width  int
	Height int
}

Rect defines a rectangular area on the screen using top-left coordinates (X, Y) and dimensions (Width, Height). Standard struct for component geometry.

type RedrawCommand

type RedrawCommand struct{}

RedrawCommand signals that the entire UI needs a redraw.

func (*RedrawCommand) Execute

func (c *RedrawCommand) Execute(app *Application)

Execute implements the Command interface.

type RemovePaneCommand

type RemovePaneCommand struct{ Index int } // Index is Slot Index

RemovePaneCommand requests removing a pane by slot index. The Layout.RemovePane method itself now dispatches the RecalculateNavIndicesCommand.

func (*RemovePaneCommand) Execute

func (c *RemovePaneCommand) Execute(app *Application)

type ScreenMode

type ScreenMode int

ScreenMode controls how the application interacts with the terminal screen buffer upon start.

const (
	// ScreenNormal operates within the terminal's main buffer, using its current size and content.
	ScreenNormal ScreenMode = iota
	// ScreenFullscreen attempts to clear and use the entire terminal window (best effort, depends on terminal).
	ScreenFullscreen
	// ScreenAlternate switches to the terminal's alternate screen buffer (if available). This typically
	// provides a clean slate and restores the previous buffer content when the application exits via Fini().
	ScreenAlternate
)

type SelectionMode

type SelectionMode int

SelectionMode defines how selection and interaction behave within a Grid component.

const (
	// SingleSelect allows only one cell to be in the 'interacted' state at a time.
	// Interacting with a cell (e.g., pressing Enter) sets it as interacted and clears any previously interacted cell.
	SingleSelect SelectionMode = iota
	// MultiSelect allows multiple cells to be independently toggled into/out of the 'interacted' state.
	MultiSelect
)

type SimpleCommand

type SimpleCommand struct {
	Func func(app *Application)
}

SimpleCommand allows dispatching an arbitrary Func function to be run in the main loop.

func (*SimpleCommand) Execute

func (c *SimpleCommand) Execute(app *Application)

Execute implements the Command interface.

type Size

type Size struct {
	FixedSize  int // Fixed size in cells (takes precedence over Proportion). Set to > 0 to use.
	Proportion int // Relative proportion of available space (used if FixedSize <= 0). Set to > 0 to use.
}

Size defines constraints for how a component should be sized within a Layout. Use either FixedSize (absolute cell count) or Proportion (relative share of remaining space). If both are zero or negative, Layout typically assumes Proportion=1.

type Sprite

type Sprite struct {
	BaseComponent
	// contains filtered or unexported fields
}

Sprite displays a fixed grid of styled characters (SpriteCells). Useful for simple pixel-art style graphics or fixed character-based layouts. Cells with no explicit background set in their Style are treated as transparent.

func NewSprite

func NewSprite(cells [][]SpriteCell) *Sprite

NewSprite creates a new sprite component with initial cell data. Initializes background style from the current theme's default text style.

func (*Sprite) ApplyTheme

func (s *Sprite) ApplyTheme(theme Theme)

ApplyTheme updates the sprite's base background style from the theme. Individual cell styles are typically set explicitly and may not react to theme changes unless done manually. Implements ThemedComponent.

func (*Sprite) Clear

func (s *Sprite) Clear(cell SpriteCell)

Clear sets all sprite cells to the specified cell data. Use a transparent cell (e.g., SpriteCell{Rune: ' ', Style: DefaultStyle}) to effectively clear to the sprite's base background style.

func (*Sprite) Dimensions

func (s *Sprite) Dimensions() (width, height int)

Dimensions returns the width (max columns) and height (number of rows) of the sprite data.

func (*Sprite) Draw

func (s *Sprite) Draw(screen tcell.Screen)

Draw renders the sprite onto the screen within the component's allocated rectangle. It respects cell transparency (cells with default background).

func (*Sprite) Focusable

func (s *Sprite) Focusable() bool

Focusable returns false, as Sprites are typically non-interactive display elements.

func (*Sprite) GetCell

func (s *Sprite) GetCell(row, col int) (SpriteCell, bool)

GetCell retrieves the SpriteCell data at a specific coordinate. Returns the cell and true if coordinates are valid, otherwise an empty cell and false.

func (*Sprite) GetCells

func (s *Sprite) GetCells() [][]SpriteCell

GetCells returns a deep copy of the sprite's cell data. This prevents external modification of the internal state.

func (*Sprite) HandleEvent

func (s *Sprite) HandleEvent(event tcell.Event) bool

HandleEvent processes events. Sprites typically don't handle any events.

func (*Sprite) Resize

func (s *Sprite) Resize(newWidth, newHeight int)

Resize changes the sprite's internal cell grid dimensions. Preserves existing cell data where possible. New cells are default (transparent space).

func (*Sprite) SetCell

func (s *Sprite) SetCell(row, col int, cell SpriteCell)

SetCell updates a specific cell (pixel) in the sprite at the given row and column. Coordinates are 0-based. Marks dirty if the cell exists and its value changes.

func (*Sprite) SetCells

func (s *Sprite) SetCells(cells [][]SpriteCell)

SetCells replaces the sprite's entire cell data. The input `cells` should ideally be rectangular.

func (*Sprite) SetCellsFromStrings

func (s *Sprite) SetCellsFromStrings(rows []string, style Style)

SetCellsFromStrings sets sprite content from a slice of strings, applying a base style. Each string is a row. Spaces in the strings are treated as transparent cells, other characters use the provided `style`. Handles wide runes.

func (*Sprite) SetContent

func (s *Sprite) SetContent(content string)

SetContent implements TextUpdater by converting a multi-line string into sprite cells. Each character becomes a cell. Non-space characters get an opaque background, spaces are transparent. This provides a basic way to display text as a sprite.

func (*Sprite) SetStyle

func (s *Sprite) SetStyle(style Style)

SetStyle explicitly sets the sprite's base background style (drawn behind transparent cells). Consider using themes instead for consistent styling.

type SpriteCell

type SpriteCell struct {
	Rune  rune
	Style Style
}

SpriteCell defines a single 'pixel' in the sprite, containing a rune and its style.

type State

type State int

State represents the interaction state of a component, primarily used for visual feedback in interactive elements like Grid cells or potentially Buttons/Checkboxes in the future.

const (
	// StateNormal is the default, non-selected, non-interacted state.
	StateNormal State = iota
	// StateSelected indicates the component/cell is currently selected (e.g., highlighted by a cursor).
	StateSelected
	// StateInteracted indicates the component/cell has been activated or toggled (e.g., Enter pressed on it).
	StateInteracted
)

type Style

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

Style encapsulates the visual attributes of a terminal cell: foreground color, background color, and text attributes (bold, italic, etc.). It wraps tcell.Style for compatibility but provides a fluent interface for modification.

func DefaultGridFocusedInteractedStyle

func DefaultGridFocusedInteractedStyle() Style

func DefaultGridFocusedSelectedStyle

func DefaultGridFocusedSelectedStyle() Style

func DefaultGridFocusedStyle

func DefaultGridFocusedStyle() Style

func DefaultGridInteractedStyle

func DefaultGridInteractedStyle() Style

func DefaultGridSelectedStyle

func DefaultGridSelectedStyle() Style

func DefaultGridStyle

func DefaultGridStyle() Style

func DefaultPaneBorderStyle

func DefaultPaneBorderStyle() Style

func DefaultPaneFocusBorderStyle

func DefaultPaneFocusBorderStyle() Style

func DefaultPaneStyle

func DefaultPaneStyle() Style

func DefaultTextSelectedStyle

func DefaultTextSelectedStyle() Style

func DefaultTextStyle

func DefaultTextStyle() Style

func GetGridStyle

func GetGridStyle(theme Theme, state State, focused bool) Style

GetGridStyle is a helper function to retrieve the appropriate style for a grid cell based on its state (Normal, Selected, Interacted), whether the grid itself has focus, and the provided theme. If `theme` is nil, it uses the current global theme.

func (Style) Attributes

func (s Style) Attributes(attrs AttrMask) Style

Attributes returns a new Style with the specified text attributes mask set, *replacing* any previously set attributes. Use the specific attribute methods (e.g., Bold(true)) or bitwise OR operations to add attributes cumulatively. Does not modify the original Style.

func (Style) Background

func (s Style) Background(c Color) Style

Background returns a new Style with the specified background color set. Does not modify the original Style.

func (s Style) Blink(enable bool) Style

Blink returns a new Style with the blink attribute set or cleared. Does not modify the original Style.

func (Style) Bold

func (s Style) Bold(enable bool) Style

Bold returns a new Style with the bold attribute set (if enable is true) or cleared (if enable is false). Does not modify the original Style.

func (Style) Deconstruct

func (s Style) Deconstruct() (fg Color, bg Color, attrs AttrMask, bgSet bool)

Deconstruct breaks down the style into its component parts: foreground color, background color, and attributes mask. It also returns a boolean `bgSet` which is true if the background color is *not* the default terminal background color. This helps determine if a style intends to be opaque or transparent.

func (Style) Dim

func (s Style) Dim(enable bool) Style

Dim returns a new Style with the dim attribute set or cleared. Does not modify the original Style.

func (Style) Foreground

func (s Style) Foreground(c Color) Style

Foreground returns a new Style with the specified foreground color set. Does not modify the original Style.

func (Style) Italic

func (s Style) Italic(enable bool) Style

Italic returns a new Style with the italic attribute set or cleared. Does not modify the original Style.

func (Style) MergeWith

func (s Style) MergeWith(other Style) Style

MergeWith creates a new style by overlaying the properties of 'other' onto 's'. - Foreground: Uses 'other' foreground if it's not ColorDefault, otherwise uses 's' foreground. - Background: Uses 'other' background if it's explicitly set (`bgSet` is true for 'other'), otherwise uses 's' background. - Attributes: Combines attributes from both styles using bitwise OR.

func (Style) Reverse

func (s Style) Reverse(enable bool) Style

Reverse returns a new Style with the reverse video attribute set or cleared. Does not modify the original Style.

func (Style) StrikeThrough

func (s Style) StrikeThrough(enable bool) Style

StrikeThrough returns a new Style with the strikethrough attribute set or cleared. Does not modify the original Style.

func (Style) ToTcell

func (s Style) ToTcell() tcell.Style

ToTcell converts this tinytui Style back into the underlying tcell.Style required by tcell screen drawing methods.

func (Style) Underline

func (s Style) Underline(enable bool) Style

Underline returns a new Style with the underline attribute set or cleared. Does not modify the original Style.

type Text

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

Text displays static or wrapping text content. It is typically not focusable or interactive, serving as a label or display area. Supports basic scrolling.

func NewText

func NewText(content string) *Text

NewText creates a new Text component with the specified initial content. Initializes style from the current theme.

func (*Text) ApplyTheme

func (t *Text) ApplyTheme(theme Theme)

ApplyTheme updates the text's style based on the provided theme. Implements ThemedComponent.

func (*Text) Draw

func (t *Text) Draw(screen tcell.Screen)

Draw renders the text component onto the screen, handling wrapping, scrolling, and alignment.

func (*Text) Focusable

func (t *Text) Focusable() bool

Focusable returns false, as Text components are not typically interactive or focusable.

func (*Text) GetContent

func (t *Text) GetContent() string

GetContent returns the raw, unprocessed text content assigned to the component.

func (*Text) GetStyle

func (t *Text) GetStyle() Style

GetStyle returns the current text style used by the component.

func (*Text) HandleEvent

func (t *Text) HandleEvent(event tcell.Event) bool

HandleEvent processes events. Text components typically don't handle events by default. Scrolling could potentially be added here if the component were made focusable.

func (*Text) ScrollDown

func (t *Text) ScrollDown(count int)

ScrollDown scrolls down by the specified number of lines. Does nothing if count <= 0.

func (*Text) ScrollTo

func (t *Text) ScrollTo(lineIndex int)

ScrollTo attempts to scroll the text so that the specified line index is at the top. Line index is 0-based. Clamps to valid range. Recalculates lines if needed.

func (*Text) ScrollUp

func (t *Text) ScrollUp(count int)

ScrollUp scrolls up by the specified number of lines. Does nothing if count <= 0.

func (*Text) SetAlignment

func (t *Text) SetAlignment(align AlignmentText)

SetAlignment sets the horizontal text alignment (Left, Center, Right).

func (*Text) SetContent

func (t *Text) SetContent(content string)

SetContent updates the text displayed by the component. Resets the line cache and scroll position.

func (*Text) SetStyle

func (t *Text) SetStyle(style Style)

SetStyle explicitly sets the text style, overriding the theme default. Consider using themes for consistent styling.

func (*Text) SetWrap

func (t *Text) SetWrap(wrap bool)

SetWrap enables or disables text wrapping within the component's width. Invalidates the line cache if the setting changes.

type TextInput

type TextInput struct {
	BaseComponent
	// contains filtered or unexported fields
}

TextInput provides a single-line text entry field with cursor navigation, editing capabilities (insert, delete, backspace), optional masking for passwords, and optional maximum length enforcement. It is focusable and interactive.

func NewTextInput

func NewTextInput() *TextInput

NewTextInput creates a new text input component. Initializes styles from the current theme.

func (*TextInput) ApplyTheme

func (t *TextInput) ApplyTheme(theme Theme)

ApplyTheme updates the text input's styles based on the provided theme. Implements ThemedComponent.

func (*TextInput) Draw

func (t *TextInput) Draw(screen tcell.Screen)

Draw renders the text input component, including text (masked or not), and requests cursor position.

func (*TextInput) Focusable

func (t *TextInput) Focusable() bool

Focusable returns true if the component is visible, indicating it can receive input focus.

func (*TextInput) GetText

func (t *TextInput) GetText() string

GetText returns the current text content as a string.

func (*TextInput) HandleEvent

func (t *TextInput) HandleEvent(event tcell.Event) bool

HandleEvent processes key events for text input manipulation (insert, delete, backspace), cursor movement (arrows, home, end), and submission (Enter).

func (*TextInput) SetContent

func (t *TextInput) SetContent(text string)

SetContent is an alias for SetText to implement the TextUpdater interface.

func (*TextInput) SetFocusedStyle

func (t *TextInput) SetFocusedStyle(style Style)

SetFocusedStyle explicitly sets the focused style, overriding the theme-derived default.

func (*TextInput) SetMasked

func (t *TextInput) SetMasked(masked bool, maskRune rune)

SetMasked enables or disables password-style masking using the specified rune.

func (*TextInput) SetMaxLength

func (t *TextInput) SetMaxLength(max int)

SetMaxLength sets the maximum number of runes allowed in the input. Truncates existing text and adjusts cursor if the new limit is smaller. Setting max to 0 disables the length limit.

func (*TextInput) SetOnChange

func (t *TextInput) SetOnChange(handler func(string))

SetOnChange sets the callback function triggered whenever the text content changes due to user input.

func (*TextInput) SetOnSubmit

func (t *TextInput) SetOnSubmit(handler func(string))

SetOnSubmit sets the callback function triggered when the Enter key is pressed within the input field.

func (*TextInput) SetStyle

func (t *TextInput) SetStyle(style Style)

SetStyle explicitly sets the base (unfocused) style, overriding the theme. Consider using themes for consistent styling.

func (*TextInput) SetText

func (t *TextInput) SetText(text string)

SetText replaces the current text content with the given string. Enforces maximum length and moves the cursor to the end.

type TextUpdater

type TextUpdater interface {
	Component
	// SetContent updates the main text content of the component.
	SetContent(content string)
}

TextUpdater is an optional interface for components whose primary content can be updated programmatically via a string, often used with UpdateTextCommand.

type Theme

type Theme interface {
	// Name returns the unique identifier of the theme (e.g., "default", "turbo").
	Name() ThemeName

	// TextStyle returns the default style for standard text elements like Text components.
	TextStyle() Style
	// TextSelectedStyle returns the style for selected text elements (e.g., in a future List component).
	TextSelectedStyle() Style

	// GridStyle returns the style for normal, unfocused grid cells.
	GridStyle() Style
	// GridSelectedStyle returns the style for selected grid cells when the grid is not focused.
	GridSelectedStyle() Style
	// GridInteractedStyle returns the style for interacted (e.g., toggled) grid cells when the grid is not focused.
	GridInteractedStyle() Style
	// GridFocusedStyle returns the style for normal grid cells when the grid itself has input focus.
	GridFocusedStyle() Style
	// GridFocusedSelectedStyle returns the style for selected grid cells when the grid has input focus.
	GridFocusedSelectedStyle() Style
	// GridFocusedInteractedStyle returns the style for interacted grid cells when the grid has input focus.
	GridFocusedInteractedStyle() Style

	// PaneStyle returns the background style for the content area within panes (inside the border).
	PaneStyle() Style
	// PaneBorderStyle returns the style for pane borders when the pane (or its children) are not focused.
	PaneBorderStyle() Style
	// PaneFocusBorderStyle returns the style for pane borders when the pane (or its children) has input focus.
	PaneFocusBorderStyle() Style

	// DefaultCellWidth returns the theme's preferred default width for grid cells (used if Grid.autoWidth is false).
	DefaultCellWidth() int
	// DefaultCellHeight returns the theme's preferred default height for grid cells (usually 1).
	DefaultCellHeight() int
	// DefaultPadding returns the theme's preferred default internal padding within widgets like Grid cells.
	DefaultPadding() int

	// IndicatorColor returns the theme's preferred color for selection indicators (e.g., the cursor in a Grid).
	IndicatorColor() Color

	// DefaultBorderType returns the theme's preferred default border type for panes (e.g., BorderSingle, BorderDouble).
	DefaultBorderType() Border
	// FocusedBorderType returns the theme's preferred border type for panes when they (or their children) have focus.
	FocusedBorderType() Border
}

Theme defines the interface for providing styles and properties for UI elements. Implementations of this interface determine the visual appearance of the application.

func GetTheme

func GetTheme() Theme

GetTheme returns the currently active global theme. It's safe for concurrent reading due to the RWMutex.

func NewDefaultTheme

func NewDefaultTheme() Theme

NewDefaultTheme creates the default theme.

func NewTokyoSweetTheme

func NewTokyoSweetTheme() Theme

NewTokyoSweetTheme creates a modern theme inspired by Tokyo Night and KDE Sweet

func NewTurboTheme

func NewTurboTheme() Theme

NewTurboTheme creates a theme inspired by classic Turbo Vision (blue background).

type ThemeName

type ThemeName string

ThemeName identifies a predefined theme (e.g., "default", "turbo"). Used for registering and setting themes.

const (
	// ThemeDefault is the standard light-background fallback theme.
	ThemeDefault ThemeName = "default"
	// ThemeTurbo is a theme inspired by Turbo Vision's classic blue-background look.
	ThemeTurbo ThemeName = "turbo"
	// ThemeTokyoSweet is a combination of KDE sweet and Tokyo night themes.
	ThemeTokyoSweet ThemeName = "tokyo-sweet"
)

type ThemedComponent

type ThemedComponent interface {
	Component
	// ApplyTheme updates the component's appearance (e.g., internal styles)
	// based on the properties of the provided theme.
	ApplyTheme(theme Theme)
}

ThemedComponent is an optional interface for components that require custom logic to update their appearance when the application's theme changes. Components implementing this will have their ApplyTheme method called automatically when app.SetTheme() is used or when added to a layout within an application.

type UpdateGridCommand

type UpdateGridCommand struct {
	Target  *Grid      // The target Grid component.
	Content [][]string // The new cell data.
}

UpdateGridCommand requests updating the cells of a Grid component.

func (*UpdateGridCommand) Execute

func (c *UpdateGridCommand) Execute(app *Application)

Execute implements the Command interface.

type UpdateSpriteCommand

type UpdateSpriteCommand struct {
	Target  *Sprite        // The target Sprite component.
	Content [][]SpriteCell // The new sprite cell data.
}

UpdateSpriteCommand requests updating the cells of a Sprite component.

func (*UpdateSpriteCommand) Execute

func (c *UpdateSpriteCommand) Execute(app *Application)

Execute implements the Command interface.

type UpdateTextCommand

type UpdateTextCommand struct {
	Target  TextUpdater // Component must implement TextUpdater.
	Content string      // The new text content.
}

UpdateTextCommand requests updating the content of a TextUpdater component.

func (*UpdateTextCommand) Execute

func (c *UpdateTextCommand) Execute(app *Application)

Execute implements the Command interface.

Directories

Path Synopsis
cmd
1 command
2 command
3 command
4 command
5 command
main_test_indexing.go
main_test_indexing.go

Jump to

Keyboard shortcuts

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