Browse Source

Add intersect to Component modify options

David Sehnal 5 years ago
parent
commit
c12d577ce6

+ 1 - 1
src/mol-plugin-state/builder/structure.ts

@@ -130,7 +130,7 @@ export class StructureBuilder {
         return props.selector;
     }
 
-    isComponent(cell: StateObjectCell) {
+    isComponentTransform(cell: StateObjectCell) {
         return cell.transform.transformer === StateTransforms.Model.StructureComponent;
     }
 

+ 16 - 8
src/mol-plugin-state/manager/structure/component.ts

@@ -7,7 +7,7 @@
 import { VisualQualityOptions } from '../../../mol-geo/geometry/base';
 import { InteractionsProvider } from '../../../mol-model-props/computed/interactions';
 import { Structure, StructureElement } from '../../../mol-model/structure';
-import { structureAreIntersecting, structureSubtract, structureUnion } from '../../../mol-model/structure/query/utils/structure-set';
+import { structureAreIntersecting, structureSubtract, structureUnion, structureIntersect } from '../../../mol-model/structure/query/utils/structure-set';
 import { setSubtreeVisibility } from '../../../mol-plugin/behavior/static/state';
 import { PluginContext } from '../../../mol-plugin/context';
 import { StateBuilder, StateTransformer } from '../../../mol-state';
@@ -130,16 +130,18 @@ class StructureComponentManager extends PluginComponent<StructureComponentManage
     }
 
     canBeModified(ref: HierarchyRef) {
-        return this.plugin.builders.structure.isComponent(ref.cell);
+        return this.plugin.builders.structure.isComponentTransform(ref.cell);
     }
 
-    modifyByCurrentSelection(components: ReadonlyArray<StructureComponentRef>, action: 'union' | 'subtract') {
-        return this.plugin.runTask(Task.create('Subtract', async taskCtx => {
+    modifyByCurrentSelection(components: ReadonlyArray<StructureComponentRef>, action: StructureComponentManager.ModifyAction) {
+        return this.plugin.runTask(Task.create('Modify Component', async taskCtx => {
             const b = this.dataState.build();        
             for (const c of components) {
+                if (!this.canBeModified(c)) continue;
+
                 const selection = this.plugin.managers.structure.selection.getStructure(c.structure.cell.obj!.data);
                 if (!selection || selection.elementCount === 0) continue;                
-                this.updateComponent(b, c, selection, action);
+                this.modifyComponent(b, c, selection, action);
             }
             await this.dataState.updateTree(b).runInContext(taskCtx);
         }));
@@ -245,13 +247,17 @@ class StructureComponentManager extends PluginComponent<StructureComponentManage
         });
     }
 
-    private updateComponent(builder: StateBuilder.Root, component: StructureComponentRef, by: Structure, action: 'union' | 'subtract') {
+    private modifyComponent(builder: StateBuilder.Root, component: StructureComponentRef, by: Structure, action: StructureComponentManager.ModifyAction) {
         const structure = component.cell.obj?.data;
         if (!structure) return;
-        if (action === 'subtract' && !structureAreIntersecting(structure, by)) return;
+        if ((action === 'subtract' || action === 'intersect') && !structureAreIntersecting(structure, by)) return;
 
         const parent = component.structure.cell.obj?.data!;
-        const modified = action === 'union' ? structureUnion(parent, [structure, by]) : structureSubtract(structure, by);
+        const modified = action === 'union' 
+            ? structureUnion(parent, [structure, by]) 
+            : action === 'intersect'
+            ? structureIntersect(structure, by)
+            : structureSubtract(structure, by);
 
         if (modified.elementCount === 0) {
             builder.delete(component.cell.transform.ref);
@@ -335,4 +341,6 @@ namespace StructureComponentManager {
         ] as [string, string][];
         return PD.Select(types[0][0], types, { label });
     }
+
+    export type ModifyAction = 'union' | 'subtract' | 'intersect'
 }

+ 4 - 6
src/mol-plugin-ui/controls/action-menu.tsx

@@ -208,12 +208,10 @@ const Action: React.FC<{
     multiselect: boolean | undefined, 
     current: ActionMenu.Item | undefined }> = ({ item, onSelect, current, multiselect }) => {
     const isCurrent = current === item;
-    return <div className='msp-control-row'>
-        <button onClick={() => onSelect(multiselect ? [item] : item as any)} disabled={item.disabled}>
-            {item.icon && <Icon name={item.icon} style={{ fontSize: '80%', marginRight: '6px' }} />}
-            {isCurrent || item.selected ? <b>{item.label}</b> : item.label}
-        </button>
-    </div>;
+    return  <button className='msp-btn msp-btn-block msp-form-control msp-action-menu-button' onClick={() => onSelect(multiselect ? [item] : item as any)} disabled={item.disabled}>
+        {item.icon && <Icon name={item.icon} />}
+        {isCurrent || item.selected ? <b>{item.label}</b> : item.label}
+    </button>;
 }
 
 function isItem(x: any): x is ActionMenu.Item {

+ 9 - 0
src/mol-plugin-ui/skin/base/components/temp.scss

@@ -326,4 +326,13 @@
     button {
         text-align: left;
     }
+
+    
+    .msp-action-menu-button {
+        margin-top: 1px;   
+        .msp-icon {
+            font-size: 80%;
+            margin-right: 6px;
+        }
+    }
 }

+ 12 - 6
src/mol-plugin-ui/structure/components.tsx

@@ -234,19 +234,25 @@ class StructureComponentGroup extends PurePluginUIComponent<{ group: StructureCo
 
     get actions(): ActionMenu.Items {
         const mng = this.plugin.managers.structure.component;
-        const ret = [
+        const ret: ActionMenu.Items = [
             [
                 'Add Representation',
                 ...StructureComponentManager.getRepresentationTypes(this.plugin, this.props.group[0])
                     .map(t => ActionMenu.Item(t[1], () => mng.addRepresentation(this.props.group, t[0])))
-            ],
-            ActionMenu.Item('Select This', 'flash', () => mng.selectThis(this.props.group))
+            ]
         ];
 
-        if (this.plugin.managers.structure.component.canBeModified(this.props.group[0])) {
-            ret.push(ActionMenu.Item('Include Current Selection', 'plus', () => mng.modifyByCurrentSelection(this.props.group, 'union')));
-            ret.push(ActionMenu.Item('Subtract Current Selection', 'minus', () => mng.modifyByCurrentSelection(this.props.group, 'subtract')));
+        if (mng.canBeModified(this.props.group[0])) {
+            ret.push([
+                'Modify by Selection',
+                ActionMenu.Item('Include', 'plus', () => mng.modifyByCurrentSelection(this.props.group, 'union')),
+                ActionMenu.Item('Subtract', 'minus', () => mng.modifyByCurrentSelection(this.props.group, 'subtract')),
+                ActionMenu.Item('Intersect', 'shuffle', () => mng.modifyByCurrentSelection(this.props.group, 'intersect'))
+            ]);
         }
+
+        ret.push(ActionMenu.Item('Select This', 'flash', () => mng.selectThis(this.props.group)));
+
         return ret;
     }