Дизайн |
Предыдущая Содержание Следующая |
Меню определяется как содержание какого-либо экрана, показываемого пользователю. Меню будет предоставлять пользователю два или более вариантов выбора:
/* 25 строк на страницу является разумным для большинства типов терминалов, но программист может выделить место для текста заголовков, колонтитулов */
#define MAX_SELECTIONS 24
< вставьте здесь определение типа для SELECTION >
typedef struct _menu { int id; int num_selections; SELECTION selection[MAX_SELECTIONS]; }MENU;
Мы добавляем для использования в дальнейшем код идентификации каждого меню. Эти идентификационные коды могут быть прикреплены в коде к меткам с описанием используя перечисление:
enum _menu_ids { MAIN_MENU, SECONDARY_MENU, .... };
Выбор является основным строительным блоком меню. Когда что-то выбрано, это может привести в другое меню или вызвать функцию действия, такую, как сохранение файла или порождение задачи управления. Как минимум, он состоит из строки с подсказкой или текстовой строки, и выбора действия:
typedef struct _selection { char prompt[MAX_PROMPT_LEN]; int (*function)(int); int fn_arg; }SELECTION;
Здесь мы предполагаем, что выбор действия будет иметь целочисленный аргумент (для дополнительной гибкости) и будет возвращать целое число (для возвращения возможных ошибок).
Структура меню в банкомате (показываемого после вставки карты и ввода ПИН-кода) может быть определена, как показано в Листинге 1.
По мере добавления новых типов счетов (финансовые рынки, МРК, кредитные карты), всё, что необходимо сделать программисту, это добавить соответствующие пункты меню, а также написать соответствующие обработчики для do_deposit(), do_withdrawl() и show_balance(). Если функции банкомата необходимо расширить, чтобы начать видео вызов в банк при помощи встроенной камеры и микрофона, к основному меню может быть добавлен новый элемент и чтобы поддержать новую возможность, пишется новая функция обработки.
Меню управляется одной функцией:
void mdi() /* интерфейс управления меню */ { char c; MENU *curr_menu = find_menu(MAIN_MENU); int curr_selection = 0;
/* выполняем инициализацию ввода/вывода, отрисовываем вводную страницу и так далее */
init_mdi()
/* отрисовка главного меню */
draw_menu(curr_menu, curr_selection);
while(TRUE) {
Следующая инструкция - это то, где mdi() будет находится основную часть своего времени ожидания. Если эта программа работает в режиме реального времени, эта функция должна иметь методы для возврата контроля над процессором для многозадачного ядра.
c = readch(); // returns special codes defined by us // for arrow keys, page_up, and so on. switch(c) { case UP_ARROW: if(curr_selection !=0) { curr_selection--; draw_menu(curr_menu, curr_selection); } break;
case DOWN_ARROW: if(curr_selection < (curr_menu->num_selections-1)) { curr_selection++; draw_menu(curr_menu, curr_selection); } break;
case ENTER: (*curr_menu->selection[curr_selection].function) (curr_menu->selection[curr_selection].fn_arg); break; } }
Функция draw_menu() не только устанавливает выбор на экране, но и показывает, какой выбор в настоящее время активен, используя инверсный режим печати текста или указывающую стрелку.
Мерцание экрана, вызванное перерисовкой меню при изменении выбора с помощью клавиш, может раздражать. Функция, которая снимает выделение текущего варианта и подсвечивает новый (одна функция, вызываемая с аргументами FORWARD или BACKWARD), является визуально более привлекательной.
|
Предыдущая Содержание Следующая |