/* select box Written by Matthias Hensler Copyright WSPse 1999+2000 eMail: wsp@gmx.de Created: 1999/06/08 Updated: 2000/03/23 */ /* Copying: This program is free software; you can redistribute it and/or modify it under the terms of the GNU Gerneral Public License as published by the Free Soft- ware Foundation; either version 2 of License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include "mp3creat.h" extern char *mp3_genre[]; extern void wuuush(int); extern WINDOW *c_newwin(int h, int l, int y, int x, void *proc, int arg1, int arg2); extern int set_active_win(WINDOW *win); extern void c_delwin(WINDOW *win); extern void free_field_select(field_select_typ **anchor); extern void store_win_poi(WINDOW *win, void *pointer); extern void *pop_win_poi(WINDOW *win); extern void win_effect(WINDOW *win, BOOL e_refresh, BOOL save_coor); extern char *copy_char_str(char *old); extern char config_fancy_colors; extern BOOL careful_batch; extern char *def_unknown_gen; field_select_typ *top_an, *curr_an; int curr_line; int sb_pressed_key; void build_win(WINDOW *fs_win, char *tx, int i) { chtype old_ch; int maxx, maxy; int j; int pos; getmaxyx(stdscr, maxy, maxx); j = (maxy)>>1; wclear(fs_win); wbkgd(fs_win, COLOR_PAIR(1) | A_BOLD); box(fs_win, 0, 0); old_ch = getbkgd(fs_win); wbkgdset(fs_win, COLOR_PAIR(2) | A_BOLD); pos = i-strlen(tx); if(pos < 2) pos=2; mvwaddnstr(fs_win, 0, pos>>1, tx, i-2); } void sign_line(field_select_typ *elem, int len, BOOL marked, int line, WINDOW *fs_win) { chtype old_ch; int maxy, maxx; int remain_len; chtype col_1, col_2; getmaxyx(stdscr, maxy, maxx); old_ch = getbkgd(fs_win); if(marked) { col_1 = COLOR_PAIR(3); col_2 = COLOR_PAIR(4) | A_BOLD; } else { col_1 = COLOR_PAIR(1); col_2 = COLOR_PAIR(2) | A_BOLD; } wbkgdset(fs_win, col_1); wmove(fs_win, line, 1); whline(fs_win, ' ', len); waddnstr(fs_win, elem->field, len); if(elem->dest) { remain_len = len - strlen(elem->field); waddnstr(fs_win, " [", remain_len); remain_len -= 2; wbkgdset(fs_win, col_2); waddnstr(fs_win, elem->dest, remain_len); wbkgdset(fs_win, col_1); remain_len -= strlen(elem->dest); if(remain_len > 0) waddch(fs_win, ']'); } wbkgdset(fs_win, old_ch); } void fill_lines(int len, WINDOW *fs_win) { int maxy, maxx; int i,j; field_select_typ *curr; getmaxyx(stdscr, maxy, maxx); j = maxy>>1; curr = top_an; i = 1; while((curr != NULL) && (i <= j)) { if(curr == curr_an) sign_line(curr, len, TRUE, i, fs_win); else sign_line(curr, len, FALSE, i, fs_win); i++; curr = curr->next; } } void rebuild(WINDOW *fs_win, int i, int i2) { int maxy, maxx; int j; getmaxyx(stdscr, maxy, maxx); j = (maxy>>1); if(i2 && j > i2) j = i2; wresize(fs_win, j+2, i+2); maxx = (maxx-(i+2))>>1; maxy = (maxy-(j+2))>>1; mvwin(fs_win, maxy, maxx); build_win(fs_win, pop_win_poi(fs_win), i); fill_lines(i, fs_win); wrefresh(fs_win); } void do_pos1(int len, int height, WINDOW *fs_win) { if(curr_line != 1) { sign_line(curr_an, len, FALSE, curr_line, fs_win); curr_an = top_an; curr_line = 1; sign_line(curr_an, len, TRUE, curr_line, fs_win); wrefresh(fs_win); return; } if(top_an->prev) { while(top_an->prev) top_an = top_an->prev; curr_an = top_an; fill_lines(len, fs_win); wrefresh(fs_win); } return; } void do_end(int len, int height, WINDOW *fs_win) { if(curr_an->next == NULL) return; if(curr_line != height) { sign_line(curr_an, len, FALSE, curr_line, fs_win); while(curr_line != height) { curr_an = curr_an->next; curr_line++; if(curr_an->next == NULL) break; } sign_line(curr_an, len, TRUE, curr_line, fs_win); } else { while(curr_an->next != NULL) { curr_an = curr_an->next; top_an = top_an->next; } fill_lines(len, fs_win); } wrefresh(fs_win); } void do_ppage(int len, int height, WINDOW *fs_win) { int i; if(top_an->prev == NULL) { if(curr_line != 1) do_pos1(len, height, fs_win); return; } for(i=0;iprev != NULL) { top_an = top_an->prev; curr_an = curr_an->prev; } else if(curr_line == 1) break; else { curr_line--; curr_an = curr_an->prev; } } fill_lines(len, fs_win); wrefresh(fs_win); } void do_npage(int len, int height, WINDOW *fs_win) { int i; BOOL fill; if(curr_an->next == NULL) return; fill = FALSE; sign_line(curr_an, len, FALSE, curr_line, fs_win); for(i=0;inext == NULL) break; if(curr_line != height) { curr_an = curr_an->next; curr_line++; } else { fill = TRUE; curr_an = curr_an->next; top_an = top_an->next; } } if(! fill) sign_line(curr_an, len, TRUE, curr_line, fs_win); else fill_lines(len, fs_win); wrefresh(fs_win); } field_select_typ *select_field_box(field_select_typ *fs_anchor, int max_length, char *stat_text, BOOL use_old, BOOL allow_space) { int i, j, i2; int maxx, maxy; int inp_ch; WINDOW *fs_win; field_select_typ *curr; sb_pressed_key = 0; if(careful_batch) return NULL; /* No select tree ---> no select box ---> no result */ if(fs_anchor == NULL) return NULL; getmaxyx(stdscr, maxy, maxx); i = max_length+2; if(i>maxx) i = maxx; j = (maxy)>>1; i2 = 0; curr = fs_anchor; while(curr) { i2++; curr = curr->next; } if(i2 && j > i2) j = i2; fs_win = c_newwin(j+2, i, (maxy-(j+2))>>1, (maxx-i)>>1, rebuild, i-2, i2); store_win_poi(fs_win, stat_text); i -= 2; build_win(fs_win, stat_text, i); if(use_old) { if((! top_an) || (! curr_an)) use_old = FALSE; if(curr_line > (maxy>>1)) use_old = FALSE; } if(! use_old) { top_an = fs_anchor; curr_an = fs_anchor; curr_line = 1; } fill_lines(i, fs_win); wrefresh(fs_win); cbreak(); noecho(); keypad(fs_win, TRUE); if(config_fancy_colors) halfdelay(1); else nodelay(fs_win, FALSE); while(1) { inp_ch = wgetch(fs_win); if(config_fancy_colors) win_effect(fs_win, TRUE, FALSE); getmaxyx(stdscr, maxy, maxx); j = (maxy)>>1; switch(inp_ch) { case '\n': case '\r': case KEY_ENTER: c_delwin(fs_win); return curr_an; break; case ' ': if(allow_space) { c_delwin(fs_win); sb_pressed_key = inp_ch; return curr_an; } break; case 27: case 'q': case 'Q': case KEY_F(12): case '\'': c_delwin(fs_win); return NULL; break; case ' ': set_active_win(fs_win); break; case KEY_DOWN: if(curr_an->next) { sign_line(curr_an, i, FALSE, curr_line, fs_win); if(curr_line < j) { curr_line++; curr_an = curr_an->next; sign_line(curr_an, i, TRUE, curr_line, fs_win); } else { top_an = top_an->next; curr_an = curr_an->next; fill_lines(i, fs_win); } wrefresh(fs_win); } break; case KEY_UP: if(curr_an->prev) { sign_line(curr_an, i, FALSE, curr_line, fs_win); if(curr_line > 1) { curr_line--; curr_an = curr_an->prev; sign_line(curr_an, i, TRUE, curr_line, fs_win); } else { top_an = top_an->prev; curr_an = curr_an->prev; fill_lines(i, fs_win); } wrefresh(fs_win); } break; case KEY_PPAGE: do_ppage(i,j, fs_win); break; case KEY_NPAGE: do_npage(i,j, fs_win); break; case KEY_HOME: case 362: do_pos1(i,j, fs_win); break; case KEY_END: case 385: do_end(i,j, fs_win); break; } } } int select_genre() { int i; field_select_typ *new, *anchor; char *tmp; anchor = NULL; for(i=TOT_GENRES;i>=0;i--) { new = (field_select_typ *) malloc(sizeof(field_select_typ)); if(new == NULL) { perror("malloc"); wuuush(1); } new->dest = NULL; tmp = (char *) malloc(sizeof(char)); if(tmp == NULL) { perror("malloc"); wuuush(1); } *tmp = (unsigned char) i; new->information = tmp; if(i == TOT_GENRES) { new->field = copy_char_str(def_unknown_gen); } else { new->field = copy_char_str(mp3_genre[i]); } new->prev = NULL; new->next = anchor; if(anchor) anchor->prev = new; anchor = new; } new = select_field_box(anchor, 25, _("select genre"), FALSE, FALSE); if(new) i = (int) ((unsigned char) *(new->information)); else i = -1; free_field_select(&anchor); return i; } BOOL ynb_field; void ynb_show(WINDOW *win, BOOL flag) { int maxy, maxx; chtype old_ch; int i; getmaxyx(win, maxy, maxx); old_ch = getbkgd(win); if(flag) wbkgdset(win, COLOR_PAIR(4) | A_BOLD); else wbkgdset(win, COLOR_PAIR(1)); i = 1 + ((maxx-12)>>2); mvwaddstr(win, 2, i, _("[Yes]")); if(flag) wbkgdset(win, COLOR_PAIR(1)); else wbkgdset(win, COLOR_PAIR(4) | A_BOLD); i = 1 + ((maxx-12)>>2); mvwaddstr(win, 2, maxx-i-4, _("[No]")); wbkgdset(win, old_ch); wrefresh(win); } void ynb_build(WINDOW *win, int dum1, int dum2) { int maxy, maxx; int i; char *tx; getmaxyx(stdscr, maxy, maxx); tx = pop_win_poi(win); i = 0; if(tx) i = strlen(tx)+2; if(i < 12) i = 12; if(i > maxx) i = maxx; mvwin(win, (maxy-4)>>1, (maxx-i)>>1); wresize(win, 4, i); wbkgd(win, COLOR_PAIR(1) | A_BOLD); wclear(win); box(win,0,0); if(tx) { i = (i-1) - strlen(tx); if(i<0) i = 0; i = (i>>1); mvwaddnstr(win, 1, i+1, tx, maxx-2); } ynb_show(win, ynb_field); } /* select yes/no. */ BOOL select_yesno_box(char *tx) { WINDOW *ynb_win; int maxy, maxx; int inp_ch; if(careful_batch) return TRUE; ynb_field = FALSE; getmaxyx(stdscr, maxy, maxx); inp_ch = 0; if(tx) inp_ch = strlen(tx) + 2; if(inp_ch < 12) inp_ch = 12; if(inp_ch > maxx) inp_ch = maxx; ynb_win = c_newwin((maxy-4)>>1, (maxx-inp_ch)>>1, 4, inp_ch, ynb_build, 0, 0); store_win_poi(ynb_win, tx); ynb_build(ynb_win, 0, 0); cbreak(); noecho(); keypad(ynb_win, TRUE); if(config_fancy_colors) halfdelay(1); else nodelay(ynb_win, FALSE); while(1) { inp_ch = wgetch(ynb_win); if(config_fancy_colors) win_effect(ynb_win, TRUE, FALSE); if(strchr(_("yY"), inp_ch)) inp_ch = 'y'; else if(strchr(_("nN"), inp_ch)) inp_ch = 'n'; switch(inp_ch) { case '\t': case KEY_RIGHT: case KEY_LEFT: case KEY_DOWN: case KEY_UP: if(ynb_field) ynb_field = FALSE; else ynb_field = TRUE; ynb_show(ynb_win, ynb_field); break; case 27: case KEY_F(12): case '\'': c_delwin(ynb_win); return FALSE; break; case KEY_ENTER: case '\n': case '\r': c_delwin(ynb_win); return ynb_field; break; case 'y': c_delwin(ynb_win); return TRUE; break; case 'n': c_delwin(ynb_win); return FALSE; } } }