Newer
Older
<div iav-media-query class="position-absolute w-100 h-100" #media="iavMediaQuery">
<ng-container *ngTemplateOutlet="viewerTmpl">
</ng-container>
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<div class="floating-ui">
<div *ngIf="(media.mediaBreakPoint$ | async) < 3"
class="fixed-bottom pe-none mb-2 d-flex justify-content-center">
<logo-container></logo-container>
</div>
<div *ngIf="(media.mediaBreakPoint$ | async) < 3" floatingMouseContextualContainerDirective>
<div class="h-0"
iav-mouse-hover
#iavMouseHoverContextualBlock="iavMouseHover">
</div>
<mat-list dense class="contextual-block">
<mat-list-item *ngFor="let cvtOutput of iavMouseHoverContextualBlock.currentOnHoverObs$ | async | mouseoverCvt"
class="h-auto">
<mat-icon
[fontSet]="cvtOutput.icon.fontSet"
[fontIcon]="cvtOutput.icon.fontIcon"
mat-list-icon>
</mat-icon>
<div matLine>{{ cvtOutput.text }}</div>
</mat-list-item>
<ng-template [ngIf]="voiFeatures.onhover | async" let-feat>
<mat-list-item>
<mat-icon
fontSet="fas"
fontIcon="fa-database"
mat-list-icon>
</mat-icon>
<div matLine>{{ feat?.metadata?.fullName || 'Feature' }}</div>
</mat-list-item>
</ng-template>
</mat-list>
<!-- TODO Potentially implementing plugin contextual info -->
</div>
<!-- mouse on click context menu, currently not used -->
<!-- <div class="floating-container"
[attr.aria-label]="CONTEXT_MENU_ARIA_LABEL"
fixedMouseContextualContainerDirective
#fixedContainer="iavFixedMouseCtxContainer">
</div> -->
</div>
<!-- master draw container -->
<mat-drawer-container
*ngIf="viewerLoaded"
iav-switch
[iav-switch-state]="!(onlyShowMiniTray$ | async)"
#showFullSidenavSwitch="iavSwitch"
class="position-absolute w-100 h-100 mat-drawer-content-overflow-visible invisible"
[hasBackdrop]="false">
<!-- master drawer -->
<mat-drawer
mode="side"
#drawer="matDrawer"
[opened]="!(onlyShowMiniTray$ | async)"
[@openClose]="showFullSidenavSwitch && (showFullSidenavSwitch.switchState$ | async) ? '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">
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<!-- entry template -->
<ng-template [ngIf]="viewerMode$ | async" let-mode [ngIfElse]="regularTmpl">
<ng-template [ngTemplateOutlet]="alternateModeDrawerTmpl"
[ngTemplateOutletContext]="{
mode: mode
}"></ng-template>
</ng-template>
<!-- regular mode -->
<ng-template #regularTmpl>
<ng-template
[ngTemplateOutlet]="regularModeDrawerTmpl"
[ngTemplateOutletContext]="{
drawer: drawer,
showFullSidenavSwitch: showFullSidenavSwitch
}">
</ng-template>
</ng-template>
</mat-drawer>
<!-- master content -->
<mat-drawer-content class="visible pe-none position-relative">
<iav-layout-fourcorners>
<!-- top left -->
<div iavLayoutFourCornersTopLeft class="ws-no-wrap">
<!-- special mode -->
<ng-template [ngIf]="viewerMode$ | async" let-mode [ngIfElse]="defaultTopLeftTmpl">
<ng-template [ngTemplateOutlet]="specialModeTopLeftTmpl"
[ngTemplateOutletContext]="{
mode: mode,
toggleMatDrawer: drawer.toggle.bind(drawer)
}">
</ng-template>
<!-- default mode top left tmpl -->
<ng-template #defaultTopLeftTmpl>
<ng-template [ngTemplateOutlet]="defaultMainContentTopLeft"
[ngTemplateOutletContext]="{
isOpen: drawer.opened,
drawer: drawer,
showFullSidenavSwitch: showFullSidenavSwitch
}">
</ng-template>
</ng-template>
</div>
<!-- top right -->
<div iavLayoutFourCornersTopRight class="ws-no-wrap">
<!-- exit special mode -->
<ng-template [ngIf]="viewerMode$ | async" 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 pe-none align-items-center mb-4">
<!-- special bottom left -->
<ng-template [ngIf]="viewerMode$ | async" 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"
[ngTemplateOutletContext]="{
showFullSideNav: (showFullSidenavSwitch.switchState$ | async)
? drawer.open.bind(drawer)
: showFullSidenavSwitch.open.bind(showFullSidenavSwitch)
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
</iav-layout-fourcorners>
</mat-drawer-content>
</mat-drawer-container>
<!-- 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
let-drawer="drawer"
let-showFullSidenavSwitch="showFullSidenavSwitch">
<!-- check if preview volume -->
<ng-template [ngIf]="overlaySidenav$ | async" let-overlaySideNav>
<!-- back btn -->
<button mat-button
(click)="clearPreviewingDataset()"
[attr.aria-label]="ARIA_LABELS.CLOSE"
class="position-absolute z-index-10 m-2">
<i class="fas fa-chevron-left"></i>
<span class="ml-1">
Back
</span>
</button>
<ng-template #genericInfoVCR>
</ng-template>
</ng-template>
<div [ngClass]="{
'invisible overflow-hidden h-0': overlaySidenav$ | async,
'h-100': !(overlaySidenav$ | async)
}" class="pe-all position-relative d-flex flex-column">
<!-- if pli voi is visible, show pli template
otherwise show region tmpl -->
<ng-template
[ngTemplateOutlet]="(selectedFeature$ | async)
? selectedFeatureTmpl
: sidenavRegionTmpl"
[ngTemplateOutletContext]="{
drawer: drawer,
showFullSidenavSwitch: showFullSidenavSwitch,
feature: selectedFeature$ | async
}">
</ng-template>
</div>
</ng-template>
<!-- minimal default drawer content -->
<ng-template #minSearchTray
let-showFullSidenav="showFullSidenav"
let-drawer="drawer">
<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"
iav-switch
[iav-switch-state]="true"
#minTrayVisSwitch="iavSwitch"
[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': !(minTrayVisSwitch.switchState$ | async),
'transition-margin-left': !drawer.opened
}">
<!-- collapsed side bar view -->
<div class="h-0 w-100 region-text-search-autocomplete-position">
<ng-container *ngTemplateOutlet="autocompleteTmpl; context: { showTour: true }">
</ng-container>
<div *ngIf="!((selectedRegions$ | async)[0])" class="sxplr-p-2 w-100">
<ng-container *ngTemplateOutlet="spatialFeatureListViewTmpl"></ng-container>
</div>
</div>
<!-- such a gross implementation -->
<!-- TODO fix this -->
sxplr-sapiviews-core-region
[sxplr-sapiviews-core-region-atlas]="selectedAtlas$ | async"
[sxplr-sapiviews-core-region-template]="templateSelected$ | async"
[sxplr-sapiviews-core-region-parcellation]="parcellationSelected$ | async"
[sxplr-sapiviews-core-region-region]="(selectedRegions$ | async)[0]"
[sxplr-sapiviews-core-region-detail-flag]="true"
#sapiRegion="sapiViewsCoreRegion">
<!-- TODO use sapiViews/core/region/base and fix the rest -->
'darktheme': sapiRegion.regionDarkmode,
'lighttheme': !sapiRegion.regionDarkmode
[style.backgroundColor]="sapiRegion.regionRgbString">
<!-- tab toggling hide/show of min search tray -->
<div class="tab-toggle-container d-inline-block v-align-top">
<ng-container *ngTemplateOutlet="tabTmpl; context: {
isOpen: minTrayVisSwitch.switchState$ | async,
regionSelected: selectedRegions$ | async,
click: minTrayVisSwitch.toggle.bind(minTrayVisSwitch),
badge: (voiFeatures.features$ | async).length || null
<!-- top left -->
<!-- default top left -->
<ng-template #defaultMainContentTopLeft
let-isOpen="isOpen"
let-drawer="drawer"
let-showFullSidenavSwitch="showFullSidenavSwitch">
<!-- min search tray -->
<ng-template [ngIf]="!(showFullSidenavSwitch.switchState$ | async)">
<ng-template
[ngTemplateOutlet]="minSearchTray"
[ngTemplateOutletContext]="{
showFullSidenav: showFullSidenavSwitch.open.bind(showFullSidenavSwitch),
drawer: drawer
}">
</ng-template>
</ng-template>
<!-- pullable tab top left corner -->
<div *ngIf="showFullSidenavSwitch.switchState$ | async"
class="v-align-top pe-all tab-toggle-container d-inline-block"
(click)="drawer.toggle()"
quick-tour
[quick-tour-description]="quickTourRegionSearch.description"
[quick-tour-order]="quickTourRegionSearch.order">
<ng-container *ngTemplateOutlet="tabTmpl; context: {
isOpen: isOpen,
regionSelected: selectedRegions$ | async
}">
</ng-container>
</div>
<!-- status panel for (for nehuba viewer) -->
<iav-cmp-viewer-nehuba-status *ngIf="(useViewer$ | async) === 'nehuba'"
class="pe-all mt-2 muted-7 d-inline-block v-align-top">
</iav-cmp-viewer-nehuba-status>
</ng-template>
<!-- special mode top left -->
<ng-template #specialModeTopLeftTmpl
let-mode="mode"
let-toggleMatDrawer="toggleMatDrawer">
<ng-container [ngSwitch]="mode">
<!-- annotating top left -->
<ng-template [ngSwitchCase]="ARIA_LABELS.VIEWER_MODE_ANNOTATING">
<ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
matColor: 'primary',
fontIcon: 'fa-list',
tooltip: 'Annotation list',
click: toggleMatDrawer,
badge: toolPanel?.annBadges$ | async
}">
</ng-container>
<annotating-tools-panel class="z-index-10 d-block"
#toolPanel="annoToolsPanel">
</annotating-tools-panel>
</ng-template>
<ng-template [ngSwitchCase]="ARIA_LABELS.VIEWER_MODE_KEYFRAME">
<ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
matColor: 'primary',
fontIcon: 'fa-play',
tooltip: 'Annotation list',
click: toggleMatDrawer
}">
</ng-container>
</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>
<sxplr-sapiviews-core-atlas-dropdown-selector
class="v-align-top sxplr-pt-2 pe-all mt-2 sxplr-custom-cmp bg card m-2 mat-elevation-z2 d-inline-block"
quick-tour
[quick-tour-description]="quickTourAtlasSelector.description"
[quick-tour-order]="quickTourAtlasSelector.order">
</sxplr-sapiviews-core-atlas-dropdown-selector>
<ng-template #specialTopRightTmpl let-mode="mode">
<mat-card class="mat-card-sm pe-all m-4">
<span>
{{ mode }}
</span>
<button mat-icon-button
color="warn"
(click)="exitSpecialViewMode()">
<i class="fas fa-times"></i>
</button>
</mat-card>
</ng-template>
<!-- bottom left -->
<ng-template #bottomLeftTmpl let-showFullSideNav="showFullSideNav">
<!-- atlas selector -->
<sxplr-sapiviews-core-atlas-tmplparcselector
*ngIf="viewerLoaded && !(isStandaloneVolumes$ | async)"
[iav-key-listener]="[{'type': 'keydown', 'key': 'Escape'}]"
(iav-key-event)="tmplParcSelector.closeSelector()"
(iav-outsideClick)="tmplParcSelector.closeSelector()"
#tmplParcSelector="sxplrSapiViewsCoreAtlasTmplparcselector">
</sxplr-sapiviews-core-atlas-tmplparcselector>
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
<!-- scroll container -->
<div class="sxplr-d-inline-flex
sxplr-flex-wrap-nowrap
sxplr-mxw-80vw
sxplr-pe-all
sxplr-of-x-auto
sxplr-of-y-hidden">
<!-- selected parcellation chip -->
<sxplr-sapiviews-core-parcellation-smartchip
class="sxplr-z-2 sxplr-mr-1"
[sxplr-sapiviews-core-parcellation-smartchip-parcellation]="parcellationSelected$ | async"
[sxplr-sapiviews-core-parcellation-smartchip-all-parcellations]="allAvailableParcellations$ | async"
(sxplr-sapiviews-core-parcellation-smartchip-dismiss-nonbase-layer)="onDismissNonbaseLayer()"
(sxplr-sapiviews-core-parcellation-smartchip-select-parcellation)="onSelectParcellation($event)"
>
</sxplr-sapiviews-core-parcellation-smartchip>
<!-- selected region chip -->
<sxplr-sapiviews-core-region-region-chip
*ngFor="let region of selectedRegions$ | async"
class="sxplr-pe-all sxplr-z-1 sxplr-mr-1"
(sxplr-sapiviews-core-region-region-chip-clicked)="showFullSideNav()"
[sxplr-sapiviews-core-region-atlas]="selectedAtlas$ | async"
[sxplr-sapiviews-core-region-template]="templateSelected$ | async"
[sxplr-sapiviews-core-region-parcellation]="parcellationSelected$ | async"
[sxplr-sapiviews-core-region-region]="region">
<div prefix>
</div>
<div suffix class="sxplr-scale-70">
<button mat-mini-fab
color="primary"
iav-stop="mousedown click"
(click)="clearRoi()">
<i class="fas fa-times"></i>
</button>
</div>
</sxplr-sapiviews-core-region-region-chip>
</div>
<!-- viewer tmpl -->
<ng-template #viewerTmpl>
<div class="position-absolute w-100 h-100 z-index-1">
<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) -->
<three-surfer-glue-cmp class="d-block w-100 h-100 position-absolute left-0 tosxplr-p-0"
</three-surfer-glue-cmp>
<!-- 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 *ngSwitchDefault>
<ui-splashscreen class="position-absolute left-0 tosxplr-p-0">
</ng-container>
<!-- <div class="h-100 w-100 overflow-hidden position-relative"
ctx-menu-host
[ctx-menu-host-tmpl]="viewerCtxMenuTmpl">
</div> -->
</div>
<!-- region-hierarchy-tmpl -->
<ng-template #regionHierarchyTmpl>
<div class="sxplr-d-flex sxplr-flex-column sxplr-h-100">
<sxplr-sapiviews-core-rich-regionshierarchy
[sxplr-sapiviews-core-rich-regionshierarchy-regions]="allAvailableRegions$ | async"
[sxplr-sapiviews-core-rich-regionshierarchy-accent-regions]="selectedRegions$ | async"
(sxplr-sapiviews-core-rich-regionshierarchy-region-select)="selectRoi($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>
<ng-template #autocompleteTmpl let-showTour="showTour">
<div class="sxplr-custom-cmp bg card ml-2 mr-2 mat-elevation-z8 pe-all auto-complete-container">
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
<ng-template #selectedRegionCheckTmpl let-region>
<ng-template #fallbackTmpl>
<button mat-icon-button
class="sxplr-mt-a sxplr-mb-a">
<i class="far fa-square"></i>
</button>
</ng-template>
<button *ngIf="selectedRegions$ | async | includes : region; else fallbackTmpl"
mat-icon-button
color="primary"
class="sxplr-mt-a sxplr-mb-a">
<i class="far fa-check-square"></i>
</button>
</ng-template>
<sxplr-sapiviews-core-rich-regionlistsearch
[sxplr-sapiviews-core-rich-regionlistsearch-regions]="allAvailableRegions$ | async"
[sxplr-sapiviews-core-rich-regionlistsearch-current-search]="selectedRegions$ | async | getProperty : 0 | getProperty : 'name'"
[sxplr-sapiviews-core-rich-regionlistsearch-region-template-ref]="selectedRegionCheckTmpl"
(sxplr-sapiviews-core-rich-regionlistsearch-region-select)="selectRoi($event)">
<button mat-icon-button
search-input-suffix
*ngIf="selectedRegions$ | async | getProperty : 'length'"
(click)="clearRoi()">
<i class="fas fa-times"></i>
</button>
</sxplr-sapiviews-core-rich-regionlistsearch>
<button mat-icon-button
color="primary"
[sxplr-dialog]="regionHierarchyTmpl"
sxplr-dialog-size="xl">
<i class="fas fa-sitemap"></i>
</button>
<div class="w-100 h-100 position-absolute pe-none" *ngIf="showTour">
</div>
</ng-template>
<!-- template for rendering tab -->
<ng-template #tabTmpl
let-isOpen="isOpen"
let-regionSelected="regionSelected"
let-iavAdditionallayers="iavAdditionallayers"
let-click="click"
let-badge="badge">
<!-- if mat drawer is open -->
<ng-template [ngIf]="isOpen" [ngIfElse]="tabTmpl_closedTmpl">
<ng-template [ngTemplateOutlet]="tabTmpl_defaultTmpl"
[ngTemplateOutletContext]="{
matColor: 'basic',
fontIcon: 'fa-chevron-left',
click: click,
badge: badge
</ng-template>
<!-- if matdrawer is closed -->
<ng-template #tabTmpl_closedTmpl>
<!-- if additional layers are being shown -->
<ng-template [ngIf]="iavAdditionallayers?.length > 0" [ngIfElse]="tabTmpl_noAdditionalLayers">
<ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
matColor: 'accent',
fontIcon: 'fa-database',
tooltip: 'Explore dataset preview',
click: click
}">
</ng-container>
</ng-template>
<!-- if additional layers not not being shown -->
<ng-template #tabTmpl_noAdditionalLayers>
<!-- if region selected > 0 -->
<ng-template [ngIf]="regionSelected?.length > 0" [ngIfElse]="tabTmpl_nothingSelected">
<div sxplr-sapiviews-core-region
[sxplr-sapiviews-core-region-detail-flag]="true"
[sxplr-sapiviews-core-region-atlas]="selectedAtlas$ | async"
[sxplr-sapiviews-core-region-template]="templateSelected$ | async"
[sxplr-sapiviews-core-region-parcellation]="parcellationSelected$ | async"
[sxplr-sapiviews-core-region-region]="regionSelected[0]"
#tabTmpl_iavRegion="sapiViewsCoreRegion">
</div>
<!-- TODO fix with sapiView/core/region directive -->
<ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
customColor: tabTmpl_iavRegion.regionRgbString,
customColorDarkmode: tabTmpl_iavRegion.regionDarkmode,
tooltip: 'Explore ' + regionSelected[0].name,
</ng-template>
<!-- nothing is selected -->
<ng-template #tabTmpl_nothingSelected>
<ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
matColor: 'primary',
fontIcon: 'fa-sitemap',
click: click,
badge: badge
}">
</ng-container>
</ng-template>
</ng-template>
</ng-template>
</ng-template>
let-matColor="matColor"
let-fontIcon="fontIcon"
let-customColor="customColor"
let-customColorDarkmode="customColorDarkmode"
let-tooltip="tooltip"
<!-- (click)="sideNavMasterSwitch.toggle()" -->
<button mat-raised-button
[attr.aria-label]="ARIA_LABELS.TOGGLE_SIDE_PANEL"
[matTooltip]="tooltip"
class="pe-all tab-toggle"
[ngClass]="{
'darktheme': customColorDarkmode === true,
'lighttheme': customColorDarkmode === false
}"
(click)="click && click()"
[style.backgroundColor]="customColor"
[color]="(!customColor && matColor) ? matColor : null"
[matBadge]="badge"
[matBadgeColor]="badgeColor || 'warn'">
<span [ngClass]="{'sxplr-custom-cmp text': !!customColor}">
<i class="fas" [ngClass]="fontIcon || 'fa-question'"></i>
</span>
<ng-template #sidenavRegionTmpl
let-drawer="drawer"
let-showFullSidenavSwitch="showFullSidenavSwitch">
<!-- 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"
[ngClass]="{'region-populated': (selectedRegions$ | async).length > 0 }">
<!-- region detail -->
<ng-container *ngIf="selectedRegions$ | async as selectedRegions; else selectRegionErrorTmpl">
<!-- single-region-wrapper -->
<ng-template [ngIf]="selectedRegions.length === 1" [ngIfElse]="multiRegionWrapperTmpl">
<!-- a series of bugs result in requiring this hacky -->
<!-- see https://github.com/HumanBrainProject/interactive-viewer/issues/698 -->
<sxplr-sapiviews-core-region-region-rich
[sxplr-sapiviews-core-region-atlas]="selectedAtlas$ | async"
[sxplr-sapiviews-core-region-template]="templateSelected$ | async"
[sxplr-sapiviews-core-region-parcellation]="parcellationSelected$ | async"
[sxplr-sapiviews-core-region-region]="selectedRegions[0]"
(sxplr-sapiviews-core-region-region-rich-feature-clicked)="showDataset($event)"
(sxplr-sapiviews-core-region-navigate-to)="navigateTo($event)"
>
<div class="sapi-container" header></div>
</sxplr-sapiviews-core-region-region-rich>
<!-- multi region wrapper -->
<ng-template #multiRegionWrapperTmpl>
<ng-container *ngTemplateOutlet="multiRegionTmpl; context: {
regions: selectedRegions
}">
</ng-container>
<!-- This is a wrapper for multiregion consisting of {{ selectedRegions.length }} regions -->
</ng-template>
<!-- place holder if length === 0 -->
<ng-container *ngIf="selectedRegions.length === 0">
</ng-container>
</ng-container>
<div class="spacer">
</div>
</div>
<!-- collapse btn -->
<ng-template [ngTemplateOutlet]="collapseBtn"
[ngTemplateOutletContext]="{
collapse: showFullSidenavSwitch.close.bind(showFullSidenavSwitch)
}">
</ng-template>
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
</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>
<!-- select region error... for whatever reason -->
<ng-template #selectRegionErrorTmpl>
SELECT REGION ERROR
</ng-template>
<!-- multi region tmpl -->
<ng-template #multiRegionTmpl let-regions="regions">
<ng-template [ngIf]="regions.length > 0" [ngIfElse]="regionPlaceholderTmpl">
<!-- other regions detail accordion -->
<mat-accordion class="bs-border-box ml-15px-n mr-15px-n mt-2">
<!-- Multi regions include -->
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
<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>
Brain 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>
<!-- TODO use actual region chip in sapiViews/core/region/chip -->
SOMETHING
</ng-template>
</mat-expansion-panel>
</mat-accordion>
</ng-template>
</ng-template>
<!-- collapse btn -->
<ng-template #collapseBtn let-collapse="collapse">
<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"
color="basic">
<i class="fas fa-chevron-up"></i>
<span>
collapse
</span>
</button>
</div>
</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">
<mat-card class="sxplr-p-0 d-flex flex-column"
[iav-key-listener]="[{type: 'keydown', target: 'document', capture: true}]"
(iav-key-event)="disposeCtxMenu()"
(iav-outsideClick)="disposeCtxMenu()">
<mat-card-content *ngFor="let tmplRef of tmplRefs"
class="m-0"
[ngStyle]="{order: tmplRef.order || 0}">
<mat-divider></mat-divider>
<!-- template provided -->
<ng-template [ngIf]="tmplRef.tmpl"
[ngIfElse]="fallbackTmpl"
[ngTemplateOutlet]="tmplRef.tmpl"
[ngTemplateOutletContext]="{$implicit: tmplRef.data}">
</ng-template>
<!-- template not provided -->
<ng-template #fallbackTmpl>
{{ tmplRef.data.message || 'test' }}
</ng-template>
</mat-card-content>
</mat-card>
</ng-template>
<!-- viewer status ctx menu -->
<ng-template #viewerStatusCtxMenu let-data>
<mat-list>
<!-- ref space & position -->
<ng-container [ngSwitch]="data.context.viewerType">
<!-- volumetric i.e. nehuba -->
<ng-container *ngSwitchCase="'nehuba'">
<mat-list-item>
<span mat-line>
{{ data.context.payload.mouse.real | nmToMm | numbers | addUnitAndJoin : '' }} (mm)
</span>
<span mat-line class="text-muted">
<i class="fas fa-map"></i>
<span>
{{ data.metadata.template.displayName || data.metadata.template.name }}
</span>
</span>
</mat-list-item>
</ng-container>
<ng-container *ngSwitchCase="'threeSurfer'">
<mat-list-item *ngIf="data?.context?.payload?.faceIndex && data?.context?.payload?.vertexIndices">
<span mat-line>
face#{{ data.context.payload.faceIndex }}
</span>
<span mat-line>
vertices#{{ data.context.payload.vertexIndices | addUnitAndJoin : '' }}
</span>
<span mat-line class="text-muted">
<i class="fas fa-map"></i>
<span>
{{ data.context.payload.fsversion }}
</span>
</span>
</mat-list-item>
</ng-container>
<ng-container *ngSwitchDefault>
DEFAULT
</ng-container>
</ng-container>
<ng-template #viewerStatusRegionCtxMenu let-data>
<!-- hovered ROIs -->
<mat-list>
<mat-list-item *ngFor="let region of data.metadata.hoveredRegions; let first = first">
<mat-divider class="top-0" *ngIf="!first"></mat-divider>
<ng-container *ngTemplateOutlet="viewerStateSapiRegionTmpl; context: { $implicit: region }">
</ng-container>
</mat-list>
</ng-template>
<!-- sapi region tmpl -->
<ng-template #viewerStateSapiRegionTmpl let-region>
<span mat-line>
{{ region.name }}
</span>
<span mat-line class="text-muted">
<i class="fas fa-brain"></i>
<span>
Brain region
</span>
</span>
<!-- lookup region -->
<button mat-icon-button
(click)="selectRoi(region)"
ctx-menu-dismiss>
<i class="fas fa-search"></i>
</button>
</ng-template>
<!-- feature tmpls -->
<ng-template #sapiBaseFeatureTmpl
let-backCb="backCb"
<sxplr-sapiviews-core-datasets-dataset class="sxplr-z-2 mat-elevation-z2"
[sxplr-sapiviews-core-datasets-dataset-input]="feature">
<div header>
<!-- back btn -->
<button mat-button
*ngIf="backCb"
(click)="backCb()"
[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-sapiviews-core-datasets-dataset>
<sxplr-sapiviews-features-entry
[sxplr-sapiviews-features-entry-atlas]="selectedAtlas$ | async"
[sxplr-sapiviews-features-entry-space]="templateSelected$ | async"
[sxplr-sapiviews-features-entry-parcellation]="parcellationSelected$ | async"
[sxplr-sapiviews-features-entry-region]="(selectedRegions$ | async)[0]"
[sxplr-sapiviews-features-entry-feature]="feature">
</sxplr-sapiviews-features-entry>
</ng-template>
<!-- general feature tmpl -->
<ng-template let-feature="feature" #selectedFeatureTmpl>
<!-- TODO differentiate between features (spatial, regional etc) -->
<!-- spatial feature tmpl -->
<ng-container *ngTemplateOutlet="sapiBaseFeatureTmpl; context: {
backCb: clearSelectedFeature.bind(this),
<ng-layer-ctl *ngFor="let vol of feature.volumes"
class="d-block"
[ng-layer-ctl-name]="vol.metadata.fullName"
[ng-layer-ctl-src]="vol.data.url"
[ng-layer-ctl-transform]="vol.data | getProperty : 'detail' | getProperty: 'neuroglancer/precomputed' | getProperty : 'transform'">
</ng-layer-ctl>
<ng-template #sapiVOITmpl>
</ng-template>
</ng-template>
<ng-template #spatialFeatureListViewTmpl>