分享
 
 
 

第十六章:面板库(下)——(NCURSES Programming HOWTO中文版)

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

第十六章:面板库(下)16.5 移动面板和改变面板的大小 函数move_panel()可以将面板移动到你想移动的地方。它不改变面板在栈里的位置。务必使用move_panel()而不是用来移动窗口的函数mvwin() 来移动面板。

改变面板的大小有一点点复杂,没有哪个函数可以用来直接改变和面板关联的窗口的大小。要改变面板的大小,只有创建一个大小为你所需的新窗口。用函数replace_panel()可以替换和相应面板关联的窗口。但是别忘了要删除旧的窗口。和面板关联的窗口可以使用函数panel_window()来创建。

下面这个程序就用简单的方式体现了这个概念。同样,你可以用<TAB>键来使它们循环。要改变大小或移动当前的面板你可以按下 ' r' 或 ' m '键。然后使用方向键来改变大小和移动。在具体操作时,为获得需要的结果这个例子利用了用户已有的数据。

例16、 一个移动和改变面板大小的例子

#include <panel.h>

typedef struct _PANEL_DATA {

int x, y, w, h;

char label[80];

int label_color;

PANEL *next;

}PANEL_DATA;

#define NLINES 10

#define NCOLS 40

void init_wins(WINDOW **wins, int n);

void win_show(WINDOW *win, char *label, int label_color);

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);

void set_user_ptrs(PANEL **panels, int n);

int main()

{ WINDOW *my_wins[3];

PANEL *my_panels[3];

PANEL_DATA *top;

PANEL *stack_top;

WINDOW *temp_win, *old_win;

int ch;

int newx, newy, neww, newh;

int size = FALSE, move = FALSE;

/* 初始化curses */

initscr();

start_color();

cbreak();

noecho();

keypad(stdscr, TRUE);

/* 初始化所有的颜色 */

init_pair(1, COLOR_RED, COLOR_BLACK);

init_pair(2, COLOR_GREEN, COLOR_BLACK);

init_pair(3, COLOR_BLUE, COLOR_BLACK);

init_pair(4, COLOR_CYAN, COLOR_BLACK);

init_wins(my_wins, 3);

/* 更新面板栈的顺序。把面板2置于栈顶*/

my_panels[0] = new_panel(my_wins[0]); /* 把面板0压入栈,顺序: stdscr-0 */

my_panels[1] = new_panel(my_wins[1]); /* 把面板1压入栈。顺序: stdscr-0-1 */

my_panels[2] = new_panel(my_wins[2]); /* 把面板2压入栈,顺序: stdscr-0-1-2 */

set_user_ptrs(my_panels, 3);

/* 更新面板栈的顺序。把面板2置于栈顶 */

update_panels();

/* 在屏幕上显示出来 */

attron(COLOR_PAIR(4));

mvprintw(LINES - 3, 0, "Use 'm' for moving, 'r' for resizing");

mvprintw(LINES - 2, 0, "Use tab to browse through the windows (F1 to Exit)");

attroff(COLOR_PAIR(4));

doupdate();

stack_top = my_panels[2];

top = (PANEL_DATA *)panel_userptr(stack_top);

newx = top->x;

newy = top->y;

neww = top->w;

newh = top->h;

while((ch = getch()) != KEY_F(1))

{ switch(ch)

{ case 9: /* Tab 对应编号 */

top = (PANEL_DATA *)panel_userptr(stack_top);

top_panel(top->next);

stack_top = top->next;

top = (PANEL_DATA *)panel_userptr(stack_top);

newx = top->x;

newy = top->y;

neww = top->w;

newh = top->h;

break;

case 'r': /* 改变大小*/

size = TRUE;

attron(COLOR_PAIR(4));

mvprintw(LINES - 4, 0, "Entered Resizing :Use Arrow Keys to resize and press <ENTER> to end resizing");

refresh();

attroff(COLOR_PAIR(4));

break;

case 'm': /* 移动 */

attron(COLOR_PAIR(4));

mvprintw(LINES - 4, 0, "Entered Moving: Use Arrow Keys to Move and press <ENTER> to end moving");

refresh();

attroff(COLOR_PAIR(4));

move = TRUE;

break;

case KEY_LEFT:

if(size == TRUE)

{ --newx;

++neww;

}

if(move == TRUE)

--newx;

break;

case KEY_RIGHT:

if(size == TRUE)

{ ++newx;

--neww;

}

if(move == TRUE)

++newx;

break;

case KEY_UP:

if(size == TRUE)

{ --newy;

++newh;

}

if(move == TRUE)

--newy;

break;

case KEY_DOWN:

if(size == TRUE)

{ ++newy;

--newh;

}

if(move == TRUE)

++newy;

break;

case 10: /* Enter对应编号 */

move(LINES - 4, 0);

clrtoeol();

refresh();

if(size == TRUE)

{ old_win = panel_window(stack_top);

temp_win = newwin(newh, neww, newy, newx);

replace_panel(stack_top, temp_win);

win_show(temp_win, top->label, top->label_color);

delwin(old_win);

size = FALSE;

}

if(move == TRUE)

{ move_panel(stack_top, newy, newx);

move = FALSE;

}

break;

}

attron(COLOR_PAIR(4));

mvprintw(LINES - 3, 0, "Use 'm' for moving, 'r' for resizing");

mvprintw(LINES - 2, 0, "Use tab to browse through the windows (F1 to Exit)");

attroff(COLOR_PAIR(4));

refresh();

update_panels();

doupdate();

}

endwin();

return 0;

}

/* 显示所有的窗口 */

void init_wins(WINDOW **wins, int n)

{ int x, y, i;

char label[80];

y = 2;

x = 10;

for(i = 0; i < n; ++i)

{ wins[i] = newwin(NLINES, NCOLS, y, x);

sprintf(label, "Window Number %d", i + 1);

win_show(wins[i], label, i + 1);

y += 3;

x += 7;

}

}

/* 把每个面板设置为 PANEL_DATA 结构 */

void set_user_ptrs(PANEL **panels, int n)

{ PANEL_DATA *ptrs;

WINDOW *win;

int x, y, w, h, i;

char temp[80];

ptrs = (PANEL_DATA *)calloc(n, sizeof(PANEL_DATA));

for(i = 0;i < n; ++i)

{ win = panel_window(panels[i]);

getbegyx(win, y, x);

getmaxyx(win, h, w);

ptrs[i].x = x;

ptrs[i].y = y;

ptrs[i].w = w;

ptrs[i].h = h;

sprintf(temp, "Window Number %d", i + 1);

strcpy(ptrs[i].label, temp);

ptrs[i].label_color = i + 1;

if(i + 1 == n)

ptrs[i].next = panels[0];

else

ptrs[i].next = panels[i + 1];

set_panel_userptr(panels[i], &ptrs[i]);

}

}

/* 用一个边框和标题栏来显示窗口 */

void win_show(WINDOW *win, char *label, int label_color)

{ int startx, starty, height, width;

getbegyx(win, starty, startx);

getmaxyx(win, height, width);

box(win, 0, 0);

mvwaddch(win, 2, 0, ACS_LTEE);

mvwhline(win, 2, 1, ACS_HLINE, width - 2);

mvwaddch(win, 2, width - 1, ACS_RTEE);

print_in_middle(win, 1, 0, width, label, COLOR_PAIR(label_color));

}

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)

{ int length, x, y;

float temp;

if(win == NULL)

win = stdscr;

getyx(win, y, x);

if(startx != 0)

x = startx;

if(starty != 0)

y = starty;

if(width == 0)

width = 80;

length = strlen(string);

temp = (width - length)/ 2;

x = startx + (int)temp;

wattron(win, color);

mvwprintw(win, y, x, "%s", string);

wattroff(win, color);

refresh();

}

我们把注意力集中在主循环上。一旦程序捕获某个键被按下,它就执行相应的动作。如果按下了'r'键,"更改大小"模式就启动了。用户可以通过按方向键来更改面板的大小。当用户按<ENTER>键时,就确定了面板的新尺寸,程序就依照上面介绍的方法更改大小。不过在"更改大小"模式中,程序并没有真正显示出面板更改大小后的边框。这就留给读者一个作业:用点来显示新尺寸面板的边框。

当用户按'm'键时"移动面板"模式就启动了。这个操作会比"更改大小"简单一点。随着方向键的按下,新面板的位置也随之移动,当<ENTER>键按下时,程序就调用panel()函数把面板移动到光标的当前位置

在这个示范程序中,用户数据就代表PANEL_DATA,在查找面板的相关信息时扮演重要角色。就象在说明中所写,PANEL_DATA保存了面板的尺寸,标题,标题颜色和循环中指向下一个面板的指针。

16.6 隐藏和显示面板隐藏一个面板可以使用函数hide_panel()。这个函数仅仅是把它从面板栈中移走,因此,要在屏幕上隐藏的话只要调用函数update_panels() 和 doupdate()就可以了。它不会破坏面板结构和这个隐藏的面板。函数show_panel()可以让它重新显示。

下面的程序显示了如何隐藏面板。按键 'a' 或 'b' 或 'c'来分别实现显示或隐藏第一,二,三个窗口,其它的依此类推。它使用了一个用户给定的一个带有隐藏的变量的数据,用来跟踪窗口是否是隐藏的。因为某些原因,按理用来告诉用户一个面板是否隐藏的函数panel_hidden没有起作用。Michael Andres 在这里提供了一个错误报告。

例17、 一个隐藏和显示面板的例子

#include <panel.h>

typedef struct _PANEL_DATA {

int hide; /* 如果面板是隐藏的时候为真 */

}PANEL_DATA;

#define NLINES 10

#define NCOLS 40

void init_wins(WINDOW **wins, int n);

void win_show(WINDOW *win, char *label, int label_color);

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);

int main()

{ WINDOW *my_wins[3];

PANEL *my_panels[3];

PANEL_DATA panel_datas[3];

PANEL_DATA *temp;

int ch;

/* 初始化curses */

initscr();

start_color();

cbreak();

noecho();

keypad(stdscr, TRUE);

/* 初始化所有的颜色 */

init_pair(1, COLOR_RED, COLOR_BLACK);

init_pair(2, COLOR_GREEN, COLOR_BLACK);

init_pair(3, COLOR_BLUE, COLOR_BLACK);

init_pair(4, COLOR_CYAN, COLOR_BLACK);

init_wins(my_wins, 3);

/* 更新面板栈的顺序。把面板2置于栈顶 */

my_panels[0] = new_panel(my_wins[0]); /* Push 0, order: stdscr-0 */

my_panels[1] = new_panel(my_wins[1]); /* Push 1, order: stdscr-0-1 */

my_panels[2] = new_panel(my_wins[2]); /* Push 2, order: stdscr-0-1-2 */

/* 初始化所有的面板并都设为非隐藏的 */

panel_datas[0].hide = FALSE;

panel_datas[1].hide = FALSE;

panel_datas[2].hide = FALSE;

set_panel_userptr(my_panels[0], &panel_datas[0]);

set_panel_userptr(my_panels[1], &panel_datas[1]);

set_panel_userptr(my_panels[2], &panel_datas[2]);

/* 更新面板栈的顺序,第二个面板将置于栈顶 */

update_panels();

/* 在屏幕上显示 */

attron(COLOR_PAIR(4));

mvprintw(LINES - 3, 0, "Show or Hide a window with 'a'(first window) 'b'(Second Window) 'c'(Third Window)");

mvprintw(LINES - 2, 0, "F1 to Exit");

attroff(COLOR_PAIR(4));

doupdate();

while((ch = getch()) != KEY_F(1))

{ switch(ch)

{ case 'a':

temp = (PANEL_DATA *)panel_userptr(my_panels[0]);

if(temp->hide == FALSE)

{ hide_panel(my_panels[0]);

temp->hide = TRUE;

}

else

{ show_panel(my_panels[0]);

temp->hide = FALSE;

}

break;

case 'b':

temp = (PANEL_DATA *)panel_userptr(my_panels[1]);

if(temp->hide == FALSE)

{ hide_panel(my_panels[1]);

temp->hide = TRUE;

}

else

{ show_panel(my_panels[1]);

temp->hide = FALSE;

}

break;

case 'c':

temp = (PANEL_DATA *)panel_userptr(my_panels[2]);

if(temp->hide == FALSE)

{ hide_panel(my_panels[2]);

temp->hide = TRUE;

}

else

{ show_panel(my_panels[2]);

temp->hide = FALSE;

}

break;

}

update_panels();

doupdate();

}

endwin();

return 0;

}

/* 显示所有窗口 */

void init_wins(WINDOW **wins, int n)

{ int x, y, i;

char label[80];

y = 2;

x = 10;

for(i = 0; i < n; ++i)

{ wins[i] = newwin(NLINES, NCOLS, y, x);

sprintf(label, "Window Number %d", i + 1);

win_show(wins[i], label, i + 1);

y += 3;

x += 7;

}

}

/* 通过边框和标题显示窗口 */

void win_show(WINDOW *win, char *label, int label_color)

{ int startx, starty, height, width;

getbegyx(win, starty, startx);

getmaxyx(win, height, width);

box(win, 0, 0);

mvwaddch(win, 2, 0, ACS_LTEE);

mvwhline(win, 2, 1, ACS_HLINE, width - 2);

mvwaddch(win, 2, width - 1, ACS_RTEE);

print_in_middle(win, 1, 0, width, label, COLOR_PAIR(label_color));

}

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)

{ int length, x, y;

float temp;

if(win == NULL)

win = stdscr;

getyx(win, y, x);

if(startx != 0)

x = startx;

if(starty != 0)

y = starty;

if(width == 0)

width = 80;

length = strlen(string);

temp = (width - length)/ 2;

x = startx + (int)temp;

wattron(win, color);

mvwprintw(win, y, x, "%s", string);

wattroff(win, color);

refresh();

}

16.7、 panel_above()和panel_below()类函数函数panel_above() 和 panel_below() 可以用来查看某一个面板的上面和下面的面板。如果函数的参变量为NULL,它们就分别返回一个指向最底层和最上层面板的指针。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有