From 478033d4055c32946e39e23fc1faab3b8e1dd7de Mon Sep 17 00:00:00 2001
From: David Sehnal <david.sehnal@gmail.com>
Date: Tue, 9 Jun 2020 19:27:56 +0200
Subject: [PATCH] mol-plugin: added excludeTargetFromSurroundings to Focus
 behavior

---
 package-lock.json                             | Bin 603054 -> 603050 bytes
 .../structure-focus-representation.ts         |  33 +++++++++++++++---
 2 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 0c5435164cb9db0db058b6d24f59968aa026e390..149b28965084d40054210f8b62733c5b4979ef5e 100644
GIT binary patch
delta 93
zcmZ4YTxHdBm4+6^ElgbY)6TJqO;7M(l9)cblXdHKhh`Rub~XnlAZ7+)mhEf~tV}K-
jMcd_DSbbUH%G-g;x6kfm<NX2>YTsYWzI}f!$NQ}S?0g|`

delta 114
zcmZ4WTxH#Jm4+6^ElgbY(+_N6m!AIN5xdCr4;z`!wzE1g0WmWWvutN|U}bWdzJQle
zb-SM;TN2~;-d5JT%&0oHPIs_n<=wtPjg5`5J)xU*dqOvx>!;}l1eqn;_tdg)-&4!+
GZYu!N%`77T

diff --git a/src/mol-plugin/behavior/dynamic/selection/structure-focus-representation.ts b/src/mol-plugin/behavior/dynamic/selection/structure-focus-representation.ts
index 74ad78176..42f8ea7d1 100644
--- a/src/mol-plugin/behavior/dynamic/selection/structure-focus-representation.ts
+++ b/src/mol-plugin/behavior/dynamic/selection/structure-focus-representation.ts
@@ -39,7 +39,8 @@ const StructureFocusRepresentationParams = (plugin: PluginContext) => {
                 size: SizeTheme.BuiltIn.uniform
             })
         }),
-        components: PD.MultiSelect(FocusComponents, PD.arrayToOptions(FocusComponents))
+        components: PD.MultiSelect(FocusComponents, PD.arrayToOptions(FocusComponents)),
+        excludeTargetFromSurroundings: PD.Boolean(false, { label: 'Exclude Target', description: 'Exclude the focus "target" from the surroudings component.' })
     };
 };
 
@@ -106,6 +107,7 @@ class StructureFocusRepresentationBehavior extends PluginBehavior.WithSubscriber
 
     private clear(root: StateTransform.Ref) {
         const state = this.plugin.state.data;
+        this.currentSource = void 0;
 
         const foci = state.select(StateSelection.Generators.byRef(root).subtree().withTag(StructureFocusRepresentationTags.TargetSel));
         const surrs = state.select(StateSelection.Generators.byRef(root).subtree().withTag(StructureFocusRepresentationTags.SurrSel));
@@ -125,21 +127,31 @@ class StructureFocusRepresentationBehavior extends PluginBehavior.WithSubscriber
         return PluginCommands.State.Update(this.plugin, { state, tree: update, options: { doNotLogTiming: true, doNotUpdateCurrent: true } });
     }
 
+    private currentSource: StructureElement.Loci | undefined = void 0;
     private async focus(sourceLoci: StructureElement.Loci) {
         const parent = this.plugin.helpers.substructureParent.get(sourceLoci.structure);
         if (!parent || !parent.obj) return;
 
+        this.currentSource = sourceLoci;
         const loci = StructureElement.Loci.remap(sourceLoci, parent.obj!.data);
 
         const residueLoci = StructureElement.Loci.extendToWholeResidues(loci);
         const residueBundle = StructureElement.Bundle.fromLoci(residueLoci);
 
-        const surroundings = MS.struct.modifier.includeSurroundings({
-            0: StructureElement.Bundle.toExpression(residueBundle),
+        const target = StructureElement.Bundle.toExpression(residueBundle);
+        let surroundings = MS.struct.modifier.includeSurroundings({
+            0: target,
             radius: this.params.expandRadius,
             'as-whole-residues': true
         });
 
+        if (this.params.excludeTargetFromSurroundings) {
+            surroundings =  MS.struct.modifier.exceptBy({
+                0: surroundings,
+                by: target
+            });
+        }
+
         const { state, builder, refs } = this.ensureShape(parent);
 
         builder.to(refs[StructureFocusRepresentationTags.TargetSel]!).update(StateTransforms.Model.StructureSelectionFromBundle, old => ({ ...old, bundle: residueBundle }));
@@ -159,6 +171,13 @@ class StructureFocusRepresentationBehavior extends PluginBehavior.WithSubscriber
         const old = this.params;
         this.params = params;
 
+        if (old.excludeTargetFromSurroundings !== params.excludeTargetFromSurroundings) {
+            if (this.currentSource) {
+                this.focus(this.currentSource);
+            }
+            return true;
+        }
+
         const state = this.plugin.state.data;
         const builder = state.build();
 
@@ -187,8 +206,12 @@ class StructureFocusRepresentationBehavior extends PluginBehavior.WithSubscriber
 
         await PluginCommands.State.Update(this.plugin, { state, tree: builder, options: { doNotLogTiming: true, doNotUpdateCurrent: true } });
 
-        // TODO: update properly
-        if (params.expandRadius !== old.expandRadius) await this.clear(StateTransform.RootRef);
+        if (params.expandRadius !== old.expandRadius) {
+            if (this.currentSource) {
+                this.focus(this.currentSource);
+            }
+            return true;
+        }
 
         return true;
     }
-- 
GitLab