girder-large-image 1.35.6.dev2__tar.gz → 1.35.6.dev7__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.
Files changed (80) hide show
  1. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/PKG-INFO +3 -3
  2. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/widgets/CompositeLayers.vue +65 -31
  3. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/widgets/FrameSelector.vue +4 -1
  4. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image.egg-info/PKG-INFO +3 -3
  5. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image.egg-info/requires.txt +2 -2
  6. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/test_girder/web_client_specs/imageViewerSpec.js +113 -1
  7. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/LICENSE +0 -0
  8. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/README.rst +0 -0
  9. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/__init__.py +0 -0
  10. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/constants.py +0 -0
  11. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/girder_tilesource.py +0 -0
  12. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/loadmodelcache.py +0 -0
  13. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/models/__init__.py +0 -0
  14. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/models/image_item.py +0 -0
  15. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/rest/__init__.py +0 -0
  16. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/rest/item_meta.py +0 -0
  17. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/rest/large_image_resource.py +0 -0
  18. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/rest/tiles.py +0 -0
  19. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/eventStream.js +0 -0
  20. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/extra/.gitignore +0 -0
  21. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/index.js +0 -0
  22. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/main.js +0 -0
  23. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/package.json +0 -0
  24. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/routes.js +0 -0
  25. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/stylesheets/fileList.styl +0 -0
  26. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/stylesheets/imageViewerSelectWidget.styl +0 -0
  27. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/stylesheets/itemList.styl +0 -0
  28. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/stylesheets/itemView.styl +0 -0
  29. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/stylesheets/itemViewCodemirror.styl +0 -0
  30. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/stylesheets/largeImageConfig.styl +0 -0
  31. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/stylesheets/metadataWidget.styl +0 -0
  32. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/templates/imageViewerSelectWidget.pug +0 -0
  33. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/templates/itemList.pug +0 -0
  34. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/templates/itemView.pug +0 -0
  35. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/templates/itemViewCodemirror.pug +0 -0
  36. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/templates/largeImageConfig.pug +0 -0
  37. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/templates/largeImage_fileAction.pug +0 -0
  38. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/templates/metadataWidget.pug +0 -0
  39. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/templates/metadatumEditWidget.pug +0 -0
  40. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/configView.js +0 -0
  41. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/fileList.js +0 -0
  42. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/imageViewerSelectWidget.js +0 -0
  43. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/imageViewerWidget/base.js +0 -0
  44. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/imageViewerWidget/geojs.js +0 -0
  45. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/imageViewerWidget/index.js +0 -0
  46. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/imageViewerWidget/leaflet.js +0 -0
  47. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/imageViewerWidget/openlayers.js +0 -0
  48. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/imageViewerWidget/openseadragon.js +0 -0
  49. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/imageViewerWidget/setFrameQuad.js +0 -0
  50. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/imageViewerWidget/slideatlas.js +0 -0
  51. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/index.js +0 -0
  52. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/itemList.js +0 -0
  53. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/itemView.js +0 -0
  54. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/itemViewCodemirror.js +0 -0
  55. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/itemViewWidget.js +0 -0
  56. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/views/metadataWidget.js +0 -0
  57. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/vue/components/PresetsMenu.vue +0 -0
  58. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/webpack.helper.js +0 -0
  59. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/widgets/DualInput.vue +0 -0
  60. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/widgets/HistogramEditor.vue +0 -0
  61. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/widgets/colors.json +0 -0
  62. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image/web_client/widgets/components.py +0 -0
  63. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image.egg-info/SOURCES.txt +0 -0
  64. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image.egg-info/dependency_links.txt +0 -0
  65. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image.egg-info/entry_points.txt +0 -0
  66. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image.egg-info/not-zip-safe +0 -0
  67. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image.egg-info/scm_file_list.json +0 -0
  68. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/girder_large_image.egg-info/top_level.txt +0 -0
  69. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/pyproject.toml +0 -0
  70. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/setup.cfg +0 -0
  71. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/setup.py +0 -0
  72. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/test_girder/__init__.py +0 -0
  73. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/test_girder/conftest.py +0 -0
  74. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/test_girder/girder_utilities.py +0 -0
  75. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/test_girder/test_large_image.py +0 -0
  76. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/test_girder/test_tiles_rest.py +0 -0
  77. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/test_girder/test_web_client.py +0 -0
  78. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/test_girder/web_client_specs/.eslintrc +0 -0
  79. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/test_girder/web_client_specs/largeImageSpec.js +0 -0
  80. {girder_large_image-1.35.6.dev2 → girder_large_image-1.35.6.dev7}/test_girder/web_client_specs/otherFeatures.js +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: girder-large-image
3
- Version: 1.35.6.dev2
3
+ Version: 1.35.6.dev7
4
4
  Summary: A Girder plugin to work with large, multiresolution images.
5
5
  Home-page: https://github.com/girder/large_image
6
6
  Author: Kitware, Inc.
@@ -19,9 +19,9 @@ Description-Content-Type: text/x-rst
19
19
  License-File: LICENSE
20
20
  Requires-Dist: girder<5,>=3.1.18
21
21
  Requires-Dist: girder-jobs<5,>=3.0.3
22
- Requires-Dist: large_image>=1.35.6.dev2
22
+ Requires-Dist: large_image>=1.35.6.dev7
23
23
  Provides-Extra: tasks
24
- Requires-Dist: large-image-tasks[girder]>=1.35.6.dev2; extra == "tasks"
24
+ Requires-Dist: large-image-tasks[girder]>=1.35.6.dev7; extra == "tasks"
25
25
  Requires-Dist: girder-worker[girder]<5,>=0.6.0; extra == "tasks"
26
26
  Dynamic: author
27
27
  Dynamic: author-email
@@ -13,7 +13,9 @@ module.exports = {
13
13
  'layerMap',
14
14
  'active',
15
15
  'colors',
16
- 'styleUpdate'
16
+ 'styleUpdate',
17
+
18
+ 'layerHotkeys'
17
19
  ],
18
20
  data() {
19
21
  return {
@@ -38,6 +40,15 @@ module.exports = {
38
40
  roundRange: true
39
41
  };
40
42
  },
43
+ customShortcuts() {
44
+ if (!this.layerHotkeys) {
45
+ return undefined;
46
+ }
47
+ const labels = this.layerHotkeys.labels || [];
48
+ return this.layers
49
+ .map((layerName, index) => ({layerName, keys: labels[index]}))
50
+ .filter((entry) => entry.keys);
51
+ },
41
52
  showExpandAllButton() {
42
53
  if (this.histogramRows.length) {
43
54
  return document.getElementsByClassName('expand-btn').length > 0;
@@ -122,25 +133,34 @@ module.exports = {
122
133
  }
123
134
  },
124
135
  keyHandler(e) {
125
- let numericKey = parseFloat(e.key);
126
- if (e.ctrlKey && !isNaN(numericKey)) {
127
- e.preventDefault();
136
+ let layerIndex;
137
+ if (this.layerHotkeys) {
138
+ layerIndex = this.layerHotkeys.layerForEvent(e);
139
+ if (layerIndex === undefined || layerIndex === null || layerIndex < 0) {
140
+ return;
141
+ }
142
+ } else {
143
+ let numericKey = parseFloat(e.key);
144
+ if (!e.ctrlKey || isNaN(numericKey)) {
145
+ return;
146
+ }
128
147
  if (numericKey === 0) {
129
148
  numericKey += 10;
130
149
  }
131
150
  if (e.altKey) {
132
151
  numericKey += 10;
133
152
  }
134
- const layerIndex = numericKey - 1;
135
- if (layerIndex < this.layers.length) {
136
- const targetLayer = this.layers[layerIndex];
137
- if (this.compositeLayerInfo[targetLayer].enabled) {
138
- this.enabledLayers = this.enabledLayers.filter((v) => v !== targetLayer);
139
- } else {
140
- this.enabledLayers.push(targetLayer);
141
- }
142
- this.updateActiveLayers();
153
+ layerIndex = numericKey - 1;
154
+ }
155
+ e.preventDefault();
156
+ if (layerIndex < this.layers.length) {
157
+ const targetLayer = this.layers[layerIndex];
158
+ if (this.compositeLayerInfo[targetLayer].enabled) {
159
+ this.enabledLayers = this.enabledLayers.filter((v) => v !== targetLayer);
160
+ } else {
161
+ this.enabledLayers.push(targetLayer);
143
162
  }
163
+ this.updateActiveLayers();
144
164
  }
145
165
  },
146
166
  initializeLayerInfo() {
@@ -342,24 +362,38 @@ module.exports = {
342
362
  <div class="h5">
343
363
  Keyboard Shortcuts
344
364
  </div>
345
- <div>
346
- <span class="monospace">ctrl + number</span>
347
- Toggle visibility of the layer at the number position
348
- </div>
349
- <div>
350
- <span style="font-weight: bold;">Example: </span>
351
- <span class="monospace">ctrl + 1</span>
352
- Toggle visibility of the first layer in the table
353
- </div>
354
- <div>
355
- <span class="monospace">ctrl + alt + number</span>
356
- Toggle visibility of the layer at the position of the number plus 10
357
- </div>
358
- <div>
359
- <span style="font-weight: bold;">Example: </span>
360
- <span class="monospace">ctrl + alt + 1</span>
361
- Toggle visibility of the eleventh layer in the table
362
- </div>
365
+ <template v-if="customShortcuts">
366
+ <div
367
+ v-for="entry in customShortcuts"
368
+ :key="entry.layerName"
369
+ >
370
+ <span class="monospace">{{ entry.keys }}</span>
371
+ Toggle visibility of {{ entry.layerName }}
372
+ </div>
373
+ <div v-if="!customShortcuts.length">
374
+ No layers have keyboard shortcuts.
375
+ </div>
376
+ </template>
377
+ <template v-else>
378
+ <div>
379
+ <span class="monospace">ctrl + number</span>
380
+ Toggle visibility of the layer at the number position
381
+ </div>
382
+ <div>
383
+ <span style="font-weight: bold;">Example: </span>
384
+ <span class="monospace">ctrl + 1</span>
385
+ Toggle visibility of the first layer in the table
386
+ </div>
387
+ <div>
388
+ <span class="monospace">ctrl + alt + number</span>
389
+ Toggle visibility of the layer at the position of the number plus 10
390
+ </div>
391
+ <div>
392
+ <span style="font-weight: bold;">Example: </span>
393
+ <span class="monospace">ctrl + alt + 1</span>
394
+ Toggle visibility of the eleventh layer in the table
395
+ </div>
396
+ </template>
363
397
  </div>
364
398
  <div class="table-container">
365
399
  <table
@@ -9,7 +9,8 @@ module.exports = {
9
9
  'liConfig',
10
10
  'colors',
11
11
  'getFrameHistogram',
12
- 'frameHistograms'
12
+ 'frameHistograms',
13
+ 'layerHotkeys'
13
14
  ],
14
15
  data() {
15
16
  return {
@@ -401,6 +402,7 @@ module.exports = {
401
402
  :active="currentModeId === 2"
402
403
  :class="currentModeId === 2 ? '' : 'invisible'"
403
404
  :colors="colors"
405
+ :layer-hotkeys="layerHotkeys"
404
406
  :style-update="(style) => updateStyle(2, style)"
405
407
  />
406
408
  <composite-layers
@@ -418,6 +420,7 @@ module.exports = {
418
420
  :active="currentModeId === 3"
419
421
  :class="currentModeId === 3 ? '' : 'invisible'"
420
422
  :colors="colors"
423
+ :layer-hotkeys="layerHotkeys"
421
424
  :style-update="(style) => updateStyle(3, style)"
422
425
  />
423
426
  </div>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: girder-large-image
3
- Version: 1.35.6.dev2
3
+ Version: 1.35.6.dev7
4
4
  Summary: A Girder plugin to work with large, multiresolution images.
5
5
  Home-page: https://github.com/girder/large_image
6
6
  Author: Kitware, Inc.
@@ -19,9 +19,9 @@ Description-Content-Type: text/x-rst
19
19
  License-File: LICENSE
20
20
  Requires-Dist: girder<5,>=3.1.18
21
21
  Requires-Dist: girder-jobs<5,>=3.0.3
22
- Requires-Dist: large_image>=1.35.6.dev2
22
+ Requires-Dist: large_image>=1.35.6.dev7
23
23
  Provides-Extra: tasks
24
- Requires-Dist: large-image-tasks[girder]>=1.35.6.dev2; extra == "tasks"
24
+ Requires-Dist: large-image-tasks[girder]>=1.35.6.dev7; extra == "tasks"
25
25
  Requires-Dist: girder-worker[girder]<5,>=0.6.0; extra == "tasks"
26
26
  Dynamic: author
27
27
  Dynamic: author-email
@@ -1,7 +1,7 @@
1
1
  girder<5,>=3.1.18
2
2
  girder-jobs<5,>=3.0.3
3
- large_image>=1.35.6.dev2
3
+ large_image>=1.35.6.dev7
4
4
 
5
5
  [tasks]
6
- large-image-tasks[girder]>=1.35.6.dev2
6
+ large-image-tasks[girder]>=1.35.6.dev7
7
7
  girder-worker[girder]<5,>=0.6.0
@@ -1,4 +1,4 @@
1
- /* globals describe, it, expect, _, girderTest, $, runs, waitsFor, xit */
1
+ /* globals describe, it, expect, _, girderTest, $, runs, waitsFor, waits, xit */
2
2
 
3
3
  girderTest.importPlugin('large_image');
4
4
 
@@ -77,6 +77,118 @@ $(function () {
77
77
  }, 'control slider to update');
78
78
  });
79
79
  });
80
+ describe('test layer hotkeys in band compositing', function () {
81
+ // CompositeLayers listens on the document with addEventListener, which
82
+ // jQuery's trigger does not reach, so dispatch native events.
83
+ function pressKey(key, mods) {
84
+ var evt = document.createEvent('Event');
85
+ evt.initEvent('keydown', true, true);
86
+ var props = _.extend({key: key, ctrlKey: false, altKey: false, shiftKey: false, metaKey: false}, mods || {});
87
+ _.each(props, function (value, name) {
88
+ Object.defineProperty(evt, name, {value: value});
89
+ });
90
+ document.dispatchEvent(evt);
91
+ }
92
+ function bandEnabled(band) {
93
+ return $('.image-frame-control-box .enable-col input[value="' + band + '"]').prop('checked');
94
+ }
95
+ function frameSelector() {
96
+ return $('.image-frame-control-box')[0].__vue__;
97
+ }
98
+
99
+ it('upload a multi-band image', function () {
100
+ runs(function () {
101
+ $('.g-item-breadcrumb-link[data-type="folder"]:last').click();
102
+ });
103
+ girderTest.waitForLoad();
104
+ runs(function () {
105
+ girderTest.binaryUpload('${large_image}/../../test/test_files/multi_test_source_bands.yml'); // eslint-disable-line no-template-curly-in-string
106
+ });
107
+ girderTest.waitForLoad();
108
+ });
109
+ it('navigate to the item and use band compositing', function () {
110
+ waitsFor(function () {
111
+ return $('a.g-item-list-link:contains(multi_test_source_bands)').length > 0;
112
+ }, 'item link to appear');
113
+ runs(function () {
114
+ $('a.g-item-list-link:contains(multi_test_source_bands)').click();
115
+ });
116
+ girderTest.waitForLoad();
117
+ waitsFor(function () {
118
+ return $('.image-frame-control-box select[name="mode"] option[value="3"]').length > 0;
119
+ }, 'band compositing mode to be available', 15000);
120
+ runs(function () {
121
+ var select = $('.image-frame-control-box select[name="mode"]')[0];
122
+ select.value = '3';
123
+ var evt = document.createEvent('HTMLEvents');
124
+ evt.initEvent('change', true, true);
125
+ select.dispatchEvent(evt);
126
+ });
127
+ waitsFor(function () {
128
+ return $('.image-frame-control-box .enable-col input[value="green"]:visible').length > 0;
129
+ }, 'band table to appear');
130
+ runs(function () {
131
+ expect(bandEnabled('red')).toBe(true);
132
+ expect(bandEnabled('green')).toBe(true);
133
+ });
134
+ });
135
+ it('toggle a band with the default keys', function () {
136
+ runs(function () {
137
+ pressKey('1', {ctrlKey: true});
138
+ });
139
+ waitsFor(function () {
140
+ return bandEnabled('red') === false;
141
+ }, 'ctrl+1 to hide the first band');
142
+ runs(function () {
143
+ pressKey('1', {ctrlKey: true});
144
+ });
145
+ waitsFor(function () {
146
+ return bandEnabled('red') === true;
147
+ }, 'ctrl+1 to show the first band');
148
+ });
149
+ it('replace the layer hotkeys', function () {
150
+ runs(function () {
151
+ frameSelector()._props.layerHotkeys = {
152
+ layerForEvent: function (evt) {
153
+ return evt.key === 'q' && !evt.ctrlKey ? 1 : undefined;
154
+ },
155
+ labels: [undefined, 'Q']
156
+ };
157
+ });
158
+ waits(100);
159
+ runs(function () {
160
+ pressKey('1', {ctrlKey: true});
161
+ pressKey('q');
162
+ });
163
+ waitsFor(function () {
164
+ return bandEnabled('green') === false;
165
+ }, 'q to hide the second band');
166
+ runs(function () {
167
+ expect(bandEnabled('red')).toBe(true);
168
+ });
169
+ });
170
+ it('list the replaced keys in the help', function () {
171
+ runs(function () {
172
+ $('.image-frame-control-box .icon-keyboard:visible').click();
173
+ });
174
+ waitsFor(function () {
175
+ return $('.image-frame-control-box .shortcuts:visible').length > 0;
176
+ }, 'shortcut help to show');
177
+ runs(function () {
178
+ var text = $('.image-frame-control-box .shortcuts:visible').text().replace(/\s+/g, ' ');
179
+ expect(text).toContain('Q Toggle visibility of green');
180
+ expect(text).not.toContain('ctrl + number');
181
+ $('.image-frame-control-box .icon-keyboard:visible').click();
182
+ frameSelector()._props.layerHotkeys = undefined;
183
+ });
184
+ // Toggling bands requests histograms; let them finish before the
185
+ // next test navigates away from this viewer.
186
+ waitsFor(function () {
187
+ return $.active === 0;
188
+ }, 'histogram requests to finish');
189
+ girderTest.waitForLoad();
190
+ });
191
+ });
80
192
  describe('upload test file', function () {
81
193
  it('go to collections page', function () {
82
194
  runs(function () {