int x loop;
int y_loop;
char a_letter = 'a';
initscr();
2. Заполните базовое окно символами, обновляя физический экран, когда заполнен логический экран:
move(5, 5);
printw("%s", "Testing multiple windows");
refresh();
for (y_loop = 0; y_loop < LINES - 1; y_loop++) {
for (x_loop = 0; x_loop < COLS - 1; x_loop++) {
mvwaddch(stdscr, y_loop, x_loop, a_letter);
a_letter++;
if (a_letter > 'z') a_letter = 'a';
}
}
/* Обновление экрана */
refresh();
sleep(2);
3. Теперь создайте окно 10×20 и вставьте в него текст перед прорисовкой окна на экране:
new_window_ptr = newwin(10, 20, 5, 5);
mvwprintw(new_window_ptr, 2, 2, "%s", "Hello World");
mwwprintw(new_window_ptr, 5, 2, "%s",
"Notice how very long lines wrap inside the window");
wrefresh(new_window_ptr);
sleep(2);
4. Измените содержимое фонового окна. Когда вы обновите экран, окно, на которое указывает new_window_ptr
, будет затемнено:
a_letter = '0';
for (y_lоор = 0; y_lоор < LINES - 1; y_lоор++) {
for (х_lоор = 0; xloop < COLS - 1; х_lоор++) {
mvwaddch(stdscr, y_loop, х_lоор, a_letter);
a_letter++;
if (a_letter > '9') a_letter = '0';
}
}
refresh();
sleep(2);
5. Если вы выполните вызов для обновления нового окна, ничего не изменится, поскольку вы не изменяли новое окно:
wrefresh(new_window_ptr);
sleep(2);
6. Но если вы сначала воспользуетесь функцией touchwin
и заставите библиотеку curses думать, что окно было изменено, следующий вызов функции wrefresh снова отобразит новое окно на переднем плане.
touchwin(new_window_ptr);
wrefresh(new_window_ptr);
sleep(2);
7. Добавьте еще одно накладывающееся окно с рамкой вокруг него.
popup_window_ptr = newwin(10, 20, 8, 8);
box(popup_window_ptr, '|', '-');
mvwprintw(popup_window_ptr, 5, 2, "%s", "Pop Up Window!");
wrefresh(popup_window_ptr);
sleep(2);
8. Поиграйте с новыми всплывающими окнами перед их очисткой и удалением.
touchwin(new_window_ptr);
wrefresh(new_window_ptr);
sleep(2);
wclear(new_window_ptr);
wrefresh(new_window_ptr);
sleep(2);
delwin(new_window_ptr);
touchwin(popup_window_ptr);
wrefresh(popup_window_ptr);
sleep(2);
delwin(popup_window_ptr);
touchwin(stdscr);
refresh();
sleep(2);
endwin();
exit(EXIT_SUCCESS);
}
К сожалению, нет возможности продемонстрировать выполнение этого фрагмента в книге, но на рис. 6.4 показан снимок экрана после отображения первого всплывающего окна.
Рис. 6.4
После того как будет изменен фон и появится новое всплывающее окно, вы увидите экран, показанный на рис. 6.5.
Рис. 6.5
Как это работает
После обычной инициализации программа заполняет стандартный экран цифрами, чтобы легче было увидеть новые окна, вставляемые на передний план. Далее показано, как можно наложить на фон новое окно с включенным в него текстом, разбитым на строки в соответствии с шириной окна. Далее вы видите, как с помощью функции touchwin
заставить curses перерисовать окно, даже если в нем ничего не менялось.
Затем перед закрытием curses и завершением программы вставляется второе окно, перекрывающее первое, чтобы показать, как библиотека curses может управлять перекрывающимися окнами.
Как видно из программного кода примера, при обновлении окон следует быть очень внимательным, чтобы они отображались в нужной очередности. Библиотека curses не хранит никаких сведений об иерархии окон, поэтому если вы попросите curses обновить несколько окон, управлять их иерархией придется вам.
Примечание
Для того чтобы библиотека curses отображала окна в нужном порядке, их следует обновлять в этом порядке. Один из способов добиться этого — сохранять все указатели ваших окон в массиве или списке, в которых поддерживается порядок их размещения, соответствующий порядку их появления на экране.
Оптимизация обновлений экрана
Как вы видели в примере из упражнения 6.4, обновление множественных окон требует некоторой ловкости, но не слишком обременительно. Но может возникнуть более серьезная проблема, если нуждающийся в обновлении терминал подключен через медленное сетевое соединение. К счастью, в наши дни с ней сталкиваются очень редко, но ее обработка настолько легка, что мы рассмотрим ее просто для полноты картины.
Читать дальше