/** * ParaViewWeb JavaScript Library. * * This module extend jQuery object to add support for graphical components * related to ParaViewWeb usage. * * This module registers itself as: 'paraview-ui-pipeline' * * @class jQuery.paraview.ui.PipelineBrowser */ (function (GLOBAL, $) { // ======================================================================= // ==== Defaults constant values ========================================= // ======================================================================= //PIPELINE_REPRESENTATION_NAMES PIPELINE_REPRESENTATION_NAMES_TO_LABELS var PIPELINE_REPRESENTATION_NAMES = 'hide outline wireframe surface surface_edge volume', PIPELINE_REPRESENTATION_NAMES_TO_LABELS = { 'hide': 'Hide', 'outline': 'Outline', 'wireframe': 'Wireframe', 'surface': 'Surface', 'surface_edge': 'Surface With Edges', 'volume': 'Volume' }, PIPELINE_REPRESENTATION_LABELS_TO_NAMES = { 'Hide': 'hide', 'Outline': 'outline', 'Wireframe': 'wireframe', 'Surface': 'surface', 'Surface With Edges': 'surface_edge', 'Volume': 'volume' }, PIPELINE_COLOR_BY_TYPES = 'color points cells', PIPELINE_VIEW_TYPES = 'view-pipeline view-files view-sources', DEFAULT_PIPELINE = { name: "kitware.com", type: 'server', children: [{ proxy_id: 234, name: "Cow.vtu", icon: 'dataset', representation: 'Outline', showScalarBar: false, pointData: [ { name: 'a', range: [0,1], size: 1 }, { name: 'b', range: [5,10], size: 1 }, { name: 'c', range: [2,4], size: 3 }], cellData: [ { name: 'aa', range: [0,1], size: 1 }, { name: 'bb', range: [5,10], size: 1 }, { name: 'cc', range: [2,4], size: 3 }], activeData: 'p:a', children: [{ proxy_id: 235, name: "Iso", icon: 'contour', representation: 'Surface', showScalarBar: false, pointData: [ { name: 'a', range: [0,1], size: 1 }, { name: 'b', range: [5,10], size: 1 }, { name: 'c', range: [2,4], size: 3 }], cellData: [ { name: 'aa', range: [0,1], size: 1 }, { name: 'bb', range: [5,10], size: 1 }, { name: 'cc', range: [2,4], size: 3 }], activeData: 'p:a', children: [{ proxy_id: 236, name: "Clip", type: 'clip', representation: 'Surface' }] }, { proxy_id: 237, name: "Slice", icon: 'slice', representation: 'Surface', showScalarBar: true, pointData: [ { name: 'a', range: [0,1], size: 1 }, { name: 'b', range: [5,10], size: 1 }, { name: 'c', range: [2,4], size: 3 }], cellData: [ { name: 'aa', range: [0,1], size: 1 }, { name: 'bb', range: [5,10], size: 1 }, { name: 'cc', range: [2,4], size: 3 }], activeData: 'p:a' }, { proxy_id: 238, name: "Stream Tracer", icon: 'stream', representation: 'Wireframe', showScalarBar: false, pointData: [ { name: 'a', range: [0,1], size: 1 }, { name: 'b', range: [5,10], size: 1 }, { name: 'c', range: [2,4], size: 3 }], cellData: [ { name: 'aa', range: [0,1], size: 1 }, { name: 'bb', range: [5,10], size: 1 }, { name: 'cc', range: [2,4], size: 3 }], activeData: 'p:a' }, { proxy_id: 239, name: "Threshold", icon: 'threshold', representation: 'Surface Width Edge', showScalarBar: false, pointData: [ { name: 'a', range: [0,1], size: 1 }, { name: 'b', range: [5,10], size: 1 }, { name: 'c', range: [2,4], size: 3 }], cellData: [ { name: 'aa', range: [0,1], size: 1 }, { name: 'bb', range: [5,10], size: 1 }, { name: 'cc', range: [2,4], size: 3 }], activeData: 'p:a' }, { proxy_id: 240, name: "Random filter", icon: 'filter', representation: 'Volume', showScalarBar: false, pointData: [ { name: 'a', range: [0,1], size: 1 }, { name: 'b', range: [5,10], size: 1 }, { name: 'c', range: [2,4], size: 3 }], cellData: [ { name: 'aa', range: [0,1], size: 1 }, { name: 'bb', range: [5,10], size: 1 }, { name: 't', range: [2,4], size: 3 }], activeData: 'c:t' }] }, { proxy_id: 245, name: "Random source", icon: 'dataset', representation: 'Surface', showScalarBar: false, pointData: [ { name: 'z', range: [0,1], size: 1 }, { name: 'b', range: [5,10], size: 1 }, { name: 'c', range: [2,4], size: 3 }], cellData: [ { name: 'aa', range: [0,1], size: 1 }, { name: 'bb', range: [5,10], size: 1 }, { name: 'cc', range: [2,4], size: 3 }], activeData: 'p:z' }] }, DEFAULT_SOURCES = [{ name: 'Cone', icon: 'dataset', category: 'source' },{ name: 'Wavelet', icon: 'dataset', category: 'source' },{ name: 'Clip', icon: 'clip', category: 'filter' },{ name: 'Slice', icon: 'slice', category: 'filter' },{ name: 'Contour', icon: 'contour', category: 'filter' },{ name: 'Threshold', icon: 'threshold', category: 'filter' },{ name: 'Stream Tracer', icon: 'stream', category: 'filter' },{ name: 'Warp', icon: 'filter', category: 'filter' }], busyStatus = 0, buffer = null; // ======================================================================= // ==== jQuery based methods ============================================= // ======================================================================= /** * Graphical component use to show and interact with the ParaViewWeb * pipeline. * * @member jQuery.paraview.ui.PipelineBrowser * @method pipelineBrowser * @param {Object} options * * Usage: * * $('.pipeline-container-div').pipelineBrowser({ * session: sessionObj, * pipeline: pipeline, * sources: sourceList, * files: fileList, * title: 'Kitware', * cacheFiles: false * }); */ $.fn.pipelineBrowser = function(options) { // Handle data with default values var opts = $.extend({},$.fn.pipelineBrowser.defaults, options); return this.each(function() { var me = $(this).empty().addClass('pipelineBrowser view-pipeline'), session = opts.session; // Initialize global html buffer if (buffer === null) { buffer = createBuffer(); } buffer.clear(); // Update DOM me.data('pipeline', opts); updateIndexMap(me, 0, opts.pipeline.children); // Fill buffer with pipeline HTML addPipelineToBuffer(opts.title, opts); me[0].innerHTML = buffer.toString(); // Initialize file section $('.pipeline-files').fileBrowser({session: session, cacheFiles: opts.cacheFiles}).bind('file-click file-group-click', function(e){ pipeline = getPipeline(me), toggleButton = $('.files.active', pipeline); pipeline.removeClass(PIPELINE_VIEW_TYPES).addClass('view-pipeline'); toggleButton.removeClass('active'); fireBusy(pipeline, true); session.call("pv.pipeline.manager.file.ropen", [e.relativePathList]).then(function(newFile){ dataChanged(me); addProxy(me, 0, newFile); fireAddSource(pipeline, newFile, 0); fireBusy(pipeline, false); }); }); // Initialize pipelineBrowser (Visibility + listeners) initializeListener(me); // Attach RPC method if possible attachSessionController(me); }); }; $.fn.pipelineBrowser.defaults = { session: null, pipeline: DEFAULT_PIPELINE, sources: DEFAULT_SOURCES, title: 'Kitware', cacheFiles: true }; /** * Method used to retreive a proxy from the Pipeline browser. * If the proxyId is null/undefined the selected proxy will be returned. * * @member jQuery.paraview.ui.PipelineBrowser * @method getProxy * @param {Number|undefined|null} proxyId * @return {pv.Proxy} proxy that have the given id or null if not found. * * Usage: * var selectedProxy = $('.pipeline-container-div').getProxy(); * var proxy = $('.pipeline-container-div').getProxy(1234); */ $.fn.getProxy = function(proxyId) { var me = $(this); if(proxyId === null || proxyId === undefined) { proxyId = me.data('active_proxy_id'); } return getProxy(me, proxyId); }; // ======================================================================= // ==== Events triggered on the pipelineBrowser ========================== // ======================================================================= /** * Event triggered when a Proxy has changed. * * @member jQuery.paraview.ui.PipelineBrowser * @event proxyModified * @param {Number} id * Proxy ID that was changed. * @param {String} origin * Origin on which the change set apply. Such as 'property' or 'representation' or 'scalarbar'. * ['property', 'representation', 'scalarbar', 'colorBy'] * @param {Object} changeSet * Object that contain a set of key/value pair that correspond to field name and field value. */ function fireProxyChange(uiWidget, origin, changeSet) { getPipeline(uiWidget).trigger({ type: 'proxyModified', proxy_id: getProxyId(uiWidget), origin: origin, changeSet: changeSet }); dataChanged(uiWidget); } /** * Event triggered when selection change in the Pipeline browser. * @member jQuery.paraview.ui.PipelineBrowser * @event proxySelected * @param {Number} id * Id of the proxy that get selected in the Pipeline. Can be 0 if no selection. */ function fireProxySelected(uiWidget) { var proxyWidget = getProxyWidget(uiWidget), activeProxyId = getProxyId(uiWidget), pipelineBrowser = getPipeline(uiWidget), proxy = getProxy(pipelineBrowser, activeProxyId); // Save selected proxy setActiveProxyId(uiWidget, activeProxyId); // Update property panel updateProxyProperties(pipelineBrowser, proxy); $('.proxy-control', pipelineBrowser).removeClass('selected'); $('.proxy-control:eq(0)', proxyWidget).addClass('selected'); // Allow delete ? if(activeProxyId === 0 || $('ul', proxyWidget).children().length > 0) { $('.pipeline-control .delete-proxy', getPipeline(uiWidget)).addClass('disabled'); } else { $('.pipeline-control .delete-proxy', getPipeline(uiWidget)).removeClass('disabled'); getPipeline(uiWidget).addClass('view-filters'); } // Send event pipelineBrowser.trigger({ type: 'proxySelected', proxy_id: activeProxyId }); } /** * Event that get triggered when the user wants to invalidate the full pipeline * and get a new version from the server. * @member jQuery.paraview.ui.PipelineBrowser * @event reloadPipeline */ function fireReloadPipeline(uiWidget) { getPipeline(uiWidget).trigger({ type: 'reloadPipeline' }); } /** * Event that get triggered when a source or a filter is getting added. * @member jQuery.paraview.ui.PipelineBrowser * @event addSource * @param {String} name * Name of the SourceProxy to be created. * @param {Number} parent * Global Id of the parent Proxy if any, null otherwise. */ function fireAddSource(container, algoName, parent) { container.trigger({ type: 'addSource', name: algoName, parent_id: parent }); dataChanged(container); } /** * Event that get triggered when a Proxy get deleted. * @member jQuery.paraview.ui.PipelineBrowser * @event deleteProxy * @param {pv.Proxy} proxy * Proxy that is getting deleted. */ function fireDeleteProxy(uiWidget) { getPipeline(uiWidget).trigger({ type: 'deleteProxy', proxy_id: getActiveProxyId(uiWidget) }); dataChanged(uiWidget); } /** * Event that get triggered when the apply button is cliked to push proxy * properties to the server. * @member jQuery.paraview.ui.PipelineBrowser * @event apply */ function fireApply(uiWidget) { getPipeline(uiWidget).trigger('apply'); dataChanged(uiWidget); } /** * Event that get triggered when the reset button is cliked to update * ui widget with previous values. * @member jQuery.paraview.ui.PipelineBrowser * @event reset */ function fireReset(uiWidget) { getPipeline(uiWidget).trigger('reset'); } /** * Event triggered when anything in the pipeline has changed and therefore * a viewport update should occurs. * * @member jQuery.paraview.ui.PipelineBrowser * @event dataChanged */ function dataChanged(uiWidget) { getPipeline(uiWidget).trigger('dataChanged'); } /** * Event triggered when the pipeline browser changes busy states * * @member jQuery.paraview.ui.PipelineBrowser * @event busy * @param {Boolean} status * True when pipeline is busy, false otherwise */ function fireBusy(uiWidget, isBusy) { busyStatus += (isBusy ? 1 : -1); getPipeline(uiWidget).trigger({ type: 'busy', status: (busyStatus > 0) }); } // ======================================================================= // ==== Data Model Access ================================================ // ======================================================================= function updateIndexMap(pipelineBrowser, parentId, childrenList) { var indexObject = pipelineBrowser.data('proxyIndexMaps'), proxy, idx; if(indexObject === null || indexObject === undefined) { indexObject = { 'ProxyIdToProxy': {}, 'ProxyIdToParentId': {} }; pipelineBrowser.data('proxyIndexMaps', indexObject); } // Create fake root node that has the children if(parentId === 0) { indexObject.ProxyIdToProxy['0'] = { 'children': childrenList }; } // Fill maps for(idx in childrenList) { proxy = childrenList[idx]; indexObject.ProxyIdToProxy[proxy.proxy_id.toString()] = proxy; indexObject.ProxyIdToParentId[proxy.proxy_id.toString()] = parentId; if(proxy.hasOwnProperty("children")) { updateIndexMap(pipelineBrowser, proxy.proxy_id, proxy.children); } } } // ======================================================================= function generateDisabledLut(dataArray) { var lutArray = []; if(dataArray != null) { for(var idx in dataArray) { lutArray.push( { id: (dataArray[idx].name + '_' + dataArray[idx].size), name: dataArray[idx].name, size: dataArray[idx].size, enabled: 0 }); } } return lutArray; } // ======================================================================= function getActiveLookupTable(proxy) { var activeData = proxy.activeData, name, arrays = null; if(activeData.indexOf('POINT_DATA:') === 0 ) { arrays = proxy.pointData; } else if(activeData.indexOf('CELL_DATA:') === 0) { arrays = proxy.cellData; } if(arrays != null) { name = activeData.split(':')[1]; for(var idx in arrays) { if(arrays[idx].name === name) { return { id: (name + '_' + arrays[idx].size), name: name, size: arrays[idx].size, enabled: 0 }; } } } return null; // Color } // ======================================================================= function generateScalarbarStatus(pipelineBrowser, changedProxy) { var indexObject = pipelineBrowser.data('proxyIndexMaps'), proxy, lut, state = {}, fullLutArray = [], lutsToEnable = {}, lutToDisable = null; if(changedProxy != null && !changedProxy.showScalarBar) { // Need to force active lut to 0 lutToDisable = getActiveLookupTable(changedProxy); } if(indexObject != null && indexObject != undefined) { for(var key in indexObject.ProxyIdToProxy) { proxy = indexObject.ProxyIdToProxy[key]; if(proxy.hasOwnProperty('showScalarBar')) { // Generate lut info for each data array fullLutArray = fullLutArray.concat(generateDisabledLut(proxy.pointData)); fullLutArray = fullLutArray.concat(generateDisabledLut(proxy.cellData)); // Valid proxy lut = getActiveLookupTable(proxy); if(lut != null && proxy.showScalarBar) { lutsToEnable[lut.id] = 1; } } } } // Build state for(var idx in fullLutArray) { lut = fullLutArray[idx]; state[lut.id] = lut; if(lutsToEnable.hasOwnProperty(lut.id)) { state[lut.id].enabled = 1; } } // Update LUT from changed proxy if need be if(lutToDisable != null) { state[lutToDisable.id].enabled = 0; } return state; } // ======================================================================= function getProxy(anyInnerPipelineWidget, proxyId) { var indexObject = getPipeline(anyInnerPipelineWidget).data('proxyIndexMaps'); return indexObject.ProxyIdToProxy[proxyId.toString()]; } // ======================================================================= function getParentProxyId(anyInnerPipelineWidget, proxyId) { var indexObject = getPipeline(anyInnerPipelineWidget).data('proxyIndexMaps'); return indexObject.ProxyIdToParentId[proxyId.toString()]; } // ======================================================================= function getActiveProxyId(anyInnerPipelineWidget) { return getPipeline(anyInnerPipelineWidget).data('active_proxy_id'); } // ======================================================================= function setActiveProxyId(anyInnerPipelineWidget, proxyId) { getPipeline(anyInnerPipelineWidget).data('active_proxy_id', proxyId); } // ======================================================================= function updateProxy(pipelineBrowser, proxy) { var proxyInModel, pipelineLineAfter, pipelineLineBefore; // Handle data model part proxyInModel = getProxy(pipelineBrowser, proxy.proxy_id); mergeProxy(proxyInModel, proxy); // Handle UI part // Update subtree // Generate html buffer.clear(); addProxyToBuffer(proxy); // Update HTML pipelineLineBefore = $('.proxy[proxy_id=' + proxy.proxy_id + '] > .pipeline-line', pipelineBrowser); pipelineLineAfter = $(buffer.toString()).find('.pipeline-line'); pipelineLineBefore.empty() pipelineLineBefore[0].innerHTML = pipelineLineAfter[0].innerHTML; // Attach listeners initializeListener(pipelineLineBefore); // Update proxy editor updateProxyProperties(pipelineBrowser, proxy); } // ======================================================================= function addProxy(pipelineBrowser, parentId, newNode) { var container, parentProxy, newProxyContainer; // Handle data model part parentProxy = getProxy(pipelineBrowser, parentId); parentProxy.children.push(newNode); updateIndexMap(pipelineBrowser, parentId, parentProxy.children); // Handle UI part if(parentId === 0) { container = $('li.server > ul', pipelineBrowser); } else { proxyWidget = $('.proxy[proxy_id=' + parentId + '] > .proxy-control > .representation', pipelineBrowser); container = $('.proxy[proxy_id=' + parentId + '] > ul', pipelineBrowser); // Update data model for new representation parentProxy.representation = 'Hide'; // Update UI to hide proxy proxyWidget.removeClass(PIPELINE_REPRESENTATION_NAMES).addClass('hide'); // Hide parent proxy fireProxyChange(container, 'representation', { 'representation': 'Hide' }) } // Generate html buffer.clear(); addProxyToBuffer(newNode); // Append to children list container.append($(buffer.toString())); // Attach listeners initializeListener(container); // Set that proxy to be active newProxyContainer = $('.proxy[proxy_id=' + newNode['proxy_id'] + '] .proxy-control', container); fireProxySelected(newProxyContainer); } // ======================================================================= function removeProxy(pipelineBrowser, proxyId) { // Handle data model part var parentProxyId, parentProxy, proxy, idxToDelete, indexObject; proxy = getProxy(pipelineBrowser, proxyId); parentProxyId = getParentProxyId(pipelineBrowser, proxyId); parentProxy = getProxy(pipelineBrowser, parentProxyId); idxToDelete = parentProxy.children.indexOf(proxy); parentProxy.children.splice(idxToDelete,1); // Remove Proxy entry in map connectivity indexObject = pipelineBrowser.data('proxyIndexMaps'); delete indexObject.ProxyIdToProxy[proxyId.toString()]; delete indexObject.ProxyIdToParentId[proxyId.toString()]; // Handle UI part $('.proxy[proxy_id=' + proxyId + ']', pipelineBrowser).remove(); updateUIPipeline(pipelineBrowser); $('.delete-proxy', pipelineBrowser).addClass('disabled'); $('.property', pipelineBrowser).remove(); setActiveProxyId(pipelineBrowser, 0); } // ======================================================================= // ==== HTML code generators ============================================= // ======================================================================= function VTK2ColorRGB(rgb) { var tmpBuffer = createBuffer(), hexCode = '0123456789ABCDEF', value; tmpBuffer.append("#"); for(var i in rgb) { value = rgb[i] * 255; tmpBuffer.append(hexCode[Math.floor(value/16)]); tmpBuffer.append(hexCode[Math.floor(value%16)]); } return tmpBuffer.toString(); } // ======================================================================= function addPipelineToBuffer(title, data) { // Build pipeline header buffer.append("
"); // Add floating selector buffer.append("
"); // pipeline-tree buffer.append("
\n"); // Build file selector buffer.append("
"); // Build source/filter selector buffer.append("
"); addSourcesToBuffer(data.sources); buffer.append("
"); // Build pipeline-editor buffer.append("
"); buffer.append("
Property panel
"); buffer.append("
"); } // ======================================================================= function addProxiesToBuffer(proxyList) { if(proxyList === undefined || proxyList === null) { return; } buffer.append(""); } // ======================================================================= function addProxyToBuffer(proxy) { if(proxy === undefined || proxy === null) { return; } var colorBy = '#FFFFFF', selected = '' + proxy.activeData, lut = getActiveLookupTable(proxy); // Handle pipeline topology buffer.append("
  • "); // Add header line buffer.append("
    "); buffer.append(proxy.name); buffer.append("
    "); // Handle children if any if(proxy.hasOwnProperty("children")) { addProxiesToBuffer(proxy.children); } buffer.append("
  • "); } // ======================================================================= function addSourcesToBuffer(sourceList) { if(sourceList === undefined || sourceList === null) { return; } // Build proxy line var i, item; buffer.append(""); } // ======================================================================= function updateArrayList(proxyId, container) { var pipeline = getPipeline(container), proxy = getProxy(pipeline, proxyId), list = $('ul', container), idx = 0; // Generate HTML buffer.clear(); buffer.append("
  • Solid Color
  • \n"); for(idx in proxy.pointData) { buffer.append("
  • "); buffer.append(proxy.pointData[idx].name); buffer.append(" ["); buffer.append(proxy.pointData[idx].size); buffer.append("]
  • \n"); } for(idx in proxy.cellData) { buffer.append("
  • "); buffer.append(proxy.cellData[idx].name); buffer.append(" ["); buffer.append(proxy.cellData[idx].size); buffer.append("]
  • \n"); } list.empty()[0].innerHTML = buffer.toString(); initializeListener(container); return container; } // ======================================================================= // ==== Helper internal functions ======================================== // ======================================================================= function createBuffer() { var idx = -1, buffer = []; return { clear: function(){ idx = -1; buffer = []; }, append: function(str) { buffer[++idx] = str; return this; }, toString: function() { return buffer.join(''); } }; } // ======================================================================= function getProxyId(anyInnerProxyWidget) { var value = Number(getProxyWidget(anyInnerProxyWidget).attr('proxy_id')); return value ? value : 0; } // ======================================================================= function getProxyWidget(anyInnerProxyWidget) { return anyInnerProxyWidget.closest('.proxy'); } // ======================================================================= function getPipeline(anyInnerPipelineWidget) { return anyInnerPipelineWidget.closest('.pipelineBrowser'); } // ======================================================================= function mergeProxy(proxyToUpdate, newProxy) { proxyToUpdate.state = newProxy.state; proxyToUpdate.pointData = newProxy.pointData; proxyToUpdate.cellData = newProxy.cellData; proxyToUpdate.activeData = newProxy.activeData; proxyToUpdate.name = newProxy.name; proxyToUpdate.diffuseColor = newProxy.diffuseColor; } // ======================================================================= function getProxyPropertyPanelState(anyInnerProxyWidget, onRepresentation) { var pipelineBrowser = getPipeline(anyInnerProxyWidget), state = {}; state.proxy = getActiveProxyId(pipelineBrowser); $('.property' + (onRepresentation?".on-representation":""), pipelineBrowser).each(function(){ var property = $(this), values = [], value = 0, isNumber = false, type = property.attr('data-type'); if (type != undefined) { isNumber = domainIsNumber(type); } // Extract property values $('input[type=text]', property).each(function(){ value = isNumber ? Number($(this).val()) : $(this).val(); values.push(value); }); $('input[type=checkbox]', property).each(function(){ values.push($(this).is(':checked') ? 1 : 0); }); $('select[type=array]', property).each(function(){ value = $(this).val(); if(value != null) { values = $(this).val().split(';'); } else { values = null; } }); $('select[type=enum]', property).each(function(){ value = Number($(this).val()); values.push(value); }); $('select[type=list]', property).each(function(){ value = $(this).val(); values.push(value); }); // Build property info if(!state.hasOwnProperty(property.attr('proxy'))) { state[property.attr('proxy')] = {}; } if(values != null) { state[property.attr('proxy')][property.attr('label')] = values; } }); return state; } // ======================================================================= // ==== Controller methods (event > actions) ============================= // ======================================================================= function attachSessionController(pipelineBrowser) { // Is it a pipelineBrowser if(!pipelineBrowser.data('pipeline').hasOwnProperty('session')) { // No job for us... return; } // Get session var session = pipelineBrowser.data('pipeline').session; if(session === null || session === undefined) { // No job for us... return; } function idle() { fireBusy(pipelineBrowser, false); } // Attach filter creation pipelineBrowser.bind('addSource', function(e) { var parentId = (e.parent_id ? e.parent_id : 0); fireBusy(pipelineBrowser, true); session.call('pv.pipeline.manager.proxy.add', [e.name, parentId]).then(function(newNode) { fireBusy(pipelineBrowser, false); addProxy(pipelineBrowser, parentId, newNode); }, idle); }); // Attach pipeline reload pipelineBrowser.bind('reloadPipeline', function(e) { fireBusy(pipelineBrowser, true); session.call('pv.pipeline.manager.reload').then(function(rootNode) { fireBusy(pipelineBrowser, false); var pipelineLineAfter, pipelineLineBefore; // Update data model part data = pipelineBrowser.data('pipeline'); data.pipeline = rootNode; updateIndexMap(pipelineBrowser, 0, rootNode.children); // Handle UI part // Update subtree // Generate html buffer.clear(); addProxiesToBuffer(rootNode['children']); // Update HTML pipelineLineBefore = $('li.server > ul', pipelineBrowser); pipelineLineAfter = $(buffer.toString()); pipelineLineBefore.empty() pipelineLineBefore[0].innerHTML = pipelineLineAfter[0].innerHTML; // Attach listeners initializeListener(pipelineLineBefore); // Update proxy editor setActiveProxyId(pipelineBrowser, 0); }, idle); }); // Attach representation change pipelineBrowser.bind('proxyModified', function(e) { var changeSet = e.changeSet, options = { 'proxy_id': e.proxy_id, 'action' : e.origin }; if(e.origin === 'representation') { if(changeSet.representation === 'Hide') { options['Visibility'] = 0; } else { options['Visibility'] = 1; options['Representation'] = changeSet.representation; } session.call('pv.pipeline.manager.proxy.representation.update', [options]); } else if(e.origin === 'colorBy') { if(changeSet.hasOwnProperty('color')) { // Solid color var colorArray = changeSet.color.split(','); for(var i in colorArray) { colorArray[i] = Number(colorArray[i]); } options['DiffuseColor'] = colorArray; options['ColorArrayName'] = ''; } else { // Data array options['ColorAttributeType'] = (changeSet.array_type === 'points') ? 'POINT_DATA' : 'CELL_DATA'; options['ColorArrayName'] = changeSet.array; } // Update server fireBusy(pipelineBrowser, true); session.call('pv.pipeline.manager.proxy.representation.update', [options]).then(function(){ session.call('pv.pipeline.manager.scalarbar.visibility.update').then(function(status){ pipelineBrowser.data('scalarbars', status); updateUIPipeline(pipelineBrowser); updateScalarBarUI(pipelineBrowser, status); fireBusy(pipelineBrowser, false); }, idle); }, idle); } else if(e.origin === 'scalarbar') { fireBusy(pipelineBrowser, true); session.call('pv.pipeline.manager.scalarbar.visibility.update', [changeSet]).then(function(status){ fireBusy(pipelineBrowser, false); pipelineBrowser.data('scalarbars', status); updateScalarBarUI(pipelineBrowser, status); }, idle); } else if(e.origin === 'property') { for(var key in changeSet) { options[key] = changeSet[key]; } fireBusy(pipelineBrowser, true); session.call('pv.pipeline.manager.proxy.update', [options]).then(function(newState){ fireBusy(pipelineBrowser, false); updateProxy(pipelineBrowser, newState); }, idle); } else if(e.origin === 'representation-property') { for(var key in changeSet) { options[key] = changeSet[key]; } session.call('pv.pipeline.manager.proxy.representation.update', [options]); } }); // Attach delete action pipelineBrowser.bind('deleteProxy', function(e) { fireBusy(pipelineBrowser, true); session.call('pv.pipeline.manager.proxy.delete', [e.proxy_id]).then(function(){ removeProxy(pipelineBrowser, e.proxy_id); var fullLutStatus = pipelineBrowser.data('scalarbars'), localStatus = generateScalarbarStatus(pipelineBrowser, null), lutToDelete = {}, needToUpdateServer = false; for(var key in fullLutStatus) { if(!localStatus.hasOwnProperty(key)) { lutToDelete[key] = fullLutStatus[key]; lutToDelete[key].enabled = 0; needToUpdateServer = true; } else if(fullLutStatus[key].enabled != 0 && localStatus[key].enabled == 0){ lutToDelete[key] = fullLutStatus[key]; lutToDelete[key].enabled = 0; needToUpdateServer = true; } } fireBusy(pipelineBrowser, false); if(needToUpdateServer) { fireBusy(pipelineBrowser, true); session.call('pv.pipeline.manager.scalarbar.visibility.update', [lutToDelete]).then(function(status){ updateScalarBarUI(pipelineBrowser, status); fireBusy(pipelineBrowser, false); }, idle); } }, idle); }); // Attach property editing pipelineBrowser.bind('apply', function() { var proxyState = getProxyPropertyPanelState(pipelineBrowser, false), repState = getProxyPropertyPanelState(pipelineBrowser, true), repState_OK = {}; // Convert representation props repState_OK['proxy_id'] = repState['proxy']; for(var key in repState[repState['proxy']]) { repState_OK[key] = repState[repState['proxy']][key]; } getProxy(pipelineBrowser, repState_OK['proxy_id']).opacity = repState_OK['Opacity'][0]; fireBusy(pipelineBrowser, true); session.call('pv.pipeline.manager.proxy.update', [proxyState]).then(function(newState){ fireBusy(pipelineBrowser, false); session.call('pv.pipeline.manager.proxy.representation.update', [repState_OK]).then(function(){ newState.opacity = repState_OK['Opacity'][0]; updateProxy(pipelineBrowser, newState); }); }, idle); }); pipelineBrowser.bind('reset', function() { var activeProxyId = getActiveProxyId(pipelineBrowser), activeProxy = getProxy(pipelineBrowser, activeProxyId); updateProxyProperties(pipelineBrowser, activeProxy); }); } // ======================================================================= // ==== UI Listeners ===================================================== // ======================================================================= function updateUIPipeline(pipelineBrowser) { // Update Pipeline UI tree look $('li.proxy', pipelineBrowser).removeClass('lastChild open'); $('li.proxy:last-child', pipelineBrowser).addClass('lastChild'); $('li.proxy > ul > li.proxy', pipelineBrowser).parent().parent().addClass('open'); // Handle delete button status var selectedProxy = $('.proxy > div.selected', pipelineBrowser); if(selectedProxy.length > 0) { $('.server .delete-proxy', pipelineBrowser).removeClass('disabled'); selectedProxy.parent().children('ul').children('li').closest('.server').find('.delete-proxy').addClass('disabled'); } else { $('.server .delete-proxy', pipelineBrowser).addClass('disabled'); } } // ======================================================================= function updateScalarBarUI(pipelineBrowser, state) { // Update scalarbar visibility $('.scalarbar', pipelineBrowser).each(function(){ var me = $(this), lutId, colorBy = me.siblings(); if(colorBy.attr('name') === undefined) { me.addClass('disable'); } else { lutId = colorBy.attr('name') + '_' + colorBy.attr('size'); if(state.hasOwnProperty(lutId) && state[lutId].enabled != 0) { me.removeClass('disable off'); } else { me.removeClass('disable').addClass('off'); } } }); } // ======================================================================= function initializeListener(container) { var pipelineBrowser = getPipeline(container), selectedProxy = getActiveProxyId(pipelineBrowser), colorPicker = pipelineBrowser.data('colorPicker'); updateUIPipeline(pipelineBrowser); updateScalarBarUI(pipelineBrowser,generateScalarbarStatus(pipelineBrowser, null)); // ============ Update UI to show selected proxy =========== if(selectedProxy === 0) { $('.proxy > div', pipelineBrowser).removeClass('selected'); } else { $('.proxy[proxy_id=' + selectedProxy +'] > div', pipelineBrowser).addClass('selected'); } // ============ Representations ============ $(".representation:not(.all)", pipelineBrowser).unbind().click(function(e){ var me = $(this), selector = $(".representation-selector", pipelineBrowser); if(me.hasClass('active') && selector.is(':visible')) { selector.hide(); $(".representation", pipelineBrowser).removeClass("active"); } else { $(".representation", pipelineBrowser).removeClass("active"); me.addClass("active"); selector.css("left", me.offset().left /*- 4*/ + 5 + me.width() ).css("top", me.offset().top - pipelineBrowser.offset().top - 5).show(); } }); // ============ Representations Selection ============ $(".representation-selector", pipelineBrowser).unbind().click(function(e){ var me = $(this), pos = Math.floor((e.pageX - me.offset().left)/34), representation = PIPELINE_REPRESENTATION_NAMES.split(' ')[pos], proxyWidget = $('.representation.active', pipelineBrowser); // Update UI proxyWidget.removeClass(PIPELINE_REPRESENTATION_NAMES).addClass(representation); me.hide(); // Trigger event fireProxyChange(proxyWidget, 'representation', { 'representation': PIPELINE_REPRESENTATION_NAMES_TO_LABELS[representation] } ); }).mousemove(function(e){ var me = $(this), pos = Math.floor((e.pageX - me.offset().left)/34), label = $('.representation-overlay-label', pipelineBrowser), selector = $(".representation-overlay-selector", pipelineBrowser); if(pos < PIPELINE_REPRESENTATION_NAMES.split(' ').length) { label.empty().html(PIPELINE_REPRESENTATION_NAMES_TO_LABELS[PIPELINE_REPRESENTATION_NAMES.split(' ')[pos]].replace(/ /g,' ')).css("left", me.width() + 10).show(); selector.css("left", 34*pos - 1).show(); } }); // ============ Color By / Array Selection ============ $(".colorBy.color", pipelineBrowser).each(function(){ // UpdateColor var me = $(this), proxyId = getProxyId(me), proxy = getProxy(me, proxyId), colorArray = eval(proxy.diffuseColor), color = VTK2ColorRGB(colorArray); me.css("background", color); }); $(".colorBy", pipelineBrowser).unbind().hover(function(){ // in var me = $(this), tooltip = $('.tooltip', pipelineBrowser); if(me.hasClass("color")) { // Nothing to do } else if(me.attr('active-data')) { tooltip.empty().html(me.attr('active-data')); tooltip.css("left", me.offset().left - 15 - tooltip.width()).css("top", me.offset().top - pipelineBrowser.offset().top - 3).show(); } }, function() { // out $('.tooltip', pipelineBrowser).empty().hide(); }).click(function(){ var me = $(this), selector = $(".array-selector", pipelineBrowser), delta = 0, colorBy = $(".colorBy", pipelineBrowser); if(me.hasClass('active') && ((jscolor.picker && $(jscolor.picker.boxB).is(':visible')) || selector.is(':visible'))) { colorPicker = pipelineBrowser.data('colorPicker'); colorPicker.hidePicker(); selector.hide(); colorBy.removeClass("active"); pipelineBrowser.data('colorPicker').hidePicker(); // Trigger event for color if(me.hasClass('color')) { fireProxyChange(me, 'colorBy', { 'color': me.attr('active-data') }); } } else { colorBy.removeClass("active"); me.addClass("active"); $('.array-selector', pipelineBrowser).show(); if(me.hasClass('color')) { delta = 6; } selector.css("left", me.offset().left + me.width() + delta - selector.width()).css("top", me.offset().top + me.height() + delta - pipelineBrowser.offset().top + 5); updateArrayList(getProxyId(me),selector).show(); } }); // ============ Scalar bar ============ $(".scalarbar", pipelineBrowser).unbind().click(function(){ var me = $(this), state = {}, proxyId = getProxyId(me), proxy = getProxy(me, proxyId); if(!me.hasClass("disable")) { proxy.showScalarBar = !proxy.showScalarBar; state = generateScalarbarStatus(pipelineBrowser, proxy); fireProxyChange(me, 'scalarbar', state); updateScalarBarUI(pipelineBrowser, state); } }); // ============ Array Selection ============ $(".array-selector", pipelineBrowser).unbind().hover(function(){}, function(){ if($('ul', this).is(':visible')) { $(this).hide(); } }); $(".array-selector li", pipelineBrowser).unbind().click(function(){ // Select array action var me = $(this), activeColorBy = $(".colorBy.active", pipelineBrowser), colorPicker, colorPickerWidget, proxyId = getProxyId(activeColorBy), proxy = getProxy(activeColorBy, proxyId); activeColorBy.attr('active-data', me.html()).removeClass(PIPELINE_COLOR_BY_TYPES).addClass(me.attr('class')); if(me.hasClass('color')) { // We are not done, we need to pick a color colorPicker = pipelineBrowser.data('colorPicker'); colorPicker.showPicker(); colorPickerWidget = $(jscolor.picker.boxB); colorPickerWidget.css('top', activeColorBy.offset().top - 2).css('left', activeColorBy.offset().left - colorPickerWidget.width() - 10); $('.array-selector', pipelineBrowser).hide(); activeColorBy.removeAttr('name').removeAttr('size'); proxy.activeData = '#'; proxy.showScalarBar = false; } else { $(".array-selector", pipelineBrowser).hide(); activeColorBy.attr('name', me.attr('name')).attr('size', me.attr('size')); proxy.activeData = (me.attr('class') === 'points' ? 'POINT_DATA:' : 'CELL_DATA:') + me.attr('name'); // Trigger event fireProxyChange(activeColorBy, 'colorBy', { 'array': me.attr('name'), 'number_of_components': me.attr('size'), 'array_type': me.attr('class') }); } // Update scalar bar visibility var scalarBarState = generateScalarbarStatus(pipelineBrowser); fireProxyChange(pipelineBrowser, 'scalarbar', scalarBarState); updateScalarBarUI(pipelineBrowser,scalarBarState); }); // ============ Color picker ============ try { if(colorPicker === null || colorPicker === undefined) { colorPicker = new jscolor.color($('input.color')[0], { slider: false, onImmediateChange: updateColorCallback }); pipelineBrowser.data('colorPicker', colorPicker); } } catch(error) { console.log("No color picker library"); console.log(error); } function updateColorCallback() { var colorPicker = pipelineBrowser.data('colorPicker'), proxyWidget = $(".colorBy.active", pipelineBrowser), color = "#" + colorPicker.toString(); proxyWidget.attr('active-data', colorPicker.rgb).css("background", color); } // ============ Proxy Selection ============ $('.proxy-control', pipelineBrowser).unbind().click(function(){ var me = $(this), selector = $('.option-selector:visible', pipelineBrowser); if(getProxyId($('.proxy-control.selected', pipelineBrowser)) === getProxyId(me)) { return; } $('.proxy-control', pipelineBrowser).removeClass('selected'); me.addClass('selected'); if(selector && getProxyId(me) != getProxyId($('.active', pipelineBrowser))) { selector.hide(); } // Trigger new selected proxy fireProxySelected(me); }); // ============= Toggle Panel visibility =========== $('.pipeline-control .files', pipelineBrowser).unbind().click(function(){ var me = $(this), pipeline = getPipeline(me), activeView = 'view-files'; if(pipeline.hasClass('view-files')) { activeView = 'view-pipeline'; } pipeline.removeClass(PIPELINE_VIEW_TYPES).addClass(activeView); me.toggleClass('active'); if(me.hasClass('active')) { $('.pipeline-control .add', pipelineBrowser).removeClass('active'); } }); $('.pipeline-control .add', pipelineBrowser).unbind().click(function(){ var me = $(this), pipeline = getPipeline(me), activeView = 'view-sources'; if(pipeline.hasClass('view-sources')) { activeView = 'view-pipeline'; } pipeline.removeClass(PIPELINE_VIEW_TYPES).addClass(activeView); me.toggleClass('active'); if(me.hasClass('active')) { $('.pipeline-control .files', pipelineBrowser).removeClass('active'); } }); $('.pipeline-control .edit', pipelineBrowser).unbind().click(function(){ var me = $(this), pipeline = getPipeline(me); pipeline.toggleClass('view-pipeline-editor'); me.toggleClass('active'); }); // ============= Source/Filter browsing =========== $(".pipeline-sources .action", pipelineBrowser).unbind().click(function(){ var me = $(this), pipeline = getPipeline(me), toggleButton = $('.add.active', pipeline); pipeline.removeClass(PIPELINE_VIEW_TYPES).addClass('view-pipeline'); toggleButton.removeClass('active'); var parentId = (me.attr('category') === 'filter') ? getActiveProxyId(pipelineBrowser) : 0; fireAddSource(pipeline, me.text(), parentId); }); // ============= Delete Selected Proxy =========== $('.delete-proxy', pipelineBrowser).unbind().click(function(){ var me = $(this); if(!me.hasClass('disabled')) { fireDeleteProxy(me); } }); // ============= Apply / Reset =========== $('.apply', pipelineBrowser).unbind().click(function(){ var me = $(this); me.removeClass('modified'); fireApply(me); }); $('.reset', pipelineBrowser).unbind().click(function(){ fireReset($(this)); }); // ============= Invalidate / Reload Pipeline =========== $('.head-icon.server',pipelineBrowser).unbind().click(function(){ fireReloadPipeline($(this)); }); // ============= Representation properties =========== $('.pipeline-editor-representation input[type="range"]').change(function(){ var me = $(this), name = me.attr('name'), value = Number(me.val()) / 100, changeSet = {}; changeSet[name] = value; fireProxyChange(me, 'representation-property', changeSet) }); } // ======================================================================= // ==== Property Panel - HTML code generators ============================ // ======================================================================= function domainIsNumber(domainName){ return (domainName.indexOf('Int') != -1) || (domainName.indexOf('Double') != -1); } // ======================================================================= function domainHasRange(domainName){ return (domainName.indexOf('Range') != -1); } // ======================================================================= function isInputArrayDomain(domainList) { for(var idx in domainList) { if(domainList[idx].type === 'ArrayList') { return true; } } return false; } // ======================================================================= function isEnumDomain(domainList) { for(var idx in domainList) { if(domainList[idx].type === 'Enumeration') { return true; } } return false; } // ======================================================================= function isProxyListDomain(domainList) { for(var idx in domainList) { if(domainList[idx].type === 'ProxyList') { return true; } } return false; } // ======================================================================= function getInputArrayNumberOfComponents(domainList) { for(var idx in domainList) { if(domainList[idx].type === 'ArrayList') { return domainList[idx].nb_components; } } return -1; } // ======================================================================= function updateProxyProperties(pipelineBrowser, proxy) { var me = $(".pipeline-editor-content",pipelineBrowser).empty(), key, value, opacityValue = proxy.opacity; if(opacityValue === undefined) { opacityValue = 1; } buffer.clear(); buffer.append(""); if(proxy && proxy.state) { // Add Opacity property addPropertyToBuffer(proxy.state['proxy_id'], 'Opacity', opacityValue, { "default_values": "1", "domains": [{ "max":"1", "type":"DoubleRange", "min":"0"} ], "name": "Opacity", "order": 100, "size": "1", "type": "Double" }, true); // Other properties for(key in proxy.state.properties) { if(proxy.state.domains.hasOwnProperty(key)) { addPropertyToBuffer(proxy.state['proxy_id'], key, proxy.state.properties[key], proxy.state.domains[key], false); } else { addPropertyToBuffer(proxy.state['proxy_id'], key, proxy.state.properties[key], null, false); } } } buffer.append("
    "); me[0].innerHTML = buffer.toString(); // Reorder the properties $(".property", pipelineBrowser).each(function(){ updatePropertyPosition($(this)); }); generateWidget(me); $('.apply', pipelineBrowser).removeClass('modified'); } // ======================================================================= function markProxyModified(anyInnerPipelineWidget) { var pipelineBrowser = getPipeline(anyInnerPipelineWidget); $('.apply', pipelineBrowser).addClass('modified'); } // ======================================================================= function addPropertyToBuffer(proxyId, key, value, domain, onRepresentation) { var idx, filterList = ['proxy_id', 'type', 'domains'], nbComponents; for(idx in filterList) { if(key === filterList[idx]) { return; } } if(domain === null) { if(value.hasOwnProperty('proxy_id')) { buffer.append(""); for(var key2 in value.properties) { addPropertyToBuffer(value['proxy_id'], key2, value.properties[key2], value.domains[key2], onRepresentation); } buffer.append("
    "); } } else { buffer.append(" 0) { buffer.append(domain['label']); } else { buffer.append(key); } buffer.append("' widget-type='"); if(domain['domains'].length == 1 && domain['domains'][0]['type'] == 'Boolean') { buffer.append("boolean'"); } else if (domain['domains'].length == 1 && domainHasRange(domain['domains'][0]['type']) && domain['domains'][0].hasOwnProperty('min') && domain['domains'][0].hasOwnProperty('max')) { buffer.append('range'); buffer.append("' min='"); buffer.append(domain['domains'][0]['min']); buffer.append("' max='"); buffer.append(domain['domains'][0]['max']); buffer.append("' data-type='"); buffer.append(domain['type']); buffer.append("'"); } else if (isInputArrayDomain(domain['domains'])) { // Handle input array nbComponents = getInputArrayNumberOfComponents(domain['domains']); buffer.append("array' nb_comp='"); buffer.append(nbComponents); buffer.append("' proxy='"); buffer.append(proxyId); buffer.append("' selected_array_type='"); buffer.append(value[0]); buffer.append("' selected_array='"); buffer.append(value[1]); buffer.append("'"); } else if (isEnumDomain(domain['domains'])) { buffer.append("enum' key='"); buffer.append(key); buffer.append("'"); } else if (isProxyListDomain(domain['domains'])) { buffer.append("list' key='"); buffer.append(key); buffer.append("'"); } else if (domain.hasOwnProperty('size')) { if(domain['size'] === '0') { buffer.append('multi-value'); } else { buffer.append('text'); } buffer.append("' size='"); buffer.append(domain['size']); buffer.append("' data-type='"); buffer.append(domain['type']); buffer.append("'"); } else { buffer.append("?'"); } buffer.append(">"); } } // ======================================================================= function generateWidget(container) { $('.property', container).each(function(){ var property = $(this).empty(); var propertyName = property.attr('label'); var propertyValue = property.attr('data-value'); createWidget(property, propertyName, propertyValue); }); } // ======================================================================= function updatePropertyPosition(propertyElement) { var other = propertyElement.next(); while(other.length == 1) { if(Number(propertyElement.attr('order')) > Number(other.attr('order'))) { other.after(propertyElement); } other = other.next(); } } // ======================================================================= function createWidget(container, propertyName, value) { var widgetType = container.attr('widget-type'); if(widgetType === 'boolean') { createCheckbox(container, propertyName, value); } else if (widgetType === 'text') { createTextField(container, propertyName, container.attr('size'), container.attr('data-type'), value); } else if (widgetType === 'enum') { createEnumeration(container, container.attr('proxy'), propertyName, container.attr('key'), value); } else if (widgetType === 'list') { createList(container, container.attr('proxy'), propertyName, container.attr('key'), value); } else if (widgetType === 'range') { createSlider(container, propertyName, container.attr('min'), container.attr('max'), container.attr('data-type'), value) } else if (widgetType === 'array') { createArraySelector(container, propertyName, container.attr('proxy'), Number(container.attr('nb_comp')), container.attr('selected_array_type'), container.attr('selected_array')); } else if (widgetType === 'multi-value') { var array = value.length === 0 ? [] : value.split(','); createMultiValue(container, propertyName, array); } } // ======================================================================= function createSliderOLD(container, propertyName, min, max, type, propertyValue) { tmpBuffer = createBuffer(); tmpBuffer.append(""); tmpBuffer.append(propertyName); tmpBuffer.append("
    "); container[0].innerHTML = tmpBuffer.toString(); var updateValue = function(event, ui) { $('input', container).val(ui.value); markProxyModified(container); } $('input', container).change(function(){ $('div.pv-widget-slider', container).slider('value', Number($(this).val())); }); var options = { min: Number(min), max: Number(max), value: Number(propertyValue), slide: updateValue, change: updateValue }; if(type === 'Int') { options['step'] = 1; } $('div.pv-widget-slider', container).slider(options); } // ======================================================================= function createSlider(container, propertyName, min, max, type, propertyValue) { var minValue = Number(min), maxValue = Number(max), deltaValue = maxValue - minValue; function sliderValueToPropertyValue(v) { var sv = deltaValue * Number(v) / 100.0 + minValue; if(type === 'Int') { return Math.floor(sv); } return sv; } function propertyValueToSliderValue(v) { return 100 * (Number(v) - minValue) / deltaValue ; } container[0].innerHTML = "NAME
    " .replace(/VALUE/g, propertyValue) .replace(/NAME/g, propertyName) .replace(/MIN/g, min) .replace(/MAX/g, max) .replace(/VALUE/g, propertyValue) .replace(/SLIDE/g, propertyValueToSliderValue(propertyValue)); var textProperty = $('input[type="text"]', container), sliderProperty = $('input[type="range"]', container); function invalidateProperty(newValue) { textProperty.val(newValue); sliderProperty.attr('data-value', newValue).val(propertyValueToSliderValue(newValue)); markProxyModified(container); } $('input[type="text"]', container).change(function() { var me = $(this), value = me.val(); invalidateProperty(value); }); $('input[type="range"]', container).bind('change keyup', function() { var me = $(this), value = sliderValueToPropertyValue(me.val()); invalidateProperty(value); }); } // ======================================================================= function createTextField(container, propertyName, nbFields, type, propertyValue) { var values = [], tmpBuffer = createBuffer(); if(nbFields === 1) { values = [ propertyValue ] } else { values = propertyValue.split(','); } tmpBuffer.append(""); tmpBuffer.append(propertyName); tmpBuffer.append(""); for(var i = 0; i < nbFields; ++i) { tmpBuffer.append(""); } tmpBuffer.append(""); container[0].innerHTML = tmpBuffer.toString(); $('input', container).change(function(){ markProxyModified(container); }); } // ======================================================================= function createCheckbox(container, propertyName, propertyValue) { var tmpBuffer = createBuffer(); tmpBuffer.append(""); tmpBuffer.append(propertyName); tmpBuffer.append(""); tmpBuffer.append(""); container[0].innerHTML = tmpBuffer.toString(); $('input', container).change(function(){ markProxyModified(container); }); } // ======================================================================= function createEnumeration(container, proxyId, propertyLabel, propertyName, propertyValue) { var tmpBuffer = createBuffer(), proxy = getProxy(container, proxyId), list = proxy.state.domains[propertyName].domains[0]['enum']; tmpBuffer.append(""); tmpBuffer.append(propertyName); tmpBuffer.append(""); container[0].innerHTML = tmpBuffer.toString(); $('select', container).change(function(){ markProxyModified(container); }); } // ======================================================================= function createList(container, proxyId, propertyLabel, propertyName, propertyValue) { var tmpBuffer = createBuffer(), proxy = getProxy(container, proxyId), list = [], domains = proxy.state.domains[propertyName].domains, idx; // Search the list domain for(idx in domains) { if(domains[idx].hasOwnProperty('list')) { list = domains[idx].list } } tmpBuffer.append(""); tmpBuffer.append(propertyLabel); tmpBuffer.append(""); container[0].innerHTML = tmpBuffer.toString(); $('select', container).change(function(){ markProxyModified(container); }); } // ======================================================================= function createArraySelector(container, propertyName, proxyId, nbComponents, arrayType, arrayName) { var tmpBuffer = createBuffer(), list, isArrayInList, parentProxy = getProxy(container, getParentProxyId(container, proxyId)); tmpBuffer.append(""); tmpBuffer.append(propertyName); tmpBuffer.append(""); container[0].innerHTML = tmpBuffer.toString(); $('input', container).change(function(){ markProxyModified(container); }); } // ======================================================================= function createMultiValue(container, propertyName, propertyValue) { var tmpBuffer = createBuffer(), emptyLineHTML = ""; function addEntry() { attachListener($(emptyLineHTML).appendTo($('table', container))); markProxyModified(container); } function attachListener(parent) { $('input', parent).change(function(){ markProxyModified(container); }); $('.add', parent).click(addEntry); $('.delete-value', parent).click(function(){ $(this).parent().remove(); markProxyModified(container); }); } // First line with title tmpBuffer.append(""); tmpBuffer.append("
    "); tmpBuffer.append(propertyName); tmpBuffer.append("
    "); container[0].innerHTML = tmpBuffer.toString(); attachListener(container); // Update values for(var idx = 1; idx < propertyValue.length; idx++) { addEntry(); } for(idx in propertyValue) { $('input.multi-value', container).eq(idx).val(propertyValue[idx]); } } // ---------------------------------------------------------------------- // Local module registration // ---------------------------------------------------------------------- try { // Tests for presence of jQuery, then registers this module if ($ !== undefined) { vtkWeb.registerModule('paraview-ui-pipeline'); } else { console.error('Module failed to register, jQuery is missing: ' + err.message); } } catch(err) { console.error('Caught exception while registering module: ' + err.message); } }(window, jQuery));