Rassicurati dalla sia pur minimale funzionalità dello stub di IndiEs, messa sia pur minimamente alla prova dal relativo skeleton, possiamo passare a pensare seriamente alla GUI (sigla di "graphical user interface", cioè "interfaccia-utente grafica") con la quale vorremo presentare il nostro famoso grafico di funzione.
La struttura principale sarà naturalmente un dialogo, sia perchè, sinora, non ne abbiamo studiate altre:-), sia perchè un dialogo è, in effetti, ragionevolmente adeguato ai nostri scopi. Sul dialogo dovranno trovare posto vari controlli cui accennavamo un paio di capitoli fa (oltre alle scritte con le quali i controlli stessi vengono identificati):
Un attimo di ulteriore riflessione ci rivela che manca almeno una indicazione: quando calcoleremo la funzione, N volte, per disegnarla e determinare, se richiesto, i min e max di Y? Oops, due indicazioni: quanto deve valere N, il numero di punti separati (e presumibilmente equidistanti) in cui calcolare la funzione...?
Nessun 'evento' identificabile, sui controlli sinora pensati, ci dice univocamente 'disegna adesso': se anche l'utente, ad esempio, ha finito di immettere il testo della funzione, o uno dei vari dati di min e max (e questo possiamo saperlo, basandoci sull'evento 'perdita di focus' del relativo controllo di edit), ciò non significa che sia già pronto a vedere il grafico -- bisognerà che tutti i vari controlli siano considerati "pronti" dall'utente, e questo 'evento semantico' può segnalarcelo solo lui. E quindi, ci vorrà un pushbutton 'Disegna'; ne faremo, naturalmente, il pushbutton di default, cosicchè un 'Enter' in qualsiasi momento causi il disegno.
Il numero di punti in cui è necessario il calcolo della funzione potremmo imporlo noi, basandoci sull'ampiezza in pixel della "area di disegno" e una qualche scelta forzata di 'precisione'; ma sembra assai più flessibile non forzare questa scelta, lasciando invece che sia l'utente a determinare la precisione ottenuta; avremo, dunque, un ulteriore campo di edit, per darci il numero dei 'passi' in cui dividere il disegno.
Infine, poichè è probabile che l'utente faccia un qualche errore prima o poi (nel formato di uno dei vari numeri che può editare, nella sintassi dell'espressione, ...), dobbiamo già pensare, in fase di progetto del dialogo, a come lo segnaleremo. Una possibilità è certamente una "message box" -- ma, riflettendoci, NON è la cosa più comoda per l'utente; ad ogni errore, egli dovrebbe cliccare sull'OK della message box prima di poterlo correggere. Riserviamo, piuttosto, un'area di testo (uno static, quindi), normalmente vuoto, nel quale porre eventuali messaggi d'errore necessari; diagnosticando un errore, rimetteremo inoltre il focus sul campo non soddisfacente, per rendere il più facile possibile all'utente apportare la necessaria correzione.
Ecco, dunque, un possibile schema di dialogo, come emerge da tutte queste considerazioni...:
Abbiamo usato IDC_STATIC
come id di tutte le scritte; questa
costante vale 0, e indica un controllo a cui non ci interesserà
mai accedere nel corso dell'esecuzione. L'ordine dei
controlli (scritte a parte, che non sono tab-stop) è un
minimo pensato per comodità dell'utente -- il pushbutton
di default è messo per ultimo, perchè è l'ultima delle
preoccupazioni dell'utente quella di arrivarci a forza di
tab, visto che, per "premerlo", gli basta in realtà battere
un Enter.
Il controllo più grande di tutto il dialogo, naturalmente,
è IDC_GRAFICO
; esso non è altro che uno static, con
il bit di stile SS_OWNERDRAW
(oltre ad altri, puramente
estetici, come SS_SUNKEN
per dargli un aspetto "scavato"
rispetto al resto del dialogo). Come faremo a disegnare
su di questo, è dunque l'aspetto chiave che ci resta da
chiarire, al di là di tante piccole finezze sul "controllo"
complessivo del dialogo nel suo insieme e nel dettaglio.
E questo chiarimento, naturalmente, lo proseguiremo al
prossimo capitolo.
Capitolo 28: l'interprete: stub+scheletro
Capitolo 30: il disegno in Windows
Elenco dei capitoli