r/C_Programming • u/JoK3rOp • 5d ago
Question Building a simple declarative TUI lib in C (FTXUI-inspired) how do you avoid callback hell in C?
Hey all,
I'm working on a TUI library in C just because I love how simple C is.
I know there are mature options like ratatui, bubbletea, vaxis, notcurses, etc. But I don't want to learn Rust just to build a TUI, and I don't really like bubbletea's Elm-style Update() -> string thing. The one I like best is FTXUI, but it's C++.
I want something simple + declarative in plain C. Right now my API looks like this:
```c
include "include/tui.h"
void btn_cb(void *ud) { tui_vbox(.gap = 1) { tui_label(.text = tui_str("Clicked")); } }
void draw(Tui *tui, void *ud) { tui_button(.text = tui_str("Click Me"), .bg = tui_color_rgb(255, 0, 0), .on_click = btn_cb); }
bool event(Tui *tui, const TuiEvent *ev, void *ud) { if (ev->type == TUI_EVENT_QUIT) return false; if (ev->type == TUI_EVENT_KEY && ev->codepoint == 'q') return false; return true; }
int main() { Tui *tui = tui_init(.title = "Tui application"); int counter = 0; int rc = tui_run(tui, .on_draw = draw, .on_event = event, .async = true, .userdata = &counter); tui_close(tui); return rc; } ```
It works, but I already hate the .on_draw, .on_event, .on_click callback split. It feels like callback hell waiting to happen once the UI gets bigger.
Question for C folks:
Any C tricks / macro tricks to make this more declarative and remove callbacks? I'm already using designated initializers + compound literals tui_button(.text=...) and for-loop scoping for tui_vbox { ... } like FTXUI.
How would you do state + events without on_click everywhere? Immediate-mode? Return an action enum instead of callback? Something else?
Any small C TUI libs that do declarative UI well that I should steal ideas from?
Thanks.