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
Go to the documentation of this file.
1
2/* Storage capacities in elements; text buffers include the terminating NUL. */
3#define UI_TABLE_CLIPPED_BUFFER_SIZE 8192
4#define UI_TABLE_LINE_BUFFER_SIZE 8192
5
6/* Existing buffer budgets in bytes, including NUL for text storage. */
7#define UI_TABLE_CELL_CAPACITY 32
8
11#include <ascii-chat/ui/table.h>
14#include <stdio.h>
15#include <stdint.h>
16#include <string.h>
17
18size_t ui_table_row(char *out, size_t cap, const ui_table_column_t *cols, const char *const *cells, size_t count,
19 int width, bool selectable, bool selected) {
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}
75
76void ui_table_render(frame_buffer_t *out, ui_table_t *t, int row, int col, int width, int height) {
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}
Synchronized per-thread pending error stacks and value snapshots. SET_ERRNO pushes,...
#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.
struct frame_buffer frame_buffer_t
Opaque frame buffer handle.
@ ERROR_INVALID_PARAM
@ LOG_COLOR_RESET
Definition log/log.h:155
@ LOG_COLOR_DEBUG
Definition log/log.h:149
#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
🖥️ Display Width and Terminal Centering Utilities
⚙️ Unified options parsing system for ascii-chat with builder pattern and lock-free access
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
🔤 String Manipulation and Shell Escaping Utilities
const char * heading
Definition table.h:6
The useful part of ui table column is in heading, width, alignment, ellipsis: together they describe ...
Definition table.h:22
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
void ui_table_render(frame_buffer_t *out, ui_table_t *t, int row, int col, int width, int height)
Definition table.c:76
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
#define UI_TABLE_CLIPPED_BUFFER_SIZE
Definition table.c:3
const char * ui_text_color_prefix(log_color_t color)
Definition text.c:18
size_t ui_text_cell(char *out, size_t cap, const char *text, int width, ui_alignment_t align)
Definition text.c:48
ui_viewport_range_t ui_viewport_update(ui_viewport_t *v, size_t count, size_t rows)
Definition viewport.c:4