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 | |
| parent | 40bd036c5390118a8f1631e1d990cce29edb40f4 (diff) | |
| download | bemenu-cc93ff905ff9cf8bcb71a088a16529167511b8ad.tar.gz bemenu-cc93ff905ff9cf8bcb71a088a16529167511b8ad.tar.bz2 bemenu-cc93ff905ff9cf8bcb71a088a16529167511b8ad.zip | |
Draw lines properly.
Diffstat (limited to 'lib')
| -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();  } | 
