giovedì 28 novembre 2013

RaspberryPi: slide ITDevCon e giornata FocusOn

Ho pubblicato le slide della mia sessione "RaspberryPi: alta tecnologia a basso costo" per ITDevCon 2013, le trovate a questo link.




Se l'argomento vi interessa, vi ricordo anche la giornata "Focus On: RaspberryPi, alta tecnologia a basso costo" organizzata da Wintech-Italia per il prossimo 10 dicembre!

A presto

mercoledì 27 novembre 2013

TGmailLabel un esempio di custom component FireMonkey

Introduzione

Per la mia sessione "FireMonkey e gli stili: hands on" di ITDevCon 2013, ho preparato alcuni esempi pratici. Uno di questi esempi consiste nel creare un nuovo componente visuale (derivato da TStyledControl) con uno stile grafico che riproduce l'aspetto delle etichette GMail.

L'esempio è pensato per mostrare come:
  • comporre uno stile usando l'IDE di Delphi;
  • creare un nuovo componente derivato da TStyledControl;
  • integrare lo stile del componente nelle risorse dell'eseguibile;
  • installare il componente nell'IDE di Delphi, di modo da poterne disporre a design-time (ed eventualmente customizzarne ulteriormente lo stile, come è possibile fare con tutti i componenti FM).
Nonostante sia d'obbligo un po' di esercizio per prendere confidenza con i nuovi concetti in gioco (rispetto al mondo VCL), è relativamente semplice creare un nuovo componente visuale che possa essere poi utilizzato su tutte le piattaforme attualmente supportate (con Delphi XE5: Windows, Mac OS, iOS e Android).

Le slide che ho preparato per la mia presentazione a ITDevCon offrono una brevissima introduzione a FireMonkey, la nuova application platform presente nelle ultime versioni di Delphi (XE2 - XE5).
Uno dei concetti fondanti è quello di "style": la definizione (e, per estensione, la sua rappresentazione testuale o binaria) della composizione di oggetti (primitivi o a loro volta composti, visuali e non) che implementa l'aspetto visuale di un componente FM derivato da TStyledControl.

In termini più semplici, i componenti visuali FireMonkey possono essere "forme semplici" (linee, rettangoli, forme geometriche elementari, testo...) oppure "complessi" (frutto della composizione di altri oggetti). Chiamiamo stile la composizione di componenti che realizza le caratteristiche visuali di un componente "complesso".

Comporre lo stile in modo visuale

Uno stile è esso stesso un oggetto FM (un'istanza di TFmxObject) e la sua rappresentazione testuale non è affatto diversa da quella usata nei file .FMX dal form designer dell'IDE, usata per caricare a run-time gli oggetti che compongono una form FM (analogamente a quanto avviene con i file .DFM per le form VCL).

Per editare visualmente gli stili, l'IDE ci mette a disposizione uno strumento specifico, analogo al form designer, denominato "Style Designer". Potete vederlo facendo doppio click su un componente TStyleBook e, insieme all'Object Inspector e la Componente Palette, permette anche di manipolare gli elementi di stile e anche di caricare/salvare su file gli stili FireMonkey.  

L'IDE di Delphi XE5 con lo Style Designer aperto

Purtroppo, questo strumento soffre ancora di qualche problema di gioventù e a volte può risultare un po' ostico da usare. Per ovviare a questo, è possibile percorrere un'altra strada e usare il form designer dell'IDE per comporre, su una qualunque form "di appoggio", la parte visuale del componente. 

Il Form Designer dell'IDE di Delphi XE5

Una volta terminato, grazie all'ampia compatibilità fra il formato usato negli stili e quello usato nei file .FMX delle form, basta chiedere all'IDE di mostrarci la form in modalità testuale (Pulsante destro -> "View as text") e copia-incollare la nostra composizione dalla form ad un file testuale (con estensione .style).

La rappresentazione testuale della form "di appoggio"

Una volta effettuate alcune semplici modifiche (come la rimozione di tutti i component name presenti), il file sarà perfettamente compatibile e potrà essere usato come definizione di style per il nostro componente.

Lo style, ottenuto "ripulendo" la rappresentazione testuale del nostro layout

Possiamo ora includere il contenuto del file .style fra le risorse binarie del nostro eseguibile, di modo di poterne usufruire a run-time; per farlo ci basta preparare un altro file testuale con estensione .rc e chiedere l'inclusione del file indicando anche il nome da assegnare alla risorsa relativa. 

Il contenuto del file GMailLabel.rc

Quando l'IDE processerà questo file, verrà generato un file .RES contenente la risorsa "GMailLabelstyle" che verrà (grazie ad apposita direttiva nel file sorgente del componente) compilata e inclusa nell'eseguibile.

Il codice del componente

Una volta preparata la risorsa contenente la definizione dello stile da applicare al componente, non ci resta che creare la classe del componente stesso.
Io ho usato il wizard di creazione dei componenti (nell'IDE di Delphi, Menù File --> New --> Other --> Delphi files --> Component).
NB: Il codice sorgente completo è disponibile al link indicato nella sezione Materiali di questo articolo.

Sostanzialmente ho creato un componente ereditato da TStyledControl e ho fatto override di alcuni metodi fondamentali per la gestione degli stili, fra cui 
  1. procedure ApplyStyle;
  2. function GetStyleObject(const Clone: Boolean): TFmxObject; 
che si occupano rispettivamente di:
  1. eseguire del codice di collegamento fra gli elementi di stile e i dati del componente (es. impostare la proprietà Text del componente TText mostrando il valore della proprietà LabelName);
  2. ritornare, caricandolo dalle risorse dell'eseguibile, l'oggetto di stile da applicare al componente;
L'intero file non è più lungo di 180 righe (incluse quelle vuote) e il codice è particolarmente semplice.


Package: codice e risorse

Una volta creato il componente, possiamo creare un nuovo package che lo contenga (nell'IDE di Delphi, Menù File --> New --> Delphi Projects --> Package) e seguire questi semplici passi:

  • aggiungiamo la unit del nuovo componente;
  • rimuoviamo eventuali dipendenze dalla VCL che il wizard potrebbe aver impostato;
  • aggiungiamo al package tutte le piattaforme per cui vogliamo rendere disponibile il componente;
  • selezioniamo nuovamente la piattaforma Win32, rendendola attiva;
  • click destro sul nome del package dentro il Project Manager, scegliamo Build;
  • click destro sul nome del package dentro il Project Manager, scegliamo Install;
E dovremmo ottenere conferma che il nostro nuovo componente è stato installato nell'IDE.
Se creiamo una nuova applicazione (desktop o mobile) e apriamo una form, dovremmo vedere comparire nella Tool Palette il nostro nuovo componente.
Ricordate che il componente verrà registrato nella pagina della Palette che avete specificato nel wizard di creazione del componente (potete controllare nel file .pas del componente i valori dei parametri della procedura RegisterComponents che il wizard avrà predisposto per voi. Se li variate, ricordare ti reinstallare il vostro package dopo aver fatto una nuova build).



procedure Register;
begin
  RegisterComponents('Andrea', [TGMailLabel]);
end;

La procedura Register del mio componente TGMailLabel

Ricordatevi di includere il file .style e il file .rc, di modo che le risorse vengano compilate ogni volta che fate Build del package e (grazie alla direttiva {$R GMailLabel.res} presente nel file .pas) incluse negli eseguibili delle applicazioni compilate.

Un componente, 4 piattaforme

Abbiamo quindi a disposizione un nuovo componente visuale che possiamo usare sia in applicazioni FireMonkey desktop (su Windows e Mac OS X) che in applicazioni mobile (su Android e iOS). Ecco qualche screenshot sia dell'IDE che delle applicazioni in esecuzione:

La form desktop con alcune istanze di TGMailLabel, a design-time

Come potete notare nella Structure View si vede anche un componente ShadowEffect1 applicato a GMailLabel4: ovviamente è possibile utilizzare il componente TGMailLabel esattamente come tutti i componenti standard FireMonkey e quindi ho aggiunto un effetto ombreggiatura che viene applicato a run-time (NB: nello screenshot seguente non è visibile per colpa del mio Win XP in esecuzione nella virtual machine sul mio MacBookPro, si vede bene nello screenshot Mac OS X).

Una form FireMonkey desktop, in esecuzione su Windows (Win XP)

Form FireMonkey desktop, in esecuzione su Mac OS X (Mavericks)


Una form FireMonkey mobile (piattaforma Android), a design-time

Una form FireMonkey mobile (piattaforma iOS), a design-time

Una form FireMonkey mobile, in esecuzione sul mio Samsung S2

Una form FireMonkey mobile, in esecuzione nel iOS Simulator

Riferimenti

Se siete interessati alla scrittura di componenti FireMonkey, non posso che consigliarvi il materiale di Ray Konopka disponibile in rete, ad esempio le due sessioni dell'ultima CodeRage, "Creating Custom Controls for the FM Application Platform" e "Effectively Using List Controls in Mobile Apps".

Conclusioni

Oltre ad essere uno strumento fondamentale con cui la piattaforma FireMonkey permette di realizzare applicazioni GUI su piattaforme differenti, gli stili possono essere usati per realizzare componenti custom anche complessi con poco sforzo e sfruttando le potenzialità dell'IDE.
Una volta installati nell'IDE, questi componenti possono essere utilizzati in applicazioni desktop e/o mobile sulle quattro piattaforme attualmente supportate da Delphi XE5.

Materiale

Potete scaricare il codice sorgente completo dell'esempio al seguente link:
Source code - Link to DropBox

domenica 24 novembre 2013

Gli strumenti per potenziare l'IDE di Delphi (Parte 1 - MMX)

Se usate le ultime versioni di Delphi (in realtà anche non tanto "ultime", basta usare da Delphi 2007 in avanti) vi sarete abituati al nuovo IDE "Galileo" che, sebbene forse un poco più pesante rispetto ai primi Delphi, è sicuramente più ricco di funzionalità tali da farmi (personalmente) ritenere l'IDE di Delphi 7 - Delphi 1 ormai inadeguato per la scrittura di codice.

Rimandando ad un altro post la descrizione delle funzionalità dell'IDE che ritengo più interessanti, volevo invece passare in rassegna a tool esterni che potenziano l'ambiente di sviluppo e sono compatibili con più versioni di Delphi (in molti casi supportano anche le versioni pre-galileo).

Voglio ancora ricordare che questa non è una presentazione esaustiva dei tool Delphi ma solo la presentazione dei tool che uso personalmente sulle versioni di Delphi che ho installato per i progetti (miei e dei miei clienti), ovvero Delphi 2007 e Delphi XE4/5

La mia lista dei tool Delphi

In questa serie di articoli sui tool di Delphi cercherò di mostrare i vantaggi per lo sviluppo di ognuno di questi tool e in particolare mi focalizzerò sull'aumento di velocità di scrittura del codice e quindi sull'aumento di produttività che questi tool (con le varie funzionalità aggiunte) offrono.
  • ModelMaker Code Explorer (MMX)
  • GExperts
  • CnPack
  • Documentation Insight
  • Andy's IDE Tools
    • DelphiSpeedUp (D2007)
    • IDE Fix Pack (D2007)
    • DDevExtensions (D2007 - DXE5)

ModelMaker Code Explorer (MMX)

Nome:ModelMaker Code Explorer
Sito:http://www.modelmakertools.com/code-explorer/
Licenza:Commerciale
Prezzo:99€ (69€ Upgrade)


Forse alcuni di voi ricorderanno ModelMaker perché veniva installato con Delphi 6 e Delphi 7 (almeno nelle versioni Enterprise) come strumento di refactoring UML poi rimpiazzato da Together.
 è invece uno strumento che velocizza la scrittura, la modifica (refactoring) di codice Delphi che però mostra la sua massima utilità se il codice è scritto ad oggetti.

ModelMaker Code Explorer (da qui in poi MMX) consente di velocizzare la scrittura e la modifica del codice fornendo numerosi strumenti sia sotto forma di wizard sia sotto forma di comandi attivabile con una sequenza di tasti.

Devo subito dire che il maggior risparmio (di tempo e tasti) MMX lo permette quando si scrive o modifica codice ad oggetti e comunque conoscendo le funzionalità principali della programmazione ad oggetti.

La finestra principale (la console dalla quale partire soprattutto le prime volte) è la "Model Maker Code Explorer" e possiamo dire che è una finestra simile alla finestra "Structure" di Delphi, la differenza è che il "navigatore" di MMX è notevolmente più potente: più comandi, più filtri di visualizzazione, più strumenti di refactoring, diverse modalità di navigazione, Live Metrics, ecc...


Con un click è possibile aggiungere visualmente campi, metodi, proprietà, eventi, indexer alla nostra classe, editare (sempre visualmente) qualsiasi entità del vostro codice.

Mentre scrivete il codice nell'editor di Delphi MMX mostra poi due toolbar (personalizzabili) agganciate alla finestra di editing che mostrano i principali comandi di navigazione e modifica.


Se, come me, quando scrivete codice odiate staccare le dita e lo sguardo dalla tastiera e considerate il concetto dei wizard troppo invasivo, MMX allora è davvero lo strumento che fa per voi.
Tutti i comandi che trovate nella finestra principale, nelle toolbar, nel menu MMX di Delphi sono infatti invocabili anche da tastiera con tasti rapidi visualizzabili e personalizzabili tramite le opzioni di MMX.

Veniamo finalmente ad una lista (molto personale) di comandi e funzionalità che ritengo essenziale per una scrittura veloce, e sicura, del proprio codice.

1) Copia e spostamento entità.

Il refactoring di progetti grandi e complicati a volte è davvero un incubo quando dobbiamo spostare metodi, proprietà e anche classi intere da un punto dell'applicativo ad un altro. In Delphi lo spostamento di queste entità è complicato dall'obbligo di tener sincronizzata la dichiarazione e l'implementazione dei metodi. Con MMX posso dimenticarmi di tutto ciò ed utilizzare i comandi di clipboard:





"Cut Entity"   -> "Ctrl-Alt-X"
"Copy Entity"  -> "Ctrl-Alt-C"
"Paste Entity" -> "Ctrl-Alt-V"

Usando questi comandi riuscirete a spostare metodi, proprietà e classi da una unit all'altra senza perdere tempo a cercare in giro pezzi di codice. MMX riesce anche a capire quali sono le unit di cui avete bisogno nei metodi tagliati/copiati e quindi aggiungere tali clausole uses alla unit di destinazione.
Questa è di gran lunga la mia funzionalità preferita di MMX, mi ha fatto risparmiare davvero molto tempo e anche notevoli "mal di pancia" quando ci si ingroviglia con il taglia/incolla tradizionale!

2) Cancellazione entità e sincronizzazione metodi

Un'altra funzionalità forse meno "eclatante" ma ugualmente utile (e parente della prima) è la possibilità di cancellare metodi "Ctrl-Shift-Del" (ma anche campi, proprietà, classi) anche qui senza di preoccuparsi di dove si trovi l'implementazione.


Anche la sincronizzazione dei parametri dei metodi "Ctrl-Alt-Y" è molto semplice ma data l'altissima frequenza di questa operazione risulta davvero un "time-saver".

3) Editing delle entità



L'editing delle entità "Ctrl-E" è davvero molto potente e si risolve nell'invocazione di una finestra (diversa a seconda dell'entità) in cui si possono modificare tutti i parametri in questione. Ad esempio se modifico un metodo posso modificare:
  il nome
  la visibilità (provate, protected, public, ecc...)
  i parametri (aggiungerne, modificarne il tipo, ecc...)
  il tipo del metodo (funzione, procedura, metodo statico, ecc...)
  varie opzioni (virtuale, override, message, final, ecc...)
Anche in questo caso, ovviamente non mi preoccupo minimamente della parte di implementazione, infatti all'OK sulla finestra di modifica il codice sarà perfettamente aggiornato e sincronizzato.

4) Aggiunta Variabili locali



Questa funzionalità (ormai presente anche in Delphi) consente di aggiungere una variabile locale nel metodo corrente. La cosa sembra *troppo* banale per comparire in un wizard, pensate però di essere in un metodo abbastanza lungo e di aver bisogno di una variabile stringa opportunamente inizializzata a stringa nulla ''. Con il comando "Add local var" -> "Ctrl-L" dovete semplicemente scrivere il nome ed il tipo della variabile senza spostarvi dal punto in cui stavate scrivendo e la variabile sarà definita ed inizializzata per voi alla prima riga del metodo. Semplice ma efficace!

5) Rename in Scope



Un'altra operazione molto frequente nella modifica del codice sorgente è il rename dei simboli solitamente fatta dalle classiche operazioni di Search/Replace su testo selezionato oppure sull'intero file. MMX ha invece il comando "Rename in Scope" -> "Ctrl-Alt-L" che consente di rinominare il simbolo su cui è posizionato il cursore e di applicare le regole di rename legate allo scope: localmente, nella classe, nel modulo (unit). Questo limita gli errori dovuti al "Replace Selvaggio" che possono avere conseguenze anche gravi per l'introduzione di bug particolarmente insidiosi.

6) Extract Methods



La funzionalità "principe" per il refactoring è sicuramente il comando "Extract Method" (presente anche in Delphi) è uno strumento molto comodo per riconoscere pezzi di codice da raccogliere a fattore comune o semplicemente effettuare cambiamenti pesanti sui metodi delle mie unit.

7) Aggiunta entità



Le finestre di "Add Entity" (dove Entity può essere un metodo, una classe, un'interfaccia, una property, ecc...) sono le stesse di editing delle stesse con ovviamente i settaggi non inizializzati. Personalmente sull'aggiunta di proprietà, metodi o classi ritengo più veloce l'immissione manuale scrivendo direttamente il codice, tuttavia sono un aiuto importantissimo a chi si avvicina alla programmazione Delphi e soprattutto ai programmatori Delphi, anche di lunga data, che si approcciano seriamente alla programmazione ad oggetti.

Conclusioni

Questa è la lista delle funzionalità che ritengo più utili in ModelMaker CodeExplorer, funzionalità che però non si esauriscono qui anzi sono cosciente di usare lo strumento ad una frazione delle sue potenzialità ma ognuno deve trovare un equilibrio tra le innumerevoli funzionalità che uno strumento offre e quelle che sono davvero in grado di apportare un netto miglioramento nel suo modo di scrivere codice.

Nel prossimo articolo vedremo in azione uno dei più longevi tool di Delphi: i GExperts.

Se avete quesiti o proposte di recensione di altri tool scrivetemi o lasciate un commento su questo blog.



Paolo Rossi.


ITDevCon 2013 - Materiale disponibile

ITDevCon 2013 si è conclusa venerdì scorso e qualche giorno fa il materiale della conferenza (incluse le mie presentazioni e i relativi esempi) è stato reso disponibile a tutti i partecipanti (vi sarà arrivata comunicazione via mail).

In particolare volevo segnalarvi l'esempio CustomComponent della sessione "FireMonkey e gli stili: hands on" in cui mostro come creare un nuovo componente FireMonkey: TGMailLabel che mima il comportamento del pulsante delle etichette di GMail (prossimamente posterò qualche dettaglio in più anche qui).

Per quanto riguarda la conferenza, è stata un'esperienza positiva: molte le sessioni interessanti (ma poche quelle a cui sono riuscito effettivamente a partecipare, per vari motivi fra cui la sistemazione in extremis di slide e demo delle mie sessioni!) e ottimo lo scambio di opinioni e informazioni con gli altri speaker e con i partecipanti.

Sono stato felice di vedere che le mie sessioni (sia quella sugli stili FireMonkey che quella su un argomento "nuovo" come RaspberryPi) hanno avuto buona partecipazione e suscitato interesse fra i partecipanti: più di una persona mi ha scritto, nei giorni seguenti la conferenza, che aveva già ordinato un RaspberryPi per farci qualche esperimento!

Vi ricordo che il 10 dicembre prossimo ci sarà un evento FocusOn dedicato a RaspberryPi in Wintech-Italia a Piacenza.

Vi lascio una fotografia proprio della sessione RaspberryPi e un saluto a tutti i partecipanti / speaker / organizzatori di questo evento.


Qui trovate altre fotografie dagli organizzatori

Qui trovate un reportage a cura di Marco Breveglieri