Просмотр исходного кода

add basic scipt language selector

Alexander Rose 2 лет назад
Родитель
Сommit
080c8e7af3
3 измененных файлов с 46 добавлено и 42 удалено
  1. 26 21
      src/mol-plugin-ui/controls/parameters.tsx
  2. 15 19
      src/mol-script/script.ts
  3. 5 2
      src/mol-script/transpile.ts

+ 26 - 21
src/mol-plugin-ui/controls/parameters.tsx

@@ -7,6 +7,7 @@
 
 import * as React from 'react';
 import { Mat4, Vec2, Vec3 } from '../../mol-math/linear-algebra';
+import { Script } from '../../mol-script/script';
 import { Asset } from '../../mol-util/assets';
 import { Color } from '../../mol-util/color';
 import { ColorListEntry } from '../../mol-util/color/color';
@@ -1466,31 +1467,35 @@ export class ConvertedControl extends React.PureComponent<ParamProps<PD.Converte
     }
 }
 
-export class ScriptControl extends SimpleParam<PD.Script> {
-    onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
-        const value = e.target.value;
-        if (value !== this.props.value.expression) {
-            this.update({ language: this.props.value.language, expression: value });
+export class ScriptControl extends React.PureComponent<ParamProps<PD.Script>> {
+    onChange: ParamOnChange = ({ name, value }) => {
+        const k = name as 'language' | 'expression';
+        if (value !== this.props.value[k]) {
+            this.props.onChange({ param: this.props.param, name: this.props.name, value: { ...this.props.value, [k]: value } });
         }
     };
 
-    onKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
-        if ((e.keyCode === 13 || e.charCode === 13 || e.key === 'Enter')) {
-            if (this.props.onEnter) this.props.onEnter();
-        }
-        e.stopPropagation();
-    };
-
-    renderControl() {
+    render() {
         // TODO: improve!
 
-        const placeholder = this.props.param.label || camelCaseToWords(this.props.name);
-        return <input type='text'
-            value={this.props.value.expression || ''}
-            placeholder={placeholder}
-            onChange={this.onChange}
-            onKeyPress={this.props.onEnter ? this.onKeyPress : void 0}
-            disabled={this.props.isDisabled}
-        />;
+        const selectParam: PD.Select<PD.Script['defaultValue']['language']> = {
+            defaultValue: this.props.value.language,
+            options: PD.objectToOptions(Script.Info),
+            type: 'select',
+        };
+        const select = <SelectControl param={selectParam}
+            isDisabled={this.props.isDisabled} onChange={this.onChange} onEnter={this.props.onEnter}
+            name='language' value={this.props.value.language} />;
+
+        const textParam: PD.Text = {
+            defaultValue: this.props.value.language,
+            type: 'text',
+        };
+        const text = <TextControl param={textParam} isDisabled={this.props.isDisabled} onChange={this.onChange} name='expression' value={this.props.value.expression} />;
+
+        return <>
+            {select}
+            {text}
+        </>;
     }
 }

+ 15 - 19
src/mol-script/script.ts

@@ -11,15 +11,7 @@ import { Expression } from './language/expression';
 import { StructureElement, QueryContext, StructureSelection, Structure, QueryFn, QueryContextOptions } from '../mol-model/structure';
 import { compile } from './runtime/query/compiler';
 import { MolScriptBuilder } from './language/builder';
-
-
-
-
-
-
-
-
-
+import { assertUnreachable } from '../mol-util/type-helpers';
 
 export { Script };
 
@@ -30,7 +22,14 @@ function Script(expression: string = '(sel.atom.all)', language: Script.Language
 }
 
 namespace Script {
-    export type Language = 'mol-script' | 'pymol' | 'vmd' | 'jmol' | 'rasmol'
+    export const Info = {
+        'mol-script': 'Mol-Script',
+        'pymol': 'PyMOL',
+        'vmd': 'VMD',
+        'jmol': 'Jmol',
+        'rasmol': 'Rasmol'
+    };
+    export type Language = keyof typeof Info;
 
     export function is(x: any): x is Script {
         return !!x && typeof (x as Script).expression === 'string' && !!(x as Script).language;
@@ -43,20 +42,17 @@ namespace Script {
     export function toExpression(script: Script): Expression {
         switch (script.language) {
             case 'mol-script':
-	    const parsed = parseMolScript(script.expression);
-	    if (parsed.length === 0) throw new Error('No query');
-	    return transpileMolScript(parsed[0]);
+                const parsed = parseMolScript(script.expression);
+                if (parsed.length === 0) throw new Error('No query');
+                return transpileMolScript(parsed[0]);
             case 'pymol':
-	    return parse('pymol', script.expression) as Expression;
             case 'jmol':
-	    return parse('jmol', script.expression) as Expression;
             case 'vmd':
-	    return parse('vmd', script.expression) as Expression;
             case 'rasmol':
-	    return parse('rasmol', script.expression) as Expression;
+                return parse(script.language, script.expression);
+            default:
+                assertUnreachable(script.language);
         }
-
-        throw new Error('unsupported script language');
     }
 
     export function toQuery(script: Script): QueryFn<StructureSelection> {

+ 5 - 2
src/mol-script/transpile.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Koya Sakuma
  */
@@ -9,9 +9,11 @@
 
 import { Transpiler } from './transpilers/transpiler';
 import { _transpiler } from './transpilers/all';
+import { Expression } from './language/expression';
+import { Script } from './script';
 const transpiler: {[index: string]: Transpiler} = _transpiler;
 
-export function parse(lang: string, str: string) {
+export function parse(lang: Script.Language, str: string): Expression {
     try {
         const query = transpiler[lang](str);
 
@@ -25,5 +27,6 @@ export function parse(lang: string, str: string) {
         console.log(str);
         console.log(e.message);
         console.log('\n');
+        throw e;
     }
 }