123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- /**
- * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- * @author David Sehnal <david.sehnal@gmail.com>
- */
- import * as React from 'react';
- import { HierarchyRef } from '../../mol-plugin-state/manager/structure/hierarchy-state';
- import { PluginCommands } from '../../mol-plugin/commands';
- import { State } from '../../mol-state';
- import { PurePluginUIComponent } from '../base';
- import { IconButton } from '../controls/common';
- import { UpdateTransformControl } from '../state/update-transform';
- export class GenericEntryListControls extends PurePluginUIComponent {
- get current() {
- return this.plugin.managers.structure.hierarchy.behaviors.selection;
- }
- componentDidMount() {
- this.subscribe(this.current, () => this.forceUpdate());
- }
- get unitcell() {
- const { selection } = this.plugin.managers.structure.hierarchy;
- if (selection.structures.length === 0) return null;
- const refs = [];
- for (const s of selection.structures) {
- const model = s.model;
- if (model?.unitcell && model.unitcell?.cell.obj) refs.push(model.unitcell);
- }
- if (refs.length === 0) return null;
- return <GenericEntry refs={refs} labelMultiple='Unitcells' />;
- }
- get customControls(): JSX.Element[] | null {
- const controls: JSX.Element[] = []
- this.plugin.genericRepresentationControls.forEach((provider, key) => {
- const [refs, labelMultiple] = provider(this.plugin.managers.structure.hierarchy.selection)
- if (refs.length > 0) {
- controls.push(<div key={key}>
- <GenericEntry refs={refs} labelMultiple={labelMultiple} />
- </div>)
- }
- })
- return controls.length > 0 ? controls : null
- }
- render() {
- return <>
- <div style={{ marginTop: '6px' }}>
- {this.unitcell}
- {this.customControls}
- </div>
- </>
- }
- }
- export class GenericEntry<T extends HierarchyRef> extends PurePluginUIComponent<{ refs: T[], labelMultiple?: string }, { showOptions: boolean }> {
- state = { showOptions: false }
- componentDidMount() {
- this.subscribe(this.plugin.events.state.cell.stateUpdated, e => {
- if (State.ObjectEvent.isCell(e, this.pivot?.cell)) this.forceUpdate();
- });
- }
- get pivot() { return this.props.refs[0]; }
- toggleVisibility = (e: React.MouseEvent<HTMLElement>) => {
- e.preventDefault();
- this.plugin.managers.structure.hierarchy.toggleVisibility(this.props.refs);
- e.currentTarget.blur();
- }
- highlight = (e: React.MouseEvent<HTMLElement>) => {
- e.preventDefault();
- PluginCommands.Interactivity.Object.Highlight(this.plugin, {
- state: this.pivot.cell.parent,
- ref: this.props.refs.map(c => c.cell.transform.ref)
- });
- }
- clearHighlight = (e: React.MouseEvent<HTMLElement>) => {
- e.preventDefault();
- PluginCommands.Interactivity.ClearHighlights(this.plugin);
- }
- focus = (e: React.MouseEvent<HTMLElement>) => {
- e.preventDefault();
- let allHidden = true;
- for (const uc of this.props.refs) {
- if (!uc.cell.state.isHidden) {
- allHidden = false;
- break;
- }
- }
- if (allHidden) {
- this.plugin.managers.structure.hierarchy.toggleVisibility(this.props.refs, 'show');
- }
- const loci = [];
- for (const uc of this.props.refs) {
- if (uc.cell.state.isHidden) {
- continue;
- }
- const l = uc.cell.obj?.data.repr.getLoci()
- if (l) loci.push(l);
- }
- this.plugin.managers.camera.focusLoci(loci);
- }
- toggleOptions = () => this.setState({ showOptions: !this.state.showOptions })
- render() {
- const { refs, labelMultiple } = this.props;
- if (refs.length === 0) return null;
- const pivot = refs[0];
- let label, description;
- if (refs.length === 1) {
- const { obj } = pivot.cell;
- if (!obj) return null;
- label = obj?.label;
- description = obj?.description;
- } else {
- label = `${refs.length} ${labelMultiple || 'Objects'}`;
- }
- return <>
- <div className='msp-btn-row-group'>
- <button className='msp-form-control msp-control-button-label' title={`${label}. Click to focus.`} onClick={this.focus} onMouseEnter={this.highlight} onMouseLeave={this.clearHighlight} style={{ textAlign: 'left' }}>
- {label} <small>{description}</small>
- </button>
- <IconButton customClass='msp-form-control' onClick={this.toggleVisibility} icon='visual-visibility' toggleState={!pivot.cell.state.isHidden} title={`${pivot.cell.state.isHidden ? 'Show' : 'Hide'}`} small style={{ flex: '0 0 32px', padding: 0 }} />
- {refs.length === 1 && <IconButton customClass='msp-form-control' onClick={this.toggleOptions} icon='dot-3' title='Options' toggleState={this.state.showOptions} style={{ flex: '0 0 32px', padding: 0 }} />}
- </div>
- {(refs.length === 1 && this.state.showOptions) && <>
- <div className='msp-control-offset'>
- <UpdateTransformControl state={pivot.cell.parent} transform={pivot.cell.transform} customHeader='none' autoHideApply />
- </div>
- </>}
- </>;
- }
- }
|