Browse Source

Selection UI improvements

David Sehnal 5 years ago
parent
commit
ab996b5189

+ 5 - 3
src/mol-plugin-ui/controls/action-menu.tsx

@@ -7,6 +7,7 @@
 import * as React from 'react'
 import { Icon, IconName } from './icons';
 import { ParamDefinition } from '../../mol-util/param-definition';
+import { ControlGroup } from './common';
 
 export class ActionMenu extends React.PureComponent<ActionMenu.Props> {
     hide = () => this.props.onSelect(void 0)
@@ -14,13 +15,14 @@ export class ActionMenu extends React.PureComponent<ActionMenu.Props> {
     render() {
         const cmd = this.props;
 
-        return <div className='msp-action-menu-options' style={{ marginTop: '1px' }}>
-            {cmd.header && <div className='msp-control-group-header' style={{ position: 'relative' }}>
+        return <div className='msp-action-menu-options' style={{ marginTop: cmd.header ? void 0 : '1px' }}>
+            {/* {cmd.header && <div className='msp-control-group-header' style={{ position: 'relative' }}>
                 <button className='msp-btn msp-btn-block' onClick={this.hide}>
                     <Icon name='off' style={{ position: 'absolute', right: '2px', top: 0 }} />
                     <b>{cmd.header}</b>
                 </button>
-            </div>}
+            </div>} */}
+            {cmd.header && <ControlGroup header={cmd.header} initialExpanded={true} hideExpander={true} hideOffset={false} onHeaderClick={this.hide} topRightIcon='off'></ControlGroup>}
             <Section items={cmd.items} onSelect={cmd.onSelect} current={cmd.current} multiselect={this.props.multiselect} />
         </div>
     }

+ 4 - 4
src/mol-plugin-ui/controls/common.tsx

@@ -35,13 +35,12 @@ export class ControlGroup extends React.Component<{
                 <button className='msp-btn msp-btn-block' onClick={this.headerClicked}>
                     {!this.props.hideExpander && <Icon name={this.state.isExpanded ? 'collapse' : 'expand'} />}
                     {this.props.topRightIcon && <Icon name={this.props.topRightIcon} style={{ position: 'absolute', right: '2px', top: 0 }} />}
-                    {this.props.header}
+                    <b>{this.props.header}</b>
                 </button>
             </div>
             {this.state.isExpanded && <div className={this.props.hideOffset ? '' : 'msp-control-offset'} style={{ display: this.state.isExpanded ? 'block' : 'none' }}>
                 {this.props.children}
-            </div>
-            }
+            </div>}
         </div>
     }
 }
@@ -326,8 +325,9 @@ export class ToggleButton extends React.PureComponent<ToggleButtonProps> {
     render() {
         const props = this.props;
         const label = props.label;
+        const className = props.isSelected ? `${props.className || ''} msp-control-current` : props.className;
         return <button onClick={this.onClick} title={this.props.title}
-            disabled={props.disabled} style={props.style} className={props.className}>
+            disabled={props.disabled} style={props.style} className={className}>
             <Icon name={this.props.icon} />
             <Shape name={this.props.shape} />
             {label && this.props.isSelected ? <b>{label}</b> : label}

+ 12 - 0
src/mol-plugin-ui/skin/base/components/controls.scss

@@ -50,6 +50,10 @@
         @extend .msp-btn-block;
     }
 
+    .msp-control-current {
+        background: $default-background;
+    }
+
     > div:nth-child(2) {
         position: absolute;
         left: $control-label-width + $control-spacing;
@@ -249,6 +253,10 @@
         background: $default-background !important;
         color: color-lower-contrast($font-color, 15%) !important;
     }
+    .msp-icon {
+        height: 22px !important;
+        line-height: 22px !important;
+    }
     > span {
         padding-left: $control-spacing / 2;
         line-height: 2 * $row-height / 3;
@@ -258,6 +266,10 @@
     }
 }
 
+.msp-control-current {
+    background: $default-background;
+}
+
 .msp-control-group-footer {
     background: color-increase-contrast($default-background, 5%);
     height: $control-spacing / 2;

+ 19 - 9
src/mol-plugin-ui/structure/selection.tsx

@@ -17,7 +17,7 @@ import { ParamDefinition } from '../../mol-util/param-definition';
 import { stripTags } from '../../mol-util/string';
 import { CollapsableControls, CollapsableState, PurePluginUIComponent } from '../base';
 import { ActionMenu } from '../controls/action-menu';
-import { ExpandGroup, ToggleButton } from '../controls/common';
+import { ExpandGroup, ToggleButton, ControlGroup } from '../controls/common';
 import { Icon } from '../controls/icons';
 import { ParameterControls } from '../controls/parameters';
 
@@ -42,6 +42,13 @@ interface StructureSelectionControlsState extends CollapsableState {
     action?: StructureSelectionModifier | 'color'
 }
 
+const ActionHeader = new Map<StructureSelectionModifier, string>([
+    ['add', 'Add/Union'],
+    ['remove', 'Remove/Subtract'],
+    ['intersect', 'Intersect'],
+    ['set', 'Set']
+] as const);
+
 export class StructureSelectionControls<P, S extends StructureSelectionControlsState> extends CollapsableControls<P, S> {
     componentDidMount() {
         this.subscribe(this.plugin.managers.structure.selection.events.changed, () => {
@@ -135,17 +142,20 @@ export class StructureSelectionControls<P, S extends StructureSelectionControlsS
     toggleColor = this.showAction('color')
 
     get controls() {
-        return <div>
+        return <>
             <div className='msp-control-row msp-select-row'>
-                <ToggleButton shape='union' title='Add/Union' toggle={this.toggleAdd} isSelected={this.state.action === 'add'} disabled={this.isDisabled} />
-                <ToggleButton shape='subtract' title='Remove/Subtract' toggle={this.toggleRemove} isSelected={this.state.action === 'remove'} disabled={this.isDisabled} />
-                <ToggleButton shape='intersect' title='Intersect' toggle={this.toggleIntersect} isSelected={this.state.action === 'intersect'} disabled={this.isDisabled} />
-                <ToggleButton shape='set' title='Set' toggle={this.toggleSet} isSelected={this.state.action === 'set'} disabled={this.isDisabled} />
+                <ToggleButton shape='union' title={ActionHeader.get('add')} toggle={this.toggleAdd} isSelected={this.state.action === 'add'} disabled={this.isDisabled} />
+                <ToggleButton shape='subtract' title={ActionHeader.get('remove')} toggle={this.toggleRemove} isSelected={this.state.action === 'remove'} disabled={this.isDisabled} />
+                <ToggleButton shape='intersect' title={ActionHeader.get('intersect')} toggle={this.toggleIntersect} isSelected={this.state.action === 'intersect'} disabled={this.isDisabled} />
+                <ToggleButton shape='set' title={ActionHeader.get('set')} toggle={this.toggleSet} isSelected={this.state.action === 'set'} disabled={this.isDisabled} />
                 <ToggleButton icon='brush' title='Color' toggle={this.toggleColor} isSelected={this.state.action === 'color'} disabled={this.isDisabled} />
             </div>
-            {(this.state.action && this.state.action !== 'color') && <ActionMenu items={this.queries} onSelect={this.selectQuery} />}
-            {this.state.action === 'color' && <div className='msp-control-offset'><ApplyColorControls /></div>}
-        </div>
+            {(this.state.action && this.state.action !== 'color') && <ActionMenu header={ActionHeader.get(this.state.action as StructureSelectionModifier)} items={this.queries} onSelect={this.selectQuery} />}
+            {this.state.action === 'color' && 
+                <ControlGroup header='Color' initialExpanded={true} hideExpander={true} hideOffset={false} onHeaderClick={this.toggleColor} topRightIcon='off'>
+                    <ApplyColorControls />
+                </ControlGroup>}
+        </>
     }
 
     defaultState() {