<div class="position-absolute w-100 h-100"> <ng-container *ngTemplateOutlet="viewerTmpl"> </ng-container> </div> <layout-floating-container [zIndex]="10"> <!-- Annotation mode --> <div *ngIf="(viewerMode$ | async) === ARIA_LABELS.VIEWER_MODE_ANNOTATING"> <mat-drawer-container class="mat-drawer-content-overflow-visible w-100 h-100 position-absolute invisible" [hasBackdrop]="false"> <mat-drawer #annotationDrawer="matDrawer" mode="side" (annotation-event-directive)="annotationDrawer.open()" [annotation-event-directive-filter]="['showList']" [autoFocus]="false" [disableClose]="true" class="p-0 pe-all col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2"> <annotation-list></annotation-list> </mat-drawer> <mat-drawer-content class="visible position-relative pe-none"> <iav-layout-fourcorners> <!-- pullable tab top right corner --> <div iavLayoutFourCornersTopLeft class="tab-toggle-container"> <div> <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: { matColor: 'primary', fontIcon: 'fa-list', tooltip: 'Annotation list', click: annotationDrawer.toggle.bind(annotationDrawer) }"> </ng-container> </div> <annotating-tools-panel class="z-index-10"> </annotating-tools-panel> </div> <div iavLayoutFourCornersTopRight> <mat-card class="mat-card-sm pe-all m-4"> <span> Annotating </span> <button mat-icon-button [matTooltip]="ARIA_LABELS.EXIT_ANNOTATION_MODE" color="warn" annotation-switch annotation-switch-mode="off"> <i class="fas fa-times"></i> </button> </mat-card> </div> </iav-layout-fourcorners> </mat-drawer-content> </mat-drawer-container> <!-- <annotation-message></annotation-message> --> </div> <!-- top drawer --> <mat-drawer-container [hidden]="viewerMode$ | async" [iav-switch-initstate]="false" iav-switch #sideNavTopSwitch="iavSwitch" class="mat-drawer-content-overflow-visible w-100 h-100 position-absolute invisible" [hasBackdrop]="false"> <!-- sidenav-content --> <!-- (closedStart)="sideNavwFullLeftSwitch.switchState && matDrawerLeft.close()" (openedStart)="sideNavFullLeftSwitch.switchState && matDrawerLeft.open()" --> <mat-drawer class="box-shadow-none border-0 pe-none bg-none col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2" mode="side" [attr.data-mat-drawer-top-open]="matDrawerTop.opened" [opened]="sideNavTopSwitch.switchState" [autoFocus]="false" [disableClose]="true" (openedChange)="handleSideNavAnimationDone($event)" #matDrawerTop="matDrawer"> <div class="h-0 w-100 region-text-search-autocomplete-position"> <ng-container *ngTemplateOutlet="autocompleteTmpl; context: { showTour: true }"> </ng-container> </div> <button mat-raised-button *ngIf="!(alwaysHideMinorPanel$ | async)" [attr.aria-label]="ARIA_LABELS.EXPAND" (click)="sideNavFullLeftSwitch && sideNavFullLeftSwitch.open()" class="explore-btn pe-all w-100" [ngClass]="{ 'darktheme': iavRegion.rgbDarkmode === true, 'lighttheme': iavRegion.rgbDarkmode === false }" [style.backgroundColor]="iavRegion?.rgbString || 'accent'"> <span class="text iv-custom-comp"> Explore </span> <div class="hidden" iav-region [region]="(selectedRegions$ | async) && (selectedRegions$ | async)[0]" #iavRegion="iavRegion"> </div> </button> </mat-drawer> <mat-drawer-content class="visible position-relative pe-none"> <iav-layout-fourcorners [iav-layout-fourcorners-cnr-cntr-ngclass]="{'w-100': true}"> <!-- pullable tab top left corner --> <div iavLayoutFourCornersTopLeft class="d-flex flex-nowrap w-100"> <!-- top left --> <div class="flex-grow-1 d-flex flex-nowrap align-items-start"> <div *ngIf="viewerLoaded" class="pe-all tab-toggle-container" (click)="sideNavTopSwitch && sideNavTopSwitch.toggle()" quick-tour [quick-tour-description]="quickTourRegionSearch.description" [quick-tour-order]="quickTourRegionSearch.order" #regionSearchQuickTour="quickTour"> <ng-container *ngTemplateOutlet="tabTmpl; context: { isOpen: sideNavTopSwitch.switchState, regionSelected: selectedRegions$ | async, iavAdditionallayers: iavAdditionalLayers$ | async }"> </ng-container> </div> <iav-cmp-viewer-nehuba-status *ngIf="(useViewer$ | async) === 'nehuba'" class="pe-all mt-2 muted-7"> </iav-cmp-viewer-nehuba-status> </div> <!-- top right --> <div class="flex-grow-0 d-inline-flex align-items-start"> <!-- signin banner at top right corner --> <top-menu-cmp class="mt-3 mr-2 d-inline-block" [ismobile]="ismobile" [viewerLoaded]="viewerLoaded"> </top-menu-cmp> <div *ngIf="viewerLoaded" class="iv-custom-comp bg card m-2 mat-elevation-z2" quick-tour [quick-tour-description]="quickTourAtlasSelector.description" [quick-tour-order]="quickTourAtlasSelector.order"> <atlas-dropdown-selector class="pe-all mt-2"> </atlas-dropdown-selector> </div> </div> </div> </iav-layout-fourcorners> </mat-drawer-content> </mat-drawer-container> <!-- full left drawer --> <mat-drawer-container [hidden]="viewerMode$ | async" [iav-switch-initstate]="!(alwaysHideMinorPanel$ | async)" iav-switch #sideNavFullLeftSwitch="iavSwitch" class="mat-drawer-content-overflow-visible w-100 h-100 position-absolute invisible" [hasBackdrop]="false"> <!-- sidenav-content --> <mat-drawer class="darker-bg iv-custom-comp visible col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2 d-flex flex-column pe-all" mode="push" [opened]="sideNavTopSwitch.switchState && sideNavFullLeftSwitch.switchState" [attr.data-mat-drawer-fullleft-open]="matDrawerLeft.opened" [autoFocus]="false" #matDrawerLeft="matDrawer" (openedChange)="$event && sideNavFullLeftSwitch.open()" [@openClose]="sideNavTopSwitch.switchState && sideNavFullLeftSwitch.switchState ? 'open' : 'closed'" (@openClose.done)="$event.toState === 'closed' && matDrawerLeft.close()" [disableClose]="true"> <!-- check if preview volume --> <div *ngIf="overlaySidenav$ | async as overlaySideNav" class="position-relative d-flex flex-column h-100"> <div class="position-relative ml-15px-n mr-15px-n"> <!-- 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> </div> </div> <div [ngClass]="{ 'invisible overflow-hidden h-0': overlaySidenav$ | async, 'h-100': !(overlaySidenav$ | async) }" class="position-relative d-flex flex-column"> <ng-container *ngTemplateOutlet="sidenavRegionTmpl"> </ng-container> <!-- TODO dataset preview will become deprecated in the future. Regional feature/data feature will replace it --> <!-- <div class="hidden" iav-shown-dataset #iavShownDataset="iavShownDataset"> </div> --> </div> </mat-drawer> <!-- main-content --> <mat-drawer-content class="visible position-relative" [hidden]="viewerMode$ | async"> <iav-layout-fourcorners [iav-layout-fourcorners-cnr-cntr-ngclass]="{'w-100': true}"> <!-- bottom left corner (atlas selector and currently selected) --> <div iavLayoutFourCornersBottomLeft class="d-inline-flex align-items-center mb-4 ml-2 w-100"> <!-- atlas selector --> <atlas-layer-selector *ngIf="viewerLoaded && !(isStandaloneVolumes$ | async)" #alSelector="atlasLayerSelector" (iav-outsideClick)="alSelector.selectorExpanded = false"> </atlas-layer-selector> <!-- chips --> <div *ngIf="parcellationSelected$ | async" class="flex-grow-0 p-1 pr-2 flex-shrink-1 overflow-y-hidden overflow-x-auto pe-all"> <viewer-state-breadcrumb (on-item-click)="handleChipClick()"> </viewer-state-breadcrumb> </div> </div> </iav-layout-fourcorners> </mat-drawer-content> </mat-drawer-container> </layout-floating-container> <!-- viewer tmpl --> <ng-template #viewerTmpl> <iav-layout-fourcorners> <div iavLayoutFourCornersContent class="w-100 h-100 position-absolute"> <div class="h-100 w-100 overflow-hidden position-relative" 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 top-0" *ngSwitchCase="'nehuba'" (viewerEvent)="handleViewerEvent($event)" [selectedTemplate]="templateSelected$ | async" [selectedParcellation]="parcellationSelected$ | async" #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 top-0" *ngSwitchCase="'threeSurfer'" (viewerEvent)="handleViewerEvent($event)" [selectedTemplate]="templateSelected$ | async" [selectedParcellation]="parcellationSelected$ | async"> </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 top-0"> </ui-splashscreen> </div> </ng-container> </div> </div> </iav-layout-fourcorners> </ng-template> <!-- auto complete search box --> <ng-template #autocompleteTmpl let-showTour="showTour"> <div class="iv-custom-comp bg card w-100 mat-elevation-z8 pe-all"> <region-text-search-autocomplete class="w-100 pt-2 flex-shrink-0 flex-grow-0"> </region-text-search-autocomplete> <div class="w-100 h-100 position-absolute pe-none" *ngIf="showTour" #regionSelRef> </div> </div> </ng-template> <!-- template for rendering tab --> <ng-template #tabTmpl let-isOpen="isOpen" let-regionSelected="regionSelected" let-iavAdditionallayers="iavAdditionallayers"> <!-- if mat drawer is open --> <ng-template [ngIf]="isOpen" [ngIfElse]="tabTmpl_closedTmpl"> <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: { matColor: 'basic', fontIcon: 'fa-chevron-left' }"> </ng-container> </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' }"> </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 class="hidden" iav-region [region]="regionSelected[0]" #tabTmpl_iavRegion="iavRegion"> </div> <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: { matColor: 'accent', customColor: tabTmpl_iavRegion.rgbString, customColorDarkmode: tabTmpl_iavRegion.rgbDarkmode, fontIcon: 'fa-brain', tooltip: 'Explore ' + tabTmpl_iavRegion.region.name }"> </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' }"> </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-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"> <span [ngClass]="{'iv-custom-comp text': !!customColor}"> <i class="fas" [ngClass]="fontIcon || 'fa-question'"></i> </span> </button> </ng-template> <!-- region sidenav tmpl --> <ng-template #sidenavRegionTmpl> <!-- 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 --> <ng-container *ngTemplateOutlet="singleRegionTmpl; context: { region: (regionOfInterest$ | async) }"> </ng-container> </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"> <ng-container *ngTemplateOutlet="singleRegionTmpl; context: { region: false }"> </ng-container> </ng-container> </ng-container> <div class="spacer"> </div> </div> <!-- collapse btn --> <ng-container *ngTemplateOutlet="collapseBtn"> </ng-container> </ng-template> <!-- single region tmpl --> <ng-template #singleRegionTmpl let-region="region"> <!-- region detail --> <region-menu [region]="region" class="flex-grow-1 bs-border-box ml-15px-n mr-15px-n mat-elevation-z4"> </region-menu> </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"> <mat-expansion-panel [attr.data-opened]="expansionPanel.expanded" [attr.data-mat-expansion-title]="title" hideToggle *ngIf="iavNgIf" #expansionPanel="matExpansionPanel"> <mat-expansion-panel-header> <!-- title --> <mat-panel-title> {{ title }} </mat-panel-title> <!-- desc + icon --> <mat-panel-description class="d-flex align-items-center justify-content-end" [matTooltip]="iconTooltip"> <span class="mr-3">{{ desc }}</span> <span class="accordion-icon d-inline-flex justify-content-center"> <i [class]="iconClass"></i> </span> </mat-panel-description> </mat-expansion-panel-header> <!-- content --> <ng-template matExpansionPanelContent> <ng-container *ngTemplateOutlet="content; context: { expansionPanel: expansionPanel }"> </ng-container> </ng-template> </mat-expansion-panel> </ng-template> <!-- misc dataset (e.g. PLI) --> <!-- <ng-template #sidenavDsPreviewTmpl let-file="file" let-filename="filename" let-datasetId="datasetId"> <div class="w-100 flex-grow-1 d-flex flex-column"> Previewing misc dataset <ng-container *ngTemplateOutlet="collapseBtn"> </ng-container> </div> </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"> <region-menu [region]="{ name: CONST.MULTI_REGION_SELECTION }" class="bs-border-box ml-15px-n mr-15px-n mat-elevation-z4"> </region-menu> <!-- other regions detail accordion --> <mat-accordion class="bs-border-box ml-15px-n mr-15px-n mt-2"> <!-- Multi regions include --> <ng-template #multiRegionInclTmpl> <mat-chip-list> <mat-chip *ngFor="let r of regions" iav-region [region]="r" [ngClass]="{ 'darktheme':regionDirective.rgbDarkmode === true, 'lighttheme': regionDirective.rgbDarkmode === false }" [style.backgroundColor]="regionDirective.rgbString" #regionDirective="iavRegion"> <span class="iv-custom-comp text text-truncate d-inline pl-4"> {{ r.name }} </span> </mat-chip> </mat-chip-list> </ng-template> <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: { title: 'Brain regions', desc: regions.length, iconClass: 'fas fa-brain', iavNgIf: true, content: multiRegionInclTmpl }"> </ng-container> </mat-accordion> </ng-template> </ng-template> <!-- collapse btn --> <ng-template #collapseBtn> <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)="sideNavFullLeftSwitch.close()" 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="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-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 | 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> <ng-template #viewerStatusRegionCtxMenu let-data> <!-- hovered ROIs --> <mat-list> <mat-list-item *ngFor="let hoveredR of data.metadata.hoveredRegions; let first = first"> <mat-divider class="top-0" *ngIf="!first"></mat-divider> <span mat-line> {{ hoveredR.displayName || hoveredR.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(hoveredR)" ctx-menu-dismiss> <i class="fas fa-search"></i> </button> </mat-list-item> </mat-list> </ng-template>