.. -*- mode: rst; coding: utf-8 -*- ============================ Presentazione per LD2005GR ============================ :Author: dakkar :CreationDate: 2005-11-21 Note generali a uso dakkar ========================== Tempo: 1h – 1h20 Audience: non sanno nulla di Perl, ma sono venuti qui per mettere su il loro sistema Linux figo. Hanno qualche idea di come mettere su uno pseudo-server, forse. Parte prima: di cosa si parla ============================= Cos'è Perl ---------- Perl è un linguaggio di programmazione creato per «rendere facili le cose facili, e possibili quelle difficili». Ha un sacco di idiosincrasie, ma è progettato per essere comodo da usare e da imparare: non dovete per forza impararlo tutto in uan volta, potete impararlo poco a poco, e ottenere comunque dei risultati. Cosa sono le GUI ---------------- Interfacce utente grafiche: per quando preferite i disegnini alla linea di comando. O quando è più comodo scegliere un'opzione da un elenco piuttosto che ricordarsi il comando. Non sono la soluzione definitiva a tutti i problemi, ma in alcuni casi aiutano. Spesso sono ritenute difficili da implementare, e molti ne producono di brutte e scomode. Specie sotto Linux, tutti si lamentano che non c'è VisualBasic o Delphi (Kylyx notwithstanding). Dove vogliamo arrivare ---------------------- Tra un'ora avremo scritto un file manager a due pannelli, stile Norton Commander. In Perl, con Gtk+2, in 23KiB totali, di cui scritti a mano 7KiB. Parte seconda: gli strumenti ============================ Usiamo Gtk+2, il toolkit grafico su cui si basa Gnome, e Glade, uno strumento per disegnare le interfacce grafiche, simile a VB o Delphi, ma più che altro all'Interfcae Builder di NeXT o MacOSX. Gtk+2 offre molti controlli (“widget”) comuni e perfettamente funzionanti. Glade ci permette di separare il disegno dell'interfaccia dal codice che implementa la logica: in questo modo il nostro codice è pulito e concentrato sulle cose importanti («cosa deve fare»), e per cambiare la posizione di un pulsante non dobbiamo toccare il sorgente. Usiamo Perl perché è comodo e permette di concentrarsi sul codice “utile”, lasciando al compilatore/interprete il compito di spiegarlo alla macchina. Parte terza: andiamo ==================== Stage 1: lo scheletro --------------------- Mostrare: * Build.PL * LDFM::MainController * ldfm Il primo è una specie di Makefile: indica cosa serve e cosa bisogna produrre. Il secondo è la classe controller del file manager: per ora è vuota. Il terzo è lo script che useremo per lanciare il tutto: per ora scrive ``buh!``. Stage 2: Glade -------------- Mostrare: * Build.PL * ldfm * LDFM::MainController * ldfm-main.glade (in Glade) ``Path::Class`` ci semplifica la gestione delle directory e dei file. Lo script di avvio è modificato in modo da scoprire dove stiano i file generati con Glade, e passare questa directory al costruttore del controller. Il controller ricava il suo file di interfaccia, e lo carica chiamando il costruttore della super-classe. Dentro Glade: giro di prova, mettendo un po' di controlli a caso. Caricare ``ldfm-main.glade``, mostrare i controlli usati, far notare come molti hanno delle call-back associate. Eseguire il codice: mostrare gli warning, e che la chiusura non va. Stage 3: le liste dei file -------------------------- Mostrare: * Build.PL * LDFM::MainController ``Gtk2::Ex::Simple::List`` rende più semplice e comoda la gestione dei list-box in Gtk+2, che sono dei controlli molto potenti e flessibili, ma non proprio immediati da usare. Aggiriamo il problema usando codice già scritto. ``simplify_list`` sostituisce i controlli list-bax normali con quelli "semplificati". ``update_list_with_path`` carica la lista di file nel list-box, usando i metodi di ``Path::Class``. ``quit`` è la prima call-back che vediamo: si limita a terminare l'applicazione. Eseguire il codice: mostrare le liste, far notare che ancora non funziona altro, ma la chiusura sì. Stage 4: il doppio click ------------------------ Mostrare: * LDFM::MainController ``update_list_with_path`` è stata modificata per gestire in maniera corretta ``..`` e i path relativi. ``set_*_path`` viene chiamata quando si preme “Invio” in uno degli input-box in alto: prende il testo che abbiamo scritto e lo passa a ``update_list_with_path``. ``use_*_row`` viene chiamata quando facciamo doppio click su una riga di una lista: chiama ``use_a_row``, che prende il nome in quella riga e lo passa a ``update_list_with_path``. Eseguire il codice: mostrare come si possa cambiare dir sia scrivendo un path sia facendo doppio click. Stage 5: i pulsanti in basso ---------------------------- Mostrare: * LDFM::MainController Impostiamo le liste perché permettano la selezione multipla. ``get_selected_side`` ci dice se il focus sta a sinistra o a destra (i pulsanti sono configurati da Glade in modo da non prendere mai il focus). ``get_files_from_list`` ci restituisce l'elenco dei file selezionati di una lista, agganciandoli alla directory giusta. ``get_selected_files`` ci dà l'elenco dei file selezionati nella lista col focus. ``mkdir`` fa finta di creare una directory: sa dove, ma non sa con che nome. Ci servirebbe un dialog box, poi lo creeremo. ``delete`` fa finta di cancellare i file selezionati: non lo fa davvero perché non voglio fare danni sul mio computer ;-) ``rename`` accetta un solo file da rinominare, ma anche qui servirebbe il dialog per il nuovo nome. Eseguire il codice: mostrare gli warning. Stage 6: pulsanti al centro --------------------------- Mostrare: * LDFM::MainController ``copy_lr``, ``copy_rl``, ``move_lr`` e ``move_rl`` vengono chiamate dai pulsanti ovvi. Chiamano le funzioni ``copy_files`` e ``move_files`` per evitare di scrivere due volte lo stesso codice. Le funzioni scrivono soltanto quello che farebbero, per non fare danni. Eseguire il codice: mostrare gli warning. Stage 7: il dialog box ---------------------- Un dialog box è un'altra finestra, per cui facciamo un nuovo file Glade e un nuovo controller. Mostrare: * ldfm-dialog.glade (in Glade) * LDFM::DialogController * LDFM::MainController Il dialog è creato di tipo “dialog” in modo che si comporti come tale. Domanda e risposta verranno impostate e lette dal controller. ``LDFM::DialogController`` si limita a impostare l'etichetta e il campo, e quando gli si chiede di ``run`` esegue il dialog e prende la risposta. Nel main: ci segnamo dove stanno i file Glade in modo da poterlo dire al DialogController; quando serve una risposta dall'utente (``mkdir``, ``rename``) si istanzia il dialog e si usa la risposta (sempre per finta). In ``delete`` ci basta un sì o un no, per cui usiamo il MessageBox predefinito di Gtk+2. Eseguire il codice: mostrare i tre dialog e gli warning con il risultato. Stage 8: riconoscimento dei tipi -------------------------------- Mostrare: * Build.PL * LDFM::MainController Per riconoscere i tipi dei file usiamo un modulo che funziona come il comando ``file``: guarda sia il nome sia il contenuto dei file e dice di che tipo sono. Tutto quello che dobbiamo fare è chiamare il metodo giusto quando carichiamo i dati nelle liste. Eseguire il codice: mostrare i tipi. Stage 9: doppio click sui file ------------------------------ Mostrare: * LDFM::MainController Per ora fare doppio click su un file non ha alcun effetto. Con 6 righe di codice distinguiamo un file da una directory e facciamo finta di aprirlo. Eseguire il codice: mostrare gli warning. Parte quarta: conclusioni ========================= Le GUI non sono difficili: basta usare gli strumenti giusti. Non mescolate vista e controller: vi fareste solo del male. Se avete un problema, molto probabilmente qualcun'altro l'ha avuto prima di voi: le librerie sono la vostra salvezza.