ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
table.c File Reference

Go to the source code of this file.

Macros

#define UI_TABLE_CLIPPED_BUFFER_SIZE   8192
#define UI_TABLE_LINE_BUFFER_SIZE   8192
#define UI_TABLE_CELL_CAPACITY   32

Functions

size_t ui_table_row (char *out, size_t cap, const ui_table_column_t *cols, const char *const *cells, size_t count, int width, bool selectable, bool selected)
 When code needs to work with ui table, it keeps columns, column_count, row_count, viewport here instead of scattering it across globals. Initialization establishes the handles and sizes; teardown must release any allocation, lock, thread, or callback context recorded in those fields. terminal columns, never by bytes. The caller owns data and sorting.
void ui_table_render (frame_buffer_t *out, ui_table_t *t, int row, int col, int width, int height)

Macro Definition Documentation

◆ UI_TABLE_CELL_CAPACITY

#define UI_TABLE_CELL_CAPACITY   32

Definition at line 7 of file table.c.

Referenced by ui_table_render().

◆ UI_TABLE_CLIPPED_BUFFER_SIZE

#define UI_TABLE_CLIPPED_BUFFER_SIZE   8192

Definition at line 3 of file table.c.

Referenced by ui_table_row().

◆ UI_TABLE_LINE_BUFFER_SIZE

#define UI_TABLE_LINE_BUFFER_SIZE   8192

Definition at line 4 of file table.c.

Referenced by ui_table_render().

Function Documentation

◆ ui_table_render()

void ui_table_render ( frame_buffer_t * out,
ui_table_t * table,
int row,
int column,
int width,
int height )

Rectangular table with a fixed header and independent page/scroll state.

Definition at line 76 of file table.c.

76 {
77 if (!out || !t || !t->columns || !t->column_count || t->column_count > 32 || !t->cells || width < 2 || height < 1 ||
78 row < 1 || col < 1) {
79 SET_ERRNO(ERROR_INVALID_PARAM, "Invalid table output, data source or geometry");
80 return;
81 }
83 if (t->header) {
84 ui_table_row(line, sizeof(line), t->columns, NULL, t->column_count, width - 1, t->selectable, false);
85 frame_buffer_printf(out, "\033[%d;%dH%s%s%s", row++, col, ui_text_color_prefix(LOG_COLOR_DEBUG), line,
87 --height;
88 }
89 if (height < 1)
90 return;
92 for (int i = 0; i < height; ++i) {
93 const char *cells[UI_TABLE_CELL_CAPACITY] = {0};
94 if ((size_t)i < range.count) {
95 t->cells(range.first + (size_t)i, cells, t->column_count, t->data);
96 ui_table_row(line, sizeof(line), t->columns, cells, t->column_count, width - 1, t->selectable,
97 range.first + (size_t)i == t->viewport.selected);
98 } else
99 snprintf(line, sizeof(line), "%*s", width - 1, "");
100 bool selected = t->selectable && (size_t)i < range.count && range.first + (size_t)i == t->viewport.selected;
101 frame_buffer_printf(out, "\033[%d;%dH%s%s%s", row + i, col, selected ? "\033[7m" : "", line,
102 selected ? "\033[27m" : "");
103 }
104 ui_scrollbar_render(out, row, col + width - 1, height, range.page_count, (size_t)height, t->viewport.first_visible);
105}
#define SET_ERRNO(code,...)
char cells[(512 *256 *2)]
Definition fft.c:21
unsigned int height
Definition fft.c:23
unsigned int width
Definition fft.c:23
void frame_buffer_printf(frame_buffer_t *buf, const char *fmt,...)
Printf-style append to the buffer.
@ ERROR_INVALID_PARAM
@ LOG_COLOR_RESET
Definition log/log.h:155
@ LOG_COLOR_DEBUG
Definition log/log.h:149
static bool size_t gotel_query_t * out
Definition queries.h:8
void ui_scrollbar_render(frame_buffer_t *out, int row, int col, int height, size_t total, size_t visible, size_t offset)
Definition scrollbar.c:40
bool header
Definition table.h:28
const ui_table_column_t * columns
Definition table.h:23
size_t row_count
Definition table.h:24
size_t column_count
Definition table.h:24
bool selectable
Definition table.h:28
ui_viewport_t viewport
Definition table.h:25
void * data
Definition table.h:27
ui_table_cells_fn cells
Definition table.h:26
size_t first_visible
Definition viewport.h:11
size_t selected
Definition viewport.h:11
size_t ui_table_row(char *out, size_t cap, const ui_table_column_t *cols, const char *const *cells, size_t count, int width, bool selectable, bool selected)
When code needs to work with ui table, it keeps columns, column_count, row_count, viewport here inste...
Definition table.c:18
#define UI_TABLE_LINE_BUFFER_SIZE
Definition table.c:4
#define UI_TABLE_CELL_CAPACITY
Definition table.c:7
const char * ui_text_color_prefix(log_color_t color)
Definition text.c:18
ui_viewport_range_t ui_viewport_update(ui_viewport_t *v, size_t count, size_t rows)
Definition viewport.c:4

References cells, ui_table_t::cells, ui_table_t::column_count, ui_table_t::columns, ui_viewport_range_t::count, ui_table_t::data, ERROR_INVALID_PARAM, ui_viewport_range_t::first, ui_viewport_t::first_visible, frame_buffer_printf(), ui_table_t::header, height, LOG_COLOR_DEBUG, LOG_COLOR_RESET, out, ui_viewport_range_t::page_count, ui_table_t::row_count, ui_table_t::selectable, ui_viewport_t::selected, SET_ERRNO, ui_scrollbar_render(), UI_TABLE_CELL_CAPACITY, UI_TABLE_LINE_BUFFER_SIZE, ui_table_row(), ui_text_color_prefix(), ui_viewport_update(), ui_table_t::viewport, and width.

Referenced by tui_stats_render().

◆ ui_table_row()

size_t ui_table_row ( char * out,
size_t capacity,
const ui_table_column_t * columns,
const char *const * cells,
size_t count,
int width,
bool selectable,
bool selected )

When code needs to work with ui table, it keeps columns, column_count, row_count, viewport here instead of scattering it across globals. Initialization establishes the handles and sizes; teardown must release any allocation, lock, thread, or callback context recorded in those fields. terminal columns, never by bytes. The caller owns data and sorting.

Format a complete row without allocation. Styled cells are clipped by

Definition at line 18 of file table.c.

19 {
20 if (!out || !cap) {
21 SET_ERRNO(ERROR_INVALID_PARAM, "Table row requires output storage");
22 return 0;
23 }
24 out[0] = '\0';
25 if (!cols || !count || count > 32 || width <= 0) {
26 SET_ERRNO(ERROR_INVALID_PARAM, "Invalid table columns or width");
27 return 0;
28 }
29 int64_t remaining = (int64_t)width - (selectable ? 1 : 0) - (int)(count - 1);
30 size_t flexible = 0;
31 for (size_t i = 0; i < count; ++i) {
32 if (cols[i].width < 0) {
33 SET_ERRNO(ERROR_INVALID_PARAM, "Table column width cannot be negative");
34 return 0;
35 }
36 if (cols[i].width > 0)
37 remaining -= cols[i].width;
38 else
39 ++flexible;
40 }
41 size_t used = 0;
42 int available = width;
43 if (selectable && cap > 1) {
44 out[used++] = selected ? '>' : ' ';
45 out[used] = '\0';
46 --available;
47 }
48 for (size_t i = 0; i < count && available > 0; ++i) {
49 if (i && used + 1 < cap) {
50 out[used++] = ' ';
51 out[used] = '\0';
52 --available;
53 }
54 int cell_width = cols[i].width > 0 ? cols[i].width : flexible ? remaining / (int)flexible : 0;
55 if (cell_width < 0)
56 cell_width = 0;
57 if (!cols[i].width && flexible) {
58 remaining -= cell_width;
59 --flexible;
60 }
61 if (cell_width > available)
62 cell_width = available;
63 const char *text = cells ? cells[i] : cols[i].heading;
64 char clipped[UI_TABLE_CLIPPED_BUFFER_SIZE];
65 if (text && cols[i].ellipsis && display_width(text) > cell_width) {
66 truncate_with_ellipsis_mode(text, clipped, sizeof(clipped), cell_width,
67 terminal_should_use_utf8(GET_OPTION(force_utf8)));
68 text = clipped;
69 }
70 used += ui_text_cell(out + used, cap - used, text, cell_width, cols[i].alignment);
71 available -= cell_width;
72 }
73 return used;
74}
#define GET_OPTION(field)
Safely get a specific option field (lock-free read).
Definition options.h:1336
int display_width(const char *text)
Calculate the visible display width of text with ANSI escape codes.
void truncate_with_ellipsis_mode(const char *input, char *output, size_t output_size, int max_width, bool utf8)
Truncate a string to a maximum display width with a terminal-appropriate ellipsis.
Definition string.c:334
const char * heading
Definition table.h:6
#define UI_TABLE_CLIPPED_BUFFER_SIZE
Definition table.c:3
size_t ui_text_cell(char *out, size_t cap, const char *text, int width, ui_alignment_t align)
Definition text.c:48

References cells, display_width(), ERROR_INVALID_PARAM, GET_OPTION, ui_table_column_t::heading, out, SET_ERRNO, truncate_with_ellipsis_mode(), UI_TABLE_CLIPPED_BUFFER_SIZE, ui_text_cell(), ui_table_column_t::width, and width.

Referenced by ui_sync_render(), and ui_table_render().