我是 c 编码的新手,并尝试了这个和那个。最近我偶然发现了 ncurses 并正在尝试它。
在 Dan Gookin 的“ncurses 编程指南”中。我看到了焊盘及其属性和功能,现在我想归档以下内容:
我想分别创建一个比屏幕大得多的焊盘,一个 stdscr 的输出,所以屏幕显示了焊盘的一部分。与其他解决方案相比的优点是我不需要弄乱偏移量。你可以调用函数
prefresh(padname, y, x, min_y, min_x, max_y, max_y);
这会刷新屏幕 stdscr 并在从 min_y、min_x 到 max_y、max_x 的“剪切”中显示之前准备好的 pad 内容的一部分。到左上角的偏移量是 y,x。
所以稍后我想在左右和上下两个方向上围绕垫移动。我用一些虚拟数据(“吃我的裤子”和一个递增的数字)填充了一个垫子,并用简单的 for 循环移动它。它运行得很顺利,但我意识到了一个缺陷。在垫的边缘,信息被“剪切”了,我找不到制作包装的解决方案。如果偏移量为负,则预刷新仅通过 ERR,屏幕保持空白,而如果偏移量太大,则左侧或下边界进入视野。这通常不是问题,但我想存档一个解决方案,我可以在其中控制内容,使其成为无边对象。因此,如果将焊盘也移动到左侧,则右侧应移动到视野中,反之亦然。上下都一样。
有人知道如何在 C 环境中使用带有 ncurses 的 stdscr 上显示的垫来实现这一点吗?
这是我的测试文件(注释部分和下部分别用于测试,只是为了检查子窗口中的滚动是如何工作的。按几次任意键后,您将看到下边界进入视图。
#include <ncurses.h>
void draw_borders(WINDOW *screen); // some test on winndows only
int main(int argc, char *argv[]) {
int parent_x, parent_y, new_x, new_y;
int left_size = 10; // bad name, means height of the lower windows
initscr();
noecho();
curs_set(FALSE);
// init color use and define two colorpairs
start_color();
init_pair(1,COLOR_WHITE,COLOR_BLUE);
init_pair(2,COLOR_BLACK, COLOR_YELLOW);
init_pair(3,COLOR_BLACK, COLOR_CYAN);
// get our maximum window dimensions
getmaxyx(stdscr, parent_y, parent_x);
// set up initial windows
// WINDOW *field = newwin(parent_y - left_size, parent_x, 0, 0);
// but main screen will be stdscr showing an
// outcut of a padn so init pad here bigger than a screen
WINDOW *mainscreen;
mainscreen = newpad(500,1000);
if (mainscreen == NULL) {
endwin();
puts("Sorry, unable to allocate mainscreen");
return 1;
}
addstr("Added the new pad. Filling.\n");
// fill the pad
for ( int i = 0 ; i < 500000 ; i++) {
wprintw(mainscreen, " Eat my shorts %4d ", i);
}
addstr("Press key to update screen.\n");
getch();
// this is to checkout what happens if the right edge comes into view
// for (int x = 1000-parent_x ; x < 1000-parent_x + 10; x++) {
// prefresh(mainscreen, 0, x, 0 , 0, parent_y - left_size -1, parent_x-1);
// // napms(100);
// getch();
// }
// lower edge coming into view
for (int y = 0 ; y < 10 ; y++) {
prefresh(mainscreen, 500 - parent_y + left_size + y,
0, 0 , 0, parent_y - left_size -1, parent_x-1);
// napms(100);
getch();
}
// only to checkout how subwindows work
WINDOW *left = newwin(left_size, parent_x/2, parent_y - left_size, 0);
WINDOW *right = newwin(left_size, parent_x/2, parent_y - left_size, parent_x/2);
WINDOW *subwindow;
//assign color to windows
//wbkgd(field,COLOR_PAIR(1));
wbkgd(left,COLOR_PAIR(2));
wbkgd(right,COLOR_PAIR(3));
// draw our borders
//draw_borders(field);
draw_borders(left);
draw_borders(right);
// simulate a loop
// while(1) {
// getmaxyx(stdscr, new_y, new_x);
// if (new_y != parent_y || new_x != parent_x) {
// parent_x = new_x;
// parent_y = new_y;
// wresize(field, new_y - left_size, new_x);
// wresize(left, left_size, new_x/2);
// wresize(right, left_size, new_x/2);
//
// mvwin(left, new_y - left_size, 0);
// mvwin(right, new_y - left_size, parent_x/2);
//
//
//
// wclear(stdscr);
// wclear(field);
// wclear(left);
// wclear(right);
//
// draw_borders(field);
// draw_borders(left);
// draw_borders(right);
//
// }
// wresize(field,parent_y - left_size, parent_x);
wresize(left, left_size, parent_x/2);
wresize(right, left_size, parent_x/2);
mvwin(left, parent_y - left_size, 0);
mvwin(right, parent_y - left_size, parent_x/2);
// wclear(stdscr);
// wclear(field);
wclear(left);
wclear(right);
// draw_borders(field);
// draw_borders(left);
draw_borders(right);
// draw to our windows
mvwprintw(left, 1, 1, "Left. ");
mvwprintw(right, 1, 1, "Right");
// refresh each window
refresh();
// wrefresh(field);
wrefresh(left);
wrefresh(right);
subwindow = derwin(left, left_size-2, (parent_x/2)-2, 1, 1);
// scroll newly setup subwindow or not
scrollok(subwindow, TRUE);
for (int i = 0 ; i < 20 ; i++) {
waddstr(subwindow, "This is just some boring placeholder text. ");
napms(100);
wrefresh(subwindow);
}
for (int i = 0 ; i < 3 ; i++) {
scroll(subwindow);
napms(100);
wrefresh(subwindow);
}
for (int i = 0 ; i < 1 ; i++) {
wscrl(subwindow,-3);
napms(100);
wrefresh(subwindow);
}
// }
getch();
// clean up
// delwin(field);
delwin(left);
endwin();
return 0;
}
void draw_borders(WINDOW *screen) {
int x, y, i; getmaxyx(screen, y, x);
// 4 corners
mvwprintw(screen, 0, 0, "+");
mvwprintw(screen, y - 1, 0, "+");
mvwprintw(screen, 0, x - 1, "+");
mvwprintw(screen, y - 1, x - 1, "+");
// sides
for (i = 1; i < (y - 1); i++) {
mvwprintw(screen, i, 0, "|");
mvwprintw(screen, i, x - 1, "|");
}
// top and bottom
for (i = 1; i < (x - 1); i++) {
mvwprintw(screen, 0, i, "-");
mvwprintw(screen, y - 1, i, "-");
}
}