ncurses皮膚庫:new_panel(),doupdate(),show_panel(),hide_panel(),move_panel(),del_panel()...
- Copyright(C)
NCURSES Programming HOWTO
皮膚庫
在精通curses 庫後,你可能會想嘗試著做一些更大的專案。為了讓介面看起來更專業,你可能會建立許多重疊的視窗,但不幸的是,你很快會發現它們變得難以管理,多次的更新視窗使開發變得異常困難。如果你沒有按照適當的順序重新整理那些視窗的話,它們就會給你帶來很多麻煩。
不過別失望,皮膚庫(Panel Library
)提供了一個很好的解決方案。用ncureses 的開發者的話來說就是:
如果你的介面設計需要使視窗在執行時置底或者置頂,雖然會為此付出很大代價,但是想要顯示正確的結果仍然很困難。這時候Panels 庫就可以派上用場了。 如果你要處理重疊的視窗,panels 庫就派上用場了。它使程式設計師避免使用大量的wnoutrefresh()
和doupdate()
函式來處理這個問題,並且減輕了由底向上正確處理這些資訊的負擔。這個庫維持著視窗重疊關係以及視窗順序,並在適當的時候更新它們。
那麼還等什麼呢?讓我們開始吧!
基礎知識
皮膚物件實際上是一個視窗,和其它視窗一樣被隱含地處理為容器的一部分。這個容器實際上是一個棧
,棧頂的皮膚是完全可見的。而其它皮膚在棧中所處的位置,決定了它們是否可見。其基本思想
是:建立一個棧來儲存那些重疊的皮膚,然後使用皮膚庫來正確的顯示它們
。 例如呼叫一個類似於refresh()
函式就按正確的順序來顯示這些皮膚。皮膚庫提供了一系列隱藏、顯示、移動、改變大小等皮膚操作的函式,使操作重疊的視窗變得更加簡單。 通常,一個皮膚程式的設計流程如下:
- 使用
newwin()
函式建立一個視窗,它將新增到皮膚裡。 - 建立皮膚(利用所建立的視窗)並將皮膚依據使用者指定的可見順序壓進棧。呼叫
new_panel()
函式即可建立該皮膚。 - 呼叫
update_panels()
函式就可將皮膚按正確的順序寫入虛擬螢幕,呼叫doupdate()
函式就能讓皮膚顯示出來。 show_panel()
,hide_panel()
,move_panel()
等函式分別用來對皮膚進行顯示、隱藏、移動等操作時,可以使用panel_hidden()
和panel_window()
這兩個輔助函式。你也可以使用使用者指標來儲存皮膚的資料,set_panel_userptr()
和panel_userptr()
函式分別用來設定和取得一個皮膚的使用者指標。- 當一個皮膚使用完畢後,用
del_panel()
函式就可刪除指定的皮膚。
現在讓我們通過一些程式來加深對這些概念的理解。下面將要看到的程式建立了3 個重疊的皮膚並把它們按次序顯示在螢幕上。
編譯包含皮膚庫的程式
要使用皮膚庫裡的函式,你首先要把panel.h
這個標頭檔案包含到你的程式碼中,同時編譯並連線與皮膚庫相關的程式必須新增-lpanel
和–lncurses
兩個引數。
#include <panel.h>
編譯和連線: gcc <program file> -lpanel –lncurses
例.一個有關皮膚庫的基礎例子
/*
Compile: gcc main.c -lncurses -lpanel
*/
#include <ncurses.h>
#include <panel.h>
int main()
{
WINDOW *my_wins[3];
PANEL *my_panels[3];
int lines = 10, cols = 40, y = 2, x = 4, i;
initscr();
cbreak();
noecho();
/* 為每個皮膚建立視窗*/
my_wins[0] = newwin(lines, cols, y, x);
my_wins[1] = newwin(lines, cols, y + 1, x + 5);
my_wins[2] = newwin(lines, cols, y + 2, x + 10);
/* 為視窗新增建立邊框以便你能看到皮膚的效果*/
for(i = 0; i < 3; ++i)
box(my_wins[i], 0, 0);
/* 按自底向上的順序,為每一個皮膚關聯一個視窗*/
my_panels[0] = new_panel(my_wins[0]);
/* 把皮膚0 壓進棧, 疊放順序: stdscr0*/
my_panels[1] = new_panel(my_wins[1]);
/* 把皮膚1 壓進棧, 疊放順序: stdscr01*/
my_panels[2] = new_panel(my_wins[2]);
/* 把皮膚2 壓進棧, 疊放順序: stdscr012*/
/* 更新棧的順序。把皮膚2 置於棧頂*/
update_panels();
/* 在螢幕上顯示*/
doupdate();
getch();
endwin();
}
/**
結果:
┌──────────────────────────────────────┐
│ ┌──────────────────────────────────────┐
│ │ ┌──────────────────────────────────────┐
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
└────│ │ │
└────│ │
└──────────────────────────────────────┘
*/
如你所見,這個程式就是按照16.1 所介紹的流程進行的。用newwin()
函式來建立視窗,然後通過new_panel()
函式把視窗新增到panels 棧裡面,當那些皮膚一個一個壓進棧的時候,棧就隨之更新了。最後呼叫update_panels()
函式和doupdate()
函式就可以讓它們在螢幕上顯示出來。
皮膚瀏覽
下面給出一個較複雜的例子。它建立了3 個視窗,通過<TAB>
鍵可以使它們迴圈置頂顯示。讓我們來看一下程式碼:
例 一個皮膚視窗瀏覽的例子
/*
Compile: gcc main.c -lncurses -lpanel
*/
#include <ncurses.h>
#include <panel.h>
#include <string.h>
#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 *top;
int ch;
/*初始化curses */
initscr();
start_color();
cbreak();
noecho();
keypad(stdscr, TRUE);
/* 初始化所有的顏色*/
init_pair(1, COLOR_RED, COLOR_WHITE);
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);
/* 按自底向上的順序,把每個視窗新增進一個皮膚*/
my_panels[0] = new_panel(my_wins[0]);
/* 把皮膚0 壓入棧, 順序: stdscr0*/
my_panels[1] = new_panel(my_wins[1]);
/* 把皮膚1 壓入棧,順序: stdscr01*/
my_panels[2] = new_panel(my_wins[2]);
/* 把皮膚2 壓入棧,順序: stdscr012*/
/* 為下一個皮膚建立使用者指標*/
set_panel_userptr(my_panels[0],my_panels[1]);
set_panel_userptr(my_panels[1],my_panels[2]);
set_panel_userptr(my_panels[2],my_panels[0]);
/* 更新皮膚棧的順序。把皮膚2 置於棧頂*/
update_panels();
/* 在螢幕上顯示*/
attron(COLOR_PAIR(4));
mvprintw(LINES-2, 0, "Use tab to browse through the windows (F1 to Exit)");
attroff(COLOR_PAIR(4));
doupdate();
top = my_panels[2];
while((ch = getch()) != KEY_F(1))
{
switch(ch)
{
case 9:
top = (PANEL *)panel_userptr(top);
top_panel(top);
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();
}
/**
結果:
┌──────────────────────────────────────┐
│ Window Number 1 │
├──────────────────────────────────────┤
│ ┌──────────────────────────────────────┐
│ │ Window Number 2 │
│ ├──────────────────────────────────────┤
│ │ ┌──────────────────────────────────────┐
│ │ │ Window Number 3 │
│ │ ├──────────────────────────────────────┤
└──────│ │ │
│ │ │
│ │ │
└──────│ │
│ │
│ │
└──────────────────────────────────────┘
Use tab to browse through the windows (F1 to Exit)
*/
使用使用者指標
在上面例子中,使用使用者指標在迴圈裡查詢下一個要顯示的皮膚。我們可以通過指定一個使用者指標給皮膚新增自定義資訊,這個指標可以指向你想要儲存的任何資訊。在這個例子中,我們用指標儲存了迴圈中下一個要顯示的皮膚。其中,使用者指標可以用set_panel_userptr()
函式設定。要想訪問某個皮膚的使用者指標,就必須以該皮膚作為panel_userprt()
函式的引數,函式就會返回該皮膚的使用者指標。結束皮膚的查詢後, top_panel()
函式就會將其置於皮膚棧的頂層。要想將任意一個皮膚置於皮膚棧的頂層,只需將該皮膚作為top_panel()
函式的引數。
移動皮膚和改變皮膚的大小
move_panel()
函式可將皮膚移動到螢幕上指定的位置,而不是改變皮膚在棧中的位置。確保在移動皮膚視窗時使用move_panel()
函式,而不是mvwin()
函式。改變皮膚大小有點兒複雜,因為沒有一個函式可以直接改變皮膚所關聯視窗的大小。一個可替代的解決方案是按照所需的大小建立一個新視窗,再呼叫replace_panel()
函式來替換相應皮膚上的關聯視窗。別忘了替換後刪除原視窗,使用panel_window()
函式可以找到與該皮膚關聯的視窗。 下面這個程式就體現了這種思想。你可以像先前那樣,用<Tab>
鍵迴圈檢視視窗。如果要改變當前皮膚大小或移動當前皮膚的位置,就要分別按下‘r’
或‘m’
鍵,然後使用方向鍵來調節,最後以<Enter>
鍵確定大小或者位置.。這個例子利用使用者資料儲存程式執行的必要資料。
例、一個移動和改變皮膚大小的例子
/*
Compile: gcc main.c -lncurses -lpanel
*/
#include <ncurses.h>
#include <panel.h>
#include <string.h>
#include <stdlib.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 壓入棧,順序: stdscr0*/
my_panels[1] = new_panel(my_wins[1]); /* 把皮膚1 壓入棧。順序: stdscr01*/
my_panels[2] = new_panel(my_wins[2]); /* 把皮膚2 壓入棧,順序: stdscr012*/
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"\
"resizeand 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();
}
結果測試
原始:
┌──────────────────────────────────────┐
│ Window Number 1 │
├──────────────────────────────────────┤
│ ┌──────────────────────────────────────┐
│ │ Window Number 2 │
│ ├──────────────────────────────────────┤
│ │ ┌──────────────────────────────────────┐
│ │ │ Window Number 3 │
│ │ ├──────────────────────────────────────┤
└──────│ │ │
│ │ │
│ │ │
└──────│ │
│ │
│ │
└──────────────────────────────────────┘
Use 'm' for moving, 'r' for resizing
Use tab to browse through the windows (F1 to Exit)
Tab鍵功能:
┌──────────────────────────────────────┐
│ Window Number 1 │
├──────────────────────────────────────┤
│ │──────┐
│ │ │
│ │──────┤
│ │─────────────┐
│ │3 │
│ │─────────────┤
└──────────────────────────────────────┘ │
│ │ │
│ │ │
└──────│ │
│ │
│ │
└──────────────────────────────────────┘
調整大小:
┌──────────────────────────────────────┐──────┐
│ Window Number 1 │ │
├──────────────────────────────────────┤──────┤
│ │─────────────┐
│ │3 │
│ │─────────────┤
└──────────────────────────────────────┘ │
│ │ │
│ │ │
└──────│ │
│ │
│ │
└──────────────────────────────────────┘
調整位置:
┌──────────────────────────────────────┐
│ Window Number 1 │
├──────────────────────────────────────┤
│ ┌──────────────────────────────────────┐─────────┐
│ │ Window Number 2 │ │
│ ├──────────────────────────────────────┤─────────┤
└───│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
└──────────────────────────────────────┘─────────┘
讓我們把注意力集中在主while 迴圈體上。一旦該迴圈發現某個鍵被按下,程式就會執行該鍵相應的處理。 當按下‘r’
鍵時,程式就會執行“更改大小”操作,同時你就可以通過方向鍵更改皮膚的大小,然後按<Enter>
鍵確定大小。在“更改大小”模式下,程式不會顯示視窗是怎樣更改大小的。請讀者思考一下如何用“點”來列印更改大小後視窗的邊框。 當按下‘m’
鍵時,程式就會執行“移動皮膚”操作。這個操作比“更改大小”簡單一點。按下方向鍵的同時,皮膚的位置隨之改變,當按下<Enter>
鍵時,程式就會呼叫move_panel()函式把皮膚固定到當前游標的位置。 在這個程式中, PANEL_DATA
就是所謂的使用者資料,它在查詢皮膚的相關資訊時扮演重要角色,正如說明中所說的那樣,PANEL_DATA
儲存了皮膚的尺寸,標題,標題顏色以及指向下一個皮膚的指標。
隱藏和顯示皮膚
使用hide_panel()
函式可以隱藏皮膚,它僅僅是把皮膚從皮膚棧中移走,不會破壞被隱藏皮膚所關聯的結構。而要在螢幕上隱藏皮膚需要呼叫update_panels()
函式和doupdate()
函式。此外,show_panel()函式可以讓顯示已隱藏皮膚。 以下程式展示了皮膚的隱藏。按下’a’
或’b’
或‘c’
鍵分別顯示或隱藏第一、二、三個視窗。使用了使用者資料中一個叫做hide
的變數來跟蹤視窗,標記出該視窗是否被隱藏。由於某些原因,panel_hidden()
函式(它用來告訴使用者一個皮膚是否隱藏)不能夠正常工作。MichaelAndres
在這裡提供了一個錯誤報告。
例、一個隱藏和顯示皮膚的例子
/*
Compile: gcc main.c -lncurses -lpanel
*/
#include <ncurses.h>
#include <panel.h>
#include <string.h>
#include <stdlib.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]);
/* 把皮膚0 壓入棧,順序: stdscr0*/
my_panels[1] = new_panel(my_wins[1]);
/* 把皮膚1 壓入棧。順序: stdscr01*/
my_panels[2] = new_panel(my_wins[2]);
/* 把皮膚2 壓入棧,順序: stdscr012*/
/* 初始化所有的皮膚並都設為非隱藏的*/
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'(ThirdWindow)");
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();
}
測試結果
原始:
┌──────────────────────────────────────┐
│ Window Number 1 │
├──────────────────────────────────────┤
│ ┌──────────────────────────────────────┐
│ │ Window Number 2 │
│ ├──────────────────────────────────────┤
│ │ ┌──────────────────────────────────────┐
│ │ │ Window Number 3 │
│ │ ├──────────────────────────────────────┤
└──────│ │ │
│ │ │
│ │ │
└──────│ │
│ │
│ │
└──────────────────────────────────────┘
Show or Hide a window with 'a'(first window)'b'(Second Window)'c'(ThirdWindow)
F1 to Exit
隱藏window1,press“a”
┌──────────────────────────────────────┐
│ Window Number 2 │
├──────────────────────────────────────┤
│ ┌──────────────────────────────────────┐
│ │ Window Number 3 │
│ ├──────────────────────────────────────┤
│ │ │
│ │ │
│ │ │
└──────│ │
│ │
│ │
└──────────────────────────────────────┘
同理,隱藏window2和window3按“b”,“c”
┌──────────────────────────────────────┐
│ Window Number 1 │
├──────────────────────────────────────┤
│ │
│ │
│ │
│ │─────────────┐
│ │3 │
│ │─────────────┤
└──────────────────────────────────────┘ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│ Window Number 1 │
├──────────────────────────────────────┤
│ ┌──────────────────────────────────────┐
│ │ Window Number 2 │
│ ├──────────────────────────────────────┤
│ │ │
│ │ │
│ │ │
└──────│ │
│ │
│ │
└──────────────────────────────────────┘
panel_above()
和panel_below()
類函式
panel_above()
和panel_below()
函式可以分別用來檢視某個皮膚的上層和下層皮膚。如果引數為NULL
,它們就分別返回皮膚棧中最上層和最下層皮膚的指標。
相關文章
- VC皮膚庫SkinCrafter.v3.4.0.0使用Raft
- 寶塔皮膚 資料庫怎麼連資料庫
- 用ncurses庫寫掃雷
- 小喬皮膚
- 部落格皮膚
- 寶塔皮膚
- wampserver服務皮膚Server
- jq切換皮膚
- 本部落格皮膚
- 部落格園皮膚-我的部落格園皮膚設定教程
- nvidia控制皮膚怎麼調 nvidia控制皮膚怎麼設定
- 如何在Linux中安裝Ncurses庫Linux
- Chrome DevTools的Network皮膚Chromedev
- [萌]chrome效能分析皮膚Chrome
- python 爬取 mc 皮膚Python
- SimpleMemory部落格園皮膚
- 安裝寶塔皮膚
- 如何使用Media Encoder中的「編碼」皮膚和「佇列」皮膚詳解佇列
- 寶塔皮膚進不去—寶塔皮膚進不去,網站打不開網站
- win10控制皮膚在哪裡 控制皮膚快捷鍵的開啟方式Win10
- CINNO Research:2021年1月手機皮膚行情: LTPS皮膚價格續跌
- centos寶塔皮膚修復CentOS
- 寶塔Linux皮膚命令大全Linux
- 部落格園自定義皮膚
- 手機端除錯皮膚除錯
- MyEclipse更換主題皮膚Eclipse
- 測試部落格園皮膚
- 寶塔皮膚安裝要求
- DSCC:MiniLED皮膚快速增長
- 阿里雲搭建寶塔皮膚阿里
- Linux效能監測皮膚 | NETDATALinux
- win10 如何禁用前皮膚插孔檢測 win10禁用前皮膚方法Win10
- win10控制皮膚在哪裡 win10如何開啟控制皮膚的方法Win10
- win10控制皮膚在哪裡 win10控制皮膚開啟的方法教程Win10
- windows10控制皮膚在哪裡 win10控制皮膚怎麼調出來WindowsWin10
- nvidia控制皮膚打不開 nvidia控制皮膚點了沒反應win10Win10
- win10撥出控制皮膚方法 win10怎麼撥出控制皮膚Win10
- win10 怎麼開啟控制皮膚_win10系統控制皮膚在哪裡Win10