diff options
author | TheJackiMonster <thejackimonster@gmail.com> | 2022-08-03 23:47:05 +0200 |
---|---|---|
committer | TheJackiMonster <thejackimonster@gmail.com> | 2022-08-03 23:47:05 +0200 |
commit | c1344f9692273f2e1bd5688adfb39bda33394a0b (patch) | |
tree | 5b98c1e38a9d0793d9c016cfa7fd9e36e5c3295b | |
parent | 0616015bc457d387dbaa86cd428f119d51511341 (diff) |
Implemented dynamic layout with subwindows
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r-- | src/application.c | 16 | ||||
-rw-r--r-- | src/application.h | 11 | ||||
-rw-r--r-- | src/chat.c | 200 | ||||
-rw-r--r-- | src/chat.h | 4 | ||||
-rw-r--r-- | src/ui/account_create_dialog.c | 13 | ||||
-rw-r--r-- | src/ui/account_create_dialog.h | 2 | ||||
-rw-r--r-- | src/ui/accounts.c | 6 | ||||
-rw-r--r-- | src/ui/accounts.h | 3 | ||||
-rw-r--r-- | src/ui/chat_open_dialog.c | 13 | ||||
-rw-r--r-- | src/ui/chat_open_dialog.h | 2 | ||||
-rw-r--r-- | src/ui/chats.c | 6 | ||||
-rw-r--r-- | src/ui/chats.h | 3 | ||||
-rw-r--r-- | src/ui/members.c | 4 | ||||
-rw-r--r-- | src/ui/members.h | 2 | ||||
-rw-r--r-- | src/ui/messages.c | 47 | ||||
-rw-r--r-- | src/ui/messages.h | 2 | ||||
-rw-r--r-- | src/util.c | 20 | ||||
-rw-r--r-- | src/util.h | 3 |
18 files changed, 297 insertions, 60 deletions
diff --git a/src/application.c b/src/application.c index 65bdd81..d8314df 100644 --- a/src/application.c +++ b/src/application.c @@ -51,12 +51,28 @@ application_init(MESSENGER_Application *app, return; } + application_refresh(app); + noecho(); keypad(app->window, TRUE); wtimeout(app->window, 10); } +void +application_refresh(MESSENGER_Application *app) +{ + if (app->ui.logo) delwin(app->ui.logo); + if (app->ui.main) delwin(app->ui.main); + if (app->ui.left) delwin(app->ui.left); + if (app->ui.right) delwin(app->ui.right); + if (app->ui.input) delwin(app->ui.input); + + memset(&(app->ui), 0, sizeof(app->ui)); + + curs_set(0); +} + static void run (void *cls, UNUSED char* const* args, diff --git a/src/application.h b/src/application.h index 1ad0c11..75bf336 100644 --- a/src/application.h +++ b/src/application.h @@ -43,6 +43,14 @@ typedef struct MESSENGER_Application int status; WINDOW *window; + struct { + WINDOW *logo; + WINDOW *main; + WINDOW *left; + WINDOW *right; + WINDOW *input; + } ui; + MESSENGER_Chat chat; UI_ACCOUNTS_Handle accounts; @@ -59,6 +67,9 @@ application_init(MESSENGER_Application *app, char **argv); void +application_refresh(MESSENGER_Application *app); + +void application_run(MESSENGER_Application *app); int @@ -25,32 +25,26 @@ #include "chat.h" #include "application.h" +#include "util.h" static void _chat_refresh(MESSENGER_Application *app) { - const struct GNUNET_CHAT_Account *account = GNUNET_CHAT_get_connected( - app->chat.handle - ); - application_clear(app); - - if (!account) - app->accounts.window = app->window; - else if (app->chat.context) - { - if (app->chat.show_members) - app->current.members.window = app->window; - else - app->current.messages.window = app->window; - } - else - app->chats.window = app->window; + chat_update_layout(&(app->chat), app); accounts_print(&(app->accounts), app); chats_print(&(app->chats), app); members_print(&(app->current.members)); messages_print(&(app->current.messages)); + + if (!app->ui.logo) + return; + + werase(app->ui.logo); + wmove(app->ui.logo, 0, 0); + + util_print_logo(app->ui.logo); } static bool @@ -160,6 +154,180 @@ chat_stop(MESSENGER_Chat *chat) } void +_chat_update_layout_accounts(struct MESSENGER_Application *app) +{ + int rows, cols; + getmaxyx(app->window, rows, cols); + + if (rows >= UTIL_LOGO_ROWS + UI_ACCOUNTS_ROWS_MIN) + { + const int offset = UTIL_LOGO_ROWS + 1; + + app->ui.logo = subwin(app->window, UTIL_LOGO_ROWS, cols, 0, 0); + app->ui.main = subwin(app->window, rows - offset, cols, offset, 0); + + wmove(app->window, UTIL_LOGO_ROWS, 0); + whline(app->window, ACS_HLINE, cols); + } + else + app->ui.main = subwin(app->window, rows, cols, 0, 0); + + app->accounts.window = app->ui.main; +} + +void +_chat_update_layout_chats(struct MESSENGER_Application *app) +{ + int rows, cols; + getmaxyx(app->window, rows, cols); + + int min_rows = UI_CHATS_ROWS_MIN; + int offset_x = 0; + int offset_y = 0; + + if (cols >= UI_ACCOUNTS_COLS_MIN + UI_CHATS_COLS_MIN) + { + offset_x = UI_ACCOUNTS_COLS_MIN + 1; + + if (UI_ACCOUNTS_ROWS_MIN > min_rows) min_rows = UI_ACCOUNTS_ROWS_MIN; + } + + if (rows >= UTIL_LOGO_ROWS + min_rows) + { + offset_y = UTIL_LOGO_ROWS + 1; + + app->ui.logo = subwin(app->window, UTIL_LOGO_ROWS, cols, 0, 0); + + wmove(app->window, UTIL_LOGO_ROWS, 0); + whline(app->window, ACS_HLINE, cols); + } + + if (offset_x > 0) + { + app->ui.left = subwin( + app->window, + rows - offset_y, + UI_ACCOUNTS_COLS_MIN, + offset_y, + 0 + ); + + wmove(app->window, offset_y > 0? offset_y : 0, UI_ACCOUNTS_COLS_MIN); + wvline(app->window, ACS_VLINE, rows - offset_y); + + if (offset_y > 0) + { + wmove(app->window, offset_y - 1, UI_ACCOUNTS_COLS_MIN); + waddch(app->window, ACS_TTEE); + } + } + + app->ui.main = subwin( + app->window, + rows - offset_y, + cols - offset_x, + offset_y, + offset_x + ); + + app->accounts.window = app->ui.left; + app->chats.window = app->ui.main; +} + +void +_chat_update_layout_messages(struct MESSENGER_Application *app) +{ + int rows, cols; + getmaxyx(app->window, rows, cols); + + const int cols_min_left = (UTIL_LOGO_COLS > UI_CHATS_COLS_MIN? + UTIL_LOGO_COLS : UI_CHATS_COLS_MIN + ); + + int offset_x = 0; + + if (cols >= cols_min_left + UI_MESSAGES_COLS_MIN) + offset_x = cols_min_left + 1; + else + goto skip_left_split; + + if (rows >= UTIL_LOGO_ROWS + UI_CHATS_ROWS_MIN) + { + const int offset = UTIL_LOGO_ROWS + 1; + + app->ui.logo = subwin(app->window, UTIL_LOGO_ROWS, cols_min_left, 0, 0); + app->ui.left = subwin(app->window, rows - offset, cols_min_left, offset, 0); + + wmove(app->window, UTIL_LOGO_ROWS, 0); + whline(app->window, ACS_HLINE, cols_min_left); + } + else + app->ui.left = subwin(app->window, rows, cols_min_left, 0, 0); + + int cut_x = 0; + + if (cols >= cols_min_left + UI_MESSAGES_COLS_MIN + UI_MEMBERS_COLS_MIN) + { + cut_x = UI_MEMBERS_COLS_MIN + 1; + + app->ui.right = subwin( + app->window, + rows, + UI_MEMBERS_COLS_MIN, + 0, + cols - UI_MEMBERS_COLS_MIN + ); + + wmove(app->window, 0, cols - cut_x); + wvline(app->window, ACS_VLINE, rows); + } + + wmove(app->window, 0, cols_min_left); + wvline(app->window, ACS_VLINE, rows); + +skip_left_split: + app->ui.main = subwin( + app->window, + rows, + cols - offset_x - cut_x, + 0, + offset_x + ); + + app->chats.window = app->ui.left; + + if (app->ui.right) + { + app->current.members.window = app->ui.right; + app->current.messages.window = app->ui.main; + return; + } + + if (app->chat.show_members) + app->current.members.window = app->ui.main; + else + app->current.messages.window = app->ui.main; +} + +void +chat_update_layout(MESSENGER_Chat *chat, + struct MESSENGER_Application *app) +{ + const struct GNUNET_CHAT_Account *account = GNUNET_CHAT_get_connected( + chat->handle + ); + + application_refresh(app); + + if (!account) + _chat_update_layout_accounts(app); + else if (app->chat.context) + _chat_update_layout_messages(app); + else + _chat_update_layout_chats(app); +} + +void chat_process_message(UNUSED MESSENGER_Chat *chat, struct GNUNET_CHAT_Context *context, const struct GNUNET_CHAT_Message *message) @@ -51,6 +51,10 @@ void chat_stop(MESSENGER_Chat *chat); void +chat_update_layout(MESSENGER_Chat *chat, + struct MESSENGER_Application *app); + +void chat_process_message(MESSENGER_Chat *chat, struct GNUNET_CHAT_Context *context, const struct GNUNET_CHAT_Message *message); diff --git a/src/ui/account_create_dialog.c b/src/ui/account_create_dialog.c index b283092..5472bc7 100644 --- a/src/ui/account_create_dialog.c +++ b/src/ui/account_create_dialog.c @@ -114,9 +114,14 @@ account_create_dialog_print(UI_ACCOUNT_CREATE_DIALOG_Handle *create_dialog, if (!(create_dialog->window)) return; - werase(create_dialog->window); - wmove(create_dialog->window, 0, 0); + WINDOW *window = *(create_dialog->window); - wprintw(create_dialog->window, "%s", create_dialog->name); - wmove(create_dialog->window, 0, create_dialog->name_pos); + werase(window); + wmove(window, 0, 0); + + wprintw(window, "%s", create_dialog->name); + wmove(window, 0, create_dialog->name_pos); + + wcursyncup(window); + curs_set(1); } diff --git a/src/ui/account_create_dialog.h b/src/ui/account_create_dialog.h index 69dbb1c..d42fef2 100644 --- a/src/ui/account_create_dialog.h +++ b/src/ui/account_create_dialog.h @@ -32,7 +32,7 @@ struct MESSENGER_Application; typedef struct UI_ACCOUNT_CREATE_DIALOG_Handle { - WINDOW *window; + WINDOW **window; char name [256]; int name_len; diff --git a/src/ui/accounts.c b/src/ui/accounts.c index ced1d68..4936c82 100644 --- a/src/ui/accounts.c +++ b/src/ui/accounts.c @@ -88,7 +88,7 @@ accounts_event(UI_ACCOUNTS_Handle *accounts, if (accounts->selected) GNUNET_CHAT_connect(app->chat.handle, accounts->selected); else - accounts->create_dialog.window = accounts->window; + accounts->create_dialog.window = &(accounts->window); break; } default: @@ -103,7 +103,7 @@ accounts_event(UI_ACCOUNTS_Handle *accounts, if (!(accounts->window)) return; - const int height = getmaxy(accounts->window) - getbegy(accounts->window); + const int height = getmaxy(accounts->window); const int y = accounts->line_selected - accounts->line_offset; if (y < 0) @@ -130,7 +130,7 @@ _accounts_print_entry(UI_ACCOUNTS_Handle *accounts, if (y < 0) return GNUNET_YES; - const int height = getmaxy(accounts->window) - getbegy(accounts->window); + const int height = getmaxy(accounts->window); if (y >= height) return GNUNET_NO; diff --git a/src/ui/accounts.h b/src/ui/accounts.h index 2ca55b5..fe0e1b1 100644 --- a/src/ui/accounts.h +++ b/src/ui/accounts.h @@ -49,6 +49,9 @@ typedef struct UI_ACCOUNTS_Handle UI_ACCOUNT_CREATE_DIALOG_Handle create_dialog; } UI_ACCOUNTS_Handle; +#define UI_ACCOUNTS_ROWS_MIN 5 +#define UI_ACCOUNTS_COLS_MIN 30 + void accounts_event(UI_ACCOUNTS_Handle *accounts, struct MESSENGER_Application *app, diff --git a/src/ui/chat_open_dialog.c b/src/ui/chat_open_dialog.c index 180d7be..701b8e5 100644 --- a/src/ui/chat_open_dialog.c +++ b/src/ui/chat_open_dialog.c @@ -114,9 +114,14 @@ chat_open_dialog_print(UI_CHAT_OPEN_DIALOG_Handle *open_dialog, if (!(open_dialog->window)) return; - werase(open_dialog->window); - wmove(open_dialog->window, 0, 0); + WINDOW *window = *(open_dialog->window); - wprintw(open_dialog->window, "%s", open_dialog->topic); - wmove(open_dialog->window, 0, open_dialog->topic_pos); + werase(window); + wmove(window, 0, 0); + + wprintw(window, "%s", open_dialog->topic); + wmove(window, 0, open_dialog->topic_pos); + + wcursyncup(window); + curs_set(1); } diff --git a/src/ui/chat_open_dialog.h b/src/ui/chat_open_dialog.h index 2adf465..0367abc 100644 --- a/src/ui/chat_open_dialog.h +++ b/src/ui/chat_open_dialog.h @@ -32,7 +32,7 @@ struct MESSENGER_Application; typedef struct UI_CHAT_OPEN_DIALOG_Handle { - WINDOW *window; + WINDOW **window; char topic [256]; int topic_len; diff --git a/src/ui/chats.c b/src/ui/chats.c index f727a37..ddeb5d4 100644 --- a/src/ui/chats.c +++ b/src/ui/chats.c @@ -141,7 +141,7 @@ chats_event(UI_CHATS_Handle *chats, app->chat.context = chats->selected; } else - chats->open_dialog.window = chats->window; + chats->open_dialog.window = &(chats->window); break; } default: @@ -156,7 +156,7 @@ chats_event(UI_CHATS_Handle *chats, if (!(chats->window)) return; - const int height = getmaxy(chats->window) - getbegy(chats->window); + const int height = getmaxy(chats->window); const int y = chats->line_selected - chats->line_offset; if (y < 0) @@ -184,7 +184,7 @@ _chats_print_entry(UI_CHATS_Handle *chats, if (y < 0) return GNUNET_YES; - const int height = getmaxy(chats->window) - getbegy(chats->window); + const int height = getmaxy(chats->window); if (y >= height) return GNUNET_NO; diff --git a/src/ui/chats.h b/src/ui/chats.h index 85a84eb..339cb9c 100644 --- a/src/ui/chats.h +++ b/src/ui/chats.h @@ -49,6 +49,9 @@ typedef struct UI_CHATS_Handle UI_CHAT_OPEN_DIALOG_Handle open_dialog; } UI_CHATS_Handle; +#define UI_CHATS_ROWS_MIN 8 +#define UI_CHATS_COLS_MIN 30 + void chats_event(UI_CHATS_Handle *chats, struct MESSENGER_Application *app, diff --git a/src/ui/members.c b/src/ui/members.c index 710c0d6..509e03b 100644 --- a/src/ui/members.c +++ b/src/ui/members.c @@ -86,7 +86,7 @@ members_event(UI_MEMBERS_Handle *members, if (!(members->window)) return; - const int height = getmaxy(members->window) - getbegy(members->window); + const int height = getmaxy(members->window); const int y = members->line_selected - members->line_offset; if (y < 0) @@ -112,7 +112,7 @@ _members_iterate_print(UI_MEMBERS_Handle *members, if (y < 0) return; - const int height = getmaxy(members->window) - getbegy(members->window); + const int height = getmaxy(members->window); if (y >= height) return; diff --git a/src/ui/members.h b/src/ui/members.h index 4f7c50d..8e70ca4 100644 --- a/src/ui/members.h +++ b/src/ui/members.h @@ -56,6 +56,8 @@ typedef struct UI_MEMBERS_Handle const struct GNUNET_CHAT_Contact *selected; } UI_MEMBERS_Handle; +#define UI_MEMBERS_COLS_MIN 30 + void members_event(UI_MEMBERS_Handle *members, struct MESSENGER_Application *app, diff --git a/src/ui/messages.c b/src/ui/messages.c index 9b0a692..26df838 100644 --- a/src/ui/messages.c +++ b/src/ui/messages.c @@ -158,7 +158,7 @@ messages_event(UI_MESSAGES_Handle *messages, if (!(messages->window)) return; - const int height = getmaxy(messages->window) - getbegy(messages->window); + const int height = getmaxy(messages->window); const int y = messages->line_selected - messages->line_offset; const int line_height = height - 2; @@ -188,7 +188,7 @@ _messages_iterate_print(UI_MESSAGES_Handle *messages, if (y < 0) return; - const int height = getmaxy(messages->window) - getbegy(messages->window); + const int height = getmaxy(messages->window); const int line_height = height - 2; if (y >= line_height) @@ -199,38 +199,49 @@ _messages_iterate_print(UI_MESSAGES_Handle *messages, const char *name = sender? GNUNET_CHAT_contact_get_name(sender) : NULL; const char *text = GNUNET_CHAT_message_get_text(message); - struct GNUNET_TIME_Absolute timestamp = GNUNET_CHAT_message_get_timestamp( + struct GNUNET_TIME_Absolute abs_time = GNUNET_CHAT_message_get_timestamp( message ); + struct GNUNET_TIME_Timestamp timestamp = GNUNET_TIME_absolute_to_timestamp( + abs_time + ); + + const time_t s_after_epoch = ( + GNUNET_TIME_timestamp_to_s(timestamp) + ); + + struct tm* ts = localtime(&s_after_epoch); + char time_buf [255]; + + strftime(time_buf, sizeof(time_buf), "%H:%M", ts); + const int attrs_select = A_BOLD; if (selected) wattron(messages->window, attrs_select); wmove(messages->window, y, 0); + wprintw(messages->window, "%s | ", time_buf); switch (kind) { case GNUNET_CHAT_KIND_JOIN: wprintw( messages->window, - "%s | %s joins the room.", - GNUNET_TIME_absolute2s(timestamp), + "%s joins the room.", name ); break; case GNUNET_CHAT_KIND_LEAVE: wprintw( messages->window, - "%s | %s leaves the room.", - GNUNET_TIME_absolute2s(timestamp), + "%s leaves the room.", name ); break; case GNUNET_CHAT_KIND_INVITATION: wprintw( messages->window, - "%s | %s invites you to a room.", - GNUNET_TIME_absolute2s(timestamp), + "%s invites you to a room.", name ); break; @@ -238,8 +249,7 @@ _messages_iterate_print(UI_MESSAGES_Handle *messages, case GNUNET_CHAT_KIND_FILE: wprintw( messages->window, - "%s | %s: %s", - GNUNET_TIME_absolute2s(timestamp), + "%s: %s", name, text ); @@ -247,8 +257,7 @@ _messages_iterate_print(UI_MESSAGES_Handle *messages, default: wprintw( messages->window, - "%s | [%d] %s: %s", - GNUNET_TIME_absolute2s(timestamp), + "[%d] %s: %s", (int) kind, name, text @@ -282,8 +291,8 @@ messages_print(UI_MESSAGES_Handle *messages) const bool selected = (count == messages->line_selected); - const int width = getmaxx(messages->window) - getbegx(messages->window); - const int height = getmaxy(messages->window) - getbegy(messages->window); + const int width = getmaxx(messages->window); + const int height = getmaxy(messages->window); const int line_height = height - 2; wmove(messages->window, line_height, 0); @@ -299,6 +308,12 @@ messages_print(UI_MESSAGES_Handle *messages) if (selected) wattroff(messages->window, attrs_select); wmove(messages->window, height - 1, messages->text_pos); + + if (selected) + { + wcursyncup(messages->window); + curs_set(1); + } } void @@ -355,7 +370,7 @@ messages_add(UI_MESSAGES_Handle *messages, break; } - const int height = getmaxy(messages->window) - getbegy(messages->window); + const int height = getmaxy(messages->window); const int line_height = height - 2; int count = 0; diff --git a/src/ui/messages.h b/src/ui/messages.h index 06de97f..166941a 100644 --- a/src/ui/messages.h +++ b/src/ui/messages.h @@ -62,6 +62,8 @@ typedef struct UI_MESSAGES_Handle int text_pos; } UI_MESSAGES_Handle; +#define UI_MESSAGES_COLS_MIN 50 + void messages_event(UI_MESSAGES_Handle *messages, struct MESSENGER_Application *app, @@ -30,14 +30,14 @@ util_print_logo(WINDOW *window) int x = getcurx(window); int y = getcury(window); - wmove(window, x, y++); wprintw(window, " "); - wmove(window, x, y++); wprintw(window, " o/ \\o "); - wmove(window, x, y++); wprintw(window, " ooo oo "); - wmove(window, x, y++); wprintw(window, " \\oooo\\ /oooo/ "); - wmove(window, x, y++); wprintw(window, " oo ooo "); - wmove(window, x, y++); wprintw(window, " oo ooo "); - wmove(window, x, y++); wprintw(window, " ooooooo "); - wmove(window, x, y++); wprintw(window, " \\oooo/ "); - wmove(window, x, y++); wprintw(window, " oooo "); - wmove(window, x, y++); wprintw(window, " "); + wmove(window, y++, x); wprintw(window, " "); + wmove(window, y++, x); wprintw(window, " o/ \\o "); + wmove(window, y++, x); wprintw(window, " ooo oo "); + wmove(window, y++, x); wprintw(window, " \\oooo\\ /oooo/ "); + wmove(window, y++, x); wprintw(window, " oo ooo "); + wmove(window, y++, x); wprintw(window, " oo ooo "); + wmove(window, y++, x); wprintw(window, " ooooooo "); + wmove(window, y++, x); wprintw(window, " \\oooo/ "); + wmove(window, y++, x); wprintw(window, " oooo "); + wmove(window, y++, x); wprintw(window, " "); } @@ -31,6 +31,9 @@ #define UNUSED __attribute__((unused)) +#define UTIL_LOGO_ROWS 10 +#define UTIL_LOGO_COLS 28 + void util_print_logo(WINDOW *window); |