mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 08:14:37 +08:00
tui: lighter, segmented title bar (M7-2)
Replace the full-width reverse-video title
▍ tester | 在线: 3 | 模式: INSERT | ? 帮助 ▎ (reversed)
with a single line of small chips on a normal background:
tester · 在线 3 · INSERT ? 帮助
- username is bold white, online count is plain
- mode name carries its own colour, so glance + colour disambiguates
it (INSERT cyan, NORMAL yellow, COMMAND magenta, HELP blue) without
having to read the word
- separators are dim grey middle-dots so the eye groups segments
- mute marker shrinks from "[静音]" to a dim "静音" suffix when active
- hint "? 帮助" is right-aligned in dim grey, far from content
The horizontal rule below the chat already provides the visual divider
that the reverse-video bar used to provide, so the bar can drop the
heaviness without losing structure.
This commit is contained in:
parent
159073ec49
commit
e2b16cf477
1 changed files with 60 additions and 15 deletions
75
src/tui.c
75
src/tui.c
|
|
@ -298,26 +298,71 @@ void tui_render_screen(client_t *client) {
|
||||||
/* Move to top (Home) - Do NOT clear screen to prevent flicker */
|
/* Move to top (Home) - Do NOT clear screen to prevent flicker */
|
||||||
buffer_appendf(buffer, buf_size, &pos, ANSI_HOME);
|
buffer_appendf(buffer, buf_size, &pos, ANSI_HOME);
|
||||||
|
|
||||||
/* Title bar */
|
/* Title bar — segmented chips on a single line, no full-line reverse.
|
||||||
const char *mode_str = (client->mode == MODE_INSERT) ? "INSERT" :
|
*
|
||||||
(client->mode == MODE_NORMAL) ? "NORMAL" :
|
* Segments (left to right):
|
||||||
(client->mode == MODE_COMMAND) ? "COMMAND" : "HELP";
|
* • bold username
|
||||||
|
* • online count
|
||||||
|
* • mode name (colour matches the mode itself: cyan/yellow/magenta)
|
||||||
|
* • mute marker, only when active
|
||||||
|
* • right-aligned hint
|
||||||
|
*
|
||||||
|
* `· ` separators are dim grey so the eye groups segments without
|
||||||
|
* mistaking them for content. */
|
||||||
|
struct title_chip { const char *value; const char *value_color; };
|
||||||
|
struct title_chip chips[3];
|
||||||
|
int chip_count = 0;
|
||||||
|
|
||||||
char title[256];
|
chips[chip_count].value = client->username;
|
||||||
snprintf(title, sizeof(title),
|
chips[chip_count].value_color = "\033[1;37m";
|
||||||
" %s | 在线: %d | 模式: %s%s | ? 帮助 ",
|
chip_count++;
|
||||||
client->username, online, mode_str,
|
|
||||||
client->mute_joins ? " [静音]" : "");
|
|
||||||
|
|
||||||
int title_width = utf8_string_width(title);
|
char online_buf[32];
|
||||||
int padding = render_width - title_width;
|
snprintf(online_buf, sizeof(online_buf), "在线 %d", online);
|
||||||
if (padding < 0) padding = 0;
|
chips[chip_count].value = online_buf;
|
||||||
|
chips[chip_count].value_color = "\033[37m";
|
||||||
|
chip_count++;
|
||||||
|
|
||||||
buffer_appendf(buffer, buf_size, &pos, ANSI_REVERSE "%s", title);
|
const char *mode_str;
|
||||||
for (int i = 0; i < padding; i++) {
|
const char *mode_color;
|
||||||
|
switch (client->mode) {
|
||||||
|
case MODE_INSERT: mode_str = "INSERT"; mode_color = "\033[36m"; break;
|
||||||
|
case MODE_NORMAL: mode_str = "NORMAL"; mode_color = "\033[33m"; break;
|
||||||
|
case MODE_COMMAND: mode_str = "COMMAND"; mode_color = "\033[35m"; break;
|
||||||
|
default: mode_str = "HELP"; mode_color = "\033[34m"; break;
|
||||||
|
}
|
||||||
|
chips[chip_count].value = mode_str;
|
||||||
|
chips[chip_count].value_color = mode_color;
|
||||||
|
chip_count++;
|
||||||
|
|
||||||
|
/* Compose left half. */
|
||||||
|
char left[256];
|
||||||
|
size_t lpos = 0;
|
||||||
|
int left_width = 0;
|
||||||
|
for (int i = 0; i < chip_count; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
buffer_appendf(left, sizeof(left), &lpos, "\033[2;37m · \033[0m");
|
||||||
|
left_width += 3;
|
||||||
|
}
|
||||||
|
buffer_appendf(left, sizeof(left), &lpos, "%s%s\033[0m",
|
||||||
|
chips[i].value_color, chips[i].value);
|
||||||
|
left_width += utf8_string_width(chips[i].value);
|
||||||
|
}
|
||||||
|
if (client->mute_joins) {
|
||||||
|
buffer_appendf(left, sizeof(left), &lpos, " \033[2;37m静音\033[0m");
|
||||||
|
left_width += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *hint = "? 帮助";
|
||||||
|
int hint_width = utf8_string_width(hint);
|
||||||
|
int gap = render_width - left_width - hint_width - 2;
|
||||||
|
if (gap < 1) gap = 1;
|
||||||
|
|
||||||
|
buffer_appendf(buffer, buf_size, &pos, " %s", left);
|
||||||
|
for (int i = 0; i < gap; i++) {
|
||||||
buffer_append_bytes(buffer, buf_size, &pos, " ", 1);
|
buffer_append_bytes(buffer, buf_size, &pos, " ", 1);
|
||||||
}
|
}
|
||||||
buffer_appendf(buffer, buf_size, &pos, ANSI_RESET "\033[K\r\n");
|
buffer_appendf(buffer, buf_size, &pos, "\033[2;37m%s\033[0m \033[K\r\n", hint);
|
||||||
|
|
||||||
/* Render messages from snapshot */
|
/* Render messages from snapshot */
|
||||||
if (msg_snapshot) {
|
if (msg_snapshot) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue