diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-12-24 01:23:24 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-12-24 01:23:24 +0330 |
commit | 55d29d0df8681efe01e88e0475c8512c44ec4bc4 (patch) | |
tree | 2b07ab80b17c8bb6b20837e104aa863854f7ccff /src/ui | |
parent | 217e7d18dbaa260a15f5612d9670105b04cd455f (diff) |
fixed some bugs
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/color.h | 11 | ||||
-rw-r--r-- | src/ui/tui.c | 105 | ||||
-rw-r--r-- | src/ui/tui.h | 17 |
3 files changed, 89 insertions, 44 deletions
diff --git a/src/ui/color.h b/src/ui/color.h index 43005a6..75df571 100644 --- a/src/ui/color.h +++ b/src/ui/color.h @@ -6,11 +6,12 @@ typedef struct COLOR { uint8_t b, g, r, a; } COLOR; -#define color_hex(value) \ - (uint8_t)((uint32_t)value >> 3), \ - (uint8_t)((uint32_t)value >> 2), \ - (uint8_t)((uint32_t)value >> 1), \ - (uint8_t)((uint32_t)value >> 0) \ +#define color_hex(value) { \ + (uint8_t)(((uint32_t)value >> 8*0)&0xFF), \ + (uint8_t)(((uint32_t)value >> 8*1)&0xFF), \ + (uint8_t)(((uint32_t)value >> 8*2)&0xFF), \ + (uint8_t)(((uint32_t)value >> 8*3)&0xFF), \ +} constexpr COLOR COLOR_NO_COLOR = { .a = 0, diff --git a/src/ui/tui.c b/src/ui/tui.c index 62eb585..901cbc1 100644 --- a/src/ui/tui.c +++ b/src/ui/tui.c @@ -20,12 +20,14 @@ const int MIN_HEIGHT = -2; const int FRAME_UNLIMITED = 0; void _tui_clear_cells(TUI *tui) { - const TERMINAL_CELL empty = {.c = ' ', - .color = COLOR_NO_COLOR, - .background_color = COLOR_NO_COLOR, - .on_click_callback = NULL}; + constexpr TERMINAL_CELL EMPTY_CELL = { + .c = ' ', + .color = COLOR_NO_COLOR, + .background_color = COLOR_NO_COLOR, + .on_click_callback = NULL, + }; for (size_t i = 0; i < tui->cells_length; ++i) { - tui->cells[i] = empty; + tui->cells[i] = EMPTY_CELL; } } @@ -184,26 +186,6 @@ void tui_handle_mouse_action(TUI *tui, const MOUSE_ACTION *mouse_action) { } } -/* -int tui_change_terminal_text_color(COLOR color) { - if (color_equals(color, COLOR_NO_COLOR)) { - return 0; - } else if (color == COLOR_RESET) { - return printf("\033[%dm", COLOR_RESET); - } - return printf("\033[%dm", color + 30); -} - -int tui_change_terminal_background_color(COLOR color) { - if (color == COLOR_NO_COLOR) { - return 0; - } else if (color == COLOR_RESET) { - return printf("\033[%dm", COLOR_RESET); - } - return printf("\033[%dm", color + 40); -} -*/ - bool handle_input(TUI *tui) { unsigned char buff[6]; read(STDIN_FILENO, &buff, 1); @@ -418,12 +400,12 @@ void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin, if (metadata != NULL) { _tui_get_widget_size(metadata, width_begin, width_end, height_begin, height_end, child_width, child_height); - const int horizontalPadding = width_end - *child_width; - const int verticalPadding = height_end - *child_height; - const int leftPadding = horizontalPadding / 2; - const int rightPadding = horizontalPadding - leftPadding; - const int bottomPadding = verticalPadding / 2; - const int topPadding = verticalPadding - bottomPadding; + const uint horizontalPadding = width_end - *child_width; + const uint verticalPadding = height_end - *child_height; + const uint leftPadding = horizontalPadding / 2; + const uint rightPadding = horizontalPadding - leftPadding; + const uint bottomPadding = verticalPadding / 2; + const uint topPadding = verticalPadding - bottomPadding; _tui_draw_widget_to_cells( tui, metadata, width_begin + leftPadding, width_end - rightPadding, @@ -440,6 +422,14 @@ void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin, width_end - metadata->padding_right, height_begin + metadata->padding_top, height_end - metadata->padding_bottom, child_width, child_height); + *child_width += metadata->padding_left + metadata->padding_right; + *child_height += metadata->padding_top + metadata->padding_bottom; + if (*child_width > width_end) { + *child_width = width_end; + } + if (*child_height > height_end) { + *child_height = height_end; + } } } return; @@ -579,6 +569,7 @@ void _tui_get_widget_size(const WIDGET *widget, int width_begin, int width_end, *widget_height = height_end; } } + return; } fprintf(stderr, "widget type '%d' went wrong in %s %d", widget->type, __FILE_NAME__, __LINE__); @@ -591,6 +582,7 @@ bool _tui_is_max_width(const WIDGET *widget) { } switch (widget->type) { case WIDGET_TYPE_TEXT: + case WIDGET_TYPE_TEXT_INPUT: return false; case WIDGET_TYPE_BUTTON: return _tui_is_max_width(((BUTTON_METADATA *)widget->metadata)->child); @@ -762,32 +754,43 @@ bool tui_widget_eqauls(const WIDGET *restrict left, left_data->padding_left == right_data->padding_left && left_data->padding_right == right_data->padding_right; } + case WIDGET_TYPE_TEXT_INPUT: { + const TEXT_INPUT_METADATA *left_data = left->metadata; + const TEXT_INPUT_METADATA *right_data = right->metadata; + return color_equals(left_data->color, right_data->color) && + strcmp(left_data->text, right_data->text) == 0 && + left_data->on_text_input == right_data->on_text_input; + } } fprintf(stderr, "Type error '%d' in %s %d\n", left->type, __FILE__, __LINE__); exit(1); } -const int NANO_TO_SECOND = 1000000000; - -int64_t nano_sleep(long int nano_seconds) { +int64_t nano_sleep(uint64_t nano_seconds) { struct timespec remaining, request = {nano_seconds / NANO_TO_SECOND, nano_seconds % NANO_TO_SECOND}; nanosleep(&request, &remaining); - return remaining.tv_sec * NANO_TO_SECOND + remaining.tv_nsec; + int64_t ret = remaining.tv_sec * NANO_TO_SECOND + remaining.tv_nsec; + if (ret < 0 || ret > NANO_TO_SECOND) { // TODO: fix later + return 0; + } else { + return ret; + } } -long int nano_time() { +int64_t nano_time() { struct timespec t = {0, 0}; clock_gettime(CLOCK_MONOTONIC, &t); return t.tv_sec * NANO_TO_SECOND + t.tv_nsec; } +uint64_t frame_count = 0; void tui_main_loop(TUI *tui, WIDGET_BUILDER widget_builder, int fps) { - const long int frame_nano = + const uint64_t frame_nano = (fps == FRAME_UNLIMITED) ? 0 : NANO_TO_SECOND / fps; int64_t last_remaining = 0; while (1) { - const long int start = nano_time(); + const int64_t start = nano_time(); tui_save_cursor(); tui_refresh(tui); WIDGET *root_widget = widget_builder(tui); @@ -803,10 +806,11 @@ void tui_main_loop(TUI *tui, WIDGET_BUILDER widget_builder, int fps) { /*printf("%ld\t%ld", last_frame_time, frame_nano);*/ tui_restore_cursor(); if (fps != FRAME_UNLIMITED) { - const long int diff = nano_time() - start; + const int64_t diff = nano_time() - start; last_remaining = nano_sleep(frame_nano - diff + last_remaining); } tui->last_frame = nano_time() - start; + ++frame_count; if (kbhit()) { if (handle_input(tui)) { return; @@ -848,6 +852,9 @@ void tui_delete_widget(WIDGET *restrict widget) { case WIDGET_TYPE_PADDING: _tui_delete_padding(widget); goto RETURN_SUCCESS; + case WIDGET_TYPE_TEXT_INPUT: + _tui_delete_input_text(widget); + goto RETURN_SUCCESS; } fprintf(stderr, "Type error '%d' in %s %d\n", widget->type, __FILE__, __LINE__); @@ -983,6 +990,26 @@ void _tui_delete_padding(WIDGET *restrict padding) { free(padding->metadata); } +extern WIDGET *tui_make_text_input(char *restrict text, COLOR color, + ON_TEXT_INPUT on_text_input) { + return tui_new_widget( + WIDGET_TYPE_TEXT_INPUT, + _tui_make_text_input_metadata(text, color, on_text_input)); +} +extern TEXT_INPUT_METADATA *_tui_make_text_input_metadata( + char *restrict text, COLOR color, ON_TEXT_INPUT on_text_input) { + TEXT_INPUT_METADATA *metadata = malloc(sizeof(*metadata)); + metadata->text = malloc(strlen(text) + 1); + strcpy(metadata->text, text); + metadata->color = color; + metadata->on_text_input = on_text_input; + return metadata; +} +extern void _tui_delete_input_text(WIDGET *restrict text_input) { + free(((TEXT_INPUT_METADATA *)text_input->metadata)->text); + free(text_input->metadata); +} + WIDGET_ARRAY *tui_make_widget_array_raw(size_t size, ...) { va_list arg_pointer; va_start(arg_pointer, size); diff --git a/src/ui/tui.h b/src/ui/tui.h index 8678804..605376f 100644 --- a/src/ui/tui.h +++ b/src/ui/tui.h @@ -52,6 +52,8 @@ typedef struct TUI { uint64_t last_frame; // in nanoseconds } TUI; +constexpr int64_t NANO_TO_SECOND = 1000000000; + typedef enum WIDGET_TYPE { WIDGET_TYPE_TEXT, WIDGET_TYPE_BUTTON, @@ -60,6 +62,7 @@ typedef enum WIDGET_TYPE { WIDGET_TYPE_BOX, WIDGET_TYPE_CENTER, WIDGET_TYPE_PADDING, + WIDGET_TYPE_TEXT_INPUT, } WIDGET_TYPE; typedef struct WIDGET { @@ -107,6 +110,14 @@ typedef struct PADDING_METADATA { int padding_right; } PADDING_METADATA; +typedef void (*ON_TEXT_INPUT)(char c); + +typedef struct TEXT_INPUT_METADATA { + char *text; + COLOR color; + ON_TEXT_INPUT on_text_input; +} TEXT_INPUT_METADATA; + typedef WIDGET *(*WIDGET_BUILDER)(TUI *tui); extern TUI *tui_init(); @@ -173,6 +184,12 @@ extern WIDGET *tui_make_center(WIDGET *restrict child); extern CENTER_METADATA *_tui_make_center_metadata(WIDGET *restrict child); extern void _tui_delete_center(WIDGET *restrict center); +extern WIDGET *tui_make_text_input(char *restrict text, COLOR color, + ON_TEXT_INPUT on_text_input); +extern TEXT_INPUT_METADATA *_tui_make_text_input_metadata( + char *restrict text, COLOR color, ON_TEXT_INPUT on_text_input); +extern void _tui_delete_input_text(WIDGET *restrict text_input); + extern WIDGET *tui_make_padding(WIDGET *restrict child, int padding_top, int padding_bottom, int padding_left, int padding_right); |