2026-01-16 19:34:06 +05:00
2026-01-13 11:17:14 +05:00
2026-01-12 22:57:31 +05:00
2026-01-16 19:34:06 +05:00
2026-01-16 19:34:06 +05:00
2026-01-09 02:21:50 +05:00
2026-01-12 21:54:15 +05:00
2026-01-13 18:41:22 +05:00
2026-01-09 06:11:44 +05:00

tim

Fork of https://codeberg.org/chuvok/tim.h

about

tim is a portable library to create simple terminal applications Demo video: https://asciinema.org/a/zn3p0dsVCOQOzwY1S9gDfyaxQ

build

  1. Clone this repository.

    git clone https://timerix.ddns.net/git/Timerix/tim.git
    
  2. Install cbuild. Select latest version compatible with the one in project.config. Example: For 2.3.2 download latest 2.3.x.

  3. Build static library

    cd tim
    cbuild build_static_lib
    
  4. Build tests and examples

    cbuild ask hello snek test color string
    

quick start

See example/hello.c

layout

The terminal's columns (x) and rows (y) are addressed by their coordinates, the origin is in the top left corner.

Scopes are the primary layout mechanism. They are used to group and place multiple elements. Scopes can be nested.

The root scope is the full terminal screen. The scope macro is constructed with a for loop, so statements like break or return inside the scope block will probably give you a bad time.

Elements (widget, control, component) are elements of user interaction, such as a button or edit box. Most elements take x/y/w/h arguments to control placement. All positions are given in relation the element's parent scope.

Automatic (A) width and height are either based on the element's content, or take the full available space from parent.

arg value placement
x n n columns to left
x ~n n columns to right
x A center horizontally
y n n rows to top
y ~n n rows to bottom
y A center vertically
w n n columns wide
w ~n fit width to n columns to right
w A automatic width
h n n rows high
h ~n fit height n rows to bottom
h A automatic height

The layout automatically adopts to terminal window resize events.

colors

Colors are stored as 8-bit values. Most terminals support 16 ANSI colors. You can see them in TimColor16 enum. It's better to use xterm256 colors istead, because ANSI colors look different in each terminal. https://www.ditig.com/256-colors-cheat-sheet xterm-256 color chart

events

tim_run blocks until it observes an event. Mouse and key events are always immediately followed by a draw event in order to make changes visible.

Some elements need to consume events, for example edit consumes the key event when focused in order to prevent other key handlers on acting on them.

The current event is stored in tim->event.

elements

frame (x, y, w, h, color)

Draw an empty frame and fill area.

x/y/w/h see layout documentation
style   background, frame

label (str, x, y, w, h, color)

Draw text label. Automatic width and height are supported. Strings
exceeding width or height are clipped.

str     zero terminated string
x/y/w/h see layout documentation
style   background, text

button (str, x, y, w, h, color) -> bool

Draw button. Automatic width and height are supported. Strings exceeding
width or height are clipped. Returns true when clicked.

str     zero terminated string
x/y/w/h see layout documentation
style   frame, background, text

edit (state, x, y, w, color) -> int

Draw text edit. Output is stored in state.s. 
Receives input events when focused by mouse click or by setting focus manually. 
Escape or return relinquish focus.
Returns key id if received key input.

state   pointer to persistent edit state struct
x/y/w   see layout documentation
style   f   rame, background, text

check (str, state, x, y, w, color) -> bool

Draw check box. State determines how the box is checked. [x] when state
is non-zero, [ ] when state is zero, [-] when state is -1. A mouse click
toggles the state between one and zero and returns true.

str     zero terminated string
state   pointer to persistent state variable
x/y/w   see layout documentation
style   check, background, text

radio (str, state, v, x, y, w, color) -> bool

Draw radio box. If state equals v, the box is selected. Radios are
grouped through a shared state. Within that group, each v must be unique.
A mouse click assigns v to state and returns true.

str     zero terminated string
state   pointer to persistent state variable
v       unique state value
x/y/w   see layout documentation
style   radio, background, text

functions

tim_run (fps) -> bool

Process events and render frame. Blocks until input is received or the
next frame is due. First call also initializes the terminal. When fps is
zero the function blocks until input is received. Key and mouse events
are immediately followed by a draw event, so the actual fps can be
significantly greater than requested. Always returns true. To reset the
terminal after a crash, run "reset".
The Ctrl-C interrupt is masked, so make sure to put an exit condition
like this at the end of the main loop:

    if (tim_is_key_press(ESCAPE_KEY))
        exit(0);

fps     frames per second

tim_is_key_press (key) -> bool

Returns true if key was pressed.

key     char literal or one of the KEY constants, see constants

tim_time_usec () -> int64

Returns monotonic clock value in microseconds. Not affected by summer
time or leap seconds.

https://invisible-island.net/xterm/ctlseqs/ctlseqs.html https://learn.microsoft.com/en-us/windows/console/

bugs

  • If Enter key doesn't work as expected on linux, write stty sane to ~/.profile. It will change terminal settings from insane to sane xD
  • Double buffering is still new, set ENABLE_DBUF to 0 if you see glitches
  • Double width characters like 彁 are not fully supported. Terminals do not handle these consistently and there is no portable way to reliably determine character width. The renderer can deal with some of the problems caused by this, but results may vary.
  • Decomposed (NFD) UTF-8 is not supported and will cause havoc
  • Zero width code points are not supported
  • Windows cmd.exe resize events may be delayed

compatibility

emulator support remarks
Alacritty ?
cmd.exe good resize may lag
Cool Retro Term good wide character spill
Deepin Terminal good wide character spill
Eterm abysmal garbled output
GNOME Terminal full
GNUstep Terminal abysmal garbled output
iTerm2 ?
kitty full
Konsole full
LXTerminal full
macOS Terminal ?
PuTTY full
QTerminal good wide character spill
rxvt-unicode full
GNU Screen good no alternate buffer, double esc
st full
Terminator full
Terminology full
tmux good esc lags
Windows Terminal full
Xfce Terminal full
XTerm full XTerm is law
Zutty full

license

MIT License

Copyright (c) MMXXIV Chu'vok chuvok@maeppi.e4ward.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.

Description
TUI library
Readme 352 KiB
Languages
C 91.3%
Shell 8.7%