원하는 위치에 글자를 출력할 수 있도록 하는 move 류 함수들과, Window를 활용하기 위한 기초 함수들을 알아봅니다.
커서 이동: move 함수
ncurses를 사용하는 큰 이유 중 하나가 터미널 상에 원하는 위치에 원하는 문자를 출력할 수 있게 해주는 점입니다. 터미널 상에서의 커서 이동은 move
와 그 류의 함수들을 사용합니다.
1. move
제일 먼저, 커서의 이동을 위한 함수는 move()
입니다. 인자는 순서대로 커서를 놓을 Y좌표, X좌표입니다.
move(5, 7);
이렇게 호출하면 커서는 stdscr
의 5번째 줄, 7번째 글자 칸에 위치하게 됩니다.
ncurses의 대부분의 함수가 그렇듯이, move
함수도 wmove()
함수를 짝으로 가지고 있습니다. 그리고 자연스럽게 wmove
함수에는 윈도우가 인자로 들어갑니다.
wmove(win, 2, 3);
이 함수는 win
윈도우 내의 2번째 줄, 3번째 칸에 커서를 위치시킵니다.
stdscr
도 윈도우이므로, 다음 두 문장은 같은 동작을 수행합니다.
move(5, 7);
wmove(stdscr, 5, 7);
커서를 원하는 위치에 놓은 후 문자열을 출력해야 할 때가 있습니다. move 함수를 이용하면 쉽게 할 수 있습니다.
#include <ncurses.h>
int main(void){
initscr();
printw("0, 0");
move(5, 5);
printw("5, 5");
refresh();
getch();
endwin();
}
커서가 이동되어 출력된 것을 볼 수 있습니다.
2. mvprintw
move
와 printw
를 합쳐놓은 함수가 있습니다. 바로 mvprintw()
함수입니다. 보통 함수 이름 앞에 mv
가 붙으면 커서를 이동하는 기능 을 같이 가지고 있습니다. 따라서 아래 두 코드는 같은 동작을 수행합니다.
move(10, 10);
printw("10, 10");
mvprintw(10, 10, "10, 10");
3. mvwprintw
wmove
와 wprintw
를 합쳐놓은 함수도 존재합니다. wprintw
에 이동 기능이 합쳐쳤으니, 함수 이름은 mvwprintw()
입니다. 사용법은 mvprintw()
와 동일하고, 윈도우가 인자로 추가로 들어갑니다.
WINDOW * win = newwin(10, 20, 5, 10);
mvwprintw(win, 5, 5, "5, 5 : win");
wrefresh(win);
윈도우를 5, 10 위치에 만들었고, 윈도우 내부에서 5, 5 위치로 커서를 옮겼으므로, stdscr 입장에서 커서는 10, 15 위치에 위치한 후 출력하게 됩니다. 결과를 보시면 실제로 그런 것을 알 수 있습니다. 쉽게 확인하기 위해서 stdscr의 0, 0 위치에 출력을 해 놓았습니다.
Window 활용을 위한 기초 함수들
1. box
box()
는 윈도우의 테두리 를 만들어주기 위한 함수입니다. 지금까지는 윈도우를 만들면 만들었다는 표시가 나지 않았습니다. 하지만 box
를 이용하면 ncurses가 스스로 윈도우의 테두리를 만들어 줍니다. box()
함수의 인자로는 윈도우, 세로 테두리를 만들 문자, 가로 테두리를 만들 문자가 순서대로 들어갑니다.
#include <ncurses.h>
int main(void){
initscr();
WINDOW * win = newwin(10, 10, 10, 10);
box(win, '|', '-'); //테두리 만들기
mvwprintw(win, 1, 1, "Hello");
box(win, '*', '*');
refresh();
wrefresh(win);
getch();
endwin();
}
box 함수를 사용하여 테두리를 만들 때 주의할 점은, 테두리 또한 윈도우의 내용에 포함된다는 뜻입니다. 위 코드가 윈도우 내에서 1, 1 위치에 Hello를 출력하는 것을 볼 수 있듯이, 테두리의 내용도 윈도우의 내용에 포함됩니다. 그래서 box
를 이용한 테두리 작업 후에는 move
함수를 사용하여 커서를 적절히 옮긴 후 사용해야 합니다.
2. erase, werase
erase()
와 werase()
는 윈도우 안의 모든 내용을 공백으로 채워 윈도우를 지우는 기능을 합니다. werase()
는 내용을 지울 윈도우를 지정하고, erase()
는 stdscr
을 지웁니다.
#include <ncurses.h>
int main(void){
initscr();
WINDOW * win = newwin(10, 10, 10, 10);
box(win, '|', '-');
mvwprintw(win, 1, 1, "Hello");
werase(win);
refresh();
wrefresh(win);
getch();
endwin();
}
box()
함수로 만들었던 테두리 또한 윈도우의 내용이므로, 테두리까지 모두 지워버립니다.
3. mvwin
mvwin()
함수는 윈도우의 위치를 이동시킵니다.
#include <ncurses.h>
int main(void){
initscr();
WINDOW * win = newwin(10, 10, 10, 10);
box(win, '|', '-');
mvwin(20, 20); //10, 10 위치에 있던 윈도우를 20, 20으로 이동
refresh();
wrefresh(win);
getch();
endwin();
}
10, 10 위치에 생성되었던 윈도우를 20, 20 위치로 이동하였습니다.
4. delwin
이름에서 알 수 있듯이, 윈도우 객체를 소멸시키고 메모리 공간을 반환합니다. 하지만 객체만 사라질 뿐이고 스크린에 그린 내용이 바로 사라지지는 않습니다. 따라서 출력된 내용까지 모두 지우고자 할 경우, werase()
로 내용을 지운 후 delwin()
으로 객체를 지우면 됩니다. 코드로 보겠습니다.
#include <ncurses.h>
int main(void){
initscr();
WINDOW * win1 = newwin(10, 10, 10, 10);
WINDOW * win2 = newwin(10, 10, 25, 25);
box(win1, '|', '-');
box(win2, '*', '*');
refresh();
wrefresh(win1);
wrefresh(win2);
/* win1 삭제 */
werase(win1);
wrefresh(win1);
delwin(win1);
refresh();
getch();
endwin();
}
win1의 내용을 모두 지운 후 윈도우를 삭제하였으므로, 화면과 메모리에는 win2만 남게 됩니다.