C指針原理(34)-Ncurses-文本終端的圖形

調用mousemask( )這個函數來激活你想要接收的鼠標事件。

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>

//code by [email protected]

//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>

//code by [email protected]

//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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章