static void lua_paint_info(struct window *wnd, const struct state *st) { struct lua_State *L = paint_state; int nx = st->cursor.x, ny = st->cursor.y; pnormalize(&nx, &ny, st->cursor.pl); lua_rawgeti(L, LUA_REGISTRYINDEX, paint_handle); lua_pushinteger(L, nx); lua_pushinteger(L, ny); if (lua_pcall(L, 2, 1, 0) != 0) { const char *error = lua_tostring(L, -1); log_error("paint function failed: %s\n", error); lua_pop(L, 1); tolua_error(L, TOLUA_CAST "event handler call failed", NULL); } else { const char *result = lua_tostring(L, -1); WINDOW *win = wnd->handle; int size = getmaxx(win) - 2; int line = 0, maxline = getmaxy(win) - 2; const char *str = result; wxborder(win); while (*str && line < maxline) { const char *end = strchr(str, '\n'); if (!end) break; else { int bytes = (int)(end - str); if (bytes < size) bytes = size; mvwaddnstr(win, line++, 1, str, bytes); wclrtoeol(win); str = end + 1; } } } }
list_selection *do_selection(list_selection * sel, const char *title, void (*perform) (list_selection *, void *), void *data) { WINDOW *wn; bool update = true; list_selection *s; list_selection *top = sel; list_selection *current = top; int i; int height = 0, width = (int)strlen(title) + 8; for (s = sel; s; s = s->next) { if ((int)strlen(s->str) > width) { width = (int)strlen(s->str); } ++height; if (verbosity >= 5) { log_printf(stdout, "s %s w %d h %d\n", s->str, width, height); } } if (height == 0 || width == 0) return 0; if (width + 3 > SX) width = SX - 4; if (height + 2 > SY) height = SY - 2; if (verbosity >= 5) log_printf(stdout, "w %d h %d\n", width, height); wn = newwin(height + 2, width + 4, (SY - height - 2) / 2, (SX - width - 4) / 2); for (;;) { int input; if (update) { for (s = top; s != NULL && top->index + height != s->index; s = s->next) { i = s->index - top->index; wmove(wn, i + 1, 4); waddnstr(wn, s->str, -1); wclrtoeol(wn); } wclrtobot(wn); wxborder(wn); mvwprintw(wn, 0, 2, "[ %s ]", title); update = false; } i = current->index - top->index; wattron(wn, A_BOLD | COLOR_PAIR(COLOR_YELLOW)); wmove(wn, i + 1, 2); waddstr(wn, "->"); wmove(wn, i + 1, 4); waddnstr(wn, current->str, width - 2); wattroff(wn, A_BOLD | COLOR_PAIR(COLOR_YELLOW)); wrefresh(wn); input = getch(); wmove(wn, i + 1, 2); waddstr(wn, " "); wmove(wn, i + 1, 4); waddnstr(wn, current->str, width); switch (input) { case KEY_NPAGE: for (i = 0; i != height / 2; ++i) { if (current->next) { current = current->next; if (current->index - height >= top->index) { top = current; update = true; } } } break; case KEY_PPAGE: for (i = 0; i != height / 2; ++i) { if (current->prev) { if (current == top) { top = sel; while (top->index + height < current->index) top = top->next; update = true; } current = current->prev; } } break; case KEY_DOWN: if (current->next) { current = current->next; if (current->index - height >= top->index) { top = current; update = true; } } break; case KEY_UP: if (current->prev) { if (current == top) { top = sel; while (top->index + height < current->index) top = top->next; update = true; } current = current->prev; } break; case 27: case 'q': delwin(wn); return NULL; case 10: case 13: if (perform) perform(current, data); else { delwin(wn); return current; } break; default: s = current->next; if (s == NULL) s = top; while (s != current) { if (tolower(s->str[0]) == tolower(input)) { current = s; update = true; } else { s = s->next; if (s == NULL) s = top; } } if (current->index - height >= top->index) { top = current; update = true; } } } }