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

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