diff --git a/src/ui/nehubaContainer/nehubaContainer.component.ts b/src/ui/nehubaContainer/nehubaContainer.component.ts index 2e99ceb8909fef4fea11ee6d7a401ca7a43a0b22..a6e6e99daf19bd2f9eadb72efc7479788023913c 100644 --- a/src/ui/nehubaContainer/nehubaContainer.component.ts +++ b/src/ui/nehubaContainer/nehubaContainer.component.ts @@ -193,20 +193,20 @@ export class NehubaContainer implements OnInit, OnDestroy{ // TODO hack, even though octant is hidden, it seems with VTK, one can highlight this.onHoverSegmentName$ = combineLatest( - this.store.pipe( - select('uiState'), - filter(state=>isDefined(state)), - map(state=>state.mouseOverSegment ? - state.mouseOverSegment.constructor === Number ? - state.mouseOverSegment.toString() : - state.mouseOverSegment.name : - '' ), - distinctUntilChanged() - ), - this.onHoverLandmark$ - ).pipe( - map(results => results[1] === null ? results[0] : '') - ) + this.store.pipe( + select('uiState'), + filter(state=>isDefined(state)), + map(state=>state.mouseOverSegment ? + state.mouseOverSegment.constructor === Number ? + state.mouseOverSegment.toString() : + state.mouseOverSegment.name : + '' ), + distinctUntilChanged() + ), + this.onHoverLandmark$ + ).pipe( + map(results => results[1] === null ? results[0] : '') + ) /* each time a new viewer is initialised, take the first event to get the translation function */ this.newViewer$.pipe( diff --git a/src/ui/nehubaContainer/nehubaContainer.template.html b/src/ui/nehubaContainer/nehubaContainer.template.html index 912caf023dff43223b323cb34c0be195d697c9da..9174725eefa76c31b6c733e3fbd37bbd32d7837e 100644 --- a/src/ui/nehubaContainer/nehubaContainer.template.html +++ b/src/ui/nehubaContainer/nehubaContainer.template.html @@ -7,17 +7,12 @@ <div landmarkMasterContainer> <div> - <layout-floating-container - pos00 - landmarkContainer> - <nehuba-2dlandmark-unit - *ngFor="let spatialData of (selectedPtLandmarks$ | async)" - (mouseenter)="handleMouseEnterLandmark(spatialData)" - (mouseleave)="handleMouseLeaveLandmark(spatialData)" + <layout-floating-container pos00 landmarkContainer> + <nehuba-2dlandmark-unit *ngFor="let spatialData of (selectedPtLandmarks$ | async)" + (mouseenter)="handleMouseEnterLandmark(spatialData)" (mouseleave)="handleMouseLeaveLandmark(spatialData)" [highlight]="spatialData.highlight ? spatialData.highlight : false" [fasClass]="spatialData.type === 'userLandmark' ? 'fa-chevron-down' : 'fa-map-marker'" - [positionX]="getPositionX(0,spatialData)" - [positionY]="getPositionY(0,spatialData)" + [positionX]="getPositionX(0,spatialData)" [positionY]="getPositionY(0,spatialData)" [positionZ]="getPositionZ(0,spatialData)"> </nehuba-2dlandmark-unit> @@ -29,20 +24,15 @@ </layout-floating-container> </div> <div> - <layout-floating-container - pos01 - landmarkContainer> - <nehuba-2dlandmark-unit - *ngFor="let spatialData of (selectedPtLandmarks$ | async)" - (mouseenter)="handleMouseEnterLandmark(spatialData)" - (mouseleave)="handleMouseLeaveLandmark(spatialData)" + <layout-floating-container pos01 landmarkContainer> + <nehuba-2dlandmark-unit *ngFor="let spatialData of (selectedPtLandmarks$ | async)" + (mouseenter)="handleMouseEnterLandmark(spatialData)" (mouseleave)="handleMouseLeaveLandmark(spatialData)" [highlight]="spatialData.highlight ? spatialData.highlight : false" [fasClass]="spatialData.type === 'userLandmark' ? 'fa-chevron-down' : 'fa-map-marker'" - [positionX]="getPositionX(1,spatialData)" - [positionY]="getPositionY(1,spatialData)" + [positionX]="getPositionX(1,spatialData)" [positionY]="getPositionY(1,spatialData)" [positionZ]="getPositionZ(1,spatialData)"> </nehuba-2dlandmark-unit> - + <div *ngIf="sliceViewLoading1$ | async" class="loadingIndicator"> <div class="spinnerAnimationCircle"> @@ -51,20 +41,15 @@ </layout-floating-container> </div> <div> - <layout-floating-container - pos10 - landmarkContainer> - <nehuba-2dlandmark-unit - *ngFor="let spatialData of (selectedPtLandmarks$ | async)" - (mouseenter)="handleMouseEnterLandmark(spatialData)" - (mouseleave)="handleMouseLeaveLandmark(spatialData)" + <layout-floating-container pos10 landmarkContainer> + <nehuba-2dlandmark-unit *ngFor="let spatialData of (selectedPtLandmarks$ | async)" + (mouseenter)="handleMouseEnterLandmark(spatialData)" (mouseleave)="handleMouseLeaveLandmark(spatialData)" [highlight]="spatialData.highlight ? spatialData.highlight : false" [fasClass]="spatialData.type === 'userLandmark' ? 'fa-chevron-down' : 'fa-map-marker'" - [positionX]="getPositionX(2,spatialData)" - [positionY]="getPositionY(2,spatialData)" + [positionX]="getPositionX(2,spatialData)" [positionY]="getPositionY(2,spatialData)" [positionZ]="getPositionZ(2,spatialData)"> </nehuba-2dlandmark-unit> - + <div *ngIf="sliceViewLoading2$ | async" class="loadingIndicator"> <div class="spinnerAnimationCircle"> @@ -73,9 +58,7 @@ </layout-floating-container> </div> <div> - <layout-floating-container - pos11 - landmarkContainer> + <layout-floating-container pos11 landmarkContainer> <div *ngIf="perspectiveViewLoading$ | async" class="loadingIndicator"> <div class="spinnerAnimationCircle"></div> <div perspectiveLoadingText> @@ -88,20 +71,16 @@ <layout-floating-container *ngIf="viewerLoaded"> <!-- StatusCard container--> - <ui-status-card - [selectedTemplate] = "selectedTemplate" - [isMobile] = "isMobile" - [nehubaViewer] = "nehubaViewer"> + <ui-status-card [selectedTemplate]="selectedTemplate" [isMobile]="isMobile" + [onHoverSegmentName]="onHoverSegmentName$ | async" [nehubaViewer]="nehubaViewer"> </ui-status-card> </layout-floating-container> <div id="scratch-pad"> - + </div> -<mobile-overlay - *ngIf="isMobile && viewerLoaded" - [tunableProperties]="tunableMobileProperties" +<mobile-overlay *ngIf="isMobile && viewerLoaded" [tunableProperties]="tunableMobileProperties" (deltaValue)="handleMobileOverlayEvent($event)"> <div class="base" delta> <div mobileObliqueGuide class="p-2 mb-4 shadow"> @@ -111,7 +90,7 @@ <div class="base" guide> <div mobileObliqueGuide class="p-2 mb-4 shadow"> <div> - <i class="fas fa-arrows-alt-v"></i> oblique mode + <i class="fas fa-arrows-alt-v"></i> oblique mode </div> <div> <i class="fas fa-arrows-alt-h"></i> rotate slice @@ -121,4 +100,4 @@ <div mobileObliqueCtrl initiator> <i class="fas fa-globe"></i> </div> -</mobile-overlay> +</mobile-overlay> \ No newline at end of file diff --git a/src/ui/nehubaContainer/statusCard/statusCard.component.ts b/src/ui/nehubaContainer/statusCard/statusCard.component.ts index ce6bbfa5ec3a9f46cf3c33b7a40f4ec8c6fd9066..875154f70bcd60f0584cf5b168122ef1bcbb7715 100644 --- a/src/ui/nehubaContainer/statusCard/statusCard.component.ts +++ b/src/ui/nehubaContainer/statusCard/statusCard.component.ts @@ -1,5 +1,4 @@ -import { Component, OnInit, Input } from "@angular/core"; -import { AtlasViewerConstantsServices } from "src/atlasViewer/atlasViewer.constantService.service"; +import { Component, Input } from "@angular/core"; import { CHANGE_NAVIGATION, ViewerStateInterface } from "src/services/stateStore.service"; import { Store } from "@ngrx/store"; import { NehubaViewerUnit } from "../nehubaViewer/nehubaViewer.component"; @@ -9,108 +8,104 @@ import { NehubaViewerUnit } from "../nehubaViewer/nehubaViewer.component"; templateUrl : './statusCard.template.html', styleUrls : ['./statusCard.style.css'] }) -export class StatusCardComponent implements OnInit { - - - @Input() selectedTemplate: any; - @Input() isMobile: boolean; - @Input() nehubaViewer: NehubaViewerUnit; - - - constructor( - private constantService : AtlasViewerConstantsServices, - private store : Store<ViewerStateInterface>, - ) {} - - ngOnInit() { - - } - - - statusPanelRealSpace : boolean = true - - get mouseCoord():string{ - return this.nehubaViewer ? - this.statusPanelRealSpace ? - this.nehubaViewer.mousePosReal ? - Array.from(this.nehubaViewer.mousePosReal.map(n=> isNaN(n) ? 0 : n/1e6)) - .map(n=>n.toFixed(3)+'mm').join(' , ') : - '0mm , 0mm , 0mm (mousePosReal not yet defined)' : - this.nehubaViewer.mousePosVoxel ? - this.nehubaViewer.mousePosVoxel.join(' , ') : - '0 , 0 , 0 (mousePosVoxel not yet defined)' : - '0 , 0 , 0 (nehubaViewer not defined)' - } - - editingNavState : boolean = false - - textNavigateTo(string:string){ - if(string.split(/[\s|,]+/).length>=3 && string.split(/[\s|,]+/).slice(0,3).every(entry=>!isNaN(Number(entry.replace(/mm/,''))))){ - const pos = (string.split(/[\s|,]+/).slice(0,3).map((entry)=>Number(entry.replace(/mm/,''))*(this.statusPanelRealSpace ? 1000000 : 1))) - this.nehubaViewer.setNavigationState({ - position : (pos as [number,number,number]), - positionReal : this.statusPanelRealSpace - }) - }else{ - console.log('input did not parse to coordinates ',string) - } - } - - navigationValue(){ - return this.nehubaViewer ? - this.statusPanelRealSpace ? - Array.from(this.nehubaViewer.navPosReal.map(n=> isNaN(n) ? 0 : n/1e6)) - .map(n=>n.toFixed(3)+'mm').join(' , ') : - Array.from(this.nehubaViewer.navPosVoxel.map(n=> isNaN(n) ? 0 : n)).join(' , ') : - `[0,0,0] (neubaViewer is undefined)` - } - - - get showCitation(){ - return this.selectedTemplate && this.selectedTemplate.properties && this.selectedTemplate.properties.publications && this.selectedTemplate.properties.publications.constructor === Array +export class StatusCardComponent{ + + @Input() selectedTemplate: any; + @Input() isMobile: boolean; + @Input() nehubaViewer: NehubaViewerUnit; + @Input() onHoverSegmentName: String; + + constructor( + private store : Store<ViewerStateInterface>, + ) {} + + statusPanelRealSpace : boolean = true + + get mouseCoord():string{ + return this.nehubaViewer ? + this.statusPanelRealSpace ? + this.nehubaViewer.mousePosReal ? + Array.from(this.nehubaViewer.mousePosReal.map(n=> isNaN(n) ? 0 : n/1e6)) + .map(n=>n.toFixed(3)+'mm').join(' , ') : + '0mm , 0mm , 0mm (mousePosReal not yet defined)' : + this.nehubaViewer.mousePosVoxel ? + this.nehubaViewer.mousePosVoxel.join(' , ') : + '0 , 0 , 0 (mousePosVoxel not yet defined)' : + '0 , 0 , 0 (nehubaViewer not defined)' + } + + editingNavState : boolean = false + + textNavigateTo(string:string){ + if(string.split(/[\s|,]+/).length>=3 && string.split(/[\s|,]+/).slice(0,3).every(entry=>!isNaN(Number(entry.replace(/mm/,''))))){ + const pos = (string.split(/[\s|,]+/).slice(0,3).map((entry)=>Number(entry.replace(/mm/,''))*(this.statusPanelRealSpace ? 1000000 : 1))) + this.nehubaViewer.setNavigationState({ + position : (pos as [number,number,number]), + positionReal : this.statusPanelRealSpace + }) + }else{ + console.log('input did not parse to coordinates ',string) } + } + + navigationValue(){ + return this.nehubaViewer ? + this.statusPanelRealSpace ? + Array.from(this.nehubaViewer.navPosReal.map(n=> isNaN(n) ? 0 : n/1e6)) + .map(n=>n.toFixed(3)+'mm').join(' , ') : + Array.from(this.nehubaViewer.navPosVoxel.map(n=> isNaN(n) ? 0 : n)).join(' , ') : + `[0,0,0] (neubaViewer is undefined)` + } + + /** + * TODO + * maybe have a nehuba manager service + * so that reset navigation logic can stay there + * + * When that happens, we don't even need selectTemplate input + * + * the info re: nehubaViewer can stay there, too + */ + resetNavigation({rotation: rotationFlag = false, position: positionFlag = false, zoom : zoomFlag = false} : {rotation: boolean, position: boolean, zoom: boolean}){ + const initialNgState = this.selectedTemplate.nehubaConfig.dataset.initialNgState - - resetNavigation({rotation: rotationFlag = false, position: positionFlag = false, zoom : zoomFlag = false} : {rotation: boolean, position: boolean, zoom: boolean}){ - const initialNgState = this.selectedTemplate.nehubaConfig.dataset.initialNgState - - const perspectiveZoom = initialNgState ? initialNgState.perspectiveZoom : undefined - const perspectiveOrientation = initialNgState ? initialNgState.perspectiveOrientation : undefined - const zoom = (zoomFlag - && initialNgState - && initialNgState.navigation - && initialNgState.navigation.zoomFactor) - || undefined - - const position = (positionFlag - && initialNgState - && initialNgState.navigation - && initialNgState.navigation.pose - && initialNgState.navigation.pose.position.voxelCoordinates - && initialNgState.navigation.pose.position.voxelCoordinates) - || undefined - - const orientation = rotationFlag - ? [0,0,0,1] - : undefined - - this.store.dispatch({ - type : CHANGE_NAVIGATION, - navigation : Object.assign({}, - { - perspectiveZoom, - perspectiveOrientation, - zoom, - position, - orientation - },{ - positionReal : false, - animation : { - - } - }) - }) + const perspectiveZoom = initialNgState ? initialNgState.perspectiveZoom : undefined + const perspectiveOrientation = initialNgState ? initialNgState.perspectiveOrientation : undefined + const zoom = (zoomFlag + && initialNgState + && initialNgState.navigation + && initialNgState.navigation.zoomFactor) + || undefined + + const position = (positionFlag + && initialNgState + && initialNgState.navigation + && initialNgState.navigation.pose + && initialNgState.navigation.pose.position.voxelCoordinates + && initialNgState.navigation.pose.position.voxelCoordinates) + || undefined + + const orientation = rotationFlag + ? [0,0,0,1] + : undefined + + this.store.dispatch({ + type : CHANGE_NAVIGATION, + navigation : { + ...{ + perspectiveZoom, + perspectiveOrientation, + zoom, + position, + orientation + }, + ...{ + positionReal : false, + animation : {} + } } + }) + } } diff --git a/src/ui/nehubaContainer/statusCard/statusCard.template.html b/src/ui/nehubaContainer/statusCard/statusCard.template.html index 7a0c90fa5cc598347aa6b7046fd7c82f7b7d3bba..c5e3f8541750cf7cd9dad508ef3843faf9155120 100644 --- a/src/ui/nehubaContainer/statusCard/statusCard.template.html +++ b/src/ui/nehubaContainer/statusCard/statusCard.template.html @@ -1,7 +1,5 @@ <div statusCard> - <hr *ngIf="showCitation && !isMobile" /> - <div linksContainer> <span> reset: @@ -53,7 +51,7 @@ </small> <br *ngIf="!isMobile" /> <small onHoverSegment> - {{ onHoverSegmentName$ | async }} + {{ onHoverSegmentName }} </small> </div> </div> \ No newline at end of file