Bladeren bron

added PD.Group.isExpanded, wip mol-plugin

David Sehnal 6 jaren geleden
bovenliggende
commit
803d5dff29

+ 3 - 2
src/mol-plugin/index.ts

@@ -10,7 +10,7 @@ import * as React from 'react';
 import * as ReactDOM from 'react-dom';
 import { PluginCommands } from './command';
 import { PluginSpec } from './spec';
-import { ObtainAtomicStructure } from './state/actions/basic';
+import { DownloadAtomicStructure, CreateComplexRepresentation } from './state/actions/basic';
 import { StateTransforms } from './state/transforms';
 import { PluginBehaviors } from './behavior';
 import { LogEntry } from 'mol-util/log-entry';
@@ -22,7 +22,8 @@ function getParam(name: string, regex: string): string {
 
 const DefaultSpec: PluginSpec = {
     actions: [
-        PluginSpec.Action(ObtainAtomicStructure),
+        PluginSpec.Action(DownloadAtomicStructure),
+        PluginSpec.Action(CreateComplexRepresentation),
         PluginSpec.Action(StateTransforms.Data.Download),
         PluginSpec.Action(StateTransforms.Data.ParseCif),
         PluginSpec.Action(StateTransforms.Model.StructureAssemblyFromModel),

+ 28 - 8
src/mol-plugin/state/actions/basic.ts

@@ -13,8 +13,8 @@ import { CartoonParams } from 'mol-repr/structure/representation/cartoon';
 import { BallAndStickParams } from 'mol-repr/structure/representation/ball-and-stick';
 import { Download } from '../transforms/data';
 
-export { ObtainAtomicStructure }
-namespace ObtainAtomicStructure {
+export { DownloadAtomicStructure }
+namespace DownloadAtomicStructure {
     export type Sources = 'pdbe-updated' | 'rcsb' | 'bcif-static' | 'url' | 'file'
     export type Source = ObtainStructureHelpers.MapParams<Sources, typeof ObtainStructureHelpers.ControlMap>
     export interface Params {
@@ -22,25 +22,26 @@ namespace ObtainAtomicStructure {
     }
 }
 namespace ObtainStructureHelpers {
-    export const SourceOptions: [ObtainAtomicStructure.Sources, string][] = [
+    export const SourceOptions: [DownloadAtomicStructure.Sources, string][] = [
         ['pdbe-updated', 'PDBe Updated'],
         ['rcsb', 'RCSB'],
         ['bcif-static', 'BinaryCIF (static PDBe Updated)'],
         ['url', 'URL'],
+        // TODO
         // ['file', 'File']
     ];
     export const ControlMap = {
         'pdbe-updated': PD.Text('1cbs', { label: 'Id' }),
         'rcsb': PD.Text('1tqn', { label: 'Id' }),
         'bcif-static': PD.Text('1tqn', { label: 'Id' }),
-        'url': PD.Group({ url: PD.Text(''), isBinary: PD.Boolean(false) }),
+        'url': PD.Group({ url: PD.Text(''), isBinary: PD.Boolean(false) }, { isExpanded: true }),
         'file': PD.Group({ })
     }
     export function getControls(key: string) { return (ControlMap as any)[key]; }
 
-    export type MapParams<P extends ObtainAtomicStructure.Sources, Map extends { [K in P]: PD.Any }> = P extends ObtainAtomicStructure.Sources ? PD.NamedParams<Map[P]['defaultValue'], P> : never
+    export type MapParams<P extends DownloadAtomicStructure.Sources, Map extends { [K in P]: PD.Any }> = P extends DownloadAtomicStructure.Sources ? PD.NamedParams<Map[P]['defaultValue'], P> : never
 
-    export function getUrl(src: ObtainAtomicStructure.Source): Download.Params {
+    export function getUrl(src: DownloadAtomicStructure.Source): Download.Params {
         switch (src.name) {
             case 'url': return src.params;
             case 'pdbe-updated': return { url: `https://www.ebi.ac.uk/pdbe/static/entry/${src.params.toLowerCase()}_updated.cif`, isBinary: false, label: `PDBe: ${src.params}` };
@@ -50,10 +51,10 @@ namespace ObtainStructureHelpers {
         }
     }
 }
-const ObtainAtomicStructure = StateAction.create<PluginStateObject.Root, void, ObtainAtomicStructure.Params>({
+const DownloadAtomicStructure = StateAction.create<PluginStateObject.Root, void, DownloadAtomicStructure.Params>({
     from: [PluginStateObject.Root],
     display: {
-        name: 'Obtain Structure',
+        name: 'Download Structure',
         description: 'Load a structure from PDBe and create its default Assembly and visual'
     },
     params: () => ({ source: PD.Mapped('bcif-static', ObtainStructureHelpers.SourceOptions, ObtainStructureHelpers.getControls) }),
@@ -91,6 +92,25 @@ const ObtainAtomicStructure = StateAction.create<PluginStateObject.Root, void, O
     }
 });
 
+export const CreateComplexRepresentation = StateAction.create<PluginStateObject.Molecule.Structure, void, {}>({
+    from: [PluginStateObject.Molecule.Structure],
+    display: {
+        name: 'Create Complex',
+        description: 'Split the structure into Sequence/Water/Ligands/... '
+    },
+    apply({ ref, state }) {
+        const root = state.build().to(ref);
+        root.apply(StateTransforms.Model.StructureComplexElement, { type: 'sequence' })
+            .apply(StateTransforms.Representation.StructureRepresentation3D, { type: { name: 'cartoon', params: PD.getDefaultValues(CartoonParams) } });
+        root.apply(StateTransforms.Model.StructureComplexElement, { type: 'ligands' })
+            .apply(StateTransforms.Representation.StructureRepresentation3D, { type: { name: 'ball-and-stick', params: PD.getDefaultValues(BallAndStickParams) } });
+        root.apply(StateTransforms.Model.StructureComplexElement, { type: 'water' })
+            .apply(StateTransforms.Representation.StructureRepresentation3D, { type: { name: 'ball-and-stick', params: { ...PD.getDefaultValues(BallAndStickParams), alpha: 0.51 } } });
+
+        return state.update(root.getTree());
+    }
+});
+
 export const UpdateTrajectory = StateAction.create<PluginStateObject.Root, void, { action: 'advance' | 'reset', by?: number }>({
     from: [],
     display: {

+ 1 - 1
src/mol-plugin/ui/controls/parameters.tsx

@@ -224,7 +224,7 @@ export class MultiSelectControl extends React.PureComponent<ParamProps<PD.MultiS
 }
 
 export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>, { isExpanded: boolean }> {
-    state = { isExpanded: false }
+    state = { isExpanded: !!this.props.param.isExpanded }
 
     change(value: any ) {
         this.props.onChange({ name: this.props.name, param: this.props.param, value });

+ 10 - 11
src/mol-plugin/ui/plugin.tsx

@@ -19,6 +19,7 @@ import { BackgroundTaskProgress } from './task';
 import { ApplyActionContol } from './state/apply-action';
 import { PluginState } from 'mol-plugin/state';
 import { UpdateTransformContol } from './state/update-transform';
+import { StateObjectCell } from 'mol-state';
 
 export class Plugin extends React.Component<{ plugin: PluginContext }, {}> {
 
@@ -141,22 +142,20 @@ export class CurrentObject extends PluginComponent {
         const current = this.current;
 
         const ref = current.ref;
-        // const n = this.props.plugin.state.data.tree.nodes.get(ref)!;
-        const obj = current.state.cells.get(ref)!;
+        const cell = current.state.cells.get(ref)!;
+        const parent: StateObjectCell | undefined = (cell.sourceRef && current.state.cells.get(cell.sourceRef)!) || void 0;
 
-        const type = obj && obj.obj ? obj.obj.type : void 0;
+        const type = cell && cell.obj ? cell.obj.type : void 0;
+        const transform = cell.transform;
+        const def = transform.transformer.definition;
 
-        const transform = current.state.transforms.get(ref);
-
-        const actions = type
-            ? current.state.actions.fromType(type)
-            : []
+        const actions = type ? current.state.actions.fromType(type) : [];
         return <>
             <div className='msp-section-header'>
-                {obj.obj ? obj.obj.label : ref}
+                {cell.obj ? cell.obj.label : (def.display && def.display.name) || def.name}
             </div>
-            <UpdateTransformContol state={current.state} transform={transform} />
-            {
+            { (parent && parent.status === 'ok') && <UpdateTransformContol state={current.state} transform={transform} /> }
+            {cell.status === 'ok' &&
                 actions.map((act, i) => <ApplyActionContol plugin={this.plugin} key={`${act.id}`} state={current.state} action={act} nodeRef={ref} />)
             }
         </>;

+ 1 - 0
src/mol-state/action.ts

@@ -31,6 +31,7 @@ namespace StateAction {
     }
 
     export interface ApplyParams<A extends StateObject = StateObject, P extends {} = {}> {
+        ref: string,
         cell: StateObjectCell,
         a: A,
         state: State,

+ 1 - 1
src/mol-state/state.ts

@@ -104,7 +104,7 @@ class State {
             if (!cell) throw new Error(`'${ref}' does not exist.`);
             if (cell.status !== 'ok') throw new Error(`Action cannot be applied to a cell with status '${cell.status}'`);
 
-            return runTask(action.definition.apply({ cell, a: cell.obj!, params, state: this }, this.globalContext), ctx);
+            return runTask(action.definition.apply({ ref, cell, a: cell.obj!, params, state: this }, this.globalContext), ctx);
         });
     }
 

+ 6 - 3
src/mol-util/param-definition.ts

@@ -126,10 +126,13 @@ export namespace ParamDefinition {
 
     export interface Group<T> extends Base<T> {
         type: 'group',
-        params: Params
+        params: Params,
+        isExpanded?: boolean
     }
-    export function Group<P extends Params>(params: P, info?: Info): Group<Values<P>> {
-        return setInfo<Group<Values<P>>>({ type: 'group', defaultValue: getDefaultValues(params) as any, params }, info);
+    export function Group<P extends Params>(params: P, info?: Info & { isExpanded?: boolean }): Group<Values<P>> {
+        const ret = setInfo<Group<Values<P>>>({ type: 'group', defaultValue: getDefaultValues(params) as any, params }, info);
+        if (info && info.isExpanded) ret.isExpanded = info.isExpanded;
+        return ret;
     }
 
     export interface NamedParams<T = any, K = string> { name: K, params: T }