server/src/listbox.c
Enno Rehling 28726e2bea update cmake to compile without sqlite3, curses or libxml2 installed.
This is not actually recommended, but your system may not have
this,and you should still be able to contribute. also, libxml2 is on
the way out, I am beginning to really hate it.

Moving a couple of files around.
2014-06-11 20:30:34 -07:00

216 lines
5.2 KiB
C

/* vi: set ts=2:
* +-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
* | | Enno Rehling <enno@eressea.de>
* | Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
* | (c) 1998 - 2006 |
* | | This program may not be used, modified or distributed
* +-------------------+ without prior permission by the authors of Eressea.
*
*/
/* wenn platform.h nicht vor curses included wird, kompiliert es unter windows nicht */
#include <platform.h>
#include <curses.h>
#include <kernel/config.h>
#include "listbox.h"
#include "gmtool_structs.h"
#include <util/log.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void
insert_selection(list_selection ** p_sel, list_selection * prev,
const char *str, void *payload)
{
list_selection *sel = calloc(sizeof(list_selection), 1);
sel->str = _strdup(str);
sel->data = payload;
if (*p_sel) {
list_selection *s;
sel->next = *p_sel;
sel->prev = sel->next->prev;
sel->next->prev = sel;
if (sel->prev) {
sel->prev->next = sel;
sel->index = sel->prev->index + 1;
}
for (s = sel->next; s; s = s->next) {
s->index = s->prev->index + 1;
}
*p_sel = sel;
} else {
*p_sel = sel;
sel->prev = prev;
if (prev)
sel->index = prev->index + 1;
}
}
list_selection **push_selection(list_selection ** p_sel, char *str,
void *payload)
{
list_selection *sel = calloc(sizeof(list_selection), 1);
list_selection *prev = NULL;
sel->str = str;
sel->data = payload;
while (*p_sel) {
prev = *p_sel;
p_sel = &prev->next;
}
*p_sel = sel;
if (prev) {
sel->prev = prev;
sel->index = prev->index + 1;
}
return p_sel;
}
#define SX (getmaxx(stdscr))
#define SY (getmaxy(stdscr))
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;
}
}
}
}