C指針原理(34)-Ncurses-文本終端的圖形
mousemask(?mmask_t?newmask,?/?你想要監聽的鼠標事件掩碼/
mmask_t?oldmask?)?/?舊版本使用的鼠標事件掩碼*/
主要事件如下:(一般來說,左鍵為1?號,右鍵為2?號)
BUTTON1_PRESSED?鼠標1?號鍵按下
BUTTON1_RELEASED?鼠標1?號鍵釋放
BUTTON1_CLICKED?鼠標1?號鍵單擊
BUTTON1_DOUBLE_CLICKED?鼠標1?號鍵雙擊
BUTTON1_TRIPLE_CLICKED?鼠標1?號鍵三擊
BUTTON2_PRESSED?鼠標2?號鍵按下
BUTTON2_RELEASED?鼠標2?號鍵釋放
BUTTON2_CLICKED?鼠標2?號鍵單擊
BUTTON2_DOUBLE_CLICKED?鼠標2?號鍵雙擊
BUTTON2_TRIPLE_CLICKED?鼠標2?號鍵三擊
BUTTON3_PRESSED?鼠標3?號鍵按下
BUTTON3_RELEASED?鼠標3?號鍵釋放
BUTTON3_CLICKED?鼠標3?號鍵單擊
BUTTON3_DOUBLE_CLICKED?鼠標3?號鍵雙擊
BUTTON3_TRIPLE_CLICKED?鼠標3?號鍵三擊
BUTTON4_PRESSED?鼠標4?號鍵按下
BUTTON4_RELEASED?鼠標4?號鍵釋放
BUTTON4_CLICKED?鼠標4?號鍵單擊
BUTTON4_DOUBLE_CLICKED?鼠標4?號鍵雙擊
BUTTON4_TRIPLE_CLICKED?鼠標4?號鍵三擊
BUTTON_SHIFT?在鼠標事件發生時,伴隨Shift?鍵按下
BUTTON_CTRL?在鼠標事件發生時,伴隨Ctrl?鍵按下
BUTTON_ALT?在鼠標事件發生時,伴隨Alt?鍵按下
ALL_MOUSE_EVENTS?報告所有的鼠標事件
REPORT_MOUSE_POSITION?報告鼠標移動位置
getmouse()函數將這個事件返回一個相應的指針。這個指針結構是這樣的:
typedef?struct
{
short?id??/?ID?用來辨別不同的設備
int?x,?y,?z??/?事件發生的坐標/
mmask_t?bstate??/?鼠標按鍵狀態/
}
Bstate?是我們關註的最主要變量,它返回了當前鼠標按鍵的狀態。下面的這段代碼可以捕捉鼠標左鍵按下:
if(event.bstate?&?BUTTON1_PRESSED)
我們在上面的編輯器中加上鼠標左鍵定位。
dp@dp:~/cursestest?%?cat?a.c
#include?<locale.h>
#include?<stdio.h>
#include?<ncurses.h>
//date:2014/1/17
int?main(int?argc,?char?*argv[])
{
MEVENT?event;
setlocale(LC_ALL,"");
initscr();
clear();
noecho();
cbreak();
if(has_colors()?==?FALSE)
{?
endwin();
printf("你的終端不支持色彩!\n");
return?(1);
}
start_color();?/啟動color?機制/
mvprintw(5,COLS/2-10,"簡單編輯器-僅限於單個屏幕的編輯");
refresh();
init_pair(1,?COLOR_GREEN,?COLOR_BLACK);
WINDOW?*win1;??
int?width=COLS-14;
??????? int?height=LINES-14;
??????? int?x,y;
??????? win1=newwin(height,width,7,7);//新窗口(行,列,begin_y,begin_x)
keypad(win1,TRUE);
????????wattron(win1,COLOR_PAIR(1));
????????box(win1,ACS_VLINE,ACS_HLINE);
wrefresh(win1);
getyx(win1,y,x);
++y;++x;
mmask_t?oldmousemask;
mousemask(ALL_MOUSE_EVENTS,?&oldmousemask);
while(1){
int?c=mvwgetch(win1,y,x);
switch(c)
{ case?KEY_MOUSE:
if(getmouse(&event)?==?OK)
{ /?When?the?user?clicks?left?mouse?button?/
if(event.bstate?&?BUTTON1_PRESSED)
{
y=event.y-7;x=event.x-7;
wmove(win1,y,x);
}
}
break;
case?KEY_RIGHT:
++x;
if?(x>=width-1)?{
++y;
x=1;
}
break;
case?KEY_LEFT:?--x;
if?(x<1){
--y;
x=width-2;
}
break;
case?KEY_UP:
??????? --y;
if?(y<1){
y=height-2;
}
break;
case?KEY_DOWN:
??????? ++y;
if?(y>=height-1){
y=1;
}
break;
case?10:
??????? ++y;
if?(y>=height-1){
y=1;
}
break;
case?KEY_F(1):
??????? //退出
mvprintw(LINES-3,2,"退出編輯器嗎?");
mvprintw(LINES-2,2,"????");
refresh();
int?ans=getch();
if?(ans==‘Y‘?||ans==‘y‘)
{
mvprintw(LINES-2,2,"是\n");
refresh();
return?0;
}else
mvprintw(LINES-2,2,"否\n");
refresh();
break;
case?KEY_F(12):
??????? //刪除某行
wdeleteln(win1);
winsertln(win1);
???????? box(win1,ACS_VLINE,ACS_HLINE);
case?KEY_DC:
??????? //刪除某字符
??????? ???????? mvwprintw(win1,y,x,"?");
break;
default:
??????? ???????? mvwprintw(win1,y,x,"%c",c);
++x;
if?(x>=width-1){
?????? ? ++y;
x=1;
}
if?(y>=height-1){
y=1;
}
wrefresh(win1);
}
}
????????wattroff(win1,COLOR_PAIR(1));
endwin();
mousemask(oldmousemask,NULL);
return?0;
}
執行
dp@dp:~/cursestest?%?gcc?-lncursesw?a.c?-o?mytest
dp@dp:~/cursestest?%?./mytest
scr_dump()?函數可以把當前屏幕的內容存入指定文件,即以文件名作為函數的參數,而通過?scr_restore()函數調用屏幕數據文件來恢復屏幕。它們的函數調用方式為:
scr_dump(const?char?*file)?
scr_restore(const?char?*file)?
getwin()函數用來將窗口內容存儲到一個指定的文件中。?putwin()?函數則調用相應的文件來恢復窗口。
它們的函數調用方式為:
getwin(FILE?*?filep)?
putwin(WINDOW?win,?FILE??filep)
我們先利用scr_dump()與scr_restore()函數,實現將編輯器的內容存盤與讀取,但是它會把整個屏幕保存下來。
設定F9讀取,F10存盤,同時修改退出為F11,並加入對退格鍵的支持。
dp@dp:~/cursestest?%?cat?a.c
#include?<locale.h>
#include?<stdio.h>
#include?<ncurses.h>
//date:2014/1/17
int?isExist(char?*filename)
{
?????????return?(access(filename,?0)?==?0);
}
int?main(int?argc,?char?*argv[])
{
????????MEVENT?event;
????????setlocale(LC_ALL,"");
????????initscr();
????????clear();
????????noecho();
????????cbreak();
????????if(has_colors()?==?FALSE)
????????{
????????endwin();
????????printf("你的終端不支持色彩!\n");
????????return?(1);
????????}
????????start_color();?/啟動color?機制/
????????mvprintw(3,COLS/2-10,"簡單編輯器-僅限於單個屏幕的編輯");
????????mvprintw(4,COLS/2-15,"【F9讀保存內容,F10存盤,F11退出,F12刪除整行】");
????????refresh();
????????init_pair(1,?COLOR_GREEN,?COLOR_BLACK);
????????WINDOW?*win1;
????????int?width=COLS-14;
????????int?height=LINES-14;
????????int?x,y;
????????win1=newwin(height,width,7,7);//新窗口(行,列,begin_y,begin_x)
????????keypad(win1,TRUE);
????????wattron(win1,COLOR_PAIR(1));
????????box(win1,ACS_VLINE,ACS_HLINE);
????????wrefresh(win1);
????????getyx(win1,y,x);
????????++y;++x;
????????mmask_t?oldmousemask;
????????int?ans=0;
????????mousemask(ALL_MOUSE_EVENTS,?&oldmousemask);
????????while(1){
????????????????int?c=mvwgetch(win1,y,x);
????????????????switch(c)
????????????????{???????case?KEY_MOUSE:
????????????????????????if(getmouse(&event)?==?OK)
????????????????????????{???????/?When?the?user?clicks?left?mouse?button?/
????????????????????????????????if(event.bstate?&?BUTTON1_PRESSED)
????????????????????????????????{
????????????????????????????????????????????????y=event.y-7;x=event.x-7;
????????????????????????????????????????????????wmove(win1,y,x);
????????????????????????????????}
????????????????????????}
????????????????????????break;
????????????????????????case?KEY_BACKSPACE:
????????????????????????????????--x;
????????????????????????????????if?(x<1){
????????????????????????????????????????--y;x=width-2;
????????????????????????????????}
????????????????????????????????if?(y<1){
????????????????????????????????????????y=height-2;
????????????????????????????????}
????????????????????????????????mvwprintw(win1,y,x,"?");
????????????????????????????????break;
????????????????????????case?KEY_RIGHT:
????????????????????????????????++x;
????????????????????????????????if?(x>=width-1)?{
????????????????????????????????????????++y;
????????????????????????????????????????x=1;
????????????????????????????????}
????????????????????????????????break;
????????????????????????case?KEY_LEFT:?--x;
????????????????????????????????if?(x<1){
????????????????????????????????????????--y;
????????????????????????????????????????x=width-2;
????????????????????????????????}
????????????????????????????????break;
????????????????????????case?KEY_UP:
????????????????????????????????--y;
????????????????????????????????if?(y<1){
????????????????????????????????????????y=height-2;
????????????????????????????????}
????????????????????????????????break;
????????????????????????case?KEY_DOWN:
????????????????????????????????++y;
????????????????????????????????if?(y>=height-1){
????????????????????????????????????????y=1;
????????????????????????????????}
????????????????????????????????break;
????????????????????????case?10:
????????????????????????????????++y;
????????????????????????????????if?(y>=height-1){
????????????????????????????????????????y=1;
????????????????????????????????}
????????????????????????????????break;
????????????????????????case?KEY_F(11):
????????????????????????????????//退出
????????????????????????????????mvprintw(LINES-3,2,"?????????????????????");
????????????????????????????????mvprintw(LINES-3,2,"退出編輯器嗎??????");
????????????????????????????????mvprintw(LINES-2,2,"????");
????????????????????????????????refresh();
????????????????????????????????ans=getch();
????????????????????????????????if?(ans==‘Y‘?||ans==‘y‘)
????????????????????????????????{
????????????????????????????????????????mvprintw(LINES-2,2,"是\n");
????????????????????????????????????????refresh();
????????????????????????????????????????return?0;
????????????????????????????????}else
????????????????????????????????????????mvprintw(LINES-2,2,"否\n");
????????????????????????????????????????refresh();
????????????????????????????????break;
????????????????????????case?KEY_F(10):
????????????????????????????????//存盤
????????????????????????????????mvprintw(LINES-3,2,"?????????????????????");
????????????????????????????????mvprintw(LINES-3,2,"保存當前內容嗎??????");
????????????????????????????????mvprintw(LINES-2,2,"????");
????????????????????????????????refresh();
????????????????????????????????ans=getch();
????????????????????????????????if?(ans==‘Y‘?||ans==‘y‘)
????????????????????????????????{
????????????????????????????????????????mvprintw(LINES-3,2,"?????????????????????");
????????????????????????????????????????scr_dump("myedit.dat");
????????????????????????????????????????mvprintw(LINES-3,2,"保存當前內容嗎??????");
????????????????????????????????????????mvprintw(LINES-2,2,"是\n");
????????????????????????????????????????refresh();
????????????????????????????????}else
????????????????????????????????????????mvprintw(LINES-2,2,"否\n");
????????????????????????????????????????refresh();
????????????????????????????????break;
????????????????????????case?KEY_F(9):
????????????????????????????????//讀取存盤
????????????????????????????????mvprintw(LINES-3,2,"????????????????????");
????????????????????????????????mvprintw(LINES-3,2,"讀取保存內容嗎?????");
????????????????????????????????mvprintw(LINES-2,2,"????");
????????????????????????????????refresh();
????????????????????????????????ans=getch();
????????????????????????????????if?(ans==‘Y‘?||ans==‘y‘)
????????????????????????????????{
????????????????????????????????????????if?(isExist("myedit.dat"))?scr_restore("myedit.dat");
????????????????????????????????????????mvprintw(LINES-3,2,"讀取保存內容嗎?????");
????????????????????????????????????????mvprintw(LINES-2,2,"是\n");
????????????????????????????????????????refresh();
????????????????????????????????}else
????????????????????????????????????????mvprintw(LINES-2,2,"否\n");
????????????????????????????????????????refresh();
????????????????????????????????break;
????????????????????????case?KEY_F(12):
????????????????????????????????//刪除某行
????????????????????????????????wdeleteln(win1);
????????????????????????????????winsertln(win1);
????????????????????????????????box(win1,ACS_VLINE,ACS_HLINE);
????????????????????????????????break;
????????????????????????case?KEY_DC:
????????????????????????????????//刪除某字符
????????????????????????????????mvwprintw(win1,y,x,"?");
????????????????????????????????break;
????????????????????????default:
????????????????????????????????mvwprintw(win1,y,x,"%c",c);
????????????????????????????????++x;
????????????????????????????????if?(x>=width-1){
????????????????????????????????????????++y;
????????????????????????????????????????x=1;
????????????????????????????????}
????????????????????????????????if?(y>=height-1){
????????????????????????????????????????y=1;
????????????????????????????????}
????????????????????????????????wrefresh(win1);
????????????????}
????????}
????????wattroff(win1,COLOR_PAIR(1));
????????endwin();
????????mousemask(oldmousemask,NULL);
????????return?0;
}
執行
dp@dp:~/cursestest?%?gcc?-lncursesw?a.c?-o?mytest
dp@dp:~/cursestest?%?./mytest
C指針原理(34)-Ncurses-文本終端的圖形