--- uae/src/svgancui.c 2018/04/24 16:39:07 1.1.1.2 +++ uae/src/svgancui.c 2018/04/24 16:40:01 1.1.1.3 @@ -25,6 +25,10 @@ #include "uae.h" #include "tui.h" +#ifdef DONT_HAVE_ATTR_T +typedef int attr_t; +#endif + static WINDOW *currwin; static WINDOW *winstack[10]; /* more than enough */ @@ -33,7 +37,7 @@ static int winnr = 0; void tui_setup(void) { int i; - + for (i = 0; i < 10; i++) winstack[i] = NULL; /* From the ncurses manpage... */ @@ -45,7 +49,7 @@ void tui_setup(void) wattron(currwin, COLOR_PAIR(1) | A_BOLD); wbkgd(currwin, ' '|COLOR_PAIR(1)); } - + winstack[0] = stdscr; winnr = 1; } @@ -145,7 +149,7 @@ void tui_dlogdie(int w) winstack[w] = NULL; while (winstack[winnr-1] == NULL) winnr--; - + for (w = 0; w < winnr; w++) redrawwin(winstack[w]), wrefresh(winstack[w]); } @@ -165,7 +169,7 @@ int tui_gets(char *buf, int x, int y, in wmove(currwin, y, x + i); wrefresh(currwin); - + c = getch(); wmove(currwin, y, x + i); @@ -195,15 +199,22 @@ int tui_wgets(char *buf, const char *tit return result; } -int tui_menubrowse(struct bstring *menu, int xoff, int yoff, int selected) +int tui_menubrowse(struct bstring *menu, int xoff, int yoff, int selected, int height) { int count = 0, maxsel = 0, maxw = 0; - int i, j, w; + int i, j, w, s, yp, oldyp; + chtype moresave[6][2]; + int xpos, ypos; const char *mtitle = NULL; - + for (i = 0; menu[i].val != -3; i++) { int tmp; + if (menu[i].val == -4) { + if (maxsel < selected) + selected--; + continue; + } if (menu[i].val != 0) { count++; if (menu[i].val != -2) @@ -213,40 +224,67 @@ int tui_menubrowse(struct bstring *menu, if ((tmp = strlen(menu[i].data)) > maxw) maxw = tmp; } + if (height > count) + height = count; maxw += 3; - w = tui_dlog(xoff, yoff, xoff+maxw, yoff+count+1); + if (strlen(mtitle ? mtitle : "") + 8 > maxw) + maxw = strlen(mtitle ? mtitle : "") + 8; + if (xoff > 0) + xpos = xoff; + else + xpos = tui_cols() + xoff - maxw - 1; + if (yoff > 0) + ypos = yoff; + else + ypos = tui_lines() + yoff - height - 2; + w = tui_dlog(xpos, ypos, xpos+maxw, ypos+height+1); tui_selwin(w); tui_drawbox(w); if (mtitle != NULL) { - wmove(currwin, 0, 1); - waddstr(currwin, mtitle); + mvwaddstr(currwin, 0, 1, mtitle); } - + for (i = 0; i < 6; i++) { + moresave[i][0] = mvwinch(currwin, 0, maxw-6+i); + moresave[i][1] = mvwinch(currwin, height+1, maxw-6+i); + } + s = yp = 0; oldyp = -1; for (;;) { int c; int s2; - - for (i = j = s2 = 0; i < count; i++, j++) { + + while (selected < yp) + yp--; + while (selected >= yp + height) + yp++; + if (yp == 0) + for (i = 0; i < 6; i++) + mvwaddch(currwin, 0, maxw-6+i, moresave[i][0]); + else + mvwaddstr(currwin, 0, maxw-6, "(more)"); + if (yp + height == count) + for (i = 0; i < 6; i++) + mvwaddch(currwin, height+1, maxw-6+i, moresave[i][1]); + else + mvwaddstr(currwin, height+1, maxw-6, "(more)"); + for (i = s2 = j = 0; i < count; i++, j++) { int k, x; attr_t a = s2 == selected ? A_STANDOUT : 0; - - while (menu[j].val == 0) + while (menu[j].val == 0 || menu[j].val == -4) j++; - wmove(currwin, 1+i, 1); - waddch(currwin, ' ' | a); - for (k = x = 0; menu[j].data[k]; k++, x++) { - int a2 = 0; - c = menu[j].data[k]; - if (c == '_') - c = menu[j].data[++k], a2 = A_UNDERLINE; - wmove(currwin, 1+i, 2+x); - waddch(currwin, c | a | a2); - } - for (; x < maxw-2; x++) { - wmove(currwin, 1+i, 2+x); - waddch(currwin, ' ' | a); + if (i >= yp && i < yp+height) { + mvwaddch(currwin, 1+i-yp, 1, ' ' | a); + for (k = x = 0; menu[j].data[k]; k++, x++) { + int a2 = 0; + c = menu[j].data[k]; + if (c == '_') + c = menu[j].data[++k], a2 = A_UNDERLINE; + mvwaddch(currwin, 1+i-yp, 2+x, c | a | a2); + } + for (; x < maxw-2; x++) { + mvwaddch(currwin, 1+i-yp, 2+x, ' ' | a); + } } - if (menu[j].val != -1) + if (menu[j].val != -2) s2++; } @@ -257,7 +295,18 @@ int tui_menubrowse(struct bstring *menu, return -1; } else if (c == KEY_ENTER || c == 13 || c == ' ') { tui_dlogdie(w); - return selected; + for (i = s2 = j = 0; s2 <= selected; j++) { + if (menu[j].val == -4) { + i++; j++; continue; + } + while (menu[j].val == 0) + j++; + if (s2 == selected) + return i; + if (menu[j].val != -2) + s2++, i++; + } + abort(); } else switch (c) { case KEY_UP: if (selected > 0) @@ -268,17 +317,23 @@ int tui_menubrowse(struct bstring *menu, selected++; break; case KEY_PPAGE: - selected = 0; + if (selected > height) + selected -= height; + else + selected = 0; break; case KEY_NPAGE: - selected = count - 1; + if (selected + height < count) + selected += height; + else + selected = count-1; break; default: - for (j = i = 0; menu[i].val != -3; i++) + for (j = i = 0; menu[i].val != -3; i++) if (menu[i].val == toupper(c)) { tui_dlogdie(w); return j; - } else if (menu[i].val == -1 || menu[i].val > 0) { + } else if (menu[i].val == -1 || menu[i].val == -4 || menu[i].val > 0) { j++; } @@ -296,14 +351,14 @@ void tui_errorbox(const char *err) int ww = (l > n ? l : n) + 2; int w = tui_dlog((tui_cols()-ww)/2, tui_lines()/2-1, (tui_cols()+ww)/2, tui_lines()/2+1); tui_selwin(w); tui_drawbox(w); - + wmove(currwin, 0, (ww-6)/2); waddstr(currwin, "Error!"); wmove(currwin, 1, (ww-l)/2); waddstr(currwin, err); wmove(currwin, 2, (ww-n)/2); waddstr(currwin, hak); - + wrefresh(currwin); for (;;) { int c = getch(); @@ -354,12 +409,19 @@ static int selectfn(const struct dirent return 1; } -char *tui_filereq(char *s, char *oldfile) +static int my_alphasort (const void *a, const void *b) +{ + return strcmp ((*(struct dirent **) a)->d_name, + (*(struct dirent **) b)->d_name); +} + +char *tui_filereq(char *s, char *oldfile, const char *title) { char cwd[256]; char *retval = fsbuf; char *tmp; int fin = 0; + chtype moresave[6][2]; /* Save wd */ if (getcwd(cwd, 256) == NULL) @@ -373,7 +435,7 @@ char *tui_filereq(char *s, char *oldfile if (strlen(fsbuf) > 0) chdir(fsbuf); } - + pattern = s; if (s[0] != '*') fprintf(stderr, "Can't handle wildcard %s\n", s); @@ -382,18 +444,26 @@ char *tui_filereq(char *s, char *oldfile for (;!fin;) { struct dirent **names; int i, w, n, l, yp, oldyp, s; - + maxlen = 0; - n = scandir(".", &names, selectfn, alphasort); - + n = scandir(".", &names, selectfn, my_alphasort); + if (n <= 0) return NULL; + if (title != NULL && strlen(title) + 6 > maxlen) + maxlen = strlen(title) + 6; l = n; if (l > 15) l = 15; yp = s = 0; oldyp = -1; - w = tui_dlog(5, 5, 5 + maxlen + 3, 5 + l + 1); + w = tui_dlog(tui_cols() - maxlen - 8, 5, tui_cols() - 5, 5 + l + 1); tui_selwin(w); tui_drawbox(w); + if (title) + mvwaddstr(currwin, 0, 2, title); + for (i = 0; i < 6; i++) { + moresave[i][0] = mvwinch(currwin, 0, maxlen-3+i); + moresave[i][1] = mvwinch(currwin, l+1, maxlen-3+i); + } for (;;) { int c; char tmp[256]; @@ -408,6 +478,18 @@ char *tui_filereq(char *s, char *oldfile } } put_filename(names[s]->d_name, 3, 2 + s - yp, A_STANDOUT); + + if (yp == 0) + for (i = 0; i < 6; i++) + mvwaddch(currwin, 0, maxlen-3+i, moresave[i][0]); + else + mvwaddstr(currwin, 0, maxlen-3, "(more)"); + if (yp + l == n) + for (i = 0; i < 6; i++) + mvwaddch(currwin, l+1, maxlen-3+i, moresave[i][1]); + else + mvwaddstr(currwin, l+1, maxlen-3, "(more)"); + tui_refresh(); c = getch(); put_filename(names[s]->d_name, 3, 2 + s - yp, 0); @@ -416,14 +498,14 @@ char *tui_filereq(char *s, char *oldfile break; } else if (c == KEY_ENTER || c == 13 || c == ' ') { int err; - + if (strcmp(names[s]->d_name, ".") == 0) { fin = 1; strcpy(fsbuf, ""); break; } err = chdir(names[s]->d_name); - + if (err == 0) break; else if (errno == ENOTDIR) { @@ -461,17 +543,24 @@ char *tui_filereq(char *s, char *oldfile s = n - 1; break; default: - for (i = 0; i < n; i++) - if (names[i]->d_name[0] == c) { - s = i; + i = 0; + if (names[s]->d_name[0] == c) + i = s+1; + for (; i < n*2; i++) { + int j = i; + if (i >= n) + j -= n; + if (names[j]->d_name[0] == c) { + s = j; break; } + } } } #if 0 /* @@@ is this right? */ for (i = 0; i < n; i++) - free(names[i]->d_name); + free(names[i]); free(names); #endif tui_dlogdie(w);