yann@2454: /* yann@2454: * Copyright (C) 2008 Nir Tzachar 0) yann@2454: win_rows = msg_lines+4; yann@2454: else yann@2454: win_rows = msg_lines+2; yann@2454: yann@2454: win = newwin(win_rows, total_width+4, y, x); yann@2454: keypad(win, TRUE); yann@2454: menu_win = derwin(win, 1, btns_width, win_rows-2, yann@2454: 1+(total_width+2-btns_width)/2); yann@2454: menu = new_menu(btns); yann@2454: msg_win = derwin(win, win_rows-2, msg_width, 1, yann@2454: 1+(total_width+2-msg_width)/2); yann@2454: yann@2454: set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); yann@2454: set_menu_back(menu, attributes[DIALOG_MENU_BACK]); yann@2454: yann@2454: (void) wattrset(win, attributes[DIALOG_BOX]); yann@2454: box(win, 0, 0); yann@2454: yann@2454: /* print message */ yann@2454: (void) wattrset(msg_win, attributes[DIALOG_TEXT]); yann@2454: fill_window(msg_win, msg); yann@2454: yann@2454: set_menu_win(menu, win); yann@2454: set_menu_sub(menu, menu_win); yann@2454: set_menu_format(menu, 1, btn_num); yann@2454: menu_opts_off(menu, O_SHOWDESC); yann@2454: menu_opts_off(menu, O_SHOWMATCH); yann@2454: menu_opts_on(menu, O_ONEVALUE); yann@2454: menu_opts_on(menu, O_NONCYCLIC); yann@2454: set_menu_mark(menu, ""); yann@2454: post_menu(menu); yann@2454: yann@2454: yann@2454: touchwin(win); yann@2454: refresh_all_windows(main_window); yann@2454: while ((res = wgetch(win))) { yann@2454: switch (res) { yann@2454: case KEY_LEFT: yann@2454: menu_driver(menu, REQ_LEFT_ITEM); yann@2454: break; yann@2454: case KEY_RIGHT: yann@2454: menu_driver(menu, REQ_RIGHT_ITEM); yann@2454: break; yann@2454: case 10: /* ENTER */ yann@2454: case 27: /* ESCAPE */ yann@2454: case ' ': yann@2454: case KEY_F(F_BACK): yann@2454: case KEY_F(F_EXIT): yann@2454: break; yann@2454: } yann@2454: touchwin(win); yann@2454: refresh_all_windows(main_window); yann@2454: yann@2454: if (res == 10 || res == ' ') { yann@2454: res = item_index(current_item(menu)); yann@2454: break; yann@2454: } else if (res == 27 || res == KEY_F(F_BACK) || yann@2454: res == KEY_F(F_EXIT)) { yann@2454: res = KEY_EXIT; yann@2454: break; yann@2454: } yann@2454: } yann@2454: yann@2454: unpost_menu(menu); yann@2454: free_menu(menu); yann@2454: for (i = 0; i < btn_num; i++) yann@2454: free_item(btns[i]); yann@2454: yann@2454: delwin(win); yann@2454: return res; yann@2454: } yann@2454: yann@2454: int dialog_inputbox(WINDOW *main_window, yann@2454: const char *title, const char *prompt, yann@2454: const char *init, char *result, int result_len) yann@2454: { yann@2454: int prompt_lines = 0; yann@2454: int prompt_width = 0; yann@2454: WINDOW *win; yann@2454: WINDOW *prompt_win; yann@2454: WINDOW *form_win; yann@2454: PANEL *panel; yann@2454: int i, x, y; yann@2454: int res = -1; yann@2454: int cursor_position = strlen(init); yann@2454: yann@2454: yann@2454: /* find the widest line of msg: */ yann@2454: prompt_lines = get_line_no(prompt); yann@2454: for (i = 0; i < prompt_lines; i++) { yann@2454: const char *line = get_line(prompt, i); yann@2454: int len = get_line_length(line); yann@2454: prompt_width = max(prompt_width, len); yann@2454: } yann@2454: yann@2454: if (title) yann@2454: prompt_width = max(prompt_width, strlen(title)); yann@2454: yann@2454: /* place dialog in middle of screen */ yann@2454: y = (LINES-(prompt_lines+4))/2; yann@2454: x = (COLS-(prompt_width+4))/2; yann@2454: yann@2454: strncpy(result, init, result_len); yann@2454: yann@2454: /* create the windows */ yann@2454: win = newwin(prompt_lines+6, prompt_width+7, y, x); yann@2454: prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2); yann@2454: form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); yann@2454: keypad(form_win, TRUE); yann@2454: yann@2454: (void) wattrset(form_win, attributes[INPUT_FIELD]); yann@2454: yann@2454: (void) wattrset(win, attributes[INPUT_BOX]); yann@2454: box(win, 0, 0); yann@2454: (void) wattrset(win, attributes[INPUT_HEADING]); yann@2454: if (title) yann@2454: mvwprintw(win, 0, 3, "%s", title); yann@2454: yann@2454: /* print message */ yann@2454: (void) wattrset(prompt_win, attributes[INPUT_TEXT]); yann@2454: fill_window(prompt_win, prompt); yann@2454: yann@2454: mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); yann@2454: mvwprintw(form_win, 0, 0, "%s", result); yann@2454: yann@2454: /* create panels */ yann@2454: panel = new_panel(win); yann@2454: yann@2454: /* show the cursor */ yann@2454: curs_set(1); yann@2454: yann@2454: touchwin(win); yann@2454: refresh_all_windows(main_window); yann@2454: while ((res = wgetch(form_win))) { yann@2454: int len = strlen(result); yann@2454: switch (res) { yann@2454: case 10: /* ENTER */ yann@2454: case 27: /* ESCAPE */ yann@2454: case KEY_F(F_HELP): yann@2454: case KEY_F(F_EXIT): yann@2454: case KEY_F(F_BACK): yann@2454: break; yann@2454: case 127: yann@2454: case KEY_BACKSPACE: yann@2454: if (cursor_position > 0) { yann@2454: memmove(&result[cursor_position-1], yann@2454: &result[cursor_position], yann@2454: len-cursor_position+1); yann@2454: cursor_position--; yann@2454: } yann@2454: break; yann@2454: case KEY_DC: yann@2454: if (cursor_position >= 0 && cursor_position < len) { yann@2454: memmove(&result[cursor_position], yann@2454: &result[cursor_position+1], yann@2454: len-cursor_position+1); yann@2454: } yann@2454: break; yann@2454: case KEY_UP: yann@2454: case KEY_RIGHT: yann@2454: if (cursor_position < len && yann@2454: cursor_position < min(result_len, prompt_width)) yann@2454: cursor_position++; yann@2454: break; yann@2454: case KEY_DOWN: yann@2454: case KEY_LEFT: yann@2454: if (cursor_position > 0) yann@2454: cursor_position--; yann@2454: break; yann@2454: default: yann@2454: if ((isgraph(res) || isspace(res)) && yann@2454: len-2 < result_len) { yann@2454: /* insert the char at the proper position */ yann@2454: memmove(&result[cursor_position+1], yann@2454: &result[cursor_position], yann@2454: len+1); yann@2454: result[cursor_position] = res; yann@2454: cursor_position++; yann@2454: } else { yann@2454: mvprintw(0, 0, "unknow key: %d\n", res); yann@2454: } yann@2454: break; yann@2454: } yann@2454: wmove(form_win, 0, 0); yann@2454: wclrtoeol(form_win); yann@2454: mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); yann@2454: mvwprintw(form_win, 0, 0, "%s", result); yann@2454: wmove(form_win, 0, cursor_position); yann@2454: touchwin(win); yann@2454: refresh_all_windows(main_window); yann@2454: yann@2454: if (res == 10) { yann@2454: res = 0; yann@2454: break; yann@2454: } else if (res == 27 || res == KEY_F(F_BACK) || yann@2454: res == KEY_F(F_EXIT)) { yann@2454: res = KEY_EXIT; yann@2454: break; yann@2454: } else if (res == KEY_F(F_HELP)) { yann@2454: res = 1; yann@2454: break; yann@2454: } yann@2454: } yann@2454: yann@2454: /* hide the cursor */ yann@2454: curs_set(0); yann@2454: del_panel(panel); yann@2454: delwin(prompt_win); yann@2454: delwin(form_win); yann@2454: delwin(win); yann@2454: return res; yann@2454: } yann@2454: yann@2454: /* refresh all windows in the correct order */ yann@2454: void refresh_all_windows(WINDOW *main_window) yann@2454: { yann@2454: update_panels(); yann@2454: touchwin(main_window); yann@2454: refresh(); yann@2454: } yann@2454: yann@2454: /* layman's scrollable window... */ yann@2454: void show_scroll_win(WINDOW *main_window, yann@2454: const char *title, yann@2454: const char *text) yann@2454: { yann@2454: int res; yann@2454: int total_lines = get_line_no(text); yann@2454: int x, y; yann@2454: int start_x = 0, start_y = 0; yann@2454: int text_lines = 0, text_cols = 0; yann@2454: int total_cols = 0; yann@2454: int win_cols = 0; yann@2454: int win_lines = 0; yann@2454: int i = 0; yann@2454: WINDOW *win; yann@2454: WINDOW *pad; yann@2454: PANEL *panel; yann@2454: yann@2454: /* find the widest line of msg: */ yann@2454: total_lines = get_line_no(text); yann@2454: for (i = 0; i < total_lines; i++) { yann@2454: const char *line = get_line(text, i); yann@2454: int len = get_line_length(line); yann@2454: total_cols = max(total_cols, len+2); yann@2454: } yann@2454: yann@2454: /* create the pad */ yann@2454: pad = newpad(total_lines+10, total_cols+10); yann@2454: (void) wattrset(pad, attributes[SCROLLWIN_TEXT]); yann@2454: fill_window(pad, text); yann@2454: yann@2454: win_lines = min(total_lines+4, LINES-2); yann@2454: win_cols = min(total_cols+2, COLS-2); yann@2454: text_lines = max(win_lines-4, 0); yann@2454: text_cols = max(win_cols-2, 0); yann@2454: yann@2454: /* place window in middle of screen */ yann@2454: y = (LINES-win_lines)/2; yann@2454: x = (COLS-win_cols)/2; yann@2454: yann@2454: win = newwin(win_lines, win_cols, y, x); yann@2454: keypad(win, TRUE); yann@2454: /* show the help in the help window, and show the help panel */ yann@2454: (void) wattrset(win, attributes[SCROLLWIN_BOX]); yann@2454: box(win, 0, 0); yann@2454: (void) wattrset(win, attributes[SCROLLWIN_HEADING]); yann@2454: mvwprintw(win, 0, 3, " %s ", title); yann@2454: panel = new_panel(win); yann@2454: yann@2454: /* handle scrolling */ yann@2454: do { yann@2454: yann@2454: copywin(pad, win, start_y, start_x, 2, 2, text_lines, yann@2454: text_cols, 0); yann@2454: print_in_middle(win, yann@2454: text_lines+2, yann@2454: 0, yann@2454: text_cols, yann@2454: "", yann@2454: attributes[DIALOG_MENU_FORE]); yann@2454: wrefresh(win); yann@2454: yann@2454: res = wgetch(win); yann@2454: switch (res) { yann@2454: case KEY_NPAGE: yann@2454: case ' ': yann@2454: start_y += text_lines-2; yann@2454: break; yann@2454: case KEY_PPAGE: yann@2454: start_y -= text_lines+2; yann@2454: break; yann@2454: case KEY_HOME: yann@2454: start_y = 0; yann@2454: break; yann@2454: case KEY_END: yann@2454: start_y = total_lines-text_lines; yann@2454: break; yann@2454: case KEY_DOWN: yann@2454: case 'j': yann@2454: start_y++; yann@2454: break; yann@2454: case KEY_UP: yann@2454: case 'k': yann@2454: start_y--; yann@2454: break; yann@2454: case KEY_LEFT: yann@2454: case 'h': yann@2454: start_x--; yann@2454: break; yann@2454: case KEY_RIGHT: yann@2454: case 'l': yann@2454: start_x++; yann@2454: break; yann@2454: } yann@2454: if (res == 10 || res == 27 || res == 'q' yann@2454: || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) { yann@2454: break; yann@2454: } yann@2454: if (start_y < 0) yann@2454: start_y = 0; yann@2454: if (start_y >= total_lines-text_lines) yann@2454: start_y = total_lines-text_lines; yann@2454: if (start_x < 0) yann@2454: start_x = 0; yann@2454: if (start_x >= total_cols-text_cols) yann@2454: start_x = total_cols-text_cols; yann@2454: } while (res); yann@2454: yann@2454: del_panel(panel); yann@2454: delwin(win); yann@2454: refresh_all_windows(main_window); yann@2454: }