static void _print_string(const char *ptr, size_t width, bool utf8, bool left_adjust) { if (!ptr) ptr = nullstr; size_t padding = 0; if (width) { size_t w = screen_display_width(ptr, utf8); if (w < width) padding = width - w; } if (padding && !left_adjust) tui_repeat_char(' ', padding); if (utf8) { screen_puts(ptr, 0); } else { convert(CONVERT_G2U, ptr, CONVERT_ALL, NULL, 0, screen_put_gbk_helper, NULL); } if (padding && left_adjust) tui_repeat_char(' ', padding); }
/** * 重绘屏幕 */ void screen_redraw(void) { if (!screen.buf) return; ansi_cmd(ANSI_CMD_CL); screen.tc_col = 0; screen.tc_line = 0; for (int i = 0; i < screen.lines; ++i) { screen_line_t *sl = get_screen_line(i); if (!sl->len) continue; move_terminal_cursor(0, i); screen_write_cached(sl->data, sl->len); screen.tc_col += sl->len; if (screen.tc_col >= screen.columns) { screen.tc_col = screen.columns - 1; } sl->modified = false; sl->data[sl->len] = '\0'; sl->old_width = screen_display_width((char *) sl->data, true); } move_terminal_cursor(screen.cur_col, screen.cur_ln); screen.redraw = false; screen.scrollcnt = 0; terminal_flush(); }
void screen_flush(void) { if (!screen.buf) { terminal_flush(); return; } if (!terminal_input_buffer_empty()) return; if (screen.redraw || (abs(screen.scrollcnt) >= (screen.lines - 3))) { screen_redraw(); return; } if (screen.scrollcnt < 0) { move_terminal_cursor(0, 0); while (screen.scrollcnt < 0) { ansi_cmd(ANSI_CMD_SR); screen.scrollcnt++; } } if (screen.scrollcnt > 0) { move_terminal_cursor(0, screen.lines - 1); while (screen.scrollcnt > 0) { terminal_putchar('\n'); screen.scrollcnt--; } } for (int i = 0; i < screen.lines; i++) { screen_line_t *sl = get_screen_line(i); sl->data[sl->len] = '\0'; int width = screen_display_width((char *) sl->data, true); if (sl->modified) { sl->modified = false; move_terminal_cursor(0, i); screen_write_cached(sl->data, sl->len); screen.tc_col = width; if (screen.tc_col >= screen.columns) { screen.tc_col -= screen.columns; screen.tc_line++; if (screen.tc_line >= screen.lines) screen.tc_line = screen.lines - 1; } } if (sl->old_width > width) { move_terminal_cursor(width, i); ansi_cmd(ANSI_CMD_CE); } sl->old_width = width; } move_terminal_cursor(screen.cur_col, screen.cur_ln); terminal_flush(); }
void tui_update_status_line(void) { extern time_t login_start_time; //main.c char date[STRLEN]; screen_move_clear(-1); if (!DEFINE(DEF_ENDLINE)) return; fb_time_t now = fb_time(); int cur_sec = now % 10; if (cur_sec < 5) { strlcpy(date, format_time(now, TIME_FORMAT_UTF8_ZH), sizeof(date)); } else { if (resolve_boards() >= 0) convert_g2u(brdshm->date, date); else date[0] = '\0'; } if (cur_sec >= 5 && is_birth(¤tuser)) { screen_printf("\033[0;1;33;44m[\033[36m " "啦啦~~生日快乐!记得要请客哟 :P" " \033[33m]\033[m"); } else { int stay = (now - login_start_time) / 60; char stay_str[20]; describe_stay(stay, stay_str, sizeof(stay_str)); char notice[128]; notice_string(notice, sizeof(notice)); int notice_width = screen_display_width(notice, true); screen_printf("\033[1;44;33m[\033[36m%29s\033[33m]" "[\033[36m%5d\033[33m人\033[36m%3d\033[33m友]", date, session_count_online(), session_count_online_followed(!HAS_PERM(PERM_SEECLOAK))); // 剩下35列 if (notice_width) { int space = 33 - notice_width; if (space > 0) tui_repeat_char(' ', space); screen_printf("[\033[%d;36m%s\033[m\033[1;33;44m]\033[m", _suppress_notice ? 1 : 5, notice); } else { int space = 27 - strlen(currentuser.userid); tui_repeat_char(' ', space); prints("[\033[36m%s\033[33m]%s\033[m", currentuser.userid, stay_str); } } }
void tui_header_line(const char *menu, bool check_mail) { extern int mailXX; //main.c char title[36]; if (check_mail && chkmail()) strlcpy(title, strstr(menu, "讨论区列表") ? "[您有信件,按 M 看新信]" : "[您有信件]", sizeof(title)); else if (check_mail && mailXX == 1) strlcpy(title, "[信件过量,请整理信件!]", sizeof(title)); else strlcpy(title, BBSNAME_UTF8, sizeof(title)); bool show_board = true; int w1 = screen_display_width(menu, true), w2 = screen_display_width(title, true), w3 = screen_display_width(currboard, true) + 2; int spaces = 80 - w1 - w2 - w3; if (spaces < 0) { spaces = 80 - w1 - w2; show_board = false; } screen_move_clear(0); screen_printf("\033[1;33;44m%s", menu); if (spaces > 0) tui_repeat_char(' ', spaces / 2); if (streq(title, BBSNAME_UTF8)) screen_printf("\033[37m%s", title); else if (title[0] == '[') screen_printf("\033[5;36m%s\033[0;1;44m", title); else screen_printf("\033[36m%s", title); if (spaces > 0) tui_repeat_char(' ', spaces - spaces / 2); if (show_board) screen_printf("\033[33m[%s]\033[m", currboard); tui_update_status_line(); screen_move(1, 0); }
static void notice_string(char *buf, size_t size) { *buf = '\0'; int replies, mentions; notice_count(&replies, &mentions); bool empty = !(replies || mentions); if (!empty) { char **dst = &buf; if (replies > 0) { char str[24]; snprintf(str, sizeof(str), "%d篇回复", replies); strappend(dst, &size, str); } if (mentions > 0) { char str[24]; snprintf(str, sizeof(str), "%d篇提及", mentions); strappend(dst, &size, str); } if (!_suppress_notice && screen_display_width(buf, true) <= 24) strappend(dst, &size, " 按^T查看"); } }
static int _tui_input(int line, int col, const char *prompt, char *buf, int len, int echo, int clear, bool utf8) { extern int RMSG; extern int msg_num; if (clear) buf[0] = '\0'; buf[len - 1] = '\0'; int real_x = prompt ? screen_display_width(prompt, utf8) : 0; int cur, clen; cur = clen = strlen(buf); bool inited = screen_inited(), prompted = false; while (1) { if (inited || !prompted) { screen_move(line, col); clrtoeol(); if (prompt) { if (utf8) screen_printf("%s", prompt); else prints("%s", prompt); } prompted = true; } if (inited) { if (echo) prints("%s", buf); else tui_repeat_char('*', clen); screen_move(line, real_x + cur); } if (RMSG) screen_flush(); int ch = terminal_getchar(); if (RMSG && msg_num == 0) { if (ch == Ctrl('Z') || ch == KEY_UP) { buf[0] = Ctrl('Z'); clen = 1; break; } if (ch == Ctrl('A') || ch == KEY_DOWN) { buf[0] = Ctrl('A'); clen = 1; break; } } if (ch == '\n' || ch == '\r') break; if (!inited) { if (ch == '\x7f' || ch == Ctrl('H')) { int dec = remove_character(buf, &cur, clen, true); if (dec) { clen -= dec; screen_puts("\x8 \x8", 3); } } else if (isprint2(ch) && clen < len - 1) { buf[cur] = ch; buf[++cur] = '\0'; ++clen; screen_putc(echo ? ch : '*'); } continue; } if (ch == '\x7f' || ch == Ctrl('H')) { clen -= remove_character(buf, &cur, clen, true); } else if (ch == KEY_DEL) { clen -= remove_character(buf, &cur, clen, false); } else if (ch == KEY_LEFT) { if (cur > 0) --cur; } else if (ch == KEY_RIGHT) { if (cur < clen) ++cur; } else if (ch == Ctrl('E') || ch == KEY_END) { cur = clen; } else if (ch == Ctrl('A') || ch == KEY_HOME) { cur = 0; } else if (isprint2(ch) && clen < len - 1) { if (buf[cur] != '\0') memmove(buf + cur + 1, buf + cur, clen - cur); buf[cur++] = ch; buf[++clen] = '\0'; } } screen_putc('\n'); screen_flush(); return clen; }