@aics/vole-app 2.15.0 → 3.1.1
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.
- package/es/aics-image-viewer/components/App/ChannelUpdater.js +21 -3
- package/es/aics-image-viewer/components/App/index.js +156 -199
- package/es/aics-image-viewer/components/CellViewerCanvasWrapper/index.js +10 -9
- package/es/aics-image-viewer/components/ChannelsWidget.js +35 -22
- package/es/aics-image-viewer/components/ChannelsWidgetRow/index.js +27 -71
- package/es/aics-image-viewer/components/ChannelsWidgetRow/styles.css +0 -6
- package/es/aics-image-viewer/components/ColorPicker.js +1 -1
- package/es/aics-image-viewer/components/ControlPanel/index.js +5 -4
- package/es/aics-image-viewer/components/CustomizeWidget.js +12 -8
- package/es/aics-image-viewer/components/ErrorAlert/index.js +4 -4
- package/es/aics-image-viewer/components/GlobalVolumeControls.js +12 -10
- package/es/aics-image-viewer/components/StyleProvider/index.js +4 -2
- package/es/aics-image-viewer/components/TfEditor/index.js +304 -154
- package/es/aics-image-viewer/components/TfEditor/styles.css +53 -31
- package/es/aics-image-viewer/components/Toolbar/DownloadButton.js +1 -1
- package/es/aics-image-viewer/components/Toolbar/index.js +18 -16
- package/es/aics-image-viewer/components/shared/SharedCheckBox.js +1 -1
- package/es/aics-image-viewer/components/shared/SliderRow/styles.css +1 -0
- package/es/aics-image-viewer/components/shared/SmarterSlider.js +1 -1
- package/es/aics-image-viewer/components/shared/ViewerIcon.js +1 -1
- package/es/aics-image-viewer/components/useVolume.js +59 -58
- package/es/aics-image-viewer/shared/constants.js +2 -2
- package/es/aics-image-viewer/shared/utils/controlPointsToLut.js +57 -24
- package/es/aics-image-viewer/shared/utils/sceneStore.js +5 -3
- package/es/aics-image-viewer/shared/utils/storage.js +238 -0
- package/es/aics-image-viewer/shared/utils/test/storage.test.js +264 -0
- package/es/aics-image-viewer/shared/utils/test/urlParsing.test.js +240 -108
- package/es/aics-image-viewer/shared/utils/test/viewerChannelSettings.test.js +1 -1
- package/es/aics-image-viewer/shared/utils/urlParsing.js +278 -153
- package/es/aics-image-viewer/shared/utils/viewerState.js +4 -24
- package/es/aics-image-viewer/state/reset.js +111 -0
- package/es/aics-image-viewer/state/store.js +90 -0
- package/es/aics-image-viewer/state/subscribers.js +153 -0
- package/es/aics-image-viewer/state/test/reset.test.js +247 -0
- package/es/aics-image-viewer/state/util.js +71 -0
- package/es/index.js +3 -3
- package/package.json +18 -11
- package/type-declarations/aics-image-viewer/components/App/ChannelUpdater.d.ts +2 -4
- package/type-declarations/aics-image-viewer/components/App/types.d.ts +3 -3
- package/type-declarations/aics-image-viewer/components/AxisClipSliders/index.d.ts +6 -6
- package/type-declarations/aics-image-viewer/components/CellViewerCanvasWrapper/index.d.ts +5 -14
- package/type-declarations/aics-image-viewer/components/ChannelsWidget.d.ts +3 -6
- package/type-declarations/aics-image-viewer/components/ChannelsWidgetRow/index.d.ts +3 -6
- package/type-declarations/aics-image-viewer/components/ColorPicker.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/ControlPanel/index.d.ts +6 -7
- package/type-declarations/aics-image-viewer/components/CustomizeWidget.d.ts +2 -8
- package/type-declarations/aics-image-viewer/components/ErrorAlert/index.d.ts +4 -0
- package/type-declarations/aics-image-viewer/components/GlobalVolumeControls.d.ts +2 -9
- package/type-declarations/aics-image-viewer/components/MetadataViewer/index.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/StyleProvider/index.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/TfEditor/index.d.ts +10 -3
- package/type-declarations/aics-image-viewer/components/Toolbar/index.d.ts +3 -12
- package/type-declarations/aics-image-viewer/components/shared/SliderRow/index.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/shared/SmarterSlider.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/shared/ViewerIcon.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/useVolume.d.ts +7 -4
- package/type-declarations/aics-image-viewer/shared/constants.d.ts +5 -5
- package/type-declarations/aics-image-viewer/shared/types.d.ts +1 -1
- package/type-declarations/aics-image-viewer/shared/utils/controlPointsToLut.d.ts +9 -5
- package/type-declarations/aics-image-viewer/shared/utils/firebase/index.d.ts +1 -1
- package/type-declarations/aics-image-viewer/shared/utils/hooks.d.ts +1 -1
- package/type-declarations/aics-image-viewer/shared/utils/playControls.d.ts +1 -1
- package/type-declarations/aics-image-viewer/shared/utils/sceneStore.d.ts +8 -4
- package/type-declarations/aics-image-viewer/shared/utils/storage.d.ts +15 -0
- package/type-declarations/aics-image-viewer/shared/utils/urlParsing.d.ts +94 -31
- package/type-declarations/aics-image-viewer/shared/utils/viewerChannelSettings.d.ts +39 -1
- package/type-declarations/aics-image-viewer/shared/utils/viewerState.d.ts +3 -6
- package/type-declarations/aics-image-viewer/state/reset.d.ts +29 -0
- package/type-declarations/aics-image-viewer/state/store.d.ts +30 -0
- package/type-declarations/aics-image-viewer/state/subscribers.d.ts +4 -0
- package/type-declarations/aics-image-viewer/state/types.d.ts +46 -0
- package/type-declarations/aics-image-viewer/state/util.d.ts +8 -0
- package/type-declarations/index.d.ts +4 -4
- package/es/aics-image-viewer/components/ViewerStateProvider/ResetStateProvider.js +0 -163
- package/es/aics-image-viewer/components/ViewerStateProvider/index.js +0 -259
- package/type-declarations/aics-image-viewer/components/ViewerStateProvider/ResetStateProvider.d.ts +0 -34
- package/type-declarations/aics-image-viewer/components/ViewerStateProvider/index.d.ts +0 -33
- package/type-declarations/aics-image-viewer/components/ViewerStateProvider/types.d.ts +0 -107
- /package/es/aics-image-viewer/{components/ViewerStateProvider → state}/types.js +0 -0
|
@@ -1,29 +1,6 @@
|
|
|
1
1
|
import { getDefaultChannelState } from "../constants";
|
|
2
2
|
import { findFirstChannelMatch, getDisplayName } from "./viewerChannelSettings";
|
|
3
3
|
|
|
4
|
-
/** Sets all fields of the viewer state to the values of the `newState`. */
|
|
5
|
-
export function overrideViewerState(changeViewerSetting, newState) {
|
|
6
|
-
for (var _i = 0, _arr = Object.keys(newState); _i < _arr.length; _i++) {
|
|
7
|
-
var key = _arr[_i];
|
|
8
|
-
changeViewerSetting(key, newState[key]);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// Pathtrace rendering is not allowed in 2D view mode but is in 3D mode.
|
|
12
|
-
// Since we're not guaranteed on the order of object keys, apply changes to render mode a second time
|
|
13
|
-
// in case we were previously in 2D view mode and the change was blocked, but we're now in 3D.
|
|
14
|
-
changeViewerSetting("renderMode", newState.renderMode);
|
|
15
|
-
}
|
|
16
|
-
export function overrideChannelStates(setChannelSettings, currentStates, newStates) {
|
|
17
|
-
// Match the names in the new state with the existing state so we do not override the names.
|
|
18
|
-
// Also don't reset the control points or ramps, since these will be reset in the app.
|
|
19
|
-
for (var i = 0; i < newStates.length; i++) {
|
|
20
|
-
newStates[i].name = currentStates[i].name;
|
|
21
|
-
newStates[i].controlPoints = currentStates[i].controlPoints;
|
|
22
|
-
newStates[i].ramp = currentStates[i].ramp;
|
|
23
|
-
}
|
|
24
|
-
setChannelSettings(newStates);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
4
|
/** Returns the indices of channels that have either the volume or isosurface enabled. */
|
|
28
5
|
export function getEnabledChannelIndices(channelSettings) {
|
|
29
6
|
var enabledChannels = [];
|
|
@@ -44,7 +21,7 @@ export function colorHexToArray(hex) {
|
|
|
44
21
|
}
|
|
45
22
|
}
|
|
46
23
|
export function initializeOneChannelSetting(channelName, index, defaultColor, viewerChannelSettings) {
|
|
47
|
-
var _initSettings$enabled, _initSettings$surface, _initSettings$coloriz, _initSettings$coloriz2, _initSettings$isovalu, _initSettings$surface2, _colorHexToArray, _initSettings$color, _initSettings$control, _initSettings$control2, _initSettings$ramp;
|
|
24
|
+
var _initSettings$enabled, _initSettings$surface, _initSettings$coloriz, _initSettings$coloriz2, _initSettings$isovalu, _initSettings$surface2, _colorHexToArray, _initSettings$color, _initSettings$control, _initSettings$keepInt, _initSettings$control2, _initSettings$ramp;
|
|
48
25
|
var defaultChannelState = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : getDefaultChannelState();
|
|
49
26
|
var initSettings = {};
|
|
50
27
|
if (viewerChannelSettings) {
|
|
@@ -63,6 +40,9 @@ export function initializeOneChannelSetting(channelName, index, defaultColor, vi
|
|
|
63
40
|
opacity: (_initSettings$surface2 = initSettings.surfaceOpacity) !== null && _initSettings$surface2 !== void 0 ? _initSettings$surface2 : defaultChannelState.opacity,
|
|
64
41
|
color: (_colorHexToArray = colorHexToArray((_initSettings$color = initSettings.color) !== null && _initSettings$color !== void 0 ? _initSettings$color : "")) !== null && _colorHexToArray !== void 0 ? _colorHexToArray : defaultColor,
|
|
65
42
|
useControlPoints: (_initSettings$control = initSettings.controlPointsEnabled) !== null && _initSettings$control !== void 0 ? _initSettings$control : defaultChannelState.useControlPoints,
|
|
43
|
+
keepIntensityRange: (_initSettings$keepInt = initSettings.keepIntensityRange) !== null && _initSettings$keepInt !== void 0 ? _initSettings$keepInt : defaultChannelState.keepIntensityRange,
|
|
44
|
+
// Note: The below values are placeholders and will be overridden (and the
|
|
45
|
+
// initial settings applied) when the channel is first loaded.
|
|
66
46
|
controlPoints: (_initSettings$control2 = initSettings.controlPoints) !== null && _initSettings$control2 !== void 0 ? _initSettings$control2 : defaultChannelState.controlPoints,
|
|
67
47
|
ramp: (_initSettings$ramp = initSettings.ramp) !== null && _initSettings$ramp !== void 0 ? _initSettings$ramp : defaultChannelState.ramp,
|
|
68
48
|
plotMin: defaultChannelState.plotMin,
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
3
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
5
|
+
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
6
|
+
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
7
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
8
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
9
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
10
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
11
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
12
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
13
|
+
import { getDefaultCameraState, getDefaultChannelColor, getDefaultChannelState, getDefaultViewerState } from "../shared/constants";
|
|
14
|
+
import { ViewMode } from "../shared/enums";
|
|
15
|
+
import { getEnabledChannelIndices, initializeOneChannelSetting } from "../shared/utils/viewerState";
|
|
16
|
+
import { validateState } from "./util";
|
|
17
|
+
var resetState = function resetState(currentState, newState, newChannelStates) {
|
|
18
|
+
var channelSettings = currentState.channelSettings,
|
|
19
|
+
viewMode = currentState.viewMode,
|
|
20
|
+
time = currentState.time,
|
|
21
|
+
slice = currentState.slice,
|
|
22
|
+
scene = currentState.scene;
|
|
23
|
+
|
|
24
|
+
// Needs reset on reload if one of the view modes is 2D while the other is 3D,
|
|
25
|
+
// if the timestamp is different, or if we're on a different z slice.
|
|
26
|
+
// TODO: Handle stopping playback? Requires playback to be part of ViewerStateContext
|
|
27
|
+
var isInDifferentViewMode = viewMode !== newState.viewMode && (viewMode === ViewMode.xy || newState.viewMode === ViewMode.xy);
|
|
28
|
+
var isAtDifferentTime = time !== newState.time;
|
|
29
|
+
var isAtDifferentZSlice = newState.viewMode === ViewMode.xy && !(newState.slice.z === slice.z);
|
|
30
|
+
var isAtDifferentScene = newState.scene !== scene;
|
|
31
|
+
var willNeedResetOnLoad = isInDifferentViewMode || isAtDifferentTime || isAtDifferentZSlice || isAtDifferentScene;
|
|
32
|
+
var viewerState = validateState(currentState, newState);
|
|
33
|
+
// Match the names in the new state with the existing state so we do not override the names.
|
|
34
|
+
// Also don't reset the control points or ramps, since these will be reset in the app.
|
|
35
|
+
var channelState = newChannelStates.map(function (state, index) {
|
|
36
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
37
|
+
name: channelSettings[index].name,
|
|
38
|
+
displayName: channelSettings[index].displayName,
|
|
39
|
+
controlPoints: channelSettings[index].controlPoints,
|
|
40
|
+
ramp: channelSettings[index].ramp,
|
|
41
|
+
plotMin: channelSettings[index].plotMin,
|
|
42
|
+
plotMax: channelSettings[index].plotMax
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
var channelsToReset = _toConsumableArray(Array(newChannelStates.length).keys());
|
|
46
|
+
var channelsToResetOnLoad = [];
|
|
47
|
+
if (willNeedResetOnLoad) {
|
|
48
|
+
channelsToResetOnLoad = getEnabledChannelIndices(newChannelStates);
|
|
49
|
+
channelsToReset = channelsToReset.filter(function (ch) {
|
|
50
|
+
return !channelsToResetOnLoad.includes(ch);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return _objectSpread(_objectSpread({}, viewerState), {}, {
|
|
54
|
+
channelSettings: channelState,
|
|
55
|
+
channelsToReset: channelsToReset,
|
|
56
|
+
channelsToResetOnLoad: channelsToResetOnLoad
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
export var createResetSlice = function createResetSlice(set) {
|
|
60
|
+
return {
|
|
61
|
+
channelsToReset: [],
|
|
62
|
+
channelsToResetOnLoad: [],
|
|
63
|
+
savedViewerChannelSettings: undefined,
|
|
64
|
+
useDefaultViewerChannelSettings: false,
|
|
65
|
+
onResetChannel: function onResetChannel(channelIndex) {
|
|
66
|
+
set(function (_ref) {
|
|
67
|
+
var channelsToReset = _ref.channelsToReset,
|
|
68
|
+
channelsToResetOnLoad = _ref.channelsToResetOnLoad;
|
|
69
|
+
return {
|
|
70
|
+
channelsToReset: channelsToReset.filter(function (ch) {
|
|
71
|
+
return ch !== channelIndex;
|
|
72
|
+
}),
|
|
73
|
+
channelsToResetOnLoad: channelsToResetOnLoad.filter(function (ch) {
|
|
74
|
+
return ch !== channelIndex;
|
|
75
|
+
})
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
resetToSavedViewerState: function resetToSavedViewerState(savedState, viewerChannelSettings) {
|
|
80
|
+
set(function (currentState) {
|
|
81
|
+
var _savedState$viewMode;
|
|
82
|
+
var channelSettings = currentState.channelSettings;
|
|
83
|
+
var newViewerState = _objectSpread(_objectSpread({}, getDefaultViewerState()), {}, {
|
|
84
|
+
cameraState: getDefaultCameraState((_savedState$viewMode = savedState === null || savedState === void 0 ? void 0 : savedState.viewMode) !== null && _savedState$viewMode !== void 0 ? _savedState$viewMode : ViewMode.threeD)
|
|
85
|
+
}, savedState);
|
|
86
|
+
var newChannelSettings = channelSettings.map(function (_, index) {
|
|
87
|
+
return initializeOneChannelSetting(channelSettings[index].name, index, getDefaultChannelColor(index), viewerChannelSettings);
|
|
88
|
+
});
|
|
89
|
+
return _objectSpread(_objectSpread({}, resetState(currentState, newViewerState, newChannelSettings)), {}, {
|
|
90
|
+
useDefaultViewerChannelSettings: false
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
resetToDefaultViewerState: function resetToDefaultViewerState() {
|
|
95
|
+
set(function (currentState) {
|
|
96
|
+
var channelSettings = currentState.channelSettings;
|
|
97
|
+
var defaultViewerState = _objectSpread(_objectSpread({}, getDefaultViewerState()), {}, {
|
|
98
|
+
cameraState: getDefaultCameraState(ViewMode.threeD)
|
|
99
|
+
});
|
|
100
|
+
var defaultChannelStates = channelSettings.map(function (_, index) {
|
|
101
|
+
var defaultState = getDefaultChannelState(index);
|
|
102
|
+
defaultState.volumeEnabled = index < 3;
|
|
103
|
+
return defaultState;
|
|
104
|
+
});
|
|
105
|
+
return _objectSpread(_objectSpread({}, resetState(currentState, defaultViewerState, defaultChannelStates)), {}, {
|
|
106
|
+
useDefaultViewerChannelSettings: true
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
5
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
6
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
7
|
+
import { create } from "zustand";
|
|
8
|
+
import { subscribeWithSelector } from "zustand/middleware";
|
|
9
|
+
import { getDefaultViewerState } from "../shared/constants";
|
|
10
|
+
import { createResetSlice } from "./reset";
|
|
11
|
+
import { validateState, validateStateValue } from "./util";
|
|
12
|
+
var createViewerStateStore = function createViewerStateStore(set) {
|
|
13
|
+
for (var _len = arguments.length, etc = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
14
|
+
etc[_key - 1] = arguments[_key];
|
|
15
|
+
}
|
|
16
|
+
return _objectSpread(_objectSpread(_objectSpread({}, createResetSlice.apply(void 0, [set].concat(etc))), getDefaultViewerState()), {}, {
|
|
17
|
+
channelSettings: [],
|
|
18
|
+
changeViewerSetting: function changeViewerSetting(key, value) {
|
|
19
|
+
return set(function (state) {
|
|
20
|
+
return validateStateValue(state, key, value);
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
mergeViewerSettings: function mergeViewerSettings(settings) {
|
|
24
|
+
return set(function (state) {
|
|
25
|
+
return validateState(state, settings);
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
changeChannelSetting: function changeChannelSetting(index, value) {
|
|
29
|
+
set(function (_ref) {
|
|
30
|
+
var channelSettings = _ref.channelSettings;
|
|
31
|
+
return {
|
|
32
|
+
channelSettings: channelSettings.map(function (channel, channelIndex) {
|
|
33
|
+
var changeThisChannel = Array.isArray(index) ? index.includes(channelIndex) : index === channelIndex;
|
|
34
|
+
return changeThisChannel ? _objectSpread(_objectSpread({}, channel), value) : channel;
|
|
35
|
+
})
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
replaceAllChannelSettings: function replaceAllChannelSettings(channelSettings) {
|
|
40
|
+
return set({
|
|
41
|
+
channelSettings: channelSettings
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
applyColorPresets: function applyColorPresets(colors) {
|
|
45
|
+
set(function (_ref2) {
|
|
46
|
+
var channelSettings = _ref2.channelSettings;
|
|
47
|
+
return {
|
|
48
|
+
channelSettings: channelSettings.map(function (channel, channelIndex) {
|
|
49
|
+
return _objectSpread(_objectSpread({}, channel), {}, {
|
|
50
|
+
color: colors[channelIndex % colors.length]
|
|
51
|
+
});
|
|
52
|
+
})
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
export var useViewerState = create()(subscribeWithSelector(createViewerStateStore));
|
|
59
|
+
export var selectViewerSettings = function selectViewerSettings(store) {
|
|
60
|
+
return {
|
|
61
|
+
viewMode: store.viewMode,
|
|
62
|
+
renderMode: store.renderMode,
|
|
63
|
+
imageType: store.imageType,
|
|
64
|
+
showAxes: store.showAxes,
|
|
65
|
+
showBoundingBox: store.showBoundingBox,
|
|
66
|
+
boundingBoxColor: store.boundingBoxColor,
|
|
67
|
+
backgroundColor: store.backgroundColor,
|
|
68
|
+
autorotate: store.autorotate,
|
|
69
|
+
maskAlpha: store.maskAlpha,
|
|
70
|
+
brightness: store.brightness,
|
|
71
|
+
density: store.density,
|
|
72
|
+
levels: store.levels,
|
|
73
|
+
interpolationEnabled: store.interpolationEnabled,
|
|
74
|
+
region: store.region,
|
|
75
|
+
slice: store.slice,
|
|
76
|
+
time: store.time,
|
|
77
|
+
scene: store.scene,
|
|
78
|
+
cameraState: store.cameraState
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* A small boilerplate-reducer for subscribing to a single state value with `useViewerStore`.
|
|
84
|
+
* Should only be used with string literals for best type-checking results.
|
|
85
|
+
*/
|
|
86
|
+
export var select = function select(key) {
|
|
87
|
+
return function (settings) {
|
|
88
|
+
return settings[key];
|
|
89
|
+
};
|
|
90
|
+
};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
4
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
7
|
+
import { RENDERMODE_PATHTRACE, RENDERMODE_RAYMARCH } from "@aics/vole-core";
|
|
8
|
+
import { shallow } from "zustand/shallow";
|
|
9
|
+
import { RenderMode, ViewMode } from "../shared/enums";
|
|
10
|
+
import { activeAxisMap } from "../shared/types";
|
|
11
|
+
import { colorArrayToFloats } from "../shared/utils/colorRepresentations";
|
|
12
|
+
import { alphaSliderToImageValue, brightnessSliderToImageValue, densitySliderToImageValue, gammaSliderToImageValues } from "../shared/utils/sliderValuesToImageValues";
|
|
13
|
+
import { select } from "./store";
|
|
14
|
+
var REF_EQ = {
|
|
15
|
+
fireImmediately: true
|
|
16
|
+
};
|
|
17
|
+
var DEEP_EQ = {
|
|
18
|
+
fireImmediately: true,
|
|
19
|
+
equalityFn: shallow
|
|
20
|
+
};
|
|
21
|
+
export var subscribeViewToState = function subscribeViewToState(store, view3d) {
|
|
22
|
+
var unsubscribers = [
|
|
23
|
+
// view mode
|
|
24
|
+
store.subscribe(select("viewMode"), function (viewMode) {
|
|
25
|
+
view3d.setCameraMode(viewMode);
|
|
26
|
+
view3d.resize(null);
|
|
27
|
+
}, REF_EQ),
|
|
28
|
+
// camera state
|
|
29
|
+
store.subscribe(select("cameraState"), function (cameraState) {
|
|
30
|
+
if (cameraState) {
|
|
31
|
+
view3d.setCameraState(cameraState);
|
|
32
|
+
}
|
|
33
|
+
}, DEEP_EQ),
|
|
34
|
+
// autorotate
|
|
35
|
+
store.subscribe(select("autorotate"), view3d.setAutoRotate.bind(view3d), REF_EQ),
|
|
36
|
+
// show axes
|
|
37
|
+
store.subscribe(select("showAxes"), view3d.setShowAxis.bind(view3d), REF_EQ),
|
|
38
|
+
// background color
|
|
39
|
+
store.subscribe(select("backgroundColor"), function (backgroundColor) {
|
|
40
|
+
return view3d.setBackgroundColor(colorArrayToFloats(backgroundColor));
|
|
41
|
+
}, REF_EQ),
|
|
42
|
+
// brightness
|
|
43
|
+
store.subscribe(select("brightness"), function (brightness) {
|
|
44
|
+
view3d.updateExposure(brightnessSliderToImageValue(brightness));
|
|
45
|
+
}, REF_EQ)];
|
|
46
|
+
return function () {
|
|
47
|
+
return unsubscribers.forEach(function (unsubscribe) {
|
|
48
|
+
return unsubscribe();
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
var selectAxisClipUpdateInfo = function selectAxisClipUpdateInfo(axis) {
|
|
53
|
+
return function (_ref) {
|
|
54
|
+
var region = _ref.region,
|
|
55
|
+
slice = _ref.slice,
|
|
56
|
+
viewMode = _ref.viewMode;
|
|
57
|
+
return {
|
|
58
|
+
region: region[axis],
|
|
59
|
+
slice: slice[axis],
|
|
60
|
+
viewMode: viewMode
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
export var subscribeImageToState = function subscribeImageToState(store, view3d, image) {
|
|
65
|
+
var axisClipUpdater = function axisClipUpdater(axis) {
|
|
66
|
+
return function (_ref2) {
|
|
67
|
+
var _ref2$region = _slicedToArray(_ref2.region, 2),
|
|
68
|
+
minval = _ref2$region[0],
|
|
69
|
+
maxval = _ref2$region[1],
|
|
70
|
+
slice = _ref2.slice,
|
|
71
|
+
viewMode = _ref2.viewMode;
|
|
72
|
+
var isOrthoAxis = false;
|
|
73
|
+
var axismin = 0.0;
|
|
74
|
+
var axismax = 1.0;
|
|
75
|
+
if (viewMode === ViewMode.threeD) {
|
|
76
|
+
// 3d mode: just use the region from state
|
|
77
|
+
axismin = minval;
|
|
78
|
+
axismax = maxval;
|
|
79
|
+
} else {
|
|
80
|
+
// 2d mode: if this is the looked-down axis...
|
|
81
|
+
if (activeAxisMap[viewMode] === axis) {
|
|
82
|
+
// ...show a one-slice region around `slice`
|
|
83
|
+
var oneSlice = 1 / image.imageInfo.volumeSize[axis];
|
|
84
|
+
axismin = slice;
|
|
85
|
+
axismax = slice + oneSlice;
|
|
86
|
+
} else {
|
|
87
|
+
// ...otherwise, reset to [0, 1] - we probably just changed `viewMode` to 2d and want to see the whole slice
|
|
88
|
+
axismin = 0.0;
|
|
89
|
+
axismax = 1.0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// also, "look down z" has a special mode with its own special setting
|
|
93
|
+
if (axis === "z" && viewMode === ViewMode.xy) {
|
|
94
|
+
view3d.setZSlice(image, Math.floor(slice * image.imageInfo.volumeSize.z));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// view3d wants the coordinates in the -0.5 to 0.5 range
|
|
99
|
+
view3d.setAxisClip(image, axis, axismin - 0.5, axismax - 0.5, isOrthoAxis);
|
|
100
|
+
// TODO necessary?
|
|
101
|
+
// view3d.setCameraMode(viewMode);
|
|
102
|
+
// TODO under some circumstances, this effect will trigger a load. Ideally, this would be reflected in the load
|
|
103
|
+
// state managed by `useVolume`. This is complicated by the fact that the relevant methods (`setAxisClip` and
|
|
104
|
+
// `setZSlice`) don't provide a channel load callback like other load-triggering methods (e.g. `setTime`).
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
var unsubscribers = [
|
|
108
|
+
// show bounding box
|
|
109
|
+
store.subscribe(select("showBoundingBox"), function (showBoundingBox) {
|
|
110
|
+
return view3d.setShowBoundingBox(image, showBoundingBox);
|
|
111
|
+
}, REF_EQ),
|
|
112
|
+
// bounding box color
|
|
113
|
+
store.subscribe(select("boundingBoxColor"), function (boundingBoxColor) {
|
|
114
|
+
return view3d.setBoundingBoxColor(image, colorArrayToFloats(boundingBoxColor));
|
|
115
|
+
}, REF_EQ),
|
|
116
|
+
// render mode
|
|
117
|
+
store.subscribe(select("renderMode"), function (renderMode) {
|
|
118
|
+
view3d.setMaxProjectMode(image, renderMode === RenderMode.maxProject);
|
|
119
|
+
view3d.setVolumeRenderMode(renderMode === RenderMode.pathTrace ? RENDERMODE_PATHTRACE : RENDERMODE_RAYMARCH);
|
|
120
|
+
view3d.updateActiveChannels(image);
|
|
121
|
+
}, REF_EQ),
|
|
122
|
+
// mask alpha
|
|
123
|
+
store.subscribe(select("maskAlpha"), function (maskAlpha) {
|
|
124
|
+
view3d.updateMaskAlpha(image, alphaSliderToImageValue(maskAlpha));
|
|
125
|
+
view3d.updateActiveChannels(image);
|
|
126
|
+
}, REF_EQ),
|
|
127
|
+
// density
|
|
128
|
+
store.subscribe(select("density"), function (density) {
|
|
129
|
+
return view3d.updateDensity(image, densitySliderToImageValue(density));
|
|
130
|
+
}, REF_EQ),
|
|
131
|
+
// gamma
|
|
132
|
+
store.subscribe(select("levels"), function (levels) {
|
|
133
|
+
var _gammaSliderToImageVa = gammaSliderToImageValues(levels),
|
|
134
|
+
min = _gammaSliderToImageVa.min,
|
|
135
|
+
max = _gammaSliderToImageVa.max,
|
|
136
|
+
scale = _gammaSliderToImageVa.scale;
|
|
137
|
+
view3d.setGamma(image, min, max, scale);
|
|
138
|
+
}, REF_EQ),
|
|
139
|
+
// interpolation
|
|
140
|
+
store.subscribe(select("interpolationEnabled"), function (enabled) {
|
|
141
|
+
return view3d.setInterpolationEnabled(image, enabled);
|
|
142
|
+
}, REF_EQ),
|
|
143
|
+
// clipping
|
|
144
|
+
store.subscribe(selectAxisClipUpdateInfo("x"), axisClipUpdater("x"), DEEP_EQ), store.subscribe(selectAxisClipUpdateInfo("y"), axisClipUpdater("y"), DEEP_EQ), store.subscribe(selectAxisClipUpdateInfo("z"), axisClipUpdater("z"), DEEP_EQ)
|
|
145
|
+
|
|
146
|
+
// TODO reset channels, time, scene?
|
|
147
|
+
];
|
|
148
|
+
return function () {
|
|
149
|
+
return unsubscribers.forEach(function (unsubscribe) {
|
|
150
|
+
return unsubscribe();
|
|
151
|
+
});
|
|
152
|
+
};
|
|
153
|
+
};
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
3
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
4
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
5
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
6
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
7
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
8
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
9
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
10
|
+
import { describe, expect, it } from "@jest/globals";
|
|
11
|
+
import { getDefaultCameraState, getDefaultChannelState, getDefaultViewerState } from "../../shared/constants";
|
|
12
|
+
import { ImageType, RenderMode, ViewMode } from "../../shared/enums";
|
|
13
|
+
import { useViewerState } from "../store";
|
|
14
|
+
var arbitraryViewerState = function arbitraryViewerState() {
|
|
15
|
+
return {
|
|
16
|
+
viewMode: ViewMode.xy,
|
|
17
|
+
renderMode: RenderMode.pathTrace,
|
|
18
|
+
imageType: ImageType.fullField,
|
|
19
|
+
showAxes: true,
|
|
20
|
+
showBoundingBox: true,
|
|
21
|
+
boundingBoxColor: [0, 255, 0],
|
|
22
|
+
backgroundColor: [255, 255, 0],
|
|
23
|
+
autorotate: true,
|
|
24
|
+
maskAlpha: 255,
|
|
25
|
+
brightness: 0,
|
|
26
|
+
density: 0,
|
|
27
|
+
levels: [253, 254, 255],
|
|
28
|
+
interpolationEnabled: false,
|
|
29
|
+
region: {
|
|
30
|
+
x: [0, 0],
|
|
31
|
+
y: [0, 0],
|
|
32
|
+
z: [0, 0]
|
|
33
|
+
},
|
|
34
|
+
slice: {
|
|
35
|
+
x: 3,
|
|
36
|
+
y: 3,
|
|
37
|
+
z: 3
|
|
38
|
+
},
|
|
39
|
+
time: 12,
|
|
40
|
+
scene: 3,
|
|
41
|
+
cameraState: undefined
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
var arbitraryChannelState = function arbitraryChannelState() {
|
|
45
|
+
return {
|
|
46
|
+
name: "foo",
|
|
47
|
+
displayName: "foo",
|
|
48
|
+
volumeEnabled: true,
|
|
49
|
+
isosurfaceEnabled: true,
|
|
50
|
+
isovalue: 77,
|
|
51
|
+
colorizeEnabled: true,
|
|
52
|
+
colorizeAlpha: 88,
|
|
53
|
+
opacity: 0.5,
|
|
54
|
+
color: [0, 0, 255],
|
|
55
|
+
ramp: [12, 13],
|
|
56
|
+
useControlPoints: true,
|
|
57
|
+
controlPoints: [{
|
|
58
|
+
x: 0,
|
|
59
|
+
opacity: 0,
|
|
60
|
+
color: [255, 0, 0]
|
|
61
|
+
}, {
|
|
62
|
+
x: 100,
|
|
63
|
+
opacity: 1,
|
|
64
|
+
color: [0, 255, 0]
|
|
65
|
+
}],
|
|
66
|
+
plotMin: 50,
|
|
67
|
+
plotMax: 85,
|
|
68
|
+
keepIntensityRange: true
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
var multipleArbitraryChannels = function multipleArbitraryChannels() {
|
|
72
|
+
return [_objectSpread(_objectSpread({}, arbitraryChannelState()), {}, {
|
|
73
|
+
name: "one",
|
|
74
|
+
displayName: "one",
|
|
75
|
+
volumeEnabled: false
|
|
76
|
+
}), _objectSpread(_objectSpread({}, arbitraryChannelState()), {}, {
|
|
77
|
+
name: "two",
|
|
78
|
+
displayName: "two",
|
|
79
|
+
volumeEnabled: false
|
|
80
|
+
}), _objectSpread(_objectSpread({}, arbitraryChannelState()), {}, {
|
|
81
|
+
name: "three",
|
|
82
|
+
displayName: "three"
|
|
83
|
+
}), _objectSpread(_objectSpread({}, arbitraryChannelState()), {}, {
|
|
84
|
+
name: "fish",
|
|
85
|
+
displayName: "fish",
|
|
86
|
+
volumeEnabled: true
|
|
87
|
+
})];
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/** We expect these keys of `ChannelState` to never be reset by the functions tested in this file */
|
|
91
|
+
var NOT_RESET_KEYS = ["name", "displayName", "volumeEnabled", "controlPoints", "ramp", "plotMin", "plotMax"];
|
|
92
|
+
var checkViewerState = function checkViewerState(state) {
|
|
93
|
+
var exclude = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
94
|
+
var defaultState = _objectSpread(_objectSpread({}, getDefaultViewerState()), {}, {
|
|
95
|
+
cameraState: getDefaultCameraState(ViewMode.threeD)
|
|
96
|
+
});
|
|
97
|
+
var allStateKeys = Object.keys(defaultState);
|
|
98
|
+
var stateKeys = allStateKeys.filter(function (key) {
|
|
99
|
+
return !exclude.includes(key);
|
|
100
|
+
});
|
|
101
|
+
var _iterator = _createForOfIteratorHelper(stateKeys),
|
|
102
|
+
_step;
|
|
103
|
+
try {
|
|
104
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
105
|
+
var key = _step.value;
|
|
106
|
+
expect(defaultState[key]).toEqual(state[key]);
|
|
107
|
+
}
|
|
108
|
+
} catch (err) {
|
|
109
|
+
_iterator.e(err);
|
|
110
|
+
} finally {
|
|
111
|
+
_iterator.f();
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
var checkChannelState = function checkChannelState(index, state, exclude) {
|
|
115
|
+
var defaultState = getDefaultChannelState(index);
|
|
116
|
+
var allStateKeys = Object.keys(defaultState);
|
|
117
|
+
var stateKeys = allStateKeys.filter(function (key) {
|
|
118
|
+
return !exclude.includes(key);
|
|
119
|
+
});
|
|
120
|
+
var _iterator2 = _createForOfIteratorHelper(stateKeys),
|
|
121
|
+
_step2;
|
|
122
|
+
try {
|
|
123
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
124
|
+
var key = _step2.value;
|
|
125
|
+
expect(defaultState[key]).toEqual(state[key]);
|
|
126
|
+
}
|
|
127
|
+
} catch (err) {
|
|
128
|
+
_iterator2.e(err);
|
|
129
|
+
} finally {
|
|
130
|
+
_iterator2.f();
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
describe("reset state", function () {
|
|
134
|
+
describe("resetToDefaultViewerState", function () {
|
|
135
|
+
it("resets viewer state properties to their defaults", function () {
|
|
136
|
+
useViewerState.setState(arbitraryViewerState());
|
|
137
|
+
useViewerState.getState().resetToDefaultViewerState();
|
|
138
|
+
checkViewerState(useViewerState.getState());
|
|
139
|
+
});
|
|
140
|
+
it("resets most properties to their defaults", function () {
|
|
141
|
+
useViewerState.getState().replaceAllChannelSettings(multipleArbitraryChannels());
|
|
142
|
+
useViewerState.getState().resetToDefaultViewerState();
|
|
143
|
+
useViewerState.getState().channelSettings.forEach(function (channel, index) {
|
|
144
|
+
checkChannelState(index, channel, NOT_RESET_KEYS);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
it("preserves each channel's original names and transfer function configs", function () {
|
|
148
|
+
var arbitraryChannels = multipleArbitraryChannels();
|
|
149
|
+
useViewerState.getState().replaceAllChannelSettings(arbitraryChannels);
|
|
150
|
+
useViewerState.getState().resetToDefaultViewerState();
|
|
151
|
+
useViewerState.getState().channelSettings.forEach(function (channel, index) {
|
|
152
|
+
var originalChannel = arbitraryChannels[index];
|
|
153
|
+
expect(channel.name).toEqual(originalChannel.name);
|
|
154
|
+
expect(channel.displayName).toEqual(originalChannel.displayName);
|
|
155
|
+
expect(channel.controlPoints).toEqual(originalChannel.controlPoints);
|
|
156
|
+
expect(channel.ramp).toEqual(originalChannel.ramp);
|
|
157
|
+
expect(channel.plotMin).toEqual(originalChannel.plotMin);
|
|
158
|
+
expect(channel.plotMax).toEqual(originalChannel.plotMax);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
it("sets only the first three channels to have volumes enabled", function () {
|
|
162
|
+
useViewerState.getState().replaceAllChannelSettings(multipleArbitraryChannels());
|
|
163
|
+
useViewerState.getState().resetToDefaultViewerState();
|
|
164
|
+
var _useViewerState$getSt = useViewerState.getState(),
|
|
165
|
+
channelSettings = _useViewerState$getSt.channelSettings;
|
|
166
|
+
expect(channelSettings[0].volumeEnabled).toBe(true);
|
|
167
|
+
expect(channelSettings[1].volumeEnabled).toBe(true);
|
|
168
|
+
expect(channelSettings[2].volumeEnabled).toBe(true);
|
|
169
|
+
expect(channelSettings[3].volumeEnabled).toBe(false);
|
|
170
|
+
});
|
|
171
|
+
it("sets `useDefaultViewerChannelSettings` to `true`", function () {
|
|
172
|
+
useViewerState.getState().resetToSavedViewerState();
|
|
173
|
+
useViewerState.getState().resetToDefaultViewerState();
|
|
174
|
+
expect(useViewerState.getState().useDefaultViewerChannelSettings).toBe(true);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
describe("resetToSavedViewerState", function () {
|
|
178
|
+
it('sets viewer state properties passed in as "saved," and resets all others', function () {
|
|
179
|
+
var savedState = {
|
|
180
|
+
renderMode: RenderMode.pathTrace,
|
|
181
|
+
brightness: 33,
|
|
182
|
+
backgroundColor: [128, 128, 128],
|
|
183
|
+
showAxes: true,
|
|
184
|
+
time: 4
|
|
185
|
+
};
|
|
186
|
+
var savedStateKeys = Object.keys(savedState);
|
|
187
|
+
useViewerState.setState(arbitraryViewerState());
|
|
188
|
+
useViewerState.getState().resetToSavedViewerState(savedState);
|
|
189
|
+
checkViewerState(useViewerState.getState(), savedStateKeys);
|
|
190
|
+
var state = useViewerState.getState();
|
|
191
|
+
expect(state.renderMode).toEqual(savedState.renderMode);
|
|
192
|
+
expect(state.brightness).toEqual(savedState.brightness);
|
|
193
|
+
expect(state.backgroundColor).toEqual(savedState.backgroundColor);
|
|
194
|
+
expect(state.showAxes).toEqual(savedState.showAxes);
|
|
195
|
+
expect(state.time).toEqual(savedState.time);
|
|
196
|
+
});
|
|
197
|
+
it("applies saved viewer channel settings", function () {
|
|
198
|
+
var viewerChannelSettings = {
|
|
199
|
+
groups: [{
|
|
200
|
+
name: "group",
|
|
201
|
+
channels: [{
|
|
202
|
+
match: ["one", "three"],
|
|
203
|
+
surfaceEnabled: true,
|
|
204
|
+
isovalue: 38,
|
|
205
|
+
color: "ff00ff"
|
|
206
|
+
}, {
|
|
207
|
+
match: "two",
|
|
208
|
+
controlPointsEnabled: true,
|
|
209
|
+
colorizeEnabled: true,
|
|
210
|
+
colorizeAlpha: 27
|
|
211
|
+
}]
|
|
212
|
+
}]
|
|
213
|
+
};
|
|
214
|
+
var arbitraryChannels = multipleArbitraryChannels();
|
|
215
|
+
useViewerState.getState().replaceAllChannelSettings(arbitraryChannels);
|
|
216
|
+
useViewerState.getState().resetToSavedViewerState({}, viewerChannelSettings);
|
|
217
|
+
var _useViewerState$getSt2 = useViewerState.getState(),
|
|
218
|
+
channelSettings = _useViewerState$getSt2.channelSettings;
|
|
219
|
+
|
|
220
|
+
// Channel named "one" should have matched group 1 above
|
|
221
|
+
checkChannelState(0, channelSettings[0], [].concat(NOT_RESET_KEYS, ["isosurfaceEnabled", "color", "isovalue"]));
|
|
222
|
+
expect(channelSettings[0].isosurfaceEnabled).toBe(true);
|
|
223
|
+
expect(channelSettings[0].color).toEqual([255, 0, 255]);
|
|
224
|
+
expect(channelSettings[0].isovalue).toBe(38);
|
|
225
|
+
|
|
226
|
+
// Channel named "two" should have matched group 2 above
|
|
227
|
+
checkChannelState(1, channelSettings[1], [].concat(NOT_RESET_KEYS, ["useControlPoints", "colorizeEnabled", "colorizeAlpha"]));
|
|
228
|
+
expect(channelSettings[1].useControlPoints).toBe(true);
|
|
229
|
+
expect(channelSettings[1].colorizeEnabled).toBe(true);
|
|
230
|
+
expect(channelSettings[1].colorizeAlpha).toBe(27);
|
|
231
|
+
|
|
232
|
+
// Channel named "three" should have matched group 1 above
|
|
233
|
+
checkChannelState(2, channelSettings[2], [].concat(NOT_RESET_KEYS, ["isosurfaceEnabled", "color", "isovalue"]));
|
|
234
|
+
expect(channelSettings[2].isosurfaceEnabled).toBe(true);
|
|
235
|
+
expect(channelSettings[2].color).toEqual([255, 0, 255]);
|
|
236
|
+
expect(channelSettings[2].isovalue).toBe(38);
|
|
237
|
+
|
|
238
|
+
// Channel named "fish" should not have matched any group and have default settings
|
|
239
|
+
checkChannelState(3, channelSettings[3], NOT_RESET_KEYS);
|
|
240
|
+
});
|
|
241
|
+
it("sets `useDefaultViewerChannelSettings` to `false`", function () {
|
|
242
|
+
useViewerState.getState().resetToDefaultViewerState();
|
|
243
|
+
useViewerState.getState().resetToSavedViewerState();
|
|
244
|
+
expect(useViewerState.getState().useDefaultViewerChannelSettings).toBe(false);
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
});
|