#ifndef DESIGN_H
#define DESIGN_H
#include <iostream>
#include <conio.h>
#include <fstream>
#include <windows.h>
using namespace std;
// costanti con le dimensioni della classica schermata DOS
const int nROW = 24, // numero di righe
nCOLUMN = 79; // numero di colonne
// costanti coi valori dei tasti che l'utente può premere
const char UP = 119, // W = sù
DOWN = 115, // S = giù
LEFT = 97, // A = sinistra
RIGHT = 100, // D = destra
EXIT = 27, // Esc = esci
DRAW = 49, // 1 = attiva/disattiva matita
CANCEL = 50, // 2 = attiva/disattiva gomma
SAVE = 48, // 0 = salva disegno
CLEAR = 32; // Space = cancela disegno
/* procedura per spostare il cursore sullo schermo, il primo valore lo sposta
orizzontalmente, il secondo verticalmente */
void gotoxy(int y, int x)
{
COORD coor;
HANDLE hOutput;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
coor.X = x;
coor.Y = y;
SetConsoleCursorPosition(hOutput,coor);
}
// classe per la gestione dei disegni
class design
{
// matrice in cui viene salvato l'intero disegno
bool screen_view[nROW][nCOLUMN];
public:
void clear();
design() { clear(); }
void draw();
void save();
void load(string);
};
// procedura per pulire la matrice
void design::clear()
{
int i, j;
for (i=0; i<nROW; i++) {
for (j=0; j<nCOLUMN; j++) screen_view[i][j] = false;
}
}
// procedura per disegnare
void design::draw()
{
int mx, // movimento in orizzontale
my, // movimento in verticale
x = 12, // posizione del cursore in orizzontale
y = 40; // posizione del cursore in verticale
// gli interruttori per disegnare e cancellare
bool draw_switch = false,
cancel_switch = false;
char move;
for (;;) {
// l'utente preme un tasto finchè non ne preme uno di quelli precedentemente indicati
do {
move = getch();
} while(move!=UP && move!=DOWN && move!=LEFT && move!=RIGHT && move!=EXIT && move!=DRAW && move!=CANCEL && move!=CLEAR && move!=SAVE);
// in base al tasto premuto viene eseguita un'istruzione diversa
switch (move) {
case UP: mx=-1; my=0; break;
case DOWN: mx=1; my=0; break;
case LEFT: mx=0; my=-1; break;
case RIGHT: mx=0; my=1; break;
case DRAW:
mx=0; my=0;
if(draw_switch) draw_switch = false;
else draw_switch = true;
cancel_switch = false;
break;
case CANCEL:
mx=0; my=0;
if(cancel_switch) cancel_switch = false;
else cancel_switch = true;
draw_switch = false;
break;
case CLEAR:
mx=0; my=0;
system("cls");
clear();
break;
case SAVE:
mx=0; my=0;
save();
break;
}
if(move == EXIT) break;
// aggiorna le coordinate del cursore coi rispettivi controlli che il cursore
// non finisca fuori dalla finestra
x += mx;
if(x == nROW) x--;
if(x == -1) x++;
y += my;
if(y == nCOLUMN) y--;
if(y == -1) y++;
gotoxy(x, y);
// in base all'interruttore attivo esegue uno dei seguenti effetti
if (draw_switch) {
cout <<'#';
screen_view[x][y] = true;
}
if (cancel_switch) {
cout <<' ';
screen_view[x][y] = false;
}
}
// pulisce la matrice alla fine dell'esecuzione
clear();
}
// precedura per salvare il disegno
void design::save()
{
string file_name;
char ok;
system("cls");
// chiede il nome dell'immagine da salvare
cout <<"\n\n\nInserire nome dell'immagine da salvare: ";
cin >> file_name;
// aggiunge al nome immesso l'estensione
file_name += ".dat";
// dichiaro la variabile di stream
ofstream fout;
// crea ed apre il file con il nome che si è appena inserito specificando
// che sarà un flusso di output dal programma al file (ios::out) e che
// il file sarà di tipo binario (ios__binary)
fout.open(file_name.c_str(), ios::out | ios::binary);
// scrivo sul file la matrice sotto forma di classe
fout.write((char*)this, sizeof(*this));
// chiudo il file
fout.close();
// chiedo se si vuole continuare il disegno o no
cout <<"\n\nVuole tornare al disegno (s=si', n=no): ";
do { ok = getch(); } while(ok!=115 && ok!=110);
if(ok == 115) load("file_name");
else exit(0);
}
void design::load(string file_name)
{
int i, j;
system("cls");
// dichiaro la variabile di stream
ifstream fin;
// crea ed apre il file con il nome che si è appena inserito specificando
// che sarà un flusso di input dal file al programma (ios::in) e che
// il file sarà di tipo binario (ios__binary)
fin.open(file_name.c_str(), ios::in | ios::binary);
// legge le informazioni contenute nel file sotto forma di classe design
fin.read((char*)this, sizeof(*this));
// stampo a video le informazioni appena ricevute
for (i=0; i<nROW; i++) {
for (j=0; j<nCOLUMN; j++) {
if(screen_view[i][j]) cout <<'#';
else cout <<' ';
}
cout << endl;
}
// chiudo il file
fin.close();
// parte la procedura per disegnare avendo come base il disegno appena aperto
draw();
}
#endif