diff --git a/src/mol-plugin/command.ts b/src/mol-plugin/command.ts index ec948ef858251ab75850ecb96604d26dc1040481..880d8d053971d169d06c5a406cebed20d33c215d 100644 --- a/src/mol-plugin/command.ts +++ b/src/mol-plugin/command.ts @@ -4,12 +4,42 @@ * @author David Sehnal <david.sehnal@gmail.com> */ -import * as State from './command/state'; -import * as Camera from './command/camera'; +import { Camera } from 'mol-canvas3d/camera'; +import { PluginCommand } from './command/base'; +import { Transform, State } from 'mol-state'; +import { StateAction } from 'mol-state/action'; -export * from './command/command'; +export * from './command/base'; export const PluginCommands = { - State, - Camera + State: { + SetCurrentObject: PluginCommand<{ state: State, ref: Transform.Ref }>(), + ApplyAction: PluginCommand<{ state: State, action: StateAction.Instance, ref?: Transform.Ref }>(), + Update: PluginCommand<{ state: State, tree: State.Tree | State.Builder }>(), + + RemoveObject: PluginCommand<{ state: State, ref: Transform.Ref }>(), + + ToggleExpanded: PluginCommand<{ state: State, ref: Transform.Ref }>({ isImmediate: true }), + ToggleVisibility: PluginCommand<{ state: State, ref: Transform.Ref }>({ isImmediate: true }), + + Snapshots: { + Add: PluginCommand<{ name?: string, description?: string }>({ isImmediate: true }), + Remove: PluginCommand<{ id: string }>({ isImmediate: true }), + Apply: PluginCommand<{ id: string }>({ isImmediate: true }), + Clear: PluginCommand<{}>({ isImmediate: true }), + + Upload: PluginCommand<{ name?: string, description?: string, serverUrl: string }>({ isImmediate: true }), + Fetch: PluginCommand<{ url: string }>() + } + }, + Camera: { + Reset: PluginCommand<{}>({ isImmediate: true }), + SetSnapshot: PluginCommand<{ snapshot: Camera.Snapshot, durationMs?: number }>({ isImmediate: true }), + Snapshots: { + Add: PluginCommand<{ name?: string, description?: string }>({ isImmediate: true }), + Remove: PluginCommand<{ id: string }>({ isImmediate: true }), + Apply: PluginCommand<{ id: string }>({ isImmediate: true }), + Clear: PluginCommand<{}>({ isImmediate: true }), + } + } } \ No newline at end of file diff --git a/src/mol-plugin/command/command.ts b/src/mol-plugin/command/base.ts similarity index 100% rename from src/mol-plugin/command/command.ts rename to src/mol-plugin/command/base.ts diff --git a/src/mol-plugin/command/camera.ts b/src/mol-plugin/command/camera.ts deleted file mode 100644 index b5138f9d66519b0ef0beb33447641d3db22cdb7d..0000000000000000000000000000000000000000 --- a/src/mol-plugin/command/camera.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. - * - * @author David Sehnal <david.sehnal@gmail.com> - */ - -import { PluginCommand } from './command'; -import { Camera } from 'mol-canvas3d/camera'; - -export const Reset = PluginCommand<{}>({ isImmediate: true }); -export const SetSnapshot = PluginCommand<{ snapshot: Camera.Snapshot, durationMs?: number }>({ isImmediate: true }); - -export const Snapshots = { - Add: PluginCommand<{ name?: string, description?: string }>({ isImmediate: true }), - Remove: PluginCommand<{ id: string }>({ isImmediate: true }), - Apply: PluginCommand<{ id: string }>({ isImmediate: true }), - Clear: PluginCommand<{ }>({ isImmediate: true }), -} \ No newline at end of file diff --git a/src/mol-plugin/command/state.ts b/src/mol-plugin/command/state.ts deleted file mode 100644 index e9b092b00e04e65e1c910d6bde8c73325de761f7..0000000000000000000000000000000000000000 --- a/src/mol-plugin/command/state.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. - * - * @author David Sehnal <david.sehnal@gmail.com> - */ - -import { PluginCommand } from './command'; -import { Transform, State } from 'mol-state'; -import { StateAction } from 'mol-state/action'; - -export const SetCurrentObject = PluginCommand<{ state: State, ref: Transform.Ref }>(); -export const ApplyAction = PluginCommand<{ state: State, action: StateAction.Instance, ref?: Transform.Ref }>(); -export const Update = PluginCommand<{ state: State, tree: State.Tree | State.Builder }>(); - -// export const UpdateObject = PluginCommand<{ ref: Transform.Ref, params: any }>('ms-data', 'update-object'); - -export const RemoveObject = PluginCommand<{ state: State, ref: Transform.Ref }>(); - -export const ToggleExpanded = PluginCommand<{ state: State, ref: Transform.Ref }>({ isImmediate: true }); - -export const ToggleVisibility = PluginCommand<{ state: State, ref: Transform.Ref }>({ isImmediate: true }); - -export const Snapshots = { - Add: PluginCommand<{ name?: string, description?: string }>({ isImmediate: true }), - Remove: PluginCommand<{ id: string }>({ isImmediate: true }), - Apply: PluginCommand<{ id: string }>({ isImmediate: true }), - Clear: PluginCommand<{ }>({ isImmediate: true }), - - Upload: PluginCommand<{ name?: string, description?: string, serverUrl: string }>({ isImmediate: true }), - Fetch: PluginCommand<{ url: string }>() -} \ No newline at end of file diff --git a/src/mol-plugin/index.ts b/src/mol-plugin/index.ts index 29471e0c80abb6bb4ce1da3ee9a22b5c15d48d94..7a87cb5049d4271438b60081eeb0aab8bbaacff9 100644 --- a/src/mol-plugin/index.ts +++ b/src/mol-plugin/index.ts @@ -25,10 +25,10 @@ const DefaultSpec: PluginSpec = { PluginSpec.Action(CreateStructureFromPDBe), PluginSpec.Action(StateTransforms.Data.Download), PluginSpec.Action(StateTransforms.Data.ParseCif), - PluginSpec.Action(StateTransforms.Model.CreateStructureAssembly), - PluginSpec.Action(StateTransforms.Model.CreateStructure), - PluginSpec.Action(StateTransforms.Model.CreateModelFromTrajectory), - PluginSpec.Action(StateTransforms.Visuals.CreateStructureRepresentation) + PluginSpec.Action(StateTransforms.Model.StructureAssemblyFromModel), + PluginSpec.Action(StateTransforms.Model.StructureFromModel), + PluginSpec.Action(StateTransforms.Model.ModelFromTrajectory), + PluginSpec.Action(StateTransforms.Representation.StructureRepresentation3D) ], behaviors: [ PluginSpec.Behavior(PluginBehaviors.Representation.HighlightLoci), diff --git a/src/mol-plugin/state/actions/basic.ts b/src/mol-plugin/state/actions/basic.ts index 65914ce4c61fe9b3ce28b580288e686e4ae45dc4..754282bbcc7794854a741e4752f348d8b20b3e64 100644 --- a/src/mol-plugin/state/actions/basic.ts +++ b/src/mol-plugin/state/actions/basic.ts @@ -36,11 +36,11 @@ export const CreateStructureFromPDBe = StateAction.create<PluginStateObject.Root const newTree = b.toRoot() .apply(StateTransforms.Data.Download, { url }) .apply(StateTransforms.Data.ParseCif) - .apply(StateTransforms.Model.ParseTrajectoryFromMmCif, {}) - .apply(StateTransforms.Model.CreateModelFromTrajectory, { modelIndex: 0 }) - .apply(StateTransforms.Model.CreateStructureAssembly) + .apply(StateTransforms.Model.TrajectoryFromMmCif, {}) + .apply(StateTransforms.Model.ModelFromTrajectory, { modelIndex: 0 }) + .apply(StateTransforms.Model.StructureAssemblyFromModel) // .apply(StateTransforms.Model.CreateStructureSelection, { query, label: 'ALA residues' }) - .apply(StateTransforms.Visuals.CreateStructureRepresentation, { + .apply(StateTransforms.Representation.StructureRepresentation3D, { type: { name: 'cartoon', params: PD.getDefaultValues(CartoonParams) @@ -62,13 +62,14 @@ export const UpdateTrajectory = StateAction.create<PluginStateObject.Root, void, by: PD.Numeric(1, { min: -1, max: 1, step: 1 }, { isOptional: true }) }), apply({ params, state }) { - const models = state.select(q => q.rootsOfType(PluginStateObject.Molecule.Model).filter(c => c.transform.transformer === StateTransforms.Model.CreateModelFromTrajectory)); + const models = state.select(q => q.rootsOfType(PluginStateObject.Molecule.Model) + .filter(c => c.transform.transformer === StateTransforms.Model.ModelFromTrajectory)); const update = state.build(); if (params.action === 'reset') { for (const m of models) { - update.to(m.transform.ref).update(StateTransforms.Model.CreateModelFromTrajectory, + update.to(m.transform.ref).update(StateTransforms.Model.ModelFromTrajectory, () => ({ modelIndex: 0})); } } else { @@ -76,7 +77,7 @@ export const UpdateTrajectory = StateAction.create<PluginStateObject.Root, void, const parent = StateSelection.findAncestorOfType(state.tree, state.cells, m.transform.ref, [PluginStateObject.Molecule.Trajectory]); if (!parent || !parent.obj) continue; const traj = parent.obj as PluginStateObject.Molecule.Trajectory; - update.to(m.transform.ref).update(StateTransforms.Model.CreateModelFromTrajectory, + update.to(m.transform.ref).update(StateTransforms.Model.ModelFromTrajectory, old => { let modelIndex = (old.modelIndex + params.by!) % traj.data.length; if (modelIndex < 0) modelIndex += traj.data.length; diff --git a/src/mol-plugin/state/transforms.ts b/src/mol-plugin/state/transforms.ts index c2b27831faceaef6ca37bcefe0e530a559598134..c6914174cf71c4d92ec64916da5341ea78ff6b84 100644 --- a/src/mol-plugin/state/transforms.ts +++ b/src/mol-plugin/state/transforms.ts @@ -6,10 +6,10 @@ import * as Data from './transforms/data' import * as Model from './transforms/model' -import * as Visuals from './transforms/visuals' +import * as Representation from './transforms/representation' export const StateTransforms = { Data, Model, - Visuals + Representation } \ No newline at end of file diff --git a/src/mol-plugin/state/transforms/model.ts b/src/mol-plugin/state/transforms/model.ts index 3a4a7963993809f53642b98cfab6f88a1de84fb8..3a5e74757c439500f17cef0661de628ba361cc6a 100644 --- a/src/mol-plugin/state/transforms/model.ts +++ b/src/mol-plugin/state/transforms/model.ts @@ -7,17 +7,16 @@ import { PluginStateTransform } from '../objects'; import { PluginStateObject as SO } from '../objects'; import { Task } from 'mol-task'; -import { Model, Format, Structure, ModelSymmetry, StructureSymmetry, QueryContext, StructureSelection } from 'mol-model/structure'; +import { Model, Format, Structure, ModelSymmetry, StructureSymmetry, QueryContext, StructureSelection as Sel } from 'mol-model/structure'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import Expression from 'mol-script/language/expression'; import { compile } from 'mol-script/runtime/query/compiler'; -import { Mat4 } from 'mol-math/linear-algebra'; import { MolScriptBuilder } from 'mol-script/language/builder'; -export { ParseTrajectoryFromMmCif } -namespace ParseTrajectoryFromMmCif { export interface Params { blockHeader?: string } } -const ParseTrajectoryFromMmCif = PluginStateTransform.Create<SO.Data.Cif, SO.Molecule.Trajectory, ParseTrajectoryFromMmCif.Params>({ - name: 'parse-trajectory-from-mmcif', +export { TrajectoryFromMmCif } +namespace TrajectoryFromMmCif { export interface Params { blockHeader?: string } } +const TrajectoryFromMmCif = PluginStateTransform.Create<SO.Data.Cif, SO.Molecule.Trajectory, TrajectoryFromMmCif.Params>({ + name: 'trajectory-from-mmcif', display: { name: 'Models from mmCIF', description: 'Identify and create all separate models in the specified CIF data block' @@ -45,11 +44,11 @@ const ParseTrajectoryFromMmCif = PluginStateTransform.Create<SO.Data.Cif, SO.Mol } }); -export { CreateModelFromTrajectory } +export { ModelFromTrajectory } const plus1 = (v: number) => v + 1, minus1 = (v: number) => v - 1; -namespace CreateModelFromTrajectory { export interface Params { modelIndex: number } } -const CreateModelFromTrajectory = PluginStateTransform.Create<SO.Molecule.Trajectory, SO.Molecule.Model, CreateModelFromTrajectory.Params>({ - name: 'create-model-from-trajectory', +namespace ModelFromTrajectory { export interface Params { modelIndex: number } } +const ModelFromTrajectory = PluginStateTransform.Create<SO.Molecule.Trajectory, SO.Molecule.Model, ModelFromTrajectory.Params>({ + name: 'model-from-trajectory', display: { name: 'Model from Trajectory', description: 'Create a molecular structure from the specified model.' @@ -66,19 +65,18 @@ const CreateModelFromTrajectory = PluginStateTransform.Create<SO.Molecule.Trajec } }); -export { CreateStructure } -namespace CreateStructure { export interface Params { transform3d?: Mat4 } } -const CreateStructure = PluginStateTransform.Create<SO.Molecule.Model, SO.Molecule.Structure, CreateStructure.Params>({ - name: 'create-structure-from-model', +export { StructureFromModel } +namespace StructureFromModel { export interface Params { } } +const StructureFromModel = PluginStateTransform.Create<SO.Molecule.Model, SO.Molecule.Structure, StructureFromModel.Params>({ + name: 'structure-from-model', display: { name: 'Structure from Model', description: 'Create a molecular structure from the specified model.' }, from: [SO.Molecule.Model], to: [SO.Molecule.Structure], - apply({ a, params }) { + apply({ a }) { let s = Structure.ofModel(a.data); - if (params.transform3d) s = Structure.transform(s, params.transform3d); const label = { label: a.data.label, description: s.elementCount === 1 ? '1 element' : `${s.elementCount} elements` }; return new SO.Molecule.Structure(s, label); } @@ -88,10 +86,10 @@ function structureDesc(s: Structure) { return s.elementCount === 1 ? '1 element' : `${s.elementCount} elements`; } -export { CreateStructureAssembly } -namespace CreateStructureAssembly { export interface Params { /** if not specified, use the 1st */ id?: string } } -const CreateStructureAssembly = PluginStateTransform.Create<SO.Molecule.Model, SO.Molecule.Structure, CreateStructureAssembly.Params>({ - name: 'create-structure-assembly', +export { StructureAssemblyFromModel } +namespace StructureAssemblyFromModel { export interface Params { /** if not specified, use the 1st */ id?: string } } +const StructureAssemblyFromModel = PluginStateTransform.Create<SO.Molecule.Model, SO.Molecule.Structure, StructureAssemblyFromModel.Params>({ + name: 'structure-assembly-from-model', display: { name: 'Structure Assembly', description: 'Create a molecular structure assembly.' @@ -119,10 +117,10 @@ const CreateStructureAssembly = PluginStateTransform.Create<SO.Molecule.Model, S } }); -export { CreateStructureSelection } -namespace CreateStructureSelection { export interface Params { query: Expression, label?: string } } -const CreateStructureSelection = PluginStateTransform.Create<SO.Molecule.Structure, SO.Molecule.Structure, CreateStructureSelection.Params>({ - name: 'create-structure-selection', +export { StructureSelection } +namespace StructureSelection { export interface Params { query: Expression, label?: string } } +const StructureSelection = PluginStateTransform.Create<SO.Molecule.Structure, SO.Molecule.Structure, StructureSelection.Params>({ + name: 'structure-selection', display: { name: 'Structure Selection', description: 'Create a molecular structure from the specified model.' @@ -130,14 +128,14 @@ const CreateStructureSelection = PluginStateTransform.Create<SO.Molecule.Structu from: [SO.Molecule.Structure], to: [SO.Molecule.Structure], params: () => ({ - query: PD.Value<Expression>(MolScriptBuilder.struct.generator.all), - label: PD.Text('', { isOptional: true }) + query: PD.Value<Expression>(MolScriptBuilder.struct.generator.all, { isHidden: true }), + label: PD.Text('', { isOptional: true, isHidden: true }) }), apply({ a, params }) { // TODO: use cache, add "update" - const compiled = compile<StructureSelection>(params.query); + const compiled = compile<Sel>(params.query); const result = compiled(new QueryContext(a.data)); - const s = StructureSelection.unionStructure(result); + const s = Sel.unionStructure(result); const label = { label: `${params.label || 'Selection'}`, description: structureDesc(s) }; return new SO.Molecule.Structure(s, label); } diff --git a/src/mol-plugin/state/transforms/visuals.ts b/src/mol-plugin/state/transforms/representation.ts similarity index 87% rename from src/mol-plugin/state/transforms/visuals.ts rename to src/mol-plugin/state/transforms/representation.ts index cf1d4ee95bac8977817c3fe23c74cf714ac2f51f..cd51ffcbcf7c09e928055be01cd891955acb4554 100644 --- a/src/mol-plugin/state/transforms/visuals.ts +++ b/src/mol-plugin/state/transforms/representation.ts @@ -11,14 +11,14 @@ import { PluginStateObject as SO } from '../objects'; import { PluginContext } from 'mol-plugin/context'; import { ParamDefinition as PD } from 'mol-util/param-definition'; -export { CreateStructureRepresentation } -namespace CreateStructureRepresentation { +export { StructureRepresentation3D } +namespace StructureRepresentation3D { export interface Params { type: { name: string, params: any /** todo is there "common type" */ }, } } -const CreateStructureRepresentation = PluginStateTransform.Create<SO.Molecule.Structure, SO.Molecule.Representation3D, CreateStructureRepresentation.Params>({ - name: 'create-structure-representation', +const StructureRepresentation3D = PluginStateTransform.Create<SO.Molecule.Structure, SO.Molecule.Representation3D, StructureRepresentation3D.Params>({ + name: 'structure-representation-3d', display: { name: '3D Representation' }, from: [SO.Molecule.Structure], to: [SO.Molecule.Representation3D], diff --git a/src/mol-plugin/ui/controls/parameters.tsx b/src/mol-plugin/ui/controls/parameters.tsx index 86c955cb0c2336f8e10b27e87406da2cf36ee82f..de4a6afbb493272cf0572f679557a3ff4262d7b5 100644 --- a/src/mol-plugin/ui/controls/parameters.tsx +++ b/src/mol-plugin/ui/controls/parameters.tsx @@ -27,6 +27,7 @@ export class ParameterControls<P extends PD.Params> extends React.PureComponent< return <div style={{ width: '100%' }}> {Object.keys(params).map(key => { const param = params[key]; + if (param.isHidden) return null; const Control = controlFor(param); if (!Control) return null; return <Control param={param} key={key} onChange={this.props.onChange} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} name={key} value={values[key]} /> diff --git a/src/mol-plugin/ui/state/common.tsx b/src/mol-plugin/ui/state/common.tsx index ca64bbf00308c28366a9261e1596e163017fd81a..d58978b55e65a0edcddab82fce23ebe1aa6ebc51 100644 --- a/src/mol-plugin/ui/state/common.tsx +++ b/src/mol-plugin/ui/state/common.tsx @@ -53,6 +53,14 @@ namespace StateTransformParameters { export type Class = React.ComponentClass<Props> + function areParamsEmpty(params: PD.Params) { + const keys = Object.keys(params); + for (const k of keys) { + if (!params[k].isHidden) return false; + } + return true; + } + export function infoFromAction(plugin: PluginContext, state: State, action: StateAction, nodeRef: Transform.Ref): Props['info'] { const source = state.cells.get(nodeRef)!.obj!; const params = action.definition.params ? action.definition.params(source, plugin) : { }; @@ -60,7 +68,7 @@ namespace StateTransformParameters { return { initialValues, params, - isEmpty: Object.keys(params).length === 0 + isEmpty: areParamsEmpty(params) }; } @@ -72,7 +80,7 @@ namespace StateTransformParameters { return { initialValues: transform.params, params, - isEmpty: Object.keys(params).length === 0 + isEmpty: areParamsEmpty(params) } } } diff --git a/src/mol-util/param-definition.ts b/src/mol-util/param-definition.ts index 8bb45df5b470cdb53cbe3acb8d691de78ed21b92..e508a72c7e8aaffd8d4cc988ceb7fd50b66a9a71 100644 --- a/src/mol-util/param-definition.ts +++ b/src/mol-util/param-definition.ts @@ -14,7 +14,8 @@ export namespace ParamDefinition { export interface Info { label?: string, description?: string, - isOptional?: boolean + isOptional?: boolean, + isHidden?: boolean } function setInfo<T extends Info>(param: T, info?: Info): T { @@ -22,6 +23,7 @@ export namespace ParamDefinition { if (info.description) param.description = info.description; if (info.label) param.label = info.label; if (info.isOptional) param.isOptional = info.isOptional; + if (info.isHidden) param.isHidden = info.isHidden; return param; }