|
@@ -31,30 +31,67 @@ export interface ParameterControlsProps<P extends PD.Params = PD.Params> {
|
|
|
values: any,
|
|
|
onChange: ParamsOnChange<PD.Values<P>>,
|
|
|
isDisabled?: boolean,
|
|
|
- /** null <=> "support" PD.categories === undefined */
|
|
|
- categoryFilter?: ParameterControlsCategoryFilter
|
|
|
onEnter?: () => void
|
|
|
}
|
|
|
|
|
|
-export class ParameterControls<P extends PD.Params> extends React.PureComponent<ParameterControlsProps<P>, {}> {
|
|
|
+export class ParameterControls<P extends PD.Params> extends React.PureComponent<ParameterControlsProps<P>, { isExpanded: boolean }> {
|
|
|
+ state = { isExpanded: false };
|
|
|
+
|
|
|
onChange: ParamOnChange = (params) => this.props.onChange(params, this.props.values);
|
|
|
|
|
|
- render() {
|
|
|
+ renderControls(keys: string[], essentials: boolean) {
|
|
|
const params = this.props.params;
|
|
|
const values = this.props.values;
|
|
|
- const filter = this.props.categoryFilter;
|
|
|
- const keys = filterParamKeys(params, filter);
|
|
|
- if (keys.length === 0 || values === undefined) return null;
|
|
|
+
|
|
|
return <>
|
|
|
- {keys.map(key => {
|
|
|
+ {keys.map(key => {
|
|
|
const param = params[key];
|
|
|
if (param.isHidden) return null;
|
|
|
+ if ((essentials && !param.isEssential) || (!essentials && param.isEssential)) return null;
|
|
|
const Control = controlFor(param);
|
|
|
if (!Control) return null;
|
|
|
- return <Control param={param} key={key} onChange={this.onChange} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} name={key} value={values[key]} categoryFilter={filter} />
|
|
|
+ return <Control param={param} key={key} onChange={this.onChange} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} name={key} value={values[key]} />
|
|
|
})}
|
|
|
</>;
|
|
|
}
|
|
|
+
|
|
|
+ toggleExpanded = () => this.setState({ isExpanded: !this.state.isExpanded });
|
|
|
+
|
|
|
+ renderCategories(keys: string[]) {
|
|
|
+ return <>
|
|
|
+ {this.renderControls(keys, true)}
|
|
|
+ <div className='msp-control-group-header' style={{ marginTop: '1px' }}>
|
|
|
+ <button className='msp-btn msp-btn-block' onClick={this.toggleExpanded}>
|
|
|
+ <span className={`msp-icon msp-icon-${this.state.isExpanded ? 'collapse' : 'expand'}`} />
|
|
|
+ {'Advanced Parameters'}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ {this.state.isExpanded && <div className='msp-control-offset'>
|
|
|
+ {this.renderControls(keys, false)}
|
|
|
+ </div>}
|
|
|
+ </>;
|
|
|
+ }
|
|
|
+
|
|
|
+ render() {
|
|
|
+ const params = this.props.params;
|
|
|
+ const values = this.props.values;
|
|
|
+ const keys = Object.keys(params);
|
|
|
+ if (keys.length === 0 || values === undefined) return null;
|
|
|
+
|
|
|
+ let essentialCount = 0, nonEssentialCount = 0;
|
|
|
+ for (const k of keys) {
|
|
|
+ const p = params[k];
|
|
|
+ if (p.isEssential) essentialCount += p.isHidden ? 0 : 1;
|
|
|
+ else nonEssentialCount += p.isHidden ? 0 : 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (essentialCount === 0 && nonEssentialCount === 0) return null;
|
|
|
+
|
|
|
+ if (essentialCount === 0) return this.renderControls(keys, false);
|
|
|
+ if (nonEssentialCount === 0) return this.renderControls(keys, true);
|
|
|
+
|
|
|
+ return this.renderCategories(keys);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
export class ParameterMappingControl<S, T> extends PluginUIComponent<{ mapping: ParamMapping<S, T, PluginContext> }> {
|
|
@@ -76,10 +113,6 @@ export class ParameterMappingControl<S, T> extends PluginUIComponent<{ mapping:
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-function filterParamKeys(params: PD.Params, filter: ParameterControlsCategoryFilter | undefined) {
|
|
|
- return filter === void 0 ? Object.keys(params) : Object.keys(params).filter(key => PD.hasCategory(params[key], filter));
|
|
|
-}
|
|
|
-
|
|
|
function controlFor(param: PD.Any): ParamControl | undefined {
|
|
|
switch (param.type) {
|
|
|
case 'value': return void 0;
|
|
@@ -131,7 +164,6 @@ export interface ParamProps<P extends PD.Base<any> = PD.Base<any>> {
|
|
|
value: P['defaultValue'],
|
|
|
param: P,
|
|
|
isDisabled?: boolean,
|
|
|
- categoryFilter?: ParameterControlsCategoryFilter
|
|
|
onChange: ParamOnChange,
|
|
|
onEnter?: () => void
|
|
|
}
|
|
@@ -428,7 +460,7 @@ export class IntervalControl extends React.PureComponent<ParamProps<PD.Interval>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div className='msp-control-offset' style={{ display: this.state.isExpanded ? 'block' : 'none' }}>
|
|
|
- <ParameterControls params={this.components} values={v} onChange={this.componentChange} onEnter={this.props.onEnter} categoryFilter={this.props.categoryFilter} />
|
|
|
+ <ParameterControls params={this.components} values={v} onChange={this.componentChange} onEnter={this.props.onEnter} />
|
|
|
</div>
|
|
|
</>;
|
|
|
}
|
|
@@ -553,7 +585,7 @@ export class Vec3Control extends React.PureComponent<ParamProps<PD.Vec3>, { isEx
|
|
|
</div>
|
|
|
</div>
|
|
|
<div className='msp-control-offset' style={{ display: this.state.isExpanded ? 'block' : 'none' }}>
|
|
|
- <ParameterControls params={this.components} values={v} onChange={this.componentChange} onEnter={this.props.onEnter} categoryFilter={this.props.categoryFilter} />
|
|
|
+ <ParameterControls params={this.components} values={v} onChange={this.componentChange} onEnter={this.props.onEnter} />
|
|
|
</div>
|
|
|
</>;
|
|
|
}
|
|
@@ -668,11 +700,11 @@ export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>
|
|
|
const params = this.props.param.params;
|
|
|
|
|
|
// Do not show if there are no params.
|
|
|
- if (filterParamKeys(params, this.props.categoryFilter).length === 0) return null;
|
|
|
+ if (Object.keys(params).length === 0) return null;
|
|
|
|
|
|
const label = this.props.param.label || camelCaseToWords(this.props.name);
|
|
|
|
|
|
- const controls = <ParameterControls params={params} onChange={this.onChangeParam} values={this.props.value} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} categoryFilter={this.props.categoryFilter} />;
|
|
|
+ const controls = <ParameterControls params={params} onChange={this.onChangeParam} values={this.props.value} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} />;
|
|
|
|
|
|
if (this.props.inMapped) {
|
|
|
return <div className='msp-control-offset'>{controls}</div>;
|
|
@@ -689,7 +721,7 @@ export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>
|
|
|
{label}
|
|
|
</button>
|
|
|
</div>
|
|
|
- {this.state.isExpanded && <div className='msp-control-offset' style={{ display: this.state.isExpanded ? 'block' : 'none' }}>
|
|
|
+ {this.state.isExpanded && <div className='msp-control-offset'>
|
|
|
{controls}
|
|
|
</div>}
|
|
|
</div>
|
|
@@ -749,11 +781,11 @@ export class MappedControl extends React.PureComponent<ParamProps<PD.Mapped<any>
|
|
|
}
|
|
|
|
|
|
if (param.type === 'group' && !param.isFlat) {
|
|
|
- if (filterParamKeys(param.params, this.props.categoryFilter).length > 0) {
|
|
|
+ if (Object.keys(param.params).length > 0) {
|
|
|
return <div className='msp-mapped-parameter-group'>
|
|
|
{Select}
|
|
|
<IconButton icon='log' onClick={this.toggleExpanded} toggleState={this.state.isExpanded} title={`${label} Properties`} />
|
|
|
- {this.state.isExpanded && <GroupControl inMapped param={param} value={value.params} name={`${label} Properties`} onChange={this.onChangeParam} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} categoryFilter={this.props.categoryFilter} />}
|
|
|
+ {this.state.isExpanded && <GroupControl inMapped param={param} value={value.params} name={`${label} Properties`} onChange={this.onChangeParam} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} />}
|
|
|
</div>
|
|
|
}
|
|
|
|
|
@@ -762,12 +794,12 @@ export class MappedControl extends React.PureComponent<ParamProps<PD.Mapped<any>
|
|
|
|
|
|
return <>
|
|
|
{Select}
|
|
|
- <Mapped param={param} value={value.params} name={`${label} Properties`} onChange={this.onChangeParam} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} categoryFilter={this.props.categoryFilter} />
|
|
|
+ <Mapped param={param} value={value.params} name={`${label} Properties`} onChange={this.onChangeParam} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} />
|
|
|
</>
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-class ObjectListEditor extends React.PureComponent<{ params: PD.Params, value: object, isUpdate?: boolean, apply: (value: any) => void, isDisabled?: boolean, categoryFilter?: ParameterControlsCategoryFilter }, { params: PD.Params, value: object, current: object }> {
|
|
|
+class ObjectListEditor extends React.PureComponent<{ params: PD.Params, value: object, isUpdate?: boolean, apply: (value: any) => void, isDisabled?: boolean }, { params: PD.Params, value: object, current: object }> {
|
|
|
state = { params: {}, value: void 0 as any, current: void 0 as any };
|
|
|
|
|
|
onChangeParam: ParamOnChange = e => {
|
|
@@ -789,7 +821,7 @@ class ObjectListEditor extends React.PureComponent<{ params: PD.Params, value: o
|
|
|
|
|
|
render() {
|
|
|
return <>
|
|
|
- <ParameterControls params={this.props.params} onChange={this.onChangeParam} values={this.state.current} onEnter={this.apply} isDisabled={this.props.isDisabled} categoryFilter={this.props.categoryFilter} />
|
|
|
+ <ParameterControls params={this.props.params} onChange={this.onChangeParam} values={this.state.current} onEnter={this.apply} isDisabled={this.props.isDisabled} />
|
|
|
<button className={`msp-btn msp-btn-block msp-form-control msp-control-top-offset`} onClick={this.apply} disabled={this.props.isDisabled}>
|
|
|
{this.props.isUpdate ? 'Update' : 'Add'}
|
|
|
</button>
|
|
@@ -797,7 +829,7 @@ class ObjectListEditor extends React.PureComponent<{ params: PD.Params, value: o
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-class ObjectListItem extends React.PureComponent<{ param: PD.ObjectList, value: object, index: number, actions: ObjectListControl['actions'], isDisabled?: boolean, categoryFilter?: ParameterControlsCategoryFilter }, { isExpanded: boolean }> {
|
|
|
+class ObjectListItem extends React.PureComponent<{ param: PD.ObjectList, value: object, index: number, actions: ObjectListControl['actions'], isDisabled?: boolean }, { isExpanded: boolean }> {
|
|
|
state = { isExpanded: false };
|
|
|
|
|
|
update = (v: object) => {
|
|
@@ -846,7 +878,7 @@ class ObjectListItem extends React.PureComponent<{ param: PD.ObjectList, value:
|
|
|
</div>
|
|
|
</div>
|
|
|
{this.state.isExpanded && <div className='msp-control-offset'>
|
|
|
- <ObjectListEditor params={this.props.param.element} apply={this.update} value={this.props.value} isUpdate isDisabled={this.props.isDisabled} categoryFilter={this.props.categoryFilter} />
|
|
|
+ <ObjectListEditor params={this.props.param.element} apply={this.update} value={this.props.value} isUpdate isDisabled={this.props.isDisabled} />
|
|
|
</div>}
|
|
|
</>;
|
|
|
}
|
|
@@ -910,9 +942,9 @@ export class ObjectListControl extends React.PureComponent<ParamProps<PD.ObjectL
|
|
|
</div>
|
|
|
|
|
|
{this.state.isExpanded && <div className='msp-control-offset'>
|
|
|
- {this.props.value.map((v, i) => <ObjectListItem key={i} param={this.props.param} value={v} index={i} actions={this.actions} categoryFilter={this.props.categoryFilter} />)}
|
|
|
+ {this.props.value.map((v, i) => <ObjectListItem key={i} param={this.props.param} value={v} index={i} actions={this.actions} />)}
|
|
|
<ControlGroup header='New Item'>
|
|
|
- <ObjectListEditor params={this.props.param.element} apply={this.add} value={this.props.param.ctor()} isDisabled={this.props.isDisabled} categoryFilter={this.props.categoryFilter} />
|
|
|
+ <ObjectListEditor params={this.props.param.element} apply={this.add} value={this.props.param.ctor()} isDisabled={this.props.isDisabled} />
|
|
|
</ControlGroup>
|
|
|
</div>}
|
|
|
</>;
|