summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheJackiMonster <thejackimonster@gmail.com>2022-08-03 23:47:05 +0200
committerTheJackiMonster <thejackimonster@gmail.com>2022-08-03 23:47:05 +0200
commitc1344f9692273f2e1bd5688adfb39bda33394a0b (patch)
tree5b98c1e38a9d0793d9c016cfa7fd9e36e5c3295b
parent0616015bc457d387dbaa86cd428f119d51511341 (diff)
Implemented dynamic layout with subwindows
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r--src/application.c16
-rw-r--r--src/application.h11
-rw-r--r--src/chat.c200
-rw-r--r--src/chat.h4
-rw-r--r--src/ui/account_create_dialog.c13
-rw-r--r--src/ui/account_create_dialog.h2
-rw-r--r--src/ui/accounts.c6
-rw-r--r--src/ui/accounts.h3
-rw-r--r--src/ui/chat_open_dialog.c13
-rw-r--r--src/ui/chat_open_dialog.h2
-rw-r--r--src/ui/chats.c6
-rw-r--r--src/ui/chats.h3
-rw-r--r--src/ui/members.c4
-rw-r--r--src/ui/members.h2
-rw-r--r--src/ui/messages.c47
-rw-r--r--src/ui/messages.h2
-rw-r--r--src/util.c20
-rw-r--r--src/util.h3
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
diff --git a/src/chat.c b/src/chat.c
index fac192e..b7ed4fa 100644
--- a/src/chat.c
+++ b/src/chat.c
@@ -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)
diff --git a/src/chat.h b/src/chat.h
index 8ce5f3e..5422e3b 100644
--- a/src/chat.h
+++ b/src/chat.h
@@ -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,
diff --git a/src/util.c b/src/util.c
index d32eb6e..6647fef 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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, " ");
}
diff --git a/src/util.h b/src/util.h
index 561f3ac..367eec9 100644
--- a/src/util.h
+++ b/src/util.h
@@ -31,6 +31,9 @@
#define UNUSED __attribute__((unused))
+#define UTIL_LOGO_ROWS 10
+#define UTIL_LOGO_COLS 28
+
void
util_print_logo(WINDOW *window);