• Non ci sono risultati.

6. L’INTEGRAZIONE DI 3DHOP IN EVT

6.2 Implementazione della view 3DHOP

6.2.4 La modifica di moduli preesistent

L’implementazione del supporto alla nuova modalità di visualizzazione 3D ha richiesto la modifica di alcuni componenti preesistenti di EVT.

In questa Sezione si descrivono le modifiche più rilevanti eseguite al fine di: ○ integrare il framework 3DHOP in EVT 2js;

148

○ rendere la vista 3D parametrica rispetto alle configurazioni dell’editore;

○ realizzare l’interconnessione tra contenuti testuali e 3D;

Si indicano per ogni componente la sua funzionalità originaria e il motivo per cui è stato necessario apportare le modifiche e si riportano alcuni estratti di codice.

La direttiva evtBox gestisce l’adattamento dei pannelli che compongono l’interfaccia in base alle diverse modalità di visualizzazione. La modifica del template HTML della direttiva consente di creare la nuova modalità di visualizzazione che contiene il viewer 3D e testo dell’edizione affiancato. La vista 3DHOP-testo si realizza con il seguente codice:

<div ng-if="::vm.type === 'tdhop'"

class="box-body {{vm.edition}}Edition {{vm.getNamedEntitiesActiveTypes()}}

{{vm.getAdditionalClass()}}" style="padding: 0px;"

ng-controller="TreDHOPCtrl">

<evt-tredhop id='tdhop' name="tredhopViewer">

<!-- viewer 3DHOP --> </evt-tredhop>

</div>

dove la direttiva ng-if="vm.type === 'tdhop'" indica che se l’utente ha selezionato la modalità di visualizzazione 3DHOP-testo, identificata dal

type tdhop, allora sarà creato l’apposito box. La direttiva ng-

controller='TreDHOPCtrl' indica che il box è gestito all’interno del

controller appositamente definito. L’elemento <evt-tredhop id='tdhop' name="tredhopViewer"> conterrà la scena e il modello

149

3D grazie alla direttiva evtTredhop, che si occupa della creazione e gestione di tutti gli elementi di cui si compone il visualizzatore 3D.

La direttiva evtBox gestisce inoltre la disponibilità o meno degli strumenti nelle diverse modalità di visualizzazione (testo-testo, immagine- testo, 3DHOP-testo etc.). La modifica del template HTML della direttiva si è resa necessaria al fine di integrare nel box gli strumenti relativi alla vista 3D:

<div class="box-menu"

data-position="top"

ng-if="::vm.type === 'tdhop'">

<evt-select

data-id="{{::selector.id}}"

data-type="{{::selector.type}}"

data-init="{{::selector.initValue}}"

ng-repeat="selector in ::vm.topMenuList.selectors track by $index"> </evt-select> <button-switch title="{{::button.title}}" data-label="{{::button.label}}" data-icon="{{::button.icon}}" data-icon-pos="{{::button.iconPos}}" data-type="{{::button.type}}"

ng-repeat="button in ::vm.topMenuList.buttons track by $index">

</button-switch>

[...]

150

dove, grazie alla direttiva ng-repeat, ogni selettore e bottone presente nell’array topMenuList sarà opportunamente visualizzato nella barra degli strumenti del box. Ad ogni selettore e pulsante è associato un type che consente di identificarlo univocamente (ad esempio al pulsante info corrisponde il type "front").

Per definire quali pulsanti visualizzare sulla barra degli strumenti del

viewer 3D è stato necessario aggiungere una struttura di controllo che

gestisce i pulsanti della vista 3D. Al provider evtProvider è stato aggiunto il codice: case 'tdhop': topMenuList.buttons.push({ title: 'BUTTONS.IMAGE_TEXT_LINKING', label: '', icon: 'itl', type: 'itl' }); topMenuList.buttons.push({ title: 'BUTTONS.HOTSPOTS', label: '', icon: 'hts', type: 'hts' }); if ((config.showObjectSelector)) { topMenuList.selectors.push({

id: 'object_' + config.tdhopViewerOptions.name, type: 'document',

initValue: evtInterface.getState('currentDoc') });

}

151 scope.vm.isLoading = true; [...] scope.vm.content = newContent; scope.vm.isLoading = false; }; break; dove topMenuList.buttons.push e

topMenuList.selectors.push memorizzano rispettivamente una determinata tipologia di pulsante o selettore (identificati dal type) all’interno della lista relativa a quel determinato box.

Si noti la possibilità di configurare alcuni dei selettori e pulsanti, come ad esempio il selettore per il passaggio da un oggetto 3D all’altro, se configurato dall’utente e se disponibili più oggetti 3D. L’istruzione condizionale if ((config.showObjectSelector)) consente di verificare se l’utente ha impostato nel file di configurazione un valore booleano true per l’apposita voce relativa al selettore degli oggetti 3D e in base a questo inserirlo nella fascia superiore del box.207

Il modulo buttonSwitch gestisce l’interazione dell’utente con i pulsanti e i selettori dell’interfaccia, è stato necessario modificare la direttiva buttonSwitch, il relativo template HTML e il provider evtButtonSwitch al fine di aggiungere funzioni per gestire l’interazione dell’utente con i nuovi elementi introdotti nell’interfaccia.

Tutti i nuovi pulsanti introdotti sono implementati con la stessa logica, pertanto, si riporta come caso esemplificativo lo sviluppo del codice per il pulsante che attiva la vista del testo descrittivo, nel provider evtButtonSwitch:

207 La configurazione degli strumenti del viewer 3DHOP è gestita dal controller tdhop, così da mantenere indipendente il framework rispetto all’architettura globale di EVT 2js. Per approfondimenti si veda 6.3.3.

152 case 'listObject':

btnType = 'standAlone'; callback = function() {

var parentBox = scope.$parent.vm;

var topBox=document.getElementsByClassName('box-top-box'); topBox[0].setAttribute('id','listObject');

if (parentBox.getState('topBoxOpened') &&

parentBox.getState('topBoxContent') === 'listObject') { parentBox.toggleTopBox();

} else {

var content;

var currentDocument = evtInterface.getState('currentDoc'); if (currentDocument) { content = parsedData.getProjectInfo().listObject ? parsedData.getProjectInfo().listObject : [...] scope.$parent.vm.updateTopBoxContent(content); scope.$parent.vm.toggleTopBox(); }

var newTopBoxContent = content || '<span

class="errorMsg">{{ \'MESSAGES.GENERIC_ERROR\' | translate }}</span>'; parentBox.updateTopBoxContent(newTopBoxContent); parentBox.updateState('topBoxContent', 'listObject'); if (!parentBox.getState('topBoxOpened')) { parentBox.toggleTopBox(); } } }; fakeCallback = function() {

153

var parentBox = scope.$parent.vm;

parentBox.updateState('topBoxOpened', false); };

break;

Come descritto poco sopra, per la gestione dei pulsanti in base alla modalità di visualizzazione si dovrà implementare il codice per salvare il pulsante all’interno della lista predefinita, integrando la direttiva evtBox come segue: topMenuList.buttons.push({ title: 'BUTTONS.3D', label: 'BUTTONS.OBJ', type: 'listObject' });

Il modulo dataHandler si occupa della gestione dei dati, pertanto è stato necessario modificarlo per salvare e manipolare opportunamente i dati necessari per la modalità 3DHOP-testo. In particolare, si sono modificati il

service baseData, che contiene i metodi per gestire il caricamento iniziale

dei dati e memorizzare i documenti XML e il service parsedData, che si occupa dell’archiviazione e del recupero dei dati caricati.

Questi service sono stati modificati aggiungendo nuovi attributi e funzioni, al fine di implementare il nuovo livello di edizione facsimile e visualizzare opportunamente l’alfabeto runico. La trasformazione dei glifi è gestita tramite la funzione getCurrentGlyph:

function getCurrentGlyph(node) {

var currentGlyph,

154

sRef = node.getAttribute('ref');

try { sRef = sRef.replace('#', ''); currentGlyph = glyphs[sRef].mapping; currentGlyph.id = sRef; } catch(e) { console.log(e); return true; } return currentGlyph; }

In base al livello di edizione (diplomatica, interpretativa e, funzionalità implementata nel corso del presente lavoro, facsimile) il testo viene parsato e gestito da apposite funzioni. La visualizzazione del testo runico ha reso necessaria l’implementazione del supporto al nuovo livello di edizione facsimile.

Al fine di estrarre e successivamente visualizzare correttamente i glifi relativi all’alfabeto runico si è modificato il servizio evtGlyph:

angular.module('evtviewer.dataHandler')

.service('evtGlyph', ['parsedData', function Glyph(parsedData) { Glyph.prototype.getGlyph = function (node, editionType) { var currentGlyph = getCurrentGlyph(node),

isRune = currentGlyph.runic, edition = {};

if(isRune) { edition = {

'diplomatic': function () {

155

currentGlyph.runic.content : ''; },

'facsimile': function () {

return currentGlyph.runic !== undefined ? currentGlyph.runic.content : ''; },

'interpretative': function () {

return currentGlyph.transliterated !== undefined ? currentGlyph.transliterated.content : ''; } }; } else { edition = { 'diplomatic': function () {

return currentGlyph.diplomatic !== undefined ? currentGlyph.diplomatic.content : ''; },

'facsimile': function () {

return currentGlyph.facsimile !== undefined ? currentGlyph.facsimile.content : ''; },

'interpretative': function () {

return currentGlyph.normalized !== undefined ? currentGlyph.normalized.content : ''; } }; } return edition[editionType](); };

156

dove il metodo .getGlyph(node, editionType) individua il glifo relativo al nodo <g> ed estrae il carattere corrispondente a seconda del tipo di edizione (valutato in base al valore del parametro editionType): si seleziona il carattere runico per il livello di edizione facsimile e diplomatico, normalizzato per il livello di edizione interpretativa.

Per la consultazione del testo descrittivo che affianca il box contenente il visualizzatore 3D è stata implementata una nuova vista che si attiva selezionando un apposito pulsante nella barra degli strumenti. Questa implementazione ha richiesto l’ulteriore modifica del modulo dataHandler. In particolare, oltre che alla modifica dei già citati service baseData, parsedData si è reso necessario aggiungere specifiche funzioni nel service evtProjectInfoParser, che contiene i metodi per analizzare i dati relativi alle informazioni nell’header dell’edizione.

Il servizio è stato integrato aggiungendo le variabili necessarie per il

parsing e la memorizzazione dei dati relativi alla descrizione dei singoli

oggetti, codificati nel testo dell’edizione con l’elemento listObject e implementando le funzioni necessarie alla loro gestione.

Il parsing degli elementi descrittivi relativi all’oggetto 3D, contenuti nell’intestazione della codifica, è gestita dal parser

parselistObjectription, implementato con il seguente codice:

parser.parselistObjectription = function (teiHeader) { var currentDocument = angular.element(teiHeader);

angular.forEach(currentDocument.find(listObject.replace(/[<>]/g, '')), function(element) {

var listObjectContent = evtParser.parseXMLElement(teiHeader, element, { skip: skipElementsFromParser, exclude: skipElementsFromInfo, context:'projectInfo'

}).outerHTML;

parsedData.updateProjectInfoContent( listObjectContent, 'listObject');

157 });

console.log('## parselistObjectription ##', parsedData.getProjectInfo().listObject); };

come si può osservare, il parser consente di memorizzare ogni elemento listObject contenuto nel teiHeader del documento xml. Questa funzionalità offre all’editore la possibilità di visualizzare nell’interfaccia finale il contenuto descrittivo del modello 3D semplicemente indicando le informazioni nell’elemento listObject nell’edizione del testo.

158