From 793cc99ab134bc5aa4667c95def851ce08d35146 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 11 Feb 2019 21:17:24 -0500
Subject: added aspect resizing.  fixed pinch zoom for macs

---
 src/client/views/DocumentDecorations.tsx | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 8a94bff36..7efaa5533 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -111,8 +111,10 @@ export class DocumentDecorations extends React.Component {
                 let actualdH = Math.max(element.height + (dH * scale), 20);
                 element.x += dX * (actualdW - element.width);
                 element.y += dY * (actualdH - element.height);
-                element.width = actualdW;
-                element.height = actualdH;
+                if (Math.abs(dW) > Math.abs(dH))
+                    element.width = actualdW;
+                else
+                    element.height = actualdH;
             }
         })
     }
-- 
cgit v1.2.3-70-g09d2


From b199fa38a0697c850a48651639bbfc6b5f713055 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Tue, 12 Feb 2019 16:12:13 -0500
Subject: Started adding transforms

---
 src/client/util/Transform.ts                       | 19 ++++++
 src/client/views/DocumentDecorations.tsx           |  9 +--
 .../views/collections/CollectionFreeFormView.tsx   | 16 +++--
 .../views/collections/CollectionViewBase.tsx       |  4 +-
 src/client/views/nodes/DocumentView.tsx            | 71 +---------------------
 5 files changed, 42 insertions(+), 77 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/util/Transform.ts b/src/client/util/Transform.ts
index 7861ed308..3edc8d569 100644
--- a/src/client/util/Transform.ts
+++ b/src/client/util/Transform.ts
@@ -7,6 +7,10 @@ export class Transform {
         return new Transform(0, 0, 1);
     }
 
+    get TranslateX(): number { return this._translateX; }
+    get TranslateY(): number { return this._translateY; }
+    get Scale(): number { return this._scale; }
+
     constructor(x: number, y: number, scale: number) {
         this._translateX = x;
         this._translateY = y;
@@ -42,6 +46,17 @@ export class Transform {
         return this.copy().scale(scale);
     }
 
+    scaleAbout = (scale: number, x: number, y: number): Transform => {
+        this._translateX += x * this._scale - x * this._scale * scale;
+        this._translateY += y * this._scale - y * this._scale * scale;
+        this._scale *= scale;
+        return this;
+    }
+
+    scaledAbout = (scale: number, x: number, y: number): Transform => {
+        return this.copy().scaleAbout(scale, x, y);
+    }
+
     preScale = (scale: number): Transform => {
         this._scale *= scale;
         this._translateX *= scale;
@@ -83,6 +98,10 @@ export class Transform {
         return [x, y];
     }
 
+    transformDirection = (x: number, y: number): [number, number] => {
+        return [x * this._scale, y * this._scale];
+    }
+
     inverse = () => {
         return new Transform(-this._translateX / this._scale, -this._translateY / this._scale, 1 / this._scale)
     }
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 7efaa5533..85b44307f 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -25,11 +25,12 @@ export class DocumentDecorations extends React.Component {
                 !(element.props.ContainingCollectionView instanceof CollectionFreeFormView)) {
                 return bounds;
             }
-            var spt = element.TransformToScreenPoint(0, 0);
-            var bpt = element.TransformToScreenPoint(element.width, element.height);
+            let transform = element.getTransform().inverse();
+            var [sptX, sptY] = transform.transformPoint(0, 0);
+            var [bptX, bptY] = transform.transformDirection(element.width, element.height);
             return {
-                x: Math.min(spt.ScreenX, bounds.x), y: Math.min(spt.ScreenY, bounds.y),
-                r: Math.max(bpt.ScreenX, bounds.r), b: Math.max(bpt.ScreenY, bounds.b)
+                x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
+                r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
             }
         }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE });
     }
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 977a03f58..5b520676f 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -123,14 +123,17 @@ export class CollectionFreeFormView extends CollectionViewBase {
         let coefficient = 1000;
         // if (modes[e.deltaMode] == 'pixels') coefficient = 50;
         // else if (modes[e.deltaMode] == 'lines') coefficient = 1000; // This should correspond to line-height??
+        let transform = this.getTransform();
+        let localTransform = this.getLocalTransform();
 
-        let { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY);
+        let deltaScale = (1 - (e.deltaY / coefficient)) * transform.Scale;
+        let newDeltaScale = this.isAnnotationOverlay ? Math.max(1, deltaScale) : deltaScale;
+        let [x, y] = transform.transformPoint(e.clientX, e.clientY);
 
-        var deltaScale = (1 - (e.deltaY / coefficient)) * Ss;
-        var newDeltaScale = this.isAnnotationOverlay ? Math.max(1, deltaScale) : deltaScale;
+        localTransform.scaleAbout(newDeltaScale, x, y);
 
         this.props.DocumentForCollection.SetNumber(KeyStore.Scale, newDeltaScale);
-        this.SetPan(ContainerX - (LocalX * newDeltaScale + Xx), ContainerY - (LocalY * newDeltaScale + Yy));
+        this.SetPan(localTransform.TranslateX, localTransform.TranslateY);
     }
 
     @action
@@ -213,6 +216,11 @@ export class CollectionFreeFormView extends CollectionViewBase {
         return this.props.GetTransform().scaled(this.scale).translate(x, y);
     }
 
+    getLocalTransform = (): Transform => {
+        const [x, y] = this.translate;
+        return new Transform(x, y, this.scale);
+    }
+
     render() {
         const Document: Document = this.props.DocumentForCollection;
         const value: Document[] = Document.GetList<Document>(this.props.CollectionFieldKey, []);
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index eea7908ce..2dc6abf11 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -27,7 +27,9 @@ export const COLLECTION_BORDER_WIDTH = 2;
 export class CollectionViewBase extends React.Component<CollectionViewProps> {
 
     public static LayoutString(collectionType: string) {
-        return `<${collectionType} DocumentForCollection={Document} CollectionFieldKey={DataKey} ContainingDocumentView={DocumentView}/>`;
+        return `<${collectionType} DocumentForCollection={Document} CollectionFieldKey={DataKey}
+                    GetTransform={GetTransform}
+                    ContainingDocumentView={DocumentView}/>`;
     }
     @computed
     public get active(): boolean {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 691ac6311..7503e9fc7 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -69,80 +69,15 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         return 1;
     }
 
-    //
-    // Converts a coordinate in the screen space of the app into a local document coordinate.
-    //
-    public TransformToLocalPoint(screenX: number, screenY: number) {
-        // if this collection view is nested within another collection view, then 
-        // first transform the screen point into the parent collection's coordinate space.
-        let { LocalX: parentX, LocalY: parentY } = this.props.ContainingCollectionView != undefined &&
-            this.props.ContainingCollectionView.props.ContainingDocumentView != undefined ?
-            this.props.ContainingCollectionView.props.ContainingDocumentView.TransformToLocalPoint(screenX, screenY) :
-            { LocalX: screenX, LocalY: screenY };
-        let ContainerX: number = parentX - COLLECTION_BORDER_WIDTH;
-        let ContainerY: number = parentY - COLLECTION_BORDER_WIDTH;
-
-        var Xx = this.props.Document.GetData(KeyStore.X, NumberField, Number(0));
-        var Yy = this.props.Document.GetData(KeyStore.Y, NumberField, Number(0));
-        // CollectionDockingViews change the location of their children frames without using a Dash transformation.
-        // They also ignore any transformation that may have been applied to their content document.
-        // NOTE: this currently assumes CollectionDockingViews aren't nested.
-        if (this.props.ContainingCollectionView instanceof CollectionDockingView) {
-            var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!);
-            Xx = rx - COLLECTION_BORDER_WIDTH;
-            Yy = ry - COLLECTION_BORDER_WIDTH;
-        }
-
-        let Ss = this.props.Document.GetNumber(KeyStore.Scale, 1);
-        let Panxx = this.props.Document.GetData(KeyStore.PanX, NumberField, Number(0));
-        let Panyy = this.props.Document.GetData(KeyStore.PanY, NumberField, Number(0));
-        let LocalX = (ContainerX - (Xx + Panxx)) / Ss;
-        let LocalY = (ContainerY - (Yy + Panyy)) / Ss;
-
-        return { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY };
-    }
-
-    //
-    // Converts a point in the coordinate space of a document to a screen space coordinate.
-    //
-    public TransformToScreenPoint(localX: number, localY: number, Ss: number = 1, Panxx: number = 0, Panyy: number = 0): { ScreenX: number, ScreenY: number } {
-
-        var Xx = this.props.Document.GetData(KeyStore.X, NumberField, Number(0));
-        var Yy = this.props.Document.GetData(KeyStore.Y, NumberField, Number(0));
-        // CollectionDockingViews change the location of their children frames without using a Dash transformation.
-        // They also ignore any transformation that may have been applied to their content document.
-        // NOTE: this currently assumes CollectionDockingViews aren't nested.
-        if (this.props.ContainingCollectionView instanceof CollectionDockingView) {
-            var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!);
-            Xx = rx - COLLECTION_BORDER_WIDTH;
-            Yy = ry - COLLECTION_BORDER_WIDTH;
-        }
-
-        let W = COLLECTION_BORDER_WIDTH;
-        let H = COLLECTION_BORDER_WIDTH;
-        let parentX = (localX - W) * Ss + (Xx + Panxx) + W;
-        let parentY = (localY - H) * Ss + (Yy + Panyy) + H;
-
-        // if this collection view is nested within another collection view, then 
-        // first transform the local point into the parent collection's coordinate space.
-        let containingDocView = this.props.ContainingCollectionView != undefined ? this.props.ContainingCollectionView.props.ContainingDocumentView : undefined;
-        if (containingDocView != undefined) {
-            let ss = containingDocView.props.Document.GetNumber(KeyStore.Scale, 1) * this.props.Scaling;
-            let panxx = containingDocView.props.Document.GetData(KeyStore.PanX, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss;
-            let panyy = containingDocView.props.Document.GetData(KeyStore.PanY, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss;
-            let { ScreenX, ScreenY } = containingDocView.TransformToScreenPoint(parentX, parentY, ss, panxx, panyy);
-            parentX = ScreenX;
-            parentY = ScreenY;
-        }
-        return { ScreenX: parentX, ScreenY: parentY };
-    }
-
 
     render() {
         let bindings = { ...this.props } as any;
         for (const key of this.layoutKeys) {
             bindings[key.Name + "Key"] = key;  // this maps string values of the form <keyname>Key to an actual key Kestore.keyname  e.g,   "DataKey" => KeyStore.Data
         }
+        if (!bindings.GetTransform) {
+            console.log("test");
+        }
         for (const key of this.layoutFields) {
             let field = this.props.Document.Get(key);
             bindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field;
-- 
cgit v1.2.3-70-g09d2


From e09ddf280d0e2bdef28477a6d7be06c57051dab6 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 12 Feb 2019 21:08:04 -0500
Subject: fixed up nested selections and scaling

---
 src/client/views/DocumentDecorations.tsx           |  9 +-
 src/client/views/Main.tsx                          |  4 +-
 .../views/collections/CollectionDockingView.tsx    | 34 +++-----
 .../views/collections/CollectionFreeFormView.tsx   | 12 +--
 .../views/collections/CollectionSchemaView.tsx     |  2 +-
 .../views/collections/CollectionViewBase.tsx       |  4 +-
 .../views/nodes/CollectionFreeFormDocumentView.tsx | 47 +++++------
 src/client/views/nodes/DocumentView.tsx            | 97 ++++++++++++----------
 8 files changed, 104 insertions(+), 105 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 7efaa5533..cc43372af 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -4,6 +4,7 @@ import { SelectionManager } from "../util/SelectionManager";
 import { observer } from "mobx-react";
 import './DocumentDecorations.scss'
 import { CollectionFreeFormView } from "./collections/CollectionFreeFormView";
+import { KeyStore } from '../../fields/Key'
 
 @observer
 export class DocumentDecorations extends React.Component {
@@ -25,8 +26,8 @@ export class DocumentDecorations extends React.Component {
                 !(element.props.ContainingCollectionView instanceof CollectionFreeFormView)) {
                 return bounds;
             }
-            var spt = element.TransformToScreenPoint(0, 0);
-            var bpt = element.TransformToScreenPoint(element.width, element.height);
+            var spt = element.TransformToScreenPoint(0, 0, 1, 0, 0, false);
+            var bpt = element.TransformToScreenPoint(element.width, element.height, 1, 0, 0, false);
             return {
                 x: Math.min(spt.ScreenX, bounds.x), y: Math.min(spt.ScreenY, bounds.y),
                 r: Math.max(bpt.ScreenX, bounds.r), b: Math.max(bpt.ScreenY, bounds.b)
@@ -109,8 +110,8 @@ export class DocumentDecorations extends React.Component {
                 let scale = element.width / rect.width;
                 let actualdW = Math.max(element.width + (dW * scale), 20);
                 let actualdH = Math.max(element.height + (dH * scale), 20);
-                element.x += dX * (actualdW - element.width);
-                element.y += dY * (actualdH - element.height);
+                element.props.Document.SetNumber(KeyStore.X, element.props.Document.GetNumber(KeyStore.X, 0) + dX * (actualdW - element.width));
+                element.props.Document.SetNumber(KeyStore.Y, element.props.Document.GetNumber(KeyStore.Y, 0) + dY * (actualdH - element.height));
                 if (Math.abs(dW) > Math.abs(dH))
                     element.width = actualdW;
                 else
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index ba92cc17e..e78949ba7 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -62,7 +62,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) {
     // let doc5 = Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", {
     //     x: 650, y: 500, width: 600, height: 600, title: "cat 2"
     // });
-    let docset2 = [doc3, doc1, doc2];
+    let docset2 = [doc3, doc4, doc2];
     let doc6 = Documents.CollectionDocument(docset2, {
         x: 350, y: 100, width: 600, height: 600, title: "docking collection"
     });
@@ -87,7 +87,7 @@ ReactDOM.render((
     <div style={{ position: "absolute", width: "100%", height: "100%" }}>
         <DocumentView Document={mainContainer}
             AddDocument={undefined} RemoveDocument={undefined} GetTransform={() => Transform.Identity}
-            Scaling={1}
+            ParentScaling={1}
             ContainingCollectionView={undefined} DocumentView={undefined} />
         <DocumentDecorations />
         <ContextMenu />
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index d3e90d11c..8abb0dbaa 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -100,7 +100,7 @@ export class CollectionDockingView extends CollectionViewBase {
                 return (<DocumentView key={value[i].Id} Document={value[i]}
                     AddDocument={this.addDocument} RemoveDocument={this.removeDocument}
                     GetTransform={() => Transform.Identity}
-                    Scaling={1}
+                    ParentScaling={1}
                     ContainingCollectionView={this} DocumentView={undefined} />);
             }
         }
@@ -267,17 +267,15 @@ export class CollectionDockingView extends CollectionViewBase {
         }
 
         return (
-            <div className="border" style={{
-                borderStyle: "solid",
-                borderWidth: `${COLLECTION_BORDER_WIDTH}px`,
-            }}>
-                <div className="collectiondockingview-container" id="menuContainer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} ref={this._containerRef}
-                    style={{
-                        width: CollectionDockingView.UseGoldenLayout || s > 1 ? "100%" : w - 2 * COLLECTION_BORDER_WIDTH,
-                        height: CollectionDockingView.UseGoldenLayout || s > 1 ? "100%" : h - 2 * COLLECTION_BORDER_WIDTH
-                    }} >
-                    {chooseLayout()}
-                </div>
+            <div className="collectiondockingview-container" id="menuContainer"
+                onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} ref={this._containerRef}
+                style={{
+                    width: CollectionDockingView.UseGoldenLayout || s > 1 ? "100%" : w - 2 * COLLECTION_BORDER_WIDTH,
+                    height: CollectionDockingView.UseGoldenLayout || s > 1 ? "100%" : h - 2 * COLLECTION_BORDER_WIDTH,
+                    borderStyle: "solid",
+                    borderWidth: `${COLLECTION_BORDER_WIDTH}px`,
+                }} >
+                {chooseLayout()}
             </div>
         );
     }
@@ -295,25 +293,19 @@ class RenderClass {
         this._htmlElement = document.getElementById(containingDiv);
         this._document = doc;
         container.on('resize', action((e: any) => {
-            var nativeWidth = doc.GetNumber(KeyStore.NativeWidth, 0);
-            if (this._htmlElement != null && this._htmlElement.childElementCount > 0 && nativeWidth > 0) {
-                let scaling = nativeWidth > 0 ? this._htmlElement!.clientWidth / nativeWidth : 1;
-                (this._htmlElement!.children[0] as any).style.transformOrigin = "0px 0px";
-                (this._htmlElement!.children[0] as any).style.transform = `translate(0px,0px)  scale(${scaling}, ${scaling}) `;
-                (this._htmlElement!.children[0] as any).style.width = nativeWidth.toString() + "px";
-            }
+            this.render();
         }));
 
         this.render();
     }
     render() {
         var nativeWidth = this._document.GetNumber(KeyStore.NativeWidth, 0);
-        let scaling = nativeWidth > 0 ? this._htmlElement!.clientWidth / nativeWidth : 1;
+        let parentScaling = nativeWidth > 0 ? this._htmlElement!.clientWidth / nativeWidth : 1;
         ReactDOM.render((
             <DocumentView key={this._document.Id} Document={this._document}
                 AddDocument={this._collectionDockingView.addDocument} RemoveDocument={this._collectionDockingView.removeDocument}
                 GetTransform={() => Transform.Identity}
-                Scaling={scaling}
+                ParentScaling={parentScaling}
                 ContainingCollectionView={this._collectionDockingView} DocumentView={undefined} />
         ),
             this._htmlElement
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 15450d737..0262e4a6c 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -58,8 +58,8 @@ export class CollectionFreeFormView extends CollectionViewBase {
             const currScale = this.resizeScaling * this.zoomScaling * this.props.ContainingDocumentView!.ScalingToScreenSpace;
             const screenX = de.x - xOffset;
             const screenY = de.y - yOffset;
-            doc.x = (screenX - translateX) / currScale;
-            doc.y = (screenY - translateY) / currScale;
+            doc.props.Document.SetNumber(KeyStore.X, (screenX - translateX) / currScale);
+            doc.props.Document.SetNumber(KeyStore.Y, (screenY - translateY) / currScale);
             this.bringToFront(doc);
         }
         e.stopPropagation();
@@ -124,7 +124,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
         // if (modes[e.deltaMode] == 'pixels') coefficient = 50;
         // else if (modes[e.deltaMode] == 'lines') coefficient = 1000; // This should correspond to line-height??
 
-        let { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY);
+        let { LocalX, Ss, Xx, LocalY, Yy, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY);
 
         var deltaScale = (1 - (e.deltaY / coefficient)) * Ss;
         var newDeltaScale = this.isAnnotationOverlay ? Math.max(1, deltaScale) : deltaScale;
@@ -135,8 +135,8 @@ export class CollectionFreeFormView extends CollectionViewBase {
 
     @action
     private SetPan(panX: number, panY: number) {
-        const newPanX = Math.max(-(this.resizeScaling * this.zoomScaling - this.resizeScaling) * this.nativeWidth, Math.min(0, panX));
-        const newPanY = Math.max(-(this.resizeScaling * this.zoomScaling - this.resizeScaling) * this.nativeHeight, Math.min(0, panY));
+        const newPanX = Math.max((1 - this.zoomScaling) * this.nativeWidth, Math.min(0, panX));
+        const newPanY = Math.max((1 - this.zoomScaling) * this.nativeHeight, Math.min(0, panY));
         this.props.DocumentForCollection.SetNumber(KeyStore.PanX, this.isAnnotationOverlay ? newPanX : panX);
         this.props.DocumentForCollection.SetNumber(KeyStore.PanY, this.isAnnotationOverlay ? newPanY : panY);
     }
@@ -241,7 +241,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
                             AddDocument={this.addDocument}
                             RemoveDocument={this.removeDocument}
                             GetTransform={this.getTransform}
-                            Scaling={1}
+                            ParentScaling={1}
                             ContainingCollectionView={this} DocumentView={undefined} />);
                     })}
                 </div>
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index f1e882e20..eec3b275c 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -109,7 +109,7 @@ export class CollectionSchemaView extends CollectionViewBase {
                 <DocumentView Document={children[this.selectedIndex]}
                     AddDocument={this.addDocument} RemoveDocument={this.removeDocument}
                     GetTransform={() => Transform.Identity}//TODO This should probably be an actual transform
-                    Scaling={1}
+                    ParentScaling={1}
                     DocumentView={undefined} ContainingCollectionView={this} />
             )
         } else {
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index 7e2fcb39d..1cf07ce05 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -19,7 +19,7 @@ export interface CollectionViewProps {
     ContainingDocumentView: Opt<DocumentView>;
     GetTransform: () => Transform;
     BackgroundView: Opt<DocumentView>;
-    Scaling: number;
+    ParentScaling: number;
 }
 
 export const COLLECTION_BORDER_WIDTH = 2;
@@ -28,7 +28,7 @@ export const COLLECTION_BORDER_WIDTH = 2;
 export class CollectionViewBase extends React.Component<CollectionViewProps> {
 
     public static LayoutString(collectionType: string, fieldKey: string = "DataKey") {
-        return `<${collectionType} Scaling={Scaling} DocumentForCollection={Document} CollectionFieldKey={${fieldKey}} ContainingDocumentView={DocumentView} BackgroundView={BackgroundView} />`;
+        return `<${collectionType} ParentScaling={ParentScaling} DocumentForCollection={Document} CollectionFieldKey={${fieldKey}} ContainingDocumentView={DocumentView} BackgroundView={BackgroundView} />`;
     }
     @computed
     public get active(): boolean {
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 9cd42a069..7a895dd60 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -11,6 +11,7 @@ import "./NodeView.scss";
 import React = require("react");
 import { DocumentView, DocumentViewProps } from "./DocumentView";
 import { Transform } from "../../util/Transform";
+import { COLLECTION_BORDER_WIDTH } from '../../views/collections/CollectionViewBase';
 
 
 @observer
@@ -30,27 +31,17 @@ export class CollectionFreeFormDocumentView extends DocumentView {
         return new DOMRect();
     }
 
-    @computed
-    get x(): number {
-        return this.props.Document.GetData(KeyStore.X, NumberField, Number(0));
-    }
-
-    @computed
-    get y(): number {
-        return this.props.Document.GetData(KeyStore.Y, NumberField, Number(0));
+    public LeftCorner(): number {
+        return this.props.Document.GetNumber(KeyStore.X, 0) + super.LeftCorner();
     }
 
-    set x(x: number) {
-        this.props.Document.SetData(KeyStore.X, x, NumberField)
-    }
-
-    set y(y: number) {
-        this.props.Document.SetData(KeyStore.Y, y, NumberField)
+    public TopCorner(): number {
+        return this.props.Document.GetNumber(KeyStore.Y, 0) + super.TopCorner();
     }
 
     @computed
     get transform(): string {
-        return `scale(${this.props.Scaling}, ${this.props.Scaling}) translate(${this.x}px, ${this.y}px)`;
+        return `scale(${this.props.ParentScaling}, ${this.props.ParentScaling}) translate(${this.props.Document.GetNumber(KeyStore.X, 0)}px, ${this.props.Document.GetNumber(KeyStore.Y, 0)}px)`;
     }
 
     @computed
@@ -221,24 +212,26 @@ export class CollectionFreeFormDocumentView extends DocumentView {
     }
 
     getTransform = (): Transform => {
-        return this.props.GetTransform().translated(this.x, this.y);
+        return this.props.GetTransform().translated(this.props.Document.GetNumber(KeyStore.X, 0), this.props.Document.GetNumber(KeyStore.Y, 0));
     }
 
     render() {
         var freestyling = this.props.ContainingCollectionView instanceof CollectionFreeFormView;
+        var parentScaling = this.nativeWidth > 0 ? this.width / this.nativeWidth : 1;
         return (
-            <div className="node" ref={this._mainCont} style={{
-                transformOrigin: "left top",
-                transform: freestyling ? this.transform : "",
-                width: freestyling ? this.width : "100%",
-                height: freestyling ? this.height : "100%",
-                position: freestyling ? "absolute" : "relative",
-                zIndex: freestyling ? this.zIndex : 0,
-            }}
+            <div className="node" ref={this._mainCont}
                 onContextMenu={this.onContextMenu}
-                onPointerDown={this.onPointerDown}>
-
-                <DocumentView {...this.props} Scaling={this.width / this.nativeWidth} GetTransform={this.getTransform} DocumentView={this} />
+                onPointerDown={this.onPointerDown}
+                style={{
+                    transformOrigin: "left top",
+                    transform: freestyling ? this.transform : "",
+                    width: freestyling ? this.width : "100%",
+                    height: freestyling ? this.height : "100%",
+                    position: freestyling ? "absolute" : "relative",
+                    zIndex: freestyling ? this.zIndex : 0,
+                }}>
+
+                <DocumentView {...this.props} ref={this._renderDoc} ParentScaling={parentScaling} GetTransform={this.getTransform} DocumentView={this} />
             </div>
         );
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 3a73f2fde..51959841b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -17,6 +17,7 @@ import "./NodeView.scss";
 import React = require("react");
 import { Transform } from "../../util/Transform";
 const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this?
+import { CollectionFreeFormDocumentView } from '../../views/nodes/CollectionFreeFormDocumentView';
 
 export interface DocumentViewProps {
     DocumentView: Opt<DocumentView>  // needed only to set ContainingDocumentView on CollectionViewProps when invoked from JsxParser -- is there a better way?
@@ -26,16 +27,23 @@ export interface DocumentViewProps {
     AddDocument?: (doc: Document) => void;
     RemoveDocument?: (doc: Document) => boolean;
     GetTransform: () => Transform;
-    Scaling: number;
+    ParentScaling: number;
 }
 
 @observer
 export class DocumentView extends React.Component<DocumentViewProps> {
 
+    protected _renderDoc = React.createRef<any>();
     protected _mainCont = React.createRef<any>();
     get MainContent() {
         return this._mainCont;
     }
+
+    @computed
+    get parentScaling(): number {
+        return this._renderDoc.current ? this._renderDoc.current.props.ParentScaling : this.props.ParentScaling > 1 ? this.props.ParentScaling : 1;
+    }
+
     @computed
     get layout(): string {
         return this.props.Document.GetData(KeyStore.Layout, TextField, String("<p>Error loading layout data</p>"));
@@ -43,7 +51,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
 
     @computed
     get backgroundLayout(): string {
-        return this.props.Document.GetData(KeyStore.BackgroundLayout, TextField, String("<p>Error loading layout data</p>"));
+        return this.props.Document.GetText(KeyStore.BackgroundLayout, "");
     }
 
     @computed
@@ -69,67 +77,72 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         return 1;
     }
 
+
+    public LeftCorner(): number {
+        if (this.props.ContainingCollectionView) {
+            if (this.props.ContainingCollectionView instanceof CollectionDockingView) {
+                // this is a hacky way to account for the titles/pane placement/etc of a CollectionDockingView 
+                // this only works if the collectionDockingView is the root collection, too.
+                // need to find a better way.
+                var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!);
+                return rx + COLLECTION_BORDER_WIDTH;
+            }
+            return COLLECTION_BORDER_WIDTH; // assumes all collections have the same border
+        }
+        return 0;
+    }
+
+    public TopCorner(): number {
+        if (this.props.ContainingCollectionView) {
+            if (this.props.ContainingCollectionView instanceof CollectionDockingView) {
+                // this is a hacky way to account for the titles/pane placement/etc of a CollectionDockingView 
+                // this only works if the collectionDockingView is the root collection, too.
+                // need to find a better way.
+                var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!);
+                return ry + COLLECTION_BORDER_WIDTH;
+            }
+            return COLLECTION_BORDER_WIDTH;  // assumes all collections have the same border
+        }
+        return 0;
+    }
     //
     // Converts a coordinate in the screen space of the app into a local document coordinate.
     //
     public TransformToLocalPoint(screenX: number, screenY: number) {
         // if this collection view is nested within another collection view, then 
         // first transform the screen point into the parent collection's coordinate space.
-        let { LocalX: parentX, LocalY: parentY } = this.props.ContainingCollectionView != undefined &&
-            this.props.ContainingCollectionView.props.ContainingDocumentView != undefined ?
+        let { LocalX: parentX, LocalY: parentY } = this.props.ContainingCollectionView &&
+            this.props.ContainingCollectionView.props.ContainingDocumentView ?
             this.props.ContainingCollectionView.props.ContainingDocumentView.TransformToLocalPoint(screenX, screenY) :
             { LocalX: screenX, LocalY: screenY };
         let ContainerX: number = parentX - COLLECTION_BORDER_WIDTH;
         let ContainerY: number = parentY - COLLECTION_BORDER_WIDTH;
 
-        var Xx = this.props.Document.GetData(KeyStore.X, NumberField, Number(0));
-        var Yy = this.props.Document.GetData(KeyStore.Y, NumberField, Number(0));
-        // CollectionDockingViews change the location of their children frames without using a Dash transformation.
-        // They also ignore any transformation that may have been applied to their content document.
-        // NOTE: this currently assumes CollectionDockingViews aren't nested.
-        if (this.props.ContainingCollectionView instanceof CollectionDockingView) {
-            var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!);
-            Xx = rx - COLLECTION_BORDER_WIDTH;
-            Yy = ry - COLLECTION_BORDER_WIDTH;
-        }
-
         let Ss = this.props.Document.GetNumber(KeyStore.Scale, 1);
-        let Panxx = this.props.Document.GetData(KeyStore.PanX, NumberField, Number(0));
-        let Panyy = this.props.Document.GetData(KeyStore.PanY, NumberField, Number(0));
-        let LocalX = (ContainerX - (Xx + Panxx)) / Ss;
-        let LocalY = (ContainerY - (Yy + Panyy)) / Ss;
+        let Panxx = this.props.Document.GetNumber(KeyStore.PanX, 0);
+        let Panyy = this.props.Document.GetNumber(KeyStore.PanY, 0);
+        let LocalX = (ContainerX - (this.LeftCorner() + Panxx)) / Ss;
+        let LocalY = (ContainerY - (this.TopCorner() + Panyy)) / Ss;
 
-        return { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY };
+        return { LocalX, Ss, Xx: this.LeftCorner(), LocalY, Yy: this.TopCorner(), ContainerX, ContainerY };
     }
 
     //
     // Converts a point in the coordinate space of a document to a screen space coordinate.
     //
-    public TransformToScreenPoint(localX: number, localY: number, Ss: number = 1, Panxx: number = 0, Panyy: number = 0): { ScreenX: number, ScreenY: number } {
-
-        var Xx = this.props.Document.GetData(KeyStore.X, NumberField, Number(0));
-        var Yy = this.props.Document.GetData(KeyStore.Y, NumberField, Number(0));
-        // CollectionDockingViews change the location of their children frames without using a Dash transformation.
-        // They also ignore any transformation that may have been applied to their content document.
-        // NOTE: this currently assumes CollectionDockingViews aren't nested.
-        if (this.props.ContainingCollectionView instanceof CollectionDockingView) {
-            var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!);
-            Xx = rx - COLLECTION_BORDER_WIDTH;
-            Yy = ry - COLLECTION_BORDER_WIDTH + 18 * Ss;
-        }
+    public TransformToScreenPoint(localX: number, localY: number, Ss: number = 1, Panxx: number = 0, Panyy: number = 0, apply: boolean = true): { ScreenX: number, ScreenY: number } {
+        var parentScaling = apply ? this.parentScaling : 1;
 
-        let W = COLLECTION_BORDER_WIDTH;
-        let H = COLLECTION_BORDER_WIDTH;
-        let parentX = (localX - W) * Ss + (Xx + Panxx) + W;
-        let parentY = (localY - H) * Ss + (Yy + Panyy) + H;
+        let parentX = (Panxx + (localX - COLLECTION_BORDER_WIDTH) * Ss) * parentScaling + this.LeftCorner();
+        let parentY = (Panyy + (localY - COLLECTION_BORDER_WIDTH) * Ss) * parentScaling + this.TopCorner();
 
         // if this collection view is nested within another collection view, then 
         // first transform the local point into the parent collection's coordinate space.
         let containingDocView = this.props.ContainingCollectionView != undefined ? this.props.ContainingCollectionView.props.ContainingDocumentView : undefined;
-        if (containingDocView != undefined) {
-            let ss = containingDocView.props.Document.GetNumber(KeyStore.Scale, 1) * this.props.Scaling;
-            let panxx = containingDocView.props.Document.GetData(KeyStore.PanX, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss;
-            let panyy = containingDocView.props.Document.GetData(KeyStore.PanY, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss;
+        if (containingDocView) {
+            let ss = containingDocView.props.Document.GetNumber(KeyStore.Scale, 1);
+            let panxx = containingDocView.props.Document.GetNumber(KeyStore.PanX, 0) + COLLECTION_BORDER_WIDTH * ss * parentScaling;
+            let panyy = containingDocView.props.Document.GetNumber(KeyStore.PanY, 0) + COLLECTION_BORDER_WIDTH * ss * parentScaling;
             let { ScreenX, ScreenY } = containingDocView.TransformToScreenPoint(parentX, parentY, ss, panxx, panyy);
             parentX = ScreenX;
             parentY = ScreenY;
@@ -158,13 +171,13 @@ export class DocumentView extends React.Component<DocumentViewProps> {
             onError={(test: any) => { console.log(test) }}
         />;
         bindings["BackgroundView"] = this.backgroundLayout ? annotated : null;
-
+        bindings["ParentScaling"] = 1;
         var width = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
         var strwidth = width > 0 ? width.toString() + "px" : "100%";
         var height = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
         var strheight = height > 0 ? height.toString() + "px" : "100%";
         return (
-            <div className="node" ref={this._mainCont} style={{ width: strwidth, height: strheight, transformOrigin: "left top", transform: `scale(${this.props.Scaling},${this.props.Scaling})` }}>
+            <div className="node" ref={this._mainCont} style={{ width: strwidth, height: strheight, transformOrigin: "0 0", transform: `scale(${this.props.ParentScaling},${this.props.ParentScaling})` }}>
                 <JsxParser
                     components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
                     bindings={bindings}
-- 
cgit v1.2.3-70-g09d2


From 9cb0bf595b47d6a76113e3ed2f99d34e1713904e Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 12 Feb 2019 22:43:23 -0500
Subject: more minor api cleanup

---
 src/client/views/DocumentDecorations.tsx |  4 ++--
 src/client/views/nodes/DocumentView.tsx  | 30 +++++++++++++++++++-----------
 2 files changed, 21 insertions(+), 13 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index cc43372af..1224495f6 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -26,8 +26,8 @@ export class DocumentDecorations extends React.Component {
                 !(element.props.ContainingCollectionView instanceof CollectionFreeFormView)) {
                 return bounds;
             }
-            var spt = element.TransformToScreenPoint(0, 0, 1, 0, 0, false);
-            var bpt = element.TransformToScreenPoint(element.width, element.height, 1, 0, 0, false);
+            var spt = element.TransformToScreenPoint(0, 0);
+            var bpt = element.TransformToScreenPoint(element.width, element.height);
             return {
                 x: Math.min(spt.ScreenX, bounds.x), y: Math.min(spt.ScreenY, bounds.y),
                 r: Math.max(bpt.ScreenX, bounds.r), b: Math.max(bpt.ScreenY, bounds.b)
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 9607a4984..355e431e6 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -130,7 +130,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     //
     // Converts a point in the coordinate space of the document to coordinate in app screen coordinates
     //
-    public TransformToScreenPoint(localX: number, localY: number, Ss: number = 1, Panxx: number = 0, Panyy: number = 0, apply: boolean = true): { ScreenX: number, ScreenY: number } {
+    public TransformToScreenPoint(localX: number, localY: number, Ss: number = 1, Panxx: number = 0, Panyy: number = 0, apply: boolean = false): { ScreenX: number, ScreenY: number } {
         var parentScaling = apply ? this.parentScaling : 1;
 
         let parentX = (Panxx + (localX - COLLECTION_BORDER_WIDTH) * Ss) * parentScaling + this.LeftCorner();
@@ -143,7 +143,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
             let ss = containingDocView.props.Document.GetNumber(KeyStore.Scale, 1);
             let panxx = containingDocView.props.Document.GetNumber(KeyStore.PanX, 0) + COLLECTION_BORDER_WIDTH * ss * parentScaling;
             let panyy = containingDocView.props.Document.GetNumber(KeyStore.PanY, 0) + COLLECTION_BORDER_WIDTH * ss * parentScaling;
-            let { ScreenX, ScreenY } = containingDocView.TransformToScreenPoint(parentX, parentY, ss, panxx, panyy);
+            let { ScreenX, ScreenY } = containingDocView.TransformToScreenPoint(parentX, parentY, ss, panxx, panyy, true);
             parentX = ScreenX;
             parentY = ScreenY;
         }
@@ -163,20 +163,28 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         if (bindings.DocumentView === undefined) {
             bindings.DocumentView = this; // set the DocumentView to this if it hasn't already been set by a sub-class during its render method.
         }
-        var annotated = <JsxParser
-            components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
-            bindings={bindings}
-            jsx={this.backgroundLayout}
-            showWarnings={true}
-            onError={(test: any) => { console.log(test) }}
-        />;
-        bindings["BackgroundView"] = this.backgroundLayout ? annotated : null;
+        if (this.backgroundLayout) {
+            var backgroundview = <JsxParser
+                components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
+                bindings={bindings}
+                jsx={this.backgroundLayout}
+                showWarnings={true}
+                onError={(test: any) => { console.log(test) }}
+            />;
+            bindings["BackgroundView"] = backgroundview;
+        }
         var nativewidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
         var nativeheight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
         var width = nativewidth > 0 ? nativewidth + "px" : "100%";
         var height = nativeheight > 0 ? nativeheight + "px" : "100%";
         return (
-            <div className="node" ref={this._mainCont} style={{ width: width, height: height, transformOrigin: "0 0", transform: `scale(${this.props.ParentScaling},${this.props.ParentScaling})` }}>
+            <div className="node" ref={this._mainCont}
+                style={{
+                    width: width,
+                    height: height,
+                    transformOrigin: "top left",
+                    transform: `scale(${this.props.ParentScaling},${this.props.ParentScaling})`
+                }}>
                 <JsxParser
                     components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
                     bindings={bindings}
-- 
cgit v1.2.3-70-g09d2


From c93c3e1970c6ecc91b60f1782e82b1bfdc7fef30 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Wed, 13 Feb 2019 04:50:56 -0500
Subject: A lot of stuff working, a lot of other stuff not working

---
 .vscode/launch.json                                |   6 +-
 src/client/util/DragManager.ts                     |   2 +
 src/client/util/SelectionManager.ts                |  12 +-
 src/client/util/Transform.ts                       |  70 ++++----
 src/client/views/DocumentDecorations.tsx           |  39 ++++-
 src/client/views/Main.tsx                          |   1 +
 .../views/collections/CollectionDockingView.tsx    |  10 +-
 .../views/collections/CollectionFreeFormView.tsx   |  55 +++---
 .../views/collections/CollectionSchemaView.tsx     |   4 +-
 .../views/collections/CollectionViewBase.tsx       |  10 +-
 .../views/nodes/CollectionFreeFormDocumentView.tsx | 138 +---------------
 src/client/views/nodes/DocumentView.tsx            | 184 +++++++++++++++++++--
 src/client/views/nodes/FieldView.tsx               |   6 +-
 src/client/views/nodes/FormattedTextBox.tsx        |   2 +-
 src/client/views/nodes/ImageBox.tsx                |   4 +-
 15 files changed, 303 insertions(+), 240 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/.vscode/launch.json b/.vscode/launch.json
index 9a0a9afb4..546ede805 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -11,7 +11,11 @@
             "sourceMaps": true,
             "breakOnLoad": true,
             "url": "http://localhost:1050",
-            "webRoot": "${workspaceFolder}"
+            "webRoot": "${workspaceFolder}",
+            "skipFiles": [
+                "${workspaceRoot}/node_modules/**/*.js",
+                "${workspaceRoot}/node_modules/**/*.ts",
+            ]
         },
         {
             "type": "node",
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index f4dcce7c8..93b927f8b 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -78,6 +78,8 @@ export namespace DragManager {
         dragElement.style.transformOrigin = "0 0";
         dragElement.style.zIndex = "1000";
         dragElement.style.transform = `translate(${x}px, ${y}px) scale(${scaleX}, ${scaleY})`;
+        dragElement.style.width = `${rect.width}px`;
+        dragElement.style.height = `${rect.height}px`;
         dragDiv.appendChild(dragElement);
         _lastPointerX = dragData["xOffset"] + rect.left;
         _lastPointerY = dragData["yOffset"] + rect.top;
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 0759ae110..1a711ae64 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -1,13 +1,13 @@
-import { CollectionFreeFormDocumentView } from "../views/nodes/CollectionFreeFormDocumentView";
 import { observable, action } from "mobx";
+import { DocumentView } from "../views/nodes/DocumentView";
 
 export namespace SelectionManager {
     class Manager {
         @observable
-        SelectedDocuments: Array<CollectionFreeFormDocumentView> = [];
+        SelectedDocuments: Array<DocumentView> = [];
 
         @action
-        SelectDoc(doc: CollectionFreeFormDocumentView, ctrlPressed: boolean): void {
+        SelectDoc(doc: DocumentView, ctrlPressed: boolean): void {
             // if doc is not in SelectedDocuments, add it
             if (!ctrlPressed) {
                 manager.SelectedDocuments = [];
@@ -21,11 +21,11 @@ export namespace SelectionManager {
 
     const manager = new Manager;
 
-    export function SelectDoc(doc: CollectionFreeFormDocumentView, ctrlPressed: boolean): void {
+    export function SelectDoc(doc: DocumentView, ctrlPressed: boolean): void {
         manager.SelectDoc(doc, ctrlPressed)
     }
 
-    export function IsSelected(doc: CollectionFreeFormDocumentView): boolean {
+    export function IsSelected(doc: DocumentView): boolean {
         return manager.SelectedDocuments.indexOf(doc) !== -1;
     }
 
@@ -33,7 +33,7 @@ export namespace SelectionManager {
         manager.SelectedDocuments = []
     }
 
-    export function SelectedDocuments(): Array<CollectionFreeFormDocumentView> {
+    export function SelectedDocuments(): Array<DocumentView> {
         return manager.SelectedDocuments;
     }
 }
\ No newline at end of file
diff --git a/src/client/util/Transform.ts b/src/client/util/Transform.ts
index 3edc8d569..8ae3f837f 100644
--- a/src/client/util/Transform.ts
+++ b/src/client/util/Transform.ts
@@ -23,29 +23,13 @@ export class Transform {
         return this;
     }
 
-    translated = (x: number, y: number): Transform => {
-        return this.copy().translate(x, y);
-    }
-
-    preTranslate = (x: number, y: number): Transform => {
-        this._translateX += x * this._scale;
-        this._translateY += y * this._scale;
-        return this;
-    }
-
-    preTranslated = (x: number, y: number): Transform => {
-        return this.copy().preTranslate(x, y);
-    }
-
     scale = (scale: number): Transform => {
         this._scale *= scale;
+        this._translateX *= scale;
+        this._translateY *= scale;
         return this;
     }
 
-    scaled = (scale: number): Transform => {
-        return this.copy().scale(scale);
-    }
-
     scaleAbout = (scale: number, x: number, y: number): Transform => {
         this._translateX += x * this._scale - x * this._scale * scale;
         this._translateY += y * this._scale - y * this._scale * scale;
@@ -53,21 +37,6 @@ export class Transform {
         return this;
     }
 
-    scaledAbout = (scale: number, x: number, y: number): Transform => {
-        return this.copy().scaleAbout(scale, x, y);
-    }
-
-    preScale = (scale: number): Transform => {
-        this._scale *= scale;
-        this._translateX *= scale;
-        this._translateY *= scale;
-        return this;
-    }
-
-    preScaled = (scale: number): Transform => {
-        return this.copy().preScale(scale);
-    }
-
     transform = (transform: Transform): Transform => {
         this._translateX += transform._translateX * this._scale;
         this._translateY += transform._translateY * this._scale;
@@ -75,8 +44,15 @@ export class Transform {
         return this;
     }
 
-    transformed = (transform: Transform): Transform => {
-        return this.copy().transform(transform);
+    preTranslate = (x: number, y: number): Transform => {
+        this._translateX += this._scale * x;
+        this._translateY += this._scale * y;
+        return this;
+    }
+
+    preScale = (scale: number): Transform => {
+        this._scale *= scale;
+        return this;
     }
 
     preTransform = (transform: Transform): Transform => {
@@ -86,6 +62,30 @@ export class Transform {
         return this;
     }
 
+    translated = (x: number, y: number): Transform => {
+        return this.copy().translate(x, y);
+    }
+
+    preTranslated = (x: number, y: number): Transform => {
+        return this.copy().preTranslate(x, y);
+    }
+
+    scaled = (scale: number): Transform => {
+        return this.copy().scale(scale);
+    }
+
+    scaledAbout = (scale: number, x: number, y: number): Transform => {
+        return this.copy().scaleAbout(scale, x, y);
+    }
+
+    preScaled = (scale: number): Transform => {
+        return this.copy().preScale(scale);
+    }
+
+    transformed = (transform: Transform): Transform => {
+        return this.copy().transform(transform);
+    }
+
     preTransformed = (transform: Transform): Transform => {
         return this.copy().preTransform(transform);
     }
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 85b44307f..5abe3f5b2 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -4,6 +4,8 @@ import { SelectionManager } from "../util/SelectionManager";
 import { observer } from "mobx-react";
 import './DocumentDecorations.scss'
 import { CollectionFreeFormView } from "./collections/CollectionFreeFormView";
+import { KeyStore } from "../../fields/Key";
+import { NumberField } from "../../fields/NumberField";
 
 @observer
 export class DocumentDecorations extends React.Component {
@@ -25,9 +27,12 @@ export class DocumentDecorations extends React.Component {
                 !(element.props.ContainingCollectionView instanceof CollectionFreeFormView)) {
                 return bounds;
             }
-            let transform = element.getTransform().inverse();
+            let transform = element.props.GetTransform().inverse();
             var [sptX, sptY] = transform.transformPoint(0, 0);
-            var [bptX, bptY] = transform.transformDirection(element.width, element.height);
+            // var [bptX, bptY] = transform.transformDirection(element.width, element.height);
+            let doc = element.props.Document;
+            let [bptX, bptY] = [doc.GetNumber(KeyStore.Width, 0), doc.GetNumber(KeyStore.Height, 0)];
+            [bptX, bptY] = transform.transformPoint(bptX, bptY);
             return {
                 x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
                 r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
@@ -106,16 +111,32 @@ export class DocumentDecorations extends React.Component {
 
         SelectionManager.SelectedDocuments().forEach(element => {
             const rect = element.screenRect;
+            // if (rect.width !== 0) {
+            //     let scale = element.width / rect.width;
+            //     let actualdW = Math.max(element.width + (dW * scale), 20);
+            //     let actualdH = Math.max(element.height + (dH * scale), 20);
+            //     element.x += dX * (actualdW - element.width);
+            //     element.y += dY * (actualdH - element.height);
+            //     if (Math.abs(dW) > Math.abs(dH))
+            //         element.width = actualdW;
+            //     else
+            //         element.height = actualdH;
+            // }
             if (rect.width !== 0) {
-                let scale = element.width / rect.width;
-                let actualdW = Math.max(element.width + (dW * scale), 20);
-                let actualdH = Math.max(element.height + (dH * scale), 20);
-                element.x += dX * (actualdW - element.width);
-                element.y += dY * (actualdH - element.height);
+                let doc = element.props.Document;
+                let width = doc.GetOrCreate(KeyStore.Width, NumberField);
+                let height = doc.GetOrCreate(KeyStore.Height, NumberField);
+                let x = doc.GetOrCreate(KeyStore.X, NumberField);
+                let y = doc.GetOrCreate(KeyStore.X, NumberField);
+                let scale = width.Data / rect.width;
+                let actualdW = Math.max(width.Data + (dW * scale), 20);
+                let actualdH = Math.max(height.Data + (dH * scale), 20);
+                x.Data += dX * (actualdW - width.Data);
+                y.Data += dY * (actualdH - height.Data);
                 if (Math.abs(dW) > Math.abs(dH))
-                    element.width = actualdW;
+                    width.Data = actualdW;
                 else
-                    element.height = actualdH;
+                    height.Data = actualdH;
             }
         })
     }
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 6ca0000b8..c7ad3e249 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -84,6 +84,7 @@ ReactDOM.render((
         <DocumentView Document={mainContainer}
             AddDocument={undefined} RemoveDocument={undefined} GetTransform={() => Transform.Identity}
             Scaling={1}
+            isTopMost={true}
             ContainingCollectionView={undefined} DocumentView={undefined} />
         <DocumentDecorations />
         <ContextMenu />
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index d3e90d11c..c870a9cf0 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -16,6 +16,7 @@ import "./CollectionDockingView.scss";
 import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase";
 import React = require("react");
 import { changeDependenciesStateTo0 } from "mobx/lib/internal";
+import { Utils } from "../../../Utils";
 
 @observer
 export class CollectionDockingView extends CollectionViewBase {
@@ -100,6 +101,7 @@ export class CollectionDockingView extends CollectionViewBase {
                 return (<DocumentView key={value[i].Id} Document={value[i]}
                     AddDocument={this.addDocument} RemoveDocument={this.removeDocument}
                     GetTransform={() => Transform.Identity}
+                    isTopMost={true}
                     Scaling={1}
                     ContainingCollectionView={this} DocumentView={undefined} />);
             }
@@ -307,12 +309,16 @@ class RenderClass {
         this.render();
     }
     render() {
-        var nativeWidth = this._document.GetNumber(KeyStore.NativeWidth, 0);
+        let nativeWidth = this._document.GetNumber(KeyStore.NativeWidth, 0);
         let scaling = nativeWidth > 0 ? this._htmlElement!.clientWidth / nativeWidth : 1;
         ReactDOM.render((
             <DocumentView key={this._document.Id} Document={this._document}
                 AddDocument={this._collectionDockingView.addDocument} RemoveDocument={this._collectionDockingView.removeDocument}
-                GetTransform={() => Transform.Identity}
+                GetTransform={() => {
+                    let { scale, translateX, translateY } = Utils.GetScreenTransform(this._htmlElement);
+                    return this._collectionDockingView.props.GetTransform().scale(scale).translate(-translateX, -translateY)
+                }}
+                isTopMost={true}
                 Scaling={scaling}
                 ContainingCollectionView={this._collectionDockingView} DocumentView={undefined} />
         ),
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 975eaaae8..7947b1c51 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -14,6 +14,7 @@ import { NumberField } from "../../../fields/NumberField";
 import { Documents } from "../../documents/Documents";
 import { FieldWaiting } from "../../../fields/Field";
 import { Transform } from "../../util/Transform";
+import { DocumentView } from "../nodes/DocumentView";
 
 @observer
 export class CollectionFreeFormView extends CollectionViewBase {
@@ -45,23 +46,21 @@ export class CollectionFreeFormView extends CollectionViewBase {
 
     @action
     drop = (e: Event, de: DragManager.DropEvent) => {
-        const doc = de.data["document"];
+        const doc: DocumentView = de.data["document"];
         var me = this;
-        if (doc instanceof CollectionFreeFormDocumentView) {
-            if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this) {
-                doc.props.ContainingCollectionView.removeDocument(doc.props.Document);
-                this.addDocument(doc.props.Document);
-            }
-            const xOffset = de.data["xOffset"] as number || 0;
-            const yOffset = de.data["yOffset"] as number || 0;
-            const { translateX, translateY } = Utils.GetScreenTransform(this._canvasRef.current!);
-            const currScale = this.resizeScaling * this.zoomScaling * this.props.ContainingDocumentView!.ScalingToScreenSpace;
-            const screenX = de.x - xOffset;
-            const screenY = de.y - yOffset;
-            doc.x = (screenX - translateX) / currScale;
-            doc.y = (screenY - translateY) / currScale;
-            this.bringToFront(doc);
+        if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this) {
+            doc.props.ContainingCollectionView.removeDocument(doc.props.Document);
+            this.addDocument(doc.props.Document);
         }
+        const xOffset = de.data["xOffset"] as number || 0;
+        const yOffset = de.data["yOffset"] as number || 0;
+        const transform = doc.props.GetTransform();
+        const screenX = de.x - xOffset;
+        const screenY = de.y - yOffset;
+        const [x, y] = transform.transformPoint(screenX, screenY);
+        doc.props.Document.SetNumber(KeyStore.X, x);
+        doc.props.Document.SetNumber(KeyStore.Y, y);
+        this.bringToFront(doc);
         e.stopPropagation();
     }
 
@@ -94,8 +93,8 @@ export class CollectionFreeFormView extends CollectionViewBase {
         document.removeEventListener("pointerup", this.onPointerUp);
         e.stopPropagation();
         if (Math.abs(this._downX - e.clientX) < 3 && Math.abs(this._downY - e.clientY) < 3) {
-            if (!SelectionManager.IsSelected(this.props.ContainingDocumentView as CollectionFreeFormDocumentView)) {
-                SelectionManager.SelectDoc(this.props.ContainingDocumentView as CollectionFreeFormDocumentView, false);
+            if (!this.props.isSelected()) {
+                this.props.select(false);
             }
         }
     }
@@ -105,11 +104,11 @@ export class CollectionFreeFormView extends CollectionViewBase {
         if (!e.cancelBubble && this.active) {
             e.preventDefault();
             e.stopPropagation();
-            let currScale: number = this.props.ContainingDocumentView!.ScalingToScreenSpace;
             let x = this.props.DocumentForCollection.GetNumber(KeyStore.PanX, 0);
             let y = this.props.DocumentForCollection.GetNumber(KeyStore.PanY, 0);
+            let [dx, dy] = this.props.GetTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
 
-            this.SetPan(x + (e.pageX - this._lastX) / currScale, y + (e.pageY - this._lastY) / currScale);
+            this.SetPan(x + dx, y + dy);
         }
         this._lastX = e.pageX;
         this._lastY = e.pageY;
@@ -124,15 +123,14 @@ export class CollectionFreeFormView extends CollectionViewBase {
         // if (modes[e.deltaMode] == 'pixels') coefficient = 50;
         // else if (modes[e.deltaMode] == 'lines') coefficient = 1000; // This should correspond to line-height??
         let transform = this.getTransform();
-        let localTransform = this.getLocalTransform();
 
-        let deltaScale = (1 - (e.deltaY / coefficient)) * transform.Scale;
-        let newDeltaScale = this.isAnnotationOverlay ? Math.max(1, deltaScale) : deltaScale;
+        let deltaScale = (1 - (e.deltaY / coefficient));
         let [x, y] = transform.transformPoint(e.clientX, e.clientY);
 
-        localTransform.scaleAbout(newDeltaScale, x, y);
+        let localTransform = this.getLocalTransform();
+        localTransform.scaleAbout(deltaScale, x, y);
 
-        this.props.DocumentForCollection.SetNumber(KeyStore.Scale, newDeltaScale);
+        this.props.DocumentForCollection.SetNumber(KeyStore.Scale, localTransform.Scale);
         this.SetPan(localTransform.TranslateX, localTransform.TranslateY);
     }
 
@@ -182,7 +180,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
     }
 
     @action
-    bringToFront(doc: CollectionFreeFormDocumentView) {
+    bringToFront(doc: DocumentView) {
         const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props;
 
         const value: Document[] = Document.GetList<Document>(fieldKey, []);
@@ -213,12 +211,12 @@ export class CollectionFreeFormView extends CollectionViewBase {
 
     getTransform = (): Transform => {
         const [x, y] = this.translate;
-        return this.props.GetTransform().scaled(this.scale).translate(x, y);
+        return this.props.GetTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).transform(this.getLocalTransform().inverse())
     }
 
     getLocalTransform = (): Transform => {
         const [x, y] = this.translate;
-        return new Transform(x, y, this.scale);
+        return Transform.Identity.scale(this.scale).translate(x, y);
     }
 
     render() {
@@ -249,8 +247,9 @@ export class CollectionFreeFormView extends CollectionViewBase {
                             AddDocument={this.addDocument}
                             RemoveDocument={this.removeDocument}
                             GetTransform={this.getTransform}
+                            isTopMost={false}
                             Scaling={1}
-                            ContainingCollectionView={this} DocumentView={undefined} />);
+                            ContainingCollectionView={this} DocumentView={this.props.ContainingDocumentView} />);
                     })}
                 </div>
             </div>
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index f1e882e20..adae8560e 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -27,7 +27,8 @@ export class CollectionSchemaView extends CollectionViewBase {
         let props: FieldViewProps = {
             doc: rowProps.value[0],
             fieldKey: rowProps.value[1],
-            DocumentViewForField: undefined,
+            isSelected: () => false,
+            isTopMost: false
         }
         let contents = (
             <FieldView {...props} />
@@ -110,6 +111,7 @@ export class CollectionSchemaView extends CollectionViewBase {
                     AddDocument={this.addDocument} RemoveDocument={this.removeDocument}
                     GetTransform={() => Transform.Identity}//TODO This should probably be an actual transform
                     Scaling={1}
+                    isTopMost={false}
                     DocumentView={undefined} ContainingCollectionView={this} />
             )
         } else {
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index cf5bc70c4..2c950c8ae 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -18,6 +18,9 @@ export interface CollectionViewProps {
     DocumentForCollection: Document;
     ContainingDocumentView: Opt<DocumentView>;
     GetTransform: () => Transform;
+    isSelected: () => boolean;
+    isTopMost: boolean;
+    select: (ctrlPressed: boolean) => void;
     BackgroundView: Opt<DocumentView>;
     Scaling: number;
 }
@@ -29,16 +32,15 @@ export class CollectionViewBase extends React.Component<CollectionViewProps> {
 
     public static LayoutString(collectionType: string, fieldKey: string = "DataKey") {
         return `<${collectionType} Scaling={Scaling} DocumentForCollection={Document}
-                    GetTransform={GetTransform} CollectionFieldKey={${fieldKey}}
+                    GetTransform={GetTransform} CollectionFieldKey={${fieldKey}} isSelected={isSelected} select={select}
+                    isTopMost={isTopMost}
                     ContainingDocumentView={DocumentView} BackgroundView={BackgroundView} />`;
     }
     @computed
     public get active(): boolean {
         var isSelected = (this.props.ContainingDocumentView instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.ContainingDocumentView));
         var childSelected = SelectionManager.SelectedDocuments().some(view => view.props.ContainingCollectionView == this);
-        var topMost = this.props.ContainingDocumentView != undefined && (
-            this.props.ContainingDocumentView.props.ContainingCollectionView == undefined ||
-            this.props.ContainingDocumentView.props.ContainingCollectionView instanceof CollectionDockingView);
+        var topMost = this.props.isTopMost;
         return isSelected || childSelected || topMost;
     }
     @action
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 9cd42a069..54bc7327b 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -14,11 +14,8 @@ import { Transform } from "../../util/Transform";
 
 
 @observer
-export class CollectionFreeFormDocumentView extends DocumentView {
-    private _contextMenuCanOpen = false;
-    private _downX: number = 0;
-    private _downY: number = 0;
-    // private _mainCont = React.createRef<HTMLDivElement>();
+export class CollectionFreeFormDocumentView extends React.Component<DocumentViewProps> {
+    private _mainCont = React.createRef<HTMLDivElement>();
 
     constructor(props: DocumentViewProps) {
         super(props);
@@ -95,130 +92,6 @@ export class CollectionFreeFormDocumentView extends DocumentView {
         this.props.Document.SetData(KeyStore.ZIndex, h, NumberField)
     }
 
-    @action
-    dragComplete = (e: DragManager.DragCompleteEvent) => {
-    }
-
-    @computed
-    get active(): boolean {
-        return SelectionManager.IsSelected(this) || this.props.ContainingCollectionView === undefined ||
-            this.props.ContainingCollectionView.active;
-    }
-
-    @computed
-    get topMost(): boolean {
-        return this.props.ContainingCollectionView == undefined || this.props.ContainingCollectionView instanceof CollectionDockingView;
-    }
-
-    onPointerDown = (e: React.PointerEvent): void => {
-        this._downX = e.clientX;
-        this._downY = e.clientY;
-        var me = this;
-        if (e.shiftKey && e.buttons === 1) {
-            CollectionDockingView.StartOtherDrag(this._mainCont.current!, this.props.Document);
-            e.stopPropagation();
-            return;
-        }
-        this._contextMenuCanOpen = e.button == 2;
-        if (this.active && !e.isDefaultPrevented()) {
-            e.stopPropagation();
-            if (e.buttons === 2) {
-                e.preventDefault();
-            }
-            document.removeEventListener("pointermove", this.onPointerMove)
-            document.addEventListener("pointermove", this.onPointerMove);
-            document.removeEventListener("pointerup", this.onPointerUp)
-            document.addEventListener("pointerup", this.onPointerUp);
-        }
-    }
-
-    onPointerMove = (e: PointerEvent): void => {
-        if (e.cancelBubble) {
-            this._contextMenuCanOpen = false;
-            return;
-        }
-        if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) {
-            this._contextMenuCanOpen = false;
-            if (this._mainCont.current != null && !this.topMost) {
-                this._contextMenuCanOpen = false;
-                const rect = this.screenRect;
-                let dragData: { [id: string]: any } = {};
-                dragData["document"] = this;
-                dragData["xOffset"] = e.x - rect.left;
-                dragData["yOffset"] = e.y - rect.top;
-                DragManager.StartDrag(this._mainCont.current, dragData, {
-                    handlers: {
-                        dragComplete: this.dragComplete,
-                    },
-                    hideSource: true
-                })
-            }
-        }
-        e.stopPropagation();
-        e.preventDefault();
-    }
-
-    onPointerUp = (e: PointerEvent): void => {
-        document.removeEventListener("pointermove", this.onPointerMove)
-        document.removeEventListener("pointerup", this.onPointerUp)
-        e.stopPropagation();
-        if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) {
-            SelectionManager.SelectDoc(this, e.ctrlKey);
-        }
-    }
-
-    openRight = (e: React.MouseEvent): void => {
-        CollectionDockingView.AddRightSplit(this.props.Document);
-    }
-
-    deleteClicked = (e: React.MouseEvent): void => {
-        if (this.props.ContainingCollectionView instanceof CollectionFreeFormView) {
-            this.props.ContainingCollectionView.removeDocument(this.props.Document)
-        }
-    }
-    @action
-    fullScreenClicked = (e: React.MouseEvent): void => {
-        CollectionDockingView.OpenFullScreen(this.props.Document);
-        ContextMenu.Instance.clearItems();
-        ContextMenu.Instance.addItem({ description: "Close Full Screen", event: this.closeFullScreenClicked });
-        ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
-    }
-    @action
-    closeFullScreenClicked = (e: React.MouseEvent): void => {
-        CollectionDockingView.CloseFullScreen();
-        ContextMenu.Instance.clearItems();
-        ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked })
-        ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
-    }
-
-    @action
-    onContextMenu = (e: React.MouseEvent): void => {
-        if (!SelectionManager.IsSelected(this)) {
-            return;
-        }
-        e.preventDefault()
-
-        if (!this._contextMenuCanOpen) {
-            return;
-        }
-
-        if (this.topMost) {
-            ContextMenu.Instance.clearItems()
-            ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked })
-            ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
-        }
-        else {
-            // DocumentViews should stop propogation of this event
-            e.stopPropagation();
-
-            ContextMenu.Instance.clearItems();
-            ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked })
-            ContextMenu.Instance.addItem({ description: "Open Right", event: this.openRight })
-            ContextMenu.Instance.addItem({ description: "Delete", event: this.deleteClicked })
-            ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
-            SelectionManager.SelectDoc(this, e.ctrlKey);
-        }
-    }
 
     getTransform = (): Transform => {
         return this.props.GetTransform().translated(this.x, this.y);
@@ -234,11 +107,10 @@ export class CollectionFreeFormDocumentView extends DocumentView {
                 height: freestyling ? this.height : "100%",
                 position: freestyling ? "absolute" : "relative",
                 zIndex: freestyling ? this.zIndex : 0,
-            }}
-                onContextMenu={this.onContextMenu}
-                onPointerDown={this.onPointerDown}>
+                backgroundColor: "transparent"
+            }} >
 
-                <DocumentView {...this.props} Scaling={this.width / this.nativeWidth} GetTransform={this.getTransform} DocumentView={this} />
+                <DocumentView {...this.props} Scaling={this.width / this.nativeWidth} GetTransform={this.getTransform} />
             </div>
         );
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index d7ecc6d9d..cb080c08e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -16,6 +16,9 @@ import { ImageBox } from "../nodes/ImageBox";
 import "./NodeView.scss";
 import React = require("react");
 import { Transform } from "../../util/Transform";
+import { SelectionManager } from "../../util/SelectionManager";
+import { DragManager } from "../../util/DragManager";
+import { ContextMenu } from "../ContextMenu";
 const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this?
 
 export interface DocumentViewProps {
@@ -26,24 +29,34 @@ export interface DocumentViewProps {
     AddDocument?: (doc: Document) => void;
     RemoveDocument?: (doc: Document) => boolean;
     GetTransform: () => Transform;
+    isTopMost: boolean;
     Scaling: number;
 }
 
 @observer
 export class DocumentView extends React.Component<DocumentViewProps> {
 
-    protected _mainCont = React.createRef<any>();
+    private _mainCont = React.createRef<HTMLDivElement>();
     get MainContent() {
         return this._mainCont;
     }
+    get screenRect(): ClientRect | DOMRect {
+        if (this._mainCont.current) {
+            return this._mainCont.current.getBoundingClientRect();
+        }
+        return new DOMRect();
+    }
     @computed
     get layout(): string {
         return this.props.Document.GetData(KeyStore.Layout, TextField, String("<p>Error loading layout data</p>"));
     }
 
     @computed
-    get backgroundLayout(): string {
-        return this.props.Document.GetData(KeyStore.BackgroundLayout, TextField, String("<p>Error loading layout data</p>"));
+    get backgroundLayout(): string | undefined {
+        let field = this.props.Document.GetT(KeyStore.BackgroundLayout, TextField);
+        if (field && field !== "<Waiting>") {
+            return field.Data;
+        }
     }
 
     @computed
@@ -56,6 +69,134 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array<Key>());
     }
 
+    @computed
+    get active(): boolean {
+        return SelectionManager.IsSelected(this) || this.props.ContainingCollectionView === undefined ||
+            this.props.ContainingCollectionView.active;
+    }
+
+    private _contextMenuCanOpen = false;
+    private _downX: number = 0;
+    private _downY: number = 0;
+    onPointerDown = (e: React.PointerEvent): void => {
+        this._downX = e.clientX;
+        this._downY = e.clientY;
+        var me = this;
+        if (e.shiftKey && e.buttons === 1) {
+            CollectionDockingView.StartOtherDrag(this._mainCont.current!, this.props.Document);
+            e.stopPropagation();
+            return;
+        }
+        this._contextMenuCanOpen = e.button == 2;
+        if (this.active && !e.isDefaultPrevented()) {
+            e.stopPropagation();
+            if (e.buttons === 2) {
+                e.preventDefault();
+            }
+            document.removeEventListener("pointermove", this.onPointerMove)
+            document.addEventListener("pointermove", this.onPointerMove);
+            document.removeEventListener("pointerup", this.onPointerUp)
+            document.addEventListener("pointerup", this.onPointerUp);
+        }
+    }
+
+    @action
+    dragComplete = (e: DragManager.DragCompleteEvent) => {
+    }
+
+    @computed
+    get topMost(): boolean {
+        return this.props.ContainingCollectionView == undefined || this.props.ContainingCollectionView instanceof CollectionDockingView;
+    }
+
+    onPointerMove = (e: PointerEvent): void => {
+        if (e.cancelBubble) {
+            this._contextMenuCanOpen = false;
+            return;
+        }
+        if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) {
+            this._contextMenuCanOpen = false;
+            if (this._mainCont.current != null && !this.topMost) {
+                this._contextMenuCanOpen = false;
+                const [left, top] = this.props.GetTransform().inverse().transformPoint(0, 0);
+                let dragData: { [id: string]: any } = {};
+                dragData["document"] = this;
+                dragData["xOffset"] = e.x - left;
+                dragData["yOffset"] = e.y - top;
+                DragManager.StartDrag(this._mainCont.current, dragData, {
+                    handlers: {
+                        dragComplete: this.dragComplete,
+                    },
+                    hideSource: true
+                })
+            }
+        }
+        e.stopPropagation();
+        e.preventDefault();
+    }
+
+    onPointerUp = (e: PointerEvent): void => {
+        document.removeEventListener("pointermove", this.onPointerMove)
+        document.removeEventListener("pointerup", this.onPointerUp)
+        e.stopPropagation();
+        if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) {
+            SelectionManager.SelectDoc(this, e.ctrlKey);
+        }
+    }
+
+    openRight = (e: React.MouseEvent): void => {
+        CollectionDockingView.AddRightSplit(this.props.Document);
+    }
+
+    deleteClicked = (e: React.MouseEvent): void => {
+        if (this.props.RemoveDocument) {
+            this.props.RemoveDocument(this.props.Document);
+        }
+    }
+    @action
+    fullScreenClicked = (e: React.MouseEvent): void => {
+        CollectionDockingView.OpenFullScreen(this.props.Document);
+        ContextMenu.Instance.clearItems();
+        ContextMenu.Instance.addItem({ description: "Close Full Screen", event: this.closeFullScreenClicked });
+        ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
+    }
+    @action
+    closeFullScreenClicked = (e: React.MouseEvent): void => {
+        CollectionDockingView.CloseFullScreen();
+        ContextMenu.Instance.clearItems();
+        ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked })
+        ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
+    }
+
+    @action
+    onContextMenu = (e: React.MouseEvent): void => {
+        if (!SelectionManager.IsSelected(this)) {
+            return;
+        }
+        e.preventDefault()
+
+        if (!this._contextMenuCanOpen) {
+            return;
+        }
+
+        if (this.topMost) {
+            ContextMenu.Instance.clearItems()
+            ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked })
+            ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
+        }
+        else {
+            // DocumentViews should stop propogation of this event
+            e.stopPropagation();
+
+            ContextMenu.Instance.clearItems();
+            ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked })
+            ContextMenu.Instance.addItem({ description: "Open Right", event: this.openRight })
+            ContextMenu.Instance.addItem({ description: "Delete", event: this.deleteClicked })
+            ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
+            SelectionManager.SelectDoc(this, e.ctrlKey);
+        }
+    }
+
     // 
     // returns the cumulative scaling between the document and the screen
     //
@@ -69,9 +210,19 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         return 1;
     }
 
+    isSelected = () => {
+        return SelectionManager.IsSelected(this);
+    }
+
+    select = (ctrlPressed: boolean) => {
+        SelectionManager.SelectDoc(this, ctrlPressed)
+    }
+
 
     render() {
         let bindings = { ...this.props } as any;
+        bindings.isSelected = this.isSelected;
+        bindings.select = this.select;
         for (const key of this.layoutKeys) {
             bindings[key.Name + "Key"] = key;  // this maps string values of the form <keyname>Key to an actual key Kestore.keyname  e.g,   "DataKey" => KeyStore.Data
         }
@@ -82,26 +233,29 @@ export class DocumentView extends React.Component<DocumentViewProps> {
             let field = this.props.Document.Get(key);
             bindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field;
         }
-        if (bindings.DocumentView === undefined) {
-            bindings.DocumentView = this; // set the DocumentView to this if it hasn't already been set by a sub-class during its render method.
+        let annotated = null;
+        let backgroundLayout = this.backgroundLayout;
+        if (backgroundLayout) {
+            annotated = <JsxParser
+                components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
+                bindings={bindings}
+                jsx={this.backgroundLayout}
+                showWarnings={true}
+                onError={(test: any) => { console.log(test) }}
+            />;
         }
-        var annotated = <JsxParser
-            components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
-            bindings={bindings}
-            jsx={this.backgroundLayout}
-            showWarnings={true}
-            onError={(test: any) => { console.log(test) }}
-        />;
-        bindings["BackgroundView"] = this.backgroundLayout ? annotated : null;
+        bindings.BackgroundView = annotated;
 
         var width = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
         var strwidth = width > 0 ? width.toString() + "px" : "100%";
         var height = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
         var strheight = height > 0 ? height.toString() + "px" : "100%";
         return (
-            <div className="node" ref={this._mainCont} style={{ width: strwidth, height: strheight, transformOrigin: "left top", transform: `scale(${this.props.Scaling},${this.props.Scaling})` }}>
+            <div className="node" ref={this._mainCont} style={{ width: strwidth, height: strheight, transformOrigin: "left top", transform: `scale(${this.props.Scaling},${this.props.Scaling})` }}
+                onContextMenu={this.onContextMenu}
+                onPointerDown={this.onPointerDown} >
                 <JsxParser
-                    components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
+                    components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
                     bindings={bindings}
                     jsx={this.layout}
                     showWarnings={true}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 12371eb2e..08de53e1c 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -10,7 +10,6 @@ import { ImageField } from "../../../fields/ImageField";
 import { Key } from "../../../fields/Key";
 import { FormattedTextBox } from "./FormattedTextBox";
 import { ImageBox } from "./ImageBox";
-import { DocumentView } from "./DocumentView";
 
 //
 // these properties get assigned through the render() method of the DocumentView when it creates this node.
@@ -20,12 +19,13 @@ import { DocumentView } from "./DocumentView";
 export interface FieldViewProps {
     fieldKey: Key;
     doc: Document;
-    DocumentViewForField: Opt<DocumentView>
+    isSelected: () => boolean;
+    isTopMost: boolean;
 }
 
 @observer
 export class FieldView extends React.Component<FieldViewProps> {
-    public static LayoutString(fieldType: string) { return `<${fieldType} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} />`; }
+    public static LayoutString(fieldType: string) { return `<${fieldType} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} isSelected={isSelected} isTopMost={isTopMost} />`; }
     @computed
     get field(): FieldValue<Field> {
         const { doc, fieldKey } = this.props;
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index f6bd0c0f8..2e3d396c1 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -110,7 +110,7 @@ export class FormattedTextBox extends React.Component<FieldViewProps> {
     }
     onPointerDown = (e: React.PointerEvent): void => {
         let me = this;
-        if (e.buttons === 1 && me.props.DocumentViewForField instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(me.props.DocumentViewForField)) {
+        if (e.buttons === 1 && this.props.isSelected()) {
             e.stopPropagation();
         }
     }
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 2fa70734d..e1fa26e2f 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -41,7 +41,7 @@ export class ImageBox extends React.Component<FieldViewProps> {
 
     onPointerDown = (e: React.PointerEvent): void => {
         if (Date.now() - this._lastTap < 300) {
-            if (e.buttons === 1 && this.props.DocumentViewForField instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.DocumentViewForField)) {
+            if (e.buttons === 1 && this.props.isSelected()) {
                 e.stopPropagation();
                 this._downX = e.clientX;
                 this._downY = e.clientY;
@@ -63,7 +63,7 @@ export class ImageBox extends React.Component<FieldViewProps> {
 
     lightbox = (path: string) => {
         const images = [path, "http://www.cs.brown.edu/~bcz/face.gif"];
-        if (this._isOpen && this.props.DocumentViewForField instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.DocumentViewForField)) {
+        if (this._isOpen && this.props.isSelected()) {
             return (<Lightbox
                 mainSrc={images[this._photoIndex]}
                 nextSrc={images[(this._photoIndex + 1) % images.length]}
-- 
cgit v1.2.3-70-g09d2


From 4ae8e7791d217a04a913caa75c8e276a50608865 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Mon, 18 Feb 2019 01:45:19 -0500
Subject: Fixed up a bunch of tranform stuff

---
 src/client/util/Transform.ts                              |  8 ++++----
 src/client/views/DocumentDecorations.tsx                  |  2 +-
 src/client/views/Main.tsx                                 |  2 +-
 src/client/views/collections/CollectionDockingView.tsx    |  6 +++---
 src/client/views/collections/CollectionFreeFormView.tsx   | 15 ++++++---------
 src/client/views/collections/CollectionSchemaView.tsx     |  2 +-
 src/client/views/collections/CollectionViewBase.tsx       |  4 ++--
 src/client/views/nodes/CollectionFreeFormDocumentView.tsx |  4 ++--
 src/client/views/nodes/DocumentView.tsx                   |  7 ++-----
 9 files changed, 22 insertions(+), 28 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/util/Transform.ts b/src/client/util/Transform.ts
index 8ae3f837f..9fd4f7bef 100644
--- a/src/client/util/Transform.ts
+++ b/src/client/util/Transform.ts
@@ -38,8 +38,8 @@ export class Transform {
     }
 
     transform = (transform: Transform): Transform => {
-        this._translateX += transform._translateX * this._scale;
-        this._translateY += transform._translateY * this._scale;
+        this._translateX = transform._translateX + transform._scale * this._translateX;
+        this._translateY = transform._translateY + transform._scale * this._translateY;
         this._scale *= transform._scale;
         return this;
     }
@@ -56,8 +56,8 @@ export class Transform {
     }
 
     preTransform = (transform: Transform): Transform => {
-        this._translateX = transform._translateX + this._translateX * transform._scale;
-        this._translateY = transform._translateY + this._translateY * transform._scale;
+        this._translateX += transform._translateX * this._scale;
+        this._translateY += transform._translateY * this._scale;
         this._scale *= transform._scale;
         return this;
     }
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 23c952ef4..d385bcdef 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -27,7 +27,7 @@ export class DocumentDecorations extends React.Component {
                 !(element.props.ContainingCollectionView instanceof CollectionFreeFormView)) {
                 return bounds;
             }
-            let transform = element.props.GetTransform().inverse();
+            let transform = element.props.ScreenToLocalTransform().inverse();
             var [sptX, sptY] = transform.transformPoint(0, 0);
             // var [bptX, bptY] = transform.transformDirection(element.width, element.height);
             let doc = element.props.Document;
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 52f4962f7..1eeec7ff5 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -83,7 +83,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) {
 ReactDOM.render((
     <div style={{ position: "absolute", width: "100%", height: "100%" }}>
         <DocumentView Document={mainContainer}
-            AddDocument={undefined} RemoveDocument={undefined} GetTransform={() => Transform.Identity}
+            AddDocument={undefined} RemoveDocument={undefined} ScreenToLocalTransform={() => Transform.Identity}
             Scaling={1}
             isTopMost={true}
             ContainingCollectionView={undefined} DocumentView={undefined} />
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index adfcb96ee..1c1f6f8b4 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -98,7 +98,7 @@ export class CollectionDockingView extends CollectionViewBase {
             if (value[i].Id === component) {
                 return (<DocumentView key={value[i].Id} Document={value[i]}
                     AddDocument={this.addDocument} RemoveDocument={this.removeDocument}
-                    GetTransform={() => Transform.Identity}
+                    ScreenToLocalTransform={() => Transform.Identity}
                     isTopMost={true}
                     Scaling={1}
                     ContainingCollectionView={this} DocumentView={undefined} />);
@@ -309,9 +309,9 @@ export class RenderClass extends React.Component<DockingProps> {
                 AddDocument={this.props.CollectionDockingView.addDocument}
                 RemoveDocument={this.props.CollectionDockingView.removeDocument}
                 Scaling={this._parentScaling}
-                GetTransform={() => {
+                ScreenToLocalTransform={() => {
                     let { scale, translateX, translateY } = Utils.GetScreenTransform(this.props.HtmlElement);
-                    return this.props.CollectionDockingView.props.GetTransform().scale(scale).translate(translateX, translateY)
+                    return this.props.CollectionDockingView.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(scale)
                 }}
                 isTopMost={true}
                 ContainingCollectionView={this.props.CollectionDockingView} DocumentView={undefined} />
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 49864ca6c..f0cf7f0ca 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -55,9 +55,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
         const xOffset = de.data["xOffset"] as number || 0;
         const yOffset = de.data["yOffset"] as number || 0;
         //this should be able to use translate and scale methods on an Identity transform, no?
-        const transform = new Transform(0, 0, 1 / me.props.DocumentForCollection.GetNumber(KeyStore.Scale, 1)).transform(
-            new Transform(-me.props.DocumentForCollection.GetNumber(KeyStore.PanX, 0), -me.props.DocumentForCollection.GetNumber(KeyStore.PanY, 0), 1)
-        ).transform(me.props.GetTransform());
+        const transform = me.getTransform();
         const screenX = de.x - xOffset;
         const screenY = de.y - yOffset;
         const [x, y] = transform.transformPoint(screenX, screenY);
@@ -109,7 +107,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
             e.stopPropagation();
             let x = this.props.DocumentForCollection.GetNumber(KeyStore.PanX, 0);
             let y = this.props.DocumentForCollection.GetNumber(KeyStore.PanY, 0);
-            let [dx, dy] = this.props.GetTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
+            let [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
 
             this.SetPan(x + dx, y + dy);
         }
@@ -131,7 +129,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
         let [x, y] = transform.transformPoint(e.clientX, e.clientY);
 
         let localTransform = this.getLocalTransform();
-        localTransform.scaleAbout(deltaScale, x, y);
+        localTransform = localTransform.inverse().scaleAbout(deltaScale, x, y)
 
         this.props.DocumentForCollection.SetNumber(KeyStore.Scale, localTransform.Scale);
         this.SetPan(localTransform.TranslateX, localTransform.TranslateY);
@@ -213,13 +211,12 @@ export class CollectionFreeFormView extends CollectionViewBase {
     }
 
     getTransform = (): Transform => {
-        const [x, y] = this.translate;
-        return this.getLocalTransform().inverse().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).transform(this.props.GetTransform())
+        return this.props.ScreenToLocalTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).transform(this.getLocalTransform())
     }
 
     getLocalTransform = (): Transform => {
         const [x, y] = this.translate;
-        return Transform.Identity.scale(this.scale).translate(x, y);
+        return Transform.Identity.translate(-x, -y).scale(1 / this.scale);
     }
 
     render() {
@@ -249,7 +246,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
                         return (<CollectionFreeFormDocumentView key={doc.Id} Document={doc}
                             AddDocument={this.addDocument}
                             RemoveDocument={this.removeDocument}
-                            GetTransform={this.getTransform}
+                            ScreenToLocalTransform={this.getTransform}
                             isTopMost={false}
                             Scaling={1}
                             ContainingCollectionView={this} DocumentView={this.props.ContainingDocumentView} />);
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 21780bdb3..9a0ce0782 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -123,7 +123,7 @@ export class CollectionSchemaView extends CollectionViewBase {
                         <div ref={measureRef}>
                             <DocumentView Document={children[this.selectedIndex]}
                                 AddDocument={this.addDocument} RemoveDocument={this.removeDocument}
-                                GetTransform={() => Transform.Identity}//TODO This should probably be an actual transform
+                                ScreenToLocalTransform={() => Transform.Identity}//TODO This should probably be an actual transform
                                 Scaling={this._parentScaling}
                                 isTopMost={false}
                                 DocumentView={undefined} ContainingCollectionView={me} />
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index aae85b3f9..a8dceff0a 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -17,7 +17,7 @@ export interface CollectionViewProps {
     CollectionFieldKey: Key;
     DocumentForCollection: Document;
     ContainingDocumentView: Opt<DocumentView>;
-    GetTransform: () => Transform;
+    ScreenToLocalTransform: () => Transform;
     isSelected: () => boolean;
     isTopMost: boolean;
     select: (ctrlPressed: boolean) => void;
@@ -32,7 +32,7 @@ export class CollectionViewBase extends React.Component<CollectionViewProps> {
 
     public static LayoutString(collectionType: string, fieldKey: string = "DataKey") {
         return `<${collectionType} Scaling={Scaling} DocumentForCollection={Document}
-                    GetTransform={GetTransform} CollectionFieldKey={${fieldKey}} isSelected={isSelected} select={select}
+                    ScreenToLocalTransform={ScreenToLocalTransform} CollectionFieldKey={${fieldKey}} isSelected={isSelected} select={select}
                     isTopMost={isTopMost}
                     ContainingDocumentView={DocumentView} BackgroundView={BackgroundView} />`;
     }
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 31509d3ba..57527076b 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -76,7 +76,7 @@ export class CollectionFreeFormDocumentView extends React.Component<DocumentView
 
 
     getTransform = (): Transform => {
-        return this.props.GetTransform().translated(this.props.Document.GetNumber(KeyStore.X, 0), this.props.Document.GetNumber(KeyStore.Y, 0));
+        return this.props.ScreenToLocalTransform().translate(-this.props.Document.GetNumber(KeyStore.X, 0), -this.props.Document.GetNumber(KeyStore.Y, 0));
     }
 
     render() {
@@ -92,7 +92,7 @@ export class CollectionFreeFormDocumentView extends React.Component<DocumentView
                 backgroundColor: "transparent"
             }} >
 
-                <DocumentView {...this.props} Scaling={this.width / this.nativeWidth} GetTransform={this.getTransform} />
+                <DocumentView {...this.props} Scaling={this.width / this.nativeWidth} ScreenToLocalTransform={this.getTransform} />
             </div>
         );
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 1db982f87..b25a29ad0 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -27,7 +27,7 @@ export interface DocumentViewProps {
     Document: Document;
     AddDocument?: (doc: Document) => void;
     RemoveDocument?: (doc: Document) => boolean;
-    GetTransform: () => Transform;
+    ScreenToLocalTransform: () => Transform;
     isTopMost: boolean;
     Scaling: number;
 }
@@ -117,7 +117,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
             this._contextMenuCanOpen = false;
             if (this._mainCont.current != null && !this.topMost) {
                 this._contextMenuCanOpen = false;
-                const [left, top] = this.props.GetTransform().inverse().transformPoint(0, 0);
+                const [left, top] = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
                 let dragData: { [id: string]: any } = {};
                 dragData["document"] = this;
                 dragData["xOffset"] = e.x - left;
@@ -224,9 +224,6 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         for (const key of this.layoutKeys) {
             bindings[key.Name + "Key"] = key;  // this maps string values of the form <keyname>Key to an actual key Kestore.keyname  e.g,   "DataKey" => KeyStore.Data
         }
-        if (!bindings.GetTransform) {
-            console.log("test");
-        }
         for (const key of this.layoutFields) {
             let field = this.props.Document.Get(key);
             bindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field;
-- 
cgit v1.2.3-70-g09d2


From 98f5f8200ad98f93f14eb97af9fdc6619dabe442 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Tue, 19 Feb 2019 06:25:29 -0500
Subject: Fixed bug with resizing

---
 src/client/views/DocumentDecorations.tsx | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 62a1899bb..48f5f01a1 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -127,16 +127,14 @@ export class DocumentDecorations extends React.Component {
                 let width = doc.GetOrCreate(KeyStore.Width, NumberField);
                 let height = doc.GetOrCreate(KeyStore.Height, NumberField);
                 let x = doc.GetOrCreate(KeyStore.X, NumberField);
-                let y = doc.GetOrCreate(KeyStore.X, NumberField);
+                let y = doc.GetOrCreate(KeyStore.Y, NumberField);
                 let scale = width.Data / rect.width;
                 let actualdW = Math.max(width.Data + (dW * scale), 20);
                 let actualdH = Math.max(height.Data + (dH * scale), 20);
                 x.Data += dX * (actualdW - width.Data);
                 y.Data += dY * (actualdH - height.Data);
-                if (Math.abs(dW) > Math.abs(dH))
-                    width.Data = actualdW;
-                else
-                    height.Data = actualdH;
+                width.Data = actualdW;
+                height.Data = actualdH;
             }
         })
     }
-- 
cgit v1.2.3-70-g09d2


From 61c8c4baa4ead8be64b9f902075a0f3022aaef9e Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 19 Feb 2019 17:15:59 -0500
Subject: clean up and aspect resizing w/ doc dec.

---
 src/client/views/DocumentDecorations.tsx              | 19 ++++++++-----------
 .../views/collections/CollectionDockingView.tsx       | 12 +++++++-----
 2 files changed, 15 insertions(+), 16 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 48f5f01a1..7985b77dd 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -111,17 +111,6 @@ export class DocumentDecorations extends React.Component {
 
         SelectionManager.SelectedDocuments().forEach(element => {
             const rect = element.screenRect;
-            // if (rect.width !== 0) {
-            //     let scale = element.width / rect.width;
-            //     let actualdW = Math.max(element.width + (dW * scale), 20);
-            //     let actualdH = Math.max(element.height + (dH * scale), 20);
-            //     element.x += dX * (actualdW - element.width);
-            //     element.y += dY * (actualdH - element.height);
-            //     if (Math.abs(dW) > Math.abs(dH))
-            //         element.width = actualdW;
-            //     else
-            //         element.height = actualdH;
-            // }
             if (rect.width !== 0) {
                 let doc = element.props.Document;
                 let width = doc.GetOrCreate(KeyStore.Width, NumberField);
@@ -133,6 +122,14 @@ export class DocumentDecorations extends React.Component {
                 let actualdH = Math.max(height.Data + (dH * scale), 20);
                 x.Data += dX * (actualdW - width.Data);
                 y.Data += dY * (actualdH - height.Data);
+                var nativeWidth = doc.GetNumber(KeyStore.NativeWidth, 0);
+                var nativeHeight = doc.GetNumber(KeyStore.NativeHeight, 0);
+                if (nativeWidth > 0 && nativeHeight > 0) {
+                    if (Math.abs(dW) > Math.abs(dH))
+                        actualdH = nativeHeight / nativeWidth * actualdW;
+                    else
+                        actualdW = nativeWidth / nativeHeight * actualdH;
+                }
                 width.Data = actualdW;
                 height.Data = actualdH;
             }
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 9c396e412..842312faa 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -98,7 +98,6 @@ export class CollectionDockingView extends CollectionViewBase {
 
         if (this._goldenLayout.root.contentItems[0].isRow) {
             this._goldenLayout.root.contentItems[0].addChild(newContentItem);
-            collayout.callDownwards('setSize');
         }
         else {
             var collayout = this._goldenLayout.root.contentItems[0];
@@ -110,7 +109,6 @@ export class CollectionDockingView extends CollectionViewBase {
 
             collayout.config["width"] = 50;
             newContentItem.config["width"] = 50;
-            collayout.parent.callDownwards('setSize');
         }
         this._forceRecreate = true;
     }
@@ -227,12 +225,16 @@ interface DockedFrameProps {
 @observer
 export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
 
-    private _mainCont = React.createRef<HTMLDivElement>();
+    _mainCont: any = null;
     constructor(props: any) {
         super(props);
         Server.GetField(this.props.documentId, (f) => { this.Document = f as Document; })
     }
 
+    setMainCont: any = (element: any) => {
+        this._mainCont = element;
+    }
+
     @observable
     private _parentScaling = 1; // used to transfer the dimensions of the content pane in the DOM to the ParentScaling prop of the DocumentView
 
@@ -245,13 +247,13 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         let nativeWidth = this.Document.GetNumber(KeyStore.NativeWidth, 0);
         var layout = this.Document.GetText(KeyStore.Layout, "");
         var content =
-            <div ref={this._mainCont}>
+            <div ref={this.setMainCont}>
                 <DocumentView key={this.Document.Id} Document={this.Document}
                     AddDocument={undefined}
                     RemoveDocument={undefined}
                     Scaling={this._parentScaling}
                     ScreenToLocalTransform={() => {
-                        let { scale, translateX, translateY } = Utils.GetScreenTransform(this._mainCont.current!);
+                        let { scale, translateX, translateY } = Utils.GetScreenTransform(this._mainCont);
                         var props = CollectionDockingView.Instance.props;
                         return props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(scale / this._parentScaling)
                     }}
-- 
cgit v1.2.3-70-g09d2


From 7b1062ad66c075b411025f31af8820049e53f3a4 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Tue, 19 Feb 2019 20:47:39 -0500
Subject: fixed doc decs so they don't appear on topmost collections

---
 src/client/views/DocumentDecorations.tsx                | 3 +--
 src/client/views/collections/CollectionFreeFormView.tsx | 3 +--
 src/client/views/nodes/DocumentView.tsx                 | 4 ++--
 3 files changed, 4 insertions(+), 6 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 7985b77dd..770433e27 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -23,8 +23,7 @@ export class DocumentDecorations extends React.Component {
     @computed
     get Bounds(): { x: number, y: number, b: number, r: number } {
         return SelectionManager.SelectedDocuments().reduce((bounds, element) => {
-            if (element.props.ContainingCollectionView != undefined &&
-                !(element.props.ContainingCollectionView instanceof CollectionFreeFormView)) {
+            if (element.props.isTopMost) {
                 return bounds;
             }
             let transform = element.props.ScreenToLocalTransform().inverse();
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 1f15069fd..ce480acd1 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -40,7 +40,6 @@ export class CollectionFreeFormView extends CollectionViewBase {
     @action
     drop = (e: Event, de: DragManager.DropEvent) => {
         const doc: DocumentView = de.data["document"];
-        var me = this;
         if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this) {
             doc.props.ContainingCollectionView.removeDocument(doc.props.Document);
             this.addDocument(doc.props.Document);
@@ -48,7 +47,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
         const xOffset = de.data["xOffset"] as number || 0;
         const yOffset = de.data["yOffset"] as number || 0;
         //this should be able to use translate and scale methods on an Identity transform, no?
-        const transform = me.getTransform();
+        const transform = this.getTransform();
         const screenX = de.x - xOffset;
         const screenY = de.y - yOffset;
         const [x, y] = transform.transformPoint(screenX, screenY);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 518add0fc..97bcdd333 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -112,7 +112,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
 
     @computed
     get active(): boolean {
-        return SelectionManager.IsSelected(this) || this.props.ContainingCollectionView === undefined ||
+        return SelectionManager.IsSelected(this) || !this.props.ContainingCollectionView ||
             this.props.ContainingCollectionView.active;
     }
 
@@ -146,7 +146,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
 
     @computed
     get topMost(): boolean {
-        return this.props.ContainingCollectionView == undefined || this.props.ContainingCollectionView instanceof CollectionDockingView;
+        return !this.props.ContainingCollectionView || this.props.ContainingCollectionView instanceof CollectionDockingView;
     }
 
     onPointerMove = (e: PointerEvent): void => {
-- 
cgit v1.2.3-70-g09d2


From dd4aa3e6595aba8f421aed7fdcc663c051b509a8 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 20 Feb 2019 10:55:30 -0500
Subject: fixed dragdrop issue.  improved selection in schema views, but not
 fixed fully.

---
 src/client/util/DragManager.ts                     |   6 +-
 src/client/views/DocumentDecorations.tsx           |  19 ++--
 .../views/collections/CollectionSchemaView.tsx     | 110 ++++++++++-----------
 3 files changed, 62 insertions(+), 73 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 337ec855a..6d5fe12a7 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,3 +1,4 @@
+import { DocumentDecorations } from "../views/DocumentDecorations";
 
 export namespace DragManager {
     export function Root() {
@@ -59,10 +60,8 @@ export namespace DragManager {
         };
     }
 
-
-    let _lastPointerX: number = 0;
-    let _lastPointerY: number = 0;
     export function StartDrag(ele: HTMLElement, dragData: { [id: string]: any }, options: DragOptions) {
+        DocumentDecorations.Instance.Hidden = true;
         if (!dragDiv) {
             dragDiv = document.createElement("div");
             DragManager.Root().appendChild(dragDiv);
@@ -131,5 +130,6 @@ export namespace DragManager {
             }
         }));
         options.handlers.dragComplete({});
+        DocumentDecorations.Instance.Hidden = false;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 770433e27..dccab1dc5 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -1,9 +1,8 @@
-import { observable, computed } from "mobx";
+import { observable, computed, action } from "mobx";
 import React = require("react");
 import { SelectionManager } from "../util/SelectionManager";
 import { observer } from "mobx-react";
 import './DocumentDecorations.scss'
-import { CollectionFreeFormView } from "./collections/CollectionFreeFormView";
 import { KeyStore } from '../../fields/KeyStore'
 import { NumberField } from "../../fields/NumberField";
 
@@ -12,7 +11,7 @@ export class DocumentDecorations extends React.Component {
     static Instance: DocumentDecorations
     private _resizer = ""
     private _isPointerDown = false;
-    @observable private _opacity = 1;
+    @observable private _hidden = false;
 
     constructor(props: Readonly<{}>) {
         super(props)
@@ -39,14 +38,10 @@ export class DocumentDecorations extends React.Component {
         }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE });
     }
 
-    @computed
-    get opacity(): number {
-        return this._opacity
-    }
 
-    set opacity(o: number) {
-        this._opacity = Math.min(Math.max(0, o), 1)
-    }
+    @computed
+    public get Hidden() { return this._hidden; }
+    public set Hidden(value: boolean) { this._hidden = value; }
 
     onPointerDown = (e: React.PointerEvent): void => {
         e.stopPropagation();
@@ -147,13 +142,15 @@ export class DocumentDecorations extends React.Component {
 
     render() {
         var bounds = this.Bounds;
+        if (this.Hidden) {
+            return (null);
+        }
         return (
             <div id="documentDecorations-container" style={{
                 width: (bounds.r - bounds.x + 40) + "px",
                 height: (bounds.b - bounds.y + 40) + "px",
                 left: bounds.x - 20,
                 top: bounds.y - 20,
-                opacity: this.opacity
             }}>
                 <div id="documentDecorations-topLeftResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
                 <div id="documentDecorations-topResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 597a97222..fa37e0e76 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -2,7 +2,6 @@ import React = require("react")
 import { action, observable } from "mobx";
 import { observer } from "mobx-react";
 import Measure from "react-measure";
-import SplitPane from "react-split-pane";
 import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
 import "react-table/react-table.css";
 import { Document } from "../../../fields/Document";
@@ -15,7 +14,6 @@ import { DocumentView } from "../nodes/DocumentView";
 import { FieldView, FieldViewProps } from "../nodes/FieldView";
 import "./CollectionSchemaView.scss";
 import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase";
-import { relative } from "path";
 
 @observer
 export class CollectionSchemaView extends CollectionViewBase {
@@ -67,6 +65,7 @@ export class CollectionSchemaView extends CollectionViewBase {
         )
     }
 
+
     private getTrProps: ComponentPropsGetterR = (state, rowInfo) => {
         const that = this;
         if (!rowInfo) {
@@ -75,8 +74,7 @@ export class CollectionSchemaView extends CollectionViewBase {
         return {
             onClick: action((e: React.MouseEvent, handleOriginal: Function) => {
                 that.selectedIndex = rowInfo.index;
-                const doc: Document = rowInfo.original;
-                console.log("Row clicked: ", doc.Title)
+                this._splitPercentage += 0.05; // bcz - ugh - needed to force Measure to do its thing and call onResize
 
                 if (handleOriginal) {
                     handleOriginal()
@@ -118,70 +116,64 @@ export class CollectionSchemaView extends CollectionViewBase {
         }
     }
 
+    innerScreenToLocal(tx: number, ty: number) {
+        return () => this.props.ScreenToLocalTransform().transform(new Transform(-tx - 5 - COLLECTION_BORDER_WIDTH, -ty - COLLECTION_BORDER_WIDTH, 1))
+    }
 
-    @observable
-    private _parentScaling = 1; // used to transfer the dimensions of the content pane in the DOM to the ParentScaling prop of the DocumentView
+    @observable _parentScaling = 1; // used to transfer the dimensions of the content pane in the DOM to the ParentScaling prop of the DocumentView
+    @observable _dividerX = 0;
+    @observable _dividerY = 0;
     render() {
-        const { Document: Document, fieldKey: fieldKey } = this.props;
-        const children = Document.GetList<Document>(fieldKey, []);
-        const columns = Document.GetList(KeyStore.ColumnsKey,
-            [KeyStore.Title, KeyStore.Data, KeyStore.Author])
-        let content = <div></div>
+        const columns = this.props.Document.GetList(KeyStore.ColumnsKey, [KeyStore.Title, KeyStore.Data, KeyStore.Author])
+        const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
+        const selected = children.length > this.selectedIndex ? children[this.selectedIndex] : undefined;
         let me = this;
-        if (this.selectedIndex != -1) {
-            content = (
+        let content = this.selectedIndex == -1 || !selected ? (null) : (
+            <Measure onResize={action((r: any) => this._parentScaling = r.entry.width / selected.GetNumber(KeyStore.NativeWidth, r.entry.width))}>
+                {({ measureRef }) =>
+                    <div ref={measureRef}>
+                        <DocumentView Document={selected}
+                            AddDocument={this.addDocument} RemoveDocument={this.removeDocument}
+                            ScreenToLocalTransform={this.innerScreenToLocal(me._dividerX, me._dividerY)}//TODO This should probably be an actual transform
+                            Scaling={this._parentScaling}
+                            isTopMost={false}
+                            ContainingCollectionView={me} />
+                    </div>
+                }
+            </Measure>
+        )
+        return (
+            <div onPointerDown={this.onPointerDown} ref={this._mainCont} className="collectionSchemaView-container" style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
                 <Measure onResize={action((r: any) => {
-                    var doc = children[this.selectedIndex];
-                    var n = doc.GetNumber(KeyStore.NativeWidth, 0);
-                    if (n > 0 && r.entry.width > 0) {
-                        this._parentScaling = r.entry.width / n;
-                    }
+                    this._dividerX = r.entry.width;
                 })}>
                     {({ measureRef }) =>
-                        <div ref={measureRef}>
-                            <DocumentView Document={children[this.selectedIndex]}
-                                AddDocument={this.addDocument} RemoveDocument={this.removeDocument}
-                                ScreenToLocalTransform={() => Transform.Identity}//TODO This should probably be an actual transform
-                                Scaling={this._parentScaling}
-                                isTopMost={false}
-                                ContainingCollectionView={me} />
+                        <div ref={measureRef} className="collectionSchemaView-tableContainer" style={{ position: "relative", float: "left", width: `${this._splitPercentage}%`, height: "100%" }}>
+                            <ReactTable
+                                data={children}
+                                pageSize={children.length}
+                                page={0}
+                                showPagination={false}
+                                columns={columns.map(col => {
+                                    return (
+                                        {
+                                            Header: col.Name,
+                                            accessor: (doc: Document) => [doc, col],
+                                            id: col.Id
+                                        })
+                                })}
+                                column={{
+                                    ...ReactTableDefaults.column,
+                                    Cell: this.renderCell
+                                }}
+                                getTrProps={this.getTrProps}
+                            />
                         </div>
                     }
                 </Measure>
-            )
-        }
-        let nativeWidth = Document.GetNumber(KeyStore.NativeWidth, 0);
-        return (
-            <div onPointerDown={this.onPointerDown} ref={this._mainCont} className="collectionSchemaView-container"
-                style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
-                <div className="collectionSchemaView-tableContainer" style={{ position: "relative", float: "left", width: `${this._splitPercentage}%`, height: "100%" }}>
-                    <ReactTable
-                        data={children}
-                        pageSize={children.length}
-                        page={0}
-                        showPagination={false}
-                        columns={columns.map(col => {
-                            return (
-                                {
-                                    Header: col.Name,
-                                    accessor: (doc: Document) => [doc, col],
-                                    id: col.Id
-                                })
-                        })}
-                        column={{
-                            ...ReactTableDefaults.column,
-                            Cell: this.renderCell
-                        }}
-                        getTrProps={this.getTrProps}
-                    />
-                </div>
-                <div onPointerDown={this.onDividerDown} style={{ position: "relative", background: "black", float: "left", width: "5px", height: "100%" }}>
-
-                </div>
-                <div style={{ position: "relative", float: "left", width: `calc(${100 - this._splitPercentage}% - 5px)`, height: "100%" }}>
-                    <Measure onResize={action((r: any) => this._parentScaling = nativeWidth > 0 ? r.entry.width / nativeWidth : 1)}>
-                        {({ measureRef }) => <div ref={measureRef}>  {content} </div>}
-                    </Measure>
+                <div className="collectionSchemaView-dividerDragger" style={{ position: "relative", background: "black", float: "left", width: "5px", height: "100%" }} onPointerDown={this.onDividerDown} />
+                <div className="collectionSchemaView-previewRegion" style={{ position: "relative", float: "left", width: `calc(${100 - this._splitPercentage}% - 5px)`, height: "100%" }}>
+                    {content}
                 </div>
             </div >
         )
-- 
cgit v1.2.3-70-g09d2


From 3207b098d206f4eb1a3c0f23afdd5cf072c308fb Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 20 Feb 2019 17:29:53 -0500
Subject: working, but oh so confusing transforms for selections.

---
 src/client/views/DocumentDecorations.tsx           |  8 ++--
 .../views/collections/CollectionDockingView.tsx    |  1 +
 .../views/collections/CollectionFreeFormView.tsx   |  1 +
 .../views/collections/CollectionSchemaView.tsx     | 49 +++++++++++++++++++---
 src/client/views/nodes/DocumentView.tsx            | 35 ++++++++++++----
 5 files changed, 77 insertions(+), 17 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index dccab1dc5..0aaea7ae5 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -25,11 +25,13 @@ export class DocumentDecorations extends React.Component {
             if (element.props.isTopMost) {
                 return bounds;
             }
-            let transform = element.props.ScreenToLocalTransform().inverse();
+            let transform = element.ScreenToLocalTransform().inverse();
             var [sptX, sptY] = transform.transformPoint(0, 0);
-            // var [bptX, bptY] = transform.transformDirection(element.width, element.height);
             let doc = element.props.Document;
-            let [bptX, bptY] = [doc.GetNumber(KeyStore.Width, 0), doc.GetNumber(KeyStore.Height, 0)];
+            let [bptX, bptY] = [
+                element.props.PanelSize[0] > 0 ? element.props.PanelSize[0] : doc.GetNumber(KeyStore.Width, 0),
+                element.props.PanelSize[1] > 0 ? element.props.PanelSize[1] : doc.GetNumber(KeyStore.Height, 0)
+            ];
             [bptX, bptY] = transform.transformPoint(bptX, bptY);
             return {
                 x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index ceb638ab4..fc5b8dacd 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -253,6 +253,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
                     AddDocument={undefined}
                     RemoveDocument={undefined}
                     Scaling={this._parentScaling}
+                    PanelSize={[0, 0]}
                     ScreenToLocalTransform={() => {
                         let { scale, translateX, translateY } = Utils.GetScreenTransform(this._mainCont);
                         var props = CollectionDockingView.Instance.props;
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 54757cce5..ffd4d211f 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -247,6 +247,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
                             ScreenToLocalTransform={this.getTransform}
                             isTopMost={false}
                             Scaling={1}
+                            PanelSize={[0, 0]}
                             ContainingCollectionView={this} />);
                     })}
                 </div>
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index fa37e0e76..0c7577421 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,5 +1,5 @@
 import React = require("react")
-import { action, observable } from "mobx";
+import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
 import Measure from "react-measure";
 import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
@@ -14,6 +14,7 @@ import { DocumentView } from "../nodes/DocumentView";
 import { FieldView, FieldViewProps } from "../nodes/FieldView";
 import "./CollectionSchemaView.scss";
 import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase";
+import { Z_DEFAULT_COMPRESSION } from "zlib";
 
 @observer
 export class CollectionSchemaView extends CollectionViewBase {
@@ -117,26 +118,63 @@ export class CollectionSchemaView extends CollectionViewBase {
     }
 
     innerScreenToLocal(tx: number, ty: number) {
-        return () => this.props.ScreenToLocalTransform().transform(new Transform(-tx - 5 - COLLECTION_BORDER_WIDTH, -ty - COLLECTION_BORDER_WIDTH, 1))
+        var zoom = this.props.Document.GetNumber(KeyStore.Scale, 1);
+        var xf = this.props.ScreenToLocalTransform().transform(new Transform(- 5 - COLLECTION_BORDER_WIDTH, - COLLECTION_BORDER_WIDTH, 1)).translate(-tx, -ty);
+        var center = [0, 0];
+        var sabout = new Transform(center[0] / zoom, center[1] / zoom, 1).scaled(1 / this._parentScaling).translated(-center[0] / zoom, -center[1] / zoom);
+        var total = xf.transformed(sabout);
+        return () => total
+    }
+    @computed
+    get scale(): number {
+        return this.props.Document.GetNumber(KeyStore.Scale, 1);
+    }
+    @computed
+    get translate(): [number, number] {
+        const x = this.props.Document.GetNumber(KeyStore.PanX, 0);
+        const y = this.props.Document.GetNumber(KeyStore.PanY, 0);
+        return [x, y];
+    }
+
+    getTransform = (): Transform => {
+        return this.props.ScreenToLocalTransform().translate(- COLLECTION_BORDER_WIDTH - this._dividerX - 5, - COLLECTION_BORDER_WIDTH).transform(this.getLocalTransform())
+    }
+
+    getLocalTransform = (): Transform => {
+        const [x, y] = this.translate;
+        return Transform.Identity.translate(-x, -y).scale(1 / this.scale / this._parentScaling);
+    }
+
+    @action
+    setScaling = (r: any) => {
+        var me = this;
+        const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
+        const selected = children.length > this.selectedIndex ? children[this.selectedIndex] : undefined;
+        this._panelWidth = r.entry.width;
+        if (r.entry.height)
+            this._panelHeight = r.entry.height;
+        me._parentScaling = r.entry.width / selected!.GetNumber(KeyStore.NativeWidth, r.entry.width);
     }
 
     @observable _parentScaling = 1; // used to transfer the dimensions of the content pane in the DOM to the ParentScaling prop of the DocumentView
     @observable _dividerX = 0;
-    @observable _dividerY = 0;
+    @observable _panelWidth = 0;
+    @observable _panelHeight = 0;
     render() {
         const columns = this.props.Document.GetList(KeyStore.ColumnsKey, [KeyStore.Title, KeyStore.Data, KeyStore.Author])
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
         const selected = children.length > this.selectedIndex ? children[this.selectedIndex] : undefined;
         let me = this;
         let content = this.selectedIndex == -1 || !selected ? (null) : (
-            <Measure onResize={action((r: any) => this._parentScaling = r.entry.width / selected.GetNumber(KeyStore.NativeWidth, r.entry.width))}>
+            <Measure onResize={this.setScaling}>
                 {({ measureRef }) =>
                     <div ref={measureRef}>
                         <DocumentView Document={selected}
                             AddDocument={this.addDocument} RemoveDocument={this.removeDocument}
-                            ScreenToLocalTransform={this.innerScreenToLocal(me._dividerX, me._dividerY)}//TODO This should probably be an actual transform
+                            ScreenToLocalTransform={this.getTransform}//TODO This should probably be an actual transform
                             Scaling={this._parentScaling}
                             isTopMost={false}
+                            PanelSize={[this._panelWidth, this._panelHeight]}
                             ContainingCollectionView={me} />
                     </div>
                 }
@@ -146,6 +184,7 @@ export class CollectionSchemaView extends CollectionViewBase {
             <div onPointerDown={this.onPointerDown} ref={this._mainCont} className="collectionSchemaView-container" style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
                 <Measure onResize={action((r: any) => {
                     this._dividerX = r.entry.width;
+                    this._panelHeight = r.entry.height;
                 })}>
                     {({ measureRef }) =>
                         <div ref={measureRef} className="collectionSchemaView-tableContainer" style={{ position: "relative", float: "left", width: `${this._splitPercentage}%`, height: "100%" }}>
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index e9b1d5c8a..fa39ad09a 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -31,6 +31,7 @@ export interface DocumentViewProps {
     isTopMost: boolean;
     //tfs: This shouldn't be necessary I don't think
     Scaling: number;
+    PanelSize: number[];
 }
 export interface JsxArgs extends DocumentViewProps {
     Keys: { [name: string]: Key }
@@ -245,8 +246,19 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         SelectionManager.SelectDoc(this, ctrlPressed)
     }
 
-    screenToLocalTransform = () => {
-        return this.props.ScreenToLocalTransform().transform(Transform.Identity.scale(1 / this.props.Scaling));
+    ScreenToLocalTransform = () => {
+        return this.props.PanelSize[0] ? this.backgroundScreenToLocalTransform() : this.props.ScreenToLocalTransform();
+    }
+
+    backgroundScreenToLocalTransform = () => {
+        if (this.props.PanelSize[0])
+            return this.props.ScreenToLocalTransform().scale(this.props.Scaling);
+        else return this.props.ScreenToLocalTransform().scale(1 / this.props.Scaling);
+    }
+    documentScreenToLocalTransform = () => {
+        if (this.props.PanelSize[0])
+            return this.props.ScreenToLocalTransform();
+        else return this.backgroundScreenToLocalTransform();
     }
     render() {
         if (!this.props.Document)
@@ -255,18 +267,23 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         if (!lkeys || lkeys === "<Waiting>") {
             return <p>Error loading layout keys</p>;
         }
-        let bindings = {
+        let backgroundBindings = {
             ...this.props,
-            ScreenToLocalTransform: this.screenToLocalTransform, // adds 'Scaling' to the screen to local Xf
+            ScreenToLocalTransform: this.backgroundScreenToLocalTransform, // adds 'Scaling' to the screen to local Xf
             isSelected: this.isSelected,
             select: this.select
         } as any;
         for (const key of this.layoutKeys) {
-            bindings[key.Name + "Key"] = key;  // this maps string values of the form <keyname>Key to an actual key Kestore.keyname  e.g,   "DataKey" => KeyStore.Data
+            backgroundBindings[key.Name + "Key"] = key;  // this maps string values of the form <keyname>Key to an actual key Kestore.keyname  e.g,   "DataKey" => KeyStore.Data
         }
         for (const key of this.layoutFields) {
             let field = this.props.Document.Get(key);
-            bindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field;
+            backgroundBindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field;
+        }
+
+        let documentBindings = {
+            ...backgroundBindings,
+            ScreenToLocalTransform: this.documentScreenToLocalTransform, // adds 'Scaling' to the screen to local Xf
         }
         /*
         tfs:
@@ -278,12 +295,12 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         if (backgroundLayout) {
             let backgroundView = () => (<JsxParser
                 components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
-                bindings={bindings}
+                bindings={backgroundBindings}
                 jsx={this.backgroundLayout}
                 showWarnings={true}
                 onError={(test: any) => { console.log(test) }}
             />);
-            bindings.BackgroundView = backgroundView;
+            documentBindings.BackgroundView = backgroundView;
         }
 
         var width = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
@@ -297,7 +314,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                 onPointerDown={this.onPointerDown} >
                 <JsxParser
                     components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
-                    bindings={bindings}
+                    bindings={documentBindings}
                     jsx={this.layout}
                     showWarnings={true}
                     onError={(test: any) => { console.log(test) }}
-- 
cgit v1.2.3-70-g09d2


From 22192a4ec1a1a041b7de3f69f48f5f9b4903248f Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 20 Feb 2019 19:42:24 -0500
Subject: cleaned up screen transforms at last.

---
 src/client/views/DocumentDecorations.tsx            |  9 ++-------
 .../views/collections/CollectionFreeFormView.tsx    |  2 +-
 .../views/nodes/CollectionFreeFormDocumentView.tsx  |  9 +++++++--
 src/client/views/nodes/DocumentView.tsx             | 21 +--------------------
 4 files changed, 11 insertions(+), 30 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 0aaea7ae5..4e109d475 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -25,14 +25,9 @@ export class DocumentDecorations extends React.Component {
             if (element.props.isTopMost) {
                 return bounds;
             }
-            let transform = element.ScreenToLocalTransform().inverse();
+            let transform = (element.props.ScreenToLocalTransform().scale(element.props.Scaling)).inverse();
             var [sptX, sptY] = transform.transformPoint(0, 0);
-            let doc = element.props.Document;
-            let [bptX, bptY] = [
-                element.props.PanelSize[0] > 0 ? element.props.PanelSize[0] : doc.GetNumber(KeyStore.Width, 0),
-                element.props.PanelSize[1] > 0 ? element.props.PanelSize[1] : doc.GetNumber(KeyStore.Height, 0)
-            ];
-            [bptX, bptY] = transform.transformPoint(bptX, bptY);
+            let [bptX, bptY] = transform.transformPoint(element.props.PanelSize[0], element.props.PanelSize[1]);
             return {
                 x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
                 r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index ffd4d211f..412a4d03d 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -247,7 +247,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
                             ScreenToLocalTransform={this.getTransform}
                             isTopMost={false}
                             Scaling={1}
-                            PanelSize={[0, 0]}
+                            PanelSize={[doc.GetNumber(KeyStore.Width, 0), doc.GetNumber(KeyStore.Height, 0)]}
                             ContainingCollectionView={this} />);
                     })}
                 </div>
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index bb85f85a3..7cad6ffc1 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -77,7 +77,9 @@ export class CollectionFreeFormDocumentView extends React.Component<DocumentView
 
 
     getTransform = (): Transform => {
-        return this.props.ScreenToLocalTransform().translate(-this.props.Document.GetNumber(KeyStore.X, 0), -this.props.Document.GetNumber(KeyStore.Y, 0));
+        var parentScaling = this.nativeWidth > 0 ? this.width / this.nativeWidth : 1;
+        return this.props.ScreenToLocalTransform().
+            translate(-this.props.Document.GetNumber(KeyStore.X, 0), -this.props.Document.GetNumber(KeyStore.Y, 0)).scale(1 / parentScaling);
     }
 
     render() {
@@ -93,7 +95,10 @@ export class CollectionFreeFormDocumentView extends React.Component<DocumentView
                 backgroundColor: "transparent"
             }} >
 
-                <DocumentView {...this.props} Scaling={parentScaling} ScreenToLocalTransform={this.getTransform} />
+                <DocumentView {...this.props}
+                    Scaling={parentScaling}
+                    ScreenToLocalTransform={this.getTransform}
+                />
             </div>
         );
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 4eb49f18f..20875586d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -246,20 +246,6 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         SelectionManager.SelectDoc(this, ctrlPressed)
     }
 
-    ScreenToLocalTransform = () => {
-        return this.props.PanelSize[0] ? this.backgroundScreenToLocalTransform() : this.props.ScreenToLocalTransform();
-    }
-
-    backgroundScreenToLocalTransform = () => {
-        if (this.props.PanelSize[0])
-            return this.props.ScreenToLocalTransform().scale(this.props.Scaling);
-        else return this.props.ScreenToLocalTransform().scale(1 / this.props.Scaling);
-    }
-    documentScreenToLocalTransform = () => {
-        if (this.props.PanelSize[0])
-            return this.props.ScreenToLocalTransform();
-        else return this.backgroundScreenToLocalTransform();
-    }
     render() {
         if (!this.props.Document)
             return <div></div>
@@ -269,7 +255,6 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         }
         let documentBindings = {
             ...this.props,
-            ScreenToLocalTransform: this.documentScreenToLocalTransform, // adds 'Scaling' to the screen to local Xf
             isSelected: this.isSelected,
             select: this.select
         } as any;
@@ -289,13 +274,9 @@ export class DocumentView extends React.Component<DocumentViewProps> {
          */
         let backgroundLayout = this.backgroundLayout;
         if (backgroundLayout) {
-            let backgroundBindings = {
-                ...documentBindings,
-                ScreenToLocalTransform: this.backgroundScreenToLocalTransform, // adds 'Scaling' to the screen to local Xf
-            }
             let backgroundView = () => (<JsxParser
                 components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }}
-                bindings={backgroundBindings}
+                bindings={documentBindings}
                 jsx={this.backgroundLayout}
                 showWarnings={true}
                 onError={(test: any) => { console.log(test) }}
-- 
cgit v1.2.3-70-g09d2


From 81511528e418c41332d06faea9c3287cf8abf553 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 22 Feb 2019 10:07:26 -0500
Subject: fixed some exceptions.  fixed spurious context menu.  fixed excessive
 rendering.

---
 src/client/views/DocumentDecorations.tsx           |  5 +++
 .../views/collections/CollectionDockingView.tsx    | 11 +++++-
 .../views/collections/CollectionFreeFormView.tsx   | 43 ++++++++++++----------
 .../views/collections/CollectionSchemaView.tsx     |  3 +-
 src/client/views/nodes/DocumentView.tsx            |  3 +-
 5 files changed, 40 insertions(+), 25 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 4e109d475..395a37ba5 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -5,6 +5,7 @@ import { observer } from "mobx-react";
 import './DocumentDecorations.scss'
 import { KeyStore } from '../../fields/KeyStore'
 import { NumberField } from "../../fields/NumberField";
+import { number } from "prop-types";
 
 @observer
 export class DocumentDecorations extends React.Component {
@@ -142,6 +143,10 @@ export class DocumentDecorations extends React.Component {
         if (this.Hidden) {
             return (null);
         }
+        if (isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) {
+            console.log("DocumentDecorations: Bounds Error")
+            return (null);
+        }
         return (
             <div id="documentDecorations-container" style={{
                 width: (bounds.r - bounds.x + 40) + "px",
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 6d91aef5e..752007439 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -6,7 +6,7 @@ import { observer } from "mobx-react";
 import * as ReactDOM from 'react-dom';
 import Measure from "react-measure";
 import { Document } from "../../../fields/Document";
-import { FieldId, Opt } from "../../../fields/Field";
+import { FieldId, Opt, Field } from "../../../fields/Field";
 import { KeyStore } from "../../../fields/KeyStore";
 import { Utils } from "../../../Utils";
 import { Server } from "../../Server";
@@ -148,6 +148,13 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
             this._goldenLayout.on('stackCreated', this.stackCreated);
             this._goldenLayout.registerComponent('DocumentFrameRenderer', DockedFrameRenderer);
             this._goldenLayout.container = this._containerRef.current;
+            if (this._goldenLayout.config.maximisedItemId === '__glMaximised') {
+                try {
+                    this._goldenLayout.config.root.getItemsById(this._goldenLayout.config.maximisedItemId)[0].toggleMaximise();
+                } catch (e) {
+                    this._goldenLayout.config.maximisedItemId = null;
+                }
+            }
             this._goldenLayout.init();
         }
     }
@@ -261,7 +268,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
 
     constructor(props: any) {
         super(props);
-        Server.GetField(this.props.documentId, f => this._document = f as Document)
+        Server.GetField(this.props.documentId, action((f: Opt<Field>) => this._document = f as Document));
     }
 
     @computed private get _nativeWidth() { return this._document!.GetNumber(KeyStore.NativeWidth, 0); }
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index bd7ca5b6f..c44381f13 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -1,6 +1,6 @@
 import { observer } from "mobx-react";
 import React = require("react");
-import { action, computed } from "mobx";
+import { action, computed, trace } from "mobx";
 import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
 import { DragManager } from "../../util/DragManager";
 import "./CollectionFreeFormView.scss";
@@ -14,6 +14,7 @@ import { FieldWaiting } from "../../../fields/Field";
 import { Transform } from "../../util/Transform";
 import { DocumentView } from "../nodes/DocumentView";
 import { undoBatch } from "../../util/UndoManager";
+import { jSXElement } from "babel-types";
 
 @observer
 export class CollectionFreeFormView extends React.Component<SubCollectionViewProps> {
@@ -221,16 +222,29 @@ export class CollectionFreeFormView extends React.Component<SubCollectionViewPro
         return Transform.Identity.translate(-x, -y).scale(1 / this.scale);
     }
 
-    render() {
+    @computed
+    get views() {
         const { fieldKey, Document } = this.props;
-        // const value: Document[] = Document.GetList<Document>(fieldKey, []);
         const lvalue = Document.GetT<ListField<Document>>(fieldKey, ListField);
-        if (!lvalue || lvalue === "<Waiting>") {
-            return <p>Error loading collection data</p>
+        if (lvalue && lvalue != FieldWaiting) {
+            return lvalue.Data.map(doc => {
+                return (<CollectionFreeFormDocumentView key={doc.Id} Document={doc}
+                    AddDocument={this.props.addDocument}
+                    RemoveDocument={this.props.removeDocument}
+                    ScreenToLocalTransform={this.getTransform}
+                    isTopMost={false}
+                    Scaling={1}
+                    PanelSize={[doc.GetNumber(KeyStore.Width, 0), doc.GetNumber(KeyStore.Height, 0)]}
+                    ContainingCollectionView={this.props.CollectionView} />);
+            })
         }
-        const panx: number = Document.GetNumber(KeyStore.PanX, 0);
-        const pany: number = Document.GetNumber(KeyStore.PanY, 0);
+        return null;
+    }
 
+    render() {
+        const panx: number = this.props.Document.GetNumber(KeyStore.PanX, 0);
+        const pany: number = this.props.Document.GetNumber(KeyStore.PanY, 0);
+        trace()
         return (
             <div className="collectionfreeformview-container"
                 onPointerDown={this.onPointerDown}
@@ -238,25 +252,14 @@ export class CollectionFreeFormView extends React.Component<SubCollectionViewPro
                 onContextMenu={(e) => e.preventDefault()}
                 onDrop={this.onDrop}
                 onDragOver={this.onDragOver}
-                style={{
-                    borderWidth: `${COLLECTION_BORDER_WIDTH}px`,
-                }}
+                style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px`, }}
                 ref={this.createDropTarget}>
                 <div className="collectionfreeformview"
                     style={{ width: "100%", transformOrigin: "left top", transform: ` translate(${panx}px, ${pany}px) scale(${this.zoomScaling}, ${this.zoomScaling})` }}
                     ref={this._canvasRef}>
 
                     {this.props.BackgroundView ? this.props.BackgroundView() : null}
-                    {lvalue.Data.map(doc => {
-                        return (<CollectionFreeFormDocumentView key={doc.Id} Document={doc}
-                            AddDocument={this.props.addDocument}
-                            RemoveDocument={this.props.removeDocument}
-                            ScreenToLocalTransform={this.getTransform}
-                            isTopMost={false}
-                            Scaling={1}
-                            PanelSize={[doc.GetNumber(KeyStore.Width, 0), doc.GetNumber(KeyStore.Height, 0)]}
-                            ContainingCollectionView={this.props.CollectionView} />);
-                    })}
+                    {this.views}
                 </div>
             </div>
         );
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 9405c820f..f25e721c0 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,5 +1,5 @@
 import React = require("react")
-import { action, observable } from "mobx";
+import { action, observable, trace } from "mobx";
 import { observer } from "mobx-react";
 import Measure from "react-measure";
 import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
@@ -138,7 +138,6 @@ export class CollectionSchemaView extends React.Component<SubCollectionViewProps
         const columns = this.props.Document.GetList(KeyStore.ColumnsKey, [KeyStore.Title, KeyStore.Data, KeyStore.Author])
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
         const selected = children.length > this.selectedIndex ? children[this.selectedIndex] : undefined;
-        let me = this;
         let content = this.selectedIndex == -1 || !selected ? (null) : (
             <Measure onResize={this.setScaling}>
                 {({ measureRef }) =>
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 2114a5697..69e413c6f 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -211,10 +211,11 @@ export class DocumentView extends React.Component<DocumentViewProps> {
 
     @action
     onContextMenu = (e: React.MouseEvent): void => {
+        e.preventDefault()
+        e.stopPropagation();
         if (!SelectionManager.IsSelected(this)) {
             return;
         }
-        e.preventDefault()
 
         if (!this._contextMenuCanOpen) {
             return;
-- 
cgit v1.2.3-70-g09d2


From bc9096366d10654d16ed84251e7f4b7fb3a46727 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 22 Feb 2019 15:24:42 -0500
Subject: changed PanelSize to PanelWidth/Height

---
 src/client/views/DocumentDecorations.tsx           |  2 +-
 src/client/views/Main.tsx                          |  3 ++-
 .../views/collections/CollectionDockingView.tsx    |  3 ++-
 .../views/collections/CollectionFreeFormView.tsx   |  3 ++-
 .../views/collections/CollectionSchemaView.tsx     |  3 ++-
 .../views/nodes/CollectionFreeFormDocumentView.tsx | 24 ++++++++++++++--------
 src/client/views/nodes/DocumentView.tsx            |  3 ++-
 7 files changed, 26 insertions(+), 15 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 395a37ba5..7b64a4c2c 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -28,7 +28,7 @@ export class DocumentDecorations extends React.Component {
             }
             let transform = (element.props.ScreenToLocalTransform().scale(element.props.Scaling)).inverse();
             var [sptX, sptY] = transform.transformPoint(0, 0);
-            let [bptX, bptY] = transform.transformPoint(element.props.PanelSize[0], element.props.PanelSize[1]);
+            let [bptX, bptY] = transform.transformPoint(element.props.PanelWidth, element.props.PanelHeight);
             return {
                 x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
                 r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index fe1a999ec..6f6a89839 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -107,7 +107,8 @@ Documents.initProtos(() => {
                 <DocumentView Document={mainContainer}
                     AddDocument={undefined} RemoveDocument={undefined} ScreenToLocalTransform={() => Transform.Identity}
                     Scaling={1}
-                    PanelSize={[0, 0]}
+                    PanelWidth={0}
+                    PanelHeight={0}
                     isTopMost={true}
                     ContainingCollectionView={undefined} />
                 <DocumentDecorations />
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 857af023d..7ac8ea5e4 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -290,7 +290,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
                     AddDocument={undefined}
                     RemoveDocument={undefined}
                     Scaling={this._parentScaling}
-                    PanelSize={[this._nativeWidth, this._nativeHeight]}
+                    PanelWidth={this._nativeWidth}
+                    PanelHeight={this._nativeHeight}
                     ScreenToLocalTransform={this.ScreenToLocalTransform}
                     isTopMost={true}
                     ContainingCollectionView={undefined} />
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index b8312aff7..e31fb25b9 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -187,7 +187,8 @@ export class CollectionFreeFormView extends CollectionViewBase {
                     ScreenToLocalTransform={this.getTransform}
                     isTopMost={false}
                     Scaling={1}
-                    PanelSize={[doc.GetNumber(KeyStore.Width, 0), doc.GetNumber(KeyStore.Height, 0)]}
+                    PanelWidth={doc.GetNumber(KeyStore.Width, 0)}
+                    PanelHeight={doc.GetNumber(KeyStore.Height, 0)}
                     ContainingCollectionView={this.props.CollectionView} />);
             })
         }
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index df732308a..7e7d23fe4 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -149,7 +149,8 @@ export class CollectionSchemaView extends CollectionViewBase {
                             ScreenToLocalTransform={this.getTransform}
                             Scaling={this._parentScaling}
                             isTopMost={false}
-                            PanelSize={[this._panelWidth, this._panelHeight]}
+                            PanelWidth={this._panelWidth}
+                            PanelHeight={this._panelHeight}
                             ContainingCollectionView={this.props.CollectionView} />
                     </div>
                 }
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 5568935fa..ad6756918 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,4 +1,4 @@
-import { computed } from "mobx";
+import { computed, trace } from "mobx";
 import { observer } from "mobx-react";
 import { KeyStore } from "../../../fields/KeyStore";
 import { NumberField } from "../../../fields/NumberField";
@@ -69,15 +69,25 @@ export class CollectionFreeFormDocumentView extends React.Component<DocumentView
         this.props.Document.SetData(KeyStore.ZIndex, h, NumberField)
     }
 
+    @computed
+    get parentScaling() {
+        return this.nativeWidth > 0 ? this.width / this.nativeWidth : 1;
+    }
 
     getTransform = (): Transform => {
-        var parentScaling = this.nativeWidth > 0 ? this.width / this.nativeWidth : 1;
         return this.props.ScreenToLocalTransform().
-            translate(-this.props.Document.GetNumber(KeyStore.X, 0), -this.props.Document.GetNumber(KeyStore.Y, 0)).scale(1 / parentScaling);
+            translate(-this.props.Document.GetNumber(KeyStore.X, 0), -this.props.Document.GetNumber(KeyStore.Y, 0)).scale(1 / this.parentScaling);
+    }
+
+    @computed
+    get docView() {
+        return <DocumentView {...this.props}
+            Scaling={this.parentScaling}
+            ScreenToLocalTransform={this.getTransform}
+        />
     }
 
     render() {
-        var parentScaling = this.nativeWidth > 0 ? this.width / this.nativeWidth : 1;
         return (
             <div ref={this._mainCont} style={{
                 transformOrigin: "left top",
@@ -88,11 +98,7 @@ export class CollectionFreeFormDocumentView extends React.Component<DocumentView
                 zIndex: this.zIndex,
                 backgroundColor: "transparent"
             }} >
-
-                <DocumentView {...this.props}
-                    Scaling={parentScaling}
-                    ScreenToLocalTransform={this.getTransform}
-                />
+                {this.docView}
             </div>
         );
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 69e413c6f..c026e13cd 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -31,7 +31,8 @@ export interface DocumentViewProps {
     isTopMost: boolean;
     //tfs: This shouldn't be necessary I don't think
     Scaling: number;
-    PanelSize: number[];
+    PanelWidth: number;
+    PanelHeight: number;
 }
 export interface JsxArgs extends DocumentViewProps {
     Keys: { [name: string]: Key }
-- 
cgit v1.2.3-70-g09d2


From 530be8dc0f049a4c05431c7b10ae47e46575fcbe Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 22 Feb 2019 17:10:44 -0500
Subject: fixed re-render issue for collection free form documents.

---
 src/client/views/DocumentDecorations.tsx           |  5 +--
 src/client/views/Main.tsx                          |  6 +--
 .../views/collections/CollectionDockingView.tsx    | 10 ++---
 .../views/collections/CollectionFreeFormView.tsx   | 46 ++++++-------------
 .../views/collections/CollectionSchemaView.tsx     | 52 ++++++++++------------
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  9 ++--
 src/client/views/nodes/DocumentView.tsx            |  8 ++--
 src/fields/Document.ts                             |  4 ++
 8 files changed, 59 insertions(+), 81 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 7b64a4c2c..efd50e49e 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -5,7 +5,6 @@ import { observer } from "mobx-react";
 import './DocumentDecorations.scss'
 import { KeyStore } from '../../fields/KeyStore'
 import { NumberField } from "../../fields/NumberField";
-import { number } from "prop-types";
 
 @observer
 export class DocumentDecorations extends React.Component {
@@ -26,9 +25,9 @@ export class DocumentDecorations extends React.Component {
             if (element.props.isTopMost) {
                 return bounds;
             }
-            let transform = (element.props.ScreenToLocalTransform().scale(element.props.Scaling)).inverse();
+            let transform = (element.props.ScreenToLocalTransform().scale(element.props.ContentScaling())).inverse();
             var [sptX, sptY] = transform.transformPoint(0, 0);
-            let [bptX, bptY] = transform.transformPoint(element.props.PanelWidth, element.props.PanelHeight);
+            let [bptX, bptY] = transform.transformPoint(element.props.PanelWidth(), element.props.PanelHeight());
             return {
                 x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
                 r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 6f6a89839..661a2ac20 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -106,9 +106,9 @@ Documents.initProtos(() => {
             <div style={{ position: "absolute", width: "100%", height: "100%" }}>
                 <DocumentView Document={mainContainer}
                     AddDocument={undefined} RemoveDocument={undefined} ScreenToLocalTransform={() => Transform.Identity}
-                    Scaling={1}
-                    PanelWidth={0}
-                    PanelHeight={0}
+                    ContentScaling={() => 1}
+                    PanelWidth={() => 0}
+                    PanelHeight={() => 0}
                     isTopMost={true}
                     ContainingCollectionView={undefined} />
                 <DocumentDecorations />
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 7ac8ea5e4..86dc66e39 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -272,13 +272,13 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         Server.GetField(this.props.documentId, action((f: Opt<Field>) => this._document = f as Document));
     }
 
-    @computed private get _nativeWidth() { return this._document!.GetNumber(KeyStore.NativeWidth, 0); }
-    @computed private get _nativeHeight() { return this._document!.GetNumber(KeyStore.NativeHeight, 0); }
-    @computed private get _parentScaling() { return this._panelWidth / (this._nativeWidth ? this._nativeWidth : this._panelWidth); }; // used to transfer the dimensions of the content pane in the DOM to the ParentScaling prop of the DocumentView
+    private _nativeWidth = () => { return this._document!.GetNumber(KeyStore.NativeWidth, 0); }
+    private _nativeHeight = () => { return this._document!.GetNumber(KeyStore.NativeHeight, 0); }
+    private _contentScaling = () => { return this._panelWidth / (this._nativeWidth() ? this._nativeWidth() : this._panelWidth); }
 
     ScreenToLocalTransform = () => {
         let { scale, translateX, translateY } = Utils.GetScreenTransform(this._mainCont.current!);
-        return CollectionDockingView.Instance.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(scale / this._parentScaling)
+        return CollectionDockingView.Instance.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(scale / this._contentScaling())
     }
 
     render() {
@@ -289,7 +289,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
                 <DocumentView key={this._document.Id} Document={this._document}
                     AddDocument={undefined}
                     RemoveDocument={undefined}
-                    Scaling={this._parentScaling}
+                    ContentScaling={this._contentScaling}
                     PanelWidth={this._nativeWidth}
                     PanelHeight={this._nativeHeight}
                     ScreenToLocalTransform={this.ScreenToLocalTransform}
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index e31fb25b9..43bc24a12 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -22,23 +22,14 @@ export class CollectionFreeFormView extends CollectionViewBase {
     private _downX: number = 0;
     private _downY: number = 0;
 
-    @computed
-    get isAnnotationOverlay() { return this.props.fieldKey == KeyStore.Annotations; }
-
-    @computed
-    get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); }
-    @computed
-    get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); }
-
-    @computed
-    get zoomScaling() { return this.props.Document.GetNumber(KeyStore.Scale, 1); }
-
-    @computed
-    get resizeScaling() { return this.isAnnotationOverlay ? this.props.Document.GetNumber(KeyStore.Width, 0) / this.nativeWidth : 1; }
 
-    constructor(props: SubCollectionViewProps) {
-        super(props);
-    }
+    @computed get panX(): number { return this.props.Document.GetNumber(KeyStore.PanX, 0) }
+    @computed get panY(): number { return this.props.Document.GetNumber(KeyStore.PanY, 0) }
+    @computed get scale(): number { return this.props.Document.GetNumber(KeyStore.Scale, 1); }
+    @computed get isAnnotationOverlay() { return this.props.fieldKey == KeyStore.Annotations; }
+    @computed get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); }
+    @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); }
+    @computed get zoomScaling() { return this.props.Document.GetNumber(KeyStore.Scale, 1); }
 
     @undoBatch
     @action
@@ -154,27 +145,16 @@ export class CollectionFreeFormView extends CollectionViewBase {
         });
     }
 
-    @computed
-    get translate(): [number, number] {
-        const x = this.props.Document.GetNumber(KeyStore.PanX, 0);
-        const y = this.props.Document.GetNumber(KeyStore.PanY, 0);
-        return [x, y];
-    }
-
-    @computed
-    get scale(): number {
-        return this.props.Document.GetNumber(KeyStore.Scale, 1);
-    }
-
     getTransform = (): Transform => {
         return this.props.ScreenToLocalTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).transform(this.getLocalTransform())
     }
 
     getLocalTransform = (): Transform => {
-        const [x, y] = this.translate;
-        return Transform.Identity.translate(-x, -y).scale(1 / this.scale);
+        return Transform.Identity.translate(-this.panX, -this.panY).scale(1 / this.scale);
     }
 
+    noScaling = () => 1;
+
     @computed
     get views() {
         const { fieldKey, Document } = this.props;
@@ -186,9 +166,9 @@ export class CollectionFreeFormView extends CollectionViewBase {
                     RemoveDocument={this.props.removeDocument}
                     ScreenToLocalTransform={this.getTransform}
                     isTopMost={false}
-                    Scaling={1}
-                    PanelWidth={doc.GetNumber(KeyStore.Width, 0)}
-                    PanelHeight={doc.GetNumber(KeyStore.Height, 0)}
+                    ContentScaling={this.noScaling}
+                    PanelWidth={doc.Width}
+                    PanelHeight={doc.Height}
                     ContainingCollectionView={this.props.CollectionView} />);
             })
         }
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 7e7d23fe4..ca47f6998 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -19,14 +19,14 @@ import { CollectionViewBase } from "./CollectionViewBase";
 @observer
 export class CollectionSchemaView extends CollectionViewBase {
     private _mainCont = React.createRef<HTMLDivElement>();
-
     private DIVIDER_WIDTH = 5;
 
-    @observable
-    selectedIndex = 0;
-
-    @observable
-    _splitPercentage: number = 50;
+    @observable _contentScaling = 1; // used to transfer the dimensions of the content pane in the DOM to the ContentScaling prop of the DocumentView
+    @observable _dividerX = 0;
+    @observable _panelWidth = 0;
+    @observable _panelHeight = 0;
+    @observable _selectedIndex = 0;
+    @observable _splitPercentage: number = 50;
 
     renderCell = (rowProps: CellInfo) => {
         let props: FieldViewProps = {
@@ -67,7 +67,6 @@ export class CollectionSchemaView extends CollectionViewBase {
         )
     }
 
-
     private getTrProps: ComponentPropsGetterR = (state, rowInfo) => {
         const that = this;
         if (!rowInfo) {
@@ -75,7 +74,7 @@ export class CollectionSchemaView extends CollectionViewBase {
         }
         return {
             onClick: action((e: React.MouseEvent, handleOriginal: Function) => {
-                that.selectedIndex = rowInfo.index;
+                that._selectedIndex = rowInfo.index;
                 this._splitPercentage += 0.05; // bcz - ugh - needed to force Measure to do its thing and call onResize
 
                 if (handleOriginal) {
@@ -83,8 +82,8 @@ export class CollectionSchemaView extends CollectionViewBase {
                 }
             }),
             style: {
-                background: rowInfo.index == this.selectedIndex ? "#00afec" : "white",
-                color: rowInfo.index == this.selectedIndex ? "white" : "black"
+                background: rowInfo.index == this._selectedIndex ? "#00afec" : "white",
+                color: rowInfo.index == this._selectedIndex ? "white" : "black"
             }
         };
     }
@@ -94,7 +93,6 @@ export class CollectionSchemaView extends CollectionViewBase {
         let nativeWidth = this._mainCont.current!.getBoundingClientRect();
         this._splitPercentage = Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100);
     }
-
     onDividerUp = (e: PointerEvent): void => {
         document.removeEventListener("pointermove", this.onDividerMove);
         document.removeEventListener('pointerup', this.onDividerUp);
@@ -118,39 +116,37 @@ export class CollectionSchemaView extends CollectionViewBase {
         }
     }
 
-
-    getTransform = (): Transform => {
-        return this.props.ScreenToLocalTransform().translate(- COLLECTION_BORDER_WIDTH - this.DIVIDER_WIDTH - this._dividerX, - COLLECTION_BORDER_WIDTH).scale(1 / this._parentScaling);
-    }
-
     @action
     setScaling = (r: any) => {
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
-        const selected = children.length > this.selectedIndex ? children[this.selectedIndex] : undefined;
+        const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined;
         this._panelWidth = r.entry.width;
         this._panelHeight = r.entry.height ? r.entry.height : this._panelHeight;
-        this._parentScaling = r.entry.width / selected!.GetNumber(KeyStore.NativeWidth, r.entry.width);
+        this._contentScaling = r.entry.width / selected!.GetNumber(KeyStore.NativeWidth, r.entry.width);
+    }
+
+    getContentScaling = (): number => this._contentScaling;
+    getPanelWidth = (): number => this._panelWidth;
+    getPanelHeight = (): number => this._panelHeight;
+    getTransform = (): Transform => {
+        return this.props.ScreenToLocalTransform().translate(- COLLECTION_BORDER_WIDTH - this.DIVIDER_WIDTH - this._dividerX, - COLLECTION_BORDER_WIDTH).scale(1 / this._contentScaling);
     }
 
-    @observable _parentScaling = 1; // used to transfer the dimensions of the content pane in the DOM to the ParentScaling prop of the DocumentView
-    @observable _dividerX = 0;
-    @observable _panelWidth = 0;
-    @observable _panelHeight = 0;
     render() {
         const columns = this.props.Document.GetList(KeyStore.ColumnsKey, [KeyStore.Title, KeyStore.Data, KeyStore.Author])
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
-        const selected = children.length > this.selectedIndex ? children[this.selectedIndex] : undefined;
-        let content = this.selectedIndex == -1 || !selected ? (null) : (
+        const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined;
+        let content = this._selectedIndex == -1 || !selected ? (null) : (
             <Measure onResize={this.setScaling}>
                 {({ measureRef }) =>
                     <div ref={measureRef}>
                         <DocumentView Document={selected}
                             AddDocument={this.props.addDocument} RemoveDocument={this.props.removeDocument}
-                            ScreenToLocalTransform={this.getTransform}
-                            Scaling={this._parentScaling}
                             isTopMost={false}
-                            PanelWidth={this._panelWidth}
-                            PanelHeight={this._panelHeight}
+                            ScreenToLocalTransform={this.getTransform}
+                            ContentScaling={this.getContentScaling}
+                            PanelWidth={this.getPanelWidth}
+                            PanelHeight={this.getPanelHeight}
                             ContainingCollectionView={this.props.CollectionView} />
                     </div>
                 }
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index ad6756918..17123bf52 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -24,7 +24,7 @@ export class CollectionFreeFormDocumentView extends React.Component<DocumentView
 
     @computed
     get transform(): string {
-        return `scale(${this.props.Scaling}, ${this.props.Scaling}) translate(${this.props.Document.GetNumber(KeyStore.X, 0)}px, ${this.props.Document.GetNumber(KeyStore.Y, 0)}px)`;
+        return `scale(${this.props.ContentScaling()}, ${this.props.ContentScaling()}) translate(${this.props.Document.GetNumber(KeyStore.X, 0)}px, ${this.props.Document.GetNumber(KeyStore.Y, 0)}px)`;
     }
 
     @computed
@@ -69,20 +69,19 @@ export class CollectionFreeFormDocumentView extends React.Component<DocumentView
         this.props.Document.SetData(KeyStore.ZIndex, h, NumberField)
     }
 
-    @computed
-    get parentScaling() {
+    contentScaling = () => {
         return this.nativeWidth > 0 ? this.width / this.nativeWidth : 1;
     }
 
     getTransform = (): Transform => {
         return this.props.ScreenToLocalTransform().
-            translate(-this.props.Document.GetNumber(KeyStore.X, 0), -this.props.Document.GetNumber(KeyStore.Y, 0)).scale(1 / this.parentScaling);
+            translate(-this.props.Document.GetNumber(KeyStore.X, 0), -this.props.Document.GetNumber(KeyStore.Y, 0)).scale(1 / this.contentScaling());
     }
 
     @computed
     get docView() {
         return <DocumentView {...this.props}
-            Scaling={this.parentScaling}
+            ContentScaling={this.contentScaling}
             ScreenToLocalTransform={this.getTransform}
         />
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index c026e13cd..34a230669 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -30,9 +30,9 @@ export interface DocumentViewProps {
     ScreenToLocalTransform: () => Transform;
     isTopMost: boolean;
     //tfs: This shouldn't be necessary I don't think
-    Scaling: number;
-    PanelWidth: number;
-    PanelHeight: number;
+    ContentScaling: () => number;
+    PanelWidth: () => number;
+    PanelHeight: () => number;
 }
 export interface JsxArgs extends DocumentViewProps {
     Keys: { [name: string]: Key }
@@ -293,7 +293,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
         var nodeWidth = nativeWidth > 0 ? nativeWidth.toString() + "px" : "100%";
         var nodeHeight = nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%";
-        var scaling = this.props.Scaling;
+        var scaling = this.props.ContentScaling();
         return (
             <div className="documentView-node" ref={this._mainCont} style={{ width: nodeWidth, height: nodeHeight, transformOrigin: "left top", transform: `scale(${scaling},${scaling})` }}
                 onContextMenu={this.onContextMenu}
diff --git a/src/fields/Document.ts b/src/fields/Document.ts
index ff13732b3..0d7d357a0 100644
--- a/src/fields/Document.ts
+++ b/src/fields/Document.ts
@@ -30,6 +30,10 @@ export class Document extends Field {
         }
     }
 
+    public Width = () => { return this.GetNumber(KeyStore.Width, 0) }
+    public Height = () => { return this.GetNumber(KeyStore.Height, 0) }
+    public Scale = () => { return this.GetNumber(KeyStore.Scale, 1) }
+
     @computed
     public get Title() {
         return this.GetText(KeyStore.Title, "<untitled>");
-- 
cgit v1.2.3-70-g09d2


From 5d6d6e00e8fbff1f4475235b1912efcee85eb91e Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 22 Feb 2019 21:39:40 -0500
Subject: moved backgroundLayout to CollectionFreeForm

---
 src/client/views/DocumentDecorations.tsx           |  2 +-
 .../views/collections/CollectionFreeFormView.tsx   | 58 ++++++++++++++--------
 .../views/collections/CollectionSchemaView.tsx     |  3 +-
 src/client/views/collections/CollectionView.tsx    |  2 +-
 .../views/collections/CollectionViewBase.tsx       |  2 +-
 src/client/views/nodes/DocumentView.tsx            | 41 ++++-----------
 src/client/views/nodes/FieldView.tsx               |  3 +-
 src/client/views/nodes/FormattedTextBox.tsx        |  1 -
 8 files changed, 55 insertions(+), 57 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index efd50e49e..09df8cdaa 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -101,7 +101,7 @@ export class DocumentDecorations extends React.Component {
         }
 
         SelectionManager.SelectedDocuments().forEach(element => {
-            const rect = element.screenRect;
+            const rect = element.screenRect();
             if (rect.width !== 0) {
                 let doc = element.props.Document;
                 let width = doc.GetOrCreate(KeyStore.Width, NumberField);
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 43bc24a12..565402046 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -1,18 +1,25 @@
+import { action, computed } from "mobx";
 import { observer } from "mobx-react";
-import React = require("react");
-import { action, computed, trace } from "mobx";
-import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
-import { DragManager } from "../../util/DragManager";
-import "./CollectionFreeFormView.scss";
-import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
-import { KeyStore } from "../../../fields/KeyStore";
 import { Document } from "../../../fields/Document";
-import { ListField } from "../../../fields/ListField";
 import { FieldWaiting } from "../../../fields/Field";
+import { KeyStore } from "../../../fields/KeyStore";
+import { ListField } from "../../../fields/ListField";
+import { TextField } from "../../../fields/TextField";
+import { DragManager } from "../../util/DragManager";
 import { Transform } from "../../util/Transform";
-import { DocumentView } from "../nodes/DocumentView";
 import { undoBatch } from "../../util/UndoManager";
-import { CollectionViewBase, SubCollectionViewProps } from "./CollectionViewBase";
+import { CollectionDockingView } from "../collections/CollectionDockingView";
+import { CollectionSchemaView } from "../collections/CollectionSchemaView";
+import { CollectionView } from "../collections/CollectionView";
+import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
+import { DocumentView } from "../nodes/DocumentView";
+import { FormattedTextBox } from "../nodes/FormattedTextBox";
+import { ImageBox } from "../nodes/ImageBox";
+import "./CollectionFreeFormView.scss";
+import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
+import { CollectionViewBase } from "./CollectionViewBase";
+import React = require("react");
+const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this?
 
 @observer
 export class CollectionFreeFormView extends CollectionViewBase {
@@ -145,16 +152,13 @@ export class CollectionFreeFormView extends CollectionViewBase {
         });
     }
 
-    getTransform = (): Transform => {
-        return this.props.ScreenToLocalTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).transform(this.getLocalTransform())
-    }
 
-    getLocalTransform = (): Transform => {
-        return Transform.Identity.translate(-this.panX, -this.panY).scale(1 / this.scale);
+    @computed get backgroundLayout(): string | undefined {
+        let field = this.props.Document.GetT(KeyStore.BackgroundLayout, TextField);
+        if (field && field !== "<Waiting>") {
+            return field.Data;
+        }
     }
-
-    noScaling = () => 1;
-
     @computed
     get views() {
         const { fieldKey, Document } = this.props;
@@ -175,6 +179,21 @@ export class CollectionFreeFormView extends CollectionViewBase {
         return null;
     }
 
+    @computed
+    get backgroundView() {
+        return !this.backgroundLayout ? (null) :
+            (<JsxParser
+                components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView }}
+                bindings={this.props.bindings}
+                jsx={this.backgroundLayout}
+                showWarnings={true}
+                onError={(test: any) => console.log(test)}
+            />);
+    }
+    getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).transform(this.getLocalTransform())
+    getLocalTransform = (): Transform => Transform.Identity.translate(-this.panX, -this.panY).scale(1 / this.scale);
+    noScaling = () => 1;
+
     render() {
         const panx: number = this.props.Document.GetNumber(KeyStore.PanX, 0);
         const pany: number = this.props.Document.GetNumber(KeyStore.PanY, 0);
@@ -190,8 +209,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
                 <div className="collectionfreeformview"
                     style={{ width: "100%", transformOrigin: "left top", transform: ` translate(${panx}px, ${pany}px) scale(${this.zoomScaling}, ${this.zoomScaling})` }}
                     ref={this._canvasRef}>
-
-                    {this.props.BackgroundView ? this.props.BackgroundView() : null}
+                    {this.backgroundView}
                     {this.views}
                 </div>
             </div>
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index ca47f6998..d2db93120 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -34,7 +34,8 @@ export class CollectionSchemaView extends CollectionViewBase {
             fieldKey: rowProps.value[1],
             isSelected: () => false,
             select: () => { },
-            isTopMost: false
+            isTopMost: false,
+            bindings: {}
         }
         let contents = (
             <FieldView {...props} />
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index ff1803ec3..90080ab43 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -28,7 +28,7 @@ export class CollectionView extends React.Component<CollectionViewProps> {
 
     public static LayoutString(fieldKey: string = "DataKey") {
         return `<CollectionView Document={Document}
-                    ScreenToLocalTransform={ScreenToLocalTransform} fieldKey={${fieldKey}} isSelected={isSelected} select={select}
+                    ScreenToLocalTransform={ScreenToLocalTransform} fieldKey={${fieldKey}} isSelected={isSelected} select={select} bindings={bindings}
                     isTopMost={isTopMost} BackgroundView={BackgroundView} />`;
     }
     public active = () => {
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index 06de56383..da7f71163 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -19,7 +19,7 @@ export interface CollectionViewProps {
     isSelected: () => boolean;
     isTopMost: boolean;
     select: (ctrlPressed: boolean) => void;
-    BackgroundView?: () => JSX.Element;
+    bindings: any;
 }
 export interface SubCollectionViewProps extends CollectionViewProps {
     active: () => boolean;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index d9b1d90d8..a9e211431 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -5,7 +5,6 @@ import { Field, FieldWaiting, Opt } from "../../../fields/Field";
 import { Key } from "../../../fields/Key";
 import { KeyStore } from "../../../fields/KeyStore";
 import { ListField } from "../../../fields/ListField";
-import { TextField } from "../../../fields/TextField";
 import { DragManager } from "../../util/DragManager";
 import { SelectionManager } from "../../util/SelectionManager";
 import { Transform } from "../../util/Transform";
@@ -84,21 +83,13 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     private _downX: number = 0;
     private _downY: number = 0;
 
-    get screenRect(): ClientRect | DOMRect {
-        return (this._mainCont.current) ? this._mainCont.current.getBoundingClientRect() : new DOMRect();
-    }
     @computed get active(): boolean { return SelectionManager.IsSelected(this) || !this.props.ContainingCollectionView || this.props.ContainingCollectionView.active(); }
     @computed get topMost(): boolean { return !this.props.ContainingCollectionView || this.props.ContainingCollectionView.collectionViewType == CollectionViewType.Docking; }
     @computed get layout(): string { return this.props.Document.GetText(KeyStore.Layout, "<p>Error loading layout data</p>"); }
     @computed get layoutKeys(): Key[] { return this.props.Document.GetData(KeyStore.LayoutKeys, ListField, new Array<Key>()); }
     @computed get layoutFields(): Key[] { return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array<Key>()); }
-    @computed get backgroundLayout(): string | undefined {
-        let field = this.props.Document.GetT(KeyStore.BackgroundLayout, TextField);
-        if (field && field !== "<Waiting>") {
-            return field.Data;
-        }
-    }
 
+    screenRect = (): ClientRect | DOMRect => this._mainCont.current ? this._mainCont.current.getBoundingClientRect() : new DOMRect();
 
     onPointerDown = (e: React.PointerEvent): void => {
         this._downX = e.clientX;
@@ -174,6 +165,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
     }
 
+    @action
     onContextMenu = (e: React.MouseEvent): void => {
         e.preventDefault()
         e.stopPropagation();
@@ -230,32 +222,19 @@ export class DocumentView extends React.Component<DocumentViewProps> {
             let field = this.props.Document.Get(key);
             this._documentBindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field;
         }
-
-        /*
-        tfs:
-        Should this be moved to CollectionFreeformView or another component that renders
-        Document backgrounds (or contents based on a layout key, which could be used here as well)
-         that CollectionFreeformView uses? It seems like a lot for it to be here considering only one view currently uses it...
-         */
-        let backgroundLayout = this.backgroundLayout;
-        if (backgroundLayout) {
-            let backgroundView = () => (<JsxParser
-                components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView }}
-                bindings={this._documentBindings}
-                jsx={this.backgroundLayout}
-                showWarnings={true}
-                onError={(test: any) => { console.log(test) }}
-            />);
-            this._documentBindings.BackgroundView = backgroundView;
-        }
+        this._documentBindings.bindings = this._documentBindings;
 
         var scaling = this.props.ContentScaling();
         var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
         var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
-        var nodeWidth = nativeWidth > 0 ? nativeWidth.toString() + "px" : "100%";
-        var nodeHeight = nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%";
         return (
-            <div className="documentView-node" ref={this._mainCont} style={{ width: nodeWidth, height: nodeHeight, transformOrigin: "left top", transform: `scale(${scaling},${scaling})` }}
+            <div className="documentView-node" ref={this._mainCont}
+                style={{
+                    width: nativeWidth > 0 ? nativeWidth.toString() + "px" : "100%",
+                    height: nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%",
+                    transformOrigin: "left top",
+                    transform: `scale(${scaling},${scaling})`
+                }}
                 onContextMenu={this.onContextMenu}
                 onPointerDown={this.onPointerDown} >
                 {this.mainContent}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 821172d71..97d3f2a85 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -22,11 +22,12 @@ export interface FieldViewProps {
     isSelected: () => boolean;
     select: () => void;
     isTopMost: boolean;
+    bindings: any;
 }
 
 @observer
 export class FieldView extends React.Component<FieldViewProps> {
-    public static LayoutString(fieldType: { name: string }) { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} isSelected={isSelected} select={select} isTopMost={isTopMost} />`; }
+    public static LayoutString(fieldType: { name: string }) { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} bindings={bindings} fieldKey={DataKey} isSelected={isSelected} select={select} isTopMost={isTopMost} />`; }
     @computed
     get field(): FieldValue<Field> {
         const { doc, fieldKey } = this.props;
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index b17650d06..16728d471 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -6,7 +6,6 @@ import { schema } from "prosemirror-schema-basic";
 import { EditorState, Transaction } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import { Opt, FieldWaiting, FieldValue } from "../../../fields/Field";
-import { SelectionManager } from "../../util/SelectionManager";
 import "./FormattedTextBox.scss";
 import React = require("react")
 import { RichTextField } from "../../../fields/RichTextField";
-- 
cgit v1.2.3-70-g09d2


From c9d440e487a4c0b648ac68d040f844b762ec1376 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 22 Feb 2019 22:36:22 -0500
Subject: added dropping of image urls

---
 src/client/views/DocumentDecorations.tsx           |  8 ++--
 .../views/collections/CollectionFreeFormView.tsx   |  8 ++--
 .../views/collections/CollectionViewBase.tsx       | 55 +++++++++++++++-------
 3 files changed, 48 insertions(+), 23 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 09df8cdaa..2f012913d 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -21,13 +21,13 @@ export class DocumentDecorations extends React.Component {
 
     @computed
     get Bounds(): { x: number, y: number, b: number, r: number } {
-        return SelectionManager.SelectedDocuments().reduce((bounds, element) => {
-            if (element.props.isTopMost) {
+        return SelectionManager.SelectedDocuments().reduce((bounds, documentView) => {
+            if (documentView.props.isTopMost) {
                 return bounds;
             }
-            let transform = (element.props.ScreenToLocalTransform().scale(element.props.ContentScaling())).inverse();
+            let transform = (documentView.props.ScreenToLocalTransform().scale(documentView.props.ContentScaling())).inverse();
             var [sptX, sptY] = transform.transformPoint(0, 0);
-            let [bptX, bptY] = transform.transformPoint(element.props.PanelWidth(), element.props.PanelHeight());
+            let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.props.PanelHeight());
             return {
                 x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
                 r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 565402046..c12a82617 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -19,6 +19,7 @@ import "./CollectionFreeFormView.scss";
 import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
 import { CollectionViewBase } from "./CollectionViewBase";
 import React = require("react");
+import { Documents } from "../../documents/Documents";
 const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this?
 
 @observer
@@ -126,9 +127,10 @@ export class CollectionFreeFormView extends CollectionViewBase {
     onDrop = (e: React.DragEvent): void => {
         const panx: number = this.props.Document.GetNumber(KeyStore.PanX, 0);
         const pany: number = this.props.Document.GetNumber(KeyStore.PanY, 0);
-        let x = e.pageX - panx
-        let y = e.pageY - pany
-        super.onDrop(e, { x: x, y: y });
+        let transform = this.getTransform();
+
+        var pt = transform.transformPoint(e.pageX, e.pageY);
+        super.onDrop(e, { x: pt[0], y: pt[1] });
     }
 
     onDragOver = (): void => {
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index da7f71163..4bf0d074a 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -56,27 +56,50 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
     protected onDrop(e: React.DragEvent, options: DocumentOptions): void {
         e.stopPropagation()
         e.preventDefault()
-        let fReader = new FileReader()
-        let file = e.dataTransfer.items[0].getAsFile();
         let that = this;
 
-        fReader.addEventListener("load", action("drop", () => {
-            if (fReader.result) {
-                let url = "" + fReader.result;
-                let doc = Documents.ImageDocument(url, options)
-                let docs = that.props.Document.GetT(KeyStore.Data, ListField);
-                if (docs != FieldWaiting) {
-                    if (!docs) {
-                        docs = new ListField<Document>();
-                        that.props.Document.Set(KeyStore.Data, docs)
+        for (let i = 0; i < e.dataTransfer.items.length; i++) {
+            let item = e.dataTransfer.items[i];
+            if (item.kind === "string" && item.type.indexOf("uri") != -1) {
+                e.dataTransfer.items[i].getAsString(function (s) {
+                    action(() => {
+                        var img = Documents.ImageDocument(s, { ...options, nativeWidth: 300, nativeHeight: 300, width: 300, height: 300 })
+
+                        let docs = that.props.Document.GetT(KeyStore.Data, ListField);
+                        if (docs != FieldWaiting) {
+                            if (!docs) {
+                                docs = new ListField<Document>();
+                                that.props.Document.Set(KeyStore.Data, docs)
+                            }
+                            docs.Data.push(img);
+                        }
+                    })()
+
+                })
+            }
+            if (item.kind == "file" && item.type.indexOf("image")) {
+                let fReader = new FileReader()
+                let file = item.getAsFile();
+
+                fReader.addEventListener("load", action("drop", () => {
+                    if (fReader.result) {
+                        let url = "" + fReader.result;
+                        let doc = Documents.ImageDocument(url, options)
+                        let docs = that.props.Document.GetT(KeyStore.Data, ListField);
+                        if (docs != FieldWaiting) {
+                            if (!docs) {
+                                docs = new ListField<Document>();
+                                that.props.Document.Set(KeyStore.Data, docs)
+                            }
+                            docs.Data.push(doc);
+                        }
                     }
-                    docs.Data.push(doc);
+                }), false)
+
+                if (file) {
+                    fReader.readAsDataURL(file)
                 }
             }
-        }), false)
-
-        if (file) {
-            fReader.readAsDataURL(file)
         }
     }
 }
-- 
cgit v1.2.3-70-g09d2

