void move_to_menu_pos(int pos, menu_state_t *ms) { menu_data_t *const m = ms->d; int redraw; pos = MIN(m->len - 1, MAX(0, pos)); if(pos < 0) { return; } normalize_top(ms); redraw = 0; if(pos > get_last_visible_line(m)) { m->top = pos - (ms->win_rows - 2 - 1); redraw = 1; } else if(pos < m->top) { m->top = pos; redraw = 1; } if(cfg.scroll_off > 0) { int s = MIN(DIV_ROUND_UP(ms->win_rows - 2, 2), cfg.scroll_off); if(pos - m->top < s && m->top > 0) { m->top -= s - (pos - m->top); normalize_top(ms); redraw = 1; } if(pos > get_last_visible_line(m) - s) { m->top += s - (get_last_visible_line(m) - pos); normalize_top(ms); redraw = 1; } } ms->current = 1 + (pos - m->top); m->pos = pos; if(redraw) { draw_menu(ms); } else { draw_menu_item(ms, m->pos, ms->current, 0); } checked_wmove(menu_win, ms->current, 2); show_position_in_menu(m); }
void draw_menu(menu_state_t *m) { int i, pos; const int y = getmaxy(menu_win); normalize_top(m); werase(menu_win); draw_menu_frame(m); for(i = 0, pos = m->d->top; i < y - 2 && pos < m->d->len; ++i, ++pos) { draw_menu_item(m, pos, i + 1, 0); } }
void draw_menu(menu_info *m) { int i; int win_len; int x, y; getmaxyx(menu_win, y, x); win_len = x; werase(menu_win); normalize_top(m); x = m->top; box(menu_win, 0, 0); wattron(menu_win, A_BOLD); checked_wmove(menu_win, 0, 3); wprint(menu_win, m->title); wattroff(menu_win, A_BOLD); for(i = 1; x < m->len; i++, x++) { int z, off; char *buf; char *ptr = NULL; col_attr_t col; int type = WIN_COLOR; chomp(m->items[x]); if((ptr = strchr(m->items[x], '\n')) || (ptr = strchr(m->items[x], '\r'))) *ptr = '\0'; col = cfg.cs.color[WIN_COLOR]; if(cfg.hl_search && m->matches != NULL && m->matches[x]) { mix_colors(&col, &cfg.cs.color[SELECTED_COLOR]); type = SELECTED_COLOR; } init_pair(DCOLOR_BASE + type, col.fg, col.bg); wattron(menu_win, COLOR_PAIR(DCOLOR_BASE + type) | col.attr); z = m->hor_pos; off = 0; while(z-- > 0 && m->items[x][off] != '\0') { size_t l = get_char_width(m->items[x] + off); off += l; } buf = strdup(m->items[x] + off); for(z = 0; buf[z] != '\0'; z++) if(buf[z] == '\t') buf[z] = ' '; checked_wmove(menu_win, i, 2); if(get_screen_string_length(buf) > win_len - 4) { size_t len = get_normal_utf8_string_widthn(buf, win_len - 3 - 4); memset(buf + len, ' ', strlen(buf) - len); buf[len + 3] = '\0'; wprint(menu_win, buf); mvwaddstr(menu_win, i, win_len - 5, "..."); } else { const size_t len = get_normal_utf8_string_widthn(buf, win_len - 4); buf[len] = '\0'; wprint(menu_win, buf); } waddstr(menu_win, " "); free(buf); wattroff(menu_win, COLOR_PAIR(DCOLOR_BASE + type) | col.attr); if(i + 3 > y) break; } }
void move_to_menu_pos(int pos, menu_info *m) { /* TODO: refactor this function move_to_menu_pos() */ int redraw = 0; int x, z; char *buf = NULL; col_attr_t col; int off = 0; pos = MIN(m->len - 1, MAX(0, pos)); if(pos < 0) return; normalize_top(m); if(pos > get_last_visible_line(m)) { m->top = pos - (m->win_rows - 2 - 1); redraw = 1; } else if(pos < m->top) { m->top = pos; redraw = 1; } if(cfg.scroll_off > 0) { int s = MIN(DIV_ROUND_UP(m->win_rows - 2, 2), cfg.scroll_off); if(pos - m->top < s && m->top > 0) { m->top -= s - (pos - m->top); normalize_top(m); redraw = 1; } if(pos > get_last_visible_line(m) - s) { m->top += s - (get_last_visible_line(m) - pos); normalize_top(m); redraw = 1; } } m->current = 1 + (pos - m->top); if(redraw) draw_menu(m); x = getmaxx(menu_win) + get_utf8_overhead(m->items[pos]); buf = malloc(x + 2); if(buf == NULL) return; /* TODO: check if this can be false. */ if(m->items[pos] != NULL) { z = m->hor_pos; while(z-- > 0 && m->items[pos][off] != '\0') { size_t l = get_char_width(m->items[pos] + off); off += l; x -= l - 1; } snprintf(buf, x, " %s", m->items[pos] + off); } else { buf[0] = '\0'; } for(z = 0; buf[z] != '\0'; z++) if(buf[z] == '\t') buf[z] = ' '; for(z = strlen(buf); z < x; z++) buf[z] = ' '; buf[x] = ' '; buf[x + 1] = '\0'; col = cfg.cs.color[WIN_COLOR]; if(cfg.hl_search && m->matches != NULL && m->matches[pos]) mix_colors(&col, &cfg.cs.color[SELECTED_COLOR]); mix_colors(&col, &cfg.cs.color[CURR_LINE_COLOR]); init_pair(DCOLOR_BASE + MENU_CURRENT_COLOR, col.fg, col.bg); wattrset(menu_win, COLOR_PAIR(DCOLOR_BASE + MENU_CURRENT_COLOR) | col.attr); checked_wmove(menu_win, m->current, 1); if(get_screen_string_length(m->items[pos] + off) > getmaxx(menu_win) - 4) { size_t len = get_normal_utf8_string_widthn(buf, getmaxx(menu_win) - 3 - 4 + 1); memset(buf + len, ' ', strlen(buf) - len); buf[len + 3] = '\0'; wprint(menu_win, buf); mvwaddstr(menu_win, m->current, getmaxx(menu_win) - 5, "..."); } else { size_t len = get_normal_utf8_string_widthn(buf, getmaxx(menu_win) - 4 + 1); buf[len] = '\0'; wprint(menu_win, buf); } waddstr(menu_win, " "); wattroff(menu_win, COLOR_PAIR(DCOLOR_BASE + MENU_CURRENT_COLOR) | col.attr); m->pos = pos; free(buf); show_position_in_menu(m); }