diff --git a/src/mol-plugin-ui/controls/action-menu.tsx b/src/mol-plugin-ui/controls/action-menu.tsx index bc2a324b69f940a37dcde725f731841824aa3ac4..8dd5dacbb6554c4e7916dcd0882b19c819a8cac8 100644 --- a/src/mol-plugin-ui/controls/action-menu.tsx +++ b/src/mol-plugin-ui/controls/action-menu.tsx @@ -41,7 +41,7 @@ export namespace ActionMenu { export type ToggleProps = { - style?: React.HTMLAttributes<HTMLButtonElement>, + style?: React.CSSProperties, className?: string, menu: ActionMenu, disabled?: boolean, @@ -180,11 +180,14 @@ export namespace ActionMenu { if (typeof items === 'string') return null; if (isItem(items)) return <Action menu={menu} item={items} onSelect={onSelect} current={current} /> + + const hasCurrent = header && current && !!findCurrent(items, current.value) + return <div> {header && <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'}`} /> - {header} + {hasCurrent ? <b>{header}</b> : header} </button> </div>} <div className='msp-control-offset'> diff --git a/src/mol-plugin-ui/controls/parameters.tsx b/src/mol-plugin-ui/controls/parameters.tsx index 4b697ce67a2b3cfd8f487df6f9cacb30ae53bcc3..2aca7b8a758963970b050a3ccb60fc008389653c 100644 --- a/src/mol-plugin-ui/controls/parameters.tsx +++ b/src/mol-plugin-ui/controls/parameters.tsx @@ -341,8 +341,7 @@ export class SelectControl extends SimpleParam<PD.Select<string | number>> { renderControl() { const items = this.items(this.props.param); const current = ActionMenu.findCurrent(items, this.props.value); - - return <ActionMenu.Toggle menu={this.menu} disabled={this.props.isDisabled} + return <ActionMenu.Toggle menu={this.menu} disabled={this.props.isDisabled} style={{ textAlign: 'left', overflow: 'hidden', textOverflow: 'ellipsis' }} onSelect={this.onSelect} items={items as ActionMenu.Spec} label={current?.name || `[Invalid] ${this.props.value}`} current={current} />; } @@ -614,7 +613,7 @@ export class MultiSelectControl extends React.PureComponent<ParamProps<PD.MultiS } } -export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>, { isExpanded: boolean }> { +export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>> & { inMapped?: boolean }, { isExpanded: boolean }> { state = { isExpanded: !!this.props.param.isExpanded } change(value: any) { @@ -637,6 +636,10 @@ export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>, 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>; + } + if (this.props.param.isFlat) { return controls; } @@ -655,7 +658,9 @@ export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>, } } -export class MappedControl extends React.PureComponent<ParamProps<PD.Mapped<any>>> { +export class MappedControl extends React.PureComponent<ParamProps<PD.Mapped<any>>, { isExpanded: boolean }> { + state = { isExpanded: false } + private valuesCache: { [name: string]: PD.Values<any> } = {} private setValues(name: string, values: PD.Values<any>) { this.valuesCache[name] = values @@ -681,6 +686,8 @@ export class MappedControl extends React.PureComponent<ParamProps<PD.Mapped<any> this.change({ name: this.props.value.name, params: e.value }); } + toggleExpanded = () => this.setState({ isExpanded: !this.state.isExpanded }); + render() { const value: PD.Mapped<any>['defaultValue'] = this.props.value; const param = this.props.param.map(value.name); @@ -703,6 +710,14 @@ export class MappedControl extends React.PureComponent<ParamProps<PD.Mapped<any> return Select; } + if (param.type === 'group' && !param.isFlat && 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} />} + </div> + } + return <> {Select} <Mapped param={param} value={value.params} name={`${label} Properties`} onChange={this.onChangeParam} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} /> diff --git a/src/mol-plugin-ui/skin/base/components/controls.scss b/src/mol-plugin-ui/skin/base/components/controls.scss index 8a0f44a4cd5bf72828f1d4e5ce42f92b582f6c6f..725039cf8f025c6aae4781b2134ec1b1a5a9686c 100644 --- a/src/mol-plugin-ui/skin/base/components/controls.scss +++ b/src/mol-plugin-ui/skin/base/components/controls.scss @@ -31,6 +31,7 @@ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + position: relative; @include non-selectable; } diff --git a/src/mol-plugin-ui/skin/base/components/misc.scss b/src/mol-plugin-ui/skin/base/components/misc.scss index 5208ebcec37b932de09e6fc9d5dc5103b51b38cd..a37bb0d4367c29a9d3a6fe8a3ed2fc31b6ff0709 100644 --- a/src/mol-plugin-ui/skin/base/components/misc.scss +++ b/src/mol-plugin-ui/skin/base/components/misc.scss @@ -166,4 +166,21 @@ .msp-scrollable-container { left: $row-height + 1px; } +} + +.msp-mapped-parameter-group { + position: relative; + + > .msp-control-row:first-child { + > div:nth-child(2) { + right: 33px; + } + } + + > .msp-btn-icon { + position: absolute; + right: 0; + width: 32px; + top: 0; + } } \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index f33a385636c5aff1423777bb51873a7d60824ddb..9e9aceeaccfddf66f9691890c05f5a854fabdfb7 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -46,7 +46,8 @@ const sharedConfig = { 'node_modules', path.resolve(__dirname, 'lib/') ], - } + }, + devtool: '' }