HTMLify
ui.c
Views: 6 | Author: abh
#define _XOPEN_SOURCE_EXTENDED
#include <ncursesw/ncurses.h>
#include <string.h>
#include <locale.h>
#include "chatbot.h"
#include "ui.h"
enum {
HEADER_BG,
SEND_BUBBLE_BG,
RECV_BUBBLE_BG,
CHAT_BG,
TEXT_AREA_BG,
HEADER_COLOR,
SEND_BUBBLE_COLOR,
RECV_BUBBLE_COLOR,
CHAT_COLOR,
TEXT_AREA_COLOR,
};
void draw_chat_select_page(ChatBot chatbots[], int cbc, int selected) {
int i, tly, tlx = (COLS-40)/2;
for (i=0; i<cbc; i++) {
tly = i*3;
if (selected-1 == i)
attron(A_REVERSE);
mvaddwstr(tly+0, tlx, L"╔══════════════════════════════════════╗");
mvaddwstr(tly+1, tlx, L"║ ║");
mvaddwstr(tly+2, tlx, L"╚══════════════════════════════════════╝");
mvaddstr(tly+1, tlx+2, chatbots[i].name);
if (selected-1 == i)
attroff(A_REVERSE);
}
}
void draw_chatting_page(ChatBot chatbot, char *typed_message, ChatMsg messages[]) {
int i, j;
int top_pad = 4, bottom_pad = 3, left_pad = 2, right_pad = 2;
// chat messages
int
vh = LINES - top_pad - bottom_pad,
vw = COLS - left_pad - bottom_pad,
vl = vh,
mmw = vw * 0.8, msgi = chatbot.msgcount-1,
msglen, mh, mw, mhwb, tw;
ChatMsg msg;
while (vl > 0 && msgi >= 0) {
msg = chatbot.messages[msgi];
msglen = strlen(msg.content);
mw = msglen > mmw ? mmw : msglen;
mh = ((msglen + 1)/ mw)+2+(msglen%mw?1:0);
tw = 0;
// attron(COLOR_PAIR(CHAT_COLOR));
if (msg.type == SEND) {
for (i=0; i<mw+2; i++) {
mvaddwstr(top_pad + vl - mh, COLS - mw - 1 + i, L"▄");
mvaddwstr(top_pad + vl - 1, COLS - mw - 1 + i, L"▀");
}
for (i=0; i<mh; i++) {
if (i == 0) {
mvaddwstr(top_pad + vl - mh + i, COLS - mw - 2, L"▄");
mvaddwstr(top_pad + vl - mh + i, COLS - 1, L"▄");
} else if (i == mh-1) {
mvaddwstr(top_pad + vl - mh + i, COLS - mw - 2, L"▀");
mvaddwstr(top_pad + vl - mh + i, COLS - 1, L"▀");
} else {
mvaddwstr(top_pad + vl - mh + i, COLS - mw - 2, L"█");
mvaddwstr(top_pad + vl - mh + i, COLS - 1, L"█");
}
}
attron(COLOR_PAIR(SEND_BUBBLE_COLOR));
for (i=1; i<mh; i++ && tw<msglen)
for (j=0; j<mw && tw<msglen; j++, tw++)
mvaddch(top_pad + vl - mh + i, COLS-mw+j-1, msg.content[tw]);
for (;tw%mw;tw++)
mvaddch(top_pad + vl - mh + (tw/mw)+1, COLS-mw+(tw%mw)-1, ' ');
attroff(COLOR_PAIR(SEND_BUBBLE_COLOR));
} else {
for (i=0; i<mw+2; i++) {
mvaddwstr(top_pad + vl - mh, i, L"▄");
mvaddwstr(top_pad + vl - 1, i, L"▀");
}
for (i=0; i<mh; i++) {
if (i == 0) {
mvaddwstr(top_pad + vl -mh , 0, L"▄");
mvaddwstr(top_pad + vl -mh + i, mw+1, L"▄");
} else if (i == mh-1) {
mvaddwstr(top_pad + vl -mh + i, 0, L"▀");
mvaddwstr(top_pad + vl -mh + i, mw+1, L"▀");
} else {
mvaddwstr(top_pad + vl -mh + i, 0, L"█");
mvaddwstr(top_pad + vl -mh + i, mw+1, L"█");
}
}
attron(COLOR_PAIR(RECV_BUBBLE_COLOR));
for (i=0; i<mh; i++ && tw<msglen)
for (j=0; j<mw && tw<msglen; j++, tw++)
mvaddch(top_pad + vl - mh + i+1, j+1, msg.content[tw]);
for (;tw%mw;tw++)
mvaddch(top_pad + vl - mh + (tw/mw)+1, (tw%mw)+1, ' ');
attroff(COLOR_PAIR(RECV_BUBBLE_COLOR));
}
// attroff(COLOR_PAIR(CHAT_COLOR));
vl -= mh;
msgi--;
}
// header
attron(COLOR_PAIR(HEADER_COLOR));
for (i=0; i<COLS; i++) {
for (j=0; j<3; j++) {
move(j, i);
addch(' ');
}
mvaddwstr(j, i, L"━");
}
mvaddstr(1, 10, chatbot.name);
mvprintw(1, COLS-20, "message count: %d", chatbot.msgcount);
attroff(COLOR_PAIR(HEADER_COLOR));
// text box
attron(COLOR_PAIR(TEXT_AREA_COLOR));
int len = strlen(typed_message);
mvaddwstr(LINES-3, 0, L"╔"); for(i=1;i<COLS-1;i++)mvaddwstr(LINES-3,i,L"═"); mvaddwstr(LINES-3, COLS-1, L"╗");
mvaddwstr(LINES-2, 0, L"║");
for(i=1;i<COLS-1;i++)mvaddch(LINES-2,i,' ');
for(i=(len>COLS-5?len-COLS+5:0),j=2;i<len;i++,j++)mvaddch(LINES-2,j,typed_message[i]);
mvaddwstr(LINES-2, j, L"█");
mvaddwstr(LINES-2, COLS-1, L"║");
mvaddwstr(LINES-1, 0, L"╚"); for(i=1;i<COLS-1;i++)mvaddwstr(LINES-1,i,L"═"); mvaddwstr(LINES-1, COLS-1, L"╝");
attroff(COLOR_PAIR(TEXT_AREA_COLOR));
}
void ui(int cbc, ChatBot chatbots[]) {
Page page = CHAT_SELECT_PAGE;
int selected = 0, key, type_cur_pos = 0;
char typed_message[512] = "\0";
ChatBot *selected_chatbot;
setlocale(LC_ALL, "");
initscr();
noecho();
curs_set(0);
keypad(stdscr, true);
start_color();
// colors
assume_default_colors(COLOR_WHITE, COLOR_BLACK);
init_color(HEADER_BG, 85, 88, 88);
init_color(SEND_BUBBLE_BG, 74, 301, 249);
init_color(RECV_BUBBLE_BG, 141, 149, 149);
init_color(CHAT_BG, 999, 441, 446);
init_color(TEXT_AREA_BG, 141, 149, 149);
init_pair(HEADER_COLOR, COLOR_WHITE, HEADER_BG);
init_pair(SEND_BUBBLE_COLOR, COLOR_WHITE, SEND_BUBBLE_BG);
init_pair(RECV_BUBBLE_COLOR, COLOR_WHITE, RECV_BUBBLE_BG);
init_pair(CHAT_COLOR, COLOR_WHITE, CHAT_BG);
init_pair(TEXT_AREA_COLOR, COLOR_WHITE, TEXT_AREA_BG);
while (true) {
erase();
switch (page) {
case CHAT_SELECT_PAGE:
draw_chat_select_page(chatbots, cbc, selected);
break;
case CHATING_PAGE:
draw_chatting_page(chatbots[selected-1], typed_message, chatbots[selected-1].messages);
break;
}
key = getch();
switch (page) {
case CHAT_SELECT_PAGE:
switch (key) {
case 'k':
case KEY_UP:
if (selected > 1)
selected--;
else
selected = cbc;
break;
case 'j':
case KEY_DOWN:
if (selected < cbc)
selected++;
else
selected = 1;
break;
case '\n':
case KEY_ENTER:
if (selected == 0)
continue;
page = CHATING_PAGE;
selected_chatbot = &chatbots[selected-1];
break;
}
break;
case CHATING_PAGE:
if (key == '\n') {
char *buf = strdup(typed_message);
ChatBot_chat(selected_chatbot, buf);
memset(typed_message, 0, 512);
type_cur_pos = 0;
}
if (key == KEY_BACKSPACE) {
if (type_cur_pos != 0) {
type_cur_pos--;
typed_message[type_cur_pos] = '\0';
}
}
if (key == 27) {
page = CHAT_SELECT_PAGE;
}
if (31 < key && key < 127) {
typed_message[type_cur_pos] = (char)key;
type_cur_pos++;
typed_message[type_cur_pos] = '\0';
}
break;
}
}
endwin();
}