Browse Source

ParamDefinition.Group.presets support

dsehnal 3 years ago
parent
commit
67d3c65907

+ 2 - 1
CHANGELOG.md

@@ -12,7 +12,8 @@ Note that since we don't clearly distinguish between a public and private interf
 - [Breaking] Add per-object material rendering properties
   - ``SimpleSettingsParams.lighting.renderStyle`` and ``RendererParams.style`` were removed
 - Add substance theme with per-group material rendering properties
-- StructureComponentManager.Options state saving support
+- ``StructureComponentManager.Options`` state saving support
+- ``ParamDefinition.Group.presets`` support
 
 ## [v2.4.1] - 2021-11-28
 

+ 29 - 3
src/mol-plugin-ui/controls/parameters.tsx

@@ -19,7 +19,7 @@ import { PluginUIComponent } from '../base';
 import { ActionMenu } from './action-menu';
 import { ColorOptions, ColorValueOption, CombinedColorControl } from './color';
 import { Button, ControlGroup, ControlRow, ExpandGroup, IconButton, TextInput, ToggleButton } from './common';
-import { Icon, HelpOutlineSvg, CheckSvg, ClearSvg, BookmarksOutlinedSvg, MoreHorizSvg, ArrowDropDownSvg, ArrowRightSvg, ArrowDownwardSvg, ArrowUpwardSvg, DeleteOutlinedSvg } from './icons';
+import { Icon, HelpOutlineSvg, CheckSvg, ClearSvg, BookmarksOutlinedSvg, MoreHorizSvg, ArrowDropDownSvg, ArrowRightSvg, ArrowDownwardSvg, ArrowUpwardSvg, DeleteOutlinedSvg, TuneSvg } from './icons';
 import { legendFor } from './legend';
 import { LineGraphComponent } from './line-graph/line-graph-component';
 import { Slider, Slider2 } from './slider';
@@ -1079,8 +1079,8 @@ export class MultiSelectControl extends React.PureComponent<ParamProps<PD.MultiS
     }
 }
 
-export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>> & { inMapped?: boolean }, { isExpanded: boolean, showHelp: boolean }> {
-    state = { isExpanded: !!this.props.param.isExpanded, showHelp: false }
+export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>> & { inMapped?: boolean }, { isExpanded: boolean, showPresets: boolean, showHelp: boolean }> {
+    state = { isExpanded: !!this.props.param.isExpanded, showPresets: false, showHelp: false }
 
     change(value: any) {
         this.props.onChange({ name: this.props.name, param: this.props.param, value });
@@ -1091,6 +1091,30 @@ export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>
     }
 
     toggleExpanded = () => this.setState({ isExpanded: !this.state.isExpanded });
+    toggleShowPresets = () => this.setState({ showPresets: !this.state.showPresets });
+
+    presetItems = memoizeLatest((param: PD.Group<any>) => ActionMenu.createItemsFromSelectOptions(param.presets ?? []));
+
+    onSelectPreset: ActionMenu.OnSelect = item => {
+        this.setState({ showPresets: false });
+        console.log(item);
+        this.change(item?.value);
+    }
+
+    presets() {
+        if (!this.props.param.presets) return null;
+
+        const label = this.props.param.label || camelCaseToWords(this.props.name);
+        return <div className='msp-control-group-wrapper'>
+            <div className='msp-control-group-header'>
+                <button className='msp-btn msp-form-control msp-btn-block' onClick={this.toggleShowPresets}>
+                    <Icon svg={TuneSvg} />
+                    {label} Presets
+                </button>
+            </div>
+            {this.state.showPresets && <ActionMenu items={this.presetItems(this.props.param)} onSelect={this.onSelectPreset} />}
+        </div>;
+    }
 
     pivoted() {
         const key = this.props.param.pivot as string;
@@ -1116,6 +1140,7 @@ export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>
             {ctrl}
             <IconButton svg={MoreHorizSvg} onClick={this.toggleExpanded} toggleState={this.state.isExpanded} title={`More Options`} />
             <div className='msp-control-offset'>
+                {this.presets()}
                 <ParameterControls params={filtered} onEnter={this.props.onEnter} values={this.props.value} onChange={this.onChangeParam} isDisabled={this.props.isDisabled} />
             </div>
         </div>;
@@ -1149,6 +1174,7 @@ export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>
                 </button>
             </div>
             {this.state.isExpanded && <div className='msp-control-offset'>
+                {this.presets()}
                 {controls}
             </div>}
         </div>;

+ 8 - 1
src/mol-util/material.ts

@@ -50,7 +50,14 @@ export namespace Material {
             PD.Group({
                 metalness: PD.Numeric(0, { min: 0, max: 1, step: 0.01 }),
                 roughness: PD.Numeric(1, { min: 0, max: 1, step: 0.01 }),
-            }, info)
+            }, {
+                ...info,
+                presets: [
+                    [{ metalness: 0, roughness: 1 }, 'Matte'],
+                    [{ metalness: 0.5, roughness: 0.5 }, 'Metallic'],
+                    [{ metalness: 0, roughness: 0 }, 'Plastic'],
+                ]
+            })
         );
     }
 }

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

@@ -225,12 +225,14 @@ export namespace ParamDefinition {
     export interface Group<T> extends Base<T> {
         type: 'group',
         params: Params,
+        presets?: Select<T>['options'],
         isExpanded?: boolean,
         isFlat?: boolean,
         pivot?: keyof T
     }
-    export function Group<T>(params: For<T>, info?: Info & { isExpanded?: boolean, isFlat?: boolean, customDefault?: any, pivot?: keyof T }): Group<Normalize<T>> {
+    export function Group<T>(params: For<T>, info?: Info & { isExpanded?: boolean, isFlat?: boolean, customDefault?: any, pivot?: keyof T, presets?: Select<T>['options'] }): Group<Normalize<T>> {
         const ret = setInfo<Group<Normalize<T>>>({ type: 'group', defaultValue: info?.customDefault || getDefaultValues(params as any as Params) as any, params: params as any as Params }, info);
+        if (info?.presets) ret.presets = info.presets;
         if (info?.isExpanded) ret.isExpanded = info.isExpanded;
         if (info?.isFlat) ret.isFlat = info.isFlat;
         if (info?.pivot) ret.pivot = info.pivot as any;