Programowanie z ncurses (index)


Programowanie z ncurses (4) - zarządzanie oknami

ZADANIE 4.1

W katalogu domowym utworzyć podkatalog skarbiec. Utworzyć w nim pliki Makefile i skarbiec.c postaci:


/*
*  skarbiec.c
*/

#include <unistd.h>   /* sleep() */
#include <string.h>  /* strcmp() */
#include <stdlib.h>
#include <curses.h>
#define MAXLINE  80

int main(void) 
{
int c, i;
int ymax, xmax;
char tajne[]= "sezam";  /* haslo do skarbca */
char napis[MAXLINE];  /* haslo podane przez usera */
int koniec= FALSE;  /* sterowanie petla do-while */
WINDOW *win;

initscr(); /* mozna sprawdzic */
crmode();  /* zmiana trybu pracy */
getmaxyx(stdscr, ymax, xmax);

if ((win= subwin(stdscr, 3, 60, ymax/3, (xmax-60)/2)) == NULL) {
	endwin();
	fprintf(stderr,"Error: subwin()\n");
	exit(1);
}
do {  /* sprawdzanie hasla */
	box(win, ACS_VLINE, ACS_HLINE); /* ramka na okno */
	mvwaddstr(win, 1, 1, "Klucz do skarbca: ");
	wrefresh(win);
	noecho();
	i= 0;
	while ((c= getch()) != '\n' && (i < MAXLINE)) {
		napis[i]= c;
		++i;
		waddch(win, '*');
		wrefresh(win);
	}
	echo();
	napis[i]= '\0';
	if (strcmp(napis,tajne) == 0) {
		koniec= TRUE;
	} else {
		wclear(win);
		mvwprintw(win, 1, 1, "Klucz nieprawidlowy!");
		box(win, ACS_VLINE, ACS_HLINE); /* ramka na okno */
		wrefresh(win);
		sleep(2);
	}
	wclear(win);
} while (koniec == FALSE); /* powtarzaj dopoki to jest prawda */

mvwprintw(win, 1, 1, "Podano dobry klucz: %s\n", napis);
box(win, ACS_VLINE, ACS_HLINE); /* ramka na okno */
wrefresh(win);
sleep(2);
delwin(win);

endwin();
return 0;
}

Skompilować i uruchomić program.

ZADANIE 4.2

W katalogu domowym utworzyć podkatalog samolot. Utworzyć w nim pliki Makefile i samolot.c postaci:


/*
*  samolot.c (subwin)
*/

#include <unistd.h>   /* sleep() */
#include <stdlib.h>  /* exit() */
#include <curses.h>
#define ROZMIAR   10
#define KROK      7

int main(void) 
{
int i;
int xmax, ymax;
WINDOW *win;

initscr(); /* mozna sprawdzic */
bkgd('.');
refresh();
if ((win= subwin(stdscr,ROZMIAR,ROZMIAR,0,0)) == NULL) {
	endwin();
	fprintf(stderr,"Error: subwin()\n");
	exit(1);
}
wbkgd(win, ' '); /* trzeba zaslonic kropki z stdscr */
wprintw(win, "\n SAMOLOT\n");
box(win,0,0);
wrefresh(win);
sleep(1);
getmaxyx(stdscr,ymax,xmax);
i= 0;
while (i < (xmax-ROZMIAR)) {
	mvwin(win, (ymax-ROZMIAR)/2, i);
	refresh(); /* odswiezamy tylko stdscr! */
	sleep(1);
	i+= KROK;
}
delwin(win);

endwin();
return 0;
}

Skompilować i uruchomić program.

ZADANIE 4.3

W katalogu domowym utworzyć podkatalog samolot2. Utworzyć w nim pliki Makefile i samolot2.c postaci:


/*
*  samolot2.c (newwin)
*/

#include <unistd.h>   /* sleep() */
#include <stdlib.h>  /* exit() */
#include <curses.h>
#define ROZMIAR   15
#define KROK      10

int main(void) 
{
int i;
int xmax, ymax;
WINDOW *win;

initscr(); /* mozna sprawdzic */

bkgd('.');
refresh();
if ((win= newwin(ROZMIAR,ROZMIAR,1,1)) == NULL) {
	endwin();
	fprintf(stderr,"Error: newwin()\n");
	exit(1);
}
wbkgd(win, ' ');
mvwprintw(win,1,1, " SAMOLOT");
box(win,0,0);
wrefresh(win);
sleep(1);

getmaxyx(stdscr,ymax,xmax);
i= 0;
while (i < (xmax-ROZMIAR)) {
	mvwin(win, (ymax-ROZMIAR)/2, i);
	clear(); /* trzeba wymazac poprzedni obrazek okna */
	refresh();
	wrefresh(win); /* bez tego nie narysuje win */
	sleep(1);
	i+= KROK;
}
delwin(win);

endwin();
return 0;
}

Skompilować i uruchomić program.

ZADANIE 4.4

W katalogu domowym utworzyć podkatalog samolot3. Utworzyć w nim pliki Makefile i samolot3.c postaci:


/*
*  samolot3.c (sterowanie kursorami)
*/

#include <stdlib.h>  /* exit() */
#include <curses.h>
#define YSIZE  5    /* wysokosc okna */
#define XSIZE  9    /* szerokosc okna */

int main(void) 
{
int ch;
int ymax, xmax;
int ystart, xstart;
WINDOW *win;

initscr(); /* mozna sprawdzic */
cbreak();
keypad(stdscr, TRUE);
getmaxyx(stdscr,ymax,xmax);
ystart= (ymax - YSIZE) / 2;
xstart= (xmax - XSIZE) / 2;
bkgd('.');
printw("Press F1 to exit");
refresh();

if ((win= subwin(stdscr,YSIZE,XSIZE,ystart,xstart)) == NULL) {
	endwin();  /* najpierw konczymy curses */
	fprintf(stderr,"Error: subwin()\n");
	exit(1);
}
wbkgd(win, ' '); /* trzeba zaslonic kropki z stdscr */
wprintw(win, "\n SAMOLOT\n");
box(win,0,0);
wrefresh(win);
while ((ch = getch()) != KEY_F(1)) {	
	if (ch == KEY_LEFT) {
		mvwin(win, ystart, --xstart);
	} else if (ch == KEY_RIGHT) {
		mvwin(win, ystart, ++xstart);
	} else if (ch == KEY_UP) {
		mvwin(win, --ystart, xstart);
	} else if (ch == KEY_DOWN) {
		mvwin(win, ++ystart, xstart);
	}
	refresh(); /* odswiezamy tylko stdscr! */
}
delwin(win);
endwin();
return (0);
}

Skompilować i uruchomić program. Poprawić program, aby podokno nie wychodziło poza krawędzie ekranu.

ZADANIE 4.5

W katalogu domowym utworzyć podkatalog win_border. Utworzyć w nim pliki Makefile i win_border.c postaci:


/*
*  win_border.c
*
* Program z HOWTO zmodyfikowany.
*/

#include <ncurses.h>

WINDOW *create_win(int height, int width, int starty, int startx);
void destroy_win(WINDOW *local_win);

int main(void)
{
WINDOW *win;
int xmax, ymax;
int startx, starty, width, height;
int ch;

initscr();
cbreak();
keypad(stdscr, TRUE);
getmaxyx(stdscr, ymax, xmax);

height = 3;
width = 10;
starty = (ymax - height) / 2;	/* Obliczmy polozenie okna */
startx = (xmax - width) / 2;
printw("Press F1 to exit");
refresh();
win = create_win(height, width, starty, startx);

while ((ch = getch()) != KEY_F(1)) {	
	if (ch == KEY_LEFT) {
		destroy_win(win);
		win = create_win(height, width, starty, --startx);
	} else if (ch == KEY_RIGHT) {
		destroy_win(win);
		win = create_win(height, width, starty, ++startx);
	} else if (ch == KEY_UP) {
		destroy_win(win);
		win = create_win(height, width, --starty, startx);
	} else if (ch == KEY_DOWN) {
		destroy_win(win);
		win = create_win(height, width, ++starty, startx);
	}
}
endwin();
return 0;
}


WINDOW *create_win(int height, int width, int starty, int startx)
{
WINDOW *local_win;

local_win = newwin(height, width, starty, startx);
box(local_win,0,0);
wrefresh(local_win);
return local_win;
}


void destroy_win(WINDOW *local_win)
{	
/* box(local_win, ' ', ' ');   to nie dziala, bo zostaja narozniki */
/* tutaj recznie wymazuje ramki i nie trzeba robic refresh() dla stdscr */
wborder(local_win,' ',' ',' ',' ',' ',' ',' ',' ');
wrefresh(local_win);
delwin(local_win);
return;
}

Skompilować i uruchomić program. Poprawić program, aby podokno nie wychodziło poza krawędzie ekranu.

FUNKCJE


// Podokna, y i x wg ekranu
WINDOW *subwin(WINDOW *orig, int nlines, int ncols, int begin_y, int begin_x);
// jw, ale y i x wg okna nadrzędnego orig
WINDOW *derwin(WINDOW *orig, int nlines, int ncols, int begin_y, int begin_x);

// Nowe okna
WINDOW *newwin(int nlines, int ncols, int begin_y, int begin_x);
// duplikat istniejącego okna
WINDOW *dupwin(WINDOW *win);

delwin(win);

ZARZĄDZANIE OKNAMI

Okna zdefiniowane przez programistę mogą być dwojakiego rodzaju: podokna [subwin(), derwin() - współdzielą pamięć z oknem pierwotnym] lub okna niezależne [newwin(), dupwin()]. Dokumentacja biblioteki zaleca stosować okna niezależne.

Funkcja newwin() alokuje pamięć dla struktury związanej z nowym oknem, inicjalizuje dane związane z oknem, takie jak rozmiar i położenie początkowe. Funkcja zwraca wskaźnik do struktury WINDOW, który może być przekazany do funkcji typu wprintw() itp. Okno jest usuwane przez funkcję delwin(), która zwalnia pamięć związaną ze strukturą okna.


Programowanie z ncurses (index)