diff options
author | Jari Vetoniemi <mailroxas@gmail.com> | 2015-01-18 00:59:44 +0200 |
---|---|---|
committer | Jari Vetoniemi <mailroxas@gmail.com> | 2015-01-18 01:08:10 +0200 |
commit | 9c541d0b4261acd656171a03e6bfd2719f91286d (patch) | |
tree | 32d35203435cfa04aa81e4c71cab69933c050b54 /lib | |
parent | 6b5b93239eab623c786e1c537563a81a285ffbd2 (diff) | |
download | bemenu-9c541d0b4261acd656171a03e6bfd2719f91286d.tar.gz bemenu-9c541d0b4261acd656171a03e6bfd2719f91286d.tar.bz2 bemenu-9c541d0b4261acd656171a03e6bfd2719f91286d.zip |
Add --scrollbar option
Diffstat (limited to 'lib')
-rw-r--r-- | lib/bemenu.h | 16 | ||||
-rw-r--r-- | lib/internal.h | 5 | ||||
-rw-r--r-- | lib/menu.c | 12 | ||||
-rw-r--r-- | lib/renderers/cairo.h | 39 | ||||
-rw-r--r-- | lib/renderers/curses/curses.c | 20 |
5 files changed, 76 insertions, 16 deletions
diff --git a/lib/bemenu.h b/lib/bemenu.h index 54d82f9..490132f 100644 --- a/lib/bemenu.h +++ b/lib/bemenu.h @@ -387,6 +387,22 @@ bool bm_menu_set_color(struct bm_menu *menu, enum bm_color color, const char *he const char* bm_menu_get_color(const struct bm_menu *menu, enum bm_color color); /** + * Display scrollbar at left side of the menu. + * + * @param menu bm_menu instance to set scrollbar for. + * @param scrollbar true for scrollbar, false for no scrollbar. + */ +void bm_menu_set_scrollbar(struct bm_menu *menu, bool scrollbar); + +/** + * Is scrollbar being displayed on the menu? + * + * @param menu bm_menu instance where to get scrollbar display state from. + * @return true if scrollbar displayed, false otherwise. + */ +bool bm_menu_get_scrollbar(struct bm_menu *menu); + +/** * Display menu at bottom of the screen. * This may be no-op on some renderers (curses, wayland) * diff --git a/lib/internal.h b/lib/internal.h index 7b71eb4..5291b56 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -287,6 +287,11 @@ struct bm_menu { * Is menu grabbed? */ bool grabbed; + + /** + * Scrollbar enabled? + */ + bool scrollbar; }; /* library.c */ @@ -296,6 +296,18 @@ char* bm_menu_get_color(const struct bm_menu *menu, enum bm_color color) } void +bm_menu_set_scrollbar(struct bm_menu *menu, bool scrollbar) +{ + menu->scrollbar = scrollbar; +} + +bool +bm_menu_get_scrollbar(struct bm_menu *menu) +{ + return menu->scrollbar; +} + +void bm_menu_set_bottom(struct bm_menu *menu, bool bottom) { assert(menu); diff --git a/lib/renderers/cairo.h b/lib/renderers/cairo.h index 5eb5b68..c135a51 100644 --- a/lib/renderers/cairo.h +++ b/lib/renderers/cairo.h @@ -197,29 +197,31 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t ma paint.pos = (struct pos){ (menu->title ? 2 : 0) + result.x_advance, 2 }; paint.box = (struct box){ (menu->title ? 2 : 4), 0, 2, 2, width - paint.pos.x, 0 }; bm_cairo_draw_line(cairo, &paint, &result, "%s", (menu->filter ? menu->filter : "")); - out_result->height = result.height; uint32_t count; struct bm_item **items = bm_menu_get_filtered_items(menu, &count); uint32_t lines = (menu->lines > 0 ? menu->lines : 1); + uint32_t titleh = result.height; + out_result->height = titleh; if (lines > 1) { /* vertical mode */ - uint32_t spacing = 0; // 0 == variable width spacing - if (lines > max_height / result.height) { + uint32_t spacing_x = (menu->scrollbar ? 4 : 0); + uint32_t spacing_y = 0; // 0 == variable width spacing + if (lines > max_height / titleh) { /* there is more lines than screen can fit, enter fixed spacing mode */ - lines = max_height / result.height - 1; - spacing = result.height; + lines = max_height / titleh - 1; + spacing_y = titleh; } - uint32_t start_x = 0; + uint32_t prefix_x = 0; if (menu->prefix) { bm_pango_get_text_extents(cairo, &paint, &result, "%s ", menu->prefix); - start_x = result.x_advance; + prefix_x += result.x_advance; } - uint32_t posy = out_result->height; + uint32_t posy = titleh; for (uint32_t l = 0, i = (menu->index / lines) * lines; l < lines && i < count && posy < max_height; ++i, ++l) { bool highlighted = (items[i] == bm_menu_get_highlighted_item(menu)); @@ -236,18 +238,33 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t ma if (menu->prefix && highlighted) { paint.pos = (struct pos){ 0, 2 + posy }; - paint.box = (struct box){ 4, 0, 2, 2, width - paint.pos.x, 0 }; + paint.box = (struct box){ 4 + spacing_x, 0, 2, 2, width - paint.pos.x, 0 }; bm_cairo_draw_line(cairo, &paint, &result, "%s %s", menu->prefix, (items[i]->text ? items[i]->text : "")); } else { paint.pos = (struct pos){ 0, 2 + posy }; - paint.box = (struct box){ 4 + start_x, 0, 2, 2, width - paint.pos.x, 0 }; + paint.box = (struct box){ 4 + spacing_x + prefix_x, 0, 2, 2, width - paint.pos.x, 0 }; bm_cairo_draw_line(cairo, &paint, &result, "%s", (items[i]->text ? items[i]->text : "")); } - posy += (spacing ? spacing : result.height); + posy += (spacing_y ? spacing_y : result.height); out_result->height = posy + 2; out_result->displayed++; } + + if (menu->scrollbar && count > 0) { + uint32_t sheight = out_result->height - titleh; + bm_cairo_color_from_menu_color(menu, BM_COLOR_TITLE_FG, &paint.bg); + cairo_set_source_rgba(cairo->cr, paint.bg.r, paint.bg.b, paint.bg.g, paint.bg.a); + cairo_rectangle(cairo->cr, 0, titleh, 2, sheight); + cairo_fill(cairo->cr); + + uint32_t size = sheight / lines; + uint32_t percent = (menu->index / (float)(count - 1)) * (sheight - size); + bm_cairo_color_from_menu_color(menu, BM_COLOR_BG, &paint.bg); + cairo_set_source_rgba(cairo->cr, paint.bg.r, paint.bg.b, paint.bg.g, paint.bg.a); + cairo_rectangle(cairo->cr, 0, titleh + percent, 2, size); + cairo_fill(cairo->cr); + } } else { /* single-line mode */ bm_pango_get_text_extents(cairo, &paint, &result, "lorem ipsum lorem ipsum lorem ipsum lorem"); diff --git a/lib/renderers/curses/curses.c b/lib/renderers/curses/curses.c index af54846..bab031b 100644 --- a/lib/renderers/curses/curses.c +++ b/lib/renderers/curses/curses.c @@ -186,20 +186,30 @@ render(const struct bm_menu *menu) uint32_t count, cl = 1; const uint32_t lines = getmaxy(curses.stdscr); + const int32_t prefix_x = (menu->prefix ? bm_utf8_string_screen_width(menu->prefix) : 0); + const int32_t offset_x = (menu->scrollbar ? 2 : 0); if (lines > 1) { + uint32_t displayed = 0; struct bm_item **items = bm_menu_get_filtered_items(menu, &count); for (uint32_t i = (menu->index / (lines - 1)) * (lines - 1); i < count && cl < lines; ++i) { bool highlighted = (items[i] == bm_menu_get_highlighted_item(menu)); int32_t color = (highlighted ? 2 : (bm_menu_item_is_selected(menu, items[i]) ? 1 : 0)); if (menu->prefix && highlighted) { - draw_line(color, cl++, "%s %s", menu->prefix, (items[i]->text ? items[i]->text : "")); - } else if (menu->prefix) { - int32_t offset = (menu->prefix ? bm_utf8_string_screen_width(menu->prefix) : 0); - draw_line(color, cl++, "%*s %s", offset, "", (items[i]->text ? items[i]->text : "")); + draw_line(color, cl++, "%*s%s %s", offset_x, "", menu->prefix, (items[i]->text ? items[i]->text : "")); } else { - draw_line(color, cl++, "%s", (items[i]->text ? items[i]->text : "")); + draw_line(color, cl++, "%*s%s%s", offset_x + prefix_x, "", (menu->prefix ? " " : ""), (items[i]->text ? items[i]->text : "")); } + + ++displayed; + } + + if (menu->scrollbar) { + attron(COLOR_PAIR(1)); + uint32_t percent = (menu->index / (float)(count - 1)) * (displayed - 1); + for (uint32_t i = 0; i < displayed; ++i) + mvprintw(1 + i, 0, (i == percent ? "█" : "▒")); + attroff(COLOR_PAIR(1)); } } |