diff --git a/package-lock.json b/package-lock.json index d2e7d63268fff4f1f9d7a7c3db13fcb269dc59e8..ebc7133de32cbf488cf1755857f5be46fa759a44 100644 Binary files a/package-lock.json and b/package-lock.json differ diff --git a/package.json b/package.json index 6348138ccbe78b5a33286cabba9b70179fea048a..b2ec6cd349122dca3425b6c3311dfc673d211f73 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,7 @@ "react-dom": "^17.0.1", "rxjs": "^6.6.3", "swagger-ui-dist": "^3.37.2", - "tslib": "^2.0.3", + "tslib": "^2.1.0", "util.promisify": "^1.0.1", "xhr2": "^0.2.0" } diff --git a/src/apps/docking-viewer/index.ts b/src/apps/docking-viewer/index.ts index c14aa2504f2b4c910af530f28c80a246e409ee6a..c22b42be4f0d02b6e6bf8157d557fca29b9f059a 100644 --- a/src/apps/docking-viewer/index.ts +++ b/src/apps/docking-viewer/index.ts @@ -5,31 +5,32 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import '../../mol-util/polyfill'; -import { createPlugin } from '../../mol-plugin'; -import { DefaultPluginSpec } from '../../mol-plugin/spec'; -import './index.html'; -import { PluginContext } from '../../mol-plugin/context'; +import { Structure } from '../../mol-model/structure'; +import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory'; +import { PluginStateObject as PSO, PluginStateTransform } from '../../mol-plugin-state/objects'; +import { createPlugin } from '../../mol-plugin-ui'; +import { PluginUIContext } from '../../mol-plugin-ui/context'; +import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout'; +import { DefaultPluginUISpec, PluginUISpec } from '../../mol-plugin-ui/spec'; +import { PluginBehaviors } from '../../mol-plugin/behavior'; import { PluginCommands } from '../../mol-plugin/commands'; -import { PluginSpec } from '../../mol-plugin/spec'; import { PluginConfig } from '../../mol-plugin/config'; -import { ObjectKeys } from '../../mol-util/type-helpers'; -import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout'; -import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory'; -import { Structure } from '../../mol-model/structure'; -import { PluginStateTransform, PluginStateObject as PSO } from '../../mol-plugin-state/objects'; -import { ParamDefinition as PD } from '../../mol-util/param-definition'; -import { Task } from '../../mol-task'; +import { PluginSpec } from '../../mol-plugin/spec'; import { StateObject } from '../../mol-state'; -import { ViewportComponent, StructurePreset, ShowButtons } from './viewport'; -import { PluginBehaviors } from '../../mol-plugin/behavior'; -import { ColorNames } from '../../mol-util/color/names'; +import { Task } from '../../mol-task'; import { Color } from '../../mol-util/color'; +import { ColorNames } from '../../mol-util/color/names'; +import { ParamDefinition as PD } from '../../mol-util/param-definition'; +import '../../mol-util/polyfill'; +import { ObjectKeys } from '../../mol-util/type-helpers'; +import './index.html'; +import { ShowButtons, StructurePreset, ViewportComponent } from './viewport'; require('mol-plugin-ui/skin/light.scss'); export { PLUGIN_VERSION as version } from '../../mol-plugin/version'; -export { setProductionMode, setDebugMode } from '../../mol-util/debug'; +export { setDebugMode, setProductionMode } from '../../mol-util/debug'; +export { Viewer as DockingViewer }; const DefaultViewerOptions = { extensions: ObjectKeys({}), @@ -53,7 +54,7 @@ const DefaultViewerOptions = { }; class Viewer { - plugin: PluginContext + plugin: PluginUIContext constructor(elementOrId: string | HTMLElement, colors = [Color(0x992211), Color(0xDDDDDD)], showButtons = true) { const o = { ...DefaultViewerOptions, ...{ @@ -70,10 +71,10 @@ class Viewer { viewportShowSelectionMode: false, viewportShowAnimation: false, } }; - const defaultSpec = DefaultPluginSpec(); + const defaultSpec = DefaultPluginUISpec(); - const spec: PluginSpec = { - actions: [...defaultSpec.actions], + const spec: PluginUISpec = { + actions: defaultSpec.actions, behaviors: [ PluginSpec.Behavior(PluginBehaviors.Representation.HighlightLoci, { mark: false }), PluginSpec.Behavior(PluginBehaviors.Representation.DefaultLociLabelProvider), @@ -83,7 +84,7 @@ class Viewer { PluginSpec.Behavior(PluginBehaviors.CustomProps.Interactions), PluginSpec.Behavior(PluginBehaviors.CustomProps.SecondaryStructure), ], - animations: [...defaultSpec.animations || []], + animations: defaultSpec.animations, customParamEditors: defaultSpec.customParamEditors, layout: { initial: { @@ -91,15 +92,15 @@ class Viewer { showControls: o.layoutShowControls, controlsDisplay: o.layoutControlsDisplay, }, + }, + components: { + ...defaultSpec.components, controls: { - ...defaultSpec.layout && defaultSpec.layout.controls, + ...defaultSpec.components?.controls, top: o.layoutShowSequence ? undefined : 'none', bottom: o.layoutShowLog ? undefined : 'none', left: o.layoutShowLeftPanel ? undefined : 'none', - } - }, - components: { - ...defaultSpec.components, + }, remoteState: o.layoutShowRemoteState ? 'default' : 'none', viewport: { view: ViewportComponent @@ -210,4 +211,3 @@ const MergeStructures = PluginStateTransform.BuiltIn({ }); (window as any).DockingViewer = Viewer; -export { Viewer as DockingViewer }; \ No newline at end of file diff --git a/src/apps/viewer/index.ts b/src/apps/viewer/index.ts index 2b68a525ebe45adb1ea8fae2b4827e76e16d39f8..3d25b6f43c8d5efd0fd4e7b0351ad156fb74ce11 100644 --- a/src/apps/viewer/index.ts +++ b/src/apps/viewer/index.ts @@ -5,43 +5,43 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import '../../mol-util/polyfill'; -import { createPlugin } from '../../mol-plugin'; -import { DefaultPluginSpec } from '../../mol-plugin/spec'; -import './index.html'; -import './embedded.html'; -import './favicon.ico'; -import { PluginContext } from '../../mol-plugin/context'; -import { PluginCommands } from '../../mol-plugin/commands'; -import { PluginSpec } from '../../mol-plugin/spec'; -import { DownloadStructure, PdbDownloadProvider } from '../../mol-plugin-state/actions/structure'; -import { PluginConfig } from '../../mol-plugin/config'; -import { CellPack } from '../../extensions/cellpack'; -import { RCSBAssemblySymmetry, RCSBValidationReport } from '../../extensions/rcsb'; -import { PDBeStructureQualityReport } from '../../extensions/pdbe'; -import { Asset } from '../../mol-util/assets'; -import { ObjectKeys } from '../../mol-util/type-helpers'; -import { PluginState } from '../../mol-plugin/state'; -import { DownloadDensity } from '../../mol-plugin-state/actions/volume'; -import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout'; -import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory'; import { ANVILMembraneOrientation } from '../../extensions/anvil/behavior'; +import { CellPack } from '../../extensions/cellpack'; import { DnatcoConfalPyramids } from '../../extensions/dnatco'; import { G3DFormat, G3dProvider } from '../../extensions/g3d/format'; +import { Mp4Export } from '../../extensions/mp4-export'; +import { PDBeStructureQualityReport } from '../../extensions/pdbe'; +import { RCSBAssemblySymmetry, RCSBValidationReport } from '../../extensions/rcsb'; +import { DownloadStructure, PdbDownloadProvider } from '../../mol-plugin-state/actions/structure'; +import { DownloadDensity } from '../../mol-plugin-state/actions/volume'; +import { StructureRepresentationPresetProvider } from '../../mol-plugin-state/builder/structure/representation-preset'; import { DataFormatProvider } from '../../mol-plugin-state/formats/provider'; +import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory'; import { BuildInVolumeFormat } from '../../mol-plugin-state/formats/volume'; -import { Color } from '../../mol-util/color'; -import { StateObjectSelector } from '../../mol-state'; +import { createVolumeRepresentationParams } from '../../mol-plugin-state/helpers/volume-representation-params'; import { PluginStateObject } from '../../mol-plugin-state/objects'; import { StateTransforms } from '../../mol-plugin-state/transforms'; -import { createVolumeRepresentationParams } from '../../mol-plugin-state/helpers/volume-representation-params'; -import { Mp4Export } from '../../extensions/mp4-export'; -import { StructureRepresentationPresetProvider } from '../../mol-plugin-state/builder/structure/representation-preset'; +import { createPlugin } from '../../mol-plugin-ui'; +import { PluginUIContext } from '../../mol-plugin-ui/context'; +import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout'; +import { DefaultPluginUISpec, PluginUISpec } from '../../mol-plugin-ui/spec'; +import { PluginCommands } from '../../mol-plugin/commands'; +import { PluginConfig } from '../../mol-plugin/config'; +import { PluginSpec } from '../../mol-plugin/spec'; +import { PluginState } from '../../mol-plugin/state'; +import { StateObjectSelector } from '../../mol-state'; +import { Asset } from '../../mol-util/assets'; +import { Color } from '../../mol-util/color'; +import '../../mol-util/polyfill'; +import { ObjectKeys } from '../../mol-util/type-helpers'; +import './embedded.html'; +import './favicon.ico'; +import './index.html'; require('mol-plugin-ui/skin/light.scss'); export { PLUGIN_VERSION as version } from '../../mol-plugin/version'; -export { setProductionMode, setDebugMode } from '../../mol-util/debug'; +export { setDebugMode, setProductionMode } from '../../mol-util/debug'; const CustomFormats = [ ['g3d', G3dProvider] as const @@ -86,14 +86,14 @@ const DefaultViewerOptions = { type ViewerOptions = typeof DefaultViewerOptions; export class Viewer { - plugin: PluginContext + plugin: PluginUIContext constructor(elementOrId: string | HTMLElement, options: Partial<ViewerOptions> = {}) { const o = { ...DefaultViewerOptions, ...options }; - const defaultSpec = DefaultPluginSpec(); + const defaultSpec = DefaultPluginUISpec(); - const spec: PluginSpec = { - actions: [...defaultSpec.actions], + const spec: PluginUISpec = { + actions: defaultSpec.actions, behaviors: [ ...defaultSpec.behaviors, ...o.extensions.map(e => Extensions[e]), @@ -107,15 +107,15 @@ export class Viewer { showControls: o.layoutShowControls, controlsDisplay: o.layoutControlsDisplay, }, + }, + components: { + ...defaultSpec.components, controls: { - ...defaultSpec.layout && defaultSpec.layout.controls, + ...defaultSpec.components?.controls, top: o.layoutShowSequence ? undefined : 'none', bottom: o.layoutShowLog ? undefined : 'none', left: o.layoutShowLeftPanel ? undefined : 'none', - } - }, - components: { - ...defaultSpec.components, + }, remoteState: o.layoutShowRemoteState ? 'default' : 'none', }, config: [ diff --git a/src/cli/state-docs/index.ts b/src/cli/state-docs/index.ts index 36ed9a90370785d0c9cfe3a03667fd0c510a6c00..287e571c3c28749f263055fa4c148be18ad03d73 100644 --- a/src/cli/state-docs/index.ts +++ b/src/cli/state-docs/index.ts @@ -18,7 +18,6 @@ _.StateTransforms.Data.Download.id; // Empty plugin context const ctx = new PluginContext({ - actions: [], behaviors: [] }); diff --git a/src/examples/alpha-orbitals/index.ts b/src/examples/alpha-orbitals/index.ts index 97c766b956fd28241b4bc4a63e073188d9f0388a..645ab2e4d60a47633fa10f724eb17d39de10f07e 100644 --- a/src/examples/alpha-orbitals/index.ts +++ b/src/examples/alpha-orbitals/index.ts @@ -4,25 +4,25 @@ * @author David Sehnal <david.sehnal@gmail.com> */ +import { BehaviorSubject } from 'rxjs'; +import { debounceTime, skip } from 'rxjs/operators'; +import { AlphaOrbital, Basis } from '../../extensions/alpha-orbitals/data-model'; import { SphericalBasisOrder } from '../../extensions/alpha-orbitals/spherical-functions'; import { BasisAndOrbitals, CreateOrbitalDensityVolume, CreateOrbitalRepresentation3D, CreateOrbitalVolume, StaticBasisAndOrbitals } from '../../extensions/alpha-orbitals/transforms'; -import { createPluginAsync } from '../../mol-plugin'; -import { DefaultPluginSpec } from '../../mol-plugin/spec'; +import { canComputeGrid3dOnGPU } from '../../mol-gl/compute/grid3d'; import { PluginStateObject } from '../../mol-plugin-state/objects'; +import { createPluginAsync } from '../../mol-plugin-ui'; +import { PluginUIContext } from '../../mol-plugin-ui/context'; +import { DefaultPluginUISpec } from '../../mol-plugin-ui/spec'; +import { PluginCommands } from '../../mol-plugin/commands'; import { PluginConfig } from '../../mol-plugin/config'; -import { PluginContext } from '../../mol-plugin/context'; import { StateObjectSelector, StateTransformer } from '../../mol-state'; import { Color } from '../../mol-util/color'; import { ColorNames } from '../../mol-util/color/names'; import { ParamDefinition } from '../../mol-util/param-definition'; import { mountControls } from './controls'; import { DemoMoleculeSDF, DemoOrbitals } from './example-data'; -import { BehaviorSubject } from 'rxjs'; -import { debounceTime, skip } from 'rxjs/operators'; import './index.html'; -import { Basis, AlphaOrbital } from '../../extensions/alpha-orbitals/data-model'; -import { PluginCommands } from '../../mol-plugin/commands'; -import { canComputeGrid3dOnGPU } from '../../mol-gl/compute/grid3d'; require('mol-plugin-ui/skin/light.scss'); interface DemoInput { @@ -50,10 +50,10 @@ type Selectors = { } export class AlphaOrbitalsExample { - plugin: PluginContext; + plugin: PluginUIContext; async init(target: string | HTMLElement) { - const defaultSpec = DefaultPluginSpec(); + const defaultSpec = DefaultPluginUISpec(); this.plugin = await createPluginAsync(typeof target === 'string' ? document.getElementById(target)! : target, { ...defaultSpec, layout: { @@ -61,15 +61,13 @@ export class AlphaOrbitalsExample { isExpanded: false, showControls: false }, - controls: { left: 'none', right: 'none', top: 'none', bottom: 'none' }, }, components: { - viewport: { - canvas3d: { - camera: { - helper: { axes: { name: 'off', params: { } } } - } - } + controls: { left: 'none', right: 'none', top: 'none', bottom: 'none' }, + }, + canvas3d: { + camera: { + helper: { axes: { name: 'off', params: { } } } } }, config: [ diff --git a/src/examples/basic-wrapper/index.ts b/src/examples/basic-wrapper/index.ts index 8345a5df8ef076b38348d1f4309421394956b187..68f8708736e2c516400b3d69d4fd38eea89d9d63 100644 --- a/src/examples/basic-wrapper/index.ts +++ b/src/examples/basic-wrapper/index.ts @@ -4,39 +4,36 @@ * @author David Sehnal <david.sehnal@gmail.com> */ +import { PDBeStructureQualityReport } from '../../extensions/pdbe'; import { EmptyLoci } from '../../mol-model/loci'; import { StructureSelection } from '../../mol-model/structure'; -import { createPlugin } from '../../mol-plugin'; -import { DefaultPluginSpec } from '../../mol-plugin/spec'; import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in/model-index'; import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory'; +import { createPlugin } from '../../mol-plugin-ui'; +import { PluginUIContext } from '../../mol-plugin-ui/context'; +import { DefaultPluginUISpec } from '../../mol-plugin-ui/spec'; import { PluginCommands } from '../../mol-plugin/commands'; -import { PluginContext } from '../../mol-plugin/context'; import { Script } from '../../mol-script/script'; +import { Asset } from '../../mol-util/assets'; import { Color } from '../../mol-util/color'; import { StripedResidues } from './coloring'; import { CustomToastMessage } from './controls'; import './index.html'; import { buildStaticSuperposition, dynamicSuperpositionTest, StaticSuperpositionTestData } from './superposition'; -import { PDBeStructureQualityReport } from '../../extensions/pdbe'; -import { Asset } from '../../mol-util/assets'; require('mol-plugin-ui/skin/light.scss'); type LoadParams = { url: string, format?: BuiltInTrajectoryFormat, isBinary?: boolean, assemblyId?: string } class BasicWrapper { - plugin: PluginContext; + plugin: PluginUIContext; init(target: string | HTMLElement) { this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, { - ...DefaultPluginSpec(), + ...DefaultPluginUISpec(), layout: { initial: { isExpanded: false, showControls: false - }, - controls: { - // left: 'none' } }, components: { diff --git a/src/examples/lighting/index.ts b/src/examples/lighting/index.ts index ec6cd8a032d5b81671e923e79eea7335396d1a22..188f99ab9837d226efa65e0e63e2f12fe089d3c3 100644 --- a/src/examples/lighting/index.ts +++ b/src/examples/lighting/index.ts @@ -5,13 +5,13 @@ */ import { Canvas3DProps } from '../../mol-canvas3d/canvas3d'; -import { createPlugin } from '../../mol-plugin'; -import { DefaultPluginSpec } from '../../mol-plugin/spec'; import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory'; +import { createPlugin } from '../../mol-plugin-ui'; +import { PluginUIContext } from '../../mol-plugin-ui/context'; +import { DefaultPluginUISpec } from '../../mol-plugin-ui/spec'; import { PluginCommands } from '../../mol-plugin/commands'; -import { PluginContext } from '../../mol-plugin/context'; -import './index.html'; import { Asset } from '../../mol-util/assets'; +import './index.html'; require('mol-plugin-ui/skin/light.scss'); type LoadParams = { url: string, format?: BuiltInTrajectoryFormat, isBinary?: boolean, assemblyId?: string } @@ -62,7 +62,7 @@ const Canvas3DPresets = { type Canvas3DPreset = keyof typeof Canvas3DPresets class LightingDemo { - plugin: PluginContext; + plugin: PluginUIContext; private radius = 5; private bias = 1.1; @@ -70,12 +70,14 @@ class LightingDemo { init(target: string | HTMLElement) { this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, { - ...DefaultPluginSpec(), + ...DefaultPluginUISpec(), layout: { initial: { isExpanded: false, showControls: false }, + }, + components: { controls: { left: 'none', right: 'none', top: 'none', bottom: 'none' } } }); diff --git a/src/examples/proteopedia-wrapper/index.ts b/src/examples/proteopedia-wrapper/index.ts index 68bb687837c7b56e51107d71d8391107e8037f17..a322fc8aa1699dd94aa51c337ed0a5b8b1bef79a 100644 --- a/src/examples/proteopedia-wrapper/index.ts +++ b/src/examples/proteopedia-wrapper/index.ts @@ -6,15 +6,15 @@ import * as ReactDOM from 'react-dom'; import { Canvas3DProps, DefaultCanvas3DParams } from '../../mol-canvas3d/canvas3d'; -import { createPlugin } from '../../mol-plugin'; -import { DefaultPluginSpec } from '../../mol-plugin/spec'; import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in/model-index'; import { createStructureRepresentationParams } from '../../mol-plugin-state/helpers/structure-representation-params'; import { PluginStateObject, PluginStateObject as PSO } from '../../mol-plugin-state/objects'; import { StateTransforms } from '../../mol-plugin-state/transforms'; +import { createPlugin } from '../../mol-plugin-ui'; +import { PluginUIContext } from '../../mol-plugin-ui/context'; +import { DefaultPluginUISpec } from '../../mol-plugin-ui/spec'; import { CreateVolumeStreamingInfo, InitVolumeStreaming } from '../../mol-plugin/behavior/dynamic/volume-streaming/transformers'; import { PluginCommands } from '../../mol-plugin/commands'; -import { PluginContext } from '../../mol-plugin/context'; import { PluginState } from '../../mol-plugin/state'; import { MolScriptBuilder as MS } from '../../mol-script/language/builder'; import { StateBuilder, StateObject, StateSelection } from '../../mol-state'; @@ -41,13 +41,13 @@ class MolStarProteopediaWrapper { modelInfo: this._ev<ModelInfo>() }; - plugin: PluginContext; + plugin: PluginUIContext; init(target: string | HTMLElement, options?: { customColorList?: number[] }) { this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, { - ...DefaultPluginSpec(), + ...DefaultPluginUISpec(), animations: [ AnimateModelIndex ], diff --git a/src/examples/proteopedia-wrapper/ui/controls.tsx b/src/examples/proteopedia-wrapper/ui/controls.tsx index df970158b11b8c3b91a51caa96a110a265bb4303..bf74e9fcc971198ac55bd812994f0372ca37e763 100644 --- a/src/examples/proteopedia-wrapper/ui/controls.tsx +++ b/src/examples/proteopedia-wrapper/ui/controls.tsx @@ -6,12 +6,12 @@ import * as React from 'react'; import * as ReactDOM from 'react-dom'; +import { PluginUIContext } from '../../../mol-plugin-ui/context'; import { PluginContextContainer } from '../../../mol-plugin-ui/plugin'; import { TransformUpdaterControl } from '../../../mol-plugin-ui/state/update-transform'; -import { PluginContext } from '../../../mol-plugin/context'; import { StateElements } from '../helpers'; -export function volumeStreamingControls(plugin: PluginContext, parent: Element) { +export function volumeStreamingControls(plugin: PluginUIContext, parent: Element) { ReactDOM.render(<PluginContextContainer plugin={plugin}> <TransformUpdaterControl nodeRef={StateElements.VolumeStreaming} /> </PluginContextContainer>, parent); diff --git a/src/mol-plugin-ui/base.tsx b/src/mol-plugin-ui/base.tsx index f2826b3c5097d3c9f519fdc6e27462495ebb0a63..fef08ba42d11490c1bbd1deee2bbe0140f7fc2b2 100644 --- a/src/mol-plugin-ui/base.tsx +++ b/src/mol-plugin-ui/base.tsx @@ -7,15 +7,15 @@ import * as React from 'react'; import { Observable, Subscription } from 'rxjs'; -import { PluginContext } from '../mol-plugin/context'; +import { PluginUIContext } from './context'; import { Button, ColorAccent } from './controls/common'; import { Icon, ArrowRightSvg, ArrowDropDownSvg } from './controls/icons'; -export const PluginReactContext = React.createContext(void 0 as any as PluginContext); +export const PluginReactContext = React.createContext(void 0 as any as PluginUIContext); export abstract class PluginUIComponent<P = {}, S = {}, SS = {}> extends React.Component<P, S, SS> { static contextType = PluginReactContext; - readonly plugin: PluginContext; + readonly plugin: PluginUIContext; private subs: Subscription[] | undefined = void 0; @@ -33,7 +33,7 @@ export abstract class PluginUIComponent<P = {}, S = {}, SS = {}> extends React.C protected init?(): void; constructor(props: P, context?: any) { - super(props, context); + super(props); this.plugin = context; if (this.init) this.init(); } @@ -41,7 +41,7 @@ export abstract class PluginUIComponent<P = {}, S = {}, SS = {}> extends React.C export abstract class PurePluginUIComponent<P = {}, S = {}, SS = {}> extends React.PureComponent<P, S, SS> { static contextType = PluginReactContext; - readonly plugin: PluginContext; + readonly plugin: PluginUIContext; private subs: Subscription[] | undefined = void 0; diff --git a/src/mol-plugin-ui/context.ts b/src/mol-plugin-ui/context.ts new file mode 100644 index 0000000000000000000000000000000000000000..a0f14e9a0f7c7c0ea90e22b080fd4f83ae92ed3c --- /dev/null +++ b/src/mol-plugin-ui/context.ts @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2021 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author David Sehnal <david.sehnal@gmail.com> + */ + + +import { PluginContext } from '../mol-plugin/context'; +import { PluginUISpec } from './spec'; +import { StateTransformParameters } from './state/common'; + +export class PluginUIContext extends PluginContext { + readonly customParamEditors = new Map<string, StateTransformParameters.Class>(); + + private initDataActions() { + for (const a of this.spec.actions) { + this.state.data.actions.add(a.action); + } + } + + private initCustomParamEditors() { + if (!this.spec.customParamEditors) return; + + for (const [t, e] of this.spec.customParamEditors) { + this.customParamEditors.set(t.id, e); + } + } + + dispose(options?: { doNotForceWebGLContextLoss?: boolean }) { + super.dispose(options); + this.layout.dispose(); + } + + constructor(public spec: PluginUISpec) { + super(spec); + + this.initDataActions(); + this.initCustomParamEditors(); + } +} \ No newline at end of file diff --git a/src/mol-plugin-ui/controls/parameters.tsx b/src/mol-plugin-ui/controls/parameters.tsx index 0fef07e0b1a9747d7a7835a3cf1f1bfe6b9d9e18..fb414d4d11742532ecccc7531107845f4f96c1c0 100644 --- a/src/mol-plugin-ui/controls/parameters.tsx +++ b/src/mol-plugin-ui/controls/parameters.tsx @@ -7,7 +7,6 @@ import * as React from 'react'; import { Mat4, Vec2, Vec3 } from '../../mol-math/linear-algebra'; -import { PluginContext } from '../../mol-plugin/context'; import { Color } from '../../mol-util/color'; import { ColorListName, ColorListOptions, ColorListOptionsScale, ColorListOptionsSet, getColorListFromName } from '../../mol-util/color/lists'; import { Legend as LegendData } from '../../mol-util/legend'; @@ -26,6 +25,7 @@ import { LineGraphComponent } from './line-graph/line-graph-component'; import { Slider, Slider2 } from './slider'; import { Asset } from '../../mol-util/assets'; import { ColorListEntry } from '../../mol-util/color/color'; +import { PluginUIContext } from '../context'; export type ParameterControlsCategoryFilter = string | null | (string | null)[] @@ -104,7 +104,7 @@ export class ParameterControls<P extends PD.Params> extends React.PureComponent< } } -export class ParameterMappingControl<S, T> extends PluginUIComponent<{ mapping: ParamMapping<S, T, PluginContext> }> { +export class ParameterMappingControl<S, T> extends PluginUIComponent<{ mapping: ParamMapping<S, T, PluginUIContext> }> { setSettings = (p: { param: PD.Base<any>, name: string, value: any }, old: any) => { const values = { ...old, [p.name]: p.value }; const t = this.props.mapping.update(values, this.plugin); diff --git a/src/mol-plugin/index.ts b/src/mol-plugin-ui/index.ts similarity index 63% rename from src/mol-plugin/index.ts rename to src/mol-plugin-ui/index.ts index 7d715f39391c4bd5bbbb5d13618707fdced34c11..665d76d8659a6c3f2944e518a3505072f0b914ee 100644 --- a/src/mol-plugin/index.ts +++ b/src/mol-plugin-ui/index.ts @@ -7,20 +7,20 @@ import * as React from 'react'; import * as ReactDOM from 'react-dom'; -import { Plugin } from '../mol-plugin-ui/plugin'; -import { PluginContext } from './context'; -import { DefaultPluginSpec, PluginSpec } from './spec'; +import { Plugin } from './plugin'; +import { PluginUIContext } from './context'; +import { DefaultPluginUISpec, PluginUISpec } from './spec'; -export function createPlugin(target: HTMLElement, spec?: PluginSpec): PluginContext { - const ctx = new PluginContext(spec || DefaultPluginSpec()); +export function createPlugin(target: HTMLElement, spec?: PluginUISpec): PluginUIContext { + const ctx = new PluginUIContext(spec || DefaultPluginUISpec()); ctx.init(); ReactDOM.render(React.createElement(Plugin, { plugin: ctx }), target); return ctx; } /** Returns the instance of the plugin after all behaviors have been initialized */ -export async function createPluginAsync(target: HTMLElement, spec?: PluginSpec) { - const ctx = new PluginContext(spec || DefaultPluginSpec()); +export async function createPluginAsync(target: HTMLElement, spec?: PluginUISpec) { + const ctx = new PluginUIContext(spec || DefaultPluginUISpec()); const init = ctx.init(); ReactDOM.render(React.createElement(Plugin, { plugin: ctx }), target); await init; diff --git a/src/mol-plugin-ui/plugin.tsx b/src/mol-plugin-ui/plugin.tsx index 8f3061f35a51eb71a7eaf2e251ee20794d303f2b..bcef3bc4456426c83a0505ef2c29aa2f71637952 100644 --- a/src/mol-plugin-ui/plugin.tsx +++ b/src/mol-plugin-ui/plugin.tsx @@ -7,7 +7,6 @@ import { List } from 'immutable'; import * as React from 'react'; -import { PluginContext } from '../mol-plugin/context'; import { formatTime } from '../mol-util'; import { LogEntry } from '../mol-util/log-entry'; import { PluginReactContext, PluginUIComponent } from './base'; @@ -18,8 +17,9 @@ import { BackgroundTaskProgress, OverlayTaskProgress } from './task'; import { Toasts } from './toast'; import { Viewport, ViewportControls } from './viewport'; import { PluginCommands } from '../mol-plugin/commands'; +import { PluginUIContext } from './context'; -export class Plugin extends React.Component<{ plugin: PluginContext }, {}> { +export class Plugin extends React.Component<{ plugin: PluginUIContext }, {}> { region(kind: 'left' | 'right' | 'bottom' | 'main', element: JSX.Element) { return <div className={`msp-layout-region msp-layout-${kind}`}> <div className='msp-layout-static'> @@ -35,7 +35,7 @@ export class Plugin extends React.Component<{ plugin: PluginContext }, {}> { } } -export class PluginContextContainer extends React.Component<{ plugin: PluginContext }> { +export class PluginContextContainer extends React.Component<{ plugin: PluginUIContext }> { render() { return <PluginReactContext.Provider value={this.props.plugin}> <div className='msp-plugin'> @@ -62,7 +62,7 @@ class Layout extends PluginUIComponent { get layoutVisibilityClassName() { const layout = this.plugin.layout.state; - const controls = (this.plugin.spec.layout && this.plugin.spec.layout.controls) || {}; + const controls = this.plugin.spec.components?.controls ?? {}; const classList: string[] = []; if (controls.top === 'none' || !layout.showControls || layout.regionState.top === 'hidden') { @@ -127,7 +127,7 @@ class Layout extends PluginUIComponent { render() { const layout = this.plugin.layout.state; - const controls = this.plugin.spec.layout?.controls || {}; + const controls = this.plugin.spec.components?.controls || {}; const viewport = this.plugin.spec.components?.viewport?.view || DefaultViewport; return <div className='msp-plugin' onDrop={this.onDrop} onDragOver={this.onDragOver}> @@ -149,7 +149,6 @@ export class ControlsWrapper extends PluginUIComponent { render() { const StructureTools = this.plugin.spec.components?.structureTools || DefaultStructureTools; return <div className='msp-scrollable-container'> - {/* <CurrentObject /> */} <StructureTools /> </div>; } diff --git a/src/mol-plugin-ui/spec.ts b/src/mol-plugin-ui/spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..c0c8812d8e4faa6c10ea342ca7b1d14dc97334ba --- /dev/null +++ b/src/mol-plugin-ui/spec.ts @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author David Sehnal <david.sehnal@gmail.com> + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { StateActions } from '../mol-plugin-state/actions'; +import { AssignColorVolume } from '../mol-plugin-state/actions/volume'; +import { StateTransforms } from '../mol-plugin-state/transforms'; +import { StateTransformParameters } from '../mol-plugin-ui/state/common'; +import { DefaultPluginSpec, PluginSpec } from '../mol-plugin/spec'; +import { StateAction, StateTransformer } from '../mol-state'; +import { BoxifyVolumeStreaming, CreateVolumeStreamingBehavior, InitVolumeStreaming } from '../mol-plugin/behavior/dynamic/volume-streaming/transformers'; + +export { PluginUISpec }; + +interface PluginUISpec extends PluginSpec { + actions: PluginUISpec.Action[], + customParamEditors?: [StateAction | StateTransformer, StateTransformParameters.Class][], + components?: { + controls?: PluginUISpec.LayoutControls + remoteState?: 'none' | 'default', + structureTools?: React.ComponentClass, + viewport?: { + view?: React.ComponentClass, + controls?: React.ComponentClass + }, + hideTaskOverlay?: boolean + }, +} + +namespace PluginUISpec { + export interface Action { + action: StateAction | StateTransformer, + customControl?: StateTransformParameters.Class, + autoUpdate?: boolean + } + + export function Action(action: StateAction | StateTransformer, params?: { customControl?: StateTransformParameters.Class, autoUpdate?: boolean }): Action { + return { action, customControl: params && params.customControl, autoUpdate: params && params.autoUpdate }; + } + + export interface LayoutControls { + top?: React.ComponentClass | 'none', + left?: React.ComponentClass | 'none', + right?: React.ComponentClass | 'none', + bottom?: React.ComponentClass | 'none' + } +} + +export const DefaultPluginUISpec = (): PluginUISpec => ({ + ...DefaultPluginSpec(), + actions: [ + PluginUISpec.Action(StateActions.Structure.DownloadStructure), + PluginUISpec.Action(StateActions.Structure.AddTrajectory), + PluginUISpec.Action(StateActions.Volume.DownloadDensity), + PluginUISpec.Action(StateActions.DataFormat.DownloadFile), + PluginUISpec.Action(StateActions.DataFormat.OpenFiles), + PluginUISpec.Action(StateActions.Structure.EnableModelCustomProps), + PluginUISpec.Action(StateActions.Structure.EnableStructureCustomProps), + + // Volume streaming + PluginUISpec.Action(InitVolumeStreaming), + PluginUISpec.Action(BoxifyVolumeStreaming), + PluginUISpec.Action(CreateVolumeStreamingBehavior), + + PluginUISpec.Action(StateTransforms.Data.Download), + PluginUISpec.Action(StateTransforms.Data.ParseCif), + PluginUISpec.Action(StateTransforms.Data.ParseCcp4), + PluginUISpec.Action(StateTransforms.Data.ParseDsn6), + + PluginUISpec.Action(StateTransforms.Model.TrajectoryFromMmCif), + PluginUISpec.Action(StateTransforms.Model.TrajectoryFromCifCore), + PluginUISpec.Action(StateTransforms.Model.TrajectoryFromPDB), + PluginUISpec.Action(StateTransforms.Model.TransformStructureConformation), + PluginUISpec.Action(StateTransforms.Model.StructureFromModel), + PluginUISpec.Action(StateTransforms.Model.StructureFromTrajectory), + PluginUISpec.Action(StateTransforms.Model.ModelFromTrajectory), + PluginUISpec.Action(StateTransforms.Model.StructureSelectionFromScript), + PluginUISpec.Action(StateTransforms.Representation.StructureRepresentation3D), + PluginUISpec.Action(StateTransforms.Representation.StructureSelectionsDistance3D), + PluginUISpec.Action(StateTransforms.Representation.StructureSelectionsAngle3D), + PluginUISpec.Action(StateTransforms.Representation.StructureSelectionsDihedral3D), + PluginUISpec.Action(StateTransforms.Representation.StructureSelectionsLabel3D), + PluginUISpec.Action(StateTransforms.Representation.StructureSelectionsOrientation3D), + PluginUISpec.Action(StateTransforms.Representation.ModelUnitcell3D), + PluginUISpec.Action(StateTransforms.Representation.ExplodeStructureRepresentation3D), + PluginUISpec.Action(StateTransforms.Representation.UnwindStructureAssemblyRepresentation3D), + PluginUISpec.Action(StateTransforms.Representation.OverpaintStructureRepresentation3DFromScript), + PluginUISpec.Action(StateTransforms.Representation.TransparencyStructureRepresentation3DFromScript), + + PluginUISpec.Action(AssignColorVolume), + PluginUISpec.Action(StateTransforms.Volume.VolumeFromCcp4), + PluginUISpec.Action(StateTransforms.Volume.VolumeFromDsn6), + PluginUISpec.Action(StateTransforms.Volume.VolumeFromCube), + PluginUISpec.Action(StateTransforms.Volume.VolumeFromDx), + PluginUISpec.Action(StateTransforms.Representation.VolumeRepresentation3D), + ] +}); \ No newline at end of file diff --git a/src/mol-plugin-ui/viewport/simple-settings.tsx b/src/mol-plugin-ui/viewport/simple-settings.tsx index cf72e5002ca9ab640d781007e1340666d2718a7c..d74806412e744b896ffb52a1cbda57fb263350b4 100644 --- a/src/mol-plugin-ui/viewport/simple-settings.tsx +++ b/src/mol-plugin-ui/viewport/simple-settings.tsx @@ -9,13 +9,13 @@ import { produce } from 'immer'; import * as React from 'react'; import { Canvas3DParams, Canvas3DProps } from '../../mol-canvas3d/canvas3d'; import { PluginCommands } from '../../mol-plugin/commands'; -import { PluginContext } from '../../mol-plugin/context'; import { StateTransform } from '../../mol-state'; import { Color } from '../../mol-util/color'; import { ParamDefinition as PD } from '../../mol-util/param-definition'; import { ParamMapping } from '../../mol-util/param-mapping'; import { Mutable } from '../../mol-util/type-helpers'; import { PluginUIComponent } from '../base'; +import { PluginUIContext } from '../context'; import { ParameterMappingControl } from '../controls/parameters'; import { ViewportHelpContent } from './help'; @@ -71,9 +71,9 @@ const SimpleSettingsParams = { type SimpleSettingsParams = typeof SimpleSettingsParams const SimpleSettingsMapping = ParamMapping({ - params: (ctx: PluginContext) => { + params: (ctx: PluginUIContext) => { const params = PD.clone(SimpleSettingsParams); - const controls = ctx.spec.layout?.controls; + const controls = ctx.spec.components?.controls; if (controls) { const options: [LayoutOptions, string][] = []; if (controls.top !== 'none') options.push(['sequence', LayoutOptions.sequence]); @@ -83,8 +83,8 @@ const SimpleSettingsMapping = ParamMapping({ } return params; }, - target(ctx: PluginContext) { - const c = ctx.spec.layout?.controls; + target(ctx: PluginUIContext) { + const c = ctx.spec.components?.controls; const r = ctx.layout.state.regionState; const layout: SimpleSettingsParams['layout']['defaultValue'] = []; if (r.top !== 'hidden' && (!c || c.top !== 'none')) layout.push('sequence'); diff --git a/src/mol-plugin/context.ts b/src/mol-plugin/context.ts index a5e7e623a45b072b7acddd311e2844fb7dbc5a9c..30364ed39cca5a5cbe305f84cedbc244cd03a551 100644 --- a/src/mol-plugin/context.ts +++ b/src/mol-plugin/context.ts @@ -8,44 +8,51 @@ import produce, { setAutoFreeze } from 'immer'; import { List } from 'immutable'; import { merge, Subscription } from 'rxjs'; +import { filter, take } from 'rxjs/operators'; import { Canvas3D, Canvas3DContext, DefaultCanvas3DParams } from '../mol-canvas3d/canvas3d'; +import { resizeCanvas } from '../mol-canvas3d/util'; +import { Vec2 } from '../mol-math/linear-algebra'; import { CustomProperty } from '../mol-model-props/common/custom-property'; import { Model, Structure } from '../mol-model/structure'; import { DataBuilder } from '../mol-plugin-state/builder/data'; import { StructureBuilder } from '../mol-plugin-state/builder/structure'; import { DataFormatRegistry } from '../mol-plugin-state/formats/registry'; import { StructureSelectionQueryRegistry } from '../mol-plugin-state/helpers/structure-selection-query'; +import { PluginAnimationManager } from '../mol-plugin-state/manager/animation'; import { CameraManager } from '../mol-plugin-state/manager/camera'; import { InteractivityManager } from '../mol-plugin-state/manager/interactivity'; import { LociLabel, LociLabelManager } from '../mol-plugin-state/manager/loci-label'; +import { PluginStateSnapshotManager } from '../mol-plugin-state/manager/snapshots'; import { StructureComponentManager } from '../mol-plugin-state/manager/structure/component'; import { StructureFocusManager } from '../mol-plugin-state/manager/structure/focus'; import { StructureHierarchyManager } from '../mol-plugin-state/manager/structure/hierarchy'; import { StructureHierarchyRef } from '../mol-plugin-state/manager/structure/hierarchy-state'; import { StructureMeasurementManager } from '../mol-plugin-state/manager/structure/measurement'; import { StructureSelectionManager } from '../mol-plugin-state/manager/structure/selection'; -import { PluginUIComponent } from '../mol-plugin-ui/base'; -import { StateTransformParameters } from '../mol-plugin-ui/state/common'; +import { VolumeHierarchyManager } from '../mol-plugin-state/manager/volume/hierarchy'; +import { LeftPanelTabName, PluginLayout } from './layout'; import { Representation } from '../mol-repr/representation'; import { StructureRepresentationRegistry } from '../mol-repr/structure/registry'; import { VolumeRepresentationRegistry } from '../mol-repr/volume/registry'; import { StateTransform } from '../mol-state'; -import { Task, RuntimeContext } from '../mol-task'; +import { RuntimeContext, Task } from '../mol-task'; import { ColorTheme } from '../mol-theme/color'; import { SizeTheme } from '../mol-theme/size'; import { ThemeRegistryContext } from '../mol-theme/theme'; +import { AssetManager } from '../mol-util/assets'; import { Color } from '../mol-util/color'; import { ajaxGet } from '../mol-util/data-source'; import { isDebugMode, isProductionMode } from '../mol-util/debug'; import { ModifiersKeys } from '../mol-util/input/input-observer'; import { LogEntry } from '../mol-util/log-entry'; +import { objectForEach } from '../mol-util/object'; import { RxEventHelper } from '../mol-util/rx-event-helper'; +import { PluginAnimationLoop } from './animation-loop'; import { BuiltInPluginBehaviors } from './behavior'; import { PluginBehavior } from './behavior/behavior'; import { PluginCommandManager } from './command'; import { PluginCommands } from './commands'; import { PluginConfig, PluginConfigManager } from './config'; -import { LeftPanelTabName, PluginLayout } from './layout'; import { PluginSpec } from './spec'; import { PluginState } from './state'; import { SubstructureParentHelper } from './util/substructure-parent-helper'; @@ -53,15 +60,6 @@ import { TaskManager } from './util/task-manager'; import { PluginToastManager } from './util/toast'; import { ViewportScreenshotHelper } from './util/viewport-screenshot'; import { PLUGIN_VERSION, PLUGIN_VERSION_DATE } from './version'; -import { AssetManager } from '../mol-util/assets'; -import { PluginStateSnapshotManager } from '../mol-plugin-state/manager/snapshots'; -import { PluginAnimationManager } from '../mol-plugin-state/manager/animation'; -import { objectForEach } from '../mol-util/object'; -import { VolumeHierarchyManager } from '../mol-plugin-state/manager/volume/hierarchy'; -import { filter, take } from 'rxjs/operators'; -import { Vec2 } from '../mol-math/linear-algebra'; -import { PluginAnimationLoop } from './animation-loop'; -import { resizeCanvas } from '../mol-canvas3d/util'; export class PluginContext { runTask = <T>(task: Task<T>, params?: { useOverlay?: boolean }) => this.managers.task.run(task, params); @@ -71,7 +69,7 @@ export class PluginContext { return object; } - private subs: Subscription[] = []; + protected subs: Subscription[] = []; private disposed = false; private ev = RxEventHelper.create(); @@ -109,8 +107,8 @@ export class PluginContext { readonly canvas3dContext: Canvas3DContext | undefined; readonly canvas3d: Canvas3D | undefined; - readonly animationLoop = new PluginAnimationLoop(this); readonly layout = new PluginLayout(this); + readonly animationLoop = new PluginAnimationLoop(this); readonly representation = { structure: { @@ -176,9 +174,8 @@ export class PluginContext { readonly customModelProperties = new CustomProperty.Registry<Model>(); readonly customStructureProperties = new CustomProperty.Registry<Structure>(); - readonly customParamEditors = new Map<string, StateTransformParameters.Class>(); - readonly customStructureControls = new Map<string, { new(): PluginUIComponent<any, any, any> }>(); + readonly customStructureControls = new Map<string, { new(): any /* contructible react components */ }>(); readonly genericRepresentationControls = new Map<string, (selection: StructureHierarchyManager['selection']) => [StructureHierarchyRef[], string]>(); /** @@ -200,7 +197,7 @@ export class PluginContext { (this.canvas3dContext as Canvas3DContext) = Canvas3DContext.fromCanvas(canvas, { antialias, preserveDrawingBuffer, pixelScale, pickScale, enableWboit }); (this.canvas3d as Canvas3D) = Canvas3D.create(this.canvas3dContext!); this.canvas3dInit.next(true); - let props = this.spec.components?.viewport?.canvas3d; + let props = this.spec.canvas3d; const backgroundColor = Color(0xFCFBF9); if (!props) { @@ -294,7 +291,6 @@ export class PluginContext { this.ev.dispose(); this.state.dispose(); this.managers.task.dispose(); - this.layout.dispose(); this.helpers.substructureParent.dispose(); objectForEach(this.managers, m => (m as any)?.dispose?.()); @@ -385,12 +381,6 @@ export class PluginContext { } } - private initDataActions() { - for (const a of this.spec.actions) { - this.state.data.actions.add(a.action); - } - } - private initAnimations() { if (!this.spec.animations) return; for (const anim of this.spec.animations) { @@ -398,14 +388,6 @@ export class PluginContext { } } - private initCustomParamEditors() { - if (!this.spec.customParamEditors) return; - - for (const [t, e] of this.spec.customParamEditors) { - this.customParamEditors.set(t.id, e); - } - } - async init() { this.subs.push(this.events.log.subscribe(e => this.log.entries = this.log.entries.push(e))); @@ -417,9 +399,7 @@ export class PluginContext { (this.managers.lociLabels as LociLabelManager) = new LociLabelManager(this); (this.builders.structure as StructureBuilder) = new StructureBuilder(this); - this.initDataActions(); this.initAnimations(); - this.initCustomParamEditors(); await this.initBehaviors(); diff --git a/src/mol-plugin/layout.ts b/src/mol-plugin/layout.ts index a20be613e87ece25818a0d042f10e88aa3c120c9..228201d294ecd4747445c3d48bdebf164b48fb12 100644 --- a/src/mol-plugin/layout.ts +++ b/src/mol-plugin/layout.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> * @author Alexander Rose <alexander.rose@weirdbyte.de> @@ -7,8 +7,8 @@ import { ParamDefinition as PD } from '../mol-util/param-definition'; import { StatefulPluginComponent } from '../mol-plugin-state/component'; -import { PluginContext } from './context'; import { PluginCommands } from './commands'; +import { PluginContext } from './context'; const regionStateOptions = [ ['full', 'Full'], diff --git a/src/mol-plugin/spec.ts b/src/mol-plugin/spec.ts index b160f43ad7bcecb37343ca4104d2e216a891e917..1d3af5b054a8c7961b1087ca5b686ac13e9c19fd 100644 --- a/src/mol-plugin/spec.ts +++ b/src/mol-plugin/spec.ts @@ -1,65 +1,37 @@ /** - * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { StateTransformer, StateAction } from '../mol-state'; -import { StateTransformParameters } from '../mol-plugin-ui/state/common'; -import { PluginLayoutStateProps } from './layout'; -import { PluginStateAnimation } from '../mol-plugin-state/animation/model'; -import { PluginConfigItem } from './config'; import { PartialCanvas3DProps } from '../mol-canvas3d/canvas3d'; -import { DataFormatProvider } from '../mol-plugin-state/formats/provider'; -import { StateActions } from '../mol-plugin-state/actions'; -import { StateTransforms } from '../mol-plugin-state/transforms'; -import { VolumeStreamingCustomControls } from '../mol-plugin-ui/custom/volume'; -import { PluginBehaviors } from './behavior'; -import { StructureFocusRepresentation } from './behavior/dynamic/selection/structure-focus-representation'; -import { BoxifyVolumeStreaming, CreateVolumeStreamingBehavior, InitVolumeStreaming } from './behavior/dynamic/volume-streaming/transformers'; -import { AssignColorVolume } from '../mol-plugin-state/actions/volume'; -import { AnimateModelIndex } from '../mol-plugin-state/animation/built-in/model-index'; import { AnimateAssemblyUnwind } from '../mol-plugin-state/animation/built-in/assembly-unwind'; import { AnimateCameraSpin } from '../mol-plugin-state/animation/built-in/camera-spin'; +import { AnimateModelIndex } from '../mol-plugin-state/animation/built-in/model-index'; import { AnimateStateSnapshots } from '../mol-plugin-state/animation/built-in/state-snapshots'; +import { PluginStateAnimation } from '../mol-plugin-state/animation/model'; +import { DataFormatProvider } from '../mol-plugin-state/formats/provider'; +import { StateTransformer } from '../mol-state'; +import { PluginBehaviors } from './behavior'; +import { StructureFocusRepresentation } from './behavior/dynamic/selection/structure-focus-representation'; +import { PluginConfigItem } from './config'; +import { PluginLayoutStateProps } from './layout'; export { PluginSpec }; interface PluginSpec { - actions: PluginSpec.Action[], behaviors: PluginSpec.Behavior[], animations?: PluginStateAnimation[], - customParamEditors?: [StateAction | StateTransformer, StateTransformParameters.Class][], - customFormats?: [string, DataFormatProvider][] + customFormats?: [string, DataFormatProvider][], + canvas3d?: PartialCanvas3DProps, layout?: { initial?: Partial<PluginLayoutStateProps>, - controls?: PluginSpec.LayoutControls - }, - components?: { - remoteState?: 'none' | 'default', - structureTools?: React.ComponentClass, - viewport?: { - view?: React.ComponentClass, - controls?: React.ComponentClass, - canvas3d?: PartialCanvas3DProps - }, - hideTaskOverlay?: boolean }, config?: [PluginConfigItem, unknown][] } namespace PluginSpec { - export interface Action { - action: StateAction | StateTransformer, - customControl?: StateTransformParameters.Class, - autoUpdate?: boolean - } - - export function Action(action: StateAction | StateTransformer, params?: { customControl?: StateTransformParameters.Class, autoUpdate?: boolean }): Action { - return { action, customControl: params && params.customControl, autoUpdate: params && params.autoUpdate }; - } - export interface Behavior { transformer: StateTransformer, defaultParams?: any @@ -68,62 +40,9 @@ namespace PluginSpec { export function Behavior<T extends StateTransformer>(transformer: T, defaultParams: Partial<StateTransformer.Params<T>> = {}): Behavior { return { transformer, defaultParams }; } - - export interface LayoutControls { - top?: React.ComponentClass | 'none', - left?: React.ComponentClass | 'none', - right?: React.ComponentClass | 'none', - bottom?: React.ComponentClass | 'none' - } } export const DefaultPluginSpec = (): PluginSpec => ({ - actions: [ - PluginSpec.Action(StateActions.Structure.DownloadStructure), - PluginSpec.Action(StateActions.Structure.AddTrajectory), - PluginSpec.Action(StateActions.Volume.DownloadDensity), - PluginSpec.Action(StateActions.DataFormat.DownloadFile), - PluginSpec.Action(StateActions.DataFormat.OpenFiles), - PluginSpec.Action(StateActions.Structure.EnableModelCustomProps), - PluginSpec.Action(StateActions.Structure.EnableStructureCustomProps), - - // Volume streaming - PluginSpec.Action(InitVolumeStreaming), - PluginSpec.Action(BoxifyVolumeStreaming), - PluginSpec.Action(CreateVolumeStreamingBehavior), - - PluginSpec.Action(StateTransforms.Data.Download), - PluginSpec.Action(StateTransforms.Data.ParseCif), - PluginSpec.Action(StateTransforms.Data.ParseCcp4), - PluginSpec.Action(StateTransforms.Data.ParseDsn6), - - PluginSpec.Action(StateTransforms.Model.TrajectoryFromMmCif), - PluginSpec.Action(StateTransforms.Model.TrajectoryFromCifCore), - PluginSpec.Action(StateTransforms.Model.TrajectoryFromPDB), - PluginSpec.Action(StateTransforms.Model.TransformStructureConformation), - PluginSpec.Action(StateTransforms.Model.StructureFromModel), - PluginSpec.Action(StateTransforms.Model.StructureFromTrajectory), - PluginSpec.Action(StateTransforms.Model.ModelFromTrajectory), - PluginSpec.Action(StateTransforms.Model.StructureSelectionFromScript), - PluginSpec.Action(StateTransforms.Representation.StructureRepresentation3D), - PluginSpec.Action(StateTransforms.Representation.StructureSelectionsDistance3D), - PluginSpec.Action(StateTransforms.Representation.StructureSelectionsAngle3D), - PluginSpec.Action(StateTransforms.Representation.StructureSelectionsDihedral3D), - PluginSpec.Action(StateTransforms.Representation.StructureSelectionsLabel3D), - PluginSpec.Action(StateTransforms.Representation.StructureSelectionsOrientation3D), - PluginSpec.Action(StateTransforms.Representation.ModelUnitcell3D), - PluginSpec.Action(StateTransforms.Representation.ExplodeStructureRepresentation3D), - PluginSpec.Action(StateTransforms.Representation.UnwindStructureAssemblyRepresentation3D), - PluginSpec.Action(StateTransforms.Representation.OverpaintStructureRepresentation3DFromScript), - PluginSpec.Action(StateTransforms.Representation.TransparencyStructureRepresentation3DFromScript), - - PluginSpec.Action(AssignColorVolume), - PluginSpec.Action(StateTransforms.Volume.VolumeFromCcp4), - PluginSpec.Action(StateTransforms.Volume.VolumeFromDsn6), - PluginSpec.Action(StateTransforms.Volume.VolumeFromCube), - PluginSpec.Action(StateTransforms.Volume.VolumeFromDx), - PluginSpec.Action(StateTransforms.Representation.VolumeRepresentation3D), - ], behaviors: [ PluginSpec.Behavior(PluginBehaviors.Representation.HighlightLoci), PluginSpec.Behavior(PluginBehaviors.Representation.SelectLoci), @@ -139,9 +58,6 @@ export const DefaultPluginSpec = (): PluginSpec => ({ PluginSpec.Behavior(PluginBehaviors.CustomProps.ValenceModel), PluginSpec.Behavior(PluginBehaviors.CustomProps.CrossLinkRestraint), ], - customParamEditors: [ - [CreateVolumeStreamingBehavior, VolumeStreamingCustomControls] - ], animations: [ AnimateModelIndex, AnimateCameraSpin, diff --git a/src/mol-plugin/util/toast.ts b/src/mol-plugin/util/toast.ts index 5062eb4b8294fba1bcb596c3cf662c78d1e3a2b2..2a22e93904adcfb7de993ae0352cd4884f10bb4c 100644 --- a/src/mol-plugin/util/toast.ts +++ b/src/mol-plugin/util/toast.ts @@ -14,9 +14,9 @@ import { PluginCommands } from '../commands'; export interface PluginToast { title: string, /** - * The message can be either a string, html string, or an arbitrary React component. + * The message can be either a string, html string, or an arbitrary React (Function) component. */ - message: string | React.ComponentClass, + message: string | Function, /** * Only one message with a given key can be shown. */ @@ -103,7 +103,7 @@ export namespace PluginToastManager { serialNumber: number, key?: string, title: string, - message: string | React.ComponentClass, + message: string | Function, hide: () => void, timeout?: number }