Module term.ui stdlib

term.ui
Version:
0.3.3
License:
MIT
Dependencies from vmod:
0
Imports:
4
Imported by:
0
Repository:
OS-specific
Show selected OS-specific symbols.
Backend-specific
Show selected Backend-specific symbols.

Dependencies defined in v.mod

This section is empty.

Imports

Imported by

This section is empty.

Overview

term.ui

A V module for designing terminal UI apps

Quickstart
import term.ui as tui

struct App {
mut:
    tui &tui.Context = unsafe { nil }
}

fn event(e &tui.Event, x voidptr) {
    if e.typ == .key_down && e.code == .escape {
        exit(0)
    }
}

fn frame(x voidptr) {
    mut app := &App(x)

    app.tui.clear()
    app.tui.set_bg_color(r: 63, g: 81, b: 181)
    app.tui.draw_rect(20, 6, 41, 10)
    app.tui.draw_text(24, 8, 'Hello from V!')
    app.tui.set_cursor_position(0, 0)

    app.tui.reset()
    app.tui.flush()
}

fn main() {
    mut app := &App{}
    app.tui = tui.init(
        user_data: app
        event_fn: event
        frame_fn: frame
        hide_cursor: true
    )
    app.tui.run()?
}

See the /examples/term.ui/ folder for more usage examples.

Configuration
  • user_data voidptr - a pointer to any user_data, it will be passed as the last argument to each callback. Used for accessing your app context from the different callbacks.
  • init_fn fn(voidptr) - a callback that will be called after initialization and before the first event / frame. Useful for initializing any user data.
  • frame_fn fn(voidptr) - a callback that will be fired on each frame, at a rate of frame_rate frames per second. event_fn fn(&Event, voidptr) - a callback that will be fired for every event received.
  • cleanup_fn fn(voidptr) - a callback that will be fired once, before the application exits.
  • fail_fn fn(string) - a callback that will be fired if a fatal error occurs during app initialization.
  • buffer_size int = 256 - the internal size of the read buffer. Increasing it may help in case you're missing events, but you probably shouldn't lower this value unless you make sure you're still receiving all events. In general, higher frame rates work better with lower buffer sizes, and vice versa.
  • frame_rate int = 30 - the number of times per second that the frame callback will be fired. 30fps is a nice balance between smoothness and performance, but you can increase or lower it as you wish.
  • hide_cursor bool - whether to hide the mouse cursor. Useful if you want to use your own.
  • capture_events bool - sets the terminal into raw mode, which makes it intercept some escape codes such as ctrl + c and ctrl + z. Useful if you want to use those key combinations in your app.
  • window_title string - sets the title of the terminal window. This may be changed later, by calling the set_window_title() method.
  • reset []int = [1, 2, 3, 4, 6, 7, 8, 9, 11, 13, 14, 15, 19] - a list of reset signals, to setup handlers to cleanup the terminal state when they're received. You should not need to change this, unless you know what you're doing.

All of these fields may be omitted, in which case, the default value will be used. In the case of the various callbacks, they will not be fired if a handler has not been specified.

FAQ

Q: My terminal (doesn't receive events / doesn't print anything / prints gibberish characters), what's up with that? A: Please check if your terminal. The module has been tested with xterm-based terminals on Linux (like gnome-terminal and konsole), and Terminal.app and iterm2 on macOS. If your terminal does not work, open an issue with the output of echo $TERM.

Q: There are screen tearing issues when doing large prints A: This is an issue with how terminals render frames, as they may decide to do so in the middle of receiving a frame, and cannot be fully fixed unless your console implements the synchronized updates spec. It can be reduced drastically, though, by using the rendering methods built in to the module, and by only painting frames when your app's content has actually changed.

Q: Why does the module only emit keydown events, and not keyup like sokol/gg? A: It's because of the way terminals emit events. Every key event is received as a keypress, and there isn't a way of telling terminals to send keyboard events differently, nor a reliable way of converting these into keydown / keyup events.

Aliases

This section is empty.

Constants

#constant color_table

pub const color_table = init_color_table()

Sum types

This section is empty.

Functions

#fn init

Windows
fn init(cfg Config) &Context

init initializes the context of a windows console given the cfg.

#fn init

Linux
fn init(cfg Config) &Context

init initializes the terminal console with Config cfg.

Structs

#union C.Event

Windows
pub union C.Event {
	KeyEvent              C.KEY_EVENT_RECORD
	MouseEvent            C.MOUSE_EVENT_RECORD
	WindowBufferSizeEvent C.WINDOW_BUFFER_SIZE_RECORD
	MenuEvent             C.MENU_EVENT_RECORD
	FocusEvent            C.FOCUS_EVENT_RECORD
}

#struct C.INPUT_RECORD

Windowstypedef
pub struct C.INPUT_RECORD {
	EventType u16
	Event     C.Event
}

#union C.uChar

Windows
pub union C.uChar {
mut:
	UnicodeChar rune
	AsciiChar   u8
}

#struct C.KEY_EVENT_RECORD

Windowstypedef
pub struct C.KEY_EVENT_RECORD {
	bKeyDown          int
	wRepeatCount      u16
	wVirtualKeyCode   u16
	wVirtualScanCode  u16
	uChar             C.uChar
	dwControlKeyState u32
}

#struct C.MOUSE_EVENT_RECORD

Windowstypedef
pub struct C.MOUSE_EVENT_RECORD {
	dwMousePosition   C.COORD
	dwButtonState     u32
	dwControlKeyState u32
	dwEventFlags      u32
}

#struct C.WINDOW_BUFFER_SIZE_RECORD

Windowstypedef
pub struct C.WINDOW_BUFFER_SIZE_RECORD {
	dwSize C.COORD
}

#struct C.MENU_EVENT_RECORD

Windowstypedef
pub struct C.MENU_EVENT_RECORD {
	dwCommandId u32
}

#struct C.FOCUS_EVENT_RECORD

Windowstypedef
pub struct C.FOCUS_EVENT_RECORD {
	bSetFocus int
}

#struct C.COORD

Windowstypedef
pub struct C.COORD {
mut:
	X i16
	Y i16
}

#struct C.SMALL_RECT

Windowstypedef
pub struct C.SMALL_RECT {
mut:
	Left   u16
	Top    u16
	Right  u16
	Bottom u16
}

#struct C.CONSOLE_SCREEN_BUFFER_INFO

Windowstypedef
pub struct C.CONSOLE_SCREEN_BUFFER_INFO {
mut:
	dwSize              C.COORD
	dwCursorPosition    C.COORD
	wAttributes         u16
	srWindow            C.SMALL_RECT
	dwMaximumWindowSize C.COORD
}

#struct Event

pub struct Event {
pub:
	typ EventType
	// Mouse event info
	x         int
	y         int
	button    MouseButton
	direction Direction
	// Keyboard event info
	code      KeyCode
	modifiers Modifiers
	ascii     u8
	utf8      string
	// Resized event info
	width  int
	height int
}

#struct Context

pub struct Context {
	ExtraContext // contains fields specific to an implementation
pub:
	cfg Config // the initial configuration, passed to ui.init()
mut:
	print_buf  []u8
	paused     bool
	enable_su  bool
	enable_rgb bool
pub mut:
	frame_count   u64
	window_width  int
	window_height int
}

#fn (&Context) init

inline
fn (ctx &Context) init()

#fn (&Context) frame

inline
fn (ctx &Context) frame()

#fn (&Context) cleanup

inline
fn (ctx &Context) cleanup()

#fn (&Context) fail

inline
fn (ctx &Context) fail(error string)

#fn (&Context) event

inline
fn (ctx &Context) event(event &Event)

#fn (&Context) run

Linux
fn (mut ctx &Context) run() ?

run sets up and starts the terminal.

#fn (&Context) shift

Linuxinline
fn (mut ctx &Context) shift(len int)

shifts the array left, to remove any data that was just read, and updates its len TODO: remove

#fn (&Context) resize_arr

Linuxinline
fn (mut ctx &Context) resize_arr(size int)

TODO: don't actually do this, lmao

#fn (&Context) termios_setup

Linux
fn (mut ctx &Context) termios_setup() !

#fn (&Context) termios_loop

Linux
fn (mut ctx &Context) termios_loop()

///////////////////////////////////////// TODO: do multiple sleep/read cycles, rather than one big one

#fn (&Context) parse_events

Linux
fn (mut ctx &Context) parse_events()

#fn (&Context) write

inline
fn (mut ctx &Context) write(s string)

write puts the string s into the print buffer.

#fn (&Context) flush

inline
fn (mut ctx &Context) flush()

flush displays the accumulated print buffer to the screen.

#fn (&Context) bold

inline
fn (mut ctx &Context) bold()

bold sets the character state to bold.

#fn (&Context) set_cursor_position

inline
fn (mut ctx &Context) set_cursor_position(x int, y int)

set_cursor_position positions the cusor at the given coordinates x,y.

#fn (&Context) show_cursor

inline
fn (mut ctx &Context) show_cursor()

show_cursor will make the cursor appear if it is not already visible

#fn (&Context) hide_cursor

inline
fn (mut ctx &Context) hide_cursor()

hide_cursor will make the cursor invisible

#fn (&Context) set_color

inline
fn (mut ctx &Context) set_color(c Color)

set_color sets the current foreground color used by any succeeding draw_* calls.

#fn (&Context) set_bg_color

inline
fn (mut ctx &Context) set_bg_color(c Color)

set_color sets the current background color used by any succeeding draw_* calls.

#fn (&Context) reset_color

inline
fn (mut ctx &Context) reset_color()

reset_color sets the current foreground color back to it's default value.

#fn (&Context) reset_bg_color

inline
fn (mut ctx &Context) reset_bg_color()

reset_bg_color sets the current background color back to it's default value.

#fn (&Context) reset

inline
fn (mut ctx &Context) reset()

reset restores the state of all colors and text formats back to their default values.

#fn (&Context) clear

inline
fn (mut ctx &Context) clear()

clear erases the entire terminal window and any saved lines.

#fn (&Context) set_window_title

inline
fn (mut ctx &Context) set_window_title(s string)

set_window_title sets the string s as the window title.

#fn (&Context) draw_point

inline
fn (mut ctx &Context) draw_point(x int, y int)

draw_point draws a point at position x,y.

#fn (&Context) draw_text

inline
fn (mut ctx &Context) draw_text(x int, y int, s string)

draw_text draws the string s, starting from position x,y.

#fn (&Context) draw_line

fn (mut ctx &Context) draw_line(x int, y int, x2 int, y2 int)

draw_line draws a line segment, starting at point x,y, and ending at point x2,y2.

#fn (&Context) draw_dashed_line

fn (mut ctx &Context) draw_dashed_line(x int, y int, x2 int, y2 int)

draw_dashed_line draws a dashed line segment, starting at point x,y, and ending at point x2,y2.

#fn (&Context) draw_rect

fn (mut ctx &Context) draw_rect(x int, y int, x2 int, y2 int)

draw_rect draws a rectangle, starting at top left x,y, and ending at bottom right x2,y2.

#fn (&Context) draw_empty_dashed_rect

fn (mut ctx &Context) draw_empty_dashed_rect(x int, y int, x2 int, y2 int)

draw_empty_dashed_rect draws a rectangle with dashed lines, starting at top left x,y, and ending at bottom right x2,y2.

#fn (&Context) draw_empty_rect

fn (mut ctx &Context) draw_empty_rect(x int, y int, x2 int, y2 int)

draw_empty_rect draws a rectangle with no fill, starting at top left x,y, and ending at bottom right x2,y2.

#fn (&Context) horizontal_separator

inline
fn (mut ctx &Context) horizontal_separator(y int)

horizontal_separator draws a horizontal separator, spanning the width of the screen.

#struct Config

pub struct Config {
	user_data  voidptr
	init_fn    fn (voidptr)
	frame_fn   fn (voidptr)
	cleanup_fn fn (voidptr)
	event_fn   fn (&Event, voidptr)
	fail_fn    fn (string)

	buffer_size int = 256
	frame_rate  int = 30
	use_x11     bool

	window_title         string
	hide_cursor          bool
	capture_events       bool
	use_alternate_buffer bool = true
	skip_init_checks     bool
	// All kill signals to set up exit listeners on:
	reset []os.Signal = [.hup, .int, .quit, .ill, .abrt, .bus, .fpe, .kill, .segv, .pipe, .alrm, .term,
	.stop]
}

#struct C.winsize

Linux
pub struct C.winsize {
	ws_row u16
	ws_col u16
}

#struct Color

pub struct Color {
pub:
	r u8
	g u8
	b u8
}

#fn (Color) hex

fn (c Color) hex() string

hex returns c's RGB color in hex format.

Interfaces

This section is empty.

Enums

#enum KeyCode

pub enum KeyCode {
	null = 0
	tab = 9
	enter = 10
	escape = 27
	space = 32
	backspace = 127
	exclamation = 33
	double_quote = 34
	hashtag = 35
	dollar = 36
	percent = 37
	ampersand = 38
	single_quote = 39
	left_paren = 40
	right_paren = 41
	asterisk = 42
	plus = 43
	comma = 44
	minus = 45
	period = 46
	slash = 47
	_0 = 48
	_1 = 49
	_2 = 50
	_3 = 51
	_4 = 52
	_5 = 53
	_6 = 54
	_7 = 55
	_8 = 56
	_9 = 57
	colon = 58
	semicolon = 59
	less_than = 60
	equal = 61
	greater_than = 62
	question_mark = 63
	at = 64
	a = 97
	b = 98
	c = 99
	d = 100
	e = 101
	f = 102
	g = 103
	h = 104
	i = 105
	j = 106
	k = 107
	l = 108
	m = 109
	n = 110
	o = 111
	p = 112
	q = 113
	r = 114
	s = 115
	t = 116
	u = 117
	v = 118
	w = 119
	x = 120
	y = 121
	z = 122
	left_square_bracket = 91
	backslash = 92
	right_square_bracket = 93
	caret = 94
	underscore = 95
	backtick = 96
	left_curly_bracket = 123
	vertical_bar = 124
	right_curly_bracket = 125
	tilde = 126
	insert = 260
	delete = 261
	up = 262
	down = 263
	right = 264
	left = 265
	page_up = 266
	page_down = 267
	home = 268
	end = 269
	f1 = 290
	f2 = 291
	f3 = 292
	f4 = 293
	f5 = 294
	f6 = 295
	f7 = 296
	f8 = 297
	f9 = 298
	f10 = 299
	f11 = 300
	f12 = 301
	f13 = 302
	f14 = 303
	f15 = 304
	f16 = 305
	f17 = 306
	f18 = 307
	f19 = 308
	f20 = 309
	f21 = 310
	f22 = 311
	f23 = 312
	f24 = 313
}

#enum Direction

pub enum Direction {
	unknown
	up
	down
	left
	right
}

#enum MouseButton

pub enum MouseButton {
	unknown
	left
	middle
	right
}

#enum EventType

pub enum EventType {
	unknown
	mouse_down
	mouse_up
	mouse_move
	mouse_drag
	mouse_scroll
	key_down
	resized
}

#enum Modifiers

flag
pub enum Modifiers {
	ctrl
	shift
	alt
}