From 0cd0e30657873a78479847e3c7d9563ab648e83a Mon Sep 17 00:00:00 2001
From: David Sehnal <david.sehnal@gmail.com>
Date: Thu, 15 Nov 2018 00:18:43 +0100
Subject: [PATCH] updated Group and Mapped parameter definitions

---
 src/mol-plugin/state/transforms/visuals.ts |  2 +-
 src/mol-plugin/ui/controls/parameters.tsx  | 39 ++++++++++++++--------
 src/mol-util/param-definition.ts           | 12 +++----
 3 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/src/mol-plugin/state/transforms/visuals.ts b/src/mol-plugin/state/transforms/visuals.ts
index 62eb11bc4..f5aab7a45 100644
--- a/src/mol-plugin/state/transforms/visuals.ts
+++ b/src/mol-plugin/state/transforms/visuals.ts
@@ -36,7 +36,7 @@ const CreateStructureRepresentation = PluginStateTransform.Create<SO.Molecule.St
             type: PD.Mapped('Type', '',
                 ctx.structureReprensentation.registry.default.name,
                 ctx.structureReprensentation.registry.types,
-                name => ctx.structureReprensentation.registry.get(name)!.getParams(ctx.structureReprensentation.themeCtx, a.data))
+                name => PD.Group('Params', '', ctx.structureReprensentation.registry.get(name)!.getParams(ctx.structureReprensentation.themeCtx, a.data)))
         })
     },
     apply({ a, params }, plugin: PluginContext) {
diff --git a/src/mol-plugin/ui/controls/parameters.tsx b/src/mol-plugin/ui/controls/parameters.tsx
index 9e46d897f..b7b88c3f3 100644
--- a/src/mol-plugin/ui/controls/parameters.tsx
+++ b/src/mol-plugin/ui/controls/parameters.tsx
@@ -29,6 +29,7 @@ export class ParameterControls<P extends PD.Params> extends React.PureComponent<
             {Object.keys(params).map(key => {
                 const param = params[key];
                 if (param.type === 'mapped') return <MappedControl param={param} key={key} {...common} name={key} value={values[key]} />
+                if (param.type === 'group') return <GroupControl param={param} key={key} {...common} name={key} value={values[key]} />
                 return <ParamWrapper control={controlFor(param)} param={param} key={key} {...common} name={key} value={values[key]} />
             })}
         </div>;
@@ -45,14 +46,12 @@ function controlFor(param: PD.Any): ValueControl {
         case 'select': return SelectControl;
         case 'text': return TextControl;
         case 'interval': return IntervalControl;
-        case 'group': return GroupControl;
+        case 'group': throw Error('Must be handled separately');
         case 'mapped': throw Error('Must be handled separately');
     }
     throw new Error('not supported');
 }
 
-type MappedWrapperProps = { name: string, value: PD.Mapped<any>['defaultValue'], param: PD.Mapped<any>, onChange: ParamOnChange, onEnter?: () => void, isEnabled?: boolean }
-
 type ParamWrapperProps = { name: string, value: any, param: PD.Base<any>, onChange: ParamOnChange, control: ValueControl, onEnter?: () => void, isEnabled?: boolean }
 export type ParamOnChange = (params: { param: PD.Base<any>, name: string, value: any }) => void
 type ValueControlProps<P extends PD.Base<any> = PD.Base<any>> = { value: any, param: P, isEnabled?: boolean, onChange: (v: any) => void, onEnter?: () => void }
@@ -176,41 +175,55 @@ export class ColorControl extends React.PureComponent<ValueControlProps<PD.Color
     }
 }
 
-export class GroupControl extends React.PureComponent<ValueControlProps<PD.Group<any>>> {
-    // onChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
-    //     this.setState({ value: e.target.value });
-    //     this.props.onChange(e.target.value);
-    // }
+type GroupWrapperProps = { name: string, value: PD.Group<any>['defaultValue'], param: PD.Group<any>, onChange: ParamOnChange, onEnter?: () => void, isEnabled?: boolean }
+export class GroupControl extends React.PureComponent<GroupWrapperProps> {
+    change(value: PD.Mapped<any>['defaultValue'] ) {
+        this.props.onChange({ name: this.props.name, param: this.props.param, value });
+    }
+
+    onChangeParam: ParamOnChange = e => {
+        const value: PD.Mapped<any>['defaultValue'] = this.props.value;
+        this.change({ ...value.params, [e.name]: e.value });
+    }
 
     render() {
-        return <span>group TODO</span>;
+        const value: PD.Mapped<any>['defaultValue'] = this.props.value;
+        const params = this.props.param.params;
+
+        return <div>
+            <ParameterControls params={params} onChange={this.onChangeParam} values={value.params} onEnter={this.props.onEnter} isEnabled={this.props.isEnabled} />
+        </div>
     }
 }
 
+type MappedWrapperProps = { name: string, value: PD.Mapped<any>['defaultValue'], param: PD.Mapped<any>, onChange: ParamOnChange, onEnter?: () => void, isEnabled?: boolean }
 export class MappedControl extends React.PureComponent<MappedWrapperProps> {
     change(value: PD.Mapped<any>['defaultValue'] ) {
         this.props.onChange({ name: this.props.name, param: this.props.param, value });
     }
 
     onChangeName: ParamOnChange = e => {
-        this.change({ name: e.value, params: PD.getDefaultValues(this.props.param.map(e.value)) });
+        this.change({ name: e.value, params: this.props.param.map(e.value).defaultValue });
     }
 
     onChangeParam: ParamOnChange = e => {
         const value: PD.Mapped<any>['defaultValue'] = this.props.value;
-        this.change({ name: value.name, params: { ...value.params, [e.name]: e.value } });
+        this.change({ name: value.name, params: e.value });
     }
 
     render() {
         const value: PD.Mapped<any>['defaultValue'] = this.props.value;
-        const params = this.props.param.map(value.name);
+        const param = this.props.param.map(value.name);
 
         return <div>
             <ParamWrapper control={SelectControl} param={this.props.param.select}
                 isEnabled={this.props.isEnabled} onChange={this.onChangeName} onEnter={this.props.onEnter}
                 name={'name'} value={value.name} />
             <div style={{ borderLeft: '5px solid #777', paddingLeft: '5px' }}>
-                <ParameterControls params={params} onChange={this.onChangeParam} values={value.params} onEnter={this.props.onEnter} isEnabled={this.props.isEnabled} />
+                {param.type === 'group'
+                ? <GroupControl param={param} value={value} name='param' onChange={this.onChangeParam} onEnter={this.props.onEnter} isEnabled={this.props.isEnabled} />
+                : param.type === 'mapped' ? 'nested mapped params are not supported'
+                : <ParamWrapper control={controlFor(param)} param={param} onChange={this.onChangeParam} onEnter={this.props.onEnter} isEnabled={this.props.isEnabled} name={'value'} value={value} />}
             </div>
         </div>
     }
diff --git a/src/mol-util/param-definition.ts b/src/mol-util/param-definition.ts
index c77857660..2f93c7588 100644
--- a/src/mol-util/param-definition.ts
+++ b/src/mol-util/param-definition.ts
@@ -90,25 +90,25 @@ export namespace ParamDefinition {
         return { type: 'interval', label, description, defaultValue }
     }
 
-    export interface Group<T extends { [key: string]: any }> extends Base<T> {
+    export interface Group<T> extends Base<T> {
         type: 'group',
-        params: T
+        params: Params
     }
-    export function Group<T extends { [key: string]: any }>(label: string, description: string, params: T): Group<T> {
-        return { type: 'group', label, description, defaultValue: getDefaultValues(params), params };
+    export function Group<P extends Params>(label: string, description: string, params: P): Group<Values<P>> {
+        return { type: 'group', label, description, defaultValue: getDefaultValues(params) as any, params };
     }
 
     export interface Mapped<T> extends Base<{ name: string, params: T }> {
         type: 'mapped',
         select: Select<string>,
-        map(name: string): Params
+        map(name: string): Any
     }
     export function Mapped<T>(label: string, description: string, defaultKey: string, names: [string, string][], map: Mapped<T>['map']): Mapped<T> {
         return {
             type: 'mapped',
             label,
             description,
-            defaultValue: { name: defaultKey, params: getDefaultValues(map(defaultKey)) as any },
+            defaultValue: { name: defaultKey, params: map(defaultKey).defaultValue as any },
             select: Select<string>(label, description, defaultKey, names),
             map
         };
-- 
GitLab