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);
149 ui_bkgdset(sfc, WIN, &cell_nt_hl_rev);
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, NULL, &event, -1);
160 if (event.y < menu->item_count)
161 in_key = menu->line[event.y]->choice_letter;
162 ui_bkgdset(sfc, WIN, &cell_nt);
163 ui_draw_text_fill(sfc, WIN, menu->line_idx, 0,
164 menu->line[menu->line_idx]->choice_text,
165 menu->cols);
166 ui_bkgdset(sfc, WIN, &cell_nt_hl);
167 ui_draw_ch_yx(sfc, WIN, menu->line_idx,
168 menu->line[menu->line_idx]->letter_pos,
169 menu->line[menu->line_idx]->choice_letter);
170 ui_render();
171 // Initialize the mouse event coordinates to -1 to indicate no mouse
172 // event
173 switch (in_key) {
175 case UIKEY_UP:
176 i = menu->line_idx;
177 while (i > 0) {
178 i--;
179 if (menu->line[i]->type == MT_CHOICE) {
180 menu->line_idx = i;
181 break;
182 }
183 }
184 return (MA_CONTINUE);
186 case UIKEY_DOWN:
187 i = menu->line_idx;
188 while (i < menu->item_count - 1) {
189 i++;
190 if (menu->line[i]->type == MT_CHOICE) {
191 menu->line_idx = i;
192 break;
193 }
194 }
195 return (MA_CONTINUE);
198 case '\n':
199 case UIKEY_ENTER:
200 break;
202 case '?':
203 case UIKEY_F01:
204 if (menu->f_help_spec && menu->help_spec[0] != '\0')
205 strnz__cpy(tmp_str, menu->help_spec, MAXLEN - 1);
206 else {
207 strnz__cpy(tmp_str, init->mapp_help, MAXLEN - 1);
208 strnz__cat(tmp_str, "/", MAXLEN - 1);
209 strnz__cat(tmp_str, MENU_HELP_FILE, MAXLEN - 1);
210 }
211 eargc = 0;
212 eargv[eargc++] = strdup("view");
213 eargv[eargc++] = strdup("-Nf");
214 eargv[eargc++] = strdup(tmp_str);
215 eargv[eargc] = nullptr;
216 init->lines = 51;
217 init->cols = 86;
218 init->begy = menu->begy + 1;
219 init->begx = menu->begx + 1;
220 strnz__cpy(init->title, "Menu Help", MAXLEN - 1);
221 popup_view(init, eargc, eargv, init->lines, init->cols, init->begy,
222 init->begx);
224 return (MA_DISPLAY_MENU);
227 case UIKEY_F09:
228 return (MA_RETURN);
230 case UIKEY_F07:
231 d = getenv("PRTCMD");
232 if (d == nullptr || *d == '\0')
234 else
235 strnz__cpy(earg_str, d, MAXLEN - 1);
236 strnz__cat(earg_str, " ", MAXLEN - 1);
237 d = getenv("PRTFILE");
238 if (d == nullptr || *d == '\0') {
239 d = getenv("HOME");
240 if (d == nullptr || *d == '\0')
242 else {
243 strnz__cat(earg_str, d, MAXLEN - 1);
244 strnz__cat(earg_str, "/", MAXLEN - 1);
246 }
247 } else
248 strnz__cat(earg_str, d, MAXLEN - 1);
250 return (MA_RESET_MENU);
252 case UIKEY_F08:
254 return (MA_DISPLAY_MENU);
257 if (event.y >= menu->item_count)
258 return (MA_CONTINUE);
259 menu->line_idx = event.y;
260 break;
261 case 'q':
262 return (MA_RETURN);
263 break;
264 default:
267 for (i = 0; i < menu->item_count; i++) {
268 if (menu->line[i]->raw_text[0] == '_') {
269 if (menu->line[i]->choice_letter == (char)in_key) {
270 menu->line_idx = i;
271 break;
272 }
273 } else {
274 if (menu->line[i]->choice_letter == (char)in_key) {
275 menu->line_idx = i;
276 break;
277 }
278 }
279 }
280 if (i >= menu->item_count)
281 return (MA_CONTINUE);
282 break;
283 }
284 char *s;
285 c = (int)menu->line[menu->line_idx]->command_type;
286 switch (c) {
290 case CT_DEXE:
291 s = strpbrk(menu->line[menu->line_idx]->command_str, " \t\f\v");
292 strnz__cpy(earg_str, s, MAXLEN - 1);
293 trim(earg_str);
297 return (MA_RESET_MENU);
298 case CT_EXEC:
299 s = strpbrk(menu->line[menu->line_idx]->command_str, " \t\f\v");
300 strnz__cpy(earg_str, s, MAXLEN - 1);
301 trim(earg_str);
303 stdio_names(stdio_names_str, "menu_engine.c:328");
306 return (MA_RESET_MENU);
308 case CT_HELP:
309 if (menu->f_help_spec && menu->help_spec[0] != '\0')
310 strnz__cpy(tmp_str, menu->help_spec, MAXLEN - 1);
311 else {
312 strnz__cpy(tmp_str, init->mapp_help, MAXLEN - 1);
313 strnz__cat(tmp_str, "/", MAXLEN - 1);
314 strnz__cat(tmp_str, MENU_HELP_FILE, MAXLEN - 1);
315 }
316 eargc = 0;
317 eargv[eargc++] = strdup("view");
318 eargv[eargc++] = strdup("-N");
319 eargv[eargc++] = strdup("f");
320 eargv[eargc++] = strdup(tmp_str);
321 eargv[eargc] = nullptr;
322 init->lines = 40;
323 init->cols = 60;
324 init->begy = menu->begy + 1;
325 init->begx = menu->begx + 1;
326 strnz__cpy(init->title, "Menu Help", MAXLEN - 1);
327 popup_view(init, eargc, eargv, init->lines, init->cols, init->begy,
328 init->begx);
330 return (MA_DISPLAY_MENU);
333 case CT_MENU:
334 strnz__cpy(earg_str, menu->line[menu->line_idx]->command_str,
335 MAXLEN - 1);
337 if (eargc == 0)
338 return (MA_DISPLAY_MENU);
339 popup_menu(init, eargc, eargv, menu->begy + 1, menu->begx + 1);
341 return (MA_RESET_MENU);
344 case CT_PICK:
345 strnz__cpy(earg_str, menu->line[menu->line_idx]->command_str,
346 MAXLEN - 1);
348 popup_pick(init, eargc, eargv, menu->begy + 1, menu->begx + 1);
350 return (MA_DISPLAY_MENU);
353 case CT_FORM:
354 strnz__cpy(earg_str, menu->line[menu->line_idx]->command_str,
355 MAXLEN - 1);
357 popup_form(init, eargc, eargv, menu->begy + 1, menu->begx + 1);
359 return (MA_RESET_MENU);
362 case CT_VIEW:
363 strnz__cpy(earg_str, menu->line[menu->line_idx]->command_str,
364 MAXLEN - 1);
366 init->lines = 66;
367 init->cols = 80;
368 init->begy = menu->begy + 1;
369 init->begx = menu->begx + 1;
370 strnz__cpy(init->title, menu->line[menu->line_idx]->raw_text,
371 MAXLEN - 1);
372 popup_view(init, eargc, eargv, init->lines, init->cols, init->begy,
373 init->begx);
375 return (MA_DISPLAY_MENU);
377 case CT_CKEYS:
378 popup_ckeys();
379 return (MA_DISPLAY_MENU);
381 case CT_RETURN:
382 return (MA_RETURN);
384 case CT_WRITE_CONFIG:
385 write_config(init);
386 return (MA_CONTINUE);
387 default:
388 return (MA_CONTINUE);
389 }
390 }
391 return 0;
392}
#define PRINTCMD
Definition common.h:50
#define VIEW_PRT_FILE
Definition common.h:39
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:35
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:62
char stdio_names_str[4096]
Definition futil.c:122
#define MAXARGS
Definition cm.h:64
char * stdio_names(char *, char *)
Definition futil.c:1083
@ MT_CHOICE
Definition menu.h:23
@ CT_PICK
Definition menu.h:45
@ CT_FORM
Definition menu.h:41
@ CT_DEXE
Definition menu.h:37
@ CT_MENU
Definition menu.h:44
@ CT_RETURN
Definition menu.h:48
@ CT_HELP
Definition menu.h:39
@ CT_WRITE_CONFIG
Definition menu.h:50
@ CT_EXEC
Definition menu.h:38
@ CT_VIEW
Definition menu.h:46
@ CT_CKEYS
Definition menu.h:47
@ MA_RETURN
Definition menu.h:28
@ MA_DISPLAY_MENU
Definition menu.h:29
@ MA_RESET_MENU
Definition menu.h:30
@ MA_CONTINUE
Definition menu.h:31
int ui_draw_ch_yx(UiSurface *s, ss_t w, uint y, uint x, const char c)
Draw a character at a specific position in a surface window.
void ui_render()
Render the UI by updating panels and refreshing the display.
Definition ui_ncurses.c:884
int ui_draw_text_fill(UiSurface *s, ss_t w, uint y, uint x, const char *text, int m)
Draw a text string at a specific position in a surface window, filling the remaining space with space...
UiCell cell_nt
Definition ui_common.c:106
UiCell cell_nt_hl_rev
Definition ui_common.c:109
int ui_mice_enable(int mask)
Enable or disable mouse support.
int ui_wmove(UiSurface *s, ss_t w, uint y, uint x)
Move the cursor to a specified position within a UiSurface.
Definition ui_ncurses.c:653
void ui_restore_wins()
Restore the state of all windows in the UI. This function refreshes the standard screen and all surfa...
UiCell cell_nt_hl
Definition ui_common.c:108
int ui_mousemask(int mask)
Enable or disable mouse support.
int sfc_ptr
Definition ui_ncurses.c:42
int ui_scrollok(UiSurface *s, ss_t w, bool enable)
Enable or disable scrolling for a UiSurface.
Definition ui_ncurses.c:755
int ui_bkgdset(UiSurface *s, ss_t w, const UiCell *cell)
Set the background for new content to be written to a specific window within a UiSurface.
Definition ui_ncurses.c:941
UiCell cell_nt_rev
Definition ui_common.c:107
int ui_keypad(UiSurface *s, ss_t w, bool enable)
Enable or disable the keypad for a UiSurface.
Definition ui_ncurses.c:771
#define UIKEY_F09
#define UIKEY_F07
#define UIKEY_F01
#define UIKEY_UP
#define UIKEY_BUTTON1_CLICKED
#define UIKEY_ENTER
#define UIKEY_F08
#define UIKEY_DOWN
int ui_get_event(UiSurface *s, ss_t w, UiChyron *chyron, UiEvent *ev, int timeout_ms)
Read input events.
UiSurface * ui_surface[UI_SFC_MAX]
Definition ui_ncurses.c:40
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
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:41
size_t strnz__cpy(char *, const char *, size_t)
safer alternative to strncpy
Definition whence.c:291
size_t trim(char *)
Trims leading and trailing spaces from string s in place.
Definition futil.c:361
int str_to_args(char **, char *, uint)
Converts a string into an array of argument strings.
Definition futil.c:412
size_t strnz__cat(char *, const char *, size_t)
safer alternative to strncat
Definition whence.c:320
int destroy_argv(uint argc, char **argv)
Deallocates memory allocated for argument strings in argv.
Definition futil.c:468
int write_config(Init *init)
Write the current configuration to a file specified in init->minitrc.
Definition init.c:1160
UiMouseAction mouse_action
Definition ui_backend.h:114
char title[MAXLEN]
Definition common.h:132
char mapp_help[MAXLEN]
Definition common.h:152
int begx
Definition common.h:121
int cols
Definition common.h:119
int begy
Definition common.h:120
Menu * menu
Definition common.h:187
int lines
Definition common.h:118
The Menu structure is the main data structure for the menu application, containing all the informatio...
Definition menu.h:104

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, UiEvent::mouse_action, 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_mousemask(), ui_render(), ui_restore_wins(), ui_scrollok(), ui_surface, ui_wmove(), 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 ui_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 ui_tracked_sfc_box(menu->lines, menu->cols, menu->begy, menu->begx, menu->title);
55 if (sfc == nullptr) {
56 ssnprintf(tmp_str, MAXLEN - 1, "ui_tracked_sfc_box(%d, %d, %d, %d, %s) failed",
57 menu->lines, menu->cols, menu->begy, menu->begx, menu->title);
58 ui_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);
81 ui_bkgdset(sfc, WIN, &cell_nt_hl);
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_cm_surface_destroy(UiSurface *sfc)
Destroy the most recently created surface.
Definition ui_common.c:466
int ui_tracked_sfc_box(uint wlines, uint wcols, uint wbegy, uint wbegx, const char *wtitle)
Create a new surface with a box window.
Definition ui_common.c:387
int ui_mvwaddch(UiSurface *s, ss_t w, uint y, uint x, const char c)
Draw a character in a surface window.
#define _(String)
Definition amort.c:23
size_t ssnprintf(char *, size_t, const char *,...)
ssnprintf was designed to be a safer alternative to snprintf.
Definition futil.c:390
Menu * destroy_menu(Init *init)
Destroy Menu structure.
Definition mem.c:147
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.
int ui_perror(char *emsg_str)
Display a simple error message window or print to stderr.
Definition ui_common.c:1257

References Menu::begx, Menu::begy, cell_nt, cell_nt_hl, Line::choice_letter, Menu::choice_max_len, Line::choice_text, 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(), sfc_ptr, ssnprintf(), Menu::text_max_len, Menu::title, Line::type, ui_bkgdset(), ui_cm_surface_destroy(), ui_draw_text_fill(), ui_mvwaddch(), ui_perror(), ui_render(), ui_restore_wins(), ui_surface, and ui_tracked_sfc_box().

Referenced by main(), and popup_menu().

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