MartinVotruba
MartinVotruba

Reputation: 343

NCURSES - Moving cursor in pad

I am writing an application in ncurses and I am not able to move cursor in a Pad. Is there a way how to do it? I thought that wmove(Window w, int y, int x) should be the correct way but I am not able to do it that way... Am I doing something wrong?

int main(void)
{
    WINDOW *p;
    FILE *f;
    int ch;
    initscr();
    keypad(stdscr, TRUE);
    /* create a new pad */
    p = newpad(WIDE,COLS);
    if( p == NULL )
    bomb("Unable to create new pad\n");
    /* open the file */
    f = fopen(FILENAME,"r");
    if( f == NULL)
    bomb("Unable to open file\n");
    int i =0;
    while( (ch=fgetc(f)) != EOF){
        waddch(p,ch);
    }
    fclose(f);
    prefresh(p,0, 0, 0,0, LINES-1,COLS-1);
    int c, cursorY=0, cursorX=0, linseCount = 0;
    wmove(p,2,2);
    while((c=wgetch(p))!='q'){
        switch(c){
          case KEY_LEFT:
                if(cursorX != 0)
                    cursorX--;
                break;
         case KEY_RIGHT:
                if (cursorX != COLS-1)
                    cursorX++;
                break;
         case KEY_UP:
                if(cursorY==0  && linseCount==0)
                    break;
                else if(cursorY == 0){
                    linseCount--;
                    prefresh(p,linseCount, 0, 0,0, LINES-1,COLS-1);
                }
                else
                    cursorY--;
                break;
         case KEY_DOWN:
                if(cursorY==LINES-1  && linseCount==WIDE-1)
                    break;
                else if(cursorY == LINES-1){
                    linseCount++;
                    prefresh(p,linseCount, 0, 0,0, LINES-1,COLS-1);
                }
                else
                    cursorY--;
                break;  
        }
        wmove(p,cursorY,cursorX);
        prefresh(p,linseCount, 0, 0,0, LINES-1,COLS-1); 

    }
    endwin();
return 0;
}

|||--------------------- EDIT - SOLUTION ------------------------|||

int main(void)
 {
    WINDOW *p;
    FILE *f;
    int ch;
    initscr();
    savetty();
    noecho();//disable auto-echoing
    cbreak();//making getch() work without a buffer I.E. raw characters
    keypad(stdscr,TRUE);//allows use of special keys, namely the arrow keys
    clear();    // empty the screen
    timeout(0); 

    /* create a new pad */
    p = newpad(WIDE,COLS);
    keypad(p, TRUE);
    if( p == NULL )
        bomb("Unable to create new pad\n");

    /* open the file */
    f = fopen(FILENAME,"r");
    if( f == NULL)
    bomb("Unable to open file\n");
    /* display file’s contents on the pad */

    while( (ch=fgetc(f)) != EOF)
        waddch(p,ch);
    fclose(f);


    /* display the pad’s contents on the screen */
    prefresh(p,0, 0, 0,0, LINES-1,COLS-1);
    int c, cursorY=0, cursorX=0, linseCount = 0;
    while((c=wgetch(p))!='q'){
        switch(c){
           case KEY_LEFT:
                    if(cursorX != 0)
                        cursorX--;
                    break;
            case KEY_RIGHT:
                    if (cursorX != COLS-1)
                        cursorX++;
                    break;
            case KEY_UP:
                    if(cursorY==0  && linseCount==0)
                        break;
                    else if(cursorY == linseCount){
                        cursorY--;
                        linseCount--;
                        prefresh(p,linseCount, 0, 0,0, LINES-1,COLS-1);
                    }
                    else
                        cursorY--;
                    break;
            case KEY_DOWN:
                    if(cursorY==LINES-1  && linseCount==WIDE-1)
                        break;
                    else if(cursorY == linseCount+LINES-1){
                        cursorY++;
                        linseCount++;
                        prefresh(p,linseCount, 0, 0,0, LINES-1,COLS-1);
                    }
                    else
                        cursorY++;
                    break;  
            }
            wmove(p,cursorY,cursorX);
            prefresh(p,linseCount, 0, 0,0, LINES-1,COLS-1);
    }
    endwin();
    return 0;
}

Upvotes: 1

Views: 1267

Answers (2)

TonyB
TonyB

Reputation: 947

Add the following call after your p = newpad(WIDE,COLS); add this call:

keypad(p, TRUE);

This will enable your pad to correctly handle escape sequences produced by your arrow keys...

Upvotes: 0

user3629249
user3629249

Reputation: 16540

these two lines result in the cursor being in a different place from where the variables curserX and curserY think the curser is located.

int c, cursorY=0, cursorX=0, linseCount = 0;
wmove(p,2,2);

this code, in handling a key_down arrow key

if(cursorY==LINES-1  && linseCount==WIDE-1)

is checking 'linsecount' against the x width which is not correct.

suggest starting curses with:

initscr();
savetty();
noecho();//disable auto-echoing
cbreak();//making getch() work without a buffer I.E. raw characters
keypad(stdscr,TRUE);//allows use of special keys, namely the arrow keys
clear();    // empty the screen
timeout(0); // reads do not block

when handling a key_down arrow key, there is this line:

else if(cursorY == LINES-1){

which results in no action of the curser is NOT already on the bottom line

suggest:

else if(cursorY < LINES-1){

similar corrections are needed for other key handling functions

the returned codes from many of the ncurses and pad functions need to be checked. doing the error checking of those return codes will make obvious what is failing.

when using this procedure:

prefresh(p,linseCount, 0, 0,0, LINES-1,COLS-1);

strongly, until problem is debugged, refresh the whole pad rather than just a single row

Upvotes: 1

Related Questions