diff options
Diffstat (limited to 'src/ui_txtwindow.c')
-rw-r--r-- | src/ui_txtwindow.c | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/src/ui_txtwindow.c b/src/ui_txtwindow.c new file mode 100644 index 0000000..90d152d --- /dev/null +++ b/src/ui_txtwindow.c @@ -0,0 +1,187 @@ +#include <stdlib.h> +#include <string.h> + +#include "ui_txtwindow.h" + + +struct txtwindow * +init_txtwindow(unsigned int x, unsigned int y, unsigned int width, unsigned int height, window_func cb_update) +{ + struct txtwindow *a = calloc(1, sizeof(struct txtwindow)); + + a->x = x; + a->y = y; + a->width = width; + a->height = height; + a->active = false; + a->title_len = INITIAL_TITLE_LEN; + a->title = calloc(a->title_len+1, sizeof(char)); + a->text = NULL; + a->attrs = 0; + a->text_attrs = 0; + a->window_func = cb_update; + return (a); +} + +struct txtwindow * +init_txtwindow_centered(unsigned int width, unsigned int height, window_func cb_update) +{ + unsigned int x = (ui_get_maxx()/2)-(width/2); + unsigned int y = (ui_get_maxy()/2)-(height/2); + return init_txtwindow(x, y, width, height, cb_update); +} + +static void +__free_text(struct txtwindow *a) +{ + if (a->text) { + if (a->text[0]) { + free(a->text[0]); + } + free(a->text); + a->text = NULL; + } +} + +void +free_txtwindow(struct txtwindow *a) +{ + __free_text(a); + if (a->title) { + free(a->title); + } + free(a); +} + +static void +print_wnd(struct txtwindow *a) +{ + int i, x = a->x, y = a->y, w = a->width, h = a->height; + char tmp[a->width+1]; + + attron(a->attrs); + /* print window surface */ + memset(tmp, ' ', a->width); + tmp[a->width] = '\0'; + for (i = y-1; i < y+h+1; i++) + mvprintw(i, x, tmp); + /* print window border */ + mvhline(y-2, x, 0, w); + mvhline(y+h+1, x, 0, w); + mvvline(y-1, x-1, 0, h+3); + mvvline(y-1, x+w, 0, h+3); + /* print window border edges */ + mvaddch(y-2, x-1, ACS_ULCORNER); + mvaddch(y+1+h, x-1, ACS_LLCORNER); + mvaddch(y-2, x+w, ACS_URCORNER); + mvaddch(y+1+h, x+w, ACS_LRCORNER); + /* print window title */ + attroff(a->attrs); + attron(a->text_attrs); + mvprintw(y-2, x+(w/2)-((a->title_len+4)/2), "[ %s ]", a->title); + /* print windows text */ + i = -1; + if (a->text) { + while ( a->text[++i] ) { + mvprintw(y+i, x+1, a->text[i]); + } + } + attroff(a->text_attrs); +} + +static int +txtwindow_cb(WINDOW *win, void *data, bool timedout) +{ + struct txtwindow *a = (struct txtwindow *) data; + + if (a->active == true) { + print_wnd(a); + if (a->window_func) { + attron(a->text_attrs); + a->window_func(win, a, timedout); + attroff(a->text_attrs); + } + } + return (UICB_OK); +} + +void inline +register_txtwindow(struct txtwindow *a) +{ + struct ui_callbacks cbs; + cbs.ui_element = txtwindow_cb; + cbs.ui_input = NULL; + register_ui_elt(&cbs, (void *) a, NULL); +} + +static size_t +__do_textcpy(char **p_dest, size_t sz_dest, const char *p_src, size_t sz_src) +{ + size_t cursiz = sz_dest; + + if (sz_src > sz_dest) { + *p_dest = (char *) realloc(*p_dest, (sz_src+1) * sizeof(char)); + cursiz = sz_src; + } + memset(*p_dest, '\0', (cursiz+1) * sizeof(char)); + memcpy(*p_dest, p_src, (cursiz+1) * sizeof(char)); + return sz_src; +} + +/* seperate a String with NEWLINES into an array */ +static char ** +__do_textadjust(struct txtwindow *a, char *text) +{ + int i = 0, rows = (int)(strlen(text) / a->width); + char **adj_text = calloc(rows+2, sizeof(char *)); + char *p_strtok, *tok; + const char sep[] = "\n"; + + if (rows > a->height) goto error; + p_strtok = strdup(text); + do { + tok = strsep(&p_strtok, sep); + if (strlen(tok) > a->width) { + strcpy(tok+a->width-3, "..."); + *(tok+a->width) = '\0'; + } + adj_text[i] = tok; + i++; + } while (rows > 0); + return adj_text; +error: + free(adj_text); + return NULL; +} + +void +set_txtwindow_text(struct txtwindow *a, char *text) +{ + char **fmt_text = __do_textadjust(a, text); + + if (fmt_text) { + __free_text(a); + a->text = fmt_text; + } +} + +void +set_txtwindow_title(struct txtwindow *a, const char *title) +{ + a->title_len = __do_textcpy(&a->title, a->title_len, title, strlen(title)); +} + +void +set_txtwindow_color(struct txtwindow *a, chtype wnd, chtype txt) +{ + a->attrs = wnd; + a->text_attrs = txt; +} + +void +set_txtwindow_dim(struct txtwindow *a, unsigned int w, unsigned int h) +{ + a->width = w; + a->height = h; +} + |