Newer
Older
<div iav-media-query class="position-absolute w-100 h-100" #media="iavMediaQuery">
<ng-container *ngTemplateOutlet="viewerTmpl">
</ng-container>
<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-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>
<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>
<!-- 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>
<!-- default mode top left tmpl -->
<ng-template #defaultTopLeftTmpl>
<ng-template [ngTemplateOutlet]="defaultMainContentTopLeft"
[ngTemplateOutletContext]="{
isOpen: drawer.opened,
drawer: drawer,
view: view
}">
</ng-template>
<!-- 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>
<!-- default mode top right tmpl -->
<ng-template #defaultTopRightTmpl>
<ng-template [ngTemplateOutlet]="minDefaultMainContentTopRight">
</ng-template>
<!-- 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>
<!-- buttom right -->
<div iavLayoutFourCornersBottomRight>
<div class="leap-control-wrapper">
<div leap-control-view-ref></div>
</div>
</iav-layout-fourcorners>
</mat-drawer-content>
<!-- 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 [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"
</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>
<!-- 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">
<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>
<sxplr-tab
sxplr-tab-icon="fas fa-search"
sxplr-tab-color="primary"
(sxplr-tab-click)="controlHalfNav(!view.halfSidenavExpanded)">
</sxplr-tab>
<!-- top left -->
<!-- default top left -->
<ng-template #defaultMainContentTopLeft
let-drawer="drawer"
<ng-template [ngIf]="!(view.fullSidenavExpanded)">
<ng-template [ngTemplateOutlet]="minSearchTray">
<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">
<!-- 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">
<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 #specialModeTopLeftTmpl let-mode="mode">
<ng-template [ngIf]="view$ | async" let-view>
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
<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>
<!-- 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 #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>
<!-- scroll container -->
<div class="sxplr-d-inline-flex
sxplr-flex-wrap-nowrap
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>
<!-- 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"
<!-- 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>
<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">
<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()">
sxplr-dialog-size="xl"
#showHierarchyBtn="sxplrDialog">
<!-- 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">
</ng-template>
<!-- region sidenav tmpl -->
<!-- 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>
<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
}">
<!-- 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">
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
<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 *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>
</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>
<!-- context menu template -->
<ng-template #viewerCtxMenuTmpl let-tmplRefs="tmplRefs">
[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">
<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>
</ng-template>
<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>
Face Index: {{ data.face }}, Vertices Index: {{ data.vertices | addUnitAndJoin : '' }}
</span>
<span matListItemLine class="text-muted">{{ data.template.name }}</span>
</button>
</ng-template>
</mat-action-list>
<!-- viewer status ctx menu -->
<ng-template #viewerStatusCtxMenu let-data>
<!-- 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)
</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 matListItemLine class="text-muted">
Mesh Face (Not selectable for now)
</ng-template>
</ng-container>
<ng-container *ngSwitchDefault>
DEFAULT
<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>
<!-- 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>
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
<!-- 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)">
<!-- spatial search tmpls -->
<ng-template #spatialFeatureListTmpl let-view="view">
<mat-card class="sxplr-pe-all overflow-hidden"
'sxplr-d-none': !(voiSwitch.switchState$ | async) || (voiFeatureEntryCmp.totals$ | async) === 0
<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>
[ngClass]="(voiSwitch.switchState$ | async) ? 'sxplr-d-block' : 'sxplr-d-none'"
class="sxplr-pe-all mat-elevation-z8"
[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>
<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"
<ng-template [ngIf]="voiSwitch.switchState$ | async" [ngIfElse]="chevronCollapseTmpl">
<i class="fas fa-chevron-up"></i>
<span>
Collapse
</span>
</ng-template>
<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 -->