diff --git a/TODO.md b/TODO.md index 13f44a3..cdeedc7 100644 --- a/TODO.md +++ b/TODO.md @@ -3,7 +3,8 @@ ## Current: - [ ] UI: vertical layout (needs for email in registration) - [ ] Nested groups -- [ ] Create dynamic map of elements IDs and their pointers +- [x] Create dynamic map of elements IDs and their pointers +- [ ] Adapt modals to new value-forwarding method ## Features: - [x] Search files diff --git a/src/modals/ask_server_addr.c b/src/modals/ask_server_addr.c index ae1c1b3..dfe2a13 100644 --- a/src/modals/ask_server_addr.c +++ b/src/modals/ask_server_addr.c @@ -11,6 +11,7 @@ #include #include "../connection.h" #include "group.h" +#include "widget_core.h" typedef struct { button_t *element; @@ -18,19 +19,17 @@ typedef struct { } group_bt_t; void asa_modal_dialogue_callback(callback_args_t *args) { - int32_t response; callback_args_t d_args; app_t *app = args->app; dialogue_t *d = (dialogue_t *)app->active_widget; memcpy(&d_args, args, sizeof(callback_args_t)); d_args.app = NULL; - d_args.resp_data = &response; d_args.element = app->active_widget; input_t *in_ip = d->g_content->elements[0].element; input_t *in_port = d->g_content->elements[1].element; dialogue_default_callback(&d_args); - if (response > -1) { - switch (response) { + if (d_args.resp_data.code == cbrp_val) { + switch (d_args.resp_data.val.val.num) { case 0: get_ip_port(app->params, in_ip->value, in_port->value); connect_to_server(app); diff --git a/src/modals/login_credentials.c b/src/modals/login_credentials.c index 28806b3..d6de53e 100644 --- a/src/modals/login_credentials.c +++ b/src/modals/login_credentials.c @@ -13,19 +13,17 @@ typedef struct { } group_bt_t; void init_login_credentials_modal_cb(callback_args_t *args) { - int32_t response; callback_args_t d_args; app_t *app = args->app; dialogue_t *d = (dialogue_t *)app->active_widget; memcpy(&d_args, args, sizeof(callback_args_t)); d_args.app = NULL; - d_args.resp_data = &response; d_args.element = app->active_widget; input_t *in_name = d->g_content->elements[0].element; input_t *in_pass = d->g_content->elements[1].element; dialogue_default_callback(&d_args); - if (response > -1) { - switch (response) { + if (d_args.resp_data.code == cbrp_val) { + switch (d_args.resp_data.val.val.num) { case 0: app->params->uname = malloc(in_name->value_len + 1); app->params->pass = malloc(in_pass->value_len + 1); diff --git a/src/modals/login_option.c b/src/modals/login_option.c index e7d414f..e5d7e1b 100644 --- a/src/modals/login_option.c +++ b/src/modals/login_option.c @@ -13,17 +13,15 @@ typedef struct { } group_bt_t; void login_modal_option_cb(callback_args_t *args) { - int32_t response; callback_args_t d_args; app_t *app = args->app; dialogue_t *d = (dialogue_t *)app->active_widget; memcpy(&d_args, args, sizeof(callback_args_t)); d_args.app = NULL; - d_args.resp_data = &response; d_args.element = app->active_widget; dialogue_default_callback(&d_args); - if (response > -1) { - switch (response) { + if (d_args.resp_data.code == cbrp_val) { + switch (d_args.resp_data.val.val.num) { case 0: d->needs_destroy = true; app->params->uname = malloc(sizeof "anonymous"); diff --git a/src/modals/notification.c b/src/modals/notification.c index f6e959c..f85ca1e 100644 --- a/src/modals/notification.c +++ b/src/modals/notification.c @@ -6,21 +6,17 @@ #include -/* TODO: get rid of this mechanism */ - typedef struct { button_t *element; enum w_type type; } group_bt_t; void init_notification_modal_cb(callback_args_t *args) { - int32_t response; callback_args_t d_args; app_t *app = args->app; dialogue_t *d = (dialogue_t *)app->active_widget; memcpy(&d_args, args, sizeof(callback_args_t)); d_args.app = NULL; - d_args.resp_data = &response; d_args.element = app->active_widget; dialogue_default_callback(&d_args); @@ -33,7 +29,8 @@ dialogue_t *init_notification_modal(app_t *app) { return NULL; group_el_init_t actions[] = { - {.type = w_button, .label = "OK", .is_default = 1}, {.type = w_end}}; + {.type = w_button, .label = "OK", .is_default = 1, .val.num = 1}, + {.type = w_end}}; init_dialogue(&(app->modal), "Notification", app->query_args->notification, &(app->coordinates)); @@ -44,7 +41,8 @@ dialogue_t *init_notification_modal(app_t *app) { d->w.callback = init_notification_modal_cb; d->g_content = NULL; - d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), horizontal, g_action); + d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), + horizontal, g_action); dialogue_init_active_id(d); diff --git a/src/modals/register.c b/src/modals/register.c index 160cc1a..a0e570c 100644 --- a/src/modals/register.c +++ b/src/modals/register.c @@ -19,20 +19,19 @@ typedef struct { void init_register_modal_cb(callback_args_t *args) { char query[256]; int32_t qlen = 0; - int32_t response; callback_args_t d_args; app_t *app = args->app; dialogue_t *d = (dialogue_t *)app->active_widget; memcpy(&d_args, args, sizeof(callback_args_t)); d_args.app = NULL; - d_args.resp_data = &response; d_args.element = app->active_widget; input_t *in_name = d->g_content->elements[0].element; input_t *in_pass = d->g_content->elements[1].element; input_t *in_pass_r = d->g_content->elements[2].element; dialogue_default_callback(&d_args); - if (response > -1) { - switch (response) { + if (d_args.resp_data.code == cbrp_val && + d_args.resp_data.val.type == val_num) { + switch (d_args.resp_data.val.val.num) { case 0: if (strcmp(in_pass->value, in_pass_r->value)) { alert("Your passwords do not match"); @@ -93,10 +92,10 @@ dialogue_t *init_register_modal(app_t *app) { dialogue_t *d = &(app->modal); d->w.callback = init_register_modal_cb; - d->g_content = - init_group(&(d->win), &(d->w), content, &(d->id_map), horizontal, g_content); - d->g_action = - init_group(&(d->win), &(d->w), actions, &(d->id_map), horizontal, g_action); + d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map), + horizontal, g_content); + d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), + horizontal, g_action); dialogue_init_active_id(d); diff --git a/src/modals/server_message.c b/src/modals/server_message.c index 87b5e77..3b6278f 100644 --- a/src/modals/server_message.c +++ b/src/modals/server_message.c @@ -12,18 +12,16 @@ typedef struct { } group_bt_t; void server_message_modal_cb(callback_args_t *args) { - int32_t response; callback_args_t d_args; app_t *app = args->app; dialogue_t *d = (dialogue_t *)app->active_widget; memcpy(&d_args, args, sizeof(callback_args_t)); d_args.app = NULL; - d_args.resp_data = &response; d_args.element = app->active_widget; dialogue_default_callback(&d_args); - if (response > -1) { - switch (response) { - case 0: + if (d_args.resp_data.code == cbrp_val) { + switch (d_args.resp_data.val.val.num) { + case 1: d->needs_destroy = true; /* TODO: macros */ free(app->query_args->server_message.text); @@ -40,7 +38,7 @@ void *init_server_message_modal(app_t *app) { if (app == NULL) return NULL; group_el_init_t children[] = { - {.type = w_button, .label = "OK", .is_default = 1}, {.type = w_end}}; + {.type = w_button, .label = "OK", .is_default = 1, .val.num = 1}, {.type = w_end}}; init_dialogue(&(app->modal), "Server response", app->query_args->server_message.text, &(app->coordinates)); diff --git a/src/modals/upload_dialogue.c b/src/modals/upload_dialogue.c index 8245cab..78440c8 100644 --- a/src/modals/upload_dialogue.c +++ b/src/modals/upload_dialogue.c @@ -1,35 +1,35 @@ #include "../file_processor.h" #include "group.h" -#include #include #include #include +#include void upload_dialogue_modal_cb(callback_args_t *args) { - int32_t response = -1; callback_args_t d_args; app_t *app = args->app; dialogue_t *d = (dialogue_t *)app->active_widget; memcpy(&d_args, args, sizeof(callback_args_t)); d_args.app = NULL; - d_args.resp_data = &response; d_args.element = app->active_widget; dialogue_default_callback(&d_args); ui_fs_file_list_t *fui = (ui_fs_file_list_t *)d->g_content->elements[0].element; - switch (response) { - case 0: - app->query_args->state = S_WAIT_SERVER; - d->needs_destroy = true; - break; - case 1: - file_upload_open(fui->d_path, fui->current->name, app->query_args); - d->needs_destroy = true; - app->query_args->state = S_UPLOAD_PARAMS; - break; - case -2: - d->needs_destroy = true; - app->query_args->state = WAIT_CLIENT; + if (d_args.resp_data.code == cbrp_val) { + switch (d_args.resp_data.val.val.num) { + case 0: + app->query_args->state = S_WAIT_SERVER; + d->needs_destroy = true; + break; + case 1: + file_upload_open(fui->d_path, fui->current->name, app->query_args); + d->needs_destroy = true; + app->query_args->state = S_UPLOAD_PARAMS; + break; + case -2: + d->needs_destroy = true; + app->query_args->state = WAIT_CLIENT; + } } } @@ -50,8 +50,10 @@ dialogue_t *init_upload_dialogue_modal(app_t *app) { dialogue_t *d = &(app->modal); d->w.callback = upload_dialogue_modal_cb; - d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map), horizontal, g_content); - d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), horizontal, g_action); + d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map), + horizontal, g_content); + d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), + horizontal, g_action); app->query_args->active_dialogue = d; diff --git a/src/modals/upload_props_dialogue.c b/src/modals/upload_props_dialogue.c index fd90b33..3857e68 100644 --- a/src/modals/upload_props_dialogue.c +++ b/src/modals/upload_props_dialogue.c @@ -8,20 +8,18 @@ #include void upload_props_dialogue_modal_cb(callback_args_t *args) { - int32_t response = -1; callback_args_t d_args; app_t *app = args->app; dialogue_t *d = (dialogue_t *)app->active_widget; memcpy(&d_args, args, sizeof(callback_args_t)); d_args.app = NULL; - d_args.resp_data = &response; d_args.element = app->active_widget; dialogue_default_callback(&d_args); char query[256]; int32_t query_len = 0; input_t *desc_input = (input_t *)d->g_content->elements[0].element; - if (response > -1) { - switch (response) { + if (d_args.resp_data.code == cbrp_val) { + switch (d_args.resp_data.val.val.num) { case 0: query_len = sprintf(query, "file upload \"%s\" %zu 1\n", diff --git a/src/query.c b/src/query.c index 6c6fd15..58e5558 100644 --- a/src/query.c +++ b/src/query.c @@ -16,7 +16,6 @@ #include #include -#include "app.h" #include "connection.h" #include "draw_modal.h" #include "file_processor.h" @@ -25,6 +24,7 @@ #include "server.h" #include "types.h" #include "widget/app.h" +#include "widget_core/widget_core.h" static void wait_side(app_t *app); void user_request_description(query_args_t *q_args); @@ -45,8 +45,10 @@ void query_loop(app_t *app) { size_t qlen; int sr; static file_args_t file_args; - callback_args_t d_args = { - .app = app, .element = NULL, .data = NULL, .resp_data = NULL}; + callback_args_t d_args = {.app = app, + .element = NULL, + .data = NULL, + .resp_data.code = cbrc_none}; init_file_args(&file_args); query_args->sd = sd; diff --git a/src/widget/button.h b/src/widget/button.h index 57f88dc..aacb19d 100644 --- a/src/widget/button.h +++ b/src/widget/button.h @@ -1,7 +1,6 @@ #ifndef BUTTON_H #define BUTTON_H -#include "../main.h" #include #include diff --git a/src/widget/dialogue.c b/src/widget/dialogue.c index 92bacd2..63fae47 100644 --- a/src/widget/dialogue.c +++ b/src/widget/dialogue.c @@ -62,30 +62,28 @@ void dialogue_default_callback(callback_args_t *args) { dialogue_t *d = (void *)args->element; int32_t key = *((int32_t *)args->data); callback_args_t new_args; - new_args.active_el = d->active_el; - int32_t *resp_value = (int32_t *)args->resp_data; memcpy(&new_args, args, sizeof(callback_args_t)); - new_args.active_id = d->active_el->id; + new_args.active_el = d->active_el; int32_t diff; d->needs_update = true; input_t *input; widget_t *widget; - switch (key) { case '\t': incr_active_id(d); - *resp_value = -1; + args->resp_data.code = cbrc_none; break; case '\33': /* Esc key */ - *resp_value = -2; + args->resp_data.code = cbrp_val; + args->resp_data.val.val.num = -2; break; case KEY_RIGHT: incr_active_id(d); - *resp_value = -1; + args->resp_data.code = cbrc_none; break; case KEY_LEFT: decr_active_id(d); - *resp_value = -1; + args->resp_data.code = cbrc_none; break; case '\n': widget = (widget_t *)d->active_el->element; @@ -97,16 +95,19 @@ void dialogue_default_callback(callback_args_t *args) { if (d->active_el->g_type == g_action) { new_args.element = d->g_action; group_default_callback(&new_args); + mempcpy(&(args->resp_data), &(new_args.resp_data), sizeof(new_args.resp_data)); } else if (d->g_action != NULL) { for (int i = 0; i < d->g_action->count; i++) { if (d->g_action->elements[i].is_default) { - *resp_value = i; + args->resp_data.code = cbrp_val; + args->resp_data.val.val.num = i; return; } } } else { /* TODO: temp solution, improve */ - *resp_value = d->active_el->id - d->g_content->first_id; + args->resp_data.code = cbrp_val; + args->resp_data.val.val.num = d->active_el->idx; return; } break; @@ -167,7 +168,7 @@ void dialogue_init_active_id(dialogue_t *dialogue) { 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_el = &(dialogue->g_content->elements[i]); + dialogue->active_el = dialogue->g_content->elements + i; return; } } @@ -177,7 +178,7 @@ void dialogue_init_active_id(dialogue_t *dialogue) { 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_el = &(dialogue->g_action->elements[i]); + dialogue->active_el = dialogue->g_action->elements + i; return; } } diff --git a/src/widget/fs_file_list.c b/src/widget/fs_file_list.c index 5983045..c68924e 100644 --- a/src/widget/fs_file_list.c +++ b/src/widget/fs_file_list.c @@ -133,7 +133,7 @@ void fs_file_list_cb(callback_args_t *args) { } break; case '\n': - select_item(fui, (int32_t *) args->resp_data); + select_item(fui, (int32_t *) args->resp_data.val.val.num); break; } } diff --git a/src/widget/group.c b/src/widget/group.c index 5534d02..ba29455 100644 --- a/src/widget/group.c +++ b/src/widget/group.c @@ -12,26 +12,19 @@ #include #include -/* make response -1 */ -#define MAKE_RESPONSE_M1(args, resp_data, response) \ - if (args->resp_data != NULL) { \ - *response = -1; \ - } - -/* TODO: adapt to a new indexation method */ void group_default_callback(callback_args_t *args) { group_t *g = (group_t *)args->element; int32_t key = *((int32_t *)args->data); - int32_t *response = (int32_t *)args->resp_data; + int64_t response = args->resp_data.val.val.num; input_t *input; widget_t *widget; group_el_t *element_ptr = args->active_el; - int32_t element_idx = element_ptr->id - g->first_id; ; u_int32_t start_pos = 0; callback_args_t new_args; switch (key) { case '\n': /* Enter */ - *response = element_idx; + args->resp_data.code = cbrp_val; + mempcpy(&(args->resp_data.val), &(element_ptr->val), sizeof(struct val_t)); break; case KEY_BACKSPACE: case KEY_DL: @@ -47,7 +40,7 @@ void group_default_callback(callback_args_t *args) { } } } - MAKE_RESPONSE_M1(args, resp_data, response); + args->resp_data.code = cbrc_none; break; default: if (element_ptr->type == w_input) { @@ -64,6 +57,7 @@ void group_default_callback(callback_args_t *args) { } } } else { + /* callback case */ widget = (widget_t *)element_ptr->element; if (widget->callback != NULL) { memccpy(&new_args, args, 1, sizeof(callback_args_t)); @@ -72,7 +66,7 @@ void group_default_callback(callback_args_t *args) { break; } } - MAKE_RESPONSE_M1(args, resp_data, response); + args->resp_data.code = cbrc_none; break; } } @@ -104,6 +98,8 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, elements[i].type = children[i].type; elements[i].is_default = children[i].is_default; elements[i].g_type = g_type; + elements[i].idx = i; + elements[i].val.type = val_nul; } /* init child elements */ @@ -112,6 +108,8 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, switch (elements[i].type) { case w_button: elements[i].element = init_button(win, &(group->w), children[i].label); + elements[i].val.type = val_num; + elements[i].val.val.num = children[i].val.num; w = &(((button_t *)elements[i].element)->w); break; case w_box: diff --git a/src/widget/group.h b/src/widget/group.h index d3ea051..fb7cc40 100644 --- a/src/widget/group.h +++ b/src/widget/group.h @@ -5,21 +5,6 @@ #include #include -enum g_type { g_content, g_action }; - -enum g_direction { - horizontal, - vertical, -}; - -typedef struct { - uint32_t id; - void *element; - enum w_type type; - enum g_type g_type; - bool is_default; -} group_el_t; - typedef struct group_el_init_t { enum w_type type; bool is_default; @@ -27,6 +12,9 @@ typedef struct group_el_init_t { char label[DIALOGUE_TITLE]; uint32_t length; enum g_direction direction; + union { + int64_t num; + } val; struct group_el_init_t *children; } group_el_init_t; diff --git a/src/widget/input.h b/src/widget/input.h index 2409eec..54b2707 100644 --- a/src/widget/input.h +++ b/src/widget/input.h @@ -8,11 +8,11 @@ typedef struct { widget_t w; char value[INPUT_TEXT]; - uint32_t cur_pos; /* is relative to the end of a string */ - uint32_t value_len; - uint32_t max_len; - uint32_t is_disabled : 1; - uint32_t is_hidden : 1; + int64_t cur_pos; /* is relative to the end of a string */ + int64_t value_len; + int64_t max_len; + bool is_disabled; + bool is_hidden; } input_t; input_t *init_input(WINDOW **win, widget_t *w_parent, char *label, diff --git a/src/widget_core/widget_core.h b/src/widget_core/widget_core.h index 83473c9..d058c83 100644 --- a/src/widget_core/widget_core.h +++ b/src/widget_core/widget_core.h @@ -5,6 +5,13 @@ #include #include +enum g_type { g_content, g_action }; + +enum g_direction { + horizontal, + vertical, +}; + enum w_type { w_end, w_button, @@ -15,12 +22,45 @@ enum w_type { w_fs_file_list, }; +enum val_type { + val_num, + val_ptr, + val_nul, +}; + +struct val_t { + enum val_type type; + union { + void *ptr; + int64_t num; + } val; +}; + +typedef struct { + int64_t id; + int64_t idx; /* element index in the group */ + void *element; + enum w_type type; + enum g_type g_type; + bool is_default; + struct val_t val; +} group_el_t; + +enum cbrp_code { + cbrc_none, /* default */ + cbrp_val, + cbrp_g_el, /* element of type group_el_t */ + cbrp_err +}; + typedef struct { void *app; void *element; void *data; - void *resp_data; - uint32_t active_id; + struct { + enum cbrp_code code; + struct val_t val; + } resp_data; void *active_el; } callback_args_t; @@ -35,19 +75,18 @@ enum rsize { }; typedef struct widget_t { - uint32_t id; + int64_t id; char title[DIALOGUE_TITLE]; - uint32_t x; - uint32_t y; - uint32_t m_x; - uint32_t m_y; + int64_t x; + int64_t y; + int64_t m_x; + int64_t m_y; struct { - uint32_t y; - uint32_t x; + int64_t y; + int64_t x; } cur; WINDOW *const *parent_win; struct widget_t *w_parent; - // enum rsize rsize; void (*callback)(callback_args_t *args); } widget_t; @@ -60,7 +99,8 @@ enum pmt_attrs { void init_widget(widget_t *w, widget_t *w_parent, WINDOW **win, char *title); int32_t get_max_line_len(const char *text, uint32_t *line_count); -uint32_t print_multiline_text(WINDOW *win, const char *text, const uint32_t win_width, const uint32_t y, +uint32_t print_multiline_text(WINDOW *win, const char *text, + const uint32_t win_width, const uint32_t y, const uint32_t x, const uint16_t attrs); #endif \ No newline at end of file