diff --git a/src/atlasViewer/atlasViewer.component.ts b/src/atlasViewer/atlasViewer.component.ts index e77718d7a98f11501cd3e0f241faf7afe0f5a97e..deff73cac89cb51f169c118d55326a0a26030c18 100644 --- a/src/atlasViewer/atlasViewer.component.ts +++ b/src/atlasViewer/atlasViewer.component.ts @@ -44,6 +44,7 @@ import { viewerStateSetSelectedRegions, viewerStateRemoveAdditionalLayer, viewer import { viewerStateGetOverlayingAdditionalParcellations, viewerStateParcVersionSelector } from "src/services/state/viewerState/selectors"; import { ngViewerSelectorClearViewEntries } from "src/services/state/ngViewerState/selectors"; import { ngViewerActionClearView } from "src/services/state/ngViewerState/actions"; +import { uiStateMouseOverSegmentsSelector } from "src/services/state/uiState/selectors"; /** * TODO @@ -193,8 +194,7 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit { // TODO temporary hack. even though the front octant is hidden, it seems if a mesh is present, hover will select the said mesh this.onhoverSegments$ = this.store.pipe( - select('uiState'), - select('mouseOverSegments'), + select(uiStateMouseOverSegmentsSelector), filter(v => !!v), distinctUntilChanged((o, n) => o.length === n.length && n.every(segment => o.find(oSegment => oSegment.layer.name === segment.layer.name && oSegment.segment === segment.segment) ) ), /* cannot filter by state, as the template expects a default value, or it will throw ExpressionChangedAfterItHasBeenCheckedError */ diff --git a/src/atlasViewer/mouseOver.directive.ts b/src/atlasViewer/mouseOver.directive.ts index 0d31a310798e1e3ae87c5a626878a25fc950ed52..e648b53ba1c847f7610ae55d9ce1deb546313758 100644 --- a/src/atlasViewer/mouseOver.directive.ts +++ b/src/atlasViewer/mouseOver.directive.ts @@ -5,6 +5,7 @@ import { combineLatest, merge, Observable } from "rxjs"; import { distinctUntilChanged, filter, map, scan, shareReplay, startWith, withLatestFrom } from "rxjs/operators"; import { TransformOnhoverSegmentPipe } from "src/atlasViewer/onhoverSegment.pipe"; import { LoggingService } from "src/logging"; +import { uiStateMouseOverSegmentsSelector } from "src/services/state/uiState/selectors"; import { getNgIdLabelIndexFromId } from "src/services/stateStore.service"; /** @@ -85,8 +86,7 @@ export class MouseHoverDirective { ) const onHoverSegments$ = this.store$.pipe( - select('uiState'), - select('mouseOverSegments'), + select(uiStateMouseOverSegmentsSelector), filter(v => !!v), withLatestFrom( this.store$.pipe( diff --git a/src/res/ext/allenMouse.json b/src/res/ext/allenMouse.json index 09fd34b91f0890c16b516fb6cb8ede68c62f83fe..9c9a5ec855bb7c5bf3a9da191f287ff7100219ce 100644 --- a/src/res/ext/allenMouse.json +++ b/src/res/ext/allenMouse.json @@ -33,6 +33,7 @@ ], "name": "root", "labelIndex": 997, + "unselectable": true, "relatedAreas": [ { "name": "Whole brain", diff --git a/src/services/state/uiState/selectors.spec.ts b/src/services/state/uiState/selectors.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..8f26ad8b2ade3ba0d0e9cc4d6873738fbc3fefc7 --- /dev/null +++ b/src/services/state/uiState/selectors.spec.ts @@ -0,0 +1,27 @@ +import { uiStateMouseOverSegmentsSelector } from './selectors' + +describe('> uiState/selectors.ts', () => { + describe('> mouseOverSegments', () => { + it('> should filter out regions explicitly designated as unselectable', () => { + const unSelSeg = { + segment: { + unselectable: true + } + } + + const selSeg0 = { + segment: 1 + } + + const selSeg1 = { + segment: { + name: 'hello world', + unselectable: false + } + } + const filteredResult = uiStateMouseOverSegmentsSelector.projector([unSelSeg, selSeg0, selSeg1]) + + expect(filteredResult).toEqual([selSeg0, selSeg1]) + }) + }) +}) diff --git a/src/services/state/uiState/selectors.ts b/src/services/state/uiState/selectors.ts index a4db9adfc902235a510a8aa378dd9e7201ff98e8..a004f0598d0e2cfc538c952f275855134bd26264 100644 --- a/src/services/state/uiState/selectors.ts +++ b/src/services/state/uiState/selectors.ts @@ -4,3 +4,19 @@ export const uiStatePreviewingDatasetFilesSelector = createSelector( state => state['uiState'], uiState => uiState['previewingDatasetFiles'] ) + +export const uiStateMouseOverSegmentsSelector = createSelector( + state => state['uiState']['mouseOverSegments'], + mouseOverSegments => { + /** + * filter out the regions explicitly declared `unselectable` + */ + return mouseOverSegments + .filter(({ segment }) => { + if (typeof segment === 'object' && segment !== null) { + if (segment.unselectable) return false + } + return true + }) + } +)