Skip to content
Snippets Groups Projects
nehubaViewerGlue.component.ts 3.92 KiB
Newer Older
Xiao Gui's avatar
Xiao Gui committed
import { ChangeDetectionStrategy, Component, EventEmitter, Inject, OnDestroy, Optional, Output } from "@angular/core";
Xiao Gui's avatar
Xiao Gui committed
import { select, Store } from "@ngrx/store";
import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR } from "src/util";
import { distinctUntilChanged } from "rxjs/operators";
import { IViewer, TViewerEvent } from "../../viewer.interface";
import { NehubaMeshService } from "../mesh.service";
import { NehubaLayerControlService, SET_COLORMAP_OBS, SET_LAYER_VISIBILITY } from "../layerCtrl.service";
Xiao Gui's avatar
Xiao Gui committed
import { EXTERNAL_LAYER_CONTROL, NG_LAYER_CONTROL, SET_SEGMENT_VISIBILITY } from "../layerCtrl.service/layerCtrl.util";
import { SxplrRegion } from "src/atlasComponents/sapi/sxplrTypes";
import { NehubaConfig } from "../config.service";
Xiao Gui's avatar
Xiao Gui committed
import { SET_MESHES_TO_LOAD } from "../constants";
import { atlasSelection, userInteraction } from "src/state";
Xiao Gui's avatar
Xiao Gui committed

@Component({
  selector: 'iav-cmp-viewer-nehuba-glue',
  templateUrl: './nehubaViewerGlue.template.html',
  styleUrls: [
    './nehubaViewerGlue.style.css'
Xiao Gui's avatar
Xiao Gui committed
  ],
  exportAs: 'iavCmpViewerNehubaGlue',
  providers: [
    {
      provide: SET_MESHES_TO_LOAD,
      useFactory: (meshService: NehubaMeshService) => meshService.loadMeshes$,
      deps: [ NehubaMeshService ]
    },
Xiao Gui's avatar
Xiao Gui committed
    {
      provide: EXTERNAL_LAYER_CONTROL,
      useValue: NehubaLayerControlService
    },
    NehubaMeshService,
    {
      provide: SET_COLORMAP_OBS,
      useFactory: (layerCtrl: NehubaLayerControlService) => layerCtrl.setColorMap$,
      deps: [ NehubaLayerControlService ]
    },
    {
      provide: SET_LAYER_VISIBILITY,
      useFactory: (layerCtrl: NehubaLayerControlService) => layerCtrl.visibleLayer$,
      deps: [ NehubaLayerControlService ]
    },
    {
      provide: SET_SEGMENT_VISIBILITY,
      useFactory: (layerCtrl: NehubaLayerControlService) => layerCtrl.segmentVis$,
      deps: [ NehubaLayerControlService ]
    },
    {
      provide: NG_LAYER_CONTROL,
      useFactory: (layerCtrl: NehubaLayerControlService) => layerCtrl.ngLayersController$,
      deps: [ NehubaLayerControlService ]
    },
    NehubaLayerControlService,
    NehubaMeshService,
  ],
  changeDetection: ChangeDetectionStrategy.OnPush
Xiao Gui's avatar
Xiao Gui committed
})

export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy {
Xiao Gui's avatar
Xiao Gui committed

Xiao Gui's avatar
Xiao Gui committed
  private onhoverSegments: SxplrRegion[] = []
Xiao Gui's avatar
Xiao Gui committed
  private onDestroyCb: (() => void)[] = []
Xiao Gui's avatar
Xiao Gui committed

Xiao Gui's avatar
Xiao Gui committed
  public nehubaConfig: NehubaConfig
Xiao Gui's avatar
Xiao Gui committed
  ngOnDestroy(): void {
Xiao Gui's avatar
Xiao Gui committed
    while (this.onDestroyCb.length) this.onDestroyCb.pop()()
  }

  @Output()
  public viewerEvent = new EventEmitter<TViewerEvent<'nehuba'>>()
Xiao Gui's avatar
Xiao Gui committed
  constructor(
Xiao Gui's avatar
Xiao Gui committed
    private store$: Store<any>,
    @Optional() @Inject(CLICK_INTERCEPTOR_INJECTOR) clickInterceptor: ClickInterceptor,
Xiao Gui's avatar
Xiao Gui committed
  ){
Xiao Gui's avatar
Xiao Gui committed
    /**
     * define onclick behaviour
     */
    if (clickInterceptor) {
      const { deregister, register } = clickInterceptor
      const selOnhoverRegion = this.selectHoveredRegion.bind(this)
      register(selOnhoverRegion, { last: true })
fsdavid's avatar
fsdavid committed
      this.onDestroyCb.push(() => deregister(selOnhoverRegion))
Xiao Gui's avatar
Xiao Gui committed
    }

    /**
     * on hover segment
     */
    const onhovSegSub = this.store$.pipe(
Xiao Gui's avatar
Xiao Gui committed
      select(userInteraction.selectors.mousingOverRegions),
Xiao Gui's avatar
Xiao Gui committed
      distinctUntilChanged(),
    ).subscribe(arr => {
Xiao Gui's avatar
Xiao Gui committed
      this.onhoverSegments = arr
Xiao Gui's avatar
Xiao Gui committed
    })
    this.onDestroyCb.push(() => onhovSegSub.unsubscribe())
Xiao Gui's avatar
Xiao Gui committed
  }

  private selectHoveredRegion(ev: PointerEvent): boolean{
    /**
     * If label indicies are not defined by the ontology, it will be a string in the format of `{ngId}#{labelIndex}`
     */
    const trueOnhoverSegments = this.onhoverSegments && this.onhoverSegments.filter(v => typeof v === 'object')
    if (!trueOnhoverSegments || (trueOnhoverSegments.length === 0)) return true

    if (ev.ctrlKey) {
      this.store$.dispatch(
        atlasSelection.actions.toggleRegion({
          region: trueOnhoverSegments[0]
        })
      )
    } else {
      this.store$.dispatch(
        atlasSelection.actions.selectRegion({
          region: trueOnhoverSegments[0]
        })
      )
    }
Xiao Gui's avatar
Xiao Gui committed
  }