Newer
Older
<div class="position-absolute w-100 h-100">
<ng-container *ngTemplateOutlet="viewerTmpl">
</ng-container>
</div>
<layout-floating-container [zIndex]="10">
<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"
(annotation-event-directive)="annotationDrawer.open()"
[annotation-event-directive-filter]="['showList']"
class="p-0 pe-all col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2">
<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)
}">
<annotating-tools-panel class="z-index-10">
</annotating-tools-panel>
<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>
<!-- <annotation-message></annotation-message> -->
[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)"
<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>
<!-- 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>
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>
</iav-layout-fourcorners>
</mat-drawer-content>
</mat-drawer-container>
<!-- full left drawer -->
<mat-drawer-container
[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 [ngClass]="{
'invisible overflow-hidden h-0': overlaySidenav$ | async,
'h-100': !(overlaySidenav$ | async)
}" class="position-relative d-flex flex-column">
<ng-container *ngTemplateOutlet="sidenavRegionTmpl">
<!-- 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>
<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>
</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">
<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-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>
</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>
315
316
317
318
319
320
321
322
323
324
325
326
327
328
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
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
</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>
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>
</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) }">
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
456
457
458
459
<!-- 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>
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
</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>
<!-- 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">
<ng-container *ngTemplateOutlet="collapseBtn">
</ng-container>
</div>
<!-- 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"
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">
[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>
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
</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>
<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
<!-- 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>