1

我是 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, "-");
   }
}

4

0 回答 0