/** * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal */ import * as React from 'react'; import { HierarchyRef, ModelRef, TrajectoryRef } from '../../mol-plugin-state/manager/structure/hierarchy-state'; import { CollapsableControls, CollapsableState } from '../base'; import { ActionMenu } from '../controls/action-menu'; import { Icon } from '../controls/icons'; interface StructureSourceControlState extends CollapsableState { isBusy: boolean, show?: 'hierarchy' | 'actions' } export class StructureSourceControls extends CollapsableControls<{}, StructureSourceControlState> { protected defaultState(): StructureSourceControlState { return { header: 'Source', isCollapsed: false, isBusy: false }; } componentDidMount() { this.subscribe(this.plugin.managers.structure.hierarchy.behaviors.current, () => this.forceUpdate()); this.subscribe(this.plugin.behaviors.state.isBusy, v => { this.setState({ isBusy: v }) }); } private item = (ref: HierarchyRef) => { const selected = this.plugin.managers.structure.hierarchy.currentSeletionSet; return { label: ref.cell.obj?.label, selected: selected.has(ref.cell.transform.ref), value: [ref] } as ActionMenu.Item; } getTrajectoryItems = (t: TrajectoryRef): ActionMenu.Items => { if (t.models.length === 0) return this.item(t); return [t.cell.obj?.label!, ...t.models.map(this.getModelItems)]; } private getModelItems = (m: ModelRef): ActionMenu.Items => { if (m.structures.length === 0) return this.item(m); if (m.structures.length === 1) { const selected = this.plugin.managers.structure.hierarchy.currentSeletionSet; const ref = m.structures[0]; return { label: `${m.cell.obj?.label} | ${ref.cell.obj?.label}`, selected: selected.has(ref.cell.transform.ref), value: [m, ref] } as ActionMenu.Item; } return [m.cell.obj?.label!, ...m.structures.map(this.item)]; } get hierarchyItems() { return this.plugin.managers.structure.hierarchy.state.current.trajectories.map(this.getTrajectoryItems); } get label() { const { structures, models, trajectories } = this.plugin.managers.structure.hierarchy.state.current; // TODO: better labels if (structures.length === 1) { const s = structures[0]; if (s.model.trajectory.models.length === 1) return s.cell.obj?.data.label; return `${s.model.cell.obj?.label} | ${s.cell.obj?.data.label}`; } if (structures.length > 1) { return `${structures.length} structures`; } if (models.length > 0) { return `${models.length} model(s)`; } if (trajectories.length > 0) { return `${trajectories.length} trajectory(s)`; } return 'No structure loaded'; } selectHierarchy: ActionMenu.OnSelectMany = (items) => { if (!items || items.length === 0) return 0; const refs: HierarchyRef[] = []; for (const i of items) { for (const r of (i.value as HierarchyRef[])) refs.push(r); } this.plugin.managers.structure.hierarchy.updateCurrent(refs, items[0].selected ? 'remove' : 'add') } toggleHierarchy = () => this.setState({ show: this.state.show !== 'hierarchy' ? 'hierarchy' : void 0 }); toggleActions = () => this.setState({ show: this.state.show !== 'actions' ? 'actions' : void 0 }); get actions() { const ret: ActionMenu.Items = [ ActionMenu.Item('Show all models', () => this.plugin.managers.structure.hierarchy.createAllModels(this.plugin.managers.structure.hierarchy.state.current.trajectories[0])) ]; return ret; } selectAction: ActionMenu.OnSelect = item => { if (!item) return; this.setState({ show: void 0 }); (item?.value as any)(); } renderControls() { return <>
{this.state.show === 'hierarchy' && } {this.state.show === 'actions' && } ; } }