La grafica, ed in specifico la creazione dell’interfaccia, รจ un esempio tipicoย della sfera dedicata alle applicazioni.
Quando ci ritroviamo di fronte alla pagina bianca in cui dobbiamo creare un’interfaccia il nostro primo istinto รจ pensare a quante cose possiamo inserirci, alla quantitร di informazione che siamo in grado di rendere nella sua grafica ma, in realtร , dovremmo tenerci lontani da questa idea. Le interfaccie piรน effettive e ben suddivise sono, infatti, quelle che mostrano meno elementi, ben definiti cosรฌ da essere in grado di non confondere l’utente. Questo tipo di regola รจ applicabile anche nella creazione di pagine web in cui รจ preferibile aiutare, in un certo senso, l’utente nella navigazione del sito non riempendolo troppo di applicazioni, scritte di vario genere e font e finestre varie (se vi interessa un discorso di questo genere dedicato alla grafica teorica date un’occhiata a questo articolo che mette a confronto due diverse pagine di cui una un po’ piรน “pienotta” mentre l’altra piรน spoglia dimostrando come la seconda sia meno dispersiva per l’occhio del friutore).
Come prima cosa, quindi, dovremo decidere che tipo di grafica/GUI vogliamo fare cercando di renderla semplice e minimale in vista del suo uso e, conseguentemente, di limitarne le opzioni. In tal modo le classi, ovvero il gruppo di oggetti appartenenti alla nostra interfaccia con le stesse caratteristiche e funzionalitร , dovranno mostrare uno stile comune. Per esempio, se prendiamo tutte le funzioni con simili operazioni ma appartenenti a diverse classi cercheremo comunque di utilizzare una struttura simile e con un ordine coordinato nei loro argomenti. Le librerie GUI (Graphical User Interface) hanno centinaia di classi qui elencheremo le piรน semplici ed usate:
- Color,ย usato per linee, testo e riempire le forme.
- Line_style,ย usato per disegnare linee.
- Point,ย usato per segnalare posizioni sullo schermo e in una finestra.
- Line,ย รจ una linea sullo schermo definira dai due Points ai suoi estremi.
- Open_polyline, una seguenza di segmenti connessi e definiti da una sequenza di Points.
- Closed_polyline, una sequenza di segmenti connessi e definiti da una sequenza di Points in cui l’ultimo Point รจ anche il primo.
- Polygon, un Closed_polyline dove non vi sono segmenti che intersecano tra loro.
- Text, una stringa di caratteri.
- Lines, un set di segmenti definiti da coppie di Points.
- Rectangle,ย Circle, Ellipse,ย forme comuni (ovvero rispettivamente rettangolo, circolo ed elisse) ed ottimizzate per un loro veloce utilizzo.
- Axis,ย un’asse etichettata.
- Mark, un Point marcato da un carattere come, per esempio, x oppure p.
- Marks, una sequenza di punti indicati da vari marchi.
- Marked_polyline, un Open_polyline con l’indicazione di punti denominati con x, b, p, etc.
- Image, il contenuto di un file immagine.
- Window, un area dello schermo in cui possiamo vedre i nostri oggetti grafici.
- Simple_window, una finestra con il bottone “Next” (Continua).
- Button,ย un rettangolo, normalmente etichettato, in una finestra che possiamo schiacciare per avviare una funzione.
- In_box, un box, normalmente etichettato, in una finestra in cui un utente puรฒ scrivere una stringa.
- Out_box, un box, normalmente etichettato, in una finestra in cui il programma, e non l’utente, puรฒ scrivere una stringa.
- Menu, un vettore di Buttons.
Prima di tutto se una forma richiede una posizione verrร utilizzato come suo argomento iniziale una classeย Pointย per rappresentarlo. Il Point รจ una delle principali e piรน importanti classi nel sistema grafico poichรฉ ci permette di organizzare il nostro spazio geometrico: quando, per esempio, vogliamo disegnare qualcosa a mano libera tracciamo prima di tutto delle linee che ci permettano di suddividere lo spazio del foglio, questo avviene anche nel caso della computer grafica.
Stroustrup nel capitolo 13 del suo libroย Programming Principles and Practice Using C++, utilizza l’esempio di una funzione per disegnare una linea mostrando due possibilitร di scrittura:
void draw_line(Point p1, Point p2);
void draw_line(int x1, int y1, int x2, int y2);
Il primo stile utilizzato, ovveroย void draw_line (Point p1, Point p2);, รจ preferibile rispetto al secondo per la sua semplicitร ed eleganza che rendono anche la lettura del codice piรน veloce ed immediata sebbene anche la seconda linea funzioni comunque. In questo caso, al contrario del void* che abbiamo incontrato nella Lezione 10, scriviamo void come return type perchรฉย non ci interessa il risultato che la funzione restituisce: stiamo quindi attenti a non confondere i due comandi distinti tra loro dalla presenza o meno dell’asterisco. Il comando draw_line รจ semplicemente relativo alla richiesta di disegnare una linea che, come segnalato all’interno delle parentesi, vada dal punto p1 (o x1,y1) al punto p2 (o x2, y2).ย Inoltre, l’utilizzo di Point ci evita anche di far confusione quando ci troviamo davanti alle coordinate di altezza e larghezza come, per esempio:
draw_rectangle(Point(110,210),310,410);
draw_rectangle(110,210,310,410);
Come possiamo notare, รจ vero che il secondo metodo in questo caso paia piรน diretto e semplice ma non รจ cosรฌ: anche in questo caso preferiamo la prima linea di comando scritta. Questo perchรฉ sappiamo che il punto รจ definito dalla posizione (110, 210), la sua larghezza di 310 e l’altezza di 410 che sono sempre presentate in tale ordine; nel secondo caso non abbiamo la certezza di questa suddivisione o per lo meno non รจ cosรฌ immediata come dare un veloce sguardo alla locazione delle parentesi.
Tutte le operazioni identiche hanno lo stesso nome, per esempio add() vale ogni qualvolta vogliamo aggiungere una nuova forma. Ma, per esempio, se vogliamo aggiungere una forma ad una finestra useremo il comandoย attach mentre per aggiungere una linea all’interno di una forma utilizzeremoย add. Le funzioni sono simili: aggiungiamo infatti qualcosa nella nostra forma o finestra ma proprio perchรฉ l’aggiunta avviene su due diversi livelli il comando utilizzato varia. Nel primo caso, infatti, dovremo per esempio scrivere:
Open_polyline opl;
opl.add(Point(110,110));
opl.add(Point(120,220));
Qui, quindi aggiungiamo due punti nella forma chiamata opl. Mentre se dovessimo aggiungere la forma opl ad una finestra utilizzeremo il seguente comando:
win.attach(opl);
Creando, cosรฌ, una connessione tra la finestra denominata win e la forma opl. Qui, perรฒ, dovremo ricordarci di non uscire dallo scopo dell’opl mentre win sta usando l’opl.
Vediamo, ora, un piccolo software per creare due linee:
//Disegna due linee #include <iostream> #include <string> #include <Simple_window.h> #include <Graph.h> using namespace std; using namespace Graph_lib; //la struttura dei grafici si trova in Graph_lib int main() { Point tl(100, 100); //per posizionare la forma nell'angolo in alto a sinistra della finestra Simple_window win(tl, 600, 400, "Canvas"); //crea una finestra semplice Polygon poly; //crea un poligono poly.add(Point(300, 200)); //aggiunge un Point poly.add(Point(350, 100)); //aggiunge un altro Point poly.add(Point(400, 200)); //ed un terzo Point poly.set_color(Color::red); //si occupa delle proprietร del poligono win.attach(poly); //connette il poligono alla finestra win.wait_for_button(); }
Quando ci ritroveremo a tentare di usare il compiler con questo programma ci ritroveremo di fronte a parecchi problemi relativi alla libreria, ovvero a ciรฒ che dobbiamo includere: nel libro di Stroustrup, infatti, in questo esempio vengono segnalate solo due librerie ovvero:ย #includeย <Simple_window.h>ย eย #includeย <Graph.h>ย (ricordiamoci che l’uso delle virgolette non cambia nulla per cui possiamo scrivere le librerie anche in questo modo: #include “Simple_window.h” e #include “Graph.h”) che, molto probabilmente se non sicuramente, non verranno trovate dal vostro compiler: se date un’occhiata su internet c’รจ parecchia gente disperata che non sa dove sbattere la testa per riuscire a compilare questo programma.
Ergo, ci sono due soluzioni al problema: usare linux oppure sbattersi un bel po’ per far funzionare il compiler su windows come spiegato di seguito.
Cosรฌ il vostro compiler qualsiasi esso sia (nel mio caso Visual Studio) vi segnalerร un errore del tipo:ย fatal error C1083: Cannot open include file: ‘Simple_window.h’: No such file or directory. Come fare per evitare questo errore e far funzionare il nostro programmino?ย
- Clicchiamo sul seguente link che avvierร un download in automatico:ย https://github.com/bewuethr/stroustrup_ppp/archive/master.zip.
- Cerchiamo la cartella in cui abbiamo i nostri file C++, quella per intenderci con le varie cartelle denominate ConsoleApplication ed apriamola lasciandola da parte.
- Apriamo il file .zip che abbiamo ottenuto e scaricato e cerchiamo la cartellaย lib_files.ย Una volta trovata tale cartella spostiamola all’interno di quella di C++ assieme a quelle chiamate ConsoleApplication.
- Facciamo una piccola modifica alle scritte #include <Simple_window.h> e #include <Graph.h> come di seguito mostrato:
#include <C:\Users\an\Desktop\C++\lib_files\Simple_window.h>
#include <C:\Users\an\Desktop\C++\lib_files\Graph.h>
Ovviamente al posto di, per esempio,ย <C:\Users\an\Desktop\C++\lib_files\Simple_window.h> dovrete scrivere la posizione sul vostro computer della vostra cartella C++ per dar modo al compiler di sapere da dove attingere ciรฒ che gli serve.
Una volta fatto questo perรฒ il compiler ci segnalerร simpaticamente un nuovo errore:ย fatal error C1083: Cannot open include file: ‘FL/Fl.H’: No such file or directory. Questo errore si riferisce alla libreria ftlk parecchio datata e per questo non inclusa nei file standard. Quindi, a questo punto dobbiamo scaricarci anche questa libreria fltkย cliccandoย quiย farete il download automatico: il file รจ in formato .gz e potrete aprirlo come un normale file .zip, ovvero per esempio con il software 7.zip.
Fatto ciรฒ, andiamo nel nostro Visual Studio, per esempio, e seguiamo i passi qui descritti:
- Andiamo nella cartella appena creata e cerchiamo fltk.dsw aprendola. Se non la trovate ed utilizzate Windows 10 basta scriverne il nome in basso a destra accando all’icona Start.
- Si aprirร Visual Studio, diamogli l’Ok ed attendiamo alcuni minuti che si concluda il caricamento dei files.
- Poi, inย alto a destra, nella barra delle applicazioni clicchiamo su Buildย e Build Solutionย (Costruisci soluzione).
- Attendiamo nuovamente alcuni minuti perchรฉ il tutto si carichi come mostrato qui sotto.
- Chiudiamo allora Visual Studio eย facciamo ora, piรน o meno, quello che abbiamo fatto per le altre librerie copiando ed incollando la cartella lib_files presente nel download appena effettuato in una cartella raggiungibile dal nostro compiler (Stroustrup consiglia di farlo sula cartella denominata vc).
- Riapriamo Visual Studio e creiamo un nuovo progetto “Win32 project”, anzichรฉ il solito “Console Application”,ย sincerandoci di scegliere un Empty project (progetto vuoto) spuntando la casella nelle Application Settings che compariranno e cliccando poi su Finish.
- Una volta aperto il progetto vuoto andiamoย sempre in alto nella barra delle applicazioni e selezioniamoย Project (Progetto) e poiย Propertiesย (Proprietร ): si aprirร unaย nuova finestra.
- Clicchiamo due volte suย Configuration Properties (Configurazione proprietร ), dopodichรฉ suย Linker ed infine suย Input. Come mostrato nell’immagine sottostante, ora andiamo a cliccare accanto alla scrittaย Additional Dependenciesย (Dipendenze aggiuntive) aggiungendo alla lista quanto segue facendo attenzione di utilizzare i punti e virgola correttamente:ย fltkd.lib; wsock32.lib; comctl32.lib; fltkjpegd.lib; fltkimagesd.lib;
- Sempre sulla stessa pagina, selezioniamo oraย Ignore Specific Library (Ignora specifica libreria) e scriviamovi accantoย libcd.lib
- Nel nuovo progetto appena fatto cresiamo unย .cpp file su cui finalmente scrivere il nostro codice facendo attenzione di aggiungere le nuove librerie che ci servono similmente a come segue oppure utilizzando :
#include <C:\Users\an\Desktop\C++\lib_files\FL\Fl.H> #include <C:\Users\an\Desktop\C++\lib_files\FL\Fl_Box.H> #include <C:\Users\an\Desktop\C++\lib_files\FL\Fl_Window.H>
Ci sono altri modi, ovviamente, di inserire una libreria. Personalmente ho preferito mixare il mio modo con quello descritto da Stroustrup cosicchรฉ chi segue quel libro possa comunque ritrovarsi facilmente nelle spiegazioni che, comunque, sono presenti se non erro all’appendice D del libro.
Passiamo, ora, finalmente alla descrizione del piccolo software: qui oltre all’ormai conosciuto using namespace std; dobbiamo aggiungere ancheย using namespaceย graph_lib poichรฉ รจ qui che attingono i nostri strumenti grafici. Dopodichรฉ definiamo il puntoย Point tl(100,100) che segnala la posizione della nostra forma a partire dall’angolo in alto a sinistra della finestra. Poi, creiamo conย Simple_window win(tl,600,400,”Canvas”); una finestra semplice sullo schermo: win รจ il nome nonchรฉ la variabile della nostra Simple_window mentre tl segnala la posizione del Point relativo al comando precedente; 600 e 400 sono rispettivamente la larghezza e l’altezza della finestra misurate in pixel; Canvas semplicemente da un’etichetta alla finestra e potremmo cambiarla con il nome che piรน ci spieffera in quel momento.ย
I successivi comandi relativi aย Polygon.poly definiscono la figura di un poligono ed i suoi angoli con poly.addย creando praticamente un triangolo utilizzando dei Point che ne localizzano la postazione dei vertici. Mentreย poly.set_color seleziona il colore del triangolo da noi disegnato;ย win.attach(poly)ย collega il poligono alla finestra da noi creata precedentemente.
Infine, per poter osservare il nostro triangolo sullo schermo come nell’immagine qui a lato dobbiamoย aggiungere al nostro programmaย il comandoย win.wait_for_button().
Lascia un commento