1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-06-26 20:37:46 +02:00

allow line editing via arrow keys in chat/groupchat windows

This commit is contained in:
Jfreegman 2013-11-30 22:12:43 -05:00
parent c25296e65a
commit bb6b28b7c3
5 changed files with 135 additions and 24 deletions

View File

@ -283,13 +283,27 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
/* BACKSPACE key: Remove one character from line */ /* BACKSPACE key: Remove one character from line */
if (key == 0x107 || key == 0x8 || key == 0x7f) { if (key == 0x107 || key == 0x8 || key == 0x7f) {
if (ctx->pos > 0) { if (ctx->pos > 0) {
ctx->line[--ctx->pos] = L'\0'; del_char_from_buf(key, ctx->line, &ctx->pos, &ctx->len);
if (x == 0) if (x == 0)
mvwdelch(self->window, y - 1, x2 - 1); wmove(self->window, y-1, x2-1);
else else
mvwdelch(self->window, y, x - 1); wmove(self->window, y, x-1);
} }
} else if (key == KEY_LEFT && ctx->pos > 0) {
--ctx->pos;
if (x == 0)
wmove(self->window, y-1, x2-1);
else
wmove(self->window, y, x-1);
} else if (key == KEY_RIGHT && ctx->line[ctx->pos] != L'\0') {
++ctx->pos;
if (x == x2-1)
wmove(self->window, y+1, 0);
else
wmove(self->window, y, x+1);
} else } else
/* Add printable chars to buffer and print on input space */ /* Add printable chars to buffer and print on input space */
#if HAVE_WIDECHAR #if HAVE_WIDECHAR
@ -297,11 +311,14 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
#else #else
if (isprint(key)) if (isprint(key))
#endif #endif
{ { /* prevents buffer overflows and strange behaviour when cursor goes past the window */
if (ctx->pos < (MAX_STR_SIZE-1)) { if ( (ctx->len < MAX_STR_SIZE-1) && (ctx->len < (x2 * (CHATBOX_HEIGHT - 1)-1)) ) {
mvwaddstr(self->window, y, x, wc_to_char(key)); add_char_to_buf(key, ctx->line, &ctx->pos, &ctx->len);
ctx->line[ctx->pos++] = key;
ctx->line[ctx->pos] = L'\0'; if (x == x2-1)
wmove(self->window, y+1, 0);
else
wmove(self->window, y, x+1);
} }
} }
/* RETURN key: Execute command or print line */ /* RETURN key: Execute command or print line */
@ -354,8 +371,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
free(ctx); free(ctx);
free(statusbar); free(statusbar);
} else { } else {
ctx->line[0] = L'\0'; reset_buf(ctx->line, &ctx->pos, &ctx->len);
ctx->pos = 0;
} }
free(line); free(line);
@ -370,6 +386,9 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
wclear(ctx->linewin);
mvwprintw(ctx->linewin, 1, 0, "%s\n", wcs_to_char(ctx->line));
/* Draw status bar */ /* Draw status bar */
StatusBar *statusbar = self->stb; StatusBar *statusbar = self->stb;
mvwhline(statusbar->topline, 1, 0, ACS_HLINE, x); mvwhline(statusbar->topline, 1, 0, ACS_HLINE, x);
@ -434,7 +453,6 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
} }
wprintw(statusbar->topline, "\n"); wprintw(statusbar->topline, "\n");
mvwhline(ctx->linewin, 0, 0, ACS_HLINE, x); mvwhline(ctx->linewin, 0, 0, ACS_HLINE, x);
wrefresh(self->window); wrefresh(self->window);
} }

View File

@ -223,25 +223,41 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key)
/* BACKSPACE key: Remove one character from line */ /* BACKSPACE key: Remove one character from line */
if (key == 0x107 || key == 0x8 || key == 0x7f) { if (key == 0x107 || key == 0x8 || key == 0x7f) {
if (ctx->pos > 0) { if (ctx->pos > 0) {
ctx->line[--ctx->pos] = L'\0'; del_char_from_buf(key, ctx->line, &ctx->pos, &ctx->len);
if (x == 0) if (x == 0)
mvwdelch(self->window, y - 1, x2 - 1); wmove(self->window, y-1, x2-1);
else else
mvwdelch(self->window, y, x - 1); wmove(self->window, y, x-1);
} }
} else } else if (key == KEY_LEFT && ctx->pos > 0) {
/* Add printable chars to buffer and print on input space */ --ctx->pos;
if (x == 0)
wmove(self->window, y-1, x2-1);
else
wmove(self->window, y, x-1);
} else if (key == KEY_RIGHT && ctx->line[ctx->pos] != L'\0') {
++ctx->pos;
if (x == x2-1)
wmove(self->window, y+1, 0);
else
wmove(self->window, y, x+1);
} else
#if HAVE_WIDECHAR #if HAVE_WIDECHAR
if (iswprint(key)) if (iswprint(key))
#else #else
if (isprint(key)) if (isprint(key))
#endif #endif
{ { /* prevents buffer overflows and strange behaviour when cursor goes past the window */
if (ctx->pos < (MAX_STR_SIZE-1)) { if ( (ctx->len < MAX_STR_SIZE-1) && (ctx->len < (x2 * (CHATBOX_HEIGHT - 1)-1)) ) {
mvwaddstr(self->window, y, x, wc_to_char(key)); add_char_to_buf(key, ctx->line, &ctx->pos, &ctx->len);
ctx->line[ctx->pos++] = key;
ctx->line[ctx->pos] = L'\0'; if (x == x2-1)
wmove(self->window, y+1, 0);
else
wmove(self->window, y, x+1);
} }
} }
@ -287,8 +303,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key)
if (close_win) if (close_win)
free(ctx); free(ctx);
else { else {
ctx->line[0] = L'\0'; reset_buf(ctx->line, &ctx->pos, &ctx->len);
ctx->pos = 0;
} }
free(line); free(line);
@ -302,6 +317,10 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m)
getmaxyx(self->window, y, x); getmaxyx(self->window, y, x);
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
wclear(ctx->linewin);
mvwprintw(ctx->linewin, 1, 0, "%s\n", wcs_to_char(ctx->line));
wclrtobot(ctx->sidebar); wclrtobot(ctx->sidebar);
mvwhline(ctx->linewin, 0, 0, ACS_HLINE, x); mvwhline(ctx->linewin, 0, 0, ACS_HLINE, x);
mvwvline(ctx->sidebar, 0, 0, ACS_VLINE, y-CHATBOX_HEIGHT); mvwvline(ctx->sidebar, 0, 0, ACS_VLINE, y-CHATBOX_HEIGHT);
@ -338,7 +357,7 @@ static void groupchat_onInit(ToxWindow *self, Tox *m)
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
ctx->history = subwin(self->window, y-CHATBOX_HEIGHT+1, x-SIDEBAR_WIDTH-1, 0, 0); ctx->history = subwin(self->window, y-CHATBOX_HEIGHT+1, x-SIDEBAR_WIDTH-1, 0, 0);
scrollok(ctx->history, 1); scrollok(ctx->history, 1);
ctx->linewin = subwin(self->window, 2, x, y-CHATBOX_HEIGHT, 0); ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x, y-CHATBOX_HEIGHT, 0);
ctx->sidebar = subwin(self->window, y-CHATBOX_HEIGHT+1, SIDEBAR_WIDTH, 0, x-SIDEBAR_WIDTH); ctx->sidebar = subwin(self->window, y-CHATBOX_HEIGHT+1, SIDEBAR_WIDTH, 0, x-SIDEBAR_WIDTH);
print_groupchat_help(ctx); print_groupchat_help(ctx);

View File

@ -8,6 +8,7 @@
#include <limits.h> #include <limits.h>
#include "toxic_windows.h" #include "toxic_windows.h"
#include "misc_tools.h"
// XXX: FIX // XXX: FIX
unsigned char *hex_string_to_bin(char hex_string[]) unsigned char *hex_string_to_bin(char hex_string[])
@ -158,3 +159,62 @@ bool valid_nick(uint8_t *nick)
return true; return true;
} }
/*
* Buffer helper tools. Assumes buffers are no larger than MAX_STR_SIZE
*/
/* Adds char to buffer at pos */
void add_char_to_buf(wint_t ch, wchar_t *buf, size_t *pos, size_t *len)
{
if (*pos < 0 || *len >= MAX_STR_SIZE)
return;
/* if cursor is at end of line simply insert char at last position and increment */
if (buf[*pos] == L'\0') {
buf[(*pos)++] = ch;
buf[*pos] = L'\0';
++(*len);
return;
}
/* move all chars in front of pos one space forward and insert char in pos */
int i;
for (i = *len; i >= *pos && i >= 0; --i)
buf[i+1] = buf[i];
buf[(*pos)++] = ch;
++(*len);
}
/* Deletes the character before pos via the backspace key */
void del_char_from_buf(wint_t ch, wchar_t *buf, size_t *pos, size_t *len)
{
if (*pos <= 0)
return;
/* if cursor is at end of line delete previous char */
if (buf[*pos] == L'\0') {
buf[--(*pos)] = L'\0';
--(*len);
return;
}
int i;
/* similar to add_char_to_buf but deletes a char */
for (i = *pos-1; i <= *len; ++i)
buf[i] = buf[i+1];
--(*pos);
--(*len);
}
/* sets pos and len to 0 */
void reset_buf(wchar_t *buf, size_t *pos, size_t *len)
{
buf[0] = L'\0';
*pos = 0;
*len = 0;
}

View File

@ -36,3 +36,16 @@ int name_compare(const void *nick1, const void *nick2);
- cannot start with a space - cannot start with a space
- must not contain contiguous spaces */ - must not contain contiguous spaces */
bool valid_nick(uint8_t *nick); bool valid_nick(uint8_t *nick);
/*
* Buffer helper tools.
*/
/* Adds char to buffer at pos */
void add_char_to_buf(wint_t ch, wchar_t *buf, size_t *pos, size_t *len);
/* Deletes the character before pos via the backspace key */
void del_char_from_buf(wint_t ch, wchar_t *buf, size_t *pos, size_t *len);
/* sets pos and len to 0 */
void reset_buf(wchar_t *buf, size_t *pos, size_t *len);

View File

@ -99,6 +99,7 @@ struct StatusBar {
struct ChatContext { struct ChatContext {
wchar_t line[MAX_STR_SIZE]; wchar_t line[MAX_STR_SIZE];
size_t pos; size_t pos;
size_t len;
WINDOW *history; WINDOW *history;
WINDOW *linewin; WINDOW *linewin;
WINDOW *sidebar; WINDOW *sidebar;