5. Прежде чем рассматривать их реализацию, введем некоторые структуры (на самом деле массив пунктов меню) для хранения меню. Когда выбирается пункт меню, возвращается первый символ выбранного пункта. Например, если это пункт меню add new CD (добавить новый CD), при его выборе будет возвращен символ а
. Когда компакт-диск выбран, будет отображаться расширенное меню.
char *main_menu[] = {
"add new CD",
"find CD",
"count CDs and tracks in the catalog",
"quit",
0,
};
char *extended_menu[] = {
"add new CD",
"find CD",
"count CDs and tracks in the catalog",
"list tracks on current CD";
"remove current CD",
"update track information",
"quit",
0,
};
На этом инициализация закончена. Теперь можно переходить к функциям программы, но сначала необходимо составить общее представление о взаимосвязях всех 16 функций. Функции разделены на три программных секции:
отображение меню;
добавление компакт-дисков в базу данных;
извлечение и отображение данных компакт-диска.
Визуальное представление дано на рис. 6.9.
Рис. 6.9
Взгляд на функцию
Функция main
позволяет выбирать пункты меню, пока не выбран вариант выхода из меню (quit). Далее приведен соответствующий код.
int choice;
initscr;
do {
choice = getchoice("Options:", current_cd[0] ? extended_menu : main_menu);
switch (choice) {
case 'q':
break;
case 'a':
break;
case 'c':
break;
case 'f':
break;
case 'l':
break;
case 'r':
break;
case 'u':
break;
}
} while (choice != 'q');
endwin;
exit(EXIT_SUCCESS);
}
Теперь давайте подробно рассмотрим функции, связанные с тремя секциями программы.
Формирование меню
В этой секции рассматриваются три функции, относящиеся к пользовательскому интерфейсу программы.
1. Функция getchoice
, вызываемая из функции main
, — это основная функция данной секции. В функцию getchoice
передается приглашение greet
и указатель choices
на базовое или расширенное меню (в зависимости от того, выбран ли компакт-диск). Вы также увидите, как main_menu
или extended_menu
передаются как параметры в описанную ранее функцию main
.
static int selected_row = 0;
int max_row = 0;
int start_screenrow = MESSAGE_LINE, start_screencol = 10;
char **option;
int selected;
int key = 0;
option = choices;
while (*option) {
max_row++;
option++;
}
if (selected_row >= max_row)
selected_row = 0;
mvprintw(start_screenrow - 2, start_screencol, greet);
keypad(stdscr, TRUE);
cbreak;
noecho;
key = 0;
while (key != 'q' && key != KEY_ENTER && key != '\n') {
if (key == KEY_UP) {
if (selected_row == 0) selected_row = max_row - 1;
else selected_row--;
}
if (key == KEY_DOWN) {
if (selected_row == (max_row - 1)) selected_row = 0;
else selected_row++;
}
selected = *choices[selected_row];
key = getch;
}
keypad(stdscr, FALSE);
nocbreak;
echo;
if (key == 'q') selected = 'q';
return(selected);
}
2. Обратите внимание на то, как две локальные функции clear_all_screen
и draw_menu
вызываются внутри функции getchoice
. Первой рассмотрим функцию draw_menu
:
void draw_menu(char* options[], int current_highlight, int start_row, int start_col) {
int current_row = 0;
char **option_ptr;
char *txt_ptr;
option_ptr = options;
while (*option_ptr) {