From 9f4248b1e18821c4eb937a02420529ff4e46ca65 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Fri, 20 Jun 2014 23:08:13 -0400 Subject: [PATCH] redesign text input field to scroll horizontally, increase max string size --- src/chat.c | 70 ++++++++++++++++++++++++++++----------------- src/groupchat.c | 62 +++++++++++++++++++++++++-------------- src/misc_tools.c | 5 ++-- src/toxic.h | 2 +- src/toxic_strings.c | 4 ++- src/toxic_strings.h | 2 +- src/windows.h | 5 ++-- 7 files changed, 94 insertions(+), 56 deletions(-) diff --git a/src/chat.c b/src/chat.c index f64c8ae..f33dd55 100644 --- a/src/chat.c +++ b/src/chat.c @@ -547,17 +547,19 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) int x, y, y2, x2; getyx(self->window, y, x); getmaxyx(self->window, y2, x2); - int cur_len = 0; + int cur_len = 0; /* widechar len of current char */ + int len = MAX(0, wcslen(ctx->line)); /* widechar len of line */ - if (ltr) { - /* prevents buffer overflows and strange behaviour when cursor goes past the window */ - if ( (ctx->len < MAX_STR_SIZE - 1) && (ctx->len < (x2 * (CHATBOX_HEIGHT - 1) - 1)) ) { + if (ltr) { /* char is printable */ + if (ctx->len < MAX_STR_SIZE - 1) { add_char_to_buf(ctx, key); - if (x == x2 - 1) - wmove(self->window, y + 1, 0); - else + if (x >= x2 - 1) { + wmove(self->window, y, x2 / 2); + ctx->start += x2 / 2; + } else { wmove(self->window, y, x + MAX(1, wcwidth(key))); + } } if (!ctx->self_is_typing && ctx->line[0] != '/') @@ -569,13 +571,16 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) if (key == 0x107 || key == 0x8 || key == 0x7f) { /* BACKSPACE key */ if (ctx->pos > 0) { - cur_len = MAX(1, wcwidth(ctx->line[ctx->pos - 1])); + cur_len = MAX(1, wcwidth(ctx->line[ctx->pos])); del_char_buf_bck(ctx); - if (x == 0) - wmove(self->window, y - 1, x2 - cur_len); - else + if (x == 0) { + wmove(self->window, y, x2 - cur_len); + ctx->start = ctx->start >= x2 ? ctx->start - x2 : 0; + ctx->pos = ctx->start + x2 - 1; + } else { wmove(self->window, y, x - cur_len); + } } else { beep(); } @@ -607,6 +612,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) 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; + ctx->start = 0; wmove(self->window, y2 - CURS_Y_OFFSET, 0); } } @@ -614,7 +620,8 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) 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; - mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, (CHATBOX_HEIGHT - 1)*x2)), y2, x2); + ctx->start = x2 * (len / x2); + mv_curs_end(self->window, len, y2, x2); } } @@ -623,10 +630,13 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) --ctx->pos; cur_len = MAX(1, wcwidth(ctx->line[ctx->pos])); - if (x == 0) - wmove(self->window, y - 1, x2 - cur_len); - else + if (x == 0) { + wmove(self->window, y, x2 - cur_len); + ctx->start = ctx->start >= x2 ? ctx->start - x2 : 0; + ctx->pos = ctx->start + x2 - 1; + } else { wmove(self->window, y, x - cur_len); + } } else { beep(); } @@ -634,13 +644,16 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) else if (key == KEY_RIGHT) { if (ctx->pos < ctx->len) { - cur_len = MAX(1, wcwidth(ctx->line[ctx->pos])); ++ctx->pos; - if (x == x2 - 1) - wmove(self->window, y + 1, 0); - else + if (x == x2 - 1) { + wmove(self->window, y, 0); + ctx->start += x2; + ctx->pos = ctx->start; + } else { + cur_len = MAX(1, wcwidth(ctx->line[ctx->pos])); wmove(self->window, y, x + cur_len); + } } else { beep(); } @@ -648,12 +661,16 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) else if (key == KEY_UP) { /* fetches previous item in history */ fetch_hist_item(ctx, MOVE_UP); - mv_curs_end(self->window, ctx->len, y2, x2); + len = wcslen(ctx->line); + ctx->start = x2 * (len / x2); + mv_curs_end(self->window, len, y2, x2); } else if (key == KEY_DOWN) { /* fetches next item in history */ fetch_hist_item(ctx, MOVE_DOWN); - mv_curs_end(self->window, ctx->len, y2, x2); + len = wcslen(ctx->line); + ctx->start = x2 * (len / x2); + mv_curs_end(self->window, len, y2, x2); } else if (key == '\t') { /* TAB key: completes command */ @@ -662,8 +679,9 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) if (diff != -1) { if (x + diff > x2 - 1) { - int ofst = (x + diff - 1) - (x2 - 1); - wmove(self->window, y + 1, ofst); + //int ofst = x + diff - x2; + wmove(self->window, y, x + diff); + ctx->start += x2 / 2; } else { wmove(self->window, y, x + diff); } @@ -739,16 +757,15 @@ static void chat_onDraw(ToxWindow *self, Tox *m) wclear(ctx->linewin); curs_set(1); - scrollok(ctx->history, 0); - if (ctx->len> 0) { + 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); wmove(self->window, y2 - CURS_Y_OFFSET, 0); } else { - mvwprintw(ctx->linewin, 1, 0, "%s", line); + mvwprintw(ctx->linewin, 1, 0, "%s", &line[ctx->start]); } } @@ -888,6 +905,7 @@ static void chat_onInit(ToxWindow *self, Tox *m) execute(ctx->history, self, m, "/help", CHAT_COMMAND_MODE); execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE); + scrollok(ctx->history, 0); wmove(self->window, y2 - CURS_Y_OFFSET, 0); } diff --git a/src/groupchat.c b/src/groupchat.c index 20fb848..f1f5335 100644 --- a/src/groupchat.c +++ b/src/groupchat.c @@ -389,16 +389,19 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) int x, y, y2, x2; getyx(self->window, y, x); getmaxyx(self->window, y2, x2); - int cur_len = 0; + int cur_len = 0; /* widechar len of current char */ + int len = MAX(0, wcslen(ctx->line)); /* widechar len of line */ - if (ltr) { - if ( (ctx->len < MAX_STR_SIZE - 1) && (ctx->len < (x2 * (CHATBOX_HEIGHT - 1) - 1)) ) { + if (ltr) { /* char is printable */ + if (ctx->len < MAX_STR_SIZE - 1) { add_char_to_buf(ctx, key); - if (x == x2 - 1) - wmove(self->window, y + 1, 0); - else + if (x >= x2 - 1) { + wmove(self->window, y, x2 / 2); + ctx->start += x2 / 2; + } else { wmove(self->window, y, x + MAX(1, wcwidth(key))); + } } } else { /* if (!ltr) */ @@ -406,15 +409,18 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) if (line_info_onKey(self, key)) return; - if (key == 0x107 || key == 0x8 || key == 0x7f) { /* BACKSPACE key: Remove character behind pos */ + if (key == 0x107 || key == 0x8 || key == 0x7f) { /* BACKSPACE key */ if (ctx->pos > 0) { - cur_len = MAX(1, wcwidth(ctx->line[ctx->pos - 1])); + cur_len = MAX(1, wcwidth(ctx->line[ctx->pos])); del_char_buf_bck(ctx); - if (x == 0) - wmove(self->window, y - 1, x2 - cur_len); - else + if (x == 0) { + wmove(self->window, y, x2 - cur_len); + ctx->start = ctx->start >= x2 ? ctx->start - x2 : 0; + ctx->pos = ctx->start + x2 - 1; + } else { wmove(self->window, y, x - cur_len); + } } else { beep(); } @@ -446,6 +452,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) 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; + ctx->start = 0; wmove(self->window, y2 - CURS_Y_OFFSET, 0); } } @@ -453,7 +460,8 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) 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; - mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, (CHATBOX_HEIGHT - 1)*x2)), y2, x2); + ctx->start = x2 * (len / x2); + mv_curs_end(self->window, len, y2, x2); } } @@ -462,10 +470,13 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) --ctx->pos; cur_len = MAX(1, wcwidth(ctx->line[ctx->pos])); - if (x == 0) - wmove(self->window, y - 1, x2 - cur_len); - else + if (x == 0) { + wmove(self->window, y, x2 - cur_len); + ctx->start = ctx->start >= x2 ? ctx->start - x2 : 0; + ctx->pos = ctx->start + x2 - 1; + } else { wmove(self->window, y, x - cur_len); + } } else { beep(); } @@ -473,13 +484,16 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) else if (key == KEY_RIGHT) { if (ctx->pos < ctx->len) { - cur_len = MAX(1, wcwidth(ctx->line[ctx->pos])); ++ctx->pos; - if (x == x2 - 1) - wmove(self->window, y + 1, 0); - else + if (x == x2 - 1) { + wmove(self->window, y, 0); + ctx->start += x2; + ctx->pos = ctx->start; + } else { + cur_len = MAX(1, wcwidth(ctx->line[ctx->pos])); wmove(self->window, y, x + cur_len); + } } else { beep(); } @@ -487,12 +501,16 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) else if (key == KEY_UP) { /* fetches previous item in history */ fetch_hist_item(ctx, MOVE_UP); - mv_curs_end(self->window, ctx->len, y2, x2); + len = wcslen(ctx->line); + ctx->start = x2 * (len / x2); + mv_curs_end(self->window, len, y2, x2); } else if (key == KEY_DOWN) { /* fetches next item in history */ fetch_hist_item(ctx, MOVE_DOWN); - mv_curs_end(self->window, ctx->len, y2, x2); + len = wcslen(ctx->line); + ctx->start = x2 * (len / x2); + mv_curs_end(self->window, len, y2, x2); } else if (key == '\t') { /* TAB key: completes peer name */ @@ -597,7 +615,7 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m) reset_buf(ctx); wmove(self->window, y2 - CURS_Y_OFFSET, 0); } else { - mvwprintw(ctx->linewin, 1, 0, "%s", line); + mvwprintw(ctx->linewin, 1, 0, "%s", &line[ctx->start]); } } diff --git a/src/misc_tools.c b/src/misc_tools.c index 5350ccf..15641b1 100644 --- a/src/misc_tools.c +++ b/src/misc_tools.c @@ -226,9 +226,8 @@ int valid_nick(uint8_t *nick) /* Moves cursor to the end of the line in given window */ void mv_curs_end(WINDOW *w, size_t len, int max_y, int max_x) { - int end_y = (len / max_x) + (max_y - CURS_Y_OFFSET); - int end_x = len % max_x; - wmove(w, end_y, end_x); + int new_x = len < max_x ? len : len % max_x; + wmove(w, max_y - CURS_Y_OFFSET, new_x); } /* gets base file name from path or original file name if no path is supplied */ diff --git a/src/toxic.h b/src/toxic.h index df0a0fa..1a78e64 100644 --- a/src/toxic.h +++ b/src/toxic.h @@ -35,7 +35,7 @@ #define UNKNOWN_NAME "Anonymous" #define MAX_FRIENDS_NUM 500 -#define MAX_STR_SIZE 256 +#define MAX_STR_SIZE 1024 #define MAX_CMDNAME_SIZE 64 #define TOXIC_MAX_NAME_LENGTH 32 /* Must be <= TOX_MAX_NAME_LENGTH */ #define KEY_IDENT_DIGITS 2 /* number of hex digits to display for the pub-key based identifier */ diff --git a/src/toxic_strings.c b/src/toxic_strings.c index 388f9b7..d78af0e 100644 --- a/src/toxic_strings.c +++ b/src/toxic_strings.c @@ -91,6 +91,7 @@ void discard_buf(ChatContext *ctx) ctx->line[c++] = ctx->line[i]; ctx->pos = 0; + ctx->start = 0; ctx->len = c - 1; } @@ -104,12 +105,13 @@ void kill_buf(ChatContext *ctx) ctx->len = ctx->pos; } -/* nulls line and sets pos and len to 0 */ +/* nulls line and sets pos, len and start to 0 */ void reset_buf(ChatContext *ctx) { ctx->line[0] = L'\0'; ctx->pos = 0; ctx->len = 0; + ctx->start = 0; } /* Removes trailing spaces from line. */ diff --git a/src/toxic_strings.h b/src/toxic_strings.h index b792532..8c7e12a 100644 --- a/src/toxic_strings.h +++ b/src/toxic_strings.h @@ -40,7 +40,7 @@ void discard_buf(ChatContext *ctx); /* Deletes the line from pos to len */ void kill_buf(ChatContext *ctx); -/* nulls line and sets pos and len to 0 */ +/* nulls line and sets pos, len and start to 0 */ void reset_buf(ChatContext *ctx); /* Removes trailing spaces from line. */ diff --git a/src/windows.h b/src/windows.h index 3c6f57d..551af40 100644 --- a/src/windows.h +++ b/src/windows.h @@ -36,8 +36,8 @@ #include "toxic.h" #define MAX_WINDOWS_NUM 32 -#define CURS_Y_OFFSET 3 /* y-axis cursor offset for chat contexts */ -#define CHATBOX_HEIGHT 4 +#define CURS_Y_OFFSET 1 /* y-axis cursor offset for chat contexts */ +#define CHATBOX_HEIGHT 2 /* Curses foreground colours (background is black) */ enum { @@ -150,6 +150,7 @@ struct ChatContext { wchar_t line[MAX_STR_SIZE]; size_t pos; size_t len; + size_t start; /* the position to start printing line at */ wchar_t ln_history[MAX_LINE_HIST][MAX_STR_SIZE]; /* history for input lines/commands */ int hst_pos;