diff --git a/src/main.c b/src/main.c index 6fe37e7..7d89c4f 100644 --- a/src/main.c +++ b/src/main.c @@ -44,6 +44,7 @@ int main(int argc, char **argv) { q_args->buf = malloc(INBUFSIZE); app->query_args = q_args; q_args->file_list_ui = init_file_list(&(app->left_win), &(app->right_win)); + draw_file_list(q_args->file_list_ui); /* init client to connect to the server */ app->params->sd = init_client(); diff --git a/src/modals/register.c b/src/modals/register.c index bac1657..bf6704f 100644 --- a/src/modals/register.c +++ b/src/modals/register.c @@ -8,6 +8,8 @@ #include #include "alert.h" +#include "group.h" +#include "widget_core.h" typedef struct { button_t *element; @@ -46,8 +48,8 @@ void init_register_modal_cb(callback_args_t *args) { app->params->uname[in_name->value_len] = 0; strncpy(app->params->pass, in_pass->value, in_pass->value_len); app->params->pass[in_pass->value_len] = 0; - sprintf(query, "register %s %s\n%n", app->params->uname, app->params->pass, - &qlen); + sprintf(query, "register %s %s\n%n", app->params->uname, + app->params->pass, &qlen); write(app->params->sd, query, qlen); app->query_args->state = S_WAIT_REGISTER_CONFIRMATION; break; @@ -61,16 +63,24 @@ void init_register_modal_cb(callback_args_t *args) { dialogue_t *init_register_modal(app_t *app) { if (app == NULL) return NULL; + group_el_init_t content_name_email[] = { + {.type = w_input, .label = "Username", .length = 18}, + {.type = w_input, .label = "Email", .length = 18}, + {.type = w_end}}; + + group_el_init_t content_pass[] = {{.type = w_input, + .label = "Password", + .length = 18, + .is_hidden_value = true}, + {.type = w_input, + .label = "Password (repeat)", + .length = 18, + .is_hidden_value = true}, + {.type = w_end}}; + group_el_init_t content[] = { - {.type = w_input, .label = "Username", .length = 15}, - {.type = w_input, - .label = "Password", - .length = 15, - .is_hidden_value = true}, - {.type = w_input, - .label = "Password (repeat)", - .length = 15, - .is_hidden_value = true}, + {.type = w_group, .direction = vertical, .children = content_name_email}, + {.type = w_group, .direction = vertical, .children = content_pass}, {.type = w_end}}; group_el_init_t actions[] = { diff --git a/src/widget/button.c b/src/widget/button.c index 8852d75..246c581 100644 --- a/src/widget/button.c +++ b/src/widget/button.c @@ -21,8 +21,16 @@ button_t *init_button(WINDOW **win, widget_t *w_parent, char *label) { int32_t draw_button(button_t *btn, uint32_t active_id) { char title[DIALOGUE_TITLE + 6]; WINDOW *win = *(btn->w.parent_win); - uint32_t margin_y = btn->w.m_y + btn->w.w_parent->m_y; - uint32_t margin_x = btn->w.m_x + btn->w.w_parent->m_x; + uint32_t margin_y = btn->w.m_y; + uint32_t margin_x = btn->w.m_x; + + widget_t *w_par = btn->w.w_parent; + + while (w_par->parent_win == btn->w.parent_win) { + margin_y += w_par->m_y; + margin_x += w_par->m_x; + w_par = w_par->w_parent; + } if (btn->w.id == active_id) { sprintf(title, "[< %s >]", btn->w.title); diff --git a/src/widget/dialogue.c b/src/widget/dialogue.c index 8de483f..31228ec 100644 --- a/src/widget/dialogue.c +++ b/src/widget/dialogue.c @@ -179,7 +179,8 @@ void init_dialogue(dialogue_t *dialogue, const char title[], const char text[], t_size = strlen(text); strcpy(dialogue->text, text); /* trim the last new line symbol */ - if (t_size && dialogue->text[t_size-1] == '\n') dialogue->text[t_size-1] = '\0'; + if (t_size && dialogue->text[t_size - 1] == '\n') + dialogue->text[t_size - 1] = '\0'; } void dialogue_init_active_id(dialogue_t *dialogue) { @@ -211,34 +212,6 @@ void dialogue_init_active_id(dialogue_t *dialogue) { } } -// void dialogue_init_active_id(dialogue_t *dialogue) { -// enum w_type widget_type; - -// if (dialogue->g_content != NULL) { -// for (int i = 0; i < dialogue->g_content->count; i++) { -// widget_type = dialogue->g_content->elements[i].type; -// if (widget_type == w_button || widget_type == w_input || -// widget_type == w_fs_file_list) { /* Add here new types */ -// dialogue->active.type = g_content; -// widget_t *w = (widget_t *)dialogue->g_content->elements[i].element; -// dialogue->active.id = w->id; -// break; -// } -// } -// } else if (dialogue->g_action != NULL) { -// for (int i = 0; i < dialogue->g_action->count; i++) { -// widget_type = dialogue->g_action->elements[i].type; -// if (widget_type == w_button || widget_type == w_input || -// widget_type == w_fs_file_list) { -// dialogue->active.type = g_action; -// widget_t *w = (widget_t *)dialogue->g_action->elements[i].element; -// dialogue->active.id = w->id; -// break; -// } -// } -// } -// } - #define DETECT_GROUP_SIZE(group, line_max_len, y, x) \ if (group) { \ group->w.m_y = y; \ @@ -317,10 +290,10 @@ int32_t draw_dialogue(dialogue_t *d) { wattroff(d->win, A_REVERSE); if (d->g_content != NULL) { - draw_group(d->win, d->g_content, d->active.id, &(d->w)); + draw_group(d->win, d->g_content, d->active.id); } if (d->g_action != NULL) { - draw_group(d->win, d->g_action, d->active.id, &(d->w)); + draw_group(d->win, d->g_action, d->active.id); } /* move cursor */ @@ -331,19 +304,18 @@ int32_t draw_dialogue(dialogue_t *d) { FIND_ACTIVE_ELEMENT(d->g_action, d->active.id, ae_ptr, ae_idx); } - if (ae_ptr != NULL && ae_ptr->id == d->active.id) { - if (ae_ptr->type == w_input) { - input_t *input = ae_ptr->element; - d->w.cur.y = input->w.cur.y; - d->w.cur.x = input->w.cur.x + input->value_len; - d->w.cur.x -= input->cur_pos; - if (d->w.cur.y || d->w.cur.x) { - wmove(d->win, d->w.cur.y, d->w.cur.x); - curs_set(true); - } - } else { - curs_set(false); + if (ae_ptr != NULL && ae_ptr->id == d->active.id && ae_ptr->type == w_input) { + input_t *input = ae_ptr->element; + d->w.cur.y = input->w.cur.y; + d->w.cur.x = input->w.cur.x + input->value_len; + d->w.cur.x -= input->cur_pos; + if (d->w.cur.y || d->w.cur.x) { + wmove(d->win, d->w.cur.y, d->w.cur.x); + curs_set(true); } + + } else { + curs_set(false); } d->needs_update = false; diff --git a/src/widget/file_list.c b/src/widget/file_list.c index 3156e18..e4ed0dc 100644 --- a/src/widget/file_list.c +++ b/src/widget/file_list.c @@ -114,6 +114,8 @@ ui_file_list_t *init_file_list(WINDOW **win, WINDOW *const *info_win) { fui->max_lines = getmaxy(parent_win) - 3; /* 2+1 (bottom info line) */ fui->active_search = false; fui->search_key = bfromcstrrangealloc(12, 64, ""); + fui->start = NULL; + fui->current = NULL; return fui; } @@ -135,11 +137,16 @@ void draw_file_list(ui_file_list_t *fui) { int32_t sz_y_f = sz_y - 2; /* TODO: можно заменить на поле max_lines */ p_y = 1; p_x = 1; - fl_item_t *el = *(fui->start); - fl_item_t *active_el = *(fui->start); + fl_item_t *el = NULL; + fl_item_t *active_el = NULL; int32_t cur_el_idx = 0; curs_set(false); + if (fui->start != NULL) { + el = *(fui->start); + active_el = el; + } + if (fui->activate_last) { fui->current_idx = fui->current_count - 1; fui->activate_last = false; diff --git a/src/widget/group.c b/src/widget/group.c index c8b5971..2a04bbc 100644 --- a/src/widget/group.c +++ b/src/widget/group.c @@ -3,12 +3,14 @@ #include "fs_file_list.h" #include "input.h" #include "progress_bar.h" +#include "widget_core.h" #include #include #include #include #include +/* make response -1 */ #define MAKE_RESPONSE_M1(args, resp_data, response) \ if (args->resp_data != NULL) { \ *response = -1; \ @@ -62,7 +64,7 @@ void group_default_callback(callback_args_t *args) { } } } else { - widget = (widget_t *) element_ptr->element; + widget = (widget_t *)element_ptr->element; if (widget->callback != NULL) { memccpy(&new_args, args, 1, sizeof(callback_args_t)); new_args.element = element_ptr->element; @@ -104,9 +106,13 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, w = &(((button_t *)elements[i].element)->w); break; case w_box: - case w_group: case w_end: break; + case w_group: + elements[i].element = init_group(win, &(group->w), children[i].children, + children[i].direction); + w = &(((input_t *)elements[i].element)->w); + break; case w_input: elements[i].element = init_input(win, &(group->w), children[i].label, children[i].length, @@ -130,6 +136,12 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, group->w.x += w->x + 1; if (group->w.y < w->y) group->w.y = w->y; + } else { + w->m_x = group->w.m_x; + w->m_y = group->w.m_y + group->w.y; + group->w.y += w->y; + if (group->w.x < w->x) + group->w.x = w->x; } if (i == 0) { group->first_id = w->id; @@ -139,11 +151,13 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, } } + if (direction == vertical) + group->w.y++; + return group; } -void draw_group(WINDOW *win, group_t *group, int32_t active_id, - widget_t *dialog_w) { +void draw_group(WINDOW *win, group_t *group, int32_t active_id) { group_el_t *children = group->elements; for (int i = 0; i < group->count; i++) { group_el_t *el = &children[i]; @@ -151,8 +165,10 @@ void draw_group(WINDOW *win, group_t *group, int32_t active_id, case w_button: draw_button((button_t *)el->element, active_id); break; - case w_box: case w_group: + draw_group(win, (group_t *)el->element, active_id); + break; + case w_box: case w_end: break; case w_input: @@ -176,8 +192,10 @@ void destroy_group(group_t *group) { case w_button: destroy_button(el->element); break; - case w_box: case w_group: + destroy_group(el->element); + break; + case w_box: case w_end: break; case w_input: diff --git a/src/widget/group.h b/src/widget/group.h index e7cf353..36e4c68 100644 --- a/src/widget/group.h +++ b/src/widget/group.h @@ -16,12 +16,14 @@ typedef struct { uint32_t is_default : 1; } group_el_t; -typedef struct { +typedef struct group_el_init_t { enum w_type type; - uint32_t is_default : 1; - uint32_t is_hidden_value : 1; + bool is_default; + bool is_hidden_value; char label[DIALOGUE_TITLE]; uint32_t length; + enum g_direction direction; + struct group_el_init_t *children; } group_el_init_t; typedef struct { @@ -38,8 +40,7 @@ typedef struct { group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, enum g_direction dir); -void draw_group(WINDOW *win, group_t *group, int32_t active_id, - widget_t *dialog_w); +void draw_group(WINDOW *win, group_t *group, int32_t active_id); void destroy_group(group_t *group); void group_default_callback(callback_args_t *args); diff --git a/src/widget/input.c b/src/widget/input.c index 518884a..eeea55a 100644 --- a/src/widget/input.c +++ b/src/widget/input.c @@ -4,16 +4,16 @@ #include #include "app.h" -#include #include "input.h" +#include input_t *init_input(WINDOW **win, widget_t *w_parent, char *label, uint32_t length, uint32_t is_hidden_value) { input_t *input = malloc(sizeof(input_t)); init_widget(&(input->w), w_parent, win, label); input->is_disabled = 0; - input->w.y = 3; // with borders - input->w.x = length + 3; // with borders and extra space for the last element + input->w.y = 3; // with borders + input->w.x = length + 3; // with borders and extra space for the last element uint32_t t_len = strlen(input->w.title) + 4; // with borders and space if (input->w.x < t_len) input->w.x = t_len; @@ -29,8 +29,16 @@ input_t *init_input(WINDOW **win, widget_t *w_parent, char *label, int32_t draw_input(input_t *input, uint32_t active_id) { const char stars[] = "*******************"; WINDOW *win = *(input->w.parent_win); - uint32_t margin_y = input->w.m_y + input->w.w_parent->m_y; - uint32_t margin_x = input->w.m_x + input->w.w_parent->m_x; + uint32_t margin_y = input->w.m_y; + uint32_t margin_x = input->w.m_x; + + /* counts margins of the ancestors of the same window */ + widget_t *w_par = input->w.w_parent; + while (w_par->parent_win == input->w.parent_win) { + margin_y += w_par->m_y; + margin_x += w_par->m_x; + w_par = w_par->w_parent; + } wattrset(win, COLOR_PAIR(modal_color_pair)); @@ -57,13 +65,13 @@ int32_t draw_input(input_t *input, uint32_t active_id) { } if (input->is_hidden) { - mvwprintw(win, margin_y + 1, margin_x, "%.*s%*s", (int) input->value_len, stars, - input->w.x - input->value_len - 2, ""); + mvwprintw(win, margin_y + 1, margin_x, "%.*s%*s", (int)input->value_len, + stars, input->w.x - input->value_len - 2, ""); } else { mvwprintw(win, margin_y + 1, margin_x, "%s%*s", input->value, input->w.x - input->value_len - 2, ""); } - + input->w.cur.y = margin_y + 1; input->w.cur.x = margin_x;