diff options
| author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-08-29 00:32:28 +0330 | 
|---|---|---|
| committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-08-29 00:32:28 +0330 | 
| commit | 7f7ced3f7f61d6cd31a43c5d03d606879295d624 (patch) | |
| tree | ebd1c1ee0f317bb343d5ee7b10ade8c7a400f2f1 | |
| parent | 353546db994b2f71eeae731209f08da1a326a2f3 (diff) | |
added fps cap
added clang lsp configs
added restrict for pointers may have
added max and min width and height consts
fixed bug in tui_get_cursor_pos
added <ENTER> as left click behavior
| -rwxr-xr-x | .ccls | 12 | ||||
| -rwxr-xr-x | .clang-format | 4 | ||||
| -rw-r--r-- | src/main.c | 21 | ||||
| -rw-r--r-- | src/ui/tui.c | 195 | ||||
| -rw-r--r-- | src/ui/tui.h | 68 | 
5 files changed, 217 insertions, 83 deletions
@@ -0,0 +1,12 @@ +gcc +# compiler driver + +%c -std=c23 +# %cpp -std=c++23 + +# add this to support `.hpp` files as C++ headers +# %hpp -x +# %hpp c++-header + +%h -x +%h c-header diff --git a/.clang-format b/.clang-format new file mode 100755 index 0000000..5af5a7a --- /dev/null +++ b/.clang-format @@ -0,0 +1,4 @@ +# https://clang.llvm.org/docs/ClangFormatStyleOptions.html +# To disable for a line use `// clang-format off` +BasedOnStyle: Google # https://google.github.io/styleguide/cppguide.html +IndentPPDirectives: BeforeHash @@ -1,10 +1,13 @@ -#include "ui/tui.h"  #include <stdio.h>  #include <unistd.h> +#include "ui/tui.h" +  bool is_clicked = false; -void on_button_click(MOUSE_ACTION mouse_action) { is_clicked = !is_clicked; } +void on_button_click(const MOUSE_ACTION *mouse_action) { +  is_clicked = !is_clicked; +}  WIDGET *ui_build(TUI *tui) {    if (is_clicked) { @@ -17,10 +20,7 @@ WIDGET *ui_build(TUI *tui) {                  tui_make_box(                      20, 3,                      tui_make_column(tui_make_widget_array( -                        2, -                        tui_make_text( -                            "This is the second page", -                            COLOR_BLUE), +                        2, tui_make_text("This is the second page", COLOR_BLUE),                          tui_make_button(tui_make_text("       Back", COLOR_RED),                                          on_button_click))), @@ -34,10 +34,9 @@ WIDGET *ui_build(TUI *tui) {              tui_make_row(tui_make_widget_array(                  2, tui_make_box(50, 0, NULL, COLOR_NO_COLOR),                  tui_make_button( -                    tui_make_box( -                        16, 3, -                            tui_make_text("\nClick here", COLOR_BLUE), -                        COLOR_WHITE), +                    tui_make_box(16, 3, +                                 tui_make_text("\nClick here", COLOR_BLUE), +                                 COLOR_WHITE),                      on_button_click))))),          COLOR_MAGENTA);    } @@ -46,7 +45,7 @@ WIDGET *ui_build(TUI *tui) {  int main() {    TUI *tui = tui_init(); -  tui_start_app(tui, ui_build); +  tui_start_app(tui, ui_build, 144);    tui_delete(tui); diff --git a/src/ui/tui.c b/src/ui/tui.c index 7e044c2..e7336bf 100644 --- a/src/ui/tui.c +++ b/src/ui/tui.c @@ -7,12 +7,18 @@  #include <time.h>  #include <unistd.h> +const int MAX_WIDTH = -1; +const int MAX_HEIGHT = -1; + +const int MIN_WIDTH = -2; +const int MIN_HEIGHT = -2; +  void _tui_clear_cells(TUI *tui) {    const TERMINAL_CELL empty = {.c = ' ',                                 .color = COLOR_NO_COLOR,                                 .background_color = COLOR_NO_COLOR,                                 .on_click_callback = NULL}; -  for (int i = 0; i < tui->cells_length; ++i) { +  for (size_t i = 0; i < tui->cells_length; ++i) {      tui->cells[i] = empty;    }  } @@ -56,9 +62,7 @@ TUI *tui_init() {    return tui;  } -void tui_delete(TUI *tui) { -  const int width = tui_get_width(tui); - +void tui_delete(TUI *restrict tui) {    // Revert the terminal back to its original state    write(STDOUT_FILENO, "\e[?9l", 5);    write(STDOUT_FILENO, "\e[?47l", 6); @@ -111,8 +115,8 @@ void tui_get_cursor_pos(TUI *tui, int *x, int *y) {      read(STDIN_FILENO, buf, sizeof(buf));      sscanf(buf, "\033[%d;%dR", y, x); -    --x; -    --y; +    --*x; +    --*y;    }    tcsetattr(0, TCSANOW, &tui->raw);  } @@ -154,9 +158,9 @@ void _tui_set_cell_on_click_callback(TUI *tui, int x, int y,        on_click_callback;  } -void tui_handle_mouse_action(TUI *tui, MOUSE_ACTION mouse_action) { +void tui_handle_mouse_action(TUI *tui, const MOUSE_ACTION *mouse_action) {    const ON_CLICK_CALLBACK callback = -      tui->cells[_tui_get_cell_index(tui, mouse_action.x, mouse_action.y)] +      tui->cells[_tui_get_cell_index(tui, mouse_action->x, mouse_action->y)]            .on_click_callback;    if (callback != NULL) {      callback(mouse_action); @@ -191,12 +195,12 @@ bool handle_input(TUI *tui) {      read(STDIN_FILENO, &buff, 5);      switch (buff[1]) {      case 77: { -      MOUSE_ACTION mouse_action = { +      const MOUSE_ACTION mouse_action = {            .button = buff[2],            .x = buff[3] - 32 - 1, // starts at 0            .y = buff[4] - 32 - 1, // starts at 0        }; -      tui_handle_mouse_action(tui, mouse_action); +      tui_handle_mouse_action(tui, &mouse_action);        /*printf("button:%u\n\rx:%u\n\ry:%u\n\n\r", mouse_action.button,*/        /*       mouse_action.x, mouse_action.y);*/      } break; @@ -215,22 +219,33 @@ bool handle_input(TUI *tui) {      case 'l':        tui_move_right(1);        break; -      case 'q': +    case 'q':        return true; +    case '\r': { // <ENTER> +      int x, y; +      tui_get_cursor_pos(tui, &x, &y); +      const MOUSE_ACTION mouse_action = { +          .button = MOUSE_BUTTON_LEFT_CLICK, +          .x = x, +          .y = y, +      }; +      tui_handle_mouse_action(tui, &mouse_action); +    } break;      case '\b':      case 127: // back space        tui_delete_before();        break;      default:        /*printf("unknown:%c,%d\n\r", buff[0], buff[0]);*/ +      /*sleep(1);*/        break;      }    }    return false;  } -void tui_start_app(TUI *tui, WIDGET_BUILDER widget_builder) { -  tui_main_loop(tui, widget_builder); +void tui_start_app(TUI *tui, WIDGET_BUILDER widget_builder, int fps) { +  tui_main_loop(tui, widget_builder, fps);  }  void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin, @@ -240,12 +255,10 @@ void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin,    case WIDGET_TYPE_TEXT: {      const TEXT_METADATA *metadata = widget->metadata;      const int width_diff = width_end - width_begin; -    const int text_len = strlen(metadata->text); -    int inserted_index = 0; +    const size_t text_len = strlen(metadata->text); +    size_t inserted_index = 0;      int height = height_begin;      for (; height < height_end; ++height) { -      const int begin = (height - height_begin) * width_diff; -        for (int j = 0; j < width_diff; ++j) {          const int x = width_begin + j;          const int y = height; @@ -286,7 +299,7 @@ void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin,      const COLUMN_METADATA *metadata = widget->metadata;      *child_width = width_begin;      *child_height = height_begin; -    for (int i = 0; i < metadata->children->size; ++i) { +    for (size_t i = 0; i < metadata->children->size; ++i) {        const WIDGET *child = metadata->children->widgets[i];        int width_temp;        _tui_draw_widget_to_cells(tui, child, width_begin, width_end, @@ -301,7 +314,7 @@ void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin,      const ROW_METADATA *metadata = widget->metadata;      *child_width = width_begin;      *child_height = height_begin; -    for (int i = 0; i < metadata->children->size; ++i) { +    for (size_t i = 0; i < metadata->children->size; ++i) {        const WIDGET *child = metadata->children->widgets[i];        int height_temp;        _tui_draw_widget_to_cells(tui, child, *child_width, width_end, @@ -315,12 +328,12 @@ void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin,    case WIDGET_TYPE_BOX: {      const BOX_METADATA *metadata = widget->metadata; -    if (metadata->width != -1) { +    if (metadata->width != MAX_WIDTH) {        width_end = metadata->width + width_begin >= width_end                        ? width_end                        : metadata->width + width_begin;      } -    if (metadata->height != -1) { +    if (metadata->height != MAX_HEIGHT) {        height_end = metadata->height + height_begin >= height_end                         ? height_end                         : metadata->height + height_begin; @@ -372,7 +385,7 @@ void _tui_draw_cells_to_terminal(TUI *tui) {    COLOR last_color = COLOR_NO_COLOR;    COLOR last_background_color = COLOR_NO_COLOR; -  for (int i = 0; i < tui->cells_length; ++i) { +  for (size_t i = 0; i < tui->cells_length; ++i) {      const TERMINAL_CELL cell = tui->cells[i];      if (last_color != cell.color || @@ -403,11 +416,94 @@ void _tui_draw_cells_to_terminal(TUI *tui) {    write(STDOUT_FILENO, str, len);  } -void tui_main_loop(TUI *tui, WIDGET_BUILDER widget_builder) { +int kbhit() { +  struct timeval tv = {0L, 0L}; +  fd_set fds; +  FD_ZERO(&fds); +  FD_SET(0, &fds); +  return select(1, &fds, NULL, NULL, &tv) > 0; +} + +bool widget_array_eqauls(const WIDGET_ARRAY *restrict left, const WIDGET_ARRAY *restrict right) { +  if (left->size != right->size) { +    return false; +  } +  for (size_t i = 0; i < left->size; ++i) { +    if (!widget_eqauls(left->widgets[i], right->widgets[i])) { +      return false; +    } +  } +  return true; +} + +bool widget_eqauls(const WIDGET *restrict left, const WIDGET *restrict right) { +  if (left == NULL || right == NULL) { +    return left == NULL && right == NULL; +  } +  if (left->type != right->type) { +    return false; +  } + +  switch (left->type) { +  case WIDGET_TYPE_TEXT: { +    const TEXT_METADATA *left_data = left->metadata; +    const TEXT_METADATA *right_data = right->metadata; +    return left_data->color == right_data->color && +           strcmp(left_data->text, right_data->text) == 0; +  } break; +  case WIDGET_TYPE_BUTTON: { +    const BUTTON_METADATA *left_data = left->metadata; +    const BUTTON_METADATA *right_data = right->metadata; +    return left_data->callback == right_data->callback && +           widget_eqauls(left_data->child, right_data->child); +  } break; +  case WIDGET_TYPE_COLUMN: { +    const COLUMN_METADATA *left_data = left->metadata; +    const COLUMN_METADATA *right_data = right->metadata; +    return widget_array_eqauls(left_data->children, right_data->children); +  } break; +  case WIDGET_TYPE_ROW: { +    const ROW_METADATA *left_data = left->metadata; +    const ROW_METADATA *right_data = right->metadata; +    return widget_array_eqauls(left_data->children, right_data->children); +  } break; +  case WIDGET_TYPE_BOX: { +    const BOX_METADATA *left_data = left->metadata; +    const BOX_METADATA *right_data = right->metadata; +    return left_data->width == right_data->width && +           left_data->height == right_data->height && +           left_data->color == right_data->color && +           widget_eqauls(left_data->child, right_data->child); +  } break; +  default: +    fprintf(stderr, "Type error '%d' in tui_delete_widget\n", left->type); +    exit(1); +  } + +  return true; +} + +const int NANO_TO_SECOND = 1000000000; + +void nano_sleep(long int nano_seconds) { +  struct timespec remaining, +      request = {nano_seconds / NANO_TO_SECOND, nano_seconds % NANO_TO_SECOND}; +  nanosleep(&request, &remaining); +} + +long int nano_time() { +  struct timespec t = {0, 0}, tend = {0, 0}; +  clock_gettime(CLOCK_MONOTONIC, &t); +  return t.tv_sec * NANO_TO_SECOND + t.tv_nsec; +} + +void tui_main_loop(TUI *tui, WIDGET_BUILDER widget_builder, int fps) { +  const long int frame_nano = NANO_TO_SECOND / fps;    while (1) { +    const long int start = nano_time(); +    tui_save_cursor();      tui_refresh(tui);      WIDGET *root_widget = widget_builder(tui); -    tui_save_cursor();      _tui_clear_cells(tui);      int width, height; @@ -416,9 +512,17 @@ void tui_main_loop(TUI *tui, WIDGET_BUILDER widget_builder) {      _tui_draw_cells_to_terminal(tui);      tui_delete_widget(root_widget); +    /*tui_move_to(0, 0);*/ +    /*printf("%ld\t%ld", last_frame_time, frame_nano);*/      tui_restore_cursor(); -    if (handle_input(tui)) { -      return; +    if (fps != -1) { +      const long int diff = nano_time() - start; +      nano_sleep(frame_nano-diff); +    } +    if (kbhit()) { +      if (handle_input(tui)) { +        return; +      }      }    }  } @@ -430,7 +534,7 @@ WIDGET *tui_new_widget(WIDGET_TYPE type, void *metadata) {    return widget;  } -void tui_delete_widget(WIDGET *widget) { +void tui_delete_widget(WIDGET *restrict widget) {    if (widget == NULL) {      return;    } @@ -457,11 +561,11 @@ void tui_delete_widget(WIDGET *widget) {    free(widget);  } -WIDGET *tui_make_text(char *text, COLOR color) { +WIDGET *tui_make_text(char *restrict text, COLOR color) {    return tui_new_widget(WIDGET_TYPE_TEXT, _tui_make_text_metadata(text, color));  } -TEXT_METADATA *_tui_make_text_metadata(char *text, COLOR color) { +TEXT_METADATA *_tui_make_text_metadata(char *restrict text, COLOR color) {    TEXT_METADATA *metadata = malloc(sizeof(TEXT_METADATA));    metadata->text = malloc(strlen(text) + 1);    strcpy(metadata->text, text); @@ -469,17 +573,17 @@ TEXT_METADATA *_tui_make_text_metadata(char *text, COLOR color) {    return metadata;  } -void _tui_delete_text(WIDGET *text) { +void _tui_delete_text(WIDGET *restrict text) {    free(((TEXT_METADATA *)text->metadata)->text);    free(text->metadata);  } -WIDGET *tui_make_button(WIDGET *child, ON_CLICK_CALLBACK callback) { +WIDGET *tui_make_button(WIDGET *restrict child, ON_CLICK_CALLBACK callback) {    return tui_new_widget(WIDGET_TYPE_BUTTON,                          _tui_make_button_metadata(child, callback));  } -BUTTON_METADATA *_tui_make_button_metadata(WIDGET *child, +BUTTON_METADATA *_tui_make_button_metadata(WIDGET *restrict child,                                             ON_CLICK_CALLBACK callback) {    BUTTON_METADATA *metadata = malloc(sizeof(BUTTON_METADATA));    metadata->child = child; @@ -487,51 +591,52 @@ BUTTON_METADATA *_tui_make_button_metadata(WIDGET *child,    return metadata;  } -void _tui_delete_button(WIDGET *button) { +void _tui_delete_button(WIDGET *restrict button) {    tui_delete_widget(((BUTTON_METADATA *)button->metadata)->child);    free(button->metadata);  } -WIDGET *tui_make_column(WIDGET_ARRAY *children) { +WIDGET *tui_make_column(WIDGET_ARRAY *restrict children) {    return tui_new_widget(WIDGET_TYPE_COLUMN,                          _tui_make_column_metadata(children));  } -COLUMN_METADATA *_tui_make_column_metadata(WIDGET_ARRAY *children) { +COLUMN_METADATA *_tui_make_column_metadata(WIDGET_ARRAY *restrict children) {    COLUMN_METADATA *metadata = malloc(sizeof(COLUMN_METADATA));    metadata->children = children;    return metadata;  } -void _tui_delete_column(WIDGET *column) { +void _tui_delete_column(WIDGET *restrict column) {    COLUMN_METADATA *metadata = column->metadata;    _tui_delete_widget_array(metadata->children);    free(column->metadata);  } -WIDGET *tui_make_row(WIDGET_ARRAY *children) { +WIDGET *tui_make_row(WIDGET_ARRAY *restrict children) {    return tui_new_widget(WIDGET_TYPE_ROW, _tui_make_row_metadata(children));  } -ROW_METADATA *_tui_make_row_metadata(WIDGET_ARRAY *children) { +ROW_METADATA *_tui_make_row_metadata(WIDGET_ARRAY *restrict children) {    ROW_METADATA *metadata = malloc(sizeof(ROW_METADATA));    metadata->children = children;    return metadata;  } -void _tui_delete_row(WIDGET *row) { +void _tui_delete_row(WIDGET *restrict row) {    ROW_METADATA *metadata = row->metadata;    _tui_delete_widget_array(metadata->children);    free(row->metadata);  } -WIDGET *tui_make_box(int width, int height, WIDGET *child, COLOR color) { +WIDGET *tui_make_box(int width, int height, WIDGET *restrict child, +                     COLOR color) {    return tui_new_widget(WIDGET_TYPE_BOX,                          _tui_make_box_metadata(child, width, height, color));  } -BOX_METADATA *_tui_make_box_metadata(WIDGET *child, int width, int height, -                                     COLOR color) { +BOX_METADATA *_tui_make_box_metadata(WIDGET *restrict child, int width, +                                     int height, COLOR color) {    BOX_METADATA *metadata = malloc(sizeof(BOX_METADATA));    metadata->width = width;    metadata->height = height; @@ -545,13 +650,13 @@ void _tui_delete_box(WIDGET *box) {    free(box->metadata);  } -WIDGET_ARRAY *tui_make_widget_array(int size, ...) { +WIDGET_ARRAY *tui_make_widget_array(size_t size, ...) {    va_list arg_pointer;    va_start(arg_pointer, size);    WIDGET **widgets = malloc(size * sizeof(WIDGET **)); -  for (int i = 0; i < size; ++i) { +  for (size_t i = 0; i < size; ++i) {      widgets[i] = va_arg(arg_pointer, WIDGET *);    }    va_end(arg_pointer); @@ -563,7 +668,7 @@ WIDGET_ARRAY *tui_make_widget_array(int size, ...) {    return widget_array;  } -void _tui_delete_widget_array(WIDGET_ARRAY *widget_array) { +void _tui_delete_widget_array(WIDGET_ARRAY *restrict widget_array) {    for (size_t i = 0; i < widget_array->size; ++i) {      tui_delete_widget(widget_array->widgets[i]);    } diff --git a/src/ui/tui.h b/src/ui/tui.h index b21395a..0de4adb 100644 --- a/src/ui/tui.h +++ b/src/ui/tui.h @@ -1,17 +1,23 @@  #ifndef A404M_UI_TUI  #define A404M_UI_TUI 1 +#include <stdint.h>  #include <stdlib.h>  #include <sys/ioctl.h>  #include <termios.h> -#include <stdint.h> + +extern const int MAX_WIDTH; +extern const int MAX_HEIGHT; + +extern const int MIN_WIDTH; +extern const int MIN_HEIGHT;  typedef enum MOUSE_BUTTON {    MOUSE_BUTTON_LEFT_CLICK = 32,    MOUSE_BUTTON_MIDDLE_CLICK = 33,    MOUSE_BUTTON_RIGHT_CLICK = 34,    MOUSE_BUTTON_SCROLL_UP = 96, -  MOUSE_BUTTON_SCROLL_DOWN = 97 +  MOUSE_BUTTON_SCROLL_DOWN = 97,  } MOUSE_BUTTON;  typedef struct MOUSE_ACTION { @@ -20,7 +26,7 @@ typedef struct MOUSE_ACTION {    unsigned int y;  } MOUSE_ACTION; -typedef void (*ON_CLICK_CALLBACK)(MOUSE_ACTION mouse_action); +typedef void (*ON_CLICK_CALLBACK)(const MOUSE_ACTION *mouse_action);  #ifndef __cplusplus  typedef enum bool : uint8_t { false = 0, true = 1 } bool; @@ -99,7 +105,7 @@ typedef struct BOX_METADATA {  typedef WIDGET *(*WIDGET_BUILDER)(TUI *tui);  extern TUI *tui_init(); -extern void tui_delete(TUI *tui); +extern void tui_delete(TUI *restrict tui);  extern void tui_refresh(TUI *tui);  extern int tui_get_width(TUI *tui); @@ -110,38 +116,46 @@ extern int tui_move_to(int x, int y);  extern int tui_clear_screen(); -extern void tui_start_app(TUI *tui, WIDGET_BUILDER widget_builder); -extern void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin, -                             int width_end, int height_begin, int height_end, -                             int *child_width, int *childHeight); -extern void tui_main_loop(TUI *tui, WIDGET_BUILDER widget_builder); +extern void tui_start_app(TUI *tui, WIDGET_BUILDER widget_builder, int fps); +extern void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, +                                      int width_begin, int width_end, +                                      int height_begin, int height_end, +                                      int *child_width, int *childHeight); + +extern bool widget_eqauls(const WIDGET *restrict left, const WIDGET *restrict right); +extern bool widget_array_eqauls(const WIDGET_ARRAY *restrict left, const WIDGET_ARRAY * restrict right); + +extern void tui_main_loop(TUI *tui, WIDGET_BUILDER widget_builder, int fps);  extern WIDGET *tui_new_widget(WIDGET_TYPE type, void *metadata); -extern void tui_delete_widget(WIDGET *widget); +extern void tui_delete_widget(WIDGET *restrict widget); -extern WIDGET *tui_make_text(char *text, COLOR color); -extern TEXT_METADATA *_tui_make_text_metadata(char *text, COLOR color); -extern void _tui_delete_text(WIDGET *text); +extern WIDGET *tui_make_text(char *restrict text, COLOR color); +extern TEXT_METADATA *_tui_make_text_metadata(char *restrict text, COLOR color); +extern void _tui_delete_text(WIDGET *restrict text); -extern WIDGET *tui_make_button(WIDGET *child, ON_CLICK_CALLBACK callback); -extern BUTTON_METADATA *_tui_make_button_metadata(WIDGET *child, +extern WIDGET *tui_make_button(WIDGET *restrict child, +                               ON_CLICK_CALLBACK callback); +extern BUTTON_METADATA *_tui_make_button_metadata(WIDGET *restrict child,                                                    ON_CLICK_CALLBACK callback); -extern void _tui_delete_button(WIDGET *button); +extern void _tui_delete_button(WIDGET *restrict button); -extern WIDGET *tui_make_column(WIDGET_ARRAY *children); -extern COLUMN_METADATA *_tui_make_column_metadata(WIDGET_ARRAY *children); -extern void _tui_delete_column(WIDGET *column); +extern WIDGET *tui_make_column(WIDGET_ARRAY *restrict children); +extern COLUMN_METADATA * +_tui_make_column_metadata(WIDGET_ARRAY *restrict children); +extern void _tui_delete_column(WIDGET *restrict column); -extern WIDGET *tui_make_row(WIDGET_ARRAY *children); -extern ROW_METADATA *_tui_make_row_metadata(WIDGET_ARRAY *children); -extern void _tui_delete_row(WIDGET *row); +extern WIDGET *tui_make_row(WIDGET_ARRAY *restrict children); +extern ROW_METADATA *_tui_make_row_metadata(WIDGET_ARRAY *restrict children); +extern void _tui_delete_row(WIDGET *restrict row); -extern WIDGET *tui_make_box(int width, int height, WIDGET *child, COLOR color); -extern BOX_METADATA *_tui_make_box_metadata(WIDGET *child, int width, +extern WIDGET *tui_make_box(int width, int height, WIDGET *restrict child, +                            COLOR color); +extern BOX_METADATA *_tui_make_box_metadata(WIDGET *restrict child, int width,                                              int height, COLOR color); -extern void _tui_delete_box(WIDGET *box); +extern void _tui_delete_box(WIDGET *restrict box); -extern WIDGET_ARRAY *tui_make_widget_array(int size, ...); -extern void _tui_delete_widget_array(WIDGET_ARRAY *widget_array); +extern WIDGET_ARRAY *tui_make_widget_array(size_t size, ...); +extern void _tui_delete_widget_array(WIDGET_ARRAY *restrict widget_array);  #endif  |