Precedente Successivo Indice

4. La Libreria Menù

Un menù è uno SCREEN che assiste l'utente nel scegliere una porzione di un dato insieme di voci. La libreria menù è una estensione delle curese che supporta la facile programmazione di gerarchie di menù con una interfaccia uniforme ma flessibile.

La libreria menù apparve per prima nel System V di AT&T. La versione qui documentata è il codice freeware menu distribuito con le ncurses.

4.1 Compilare con la Libreria Menù

I vostri moduli che usano la libreria menù dovranno importare le dichiarazioni della libreria con


#include <menu.h>

e dovranno linkarsi esplicitamente con la libreria menù usando l'argomento -lmenu. Notate che dovranno anche linkare la libreria ncurses tramite -lncurses. Molti linker moderni eseguono due passaggi e accetteranno qualunque ordine, ma è comunque buona pratica usare -lmenu per prima e -lncurses per seconda.

4.2 Panoramica dei Menù

I menù creati con questa libreria consistono in una collezione di voci (items) composte da una parte nome ed una parte descrizione. Per creare i menù, create gruppi di queste voci e le connettete con il corpo (frame ) del menù.

Il menù può quindi venir pubblicato, cioè scritto in una finestra associata. Attualmente ciascun menù ha due finestre associate: un contenitore in cui il programmatore può scarabocchiare titoli e bordi, ed una sottofinestra in cui le voci del menù vengono visualizzate. Se una sottofinestra è troppo piccola per mostrare tutte le voci, diventerà un'apertura scorrevole sulla collezione di voci.

Un menù può anche venir spubblicato (cioè, cancellato), e finalmente rilasciato per rendere disponibile al riuso lo spazio associato a esso ed alle sue voci.

Il flusso generale del controllo di un programma menù somiglia a questo:

  1. Inizializzazione delle curses.
  2. Creazione delle voci del menù mediante new_item().
  3. Creazione del menù mediante new_menu().
  4. Pubblicazione del menù tramite menu_post().
  5. Rinfresco dello schermo.
  6. Trattamento delle richieste dell'utente attraverso un ciclo di input.
  7. Spubblicazione del menù tramite menu_unpost().
  8. Rilascio del menù attraverso free_menu().
  9. Rilascio delle voci attraverso free_item().
  10. Terminazione delle curses.

4.3 Selezione delle voci

I Menù possono essere del tipo a valori multipli (la norma) oppure a valore singolo (consultate il manuale alla pagina mitem_opts(3x) per vedere come impostarlo). Entrambi i tipi hanno una voce corrente.

È possibile leggere il valore scelto da un menù a valore singolo semplicemente consultando la voce corrente. Troverete l'insieme dei valori selezionati da un menù a valori multipli applicando ciclicamente la funzione predicato item_value(). Il codice di gestione del vostro menù può utilizzare la funzione set_item_value() per spuntare le voci nell'insieme.

Le voci di menù possono diventare non-selezionabili mediante la set_item_opts() oppure la item_opts_off() con argomento O_SELECTABLE. Benchè questa sia l'unica opzione per ora implementata nei menù, è buona pratica attivarla con questo metodo in quanto altri bit potrebbero essere settati.

4.4 Visualizzazione del Menù

La libreria menù calcola una dimensione minimale della finestra basandosi sui seguenti valori:

La finzione set_menu_format() vi permette di impostare la dimensione massima del riquadro o pagina-menù che sarà usata per visualizzare le voci del menù. Potete recuperare il formato associato ad un menù usando menu_format(). I valori iniziali sono rows=16, columns=1.

L'attuale pagina-menù può essere più piccola delle dimensioni indicate nel formato. Questo dipende dal numero e dimensioni delle voci e se O_ROWMAJOR è attiva. Questa opzione (inizialmente attiva) porta le voci del menù ad essere visualizzate in una modalità a ''scansione'', cosicchè la prima coppia di voci si dispone fianco-a-fianco sulla riga iniziale, se possibile. L'alternativa è il modello ''incolonnato'', che prova a disporre il maggior numero di voci nella prima colonna.

Come accennato prima, un formato di menù non sufficientemente largo da permettere a tutte le voci di essere visibili sullo schermo, darà origine ad un menù verticalmente scrollabile. Potete scorrerlo mediante richieste al gestore di menù, che verrà descritto nella sezione gestione dell'input.

Ogni menù è dotato di un segnaposto utilizzato per marcare le voci selezionate; vedere il manuale alla pagina menu_mark(3x) per dettagli. Il segnaposto influisce anche sulla dimensione della pagina-menù.

La funzione scale_menu() restituisce la dimensione minima calcolata in base a tutti questi fattori.

Esistono altri attributi di visualizzazione di un menù, incluso un attributo di selezione, un attributo per voci selezionabili, uno per voci non-selezionabili e un carattere riempitivo usato per separare il nome di una voce con il testo della sua descrizione. Queste hanno ragionevoli valori iniziali che la libreria vi permette di modificare (vedere il manuale alla pagina menu_attribs(3x).

4.5 Finestre Menù

Ogni menù ha, come già menzionato, una coppia di finestre associate. Entrambe queste finestre vengono riempite quando il menù viene pubblicato e cancellate quando viene spubblicato.

La finestra esterna non viene in alcun modo usata dalle routine del menù. Esiste per permettere al programmatore di associare al menù un titolo, un bordo o perfino un testo di ''help'' ed averli correttamente visualizzati o cancellati nel momento della pubblicazione o spubblicazione. La finestra interna o sottofinestra è quella in cui la pagina del menù viene correntemente visualizzata.

Inizialmente entrambe le finestre sono stdscr. Potete impostarle mediante le funzioni in menu_win(3x).

Quando chiamate la menu_post(), il menù viene scritto nella sottofinestra. Chiamando la menu_unpost(), viene cancellato dalla sottofinestra. Comunque nessuna di queste funzioni modifica lo schermo visibile. Per far ciò chiamate la wrefresh() o le equivalenti.

4.6 Gestione dell'Input del menù

Il ciclo principale del vostro codice di gestione del menù dovrà eseguire menu_driver() ripetutamente. Il primo argomento di questa routine è un puntatore ad un menù; il secondo e un comando al menù. Dovrete scrivere una routine di cattura dell'input che associ i caratteri dell'imput ai comandi del menù, e passare il suo output alla menu_driver(). I comandi del menù sono completamente documentati nel manuale alla pagina menu_driver(3x).

Il più semplice gruppo di comandi è REQ_NEXT_ITEM, REQ_PREV_ITEM, REQ_FIRST_ITEM, REQ_LAST_ITEM, REQ_UP_ITEM, REQ_DOWN_ITEM, REQ_LEFT_ITEM, REQ_RIGHT_ITEM. Questi spostano la voce correntemente selezionata. Queste richieste possono causare lo scorrimento della pagina-menù se questa è solo parzialmente visualizzata.

Ci sono richieste esplicite di scorrimento che cambiano la voce corrente (perchè la locazione selezionata non cambia, mentre cambia la voce in essa). Sono le REQ_SCR_DLINE, REQ_SCR_ULINE, REQ_SCR_DPAGE, e la REQ_SCR_UPAGE.

La REQ_TOGGLE_ITEM seleziona o de-seleziona la voce corrente. Viene usata nei menù a valori multipli; se la usate con l'opzione O_ONEVALUE attiva, vi verrà ritornato l'errore (E_REQUEST_DENIED).

Ogni menù è associato ad un buffer di confronto. La logica della menu_driver() prova ad accumularvi i caratteri ASCII stampabili che le vengono passati; quando uguagliano un prefisso o il nome di una voce, quella voce viene selezionata. Se aggiungendo un nuovo carattere non fornisce una nuova scelta, il carattere viene rimosso dal buffer, e la menu_driver() ritorna E_NO_MATCH.

Alcune richieste modificano direttamente il buffer di confronto: REQ_CLEAR_PATTERN, REQ_BACK_PATTERN, REQ_NEXT_MATCH, REQ_PREV_MATCH. Le ultime due sono utili quando l'input nel buffer soddisfa più di una voce in un menù a valori multipli.

Ogni valida richiesta di scorrimento o di cambio di voce svuota il buffer di confronto. È anche possibile cambiare esplicitamente il buffer mediante la set_menu_pattern()

Infine, ogni richiesta al gestore del menù superiore in valore alla costante MAX_COMMAND è considerata un comando specifico dell'applicazione. Il codeice della menu_driver() li ignora e ritorna E_UNKNOWN_COMMAND.

4.7 Altre Caratteristiche

Diverse opzioni possono influenzare l'aspetto visivo e l'elaborazione dell'input dei menù. Vedi il manuale alla pagina menu_opts(3x) per dettagli.

È possibile cambiare la voce corrente dal codice dell'applicazione: è comodo se volete scrivere vostre proprie richieste di navigazione. È inoltre possibile cambiare esplicitamente la prima riga del menù. Vedere mitem_current(3x).

Se la vostra applicazione ha bisogno di cambiare il cursore della sottofinestra del menù per qualunque ragione, la pos_menu_cursor() lo ripristinerà alla locazione giusta per continuare la gestione del menù.

È possibile agganciare del codice da far eseguire all'inizializzazione del menù, al momento della visualizzazione, ed ogniqualvolta la voce selezionata cambi. Vedere menu_hook(3x).

Ogni voce ed ogni menu è associato ad un puntatore d'utente a cui si possono agganciare dati dell'applicazione. Vedere mitem_userptr(3x) e menu_userptr(3x).


Precedente Successivo Indice