From 48ee4c78740c4370661e240a315b2e26c4e2358e Mon Sep 17 00:00:00 2001 From: willp24 Date: Fri, 20 Jul 2018 17:33:23 -0400 Subject: [PATCH] Volumes: Standardized the volume selection dropdown Changes made with @tomka see catmaid/CATMAID#1765 --- .../catmaid/static/js/WindowMaker.js | 75 ++++++------------ .../catmaid/static/js/helpers/volumes.js | 77 +++++++++++++++++++ .../catmaid/static/js/widgets/settings.js | 45 +++-------- .../catmaid/static/js/widgets/volumewidget.js | 38 ++++----- .../catmaid/static/libs/catmaid/filter.js | 35 +++------ 5 files changed, 141 insertions(+), 129 deletions(-) create mode 100644 django/applications/catmaid/static/js/helpers/volumes.js diff --git a/django/applications/catmaid/static/js/WindowMaker.js b/django/applications/catmaid/static/js/WindowMaker.js index 17c26317f6..50b52f861a 100644 --- a/django/applications/catmaid/static/js/WindowMaker.js +++ b/django/applications/catmaid/static/js/WindowMaker.js @@ -708,49 +708,6 @@ var WindowMaker = new function() } } - // Update volume list - var initVolumeList = function() { - return CATMAID.Volumes.listAll(project.id).then(function(json) { - var volumes = json.sort(function(a, b) { - return CATMAID.tools.compareStrings(a.name, b.name); - }).map(function(volume) { - return { - title: volume.name, - value: volume.id - }; - }); - var selectedVolumes = WA.getLoadedVolumeIds(); - // Create actual element based on the returned data - var node = DOM.createCheckboxSelect('Volumes', volumes, - selectedVolumes, true, function(row, id, visible) { - let loadedVolume = WA.loadedVolumes.get(id); - let faces, color, alpha, subdiv, bb; - if (loadedVolume) { - faces = loadedVolume.faces; - color = loadedVolume.color; - alpha = loadedVolume.opacity; - subdiv = loadedVolume.subdiv; - bb = loadedVolume.boundingBox; - } - setVolumeEntryVisible(row, id, visible, faces, color, alpha, subdiv, bb); - }); - - // Add a selection handler - node.onchange = function(e) { - var visible = e.target.checked; - var volumeId = parseInt(e.target.value, 10); - WA.showVolume(volumeId, visible, undefined, undefined, - o.meshes_faces) - .catch(CATMAID.handleError); - - setVolumeEntryVisible(e.target.closest('li'), volumeId, visible, - o.meshes_faces, o.meshes_color, o.meshes_opacity, - o.meshes_subdiv, o.meshes_boundingbox); - }; - return node; - }); - }; - // Update landmark list var initLandmarkList = function() { return CATMAID.Landmarks.listGroups(project.id).then(function(json) { @@ -859,9 +816,29 @@ var WindowMaker = new function() // Create async selection and wrap it in container to have handle on initial // DOM location - var volumeSelection = DOM.createAsyncPlaceholder(initVolumeList()); - var volumeSelectionWrapper = document.createElement('span'); - volumeSelectionWrapper.appendChild(volumeSelection); + var volumeSelectionWrapper = CATMAID.createVolumeSelector({ + mode: "checkbox", + selectedVolumeIds: WA.getLoadedVolumeIds(), + select: function(volumeId, visible, element){ + WA.showVolume(volumeId, visible, undefined, undefined, o.meshes_faces) + .catch(CATMAID.handleError); + + setVolumeEntryVisible(element.closest('li'), volumeId, visible, + o.meshes_faces, o.meshes_color, o.meshes_opacity, + o.meshes_subdiv, o.meshes_boundingbox); + }, + rowCallback: function(row, id, visible) { + let loadedVolume = WA.loadedVolumes.get(id); + let faces, color, alpha, subdiv, bb; + if (loadedVolume) { + faces = loadedVolume.faces; + color = loadedVolume.color; + alpha = loadedVolume.opacity; + subdiv = loadedVolume.subdiv; + bb = loadedVolume.boundingBox; + } + } + }); // Create async selection and wrap it in container to have handle on initial // DOM location @@ -877,11 +854,7 @@ var WindowMaker = new function() // Replace volume selection wrapper children with new select var refreshVolumeList = function() { - while (0 !== volumeSelectionWrapper.children.length) { - volumeSelectionWrapper.removeChild(volumeSelectionWrapper.children[0]); - } - var volumeSelection = DOM.createAsyncPlaceholder(initVolumeList()); - volumeSelectionWrapper.appendChild(volumeSelection); + volumeSelectionWrapper.refresh(WA.getLoadedVolumeIds()); }; // Replace point cloud selection wrapper children with new select diff --git a/django/applications/catmaid/static/js/helpers/volumes.js b/django/applications/catmaid/static/js/helpers/volumes.js new file mode 100644 index 0000000000..7674a7a1d7 --- /dev/null +++ b/django/applications/catmaid/static/js/helpers/volumes.js @@ -0,0 +1,77 @@ +/* -*- mode: espresso; espresso-indent-level: 2; indent-tabs-mode: nil -*- */ +/* vim: set softtabstop=2 shiftwidth=2 tabstop=2 expandtab: */ + +(function (CATMAID) { + + "use strict"; + + // Update volume list + let initVolumeList = function (options, newSelectedIds) { + return CATMAID.Volumes.listAll(project.id).then(function (json) { + let volumes = json.sort(function (a, b) { + return CATMAID.tools.compareStrings(a.name, b.name); + }).map(function (volume) { + return { + title: volume.name, + value: volume.id + }; + }); + if (options.mode === "radio") { + if (newSelectedIds.length > 1){ + throw new CATMAID.ValueError("Radio select only takes one selected volume"); + } + let selectedVolume = newSelectedIds[0] || options.selectedVolumeIds[0]; + // Create actual element based on the returned data + let node = CATMAID.DOM.createRadioSelect('Volumes', volumes, + selectedVolume, true); + // Add a selection handler + node.onchange = function (e) { + let volumeId = e.target.value; + let selected = true; + + if (CATMAID.tools.isFn(options.select)) { + options.select(volumeId, selected, e.target); + } + }; + return node; + } else { + let selectedVolumes = newSelectedIds || options.selectedVolumeIds; + // Create actual element based on the returned data + let node = CATMAID.DOM.createCheckboxSelect('Volumes', volumes, + selectedVolumes, true, options.rowCallback); + + // Add a selection handler + node.onchange = function (e) { + let selected = e.target.checked; + let volumeId = parseInt(e.target.value, 10); + + if (CATMAID.tools.isFn(options.select)) { + options.select(volumeId, selected, e.target); + } + }; + return node; + } + }); + }; + + CATMAID.createVolumeSelector = function (options) { + var volumeSelectionWrapper = document.createElement('span'); + let volumeSelection; + if (options.label){ + volumeSelection = CATMAID.DOM.createLabeledAsyncPlaceholder(options.label, initVolumeList(options), options.title); + } else { + volumeSelection = CATMAID.DOM.createAsyncPlaceholder(initVolumeList(options)); + } + volumeSelectionWrapper.appendChild(volumeSelection); + volumeSelectionWrapper.refresh = function(newSelectedIds){ + while (0 !== volumeSelectionWrapper.children.length) { + volumeSelectionWrapper.removeChild(volumeSelectionWrapper.children[0]); + } + var volumeSelection = CATMAID.DOM.createAsyncPlaceholder(initVolumeList(options, newSelectedIds)); + volumeSelectionWrapper.appendChild(volumeSelection); + }; + return volumeSelectionWrapper; + }; + + +})(CATMAID); \ No newline at end of file diff --git a/django/applications/catmaid/static/js/widgets/settings.js b/django/applications/catmaid/static/js/widgets/settings.js index 28e9e83e27..ffc5cb17f9 100644 --- a/django/applications/catmaid/static/js/widgets/settings.js +++ b/django/applications/catmaid/static/js/widgets/settings.js @@ -1735,42 +1735,19 @@ var dsTracingWarnings = CATMAID.DOM.addSettingsContainer(ds, "Warnings", true); - // Volume warning - let initVolumeList = function() { - return CATMAID.Volumes.listAll(project.id) - .then(function(json) { - var volumes = json.sort(function(a, b) { - return CATMAID.tools.compareStrings(a.name, b.name); - }).map(function(volume) { - return { - title: volume.name + " (#" + volume.id + ")", - value: volume.id - }; - }); - var selectedVolumeId = SkeletonAnnotations.getNewNodeVolumeWarning(); - // Create actual element based on the returned data - var node = CATMAID.DOM.createRadioSelect('Volumes', volumes, - selectedVolumeId, true); - // Add a selection handler - node.onchange = function(e) { - let volumeId = null; - if (e.srcElement.value !== "none") { - volumeId = parseInt(e.srcElement.value, 10); - } - // Remove existing handler and new one if selected - SkeletonAnnotations.setNewNodeVolumeWarning(volumeId); - }; - - return node; - }); - }; - // Create async selection and wrap it in container to have handle on initial // DOM location - var volumeSelectionSetting = CATMAID.DOM.createLabeledAsyncPlaceholder( - "New nodes not in volume", initVolumeList(), - "A warning will be shown when new nodes are created outside of the selected volume"); - dsTracingWarnings.append(volumeSelectionSetting); + var volumeSelectionWrapper = CATMAID.createVolumeSelector({ + mode: "radio", + label: "New nodes not in volume", + title: "A warning will be shown when new nodes are created outside of the selected volume", + selectedVolumeIds: [SkeletonAnnotations.getNewNodeVolumeWarning()], + select: function(volumeId, selected, element){ + // Remove existing handler and new one if selected + SkeletonAnnotations.setNewNodeVolumeWarning(element.value !== "none"? volumeId : null); + } + }); + dsTracingWarnings.append(volumeSelectionWrapper); // Skeleton length warning diff --git a/django/applications/catmaid/static/js/widgets/volumewidget.js b/django/applications/catmaid/static/js/widgets/volumewidget.js index 33d4549ab5..48c605dcb5 100644 --- a/django/applications/catmaid/static/js/widgets/volumewidget.js +++ b/django/applications/catmaid/static/js/widgets/volumewidget.js @@ -71,7 +71,7 @@ if (file.name.endsWith("stl")){ return true; } else { - this.addVolumeFromFile(file); + this.addVolumeFromFile(file).catch(CATMAID.handleError); } },this)).catch(CATMAID.handleError); } @@ -608,23 +608,25 @@ * @param {String} files The file to load */ VolumeManagerWidget.prototype.addVolumeFromFile = function(file) { - var self = this; - var reader = new FileReader(); - reader.onload = function(e) { - var volumes = JSON.parse(e.target.result); - // Try to load volumes and record invalid ones - var invalidVolumes = volumes.filter(function(v) { - var volumeType = volumeTypes[v.type]; - var properties = v.properties; - if (volumeType && properties) { - volumeType.createVolume(properties); - } else { - // Return true for invalid volume types - return !volumeType; - } - }); - }; - reader.readAsText(file); + return new Promise(function(resolve, reject) { + var self = this; + var reader = new FileReader(); + reader.onload = function(e) { + var volumes = JSON.parse(e.target.result); + // Try to load volumes and record invalid ones + var invalidVolumes = volumes.filter(function(v) { + var volumeType = volumeTypes[v.type]; + var properties = v.properties; + if (volumeType && properties) { + volumeType.createVolume(properties); + } else { + // Return true for invalid volume types + return !volumeType; + } + }); + }; + reader.readAsText(file); + }); }; VolumeManagerWidget.prototype.addVolumesFromSTL = function(files) { diff --git a/django/applications/catmaid/static/libs/catmaid/filter.js b/django/applications/catmaid/static/libs/catmaid/filter.js index dc28824713..9959705284 100644 --- a/django/applications/catmaid/static/libs/catmaid/filter.js +++ b/django/applications/catmaid/static/libs/catmaid/filter.js @@ -635,34 +635,17 @@ // Take all has no additional options }, 'volume': function(container, options) { - // Update volume list - var initVolumeList = function() { - return CATMAID.Volumes.listAll(project.id).then(function(json) { - var volumes = json.sort(function(a, b) { - return CATMAID.tools.compareStrings(a.name, b.name); - }).map(function(volume) { - return { - title: volume.name, - value: volume.id - }; - }); - var selectedVolume = options.volumeId; - // Create actual element based on the returned data - var node = CATMAID.DOM.createRadioSelect('Volumes', volumes, - selectedVolume, true); - // Add a selection handler - node.onchange = function(e) { - options.volumeId = e.target.value; - }; - return node; - }); - }; - // Create async selection and wrap it in container to have handle on initial // DOM location - var volumeSelection = CATMAID.DOM.createAsyncPlaceholder(initVolumeList()); - var volumeSelectionWrapper = document.createElement('span'); - $(container).append(volumeSelection); + var volumeSelectionWrapper = CATMAID.createVolumeSelector({ + mode: "radio", + selectedVolumeIds: [options.volumeId], + select: function(volumeId, selected, element){ + options.volumeId = volumeId; + } + }); + + container.appendChild(volumeSelectionWrapper); }, };