From 26cedef927d0e2fded3c090a57e168a8ba87bd50 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Mon, 2 Aug 2021 17:56:33 +0200 Subject: [PATCH] refactor huge render method into smaller parts --- .../view/right-border-tabs/meshes_view.js | 300 ++++++++++-------- 1 file changed, 175 insertions(+), 125 deletions(-) diff --git a/frontend/javascripts/oxalis/view/right-border-tabs/meshes_view.js b/frontend/javascripts/oxalis/view/right-border-tabs/meshes_view.js index aa40918ef9c..370dcbbfa97 100644 --- a/frontend/javascripts/oxalis/view/right-border-tabs/meshes_view.js +++ b/frontend/javascripts/oxalis/view/right-border-tabs/meshes_view.js @@ -229,13 +229,185 @@ class MeshesView extends React.Component { this.intervalID = setTimeout(() => this.pollJobData(), refreshInterval); } - render() { + getPrecomputeMeshesTooltipInfo = () => { + let title = ""; + let disabled = true; + if (!features().jobsEnabled) { + title = "Computation jobs are not enabled for this webKnossos instance."; + } else if (this.props.hasVolume) { + title = + this.props.segmentationLayer != null && this.props.segmentationLayer.fallbackLayer + ? "Meshes cannot be precomputed for volume annotations. However, you can open this dataset in view mode to precompute meshes for the dataset's segmentation layer." + : "Meshes cannot be precomputed for volume annotations."; + } else if (this.props.segmentationLayer == null) { + title = "There is no segmentation layer for which meshes could be precomputed."; + } else { + title = + "Precompute meshes for all segments of this dataset so that meshes for segments can be loaded quickly afterwards from a mesh file."; + disabled = false; + } + + return { + disabled, + title, + }; + }; + + getComputeMeshAdHocTooltipInfo = () => { + let title = ""; + let disabled = true; + if (this.props.hasVolume) { + title = + this.props.segmentationLayer != null && this.props.segmentationLayer.fallbackLayer + ? "Meshes cannot be computed for volume annotations. However, you can open this dataset in view mode to compute meshes for the dataset's segmentation layer." + : "Meshes cannot be computed for volume annotations."; + } else if (this.props.segmentationLayer == null) { + title = "There is no segmentation layer for which a mesh could be computed."; + } else { + title = "Compute mesh for the centered segment."; + disabled = false; + } + + return { + disabled, + title, + }; + }; + + getIsosurfaceList = () => { const hasSegmentation = Model.getSegmentationLayer() != null; const moveTo = (seedPosition: Vector3) => { Store.dispatch(setPositionAction(seedPosition, null, false)); }; + const getDownloadButton = (segmentId: number) => ( + + Store.dispatch(triggerIsosurfaceDownloadAction(segmentId))} + /> + + ); + const getRefreshButton = (segmentId: number, isPrecomputed: boolean, isLoading: boolean) => { + if (isLoading) { + return ( + { + Store.dispatch(refreshIsosurfaceAction(segmentId)); + }} + /> + ); + } else { + return isPrecomputed ? null : ( + + { + Store.dispatch(refreshIsosurfaceAction(segmentId)); + }} + /> + + ); + } + }; + const getDeleteButton = (segmentId: number) => ( + + { + Store.dispatch(removeIsosurfaceAction(segmentId)); + // reset the active mesh id so the deleted one is not reloaded immediately + this.props.changeActiveIsosurfaceId(0, [0, 0, 0], false); + }} + /> + + ); + const convertHSLAToCSSString = ([h, s, l, a]) => + `hsla(${360 * h}, ${100 * s}%, ${100 * l}%, ${a})`; + const convertCellIdToCSS = id => + convertHSLAToCSSString(jsConvertCellIdToHSLA(id, this.props.mappingColors)); + + const getToggleVisibilityCheckbox = (segmentId: number, isVisible: boolean) => ( + + ) => { + this.props.onChangeVisibility(segmentId, event.target.checked); + }} + /> + + ); + + const getIsosurfaceListItem = (isosurface: IsosurfaceInformation) => { + const { segmentId, seedPosition, isLoading, isPrecomputed, isVisible } = isosurface; + const isCenteredCell = hasSegmentation + ? getSegmentIdForPosition(getPosition(this.props.flycam)) + : false; + const isHoveredItem = segmentId === this.state.hoveredListItem; + const actionVisibility = isLoading || isHoveredItem ? "visible" : "hidden"; + + const textStyle = isVisible ? {} : { fontStyle: "italic", color: "#989898" }; + return ( + { + this.setState({ hoveredListItem: segmentId }); + }} + onMouseLeave={() => { + this.setState({ hoveredListItem: null }); + }} + key={segmentId} + > +
+
+ {isHoveredItem ? ( + getToggleVisibilityCheckbox(segmentId, isVisible) + ) : ( + + )}{" "} + { + this.props.changeActiveIsosurfaceId(segmentId, seedPosition, !isPrecomputed); + moveTo(seedPosition); + }} + style={textStyle} + > + Segment {segmentId} + +
+
+ {getRefreshButton(segmentId, isPrecomputed, isLoading)} + {getDownloadButton(segmentId)} + {getDeleteButton(segmentId)} +
+
+
+ ); + }; + + // $FlowIgnore[incompatible-call] + // $FlowIgnore[missing-annot] flow does not know that the values passed as isosurfaces are indeed from the type IsosurfaceInformation + return Object.values(this.props.isosurfaces).map((isosurface: IsosurfaceInformation) => + getIsosurfaceListItem(isosurface), + ); + }; + + render() { const startComputingMeshfile = async () => { const datasetResolutionInfo = getResolutionInfoOfSegmentationLayer(this.props.dataset); const defaultOrHigherIndex = datasetResolutionInfo.getIndexOrClosestHigherIndex( @@ -294,54 +466,6 @@ class MeshesView extends React.Component { ); }; - const getDownloadButton = (segmentId: number) => ( - - Store.dispatch(triggerIsosurfaceDownloadAction(segmentId))} - /> - - ); - const getRefreshButton = (segmentId: number, isPrecomputed: boolean, isLoading: boolean) => { - if (isLoading) { - return ( - { - Store.dispatch(refreshIsosurfaceAction(segmentId)); - }} - /> - ); - } else { - return isPrecomputed ? null : ( - - { - Store.dispatch(refreshIsosurfaceAction(segmentId)); - }} - /> - - ); - } - }; - const getDeleteButton = (segmentId: number) => ( - - { - Store.dispatch(removeIsosurfaceAction(segmentId)); - // reset the active mesh id so the deleted one is not reloaded immediately - this.props.changeActiveIsosurfaceId(0, [0, 0, 0], false); - }} - /> - - ); - const convertHSLAToCSSString = ([h, s, l, a]) => - `hsla(${360 * h}, ${100 * s}%, ${100 * l}%, ${a})`; - const convertCellIdToCSS = id => - convertHSLAToCSSString(jsConvertCellIdToHSLA(id, this.props.mappingColors)); - const getStlImportItem = () => ( { {getHeaderDropdownButton()}
{/* Only show option for ad-hoc computation if no mesh file is available */ - this.props.currentMeshFile ? null : getLoadTemporaryMeshButton()} + this.props.currentMeshFile ? null : getComputeMeshAdHocButton()} {this.props.currentMeshFile ? getLoadPrecomputedMeshButton() : getPrecomputeMeshesButton()}
); - const getToggleVisibilityCheckbox = (segmentId: number, isVisible: boolean) => ( - - ) => { - this.props.onChangeVisibility(segmentId, event.target.checked); - }} - /> - - ); - - const getIsosurfaceListItem = (isosurface: IsosurfaceInformation) => { - const { segmentId, seedPosition, isLoading, isPrecomputed, isVisible } = isosurface; - const isCenteredCell = hasSegmentation - ? getSegmentIdForPosition(getPosition(this.props.flycam)) - : false; - const isHoveredItem = segmentId === this.state.hoveredListItem; - const actionVisibility = isLoading || isHoveredItem ? "visible" : "hidden"; - - const textStyle = isVisible ? {} : { fontStyle: "italic", color: "#989898" }; - return ( - { - this.setState({ hoveredListItem: segmentId }); - }} - onMouseLeave={() => { - this.setState({ hoveredListItem: null }); - }} - key={segmentId} - > -
-
- {isHoveredItem ? ( - getToggleVisibilityCheckbox(segmentId, isVisible) - ) : ( - - )}{" "} - { - this.props.changeActiveIsosurfaceId(segmentId, seedPosition, !isPrecomputed); - moveTo(seedPosition); - }} - style={textStyle} - > - Segment {segmentId} - -
-
- {getRefreshButton(segmentId, isPrecomputed, isLoading)} - {getDownloadButton(segmentId)} - {getDeleteButton(segmentId)} -
-
-
- ); - }; - - const getIsosurfaceList = () => - // $FlowIgnore[incompatible-call] flow does not know that the values passed as isosurfaces are indeed from the type IsosurfaceInformation - Object.values(this.props.isosurfaces).map(isosurface => getIsosurfaceListItem(isosurface)); return (
@@ -580,7 +630,7 @@ class MeshesView extends React.Component { }`, }} > - {getIsosurfaceList()} + {this.getIsosurfaceList()}
);