1#include "menu_widget.h"
2#include "colors.h"
3#include "utils.h"
4#include "bindings.h"
5
6/* Returns
7 * - KEY_CANCEL: close is requested
8 * - KEY_ENTER: item is selected
9 * - -1: no action
10 */
11int menu_widget_handle_key(MENU *menu, int key)
12{
13	MEVENT m;
14
15	switch (key) {
16	case 27:
17	case KEY_CANCEL:
18	case 'q':
19	case 'Q':
20		return KEY_CANCEL;
21	case '\n':
22	case '\r':
23	case KEY_ENTER:
24		return KEY_ENTER;
25
26	case KEY_MOUSE:
27		switch (menu_driver(menu, KEY_MOUSE)) {
28			case E_UNKNOWN_COMMAND:
29				/* If you double-click an item a REQ_TOGGLE_ITEM is generated
30				 * and E_UNKNOWN_COMMAND is returned. (man menu_driver) */
31				return KEY_ENTER;
32			case E_REQUEST_DENIED:
33				/* If menu did not handle KEY_MOUSE is has to be removed from
34				 * input queue to prevent an infinite loop. */
35				key = wgetch(menu_win(menu));
36				if (key == KEY_MOUSE) {
37					if (getmouse(&m) == ERR)
38						return -1;
39					if (m.bstate & (BUTTON4_PRESSED|BUTTON4_CLICKED))
40						menu_driver(menu, REQ_UP_ITEM);
41#if NCURSES_MOUSE_VERSION > 1
42					else if (m.bstate & (BUTTON5_PRESSED|BUTTON5_CLICKED))
43						menu_driver(menu, REQ_DOWN_ITEM);
44#endif
45					else
46						return KEY_CANCEL;
47				}
48				else if (key > 0)
49					ungetch(key);
50		}
51		return -1;
52
53	default:
54		if (key < (int)ARRAY_SIZE(textbox_bindings)) {
55			key = textbox_bindings[key];
56			if (key >= CMD_TEXTBOX___MIN_MENU_COMMAND &&
57					key <= CMD_TEXTBOX___MAX_MENU_COMMAND)
58				menu_driver(menu, key + KEY_MAX);
59		}
60
61		return -1;
62	}
63}
64
65void menu_widget_create(struct widget *widget, MENU *menu, const char *title)
66{
67	int rows, columns;
68
69	if (menu)
70		unpost_menu(menu);
71
72	if (screen_lines < 3 || screen_cols < 10) {
73		widget->close();
74		beep();
75		return;
76	}
77	scale_menu(menu, &rows, &columns);
78	rows += 2;
79	columns += 2;
80	if (rows > screen_lines)
81		rows = screen_lines;
82	if (columns > screen_cols)
83		columns = screen_cols;
84
85	widget_init(widget, rows, columns, SCREEN_CENTER, SCREEN_CENTER,
86		    attrs.menu, WIDGET_BORDER | WIDGET_SUBWINDOW);
87
88	mvwprintw(widget->window, 0, (columns - 2 - get_mbs_width(title)) / 2, " %s ", title);
89	set_menu_win(menu, widget->window);
90	set_menu_sub(menu, widget->subwindow);
91	post_menu(menu);
92}
93