^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Derived from menuconfig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "nconf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "lkc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /* a list of all the different widgets we use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) attributes_t attributes[ATTR_MAX+1] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /* available colors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) COLOR_BLACK 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) COLOR_RED 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) COLOR_GREEN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) COLOR_YELLOW 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) COLOR_BLUE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) COLOR_MAGENTA 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) COLOR_CYAN 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) COLOR_WHITE 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static void set_normal_colors(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) init_pair(NORMAL, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) init_pair(MAIN_HEADING, COLOR_MAGENTA, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* FORE is for the selected item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) init_pair(MAIN_MENU_FORE, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* BACK for all the rest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) init_pair(MAIN_MENU_BACK, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) init_pair(MAIN_MENU_GREY, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) init_pair(SCROLLWIN_TEXT, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) init_pair(DIALOG_TEXT, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) init_pair(DIALOG_BOX, COLOR_YELLOW, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) init_pair(DIALOG_MENU_FORE, COLOR_RED, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) init_pair(INPUT_BOX, COLOR_YELLOW, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) init_pair(INPUT_HEADING, COLOR_GREEN, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) init_pair(INPUT_TEXT, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) init_pair(INPUT_FIELD, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) init_pair(FUNCTION_HIGHLIGHT, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) init_pair(FUNCTION_TEXT, COLOR_YELLOW, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* available attributes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) A_NORMAL Normal display (no highlight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) A_STANDOUT Best highlighting mode of the terminal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) A_UNDERLINE Underlining
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) A_REVERSE Reverse video
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) A_BLINK Blinking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) A_DIM Half bright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) A_BOLD Extra bright or bold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) A_PROTECT Protected mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) A_INVIS Invisible or blank mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) A_ALTCHARSET Alternate character set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) A_CHARTEXT Bit-mask to extract a character
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) COLOR_PAIR(n) Color-pair number n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static void normal_color_theme(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* automatically add color... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define mkattr(name, attr) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) attributes[name] = attr | COLOR_PAIR(name); } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) mkattr(NORMAL, NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) mkattr(MAIN_MENU_FORE, A_REVERSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) mkattr(MAIN_MENU_BACK, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) mkattr(MAIN_MENU_GREY, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) mkattr(MAIN_MENU_HEADING, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) mkattr(MAIN_MENU_BOX, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) mkattr(SCROLLWIN_TEXT, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) mkattr(SCROLLWIN_HEADING, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mkattr(SCROLLWIN_BOX, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) mkattr(DIALOG_TEXT, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) mkattr(DIALOG_BOX, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) mkattr(DIALOG_MENU_FORE, A_STANDOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) mkattr(DIALOG_MENU_BACK, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) mkattr(INPUT_BOX, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) mkattr(INPUT_HEADING, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) mkattr(INPUT_TEXT, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) mkattr(INPUT_FIELD, A_UNDERLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) mkattr(FUNCTION_HIGHLIGHT, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) mkattr(FUNCTION_TEXT, A_REVERSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static void no_colors_theme(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* automatically add highlight, no color */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define mkattrn(name, attr) { attributes[name] = attr; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) mkattrn(NORMAL, NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) mkattrn(MAIN_MENU_FORE, A_STANDOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) mkattrn(MAIN_MENU_BACK, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) mkattrn(MAIN_MENU_GREY, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) mkattrn(MAIN_MENU_HEADING, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) mkattrn(MAIN_MENU_BOX, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) mkattrn(SCROLLWIN_TEXT, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) mkattrn(SCROLLWIN_HEADING, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) mkattrn(SCROLLWIN_BOX, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) mkattrn(DIALOG_TEXT, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) mkattrn(DIALOG_BOX, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) mkattrn(DIALOG_MENU_FORE, A_STANDOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) mkattrn(DIALOG_MENU_BACK, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) mkattrn(INPUT_BOX, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) mkattrn(INPUT_HEADING, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) mkattrn(INPUT_TEXT, A_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) mkattrn(INPUT_FIELD, A_UNDERLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) mkattrn(FUNCTION_HIGHLIGHT, A_BOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) mkattrn(FUNCTION_TEXT, A_REVERSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) void set_colors(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) start_color();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) use_default_colors();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) set_normal_colors();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (has_colors()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) normal_color_theme();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* give defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) no_colors_theme();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* this changes the windows attributes !!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) void print_in_middle(WINDOW *win,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int starty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int startx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) const char *string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) chtype color)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) { int length, x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) float temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (win == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) win = stdscr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) getyx(win, y, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (startx != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) x = startx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (starty != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) y = starty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (width == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) width = 80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) length = strlen(string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) temp = (width - length) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) x = startx + (int)temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) (void) wattrset(win, color);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) mvwprintw(win, y, x, "%s", string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) refresh();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int get_line_no(const char *text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int total = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (!text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) for (i = 0; text[i] != '\0'; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (text[i] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) total++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) const char *get_line(const char *text, int line_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) int lines = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (!text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) for (i = 0; text[i] != '\0' && lines < line_no; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (text[i] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) lines++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return text+i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int get_line_length(const char *line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) while (*line != '\0' && *line != '\n') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) line++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) res++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /* print all lines to the window. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) void fill_window(WINDOW *win, const char *text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) int total_lines = get_line_no(text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) getmaxyx(win, y, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* do not go over end of line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) total_lines = min(total_lines, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) for (i = 0; i < total_lines; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) char tmp[x+10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) const char *line = get_line(text, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int len = get_line_length(line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) strncpy(tmp, line, min(len, x));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) tmp[len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) mvwprintw(win, i, 0, "%s", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* get the message, and buttons.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * each button must be a char*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * return the selected button
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * this dialog is used for 2 different things:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * 1) show a text box, no buttons.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * 2) show a dialog, with horizontal buttons
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) char *btn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int btns_width = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) int msg_lines = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int msg_width = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int total_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int win_rows = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) WINDOW *win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) WINDOW *msg_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) WINDOW *menu_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) MENU *menu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ITEM *btns[btn_num+1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int i, x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) int res = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) va_start(ap, btn_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) for (i = 0; i < btn_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) btn = va_arg(ap, char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) btns[i] = new_item(btn, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) btns_width += strlen(btn)+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) btns[btn_num] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* find the widest line of msg: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) msg_lines = get_line_no(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) for (i = 0; i < msg_lines; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) const char *line = get_line(msg, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) int len = get_line_length(line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (msg_width < len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) msg_width = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) total_width = max(msg_width, btns_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* place dialog in middle of screen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) y = (getmaxy(stdscr)-(msg_lines+4))/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) x = (getmaxx(stdscr)-(total_width+4))/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* create the windows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (btn_num > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) win_rows = msg_lines+4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) win_rows = msg_lines+2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) win = newwin(win_rows, total_width+4, y, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) keypad(win, TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) menu_win = derwin(win, 1, btns_width, win_rows-2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 1+(total_width+2-btns_width)/2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) menu = new_menu(btns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) msg_win = derwin(win, win_rows-2, msg_width, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 1+(total_width+2-msg_width)/2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) (void) wattrset(win, attributes[DIALOG_BOX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) box(win, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* print message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) (void) wattrset(msg_win, attributes[DIALOG_TEXT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) fill_window(msg_win, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) set_menu_win(menu, win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) set_menu_sub(menu, menu_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) set_menu_format(menu, 1, btn_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) menu_opts_off(menu, O_SHOWDESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) menu_opts_off(menu, O_SHOWMATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) menu_opts_on(menu, O_ONEVALUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) menu_opts_on(menu, O_NONCYCLIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) set_menu_mark(menu, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) post_menu(menu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) touchwin(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) refresh_all_windows(main_window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) while ((res = wgetch(win))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) switch (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) case KEY_LEFT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) menu_driver(menu, REQ_LEFT_ITEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) case KEY_RIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) menu_driver(menu, REQ_RIGHT_ITEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) case 10: /* ENTER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) case 27: /* ESCAPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) case ' ':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) case KEY_F(F_BACK):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) case KEY_F(F_EXIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) touchwin(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) refresh_all_windows(main_window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (res == 10 || res == ' ') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) res = item_index(current_item(menu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) } else if (res == 27 || res == KEY_F(F_BACK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) res == KEY_F(F_EXIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) res = KEY_EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) unpost_menu(menu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) free_menu(menu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) for (i = 0; i < btn_num; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) free_item(btns[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) delwin(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int dialog_inputbox(WINDOW *main_window,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) const char *title, const char *prompt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) const char *init, char **resultp, int *result_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) int prompt_lines = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) int prompt_width = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) WINDOW *win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) WINDOW *prompt_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) WINDOW *form_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) PANEL *panel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) int i, x, y, lines, columns, win_lines, win_cols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) int res = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int cursor_position = strlen(init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int cursor_form_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) char *result = *resultp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) getmaxyx(stdscr, lines, columns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (strlen(init)+1 > *result_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) *result_len = strlen(init)+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) *resultp = result = xrealloc(result, *result_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* find the widest line of msg: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) prompt_lines = get_line_no(prompt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) for (i = 0; i < prompt_lines; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) const char *line = get_line(prompt, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int len = get_line_length(line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) prompt_width = max(prompt_width, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (title)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) prompt_width = max(prompt_width, strlen(title));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) win_lines = min(prompt_lines+6, lines-2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) win_cols = min(prompt_width+7, columns-2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) prompt_lines = max(win_lines-6, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) prompt_width = max(win_cols-7, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* place dialog in middle of screen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) y = (lines-win_lines)/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) x = (columns-win_cols)/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) strncpy(result, init, *result_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* create the windows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) win = newwin(win_lines, win_cols, y, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) keypad(form_win, TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) (void) wattrset(form_win, attributes[INPUT_FIELD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) (void) wattrset(win, attributes[INPUT_BOX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) box(win, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) (void) wattrset(win, attributes[INPUT_HEADING]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (title)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) mvwprintw(win, 0, 3, "%s", title);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* print message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) (void) wattrset(prompt_win, attributes[INPUT_TEXT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) fill_window(prompt_win, prompt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) cursor_form_win = min(cursor_position, prompt_width-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) mvwprintw(form_win, 0, 0, "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) result + cursor_position-cursor_form_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* create panels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) panel = new_panel(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* show the cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) curs_set(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) touchwin(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) refresh_all_windows(main_window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) while ((res = wgetch(form_win))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int len = strlen(result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) switch (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) case 10: /* ENTER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) case 27: /* ESCAPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) case KEY_F(F_HELP):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) case KEY_F(F_EXIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) case KEY_F(F_BACK):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) case 8: /* ^H */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) case 127: /* ^? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) case KEY_BACKSPACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (cursor_position > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) memmove(&result[cursor_position-1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) &result[cursor_position],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) len-cursor_position+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) cursor_position--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) cursor_form_win--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) case KEY_DC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (cursor_position >= 0 && cursor_position < len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) memmove(&result[cursor_position],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) &result[cursor_position+1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) len-cursor_position+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) case KEY_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) case KEY_RIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (cursor_position < len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) cursor_position++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) cursor_form_win++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) case KEY_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) case KEY_LEFT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (cursor_position > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) cursor_position--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) cursor_form_win--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) case KEY_HOME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) cursor_position = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) cursor_form_win = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) case KEY_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) cursor_position = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) cursor_form_win = min(cursor_position, prompt_width-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if ((isgraph(res) || isspace(res))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* one for new char, one for '\0' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (len+2 > *result_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) *result_len = len+2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) *resultp = result = realloc(result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) *result_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* insert the char at the proper position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) memmove(&result[cursor_position+1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) &result[cursor_position],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) len-cursor_position+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) result[cursor_position] = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) cursor_position++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) cursor_form_win++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) mvprintw(0, 0, "unknown key: %d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (cursor_form_win < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) cursor_form_win = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) else if (cursor_form_win > prompt_width-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) cursor_form_win = prompt_width-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) wmove(form_win, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) wclrtoeol(form_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) mvwprintw(form_win, 0, 0, "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) result + cursor_position-cursor_form_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) wmove(form_win, 0, cursor_form_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) touchwin(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) refresh_all_windows(main_window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (res == 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) } else if (res == 27 || res == KEY_F(F_BACK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) res == KEY_F(F_EXIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) res = KEY_EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) } else if (res == KEY_F(F_HELP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /* hide the cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) curs_set(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) del_panel(panel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) delwin(prompt_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) delwin(form_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) delwin(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* refresh all windows in the correct order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) void refresh_all_windows(WINDOW *main_window)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) update_panels();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) touchwin(main_window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) refresh();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /* layman's scrollable window... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) void show_scroll_win(WINDOW *main_window,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) const char *title,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) const char *text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) int total_lines = get_line_no(text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) int x, y, lines, columns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) int start_x = 0, start_y = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) int text_lines = 0, text_cols = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) int total_cols = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int win_cols = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) int win_lines = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) WINDOW *win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) WINDOW *pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) PANEL *panel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) getmaxyx(stdscr, lines, columns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* find the widest line of msg: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) total_lines = get_line_no(text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) for (i = 0; i < total_lines; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) const char *line = get_line(text, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) int len = get_line_length(line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) total_cols = max(total_cols, len+2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /* create the pad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) pad = newpad(total_lines+10, total_cols+10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) (void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) fill_window(pad, text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) win_lines = min(total_lines+4, lines-2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) win_cols = min(total_cols+2, columns-2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) text_lines = max(win_lines-4, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) text_cols = max(win_cols-2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) /* place window in middle of screen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) y = (lines-win_lines)/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) x = (columns-win_cols)/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) win = newwin(win_lines, win_cols, y, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) keypad(win, TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* show the help in the help window, and show the help panel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) (void) wattrset(win, attributes[SCROLLWIN_BOX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) box(win, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) (void) wattrset(win, attributes[SCROLLWIN_HEADING]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) mvwprintw(win, 0, 3, " %s ", title);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) panel = new_panel(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) /* handle scrolling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) copywin(pad, win, start_y, start_x, 2, 2, text_lines,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) text_cols, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) print_in_middle(win,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) text_lines+2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) text_cols,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) "<OK>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) attributes[DIALOG_MENU_FORE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) wrefresh(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) res = wgetch(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) switch (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) case KEY_NPAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) case ' ':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) start_y += text_lines-2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) case KEY_PPAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) case 'u':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) start_y -= text_lines+2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) case KEY_HOME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) start_y = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) case KEY_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) start_y = total_lines-text_lines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) case KEY_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) case 'j':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) start_y++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) case KEY_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case 'k':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) start_y--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) case KEY_LEFT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) start_x--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) case KEY_RIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) start_x++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (res == 10 || res == 27 || res == 'q' ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) res == KEY_F(F_HELP) || res == KEY_F(F_BACK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) res == KEY_F(F_EXIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (start_y < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) start_y = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (start_y >= total_lines-text_lines)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) start_y = total_lines-text_lines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (start_x < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) start_x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (start_x >= total_cols-text_cols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) start_x = total_cols-text_cols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) } while (res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) del_panel(panel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) delwin(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) refresh_all_windows(main_window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }