From bdb132d92eafc43f04bf6f002b8082d233ccafc3 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 23 Aug 2019 14:52:29 -0400
Subject: small fixes to collection buttons.

---
 .../views/collections/CollectionViewChromes.tsx    | 90 ++++++++++++----------
 1 file changed, 50 insertions(+), 40 deletions(-)

(limited to 'src/client/views/collections/CollectionViewChromes.tsx')

diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 4c536fabe..1156d8fa7 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -41,16 +41,31 @@ let stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();
 export class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps> {
     //(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\)
 
+    private _buttonizableCommands = [{
+        // title: "set content", script: "getProto(this.target).data = aliasDocs(this.source.map(async p => await p));", params: ["target", "source"],  // bcz: doesn't look like we can do async stuff in scripting...
+        title: "set content", script: "getProto(this.target).data = aliasDocs(this.source);", params: ["target", "source"],
+        immediate: (draggedDocs: Doc[]) => Doc.GetProto(this.props.CollectionView.props.Document).data = new List<Doc>(draggedDocs.map((d: any) => Doc.MakeAlias(d)))
+    },
+    {
+        title: "set template", script: "this.target.childLayout = this.source ? this.source[0] : undefined", params: ["target", "source"],
+        immediate: (draggedDocs: Doc[]) => this.props.CollectionView.props.Document.childLayout = draggedDocs.length ? draggedDocs[0] : undefined
+    },
+    {
+        title: "restore view", script: "this.target.panX = this.restoredPanX; this.target.panY = this.restoredPanY; this.target.scale = this.restoredScale;", params: ["target"],
+        immediate: (draggedDocs: Doc[]) => { this.props.CollectionView.props.Document.panX = 0; this.props.CollectionView.props.Document.panY = 0; this.props.CollectionView.props.Document.scale = 1 },
+        initialize: (button: Doc) => { button.restoredPanX = this.props.CollectionView.props.Document.panX; button.restoredPanY = this.props.CollectionView.props.Document.panY; button.restoredScale = this.props.CollectionView.props.Document.scale; }
+    }];
+    private _picker: any;
+    private _commandRef = React.createRef<HTMLInputElement>();
+    private _autosuggestRef = React.createRef<Autosuggest>();
+    @observable private _currentKey: string = "";
     @observable private _viewSpecsOpen: boolean = false;
     @observable private _dateWithinValue: string = "";
     @observable private _dateValue: Date | string = "";
     @observable private _keyRestrictions: [JSX.Element, string][] = [];
     @observable private suggestions: string[] = [];
-    _commandRef = React.createRef<HTMLInputElement>();
     @computed private get filterValue() { return Cast(this.props.CollectionView.props.Document.viewSpecScript, ScriptField); }
 
-    private _picker: any;
-
     getFilters = (script: string) => {
         let re: any = /(!)?\(\(\(doc\.(\w+)\s+&&\s+\(doc\.\w+\s+as\s+\w+\)\.includes\(\"(\w+)\"\)/g;
         let arr: any[] = re.exec(script);
@@ -215,25 +230,10 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
 
     subChrome = () => {
         switch (this.props.type) {
-            case CollectionViewType.Stacking: return (
-                <CollectionStackingViewChrome
-                    key="collchrome"
-                    CollectionView={this.props.CollectionView}
-                    type={this.props.type} />);
-            case CollectionViewType.Schema: return (
-                <CollectionSchemaViewChrome
-                    key="collchrome"
-                    CollectionView={this.props.CollectionView}
-                    type={this.props.type}
-                />);
-            case CollectionViewType.Tree: return (
-                <CollectionTreeViewChrome
-                    key="collchrome"
-                    CollectionView={this.props.CollectionView}
-                    type={this.props.type}
-                />);
-            default:
-                return null;
+            case CollectionViewType.Stacking: return (<CollectionStackingViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
+            case CollectionViewType.Schema: return (<CollectionSchemaViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
+            case CollectionViewType.Tree: return (<CollectionTreeViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
+            default: return null;
         }
     }
 
@@ -286,21 +286,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
         }
     }
 
-
-    commands = [{
-        // title: "set content", script: "getProto(this.target).data = aliasDocs(this.source.map(async p => await p));", params: ["target", "source"],  // bcz: doesn't look like we can do async stuff in scripting...
-        title: "set content", script: "getProto(this.target).data = aliasDocs(this.source);", params: ["target", "source"],
-        immediate: (draggedDocs: Doc[]) => Doc.GetProto(this.props.CollectionView.props.Document).data = new List<Doc>(draggedDocs.map((d: any) => Doc.MakeAlias(d)))
-    },
-    {
-        title: "set template", script: "this.target.childLayout = this.source ? this.source[0] : undefined", params: ["target", "source"],
-        immediate: (draggedDocs: Doc[]) => this.props.CollectionView.props.Document.childLayout = draggedDocs.length ? draggedDocs[0] : undefined
-    }];
     @undoBatch
     @action
     protected drop(e: Event, de: DragManager.DropEvent): boolean {
         if (de.data instanceof DragManager.DocumentDragData && de.data.draggedDocuments.length) {
-            this.commands.filter(c => c.title === this._currentKey).map(c => c.immediate(de.data.draggedDocuments));
+            this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate(de.data.draggedDocuments));
             e.stopPropagation();
         }
         return true;
@@ -319,8 +309,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
             }
         }
     }
-    @observable private _currentKey: string = "";
-    private autosuggestRef = React.createRef<Autosuggest>();
 
     renderSuggestion = (suggestion: string) => {
         return <p>{suggestion}</p>;
@@ -340,19 +328,41 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
         this.suggestions = [];
     }
     getKeySuggestions = async (value: string): Promise<string[]> => {
-        return this.commands.filter(c => c.title.indexOf(value) !== -1).map(c => c.title);
+        return this._buttonizableCommands.filter(c => c.title.indexOf(value) !== -1).map(c => c.title);
     }
 
     autoSuggestDown = (e: React.PointerEvent) => {
         e.stopPropagation();
     }
 
+    private _startDragPosition: { x: number, y: number } = { x: 0, y: 0 };
+    private _sensitivity: number = 16;
+
     dragCommandDown = (e: React.PointerEvent) => {
-        this.commands.filter(c => c.title === this._currentKey).map(c =>
-            DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title,
-                { target: this.props.CollectionView.props.Document }, c.params, e.clientX, e.clientY));
+
+        this._startDragPosition = { x: e.clientX, y: e.clientY };
+        document.addEventListener("pointermove", this.dragPointerMove);
+        document.addEventListener("pointerup", this.dragPointerUp);
+        e.stopPropagation();
+        e.preventDefault();
+    }
+
+    dragPointerMove = (e: PointerEvent) => {
         e.stopPropagation();
         e.preventDefault();
+        let [dx, dy] = [e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y];
+        if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
+            this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c =>
+                DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title,
+                    { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY));
+            document.removeEventListener("pointermove", this.dragPointerMove);
+            document.removeEventListener("pointerup", this.dragPointerUp);
+        }
+    }
+    dragPointerUp = (e: PointerEvent) => {
+        document.removeEventListener("pointermove", this.dragPointerMove);
+        document.removeEventListener("pointerup", this.dragPointerUp);
+
     }
 
     render() {
@@ -439,7 +449,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
                                         renderSuggestion={this.renderSuggestion}
                                         onSuggestionsFetchRequested={this.onSuggestionFetch}
                                         onSuggestionsClearRequested={this.onSuggestionClear}
-                                        ref={this.autosuggestRef} />
+                                        ref={this._autosuggestRef} />
                                 </div>
                             </div>
                         </div>
-- 
cgit v1.2.3-70-g09d2

