trainlog/tui/include/trainlog/terminal.h

131 lines
5.8 KiB
C

/*
* Trainlog terminal interface.
*
* Declares the module boundary and ownership contract; implementation and persistence remain in their owning modules.
*/
#ifndef TRAINLOG_TERMINAL_H
#define TRAINLOG_TERMINAL_H
/**
* @file terminal.h
* @brief Small explicit Notcurses terminal boundary for the desktop TUI.
*/
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "trainlog/theme.h"
typedef struct TrainlogTerminal TrainlogTerminal;
typedef struct TrainlogPanel TrainlogPanel;
typedef struct TrainlogSurface TrainlogSurface;
typedef enum TrainlogKey {
TRAINLOG_KEY_NONE = -1,
TRAINLOG_KEY_UP = -1001,
TRAINLOG_KEY_DOWN,
TRAINLOG_KEY_LEFT,
TRAINLOG_KEY_RIGHT,
TRAINLOG_KEY_ENTER,
TRAINLOG_KEY_TAB,
TRAINLOG_KEY_ESCAPE,
TRAINLOG_KEY_BACKSPACE,
TRAINLOG_KEY_DELETE,
TRAINLOG_KEY_HOME,
TRAINLOG_KEY_END,
TRAINLOG_KEY_PAGE_UP,
TRAINLOG_KEY_PAGE_DOWN,
TRAINLOG_KEY_RESIZE,
TRAINLOG_KEY_F1,
TRAINLOG_KEY_F2,
TRAINLOG_KEY_F3,
TRAINLOG_KEY_F4,
TRAINLOG_KEY_F5,
TRAINLOG_KEY_F6,
TRAINLOG_KEY_F7,
TRAINLOG_KEY_SHIFT_TAB
} TrainlogKey;
/* Trainlog-owned input lifecycle. UNKNOWN is the legacy terminal event form;
* PRESS and REPEAT are actionable, while RELEASE is never a user action. */
typedef enum TrainlogInputEventType {
TRAINLOG_INPUT_UNKNOWN = 0,
TRAINLOG_INPUT_PRESS,
TRAINLOG_INPUT_REPEAT,
TRAINLOG_INPUT_RELEASE
} TrainlogInputEventType;
/* WHY: a run owns its terminal so cleanup is deterministic and no application
* terminal state leaks across a later run in the same process. */
TrainlogTerminal *trainlog_terminal_create(void);
void trainlog_terminal_destroy(TrainlogTerminal *terminal);
int trainlog_terminal_rows(const TrainlogTerminal *terminal);
int trainlog_terminal_columns(const TrainlogTerminal *terminal);
void trainlog_terminal_erase(TrainlogTerminal *terminal);
void trainlog_terminal_render(TrainlogTerminal *terminal);
void trainlog_terminal_style_on(TrainlogTerminal *terminal, TrainlogTextStyle style);
void trainlog_terminal_style_off(TrainlogTerminal *terminal, TrainlogTextStyle style);
void trainlog_terminal_printf(TrainlogTerminal *terminal, int row, int column,
const char *format, ...)
__attribute__((format(printf, 4, 5)));
void trainlog_terminal_putn(TrainlogTerminal *terminal, const char *text, size_t length);
void trainlog_terminal_move(TrainlogTerminal *terminal, int row, int column);
void trainlog_terminal_cursor_yx(const TrainlogTerminal *terminal, int *row, int *column);
void trainlog_terminal_clear_to_end(TrainlogTerminal *terminal);
void trainlog_terminal_cursor_visible(TrainlogTerminal *terminal, bool visible);
void trainlog_terminal_draw(TrainlogTerminal *terminal, int row, int column, uint32_t codepoint);
void trainlog_terminal_box(TrainlogTerminal *terminal, int top, int left,
int bottom, int right);
/* WHY: Notcurses can report a physical key in id while eff_text holds its
* layout-resolved Unicode character. CONTRACT: Shift may produce a printable
* action character (for example French AZERTY '/'); Ctrl/Alt/Super never
* collapse into an unmodified action. */
bool trainlog_terminal_translate_input(uint32_t id, uint32_t effective_text,
TrainlogInputEventType event_type,
bool shifted, bool control, bool alt,
bool super, int *key);
int trainlog_terminal_get_key(TrainlogTerminal *terminal);
bool trainlog_terminal_read_unicode(TrainlogTerminal *terminal, int *codepoint,
char utf8[5]);
bool trainlog_terminal_push_key(TrainlogTerminal *terminal, int key);
/* Refreshes Notcurses geometry after a resize event. */
bool trainlog_terminal_refresh_geometry(TrainlogTerminal *terminal);
/* WHY: shell chrome and overlays have independent Notcurses ownership. The
* rectangle is validated against the standard plane at create/resize time,
* and every write is clipped by this adapter rather than parent inheritance. */
TrainlogSurface *trainlog_surface_create(TrainlogTerminal *terminal,
const char *name,
int top, int left,
int height, int width);
bool trainlog_surface_set_rect(TrainlogSurface *surface,
int top, int left,
int height, int width);
void trainlog_surface_destroy(TrainlogSurface *surface);
void trainlog_surface_erase(TrainlogSurface *surface);
void trainlog_surface_set_role(TrainlogSurface *surface,
TrainlogColorRole foreground,
unsigned background_rgb,
TrainlogTextStyle style);
void trainlog_surface_printf(TrainlogSurface *surface,
int row, int column,
const char *format, ...)
__attribute__((format(printf, 4, 5)));
void trainlog_surface_draw(TrainlogSurface *surface,
int row, int column, uint32_t codepoint);
void trainlog_surface_move_top(TrainlogSurface *surface);
/* Private screen-port helpers. Panels are lightweight coordinate views over
* the one standard plane, not independently owned terminal surfaces. */
TrainlogPanel *tui_panel_create(TrainlogTerminal *terminal, int height, int width,
int top, int left);
void tui_panel_destroy(TrainlogPanel *panel);
void tui_panel_box(TrainlogPanel *panel);
void tui_panel_style_on(TrainlogPanel *panel, TrainlogTextStyle style);
void tui_panel_style_off(TrainlogPanel *panel, TrainlogTextStyle style);
void tui_panel_print(TrainlogPanel *panel, int row, int column, const char *format, ...)
__attribute__((format(printf, 4, 5)));
void tui_panel_commit(TrainlogPanel *panel);
#endif