<div iav-media-query class="position-absolute w-100 h-100" #media="iavMediaQuery"> <ng-container *ngTemplateOutlet="viewerTmpl"> </ng-container> <div class="floating-ui"> <ng-template [ngIf]="(media.mediaBreakPoint$ | async) < 2"> <div class="logo-container"> <logo-container></logo-container> </div> </ng-template> <div *ngIf="(media.mediaBreakPoint$ | async) < 2" floatingMouseContextualContainerDirective iav-mouse-hover #iavMouseHoverContextualBlock="iavMouseHover"> <mat-list class="contextual-block"> <mat-list-item *ngFor="let cvtOutput of iavMouseHoverContextualBlock.currentOnHoverObs$ | async | mouseoverCvt" class="h-auto"> <span class="centered" matListItemIcon [class]="cvtOutput.icon.cls"></span> <span matListItemTitle>{{ cvtOutput.text }}</span> </mat-list-item> </mat-list> </div> </div> </div> <!-- master draw container --> <ng-template [ngIf]="view$ | async" let-view> <mat-drawer-container *ngIf="viewerLoaded" class="position-absolute w-100 h-100 mat-drawer-content-overflow-visible invisible" [hasBackdrop]="false"> <!-- master drawer --> <mat-drawer mode="side" #drawer="matDrawer" [@openClose]="view.fullSidenavExpanded ? 'open' : 'closed'" (@openClose.start)="$event.toState === 'open' && drawer.open()" (@openClose.done)="$event.toState === 'closed' && drawer.close()" [autoFocus]="false" [disableClose]="true" class="sxplr-custom-cmp darker-bg sxplr-p-0 pe-all col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2 z-index-10"> <!-- entry template --> <ng-template [ngIf]="view.viewerMode" let-mode [ngIfElse]="regularTmpl"> <ng-template [ngTemplateOutlet]="alternateModeDrawerTmpl" [ngTemplateOutletContext]="{ mode: mode }"></ng-template> </ng-template> <!-- regular mode --> <ng-template #regularTmpl> <ng-template [ngTemplateOutlet]="regularModeDrawerTmpl"> </ng-template> </ng-template> </mat-drawer> <!-- master content --> <mat-drawer-content class="visible sxplr-pe-none position-relative"> <iav-layout-fourcorners> <!-- top left --> <div iavLayoutFourCornersTopLeft class="ws-no-wrap align-items-start d-inline-flex"> <!-- special mode --> <ng-template [ngIf]="view.viewerMode" let-mode [ngIfElse]="defaultTopLeftTmpl"> <ng-template [ngTemplateOutlet]="specialModeTopLeftTmpl" [ngTemplateOutletContext]="{ mode: mode }"> </ng-template> </ng-template> <!-- default mode top left tmpl --> <ng-template #defaultTopLeftTmpl> <ng-template [ngTemplateOutlet]="defaultMainContentTopLeft" [ngTemplateOutletContext]="{ isOpen: drawer.opened, drawer: drawer, view: view }"> </ng-template> </ng-template> </div> <!-- top right --> <div iavLayoutFourCornersTopRight class="ws-no-wrap"> <!-- exit special mode --> <ng-template [ngIf]="view.viewerMode" let-mode [ngIfElse]="defaultTopRightTmpl"> <ng-template [ngTemplateOutlet]="specialTopRightTmpl" [ngTemplateOutletContext]="{ mode: mode }"> </ng-template> </ng-template> <!-- default mode top right tmpl --> <ng-template #defaultTopRightTmpl> <ng-template [ngTemplateOutlet]="minDefaultMainContentTopRight"> </ng-template> </ng-template> </div> <!-- bottom left --> <div iavLayoutFourCornersBottomLeft class="ws-no-wrap d-inline-flex w-100vw sxplr-pe-none align-items-center mb-4"> <!-- special bottom left --> <ng-template [ngIf]="view.viewerMode" let-mode [ngIfElse]="localBottomLeftTmpl"></ng-template> <!-- default mode bottom left tmpl --> <ng-template #localBottomLeftTmpl> <!-- not the most elegant, but it's a hard problem to solve --> <!-- on the one hand, showFullSidenavSwitch can be of two states --> <!-- and drawer.opened can be of two states --> <ng-template [ngTemplateOutlet]="bottomLeftTmpl"> </ng-template> </ng-template> </div> <!-- buttom right --> <div iavLayoutFourCornersBottomRight> <div class="leap-control-wrapper"> <div leap-control-view-ref></div> </div> </div> </iav-layout-fourcorners> </mat-drawer-content> </mat-drawer-container> </ng-template> <!-- alternate mode drawer tmpl --> <ng-template #alternateModeDrawerTmpl let-mode="mode"> <ng-container [ngSwitch]="mode"> <annotation-list *ngSwitchCase="ARIA_LABELS.VIEWER_MODE_ANNOTATING"> </annotation-list> <key-frame-controller *ngSwitchCase="ARIA_LABELS.VIEWER_MODE_KEYFRAME"> </key-frame-controller> <span *ngSwitchDefault>View mode {{ mode }} does not have side nav registered.</span> </ng-container> </ng-template> <!-- regular mode drawer tmpl --> <ng-template #regularModeDrawerTmpl> <!-- selectedFeature || selectedRegion --> <ng-template [ngIf]="view$ | async" let-view> <!-- if selected feature is not null, show selected feature --> <ng-template [ngIf]="view.selectedFeature"> <ng-template [ngTemplateOutlet]="selectedFeatureTmpl" [ngTemplateOutletContext]="{ feature: view.selectedFeature }"> </ng-template> </ng-template> <!-- if selected point is not null, show selected point --> <ng-template [ngIf]="view.selectedPoint"> <ng-template [ngTemplateOutlet]="selectedPointTmpl" [ngTemplateOutletContext]="{ view: view }"> </ng-template> </ng-template> <!-- if selected feature and selected point are both null, show default (selected region) --> <!-- ngIf and ngtemplateoutlet is required when ngIf changes too quickly, it seems --> <ng-template [ngIf]="!view.selectedFeature && !view.selectedPoint"> <ng-template [ngTemplateOutlet]="sidenavRegionTmpl" [ngTemplateOutletContext]="{ view: view }"> </ng-template> </ng-template> </ng-template> </ng-template> <!-- minimal default drawer content --> <ng-template #minSearchTray> <ng-template [ngIf]="view$ | async" let-view> <div class="mt-2 d-inline-block vw-col-10 vw-col-sm-10 vw-col-md-5 vw-col-lg-4 vw-col-xl-3 vw-col-xxl-2 z-index-1" [ngClass]="{ 'vw-col-10-nm vw-col-sm-10-nm vw-col-md-5-nm vw-col-lg-4-nm vw-col-xl-3-nm vw-col-xxl-2-nm': !view.halfSidenavExpanded, 'transition-margin-left': !view.fullSidenavExpanded }"> <!-- collapsed side bar view --> <div class="h-0 w-100 region-text-search-autocomplete-position"> <ng-container *ngTemplateOutlet="autocompleteTmpl; context: { showTour: true }"> </ng-container> <!-- if no selected regions, show spatial search --> <div *ngIf="(view.selectedRegions || []).length === 0" class="sxplr-mt-1 w-100"> <ng-template [ngTemplateOutlet]="spatialFeatureListTmpl" [ngTemplateOutletContext]="{ view: view }"> </ng-template> </div> </div> <!-- such a gross implementation --> <!-- TODO fix this --> <div class="min-tray-explr-btn" sxplr-sapiviews-core-region [sxplr-sapiviews-core-region-atlas]="selectedAtlas$ | async" [sxplr-sapiviews-core-region-template]="view.selectedTemplate" [sxplr-sapiviews-core-region-parcellation]="view.selectedParcellation" [sxplr-sapiviews-core-region-region]="view.selectedRegions.length === 1 ? view.selectedRegions[0] : null" [sxplr-sapiviews-core-region-detail-flag]="true" #sapiRegion="sapiViewsCoreRegion"> <!-- TODO use sapiViews/core/region/base and fix the rest --> <button mat-raised-button *ngIf="!(view$ | async | getProperty : 'onlyShowMiniTray')" [attr.aria-label]="ARIA_LABELS.EXPAND" (click)="controlFullNav(!view.fullSidenavExpanded)" class="sxplr-mt-9 sxplr-pe-all w-100" [ngClass]="{ 'darktheme': sapiRegion.regionDarkmode, 'lighttheme': !sapiRegion.regionDarkmode }" [style.backgroundColor]="sapiRegion.regionRgbString"> <span class="text sxplr-custom-cmp"> Explore </span> </button> </div> </div> <!-- tab to minimize mini tray --> <div [ngClass]="view.halfSidenavExpanded ? '' : 'd-none'"> <sxplr-tab sxplr-tab-icon="fas fa-chevron-left" (sxplr-tab-click)="controlHalfNav(!view.halfSidenavExpanded)"> </sxplr-tab> </div> <div [ngClass]="view.halfSidenavExpanded ? 'd-none' : ''"> <ng-template [ngIf]="voiFeatureEntryCmp && (voiFeatureEntryCmp.totals$ | async)" [ngIfElse]="noBadgeTmpl" let-totals> <sxplr-tab sxplr-tab-icon="fas fa-search" sxplr-tab-color="primary" (sxplr-tab-click)="controlHalfNav(!view.halfSidenavExpanded)" [sxplr-tab-badge]="totals"> </sxplr-tab> </ng-template> <ng-template #noBadgeTmpl> <sxplr-tab sxplr-tab-icon="fas fa-search" sxplr-tab-color="primary" (sxplr-tab-click)="controlHalfNav(!view.halfSidenavExpanded)"> </sxplr-tab> </ng-template> </div> </ng-template> </ng-template> <!-- top left --> <!-- default top left --> <ng-template #defaultMainContentTopLeft let-drawer="drawer" let-view="view"> <!-- min search tray --> <ng-template [ngIf]="!(view.fullSidenavExpanded)"> <ng-template [ngTemplateOutlet]="minSearchTray"> </ng-template> </ng-template> <!-- pullable tab top left corner --> <ng-template [ngIf]="view.fullSidenavExpanded"> <sxplr-tab (sxplr-tab-click)="fullyClose()" sxplr-tab-icon="fas fa-brain" quick-tour [quick-tour-description]="quickTourRegionSearch.description" [quick-tour-order]="quickTourRegionSearch.order"> </sxplr-tab> </ng-template> <!-- status panel for (for nehuba viewer) --> <iav-cmp-viewer-nehuba-status *ngIf="(useViewer$ | async) === 'nehuba'" class="pe-all sxplr-mt-1 muted-7 d-inline-block v-align-top"> </iav-cmp-viewer-nehuba-status> <button mat-icon-button sxplr-share-view *ngIf="(useViewer$ | async) === 'threeSurfer'" class="pe-all mt-1 muted-7 d-inline-block v-align-top"> <i class="fas fa-share-square"></i> </button> </ng-template> <!-- special mode top left --> <ng-template #specialModeTopLeftTmpl let-mode="mode"> <ng-template [ngIf]="view$ | async" let-view> <div class="special-mode-topleft-wrapper"> <ng-container [ngSwitch]="mode"> <!-- annotating top left --> <ng-template [ngSwitchCase]="ARIA_LABELS.VIEWER_MODE_ANNOTATING"> <sxplr-tab sxplr-tab-icon="fas fa-list" sxplr-tab-color="primary" (sxplr-tab-click)="controlFullNav(!view.fullSidenavExpanded)" [sxplr-tab-badge]="toolPanel?.annBadges$ | async"> </sxplr-tab> <annotating-tools-panel class="z-index-10 leave-me-alone" #toolPanel="annoToolsPanel"> </annotating-tools-panel> </ng-template> <ng-template [ngSwitchCase]="ARIA_LABELS.VIEWER_MODE_KEYFRAME"> <sxplr-tab sxplr-tab-icon="fas fa-play" sxplr-tab-color="primary" (sxplr-tab-click)="controlFullNav(!view.fullSidenavExpanded)"> </sxplr-tab> </ng-template> </ng-container> </div> </ng-template> </ng-template> <!-- top right --> <!-- default top right --> <ng-template #minDefaultMainContentTopRight> <!-- signin banner at top right corner --> <top-menu-cmp class="mt-3 mr-2 d-inline-block" [ismobile]="(media.mediaBreakPoint$ | async) > 3" [viewerLoaded]="viewerLoaded"> </top-menu-cmp> </ng-template> <!-- special mode top right --> <ng-template #specialTopRightTmpl let-mode="mode"> <mat-card class="mat-card-sm pe-all m-4"> <mat-card-header> <mat-card-subtitle> <span> {{ mode }} </span> <button mat-icon-button color="warn" (click)="exitSpecialViewMode()"> <i class="fas fa-times"></i> </button> </mat-card-subtitle> </mat-card-header> <mat-card-content> </mat-card-content> </mat-card> </ng-template> <!-- bottom left --> <ng-template #bottomLeftTmpl> <ng-template [ngIf]="view$ | async" let-view> <!-- scroll container --> <div class="sxplr-d-inline-flex sxplr-flex-wrap-nowrap sxplr-mxw-100vw sxplr-pe-all sxplr-of-x-auto sxplr-of-y-hidden sxplr-align-items-stretch"> <sxplr-bottom-menu (onRegionClick)="controlHalfNav(true); controlFullNav(true)"></sxplr-bottom-menu> </div> </ng-template> </ng-template> <!-- viewer tmpl --> <ng-template #viewerTmpl> <div class="position-absolute w-100 h-100 z-index-1" ctx-menu-host [ctx-menu-host-tmpl]="viewerCtxMenuTmpl"> <ng-container [ngSwitch]="useViewer$ | async"> <!-- nehuba viewer --> <iav-cmp-viewer-nehuba-glue class="d-block w-100 h-100 position-absolute left-0 tosxplr-p-0" *ngSwitchCase="'nehuba'" (viewerEvent)="handleViewerEvent($event)" #iavCmpViewerNehubaGlue="iavCmpViewerNehubaGlue"> </iav-cmp-viewer-nehuba-glue> <!-- three surfer (free surfer viewer) --> <tmp-threesurfer-lifecycle class="d-block w-100 h-100 position-absolute left-0 tosxplr-p-0" *ngSwitchCase="'threeSurfer'" (viewerEvent)="handleViewerEvent($event)"> </tmp-threesurfer-lifecycle> <!-- if not supported, show not supported message --> <div *ngSwitchCase="'notsupported'">Template not supported by any of the viewers</div> <!-- by default, show splash screen --> <div class="sxplr-h-100" *ngSwitchDefault> <ng-template [ngIf]="(selectedAtlas$ | async)" [ngIfElse]="splashScreenTmpl"> <div class="center-a-div"> <div class="loading-atlas-text-container"> <spinner-cmp class="fs-200"></spinner-cmp> <span> Loading {{ (selectedAtlas$ | async).name }} </span> </div> </div> </ng-template> <ng-template #splashScreenTmpl> <ui-splashscreen class="position-absolute left-0 tosxplr-p-0"> </ui-splashscreen> </ng-template> </div> </ng-container> </div> </ng-template> <!-- auto complete search box --> <ng-template #autocompleteTmpl let-showTour="showTour"> <div *ngIf="view$ | async; let view" class="pe-all auto-complete-container"> <sxplr-sapiviews-core-rich-regionlistsearch class="mat-elevation-z4" [sxplr-sapiviews-core-rich-regionlistsearch-regions]="view.allAvailableRegions" [sxplr-sapiviews-core-rich-regionlistsearch-current-search]="view.selectedRegions.length === 1 ? view.selectedRegions[0].name : null" (sxplr-sapiviews-core-rich-regionlistsearch-region-select)="view.leafRegions.includes($event) ? selectRoi($event) : showHierarchyBtn.onClick({ 'searchTerm': $event.name })" (sxplr-sapiviews-core-rich-regionlistsearch-region-toggle)="view.leafRegions.includes($event) ? toggleRoi($event) : showHierarchyBtn.onClick({ 'searchTerm': $event.name })" (sxplr-sapiviews-core-rich-regionlistsearch-region-select-extra)="showHierarchyBtn.onClick({ 'searchTerm': $event })" #regionListSearch="sapiRegionListSearch"> <ng-template regionTemplate let-region> <div class="region-list-search-row"> <span> <i [ngClass]="(view.selectedRegions | includes : region: nameEql) ? 'fa-circle' : 'fa-none'" class="fas"></i> </span> <sxplr-sapiviews-core-region-region-list-item [sxplr-sapiviews-core-region-region]="region" [ngClass]="{ 'text-muted': !view.labelMappedRegionNames.includes(region.name) }"> <span prefix class="sxplr-m-2"> <i *ngIf="view.leafRegions.includes(region)" class="fas fa-brain"></i> <i *ngIf="view.branchRegions.includes(region)" class="fas fa-code-branch"></i> </span> </sxplr-sapiviews-core-region-region-list-item> </div> </ng-template> <button mat-icon-button search-input-suffix *ngIf="view.selectedRegions.length > 0" (click)="clearRoi(); regionListSearch.dismissAutoComplete()"> <i class="fas fa-times"></i> </button> <button mat-icon-button color="primary" search-input-prefix iav-stop="click" [sxplr-dialog]="regionHierarchyTmpl" sxplr-dialog-size="xl" #showHierarchyBtn="sxplrDialog"> <i class="fas fa-sitemap"></i> </button> <!-- region-hierarchy-tmpl --> <ng-template #regionHierarchyTmpl let-data> <ng-template [ngIf]="view$ | async" let-view> <div class="sxplr-d-flex sxplr-flex-column sxplr-h-100"> <div class="sxplr-m-2"> <sxplr-wrapper-atp-selector [sxplr-wrapper-atp-selector-minimized]="false" > </sxplr-wrapper-atp-selector> </div> <sxplr-sapiviews-core-rich-regionshierarchy class="sxplr-w-100 sxplr-flex-var" [sxplr-sapiviews-core-rich-regionshierarchy-searchstring]="data?.searchTerm || (regionListSearch.searchTermString$ | async)" [sxplr-sapiviews-core-rich-regionshierarchy-regions]="view.allAvailableRegions" [sxplr-sapiviews-core-rich-regionshierarchy-label-mapped-region-names]="view.labelMappedRegionNames" [sxplr-sapiviews-core-rich-regionshierarchy-accent-regions]="view.selectedRegions" (sxplr-sapiviews-core-rich-regionshierarchy-region-select)="selectRoi($event); showHierarchyBtn.close()" (sxplr-sapiviews-core-rich-regionshierarchy-region-toggle)="toggleRoi($event)" > </sxplr-sapiviews-core-rich-regionshierarchy> <mat-dialog-actions align="center" class="sxplr-flex-static"> <button mat-button mat-dialog-close>Close</button> </mat-dialog-actions> </div> </ng-template> </ng-template> </sxplr-sapiviews-core-rich-regionlistsearch> <div class="w-100 h-100 position-absolute sxplr-pe-none" *ngIf="showTour"> </div> </div> </ng-template> <!-- region sidenav tmpl --> <ng-template #sidenavRegionTmpl let-view="view"> <!-- region search autocomplete --> <!-- [@openCloseAnchor]="sideNavFullLeftSwitch.switchState ? 'open' : 'closed'" --> <div class="h-0 w-100 region-text-search-autocomplete-position"> <ng-container *ngTemplateOutlet="autocompleteTmpl"> </ng-container> </div> <div class="flex-shrink-1 flex-grow-1 d-flex flex-column sxplr-h-100" [ngClass]="{'region-populated': (view.selectedRegions || []).length > 0 }"> <!-- region detail --> <!-- single-region-wrapper --> <ng-template [ngIf]="view.selectedRegions.length === 1" [ngIfElse]="multiRegionWrapperTmpl"> <!-- a series of bugs result in requiring this hacky --> <!-- see https://github.com/HumanBrainProject/interactive-viewer/issues/698 --> <ng-template [ngIf]="regionDirective.fetchInProgress$ | async"> <spinner-cmp class="sxplr-mt-10 fs-200"></spinner-cmp> </ng-template> <sxplr-sapiviews-core-region-region-rich [sxplr-sapiviews-core-region-atlas]="selectedAtlas$ | async" [sxplr-sapiviews-core-region-template]="view.selectedTemplate" [sxplr-sapiviews-core-region-parcellation]="view.selectedParcellation" [sxplr-sapiviews-core-region-region]="view.selectedRegions[0]" (sxplr-sapiviews-core-region-region-rich-feature-clicked)="showDataset($event)" (sxplr-sapiviews-core-region-region-rich-related-region-clicked)="selectATPR($event)" (sxplr-sapiviews-core-region-navigate-to)="navigateTo($event)" #regionDirective="sapiViewsCoreRegionRich" > <div class="sapi-container" header></div> </sxplr-sapiviews-core-region-region-rich> </ng-template> <!-- multi region wrapper --> <ng-template #multiRegionWrapperTmpl> <ng-container *ngTemplateOutlet="multiRegionTmpl; context: { regions: view.selectedRegions }"> </ng-container> <!-- This is a wrapper for multiregion consisting of {{ selectedRegions.length }} regions --> </ng-template> <!-- place holder if length === 0 --> <ng-container *ngIf="view.selectedRegions.length === 0"> no region selected </ng-container> <div class="spacer"> </div> </div> <!-- collapse btn --> <div class="h-0 w-100 collapse-position d-flex flex-column justify-content-end align-items-center"> <button mat-raised-button class="mat-elevation-z8" [attr.aria-label]="ARIA_LABELS.COLLAPSE" (click)="controlFullNav(false)"> <i class="fas fa-chevron-up"></i> <span> collapse </span> </button> </div> </ng-template> <!-- expansion tmpl --> <ng-template #ngMatAccordionTmpl let-title="title" let-desc="desc" let-iconClass="iconClass" let-iconTooltip="iconTooltip" let-iavNgIf="iavNgIf" let-content="content"> </ng-template> <!-- multi region tmpl --> <ng-template #multiRegionTmpl let-regions="regions"> <ng-template [ngIf]="regions.length > 0" [ngIfElse]="regionPlaceholderTmpl"> <sxplr-side-panel> <div class="sapi-container" header></div> <div title> Multiple regions selected </div> <!-- other regions detail accordion --> <mat-accordion class="bs-border-box ml-15px-n mr-15px-n mt-2"> <!-- Multi regions include --> <mat-expansion-panel [attr.data-opened]="expansionPanel.expanded" [attr.data-mat-expansion-title]="'Brain regions'" hideToggle #expansionPanel="matExpansionPanel"> <mat-expansion-panel-header> <!-- title --> <mat-panel-title> Selected regions </mat-panel-title> <!-- desc + icon --> <mat-panel-description class="d-flex align-items-center justify-content-end"> <span class="mr-3">{{ regions.length }}</span> <span class="accordion-icon d-inline-flex justify-content-center"> <i class="fas fa-brain"></i> </span> </mat-panel-description> </mat-expansion-panel-header> <!-- content --> <ng-template matExpansionPanelContent> <mat-chip-set class="wrapped-chips"> <mat-chip *ngFor="let region of regions"> <span> {{ region.name }} </span> <button mat-icon-button (click)="toggleRoi(region)" iav-stop="mousedown click"> <i class="fas fa-times"></i> </button> </mat-chip> </mat-chip-set> </ng-template> </mat-expansion-panel> </mat-accordion> </sxplr-side-panel> </ng-template> </ng-template> <!-- region tmpl placeholder --> <ng-template #regionPlaceholderTmpl> <div class="placeholder-region-detail bs-border-box ml-15px-n mr-15px-n mat-elevation-z4"> <span class="text-muted"> Select a region by clicking on the viewer or search from above </span> </div> </ng-template> <!-- context menu template --> <ng-template #viewerCtxMenuTmpl let-tmplRefs="tmplRefs"> <mat-card [iav-key-listener]="[{type: 'keydown', target: 'document', capture: true, key: 'Esc'}]" (iav-key-event)="disposeCtxMenu()" (iav-outsideClick)="disposeCtxMenu()"> <mat-card-content class="context-menu-container"> <div *ngFor="let tmplRef of tmplRefs" [ngStyle]="{ order: tmplRef.order || 0 }"> <ng-template [ngIf]="tmplRef.tmpl" [ngIfElse]="fallbackTmpl" [ngTemplateOutlet]="tmplRef.tmpl" [ngTemplateOutletContext]="{ $implicit: tmplRef.data }"> </ng-template> <ng-template #fallbackTmpl> {{ tmplRef.data.message || 'test' }} </ng-template> </div> </mat-card-content> </mat-card> </ng-template> <ng-template #lastViewedPointTmpl let-data> <mat-divider></mat-divider> <mat-list class="sxplr-p-0"> <mat-list-item> Last selected spatial object </mat-list-item> </mat-list> <mat-action-list class="sxplr-p-0"> <ng-template [ngIf]="data?.point"> <button mat-list-item (click)="selectPoint(data, data.template)"> <span matListItemIcon> <i class="fas fa-history"></i> </span> <!-- <span matListItemLine class="text-muted">Last selected spatial object</span> --> <span matListItemLine>{{ data.point | nmToMm | numbers | addUnitAndJoin : '' }} (mm)</span> <span matListItemLine class="text-muted">Point</span> <span matListItemLine class="text-muted">{{ data.template.name }}</span> </button> </ng-template> <ng-template [ngIf]="data?.face && data?.vertices"> <button mat-list-item (click)="selectPoint(data, data.template)"> <span matListItemIcon> <i class="fas fa-history"></i> </span> <span matListItemLine> Face Index: {{ data.face }}, Vertices Index: {{ data.vertices | addUnitAndJoin : '' }} </span> <span matListItemLine class="text-muted"> Mesh Face </span> <span matListItemLine class="text-muted">{{ data.template.name }}</span> </button> </ng-template> </mat-action-list> </ng-template> <!-- viewer status ctx menu --> <ng-template #viewerStatusCtxMenu let-data> <ng-template [ngIf]="data.context" let-context> <!-- ref space & position --> <ng-container [ngSwitch]="context.viewerType"> <!-- volumetric i.e. nehuba --> <ng-container *ngSwitchCase="'nehuba'"> <mat-action-list class="sxplr-p-0"> <button mat-list-item (click)="selectPoint({ point: context.payload.mouse.real }, data.metadata.template)"> <span matListItemIcon> <i class="fas fa-map"></i> </span> <span matListItemLine> {{ context.payload.mouse.real | nmToMm | numbers | addUnitAndJoin : '' }} (mm) </span> <span matListItemLine class="text-muted"> Point </span> <span matListItemLine class="text-muted"> {{ data.metadata.template.name }} </span> </button> </mat-action-list> </ng-container> <ng-container *ngSwitchCase="'threeSurfer'"> <ng-template [ngIf]="context.payload?.faceIndex" let-faceIndex> <ng-template [ngIf]="context.payload?.vertexIndices" let-vertexIndices> <mat-action-list class="sxplr-p-0"> <button mat-list-item (click)="selectPoint({ face: faceIndex, vertices: vertexIndices }, data.metadata.template)" disabled> <span matListItemIcon> <i class="fas fa-map"></i> </span> <span matListItemLine> Face Index: {{ faceIndex }}, Vertices Index: {{ vertexIndices | addUnitAndJoin : '' }} </span> <span matListItemLine class="text-muted"> Mesh Face (Not selectable for now) </span> <span matListItemLine class="text-muted"> {{ data.metadata.template.name }} </span> </button> </mat-action-list> </ng-template> </ng-template> </ng-container> <ng-container *ngSwitchDefault> DEFAULT </ng-container> </ng-container> </ng-template> </ng-template> <!-- viewer state hover ctx menu --> <ng-template #viewerStatusRegionCtxMenu let-data> <!-- hovered ROIs --> <ng-template ngFor [ngForOf]="data.metadata.hoveredRegions" let-region> <mat-action-list class="sxplr-p-0"> <button mat-list-item (click)="$event.ctrlKey ? toggleRoi(region) : selectRoi(region)"> <span matListItemIcon> <i class="fas fa-brain"></i> </span> <span matListItemLine> {{ region.name }} </span> <span matListItemLine class="text-muted"> Brain region </span> </button> </mat-action-list> </ng-template> </ng-template> <!-- general feature tmpl --> <ng-template let-feature="feature" #selectedFeatureTmpl> <!-- TODO differentiate between features (spatial, regional etc) --> <sxplr-feature-view class="sxplr-z-2 mat-elevation-z2" [feature]="feature"> <div header> <!-- back btn --> <button mat-button (click)="clearSelectedFeature()" [attr.aria-label]="ARIA_LABELS.CLOSE" class="sxplr-mb-2" > <i class="fas fa-chevron-left"></i> <span class="ml-1"> Back </span> </button> </div> </sxplr-feature-view> </ng-template> <!-- general point tmpl --> <ng-template let-view="view" #selectedPointTmpl> <sxplr-side-panel> <div class="sxplr-custom-cmp lighttheme" header> <!-- back btn --> <button mat-button (click)="clearPoint()" [attr.aria-label]="ARIA_LABELS.CLOSE" class="sxplr-mb-2" > <i class="fas fa-chevron-left"></i> <span class="ml-1"> Back </span> </button> </div> <div title> {{ view.spatialObjectTitle }} </div> <div subtitle> {{ view.spatialObjectSubtitle }} </div> </sxplr-side-panel> <sxplr-point-assignment [point]="view.selectedPoint" [template]="view.selectedTemplate" [parcellation]="view.selectedParcellation" (clickOnRegion)="$event.event.ctrlKey ? toggleRoi($event.target) : selectRoi($event.target)"> </sxplr-point-assignment> </ng-template> <!-- spatial search tmpls --> <ng-template #spatialFeatureListTmpl let-view="view"> <mat-card class="sxplr-pe-all overflow-hidden" [ngClass]="{ 'sxplr-d-none': !(voiSwitch.switchState$ | async) || (voiFeatureEntryCmp.totals$ | async) === 0 }"> <mat-card-header> <mat-card-title> Anchored to current view </mat-card-title> <mat-card-subtitle> <div *ngIf="view.selectedTemplate"> {{ view.selectedTemplate.name }} </div> <ng-template [ngIf]="bbox.bbox$ | async | getProperty : 'bbox'" let-bbox> <div> from {{ bbox[0] | numbers | addUnitAndJoin : '' }} </div> <div> to {{ bbox[1] | numbers | addUnitAndJoin : '' }} </div> </ng-template> </mat-card-subtitle> </mat-card-header> </mat-card> <sxplr-feature-entry [ngClass]="(voiSwitch.switchState$ | async) ? 'sxplr-d-block' : 'sxplr-d-none'" class="sxplr-pe-all mat-elevation-z8" [template]="view.selectedTemplate" [bbox]="bbox.bbox$ | async | getProperty : 'bbox'" [attr.data-feature-length]="((voiFeatureEntryCmp.features$ | async) || []).length" #voiFeatureEntryCmp="featureEntryCmp"> </sxplr-feature-entry> <mat-card [ngClass]="{ 'sxplr-d-none': (voiFeatureEntryCmp.totals$ | async) > 0 }"> <mat-card-content> No spatial features found. </mat-card-content> </mat-card> <button mat-raised-button [ngClass]="{ 'sxplr-d-none': (voiFeatureEntryCmp.totals$ | async) === 0 }" class="sxplr-pe-all sxplr-w-100" iav-switch [iav-switch-state]="false" #voiSwitch="iavSwitch" (iav-switch-event)="$event && pullAllVoi()" (click)="voiSwitch.toggle()"> <ng-template [ngIf]="voiSwitch.switchState$ | async" [ngIfElse]="chevronCollapseTmpl"> <i class="fas fa-chevron-up"></i> <span> Collapse </span> </ng-template> <ng-template #chevronCollapseTmpl> <i class="fas fa-chevron-down"></i> <span> Explore {{ voiFeatureEntryCmp.totals$ | async }} spatial features </span> </ng-template> </button> <div> <mat-progress-bar mode="indeterminate" *ngIf="(voiFeatureEntryCmp.busy$ | async)"> </mat-progress-bar> </div> <!-- TODO voiBbox directive is used to draw outlines for VOI this has been temporarily disabled, since datasource is paginated and how bounding boxes are drawn needs to be reconsidered --> <div *ngIf="voiSwitch.switchState$| async" voiBbox [features]="voiFeatureEntryCmp.features$ | async"> </div> </ng-template> <div sxplr-sapiviews-core-space-boundingbox (sxplr-sapiviews-core-space-boundingbox-changed)="pullAllVoi()" [sxplr-sapiviews-core-space-boundingbox-atlas]="selectedAtlas$ | async" [sxplr-sapiviews-core-space-boundingbox-space]="templateSelected$ | async" [sxplr-sapiviews-core-space-boundingbox-spec]="viewerCtx$ | async | nehubaVCtxToBbox" #bbox="sxplrSapiViewsCoreSpaceBoundingBox"> </div>