From a2e6a25fc8cf8528e0ca2b8af8742584bc8ff38d Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Sat, 28 Jun 2014 18:40:22 -0400 Subject: [PATCH] make prompt window look like chat/groupchat windows (fixes various bugs, allows history scrolling) --- src/chat.c | 10 +-- src/friendlist.c | 1 + src/global_commands.c | 6 -- src/line_info.c | 5 +- src/prompt.c | 205 ++++++++++-------------------------------- src/prompt.h | 2 - src/toxic.c | 3 - src/windows.c | 9 +- src/windows.h | 5 +- 9 files changed, 53 insertions(+), 193 deletions(-) diff --git a/src/chat.c b/src/chat.c index 12cc635..02dd638 100644 --- a/src/chat.c +++ b/src/chat.c @@ -757,35 +757,29 @@ static void chat_onDraw(ToxWindow *self, Tox *m) /* Draw name, status and note in statusbar */ if (statusbar->is_online) { - const uint8_t *status_text = "Unknown"; int colour = WHITE; - uint8_t status = statusbar->status; switch (status) { case TOX_USERSTATUS_NONE: - status_text = "Online"; colour = GREEN; break; case TOX_USERSTATUS_AWAY: - status_text = "Away"; colour = YELLOW; break; case TOX_USERSTATUS_BUSY: - status_text = "Busy"; colour = RED; break; case TOX_USERSTATUS_INVALID: - status_text = "ERROR"; colour = MAGENTA; break; } wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); - wprintw(statusbar->topline, " [%s]", status_text); + wprintw(statusbar->topline, " O"); wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); if (friends[self->num].is_typing) @@ -798,7 +792,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m) if (friends[self->num].is_typing) wattroff(statusbar->topline, COLOR_PAIR(YELLOW)); } else { - wprintw(statusbar->topline, " [Offline]"); + wprintw(statusbar->topline, " o"); wattron(statusbar->topline, A_BOLD); wprintw(statusbar->topline, " %s ", self->name); wattroff(statusbar->topline, A_BOLD); diff --git a/src/friendlist.c b/src/friendlist.c index c2ed77d..4bb0268 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -597,6 +597,7 @@ ToxWindow new_friendlist(void) memset(&ret, 0, sizeof(ret)); ret.active = true; + ret.is_friendlist = true; ret.onKey = &friendlist_onKey; ret.onDraw = &friendlist_onDraw; diff --git a/src/global_commands.c b/src/global_commands.c index 984b668..9f2b895 100644 --- a/src/global_commands.c +++ b/src/global_commands.c @@ -196,12 +196,6 @@ void cmd_clear(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[M { line_info_clear(self->chatwin->hst); wclear(window); - - if (self->is_prompt) { - int y2, x2; - getmaxyx(window, y2, x2); - wmove(self->chatwin->history, y2 - 1, 2); - } } void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) diff --git a/src/line_info.c b/src/line_info.c index aecceb8..4946437 100644 --- a/src/line_info.c +++ b/src/line_info.c @@ -214,7 +214,7 @@ static void line_info_check_queue(ToxWindow *self) int offst = self->is_groupchat ? SIDEBAR_WIDTH : 0; /* offset width of groupchat sidebar */ int lines = 1 + line->newlines + (line->len / (x2 - offst)); - int max_y = self->is_prompt ? y2 : y2 - CHATBOX_HEIGHT; + int max_y = y2 - CHATBOX_HEIGHT; /* move line_start forward proportionate to the number of new lines */ if (y + lines - 1 >= max_y) { @@ -243,9 +243,6 @@ void line_info_print(ToxWindow *self) int y2, x2; getmaxyx(self->window, y2, x2); - if (self->is_prompt) - y2 = user_settings->history_size; /* temporary fix to make prompt scroll */ - if (x2 <= SIDEBAR_WIDTH) return; diff --git a/src/prompt.c b/src/prompt.c index f4d4126..d49cfe4 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -33,6 +33,7 @@ #include "log.h" #include "line_info.h" #include "settings.h" +#include "input.h" uint8_t pending_frnd_requests[MAX_FRIENDS_NUM][TOX_CLIENT_ID_SIZE] = {0}; uint8_t num_frnd_requests = 0; @@ -125,178 +126,65 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) ChatContext *ctx = self->chatwin; int x, y, y2, x2; - getyx(ctx->history, y, x); - getmaxyx(ctx->history, y2, x2); + getyx(self->window, y, x); + getmaxyx(self->window, y2, x2); - if (ltr) { - if (ctx->len < (MAX_STR_SIZE - 1)) { - add_char_to_buf(ctx, key); - } - } else { /* if (!ltr) */ + if (x2 <= 0) + return; - /* BACKSPACE key: Remove one character from line */ - if (key == 0x107 || key == 0x8 || key == 0x7f) { - if (ctx->pos > 0) { - del_char_buf_bck(ctx); - wmove(ctx->history, y, x - 1); /* not necessary but fixes a display glitch */ - } else { + if (ltr) { /* char is printable */ + input_new_char(self, key, x, y, x2, y2); + return; + } + + if (line_info_onKey(self, key)) + return; + + input_handle(self, key, x, y, x2, y2); + + if (key == '\t') { /* TAB key: auto-completes command */ + if (ctx->len > 1 && ctx->line[0] == '/') { + if (complete_line(ctx, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE) == -1) beep(); - } + } else { + beep(); } + } else if (key == '\n') { + rm_trailing_spaces_buf(ctx); - else if (key == KEY_DC) { /* DEL key: Remove character at pos */ - if (ctx->pos != ctx->len) { - del_char_buf_frnt(ctx); - } else { - beep(); - } - } + uint8_t line[MAX_STR_SIZE] = {0}; - else if (key == T_KEY_DISCARD) { /* CTRL-U: Delete entire line behind pos */ - if (ctx->pos > 0) { - wmove(ctx->history, ctx->orig_y, X_OFST); - wclrtobot(ctx->history); - discard_buf(ctx); - } else { - beep(); - } - } + if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) + memset(&line, 0, sizeof(line)); - else if (key == T_KEY_KILL) { /* CTRL-K: Delete entire line in front of pos */ - if (ctx->len != ctx->pos) - kill_buf(ctx); - else - beep(); - } + if (!string_is_empty(line)) + add_line_to_hist(ctx); - else if (key == KEY_HOME || key == T_KEY_C_A) { /* HOME/C-a key: Move cursor to start of line */ - if (ctx->pos != 0) - ctx->pos = 0; - } + line_info_add(self, NULL, NULL, NULL, line, PROMPT, 0, 0); + execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE); - else if (key == KEY_END || key == T_KEY_C_E) { /* END/C-e key: move cursor to end of line */ - if (ctx->pos != ctx->len) - ctx->pos = ctx->len; - } - - else if (key == KEY_LEFT) { - if (ctx->pos > 0) - --ctx->pos; - else - beep(); - } - - else if (key == KEY_RIGHT) { - if (ctx->pos < ctx->len) - ++ctx->pos; - else - beep(); - } - - else if (key == KEY_UP) { /* fetches previous item in history */ - wmove(ctx->history, ctx->orig_y, X_OFST); - fetch_hist_item(ctx, KEY_UP); - - /* adjust line y origin appropriately when window scrolls down */ - if (ctx->at_bottom && ctx->len >= x2 - X_OFST) { - int px2 = ctx->len >= x2 ? x2 : x2 - X_OFST; - int p_ofst = px2 != x2 ? 0 : X_OFST; - - if (px2 <= 0) - return; - - int k = ctx->orig_y + ((ctx->len + p_ofst) / px2); - - if (k >= y2) { - --ctx->orig_y; - } - } - } - - else if (key == KEY_DOWN) { /* fetches next item in history */ - wmove(ctx->history, ctx->orig_y, X_OFST); - fetch_hist_item(ctx, KEY_DOWN); - } - - else if (key == '\t') { /* TAB key: completes command */ - if (ctx->len > 1 && ctx->line[0] == '/') { - if (complete_line(ctx, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE) == -1) - beep(); - } else { - beep(); - } - } - - /* RETURN key: execute command */ - else if (key == '\n') { - rm_trailing_spaces_buf(ctx); - - wprintw(ctx->history, "\n"); - uint8_t line[MAX_STR_SIZE] = {0}; - - if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) - memset(&line, 0, sizeof(line)); - - if (!string_is_empty(line)) - add_line_to_hist(ctx); - - line_info_add(self, NULL, NULL, NULL, line, PROMPT, 0, 0); - execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE); - reset_buf(ctx); - } + wclear(ctx->linewin); + wmove(self->window, y2 - CURS_Y_OFFSET, 0); + reset_buf(ctx); } } static void prompt_onDraw(ToxWindow *self, Tox *m) { + int x2, y2; + getmaxyx(self->window, y2, x2); + ChatContext *ctx = self->chatwin; - int x, y, x2, y2; - getyx(ctx->history, y, x); - getmaxyx(ctx->history, y2, x2); + line_info_print(self); + wclear(ctx->linewin); curs_set(1); - scrollok(ctx->history, 1); - line_info_print(self); - - /* if len is >= screen width offset max x by X_OFST to account for prompt char */ - int px2 = ctx->len >= x2 ? x2 : x2 - X_OFST; - - if (px2 <= 0) - return; - - /* len offset to account for prompt char (0 if len is < width of screen) */ - int p_ofst = px2 != x2 ? 0 : X_OFST; - - if (ctx->len > 0) { - uint8_t line[MAX_STR_SIZE]; - - if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) - reset_buf(ctx); - else - mvwprintw(ctx->history, ctx->orig_y, X_OFST, line); - - int k = ctx->orig_y + ((ctx->len + p_ofst) / px2); - - ctx->at_bottom = k == y2 - 1; - bool botm = k == y2; - bool edge = (ctx->len + p_ofst) % px2 == 0; - - /* move point of line origin up when input scrolls screen down */ - if (edge && botm) - --ctx->orig_y; - - } else { /* Mark point of origin for new line */ - ctx->orig_y = y; - } - - wattron(ctx->history, COLOR_PAIR(GREEN)); - mvwprintw(ctx->history, ctx->orig_y, 0, "$ "); - wattroff(ctx->history, COLOR_PAIR(GREEN)); + if (ctx->len > 0) + mvwprintw(ctx->linewin, 1, 0, "%ls", &ctx->line[ctx->start]); StatusBar *statusbar = self->stb; - werase(statusbar->topline); mvwhline(statusbar->topline, 1, 0, ACS_HLINE, x2); wmove(statusbar->topline, 0, 0); @@ -343,10 +231,7 @@ static void prompt_onDraw(ToxWindow *self, Tox *m) if (statusbar->statusmsg[0]) wprintw(statusbar->topline, " - %s", statusbar->statusmsg); - /* put cursor back in correct spot */ - int y_m = ctx->orig_y + ((ctx->pos + p_ofst) / px2); - int x_m = (ctx->pos + X_OFST) % x2; - wmove(self->window, y_m, x_m); + mvwhline(ctx->linewin, 0, 0, ACS_HLINE, x2); } static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum , uint8_t status) @@ -453,14 +338,13 @@ void prompt_init_statusbar(ToxWindow *self, Tox *m) static void prompt_onInit(ToxWindow *self, Tox *m) { - ChatContext *ctx = self->chatwin; - curs_set(1); int y2, x2; getmaxyx(self->window, y2, x2); - ctx->history = subwin(self->window, y2, x2, 0, 0); - scrollok(ctx->history, 1); + ChatContext *ctx = self->chatwin; + ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, x2, 0, 0); + ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2 - CHATBOX_HEIGHT, 0); ctx->log = malloc(sizeof(struct chatlog)); ctx->hst = malloc(sizeof(struct history)); @@ -480,7 +364,8 @@ static void prompt_onInit(ToxWindow *self, Tox *m) } execute(ctx->history, self, m, "/help", GLOBAL_COMMAND_MODE); - wmove(ctx->history, y2 - 1, 2); + scrollok(ctx->history, 0); + wmove(self->window, y2 - CURS_Y_OFFSET, 0); } ToxWindow new_prompt(void) diff --git a/src/prompt.h b/src/prompt.h index 405a3ec..4bc19a9 100644 --- a/src/prompt.h +++ b/src/prompt.h @@ -26,8 +26,6 @@ #include "toxic.h" #include "windows.h" -#define X_OFST 2 /* offset to account for prompt char */ - #ifdef _SUPPORT_AUDIO #define AC_NUM_GLOB_COMMANDS 17 #else diff --git a/src/toxic.c b/src/toxic.c index b7c5e65..c6bf6f7 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -95,10 +95,7 @@ static void ignore_SIGINT(int sig) void exit_toxic_success(Tox *m) { store_data(m, DATA_FILE); - close_all_file_senders(m); - usleep(1000); - kill_all_windows(); log_disable(prompt->chatwin->log); line_info_cleanup(prompt->chatwin->hst); diff --git a/src/windows.c b/src/windows.c index d94db59..1a5f795 100644 --- a/src/windows.c +++ b/src/windows.c @@ -311,6 +311,7 @@ ToxWindow *init_windows(Tox *m) void on_window_resize(int sig) { + endwin(); refresh(); clear(); } @@ -390,10 +391,6 @@ void draw_active_window(Tox *m) draw_bar(); touchwin(a->window); -#ifndef WIN32 - wresize(a->window, LINES - 2, COLS); -#endif - a->onDraw(a, m); wrefresh(a->window); @@ -418,7 +415,7 @@ void draw_active_window(Tox *m) /* TODO verify if this works */ ltr = isprint(ch); -#endif +#endif /* HAVE_WIDECHAR */ if (!ltr && (ch == T_KEY_NEXT || ch == T_KEY_PREV)) { set_next_window((int) ch); @@ -438,7 +435,7 @@ void refresh_inactive_windows(void) for (i = 0; i < MAX_WINDOWS_NUM; ++i) { ToxWindow *a = &windows[i]; - if (a->active && a != active_window && (a->is_chat || a->is_groupchat)) + if (a->active && a != active_window && !a->is_friendlist) line_info_print(a); } } diff --git a/src/windows.h b/src/windows.h index 706f342..d07cbd3 100644 --- a/src/windows.h +++ b/src/windows.h @@ -127,6 +127,7 @@ struct ToxWindow { bool is_chat; bool is_groupchat; bool is_prompt; + bool is_friendlist; bool alert0; bool alert1; @@ -191,10 +192,6 @@ struct ChatContext { WINDOW *history; WINDOW *linewin; WINDOW *sidebar; - - /* specific for prompt */ - bool at_bottom; /* true if line end is at bottom of window */ - int orig_y; /* y axis point of line origin */ }; ToxWindow *init_windows(Tox *m);