Skip to content
Snippets Groups Projects
Commit 02da8b5d authored by Xiao Gui's avatar Xiao Gui Committed by xgui3783
Browse files

WIP layer control, glyphicon working

parent e03ea6e0
No related branches found
No related tags found
No related merge requests found
import { Component, HostBinding, ViewChild, ViewContainerRef, ComponentFactoryResolver, ComponentFactory, OnDestroy, ElementRef, Injector, ComponentRef, AfterViewInit, OnInit, TemplateRef, HostListener, Renderer2 } from "@angular/core";
import { Store, select } from "@ngrx/store";
import { ViewerStateInterface, OPEN_SIDE_PANEL, CLOSE_SIDE_PANEL, isDefined,UNLOAD_DEDICATED_LAYER, FETCHED_SPATIAL_DATA, UPDATE_SPATIAL_DATA, TOGGLE_SIDE_PANEL } from "../services/stateStore.service";
import { Observable, Subscription, combineLatest } from "rxjs";
import { map, filter, distinctUntilChanged } from "rxjs/operators";
import { ViewerStateInterface, OPEN_SIDE_PANEL, CLOSE_SIDE_PANEL, isDefined,UNLOAD_DEDICATED_LAYER, FETCHED_SPATIAL_DATA, UPDATE_SPATIAL_DATA, TOGGLE_SIDE_PANEL, NgViewerStateInterface } from "../services/stateStore.service";
import { Observable, Subscription } from "rxjs";
import { map, filter, distinctUntilChanged, delay } from "rxjs/operators";
import { AtlasViewerDataService } from "./atlasViewer.dataService.service";
import { WidgetServices } from "./widgetUnit/widgetService.service";
import { LayoutMainSide } from "../layouts/mainside/mainside.component";
......@@ -38,7 +38,7 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
@ViewChild('databrowser', { read: ElementRef }) databrowser: ElementRef
@ViewChild('temporaryContainer', { read: ViewContainerRef }) temporaryContainer: ViewContainerRef
@ViewChild('toastContainer', { read: ViewContainerRef }) toastContainer: ViewContainerRef
@ViewChild('dedicatedViewerToast', { read: TemplateRef }) dedicatedViewerToast: TemplateRef<any>
// @ViewChild('dedicatedViewerToast', { read: TemplateRef }) dedicatedViewerToast: TemplateRef<any>
@ViewChild('floatingMouseContextualContainer', { read: ViewContainerRef }) floatingMouseContextualContainer: ViewContainerRef
@ViewChild('pluginFactory', { read: ViewContainerRef }) pluginViewContainerRef: ViewContainerRef
@ViewChild(LayoutMainSide) layoutMainSide: LayoutMainSide
......@@ -51,19 +51,20 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
meetsRequirement: boolean = true
toastComponentFactory: ComponentFactory<ToastComponent>
// databrowserComponentFactory: ComponentFactory<DataBrowserUI>
// databrowserComponentRef: ComponentRef<DataBrowserUI>
// private databrowserHostComponentRef: ComponentRef<WidgetUnit>
private dedicatedViewComponentRef: ComponentRef<ToastComponent>
public sidePanelView$: Observable<string|null>
private newViewer$: Observable<any>
public selectedRegions$: Observable<any[]>
public layersLoaded$: Observable<any[]>
public dedicatedView$: Observable<string | null>
public onhoverSegment$: Observable<string>
private subscriptions: Subscription[] = []
/* handlers for nglayer */
public ngLayerNames$ : Observable<any>
public ngLayers : NgLayerInterface[]
private disposeHandler : any
constructor(
private pluginService: PluginServices,
private rd2: Renderer2,
......@@ -74,12 +75,17 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
private constantsService: AtlasViewerConstantsServices,
public urlService: AtlasViewerURLService,
public apiService: AtlasViewerAPIServices,
private modalService: BsModalService,
private injector: Injector
private modalService: BsModalService
) {
this.toastComponentFactory = this.cfr.resolveComponentFactory(ToastComponent)
// this.databrowserComponentFactory = this.cfr.resolveComponentFactory(DataBrowserUI)
// this.databrowserComponentRef = this.databrowserComponentFactory.create(this.injector)
this.ngLayerNames$ = this.store.pipe(
select('viewerState'),
filter(state => isDefined(state) && isDefined(state.templateSelected)),
distinctUntilChanged((o,n) => o.templateSelected.name === n.templateSelected.name),
map(state => Object.keys(state.templateSelected.nehubaConfig.dataset.initialNgState.layers)),
delay(0)
)
this.sidePanelView$ = this.store.pipe(
select('uiState'),
......@@ -119,11 +125,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
''),
distinctUntilChanged()
)
this.layersLoaded$ = combineLatest(
this.newViewer$,
this.dedicatedView$
)
}
ngOnInit() {
......@@ -216,13 +217,20 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
return
}
this.dedicatedViewComponentRef = this.toastContainer.createComponent(this.toastComponentFactory)
// this.dedicatedViewComponentRef.instance.messageContainer.createEmbeddedView(this.dedicatedViewerToast)
this.dedicatedViewComponentRef.instance.message = `hello`
this.dedicatedViewComponentRef.instance.dismissable = true
this.dedicatedViewComponentRef.instance.timeout = 1000
})
)
this.subscriptions.push(
this.ngLayerNames$.subscribe(() => {
this.ngLayersChangeHandler()
this.disposeHandler = window['viewer'].layerManager.layersChanged.add(() => this.ngLayersChangeHandler())
window['viewer'].registerDisposer(this.disposeHandler)
})
)
this.subscriptions.push(
this.newViewer$.subscribe(template => {
this.darktheme = this.meetsRequirement ?
......@@ -239,19 +247,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
totalResults : 0
})
// if (this.databrowserHostComponentRef) {
// // this.databrowserHostComponentRef.instance.container.detach(0)
// // this.temporaryContainer.insert(this.databrowserComponentRef.hostView)
// } else {
// this.databrowserHostComponentRef =
// this.widgetServices.addNewWidget(this.databrowserComponentRef, {
// title: 'Data Browser',
// exitable: false,
// state: 'docked',
// persistency:true
// })
// }
this.widgetServices.clearAllWidgets()
})
)
......@@ -379,6 +374,18 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
return true
}
ngLayersChangeHandler(){
console.log('handle layer change',window['viewer'].layerManager.managedLayers)
this.ngLayers = (window['viewer'].layerManager.managedLayers as any[]).map(obj => ({
name : obj.name,
type : obj.initialSpecification.type,
source : obj.sourceUrl,
visible : obj.visible
}) as NgLayerInterface)
}
/* obsolete soon */
manualPanelToggle(show: boolean) {
this.store.dispatch({
......@@ -427,4 +434,13 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
get floatingMouseContextualContainerTransform() {
return `translate(${this.mousePos[0]}px,${this.mousePos[1]}px)`
}
}
\ No newline at end of file
}
export interface NgLayerInterface{
name : string
visible : boolean
source : string
type : string // image | segmentation | etc ...
transform? : [[number, number, number, number],[number, number, number, number],[number, number, number, number],[number, number, number, number]] | null
// colormap : string
}
......@@ -37,7 +37,11 @@
Layer Browser
</div>
<div body>
<layer-browser [layers] = "layersLoaded$ | async | newViewerDisctinctViewToLayer"></layer-browser>
<layer-browser
()
[lockedLayers] = "ngLayerNames$ | async"
[ngLayers] = "ngLayers">
</layer-browser>
</div>
</panel-component>
</div>
......@@ -85,15 +89,15 @@
<span
placement = "left"
[tooltip] = "!(layersLoaded$ | async | newViewerDisctinctViewToLayer) ? '' : (((layersLoaded$ | async | newViewerDisctinctViewToLayer).length === 0 ? 'No' : (layersLoaded$ | async | newViewerDisctinctViewToLayer).length) + ' loaded layer' + ((layersLoaded$ | async | newViewerDisctinctViewToLayer).length > 1 ? 's' : ''))"
[tooltip] = "!ngLayers ? '' : ((ngLayers.length === 0 ? 'No' : ngLayers.length) + ' loaded layer' + (ngLayers.length > 1 ? 's' : ''))"
[ngClass] = "{'active-tab' : (sidePanelView$ | async) === 'ngLayer'}"
(click) = "toggleSidePanel('ngLayer')"
class = "tabContainer">
<span [@newEvent] = "layersLoaded$ | async | newViewerDisctinctViewToLayer" class = "highlightContainer">
<span [@newEvent] = "ngLayers" class = "highlightContainer">
</span>
<i class = "glyphicon glyphicon-list"></i>
<span class = "badge" *ngIf = "(layersLoaded$ | async | newViewerDisctinctViewToLayer).length > 0">
{{ (layersLoaded$ | async | newViewerDisctinctViewToLayer).length }}
<span class = "badge" *ngIf = "ngLayers && ngLayers.length > 0">
{{ ngLayers.length }}
</span>
</span>
......
......@@ -135,3 +135,8 @@ markdown-dom pre code
{
background-color:rgba(150,150,0,0.5);
}
.glyphicon-none
{
width:1em;
}
\ No newline at end of file
import { Component, Input, OnDestroy } from "@angular/core";
import { AtlasViewerLayerInterface } from "../../util/pipes/newViewerDistinctViewToLayer.pipe";
import { Observable, Subscription } from "rxjs";
import { isDefined, ViewerStateInterface } from "../../services/stateStore.service";
import { Store, select } from "@ngrx/store";
import { filter, delay, distinctUntilChanged } from "rxjs/operators";
import { Component, Input, Output, EventEmitter } from "@angular/core";
import { NgLayerInterface } from "../../atlasViewer/atlasViewer.component";
@Component({
selector : 'layer-browser',
......@@ -12,67 +7,33 @@ import { filter, delay, distinctUntilChanged } from "rxjs/operators";
styleUrls : [ './layerbrowser.style.css' ]
})
export class LayerBrowser implements OnDestroy{
@Input() layers : AtlasViewerLayerInterface[] = []
ngLayers : NgLayerInterface[] = []
newViewer$ : Observable<any>
subscription : Subscription
disposeHandler : any
constructor(private store : Store<ViewerStateInterface>){
this.newViewer$ = this.store.pipe(
select('viewerState'),
filter(state=>isDefined(state) && isDefined(state.templateSelected)),
distinctUntilChanged((o,n) => o.templateSelected.name === n.templateSelected.name)
)
this.subscription = this.newViewer$.pipe(
delay(0)
).subscribe(() => {
this.layerChangedHandler()
this.disposeHandler = window['viewer'].layerManager.layersChanged.add(() => this.layerChangedHandler())
window['viewer'].registerDisposer(this.disposeHandler)
})
}
ngOnDestroy(){
this.disposeHandler()
this.subscription.unsubscribe()
}
layerChangedHandler(){
console.log('handle layer change',window['viewer'].layerManager.managedLayers)
export class LayerBrowser {
this.ngLayers = (window['viewer'].layerManager.managedLayers as any[]).map(obj => ({
name : obj.name,
type : obj.initialSpecification.type,
source : obj.sourceUrl,
visible : obj.visible
}) as NgLayerInterface)
}
@Input() ngLayers : NgLayerInterface[] = []
@Input() lockedLayers : string[] = []
public muteClass(layer:AtlasViewerLayerInterface):boolean{
if(this.layers.length === 0)
return false
return layer.type === 'mixable'
? this.layers.some(l => l.type === 'nonmixable')
: false
}
@Output() removeLayerEmitter : EventEmitter<string> = new EventEmitter()
public classVisible(layer:NgLayerInterface):boolean{
public classVisible(layer:any):boolean{
return typeof layer.visible === 'undefined'
? true
: layer.visible
}
}
interface NgLayerInterface{
name : string
visible : boolean
source : string
type : string // image | segmentation | etc ...
transform? : [[number, number, number, number],[number, number, number, number],[number, number, number, number],[number, number, number, number]] | null
// colormap : string
checkLocked(ngLayer:NgLayerInterface):boolean{
if(!this.lockedLayers){
/* locked layer undefined. always return true for locked layer check */
return true
}else
return this.lockedLayers.findIndex(l => l === ngLayer.name) >= 0
}
removeLayer(layer:any){
if(this.checkLocked(layer)){
console.warn('this layer is locked and cannot be removed')
}else{
console.log(layer)
// this.removeLayerEmitter.emit()
}
}
}
......@@ -21,6 +21,17 @@ div[body]
.muted
{
text-decoration: line-through;
opacity : 0.5;
}
.muted-text
{
text-decoration: line-through;
}
.layerContainer
{
display: flex;
flex-direction: row;
align-items: center;
}
\ No newline at end of file
<div container>
<panel-component
[ngClass] = "{'muted' : !classVisible(ngLayer)}"
class = "layerContainer"
<div
class="layerContainer"
*ngFor = "let ngLayer of ngLayers">
<div heading>
{{ ngLayer.name }} : {{ ngLayer.type }}
</div>
<div>
<i
class = "glyphicon"
[ngClass] = "ngLayer.visible ? 'glyphicon-eye-open' : 'glyphicon-eye-close'">
<div body>
{{ ngLayer.source }}
</i>
</div>
</panel-component>
<!-- <panel-component
[ngClass] = "{'muted' : muteClass(layer)}"
class = "layerContainer"
*ngFor = "let layer of layers">
<div heading>
{{ layer.name }}
<div>
<i
container = "body"
placement = "bottom"
[tooltip] = "ngLayer.type === 'segmentation' ? null : 'only segmentation layer can hide/show segments'"
class = "glyphicon"
[ngClass] = "ngLayer.type === 'segmentation' ? 'glyphicon-th-large' : 'glyphicon-lock muted' ">
</i>
</div>
<div body>
{{ layer.url }}
<div>
<i
(click) = "removeLayer(ngLayer)"
container = "body"
placement = "bottom"
[tooltip] = "checkLocked(ngLayer) ? 'base layers cannot be removed' : null"
class = "glyphicon"
[ngClass] = "checkLocked(ngLayer) ? 'glyphicon-lock muted' : 'glyphicon-remove-circle'">
</i>
</div>
</panel-component> -->
<panel-component
[ngClass] = "{'muted-text muted' : !classVisible(ngLayer)}">
<div heading>
{{ ngLayer.name }} : {{ ngLayer.type }}
</div>
<div body>
{{ ngLayer.source }}
</div>
</panel-component>
</div>
</div>
\ No newline at end of file
......@@ -316,7 +316,6 @@ export class NehubaContainer implements OnInit, OnDestroy{
if(newLayers.length > 0){
const newLayersObj:any = {}
newLayers.forEach(obj => newLayersObj[obj.name] = obj)
debugger
this.nehubaViewer.loadLayer(newLayersObj)
this.ngLayersRegister.layers = this.ngLayersRegister.layers.concat(newLayers)
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment