Дизайн

Предыдущая  Содержание  Следующая V*D*V

Меню определяется как содержание какого-либо экрана, показываемого пользователю. Меню будет предоставлять пользователю два или более вариантов выбора:

 

/* 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), является визуально более привлекательной.

 

Предыдущая  Содержание  Следующая