diff options
author | Jari Vetoniemi <mailroxas@gmail.com> | 2014-04-11 01:59:50 +0300 |
---|---|---|
committer | Jari Vetoniemi <mailroxas@gmail.com> | 2014-04-11 01:59:50 +0300 |
commit | cc93ff905ff9cf8bcb71a088a16529167511b8ad (patch) | |
tree | 738f425ce694e18a2e3015170440e3c3b547142a /lib/draw | |
parent | 40bd036c5390118a8f1631e1d990cce29edb40f4 (diff) | |
download | bemenu-cc93ff905ff9cf8bcb71a088a16529167511b8ad.tar.gz bemenu-cc93ff905ff9cf8bcb71a088a16529167511b8ad.tar.bz2 bemenu-cc93ff905ff9cf8bcb71a088a16529167511b8ad.zip |
Draw lines properly.
Diffstat (limited to 'lib/draw')
-rw-r--r-- | lib/draw/curses.c | 75 |
1 files changed, 56 insertions, 19 deletions
diff --git a/lib/draw/curses.c b/lib/draw/curses.c index a58dd3b..22abfd9 100644 --- a/lib/draw/curses.c +++ b/lib/draw/curses.c @@ -47,37 +47,73 @@ static struct curses { int *ESCDELAY; } curses; -static void _bmDrawCursesDrawLine(int pair, int y, const char *format, ...) +static int _bmDrawCursesResizeBuffer(char **buffer, size_t osize, size_t nsize) { - static int ncols = 0; - static char *buffer = NULL; - int newNcols = curses.getmaxx(curses.stdscr); - - if (newNcols <= 0) - return; + assert(buffer); + assert(nsize); - if (!buffer || newNcols > ncols) { - if (buffer) - free(buffer); + if (nsize == 0 || nsize < osize) + return 0; - ncols = newNcols; + void *tmp; + if (!*buffer || !(tmp = realloc(*buffer, nsize))) { + if (!(tmp = malloc(nsize))) + return 0; - if (!(buffer = calloc(1, ncols + 1))) - return; + if (*buffer) { + memcpy(tmp, *buffer, osize); + free(*buffer); + } } + *buffer = tmp; + memset(*buffer + osize, ' ', (nsize - osize)); + (*buffer)[nsize - 1] = 0; + return 1; +} + +static void _bmDrawCursesDrawLine(int pair, int y, const char *format, ...) +{ + static int blen = 0; + static char *buffer = NULL; + + int ncols = curses.getmaxx(curses.stdscr); + if (ncols <= 0) + return; + va_list args; va_start(args, format); - int tlen = vsnprintf(NULL, 0, format, args) + 1; - if (tlen > ncols) - tlen = ncols; + int nlen = vsnprintf(NULL, 0, format, args) + 1; + if (nlen < ncols) + nlen = ncols; va_end(args); + if ((!buffer || nlen > blen) && !_bmDrawCursesResizeBuffer(&buffer, blen, nlen)) + return; + + blen = nlen; va_start(args, format); - vsnprintf(buffer, tlen, format, args); + int slen = vsnprintf(buffer, blen - 1, format, args); + memset(buffer + slen, ' ', (blen - slen)); + buffer[blen - 1] = 0; va_end(args); - memset(buffer + tlen - 1, ' ', ncols - tlen + 1); + int dw = 0, i = 0; + while (dw < ncols && i < blen) { + if (buffer[i] == '\t') buffer[i] = ' '; + int next = _bmUtf8RuneNext(buffer, i); + dw += _bmUtf8RuneWidth(buffer + i, next); + i += (next ? next : 1); + } + + if (dw < ncols) { + if (!_bmDrawCursesResizeBuffer(&buffer, blen - 1, blen + (ncols - dw) + 1)) + return; + } else if (i < blen) { + int cc = dw - (dw - ncols); + memset(buffer + i - (dw - ncols), ' ', (ncols - cc) + 1); + buffer[i - (dw - ncols) + (ncols - cc) + 1] = 0; + } if (pair > 0) curses.attron(COLOR_PAIR(pair)); @@ -126,7 +162,8 @@ static void _bmDrawCursesRender(const bmMenu *menu) _bmDrawCursesDrawLine(color, cl++, "%s%s", (highlighted ? ">> " : " "), items[i]->text); } - curses.move(0, titleLen + menu->cursesCursor); + unsigned int ncols = curses.getmaxx(curses.stdscr) - titleLen - 1; + curses.move(0, titleLen + (ncols < menu->cursesCursor ? ncols : menu->cursesCursor)); curses.refresh(); } |