C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
Menu Engine

Main loop and command processor for the C-Menu menu system. More...

Functions

unsigned int menu_cmd_processor (Init *init)
 Processes user input for the menu system.
unsigned int menu_engine (Init *init)
 The main loop of the menu system.

Detailed Description

Main loop and command processor for the C-Menu menu system.

This module contains the core functionality for displaying menus, processing user input, and executing commands associated with menu choices. It handles navigation through menu options, responding to special keys, and managing the display of submenus, pick lists, forms, and views.

Function Documentation

◆ menu_cmd_processor()

unsigned int menu_cmd_processor ( Init * init)

Processes user input for the menu system.

Parameters
initA pointer to an Init structure containing initialization data for the menu system.
Returns
an integer indicating the action taken by the user, such as returning to the main menu, displaying a submenu, or executing a command associated with a menu choice.

handles navigation through the menu options, executing commands associated with menu choices, and responding to special keys such as function keys and mouse clicks.

Move up to the previous menu choice

Move down to the next menu choice

Select the current menu choice and execute its associated command

Display help information for the menu system

Exit the menu and return to the previous menu or exit if at top

send default printer output file to printer

open the default editor

process mouse event

If the user presses a key that corresponds to a menu choice's letter, select that menu choice

Execute the command associated with the selected menu choice

Display help information for the menu system

Display a submenu or perform an action associated with the selected menu choice

Display a pick list or form associated with the selected menu choice

Display a form associated with the selected menu choice

Display a view associated with the selected menu choice

open ckeys (test curses keys)

return to calling program

write the current menu configuration to a file

Definition at line 121 of file menu_engine.c.

121 {
122 uint i;
123 uint c;
124 char *d;
125 int in_key;
126 char tmp_str[MAXLEN];
127 char earg_str[MAXLEN];
128 char *eargv[MAXARGS];
129 int eargc;
131 mbstate_t mbstate;
132 memset(&mbstate, 0, sizeof(mbstate));
133 Menu *menu = init->menu;
134 ui_keypad(sfc, WIN, true);
135 ui_scrollok(sfc, WIN, false);
136#ifdef UAL_UI
137 ui_mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION);
138#else
139 ui_mice_enable(NCMICE_ALL_EVENTS);
140#endif
141 UiEvent event;
142 // Highlight the currently selected menu choice
143
144 while (1) {
145 ui_bkgdset(sfc, WIN, &cell_nt_rev);
146 ui_draw_text_fill(sfc, WIN, menu->line_idx, 0,
147 menu->line[menu->line_idx]->choice_text,
148 menu->cols);
150 ui_draw_ch_yx(sfc, WIN, menu->line_idx,
151 menu->line[menu->line_idx]->letter_pos,
152 menu->line[menu->line_idx]->choice_letter);
153 ui_bkgdset(sfc, WIN, &cell_nt);
154 // Wait for user input and process it
155 event.y = event.x = -1;
156 ui_wmove(sfc, WIN, menu->line_idx, 1);
157 ui_render();
158 in_key = ui_get_event(sfc, WIN, &event, -1);
159 // Remove the highlight from the currently selected menu choice
160 ui_bkgdset(sfc, WIN, &cell_nt);
161 ui_draw_text_fill(sfc, WIN, menu->line_idx, 0,
162 menu->line[menu->line_idx]->choice_text,
163 menu->cols);
164 ui_bkgdset(sfc, WIN, &cell_nt_hl);
165 ui_draw_ch_yx(sfc, WIN, menu->line_idx,
166 menu->line[menu->line_idx]->letter_pos,
167 menu->line[menu->line_idx]->choice_letter);
168 ui_render();
169 // Initialize the mouse event coordinates to -1 to indicate no mouse
170 // event
171 switch (in_key) {
173 case KEY_UP:
174 i = menu->line_idx;
175 while (i > 0) {
176 i--;
177 if (menu->line[i]->type == MT_CHOICE) {
178 menu->line_idx = i;
179 break;
180 }
181 }
182 return (MA_CONTINUE);
184 case KEY_DOWN:
185 i = menu->line_idx;
186 while (i < menu->item_count - 1) {
187 i++;
188 if (menu->line[i]->type == MT_CHOICE) {
189 menu->line_idx = i;
190 break;
191 }
192 }
193 return (MA_CONTINUE);
196 case '\n':
197 case KEY_ENTER:
198 break;
200 case '?':
201 case KEY_F01:
202 if (menu->f_help_spec && menu->help_spec[0] != '\0')
203 strnz__cpy(tmp_str, menu->help_spec, MAXLEN - 1);
204 else {
205 strnz__cpy(tmp_str, init->mapp_help, MAXLEN - 1);
206 strnz__cat(tmp_str, "/", MAXLEN - 1);
207 strnz__cat(tmp_str, MENU_HELP_FILE, MAXLEN - 1);
208 }
209 eargc = 0;
210 eargv[eargc++] = strdup("view");
211 eargv[eargc++] = strdup("-Nf");
212 eargv[eargc++] = strdup(tmp_str);
213 eargv[eargc] = nullptr;
214 init->lines = 51;
215 init->cols = 86;
216 init->begy = menu->begy + 1;
217 init->begx = menu->begx + 1;
218 strnz__cpy(init->title, "Menu Help", MAXLEN - 1);
219 popup_view(init, eargc, eargv, init->lines, init->cols, init->begy,
220 init->begx);
222 return (MA_DISPLAY_MENU);
225 case KEY_F09:
226 case KEY_BREAK:
227 return (MA_RETURN);
229 case KEY_F07:
230 d = getenv("PRTCMD");
231 if (d == nullptr || *d == '\0')
233 else
234 strnz__cpy(earg_str, d, MAXLEN - 1);
235 strnz__cat(earg_str, " ", MAXLEN - 1);
236 d = getenv("PRTFILE");
237 if (d == nullptr || *d == '\0') {
238 d = getenv("HOME");
239 if (d == nullptr || *d == '\0')
241 else {
242 strnz__cat(earg_str, d, MAXLEN - 1);
243 strnz__cat(earg_str, "/", MAXLEN - 1);
245 }
246 } else
247 strnz__cat(earg_str, d, MAXLEN - 1);
249 return (MA_RESET_MENU);
251 case KEY_ALTF(10):
253 return (MA_DISPLAY_MENU);
255 case KEY_MOUSE:
256 if (event.y >= menu->item_count)
257 return (MA_CONTINUE);
258 menu->line_idx = event.y;
259 break;
260 case 'q':
261 return (MA_RETURN);
262 break;
263 default:
266 for (i = 0; i < menu->item_count; i++) {
267 if (menu->line[i]->raw_text[0] == '_') {
268 if (menu->line[i]->choice_letter == (char)in_key) {
269 menu->line_idx = i;
270 break;
271 }
272 } else {
273 if (menu->line[i]->choice_letter == (char)in_key) {
274 menu->line_idx = i;
275 break;
276 }
277 }
278 }
279 if (i >= menu->item_count)
280 return (MA_CONTINUE);
281 break;
282 }
283 char *s;
284 c = (int)menu->line[menu->line_idx]->command_type;
285 switch (c) {
289 case CT_DEXE:
290 s = strpbrk(menu->line[menu->line_idx]->command_str, " \t\f\v");
291 strnz__cpy(earg_str, s, MAXLEN - 1);
292 trim(earg_str);
296 return (MA_RESET_MENU);
297 case CT_EXEC:
298 s = strpbrk(menu->line[menu->line_idx]->command_str, " \t\f\v");
299 strnz__cpy(earg_str, s, MAXLEN - 1);
300 trim(earg_str);
302 stdio_names(stdio_names_str, "menu_engine.c:328");
305 return (MA_RESET_MENU);
307 case CT_HELP:
308 if (menu->f_help_spec && menu->help_spec[0] != '\0')
309 strnz__cpy(tmp_str, menu->help_spec, MAXLEN - 1);
310 else {
311 strnz__cpy(tmp_str, init->mapp_help, MAXLEN - 1);
312 strnz__cat(tmp_str, "/", MAXLEN - 1);
313 strnz__cat(tmp_str, MENU_HELP_FILE, MAXLEN - 1);
314 }
315 eargc = 0;
316 eargv[eargc++] = strdup("view");
317 eargv[eargc++] = strdup("-N");
318 eargv[eargc++] = strdup("f");
319 eargv[eargc++] = strdup(tmp_str);
320 eargv[eargc] = nullptr;
321 init->lines = 40;
322 init->cols = 60;
323 init->begy = menu->begy + 1;
324 init->begx = menu->begx + 1;
325 strnz__cpy(init->title, "Menu Help", MAXLEN - 1);
326 popup_view(init, eargc, eargv, init->lines, init->cols, init->begy,
327 init->begx);
329 return (MA_DISPLAY_MENU);
332 case CT_MENU:
333 strnz__cpy(earg_str, menu->line[menu->line_idx]->command_str,
334 MAXLEN - 1);
336 if (eargc == 0)
337 return (MA_DISPLAY_MENU);
338 popup_menu(init, eargc, eargv, menu->begy + 1, menu->begx + 1);
340 return (MA_RESET_MENU);
343 case CT_PICK:
344 strnz__cpy(earg_str, menu->line[menu->line_idx]->command_str,
345 MAXLEN - 1);
347 popup_pick(init, eargc, eargv, menu->begy + 1, menu->begx + 1);
349 return (MA_DISPLAY_MENU);
352 case CT_FORM:
353 strnz__cpy(earg_str, menu->line[menu->line_idx]->command_str,
354 MAXLEN - 1);
356 popup_form(init, eargc, eargv, menu->begy + 1, menu->begx + 1);
358 return (MA_RESET_MENU);
361 case CT_VIEW:
362 strnz__cpy(earg_str, menu->line[menu->line_idx]->command_str,
363 MAXLEN - 1);
365 init->lines = 66;
366 init->cols = 80;
367 init->begy = menu->begy + 1;
368 init->begx = menu->begx + 1;
369 strnz__cpy(init->title, menu->line[menu->line_idx]->raw_text,
370 MAXLEN - 1);
371 popup_view(init, eargc, eargv, init->lines, init->cols, init->begy,
372 init->begx);
374 return (MA_DISPLAY_MENU);
376 case CT_CKEYS:
377 popup_ckeys();
378 return (MA_DISPLAY_MENU);
380 case CT_RETURN:
381 return (MA_RETURN);
383 case CT_WRITE_CONFIG:
384 write_config(init);
385 return (MA_CONTINUE);
386 default:
387 return (MA_CONTINUE);
388 }
389 }
390 return 0;
391}
#define PRINTCMD
Definition common.h:47
#define VIEW_PRT_FILE
Definition common.h:36
int popup_form(Init *, int, char **, uint, uint)
instantiate a form popup window
Definition popups.c:113
int popup_menu(Init *, int, char **, uint, uint)
instantiate a menu popup window
Definition popups.c:53
#define MENU_HELP_FILE
Definition common.h:32
int popup_pick(Init *, int, char **, uint, uint)
instantiate a pick popup window
Definition popups.c:83
int popup_view(Init *, int, char **, uint, uint, uint, uint)
instantiate a view popup window
Definition popups.c:145
#define MAX_ARGS
Definition cm.h:48
char stdio_names_str[4096]
Definition futil.c:127
#define MAXARGS
Definition cm.h:50
char * stdio_names(char *, char *)
Definition futil.c:1057
#define KEY_ALTF(n)
Definition cm.h:503
@ MT_CHOICE
Definition menu.h:24
@ CT_PICK
Definition menu.h:46
@ CT_FORM
Definition menu.h:42
@ CT_DEXE
Definition menu.h:38
@ CT_MENU
Definition menu.h:45
@ CT_RETURN
Definition menu.h:49
@ CT_HELP
Definition menu.h:40
@ CT_WRITE_CONFIG
Definition menu.h:51
@ CT_EXEC
Definition menu.h:39
@ CT_VIEW
Definition menu.h:47
@ CT_CKEYS
Definition menu.h:48
@ MA_RETURN
Definition menu.h:29
@ MA_DISPLAY_MENU
Definition menu.h:30
@ MA_RESET_MENU
Definition menu.h:31
@ MA_CONTINUE
Definition menu.h:32
void ui_render()
Definition ui_ncurses.c:800
int ui_draw_ch_yx(UiSurface *s, uint w, uint y, uint x, const char c)
int ui_bkgdset(UiSurface *s, uint w, const UiCell *cell)
Definition ui_ncurses.c:760
int ui_mice_enable(int mask)
int ui_scrollok(UiSurface *s, uint w, bool enable)
Definition ui_ncurses.c:626
int ui_get_event(UiSurface *s, uint w, UiEvent *ev, int timeout_ms)
Wait for an input event on target (or stdscr if NULL).
void ui_restore_wins()
int ui_wmove(UiSurface *s, uint w, uint y, uint x)
Definition ui_ncurses.c:732
UiSurface * ui_surface[UI_SFC_MAX]
Definition ui_ncurses.c:28
int ui_draw_text_fill(UiSurface *s, uint w, uint y, uint x, const char *text, int m)
int ui_mousemask(int mask)
int sfc_ptr
Definition nckeys.c:47
int ui_keypad(UiSurface *s, uint w, bool enable)
Definition ui_ncurses.c:635
#define KEY_F01
#define KEY_F07
#define KEY_F09
#define KEY_DOWN
#define KEY_BREAK
#define KEY_ENTER
#define KEY_MOUSE
#define KEY_UP
Menu * menu
Definition mem.c:35
int popup_ckeys()
Definition curskeys.c:31
#define MAXLEN
Definition curskeys.c:15
char * eargv[MAXARGS]
Definition futil.c:51
int eargc
Definition futil.c:50
char earg_str[MAXLEN]
Definition futil.c:49
UiCell cell_nt
Definition dwin.c:94
UiCell cell_nt_hl_rev
Definition dwin.c:97
UiCell cell_nt_hl
Definition dwin.c:96
UiCell cell_nt_rev
Definition dwin.c:95
int full_screen_fork_exec(char **)
Execute a command in full screen mode.
Definition exec.c:45
int full_screen_shell(char *)
Execute a shell command in full screen mode.
Definition exec.c:58
int fork_detach_execvp(char **eargv)
Fork, set new session ID, close files, and execute detached command.
Definition detach.c:29
size_t strnz__cpy(char *, const char *, size_t)
safer alternative to strncpy
Definition futil.c:537
size_t trim(char *)
Trims leading and trailing spaces from string s in place.
Definition futil.c:384
int str_to_args(char **, char *, uint)
Converts a string into an array of argument strings.
Definition futil.c:433
size_t strnz__cat(char *, const char *, size_t)
safer alternative to strncat
Definition futil.c:566
int destroy_argv(uint argc, char **argv)
Deallocates memory allocated for argument strings in argv.
Definition futil.c:487
int write_config(Init *init)
Write the current configuration to a file specified in init->minitrc.
Definition init.c:1103
A drawable surface in the NotCurses backend.
char title[MAXLEN]
Definition common.h:129
char mapp_help[MAXLEN]
Definition common.h:149
int begx
Definition common.h:118
int cols
Definition common.h:116
int begy
Definition common.h:117
Menu * menu
Definition common.h:183
int lines
Definition common.h:115
The Menu structure is the main data structure for the menu application, containing all the informatio...
Definition menu.h:105

References Init::begx, Menu::begx, Init::begy, Menu::begy, cell_nt, cell_nt_hl, cell_nt_hl_rev, cell_nt_rev, Line::choice_letter, Line::choice_text, Init::cols, Menu::cols, Line::command_str, Line::command_type, CT_CKEYS, CT_DEXE, CT_EXEC, CT_FORM, CT_HELP, CT_MENU, CT_PICK, CT_RETURN, CT_VIEW, CT_WRITE_CONFIG, destroy_argv(), Menu::f_help_spec, fork_detach_execvp(), full_screen_fork_exec(), full_screen_shell(), Menu::help_spec, Menu::item_count, Line::letter_pos, Menu::line, Menu::line_idx, Init::lines, MA_CONTINUE, MA_DISPLAY_MENU, MA_RESET_MENU, MA_RETURN, Init::mapp_help, Init::menu, MT_CHOICE, popup_ckeys(), popup_form(), popup_menu(), popup_pick(), popup_view(), Line::raw_text, sfc_ptr, stdio_names(), stdio_names_str, str_to_args(), strnz__cat(), strnz__cpy(), Init::title, trim(), Line::type, ui_bkgdset(), ui_draw_ch_yx(), ui_draw_text_fill(), ui_get_event(), ui_keypad(), ui_mice_enable(), ui_render(), ui_restore_wins(), ui_scrollok(), ui_surface, ui_wmove(), WIN, write_config(), UiEvent::x, and UiEvent::y.

Referenced by menu_engine().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ menu_engine()

unsigned int menu_engine ( Init * init)

The main loop of the menu system.

Parameters
initA pointer to an Init structure containing initialization data for the menu system.
Returns
an integer indicating the action taken by the user, such as returning to the main menu or exiting the menu system.

displays the menu and processes user input until the user exits the menu or returns to the main menu.

Definition at line 36 of file menu_engine.c.

36 {
37 uint action;
38 uint i;
39 char tmp_str[MAXLEN];
40 Menu *menu = init->menu;
41 if (menu == nullptr) {
42 Perror("menu_engine: menu is nullptr");
43 return (1);
44 }
45 menu->lines = 0;
46 menu->cols = 0;
47 menu->line_idx = 0;
48 menu->item_count = 0;
49 menu->title[0] = '\0';
50 menu->choice_max_len = 0;
51 menu->text_max_len = 0;
53 surface_box_win_new(menu->lines, menu->cols, menu->begy, menu->begx, menu->title);
55 if (sfc == nullptr) {
56 ssnprintf(tmp_str, MAXLEN - 1, "surface_box_win_new(%d, %d, %d, %d, %s) failed",
57 menu->lines, menu->cols, menu->begy, menu->begx, menu->title);
58 Perror(tmp_str);
59 return 1;
60 }
61 mbstate_t mbstate;
62 memset(&mbstate, 0, sizeof(mbstate));
63 action = MA_DISPLAY_MENU;
64 while (action) {
65 switch (action) {
66 case MA_RETURN:
68 if (sfc_ptr < 0) {
69 destroy_menu(init);
70 return 0;
71 }
73 return 0;
74 case MA_DISPLAY_MENU:
75 for (menu->line_idx = 0; menu->line_idx < menu->item_count;
76 menu->line_idx++) {
77 ui_bkgdset(sfc, WIN, &cell_nt);
78 ui_draw_text_fill(sfc, WIN, menu->line_idx, 0,
79 menu->line[menu->line_idx]->choice_text,
80 menu->cols);
82 ui_mvwaddch(sfc, WIN, menu->line_idx,
83 menu->line[menu->line_idx]->letter_pos,
84 menu->line[menu->line_idx]->choice_letter);
85 ui_bkgdset(sfc, WIN, &cell_nt);
86 ui_render();
87 }
88 action = MA_RESET_MENU;
89 break;
90 case MA_RESET_MENU:
91 menu->line_idx = 0;
92 for (i = 0; i < menu->item_count; i++) {
93 if (menu->line[i]->type == MT_CHOICE) {
94 menu->line_idx = i;
95 break;
96 }
97 }
98 action = MA_CONTINUE;
99 break;
100 case MA_CONTINUE:
101 action = menu_cmd_processor(init);
102 break;
103 default:
104 break;
105 }
106 }
107 destroy_menu(init);
108 return 0;
109}
int ui_mvwaddch(UiSurface *s, uint w, uint y, uint x, const char c)
int surface_box_win_new(uint wlines, uint wcols, uint wbegy, uint wbegx, char *wtitle)
Definition dwin.c:521
int cm_surface_destroy(UiSurface *sfc)
Destroy the most recently created surface.
Definition dwin.c:576
int Perror(char *emsg_str)
Display a simple error message window or print to stderr.
Definition dwin.c:841
size_t ssnprintf(char *, size_t, const char *,...)
ssnprintf was designed to be a safer alternative to snprintf.
Definition futil.c:413
Menu * destroy_menu(Init *init)
Destroy Menu structure.
Definition mem.c:155
unsigned int menu_cmd_processor(Init *)
Processes user input for the menu system.
unsigned int parse_menu_description(Init *)
Parse menu description file and create Menu.

References Menu::begx, Menu::begy, cell_nt, cell_nt_hl, Line::choice_letter, Menu::choice_max_len, Line::choice_text, cm_surface_destroy(), Menu::cols, destroy_menu(), Menu::item_count, Line::letter_pos, Menu::line, Menu::line_idx, Menu::lines, MA_CONTINUE, MA_DISPLAY_MENU, MA_RESET_MENU, MA_RETURN, Init::menu, menu_cmd_processor(), MT_CHOICE, parse_menu_description(), Perror(), sfc_ptr, ssnprintf(), surface_box_win_new(), Menu::text_max_len, Menu::title, Line::type, ui_bkgdset(), ui_draw_text_fill(), ui_mvwaddch(), ui_render(), ui_restore_wins(), ui_surface, and WIN.

Referenced by main(), and popup_menu().

Here is the call graph for this function:
Here is the caller graph for this function: