girder-large-image 1.23.1.dev44__tar.gz → 1.23.2.dev6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/PKG-INFO +1 -1
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/templates/itemList.pug +17 -6
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/itemList.js +45 -1
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/metadataWidget.js +42 -27
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/vue/components/CompositeLayers.vue +184 -111
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/vue/components/FrameSelector.vue +2 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image.egg-info/PKG-INFO +1 -1
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image.egg-info/requires.txt +2 -2
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/LICENSE +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/README.rst +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/__init__.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/constants.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/girder_tilesource.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/loadmodelcache.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/models/__init__.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/models/image_item.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/rest/__init__.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/rest/large_image_resource.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/rest/tiles.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/eventStream.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/extra/.gitignore +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/index.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/main.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/package.json +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/routes.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/stylesheets/fileList.styl +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/stylesheets/imageViewerSelectWidget.styl +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/stylesheets/itemList.styl +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/stylesheets/itemView.styl +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/stylesheets/itemViewCodemirror.styl +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/stylesheets/largeImageConfig.styl +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/stylesheets/metadataWidget.styl +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/templates/imageViewerSelectWidget.pug +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/templates/itemView.pug +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/templates/itemViewCodemirror.pug +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/templates/largeImageConfig.pug +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/templates/largeImage_fileAction.pug +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/templates/metadataWidget.pug +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/templates/metadatumEditWidget.pug +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/configView.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/fileList.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/imageViewerSelectWidget.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/imageViewerWidget/base.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/imageViewerWidget/geojs.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/imageViewerWidget/index.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/imageViewerWidget/leaflet.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/imageViewerWidget/openlayers.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/imageViewerWidget/openseadragon.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/imageViewerWidget/setFrameQuad.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/imageViewerWidget/slideatlas.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/index.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/itemView.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/itemViewCodemirror.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/views/itemViewWidget.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/vue/components/DualInput.vue +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/vue/components/HistogramEditor.vue +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/vue/utils/clamp.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/vue/utils/colors.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/vue/utils/drag.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/web_client/webpack.helper.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image.egg-info/SOURCES.txt +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image.egg-info/dependency_links.txt +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image.egg-info/entry_points.txt +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image.egg-info/not-zip-safe +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image.egg-info/top_level.txt +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/setup.cfg +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/setup.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/__init__.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/conftest.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/girder_utilities.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/test_large_image.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/test_tiles_rest.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/test_web_client.py +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/web_client_specs/.eslintrc +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/web_client_specs/imageViewerSpec.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/web_client_specs/largeImageSpec.js +0 -0
- {girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/web_client_specs/otherFeatures.js +0 -0
|
@@ -16,7 +16,7 @@ ul.g-item-list.li-item-list
|
|
|
16
16
|
if checkboxes
|
|
17
17
|
span.li-item-list-cell
|
|
18
18
|
input.g-list-checkbox(type="checkbox", g-item-cid=item.cid)
|
|
19
|
-
for column in itemList.columns
|
|
19
|
+
for column, colidx in itemList.columns
|
|
20
20
|
if column.type !== 'image' || hasAnyLargeImage
|
|
21
21
|
-
|
|
22
22
|
var divtype = column.type !== 'record' || column.value !== 'controls' ? 'a' : 'span';
|
|
@@ -51,11 +51,22 @@ ul.g-item-list.li-item-list
|
|
|
51
51
|
column.value.split('.').forEach((part) => {
|
|
52
52
|
value = (value || {})[part];
|
|
53
53
|
})
|
|
54
|
-
|
|
55
|
-
=
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
if column.edit && accessLevel >= AccessType.WRITE
|
|
55
|
+
- if ((value === '' || value === undefined) && column.default) { value = column.default; }
|
|
56
|
+
span.large_image_metadata.lientry_edit(column-idx=colidx)
|
|
57
|
+
if column.enum
|
|
58
|
+
select.input-sm.form-control.g-widget-metadata-value-input.g-widget-metadata-lientry(title=column.description)
|
|
59
|
+
for enumval in column.enum
|
|
60
|
+
option(value=enumval, selected=enumval === value ? 'selected' : null)
|
|
61
|
+
= enumval
|
|
62
|
+
else
|
|
63
|
+
input.input-sm.form-control.g-widget-metadata-value-input.g-widget-metadata-column(placeholder=column.description || "Value", value=value, title=column.description)
|
|
64
|
+
else
|
|
65
|
+
span.large_image_metadata
|
|
66
|
+
= value
|
|
67
|
+
if value
|
|
68
|
+
span.li-item-list-cell-filter(title="Only show items that match this metadata value exactly", filter-value=value, column-value=column.value)
|
|
69
|
+
i.icon-filter
|
|
59
70
|
if (hasMore && !paginated)
|
|
60
71
|
li.g-show-more
|
|
61
72
|
a.g-show-more-items
|
|
@@ -16,6 +16,7 @@ import {addToRoute} from '../routes';
|
|
|
16
16
|
|
|
17
17
|
import '../stylesheets/itemList.styl';
|
|
18
18
|
import ItemListTemplate from '../templates/itemList.pug';
|
|
19
|
+
import {MetadatumWidget, validateMetadataValue} from './metadataWidget';
|
|
19
20
|
|
|
20
21
|
wrap(HierarchyWidget, 'render', function (render) {
|
|
21
22
|
render.call(this);
|
|
@@ -85,6 +86,9 @@ wrap(ItemListWidget, 'initialize', function (initialize, settings) {
|
|
|
85
86
|
});
|
|
86
87
|
this.events['click .li-item-list-header.sortable'] = (evt) => sortColumn.call(this, evt);
|
|
87
88
|
this.events['click .li-item-list-cell-filter'] = (evt) => itemListCellFilter.call(this, evt);
|
|
89
|
+
this.events['click .large_image_metadata.lientry_edit'] = (evt) => itemListMetadataEdit.call(this, evt);
|
|
90
|
+
this.events['change .large_image_metadata.lientry_edit'] = (evt) => itemListMetadataEdit.call(this, evt);
|
|
91
|
+
this.events['input .large_image_metadata.lientry_edit'] = (evt) => itemListMetadataEdit.call(this, evt);
|
|
88
92
|
this.delegateEvents();
|
|
89
93
|
this.setFlatten = (flatten) => {
|
|
90
94
|
if (!!flatten !== !!this._recurse) {
|
|
@@ -395,7 +399,11 @@ wrap(ItemListWidget, 'render', function (render) {
|
|
|
395
399
|
apiRoot: getApiRoot(),
|
|
396
400
|
hasAnyLargeImage: this._hasAnyLargeImage,
|
|
397
401
|
itemList: this._confList(),
|
|
398
|
-
sort: this._lastSort
|
|
402
|
+
sort: this._lastSort,
|
|
403
|
+
MetadatumWidget: MetadatumWidget,
|
|
404
|
+
accessLevel: this.accessLevel,
|
|
405
|
+
parentView: this,
|
|
406
|
+
AccessType: AccessType
|
|
399
407
|
}));
|
|
400
408
|
|
|
401
409
|
const parent = this.$el;
|
|
@@ -514,4 +522,40 @@ function itemListCellFilter(evt) {
|
|
|
514
522
|
return false;
|
|
515
523
|
}
|
|
516
524
|
|
|
525
|
+
function itemListMetadataEdit(evt) {
|
|
526
|
+
evt.preventDefault();
|
|
527
|
+
if (evt.type === 'click') {
|
|
528
|
+
return false;
|
|
529
|
+
}
|
|
530
|
+
const ctrl = $(evt.target).closest('.lientry_edit');
|
|
531
|
+
const columns = (this._confList() || {}).columns || [];
|
|
532
|
+
const column = columns[+ctrl.attr('column-idx')];
|
|
533
|
+
let tempValue = ctrl.find('.g-widget-metadata-value-input').val();
|
|
534
|
+
tempValue = tempValue.trim();
|
|
535
|
+
let valResult = validateMetadataValue(column, tempValue, self._lastValidationError || (tempValue === '' && !column.required));
|
|
536
|
+
if (tempValue === '' && !column.required) {
|
|
537
|
+
valResult = {value: tempValue};
|
|
538
|
+
}
|
|
539
|
+
if (!valResult) {
|
|
540
|
+
self._lastValidationError = true;
|
|
541
|
+
return false;
|
|
542
|
+
}
|
|
543
|
+
self._lastValidationError = false;
|
|
544
|
+
const item = this.collection.get(ctrl.closest('[g-item-cid]').attr('g-item-cid'));
|
|
545
|
+
let value = item.get('meta') || {};
|
|
546
|
+
let meta;
|
|
547
|
+
let key;
|
|
548
|
+
column.value.split('.').forEach((part) => {
|
|
549
|
+
meta = value;
|
|
550
|
+
key = part;
|
|
551
|
+
value = (value || {})[part];
|
|
552
|
+
});
|
|
553
|
+
if (value === valResult.value) {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
meta[key] = valResult.value;
|
|
557
|
+
item._sendMetadata(item.get('meta'));
|
|
558
|
+
return false;
|
|
559
|
+
}
|
|
560
|
+
|
|
517
561
|
export default ItemListWidget;
|
|
@@ -55,6 +55,43 @@ function liMetadataKeyEntry(limetadata, key) {
|
|
|
55
55
|
return result;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
function validateMetadataValue(lientry, tempValue, nowarn) {
|
|
59
|
+
if (lientry && lientry.regex && !(new RegExp(lientry.regex).exec(tempValue))) {
|
|
60
|
+
if (!nowarn) {
|
|
61
|
+
events.trigger('g:alert', {
|
|
62
|
+
text: 'The value does not match the required format.',
|
|
63
|
+
type: 'warning'
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
if (lientry && ((lientry.format || lientry.type) === 'number' || (lientry.format || lientry.type) === 'integer')) {
|
|
69
|
+
if (!Number.isFinite(parseFloat(tempValue)) || ((lientry.format || lientry.type) === 'integer' && !Number.isInteger(parseFloat(tempValue)))) {
|
|
70
|
+
if (!nowarn) {
|
|
71
|
+
events.trigger('g:alert', {
|
|
72
|
+
text: `The value must be a ${(lientry.format || lientry.type)}.`,
|
|
73
|
+
type: 'warning'
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
tempValue = parseFloat(tempValue);
|
|
79
|
+
if ((lientry.minimum !== undefined && tempValue < lientry.minimum) ||
|
|
80
|
+
(lientry.exclusiveMinimum !== undefined && tempValue <= lientry.exclusiveMinimum) ||
|
|
81
|
+
(lientry.maximum !== undefined && tempValue > lientry.maximum) ||
|
|
82
|
+
(lientry.exclusiveMaximum !== undefined && tempValue >= lientry.exclusiveMaximum)) {
|
|
83
|
+
if (!nowarn) {
|
|
84
|
+
events.trigger('g:alert', {
|
|
85
|
+
text: 'The value is outside of the allowed range.',
|
|
86
|
+
type: 'warning'
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return {value: tempValue};
|
|
93
|
+
}
|
|
94
|
+
|
|
58
95
|
var MetadatumWidget = View.extend({
|
|
59
96
|
className: 'g-widget-metadata-row',
|
|
60
97
|
|
|
@@ -286,34 +323,11 @@ var MetadatumEditWidget = View.extend({
|
|
|
286
323
|
if (keyMode && lientry) {
|
|
287
324
|
tempValue = tempValue.trim();
|
|
288
325
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
text: 'The value does not match the required format.',
|
|
292
|
-
type: 'warning'
|
|
293
|
-
});
|
|
326
|
+
const valResult = validateMetadataValue(lientry, tempValue);
|
|
327
|
+
if (!valResult) {
|
|
294
328
|
return false;
|
|
295
329
|
}
|
|
296
|
-
|
|
297
|
-
if (!Number.isFinite(parseFloat(tempValue)) || (lientry.type === 'integer' && !Number.isInteger(parseFloat(tempValue)))) {
|
|
298
|
-
events.trigger('g:alert', {
|
|
299
|
-
text: `The value must be a ${lientry.type}.`,
|
|
300
|
-
type: 'warning'
|
|
301
|
-
});
|
|
302
|
-
return false;
|
|
303
|
-
}
|
|
304
|
-
tempValue = parseFloat(tempValue);
|
|
305
|
-
if ((lientry.minimum !== undefined && tempValue < lientry.minimum) ||
|
|
306
|
-
(lientry.exclusiveMinimum !== undefined && tempValue <= lientry.exclusiveMinimum) ||
|
|
307
|
-
(lientry.maximum !== undefined && tempValue > lientry.maximum) ||
|
|
308
|
-
(lientry.exclusiveMaximum !== undefined && tempValue >= lientry.exclusiveMaximum)) {
|
|
309
|
-
events.trigger('g:alert', {
|
|
310
|
-
text: 'The value is outside of the allowed range.',
|
|
311
|
-
type: 'warning'
|
|
312
|
-
});
|
|
313
|
-
return false;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
330
|
+
tempValue = valResult.value;
|
|
317
331
|
var saveCallback = () => {
|
|
318
332
|
this.key = tempKey;
|
|
319
333
|
this.value = tempValue;
|
|
@@ -668,5 +682,6 @@ export {
|
|
|
668
682
|
MetadatumWidget,
|
|
669
683
|
MetadatumEditWidget,
|
|
670
684
|
JsonMetadatumEditWidget,
|
|
671
|
-
liMetadataKeyEntry
|
|
685
|
+
liMetadataKeyEntry,
|
|
686
|
+
validateMetadataValue
|
|
672
687
|
};
|
|
@@ -5,7 +5,7 @@ import { CHANNEL_COLORS, OTHER_COLORS } from '../utils/colors'
|
|
|
5
5
|
import HistogramEditor from './HistogramEditor.vue';
|
|
6
6
|
|
|
7
7
|
export default {
|
|
8
|
-
props: ['itemId', 'currentFrame', 'layers', 'layerMap'],
|
|
8
|
+
props: ['itemId', 'currentFrame', 'layers', 'layerMap', 'active'],
|
|
9
9
|
emits: ['updateStyle'],
|
|
10
10
|
components: {
|
|
11
11
|
'color-picker': Chrome,
|
|
@@ -27,10 +27,33 @@ export default {
|
|
|
27
27
|
resample: false,
|
|
28
28
|
style: '{}',
|
|
29
29
|
roundRange: true,
|
|
30
|
-
}
|
|
30
|
+
},
|
|
31
|
+
showKeyboardShortcuts: false,
|
|
31
32
|
}
|
|
32
33
|
},
|
|
33
34
|
methods: {
|
|
35
|
+
keyHandler(e) {
|
|
36
|
+
let numericKey = parseFloat(e.key)
|
|
37
|
+
if (e.ctrlKey && !isNaN(numericKey)) {
|
|
38
|
+
e.preventDefault()
|
|
39
|
+
if (numericKey === 0) {
|
|
40
|
+
numericKey += 10
|
|
41
|
+
}
|
|
42
|
+
if (e.altKey) {
|
|
43
|
+
numericKey += 10
|
|
44
|
+
}
|
|
45
|
+
const layerIndex = numericKey - 1
|
|
46
|
+
if (layerIndex < this.layers.length) {
|
|
47
|
+
const targetLayer = this.layers[layerIndex]
|
|
48
|
+
if (this.compositeLayerInfo[targetLayer].enabled) {
|
|
49
|
+
this.enabledLayers = this.enabledLayers.filter((v) => v !== targetLayer)
|
|
50
|
+
} else {
|
|
51
|
+
this.enabledLayers.push(targetLayer)
|
|
52
|
+
}
|
|
53
|
+
this.updateActiveLayers()
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
34
57
|
initializeLayerInfo() {
|
|
35
58
|
const usedColors = []
|
|
36
59
|
this.compositeLayerInfo = {}
|
|
@@ -211,126 +234,165 @@ export default {
|
|
|
211
234
|
}
|
|
212
235
|
this.updateActiveLayers()
|
|
213
236
|
this.updateStyle()
|
|
237
|
+
if (this.active) {
|
|
238
|
+
document.addEventListener('keydown', this.keyHandler)
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
watch: {
|
|
242
|
+
active() {
|
|
243
|
+
if (this.active) {
|
|
244
|
+
document.addEventListener('keydown', this.keyHandler)
|
|
245
|
+
} else {
|
|
246
|
+
document.removeEventListener('keydown', this.keyHandler)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
214
249
|
}
|
|
215
250
|
}
|
|
216
251
|
</script>
|
|
217
252
|
|
|
218
253
|
<template>
|
|
219
|
-
<div
|
|
220
|
-
<
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
254
|
+
<div>
|
|
255
|
+
<i
|
|
256
|
+
class="icon-keyboard"
|
|
257
|
+
@click="showKeyboardShortcuts = !showKeyboardShortcuts"
|
|
258
|
+
/>
|
|
259
|
+
<div class="shortcuts" v-if="showKeyboardShortcuts">
|
|
260
|
+
<div class="h5">Keyboard Shortcuts</div>
|
|
261
|
+
<div>
|
|
262
|
+
<span class="monospace">ctrl + number</span>
|
|
263
|
+
Toggle visibility of the layer at the number position
|
|
264
|
+
</div>
|
|
265
|
+
<div>
|
|
266
|
+
<span style="font-weight: bold;">Example: </span>
|
|
267
|
+
<span class="monospace">ctrl + 1</span>
|
|
268
|
+
Toggle visibility of the first layer in the table
|
|
269
|
+
</div>
|
|
270
|
+
<div>
|
|
271
|
+
<span class="monospace">ctrl + alt + number</span>
|
|
272
|
+
Toggle visibility of the layer at the position of the number plus 10
|
|
273
|
+
</div>
|
|
274
|
+
<div>
|
|
275
|
+
<span style="font-weight: bold;">Example: </span>
|
|
276
|
+
<span class="monospace">ctrl + alt + 1</span>
|
|
277
|
+
Toggle visibility of the eleventh layer in the table
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
280
|
+
<div :class="colorPickerShown ? 'table-container tall' : 'table-container'">
|
|
281
|
+
<table id="composite-layer-table" class="table table-condensed">
|
|
282
|
+
<thead class="table-header">
|
|
283
|
+
<tr>
|
|
284
|
+
<th>
|
|
285
|
+
<input
|
|
286
|
+
type="checkbox"
|
|
287
|
+
class="input-80"
|
|
288
|
+
:checked="enabledLayers === layers"
|
|
289
|
+
@input="toggleEnableAll"
|
|
290
|
+
>
|
|
291
|
+
</th>
|
|
292
|
+
<th></th>
|
|
293
|
+
<th></th>
|
|
294
|
+
<th>
|
|
295
|
+
<div class="auto-range-col">
|
|
296
|
+
<div class="auto-range-label">
|
|
297
|
+
<span class="small-text">Auto Range</span>
|
|
298
|
+
<label class="switch">
|
|
299
|
+
<span
|
|
300
|
+
:class="allAutoRange() ? 'slider checked' : 'slider'"
|
|
301
|
+
@click="() => updateAllAutoRanges(allAutoRange() ? undefined : 0.2)"
|
|
302
|
+
/>
|
|
303
|
+
</label>
|
|
304
|
+
</div>
|
|
305
|
+
<span
|
|
306
|
+
v-if="allAutoRange()"
|
|
307
|
+
class="percentage-input"
|
|
308
|
+
>
|
|
309
|
+
<input
|
|
310
|
+
type="number"
|
|
311
|
+
class="input-80"
|
|
312
|
+
:max="50"
|
|
313
|
+
:min="0"
|
|
314
|
+
:value="autoRangeForAll"
|
|
315
|
+
@input="(e) => updateAllAutoRanges(e.target.value)"
|
|
316
|
+
>
|
|
317
|
+
</span>
|
|
318
|
+
</div>
|
|
319
|
+
<i
|
|
320
|
+
:class="expandedRows.length === layers.length ? 'expand-btn icon-up-open' : 'expand-btn icon-down-open'"
|
|
321
|
+
@click="toggleAllExpanded"
|
|
322
|
+
/>
|
|
323
|
+
</th>
|
|
324
|
+
</tr>
|
|
325
|
+
<!-- color picker should display relative to sticky table head -->
|
|
326
|
+
<color-picker
|
|
327
|
+
v-if="colorPickerShown"
|
|
328
|
+
id="color_picker"
|
|
329
|
+
class="picker-offset"
|
|
330
|
+
:disableAlpha="true"
|
|
331
|
+
:value="Object.values(compositeLayerInfo).find((({layerName}) => layerName === colorPickerShown)).palette"
|
|
332
|
+
@input="(swatch) => {updateLayerColor(colorPickerShown, swatch)}"
|
|
333
|
+
/>
|
|
334
|
+
</thead>
|
|
335
|
+
<tbody>
|
|
336
|
+
<tr
|
|
337
|
+
v-for="{
|
|
338
|
+
layerName, index, palette,
|
|
339
|
+
autoRange, min, max,
|
|
340
|
+
framedelta
|
|
341
|
+
} in Object.values(compositeLayerInfo)"
|
|
342
|
+
:key="layerName"
|
|
343
|
+
:class="expandedRows.includes(index) ? 'tall-row' : ''"
|
|
344
|
+
>
|
|
345
|
+
<td class="enable-col">
|
|
346
|
+
<input
|
|
347
|
+
type="checkbox"
|
|
348
|
+
class="input-80"
|
|
349
|
+
:value="layerName"
|
|
350
|
+
v-model="enabledLayers"
|
|
351
|
+
@change="updateActiveLayers"
|
|
352
|
+
>
|
|
353
|
+
</td>
|
|
354
|
+
<td class="name-col">{{ layerName }}</td>
|
|
355
|
+
<td class="color-col">
|
|
356
|
+
<span
|
|
357
|
+
class="current-color"
|
|
358
|
+
:style="{ 'background-color': palette }"
|
|
359
|
+
@click="() => toggleColorPicker(layerName)"
|
|
360
|
+
/>
|
|
361
|
+
</td>
|
|
362
|
+
<td class="auto-range-col">
|
|
363
|
+
<div class="auto-range-toggle">
|
|
237
364
|
<label class="switch">
|
|
238
365
|
<span
|
|
239
|
-
:class="
|
|
240
|
-
@click="() =>
|
|
366
|
+
:class="autoRange ? 'slider checked' : 'slider'"
|
|
367
|
+
@click="() => updateLayerAutoRange(layerName, autoRange ? undefined : 0.2)"
|
|
241
368
|
/>
|
|
242
369
|
</label>
|
|
243
370
|
</div>
|
|
244
|
-
<
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
<!-- color picker should display relative to sticky table head -->
|
|
265
|
-
<color-picker
|
|
266
|
-
v-if="colorPickerShown"
|
|
267
|
-
id="color_picker"
|
|
268
|
-
class="picker-offset"
|
|
269
|
-
:disableAlpha="true"
|
|
270
|
-
:value="Object.values(compositeLayerInfo).find((({layerName}) => layerName === colorPickerShown)).palette"
|
|
271
|
-
@input="(swatch) => {updateLayerColor(colorPickerShown, swatch)}"
|
|
272
|
-
/>
|
|
273
|
-
</thead>
|
|
274
|
-
<tbody>
|
|
275
|
-
<tr
|
|
276
|
-
v-for="{
|
|
277
|
-
layerName, index, palette,
|
|
278
|
-
autoRange, min, max,
|
|
279
|
-
framedelta
|
|
280
|
-
} in Object.values(compositeLayerInfo)"
|
|
281
|
-
:key="layerName"
|
|
282
|
-
:class="expandedRows.includes(index) ? 'tall-row' : ''"
|
|
283
|
-
>
|
|
284
|
-
<td class="enable-col">
|
|
285
|
-
<input
|
|
286
|
-
type="checkbox"
|
|
287
|
-
class="input-80"
|
|
288
|
-
:value="layerName"
|
|
289
|
-
v-model="enabledLayers"
|
|
290
|
-
@change="updateActiveLayers"
|
|
291
|
-
>
|
|
292
|
-
</td>
|
|
293
|
-
<td class="name-col">{{ layerName }}</td>
|
|
294
|
-
<td class="color-col">
|
|
295
|
-
<span
|
|
296
|
-
class="current-color"
|
|
297
|
-
:style="{ 'background-color': palette }"
|
|
298
|
-
@click="() => toggleColorPicker(layerName)"
|
|
299
|
-
/>
|
|
300
|
-
</td>
|
|
301
|
-
<td class="auto-range-col">
|
|
302
|
-
<div class="auto-range-toggle">
|
|
303
|
-
<label class="switch">
|
|
304
|
-
<span
|
|
305
|
-
:class="autoRange ? 'slider checked' : 'slider'"
|
|
306
|
-
@click="() => updateLayerAutoRange(layerName, autoRange ? undefined : 0.2)"
|
|
307
|
-
/>
|
|
308
|
-
</label>
|
|
371
|
+
<i
|
|
372
|
+
:class="expandedRows.includes(index) ? 'expand-btn icon-up-open' : 'expand-btn icon-down-open'"
|
|
373
|
+
@click="() => toggleExpanded(index)"
|
|
374
|
+
/>
|
|
375
|
+
</td>
|
|
376
|
+
<div v-if="expandedRows.includes(index)" class="advanced-section">
|
|
377
|
+
<histogram-editor
|
|
378
|
+
:itemId="itemId"
|
|
379
|
+
:layerIndex="index"
|
|
380
|
+
:currentFrame="currentFrame"
|
|
381
|
+
:currentFrameHistogram="currentFrameHistogram"
|
|
382
|
+
:histogramParams="histogramParams"
|
|
383
|
+
:framedelta="framedelta"
|
|
384
|
+
:autoRange="autoRange"
|
|
385
|
+
:currentMin="min"
|
|
386
|
+
:currentMax="max"
|
|
387
|
+
@updateMin="(v, d) => updateLayerMin(layerName, v, d)"
|
|
388
|
+
@updateMax="(v, d) => updateLayerMax(layerName, v, d)"
|
|
389
|
+
@updateAutoRange="(v) => updateLayerAutoRange(layerName, v)"
|
|
390
|
+
/>
|
|
309
391
|
</div>
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
</td>
|
|
315
|
-
<div v-if="expandedRows.includes(index)" class="advanced-section">
|
|
316
|
-
<histogram-editor
|
|
317
|
-
:itemId="itemId"
|
|
318
|
-
:layerIndex="index"
|
|
319
|
-
:currentFrame="currentFrame"
|
|
320
|
-
:currentFrameHistogram="currentFrameHistogram"
|
|
321
|
-
:histogramParams="histogramParams"
|
|
322
|
-
:framedelta="framedelta"
|
|
323
|
-
:autoRange="autoRange"
|
|
324
|
-
:currentMin="min"
|
|
325
|
-
:currentMax="max"
|
|
326
|
-
@updateMin="(v, d) => updateLayerMin(layerName, v, d)"
|
|
327
|
-
@updateMax="(v, d) => updateLayerMax(layerName, v, d)"
|
|
328
|
-
@updateAutoRange="(v) => updateLayerAutoRange(layerName, v)"
|
|
329
|
-
/>
|
|
330
|
-
</div>
|
|
331
|
-
</tr>
|
|
332
|
-
</tbody>
|
|
333
|
-
</table>
|
|
392
|
+
</tr>
|
|
393
|
+
</tbody>
|
|
394
|
+
</table>
|
|
395
|
+
</div>
|
|
334
396
|
</div>
|
|
335
397
|
</template>
|
|
336
398
|
|
|
@@ -456,6 +518,17 @@ export default {
|
|
|
456
518
|
margin: 30px 0px 0px;
|
|
457
519
|
height: 40px;
|
|
458
520
|
}
|
|
521
|
+
.icon-keyboard {
|
|
522
|
+
font-size: 2rem;
|
|
523
|
+
}
|
|
524
|
+
.shortcuts {
|
|
525
|
+
padding-bottom: 10px;
|
|
526
|
+
}
|
|
527
|
+
.monospace {
|
|
528
|
+
font-family: monospace;
|
|
529
|
+
background-color: rgba(0, 0, 0, 0.2);
|
|
530
|
+
padding: 1px;
|
|
531
|
+
}
|
|
459
532
|
</style>
|
|
460
533
|
|
|
461
534
|
<style>
|
|
@@ -212,6 +212,7 @@ export default Vue.extend({
|
|
|
212
212
|
:currentFrame="currentFrame"
|
|
213
213
|
:layers="imageMetadata.channels"
|
|
214
214
|
:layerMap="imageMetadata.channelmap"
|
|
215
|
+
:active="currentModeId === 2"
|
|
215
216
|
:class="currentModeId === 2 ? '' : 'invisible'"
|
|
216
217
|
@updateStyle="(style) => updateStyle(2, style)"
|
|
217
218
|
/>
|
|
@@ -222,6 +223,7 @@ export default Vue.extend({
|
|
|
222
223
|
:currentFrame="currentFrame"
|
|
223
224
|
:layers="imageMetadata.bands"
|
|
224
225
|
:layerMap="undefined"
|
|
226
|
+
:active="currentModeId === 3"
|
|
225
227
|
:class="currentModeId === 3 ? '' : 'invisible'"
|
|
226
228
|
@updateStyle="(style) => updateStyle(3, style)"
|
|
227
229
|
/>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
girder>=3.1.18
|
|
2
2
|
girder-jobs>=3.0.3
|
|
3
|
-
large_image>=1.23.
|
|
3
|
+
large_image>=1.23.2.dev6
|
|
4
4
|
|
|
5
5
|
[:python_version < "3.8"]
|
|
6
6
|
importlib-metadata<5
|
|
7
7
|
|
|
8
8
|
[tasks]
|
|
9
|
-
large-image-tasks[girder]>=1.23.
|
|
9
|
+
large-image-tasks[girder]>=1.23.2.dev6
|
|
10
10
|
girder-worker[girder]>=0.6.0
|
|
File without changes
|
|
File without changes
|
{girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/__init__.py
RENAMED
|
File without changes
|
{girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/constants.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/girder_large_image/rest/tiles.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/girder_utilities.py
RENAMED
|
File without changes
|
{girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/test_large_image.py
RENAMED
|
File without changes
|
{girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/test_tiles_rest.py
RENAMED
|
File without changes
|
{girder-large-image-1.23.1.dev44 → girder-large-image-1.23.2.dev6}/test_girder/test_web_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|