<div iav-media-query class="position-absolute w-100 h-100" #media="iavMediaQuery"> <ng-container *ngTemplateOutlet="viewerTmpl"> </ng-container> <div class="floating-ui"> <div *ngIf="(media.mediaBreakPoint$ | async) < 2" class="fixed-bottom sxplr-pe-none sxplr-mb-10 d-flex justify-content-center"> <logo-container></logo-container> </div> <div *ngIf="(media.mediaBreakPoint$ | async) < 2" 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> </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> </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"> <!-- 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 sxplr-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> </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 sxplr-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) }"> </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> <!-- 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"> <!-- selectedFeature || selectedRegion --> <ng-template [ngTemplateOutlet]="(selectedFeature$ | async) ? selectedFeatureTmpl : sidenavRegionTmpl" [ngTemplateOutletContext]="{ drawer: drawer, showFullSidenavSwitch: showFullSidenavSwitch, feature: selectedFeature$ | async }"> </ng-template> </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-1 w-100"> <ng-container *ngTemplateOutlet="spatialFeatureListTmpl"></ng-container> </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]="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 --> <button mat-raised-button *ngIf="!(onlyShowMiniTray$ | async)" [attr.aria-label]="ARIA_LABELS.EXPAND" (click)="showFullSidenav()" 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> </ng-template> <!-- 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> <button mat-icon-button sxplr-share-view *ngIf="(useViewer$ | async) === 'threeSurfer'" class="pe-all mt-2 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" let-toggleMatDrawer="toggleMatDrawer"> <div class="tab-toggle-container"> <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> </ng-template> <!-- special mode top right --> <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"> <!-- 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 sxplr-align-items-stretch"> <sxplr-wrapper-atp-selector class="sxplr-z-2"> </sxplr-wrapper-atp-selector> <!-- selected region chip --> <ng-template ngFor [ngForOf]="selectedRegions$ | async" let-region> <sxplr-smart-chip [noMenu]="true" [color]="sapiViewsCoreRegion.regionRgbString" (click)="showFullSideNav()" 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]="region" [sxplr-sapiviews-core-region-detail-flag]="true" #sapiViewsCoreRegion="sapiViewsCoreRegion"> <ng-template sxplrSmartChipContent> <span class="regionname"> {{ region.name }} </span> <button class="sxplr-mr-n3" mat-icon-button (click)="clearRoi()"> <i class="fas fa-times"></i> </button> </ng-template> </sxplr-smart-chip> </ng-template> </div> </ng-template> <!-- 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) --> <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 class="h-100 w-100 overflow-hidden position-relative" ctx-menu-host [ctx-menu-host-tmpl]="viewerCtxMenuTmpl"> </div> --> </div> </ng-template> <!-- region-hierarchy-tmpl --> <ng-template #regionHierarchyTmpl> <div class="sxplr-d-flex sxplr-flex-column sxplr-h-100"> <sxplr-sapiviews-core-rich-regionshierarchy class="sxplr-w-100 sxplr-flex-var" [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> </div> </ng-template> <!-- auto complete search box --> <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"> <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-select)="selectRoi($event)"> <ng-template regionTemplate let-region> <div class="sxplr-d-flex"> <button mat-icon-button class="sxplr-mt-a sxplr-mb-a"> <i [ngClass]="(selectedRegions$ | async | includes : region) ? 'fa-circle' : 'fa-none'" class="fas"></i> </button> <sxplr-sapiviews-core-region-region-list-item [sxplr-sapiviews-core-region-region]="region"> </sxplr-sapiviews-core-region-region-list-item> </div> </ng-template> <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 sxplr-pe-none" *ngIf="showTour"> </div> </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> </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: { matColor: 'accent', customColor: tabTmpl_iavRegion.regionRgbString, customColorDarkmode: tabTmpl_iavRegion.regionDarkmode, fontIcon: 'fa-brain', tooltip: 'Explore ' + regionSelected[0].name, click: click }"> </ng-container> </ng-template> <!-- nothing is selected --> <ng-template #tabTmpl_nothingSelected> <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: { matColor: 'primary', fontIcon: 'fa-sitemap', tooltip: 'Explore regions', click: click, badge: badge }"> </ng-container> </ng-template> </ng-template> </ng-template> </ng-template> <ng-template #tabTmpl_defaultTmpl let-matColor="matColor" let-fontIcon="fontIcon" let-customColor="customColor" let-customColorDarkmode="customColorDarkmode" let-tooltip="tooltip" let-badge="badge" let-badgeColor="badgeColor" let-click="click"> <!-- (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> </button> </ng-template> <!-- region sidenav tmpl --> <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 sxplr-h-100" [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 --> <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]="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)" #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: 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"> no region selected </ng-container> </ng-container> <div class="spacer"> </div> </div> <!-- collapse btn --> <ng-template [ngTemplateOutlet]="collapseBtn" [ngTemplateOutletContext]="{ collapse: showFullSidenavSwitch.close.bind(showFullSidenavSwitch) }"> </ng-template> </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 --> <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" (click)="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> </ng-template> <!-- 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, key: 'Esc'}]" (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-divider></mat-divider> </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> </mat-list> </ng-template> <!-- viewer state hover ctx menu --> <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-item> </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" let-feature="feature"> <sxplr-feature-view class="sxplr-z-2 mat-elevation-z2" [feature]="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-feature-view> </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), feature: feature }"> </ng-container> <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> <!-- spatial search tmpls --> <ng-template #spatialFeatureListTmpl> <mat-card class="sxplr-pe-all" [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> {{ templateSelected$ | async | getProperty : '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-slide-toggle [formControl]="showVOIWireframeSlideToggle"> <span> Show VOI Wireframe </span> <spinner-cmp class="sxplr-d-inline-block" *ngIf="loadingVoiWireFrame$ | async"></spinner-cmp> </mat-slide-toggle> </mat-card> <sxplr-feature-entry [ngClass]="(voiSwitch.switchState$ | async) ? 'sxplr-d-block' : 'sxplr-d-none'" class="sxplr-pe-all mat-elevation-z8" [template]="templateSelected$ | async" [bbox]="bbox.bbox$ | async | getProperty : 'bbox'" #voiFeatureEntryCmp="featureEntryCmp"> </sxplr-feature-entry> <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" (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> <!-- 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="showVOIWireframeSlideToggle.valueChanges | async" voiBbox [features]="voiFeatureEntryCmp.features$ | async"> </div> </ng-template> <div sxplr-sapiviews-core-space-boundingbox [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>