if("HypeEasyPad" in window === false) window['HypeEasyPad'] = (function () { // hold our single hypeDocument API var _hypeDocument; // remember all symbols on current scene var _symbolsOnScene; // remember state history changes var _stateHistory = []; // language used in interface var _language = 'DE'; // state shorthand and object var state = {}; // current scene name var _currentStateName = '_START'; // logging off by default var _log = false; // mode of application var _mode = 'web'; // asset URL with trainling slash var _assetFolderBaseUrl = null; // simple interface tranformations var _interface = {} // fetch state from generator (later JSON or server if wanted) var stateMachine = StateMachineGenerator.asObject(); /** * setHypeSingleton * @param {Object} singelton Hype API */ function setHypeDocumentSingleton(hypeDocumentSingelton) { _hypeDocument = hypeDocumentSingelton } /** * setAssetFolderBaseUrl * @param {String} asset URL with trainling slash */ function setAssetFolderBaseUrl(assetFolderBaseUrl) { _assetFolderBaseUrl = assetFolderBaseUrl; } /** * notifyWebKit * @param {Object} paramter for webkit instance */ function notifyWebkit(cmd, obj) { if(window.webkit) { window.webkit.messageHandlers[cmd].postMessage(obj); } else { log ('No webkit object found!'); } } /** * notifyHype * @param {String} name of command * @param {Object} parameter as object */ function notifyHype(cmd, obj) { if (_hypeDocument) { switch(cmd) { case 'setLanguage': setLanguage(obj.language); break; case 'gotoStateByName': gotoStateByName(obj.name); break; case 'redrawCurrentState': redrawCurrentState(); break; case 'setExposureList': setExposureList(obj.list); break; case 'setUserInterfaceTransforms': setUserInterfaceTransforms(obj); break; } } else { log ('HypeDocument not initilized!'); } } /* Most public and notfy functions */ function enableLogging(bol){ _log = (bol==true); } function redrawCurrentState() { if (_currentStateName) { gotoStateByName (_currentStateName); } else { log('Please provide a state name!') } } function setMode(mode) { _mode = mode.toUpperCase()=='IOS'? 'iOS':'web'; redrawCurrentState(); } function setLanguage(language) { _language = language.toUpperCase()=='DE'? 'DE':'EN'; redrawCurrentState(); } function setExposureList(list) { Exposure_List = list; redrawCurrentState(); } /* Hardcoded Aufnahmebereitschaft anhand von PDF "Übersicht Aufnahmen für EasyPad Simulator_2019-12-02.pdf" */ var Exposure_List = []; // setup up symbols based on name function symbolLoad(hypeDocument, element, event) { // short hands var symbolInstance = hypeDocument.getSymbolInstanceById(element.id); var symbolElement = symbolInstance.element(); var symbolName = symbolInstance.symbolName(); var symbolState = getSymbolStateDataByName(symbolName); //var runDefaults = true; //remove any click handler symbolElement.style.cursor = 'default'; symbolElement.onclick = null; //remember this symbol if not a refresh cycle if (event.type!='refresh') { _symbolsOnScene.push(element); } // switch based on symbol name if (symbolState.hidden) { // hidden == true symbolElement.style.display = 'none'; } else { // hidden != true symbolElement.style.display = 'block'; // show (classname) if (symbolState.hasOwnProperty('show')) { displaySymbolGroupByClassname(symbolElement, symbolState.show); } // text if (symbolState.hasOwnProperty('text')) { setupTextDisplay(symbolElement, '.textDisplay', symbolState.text); } // exposureImage if (symbolState.hasOwnProperty('exposureImage')) { log('showing exposureImage', symbolState.exposureImage); var imageElm = symbolElement.querySelector('.exposureImage'); imageElm.style.backgroundSize = 'contain'; imageElm.style.backgroundPosition = 'center'; imageElm.style.backgroundRepeat = 'no-repeat'; _hypeDocument.setElementProperty(imageElm, 'background-image', _assetFolderBaseUrl+symbolState.exposureImage); } // exposureVideo if (symbolState.hasOwnProperty('exposureVideo')) { log('showing exposureVideo', symbolState.exposureVideo); var videoElm = symbolElement.querySelector('.exposureVideo video'); var gotoAfterVideo = symbolState.gotoAfterVideo; videoElm.src = _assetFolderBaseUrl + symbolState.exposureVideo; if(gotoAfterVideo){ videoElm.onended = function() { gotoStateByName(gotoAfterVideo); } } videoElm.load(); } // action if (symbolState.hasOwnProperty('action')) { switch ((typeof symbolState.action == 'object'? symbolState.action.name : symbolState.action)){ case 'showCurrentStateAsExposureImage': setupClickHandler(symbolElement, function(){ showExposureImage(_currentStateName) }); break; case 'showVideo': setupClickHandler(symbolElement, function(){ showVideo(symbolState.video, symbolState.gotoAfterVideo) }); break; case 'showExposureVideo': setupClickHandler(symbolElement, function(){ showExposureVideo(symbolState.video, symbolState.gotoAfterVideo || -1) }); break; } } // goto if (symbolState.hasOwnProperty('goto') && symbolElement.onclick == null) { setupClickHandler(symbolElement, function(){ gotoStateByName(symbolState['goto']); }); } } return true; } function setupClickHandler(symbolElement, action){ symbolElement.style.cursor = 'pointer'; symbolElement.onclick = action; } function setupTextDisplay(symbolElement, selector, content){ var elms = symbolElement.querySelectorAll(selector); elms.forEach(function(elm){ elm.innerHTML = content; }); } function showExposureImage(name){ if (Exposure_List.indexOf(name) != -1){ if (_mode == 'iOS') { notifyWebkit('showExposureImage', { 'name': name }); } else { //dynamic state stateMachine['EXPOSURE'] = { _sceneName: 'IMAGE-VIEWER', 'Image_Viewer': { exposureImage: name+'.jpg' }, 'Close': { goto: -1}, } gotoStateByName('EXPOSURE'); } } else { log('The state '+name+' is not defined in the exposure image list!'); } } function showVideo(name, gotoAfterVideo){ if (_mode == 'iOS') { notifyWebkit('showVideo', { 'name': name }); } else { //dynamic state stateMachine['EXPOSURE'] = { _sceneName: 'VIDEO-VIEWER', 'Video_Viewer': { exposureVideo: name+'.mp4', gotoAfterVideo: gotoAfterVideo }, 'Close': { goto: gotoAfterVideo}, } gotoStateByName('EXPOSURE'); } } function showExposureVideo(name, gotoAfterVideo){ if (_mode == 'iOS') { notifyWebkit('showExposureVideo', { 'name': name }); } else { //dynamic state stateMachine['EXPOSURE'] = { _sceneName: 'VIDEO-VIEWER', 'Video_Viewer': { exposureVideo: name+'_'+_language+'.mp4'}, 'Close': { goto: gotoAfterVideo}, } gotoStateByName('EXPOSURE'); } } function displaySymbolGroupByClassname(symbolElement, classname){ var symBaseSel = '#'+symbolElement.id+'> .HYPE_element_container '; var elms = symbolElement.querySelectorAll(symBaseSel+'[class*="HYPE_element"]'); var extElm = symbolElement.querySelector(symBaseSel+'[class*="'+classname+'"]'); hideAllBut(elms, extElm); } /* helper */ function hideAll (elms) { elms.forEach(function(elm) { elm.style.display = 'none';}); } function hideAllBut (elms, notElm) { elms.forEach(function(elm) { elm.style.display = (notElm == elm) ? 'block' : 'none';}); } /* getter for immutable data */ function getSymbolStateDataByName(symbolName){ if (state.hasOwnProperty(symbolName)) { if (typeof state[symbolName] == 'string') { symbolName = state[symbolName]; } } if (state.hasOwnProperty(symbolName)) { return state[symbolName]; } return {}; } function getStateDataByName(name){ if (stateMachine.hasOwnProperty(name)) { if (typeof stateMachine[name] == 'string') { log('getStateDataByName: Using state alias',stateMachine[name],'instead of',name); name = stateMachine[name]; } } if (stateMachine.hasOwnProperty(name)) { return deepClone(stateMachine[name]); } else { log('getStateDataByName: State "', name, '" not found!'); return {}; } } function getStateDataInheritedByName(name){ // fresh copy var newState = getStateDataByName(name); // inherit? only on layer deep! var inheritStates = newState.hasOwnProperty('_stateInherit')? newState._stateInherit.slice() : []; // inherit inheritStates.forEach(function (name){ if (stateMachine.hasOwnProperty(name)){ Object.assign(newState, getStateDataByName(name)); } }); // overlay in final step to ensure dominance new state data Object.assign(newState, getStateDataByName(name)); //return return newState; } function deepClone(obj){ return JSON.parse(JSON.stringify(obj)); } /* state switcher */ function gotoStateByName(name){ // make sure we have a name if (!name){ log('gotoStateByName: Please provide a name!'); return; } // check if hype is initilized else store and wait if (!_hypeDocument){ log('waiting for HypeEasyPad to load...'); _currentStateName = name; return; } // handle numbers if(name < 0){ name = _stateHistory[_stateHistory.length + (name-1)]; } // check if we have the requested state if (stateMachine.hasOwnProperty(name)) { log('gotoStateByName', name); } else { log('gotoStateByName: State', name, 'not found!'); return; } // remember current state name _currentStateName = name; // remember state name _stateHistory.push(name); // display for info location.hash = name; // refresh state with inheritance state = getStateDataInheritedByName(name); // Exposure button is managed independend of state to keep it flexible state['Text_Exposure'] = { text: (_language=='DE'? 'Aufnahmebereit' : 'Ready for exposure'), } // Check if we have a state that allows exposure if (Exposure_List.indexOf(name) != -1){ state['Fernausloeser_oben'] = { action: 'showCurrentStateAsExposureImage' } } else { state['Button_Exposure'] = { hidden: true } } //jump to state if (_hypeDocument.currentSceneName() != state._sceneName){ //load scene _hypeDocument.showSceneNamed(state._sceneName); } else { //refresh symbols manually type as refresh if (_symbolsOnScene) { _symbolsOnScene.forEach(function(elm) { symbolLoad(_hypeDocument, elm, {type:'refresh'}) }); } } } function log(){ if (_log) console.log.apply(this,arguments); } /* Hype callbacks */ function documentLoad(hypeDocument, element, event) { // set hypeDocument singleton API on HypeDocumentLoad setHypeDocumentSingleton(hypeDocument); redrawCurrentState(); return true; } function setUserInterfaceTransforms(obj){ _interface = obj; } function applyInterfaceSettings(name){ var sceneElm = document.getElementById(_hypeDocument.currentSceneId()); var elm = sceneElm.querySelector('.'+name); if( _interface[name] && elm){ if (_interface[name]['top']) { var top = _hypeDocument.getElementProperty(elm, 'top'); _hypeDocument.setElementProperty(elm, 'top', top+_interface[name]['top']); } if (_interface[name]['left']) { var left = _hypeDocument.getElementProperty(elm, 'left'); _hypeDocument.setElementProperty(elm, 'left', left+_interface[name]['left']); } if (_interface[name]['scale']) { _hypeDocument.setElementProperty(elm, 'scaleX', _interface[name]['scale']); _hypeDocument.setElementProperty(elm, 'scaleY', _interface[name]['scale']); } } } function scenePrepare(hypeDocument, element, event) { _symbolsOnScene = []; //apply API transforms applyInterfaceSettings('EasyPad_Panel'); applyInterfaceSettings('EasyPad_Remote'); // return true; } /* Setup Hype callbacks */ if("HYPE_eventListeners" in window === false) { window.HYPE_eventListeners = Array(); } window.HYPE_eventListeners.push({"type":"HypeDocumentLoad", "callback":documentLoad}); window.HYPE_eventListeners.push({"type":"HypeScenePrepareForDisplay", "callback":scenePrepare}); window.HYPE_eventListeners.push({"type":"HypeSymbolLoad", "callback":symbolLoad}); /* Reveal Public interface to window['HypeEasyPad'] */ return { version: '1.01', 'gotoStateByName': gotoStateByName, 'notifyWebkit': notifyWebkit, 'notifyHype': notifyHype, 'setLanguage': setLanguage, 'enableLogging': enableLogging, 'setExposureList': setExposureList, 'redrawCurrentState': redrawCurrentState, 'setAssetFolderBaseUrl': setAssetFolderBaseUrl, 'setUserInterfaceTransforms': setUserInterfaceTransforms, }; })();