/* Prints line onto a window highlighting it according to attrs, which should * specify 0-9 color groups for every character in line. */ static void print_with_attrs(WINDOW *win, const char line[], const char attrs[], const cchar_t *default_attr) { cchar_t attr = *default_attr; while(*line != '\0') { if(*attrs == '0') { attr = *default_attr; } else if(*attrs != ' ') { const int color = (USER1_COLOR + (*attrs - '1')); col_attr_t col = cfg.cs.color[STATUS_LINE_COLOR]; cs_mix_colors(&col, &cfg.cs.color[color]); setcchar(&attr, L" ", col.attr, colmgr_get_pair(col.fg, col.bg), NULL); } const size_t len = utf8_chrw(line); char char_buf[len + 1]; copy_str(char_buf, sizeof(char_buf), line); wprinta(win, char_buf, &attr, 0); line += len; attrs += utf8_chrsw(char_buf); } }
/* Draws single menu item at position specified by line argument. Non-zero * clear argument suppresses drawing current items in different color. */ static void draw_menu_item(menu_state_t *ms, int pos, int line, int clear) { menu_data_t *const m = ms->d; int i; int off; char *item_tail; const int width = (curr_stats.load_stage == 0) ? 100 : getmaxx(menu_win) - 2; /* Calculate color for the line. */ int attrs; col_attr_t col = cfg.cs.color[WIN_COLOR]; if(cfg.hl_search && ms->search_highlight && ms->matches != NULL && ms->matches[pos][0] >= 0) { cs_mix_colors(&col, &cfg.cs.color[SELECTED_COLOR]); } if(!clear && pos == m->pos) { cs_mix_colors(&col, &cfg.cs.color[CURR_LINE_COLOR]); } attrs = COLOR_PAIR(colmgr_get_pair(col.fg, col.bg)) | col.attr; /* Calculate offset of m->hor_pos's character in item text. */ off = 0; i = m->hor_pos; while(i-- > 0 && m->items[pos][off] != '\0') { off += utf8_chrw(m->items[pos] + off); } item_tail = strdup(m->items[pos] + off); replace_char(item_tail, '\t', ' '); wattron(menu_win, attrs); /* Clear the area. */ checked_wmove(menu_win, line, 1); if(curr_stats.load_stage != 0) { wprintw(menu_win, "%*s", width, ""); } /* Draw visible part of item. */ checked_wmove(menu_win, line, 2); if(utf8_strsw(item_tail) > (size_t)(width - 2)) { void *p; const size_t len = utf8_nstrsnlen(item_tail, width - 3 - 2 + 1); memset(item_tail + len, ' ', strlen(item_tail) - len); p = realloc(item_tail, len + 4); if(p != NULL) { item_tail = p; strcpy(item_tail + len - 1, "..."); } wprint(menu_win, item_tail); } else { const size_t len = utf8_nstrsnlen(item_tail, width - 2 + 1); item_tail[len] = '\0'; wprint(menu_win, item_tail); } wattroff(menu_win, attrs); if(ms->search_highlight && ms->matches != NULL && ms->matches[pos][0] >= 0) { draw_search_match(item_tail, ms->matches[pos][0] - m->hor_pos, ms->matches[pos][1] - m->hor_pos, line, width, attrs); } free(item_tail); }