La libreria ncurses
di per sè fornisce un buon supporto per
videate in cui le finestre sono accostate (senza sovrapporsi).
Nel caso più generale di finestre sovrapposte, dovrete usare una
serie di chiamate wnoutrefresh()
seguite da una doupdate()
,
stando attenti all'ordine in cui rifrescate le finestre.
Dovrà partire dalle sottostanti verso le sovrastanti, altrimenti
diverranno visibili quelle parti di finestre che avrebbero dovuto
restare coperte.
Quando il vostro progetto di interfaccia è tale che le finestre
si tuffano più profondamente nella pila della visibilità o ne saltano
in cima, la contabilità risultante può risultare tediosa e
difficile da mantenere.
Da qui la libreria panel
.
La libreria panel
apparve la prima volta nel System V
dell'AT&T.
La versione documentata qui è la versione freeware del
codice panel
distribuita con le ncurses
.
I vostri moduli che usano le panel devono importare le dichiarazioni della libreria mediante
#include <panel.h>
e deve essere esplicitamente linkato alla libreria panel usando
l'argomento -lpanel
.
Notate che deve anche linkare la libreria ncurses
mediante -lncurses
.
La maggior parte dei moderni linker eseguono due passaggi
e accettano qualunque ordine, ma è comunque buona pratica
mettere -lpanel
per primo e -lncurses
per secondo.
Un oggetto panel è una finestra che è implicitamente trattata
come parte di un deck (piano) che include tutti
gli altri oggetti panel.
Il piano ha un implicito ordine di visibilità da sotto a sopra.
La libreria panel include una funzione di aggiornamento (analoga
alla refresh()
) che visualizza tutti i panel del piano
nell'ordine corretto per risolvere le sovrapposizioni.
La finestra standard, stdscr
, è considerata sottostante
a tutti i panel.
Dettagli sulle funzioni panel sono disponibili nelle pagine del manuale. Qui mostreremo solo le parte più evidenti.
Si crea un panel da una finestra chiamando new_panel()
con un puntatore a WINDOW.
Questo diventa la cima del piano.
La finestra del panel è disponibile come valore della
panel_window()
chiamata con il puntatore al panel come argomento.
Si può cancellare un panel (rimuovendolo dal piano) con del_panel
.
Questo non dealloca la finestra associata; dovrete farlo da soli.
Si può sostituire la finestra del panel con una finestra diversa
chiamando la replace_window
.
La nuova finestra può essere di dimensioni diverse;
il panel ricalcolerà tutte le sovrapposizioni.
Questa operazione non modifica la posizione del panel nel piano.
Per muovere una finestra di un panel, usate move_panel()
.
La funzione mvwin()
non è sufficiente perchè questa non aggiorna
la rappresentazione della libreria panel di dove si trovano le finestre.
Questa operazione lascia intatti profondità, contenuti e dimensioni
del panel.
Due funzioni (top_panel()
, bottom_panel()
) sono
fornite per riorganizzare il piano.
La prima spinge la finestra argomento in cima
al piano; la seconda la manda sul fondo.
Entrambe le operazioni lasciano
intatti posizione, contenuti e dimensioni del panel nello schermo.
La funzione update_panels()
esegue tutte le chiamate a
wnoutrefresh()
necessarie per la successiva
doupdate()
(che dovrete eseguire esplicitamente voi).
Tipicamente, vorrete chiamare la update_panels()
e la
doupdate
proprio prima di accettare comandi in input,
una volta in ogni ciclo di interazione con l'utente.
Se chiamate la update_panels()
dopo ogni scrittura in
un pannello, genererete un sacco di attività di rinfresco
e di sfarfallio dello schermo non necessari.
Non dovrete mai usare le wnoutrefresh()
o le wrefresh()
insieme al codice dei panel; funzionerebbe solo se la finestra argomento
fosse nel pannello superiore o non oscurata da alcun altro pannello.
La finestra stsdcr
è un caso a parte. Si trova sotto tutti i
pannelli.
Siccome ogni modifica ad un pannello potrebbe oscurare stdscr
,
dovrete eseguire la update_panels()
prima della
doupdate()
anche quando avrete modificato soltanto stdscr
.
Notate che la wgetch
chiama automaticamente la wrefresh
.
Per questo, prima di chiedere input da una finestra in un pannello,
avrete bisogno che il pannello sia totalmente non-oscurato.
Attualmente non c'è modo di visualizzare modifiche ad un pannello oscurato senza rivisualizzare tutti i pannelli.
È possibile rimuovere temporaneamente un pannello dal piano;
usando hide_panel
per questo.
Potete scoprire un pannello con show_panel()
.
La funzione panel_hidden
verifica se un pannello è nascosto
o meno.
La panel_update
ignora i pannelli nascosti.
Non potete eseguire
top_panel()
oppure bottom_panel
su un pannello nascosto.
Le altre operazioni sui pannelli sono invece applicabili.
È possibile navigare sul piano utilizzando le funzioni
panel_above()
e panel_below
.
Dato un puntatore
ad un pannello, ritornano il pannello sopra o sottostante.
Dato
NULL
, ritornano il pannello più inferiore o quello più superiore.
Ogni pannello ha associato un puntatore per l'utente, non
utilizzato internamente,
al quale potrete associare dati relativi all'applicazione.
Vedere le pagine del manuale delle
set_panel_userptr()
e panel_userptr
per dettagli