diff --git a/src/apps/viewer/app.ts b/src/apps/viewer/app.ts index 2ab5c5eafb53157ff9ca975cb4041cbf990f8167..f5af2fca0f8253ee2953ec64630beeecaa4f13e1 100644 --- a/src/apps/viewer/app.ts +++ b/src/apps/viewer/app.ts @@ -5,6 +5,7 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ +import { ScriptSetting } from '../../extensions/language-select'; import { ANVILMembraneOrientation } from '../../extensions/anvil/behavior'; import { CellPack } from '../../extensions/cellpack'; import { DnatcoConfalPyramids } from '../../extensions/dnatco'; @@ -67,6 +68,7 @@ const Extensions = { 'geo-export': PluginSpec.Behavior(GeometryExport), 'ma-quality-assessment': PluginSpec.Behavior(MAQualityAssessment), 'zenodo-import': PluginSpec.Behavior(ZenodoImport), + 'script-language': PluginSpec.Behavior(ScriptSetting), }; const DefaultViewerOptions = { @@ -494,4 +496,4 @@ export const ViewerAutoPreset = StructureRepresentationPresetProvider({ return await PresetStructureRepresentations.auto.apply(ref, params, plugin); } } -}); \ No newline at end of file +}); diff --git a/src/extensions/language-select/index.ts b/src/extensions/language-select/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..831fb6dff0f88efc3ed6bc96908c2e5d8287f3ba --- /dev/null +++ b/src/extensions/language-select/index.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2022 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { PluginBehavior } from '../../mol-plugin/behavior/behavior'; +import { ScriptImportUI } from './ui'; + +export const ScriptSetting = PluginBehavior.create<{ }>({ + name: 'extension script language', + category: 'misc', + display: { + name: 'Script Language' + }, + ctor: class extends PluginBehavior.Handler<{ }> { + register(): void { + this.ctx.customImportControls.set('script-language', ScriptImportUI as any); + } + + update() { + return false; + } + + unregister() { + this.ctx.customImportControls.delete('script-language'); + } + }, + params: () => ({ }) +}); diff --git a/src/extensions/language-select/ui.tsx b/src/extensions/language-select/ui.tsx new file mode 100644 index 0000000000000000000000000000000000000000..1b648605fca8c15ac2ef2f5d22969375904185b6 --- /dev/null +++ b/src/extensions/language-select/ui.tsx @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2022 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +//import { DownloadFile } from '../../mol-plugin-state/actions/file'; +//import { DownloadStructure, LoadTrajectory } from '../../mol-plugin-state/actions/structure'; +//import { DownloadDensity } from '../../mol-plugin-state/actions/volume'; +//import { CoordinatesFormatCategory } from '../../mol-plugin-state/formats/coordinates'; +//import { TopologyFormatCategory } from '../../mol-plugin-state/formats/topology'; +//import { TrajectoryFormatCategory } from '../../mol-plugin-state/formats/trajectory'; +//import { VolumeFormatCategory } from '../../mol-plugin-state/formats/volume'; +import { CollapsableControls, CollapsableState } from '../../mol-plugin-ui/base'; +import { Button } from '../../mol-plugin-ui/controls/common'; +import { SelectionModeSvg } from '../../mol-plugin-ui/controls/icons'; +import { ParameterControls } from '../../mol-plugin-ui/controls/parameters'; +import { PluginContext } from '../../mol-plugin/context'; +//import { formatBytes } from '../../mol-util'; +import { ParamDefinition as PD } from '../../mol-util/param-definition'; + +type ScriptFile = { +} + +type ScriptLanguage = { +} + +interface State { + busy?: boolean + languageValues: PD.Values<typeof ScriptImportParams> + importValues?: PD.Values<ImportParams> + importParams?: ImportParams + language?: ScriptLanguage + files?: ScriptFile[] +} + +const ScriptImportParams = { + language: PD.Text('', { description: 'Script Language' }) +}; + +function createImportParams(files: ScriptFile[], plugin: PluginContext) { + const params: PD.Params = {}; + let defaultType = ''; + return { + type: PD.MappedStatic(defaultType, Object.keys(params).length ? params : { '': PD.EmptyGroup() }) + }; +} +type ImportParams = ReturnType<typeof createImportParams> + + +export class ScriptImportUI extends CollapsableControls<{}, State> { + protected defaultState(): State & CollapsableState { + return { + header: 'Scripting Language', + isCollapsed: true, + brand: { accent: 'cyan', svg: SelectionModeSvg }, + languageValues: PD.getDefaultValues(ScriptImportParams), + importValues: undefined, + importParams: undefined, + language: undefined, + files: undefined, + }; + } + private loadLanguage = async () => { + this.plugin.log.message(`'${this.state.languageValues.language}'`); + }; + + private languageParamsOnChange = (values: any) => { + this.setState({ languageValues: values }); + }; + + private renderLanguageInfo(language: ScriptLanguage) { + return <div style={{ marginBottom: 10 }}> + <div className='msp-help-text'> + <div>Language </div> + </div> + </div>; + } + + + + + private renderLoadLanguage() { + return <div style={{ marginBottom: 10 }}> + <ParameterControls params={ScriptImportParams} values={this.state.languageValues} onChangeValues={this.languageParamsOnChange} isDisabled={this.state.busy} /> + <Button onClick={this.loadLanguage} style={{ marginTop: 1 }} disabled={this.state.busy || !this.state.languageValues.language}> + Set Language + </Button> + </div>; + } + + + protected renderControls(): JSX.Element | null { + return <> + {!this.state.language ? this.renderLoadLanguage() : null} + {this.state.language ? this.renderLanguageInfo(this.state.language) : null} + </>; + } + + +} diff --git a/src/mol-plugin-state/helpers/structure-component.ts b/src/mol-plugin-state/helpers/structure-component.ts index 76888cf9b72cbe28e17ab262458d77eb59f8d384..6ddaac6b1c0c4f131985c9f23f36254ef8d4a1bb 100644 --- a/src/mol-plugin-state/helpers/structure-component.ts +++ b/src/mol-plugin-state/helpers/structure-component.ts @@ -40,7 +40,7 @@ export const StructureComponentParams = () => ({ static: PD.Text<StaticStructureComponentType>('polymer'), expression: PD.Value<Expression>(MolScriptBuilder.struct.generator.all), bundle: PD.Value<StructureElement.Bundle>(StructureElement.Bundle.Empty), - script: PD.Script({ language: 'pymol', expression: 'all' }), + script: PD.Script({ language: 'mol-script', expression: '(sel.atom.all)' }), }, { isHidden: true }), nullIfEmpty: PD.Optional(PD.Boolean(true, { isHidden: true })), label: PD.Text('', { isHidden: true }) @@ -167,4 +167,4 @@ export function updateStructureComponent(a: Structure, b: SO.Molecule.Structure, } return updated ? StateTransformer.UpdateResult.Updated : StateTransformer.UpdateResult.Unchanged; -} +} \ 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 5d317d4803edf97e0e9c0e561ebfbc320e52ffaa..b4b24ff137cb7cab29262f9fba96234daaa7339a 100644 --- a/src/mol-plugin-state/transforms/model.ts +++ b/src/mol-plugin-state/transforms/model.ts @@ -786,7 +786,7 @@ const StructureSelectionFromScript = PluginStateTransform.BuiltIn({ from: SO.Molecule.Structure, to: SO.Molecule.Structure, params: () => ({ - script: PD.Script({ language: 'pymol', expression: 'chain A' }), + script: PD.Script({ language: 'pymol', expression: 'all' }), label: PD.Optional(PD.Text('')) }) })({ diff --git a/src/mol-plugin-state/transforms/representation.ts b/src/mol-plugin-state/transforms/representation.ts index 1194eb09dcb6569b92a579d3e26449d3e552d1cd..1e0672b2cf1c5c9aac0c550cd3064a1a141803f2 100644 --- a/src/mol-plugin-state/transforms/representation.ts +++ b/src/mol-plugin-state/transforms/representation.ts @@ -315,12 +315,12 @@ const OverpaintStructureRepresentation3DFromScript = PluginStateTransform.BuiltI to: SO.Molecule.Structure.Representation3DState, params: () => ({ layers: PD.ObjectList({ - script: PD.Script(Script('all', 'pymol')), + script: PD.Script(Script()), color: PD.Color(ColorNames.blueviolet), clear: PD.Boolean(false) }, e => `${e.clear ? 'Clear' : Color.toRgbString(e.color)}`, { defaultValue: [{ - script: Script('all','pymol'), + script: Script(), color: ColorNames.blueviolet, clear: false }] @@ -430,11 +430,11 @@ const TransparencyStructureRepresentation3DFromScript = PluginStateTransform.Bui to: SO.Molecule.Structure.Representation3DState, params: () => ({ layers: PD.ObjectList({ - script: PD.Script(Script('all','pymol')), + script: PD.Script(Script()), value: PD.Numeric(0.5, { min: 0, max: 1, step: 0.01 }, { label: 'Transparency' }), }, e => `Transparency (${e.value})`, { defaultValue: [{ - script: Script('all','pymol'), + script: Script(), value: 0.5, }] }) @@ -541,12 +541,12 @@ const SubstanceStructureRepresentation3DFromScript = PluginStateTransform.BuiltI to: SO.Molecule.Structure.Representation3DState, params: () => ({ layers: PD.ObjectList({ - script: PD.Script(Script('all','pymol')), + script: PD.Script(Script()), material: Material.getParam(), clear: PD.Boolean(false) }, e => `${e.clear ? 'Clear' : Material.toString(e.material)}`, { defaultValue: [{ - script: Script('all','pymol'), + script: Script(), material: Material({ roughness: 1 }), clear: false }] @@ -656,11 +656,11 @@ const ClippingStructureRepresentation3DFromScript = PluginStateTransform.BuiltIn to: SO.Molecule.Structure.Representation3DState, params: () => ({ layers: PD.ObjectList({ - script: PD.Script(Script('all','pymol')), + script: PD.Script(Script()), groups: PD.Converted((g: Clipping.Groups) => Clipping.Groups.toNames(g), n => Clipping.Groups.fromNames(n), PD.MultiSelect(ObjectKeys(Clipping.Groups.Names), PD.objectToOptions(Clipping.Groups.Names))), }, e => `${Clipping.Groups.toNames(e.groups).length} group(s)`, { defaultValue: [{ - script: Script('all','pymol'), + script: Script(), groups: Clipping.Groups.Flag.None, }] }), diff --git a/src/mol-script/script.ts b/src/mol-script/script.ts index b9022c38e33e8fe9ddd3a278c70c701cf98c8cfd..59d1417c9f27c2d8aebfc6e9f6410edd39f8c8e5 100644 --- a/src/mol-script/script.ts +++ b/src/mol-script/script.ts @@ -12,11 +12,20 @@ import { StructureElement, QueryContext, StructureSelection, Structure, QueryFn, import { compile } from './runtime/query/compiler'; import { MolScriptBuilder } from './language/builder'; + + + + + + + + + export { Script }; -interface Script { expression: string, language: Script.Language } +interface Script { expression: string, language: Script.Language} -function Script(expression: string, language: Script.Language): Script { +function Script(expression: string = "(sel.atom.all)", language: Script.Language = "mol-script"): Script { return { expression, language }; }