This source file includes following definitions.
- print_item
- print_arrows
- print_buttons
- dialog_menu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include "dialog.h"
23
24 static int menu_width, item_x;
25
26
27
28
29 static void
30 print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey)
31 {
32 int i, j;
33 char menu_item[menu_width+1];
34
35 strncpy(menu_item, item, menu_width);
36 menu_item[menu_width] = 0;
37 j = first_alpha(menu_item);
38
39
40 wattrset (win, menubox_attr);
41 wmove (win, choice, 0);
42 for (i = 0; i < menu_width; i++)
43 waddch (win, ' ');
44 wattrset (win, selected ? item_selected_attr : item_attr);
45 mvwaddstr (win, choice, item_x, menu_item);
46 if (hotkey) {
47 wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
48 mvwaddch(win, choice, item_x+j, menu_item[j]);
49 }
50 }
51
52
53
54
55 static void
56 print_arrows (WINDOW * win, int item_no, int scroll,
57 int y, int x, int height)
58 {
59 int cur_y, cur_x;
60
61 getyx(win, cur_y, cur_x);
62
63 wmove(win, y, x);
64
65 if (scroll > 0) {
66 wattrset (win, uarrow_attr);
67 waddch (win, ACS_UARROW);
68 waddstr (win, "(-)");
69 }
70 else {
71 wattrset (win, menubox_attr);
72 waddch (win, ACS_HLINE);
73 waddch (win, ACS_HLINE);
74 waddch (win, ACS_HLINE);
75 waddch (win, ACS_HLINE);
76 }
77
78 y = y + height + 1;
79 wmove(win, y, x);
80
81 if ((height < item_no) && (scroll + height < item_no)) {
82 wattrset (win, darrow_attr);
83 waddch (win, ACS_DARROW);
84 waddstr (win, "(+)");
85 }
86 else {
87 wattrset (win, menubox_border_attr);
88 waddch (win, ACS_HLINE);
89 waddch (win, ACS_HLINE);
90 waddch (win, ACS_HLINE);
91 waddch (win, ACS_HLINE);
92 }
93
94 wmove(win, cur_y, cur_x);
95 }
96
97
98
99
100 static void
101 print_buttons (WINDOW *win, int height, int width, int selected)
102 {
103 int x = width / 2 - 16;
104 int y = height - 2;
105
106 print_button (win, "Select", y, x, selected == 0);
107 print_button (win, " Exit ", y, x + 12, selected == 1);
108 print_button (win, " Help ", y, x + 24, selected == 2);
109
110 wmove(win, y, x+1+12*selected);
111 wrefresh (win);
112 }
113
114
115
116
117 int
118 dialog_menu (const char *title, const char *prompt, int height, int width,
119 int menu_height, const char *current, int item_no,
120 const char * const * items)
121
122 {
123 int i, j, x, y, box_x, box_y;
124 int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
125 WINDOW *dialog, *menu;
126
127 max_choice = MIN (menu_height, item_no);
128
129
130 x = (COLS - width) / 2;
131 y = (LINES - height) / 2;
132
133 draw_shadow (stdscr, y, x, height, width);
134
135 dialog = newwin (height, width, y, x);
136 keypad (dialog, TRUE);
137
138 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
139 wattrset (dialog, border_attr);
140 mvwaddch (dialog, height - 3, 0, ACS_LTEE);
141 for (i = 0; i < width - 2; i++)
142 waddch (dialog, ACS_HLINE);
143 wattrset (dialog, dialog_attr);
144 waddch (dialog, ACS_RTEE);
145
146 if (title != NULL) {
147 wattrset (dialog, title_attr);
148 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
149 waddstr (dialog, (char *)title);
150 waddch (dialog, ' ');
151 }
152
153 wattrset (dialog, dialog_attr);
154 print_autowrap (dialog, prompt, width - 2, 1, 3);
155
156 menu_width = width - 6;
157 box_y = height - menu_height - 5;
158 box_x = (width - menu_width) / 2 - 1;
159
160
161 menu = subwin (dialog, menu_height, menu_width,
162 y + box_y + 1, x + box_x + 1);
163 keypad (menu, TRUE);
164
165
166 draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
167 menubox_border_attr, menubox_attr);
168
169
170
171
172
173 item_x = 0;
174 for (i = 0; i < item_no; i++) {
175 item_x = MAX (item_x, MIN(menu_width, strlen (items[i * 2 + 1]) + 2));
176 if (strcmp(current, items[i*2]) == 0) choice = i;
177 }
178
179 item_x = (menu_width - item_x) / 2;
180
181 if (choice >= max_choice){
182 scroll = first_item = choice - max_choice + 1;
183 choice = max_choice-1;
184 }
185
186
187 for (i=0; i < max_choice; i++) {
188 print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice,
189 (items[(first_item + i)*2][0] != ':'));
190 }
191
192 wnoutrefresh (menu);
193
194 print_arrows(dialog, item_no, scroll,
195 box_y, box_x+item_x+1, menu_height);
196
197 print_buttons (dialog, height, width, 0);
198
199 while (key != ESC) {
200 key = wgetch(dialog);
201
202 if (isalpha(key)) key = tolower(key);
203
204 if (strchr("ynm", key))
205 i = max_choice;
206 else {
207 for (i = choice+1; i < max_choice; i++) {
208 j = first_alpha(items[(scroll+i)*2+1]);
209 if (key == tolower(items[(scroll+i)*2+1][j]))
210 break;
211 }
212 if (i == max_choice)
213 for (i = 0; i < max_choice; i++) {
214 j = first_alpha(items[(scroll+i)*2+1]);
215 if (key == tolower(items[(scroll+i)*2+1][j]))
216 break;
217 }
218 }
219
220 if (i < max_choice ||
221 key == KEY_UP || key == KEY_DOWN ||
222 key == '-' || key == '+' ||
223 key == KEY_PPAGE || key == KEY_NPAGE) {
224
225 print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
226 (items[(scroll+choice)*2][0] != ':'));
227
228 if (key == KEY_UP || key == '-') {
229 if (choice < 2 && scroll) {
230
231 scrollok (menu, TRUE);
232 wscrl (menu, -1);
233 scrollok (menu, FALSE);
234
235 scroll--;
236
237 print_item (menu, items[scroll * 2 + 1], 0, FALSE,
238 (items[scroll*2][0] != ':'));
239 } else
240 choice = MAX(choice - 1, 0);
241
242 } else if (key == KEY_DOWN || key == '+') {
243
244 print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
245 (items[(scroll+choice)*2][0] != ':'));
246
247 if ((choice > max_choice-3) &&
248 (scroll + max_choice < item_no)
249 ) {
250
251 scrollok (menu, TRUE);
252 scroll (menu);
253 scrollok (menu, FALSE);
254
255 scroll++;
256
257 print_item (menu, items[(scroll+max_choice-1)*2+1],
258 max_choice-1, FALSE,
259 (items[(scroll+max_choice-1)*2][0] != ':'));
260 } else
261 choice = MIN(choice+1, max_choice-1);
262
263 } else if (key == KEY_PPAGE) {
264 scrollok (menu, TRUE);
265 for (i=0; (i < max_choice) && (scroll > 0); i++) {
266 wscrl (menu, -1);
267 scroll--;
268 print_item (menu, items[scroll * 2 + 1], 0, FALSE,
269 (items[scroll*2][0] != ':'));
270 }
271 scrollok (menu, FALSE);
272 choice = 0;
273
274 } else if (key == KEY_NPAGE) {
275 scrollok (menu, TRUE);
276 for (i=0; (i < max_choice) && (scroll+max_choice < item_no); i++) {
277 scroll(menu);
278 scroll++;
279 print_item (menu, items[(scroll+max_choice-1)*2+1],
280 max_choice-1, FALSE,
281 (items[(scroll+max_choice-1)*2][0] != ':'));
282 }
283 scrollok (menu, FALSE);
284 choice = 0;
285
286 } else
287 choice = i;
288
289 print_item (menu, items[(scroll+choice)*2+1], choice, TRUE,
290 (items[(scroll+choice)*2][0] != ':'));
291
292 print_arrows(dialog, item_no, scroll,
293 box_y, box_x+item_x+1, menu_height);
294
295 wnoutrefresh (menu);
296 wrefresh (dialog);
297
298 continue;
299 }
300
301 switch (key) {
302 case KEY_LEFT:
303 case TAB:
304 case KEY_RIGHT:
305 button = ((key == KEY_LEFT ? --button : ++button) < 0)
306 ? 2 : (button > 2 ? 0 : button);
307
308 print_buttons(dialog, height, width, button);
309 wrefresh (dialog);
310 break;
311 case 's':
312 case 'y':
313 case 'n':
314 case 'm':
315 delwin (dialog);
316 fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
317 if (key == 'y') return 3;
318 if (key == 'n') return 4;
319 if (key == 'm') return 5;
320 return 0;
321 case 'h':
322 case '?':
323 button = 2;
324 case '\n':
325 delwin (dialog);
326 if (button == 2)
327 fprintf(stderr, "%s \"%s\"\n",
328 items[(scroll + choice) * 2],
329 items[(scroll + choice) * 2 + 1] +
330 first_alpha(items[(scroll + choice) * 2 + 1]));
331 else
332 fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
333
334 return button;
335 case 'e':
336 case 'x':
337 key = ESC;
338 case ESC:
339 break;
340 }
341 }
342
343 delwin (dialog);
344 return -1;
345 }