Reputation: 343
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
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
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