Paola Magillo, Univestita' di Genova, Corso di Interfacce Utente per Informatica, a.a. 2007-2008.

STRUTTURA E FUNZIONAMENTO DI UN'INTERFACCIA UTENTE

Di che cosa parliamo

C'e' l'interfaccia di una particolare applicazione e l'interfaccia generale dell'ambiente di lavoro su una certa macchina, cioe' l'interfaccia del sistema. Qui parliamo del primo caso.

Una interfaccia utente grafica e' costituita da:

Alcuni usano il termine componenti di interfaccia per indicare sia le finestre che i dispositivi, altri solo per i dispositivi.

Le finestre intese in questa accezione sono anche chiamate "finestre top-level". In un'altra accezione per finestra si intende qualsiasi area rettangolare dello schermo con caratteristiche di comportamento proprie, quindi anche i vari elementi dentro una finestra sono finestre (ma lo vedremo piu' avanti).

Le finestre

Una finestra ha:

Non tutte le finestre hanno l'insieme completo delle decorazioni. In finestre temporanee (es. per messaggio di errore) possono mancare in parte.

Tipi di finestre

Secondo la classificazione di MS-windows.

Finestra di applicazione

Appare quando l'utente lancia un programma.
Ha l'insieme completo delle decorazioni del window manager.
In genere ha una barra di menu' che mostra le varie funzionalita' dell'applicazione (es: file, edit, view...).

Finestra di documento

E' associata ad una finestra di applicazione. E' relativa ad un file (documento) aperto nell'ambito dell'applicazione.
Ci possono essere piu' finestre di documento associate ad una stessa finestra di applicazione.
Ha un titolo col nome del documento, e in genere anche le altre decorazioni (ma... vedi qui sotto...).

Le finestre di documento dello stesso programma possono essere gestite in vari modi:

Finestra di dialogo

Finestra transitoria attraverso la quale l'applicazione presenta messaggi e/o richiede input all'utente. E' pensata per rimanere sullo schermo solo per poco tempo.
Puo' non avere tutte le decorazioni del window manager (es. puo' non avere senso spostarla o redimensionarla).
Contiene sempre bottoni (di solito in basso) per chiudere la finestra. A seconda dello scopo del dialogo: Ok, Ok/Cancel, Yes/No/Cancel, ecc.
Le dimensioni di una finestra di dialogo sono abbastanza piccole per enfatizzare la sua natura di finestra supplementare.

Esempi di finestre di dialogo:

Una finestra di dialogo puo' essere modale o non modale:

Finestre di dialogo modali vanno usate solo quando strettamente necessario.

Gerarchia di dipendenza delle finestre

Si riferisce a quando una finestra ne invoca (fa apparire) un'altra. Cioe' quando un'azione dell'utente sulla prima finestra provoca la comparsa della seconda finestra.
Si dice allora che la seconda finestra dipende funzionalmente dalla prima.

Rappresentazione grafica della gerarchia di dipendenza

La gerarchia di dipendenza funzionale si puo' visualizzare sotto forma di un albero o un grafo diretto, dove ogni volta che una finestra B dipende funzionalmente da una finestra A si ha un arco diretto da A verso B. Le finestre primarie non hanno archi entranti.

Vincoli tra finestre primarie e secondarie

Iconificazione di finestra primaria fa sparire le finestre secondarie che da essa dipendono.
De-iconificazione di finestra primaria fa riapparire anche le finestre secondarie.

Chiusura della finestra primaria termina l'applicazione e fa chiudere tutte le finestre secondarie che ha generato.

Dispositivi o componenti di un'interfaccia

Oggetti con aspetto grafico e comportamento (sensibilita' a particolari eventi e capacita' reattive) che "popolano" una finestra e permettono interazione con l'utente.

Sono forniti da una libreria o toolkit per sviluppo di interfacce: pacchetto che fornisce insieme di elementi di interfaccia pronti all'uso e insieme di funzioni (API) per utilizzarli nella costruzione di un'interfaccia.

La libreria fornisce tipi o classi di dispositivi. Ciascun tipo ha proprie caratteristiche di aspetto / comportamento (es. bottoni, campi di input testuale...) in parte personalizzabili, e possibilita' di inserire comportamenti aggiuntivi.

Esempio: un bottone e' un'area rettangolare sensibile al click del mouse. Posso personalizzarlo scegliendo dimensioni, colore, font della scritta... Ha predefinito il comportamento di evidenziarsi quando viene cliccato, posso aggiungere quello di chiamare una certa funzione applicativa (es. salvare il file corrente).

La libreria / toolkit fornisce:

Nota:
Interfaccia Utente (IU) o User Interface (UI) = interfaccia del programma applicativo verso l'utente.
Application Program Interface (API) = interfaccia del toolkit verso il programma applicativo, si tratta dell'interfaccia fra due strati SW.
Il programma applicativo usa il toolkit (tramite la sua API) per costruire la propria IU verso l'utente. L'utente poi usa il programma applicativo tramite la sua IU cosi' costruita.

Programmazione guidata da eventi
(o Event-driven programming) rivisitata

+------+         azione su                        +------------+     +--------+
|      |--(1)--> dispositivo --(2)-->  evento --->|    (3)     |     | (3bis) |
|      |         di input                         |interfaccia |     |        |
|utente|                                          |della       |<--->|appli-  |
|      |         feedback su          reazione    |applicazione|     |cazione |
|      |<--(5)-- dispositivi <--(4)-- (cambio <---|            |     |        |
+------+         di output            di stato)   +------------+     +--------+

(1) L'utente compie azioni sui dispositivi di input (mouse, tastiera).

(2) Le azioni sono tradotte in eventi. Evento = pacchetto di informazioni che descrive che cosa e' avvenuto. Qui la libreria / toolkit esegue gia' una parziale interpretazione delle azioni. Esempi:

Evento e' caratterizzato da tipo + eventuali parametri (secondo il tipo). Esempi: pressione su tastiera + quale carattere, click del mouse + quale bottone e in che punto dello schermo...

(3) L'evento viene elaborato dal codice dell'interfaccia, per decidere che cosa fare (come reagire). L'elaborazione puo' avvenire a due livelli:

  1. a livello di libreria / toolkit per i comportamenti predefiniti
  2. a livello di codice scritto dal programmatore per i comportamenti aggiuntivi (personalizzati)
La reazione cambia lo stato dell'interfaccia e/o del programma applicativo sottostante.
L'elaborazione a livello di libreria cambia sempre solo lo stato dell'interfaccia (la libreria non "conosce" l'applicazione sottostante).
L'elaborazione a livello del codice scritto dal programmatore puo' interessare l'interfaccia (es. aprire o chiudere una finestra di dialogo, abilitare o disabilitare dei dispositivi...) oppure anche l'applicazione sottostante (es. chiamare procedura di calcolo, aprire o chiudere un file...).

(4) La reazione (avvenuto cambio di stato) viene comunicata all'utente come feedback sui disposiviti di output (schermo, altoparlante).

(5) L'utente riceve il feedback e in base a questo decidera' la prossima azione...

Esempio

Applicazione per cambiare il contrasto di una foto. L'interfaccia mostra la foto e un potenziometro (o slider) con cursore mobile.

Evento di aggancio / rilascio del cursore da parte dell'utente (premendo / rilasciando il mouse sopra) e' gestito a livello libreria.
Evento di movimento del cursore (trascinandolo a mouse premuto) e' gestito:

Funzioni callback

Per associare comportamenti aggiuntivi ai dispositivi di interfaccia, le librerie / toolkit prevedono il meccanismo delle callback.

Callback = funzione "da chiamare in risposta" a un evento che accade su un certo componente di interfaccia.

Una callback e' una funzione scritta dal programmatore, il quale poi comunica alla libreria che dovra' chiamare questa funzione ogni volta che un certo tipo di evento si verifichera' su un certo componente di interfaccia. La funzione verra' poi chiamata automaticamente.

Al suo interno una funzione callback puo' accedere sia all'interfaccia (tramite le funzioni della API del toolkit), sia all'applicazione sottostante. Esempio: eseguire un calcolo applicativo e poi mostrare il risultato nell'interfaccia.

Per ogni tipo di dispositivo e ogni tipo di evento previsto su quel tipo di dispositivo il toolkit stabilisce quali sono i parametri per la callback relativa.
Esempio: per evento pressione tasto su dispositivo campo di input testuale il parametro puo' essere il codice ascii del tasto premuto.

Programmatore scrive una funzione con parametri conformi a quelli stabiliti dal toolkit e poi la registra come callback.
Al verificarsi dell'evento, il toolkit chiamera' la callback (a seguito del verificarsi dell'evento), e le passera' automaticamente i parametri prelevandoli dall'evento attuale.

Struttura del programma

Struttura del codice di un programma che implementa un'interfaccia utente (per una certa applicazione) facendo uso di un toolkit.

Vediamo le parti del programma (a livello di codice scritto dal programmatore) e che cosa succede dentro (a livello della libreria / toolkit).

Che cosa scrive il programmatore Che cosa avviene nella libreria / toolkit
1. Dichiara che intende usare il toolkit Direttiva include in C, import in java...
2. Inizializza il toolkit Istruzione della API del toolkit. Certi toolkit (es. java) non richiedono inizializzazione esplicita. Libreria si collega a librerie di piu' basso livello che le permetteranno di produrre grafica e catturare eventi (ved. punto 3)
3. Crea l'interfaccia (creare le finestre, i dispositivi, personalizzarne l'aspetto, posizionarli...) Istruzioni della API del toolkit Libreria costruisce la grafica e i comportamenti predefiniti usando librerie di piu' basso livello fornite dal sistema operativo o comunque da strati software inferiori.
4. [a parte] Scrive le callback per implementare i comportamenti aggiuntivi (es. accedere all'applicazione sottostante) Programmatore scrive una funzione con parametri e valore di ritorno conformi a quelli stabiliti dal toolkit per callback a quel tipo di evento in quel tipo di componente.
5. Registra le callback, cioe' associare le funzioni-comportamenti ai dispositivi Istruzioni della API del toolkit per registrare la funzione come callback a quel componente per quel tipo di evento. Libreria compila una tabella di associazioni dispositivo - tipo di evento - funzione callback.
6. Mostra a schermo l'interfaccia (almeno la finestra principale, mentre altre possono essere pensate per apparire a seguito di eventi) Istruzioni della API del toolkit per rendere visibili le finestre Libreria mappa finestre sullo schermo
7. Fa partire il ciclo degli eventi, cioe' l'interazione con l'utente (azione - evento - reazione - feedback...) Istruzione della API del toolkit. Certi toolkit (es. java) non hanno un'istruzione esplicita, il ciclo degli eventi parte automaticamente non appena viene mostrata una finestra. Libreria esegue ciclo infinito in cui ad ogni giro:
  • attende un evento
  • guarda il tipo di evento e il componente su cui si e' verificato
  • esegue la reazione predefinita per quel tipo di evento su quel tipo di componente
  • guarda (nella tabella) se per quel tipo di evento e quel componente e' stata registrata un callback, se si' la esegue

Tutti i passi tranne 4 compaiono in questa sequenza nel codice del main. Le callback (passo 4) sono ovviamente funzioni scritte a parte.
Dopo eseguita l'ultima istruzione del main il programma non termina perche' intanto e' stato avviato il ciclo degli eventi.
Il ciclo degli eventi (passo 7) va avanti potenzialmente all'infinito, a meno che in qualche callback si incontri l'istruzione di terminazione.

Interazione bloccante e non bloccante

Riguarda la gestione del ciclo degli eventi.

Come si realizza l'interazione non bloccante?

Tipi di dispositivi

I dispositivi forniti da una libreria / toolkit sono elementi di interfaccia pronti all'uso (bottoni, menu'...).

Si classificano in diversi tipi o classi, ciascun tipo con certe caratteristiche di aspetto / comportamento.

Come possiamo vedere un dispositivo

Dal punto di vista dell'utente dell'interfaccia un dispositivo / componente di interfaccia e' caratterizzato da:

Dal punto di vista del programmatore un componente e' caratterizzato da:

Gestione degli eventi nei componenti

Quando su un componente di interfaccia avviene un evento, il toolkit lo puo' gestire come:

Esempi

Bottone che si evidenzia quando l'utente ci passa sopra col mouse e scatta quando preme:

Campo testuale (per l'immissione di una stringa di testo):

Slider o potenziometro (barra di scorrimento per l'immissione di un valore numerico in un certo intervallo):

Componenti di base e contenitori

Due categorie fondamentali di componenti:

Mediante i contenitori si struttura lo spazio della finestra definendo vincoli per la disposizione (layout) dei componenti al suo interno. Meccanismo a scatole cinesi (gerarchia di annidamento dei contenitori).

Esempio: la finestra e' divisa in due parti verticalmente, nella parte sinistra c'e' un'area di testo, la parte destra e' strutturata come una griglia 3 righe x 3 colonne con dentro dei bottoni.

+--------------------+----+----+----+
|                    | B1 | B2 | B3 |
|                    +----+----+----+
|    area di testo   | B4 | B5 | B6 |
|                    +----+----+----+
|                    | B7 | B8 | B9 |
+--------------------+----+----+----+
La gerarchia di contenimento puo' essere rappresentata graficamente come un albero:
       contenitore a due scomparti verticali
                        |
             +----------+----------+
             |                     |
    area di testo        contenitore a griglia 3x3
                                     |
                               +-----+-----+
                               |    ...    |
                        bottone B1  ...  bottone B9

Con contenitori posso raggruppare componenti concettualmente collegati, disegnare bordi e cornici.

GUI Designer

Un toolkit puo' fornire un GUI Designer (chiamato altrimenti GUI Builder). Programma interattivo che permette la progettazione e la realizzazione di interfacce grafiche basate su tale toolkit.
Quello che si realizza e' lo scheletro dell'interfaccia utente, senza i comportamenti aggiuntivi (per quelli devo poi scrivere io le callback).

Il GUI Designer produce il codice relativo all'interfaccia.

Il programmatore deve solo riempire il corpo delle procedure callback associate ai componenti.

Esempi di GUI Designer disponibili

Nota bene: per IDE (Integrated Development Environment) si intende un ambiente integrato per lo sviluppo di applicazioni, pacchetto che comprende editor, compilatore, interprete, facilita' per debugging ecc.

Nel corso non e' richiesto di usarne uno. Si consiglia almeno all'inizio di non farlo.