Introduzione generale
Transcript
Introduzione generale
POLITECNICO DI TORINO III Facoltà di Ingegneria Corso di Laurea in Ingegneria del Cinema e dei Mezzi di Comunicazione Tesi di Laurea Magistrale Tecnologia Multitouch: ActionScript come strumento di sviluppo di applicazioni interattive Relatore Prof. Giovanni Malnati Correlatore Porf.ssa Sara Comai Candidato Juan Pablo Varón T. Novembre 2010 Indice INTRODUZIONE ...................................................................................................................1 Capitolo 1 ................................................................................................................................5 TECNOLOGIA MULTITOUCH............................................................................................5 1.1 La storia ....................................................................................................................5 1.2 Parti basici di un sistema Touchscreen .....................................................................6 1.3 Descrizione delle diverse tecniche per la costruzione dei dispositivi ottici .............7 1.3.1 1.4 Tecnologia ottica – L‟uso della luce infrarossa ................................................7 Descrizione Generale del Sistema ..........................................................................13 1.4.1 CCV – Il Tracker .............................................................................................13 1.4.2 FLASH – Uno strumento per applicazioni Interattive ....................................15 Capitolo 2 ..............................................................................................................................17 TUIO .....................................................................................................................................17 2.1 Specifica del protocollo TUIO 1.1 .........................................................................17 2.1.1 Implementazione, efficienza ed affidabilità del protocollo.............................18 2.1.2 Profili ed i suoi attributi ..................................................................................20 2.2 Touchlib..................................................................................................................21 2.2.1 Classe TUIO ....................................................................................................21 2.2.2 Classe TUIOCursor .........................................................................................22 2.2.3 Classe TUIOEvent ..........................................................................................23 2.2.4 Classe TUIOObject .........................................................................................23 Capitolo 3 ..............................................................................................................................26 Componenti di FLASH .........................................................................................................26 3.1 Cos‟è un componente? ...........................................................................................26 3.2 Struttura dei Componenti .......................................................................................28 3.3 Il codice interno dei componenti – L‟elemento componentShim ..........................29 3.4 Struttura a due frame dei componenti ....................................................................31 3.5 Struttura interna di Flash per l‟uso dei componenti ...............................................34 3.5.1 La classe base dei componenti: fl.core.UIComponent ....................................35 3.5.2 Il metodo configUI e l‟uso degli Stili .............................................................36 3.5.3 Il metodo draw() ed il modello d‟invalidazione ..............................................40 3.5.4 Metadati dei componenti .................................................................................43 2 3.5.5 Creazione del componentShim per i componenti personalizzati .................... 44 3.5.6 Definizione di un componente e creazione dell‟anteprima ............................ 47 Capitolo 4.............................................................................................................................. 50 Gesti ...................................................................................................................................... 50 4.1 Caratteristiche delle interfacce gestuali ................................................................. 50 4.1.1 Attributi dei gesti ............................................................................................ 52 4.1.2 Gesti basici/Pattern per i touchscreen ........................................................... 53 4.2 Gesti tattili non convenzionali ............................................................................... 55 4.2.1 Tecnica “$1 Recognizer” per il riconoscimento dei gesti touchscreen .......... 55 Capitolo 5.............................................................................................................................. 62 Sviluppo di strumenti basi di ActionScript per applicazioni Multitouch ............................. 62 5.1 Sviluppo di componenti tattili ................................................................................ 62 5.1.1 Componente: TouchButton............................................................................. 62 5.1.2 Componente: TouchNumericStepper ............................................................. 69 5.1.3 Componente:TouchSlider ............................................................................... 75 5.1.4 Componente:TouchKeyboard ......................................................................... 79 5.1.5 Errori nei componenti rilevati nel processo di sviluppo ................................. 93 5.1.6 Importando i componenti in FLASH .............................................................. 94 5.2 Creazione di classi di AS3 per l‟interazione con i Gesti........................................ 95 5.2.1 Classificazione dei gesti ................................................................................. 95 5.2.2 Classi di ActionScript 3.0 sviluppate.............................................................. 95 5.2.3 Applicazione di test per le classi dei gesti .................................................... 107 CONCLUSIONI ................................................................................................................. 109 BIBLIOGRAFIA ................................................................................................................ 113 ALLEGATO A ................................................................................................................... 116 3 INTRODUZIONE Lo sviluppo delle tecnologie informatiche non solo ha comportato una crescita esponenziale delle capacità di calcolo dei singoli elaboratori, ma ha permesso la creazione di interfacce uomo-macchina sempre più sofisticate, in grado di semplificare in modo sostanziale la comunicazione verso l‟elaboratore, rendendo sempre più invisibile la sua presenza all‟interno di un ambiente. Inizialmente l‟unico dispositivo di input era la tastiera, man mano altri dispositivi sono stati sviluppati ed aggiunti arricchendo il modo in cui è possibile interagire con il computer: il mouse che con i movimenti della mano permette di spostare un oggetto sullo schermo; la video camera che rileva delle immagini che possono essere inserite successivamente nel computer per modificarle. Al giorno d‟oggi è persino possibile trovare alcuni dispositivi in ambienti che possono sembrare insolti, come un bagno pubblico dove per usare i lavandini non bisogna più utilizzare le mani e basta solo metterle sotto il rubinetto per far uscire l‟acqua. Appare evidente come l‟introduzione di nuovi dispositivi d‟input e di nuove tecnologie sta portando piano piano ad un cambiamento delle abitudini e delle modalità d‟interazione delle persone con l‟ambiente che le circonda. Tutti i dispositivi di ultima generazione in ambito tecnologico aumentano sempre le loro capacità di elaborare le informazioni, permettendo così di fare operazioni ogni volta più complesse. Una tecnologia che ha cominciato a diffondersi ampiamente è quella touchscreen, e si vede implementata su un numero sempre crescente di dispositivi che integrano questo tipo d‟interfacce. I cellulari, i dispositivi elettrodomestici, e tutti i dispositivi elettronici in generale utilizzano le interfacce touchscreen per il loro funzionamento. In generale questi dispositivi riescono a ricevere soltanto un segnale d‟input alla volta, però negli ultimi anni ci sono stati grandi passi avanti nell‟ambito di questa tecnologia ed ora è possibile trovare alcuni dispositivi che riescono a rilevare ed interagire con più segnali d‟input contemporaneamente. Questo tipo d‟interfacce tattili sono note come interfacce multitouch e le loro prestazioni offrono la possibilità di creare nuovi modi di interagire con gli utenti e nuove maniere di realizzare applicazioni molto più interattive. Tutti i dispositivi che rispondono a dei gesti, come il tocco nei dispositivi touchscreen, devono avere come minimo tre parti fondamentali: la prima è un sensore che si occupa di 1 Introduzione misurare gli input del sistema; la seconda è un comparatore che elabora i dati misurati per rilevare se gli input sono validi o no; la terza è l‟attuatore che realizza un‟azione in risposta agli input che sono stati considerati validi dal comparatore. Inoltre, sempre nell‟ambito delle interfacce touchscreen, ci deve essere almeno una parte fisica, l‟hardware, con la quale l‟utente può interagire. Nei sistemi interattivi di tipo touchscreen è l‟hardware ad occuparsi di rilevare la presenza di input, e quindi l‟hardware è il sensore del sistema. Per la costruzione del dispositivo d‟input ci sono tanti tipi diversi di tecnologie: è possibile usare tecnologie Resistive1, che rilevano il tocco sul touchscreen usando due lamine resistive che entrano in contatto nel punto di appoggio del dito; tecnologie Capacitive2, che misurano la variazione di tensione causata dal cambiamento di capacità dei condensatori posti sullo schermo dovuta al contatto del dito; e sarebbe ancora possibile elencare altre tecnologie3. Nell‟ambito di questa tesi è stata utilizzata la tecnologia ottica. Questa fa uso della luce infrarossa per il rilevamento degli oggetti sullo schermo e di una video camera che è sensibile a questa parte dello spettro della luce. Le diverse tecniche esistenti per questa tecnologia sono illustrate nella sezione 1.2. Il passo successivo è l‟elaborazione, da parte del sistema, dei dati appena ricavati e questo è possibile sia con altri dispositivi hardware sia con un software. Per la tecnologia ottica le informazioni rilevate sono sotto forma d‟immagini, le quali possono essere elaborate con un software adatto. Questo software deve essere in grado di ricavare sufficente informazione dalle immagini per individuare le aree, note come blob, in cui l‟utente è entrato in contatto con lo schermo. Questi tipi di software sono anche conosciuti come tracker poichè elaborano le immagini per individuare le posizioni dei blob presenti sullo schermo. Inoltre, i tracker possono ricavare altre informazioni, come per esempio la velocità oppure l‟orientamento dei blob. Poiché è possibile individuare contemporaneamente un insieme di blob, questo tipo di software è anche utilizzato per le interfacce multitouch. Per le interfacce touchscreen, quindi, questi software sono i comparatori del sistema, e la loro capacità di elaborazione dell‟informazione è molto importante per un sistema interattivo: più informazioni riesce a rilevare il comparatore più azioni sarà possibile fare per reagire agli input dell‟utente. Il tipo d‟informazione che deve essere ricavata per poterla utilizzare nelle applicazioni interattive ed il modo in cui deve essere comunicata all‟attuatore del sistema sono descritti da un protocollo, TUIO, che permettere di standardizzare la comunicazione esistente tra il tracker e le applicazioni, e la sua descrizione si può trovare nel capitolo 2 del presente lavoro. Le applicazioni interattive che fanno uso delle informazioni descritte dal protocollo TUIO possono essere scritte in diversi linguaggi, come Python, C++, ovvero ActionScript (utilizzato nella programmazione con Flash), quindi è necessario tradurre i dati inviati dal tracker nel linguaggio con il quale si vuole lavorare per lo sviluppo dell‟applicazione. Per il 1 Resistive Touch Screen <http://resistivetouchscreen.org/> Baxter, L. K. “Capacitive Sensors: Design and applications” pg 138. 3 Henderson, H. “Encyclopedia of computer science and technology” pg 478. 2 2 Introduzione linguaggio ActionScript 3.0 esiste già una libreria di programmazione, Touchlib, che è in grado d‟interpretare i messaggi inviati col protocollo TUIO e tradurli in linguaggio ActionScript, però nel farlo questa libreria elabora ancora di più questi dati per riuscire a comunicare le azioni fatte dall‟utente in un modo più specifico, come per esempio quando l‟utente appoggia il dito sullo schermo, quando lo sposta, oppure quando lo alza. Le classi di questa libreria quindi estendono le funzioni del comparatore generando degli eventi, a partire dai dati inviati dal tracker, che possono essere utilizzati nelle applicazioni interattive. Dunque capire il funzionamento di questa libreria, per poi sfruttarne le sue capacità, è stato un punto fondamentale di questa tesi, poichè non c‟era nessuna documentazione formale relativa al suo funzionamento, alle sue proprietà ed ai suoi metodi. Questo studio si può trovare nella sezione 2.2. Una volta che sono state ricavate informazioni più dettagliate sulle azioni dell‟utente è possibile utilizzarle nelle applicazioni touchscreen. Queste applicazioni, che costituiscono l‟attuatore del sistema, prendono i dati inviati dal comparatore e li elaborano in modo tale da reagire in maniera logica alle azioni fatti dall‟utente. Le informazioni degli eventi inviati dalla libreria touchlib si possono utilizzare con il programma Adobe Flash. Questo programma utilizza degli elementi, i componenti, per sviluppare applicazioni in un modo modulare e più veloce. Utilizzare i componenti, quindi, offre un risparmio di tempo e di logica di programmazione, e le ragioni di ciò sono descritte in dettaglio nel capitolo 3. Tuttavia questi componenti non possono essere utilizzati per lo sviluppo di applicazioni touchscreen perché non sono in grado di elaborare le informazioni a esse relative. Perciò capire il processo che porta alla loro creazione per poi sviluppare dei componenti che siano in grado di reagire alle azioni dell‟utente è fondamentale per poter sfruttare i vantaggi che i componenti offrono. Dunque lo sviluppo di alcuni componenti di Flash che possano essere implementati in interfacce touchscreen è stato uno degli scopi di questa tesi. Oltre ad interagire con i componenti l‟utente può avere la possibilità di realizzare dei movimenti che possono essere interpretati come delle azioni specifiche a cui deve reagire l‟applicazione. Questi tipi di movimenti sono i gesti e, ora come ora, li si può trovare su molti dispositivi touchscreen, come per esempio l‟Iphone. La descrizione dei gesti e delle loro caratteristiche viene fatta nel capitolo 4. Grazie all‟uso comune dei dispositivi touchscreen è possibile parlare ora di alcuni gesti standard, come per esempio „drag‟, „rotate‟, „scale/zoom‟, i quali vengono applicati a un elemento presente nello schermo. Però è anche possibile parlare di gesti che non hanno una definizione univoca: un cerchio, oppure un‟onda, possono far partire delle azioni specifiche a seconda dell‟applicazione. Individuare quando un gesto è stato fatto è compito del comparatore, ma fino ad ora esso è stato unicamente in grado di rilevare degli eventi semplici. Perciò un‟altro scopo di questa tesi è stata la creazione di classi di ActionScript che estendano le funzioni del comparatore e che possano rilevare dei gesti fatti su uno schermo touchscreen, siano gesti semplici o standard, o gesti complessi che non hanno una definizione specifica. Questo porterà ad avere ancora più scelta nel modo di interazione dell‟utente con l‟interfacca touchscreen. 3 Introduzione Nell‟ambito di questa tesi si vogliono creare degli strumenti che servano come base per lo sviluppo delle applicazioni con componenti con cui l‟utente possa interagire, e che siano in grado di reagire agli eventi semplici ed ai gesti. Inoltre grazie alle caratteristiche dello schermo con tecnologia ottica, che è in grado di rilevare contemporaneamente più di un blob, questi strumenti diventano anche una base per lo sviluppo d‟interfacce interattive multitouch. 4 Capitolo 1 TECNOLOGIA MULTITOUCH 1.1 La storia La tecnologia tattile è nata molto prima dell‟esistenza dei computer. I primi dispositivi tattili sono stati elaborati da Hugh LeCain e Bob Moog, nella seconda metà degli anni „40 4. Il suo lavoro è stato basato sui sintetizzatori e sull‟uso di condensatori sensibili al tatto che, variando la loro tensione, permettevano di controllare il suono prodotto dallo strumento. Successivamente lo studio e lo sviluppo di alcuni schermi tattili sono stati fatti dall‟IBM e dalla CERN (l‟Organizzazione Europea per la Ricerca Nucleare), la quale ha implementato dei schermi che lavoravano con la capacità dei condensatori, studio basato sul lavoro di Ben Stumpe5. Contemporaneamente, la compagnia Elographics lavora su schermi di tipo resistivo, e nel anno 1977 fa un brevetto per la tecnologia che aveva sviluppata 6. Dopo di che, nell‟anno 1982, Nimish Mehta, dell‟università di Toronto, ha sviluppato un‟interfaccia multitouch per la sua tesi di grado7. Mentre che la compagnia Hewlett-Packard, nell‟anno 1983, costruisce il HP-150, che funzionava con tecnologia ottica: degli emettitori e rilevatori di luce infrarossa disposti nel bordo dello schermo che servivano per rilevare gli oggetti che si avvicinavano allo schermo.8 Altri studi sono stati eseguiti da diverse persone e aziende, questa volta cercando d‟implementare il touchscreen sui cellulari, come per esempio il cellulare „Simon‟9 prodotto dalla IBM e Bell South nell‟anno 1994, oppure l‟onyx della compagnia 4 Hugh LeCain “ELECTRONIC SACKBUT” <http://www.hughlecaine.com/en/sackbut.html> CERN, “The first capacitative touch screens at CERN” <http://cerncourier.com/cws/article/cern/42092> 6 Saffer, D. “Designing Gestural Interfaces” Pg.7 7 Idem. Pg 8. 8 Idem Pg. 9. 9 Idem Pg. 10. 5 5 Capitolo 1 – Tecnologia Multitouch Synaptics10. Però è stata finalmente la Apple con i suoi prodotti: l‟iPod nel 2007 (modello multitouch)11, e l‟iPhone nel 200712, a rendere questo tipo di tecnologia popolare e d‟uso comune. 1.2 Parti basici di un sistema Touchscreen Sia che si sta lavorando con un sistema di tocchi semplici oppure con un sistema multitouch, ci devono essere un numero minimo di componenti basici per il suo corretto funzionamento. Ogni sistema di questo tipo deve essere composto di tre parti: un sensore, un comparatore ed un attuatore. Nella Figura 1 è possibile vedere com‟è il funzionamento generali ed il rapporto esistente tra questi tre parti. Il diagramma è stato presso dal libro di Saffer, “Designing gestural interfaces”. Figura 1.Funzionamento e le parti basici di un sistema touchscreen (tocco semplice oppure multitouch.) Un sensore è un dispositivo elettronico o elettrico che è in grado di rilevare dei cambiamenti che possono essere interni del sistema oppure esterni dell‟ambiente che lo circonda13, e dipendendo del tipo di gesto che si vuole rilevare, esistono diversi tipi di sensori: di luce, di pressione, di prossimità, acustici, di movimento, ecc. Quindi la scelta di utilizzarne uno e non un‟altro è di molta importanza poichè il tipo di sensore determina il tipo di gesti che si possono utilizzare con il sistema: se il sensore non è in grado di rilevare un gesto sarebbe come se l‟utente non avessi fatto nessuna azione. Da un‟altra parte, il comparatore è la parte del sistema che riceve l‟informazione dal sensore per elaborarla. Si occupa di comparare lo stato attuale sia conuno stato precedente oppure con uno stato „scopo‟ del sistema per fare un giudizio ed individuare l‟esistenza di un gesto. Per ultimo si trova l‟attuatore il quale si occupa di realizzare un‟azione oppure un comando d‟accordo al 10 Synaptics <http://www.synaptics.com/about/press/press-releases/synaptics-and-pilotfish-collaboratedevelop-next-generation-mobile-phone-> 11 Apple “Apple Unveils iPod touch” <http://www.apple.com/pr/library/2007/09/05touch.html> 12 Apple “Apple Reinvents the Phone with iPhone” <http://www.apple.com/pr/library/2007/01/09iphone.html> 13 Saffer, D. “Designing Gestural Interfaces” pg.13 6 Capitolo 1 – Tecnologia Multitouch giudizio fatto dal comparatore. Quindi l‟attuatore può essere per esempio il software che decide che azione fare, una volta il comparatore ha individuato un gesto A continuazione si farà una breve descrizione delle diverse tecniche per la costruizione alcuni tipi di sensori. Queste la sua descrizione è importante perchè permette di capire le prestazioni del tipo di sensore, di cos‟è capace di individuare e quindi di sapere com‟è possibile utilizzarne. 1.3 Descrizione delle diverse tecniche per la costruzione dei dispositivi ottici Le tecniche descritte qui di seguito si utilizzano per la costruzione di schermi tattili di tipo ottico. L‟hardware che verrà descritto in questa sezione è quello utilizzato da parte della NUI-group, che vuole sopratutto creare sistemi open-source a basso costo. Queste tecnologie hanno una caratteristica in comune che è l‟utilizzo della luce infrarossa, sebbene esistano altri tipi di tecnologie, scegliere d‟implementare queste tecniche risulta meno costoso che implementare gli altri tecnologie (Resistive, Capacitive, ecc.). In seguito si fa una descrizione delle tecnologie ottiche. L‟ultima tecnica descritta , l‟illuminazione diffusa superficiale, è quella utilizzata nell‟ambito di questa tesi. 1.3.1 Tecnologia ottica – L‟uso della luce infrarossa La tecnologia ottica è basata sull‟utilizzo di dispositivi che siano in grado di rilevare dei cambiamenti sullo schermo del computer. Questi fanno uso di sensori che sono in grado di rilevare la presenza di sorgenti di luce. Un tipo di sensore di questo tipo è la video camera. In questo caso le informazioni che si devono elaborare sono le immagini rilevate dalla camera. Di solito questi tipi di dispositivi basati sulle tecniche ottiche sono più graditi dalle altre tecniche perchè sono scalabili, di basso costo e di bassa difficoltà per la sua costruzione. Le tecniche ottiche sono sistemi composti da un sensore ottico, i.e. la video camera, una sorgente di luce infrarossa e un feedback visivo. L‟uso della lunghezza d‟onda della luce infrarossa è una ottima scelta innanzitutto per il fatto che, non facendo parte dello spettro di luce visibile, e poiché molti sensori delle camere sono sensibili a questa lunghezza d‟onda, ciò permette di rilevare unicamente alcuni tipi di dati specifici. Infatti solitamente le telecamere hanno un filtro che non permette di far passare le lunghezze d‟onda infrarossa, togliendo però questo filtro, ed aggiungendo invece un‟altro che tolga lo spettro visibile, si ottiene che la video camera rilevi unicamente la luce infrarossa, è quindi possibile sfruttare questa caratteristica per il tracking dei tocchi e degli oggetti sulla superficie. La luce infrarossa permette di fare una distinzione tra l‟immagine visuale, gli oggetti o le dita che vengono rilevate dalla superficie. Sebbene lo schermo sia utilizzato sia per il 7 Capitolo 1 – Tecnologia Multitouch feedback visuale che come dispositivo d‟interazione per l‟utente, è importante che la video camera non catturi l‟immagine proiettata al momento di fare il tracking degli oggetti, ed è questa la ragione per cui viene inserito un filtro per la luce visibile. Togliendo dall‟immagine queste lunghezze d‟onda, gli unici oggetti che sono rilevati dalla video camera sono gli oggetti e le dita che vengono illuminati con la luce infrarossa. Tra la moltitudine di tecniche ottiche esistenti quella a LED Infrarossi è la maggiormente utilizzata. Anche se i LED-IR non sono l‟unica sorgente possibile di luce IR, esistono altri tipi di sorgenti come i Laser IR i quali sono più efficienti ed efficaci nel fornire questo spettro di luce. La scelta del tipo di LED da utilizzare dipende dalla tecnica che si vuole implementare, perciò è importante capire se le caratteristiche dei LED sono adeguate alla tecnica utilizzata: - La lunghezza d‟onda della luce emessa di solito si trova nello spettro IR che le camere possono vedere, ma più è bassa la lunghezza maggiore sarà la sensibilità14. - E‟ preferibile che l‟intensità di radiazione sia la più alta possibile. - E‟ preferibile che l‟angolo d‟illuminazione sia il più ampio possibile, così che si riesca a ottenere un‟illuminazione uniforme su tutti i punti della superficie, evitando in questo modo delle regioni con concentrazione di luce maggiore, note come hotspots. Gli hotspots, sono quindi delle regione di concentrazione di luce che rappresentano un problema poichè potrebbero portare ad un rilevamento di falsi blob sulla superficie. Per evitarli di solito si utilizzano dei filtri passa-banda che si aggiungono alla video camera. Infatti, le caratteristiche del dispositivo da soli possono condizionare significativamente il tracking. Alcune di queste caratteristiche sono elencate in seguito: 14 - La risoluzione della video camera agisce direttamente sulla precisione del rilevamento dei blob. Più pixel ci sono per immagine più accurato sarà il tracking, pertanto dipendendo ciò dalle dimensioni della superficie, bisogna capire quale sarà la risoluzione adeguata della video camera, così da ottenere la precisione desiderata. - Il frame rate influisce sulla quantità d‟informazioni disponibili per unità di tempo, fatto che diviene importante quando è necessario rilevare spostamenti veloci degli oggetti o le dita sulla superficie. Dunque un frame rate alto è più indicato. MultiTouch Technologies – Infrared Light Sources. 8 Capitolo 1 – Tecnologia Multitouch - La velocità con cui i dati vengono inviati al computer dalla video camera dipende dal tipo d‟interfaccia utilizzata. La più economica è l‟interfaccia USB ma, poichè dipende delle esigenze del sistema, si può optare per un‟interfaccia più veloce come la IEEE 1394 (FireWire). Avendo finora fatto una descrizione generale delle caratteristiche che si devono tenere in conto nei sistemi ottici, si andrà di seguito a elencare una breve descrizione delle diverse tecniche ottiche esistenti. 1.3.1.1 FTIR (Frustated total internal reflection) Questa tecnica è stata sviluppata per Jeff Han nel 200515 e si basa sull‟uso del fenomeno della riflessione totale interna: quando un raggio di luce passa attraverso mezzi con un indice di rifrazione diverso, il raggio viene deviato. L‟angolo di deviazioni dipende sia dagli indici di rifrazioni dei due mezzi che dall‟angolo d‟incidenza del raggio. Esiste un angolo d‟incidenza, noto come angolo critico, per cui il raggio di luce non attraversa più il secondo mezzo ma viene riflesso, e questo comportamento, noto come riflessione interna totale, si ripete per qualunque angolo d‟incidenza maggiore all‟angolo critico16. Figura 2. Principi di funzionamento generale di FTIR Questo fenomeno viene utilizzato per racchiudere la luce infrarossa emessa dai LED IR all‟interno di un pezzo di materiale acrilico, utilizzato come superficie di contatto. Nel momento in cui l‟utente tocca la superficie, i raggi di luce IR in quel punto sono deviati 15 “Multitouch Technologies” NUI Group Authors Total Internal reflection and lenses – Physics Department, Boston University <http://physics.bu.edu/~duffy/py106/Lenses.html> 16 9 Capitolo 1 – Tecnologia Multitouch verso il basso, attraversando la superficie acrilica, e venendo quindi catturati dalla video camera. Nella Figura 2 s‟illustra uno schema generale del funzionamento della tecnica. 1.3.1.2 Diffused Illumination (DI) Questa tecnica ha due modi diversi d‟applicazione, ed entrambi usano lo stesso principio: il contrasto tra un‟immagine base e l‟oggetto che entra in contatto con la superficie. Il primo modo di applicare la tecnica porta il nome di Front Diffused Illumination. Lo schermo viene illuminato dall‟ambiente con luce visibile e un diffusore è allocato sia nella parte superiore che in quella inferiore della superficie. Nell‟istante in cui l‟utente appoggia il dito sulla superficie si crea un‟ombra nella posizione di contatto che viene rilevata dalla video camera. Il secondo modo, noto come Rear Diffused Illumination, ha un montaggio un po‟ più complesso. Innanzitutto la superficie deve essere illuminata uniformemente con luce IR dalla parte posteriore dello schermo, ma illuminando di questo modo è però inevitabile l‟esistenza di regioni più scure, non illuminate bene, dove non sarà facile poi individuare i tocchi. Per correggere quest‟ errore si può provare modificare la parte hardware ridistribuendo in un maniera migliore la luce sulla superficie, questo si può fare sia utilizzando un diffusore di luce che modificando la posizione delle sorgente di luce IR, oppure si possono applicare dei filtri a livello software che agiscono soltanto sulle regioni dell‟immagine dove si trovano le zone più scure. Figura 3. Schema di funzionamento della tecnica Rear DI 10 Capitolo 1 – Tecnologia Multitouch Dopo di ché quando l‟utente tocca lo schermo, la luce in quel punto riflette maggiormente rispetto al resto dello schermo, ed i raggi di luce che vengono deviati sono catturati dalla video camera. Con questa tecnica, e grazie al diffusore, è possibile individuare perfino oggetti che sono sospesi sopra la superficie. Lo schema di funzionamento di questa tecnica viene illustrata nella Figura 3. 1.3.1.3 LLP (Laser Light Plane) In questa tecnica, alcuni laser di luce infrarossa sono messi in modo tale da illuminare solo sopra la superficie dello schermo, creando un piano con uno spessore di circa 1mm. In seguito, quando l‟utente prova a toccare lo schermo, tocca anche il piano di luce IR e in tal maniera viene individuato il blob (Figura 4). Figura 4. Principio di funzionamento del Laser Light Plane 1.3.1.4 LED-LP (LED- Light Plane) Il montaggio per questa tecnica è molto simile a quello di LLP eccetto per il fatto che, invece di utilizzare luce IR emessa da un laser, si usano dei LED. I LED vengono così disposti lungo il perimetro dello schermo dando luogo ad un piano di luce uniforme. Nonostante il piano sia uniforme, il cono di luce emesso dai LED illumina oggetti che sono vicini alla superficie che però non l‟hanno ancora raggiunta, rilevandoli così in anticipo sul tocco. Questo problema si può correggere con l‟utilizzo di un filtro, che è necessario tarare adeguatamente, scegliendo le soglie giuste per rilevare gli oggetti unicamente quando sono veramente vicini alla superficie, tanto da potere considerare l‟evento come un tocco. Si può anche correggere a livello meccanico con l‟utilizzo di un schermo paraluce che non 11 Capitolo 1 – Tecnologia Multitouch permetta che i raggi luminosi vengano emessi al di sopra del piano orizzontale, come si può vedere nella Figura 5. Figura 5. Schema per la tecnica LED-LP 1.3.1.5 DSI (Diffused Surface Illumination) Questa tecnica utilizza un principio simile alla FTIR ma ha bisogno per il suo montaggio di un tipo di materiale acrilico speciale - Plexiglass endlighten-. Questo materiale acrilico ha al suo interno piccole particelle che funzionano come specchi, e quando la luce IR viene emessa dal perimetro dello schermo, ridireziona i raggi verso la superficie dello schermo, ottenendo un effetto simile alla tecnica DI, con un‟illuminazione uniforme e senza hotspots (Figura 6). Figura 6. Principi di funzionamento DSI 12 Capitolo 1 – Tecnologia Multitouch 1.4 Descrizione Generale del Sistema Come già affermato il sistema è diviso in due parti, una hardware e una software, e ogni parte è ulteriormente divisa in altre due parti (Figura 7). La parte hardware ha due dispositivi principali, uno è lo schermo dove l‟utente può „toccare‟ gli oggetti visualizzati in cui è stata implementata la tecnica DSI, mentre l‟altra è la video camera infrarossa messa dietro allo schermo, che rileva l‟immagine, insieme compongono quello che sarebbe il sensore del sistema touchscreen. Dopo di che le immagini si passano al comparatore, che in questo sistema è un software che è stato elaborato dalla Nui-Group. Nell‟ambito di questa tesi si è deciso di approfondire maggiormente la parte software rispetto a quella hardware, che qui di seguito si va a illustrare, descrivendone il funzionamento e gli elementi compositivi b) c) d) a) Figura 7. Schema illustrativo del sistema generale. (a) L‟hardware composto dallo (a) schermo e dalla (b) video camera, ed il sofware composto (c) dal tracker, CCV, che invia i messaggi al programma (d) Flash. 1.4.1 CCV – Il Tracker Il comparatore entra in funzione quando le immagini ricavate dalla video camera passano al software e il primo programma, il Community Core Vision (CCV), analizza le immagini per individuare e calcolare le coordinate di ogni blob. Per fare ciò l‟immagine viene elaborata con diversi filtri, che possono essere modificati per mezzo dell‟interfaccia utente (Figura 8). I programmi che fanno questa individuazione, di solito noti come tracker, possono utilizzare diversi metodi oltre a quello ottico del CCV. Il programma analizza frame per frame l‟allocazione di ogni blob e assegna a ciascuno di loro un identificativo, tenendo sempre in considerazione di far corrispondere correttamente ogni blob da un frame all‟altro, questa azione è nota come blob tracking. In seguito il tracker deve rilevare delle informazioni relative ad ogni blob (coordinate, velocità, ecc.), le quali sono compatibili con 13 Capitolo 1 – Tecnologia Multitouch la specifica di un protocollo, noto come TUIO poichè è stato il gruppo dello stesso nombre a fare la specifica. Questo protocollo è utilizzato nella costruzione d‟interfacce utente per applicazioni multitouch. (La descrizione di questo protocollo si fa nel capitolo 2) Dopo di che tutte le informazioni ricavate per ogni blob vengono messi insieme in un messaggio ed inviate al attuatore del sistema. La struttura del messaggio è anch‟essa specificata dal protocollo TUIO. Tutte queste informazioni sono necessarie affinché l‟applicazione possa sapere la precisa collocazione dei blob sulla superficie e quale sono le sue proprietà (come ad esempio la velocità, l‟ID che gli è stato assegnato, ecc…) e così reagire adeguatamente agli input ricevuti ed eseguire i comandi che l‟utente richiede all‟interno dell‟applicazione. Figura 8. Interfaccia del software CCV – il tracker del sistema Nella Figura 8 si può vedere l‟interfaccia del programma tracker. Nella parte centrale si trovano sia l‟immagine ricavata dalla video camera, detta nome „source’, sia l‟immagine elaborata con i blob identificati e gli identificativi assegnati, detta nome „tracked’. Nella parte bassa si trovano quatro immagini di dimensione minore: la prima a sinistra, nota con il nome „background‟, è l‟immagine che viene utilizzata dal software come sfondo o immagine base e rappresenta il display quando non c‟è nessuna attività sullo schermo. Poi quando lo schermo è toccato, i punti di contatto vengono più illuminati e quindi se l‟immagine di background si sostrae dall‟immagine nuova , viene rilevata una differenza nei punti di contatto. Questo processo si ripete per ogni frame rilevato dalla video camera rilevando cosi i blob per ciascuno dei frame. Le altre tre immagini che si trovano in basso, sono filtri che si possono attivare o rimanere inattivi a seconda della necessità: il primo filtro è per smussare l‟immagine, il secondo è un filtro passa-alto, ed il terzo è un 14 Capitolo 1 – Tecnologia Multitouch amplificatore che serve per amplificare l‟immagine che è stata elaborata con gli altri due filtri. Nella parte destra dell‟interfaccia si trovano alcuni parametri del programma. Con questi parametri è possibile cambiare alcune caratteristiche delle immagini rilevate per la video camera, modificare il metodo in cui vengono inviati i messaggi ed alcune impostazioni proprie del programma. Prima di utilizzare il tracker è importante calibrarlo adeguatamente con le dimensioni dello schermo usato per fare sì che le coordinate rilevate dal tracker siano quelle giuste. Dopo di che si fanno tutti i calcoli necessari per trovare tutte le informazioni rispettive d‟ogni blob rilevato e si codificano in messaggi per inviarli all‟applicazione client, che fa di attuatore, che in questo caso è un‟applicazione eseguita con flash. Di seguito si va ad illustrare le caratteristiche ed i vantaggi che offre il programma flash nel momento di sviluppare applicazioni interattive. 1.4.2 FLASH – Uno strumento per applicazioni Interattive La versione del programma che è stata utilizzata è la versione Flash CS3 Professional. Il pogramma è stato usato innanzitutto per la realizzazione di applicazioni web, ed il suo ampio uso è dovuto a diverse ragioni principalmente perchè tanti browser sono compatibili con l‟utilizzo del Flash Player (Tabella 1.) che è un plug-in per i browser che permette di visualizzare le applicazioni sviluppate con Flash. Attualmente molte di queste applicazioni si conoscono come RIA (Rich Internet application) che sono applicazioni che contengono alcune delle caratteristiche di quelle del desktop e che permettono una maggior interazione con l‟utente rispetto a quelle che si trovavano precedentemente reperibili sul web. Platform Browser Player version Windows Internet Explorer (ed altri browser che supportano i controlli ed i 10.1.85.3 plug-ins di Internet Explorer ActiveX) Windows Firefox, Mozilla, Netscape, Opera ( ed altri browser basati 10.1.85.3 sull‟utilizzo di plug-ins) Macintosh OS X Linux Solaris 17 - Firefox, Opera, Safari 10.1.85.3 Mozilla, Firefox, SeaMonkey 10.1.85.3 Mozilla 10.1.85.3 Tabella 1. Compatibilità di Flash player con diversi sistemi operativi e browser17 Tabella presa dal sito di Adobe - <http://www.adobe.com/software/flash/about/> 15 Capitolo 1 – Tecnologia Multitouch Flash permette di eseguire applicazioni per mezzo dell‟utilizzo di alcuni componenti utilizzati per realizzare funzioni specifiche, e che hanno già al loro interno tutta la logica di programmazione necessaria per il loro funzionamento, ne sono un semplice esempio un pulsante oppure un checkbox. Questo implica innanzitutto un risparmio di tempo per lo sviluppatore di applicazioni, che quindi può dedicarsi a programmare le altre parti che compongono il programma. I componenti diventano così uno strumento molto utile per la realizzazione di qualunque tipo di applicazione. Attualmente lo sviluppo di applicazioni interattive è divenuto mano a mano sempre più importante, sopratutto nell‟ambito delle applicazioni multitouch, le quali implicitamente comportano un‟interazione con l‟utente. La creazione di queste applicazioni sarebbe eseguibile attraverso flash con l‟uso di componenti appositi, ma attualmente non esistono dei componenti di Flash per applicazioni multitouch, ed è questa la principale ragione per cui c‟è l‟interesse di sviluppare questi tipi di componenti. Per farli, bisogna programmarli con il linguaggio ActionScript, che ha avuto diverse versioni e ad oggi è reperibile nella versione 3.0. Per fare ciò, si utilizzerà il modello di programazione basato sugli EVENTS di Flash, che è ideale per l‟interazione con l‟utente poiché permette di capire quando l‟utente ha fatto un‟azione e dunque poter reagire ad essa. Per questi tipi di applicazioni esistono eventi standard che vengono generati come risposta ad alcune singole azioni dell‟utente. Queste azioni o gesti, possono essere scomposti in singole fasi oppure in azioni istantanee, le quali vengono interpretate come singoli eventi all‟interno del programma. Ad esempio questi eventi possono descrivere: l‟appoggiare il dito sullo schermo, l‟alzarlo, oppure il far scorrere il dito sul display. È anche possibile generare eventi che descrivano un gesto, come per esempio il semplice toccare lo schermo, che in realtà è composto da una serie di più eventi consequenziali (l‟azione di appoggiare il dito alla quale segue quella di alzarlo); ciò comporta l‟utilizzo di una logica di programmazione più complessa che sia in grado di interpretare la sequenza di singoli eventi. Il programma Flash in questo ambito, attraverso Actionscript, permette la creazione di classi apposite che definiscono gli eventi semplici oppure dei gesti. Quindi un vantaggio di Flash è che usa il modello di eventi per poter reagire alle azioni dell‟utente e si sa che l‟uso di componenti appositi per le applicazioni interattivi anche sarebbero molti graditi per fare questo compito. Ma per poter svilupparli, bisogna prima riuscire a rilevare l‟informazione individuata dal tracker, ed questo è possibile con la libreria touchlib ed il protocollo TUIO che si illustra nel capitolo 2. 16 Capitolo 2 TUIO TUIO è un framework che mira a di standardizzare e definire un protocollo per superfici tattili. Questo protocollo cerca di codificare l‟informazione rilevata dal tracker, per poi poterla inviare all‟applicazione che la richiede. Attualmente esistono sia diversi programmi tracker, un esempio è CCV, che librerie di programmazione per diversi linguaggi, le quali riescono a decodificare l‟informazione inviata nel protocollo TUIO. Una di queste librerie, Touchlib, verrà analizzata nello specifico più avanti. Le librerie vengono utilizzate nelle applicazioni per interpretare l‟informazione inviata nel messaggio TUIO e così reagire alle azioni dell‟utente. Tutte le informazioni riguardanti questo standard si possono reperire dal sito della comunità Tuio18. 2.1 Specifica del protocollo TUIO 1.1 Il protocollo stabilisce un‟interfaccia di comunicazione tra i dispositivi fisici e le applicazioni. Gli oggetti che vengono rintracciati sullo schermo possono essere classificati in tre diversi profili, ognuno dei quali contiene delle informazioni base comuni a tutti i tre, alle quali si aggiunge per ciascun profilo un‟informazione addizionale necessaria per la sua descrizione. Il profilo tipo Object viene identificato con un ID, con la sua locazione e infine con il suo orientamento sulla superficie; il profilo tipo Cursor, che di solito rappresenta i tocchi con le dita, questo non è identificato da un ID univoco e non ha neanche informazioni sull‟orientamento; il profilo di tipo Blob, che contiene l‟informazione per descrivere l‟estensione approssimata di alcuni oggetti non etichettati, ovvero regioni toccabili (touch region), con un riquadro di delimitazione (bounding box), che è rappresentato per l‟approssimazione ellittica, compreso l‟angolo e l‟area. (Una descrizione più dettagliata dei profili verrà fatta più avanti). Il protocollo TUIO è stato codificato utilizzando il formato OSC (Open Sound Control), il quale permette di codificare in linguaggio binario e in un modo efficiente l‟informazione. Utilizzare questo formato permette anche di trasmettere i messaggi TUIO su qualunque canale che supporti l‟implementazione di OSC. Il metodo scelto è quello di incapsulare 18 TUIO website - <http://www.tuio.org> 17 Capitolo 2 – TUIO l‟informazione OSC dentro un pacchetto UDP che si invia al <port> 3333, per default. E‟ inoltre possibile inviare l‟informazione in pacchetti TCP, a seconda della necessità e delle condizioni del canale di trasmissione. 2.1.1 Implementazione, efficienza ed affidabilità del protocollo Il protocollo TUIO definisce quattro tipi di messaggi che contengono diverse informazioni: I messaggi tipo SET contengono l‟informazione sullo stato dell‟oggetto (come la posizione, l‟orientazione e altre), invece i messaggi tipo ALIVE contengono l‟elenco degli ID di sessione dell‟insieme di oggetti presenti sulla superficie. Per sapere se un oggetto è ancora presente sulla superficie, si verifica la continuità tra un messaggio e l‟altro. Ci sono anche i messaggi tipo FSEQ che etichettano in modo unico ogni passo di aggiornamento con un ID di sequenza di frame. Facoltativamente è possibile inserire un messaggio tipo SOURCE che identifica la sorgente TUIO permettendo il multiplexing di sorgente dalla parte del client. L‟utilizzo del protocollo UDP permette una latenza bassa nel trasporto dell‟informazione. Tuttavia, con l‟utilizzo di questo protocollo esiste la possibilità di perdita dei pacchetti di informazione, perciò l‟implementazione del protocollo TUIO include informazioni ridondanti, prevedendo la perdita dei dati. L‟utilizzo del protocollo TCP fa più affidabile la trasmissione però aumenta il tempo di latenza. Per ragioni di efficienza i messaggi tipo SET sono raggruppati per l‟utilizzo dello spazio in pacchetti tipo UDP. Ogni gruppo include anche un messaggio di tipo ALIVE che preserva dalla perdita dei dati. Per un insieme più grande di oggetti, viene trasmesso un gruppo di messaggi SET, ed un messaggio ALIVE. Quando non c‟è attività sulla superficie, i messaggi ALIVE vengono inviati ad una frequenza dipendente dalla qualità del canale, così da assicurarsi che il ricevitore ottenga le informazioni sufficienti sugli oggetti che ci sono ancora sulla superficie. Successivamente le informazioni di ogni oggetto ancora presente sullo schermo che non sia cambiato viene inviato attraverso diversi messaggi SET, che contengono la stessa informazione (informazione ridondante), ma ad una frequenza minore e che comprende soltanto un sotto insieme degli oggetti che non sono cambiati ad ogni aggiornamento. Questo si fa per poter tenere aggiornata le informazioni di ogni blob, anche se la sua posizione non sia cambiata. Ad ogni pacchetto viene assegnato un ID della sequenza del frame (fseq): un numero che si incrementa ed è uguale per tutti i pacchetti che contengono le informazioni acquisite allo stesso tempo. Questo permette all‟applicazione client di avere un maggior controllo dei dati dovuto al fatto che se i pacchetti arrivano in disordine, il cliente volendo può identificare ovvero lasciarli perdere. 18 Capitolo 2 – TUIO Figura 9. Composizione dei pacchetti di messaggi per due blob trovati sullo schermo Per ogni pacchetto di messaggi UDP, quindi, bisogna come minimo inviare un messaggio tipo ALIVE ed uno FSEQ, che delimitano il gruppo. Per ognuna di queste fasce si aumenta l‟ID del FSEQ, mentre per i messaggi ridondanti l‟ID di sequenza viene assegnato il valore -1. 19 Capitolo 2 – TUIO 2.1.2 Profili ed i suoi attributi TUIO prevede tre tipi di profili: cursor, object e blob. Se questi profili non servono, è possibile avere un profilo personalizzabile in cui si permette l‟invio di parametri definiti dall‟utente. I parametri inviati per ogni profilo per una superficie 2D si possono vedere nella Tabella 2. s i x, y a w, h f X, Y A m r Attributi ID sessione ID classe Posizione Angolo Dimensioni Area Vettori di velocità Vettore velocità di rotazione Accelerazione Accelerazione di rotazione Object X X X X Cursor X Blob X X X X X X X X X X X X X X X X Tabella 2. Parametri per i diversi profili TUIO Il parametro s, ID di sessione, è un identificatore che viene assegnato ad ogni object, cursor o blob, questo rimane lo stesso durante la sessione. Anche se l‟ID di sessione è unico per ogni profilo, l‟utilizzo dello stesso ID fa referenza alla stessa istanza. Questo permette di utilizzare un profilo che contiene più informazioni, come il profilo blob, per l‟invio di dati addizionali per altri tipi di istanze per le quali i profili object o cursor risultano essere sufficienti. Il profilo blob, serve a descrivere la geometria dell‟istanza rilevata. I messaggi di questo profilo contengono la descrizione dell‟ellisse interna del riquadro di delimitazione, il punto centrale, l‟angolo dell‟asse maggiore, le due dimensioni e l‟area (Figura 10.), la quale viene normalizzata in pixel/larghezza*lunghezza. Anche la lunghezza e la larghezza del blob sono normalizzati. 20 Capitolo 2 – TUIO Figura 10. Rappresentazione grafica del riquadro di delimitazione e l‟ellisse interna calcolato per un blob 19 2.2 Touchlib Touchlib è una libreria di programmazione in linguaggio ActionScript 3.0, che gestisce il tracking dei blob per poi inviare una notifica degli eventi alle applicazioni. Questa libreria ha un‟interfaccia che può stabilire una comunicazione con diversi tipi di webcam e di dispositivi di cattura del video, e per fare ciò utilizza un pacchetto di classi noto come le classi TUIO. Queste gestiscono gli oggetti rilevati, la generazione degli eventi e la decodifica dei messaggi inviati dal software CCV, i quali contengono l‟informazione in formato TUIO. In totale ci sono 4 classi diverse e queste sono state studiate per capire il loro funzionamento e sfruttare così al meglio le loro prestazioni. Le quattro classi sono: TUIO, TUIOCursor, TUIOEvent e TUIOObject. In questa sezione viene fatta una breve descrizione delle funzione e delle caratteristiche più importanti di ogni classe, inoltre una descrizione più completa di queste si può trovare nell‟allegato A. 2.2.1 Classe TUIO Questa tra tutte e quattro è la classe più importante. La prima funzione che viene chiamata esegue il collegamento con il „server‟, che in questo caso è il software CCV; questo invia i messaggi ed inizializza anche alcune variabili di cui necessita per il suo funzionamento. Tra le variabili che contiene, si trova un vettore in cui vengono inserite le istanze della classe TUIOObject, le quali a loro volta contengono ciascuna le informazioni dei blob rilevati dal tracker. Questi dati vengono trasmessi attraverso messaggi inviati dal software CCV, e vengono poi ricavati attraverso una funzione interna della classe. La classe implementa diversi metodi che sono necessari per la gestione sia degli oggetti 19 Presa dal sito di TUIO - <http://www.tuio.org/?tuio11> 21 Capitolo 2 – TUIO TUIO che delle informazioni inviate attraverso i messaggi, inoltre sono necessari per restituire istanze che contengono l‟informazione dell‟oggetto TUIO, e per la gestione delle notifiche degli eventi TUIO ( può avvenire che la classe stessa faccia direttamente la notifica, oppure se sono necessari prima dei calcoli particolari si possono interpellare altri metodi che s‟incaricano di eseguirli e di emettere in seguito la notifica dell‟evento rispettivo). Segue qui un elenco dei metodi principali con una breve descrizione delle loro funzioni principali: - init(): Esegue il collegamento con il server ed inizializza le variabili della classe. - processMessage(): Riceve i messaggi inviati dal tracker e vi ricava i dati. Fa uso dei messaggi tipo ALIVE per aggiornare gli oggetti TUIO dentro l‟array. Se nel messaggio non viene trovato più l‟id di un oggetto ciò significa che questo non è più attivo sullo schermo, se invece nel messaggio individua un‟id che precedentemente non era presente genera un TUIOObject e lo aggiunge nell‟array. - getObjectById(): Questa funzione riceve come parametro l‟id di un oggetto TUIO e restituisce l‟oggetto a cui è stato assegnato questo id. - listenForObject(): Riceve due parametri: l‟id ed un oggetto, al quale ne aggiunge un secondo in un array d‟istanze; e queste sono pronte a ricevere la notifica degli eventi inerenti ad ogni oggetto TUIO. Ci sono altri metodi che si occupano della gestione degli eventi e di controllare la corretta comunicazione tra tutti i metodi delle altre classi. 2.2.2 Classe TUIOCursor Soltanto questa classe crea un oggetto di tipo Sprite che viene poi inserito sul display dell‟applicazione e va a indicare dov‟è stato rilevato il tocco. Le istanze di questa classe vengono create nel medesimo momento in cui si creano le istanze della classe TUIOObject. Ogni cursor è quindi collegato ad un TUIOObject. 22 Capitolo 2 – TUIO Se l‟opzione di debug è stata configurata nella classe TUIO, viene anche inserito il numero ID che è stato assegnato al blob. 2.2.3 Classe TUIOEvent Questa classe estende la classe Event ed è la tipica definizione di eventi fatta per actionScript. Gli eventi definiti nella classe sono TUIO_MOVE, TUIO_DOWN, TUIO_CLICK, TUIO_UP, TUIO_OVER, TUIO_OUT. Ogni evento contiene come informazione il tipo o il nome dell‟evento, le proprietà bubbles e cancelable che devono essere definite per passare alla classe Event. Ed è la stessa classe a contenere l‟informazione della posizione dell‟evento e l‟ID del blob. Questi eventi vengono notificati nelle classi TUIO e TUIOObject nei momenti giusti, per esempio, TUIO_DOWN e TUIO_UP vengono notificati rispettivamente quando il tracker rileva un tocco e quando il tracker stabilisce che il tocco non esiste più. Questa informazione viene estratta dai messaggi inviati dal software CCV, messaggi che si ricorda vengono processati nella classe TUIO. 2.2.4 Classe TUIOObject Questa classe s‟incarica di raccogliere le informazioni inerenti agli oggetti rilevati, e le riceve dalla classe TUIO tramite i messaggi inviati dal tracker. Una volta che viene creata un‟istanza di questa classe, i dati di posizione, velocità e rotazione, assieme alle informazioni di id dell‟oggetto rilevato, vengono salvati in quest‟istanza. Dopo di che si genera un cursore con la classe TUIOCursor a cui si assegnano le stesse coordinate dell‟oggetto. Questa classe che fa anche la notifica dell‟evento TUIO_DOWN, che si fa nel momento che si rileva un oggetto sullo schermo; in seguito bisogna utilizzare dei metodi che permettono agli oggetti di ricevere la notifica degli eventi TUIO. Questi metodi possono essere sia il metodo listenForObject() della classe TUIO, che il metodo addListener() di questa classe, i quali aggiungono all‟interno dell‟array di listeners dell‟istanza gli oggetti su cui l‟utente a „toccato‟. Ci sono anche un altro insieme di metodi necessari per rilevare le informazioni di ciascun TUIOObject che sia stato creato dalla classe TUIO; e questi gestiscono la notifica degli eventi TUIO_OVER, TUIO_OUT e TUIO_MOVE. Tutti questi metodi vengono interpellati dalla classe TUIO che è quella a cui concerne la gestione generale dei dati. Si elencano in seguito i metodi più importanti della classe: 23 Capitolo 2 – TUIO - TUIOObject(): Il metodo costruttore riceve i dati rilevati dal tracker di ogni blob individuato sullo schermo, e li salva sulle proprietà della classe. Ogni istanza di TUIOObject contiene i dati rispettivi ad un‟istanza con un identificativo specifico. Sempre che la classe TUIO venga inizializzata in modo debug, verrà creato un cursore con la classe TUIOCursor da collocare nella posizione dell‟oggetto TUIO. - notifyCreated(): Fa la notifica degli eventi TUIO_DOWN e TUIO_OVER. - notifyMoved(): Questo metodo viene chiamato periodicamente quando si aggiornano le coordinate dell‟oggetto TUIO. Per fare ciò invia la notifica dell‟evento TUIO_MOVE a tutti gli oggetti che si trovano all‟interno dell‟array di listeners. - setObjOver(): Questo metodo riceve un‟argomento di tipo DisplayObject. Se prima l‟oggetto TUIO non era rilevato sopra nessun‟altro display object, il valore ricevuto è inserito dentro il parametro „obj‟, e si esegue la notifica dell‟evento TUIO_OVER. Se invece il display object ricevuto è diverso da quello salvato precedentemente nel parametro „obj‟, oppure nel caso in cui non esista l‟oggetto (un valore „null‟), viene inviata la notifica dell‟evento TUIO_OUT (perchè il cursore non è più sopra l‟oggetto su cui si trovava prima). Ed infine se l‟oggetto nuovo esiste si salva nel parametro „obj‟, e si notifica TUIO_OVER per questo display object. - addListener(): - Il metodo riceve come argomento un‟oggetto Display che viene aggiunto nel array di listeners dell‟oggetto TUIO. removeListener(): Il metodo riceve come argomento un‟oggetto Display, il quale viene rimosso 24 Capitolo 2 – TUIO dall‟array di listeners dell‟oggetto TUIO - kill(): Il metodo si chiama quando l‟utente smette di toccare lo schermo ed il tracker rileva che il blob non esiste più, in questo caso bisogna rimuovere il TUIOObject ed il cursor che erano stati aggiunti nella medesima posizione. Una volta rimosso l‟oggetto TUIO, s‟invia la notifica dell‟evento TUIO_UP per ciascuno degli oggetti dentro dell‟array di listeners. Fino a questo punto si sono analizzati alcuni strumenti appositi per lo sviluppo di applicazioni e delle interfacce utente multitouch: Il tracker CCV che rileva l‟informazione, la libreria di programmazione in flash che interpreta i messaggi inviati dal tracker, ed il protocollo che stabilisce lo standard di comunicazione. Fatto ciò è ora possibile andare ad applicare le nozioni fino a qui apprese per sviluppare dei componenti appositi per applicazioni multitouch e che lavorino con gli eventi TUIO analizzati prima. 25 Capitolo 3 Componenti di FLASH Tra gli elementi che offre il programma Flash ci sono i componenti che in generale permettono di velocizzare la creazione delle applicazioni. Molte delle informazioni utilizzati per capire cose sono e per il suo sviluppo sono state reperite da un articolo di Adobe nella sezione di Flash development center scritto da Jeff Kamerer sullo sviluppo dei componenti in Flash20. 3.1 Cos‟è un componente? I componenti sono oggetti di flash che possiedono delle funzionalità e proprietà con cui l‟utente può lavorare senza preoccuparsi di produrre la logica di programmazione per il suo funzionamento; questo implica una maggiore facilità nella costruzione di applicazioni più complesse ed allo stesso tempo di risparmiare tempo nello sviluppo di essa. In termini tecnici, sono progetti di flash che possono essere aperti ed utilizzati all‟interno di altri progetti creati da uno sviluppatore. I componenti sono elencati nella libreria dei componenti, (Figura 11.) per utilizzarli basta trascinarli sullo stage e in seguito programmare, per mezzo di codici di programmazione abbinati al loro funzionamento, così da renderli operativi con l‟applicazione. Ciascuno di loro ha delle proprietà che controllano il loro comportamento ed il loro aspetto, e che si possono modificare sia attraverso l‟interfaccia di flash, che con ActionScript. 20 “Creating ActionScript 3.0 components in Flash”, <http://www.adobe.com/devnet/flash/articles/creating_as3_components.html> 26 Capitolo 3 – Componenti di FLASH Figura 11. Elenco dei componenti. Per usarli, li si trascina sullo stage All‟interno di flash è possibile trovare due tipi diversi di componenti: quelli che sono basati su file SWC, oppure quelli basati su file FLA. I componenti basati su SWC hanno la caratteristica di essere clip compilati, ovvero in termini propri di Flash un clip prepubblicato, e questo porta con sé due conseguenze importanti: la prima è che essendo che il clip è già stato compilato, sia a livello del codice che della parte visuale, l‟utilizzo di questi componenti offre delle prestazioni migliori in tempo di esecuzione dato che non si perde tempo nella traduzione del linguaggio di programmazione al linguaggio della macchina; la seconda conseguenza però è uno svantaggio perché avendo già tutte le sue parti compilate, il file SWC non permette di modificare nè accedere a nessuno dei suoi elementi visuali, limitando così le opzioni di modifica della parte visuale del componente. D‟altra parte, i componenti basati su FLA hanno la caratteristica che, una volta trascinati sull‟area di lavoro o stage offrono la possibilità di modificare la parte visuale, sia perché ciò permette di accedere ad ogni parte utilizzata per la sua rappresentazione visuale, che cambiare completamente i disegni utilizzati per il componente. All‟interno di flash, ci sono più di una decina di componenti diversi, ognuno dei quali con delle funzioni specifiche, ma in un contesto di applicazioni multitouch, sarebbe necessario programmare ogni componente utilizzato per ogni specifica applicazione sviluppata, spendendo più del tempo necessario se ci fossero dei componenti appositi per questo tipo di applicazioni. Tuttavia flash permette di creare dei componenti personalizzati, ovvero di modificare quelli già esistenti estendendone le loro funzionalità per otterre componenti nuovi appositi a seconda delle necessità riscontrate per ciascuna applicazione interattiva. Per tanto è necessario capire prima come funzionano i componenti, e principalmente quelli basati su FLA. 27 Capitolo 3 – Componenti di FLASH 3.2 Struttura dei Componenti Tutti i proggetti che si eseguono con Flash lavorano con dei clip, questo implica che esista una timeline come avviene nella composizione di un film. E‟ quindi possibile costruire una applicazione, oppure un componente come in questo caso, aggiungendo degli oggetti ad ogni frame, ed anche allo stesso tempo si possono aggiungere altre timeline le quali funzionano anche come dei layer (Figura 12). Quando arriva il momento di eseguire l‟applicazione, il primo frame d‟ogni timeline inserita sarà visualizzato in contemporanea con tutti gli altri primi frame, dopo verranno visualizzati tutti i secondi frame e così via. Figura 12. Progetto di flash con 2 timeline diverse e con oggetti aggiunti nel primo frame Tutti i componenti di flash hanno in comune una struttura interna che permette di organizzare adeguatamente ogni parte che li compone: possiedono una struttura a due frame e 4 layer (Figura 13), uno dei quali ha semplicemente ha lo scopo di inserire i nomi delle diverse parti del componente. Un altro layer contiene tutti gli oggetti, oppure i disegni, noti anche come Skin di cui ha bisogno il componente per la sua parte visuale; questo insieme di elementi ha il nome di assets. Alcuni degli assets di un componenti di flash, ad esempio „Button‟, sono il disegno di come questo si deve vedere quando si trova in uno stato normale, il disegno riferito a quando viene premuto ed infine il disegno per quando non è abilitato a funzionare. C‟è un terzo layer il quale contiene un simbolo noto con il nome di avatar, il quale di solito mantiene le stesse dimensioni del componente reale, ciò perché nel momento in cui viene creata un‟istanza di un componente, queste dimensioni vengono assegante ai parametri „width‟ e „height‟ della classe. L‟ultimo layer contiene unicamente un elemento il quale è molto importante ed è conosciuto come componentShim. Cos‟è questo simbolo e per cosa serve verrà spiegato in seguito, dopo di che si effettuerà una descrizione della struttura a due frame per i componenti e si illustreranno le ragioni per le quale sono fatti in questo modo. 28 Capitolo 3 – Componenti di FLASH Figura 13. La struttura a due frame, comune per tutti i componenti di flash 3.3 Il codice interno dei componenti – L‟elemento componentShim Questo elemento o simbolo di flash è molto importante per i componenti perché è lui che possiede il codice sorgente necessario per il loro funzionamento. Il componentShim è un clip precompilato che contiene le definizioni, sia delle classi di programmazioni eseguite dallo sviluppatore, che delle definizioni delle classi utilizzati da flash nella sua struttura interna (come per esempio la classe UIComponent), le quali sono necessarie al funzionamento del componente. Il fatto che questo clip sia già compilato significa che la traduzione del codice ActionScript 3.0 nel linguaggio di macchina è stato già compiuto, permettendo così di fare due cose: la prima è che in tal modo i componenti possono trovare il loro codice sorgente all‟interno di uno dei loro elementi, invece di dover ricavarlo da un file esterno e dopo compilarlo. In questo senso, avendo già tutto il codice precedentemente compilato, è possibile distribuire dei componenti senza avere bisogno di distribuire esplicitamente il loro codice sorgente. Il secondo vantaggio che si riscontra è al momento della compilazione del codice, poichè non è più necessario eseguire lo stesso. Quindi questo simbolo possiede unicamente il byte code di ActionScript compilato ed è per questa ragione che è anche noto come la definizione ABC del componente per la sua sigla in inglese: ActionScript Byte Code definition. Invece il componentShim non possiede nessuna rappresentazione visuale, come per esempio gli assets oppure l‟avatar dei componenti, e dunque le sue dimensioni sono zero sia in lunghezza che in larghezza: una volta che lo si è trascinato sullo stage, l‟elemento sembra essere invisibile e per tanto non viene mai visualizzato al momento dell‟esecuzione dell‟applicazione. 29 Capitolo 3 – Componenti di FLASH Figura 14.Le proprietà del simbolo. La voce „Export in frame 1‟ Nel momento in cui un simbolo o un clip compilato viene trascinato sullo stage, ovvero se nella definizione delle proprietà del simbolo, si sceglie la voce di “Export in frame 1” (Figura 14.), il simbolo diventa un output nell‟applicaizione, e questo significa che tutte le definizioni di classi al suo interno che servono per il suo funzionamento diventano disponibili per il compilatore. In altri termini nel momento di creare il file SWF21, vengono unicamente rese disponibili le definizioni di classi che hanno un riferimento ad un simoblo che è stato usato nel progetto. Questo vuol dire che se l‟opzione d‟esportare nel primo frame non è attivata, non basta avere un elemento nella libreria del progetto per poter utilizzarlo nell‟applicazione, ma bisogna trascinarlo sullo stage. Quindi quando si utilizza il componentShim, il quale non ha questa opzione attivata, anche se al suo interno ci sono tutte le definizioni per i componenti di Flash, nel file SWF soltanto vengono caricate le classi dei componenti che sono usati nel progetto. 21 Un file SWF è il formato del file utilizzato da flash per la esecuzioni delle applicazioni. 30 Capitolo 3 – Componenti di FLASH La seconda cosa che bisogna spiegare rispetto alla pubblicazione dei progetti è che flash ha una priorità sulla sorgente del codice utilizzato per la compilazione. Flash permette di specificare il path dove si devono cercare le definizioni delle classi utilizzate, se questo viene fatto e ci sono delle definizioni uguali a quelle all‟interno del simbolo componentShim, le classi trovate nel path specificato avranno priorità sulle altre. E questo è un aspetto importante da tenere in conto al momento di sviluppare componenti, innanzitutto perché per il loro sviluppo, si devono utilizzare definizioni di classi interne di flash che di solito non sono disponibili per lo sviluppatore di applicazioni, poiché questo solo deve utilizzare i componenti, ma al momento di sviluppare componenti è molto utile definire il path delle classi interne per poi poter costruire adeguatamente i componenti e fare i debug necessari a capire se il suo funzionamento è il corretto o meno. Ora si passerà a studiare la struttura dei componenti. 3.4 Struttura a due frame dei componenti Come visto prima nella Figura 13, i componenti vengono costruiti su due frame. Nel primo frame l‟unico elemento che viene inserito è l‟avatar, mentre che nel secondo frame vengono inseriti tutti gli asset necessari per la sua rappresentazione visuale e per il suo funzionamento. In totale tre di quattro frame contengono elementi inseriti nel secondo frame, uno dei quali fa da guida e contiene i nomi degli asset del componente, mentre gli altri elementi funzionali vengono inseriti negli altri due layer. Il componentShim deve essere inserito su un layer diverso agli asset, perchè non deve poter essere modificato dall‟utente o da un‟altro sviluppatore di componenti. Come si può vedere sempre dall‟immagine 4, tutti i layer tranne il layer degli asset si bloccano per impedire la sua modifica, questa impostazione viene rappresentata attraverso l‟icona di un lucchetto, che si trova affianco ad ogni nome di layer. Gli asset possono essere simboli creati dall‟utente oppure altri componenti precedentemente creati, facendo in questo modo un componente con dei sub-componenti, ma l‟importante è che tutto l‟insieme di elementi venga inserito nel secondo frame del layer asset. Nel momento in cui si esegue l‟applicazione, l‟unico frame che si vede è il primo frame e quindi il secondo frame è utilizzato unicamente come contenitore degli elementi che ne fanno parte, e mano a mano che bisogna cambiare l‟apparenza del componente sia perché si deve reagire a una azione dell‟utente oppure perché si è modificato qualche dato e si deve aggiornare l‟apparenza, gli asset rispettivi vengono aggiunti nel display list rimpiazzando quelli che si vedevano precedentemente. Per spiegare meglio si illustrerà questo processo con un breve esempio su di un tasto: quando il componente è sull‟area dello stage e non viene fatta alcuna azione dall‟utente si vede uno skin, che contiene un disegno specifico rappresentante un tasto in stato normale dove non c‟è nessun‟azione dell‟utente; dopo di che se l‟utente si sposta sopra col cursore del mouse, lo skin può cambiare al fine di far capire all‟utente che il mouse si trova sopra il componente; ed ancora quando il tasto viene 31 Capitolo 3 – Componenti di FLASH schiacciato, lo skin cambia ad uno che assomiglia a un bottone schiacciato, sempre per far capire lo stato in cui il componente si trova. Tutti questi tre skin sono asset che si trovano nel secondo frame del componente sul layer „assets‟, ed assieme a questi ci saranno tutti gli altri skin necessari per ognuno degli stati del componente o dei suoi sub-componenti. Per poter manipolare questi skin, gli asset devono avere delle impostazioni specifiche che permettono a Flash di utilizzarli (Figura 15): prima di tutto, è necessario convertire i componenti in un simbolo di flash, che sono elementi con cui il codice ActionScript può interagire, dopo di che nella definizione delle proprietà del simbolo deve essere scelta la voce di „Export for ActionScript‟, la quale permette di collegare ad un simbolo una definizione di una classe fatta dall‟utente, affinché il simbolo abbia delle proprietà e comportamenti personalizzati. Figura 15. Impostazioni delle proprietà degli asset per i componenti Un‟altra impostazione essenziale è l‟opzione di „Export in frame 1‟, la quale è molto importante che non venga scelta. Quest‟opzione, che si trova sempre nella definizioni delle proprietà dei simboli (Figura 15), quando viene selezionata assicura che il codice di programmazione riguardante il simbolo sia compilato nel file SWF, nonostante il simbolo non sia stato trascinato sullo stage e si trovi sulla libreria del progetto. Invece nel caso dei componenti tutti gli asset sono stati aggiunti nel secondo frame del componente, e nessuno di questi prevede l‟opzione di esportare nel primo frame selezionato; quindi se l‟utente non vuole aggiungere il componente basta non trascinarlo sullo stage e deselezionare l‟opzione per lo stesso, evitando che l‟utente debba deselezionarlo per ciascuno degli asset, e dunque facilitando la gestione e le dimensioni del file SWF (più elementi vengono creati, più pesante sarà il file). Una volta che sono state selezionate tutte le opzioni desiderate per il simbolo e si da conferma delle selezioni, se non esiste nessuna definizione di classe fatta dall‟utente, Flash ne genera una automaticamente nel momento della compilazione, e questa classe possiederà delle proprietà e metodi basici per il suo funzionamento. Quando questo accade, viene 32 Capitolo 3 – Componenti di FLASH sempre notificato da flash per mezzo di un‟avviso di allerta, (Figura 16). Se questa notifica non viene inviata significa che flash ha trovato una classe personalizzata nel progetto e quindi se questa non era prevista, serve per capire l‟esistenza di un conflitto tra i nomi delle classi esistenti. Figura 16. Notifica di flash della creazione automatica di una classe Una terza impostazione che è importante rispetto agli asset dei componenti, si può selezionare tra le preferenze di pubblicazione del progetto, sotto la scheda di Flash e nella configurazione di ActionScript. Tra le voci che emergono, infatti ne esiste una con il nome „Automatically declare stage instances‟ (Figura 17.), che come viene indicato dal suo nome, fa sì che al momento della compilazione Flash si occupi di emettere la dichiarazione delle istanze già trascinate sullo stage. Di solito il nome di queste istanze è assegnato dall‟utente, ed è lo stesso nome che viene utilizzato da Flash per fare la dichiarazione, quindi si evita di dichiarare esplicitamente le variabile nel codice. Anche se questo può essere molto utile in certi contesti, nell‟ambito dei componenti basati su FLA non è gradito. Infatti nel momento in cui un componente FLA viene copiato sul progetto, è necessario che tutti i simboli all‟interno del progetto siano compilati correttamente, questo indipendentemente dal fatto che l‟opzione di dichiarazione automatica sia stata scelta o meno. Il modo più sicuro di farlo è quello di dichiarare esplicitamente le istanze nel codice, e quindi a nessuno degli asset oppure delle istanze del componente può essere stato assegnato un nome. Ora che si è descritta la struttura dei componenti, e le impostazioni che devono avere le parti che li compongono, si passerà a spiegare il modo in cui la struttura viene integrata nel framework di lavoro di flash. 33 Capitolo 3 – Componenti di FLASH Figura 17. Opzione di „Dichiarazione automatica delle istanze sullo stage‟ 3.5 Struttura interna di Flash per l‟uso dei componenti Tutti i componenti di Flash servono per creare le interfacce delle applicazioni, e quelli che sono basati su FLA sono raccolti all‟interno di un gruppo di componenti noto come „User Interface‟ (Figura 11), che di solito fa uso dei metodi di alcune classi base facenti parte della struttura dei componenti dell‟interfaccia utente. Tutte queste classi con i loro metodi permettono di creare e sviluppare dei componenti in una maniera più facile e semplice; tutti loro fanno parte del pachetto di classi „fl.*‟. Per usufruire delle prestazioni della struttura, la classe del componente che si sta sviluppando deve rispondere a certi condizioni: una è la struttura visuale, che è stata illustrata precedentemente; una seconda condizione è che deve estendere la classe fl.core.UIComponent; la terza condizione è che, per integrarsi adeguatamente alla struttura, il componente deve implementare dei metodi specifici che permettono di usare i modelli di invalidazione e di styling, i quali verrano spiegati in seguito. 34 Capitolo 3 – Componenti di FLASH 3.5.1 La classe base dei componenti: fl.core.UIComponent Estendere una classe in Flash comporta che la classe che lo fa erediti le proprietà ed i metodi della classe base da cui è stata estesa (quelle che non siano state dichiarate come tipo „static‟22); è anche possibile che la classe base estenda a sua volta una terza classe e così via, dunque in questo modo è possibile estendere la classe UIComponent indirettamente, estendendo una classe che a sua volta estenda UIComponent. In questo modo, si possono estendere classi definite precedentemente per sfruttare le loro funzionalità, ed usarle come proprie, ma è anche certo che se una classe base per com‟è stata definita non può fare determinate cose, tutte le classi che la estendano avrano le stesse limitazioni. In questo senso è quindi importante sapere da che classe si estende la classe UIComponent, e così capire quali condizioni sono imposte a tutti gli elementi che la estendono. Tutti gli elementi che estendono la classe Sprite condividono le seguente condizioni: - L‟elemento non può fare uso dei script per frame specifici (frame scripts), che sono parti di codice che si eseguono unicamente quando si arriva al frame specifico. - La timeline dell‟elemento non si eseguirà mai rimanendo fermo nel frame uno. Queste due condizioni implicano innanzitutto che il codice necessario per il componente deve essere descritto tutto nelle definizioni delle classi, e secondo che non si possono utilizzare altri frame diversi dal primo per visualizzare il componente. I componenti, si ricorda, hanno nel suo secondo frame tutti gli elementi necessari per la sua funzione, la parte visuale con gli skin, e la parte operativa con il componentShim; ma il fatto che siano stati inseriti in un frame diverso dal primo non va contro le condizioni elencate prima, essendo che questo frame non viene mai visualizzato. Estendere la classe Sprite ha anche altre implicazioni, le quali però in questo momento non sono particolarmente inerenti allo sviluppo dei componenti, e pertanto non saranno di qui approfondite. Come si era detto prima, è importante definire il path dove si possono trovare le classi esterne del progetto, e la classe UIComponent è uno di questi casi dove bisogna indicare la sua locazione. Quindi per poter utilizzare questa classe, si deve dire al programma dove può trovarli. Questo si fa nelle preferenze di pubblicazioni, nelle opzioni di flash (Figura 17) aggiungendo il path: 22 „Static‟ è una parola chiave che in ActioScript definisce che la variabile, la costante, oppure il metodo che si sta definendo appartiene unicamente alla classe e non alle istanze della classe. <http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/statements.html> 35 Capitolo 3 – Componenti di FLASH ..Program Files\Adobe\Adobe Flash CSX\language\Configuration\Component Source\User Interface Facendo questo, nel momento di compilare il codice, verrano anche importate le definizioni delle classe esterne che servono al componente. 3.5.2 Il metodo configUI e l‟uso degli Stili Quando una classe viene utilizzata viene chiamata sempre una funzione nota come costruttore della classe, la quale inizializza le variabili di cui ha bisogno, prepara gli elementi che devono essere notificati dagli eventi registrandoli come „listeners’ degli eventi e chiama tutti i metodi che devono essere eseguiti a tal fine. Per le classi che estendono UIComponent, il metodo configUI è tra questi uno dei più importanti. Questo metodo è chiamato dal metodo costruttore solo dopo aver finito l‟inizializzazione del supporto per l‟invalidazione e per gli stili. Su questo metodo è consigliato inserire tutto il codice necessario per la creazione, inizializzazione ed aggiunta sul display list degli elementi che verrano visualizzati. Quindi bisogna sovrascrivere la funzione, ovvero in termini tecnici, fare un „override‟ della funzione; ma si deve tenere in conto che, come per tutte le funzioni che sovrascrivono un metodo della classe base, si deve chiamare la funzione originale per mezzo del codice „super.configUI()‟. Il metodo della classe base si deve chiamare per prima poiché questa s‟incarica d‟inizializzare le proprietà di altezza e larghezza del componente, e inoltre si occupa di rimuovere l‟avatar del display list per inserire in seguito il primo skin del componente. Un‟altra variabile che è inizializzata nel metodo configUI, è la variabile „isLivePreview‟, la quale viene utilizzata per sapere quando ci si trova nello stato di visualizzazione dell‟ anteprima del componente. Questo permette di vedere com‟è l‟aspetto del componente nello stage quando si cambiano delle proprietà, senza aver bisogno di eseguire l‟applicazione. Un‟altra cosa che viene fatta dal metodo costruttore di UIComponent è quella di registrare il compontente nel modello degli stili. Esiste un‟altra classe base, „StyleManager‟ che si occupa di cambiare ed aggiornare l‟apparenza dell‟oggetto con alcuni metodi specifici: gli stili di un componente possono essere per esempio il formato del testo usato, se possiede un campo di testo, oppure i diversi skin del componente. Quindi la classe StyleManager deve essere in grado di sapere quale sono gli stili di ogni componente, e perciò nel momento di definire la classe si deve definire un oggetto, che per convenzione ha il nome di „defaultStyles‟ contenente tali informazioni. Per esempio nella Figura 18, si trova un parte di codice dove si esegue la dichiariazione dell‟oggetto „defaultStyles‟ per un componente qualunque, ed al suo interno vengono definite un‟elenco degli skin che devono essere utilizzati per ogni stato del componente. L‟elenco è composto da coppie nome-valore, dove 36 Capitolo 3 – Componenti di FLASH il nome è la variabile usata nella programmazione di ActionScript, ed invece il valore è il nome del asset aggiunto nella struttura del componente. Figura 18. Esempio della definizione del oggetto „defaultSyles‟ con i diversi stili per un componente In Flash esistono esistono gli stili definiti per default a livello di codice per il componente, come nella Figura 18, ed esistono quelli che possono essere personalizzati e definiti da un utente (che anche possono essere definiti via ActionScript, in classi definite dall‟utente). Ma avendo la possibilità di creare diverse istanze per ogni componente oppure di far condividere uno stile tra alcuni componenti, in ActionScript è possibile gestire quattro livelli diversi di stili: - Stili personalizzati per un‟istanza: Sono gli stili creati dall‟utente ed applicati su una istanza di un componente. Se esiste un‟altra istanza del componente sullo Stage, quest‟ultima non cambia i suoi stili. - Stili personalizzati per un componente: L‟utente può scegliere dei tipi di stili specifici per un componente, azione che avviene su tutte le istanze del componente. - Stili globali: L‟utente può scegliere di cambiare uno stile specifico, dopo di che questo viene applicato su di tutte le istanze a cui può essere applicato, anche se sono istanze di componenti diversi. Per esempio se esiste un‟istanza del componente „List‟ ed un‟istanza del componente „TextArea‟ entrambi lavorano con il testo ed hanno un stile in 37 Capitolo 3 – Componenti di FLASH comune definito con il nome „textFormat‟. Se l‟utente cambia questo stile, il cambio avviene su ambo due le istanze. - Stili definiti per default: Sono gli stili definiti a livello di codice. La classe UIComponente definisce degli stili base che tutti i componenti che fanno parte della struttura dell‟interfaccia utente condividono, anche se questi non si utilizzano tutti. Per definizione questi stili sono globali, e si elencano in seguito: - focusRectSkin: definisce il simbolo che deve essere usato quando il componente ha il focus su di lui. - focusRectPadding: la distanza del bordo alla quale deve stare il „focusRectSkin‟. - textFormat: definisce il formato di testo da utilizzare, se il componente contiene del testo (per esempio un‟etichetta / TextField). - disabledTextFormat: definisce il formato di testo da utilizzare quando il componente non è abilitato.. - defaultTextFormat: definisce il formato di testo che si deve utilizzare per default per il componente. - defaultDisabledTextFormat: definisce il formato di testo per default che si deve utilizzare quando il componente non è abilitato. Flash possiede già una classe che si occupa di gestire gli stili dei componenti, questa classe ha il nome di „StyleManager‟, e per permettere che questa classe gesire gli stili bisogna registrare il componente alla classe, dopo di essere registrato la classe StyleManager ha un riferimento al componente per sapere che ne deve gestire i suoi stili. Se un componente estende la classe UIComponent, questa registrazione viene fatta automaticamente, ed è per questo che dopo è possibile utilizzare i suoi metodi senza alcun problema. I diversi metodi della classe StyleManager servono per tre funzione diverse: per applicare (set) uno stile specifico, per ottenere (get) lo stile attuale, e per cancellare (clear) lo stile attuale. A seconda del livello di stile che si vuole gestire ci sono diversi metodi da utilizzare che si elencano qui di seguito: - Metodi per stili d‟istanze: nomeIstanza.setStyle( nome_Dello_Stile, valore_Dello_Stile ); nomeIstanza.clearStyle( nome_Dello_Stile); 38 Capitolo 3 – Componenti di FLASH nomeIstanza.getStyle( nome_Dello_Stile); - Metodi per stili di componenti: StyleManager.setComponentStyle( classe_del_Componente, nome_Dello_Stile, valore_Dello_stile); StyleManager.clearComponentStyle( classe_del_Componente, nome_Dello_Stile); StyleManager.getComponentStyle( classe_del_Componente, nome_Dello_Stile,); - Metodi globali: StyleManager.setStyle( nome_Dello_Stile, valore_Dello_stile ); StyleManager.clearStyle( nome_Dello_Stile); StyleManager.getStyle( nome_Dello_Stile); Dove: nomeIstanza: è il nome della istanza a cui si vuole cambiare lo stile. nome_Dello_Stile: è il nome inserito in formato di testo, tipo String valore_Dello_Stile: è il valore inserito in formato di testo, tipo String classe_del_Componente: è il nome della classe a cui si vuole cambiare lo stile Per Flash, esiste un ordine di priorità per l‟uso degli stili: la priorità più alta ce l‟hanno gli stili di istanza, dopo di che seguono gli stili per i componenti e alla fine gli stili globali. Se nessuno di questi stili viene applicato ad alcuno dei metodi elencati precedentemente, lo stile che verrà utilizzato sarà quello che è stato definito nella definizione della classe all‟interno dell‟oggetto ‘defaultStyles’. Quando si vuole cambiare l‟apparenza di un componente è possibile reperire i suoi stili per capire come sono stati definiti, e per fare ciò esiste il metodo „getStyleDefinition‟ (Figura 19), il quale reperisce un elemento tipo „Object‟ contenente tutti gli stili definiti per la classe. 39 Capitolo 3 – Componenti di FLASH Figura 19. Dichiarazione della funzione getStyleDefinition Questa funzione, oltre a offrire un modo per ottenere gli stili di un componente, è utile quando la classe sta estendendo una classe base che ha già definiti degli stili. Come si vede nell‟immagine precedente, l‟oggetto ritornato è a sua volta un elemento ritornato dalla funzione „mergeStyles‟ della classe UIComponent. Questa funzione riceve due argomenti, due oggetti con la definizione degli stili: uno della classe stessa e l‟altra della classe base. Il metodo si incarica di copiare tutti gli stili di entrambe le classi unendoli in un‟unico elemento, e nel caso in cui si trovi uno stile uguale in entrambi gli oggetti utilizza la definizione del primo oggetto passato al metodo; in questo modo è possibile modificare gli stili della classe base. Una volta che sono stati definiti gli stili ed il metodo per poter avere accesso ad essi, bisogna implementarli. Dentro alla struttura dei componenti dell‟interfaccia utente esiste un metodo nel quale viene inserito tutto il codice necessario per gestire il cambio dei diversi skin e degli stili (quest‟ultimo verrà illustrato in seguito). 3.5.3 Il metodo draw() ed il modello d‟invalidazione Tutte le volte che si vuole creare un componente, che interagisca con la struttura dei componenti dell‟interfaccia utente, bisogna sovrascrivere un‟altro metodo che si occupa di gestire l‟aggiornamento della parte visuale dell‟elemento, sia direttamente, sia chiamando dei metodi appositi per farlo. Questo metodo si chiama „draw‟, e viene chiamato all‟interno del modello d‟invalidazione di Flash. Ogni volta che un componente deve essere aggiornato nel suo aspetto visuale, sia perchè ha cambiato il suo stato e si rende necessario cambiare lo skin o perché si deve aggiornare a causa della selezione di un‟opzione nell‟applicazione, il metodo draw deve essere chiamato per gestire questo aggiornamento. Tuttavia, per ragioni di efficienza non sarebbe utile aggiornare il componente ogni volta che si esegue un piccolo cambio al componente; per esempio, se si cambiano le dimensioni si deve cambiare sia la proprietà di larghezza che di 40 Capitolo 3 – Componenti di FLASH lunghezza, e non sarebbe effieciente aggiornare il componente quando si cambia ciascuna delle proprietà. Dunque è necessario stabilire un processo che si occupi di informare quando si deve aggiornare la parte visuale ogni una volta che i nuovi valori di entrambe le proprietà siano stati calcolati, e quindi chiamare una volta sola il metodo „draw‟ per cambiare contemporaneamente tutto ciò che deva essere aggiornato. È il modello d‟invalidazione quello che si occupa di farlo. Il modello lavora del seguente modo: ogni volta che il componente riceve un evento, oppure si chiama un metodo il quale cambia alcuna delle sue proprietà o semplicemente che si deva cambiare il suo aspetto visuale, il componente si mette in uno stato di invalidazione. Per fare questo si utilizza il metodo „invalidate()’ il quale programma una chiamata al metodo „draw()‟ nel frame sucessivo. Quindi così come esistono diversi ragione per le quali bisogna invalidare un componente, esistono anche diversi tipi di invalidazione e questi vengono definiti all‟interno della classe „InvalidationType’. Questa classe insieme alla classe „UIComponent „ compongono il pachetto di classi „fl.core‟ di Flash che alla fine contengono tutte le funzioni base necessari per il funzionamento della struttura dei componenti dell‟interfaccia utente. All‟interno della classe „InvalidationType‟ sono definiti le costanti che rappresentano i diversi tipi di invalidazioni, che si elencano adesso: - ALL: questa costante contiene la stringa „all‟ ed indica che il componente deve essere aggiornato completamente. - SIZE: contiene la stringa „size‟, ed indica che si devono aggiornare le dimensioni del componente. - STYLES: contiene la stringa „styles‟ ed indica che gli stili del componente sono invalidi e bisogna aggiornarli. - RENDERER_STYLES: contiene la stringa „rendererStyles‟ e si usa per indicare che si devono aggiornare i render styles del componente. - STATE: contiene la stringa „state‟ ed indica che lo stato del componente non è più valido. L‟esempio più comune di questo tipo è quando si cambia la proprietà „enabled’ del componente. - DATA: contiene la stringa „data‟ e si usa per indicare che un dato del componente non è più valido e quindi si deve aggiornare il componente. Per esempio nel componente „List‟ quando si sceglie uno dei suoi elementi. - SCROLL: contiene la stringa „scroll‟ ed indica che la posizione della barra di scorrimento non è più valida. 41 Capitolo 3 – Componenti di FLASH - SELECTED: contiene la stringa „selected‟ e si utilizza per indicare che la proprietà „selected‟ del componente non è più valida. È anche possibile di passare come argomento una stringa qualunque, ma è consigliato utilizzare le costanti già definite, ed unicamente farlo nel caso in cui la descrizione dell‟invalidazione sia tanto diversa a loro. Chiaramente una modifica nel componente può implicare l‟invalidazione di più di un tipo. Come per esempio la selezione di un elemento di un elenco potrebbe implicare l‟invalidazione di tipo DATA, dopo di che bisogna aggiornare il componente in base all‟opzione appena scelta, e questo potrebbe implicare un‟invalidazione di tipo STYLES. In questo caso, appena si rileva la selezione del dato si invalida il tipo DATA, e si passa un secondo argomento alla funzione „invalidate‟ per indicare che deve aspettare un‟altra invalidazione prima di programmare la chiamata al metodo „draw()’. Questo argomento è di tipo booleano ed deve avere il valore di „false‟. Dunque, per questo esempio, il processo d‟invalidazione (con le chiamate ai metodi) sarebbe il seguente: Selezione del dato nell'elenco (invalidazione: DATA) invalidate(InvalidationType.DATA,false); Bisogno di cambiare lo skin del componente (invalidazione: STYLES) invalidate(InvalidationType.STYLES); chiamata (automatica) al metodo draw() programmata dal modello d'invalidazione Diagramma 1. Diagramma di flusso per l‟esempio di selezione di un dato in un elenco. Un‟invalidazione tipo DATA, una di tipo STYLES e la chiamata al metodo draw() La chiamata al metodo draw è programata dal modello d‟invalidazione nel momento in cui non si passa come secondo argomento il valore „false’. Una volta fattoa, è compito del metodo „draw()’ di verificare quali invalidazioni sono state effettuate, per sapere quali metodi bisogna chiamare, e per fare ciò fa uso di un altro metodo, „isInvalid()’, che verifica quali stili sono stati invalidati e ritorna un valore di tipo booleano che indica se lo stile è stato invalidato o no. È così che al verificare queste condizione, il metodo draw può sapere che metodi chiamare, e come il modello di invalidazione si aspetta finchè si abbiano fatte 42 Capitolo 3 – Componenti di FLASH tutte le invalidazioni necessarie, quando viene chiamato il metodo draw si chiamano tutti i metodi che si occupano di cambiare ogni parte, aggiornando contemporaneamente tutte le parti del componente che devono essere aggiornate. Esistono altri due metodi che bisogna tenere in conto, i quali aiutano ad assicurarsi che il componente sia statoridisegnato correttamente, e questi metodi sono, „drawNow()’, che fa una chiamata indiretta al metodo draw23; ed il metodo „validateNow()’, che fa una invalidazione di tipo ALL per dopo di che chiama il metodo „draw()‟ e forzare l‟invalidazione di tutte le parti del componente. Queste due metodi sono utili nel momento di sviluppare componenti, ed aiutano ad assicurarsi che questo sia stato aggiornato correttamente. 3.5.4 Metadati dei componenti I metadati possono essere definiti como i dati che danno informazione su un elemento oppure che lo descrivono. Per esempio per un dipinto i metadati possono essere il suo nome, l‟anno in cui è stato dipinto, le sue dimensioni, ecc. All‟interno di Flash, i metadati sono le proprietà degli elementi alle quali l‟utente può avere accesso. Tutte le proprietà di un oggetto, simbolo di flash si possono trovare nella sua definizione di classe, tuttavia l‟utente non sempre ne ha accesso. Se si vuole quindi di permettere all‟utente di accedere a emodificare alcune delle sue proprietà, queste possono essere definite como metadati. Per fare ciò queste proprietà devono inanzitutto avere un modo per essere riperibili dall‟utente. Quindi bisogna definire un metodo che permetta di raggiungere la proprietà, ed un altro che permetta di modificarla. Questi due metodi si conoscono come i metodi „get’ e „set’, e possono essere utilizzati per qualunque variabile/proprietà. Dunque questi metodi sono necessari ma non sono sufficenti per definire un metadato. Per far vedere una proprietà come metadato, bisogna aggiungere un‟altra riga di codice che fa capire al compilatore che la variabile deve essere accessibile all‟utente, la riga di codice deve cominciare con la parola chiave „Inspectable‟ e si devono aggiungere altri parametri e valori che aiutano a definire il tipo di metadato ed il valor predefinito dello stesso. Un esempio della definizione di un metadato si può vedere nella Figura 20. Figura 20. Definizione di un metadato Nell‟immagine si vede la definizione del metadato ‟touchMode‟ che serve per accedere alla variabile ‟_touchMode‟ che è interna alla classe. Il tipo di metadato è booleano con un 23 Si fa una chiamata indiretta perchè il método „draw()’ è un metodo con accesso di tipo privato e quindi non è possibile chiamarlo direttamente. 43 Capitolo 3 – Componenti di FLASH valore predefinito di „true‟, ed il suo nome che è „touchMode‟. Questa definizione viene fatta una volta è deve essere inserita prima del metodo „get‟ o del metodo „set‟. Dopo questo valore sarà possibile visualizzarlo come una proprietà del componente alla quale si può accedere nel panello „Component Inspector’ di Flash. Esistono diversi tipi di metadati, e le sue definizioni comprendono definire dei argomenti specifici, ma in questo studio non si approfondirà nella sua descrizione. Invece nella sezione di sviluppo dei componenti sarà possibile vedere la definizione di metadati per casi specifici. Fino a questo punto si sono create e definite tutti le parti che compongono un componente. Ma bisogna ora dare all‟elemento delle impostazioni per fare che Flash capisca che il suo comportamento deve essere quello di un componente e non quello di qualunque altro simbolo creato in questo programma. 3.5.5 Creazione del componentShim per i componenti personalizzati Una volta che si ha creato tutto il codice, bisogna aggiungerlo al componente all‟interno dell‟elemento componentShim. Questo passo è molto importante perchè è questo elemento quello che possiede tutta l‟informazione del comportamento del componente. Per la creazione dell‟elemento componentShim personalizzato bisogna creare un progetto nuovo di Flash, e salvarlo nella stessa cartella in cui si è salvato il progetto dove si è sviluppato il componente. Dopo di chè si preparano tutti gli elementi necessari per la creazione del „shim‟ personalizzato, e per fare ciò si devono seguire i passi seguenti: * La parola „myComponent‟ fa riferimento al nome del compoente sviluppato. Dunque nel caso di creare un shim, questa parola deve essere rimpiazzata dal nome del componente personalizzato per il quale si sta creando l‟elemento componentShim, 1. Creare un simbolo nuovo di tipo MovieClip con il nome „myComponentShim source‟ Selezionare selezionare l‟opzione „esportare per ActionScript‟ Nel nome della classe inserire lo stesso nome del pachetto della classe del componente svilupatto. Per esempio: com.myComponentShim Cliccare su OK, dopo di che verrà visualizzata l‟alerta di creazione di una classe automatica. 44 Capitolo 3 – Componenti di FLASH 2. Creare un‟altro simbolo di tipo MovieClip con il nome „myComponent‟ Selezionare l‟opzione „esportare per ActionScript‟ Nel nome della classe inserire lo stesso nome del pachetto della classe del componente svilupatto. Per esempio: com.myComponent Verificare di lasciare selezionata la voce: „Esportare nel primo frame‟ Cliccare OK 3. Aprire il progetto del componente sviluppato e trascinare l‟elemento „componentShim‟ dalla libreria del componente personalizzato all‟interno della libreria del progetto del componentShim personalizzato. Fare click destro nel componentShim per vedere le sue opzioni e selezionare la voce „Linkage‟ Nella finestra emergente attivare la voce: „Esportare nel primo frame‟. Cliccare OK 4. Salvare il progetto. Nel caso in cui nel progetto del componente sviluppato non esista ancora l‟elemento componentShim è possibile crearne uno seguendo i passi seguenti, utilizzando un file interno di Flash che contiene tutte le preparazioni necessarie per la sua creazione. Questo file si chiama „ComponentShim.fla‟ e lo si può trovare nella cartella: …\Adobe\Adobe Flash CSX\language\Configuration\Component Source\ActionScript 3.0\User Interface\ Oppure in MAC: …/Applications/Adobe Flash CSX/Configuration/Component Source/ActionScript 3.0/User Interface/ A questo punto sono state fatte tutte le preparazioni necessarie per la creazione di un shim personalizzato, e lo stesso file può essere usato ogni volta che sia necessario. Per la creazione del clip compilato si devono fare i passi seguenti: 5. Fare click destro sul simbolo „myComponentShim source‟ e selezionare la voce „Convertire in un clip compilato. 6. Rinominare il clip appena creato nella libreria come „myComponentShim‟. 45 Capitolo 3 – Componenti di FLASH 7. Fare click destro e selezionare la voce l‟opzione „Linkage‟ e nella finestra emergente disattivare l‟opzione „esportare nel primo frame‟. 8. Trascinare dal progetto attuale il shim appena creato all‟interno della libreria del progetto del componente sviluppato (Di solito l‟allocazione nella libreria è una cartella „_private‟, Figura 21). Se prima c‟era l‟elemento „componentShim‟, cancellarlo Figura 21. Allocazione del componentShim, oppure del shim personalizzato, nella cartella „_private‟ della libreria del progetto. 9. Editare il simbolo del componente in fase di sviluppo ed inserire il nuovo elemento Shim nel frame 2 del layer „componentShim‟, preferibilmente con le coordinate x:10 e y:10. 10. Bloccare tutti i layer tranne il layer degli assets. 11. Chiudere tutte le cartelle della libreria del progetto e salvare. 46 Capitolo 3 – Componenti di FLASH Nel momento in cui venga fatto un cambio nel codice per aggiornarlo, si devono ripetere dal passo 5 fino all‟8, nel quale nel momento di trascinare il shim nella libreria, verrà fatta un‟alerta di un conflitto, indicando che Flash ha trovato un‟elemento con lo stesso nome. (Figura 22). Basta selezionare la voce di „Replace existing items‟ e l‟elemento componentShim personalizzato verrà aggiornato automaticamente. Figura 22. Alerta di conflitto nel momento di trascinare un elemeneto nuovo nella libreria di un progetto. Dopo di fare questi passi, il componente contiene tutti gli elementi necessari per il suo funzionamento ed unicamente bisogna selezionare le ultime impostazione per il componente. 3.5.6 Definizione di un componente e creazione dell‟anteprima L‟ultima cosa che bisogna fare è selezionare le impostazioni per fare che il simbolo si comporte come un componente e dopo creare l‟anteprima (livePreview) del componente. Ora si illustrerano le impostazioni necessarie per fare un componente e la creazione del livePreview Nella libreria del progetto deve essere stato creato un simbolo nel quale sono stati inseriti tutti gli asset del componente ed a cui è stata assegnata la classe personalizzata che contiene tutto il codice ActionScript per il suo funzionamento. Tra le opzioni di questo simbolo si deve scegliere la voce „Component Definition...‟, dopo di che verrà visualizzata una finestra con dei campi da compilare (Figura 23). 47 Capitolo 3 – Componenti di FLASH Figura 23. Finestra per fare la definizione di un componente Nel primo campo si deve inserire il nome della classe che contiene tutto il codice di programazione, ma si deve anche aggiungere il pachetto al quale appartiene la classe. Un breve esempio illustrera questo concetto di pacchetti. Se il progetto Flash è stato salvato sulla cartella „Documenti‟, il proggetto può avere accesso a tutte le definizioni di classe che si trovino sullo stesso path. Ma se si vuole raggruppare le definizioni di classe classificandoli per le sue funzioni, è anche possibile creare delle sotto-cartelle. Quindi Il nome della sotto cartella definisce il nome del pacchetto al quale appartiene la classe: se la sotto-cartella si chiama „com‟ ed al suo interno si inserisce la classe di nome ‟myClass‟, il nome completo sarebbe „com.myClass‟. Il nome del pacchetto permette al programma di sapere dove andare a cercare le classi che si importano nelle definizioni delle classi personalizzati. Dopo di inserire il nome della classe, si devono attivare le opzioni seguenti: „Require minimum player version, „Require minimum ActionScript version, „Display in Components panel‟ e si deve cambiare il numero del frame di edizione del componente al frame 2. A questo punto, il componente personalizzato ha tutte le caratteristiche ed impostazioni necessarie per funzionare al interno di Flash come un vero componente. L‟unica cosa che 48 Capitolo 3 – Componenti di FLASH manca è la possibilità di vedere l‟anteprima del componente. Per la sua creazione, si seguono i passi consigliati dal sito di Adobe, i quali vengono elencati in seguito: 1. Cliccare sul componente per vedere il menu di opzioni e scegliere la voce „Export SWC File‟. Salvando il fale sulla stessa cartella del progetto. 2. Prendere il file SWC e cambiare l‟estensione ad una di tipo .zip. 3. Aprire il file ed estrarre il file interno con il nome di „library.swf‟ e metterlo sulla stessa cartella del progetto. 4. Si consiglia di cambiare il nome del file „library‟ ad uno con la forma „myComponentPreview‟, per capire la funzione del file. 5. Nella definizione del componente (Figura 23) nel campo di anteprima, attivare l‟opzione di „Live Preview‟, nella finestra che esce selezionare la voce „Live Preview with .swf file embedded in .fla file‟ ed sfogliare le cartelle per selezionare il file appena cambiato nel passo precendente. Dopo di realizzare questi passi, i componente deve essere visualizzato con l‟anteprima, allo stesso modo come è possibile vedere gli altri componenti. Questo permette di cambiare le proprietà del componente ed visualizzarli senza che ci sia bisogno di eseguire l‟aaplicazione. Ora che si ha fatto uno studio di tutta la struttura dei componenti dell‟interfaccia utente insieme al modello d‟invalidazione e si sono individuati tutti i requisiti ed impostazioni che devono contenere questi simboli per essere componenti e non altro, il passo seguente sarà quello di sviluppare dei componenti che soddisfino tutti questi requisiti per poter integrarli sia alla struttura dei componenti che al modello d‟invalidazione. 49 Capitolo 4 Gesti Praticamente tutti i dispositivi di ultima generazione in ambito tecnologico offrono la possibilità di utilizzare dei gesti per controllare il loro funzionamento: scegliere un‟opzione da uno schermo, scorrere la finestra oppure trascinare un‟elemento, tutte funzioni che si possono fare appoggiando il dito sul display, e questi sono solo esempi di alcuni gesti semplici fatti su schermi. Per dare una definizione più formale di cos‟è un gesto si utilizzerà quella trovata nel libro di Saffer: “un gesto è qualsiasi movimento fisico che un sistema digitale sia in grado di rilevare e di rispondere a, senza il bisogno di un‟altro dispositivo appuntatore tradizionale, come il mouse”24. Quindi un gesto può essere un qualsiasi movimento nell‟aria oppure un tocco su uno schermo per fare una selezione. In questo capitolo si descriveranno alcune delle caratteristiche e gli attributi più importanti dei gesti tattili. Inoltre verrà presentato un algoritmo in grado di confrontare e rivelavare il gesto fatto dall‟utente e confrontarlo con dei template normalizzati, contenuti in una libreria creata anteriormente. Molta dell‟informazione sui gesti è stata presa dal libro di Saffer “Designing Gestural Interfaces”, nel quale tra tutte l‟informazione sulla creazione di interfaccie gestuali ed l‟uso in generale dei gesti, ci si è concentrati sui concetti base dei gesti tattili e su i loro attributti. 4.1 Caratteristiche delle interfacce gestuali In generale i gesti si possono classificare in due gruppi diversi: i gesti che non richiedono l‟interazione fisica con il dispositivo, noti come gesti di forma-libera, che possono utilizzare dispositivi di input, come guanti, oppure funzionare senza l‟utilizzo di nessun 24 Saffer, D. - “Designing Gestural Interfaces”, pagina 2. 50 Capitolo 4 – Gesti apporto addizionale. Mentre che gli altri gesti (tipo touchscreen) sono quelli che richiedono un interazione dell‟utente con il dispositivo. Le interfacce che usano quest‟ultimi si chiamano Interfacce di Utente di tipo Touchscreen, TUI dal suo acronimo in inglese (Touchscreen User Interface). Al giorno d‟oggi l‟utilizzo dei gesti nelle applicazione è talmente diffuso che è impossibile non percepire i cambiamenti e i vantaggi apportati nella vita quotidiana. Per questo motivo può essere interessante sviluppare una classe base di Actionscript che permetta di creare e gestire i gesti. E‟ importante tener conto che l‟uso di questi tipi di interfaccie porta con sé alcuni svantaggi come: · Una difficoltà inerente all‟uso di nuovi gesti (usabilità). Anche se molti dispostivi utilizzano già alcuni gesti, l‟uso di nuovi gesti porta sempre con sé il rischio di non permettere agli utenti apprezzare il nuovo sistema. Se i gesti sono troppo complessi oppure scomodi può darsi che l‟utente perda l‟interesse in utilizzare il sistema. · Dipendenza nella parte visuale Questo è un problema per le interfacce tattili, che necessitano di un display dove proiettare l‟immagine con la quale l‟utente interagisce. Per i gesti di forma libera non c‟è questo impedimento, ma possono esistere problematiche legate alle capacità fisiche dell‟utente. L‟uso di interfacce interattive non porta soltanto degli svantaggi ma anche porta alcuni vantaggi, come: · La possibilità di avere un‟interazione più naturale In generale agli essere umani piace poter interagire direttamente con gli oggetti, quindi i gesti interattivi permettono di interagire naturalmente e fisicamente con gli oggetti digitali così come con quelli reali. · Minor dipendenza dall‟hardware Nelle interfacce tattili, il solito sistema hardware per gli input, come la tastiera e il mouse, non sono più necesari, poichè i touchscreen o altri sensori permettono agli utenti di agire senza il bisogno di tale hardware. Questo permette di collocare tali sistemi interattivi in spazi in cui un computer classico sarebbe impraticabile o fuori luogo come ad esempio in punti vendita o altri luoghi pubblici. 51 Capitolo 4 – Gesti 4.1.1 Attributi dei gesti La maggior parte dei gesti hanno caratteristiche simili tra di loro. Deve essere chiaro, comunque, che più sofisticata sia l‟interfaccia, con un numero maggiore di sensori, più grande sarà il numero di attributi impiegati. Per i gesti touchscreen si sono identificati i seguenti attributi: · Presenza Questo è il più semplice degli attributi. Qualcosa deve essere presente per fare un gesto in modo da causare un interazione. Per il più semplice dei touchscreen, la presenza di un dito crea un evento tattile · Durata Tutti i gesti avvengono nel tempo e possono essere effettuati più o meno velocemente. Quando l‟utente interagisce con un pulsante può darsi che lo stia solo toccando o che lo stia tenendo premuto a lungo. L‟attributo è misurato calcolando il tempo dal contatto iniziale alla fine del gesto. · Posizione Questo attributo indica la posizione dove si stabilisce il contatto, delle cordinate x/y se si è dell‟intero di uno schermo oppure di un‟elemento proiettato nello schermo. Successivamente calcolando lo spostamento del dito sullo schermo. · Movimento Può essere lo spostamento del gesto, il suo orientamento o la sua direzione. Per alcuni sistemi qualsiasi movimento è sufficiente per ottenere una risposta. La posizione non influisce sulla determinazione del movimento. · Numero di punti tattili/ combinazioni Sempre più interfacce gestuali hanno compatibilità multitouch, permettendo agli utenti di usare più di un dito o mani contemporaneamente per controllarle e di svolgere combinazioni di gesti allo stesso tempo. Questo ovviamente implica una maggiore complessità nella programmazione dell‟interfaccia. Uno degli esempi più comuni è quello di usare entrambe le mani per allargare un‟immagine, trascinando in due angoli opposti apparentemente stirando l‟immagine. 52 Capitolo 4 – Gesti · Numero dei partecipanti Potrebbe essere utile che con alcuni dispositivi utilizzino utenti multipli, come ad esempio per il dispositivo Surface elaborato da Microsoft, il quale è stato pensato per essere utilizzato in attività sociali, come giochi oppure in collaborazioni lavorative. Questi concetti appena descritti sono solo alcune delle caratteristiche che si possono trovare nei gesti e nelle interfacce tattili. Ora si passerà a descrivere i diversi gesti che possono essere utilizzati sui sistemi ad interfaccia tattile. 4.1.2 Gesti basici/Pattern per i touchscreen Questo tipo d‟interfaccia esiste già su molti dispositivi, come ad esempio i cellulari. Con il tempo, tanti dei gesti che utilizzano sono diventati di uso comune e ormai si utilizzano come modelli o „pattern‟ già riconosciuti per fare delle azioni determinate. I patterns sono “combinazioni di un gesto e di un sistema di risposta che possono essere ripetuti in una varietà di situazioni attraverso diversi dispositivi”25 TAP Questo gesto può essere un tocco oppure un breve colpo, in un‟area specifica oppure su un oggetto, che inizia un‟azione. Di solito viene utilizzato ogni qualvolta si ha il bisogno di attivare, aprire un oggetto o premere un tasto. Inoltre il colpo si potrebbe usare per selezionare degli oggetti sullo schermo. Ha le stesse funzioni del click del mouse. E‟ anche possibile dividere il gesto nelle sue azioni base: appena entra in contatto con la superficie, ed appena il dito si alza dallo schermo. Se queste due azioni vengono effettuate velocemente si può interpretare come un click del mouse. Un colpo quando viene trattenuto potrebbe eseguire un azione multipla su una riga. Per la funzione di selezione deve esistere una coincidenza tra la posizione del evento tattile e la posizione dell‟oggetto sullo schermo. DRAG E‟ l‟azione di appoggiare il dito su un elemento presente sullo schermo per spostarlo o trascinarlo in un‟altra posizione. E‟ il gesto più semplice per la manipolazione degli oggetti. Gli utenti, dato che non hanno la possibilità di afferrare e prendere un 25 Idem. Pagina 45. 53 Capitolo 4 – Gesti oggetto fisico, necessitano di un modo per poter muoverli, è cosi che trascinarli o spingerli con le dita diventa un azione naturale da compiere. Per realizzare questo gesto, l‟oggetto deve essere stato selezionato prima, questo si può fare con il pattern descritto prima: l‟utente preme l‟oggetto, così da farlo reagire allo spostamento del dito attraverso lo schermo. Gli oggetti possono avere delle limitazioni sugli spostamenti, ad esempio a destra o sinistra. PINCH Quest gesto avviene quando le due dita si avvicinano (Stringere per rimpicciolire) oppure si allontanano (Estendere per ingrandire) su un oggetto causando un cambiamento delle dimensioni. Lo scalamento è quindi minore di 1 se le dita si avvicinano, rimpicciolendo l‟oggetto, e maggiore di 1 se le dita si allontanano, ingrandendo l‟oggetto. Questi due patterns solitamente si trovano insieme. Dunque questi pattern si possono utilizzare per cambiare le dimensioni di un oggetto, o di un‟immagine, facendo un effetto di zoom, come per esempio su una mappa, una pagine web, dei documenti oppure dello schermo intero. È utilizzato sopratutto per alcuni dispositivi di piccole dimensioni, dove gli utenti hanno bisogno di ingrandire per osservare correttamente gli oggetti nel dettaglio. Questo tipo di pattern richiede un sistema in grado di riconoscere due eventi tattili (multitouch). Solitamente essi scalano un oggetto in modo proporzionale anche se in genere non ci sarebbe bisogno. Il punto iniziale della posizione delle due dita corrispondono solitamente al 100% delle dimensioni di partenza dell‟oggetto. Quando le dita si avvicinano o si allontanano, l‟oggetto scala in tempo reale per adattarsi alla nuova distanza tra di esse in un rapporto che i progettisti devono stabilire in base alle dimensioni dell‟oggetto originale e dello schermo. Potrebbe esserci un punto limite oltre il quale l‟utente non può agire più per non permettere di diminuire l‟oggetto a delle dimensione che poi forse non li permettono più di manipolare l‟oggetto, impedendo anche di vedere o interagire. Questi pattern per i touchscreen descritti prima sono quelli trovati sul libro di Saffer, che sono d‟interesse per lo scopo della tesi. Però è possibile realizzare un‟altra azione sempre con l‟utilizzo di due dita sullo oggetto: ROTATION Questo gesto avviene quando due dita vengono messe sopra dello stesso oggetto. Dopo di che si prende come riferimento l‟asse formato dalle posizione iniziali delle dita ed ogni spostamento delle dita crea un'altro asse che forma un‟angolo con l‟asse 54 Capitolo 4 – Gesti di riferimento. L‟oggetto selezionato si può far ruotare lo stesso valore di quest‟angolo. Questo gesto può avvenire contemporaneamente al pattern di Pinch oppure al pattern di Drag, o a tutti e due insieme. Poiché allo stesso tempo che le dite girano sull‟asse di riferimento, possono avvicinarsi rimpicciolendo l‟oggetto, ovvero allontanarsi, ingrandendolo. E‟ anche possibile calcolare lo spostamento relativo tra un dito e l‟altro mentre stanno generando una rotazione oppure uno scalamento. 4.2 Gesti tattili non convenzionali Gli schermi touchscreen comunque offrono la possibilità di appoggiare le dita su qualsiasi parte dello schermo e spostarsi attraverso esso. In questo modo è possibile realizzare dei movimenti non standard con le dita, per esempio, un cerchio oppure un‟onda. Questi gesti sono caratterizzati da una forma libera, che però il sistema touchscreen, ovvero l‟applicazione interattiva, deve essere in grado di rilevare ed interpretare come un gesto. Per fare questo l‟interfaccia deve avere accesso ad una libreria di template con la quale confrontare i gesti fatti dall‟utente, in modo di capire e rilevare se quelli appena fatti sono validi e se si deve reagire ad essi. Bisogna allora riconoscere il gesto appena fatto dall‟utente al fine di memorizzare ogni movimento che fa ed in questo modo i gesti non convenzionali sono descritti da una sequenza di punti. Dopo la memorizzazione del gesto, si deve confrontare con ogni template della base di dati, cercando di trovare una coincidenza tra di loro. Il problema è riuscire a riconoscere lo stesso gesto fatto da diverse persone. Lavorare con questi tipi di gesti è quasi come interpretare lo stile di scrittura di ogni persona. Quindi per confrontare adeguatamente i gesti con i template bisogna tenere in conto e fare molta attenzione a questi aspetti. Per risolvere questo problema in una maniera relativamente semplice si è studiato un algoritmo che verrà esaminato più nello specifico nella sezione seguente. 4.2.1 Tecnica “$1 Recognizer” per il riconoscimento dei gesti touchscreen Questo algoritmo (Wobbork et al., 2007) si utilizza per confrontare un gesto rilevato con un insieme gesti standard che si utilizzano come riferimento. Ogni gesto in questa tecnica è descritto come un insieme di punti allocati su un sistema di coordinate, che di solito è lo schermo, oppure l‟applicazione dove si è effettuato il gesto. In questo senso è possibile avere un‟enorme quantità di gesti diversi, anche se il gesto descrive la stessa figura. 55 Capitolo 4 – Gesti Si possono incontrare due problemi legati al riconoscimento: uno dipende dalle dimensioni del gesto, l‟altro dalla velocità con cui questo è fatto. Infatti il numero di punti rilevati da un sistema dipende dal rango di velocità dei suoi componenti, dal frame rate della videocamera e dalla velocità di elaborazione del software. Figura 24. Due gesti fatti da due persone diverse26 Per esempio nella Figura 24, si illustrano due gesti svolti da due persone differenti, si possono evidenziare due cose: la prima è che hanno un numero diverso di punti, quindi dimensioni diversi di gesti possiedono un numero diverso di punti; e la seconda cosa è che se si ruota il primo gesto in un angolo di 90 gradi in senso orario, i gesti si assomigliano. In base a queste considerazioni, l‟algoritmo elaborato cerca di: · Non dipendere del numero di campioni prelevati in base alla velocità ne dalle misure del dispositivo di rilevamento · Non essere influenzato dalla rotazione, scalamento e posizione. · Non richiedere dei requisiti di tecniche matematiche avanzate. · Essere facilmente scrivibile in poche righe di codice · Essere sufficientemente veloce per scopi interattivi. · Permettere agli sviluppatori ed agli utenti d‟insegnare al sistema un gesto nuovo tramite un solo esempio. · Restituire un‟elenco con gli N-migliori possibili gesti ed il punteggio [0..1] indipendentemente dal numero di punti del input. · Prevedere un rango di velocità competitivo con algoritmi più complessi. Per riuscire a fare questo l‟algoritmo si basa su quattro passi: 26 Wobbrok, J et al. “Gestures without libraries, toolkits or training: a $1 Recognizer for user Interface prototypes” 56 Capitolo 4 – Gesti 1. Fase di ricampionamento dei dati. Sia i gesti già conosciuti che quelli che si vogliono confrontare devono essere ricampionati al fine di essere paragonati tra loro. Se il numero di punti è diverso, non è possibile confrontare i due gesti per sapere se sono uguali o meno. Quindi avere tutti i gesti ricampionati con lo stesso numero di punti è il primo passo dell‟algoritmo. Per elaborazione di questa tecnica si sono svolte delle prove per cercare un numero ottimale di campioni, al fine di non far diventare i gesti troppo piccoli, perdendo in precisione, o farli diventare troppo grandi, per non aumentare il tempo di elaborazione dei punti. Il numero consigliato è N = 64. Figura 25. Esempio di ricampionamento con diversi valori di N27 Per svolgere questa fase si calcola la lunghezza totale del gesto, utilizzando i punti originali, e successivamente questo valore viene diviso per (N-1) al fine di ottenere la nuova distanza, I, che deve intercorrere tra un punto e l‟altro. Conosciuto il valore I, si scorrono i punti originali e si sommano le distanze tra loro, se questi hanno un valore maggiore di I si aggiunge un nuovo punto utilizzando l‟interpolazione lineare. Cos`si può continuare finchè tutti i punti siano stati calcolati. 1. Rotazione basata sull‟angolo indicativo L‟angolo indicativo viene definito nello studio di (Wobbrock et al.) come l‟angolo formato tra il centro del gesto ed il suo primo punto. Una volta calcolato questo punto, utilizzando le regole trigonometriche, si fa ruotare il gesto finchè questo angolo sia zero. 27 Idem. 57 Capitolo 4 – Gesti Figura 26. Rotazione del gesto finche il suo angolo indicativo è zero28 2. Scalamento e traslamento Dopo la rotazione i gesti si scalano, in maniera non uniforme, ad uno quadrato con dimensioni fisse, detto quadrato di riferimento. Questa fase permette di ottenere i gesti tutti con le stesse dimensioni; in altre parole si fa una normalizzazione delle dimensioni del gesto e poi questo viene spostato nell‟origine, portando il centro nelle coordinate (0,0). 3. Riconoscimento Nell‟ultimo passo dell‟algoritmo si fa il riconoscimento, cioè si confronta il gesto con ogni modello della libreria di gesti. Per fare questo, si calcola la distanza media esistente tra i punti del gesto ed i punti del modello, ossia si calcola la distanza tra il primo punto del gesto e il primo punto del modello, poi si ripete il calcolo per tutti i restanti punti (Figura 27). Alla fine si sommano tutte le distanze, e il risultato viene diviso per N, numero di punti. Questo calcolo viene fatto per ogni template della libreria, alla fine, il confronto che dia la distanza media più piccola sarà quello che coincide con il gesto. 28 Idem. 58 Capitolo 4 – Gesti Figura 27. Le distanze tra punto e punto di due gesti.29 Le caratteristiche di questa tecnica appena descritta sono ottime per le applicazioni multitouch; poiché non tiene conto delle diversità di “scrittura” dei diversi utenti, né dalla posizione, scala e rotazione del gesto. Per questi ragioni questa tecnica è stata scelta per essere utilizzata nelle classi per il rilevamento dei gesti. 4.2.1.1 Classe di ActionScript che implementa la tecnica „1$'. Questo algoritmo è già implementato da alcuni classi di ActionScript30, in particolare sono due le classi che si utilizzano come oggetti, mentre una terza contiene tutto il codice per implementare l‟algoritmo „1$‟. In seguito si descrivono le classi: La classe „DollarTemplate.as‟: E‟ una classe ausiliaria che si utilizza come un oggetto, contiene il nome identificativo ed i punti di un gesto. 29 Icard, A. “Simple gesture recognition in AS3” <http://blog.sqrtof5.com/?p=173> Betriebsraum weblog “Efficient Gesture recognition and Corner Finding in AS3” <http://www.betriebsraum.de/blog/2009/07/21/efficient-gesture-recognition-and-corner-finding-in-as3/> 30 59 Capitolo 4 – Gesti Il costruttore riceve come primo argomento il nome identificativo del gesto, tipo String, e come secondo argomento una variabile di tipo Array che contiene i punti del gesto appena memorizzato tramite la tecnica „1$‟ appena descritta. La seconda classe „DollarResult.as‟: E‟ una classe in cui si salva il risultato del confronto tra il geto appena fatto dall‟utente e quello di riferimento, inoltre salva il punteggio che indica quanto si assomigliano il gesto fatto dall‟utente al modello. Il metodo costruttore riceve come primo argomento una variabile di tipo DollarTemplate, che contiene il modello di riferimento per il gesto, e come secondo argomento una variabile di tipo Number che rappresenta il punteggio ottenuto dal confronto tra il gesto ed il modello di riferimento. La terza classe, di nome „DollarRecognizer.as‟, E‟ quella che possiede tutti i metodi per implementare l‟algoritmo. I metodi che utilizza sono: o DollarRecognizer(templates:Array = null) Il metodo costruttore riceve un array con i modelli dei gesti. Se non riceve nessun argomento, si assegna un valore di „null‟ all‟array dei modello. o resample(points:Array, numPoints:uint):Array Metodo statico che si occupa del ricampionamento del gesto. Riceve il gesto originale ed il numero di punti che deve ricampionare. o rotateToZero(points:Array):Array Metodo statico che si occupa di ruotare tutti i punti di un valore uguale all‟angolo indicativo, descritto nell‟algoritmo. o scaleToSquare(points:Array, size:Number):Array Metodo che si occupa di scalare i punti del gesto che riceve come primo argomento. Lo si scala addatandolo al quadratto di riferimento descritto nel terzo passo dell‟algoritmo determinato dal secondo argomento, „size‟. Questa dimensione è definita nella costante della classe SQUARE_SIZE. 60 Capitolo 4 – Gesti o translateToOrigin(points:Array):Array Metodo che si occupa di spostare tutti punti del gesto alle coordinate (0,0). Calcola il centroide del gesto che riceve come argomento e lo sottrae a tutti i suoi punti. o recognize(points:Array):DollarResult Metodo che si occupa di confrontare il gesto che riceve come argomento e restituisce il risultato del confronto. Questo metodo si occupa di fare tutti i passi dell‟algoritmo e fa il confronto con ognuno dei modelli trovati nella libreria di gesti. La classe possiede altri metodi interni che utilizza per il calcolo dei valori utili per completare i passi dell‟algoritmo, ma per poter utilizzare questa classe bastano i metodi appena elencati. Fino a questo punto ci si è concentrati sullo studio dei diversi elementi che servono per la creazione degli strumenti base di ActionScript per lo sviluppo di applicazioni multitouch. Nel capitolo seguente verrà descritto il processo di sviluppo ed elaborazione di questi strumenti. 61 Capitolo 5 Sviluppo di strumenti basi di ActionScript per applicazioni Multitouch In questa sezione si illustrerà il processo di sviluppo di due strumenti fatti per la creazione di applicazioni multitouch: dei componenti tattili che si possono utilizzare in Flash, e delle classi per la creazione ed il rilevamento dei gesti sullo schermo. 5.1 Sviluppo di componenti tattili Si è deciso di sviluppare alcuni componenti che si pensa siano utili nel contesto di applicazioni interattive. In seguito si vedrà il processo e le caratteristiche di ogni componente sviluppato ed allo stesso tempo si daranno alcune raccomandazioni per evitare certi errori trovati nel processo di sviluppo. 5.1.1 Componente: TouchButton Figura 28. Il componente TouchButton 62 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Il tasto (Figura 28) è stato scelto come il primo componte da sviluppare per diversi ragioni. Prima di tutto, il fatto di premere un tasto per realizzare azioni semplici è un gesto molto diffuso tra la gente comune e non solo tra utenti di nuove tecnologie. Quindi un componente con le funzionalità di un tasto è di sicuro un elemento che verrá utilizzato ed integrato facilmente in tante applicazioni multitouch. 5.1.1.1 Apparenza Il componente ha degli skin di forma circolare, che assomigliano alla punta delle dita, per addatarsi meglio alla parte del dito che entra in contatto con lo schermo. Per questo componente sono stati utilizzati nove skin diversi, per rappresentare gli stati di „non premuto‟, „premuto‟, „sopra‟, „non abilitato‟, „selezionato e non premuto‟, „selezionato e premuto‟, „selezionato e spora‟, „selezionato e non abilitato‟ ed in fine lo skin per il focus „focus Skin‟. Tutti gli skin disegnati si possono vedere nella Figura 29, che mostra il frame di edizione del componente. Figura 29. Gli asset per il componente „TouchButton‟ 5.1.1.2 Proprietà Il componente estende la classe „LabelButton‟ in quanto questa classe possiede già delle proprietà utili alle funzionalità del componente in questione, proprietà come il „Label‟ del 63 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch componente, oppure „mouseState‟ che indica lo stato del componente a seconda delle azioni del mouse: se il puntatore è sopra il tasto, se il tasto è stato cliccato, o „enabled‟ che indica se il componente è abilitato. In questo modo basta aggiungere le funzioni ed il codice necessario per fare sì che il componente reagisca agli eventi di tocco ed integrare questa parte con la struttura dei componenti ed il modello d‟invalidazione. Quindi il componente „TouchButton‟ possiede tutte le proprietà del componente „LabelButton‟ ed altre due che sono state aggiunte per integrare le nuove funzionalità. o buttonState:String; Questa proprietà si utilizza per sapere lo stato attuale del tasto. Può avere due valori diversi: „up‟, „down‟ che rappresentano i due stati principali del tasto. Nel codice ci sono le due funzioni „get‟/‟set‟ che permettono di avere accesso alla proprietà, come mostrato in Figura 30. Dunque per accedere alla proprietà si esegue l‟istruzione: „nomeIstanza.buttonState‟ dove „nomeIstanza‟ sarà il nome dell‟istanza dichiarato nello stage. Figura 30. Funzione get e set per il componente „TouchButton‟ Nella funzione „set‟ si fa notare il cambio del valore della variabile „mouseState‟. Questa variabile è una proprietà della classe base „LabelButton‟ che controlla lo stato del bottone ed anche lei possiede le sue funzioni „get‟ e „set per accedere e modificare il suo valore. Nel momento in cui si cambia questa proprietà, la funzione „set‟ fa un‟invalidazione di STATO, selezionando il rispettivo per rappresentare lo stato attuale del componente. Per sapere quale skin selezionare, si verificano la variabile „mouseSate‟, ed un‟altra proprietà ereditata, „selected‟, che come indica il nome, indica se il componente è selezionato o meno. La classe base ha già dei metodi che gestiscono lo stato del componente rispetto alle azione dell‟utente con il mouse, questo stato è controllato con la proprietà „mouseState‟. Però dato che il componente TouchButton non interagisce con questo dispositivo, si è utilizzato la proprietà „buttonState‟ per cambiare 64 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch contemporaneamente entrambi i valori della proprietà „mouseState‟ in questo modo si utilizzano i metodi della classe base che lavorano già con il modello d‟invalidazione, risparmiando così tempo e logica di programmazione. o touchMode:Boolean = true; La proprietà touchMode è una variabile booleana che indica se il componente è abilitato per ricevere eventi di tipo touch o meno e per accedervi ci sono i metodi „get‟ e „set‟. Nel momento in cui la proprietà viene cambiata, si fa un‟invalidazione di STATO, come si vede nella Figura 31. L‟istruzione: „nomeIstanza.touchMode‟ permette di accedere alla proprietà dell‟istanza nello stage. Figura 31. Metodo „set‟ della prorpietà touchMode e l‟invalidazione di STATO. Dunque nel momento in cui il componente non si trova più in modalità Touch, bisogna togliere i „listeners‟ agli eventi touch. Quindi nel momento in cui si verifica l‟invalidazione di tipo STATO, si chiama il metodo „setupListeners‟ che si occupa di registrare il componente per essere notificato o meno per gli eventi touch. Questa invalidazione viene fatta nello stesso modo in tutti i componenti sviluppati. Figura 32. Collegamento dei componenti per fare il debug. Controllato dalla proprietà „_touchMode‟ Questa proprietà è anche utilizzata in tutti i componenti per per gestire il debug. Il suo valore deve essere assegnato prima di eseguire l‟applicazione per fare il collegamento o meno con il tracker per ricevere i dati. In una applicazione normale, è l‟applicazione stessa che deve occuparsi del collegamento con il tracker, ma per lo 65 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch sviluppo dei componenti serve provare le funzionalità quindi si deve accedere all‟informazione inviata dal tracker. Il collegamento viene fatto nella funzione costruttrice di ogni componente, come si può vedere nel caso particolare del componente TouchButton nella Figura 32. Le altre proprietà sono quelle ereditate dalla classe „LabelButton‟ e quindi la sua descrizione può essere trovata nella documentazione di questa classe. 5.1.1.3 Metodi o configUI() Questo metodo unicamente chiama la funzione della classe base, poiché inizialmente non bisogna aggiungere nessun‟elemento nel display. o setupListeners() Questo metodo gestisce il registro del componente per essere notificato degli eventi di tipo touch. Questo dipende dalla proprietà touchMode, ma deve essere gestito se il componente cambia da uno stato abilitato ad uno non abilitato. Questo stato viene controllato dalla proprietà „enabled‟ che tutti i componenti condividono ed è definita nella classe UIComponent. Quindi il metodo verifica le due proprietà per sapere quando registrare o meno il componente. (Figura 33). Figura 33. Metodo setupListener per il componente TouchButton Lo stesso tipo di verifica per aggiugnere o togliere il registro agli eventi è stato fatto per tutti i componenti, dato che per tutti bisogna gestire la stessa situazione. In alcuni casi bisogna fare attenzione con gli eventi dei subcomponenti. Queso caso verrà descritto con il componente TouchKeyboard. 66 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch o draw() Il codice utilizzato per il componente è stato il seguente: Figura 34. Gestione dell‟invalidazione di stato per il componente TouchButton nel metodo draw() Questo metodo è la ridefinizione del metodo „draw()‟ della classe base, che deve gestire l‟invalidazione di tipo STATO nel momento in cui si modifica la proprietà touchMode (Figura 34). o downHandler() Figura 35. Metodo „downHandler()‟ del componente TouchButton Questo metodo gestisce l‟evento di tipo TUIO_DOWN, aggiunge il componente per poter ricevere le notifiche degli eventi TUIO e notifica l‟evento BUTTON_DOWN, della classe „ComponentEvent‟, l‟ evento TOUCH_BUTTON_DOWN, della classe „TouchButtonEvent‟. Dopo di che modifica la proprietà „buttonState‟ assegnadole il valore „down‟, che come è stato spiegato prima, fa partire il modello d‟invalidazione per gestire il cambio di skin del componente. 67 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch o upHandler() Questo metodo si occupa della notifica dell‟evento TOUCH_BUTTON_UP, della classe „TouchButtonEvent‟, e modifica la proprietà „buttonState‟ assegnadole il valore „up‟, che così come fa il metodo „downHandler‟ fa partire il modello d‟invalidazione che gestisce il cambio dell‟aspetto del componente. 5.1.1.4 Stili Gli stili utilizzati da questo componente sono gli stessi del componente „LabelButton‟, quindi in seguito si fa soltanto un elenco di loro: upSkin: utilizzato per l‟apparenza del tasto quando non è premuto. downSkin: utilizzato quando il tasto è premuto. overSkin: utilizzato quando, per esempio il puntatore del mouse si trova sopra del componente disabledSkin: utilizzato quando il component non è abilitato. selectedDisabledSkin: utilizzato quando il component è selezionato e non abilitato. selectedUpSkin: utilizzato quando il tasto è selezionato però non è premuto. selectedDownSkin: utilizzato quando il tasto è selezionato e premuto. selectedOverSkin: utilizzato quando il component è selezionato ed un puntatore, per esempio, si trova sopra di lui. focusSkin: utilizzato per indicare che il componente ha il „focus‟ su di lui. focusRectSkin: lo skin utilizzato per racchiudere il componente in un rettangolo, per indicare lo stato di „focus‟. Questi stili vengono di solito utilizzati quando si usa il componente button, però per esempio nel caso delle applicazioni touch, con schermi tattili, gli skin che rappresentano gli stati di „over‟ non vengono mai utilizzati. In quanto non è possibile rilevare la mano o il dito che entri in contatto con lo schermo, lo stato „over‟ non è mai raggiunto. Tuttavia questi stili sono stati inseriti per poter fare le prove usando il mouse come dispositivo di input. 68 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch 5.1.1.5 Eventi Per il componente TouchButton fa la notifica di 3 eventi. Uno dalla classe „ComponentEvent‟: l‟evento „BUTTON_DOWN‟. Tuttavia per estendere le funzioni, e per avere un insieme di eventi per il componente, si ha creato una classe personalizzata di eventi. Questa classe contiene le definizioni per due eventi: - TOUCH_BUTTON_DOWN: Indicare il momento quando il tasto è stato premuto - TOUCH_BUTTON_UP: Indica quando il tasto è stato rilasciato. La classe non possiede nessuna proprietà. Al massimo una proprietà che potrebbe essere aggiunta sarebbe lo stato attuale del tasto, però questo variabile è stata già definita come proprietà del componente e quindi si può reperire direttamente dall‟istanza dalla quale si vuole sapere l‟informazione. 5.1.2 Componente: TouchNumericStepper Il componente TouchNumericStepper (Figura 36) è stato sviluppato come un‟estensione del componente di flash: NumericStepper. La funzionalità è la stessa del componente di partenza e quindi la programmazione si è basata nell‟aggiungere la parte della risposta tattile del componente alle azioni dell‟utente. Figura 36. Il componente TouchNumericStepper 5.1.2.1 Apparenza Gli skin utilizzati per questo componente sono stati gli stessi che per il componente NumericStepper di Flash. Semplicemente si hanno modificato le forme dei tasti ed le sue dimensioni per renderli adeguati per il suo uso in un‟applicazione tattile (Figura 37). Come 69 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch con il componte precedente si sono utilizzati skin per i quattro diversi stati, dei quali lo stato di over di nuovo è stato usato per le prove fatte con il dispositivo mouse. Questo componente contiene un subComponente: TextInput, al quale non è stato fatto cambiamento alcuno. Figura 37. Gli asset per il componente TouchNumericStepper 5.1.2.2 Proprietà Questo componente contiene unicamente una proprietà nuova, touchMode, invece tutte le altre prorpietà sono ereditate dalla classe base „NumericStepper‟. o touchMode:Boolean = true; La proprietà touchMode è una variabile Booleana che indica se il component è abilitato per ricevere eventi di tipo touch o meno, e per accedere e modificarne anche ci sono i metodi „get‟ e „set‟. Nel momento che la proprietà viene cambiata, si fa un‟invalidazione di STATO. Il valore di default è true, quindi il componente riceve gli eventi di tipo touch, per default. 70 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch 5.1.2.3 Metodi o configUI() Questo metodo fa la chiamata al metodo configUI() della classe base e poi assegna le dimensioni dei tasti di aumento e diminusione del del valore componente o setupListeners() Questo metodo gestisce il registro del componente per essere notificato degli eventi di tipo touch. Questo dipende dalla proprietà touchMode, ma anche deve essere gestito se il componente cambia di uno stato abilitato ad uno non abilitato (proprietà „enabled‟). La sua codifica è simile a quella di tutti gli altri componenti, cambiando unicamente l‟istanze che sono state registrate. (Figura 38). Figura 38. Metodo setupListeners() per il componente TouchNumericStepper o draw() Override del metodo della classe base, nella quale si aggiunge soltanto la gestione dell‟invalidazione di tipo STATO quando si modificano sia la proprietà „enabled‟ che la proprietà „touchMode‟. Il metodo è stato definito uguale che per il componente TouchButton (Figura 34). o downTouchHandler() Questo metodo viene chiamato nel momento che si schiaccia uno dei due tasti del componente (Figura 39). Prima si registra il tasto che sia stato schiacciato per 71 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch ricevere gli eventi TUIO – lo si fa con il metodo TUIO.listenForObject() -, dopo di che si controlla quale dei due tasti è stato premuto per poter aumentare o diminuire il valore del stepper a seconda del caso. Questo metodo è stato una modifica del metodo della classe base che si occupa di gestire la stessa situazione per un evento del dispositivo mouse. In questo modo, modificando soltanto le parti pertinenti, è possibile utilizzare le funzioni già elaborate per la classe base che già gestiscono tutta la funzionalità principale del componente NumericStepper. Figura 39. Metodo downTouchHandler del componente TouchNumericStepper o upTouchHandler() Questo metodo si occupa di cambiare lo stato del tasto assegnando il valore di „up‟. Per questo componente è stato necessario agigugnere una condizione per gestire il tipo di elemento che veniva rilevato come „target‟ dell‟evento, il quale non sempre risultava di essere di tipo „Button‟. Siccome il metodo „setMouseState()‟ è solo definito per questa classe, nel momento che il target non era di tipo „Button‟ accadeva un errore. L„istruzione „if‟ permette di gestire questa situazione (Figura 40). 72 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Figura 40. Metodo upTouchHandler e l‟istruzione „if‟ per gestire l‟errore del tipo di elemento del target dell‟evento. o drawLayout() Figura 41. Metodo „drawLayout()‟ del componente TouchNumericStepper. Si gestisce l‟allocazione dei pulsanti Questo metodo è un override della funzione della classe base la quale bisognava modificare per gestire le nuove dimensioni degli elementi, i tasti ed il campo del testo. Il metodo si occupa di allocare adeguatamente ogni elemento, e di cambiare la dimensione del testo, nel momento in cui le dimensioni del componente vengono modificate. Alla fine del metodo si chiamano i metodi „drawNow()‟ dei pulsanti e del campo di testo per ridisegnarli ed assicurarsi di vedere i cambiamenti (Figura 41). 73 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch 5.1.2.4 Stili Essendo che il componente estende la classe NumericStepper, gli stili utilizzati sono gli stessi della classe base. Ma soltanto si fa la definizione degli stili dei tasti poiché gli skin del campo di visualizzazione del valore non sono stati modificati. In seguito vengono elencati: downArrowDisabledSkin: skin utilizzato per il tasto che diminuisce il contatore quando il componente non è abilitato. downArrowDownSkin: utilizzato per il tasto che diminuisce il contatore quando viene premuto. downArrowOverSkin: utilizzato poer il tasto che diminuisce il contatore quando il mouse è sopra del tasto. downArrowUpSkin: utilizzato per il tasto che diminuisce il contatore quando è abilitato e non c‟è nessun‟azione su di lui. upArrowDisabledSkin: utilizzato per il tasto che aumenta il contatore quando il componente non è abilitato. upArrowDownSkin: utilizzato per il tasto che aumenta il contatore quando viene premuto. upArrowOverSkin: utilizzato poer il tasto che aumenta il contatore quando il mouse è sopra del tasto. upArrowUpSkin: utilizzato per il tasto che aumenta il contatore quando è abilitato e non c‟è nessun‟azione su di lui Ci sono altri stili, che vengono dalla classe base, che però non è stato necessario modificarli poiché non sono necessari per la funzionalità tattile del componente. 5.1.2.5 Eventi Gli eventi sono gli stessi che per il componente NumericStepper, in vista che il componente non fa nessun‟azione diversa dal componente base. Nel momento in cui il valore del contatore viene cambiato viene notificato un evento di tipo „Event.CHANGE‟. Tutta l‟informazione rispettiva si può trovare nella documentazione della classe base. 74 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch 5.1.3 Componente:TouchSlider Il componente TouchSlider (Figura 42) è stato sviluppato anche estendendo la classe base del componente di Flash: „Slider‟. Questa componente, insieme al componente TouchNumericStepper, perchè ls sue funzioni sono molto utile nel contesto di un‟applicazione tattile. Il gesto di „trascinare‟ („drag‟ dalla sua traduzione in inglese) è in generale molto naturale da fare da parte degli utenti. Ormai ci sono tanti dispositivi che usano questo gesto Figura 42. Il componente TouchSlider 5.1.3.1 Apparenza Figura 43. Gli asset per il componente TouchSlider Per questo componente è stato necessario creare degli skin per rimpiazzare gli skin utilizzati dal componente base. Per la barra, o track, sono stati creati duw skin diversi, uno per lo stato „abilitato‟ e l‟altro quando il componente è nello stato „non abilitato‟. Invece per l‟indicatore, o thumb, servono tutti i quattro skin diversi per gli stati di „premuto‟, „non premuto‟, „over‟ e „non abilitato‟ (Figura 43). Di nuovo, lo skin di „over‟ è usato per quando il componente sia usato con il dispositivo mouse. Le dimensioni sono state pensate 75 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch per dare uno spazio sufficente per toccare il componente, ma allo stesso tempo non troppo grande per non occupare più spazio del necessario – sopratutto per il track-. 5.1.3.2 Proprietà Il componente possiede solo una proprietà diversa alla sua classe base, per la funzionalità interattiva non c‟era bisogno di utilizzarne altre. o touchMode:Boolean = true; Questa proprietà, allo stesso modo che negli altri componenti, è una variabile Booleana che indica se il component è abilitato per ricevere eventi di tipo touch o meno, e per accedere e modificarne anche ci sono i metodi „get‟ e „set‟. Nel momento che la proprietà viene cambiata, si fa un‟invalidazione di STATO. 5.1.3.3 Metodi I metodi del componente TouchSlider che si occupano della parte di funizonalità sono pratticamente gli stessi della sua classe base. I metodi nuovi sono quelli che gestiscono la parte d‟interattivita e di risposta agli eventi touch e sono versioni modificati da quelle trovati nella classe „Slider‟ o configUI() Figura 44. Metodo confiGUI() del componente TouchSlider In questo metodo si chiama la funzione configUI() della classe base che si occupa d‟inserire gli elementi iniziali. Invece su questo metodo si danno le dimensioni iniziali per l‟indicatore e la barra (Figura 44). 76 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch o setupListeners() In questo metodo vengono registrati a seconda del caso, i listeners per il track e per il thumb del componente. La gestione viene fatta uguale che con i due componenti precedenti: dipende dalle proprietà „enabled‟ e „touchMode‟. o draw() Questo metodo è un override della funzione della classe base. Alla quale è stata aggiunta la gestione dell‟invalidazione di tipo STATO, che avviene quando la proprietà „touchMode‟ viene cambiata, chiamando il metodo „setupListeners‟. o downTouchHandler() Figura 45. Metodo downTouchHandler del componente TouchSlider Nel componente, sia la barra che l‟indicatore, entrambi sono subcomponenti di tipo Button. Quindi in questa funzione viene innanzitutto controllato che il target dell‟evento sia uno di questi due elementi. Dopo di che si registra l‟elemento per ricevere gli eventi TUIO e lo si cambia la proprietà „mouseState‟ utilizzando il metodo publico della classe „setMouseState()‟. Se è stato l‟indicatore ad essere premuto, lo si registra per rispondere agli eventi TUIO_MOVE e TUIO_UP, necessari per il trascinamento e poi per il rilascio dell‟indicatore. Invece se è la barra ad essere premuta, si calcola la posizione dov‟è stata toccata e si sposta il valore dello slider su quella posizione (Figura 45). 77 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Questo metodo prima verifica che il target dell‟evento sia stato l‟indicatore o la barra e dopo determina quale dei due è stato premuto e lo salva su una variabile interna, „pressedButton‟. Dopo di che, se è stato l‟indicatore ad essere premuto, si fa la notifica dell‟evento „SliderEvent.THUMB_PRESS‟, se invece è stata la barra ad essere premuta, si calcola il punto di contatto per assegnare il nuovo valore al componente e dopo si fa la notifica dell‟evento „SliderEvent.CHANGE‟ o upTouchHandler() Questo metodo si occupa di cambiare lo stato dell‟elemento per cambiare lo stile. Anche per questo componente è stato necessario controllare l‟oggetto a cui fa riferimento il target dell‟evento poiché a volte veniva riferenziato un elemento diverso ed al provare cambiare lo stato dell‟elemento, si produceva un errore. Per evitarlo si ha utilizzato un‟istruzione „if‟ che controlla il target, verificando che sia la barra oppure l‟indicatore. o doDragTouchVersion() Questo metodo è una versione modificata del metodo „doDrag‟ della classe base viene chiamata con lo spostamento del dito per trascinare l‟indicatore dello slider (con l‟evento TUIO_MOVE). o thumbReleaseTouchHandler() Questo metodo è la versione modificata del metodo „thumbreleaseHandler‟ della classe base, il quale viene chiamato nel momento che l‟indicatore viene rilasciato dall‟utenteIl metodo si occupa di togliere il registro dei listeners per gli eventi TUIO_MOVE e TUIO_UP. 5.1.3.4 Stili Gli stili sono gli stessi della sua classe base, e vengono elencati in seguito: thumbUpSkin: lo skin che viene utilizzato nello stato normale dell‟indicatore, senza che nessun evento sia stato notificato. thumbOverSkin: viene utilizzato quando il mouse, per esempio, si trova sopra dell‟indicatore. thumbDownSkin: viene utilizzato quando l‟indicatore è premuto. 78 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch thumbDisabledSkin: viene utilizzato per l‟indicatore quando il componente non è abilitato. sliderTrackSkin: lo skin utilizzato per la barra quando il componente è abilitato. sliderTrackDisabledSkin: lo skin utilizzato per la barra quando il componente non è abilitato tickSkin: skin utilizzato per il marchio dei tick (questo viene abilitato con una delle proprietà della classe base del componente) Gli altri stili non sono stati modificati è quindi hanno lo stesso valore definito nella classe base, perciò non vengono elencati qua. 5.1.3.5 Eventi Gli eventi notificati da questo componente sono gli stessi della componente slider: „SliderEvent.THUMB_PRESS‟, che viene notificato appena si preme l‟indicatore; „SliderEvent.CHANGE‟, che viene notificato quando il valore dello slider cambia sia per un tocco nella barra che per un cambio diretto alla proprietà „value‟; l‟evento „SliderEvent.THUMB_DRAG‟ che viene notificato mentre l‟indicatore è trascinato; e „SliderEvent.THUMB_RELEASE‟, notificato quando l‟indicatore è rilasciato. 5.1.4 Componente:TouchKeyboard Quest‟ultimo componente estende direttamente la classe „UIComponent‟, ma utilizza un sub-componente: TouchButton. Il modo in cui questo componente funziona è un po‟ diverso dagli altri, nel senso che inizialmente il componente è un unico tasto, noto come „openButton‟, che rappresenta la tastiera nel suo stato non attivo. Poi, nel momento in cui questo tasto è premuto, la tastiera si attiva e viene visualizzata. Il componente cambia completamente lo skin utilizzato a seconda del suo stato „attivo‟ (Figura 46).Una volta che il componente si trova nel suo stato attivo, si può disattivare premendo il tasto di chiusura, che si trova nella parte bassa a destra della tastiera, col simbolo di spegnimento. 79 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Figura 46. Il componente TouchKeyboard Questo componente implementa anche una piccola funzione multitouch: come in una tastiera reale, quando si tiene premuto il tasto „shift‟, le lettere vengono scritte come lettere maiuscole, oppure viene scritto il carattere secondario, se esiste. Nel momento in cui viene premuto il tasto „shift‟ le lettere nella tastiera diventano maiuscole, e nei tasti con caratteri secondari viene evidenziato il secondo carattere, cambiando il formato del carattere (colore e dimensioni). Dopo di che nel momento di rilasciarlo, i tasti ritornano al suo formato originale. Un‟altra funzione simile alle tastiere reali è il tasto „Caps Lock‟, il quale nel momento di essere premuto, fa diventare tutte le lettere maiuscule (anche visualmente) tranne quelle dei tasti che contengono caratteri secondari. Lo scopo di questo componente è quello di implementare una funzione multitouch, che anche se solo viene utilizzata per una funzione molto semplice (il „shift‟), fa vedere il funzionamento di questi tipi di sistemi ed i suoi vantaggi: la possibilità di realizzare azioni contemporaneamente. 5.1.4.1 Apparenza Questo componente possiede un gran numero di asset. Sono stati creati gli skin per i quattro diversi stati, tutti e quattro per ogni tipo di tasto utilizzato. Più il fondo della tastiera. In seguito si illustreranno gli asset per ogni gruppo di tasti: 80 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch o „OPEN BUTTON‟ Figura 47. Il tasto openButton della tastiera Il tasto open button appartiene alla classe TouchButton e quindi utilizza quattro simboli diversi. Gli stessi quattro simboli si sono utilizzati per rimpiazzare gli otto asset del componente TouchButton, usando per esempio l‟asset „upSkin‟ sia per lo stato „selezionato‟ che „non selezionato‟ (gli asset del componente touchButton sono nella Figura 29). Lo stesso è stato fatto per gli altri tasti della tastiera che fanno parte della stessa classe TouchButton. Figura 48. Gli asset per il tasto „openButton‟ Questo tasto ha un‟immagine di una tastiera. È visualizzato quando la tastiera non è attiva e in questo modo il componente non occupa spazio inutilmente. 81 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch o KEYBOARD BACKGROUND Figura 49. L‟asset per lo sfondo della tastiera Questo asset è utilizzato come sfondo della tastiera. Nel contesto della display list, questo simbolo è il contenitore di tutti i tasti della tastiera, tranne il tasto „open button‟. Nella Figura 49, è possibile vedere la dimensione della tastiera rispetto alla dimensione del tasto d‟attivazione. Questo simbolo è stato inserito con questi dimensioni per una ragione importante: essendo il contenitore di tutti gli altri tasti della tastiera, le variazioni nelle dimensioni di questo simbolo vengono anche applicate su tutti gli elementi che contiene. Siccome tutti gli altri asset sono stati creati con le sue dimensioni reali, se questo componente avesse inizialmente delle dimensioni più piccole, nel momento di cambiare le sue misure per rendere la tastiera di una dimensione reale, l‟aumento nelle dimensione verrebbe anche applicato a tutti i suoi elementi, rendendoli più grandi della loro misure originale. Dunque, le dimensioni di questi tipi di asset deve essere relativo al suo contenitore: se dall‟inizio si sa che al contenitore verrà applicato un cambio nelle sue dimensioni, tutti i suoi elementi devono essere createicon delle misure apposite, in modo che nel momento del cambiamento tutti gli elementi abbiano le misure desiderate. Nel caso di questo componente, tutti gli asset sono stati inseriti con le loro dimensioni originali, e non viene fatto nessun cambio nelle dimensioni del componente. 82 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch o „BASE BUTTON‟ Figura 50. Gli asset per i tasti dei caratteri e due esempi di tasti Questi tasti, sempre della classe TouchButton, contengono tutti i caratteri della tastiera. Oltre ai caratteri principali, per i tasti che contengono un carattere secondario è stato aggiunto un altro campo di testo per la loro visualizzazione. o „FUNCTION BUTTON‟ Figura 51. Gli asset per i tasti di funzione 83 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Questi tasti sono tutti quelli che servono per realizzare delle funzioni nella tastiera, per esempio il tasto „shift‟ ovvero il tasto „intro‟. Anche questi fanno parte della classe TouchButton L‟uso di questi asset esiste per tutti i tasti di funzioni che possiedono dimensioni diverse tra di loro, anche per assomigliare l‟apparenza di una tastiera reale. Dipendendo del tasto, si è anche aggiunto un campo di testo per mettere il nome della funzione. o „CLOSE BUTTON‟ Il tasto di chiusura e disattivazione della tastiera fa parte della classe TouchButton, e la si trova nella parte bassa a destra della tastiera. Figura 52. Gli asset per il tasto „close button‟ della tastiera 84 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch 5.1.4.2 Proprietà Le proprietà per questo componente sono in generale tutte quelle per controllare il suo funzionamento. Soltanto alcune proprietà sono accessibile per sapere lo stato attuale del componente (per esempio „Attivo‟/‟Disattivo‟). Molte delle informazioni utili della tastiera, come per esempio il tasto che è stato premuto, sono reperibile dagli eventi, che verranno illustrate più avanti. o const OPEN_CLOSE:String = "openCloseKeyboard"; Questa costante serve per invalidare lo stato „attivo‟/‟disattivo‟ del componente e viene utilizzata nel momento in cui sia il tasto d‟attivazione del componente che il tasto di chiusura siano schiacciati (proprietà isActive). Nel metodo set di questa proprietà viene fatta l‟invalidazione di tipo OPEN_CLOSE. o touchMode:Boolean = true; La proprietà touchMode è una variabile Booleana che indica se il componente è abilitato per ricevere eventi di tipo touch o meno, e per accederevi e modificarla ci sono i metodi „get‟ e „set‟. Nel momento che la proprietà viene cambiata, si fa un‟invalidazione di STATO. Il valore di default è true. o isActive:Boolean = false; Questa proprietà è utilizzata per gestire lo stato „attivo‟/‟disattivo‟ del componente. Possiede un valore „false‟ per default poiché la tastiera è disattiva. Viene modificata nel momento in cui il tasto d‟attivazione, open_button, oppure quello di chiusura vengono premuti. Quando questo accade, si fa un‟invalidazione di tipo OPEN_CLOSE, come si può evidenziare nella Figura 53. Figura 53. Definizione per la proprietà „isActive‟ del componente TouchKeyboard 85 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch o capsLockOn:Boolean = false; Proprietà utilizzata per indicare lo stato del tasto „Caps Lock‟. Il suo valore viene inviato come parametro dell‟evento ogni volta che un tasto viene premuto. Figura 54. Metodo set della proprietà capsLockOn Nella Figura 54 si può vedere che nel momento di cambiare il valore della proprietà si fa un‟invalidazione di tip STYLES, questa si fa perchè questa proprietà controlla il modo di vedere i caratteri dei tasti. Un cambio del suo valore quindi significa un ridisegno della parte visuale di questi tasti. o ctrlOn:Boolean = false; Proprietà utilizzata per indicare lo stato del tasto „Ctrl‟. Il suo valore viene inviato come parametro dell‟evento ogni volta che un tasto viene premuto. o shiftOn:Boolean = false; Proprietà utilizzata per indicare lo stato del tasto „Shift‟. Il suo valore viene inviato come parametro dell‟evento ogni volta che un tasto viene premuto. o altOn:Boolean = false; Proprietà utilizzata per indicare lo stato del tasto „Atl‟. Il suo valore viene inviato come parametro dell‟evento ogni volta che un tasto viene premuto. 5.1.4.3 Metodi o configUI() Questo metodo chiama la funzione configUI() della classe base. Dopo l‟inizializzazione il tasto „open_button‟ gli assegna gli stili e poi l‟aggiunge nella display list. 86 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Figura 55. Metodo configUI() del componenteTouchKeyboard Il metodo „copyStylesToChild‟ è quello che si occupa di assegnare al tasto gli stili definiti all‟interno della costante OPEN_BUTTON_STYLES. Per tutti i tasti è stato definito una costante come questa nella quale si definiscono gli stili che si devono assegnare al tasto, i valori si prendono dall‟oggetto „defaultStyles‟ del componente. o TouchKeyboard() Metodo costruttore che si occupa di inizializzare tutti i bottoni delle funzioni della tastiera, insieme a tutte le altre variabili che servono per creare la tastierat. Inoltre crea i formati di testo che devono avere i tasti quando cambia la funzionalità al premere il tasto „shift‟ o setupKeyboardLayout() Questo metodo si occupa di inizializzare tutti i tasti della tastiera assegnando le dimensioni giuste e li alloca nelle posizioni giuste. Si occupa anche di aggiungere i caratteri nel label di ogni tasto, ed i caratteri secondari su quelli che l‟hanno, e di applicare gli stili rispettivi ai tasti di funzione, dei caratteri, d‟attivazione e di chiusura. o setupMouseListeners() Questo metodo che si occupa di registrare i tasti (d‟attivazione, chiusura, dei caratteri e quelli di funzione) all‟evento MOUSE_DOWN del dispositivo Mouse, per gestire la risposta del componente quando i tasti vengono premuti con il mouse. 87 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch o isEnabled() Questo metodo è stato necessario implementarlo per gestire il cambio dagli stati „abilitato‟ e „non abilitato‟. Siccome ogni tasto è un componente a sé, bisogna cambiare non solo lo stato del componente generale ma anche di ogni subcomponente. Quando la proprietà „enabled‟ del componente viene attivata, si abilitano tutti i tasti, ed invece quando il componente viene disabilitato, tutti i subomponenti divengono „non abilitati‟. In questo modo si assicura la gestione degli eventi di tocco definiti nella classe dei tasti: TouchButton. o setupTouchListeners() Questo metodo viene chiamato dopo del metodo isEnabled(), e si occupa di gestire la registrazione dei tasti agli eventi, fatto che dipende delle proprietà „enabled‟ e „touchMode‟, così come i componenti precedenti. La registrazione deve essere fatta su ogni tasto della tastiera. Anche su questo metodo viene cambiata la proprietà „touchMode‟ di ogni tasto, per assicurare la gestione degli eventi, così com‟è stato fatta con la proprietà „enabled‟. o draw() Questo metodo gestisce le invalidazioni di tipo STATE, nella quale si chiama il metodo isEnabled(), l‟invalidazione di tipo STYLES, che se sono stati schiacciati i tasti „shift‟ o „CapsLock‟ chiama il metodo „capsLockFunction()‟, Figura 56; l‟invalidazione di tipo OPEN_CLOSE, che dipendendo della proprietà „isActive‟ chiama il metodo addRemoveKeyboard(). Nella parte finale di questo metodo, si fa la chiamata al metodo drawNow() di ogni subcomponente. Figura 56. Verifica dell‟invalidazione di tipo STYLES e chiamata al metodo „capsLockFunction()‟ dopo verificare si è stato schicciato il tasto „CapsLock‟ o „shift‟ 88 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Questo metodo è molto importante innanzitutto per i componenti che contengono come asset altri componenti. La sua chiamata assicura che il subcomponente sia aggiornato adeguatamente, assicurando la sua corretta visualizzazione. o touchDownHandler() Questo metodo si occupa di gestire la funzione della tastiera a seconda del tasto che è stato premuto per mezzo di un‟azione interattiva (Evento di tocco). Così nel momento che si preme un tasto si fa la notifica di un evento di tipo TouchKeyboardEvent. KEY_DOWN , passando gli argomenti rispettivi a seconda del tasto in funzione. Un esempio della verifica che fa il metodo s‟illustra nella Figura 57. Figura 57. Esempio della verifica per il tasto „shift‟. Come si può vedere nella figura precedente, prima si controlla che tasto sia stato premuto, questo valore viene visualizzato nella variabile „myButton‟ e dopo a seconda del tipo di tasto si calcolano i valori che devono essere passati come argomenti per creare l‟evento di tipo KeyboardEvent.TOUCH_KEY_DOWN. o touchUpHandler() Questo metodo, in un modo simile al precedente, si occupa di gestire la funzionalità della tastiera nel momento che un tasto è rilasciato. Facendo la notifica di un evento di tipo TouchKeyboardEvent. KEY_UP. o mouseDownHandler() Questo metodo si occupa di gestire gli eventi notificati sulla tastiera quando un tasto qualsiasi è schiacciata con il dispositivo Mouse. La funzionalità dipende del tasto che è stato premuto e le informazioni rispettive sono tutte reperibili dall‟evento TouchKeyboardEvent. 89 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch o mouseUpHandler() Questo metodo si occupa di gestire gli eventi di tipo MOUSE_UP, e fa lo stesso che il metodo touchUpHandler solo che per il dispositivo mouse. o capsLockFunction() Questo metodo verifica il cambiamento dei caratteri in maiuscole oppure in minuscole, cioè se i tasti „CpasLock‟ o ‟Shift‟ sono stati schiacciati. o addRemoveKeyboard() Questo metodo si occupa di togliere oppure di aggiungere la tastiera nel display List, e dipende dal fatto se la tastiera si trova in uno stato attivo o no (stato che viene cambiato quando si premono i tasti d‟attivazione e di chiusura del componente). 5.1.4.4 Stili Gli stili defniti sono quelli che vengono utilizzati per ogni tipo di tasto trovato nella tastiera: Open Button, Function Button, Base Button, Close Button. In totale sono quattro skin per ciauscuno di loro, i quali si elencano in seguito. OpenButtonDownSkin: Stile utilizzato per il tasto d‟attivazione della tastiera quando questo è stato premuto. OpenButtonUpSkin: Stile utilizzato per il tasto d‟attivazione della tastiera quando questo si trova in uno stato normale abilitato. OpenButtonOverSkin: Stile utilizzato per il tasto d‟attivazione della tastiera quando l‟indicatore del mouse si trova sopra di questo. OpenButtonDisabledSkin: Stile utilizzato per il tasto d‟attivazione della tastiera quando il componente non è abilitato. CloseButtonUpSkin: Stile utilizzato per il tasto di chiusura della tastiera quando questo si trova in uno stato normale abilitato. CloseButtonDownSkin: Stile utilizzato per il tasto di chiusura della tastiera quando questo è stato premuto. 90 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch CloseButtonOverSkin: Stile utilizzato per il tasto di chiusura della tastiera quando l‟indicatore del mouse si trova sopra di questo. CloseButtonDisabledSkin: Stile utilizzato per il tasto di chiusura della tastiera quando il componente non è abilitato. keyboardSkin: Stile utilizzato per il fondo della tastiera. KeyboardButtonUpSkin: Stile utilizzato per i tasti dei caratteri della tastiera quando questo si trova in uno stato normale abilitato. KeyboardButtonDownSkin: Stile utilizzato per i tasti dei caratteri della tastiera quando questo è stato premuto. KeyboardButtonOverSkin: Stile utilizzato per i tasti dei caratteri della tastiera quando l‟indicatore del mouse si trova sopra di questo. KeyboardButtonDisabledSkin: Stile utilizzato per i tasti dei caratteri della tastiera quando il componente non è abilitato. FunctionButtonUpSkin: Stile utilizzato per i tasti di funzione della tastiera quando questo si trova in uno stato normale abilitato. FunctionButtonDownSkin: Stile utilizzato per i tasti di funzione della tastiera quando questo è stato premuto. FunctionButtonOverSkin: Stile utilizzato per i tasti di funzione della tastiera quando l‟indicatore del mouse si trova sopra di questo. FunctionButtonDisabledSkin: Stile utilizzato per i tasti di funzione della tastiera quando il componente non è abilitato. Tutti i tasti della classe TouchButton usano in totale 8 skin diversi, definiti per la sua classe (Figura 29) però sono stati utilizzati gli stessi 4 skin sia per gli stili „selected‟ che per quelli normali. Per questo componente sono stati utilizzati tanti skin diversi, che si ricorda sono simboli che devono avere l‟opzione di „esportar per actionscript‟ selezionata, quindi è molto importante che nessuno dei simboli abbia un nome di classe uguale ad un‟altro asset del componente oppure agli asset di un altro componente di flash. Nel caso abbiano gli stessi nomi l‟applicazione comunque potrebbe funzionare, però la classe StyleManager avrá dei problemi nel momento di selezionare lo stile da utilizzare, ed utilizzerà unicamente il 91 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch primo skin che troverà tra gli asset di tutti i componenti che si stiano utilizzando per l‟applicazione. All‟interno del codice si è creato una variabile di tipo „Object‟ per ogni tipo di tasto che appartiene alla tastiera. Questi oggetti contengono gli stili che ognuno di loro deve utilizzare come asset. L‟oggetto „defaultStyles‟ del componente TouchKeyboard, possiede nel suo interno le definizioni di tutti gli stili utilizzati, quindi nel momento della creazione della tastiera si assegnano gli stili rispettivi per i tasti del componente 5.1.4.5 Eventi Per la tastiera tattile è stata definita una classe per i suoi eventi la quale estende la classe base „KeyboardEvent‟. Questa classe define due eventi: TOUCH_KEY_UP e TOUCH_KEY_DOWN che rappresentano i due stati di qualunque elemento della tastiera. Come questa classe estende la classe degli eventi di Flash utilizzata per la tastiera reale, ereda le sue proprietà, quindi è possible sapere gli stati dei tasti di funzione attraverso di loro. In questa classe è stata definita unicamente una proprietà adizionale: o charValue: contiene la lettera oppure il simbolo del tasto che è stato premuto. Nel momento che il tasto premuto è stato uno dei tasti di funzione, lo si assegna il valore vuoto (charValue = ‟‟ ). Un esempio dell‟informazione dell‟evento TOUCH_KEY_DOWN sii può vedere nella Figura 58, Figura 58. Informazione dell‟evento TouchKeyboardEvent.TOUCH_KEY_DOWN Quest informazione si può vedere all‟utilizzare l‟istruzione trace(event), dove la variabile „event‟ è l‟evento notificato al toccare il tasto „t‟. Ogni volta che viene premuto un tasto della tastiera, diverso al tasto d‟attivazione, si fa la notifica di un evento con l‟informazione rispettiva al tasto schiacciato. 92 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch 5.1.5 Errori nei componenti rilevati nel processo di sviluppo Durante il processo di sviluppo dei componenti si sono verificati alcuni problemi che non si sono riusciti ad correggere o a capirne la ragione per cui avvenivano. Questi problemi si illustrano in seguito, insieme ad alcune supposizioni sulle cause. Si sono rilevati degli errori su due dei componenti sviluppati: per quanto riguarda il TouchSlider la proprietà di orientamento del componente non funziona correttamente. Nel momento di cambiare da un orientamento orizzontale ad uno verticale, il componente non viene ruotato un angolo di 90 gradi come dovrebbe succedere ma invece viene invertito sul asse orizzontale (Figura 59). Questa funzione viene controllata dal metodo „set‟ della proprietà „direction‟ della classe base. Durante il processo di sviluppo, la proprietà è stata messa alla prova e funzionava correttamente, anzi la funzione „set‟ non è stata modificata in nessun momento. L‟errore si è presentato al momento di creare l‟anteprima. È verosimile che l‟errore si sia verificato dopo la definizione delle impostazioni del componente. Figura 59. Errore nel componente TouchSlider al cambiare la proprietà „direction‟ Tuttavia, questo problema accade unicamente quando si cambia la proprietà dal panello „Component Inspector‟, da dov‟è possibile modificare tutte le proprietà dei componenti che sono state definite come metadati. Se invece la direzione viene cambiata in fase di esecuzione del programma, il componente cambia di orientamento correttamente. L‟altro errore si è rilevato sul componente TouchKeyboard, nel quale la sua anteprima non funziona adeguatamente e si visualizza uno degli asset del componente che non dovrebbe essere visibile (Figura 60). Figura 60. Errore nell‟anteprima del componente TouchKeyboard 93 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Questo errore si crede sia dovuto a problemi di compatibilità tra Flash CS3 e CS4. Tutti i componenti sono stati sviluppati su Flash CS3, ed alla fine sono stati importati su Flash CS4 per fare le prove nello schermo tattile, ma sul programma Flash CS3 l‟anteprima del componente non è visualizzata in questo modo, mentre sulla versione più recente aveva quest‟apparenza. Nella fase di esecuzione, il componente è visualizzato normalmente senza nessun errore. 5.1.6 Importando i componenti in FLASH Per poter utilizzare i componenti appena sviluppati è necessario metterli su una cartella da dove Flash possa trovarli per poi importarli all‟interno del programma e poter utilizzarli come dei componenti, trascinabili sullo stage ogni volta che se ne vuole utilizzare uno. Per fare ciò bisogna andare alla cartella d‟istalazzione di Flash, che si trova nel path seguente: ..Program Files\Adobe\Adobe Flash CSX\language\Configuration\Components\ Oppure può essere il path seguente: ..Program Files\Adobe\Adobe Flash CSX\Common\Configuration\Components\ In questa cartella vengono inseriti tutti I componenti di flash. Qua è possibile creare una cartella nuova ed al suo interno verrà inserito il file .fla del progetto dove si è sviluppato il componente. Dopo di che si esegue il programma ed nel panello dei componenti, verrà visualizzata una voce nuova con il nome della cartella appena creata, ed una volta si estende l‟opzione, sarà possibile vedere tutti i componenti che siano stati inseriti all‟interno della cartella (Figura 61). Figura 61. I componenti personalizzati all‟interno del panello dei componenti di Flash 94 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch 5.2 Creazione di classi di AS3 per l‟interazione con i Gesti Nella parte descritta in seguito si è cercato di creare delle classi che permettessero l‟interazione con i gesti fatti dall‟utente. Per poter sviluppare una classe che se ne occupi, bisogna sapere prima a quali gesti si deve reagire e perciò è necessario fare una classificazione dei tipi di gesti con cui si vuole interagire. 5.2.1 Classificazione dei gesti Prima di tutto bisogna sapere quali gesti si possono utilizzare per una applicazione touchscreen, e rispetto a quanto esposto nel capitolo 4, si è fatta una selezione dei gesti ed una classificazione di essi: „Gesti Semplici‟, quei gesti che con il tempo sono diventati dei pattern/modelli per il loro ampio uso, e „Gesti Complessi‟, che sono quei gesti fatti dall‟utente che si devono confrontare con i modelli contenuti in una libreria template. Questo si è riassunto nella tabella 3. GESTI SEMPLICI 1 BLOB DRAG SELECTED TAP 2 BLOB ROTATE SCALE GESTI COMPLESSI Tutti i gesti fatti in modo libero dall‟utente Tabella 3. Classifica dei gesti a con cui si vuole interaggire. Questi gesti sono stati scelti per le seguenti ragioni: i gesti semplici sono i modi di fare già conosciuti da gran parte degli utenti; mentre per i gesti complessi, bisogna scegliere i gesti da utilizzare come la libreria dei template, per dopo fare il confronto con i gesti fatti dall‟utente. Quest‟ultimi permettono di arricchire le funzionalità delle interfacce touchscreen, poiché fanno possibile l‟utilizzo di un maggiore numero d‟input per il sistema. 5.2.2 Classi di ActionScript 3.0 sviluppate Dopo la classifica dei gesti ci si è incentrati sul processo di sviluppo delle classi. La prima classe sviluppata permette di creare una base di dati con i template dei gesti, che stampa le informazioni in formato XML. La seconda classe permette di creare un‟istanza capace di reagire ai gesti semplici. L‟ultima classe importante che si è creata è una classe che riesce 95 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch ad individuare il momento in cui l‟utente fa un gesto complesso, per fare ciò utilizza le altre due classi. Oltre alle tre classi principali, si sono creati altre classi aussiliari come per esempio quella che definisce gli eventi. Queste classi aussiliari non sono fondamentali per il funzionamento generale del pacchetto di classi e perciò non verranno descritte. 5.2.2.1 Classe per la creazione di una libreria di gesti: GestureCreator.as Questa classe fa uso di una delle classi che implementano la tecnica „1$‟ che si sono descritte nella sezione 4.2.1.1. La classe utilizzata è la „DollarTemplate‟, che si usa per normalizzare tutti gesti che si vogliamo salvare nella libreria. Quest‟utima è stata realizzata in modo tale da permettere di creare i gesti sia con il mouse che con le dita. Per la creazioni di gesti, bisogna implementare un‟istanza della classe „GestureCreator‟, il costruttore deve ricevere come argomento l‟elemento sul quale verranno rilevati i gesti. Questo elemento può essere sia lo stage, oppure ad esempio una Sprite o MovieClip. Questa scelta permette una maggiore libertà nell‟uso di questa classe, nel senso che se si vuole passare a un elemento disegnato all‟interno di un‟applicazione più complessa lo si può fare senza alcun problema. Figura 62. Rilevamento del tipo d‟argomento passato al costruttore della classe „GestureCreator‟. Quindi nel costruttore viene identificato se l‟elemento passato è di tipo Stage o no. Se l‟oggetto non è di tipo Stage, ci troviamo di fronte ad un elemento utilizzabile dall‟utente, come uno spazio di disegno dei gesti. Se invece è stato lo stage ad essere passato come argomento, lo si salva su una variabile interna, e si crea uno elemento tipo Sprite per usarlo come lo spazio di disegno, nella Figura 62, si può vedere questa parte del codice. Oltre alla creazione dello spazio di disegno, vengono anche aggiunti: uno spazio per il testo, dove 96 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch l‟utente può inserire il nome che vuole usare per il gesto; due tasti semplici, uno dei quali viene utilizzato per salvare il gesto appena fatto dall‟utente e l‟altro per stampare le informazioni di tutti i gesti salvati; un terzo tasto che serve per attivare l‟opzione di realizzare gesti con forma poligonale; ed un‟altro elemento sprite che serve a dipingere la traiettoria del gesto fatto dall‟utente. Tutto questo è fatto a livello di codice. La interfaccia si può vedere nella Figura 63. Figura 63. Interfaccia per la creazione dei gesti. Lo spazio di disegno viene registrato per essere notificato sia dall‟evento MOUSE_DOWN che dall‟evento TUIO_DOWN. Nel momento in cui si fa la notifica di questi eventi si chiama un metodo che prima cancella tutti i punti del gesto precedente dall‟array, e dopo elimina tutto quello che è stato disegnato in prima, successivamente registra lo spazio di disegno per essere notificato dagli eventi MOUSE_MOVE, MOUSE_UP , TUIO_MOVE e TUIO_UP. Nella Figura 64 mostra il metodo fatto per l‟evento del mouse, l‟altro metodo fa praticamente lo stesso, con la differenza che invece di registrare eventi della classe MouseEvent, ne registra quelli della classe TUIOEvent. 97 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Figura 64. Metodo per gestire l‟evento MOUSE_DOWN L‟elemento di nome „painting‟ nella funzione della figura precedente è quello che fa il disegno del gesto sullo spazio di disegno, e viene allocato nel punto dove si trova il mouse, tramite l‟istruzione: painting.graphics.moveTo(recordArea.mouseX, recordArea.mouseY); Nel caso il gesto sia stato fatto con un dito si utilizzano le proprietà „LocalX‟ e „LocalY‟ per definire la posizione del dito rispetto allo spazio di disegno. A questo punto, si comincia a seguire il movimento del dito/mouse chiamando i metodi che sono stati registrati per essere notificati ogni volta che si rileva uno spostamento di loro. Questi metodi, ogni volta che vengono chiamati, inseriscono il punto dov‟è stato rilevato l‟evento all‟interno di un array di punti. In questo modo è possibile salvare tutti i punti del gesto e allo stesso tempo completare il disegno aggiungendo il nuovo punto in cui si è spostato il dito/mouse. Il codice che sviluppa questa parte è il seguente: Figura 65. Codice utilizzato per „dipingere‟ il gesto nello spazio di disegno 98 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Dove la variabile „gesturePoints‟ è un array utilizzato per salvare i punti del gesto che sta registrando. Una volta terminato il gesto, si chiamano due metodi: il primo si occupa di normalizzare i punti appena rilevati, utilizzando un‟istanza della classe „DollarTemplate‟ ed assegnarli il nome appena inserito (sezione 4.2.1.1). Il secondo metodo gestisce la selezione dell‟opzione di „Polygonal Gesture‟. Se questa opzione è selezionata, la classe fa un‟elaborazione in più dei punti per fare un‟approssimazione del gesto ad una figura poligonale31. La parte del codice che se ne occupa è illustrata nella Figura 66, Figura 66. Codice per gestire la normalizzazione del gesto e l‟opzione dei gesti poligonali Nella prima riga di codice si fa la normalizzazione del gesto, dopo di che se l‟opzione di Gesti poligonali è attiva, la variabile booleana „polyGesture‟ richiama il metodo „getCornerPoints()‟ della classe ShortStraw32 per ottenere un vettore con gli angoli del poligono, e svolge una normalizzazione del vettore: tutti i gesti nella libreria devono avere la stessa lunghezza per poterli paragonare con i gesti fatti dall‟utente. Lasciare un gesto solo con quattro o cinque punti della figura poligonale non permetterebbe di fare un confronto corretto tra i gesti. Successivamente alla normalizzazione del gesto si chiama un‟altro metodo ausiliare che si utilizza per dipingere il gesto appena normalizzato e visualizzarlo nello stage. Un esempio si può vedere nella Figura 67. La figura viene disegnata nell‟angolo dello stage perché si utilizzano le coordinate normalizzate, per aiutare il matching dei gesti le figure vengono disegnate intorno alle coordinate (0,0). Se si vuole cambiare questo, basta sommare le coordinate del nuovo centro a tutte le coordinate dell‟array. 31 Algoritmo elaborato nello studio di Wollin, A. et al. – “Short Straw: a simple and effective corner finder for polylines” <http://srlweb.cs.tamu.edu/srlng_media/content/objects/object-1246294647350817e4b0870da27e16472ed36475db/Wolin_SBIM08.pdf> 32 Betriebsraum weblog “Efficient Gesture recognition and Corner Finding in AS3” <http://www.betriebsraum.de/blog/2009/07/21/efficient-gesture-recognition-and-corner-finding-in-as3/> 99 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Figura 67. Esempio del gesto, in blu, e la sua versione normalizzata, in rosa Dopo aver inserito i punte del gesto e averli normalizzati si può scegliere di salvare il gesto oppure stampare i gesti registrati fino a quel momento. Al premere del tasto REC si chiama un metodo che verifica che la lunghezza del gesto sia maggiore ad un unico punto e che sia stato inserito un nome per il gesto. In caso contrario il gesto non viene inserito nell‟array di gesti, questa verifica viene fatta nel momento in cui viene premuto. Figura 68 mostra questo metodo; la variabile booleana „proceed‟ è utilizzata come variabile di controllo: finchè non vengono verificate il nome e la lunghezza non viene chiamato il metodo per la normalizzazione del gesto e non si aggiunge il gesto nell‟array. Figura 68. Codice del metodo del tasto REC 100 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Per stampare le informazioni dei gesti registrati basta premere il pulsante Print e nella finestra di output ne vengono visualizzate le informazioni in formato XML, per poi copiarli su un file .xml che si può utilizzare come base per paragonarli ai gesti fatti in qualsiasi altra applicazione. Il formato è il seguente: <Gestures> <gesture name= _gestrureName> <point x = x_value y =y_value></point> … <point x = x_value y =y_value></point> </gesture> <Gestures> Il metodo che si occupa di generare il file XML viene illustrato nella Figura 69. Tutti i gesti normalizzati hanno una lunghezza di 64 punti, questa impostazione si può cambiare all‟interno della classe „DollarRecognizer‟ nella proprietà NUM_POINTS. Si possono inoltre inserire dei nomi personalizzati per ogni gesto, questo può servire per ottenere due gesti con ugual nome che possono essere utili nel caso in cui potrebbe esserci un fraintendimento dovuto alla direzione in cui l‟oggetto è stato tracciato. Un esempio è il cerchio che può essere disegnato in senso orario e antiorario; a livello grafico non c‟è differenza, ma i punti nei due casi sono molto diversi. In questo modo è possibile creare tutti le versioni di uno stesso gesto. Figura 69. Metodo per la creazione della libreria di gesti in formato XML Questa classe serve per creare, in modo semplice, un database di gesti; l‟interfaccia è creata per mezzo di ActionScript,al fine di alleggerire il lavoro all‟utente: per fare funzionare la classe bastano soltanto due righe di codice che possono essere scritte sul primo frame script: import gestures.GestureCreator; var myCreator:GestureCreator = new GestureCreator(this.stage); 101 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch 5.2.2.2 Classe simpleGestObject.as Con questa classe si è pensato di gestire i gesti semplici per un oggetto qualsiasi nello schermo con il quale si possa interagire. Inizialmente si era pensato di gestire tutto da una classe generale che determinasse ogni volta se un gesto semplice era fatto su un oggetto. Trattandosi di gesti semplici, e non avendo bisogno di paragonarli con nessun‟altro elemento, si è deciso di fare che ogni elemento determinasse da sé se un gesto semplice stava avvenendo su di lui. Questo significa che ogni elemento deve essere in grado di sapere se una azione è stata svolta su di esso. A questo punto si è affrontato il primo problema: se un‟elemento è stato già inserito nello stage, bisogna prima farlo reagire agli eventi semplici, in altre parole registrarlo come listener di questi tipi di eventi. Per fare ciò si possono fare due cose: la prima opzione è quella di aggiungere sullo stesso elemento tutti i listener e programmare la sua risposta agli eventi; la seconda opzione è inserire l‟elemento come figlio di un contenitore che abbia già il comportamento desiderato. Alla fine si è optato per la seconda opzione, poiché esiste già una classe che si comporta di questo modo. La classe si è trovata tra uno degli esempi realizzati dalla NUI-group, ed è stata definita come una classe astratta che quindi si può estendere per aggiungere le sue funzionalità in una classe nuova. La nuova classe deve allora prendere l‟elemento che si vuole far diventare interattivo ed aggiungerlo come „figlio‟, questo vuol dire che tutte le modifiche che siano applicate sulla classe nuova saranno anche applicate a tutti gli elementi che contiene. Questo si può vedere nella Figura 70, dove si mostra la definizione della classe nella quale si estende la classe „RotatableScalable‟ elaborata dalla NUI-group, e si vede anche il costruttore della classe nuova, chiamata „simpleGestObject‟. Figura 70. Definizione della classe simpleGestObject ed il metodo costruttore 102 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Nella classe si definisce una variabile „wrappedObject‟ alla quale viene assegnato l‟elemento passato come argomento al costruttore. Dato che non si conosce a priori il tipo di elemento passato (potrebbe essere di tipo „Sprite‟ o „MovieClip‟, per esempio), si preferisce non definire nessun tipo: „dispObj*‟: si cambiano le coordinate dell‟elemento per aggiungerlo come un figlio dell‟istanza della classe „simpleGestObj‟ appena creata, e al nuovo elemento si assegnano le coordinate del figlio precedente. In questo modo nel momento d‟inserire la nuova istanza, si troverà nella stessa posizione dove si trovava prima l‟elemento che si vuole far diventare interattivo. A questo punto la classe base si occupa di gestire il comportamento interattivo dell‟elemento: registrare l‟istanza per essere notificata dagli eventi TUIO e risponde agli spostamenti per fare vedere un trascinamento dell‟elemento. Se l‟elemento è toccato con due dita, è possibile ruotarlo oppure cambiare le sue dimensioni. E´anche possibile passare dei parametri booleani che permettono di controllare il modo come l‟elemento reagisce: se si vuole che l‟elemento non possa essere rotato o scalato o spostato oppure che l‟elemento nemmeno reagisca alle azioni dell‟utente. Tuttavia mancano implementare i gesti semplici di „Selected‟ ed individuare bene il gesto „TAP‟. Per gestire il gesto „Selected‟ si è utilizzato una variabile di tipo Timer, la quale si fa partire nel momento in cui l‟utente appoggia il dito sull‟oggetto. Poi, se l‟utente alza il dito prima che il Timer finisca il conteggio, si fa partire l‟evento del gesto TAP, se invece l‟utente preme a lungo l‟elemento il tempo sufficente di permettere alla variabile Timer di finire il conteggio, si fa partire l‟evento „selected‟. A questo punto, la classe fa la notifica di tutti i gesti, però bisogna gestire i momenti quando alcuni di essi non possono essere notificati: per esempio, se l‟elemento è stato già premuto, e lo si tocca con un secondo dito, non si può notificare il gesto TAP per quest‟ultimo, oppure se il timer ha già finito il conteggio, non si può di nuovo fare la notifica del TAP. Questa logica si è gestita con degli variabile booleane che utilizzate per controllare le situazioni prima considerate. 5.2.2.3 Classe generale per rilevare i gesti: TouchGesture.as Questa classe si occupa di rilevare tutti i gesti fatti dall‟utente determinando i momenti in cui accade ogni gesto, se il gesto è di tipo complesso, si confronta con i template della libreria di gesti creata precedentemente. Il costruttore si occupa di caricare la libreria di gesti per poterla utilizzare in caso di bisogno. Così com‟è stato fatto per la classe „GestureCreator.as‟, la classe riceve come argomento un elemento e questo viene usato come area d‟interazione (Figura 71). Questo elemento può essere sia di tipo Sprite, MovieClip, oppure tipo Stage. Quindi all‟inizio del metodo si verifica se l‟elemento ricevuto è uno stage, se è così si aggiunge un elemento tipo Sprite nella display list dello stage, la quale verrà utilizzata come area d‟interazione; invece se l‟elemento ricevuto è diverso dello stage, sará questo 103 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch elemento ad essere utilizzato come area di interazione e quindi viene assegnata alla variabile della classe che fa riferimento a questo spazio (la variabile „touchArea‟). L‟elemento viene inserito nella posizione 3 della display List. Le posizioni precedenti vengono occupate dal: MainTimeline, e da due elementi per il riconoscimento dei tocchi, che vengono inserite dal metodo „TUIO.init( )‟ nel momento dell‟inizio di una comunicazione col tracker. Figura 71. Costruttore della classe „TouchGesture‟ Fino a questo punto c‟è un‟area dove si possono ricevere dei gesti con cui l‟applicazione può interagire. Ora si deve gestire il rilevamento delle azioni dell‟utente per determinare se il movimento fatto da lui è un gesto semplice, o un gesto complesso che si deve confrontare con gli elementi del database. Prima si è programmata la parte che si occupa dei gesti semplici. Questi tipi di gesti sono gestiti da una delle classi create precedentemente quindi, si è creato un metodo che implementa la classe „simpleGestObject.as‟ per creare gli elementi interattivi: 104 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch o makeObjInteractive(dispObj:*, rot:Boolean = true, sca:Boolean = true, mov:Boolean = true, noSel:Boolean = true):void Questo metodo riceve come argomenti l‟oggetto d‟interesse e delle variabili booleane che controllano se l‟elemento può essere rotato, scalato, spostato oppure se può essere selezionato. Nel metodo si usa una variabile interna per fare riferimento al contenitore dell‟elemento per poter dopo aggiungerlo di nuovo sullo stesso contenitore. Per ultimo, crea un‟istanza della classe „simpleGestObj‟ passandogli come argomento l‟elemento che si vuole reagisca ai gesti semplici. Questa parte del codice s‟illustra nella Figura 72. Figura 72. Metodo della classe TouchGesture per fare che un elemento reagisca ai gesti semplici usando la classe simpleGestObject. Inoltre, si crea una variabile per controllare il gesto semplice „Selected‟, il quale avviene quando l‟utente preme a lungo l‟elemento. La durata del tempo che deve essere premuto viene controllata da una variabile di tipo Timer che si passa anche come argomento del costruttore dell‟istanza simpleGestObject. Con questo metodo viene gestita tutta la parte dei gesti semplici, poiché tutta la logica di individuazione dei momenti in cui avvengono ciascuno dei gesti semplici sull‟elemento è gestita dalla classe simpleGestObject. Dopo di questo, bisogna individuare i gesti complessi che vengono realizzati dall‟utente. Prima di tutto, un fattore che differenza un gesto dall‟altro è che i gesti semplici accadono sugli elementi, mentre che i gesti complessi lo fanno sull‟area interattiva. Il momento in cui il target dell‟evento TUIO è l‟area interattiva, è lo stesso momento in cui si deve cominciare a memorizzare i movimenti dell‟utente. Però se si vuole che l‟applicazione sia multitouch, si deve chiamare contemporaneamente questo metodo. Ci si può pensare ancora di un altro modo, ogni volta l‟utente tocca l‟area interattiva, si aggiugne un elemento che si registra come listener del movimento di quel dito e ne memorizza la sua posizione ogni volta che il dito si sposta. Questa classe aussiliare, gestureObject.as, possiede gli stessi metodi per la memorizzazione del gesto che si sono utilizzati per la classe GestureCreator. 105 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch Figura 73. Creazione delle istanze gestureObject quando l‟utente tocca l‟area interattiva Nella Figura 73 si può vedere la parte del codice che è chiamata quando l‟utente tocca la touchArea, si crea un‟istanza della classe aussiliare che si salva su un array locale, e si registra per essere notificata dagli Evento TUIO per far si che l‟istanza memorizzi i movimenti dell‟evento TUIO che l‟ha generato. Una volta che l‟utente alza il dito, si chiama il metodo stopRecording dell‟istanza: Figura 74. Metodo stopRecording della classe gestureObject. Nel metodo stopRecording dell‟istanza gestureObject, si fa la notifica dell‟evento GESTURE_END e si passa come parametro l‟identificativo del evento che ha appena finito. In questo modo la classe TouchGesture riceve l‟evento e con l‟identificativo può cercare l‟elemento per riperire il gesto memorizzato da essi e fare il confronto con i template del database: Figura 75. Metodo della clase TouchGestures che si chiama quando l‟utente a finito di fare un gesto Il metodo chiamato riceve un evento di tipo GestureEvent che contiene l‟identificativo del gesto che si usa per ricuperare l‟array di punti del gesto appena memorizzato. Dopo di che 106 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch l‟evento fa il matching con il database ed fa la notifica di un evento di tipo COMPLEX, che possiede il nome ed il punteggio risultati dal confronto con i template della libreria. Il confronto è fatto da una variabile, „recognizer‟, della classe DollarRecognizer, della quale si chiama il metodo pubblico „recognizer‟ e si passa come parametro una copia dell‟array di punti del gesto fatto dall‟utente. Il metodo confronta il gesto con tutti gli elementi del databse e determina il template si assomiglia di più. 5.2.2.4 Classe GestureEvent.as Questa classe definisce le costanti che rappresentano i gesti individuati con le classi create prima, ed possiede delle proprietà che possiedono le informazioni sugli eventi. Le costanti sono le seguenti con le proprietà della classe che possiedono le informazioni rispettive si elencano in seguito: GESTO TAP SELECTED DRAG ROTATE SCALE COMPLEX GESTURE_END PROPRIETÀ rotValue:Number scaleValX:Number, scaleValY:Number complexGest:String gestureID Tabella 4. Costanti e proprietà della classe GestureEvent 5.2.3 Applicazione di test per le classi dei gesti Una volta creati le classi si sono implementati in una piccola applicazione per vedere il loro funzionamento. Prima di tutto si è creata la libreria di template utilizzando la classe GestureCreator. I gesti utilizzati come basi di dati sono stati i seguenti CIRCLE SQUARE TRIANGLE SPIRAL WAVE Dopo di che si è fatta una piccola applicazione per realizzare gesti ed interaggire con delgi oggeti interattivi. Per i gesti si sono fatte 10 prove per ogni gesto, ogni volta che si fa un gesto, si stampa l‟identificativo del template ed il punteggio.I risultati si riassumono nella tabella seguente: 107 Capitolo 5 –Sviluppo di strumenti basi di ActionScript per applicazioni multitouch CIRCLE Circle x8 Square x2 SQUARE Square x10 TRIANGLE Triangle x9 Square x1 SPIRAL Spiral x10 WAVE Wave x7 Square x3 Anche se i numeri di casi provati non è sufficente per fare uno giudizio giusto, si illustra che il gesto con il quale si può più confondere è il quadratto Sicuramente facendo tante altre prove sarà possobile assicurare qualcosa. Ma questo è solo per chiarire che ci sono ancora cose da fare, come lavorare nella precisione del metodo di confronto. Per provare le notifiche degli eventi semplici, si è inserito un quadratto il quale si è fatto diventare interativo. Ed è stato possibile provare le azioni di rotazione, scalamento, dragging e selezione e la notifica di tutti i gesti. Tutti gli eventi individuati dalla classe TouchGesture.as. È stato possibile verificare la notifica sia dei gesti semplici sia dei gesti complessi. Con questo è finito lo sviluppo delle classi per individuare e riconoscere i gesti e si è verificato la sua funzionalità per una applicazione Multitouch. Ancora si possono migliorare molte cose, per esempio per le classi er i gesti si può migliorare la precisione oppure la logica di programmazione per farle più efficienti; con i componenti, si possono correggere gli errori nell‟anteprima oppure meglio, creare altri componenti. Ma con questo lavoro 108 CONCLUSIONI Attraverso questo lavoro sono stati sviluppati alcuni strumenti utili per la creazione di interfacce interattive di tipo touchscreen, mirati ad essere utilizzati sia con gli schermi touchscreen semplici che possono rilevare unicamente un oggetto sullo schermo alla volta, sia con schermi più avanzati che riescono a rilevare più di un oggetto contemporaneamente, noti come schermi multitouch. Anche se esistono già strumenti che permettono di lavorare con questa tecnologia, è ancora possibile creare modi nuovi e diversi tramite cui l‟utente può interagire con queste tipi di interfacce. Quindi lo sviluppo di strumenti che permettano di fare questo è stato lo scopo di questo studio. Per raggiungere l‟obiettivo di questa tesi, è stato necessario studiare la composizione di questi sistemi. Tutti i sistemi di interfacce touchscreen devono essere composti minimo di tre parti: un sensore, che misura i cambiamenti sullo schermo; un comparatore, che stabilisce se i cambiamenti rilevati dal sensore sono validi o meno; ed un attuatore che in base a cosa ha determinato il comparatore, decide come reagire al cambiamento rilevato dal sensore. Il tipo di risposta di un‟applicazione dipende del tipo d'applicazione interattiva che si vuole sviluppare, però le prestazioni dell'applicazione ed il grado di risposta alle azioni dell‟utente dipendono delle capacità delle parti che lo compongono: il sensore determina le azioni alle quali il sistema può reagire, poiché se una azione non è misurabile dal sensore, non esiste per il sistema digitale; il grado do risposta dipende anche delle capacità del comparatore per elaborare i dati misurati. Più informazione il comparatore è capace di recuperare per comunicarla all'attuatore, più interattiva potrà essere l'applicazione che si vuole sviluppare. Quindi è stato necessario studiare le diverse parti del sistema per determinare com‟era possibile migliorare le sue prestazioni. Il sistema con il quale si è lavorato è composto da una parte hardware ed una parte software. L‟hardware è uno schermo tattile fatto per misurare i cambiamenti con tecniche ottiche. Queste tecniche sono state descritte nella sezione 1.3. Invece nella parte software si trovano sia il comparatore sia l‟attuatore del sistema. Il comparatore è un software di tipo tracker, descritto nella sezione 1.4.1., che individua i blob sullo schermo, e calcola ed invia le informazioni basiche dei blob rilevati all‟attuatore. Tuttavia il sistema utilizza un insieme di classi di ActionScript 3.0, la libreria touchlib, che elaborano i messaggi inviati dal tracker per trovare ancora più informazioni 109 CONCLUSIONI sulle azioni dell‟utente. Per comprendere com‟è stato fatto questo bisognava studiare il protocollo TUIO, che standardizza il tipo d‟informazione che deve essere ricavata per ogni blob e la costruzione dei messaggi che contengono questi dati. Questo protocollo assieme alla libreria touclib, sono stati descritti nel capitolo 2. Quindi le classi di ActionScript sono state utilizzate per processare ancora di più le informazioni in formato TUIO, migliorando le prestazioni del comparatore. Per usufruire di questi dati, si utilizza un programma, Flash, che possa utilizzare AS3 per sviluppare delle applicazioni che ne facciano utilizzo per reagire alle azioni dell‟utente. Flash è un programma utile per creare applicazioni interattive che reagiscono agli eventi del mouse e della tastiera. Ciononostante, non possiede strumenti giusti per la creazione di interfacce touchscreen. Perciò uno degli scopi di questa tesi è stato sviluppare alcuni componenti di Flash che sono in grado di reagire alle azioni fatte dall‟utente sullo schermo touchscreen. Questi componenti sono un bottone, una barra di scorrimento, un stepper numerico e una tastiera. Per la creazioni di essi è stato necessario studiare cosa sono i componenti, come funzionano all‟interno del programma Flash e quale sono le loro caratteristiche. Alcuni dei componenti sviluppati sono estensioni di componenti che si trovano in Flash, dunque è stato necessario studiare il funzionamento dei componenti che si volevano estendere per integrare adeguatamente le nuove funzionalità dei componenti sviluppati. A questo scopo sono state studiate le proprietà ed i metodi di ogni componente base per sapere quali potevano essere utilizzate nei componenti nuovi. Inoltre, per tutti i componenti si deve conoscere il funzionamento di due elementi fondamentali: il primo è la classe „UIComponent‟, che è una classe che possiede le proprietà ed i metodi di base per tutti i componenti di Flash, come per esempio la proprietà „enabled‟. Tutti i componenti che si vogliano sviluppare, quindi, devono estendere questa classe, direttamente oppure indirettamente, estendendo altri componenti; il secondo elemento è il modello d‟invalidazione, il quale si utilizza per gestire il modo in cui il componente reagisce a livello visuale alle azioni dell‟utente. Per fare uso di questi elementi, sono stati implementati dei metodi specifici, per esempio il metodo configUI oppure il metodo draw, i quali vengono chiamati automaticamente dalla struttura dei componenti dell‟interfaccia utente. Ciò si è fatto mentre si è fatta la logica di funzionamento del componente nella quale si definisce la parte che interessa di più: il modo un cui il componente deve reagire alle azioni dell‟utente sullo schermo. Poi è stato necessario creare tutti gli asset di ogni componente ed assegnare ad ognuno di loro le impostazioni necessarie per funzionare con la struttura a due frame con cui si devono costruire i componenti. Inoltre, se il componente sviluppato deve notificare qualche evento particolare che contenga l‟informazione della risposta all‟utente si deve creare una classe adatta per farlo. Finalmente si è creato l‟elemento componentShim, che è fondamentale poiché contiene già compilate tutte le informazioni del comportamento del componente. A questo punto, c‟era già un componente funzionale, ma ancora è stato necessario creare un ultimo elemento, l‟anteprima, che permette allo sviluppatore dell‟applicazione di visualizzare le modifiche fatte al 110 CONCLUSIONI componente senza aver bisogno di eseguire il programma. Tutti questi passi sono state fatti per ciascuno dei componenti sviluppati. Con questo si è raggiunto il primo scopo della tesi: la creazione di componenti che si possano utilizzare per applicazioni interattive di tipo touchscreen. Per svilupparli, quindi, è stato necessario non solo capire il loro funzionamento, ma anche utilizzare adeguatamente gli eventi TUIO rilevati dalla libreria touchlib, la descrizione del processo di sviluppo si è fatta nella sezione 5.1. A questo punto è possibile creare applicazioni interattive dove l‟utente può toccare degli elementi sullo schermo e ricevere una risposta, ma questo non è l‟unico modo in cui l‟utente può interagire con le interfacce touchscreen, perciò si sono studiati i gesti (capitolo 4), insieme ad un algoritmo adatto per il loro riconoscimento. Per permettere all‟utente di interagire con il sistema per mezzo dei gesti, semplici o complessi, si sono creati delle classi apposite che estendono ancora di più le funzioni del comparatore. Nel sistema con il quale si è lavorato in questa tesi, il comparatore riusciva a rilevare unicamente gli eventi TUIO ma, utilizzando le classi create, è ora possibile rilevare quando l‟utente fa gesti semplici o complessi. Per i gesti semplici o standard, tipo „drag‟ o „rotate‟, si è creata una classe che riceve un elemento che si può visualizzare nello schermo, tipo Sprite o MovieClip, e lo fa diventare interattivo. Le classi create anche permettono al sistema di essere in grado di rilevare quando l‟utente fa altri gesti che non hanno una definizione univoca, ma per riconoscerli bisogna far uso di una libreria di template, caricata da un file esterno, con la quale si possono confrontare per sapere se i gesti sono validi o no. Anche se gli elementi di questo database saranno diversi per ogni applicazione, comunque il sistema deve essere in grado di rilevare il gesto, perciò si una delle classi create implementa dei metodi che permettono di memorizzare il movimento di ogni dito che l‟utente appoggia sullo schermo e ne registra il suo movimento. Questa caratteristica fa di questa classe uno strumento adatto per il suo uso in applicazioni multitouch. Alla fine si è creata una classe generale che utilizza tutte le due classi create prima, per poter gestire con un‟unica classe l‟interazione con l‟utente. In questa classe si sono state definite dei metodi che si occupano di gestire la creazioni di elementi interattivi così come di confrontare i gesti rilevati con gli elementi del database. Per provare le prestazioni di queste classi, si è sviluppata una piccola applicazione che permette di registrare un insieme di gesti e generare in formato XML le informazioni dei gesti che si vogliono utilizzare come template, per poi creare facilmente un file che si possa utilizzare come il database di template. Nel processo di sviluppo è stato necessario utilizzare altre classi creati da altri programmatori, come per esempio le classi che implementano l‟algoritmo di riconoscimento, e quindi è stato necessario studiare le loro funzioni per riuscire ad utilizzare adeguatamente i loro metodi. Con questo è stato possibile raggiungere l‟altro obiettivo di questo studio: creare uno strumento che permetta di arricchire il modo in cui le interfacce touchscreen, e in questo caso anche le interfacce multitouch, possono reagire alle azioni degli utenti. 111 CONCLUSIONI Da questo punto è possibile migliorare ancora molte delle funzioni degli strumenti sviluppati nel presente lavoro. Per esempio, si sono rilevati alcuni errori negli elementi di anteprima di alcuni componenti, e ciò possibilmente è dovuto ad alcune incompatibilità tra le versioni dei programmi utilizzati: i componenti sono stati sviluppati in una versione precedente a quella utilizzata nel sistema touchscreen. Chiaramente è possibile creare ancora molti altri componenti che possano essere utilizzati in questo tipo di interfacce. Invece dalla parte delle classi per il rilevamento dei gesti, è possibile migliorare la precisione di rilevamento del gesto. Questo è molto importante poiché esistono alcuni gesti che nel processo di normalizzazione per poter confrontarlo con i template, cambiano un po‟. Per esempio, si è rilevato che con un gesto come fare una riga c‟erano dei problemi per rilevarla come tale. Questo problema è legato all‟algoritmo utilizzato e quindi è possibile migliorare questi aspetti utilizzando altri algoritmi più robusti. Gli elementi sviluppati in questa tesi sono stati creati in modo tale da reagire individualmente ad un gesto fatto dall‟utente sullo schermo. In questo modo è possibile utilizzare questi strumenti sia per interfacce touchscreen normali sia per interfacce multitouch. Deve essere chiaro che questi elementi sono basati su tecniche di rilevamento ottiche e perciò non vuol dire che non ci siano altre metodi basate su altre tecniche e tecnologie che riescano a fare le stesse funzioni in un modo migliore o peggiore, ma l‟utilizzo di questa tecnologia permette di fare un‟implementazione non costosa di un‟interfaccia touchscreen, e ciò permetterebbe di utilizzare questo tipo di sistemi in molte situazioni quando non si ha accesso a tecnologie più costose. Una cosa è certa, comunque: l‟uso delle interfacce gestuali ogni volta sarà più diffuso, così come si può evidenziare in tanti dispositivi che ne fanno uso ora, e la loro implementazione in tanti ambienti diversi implicherà la creazione di nuovi modi d‟interazione con l‟utente, e perciò lo sviluppo di strumenti adatti sarà sempre necessario. 112 BIBLIOGRAFIA - Adobe Documentation – “Programming ActionScript 3.0” – Adobe Systems Incorporated , 2007, United States of America. - Baxter, L. K. - “Capacitive Sensors: Design and applications” - John Wiley & Sons, 1997, Piscataway, NJ,United States of America - De Donatis, A. - “Advanced ActionScript Components: Mastering the Flash component Architecture” – Friends of Ed, 2006, United States of America. - Henderson, H. – “Encyclopedia of Computer Science and Technology” – Seconda Edizione, Infobase Publishing, 2009, New York, United States of America. - Kaltenbrunner, M. & Bovermann, T. & Bencina, R. & Costanza, E. - "TUIO - A Protocol for Table-Top Tangible User Interfaces" - Proceedings of the 6th International Workshop on Gesture in Human-Computer Interaction and Simulation (GW 2005), Vannes, France. - NUI Group Authors - “Multitouch Technologies” - NUI Group, Prima edizione, Community Release: Maggio 2009. - Richardson, D. & Milbourne, P. – “Foundation ActionScript 3.0 for Flash and Flex” – Friends of Ed, 2009, United States of America. - Saffer, S. - “Designing Gestural Interfaces”- O‟Reilly, November, 2008, Canada. - Stumpe, B. - “A new principle for an X-Y Touch Screen” - CERN, Marzo 16, 1977. Reperibile nel sito <http://cdsweb.cern.ch/record/1266588/files/StumpeMar77.pdf> - Webster, S. & Yard, T. & McSharry, S. – “Foundation ActionScript 3.0 with Flash CS3 and Flex” – Friends of Ed, 2008, United States of America. 113 Bibliografia - Wobbrok, J. & Wilson, A. & Li, Y. –“Gestures without libraries, toolkits or training: a $1 Recognizer for user Interface prototypes”, 2007, Newport, Rhode Island, United States of America. Reperibile nel sito <http://faculty.washington.edu/wobbrock/pubs/uist-07.1.pdf> - Wollin, A. & Eoff, B. &Hammond, T. – “Short straw: A simple and effective corner finder for polylines” – Dipartamento di Computer Science dell‟universtià di Texas A&M, 2008. Reperibile nel sito <http://srlweb.cs.tamu.edu/srlng_media/content/objects/object1246294647-350817e4b0870da27e16472ed36475db/Wolin_SBIM08.pdf> WEB-SITES - Adobe - “ActionScript 3.0 Language and Components reference: Statements, keywords and directives”. <http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/statements.html > [citato: 09 Ottobre, 2010] - Apple – “Press Release Library” <http://www.apple.com/pr/library/> [citato: 21 ottobre, 2010] - Betriebsraum weblog. Rich internet applications, SW Development, HumanComputer Interaction – “Efficient Gesture recognition and corner finding in AS3”, Giulio 19, 2009. <http://www.betriebsraum.de/blog/2009/07/21/efficient-gesturerecognition-and-corner-finding-in-as3/> [citato: 10 ottobre,2010] - Hugh Le Cain “ELECTRONIC SACKBUT”, Gayle, Y. , 1999 <http://www.hughlecaine.com/en/sackbut.html> [citato: 21 Ottobre,2010] - Kamerer, J. “Creating ActionScript 3.0 components in Flash”, Adobe Developer Connection, Flash Developer Center. <http://www.adobe.com/devnet/flash/articles/creating_as3_components.html> [Citato: 9 Ottobre, 2010] - Physics Department, Boston University , “Total Internal reflection and lenses” <http://physics.bu.edu/~duffy/py106/Lenses.html> [citato: 14 Settembre, 2010] 114 Bibliografia - R-Blank, “ActionScript 3 Display List Event Flow” <http://www.rblank.com/2009/11/02/actionscript-3-display-list-event-flow/> [citato:23 Settembre, 2010] - ResistiveTouchScreens.org <http://resistivetouchscreen.org/> [citato: 20 Ottobre, 2010] - Stumpe, B. & Sutton, C. “The first capacitative touch screens at CERN”, CERN, Marzo 31, 2010, <<http://cerncourier.com/cws/article/cern/42092>> [citato: 15 Ottobre, 2010] - Synaptics, “Synaptics and Pilotfish collaborate to develop next generation mobile phone concept” Press Release, August 21st of 2006 <http://www.synaptics.com/about/press/press-releases/synaptics-and-pilotfishcollaborate-develop-next-generation-mobile-phone-> [citato: 12 Settembre, 2010] - Touchlib , NUIGroup, <http://nuigroup.com/touchlib/> 115 ALLEGATO A DOCUMENTAZIONE DELLE CLASSI TUIO DELLA LIBRERIA TOUCHLIB DELLA NUI GROUP //-----------------------------------------------------------------------------------------------------------TUIO.as La classe principale che fa il collegamento con il tracker e processa i messaggi ricevuti con le informazioni sui blob rilevati dal tracker. Proprietà static var FLOSCSocket:XMLSocket; static var FLOSCSocketHost:String; static var FLOSCSocketPort:Number; : Insieme di variabili utilizzate per fare la connessione con il server. Nella NUI Group, questo collegamento si fa con il tracker CCV che invia i messaggi con le informazioni dei blob individuati. static var thestage:Stage; : Variabile che si utilizza per avere una riferenza interna allo stage del progetto con cui si sta lavorando. static var objectArray:Array; : Vettore che contiene gli oggetti che contengono le informazioni dei blob individuati dal sensore. Questi oggetti sono della classe TUIOObject. public static var debugMode:Boolean; : variabile Booleana utilizzata per attivare la funzione di debug delle classi. In questo modo vengono visualizzati la 116 Allegato A posizione dei blob rilevati e l‟identificativo assegnato a ciascuno di loro. static var debugText:TextField; static var debugToggle:TextField; : Queste due variabili vengono usate nel modo debug, per mostrare le informazioni pertinenti. static var recordedXML:XML; : Questa variabile è utilizzata per salvare l‟informazione inviata nel messaggio dal tracker static var bRecording:Boolean = false; : Questa variabile si usa internamente per sapere se si sta facendo il debug, valore = false, oppure se si stanno ricevendo i messaggi dal tracker, valore = true. static var xmlPlaybackURL:String = ""; static var xmlPlaybackLoader:URLLoader; static var playbackXML:XML; : variabili utilizzate per caricare un file XML con dei dati precedentemente registrati. Si usano per fare il debug della libreria. static var bInitialized = false; : Variabile Boolean ache si utilizza per sapere se il collegamento con il tracker è stata fatta precedentemente, Il suo valore cambia a „true‟ una volta si fa il collegamento. Metodi - init() public static function init (s:DisplayObjectContainer, debugXMLFile:String, dbug:Boolean = true):void host:String, port:Number, - Inizializza le variabili e fa la connessione con il server. - Se il parametro 'dbug' è 'true', aggiunge il campo di testo dove è possibile vedere le posizione e l'ID di ogni cursore. Crea un bottone nell'angolo superiore sinistro che serve per cambiare il modo debug Inizializza una variabile XML, 'recordedXML', con i tag <OSCPackets></OSCPackets>. 117 Allegato A - xmlPlaybackloaded() private static function xmlPlaybackLoaded(evt:event):void - crea una variabile xml, playbackXML con l'informazione dentro xmlPlaybackLoaded.Questo metodo si utilizza per fare il DEBUG della libreria - frameUpdate() private static function frameUpdate(evt:Event):void - Se la variabile playbackXML non è vuota, invia l'informazione su playbackXML.OSCPACKET[0] sulla funzione "processMessage()" utilizzato per il debug della libreria - getObjectById() public static function getObjectById(id:Number):TUIOObject - Scorre l'array dei blob rilevati e ritorna l'ogetto con l‟identificativo richiesto. - listenForObject() public static function listenForObject(id:Number, receiver:Object):void - Registra l'oggetto, receiver, come un listener degli eventi del blob identificato con l‟identificativo, id. - processMessage() public static function processMessage(msg:XML):void - Questo metodo si occupa di prendere l‟informazione ricevuta dal tracker e salvare i dati nelle variabile locali. - Determina quali oggetti sono stati appena rilevati, quali c‟erano già prima e quali blob non ci sono più sullo schermo - Per gli oggetti nuovi, crea una nuova istanza di TUIOObject, prende i dati e li salva nelle variabili locali, aggiunge l‟oggetto sullo stage e lo inserisci nell'array di blobs. Invece se l'oggetto c'era prima, si aggiornano i suoi dati e si fa la notifica dell'evento TUIO_MOVE. - toggleDebug() private static function toggleDebug(e:Event):void - Il metodo che viene chiamato ogni volta che si clicca il tasto inserito nellángolo superiore. Fa toggle del valore de la variabile 'debugMode' a 'true o 'false'. 118 Allegato A - dataHandler() private static function dataHandler(event:Event):void - Questo metodo si chiama ogni voltache si riceve un messaggio dal tracker - se la variabile 'bRecording' è 'true', copia l'informazione dell'evento sulla variabile recordedXML - chiama il metodo processMessage() passando come argomento il messaggio appena ricevuto //-----------------------------------------------------------------------------------------------------------TUIOCursor.as extends Sprite Questa classe crea il marcatore sullo schermo che indica la posizione rilevata. - TUIOCursor() Constructor public function TUIOCursor(debugText:String):void - crea un cerchio (pallina rosa) che è posizionato nelle coordinate dell'input rilevato. - se la stringa ricevuta è diversa di null e non è vuota, aggiunge il testo, debugText, in una posizione vicina al cursore. debugText contiene l‟identificatore del cursore. //-----------------------------------------------------------------------------------------------------------TUIOEvent.as extends Event Questa classe definisce i nomi degli eventi come TUIO ed i parametri di posizione, di ID e l'oggetto relativo all'evento. Eventi TUIO_MOVE TUIO_DOWN TUIO_CLICK TUIO_UP TUIO_OVER TUIO_OUT 119 Allegato A Proprietà public var TUIOClass:String; : Contiene la classe dell‟oggetto TUIO public var sID:int; : Contiene l‟identificativo della sessione di rilevamentodel tracker. public var ID:int; : Contiene l‟identificativo dell‟oggetto che fa la notifica dell‟evento. public var angle:Number; : Il valore dell‟angolo dell‟oggetto. : Le coordinate globali dell‟evento. : Le coordinate locali dell‟evento. public var stageX:Number; public var stageY:Number; public var localX:Number; public var localY:Number; public var oldX:Number; public var oldY:Number; : le coordinate iniziali dell‟oggetto chef a la notifica dell‟evento public var buttonDown:Boolean; public var relatedObject:DisplayObject; : Contiene il marcatore, TUIOCursor, usato per indicare la posizione dove si è rilevato il contatto del oggetto con lo schermo. Metodo - TUIOEvent() Constructor public function TUIOEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, stageX:Number = 0, stageY:Number = 0, localX:Number = 0, localY:Number = 0, oldX:Number = 0, oldY:Number = 0, relatedObject:DisplayObject = null, ctrlKey:Boolean = false, altKey:Boolean = false, shiftKey:Boolean = false, buttonDown:Boolean = false, delta:int = 0, TUIOClass:String = "2Dcur", ID:int = -1, sID:int = -1, angle:Number = 0.0) 120 Allegato A Questo metodo riceve i parametri e li salva nelle variabili locali. Dopo di che chiama il metodo super(); //-----------------------------------------------------------------------------------------------------------TUIOObject.as Contiene l'informazione dell'oggetto rilevato (cursore, blob). Informazione come posizione, velocitá, accelerazione, ID della sessione, ecc.. Proprietà x:Number; y:Number; : Coordinate globali dell‟oggetto oldX:Number; oldY:Number; : Coordinate del primo punto dove si è rilevato l‟oggetto dX:Number; dY:Number; : Valori calcolati della velocità nella direzione X e Y area:Number; : Valore dell‟area dell‟oggetto rilevato. TUIOClass:String; : Variabile che contiene la classe dell‟oggetto sID:int; : Variabile con l‟identificatico della session. ID:int : Variabile con l‟identificativo dell‟oggetto rilevato angle:Number; : Variabile con il valore dell‟angolo. pressure:Number; dell‟oggetto. : Variabile utilizzata per salvare un valore di pressione isNew:Boolean; (private) : Variabile per indicare se l‟oggetto è stato appena creao isAlive:Boolean; : Variabile utilizzata per indicare la presenza dell‟oggetto sullo schermo. È´true, finche l‟oggetto ci sia sullo schermo. 121 Allegato A obj; : Variabile con cui fa riferimento all‟oggetto su cui è stato rilevato il blob. spr:Sprite; : Variabile utilizzata per fare riferimneto all‟oggetto utilizzato come marcatore trlx:Sprite; color:int; aListeners:Array; : Array con tutti gli oggetti che son ostati registrati come listeners dell‟oggetto TUIO Metodi - TUIOObject() Constructor public function TUIOObject(cls:String, id:int, px:Number, py:Number, dx:Number, dy:Number, sid:int = -1, ang:Number = 0, o = null):void - Riceve i valori trovati nel messaggio inviato dal tracker e li salva nelle variabile locali. - si crea un cursore della classe TUIOCursor e si alloca nella posizione ('px', 'py'). - notifyCreated() public function notifyCreated():void - Fa la notifica degli eventi TUIO_DOWN e TUIO_OVER. - setObjOver() public function setObjOver(o:DisplayObject):void - Il metodo si occupa di determinare quando il cursore si trova sopra di un altro oggetto, nel caso si fa il dispatch dell‟evento: TUIO_OVER. - Se l‟oggetto che aveva como riferimento è diverso all‟oggetto appena ricevuto, si fa la notifica dell‟evento: TUIO_OUT dal oggetto che aveva il riferimento. Dopo di che, se l‟ggetto ricevuto è diverso di null, si fa la notifica dell‟evento: TUIO_OVER, e si assegna come il nuovo oggetto di riferimento. - addListener() public function addListener(receiver:Object):void - aggiunge l‟elemento che riceve come argomento e lo aggiunge nell‟array di elementi che devono essere notificati dagli eventi dell‟oggetto. 122 Allegato A - removeListener() public function removeListener(receiver:Object):void - rimuove l'oggetto appena ricevuto dall'array di listeners. - kill() public function kill():void - La funzione viene chiamata per rimuovere un TUIOObject dallo schermo. - Se l‟oggetto si trovava sopra di un‟elemento del display, si fa la notifica degli eventi: TUIO_OUT e TUIO_UP. Dopo di che fa la notifica dell‟evento TUIO_UP a tutti gli elementi che si erano registrati per essere notificati dagli eventi di quest ooggetto. - poi, per tutti gli oggetti nell array 'aListeners' fa il dispatch dell'evento: TUIO_UP. - notifyMoved() publc function notifyMoved():void - Fa la notifica dell‟evento TUIO_MOVE, per tutti gli elementi che si sono registrati per essere notificati degli eventi di questa classe 123