diff --git a/src/utils/d_array.c b/src/utils/d_array.c index f0fba1d..ca9968a 100644 --- a/src/utils/d_array.c +++ b/src/utils/d_array.c @@ -13,6 +13,12 @@ void u_d_arr_ptr_init(d_array_ptr_t *arr, int32_t init_capacity) { memset(arr->arr, 0, sizeof(void *) * init_capacity); } +/* TODO: check out the correctness */ +void u_d_array_append(d_array_ptr_t *arr, void *el_ptr, size_t el_len) { + void *el = malloc(el_len); + u_d_arr_ptr_add(arr, el, arr->length); +} + void u_d_arr_ptr_add(d_array_ptr_t *arr, void *ptr, int32_t idx) { if (idx > arr->capacity - 1) { int32_t new_capacity = idx * 2; @@ -31,4 +37,16 @@ void u_d_arr_ptr_free(d_array_ptr_t *arr) { arr->length = 0; free(arr->arr); arr->arr = NULL; +} + +void u_d_arr_free_cb(d_array_ptr_t *arr, u_d_arr_free_callback *callback) { + for (int i = 0; i < arr->length; i++) { + if (arr->arr[i] != NULL) { + callback(arr->arr[i]); + } + } + arr->capacity = 0; + arr->length = 0; + free(arr->arr); + arr->arr = NULL; } \ No newline at end of file diff --git a/src/utils/d_array.h b/src/utils/d_array.h index a486f90..93c699c 100644 --- a/src/utils/d_array.h +++ b/src/utils/d_array.h @@ -1,7 +1,10 @@ #ifndef D_ARRAY_H #define D_ARRAY_H /* Dynamic array of numbers */ + +#include #include + typedef struct d_array_ptr_t { int32_t capacity; int32_t length; @@ -10,8 +13,12 @@ typedef struct d_array_ptr_t { void *last_el; } d_array_ptr_t; +typedef void *u_d_arr_free_callback(void *arg); + void u_d_arr_ptr_init(d_array_ptr_t *arr, int32_t init_capacity); void u_d_arr_ptr_add(d_array_ptr_t *arr, void *ptr, int32_t idx); void u_d_arr_ptr_free(d_array_ptr_t *arr); +void u_d_array_append(d_array_ptr_t *arr, void *el_ptr, size_t el_len); +void u_d_arr_free_cb(d_array_ptr_t *arr, u_d_arr_free_callback *callback); #endif \ No newline at end of file diff --git a/src/utils/dlist.c b/src/utils/dlist.c new file mode 100644 index 0000000..81c43ab --- /dev/null +++ b/src/utils/dlist.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include + +typedef struct dlist_el_t { + struct dlist_el_t *next; + struct dlist_el_t *previous; + void *el_ptr; +} dlist_el_t; + +typedef struct dlist_t { + dlist_el_t *start; + dlist_el_t *current; + size_t len; +} dlist_t; + +void dlist_add(dlist_t *dlist, void *el_ptr, int el_siz, bool prepend); + +dlist_t *dlist_init(void *el_ptr, int el_siz) { + dlist_t *dlist = malloc(sizeof(dlist_t)); + dlist->len = 0; + dlist->current = NULL; + dlist->start = NULL; + + if (el_ptr != NULL) { + dlist_add(dlist, el_ptr, el_siz, false); + } + + return dlist; +} + +void dlist_add(dlist_t *dlist, void *el_ptr, int el_siz, bool prepend) { + dlist_el_t *d_el = malloc(sizeof(dlist_el_t)); + d_el->el_ptr = malloc(el_siz); + memcpy(d_el->el_ptr, el_ptr, el_siz); + + if (dlist->start == NULL) { + d_el->previous = NULL; + d_el->next = NULL; + dlist->start = d_el; + dlist->current = d_el; + } else if (prepend) { + d_el->previous = NULL; + d_el->next = dlist->start; + dlist->start = d_el; + } else { + d_el->next = NULL; + dlist->current->next = d_el; + dlist->current = d_el; + } + dlist->len++; +} + +void *dlist_get_current(dlist_t *dlist) { + return dlist->current->el_ptr; +} + +void *dlist_it_prev(dlist_t *dlist) { + dlist->current = dlist->current->previous; + return dlist->current; +} \ No newline at end of file diff --git a/src/windows/text_edit.c b/src/windows/text_edit.c index aa2b56c..3d3d9cc 100644 --- a/src/windows/text_edit.c +++ b/src/windows/text_edit.c @@ -7,9 +7,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -20,27 +18,42 @@ /* TODO: create dynamic array of endline positions */ +/* + Массив d_array, состоящие из элементов, описывающий строки. + В строках записывать: длину, номер строки. +*/ + static void w_te_cb(w_cb_args_t *args) { app_t *app = args->app; int32_t key = *((int32_t *)args->data); w_te_ui_t *fui = app->query_args->main_ui->ui; + w_te_ui_line_t *line = NULL; + switch (key) { case KEY_BACKSPACE: case KEY_DL: - fui->text[fui->text_len--] = 0; + fui->line[fui->line_len--] = 0; break; case KEY_UP: fui->cur_shift_pos.y--; wchar_t *nl_ptr = NULL; - wchar_t *line_start = fui->text; - + wchar_t *line_start = fui->line; break; case KEY_DOWN: fui->cur_shift_pos.y++; break; + case '\n': + line = malloc(sizeof (w_te_ui_line_t)); + line->text = malloc(sizeof (wchar_t ) * (fui->line_len + 1)); + wcscpy(line->text, fui->line); + line->capacity = line->len = fui->line_len; + u_d_array_append(&(fui->lines_arr), fui->line, fui->line_len); + fui->line[0] = 0; + fui->line_len = 0; + break; default: - fui->text[fui->text_len++] = key; - fui->text[fui->text_len] = 0; + fui->line[fui->line_len++] = key; + fui->line[fui->line_len] = 0; } } @@ -112,14 +125,15 @@ w_te_ui_t *w_te_init_win(app_t *app) { app->top_text = malloc(sizeof(wchar_t) * (top_text_len + 1)); wcsncpy(app->top_text, top_text, top_text_len); app->top_text[top_text_len] = 0; + u_d_arr_ptr_init(&(fui->lines_arr), INBUFSIZE); return fui; } -void w_te_reset(w_te_ui_t *fl_ui) { - fl_ui->text[0] = 0; - fl_ui->cur_shift_pos.x = 0; - fl_ui->cur_shift_pos.y = 0; - fl_ui->text_len = 0; +void w_te_reset(w_te_ui_t *fui) { + fui->line[0] = 0; + fui->cur_shift_pos.x = 0; + fui->cur_shift_pos.y = 0; + fui->line_len = 0; } void w_te_reset_app(void *app) { @@ -146,32 +160,39 @@ void w_te_draw(w_te_ui_t *fui) { mvwprintw(win, p_y + i, p_x, "%*s", fui->w.sz.x, ""); } - int len_rest = fui->text_len; + int len_rest = fui->line_len; - wchar_t *cur_ptr = fui->text; + wchar_t *cur_ptr = fui->line; wchar_t *nl_ptr = wcschr(cur_ptr, '\n'); - - if (nl_ptr == NULL) { - mvwaddnwstr(win, p_y, p_x, cur_ptr, fui->text_len); - p_x += fui->text_len; - } else { - while (true) { - mvwaddnwstr(win, p_y++, p_x, cur_ptr, nl_ptr - cur_ptr); - cur_ptr = nl_ptr + 1; - nl_ptr = wcschr(cur_ptr, '\n'); - if (nl_ptr == NULL) { - int tlen = wcslen(cur_ptr); - mvwaddnwstr(win, p_y, p_x, cur_ptr, tlen); - p_x += tlen; - break; - } - } + // if (nl_ptr == NULL) { + // mvwaddnwstr(win, p_y, p_x, cur_ptr, fui->line_len); + // p_x += fui->line_len; + // } else { + // while (true) { + // mvwaddnwstr(win, p_y++, p_x, cur_ptr, nl_ptr - cur_ptr); + // cur_ptr = nl_ptr + 1; + // nl_ptr = wcschr(cur_ptr, '\n'); + // if (nl_ptr == NULL) { + // int tlen = wcslen(cur_ptr); + // mvwaddnwstr(win, p_y, p_x, cur_ptr, tlen); + // p_x += tlen; + // break; + // } + // } + // } + w_te_ui_line_t *line_arr_el = NULL; + for (int i = 0; i < fui->lines_arr.length; i++) { + line_arr_el = (w_te_ui_line_t *) fui->lines_arr.arr[i]; + mvwaddnwstr(win, p_y++, p_x, line_arr_el->text, line_arr_el->len); } + mvwaddnwstr(win, p_y, p_x, fui->line, fui->line_len); + fui->cur_abs_pos.y = p_y; fui->cur_abs_pos.x = p_x; - wmove(win, fui->cur_abs_pos.y + fui->cur_shift_pos.y, fui->cur_abs_pos.x + fui->cur_shift_pos.x); + wmove(win, fui->cur_abs_pos.y + fui->cur_shift_pos.y, + fui->cur_abs_pos.x + fui->cur_shift_pos.x); p_x = 1; diff --git a/src/windows/text_edit.h b/src/windows/text_edit.h index 75db0ad..3215004 100644 --- a/src/windows/text_edit.h +++ b/src/windows/text_edit.h @@ -15,9 +15,9 @@ typedef struct { w_t w; WINDOW *win; - wchar_t text[INBUFSIZE * 10]; - int text_len; - int text_cur_pos; + wchar_t line[INBUFSIZE * 10]; + int line_len; + int line_cur_pos; struct { int x; int y; @@ -26,9 +26,16 @@ typedef struct { int x; int y; } cur_abs_pos; - p_file_t *file_ptr; // TODO: уточнить + p_file_t *file_ptr; + d_array_ptr_t lines_arr; } w_te_ui_t; +typedef struct { + int len; + wchar_t *text; /* TODO: make dynamic */ + int capacity; +} w_te_ui_line_t; + void w_te_draw(w_te_ui_t *fl_ui); void w_te_destroy(w_te_ui_t **fui); void w_te_reset(w_te_ui_t *fl_ui);