Paola Magillo, Univestita' di Genova, Corso di Interfacce Utente per Informatica, a.a. 2004-2005.

STRUTTURA E FUNZIONAMENTO DI UN'INTERFACCIA UTENTE

Finestre e icone

Nota: in un'altra accezione (che vedremo piu' avanti) anche le icone sono finestre.

Finestra ha:

Nota: 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).

Struttura di un'interfaccia

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.

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:

Programmazione guidata da eventi
(o Event-driven programming)

Il comportamento di un programma dotato di interfaccia utente grafica e' di tipo inter-attivo.

Sono le azioni compiute dell'utente sui dispositivi di input a determinare il flusso di esecuzione del programma. Contrariamente ai programmi batch in cui il flusso e' predefinito nel codice.
Compito dell'interfaccia e' raccogliere le azioni e scatenare le reazioni corrispondenti.

+------+         azione su                        +------------+
|      |--(1)--> dispositivo --(2)-->  evento --->|    (3)     |
|      |         di input                         |interfaccia |
|utente|                                          |della       |
|      |         feedback su          reazione    |applicazione|
|      |<--(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 descrivono 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

Come funziona un programma guidato da eventi

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.
Quando il toolkit chiamera' la callback (a seguito del verificarsi dell'evento), 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 usando librerie di piu' basso livello fornite dal sistema operativo o comunque da strati software inferiore.
4. 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 - evento - 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

Interazione bloccante e non bloccante

Riguarda la gestione del ciclo degli eventi.

Come si realizza l'interazione non bloccante?

Dispositivi o componenti di interfaccia

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:

Esempi:

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 e':
       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.

In genere i componenti di un toolkit sono organizzati in classi secondo la filosofia object oriented (questo anche se il toolkit e' scritto in un linguaggio non object-oriented).
C'e' una classe per ciascun tipo di componente fornito dal toolkit. Creare un componente = creare un'istanza della classe opportuna.

Eventi in un toolkit per interfacce

Traduzione azione - evento

Le azioni dell'utente sui dispositivi di input generano segnali che sono raccolti dal sistema operativo come eventi elementari (es. pressione di un tasto della tastiera, movimento del mouse, pressione di un tasto del mouse).

Il sistema operativo (o strati sw poco sopra esso) fornisce una libreria di basso livello per accedere a questi eventi elementari.
La libreria / toolkit per interfacce utente usa questa libreria di basso livello per accedere agli eventi elementari del sistema operativo e costruire da questi i "suoi" eventi, che sono eventi a piu' alto livello di astrazione.

Esempi:

Inoltre ci sono eventi del toolkit che non hanno controparte come eventi elementari perche' non generati da utente. Esempio: evento generato da timer (ved. interazione non bloccante).

Nota: chiusa la parentesi sugli eventi elementari, per "eventi" nel seguito intendiamo gli eventi del toolkit.

Gestione degli eventi nei componenti

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

Esempi

Bottone del tipo 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" (barra di scorrimento per l'immissione di un valore numerico in un certo intervallo):

GUI Designer

Un toolkit puo' fornire un GUI Designer. Programma interattivo che permette la progettazione di interfacce grafiche basate su tale toolkit.

Il GUI Designer produce il codice relativo all'interfaccia.

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