« Tk: alcuni widget: comando menu • Appunti di Tcl/Tk • Tk: alcuni widget: comando scrollbar »
text pathName ?options?
Il widget di tipo text consente la visualizzazione e l'editing di una o più linee di testo. Si tratta di un widget molto potente, che consente di inserire diversi tipi di annotazioni nel testo, addirittura di avere immagini o finestre incorporate. È quindi possibile scrivere editor con supporto di syntax highlighting o interi word processor con questo controllo. Consultate la manpage text(n) per sfruttare queste funzionalità avanzate.
Alcune opzioni specifiche di questo widget:
Alcuni comandi di widget più importanti:
Un indice indica una posizione nel testo e deve consistere di un valore base (obbligatorio) che indica un punto di partenza e da zero o più modificatori che indicano uno scostamento dal punto di partenza. I valori di base possono essere di vario tipo. line.char indica il carattere numero char della linea numero line. Le linee sono numerate a partire da 1, mentre i caratteri all'interno di una linea sono numerati a partire da 0. Il valore end per char indica il numero di colonna del carattere newline che termina la linea. Se l'intero valore base è end, questo indica la fine del testo (l'indice del carattere che si dovrebbe trovare proprio dopo l'ultimo finelinea).
Come modificatori si possono usare le forme + count chars per muoversi in avanti di count caratteri, - count chars per muoversi indietro e analogamente + count lines, - count lines per muoversi di un certo numero di linee.
Un marcatore (MARK) è un tipo di annotazione fluttuante nel testo. Ha un nome e si riferisce ad una singola posizione del testo, ma non è associato permanentemente ad un certo carattere. È associato invece allo spazio tra due caratteri. Se i caratteri attorno ad un mark vengono cancellati, il mark rimane e avrà nuovi caratteri confinanti. L'indice equivalente di un mark può variare nel tempo mentre il testo viene editato. Il nome di un mark può essere usato come base di un indice e indica il carattere che si trova giusto dopo il marcatore specificato. Se i caratteri attorno ad un mark vengono cancellati, il mark rimane e avrà nuovi caratteri confinanti. Il comando:
pathName mark set markName index
imposta il mark chiamato markName alla posizione che precede il carattere di indice index. Se il mark markName esiste già viene spostato, altrimenti viene creato un nuovo mark di nome markName. Ritorna una stringa vuota.Il mark insert è speciale: rappresenta la posizione del cursore di inserzione, che verrà automaticamente disegnato in questo punto ogni volta che il widget di tipo text riceve il focus. Viene definito automaticamente quando viene creato un widget text e non può essere rimosso tramite il comando di widget pathName mark unset.
Esempi: leggere il carattere subito dopo il cursore e la posizione del cursore in un widget .t di tipo testo:
.t get insert .t index insert
Adesso mostrerò un espediente per intercettare i vari comandi che vengono invocati su un widget dai suoi binding predefiniti:
text .t pack .t rename .t .t.orig proc .t {option args} { puts "$option $args" eval ".t.orig $option $args" }
Ad esempio supponendo che cliccate sul widget per dargli il focus, sotto sotto vengono invocati comandi di widget simili ai seguenti:
index @112,77 bbox 1.0 mark set insert 1.0 mark set anchor insert cget -state tag remove sel 0.0 end
Quello che avviene è che viene chiesto l'indice del carattere che occupa uno spazio che include il punto di coordinate @112,77 (il vostro valore può essere diverso a seconda di dove cliccate) misurate rispetto all'angolo superiore sinistro del widget. Col sottocomando bbox vengono chieste coordinate e dimensioni dell'area occupata dal carattere di indice 1.0. Poi il cursore viene posizionato all'indice 1.0 e così pure il marcatore anchor, usato per indicare l'inizio di una eventuale selezione. Viene chiesto al widget qual'è il suo stato e viene rimossa una eventuale selezione.
Supponendo ora che uno digiti la lettera T si ottiene:
cget -state compare sel.first <= insert insert insert T see insert
Il sottocomando compare confronta due indici. Il sottocomando insert inserisce la lettera T nella posizione del cursore. Il sottocomando see aggiusta la vista in modo che il carattere all'indice insert sia visibile.
Se premete backspace avrete:
tag nextrange sel 1.0 end compare insert != 1.0 delete insert-1c see insert
Qui notate come la cancellazione del carattere che precede il cursore sia ottenuta tramite il sottocomando delete e notate anche l'espressione indice insert-1c.
Questa tecnica di intercettazione, basata sul comando rename(n), non è solo utile didatticamente. Sarebbe possibile usarla nel nostro editor di testi tpad per implementare la funzione di undo. Poiché però Tk, a partire dalla versione 8.4 incorpora le funzionalità di undo nel widget text(n), ho preferito usare queste, semplificando notevolmente il programma. tpad richiederà quindi una versione di Tk >=8.4
Ispezioniamo ora gli eventi legati ai widget text(n). È raccomandabile la lettura della manpage bind(n) per una migliore comprensione. Questo comando restituisce la lista delle sequenze per le quali esiste un binding di classe Text (ossia un binding che si applica a tutti i widget di tipo Text). Ho dovuto spezzare l'output su più linee per una migliore presentazione.
% bind Text <Button-5> <Button-4> <MouseWheel> <B2-Motion> <Button-2> <Control-Key-h> <Meta-Key-Delete> <Meta-Key-BackSpace> <Meta-Key-greater> <Meta-Key-less> <Meta-Key-f> <Meta-Key-d> <Meta-Key-b> <Control-Key-v> <Control-Key-t> <Control-Key-p> <Control-Key-o> <Control-Key-n> <Control-Key-k> <Control-Key-f> <Control-Key-e> <Control-Key-d> <Control-Key-b> <Control-Key-a> <Key-KP_Enter> <Key-Escape> <Control-Key> <Meta-Key> <Alt-Key> <Key> <Key-Insert> <<PasteSelection>> <<Clear>> <<Paste>> <<Copy>> <<Cut>> <Control-Key-backslash> <Control-Key-slash> <Shift-Key-Select> <Control-Shift-Key-space> <Key-Select> <Control-Key-space> <Key-BackSpace> <Key-Delete> <Key-Return> <Control-Key-i> <Control-Shift-Key-Tab> <Control-Key-Tab> <Shift-Key-Tab> <Key-Tab> <Control-Shift-Key-End> <Control-Key-End> <Control-Shift-Key-Home> <Control-Key-Home> <Shift-Key-End> <Key-End> <Shift-Key-Home> <Key-Home> <Control-Key-Next> <Control-Key-Prior> <Shift-Key-Next> <Key-Next> <Shift-Key-Prior> <Key-Prior> <Control-Shift-Key-Down> <Control-Shift-Key-Up> <Control-Shift-Key-Right> <Control-Shift-Key-Left> <Control-Key-Down> <Control-Key-Up> <Control-Key-Right> <Control-Key-Left> <Shift-Key-Down> <Shift-Key-Up> <Shift-Key-Right> <Shift-Key-Left> <Key-Down> <Key-Up> <Key-Right> <Key-Left> <Control-Button-1> <ButtonRelease-1> <B1-Enter> <B1-Leave> <Triple-Shift-Button-1> <Double-Shift-Button-1> <Shift-Button-1> <Triple-Button-1> <Double-Button-1> <B1-Motion> <Button-1>
Questo restituisce la lista di tutti gli eventi virtuali definiti:
% event info <<Cut>> <<Paste>> <<PrevWindow>> <<PasteSelection>> <<Copy>>
Ecco poi le liste delle sequenze degli eventi fisici associati ai vari eventi virtuali:
% event info <<Copy>> <Control-Key-c> <Key-F16> <Meta-Key-w> % event info <<PasteSelection>> <ButtonRelease-2> % even info <<PrevWindow>> <Shift-Key-Tab> % event info <<Paste>> <Control-Key-v> <Key-F18> <Control-Key-y> % event info <<Cut>> <Control-Key-x> <Key-F20> <Control-Key-w>
Vediamo ora gli script legati agli evento virtuali specificati per la classe Text:
% bind Text <<Copy>> tk_textCopy %W % bind Text <<PasteSelection>> if {!$tkPriv(mouseMoved) || $tk_strictMotif} { tkTextPaste %W %x %y } % bind Text <<Paste>> tk_textPaste %W % bind Text <<Cut>> tk_textCut %W
Control-v è legato allo scrolling di una pagina avanti:
% bind Text <Control-Key-v> if {!$tk_strictMotif} { tkTextScrollPages %W 1 }
Per usarlo per fare il pasting è sufficiente distruggere il binding precedente, con l'istruzione:
% bind Text <Control-Key-v> {}
Analogamente il binding <Control-Key-o> viene usato per spezzare una linea senza spostare il cursore.
% bind Text <Control-Key-o> if {!$tk_strictMotif} { %W insert insert \n %W mark set insert insert-1c }
Se vogliamo usarlo per richiamare la finestra di apertura dei file, dobbiamo distruggere il binding di default, onde evitare che quando si preme Control-o mentre .text ha il focus, vengano eseguite entrambe le azioni!
% bind Text <Control-Key-o> {}
Il file /usr/local/lib/tk8.4/text.tcl definisce in Tcl i binding per il widget text(n).
« Tk: alcuni widget: comando menu • Appunti di Tcl/Tk • Tk: alcuni widget: comando scrollbar »