From 59cc888c8bf0559c50e12fd2774ea5ac4ebb3059 Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Tue, 26 Feb 2019 16:33:53 -0500
Subject: basic implementation of prototype/delegate stuff

---
 src/client/views/nodes/DocumentView.tsx | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index ad1328e5d..bc8bbfef1 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -96,9 +96,12 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         this._downX = e.clientX;
         this._downY = e.clientY;
         if (e.shiftKey && e.buttons === 1) {
+            console.log("Hello")
+            let document = e.ctrlKey ? this.props.Document.CreateAlias() : this.props.Document
             CollectionDockingView.Instance.StartOtherDrag(this._mainCont.current!, this.props.Document);
             e.stopPropagation();
-        } else {
+        }
+        else {
             this._contextMenuCanOpen = true;
             if (this.active && !e.isDefaultPrevented()) {
                 e.stopPropagation();
@@ -127,11 +130,12 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                 dragData["document"] = this;
                 dragData["xOffset"] = e.x - left;
                 dragData["yOffset"] = e.y - top;
+                dragData["alias"] = e.shiftKey
                 DragManager.StartDrag(this._mainCont.current, dragData, {
                     handlers: {
                         dragComplete: action((e: DragManager.DragCompleteEvent) => { }),
                     },
-                    hideSource: true
+                    hideSource: !e.shiftKey
                 })
             }
         }
-- 
cgit v1.2.3-70-g09d2


From e0220063583922da6e8630ee2bced95a6a233b92 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Thu, 14 Mar 2019 16:40:25 -0400
Subject: Started switching stuff over to document contents

---
 src/client/views/nodes/DocumentView.tsx | 56 ++++++++++++++++++---------------
 1 file changed, 31 insertions(+), 25 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a91d2071b..8ff355a15 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -87,16 +87,42 @@ export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs {
 
 interface JsxBindings {
     Document: Document;
-    layout: string;
+    isSelected: () => boolean;
+    select: (isCtrlPressed: boolean) => void;
+    isTopMost: boolean;
+    SelectOnLoad: boolean;
     [prop: string]: any;
 }
 
-export class DocumentContents extends React.PureComponent<JsxBindings> {
+@observer
+export class DocumentContents extends React.Component<DocumentViewProps & {
+    isSelected: () => boolean,
+    select: (ctrl: boolean) => void,
+    layoutKey: Key
+}> {
+    @computed get layout(): string { return this.props.Document.GetText(this.props.layoutKey, "<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>()); }
+
+    CreateBindings(): JsxBindings {
+        let bindings: JsxBindings = {
+            ...this.props,
+        };
+        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
+        }
+        for (const key of this.layoutFields) {
+            let field = this.props.Document.Get(key);
+            bindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field;
+        }
+        return bindings;
+    }
+
     render() {
         return <JsxParser
             components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox }}
-            bindings={this.props}
-            jsx={this.props.layout}
+            bindings={this.CreateBindings()}
+            jsx={this.layout}
             showWarnings={true}
             onError={(test: any) => { console.log(test) }}
         />
@@ -302,26 +328,6 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         SelectionManager.SelectDoc(this, ctrlPressed)
     }
 
-    @computed
-    get getProps() {
-        let bindings: any = {
-            ...this.props,
-            isSelected: this.isSelected,
-            select: this.select,
-            layout: this.layout
-        };
-        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
-        }
-        for (const key of this.layoutFields) {
-            let field = this.props.Document.Get(key);
-            bindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field;
-        }
-        bindings.bindings = bindings;
-
-        return bindings
-    }
-
     render() {
         if (!this.props.Document) {
             return (null);
@@ -343,7 +349,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                 }}
                 onContextMenu={this.onContextMenu}
                 onPointerDown={this.onPointerDown} >
-                <DocumentContents {...this.getProps} />
+                <DocumentContents {...this.props} isSelected={this.isSelected} select={this.select} layoutKey={KeyStore.Layout} />
             </div>
         )
     }
-- 
cgit v1.2.3-70-g09d2


From a4fa90e0d376a993392c0eff143a5c387e387980 Mon Sep 17 00:00:00 2001
From: Andrew Kim <andrewdkim@users.noreply.github.com>
Date: Sun, 17 Mar 2019 00:15:40 -0400
Subject: testing mobile image

---
 deploy/index.html                                  |   1 -
 deploy/mobile/image.html                           |   2 +-
 package-lock.json                                  | 132 +++----
 src/.DS_Store                                      | Bin 6148 -> 6148 bytes
 src/client/documents/Documents.ts                  |  12 +-
 src/client/util/TooltipTextMenu.scss               |   7 +-
 src/client/util/TooltipTextMenu.tsx                |   2 +-
 src/client/views/.DS_Store                         | Bin 6148 -> 8196 bytes
 src/client/views/ContextMenu.scss                  |  77 +++--
 src/client/views/ContextMenu.tsx                   |  16 +-
 src/client/views/DocumentDecorations.scss          |  85 ++++-
 src/client/views/DocumentDecorations.tsx           |  17 +-
 src/client/views/EditableView.scss                 |   6 +
 src/client/views/EditableView.tsx                  |   3 +-
 src/client/views/InkingCanvas.scss                 | 131 ++++++-
 src/client/views/InkingCanvas.tsx                  |  28 +-
 src/client/views/InkingControl.tsx                 |  66 +++-
 src/client/views/InkingStroke.tsx                  |   2 -
 src/client/views/Main.scss                         | 139 +++++++-
 src/client/views/Main.tsx                          |  96 ++++--
 src/client/views/_global_variables.scss            |  17 +
 src/client/views/_nodeModuleOverrides.scss         |  23 ++
 .../views/collections/CollectionFreeFormView.scss  | 104 ++++--
 .../views/collections/CollectionFreeFormView.tsx   |  20 +-
 .../views/collections/CollectionPDFView.scss       |  27 ++
 src/client/views/collections/CollectionPDFView.tsx |  26 +-
 .../views/collections/CollectionSchemaView.scss    | 383 +++++++++++----------
 .../views/collections/CollectionSchemaView.tsx     |  32 +-
 .../views/collections/CollectionTreeView.scss      |  32 +-
 .../views/collections/CollectionTreeView.tsx       |  25 +-
 .../views/collections/CollectionVideoView.scss     |  40 +++
 .../views/collections/CollectionVideoView.tsx      |  86 ++++-
 src/client/views/collections/CollectionView.tsx    |   9 +-
 src/client/views/collections/MarqueeView.tsx       |  49 ++-
 src/client/views/collections/PreviewCursor.tsx     |   8 +-
 src/client/views/nodes/AudioBox.tsx                |  12 +-
 src/client/views/nodes/DocumentContentsView.tsx    |  35 ++
 src/client/views/nodes/DocumentView.scss           |  44 +--
 src/client/views/nodes/DocumentView.tsx            |  22 +-
 src/client/views/nodes/FieldTextBox.scss           |  14 +-
 src/client/views/nodes/FormattedTextBox.scss       |  64 ++--
 src/client/views/nodes/FormattedTextBox.tsx        |   2 +-
 src/client/views/nodes/ImageBox.scss               |  25 +-
 src/client/views/nodes/ImageBox.tsx                |   2 +-
 src/client/views/nodes/KeyValueBox.scss            |  42 +--
 src/client/views/nodes/LinkBox.scss                |  42 ++-
 src/client/views/nodes/LinkBox.tsx                 |  19 +-
 src/client/views/nodes/LinkEditor.scss             |  22 +-
 src/client/views/nodes/LinkMenu.scss               |   1 +
 src/client/views/nodes/LinkMenu.tsx                |   4 +-
 src/client/views/nodes/PDFBox.scss                 |   2 +-
 src/client/views/nodes/PDFBox.tsx                  |   2 +-
 src/client/views/nodes/VideoBox.tsx                |  18 +-
 src/fields/KeyStore.ts                             |   3 +-
 54 files changed, 1453 insertions(+), 625 deletions(-)
 create mode 100644 src/client/views/EditableView.scss
 create mode 100644 src/client/views/_global_variables.scss
 create mode 100644 src/client/views/_nodeModuleOverrides.scss
 create mode 100644 src/client/views/collections/CollectionPDFView.scss
 create mode 100644 src/client/views/collections/CollectionVideoView.scss
 create mode 100644 src/client/views/nodes/DocumentContentsView.tsx

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/deploy/index.html b/deploy/index.html
index e0892662a..130da1cb9 100644
--- a/deploy/index.html
+++ b/deploy/index.html
@@ -2,7 +2,6 @@
 
 <head>
   <title>Dash Web</title>
-  <link href="https://fonts.googleapis.com/css?family=Fjalla+One|Hind+Siliguri:300" rel="stylesheet">
   <script src="https://cdnjs.cloudflare.com/ajax/libs/typescript/3.3.1/typescript.min.js"></script>
 </head>
 
diff --git a/deploy/mobile/image.html b/deploy/mobile/image.html
index 52fad97b0..ae39a5217 100644
--- a/deploy/mobile/image.html
+++ b/deploy/mobile/image.html
@@ -7,7 +7,7 @@
 
 <body>
     <div id="root">
-        <button> hi</button>
+        <p>Capture Image: <input type="file" accept="image/*" id="capture" capture="camera">
     </div>
     <script src="../imageUpload.js"></script>
 </body>
diff --git a/package-lock.json b/package-lock.json
index 9169ae4e9..da562298b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3707,24 +3707,24 @@
       "dependencies": {
         "abbrev": {
           "version": "1.1.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
           "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
           "optional": true
         },
         "ansi-regex": {
           "version": "2.1.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
           "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
         },
         "aproba": {
           "version": "1.2.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
           "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
           "optional": true
         },
         "are-we-there-yet": {
           "version": "1.1.5",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
           "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
           "optional": true,
           "requires": {
@@ -3734,12 +3734,12 @@
         },
         "balanced-match": {
           "version": "1.0.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
           "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
         },
         "brace-expansion": {
           "version": "1.1.11",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
           "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
           "requires": {
             "balanced-match": "^1.0.0",
@@ -3748,34 +3748,34 @@
         },
         "chownr": {
           "version": "1.1.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
           "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==",
           "optional": true
         },
         "code-point-at": {
           "version": "1.1.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
           "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
         },
         "concat-map": {
           "version": "0.0.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
           "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
         },
         "console-control-strings": {
           "version": "1.1.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
           "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
         },
         "core-util-is": {
           "version": "1.0.2",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
           "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
           "optional": true
         },
         "debug": {
           "version": "2.6.9",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
           "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
           "optional": true,
           "requires": {
@@ -3784,25 +3784,25 @@
         },
         "deep-extend": {
           "version": "0.6.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
           "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
           "optional": true
         },
         "delegates": {
           "version": "1.0.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
           "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
           "optional": true
         },
         "detect-libc": {
           "version": "1.0.3",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
           "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
           "optional": true
         },
         "fs-minipass": {
           "version": "1.2.5",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz",
           "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
           "optional": true,
           "requires": {
@@ -3811,13 +3811,13 @@
         },
         "fs.realpath": {
           "version": "1.0.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
           "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
           "optional": true
         },
         "gauge": {
           "version": "2.7.4",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
           "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
           "optional": true,
           "requires": {
@@ -3833,7 +3833,7 @@
         },
         "glob": {
           "version": "7.1.3",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
           "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
           "optional": true,
           "requires": {
@@ -3847,13 +3847,13 @@
         },
         "has-unicode": {
           "version": "2.0.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
           "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
           "optional": true
         },
         "iconv-lite": {
           "version": "0.4.24",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
           "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
           "optional": true,
           "requires": {
@@ -3862,7 +3862,7 @@
         },
         "ignore-walk": {
           "version": "3.0.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz",
           "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
           "optional": true,
           "requires": {
@@ -3871,7 +3871,7 @@
         },
         "inflight": {
           "version": "1.0.6",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
           "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
           "optional": true,
           "requires": {
@@ -3881,18 +3881,18 @@
         },
         "inherits": {
           "version": "2.0.3",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
           "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
         },
         "ini": {
           "version": "1.3.5",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
           "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
           "optional": true
         },
         "is-fullwidth-code-point": {
           "version": "1.0.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
           "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
           "requires": {
             "number-is-nan": "^1.0.0"
@@ -3900,13 +3900,13 @@
         },
         "isarray": {
           "version": "1.0.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
           "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
           "optional": true
         },
         "minimatch": {
           "version": "3.0.4",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
           "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
           "requires": {
             "brace-expansion": "^1.1.7"
@@ -3914,12 +3914,12 @@
         },
         "minimist": {
           "version": "0.0.8",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
           "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
         },
         "minipass": {
           "version": "2.3.5",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
           "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
           "requires": {
             "safe-buffer": "^5.1.2",
@@ -3928,7 +3928,7 @@
         },
         "minizlib": {
           "version": "1.2.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz",
           "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==",
           "optional": true,
           "requires": {
@@ -3937,7 +3937,7 @@
         },
         "mkdirp": {
           "version": "0.5.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
           "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
           "requires": {
             "minimist": "0.0.8"
@@ -3945,13 +3945,13 @@
         },
         "ms": {
           "version": "2.0.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
           "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
           "optional": true
         },
         "needle": {
           "version": "2.2.4",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.4.tgz",
           "integrity": "sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA==",
           "optional": true,
           "requires": {
@@ -3962,7 +3962,7 @@
         },
         "node-pre-gyp": {
           "version": "0.10.3",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz",
           "integrity": "sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A==",
           "optional": true,
           "requires": {
@@ -3980,7 +3980,7 @@
         },
         "nopt": {
           "version": "4.0.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
           "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
           "optional": true,
           "requires": {
@@ -3990,13 +3990,13 @@
         },
         "npm-bundled": {
           "version": "1.0.5",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.5.tgz",
           "integrity": "sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g==",
           "optional": true
         },
         "npm-packlist": {
           "version": "1.2.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.2.0.tgz",
           "integrity": "sha512-7Mni4Z8Xkx0/oegoqlcao/JpPCPEMtUvsmB0q7mgvlMinykJLSRTYuFqoQLYgGY8biuxIeiHO+QNJKbCfljewQ==",
           "optional": true,
           "requires": {
@@ -4006,7 +4006,7 @@
         },
         "npmlog": {
           "version": "4.1.2",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
           "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
           "optional": true,
           "requires": {
@@ -4018,18 +4018,18 @@
         },
         "number-is-nan": {
           "version": "1.0.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
           "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
         },
         "object-assign": {
           "version": "4.1.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
           "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
           "optional": true
         },
         "once": {
           "version": "1.4.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
           "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
           "requires": {
             "wrappy": "1"
@@ -4037,19 +4037,19 @@
         },
         "os-homedir": {
           "version": "1.0.2",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
           "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
           "optional": true
         },
         "os-tmpdir": {
           "version": "1.0.2",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
           "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
           "optional": true
         },
         "osenv": {
           "version": "0.1.5",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
           "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
           "optional": true,
           "requires": {
@@ -4059,19 +4059,19 @@
         },
         "path-is-absolute": {
           "version": "1.0.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
           "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
           "optional": true
         },
         "process-nextick-args": {
           "version": "2.0.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
           "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
           "optional": true
         },
         "rc": {
           "version": "1.2.8",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
           "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
           "optional": true,
           "requires": {
@@ -4083,7 +4083,7 @@
           "dependencies": {
             "minimist": {
               "version": "1.2.0",
-              "resolved": false,
+              "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
               "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
               "optional": true
             }
@@ -4091,7 +4091,7 @@
         },
         "readable-stream": {
           "version": "2.3.6",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
           "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
           "optional": true,
           "requires": {
@@ -4106,7 +4106,7 @@
         },
         "rimraf": {
           "version": "2.6.3",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
           "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
           "optional": true,
           "requires": {
@@ -4115,42 +4115,42 @@
         },
         "safe-buffer": {
           "version": "5.1.2",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
           "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
         },
         "safer-buffer": {
           "version": "2.1.2",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
           "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
           "optional": true
         },
         "sax": {
           "version": "1.2.4",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
           "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
           "optional": true
         },
         "semver": {
           "version": "5.6.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
           "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
           "optional": true
         },
         "set-blocking": {
           "version": "2.0.0",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
           "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
           "optional": true
         },
         "signal-exit": {
           "version": "3.0.2",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
           "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
           "optional": true
         },
         "string-width": {
           "version": "1.0.2",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
           "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
           "requires": {
             "code-point-at": "^1.0.0",
@@ -4160,7 +4160,7 @@
         },
         "string_decoder": {
           "version": "1.1.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
           "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
           "optional": true,
           "requires": {
@@ -4169,7 +4169,7 @@
         },
         "strip-ansi": {
           "version": "3.0.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
           "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
           "requires": {
             "ansi-regex": "^2.0.0"
@@ -4177,13 +4177,13 @@
         },
         "strip-json-comments": {
           "version": "2.0.1",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
           "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
           "optional": true
         },
         "tar": {
           "version": "4.4.8",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz",
           "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==",
           "optional": true,
           "requires": {
@@ -4198,13 +4198,13 @@
         },
         "util-deprecate": {
           "version": "1.0.2",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
           "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
           "optional": true
         },
         "wide-align": {
           "version": "1.1.3",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
           "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
           "optional": true,
           "requires": {
@@ -4213,12 +4213,12 @@
         },
         "wrappy": {
           "version": "1.0.2",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
           "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
         },
         "yallist": {
           "version": "3.0.3",
-          "resolved": false,
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
           "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A=="
         }
       }
diff --git a/src/.DS_Store b/src/.DS_Store
index f20f36d63..90213270f 100644
Binary files a/src/.DS_Store and b/src/.DS_Store differ
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index f35d553b1..05bc743be 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -23,10 +23,13 @@ import { PDFField } from "../../fields/PDFField";
 import { PDFBox } from "../views/nodes/PDFBox";
 import { CollectionPDFView } from "../views/collections/CollectionPDFView";
 import { RichTextField } from "../../fields/RichTextField";
+import { CollectionVideoView } from "../views/collections/CollectionVideoView";
+import { StrokeData, InkField } from "../../fields/InkField";
 
 export interface DocumentOptions {
     x?: number;
     y?: number;
+    ink?: Map<string, StrokeData>;
     width?: number;
     height?: number;
     nativeWidth?: number;
@@ -39,6 +42,7 @@ export interface DocumentOptions {
     layout?: string;
     layoutKeys?: Key[];
     viewType?: number;
+    backgroundColor?: string;
 }
 
 export namespace Documents {
@@ -82,8 +86,10 @@ export namespace Documents {
         if (options.page !== undefined) { doc.SetNumber(KeyStore.Page, options.page); }
         if (options.scale !== undefined) { doc.SetNumber(KeyStore.Scale, options.scale); }
         if (options.viewType !== undefined) { doc.SetNumber(KeyStore.ViewType, options.viewType); }
+        if (options.backgroundColor !== undefined) { doc.SetText(KeyStore.BackgroundColor, options.backgroundColor); }
         if (options.layout !== undefined) { doc.SetText(KeyStore.Layout, options.layout); }
         if (options.layoutKeys !== undefined) { doc.Set(KeyStore.LayoutKeys, new ListField(options.layoutKeys)); }
+        if (options.ink !== undefined) { doc.Set(KeyStore.Ink, new InkField(options.ink)); }
         return doc;
     }
     function setupPrototypeOptions(protoId: string, title: string, layout: string, options: DocumentOptions): Document {
@@ -128,7 +134,7 @@ export namespace Documents {
     function GetCollectionPrototype(): Document {
         return collProto ? collProto :
             collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("DataKey"),
-                { panx: 0, pany: 0, scale: 1, layoutKeys: [KeyStore.Data] });
+                { panx: 0, pany: 0, scale: 1, width: 500, height: 500, layoutKeys: [KeyStore.Data] });
     }
 
     function GetKVPPrototype(): Document {
@@ -138,9 +144,9 @@ export namespace Documents {
     }
     function GetVideoPrototype(): Document {
         if (!videoProto) {
-            videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionView.LayoutString("AnnotationsKey"),
+            videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("AnnotationsKey"),
                 { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] });
-            videoProto.SetNumber(KeyStore.CurFrame, 1);
+            videoProto.SetNumber(KeyStore.CurPage, 0);
             videoProto.SetText(KeyStore.BackgroundLayout, VideoBox.LayoutString());
         }
         return videoProto;
diff --git a/src/client/util/TooltipTextMenu.scss b/src/client/util/TooltipTextMenu.scss
index fa43f5326..ea580d104 100644
--- a/src/client/util/TooltipTextMenu.scss
+++ b/src/client/util/TooltipTextMenu.scss
@@ -1,8 +1,9 @@
+@import "../views/global_variables";
 
 .tooltipMenu {
     position: absolute;
     z-index: 20;
-    background: rgb(19, 18, 18);
+    background: $dark-color;
     border: 1px solid silver;
     border-radius: 4px;
     padding: 2px 10px;
@@ -31,14 +32,14 @@
     bottom: -4.5px;
     border: 5px solid transparent;
     border-bottom-width: 0;
-    border-top-color: black;
+    border-top-color: $dark-color;
   }
 
   .menuicon {
     display: inline-block;
     border-right: 1px solid rgba(0, 0, 0, 0.2);
     //color: rgb(19, 18, 18);
-    color: white;
+    color: $light-color;
     line-height: 1;
     padding: 0px 2px;
     margin: 1px;
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index 3b87fe9de..8cc653bf2 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -117,7 +117,7 @@ export class TooltipTextMenu {
     let width = Math.abs(start.left - end.left) / 2;
     let mid = Math.min(start.left, end.left) + width;
     //THIS WIDTH IS 15 * NUMBER OF ICONS + 15
-    this.tooltip.style.width = 120 + "px";
+    this.tooltip.style.width = 122 + "px";
     this.tooltip.style.bottom = (box.bottom - start.top) + "px";
   }
 
diff --git a/src/client/views/.DS_Store b/src/client/views/.DS_Store
index 6bd614c8b..0964d5ff3 100644
Binary files a/src/client/views/.DS_Store and b/src/client/views/.DS_Store differ
diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss
index 41994ef79..f6830d9cd 100644
--- a/src/client/views/ContextMenu.scss
+++ b/src/client/views/ContextMenu.scss
@@ -1,42 +1,55 @@
+@import "global_variables";
 .contextMenu-cont {
-    position: absolute;
-    display: flex;
-    z-index: 1000;
-    box-shadow: #AAAAAA .2vw .2vw .4vw;
-    flex-direction: column;
+  position: absolute;
+  display: flex;
+  z-index: 1000;
+  box-shadow: $intermediate-color 0.2vw 0.2vw 0.4vw;
+  flex-direction: column;
+}
+
+.contextMenu-item:first-child {
+  background: $intermediate-color;
+  color: $light-color;
+}
+
+.contextMenu-item:first-child::placeholder {
+  color: $light-color;
+}
+
+.contextMenu-item:first-child:hover {
+  background: $intermediate-color;
+  color: $light-color;
 }
 
 .contextMenu-item {
-    width: auto;
-    height: auto;
-    background: #F0F8FF;
-    display: flex;
-    justify-content: left;
-    align-items: center;
-    -webkit-touch-callout: none;
-    -webkit-user-select: none;
-    -khtml-user-select: none;
-    -moz-user-select: none;
-    -ms-user-select: none;
-    user-select: none;
-    transition: all .1s;
-    border-width: .11px;
-    border-style: none;
-    border-color: rgb(187, 186, 186);
-    border-bottom-style: solid;
-    padding: 10px;
-    white-space: nowrap;
-   // font-size: 1.5vw;
-   font-size: 12px;
+  width: auto;
+  height: auto;
+  background: $light-color-secondary;
+  display: flex;
+  justify-content: left;
+  align-items: center;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -khtml-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  transition: all 0.1s;
+  border-width: 0.11px;
+  border-style: none;
+  border-color: $intermediate-color;
+  border-bottom-style: solid;
+  padding: 10px;
+  white-space: nowrap;
+  font-size: 13px;
 }
 
 .contextMenu-item:hover {
-    transition: all .1s;
-    background: #B0E0E6;
+  transition: all 0.1s;
+  background: $lighter-alt-accent;
 }
 
 .contextMenu-description {
-   // font-size: 1.5vw;
-    text-align: left;
-   // width: 8vw;
-}
\ No newline at end of file
+  text-align: left;
+  width: 8vw;
+}
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx
index 12352c667..9109b56bb 100644
--- a/src/client/views/ContextMenu.tsx
+++ b/src/client/views/ContextMenu.tsx
@@ -13,6 +13,8 @@ export class ContextMenu extends React.Component {
     @observable private _pageY: number = 0;
     @observable private _display: string = "none";
     @observable private _searchString: string = "";
+    // afaik displaymenu can be called before all the items are added to the menu, so can't determine in displayMenu what the height of the menu will be
+    @observable private _yRelativeToTop: boolean = true;
 
 
     private ref: React.RefObject<HTMLDivElement>;
@@ -59,8 +61,13 @@ export class ContextMenu extends React.Component {
 
     intersects = (x: number, y: number): boolean => {
         if (this.ref.current && this._display !== "none") {
-            if (x >= this._pageX && x <= this._pageX + this.ref.current.getBoundingClientRect().width) {
-                if (y >= this._pageY && y <= this._pageY + this.ref.current.getBoundingClientRect().height) {
+            let menuSize = { width: this.ref.current.getBoundingClientRect().width, height: this.ref.current.getBoundingClientRect().height };
+
+            let upperLeft = { x: this._pageX, y: this._yRelativeToTop ? this._pageY : window.innerHeight - (this._pageY + menuSize.height) };
+            let bottomRight = { x: this._pageX + menuSize.width, y: this._yRelativeToTop ? this._pageY + menuSize.height : window.innerHeight - this._pageY };
+
+            if (x >= upperLeft.x && x <= bottomRight.x) {
+                if (y >= upperLeft.y && y <= bottomRight.y) {
                     return true;
                 }
             }
@@ -69,9 +76,12 @@ export class ContextMenu extends React.Component {
     }
 
     render() {
+        let style = this._yRelativeToTop ? { left: this._pageX, top: this._pageY, display: this._display } :
+            { left: this._pageX, bottom: this._pageY, display: this._display };
+
 
         return (
-            <div className="contextMenu-cont" style={{ left: this._pageX, top: this._pageY, display: this._display }} ref={this.ref}>
+            <div className="contextMenu-cont" style={style} ref={this.ref}>
                 <input className="contextMenu-item" type="text" placeholder="Search . . ." value={this._searchString} onChange={this.onChange}></input>
                 {this._items.filter(prop => {
                     return prop.description.toLowerCase().indexOf(this._searchString.toLowerCase()) !== -1;
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index fb9091dfc..11595aa01 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -1,17 +1,18 @@
+@import "global_variables";
 #documentDecorations-container {
     position: absolute;
     display: grid;
     z-index: 1000;
-    grid-template-rows: 20px 1fr 20px 0px;
-    grid-template-columns: 20px 1fr 20px;
+    grid-template-rows: 8px 1fr 8px 30px;
+    grid-template-columns: 8px 1fr 8px;
     pointer-events: none;
     #documentDecorations-centerCont {
         background: none;
     }
     .documentDecorations-resizer {
         pointer-events: auto;
-        background: lightblue;
-        opacity: 0.4;
+        background: $alt-accent;
+        opacity: 0.8;
     }
     #documentDecorations-topLeftResizer,
     #documentDecorations-bottomRightResizer {
@@ -29,23 +30,89 @@
     #documentDecorations-rightResizer {
         cursor: ew-resize;
     }
-    
 }
+
+//     position: absolute;
+//     display: grid;
+//     z-index: 1000;
+//     grid-template-rows: 20px 1fr 20px 0px;
+//     grid-template-columns: 20px 1fr 20px;
+//     pointer-events: none;
+//     #documentDecorations-centerCont {
+//         background: none;
+//     }
+//     .documentDecorations-resizer {
+//         pointer-events: auto;
+//         background: lightblue;
+//         opacity: 0.4;
+//     }
+//     #documentDecorations-topLeftResizer,
+//     #documentDecorations-bottomRightResizer {
+//         cursor: nwse-resize;
+//     }
+//     #documentDecorations-topRightResizer,
+//     #documentDecorations-bottomLeftResizer {
+//         cursor: nesw-resize;
+//     }
+//     #documentDecorations-topResizer,
+//     #documentDecorations-bottomResizer {
+//         cursor: ns-resize;
+//     }
+//     #documentDecorations-leftResizer,
+//     #documentDecorations-rightResizer {
+//         cursor: ew-resize;
+//     }
+// }
+.linkFlyout {
+    grid-column: 1/4
+}
+
+.linkButton-empty:hover {
+    background: $main-accent;
+    transform: scale(1.05);
+    cursor: pointer;
+}
+
+.linkButton-nonempty:hover {
+    background: $main-accent;
+    transform: scale(1.05);
+    cursor: pointer;
+}
+
 .linkButton-empty {
     height: 20px;
     width: 20px;
     margin-top: 10px;
     border-radius: 50%;
-    opacity: 0.6;
+    opacity: 0.9;
     pointer-events: auto;
-    background-color: #2B6091;
+    background-color: $dark-color;
+    color: $light-color;
+    text-transform: uppercase;
+    letter-spacing: 2px;
+    font-size: 75%;
+    transition: transform 0.2s;
+    text-align: center;
+    display: flex;
+    justify-content: center;
+    align-items: center;
 }
+
 .linkButton-nonempty {
     height: 20px;
     width: 20px;
     margin-top: 10px;
     border-radius: 50%;
-    opacity: 0.6;
+    opacity: 0.9;
     pointer-events: auto;
-    background-color: rgb(35, 165, 42);
+    background-color: $dark-color;
+    color: $light-color;
+    text-transform: uppercase;
+    letter-spacing: 2px;
+    font-size: 75%;
+    transition: transform 0.2s;
+    text-align: center;
+    display: flex;
+    justify-content: center;
+    align-items: center;
 }
\ No newline at end of file
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index dc62f97cf..3bdb7d5b3 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -18,6 +18,8 @@ export class DocumentDecorations extends React.Component {
     static Instance: DocumentDecorations
     private _resizer = ""
     private _isPointerDown = false;
+
+    private _resizeBorderWidth = 16;
     private _linkButton = React.createRef<HTMLDivElement>();
     @observable private _hidden = false;
 
@@ -206,21 +208,24 @@ export class DocumentDecorations extends React.Component {
         let linkButton = null;
         if (SelectionManager.SelectedDocuments().length > 0) {
             let selFirst = SelectionManager.SelectedDocuments()[0];
+            let linkToSize = selFirst.props.Document.GetData(KeyStore.LinkedToDocs, ListField, []).length;
+            let linkFromSize = selFirst.props.Document.GetData(KeyStore.LinkedFromDocs, ListField, []).length;
+            let linkCount = linkToSize + linkFromSize;
             linkButton = (<Flyout
                 anchorPoint={anchorPoints.RIGHT_TOP}
                 content={
                     <LinkMenu docView={selFirst} changeFlyout={this.changeFlyoutContent}>
                     </LinkMenu>
                 }>
-                <div className={"linkButton-" + (selFirst.props.Document.GetData(KeyStore.LinkedToDocs, ListField, []).length ? "nonempty" : "empty")} onPointerDown={this.onLinkButtonDown} ref={this._linkButton} />
+                <div className={"linkButton-" + (selFirst.props.Document.GetData(KeyStore.LinkedToDocs, ListField, []).length ? "nonempty" : "empty")} onPointerDown={this.onLinkButtonDown} ref={this._linkButton}>{linkCount}</div>
             </Flyout>);
         }
         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,
+                width: (bounds.r - bounds.x + this._resizeBorderWidth) + "px",
+                height: (bounds.b - bounds.y + this._resizeBorderWidth + 30) + "px",
+                left: bounds.x - this._resizeBorderWidth / 2,
+                top: bounds.y - this._resizeBorderWidth / 2,
             }}>
                 <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>
@@ -232,7 +237,7 @@ export class DocumentDecorations extends React.Component {
                 <div id="documentDecorations-bottomResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
                 <div id="documentDecorations-bottomRightResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
 
-                {linkButton}
+                <div title="View Links" className="linkFlyout">{linkButton}</div>
 
             </div >
         )
diff --git a/src/client/views/EditableView.scss b/src/client/views/EditableView.scss
new file mode 100644
index 000000000..be3c5069a
--- /dev/null
+++ b/src/client/views/EditableView.scss
@@ -0,0 +1,6 @@
+.editableView-container-editing {
+    overflow-wrap: break-word;
+    word-wrap: break-word;
+    hyphens: auto;
+    max-width: 300px;
+}
\ No newline at end of file
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 84b1b91c3..3b54c0dbb 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -1,6 +1,7 @@
 import React = require('react')
 import { observer } from 'mobx-react';
 import { observable, action } from 'mobx';
+import "./EditableView.scss"
 
 export interface EditableProps {
     /**
@@ -49,7 +50,7 @@ export class EditableView extends React.Component<EditableProps> {
                 style={{ display: "inline" }}></input>
         } else {
             return (
-                <div className="editableView-container-editing" style={{ display: "inline", height: "100%", maxHeight: `${this.props.height}` }}
+                <div className="editableView-container-editing" style={{ display: "inline", height: "auto", maxHeight: `${this.props.height}` }}
                     onClick={action(() => this.editing = true)}>
                     {this.props.contents}
                 </div>
diff --git a/src/client/views/InkingCanvas.scss b/src/client/views/InkingCanvas.scss
index f654b194b..e79b146b9 100644
--- a/src/client/views/InkingCanvas.scss
+++ b/src/client/views/InkingCanvas.scss
@@ -1,8 +1,10 @@
+@import "global_variables";
 .inking-canvas {
-    position: fixed;
+    position: absolute;
     top: -50000px;
     left: -50000px; // z-index: 99; //overlays ink on top of everything
     svg {
+        position:absolute;
         width: 100000px;
         height: 100000px;
         .highlight {
@@ -13,20 +15,135 @@
 
 .inking-control {
     position: absolute;
-    right: 0;
-    bottom: 75px;
-    text-align: right;
+    left: 70px;
+    bottom: 70px;
+    margin: 0;
+    padding: 0;
+    display: flex;
+    label,
+    input,
+    option {
+        font-size: 12px;
+    }
+    input[type="range"] {
+        -webkit-appearance: none;
+        background-color: transparent;
+        vertical-align: middle;
+        margin-top: 8px;
+        &:focus {
+            outline: none;
+        }
+        &::-webkit-slider-runnable-track {
+            width: 100%;
+            height: 3px;
+            border-radius: 1.5px;
+            cursor: pointer;
+            background: $intermediate-color;
+        }
+        &::-webkit-slider-thumb {
+            height: 12px;
+            width: 12px;
+            border: 1px solid $intermediate-color;
+            border-radius: 6px;
+            background: $light-color;
+            cursor: pointer;
+            -webkit-appearance: none;
+            margin-top: -4px;
+        }
+        &::-moz-range-track {
+            width: 100%;
+            height: 3px;
+            border-radius: 1.5px;
+            cursor: pointer;
+            background: $light-color;
+        }
+        &::-moz-range-thumb {
+            height: 12px;
+            width: 12px;
+            border: 1px solid $intermediate-color;
+            border-radius: 6px;
+            background: $light-color;
+            cursor: pointer;
+            -webkit-appearance: none;
+            margin-top: -4px;
+        }
+    }
+    input[type="text"] {
+        border: none;
+        padding: 0 0px;
+        background: transparent;
+        color: $dark-color;
+        font-size: 12px;
+        margin-top: 4px;
+    }
     .ink-panel {
-        margin-top: 12px;
+        margin: 6px 12px 6px 0;
+        height: 30px;
+        vertical-align: middle;
+        line-height: 36px;
+        padding: 0 10px;
+        color: $intermediate-color;
         &:first {
             margin-top: 0;
         }
     }
+    .ink-tools {
+        display: flex;
+        background-color: transparent;
+        border-radius: 0;
+        padding: 0;
+        button {
+            height: 36px;
+            padding: 0px;
+            padding-bottom: 3px;
+            margin-left: 10px;
+            background-color: transparent;
+            color: $intermediate-color;
+        }
+        button:hover {
+            transform: scale(1.15);
+        }
+    }
     .ink-size {
         display: flex;
         justify-content: space-between;
-        input {
-            width: 85%;
+        input[type="text"] {
+            width: 42px;
+        }
+        >* {
+            margin-right: 6px;
+            &:last-child {
+                margin-right: 0;
+            }
+        }
+    }
+    .ink-color {
+        display: flex;
+        position: relative;
+        padding-right: 0;
+        label {
+            margin-right: 6px;
+        }
+        .ink-color-display {
+            border-radius: 11px;
+            width: 22px;
+            height: 22px;
+            margin-top: 6px;
+            cursor: pointer;
+            text-align: center; //   span {
+            //     color: $light-color;
+            //     font-size: 8px;
+            //     user-select: none;
+            //   }
+        }
+        .ink-color-picker {
+            background-color: $light-color;
+            border-radius: 5px;
+            padding: 12px;
+            position: absolute;
+            bottom: 36px;
+            left: -3px;
+            box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw;
         }
     }
 }
\ No newline at end of file
diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx
index 0d87c1239..84c47f616 100644
--- a/src/client/views/InkingCanvas.tsx
+++ b/src/client/views/InkingCanvas.tsx
@@ -1,4 +1,5 @@
 import { observer } from "mobx-react";
+import { observable } from "mobx";
 import { action, computed } from "mobx";
 import { InkingControl } from "./InkingControl";
 import React = require("react");
@@ -6,14 +7,10 @@ import { Transform } from "../util/Transform";
 import { Document } from "../../fields/Document";
 import { KeyStore } from "../../fields/KeyStore";
 import { InkField, InkTool, StrokeData, StrokeMap } from "../../fields/InkField";
-import { JsxArgs } from "./nodes/DocumentView";
 import { InkingStroke } from "./InkingStroke";
 import "./InkingCanvas.scss"
-import { CollectionDockingView } from "./collections/CollectionDockingView";
 import { Utils } from "../../Utils";
 import { FieldWaiting } from "../../fields/Field";
-import { getMapLikeKeys } from "mobx/lib/internal";
-
 
 interface InkCanvasProps {
     getScreenTransform: () => Transform;
@@ -22,7 +19,16 @@ interface InkCanvasProps {
 
 @observer
 export class InkingCanvas extends React.Component<InkCanvasProps> {
-
+    static InkOffset: number = 50000;
+    public static IntersectStrokeRect(stroke: StrokeData, selRect: { left: number, top: number, width: number, height: number }): boolean {
+        let inside = false;
+        stroke.pathData.map(val => {
+            if (selRect.left < val.x - InkingCanvas.InkOffset && selRect.left + selRect.width > val.x - InkingCanvas.InkOffset &&
+                selRect.top < val.y - InkingCanvas.InkOffset && selRect.top + selRect.height > val.y - InkingCanvas.InkOffset)
+                inside = true;
+        });
+        return inside
+    }
     private _isDrawing: boolean = false;
     private _idGenerator: string = "";
 
@@ -51,7 +57,6 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
         document.removeEventListener("mouseup", this.handleMouseUp);
     }
 
-
     @action
     handleMouseDown = (e: React.PointerEvent): void => {
         if (e.button != 0 ||
@@ -62,7 +67,6 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
         if (InkingControl.Instance.selectedTool === InkTool.Eraser) {
             return
         }
-        e.stopPropagation()
         const point = this.relativeCoordinatesForEvent(e);
 
         // start the new line, saves a uuid to represent the field of the stroke
@@ -74,7 +78,7 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
                 color: InkingControl.Instance.selectedColor,
                 width: InkingControl.Instance.selectedWidth,
                 tool: InkingControl.Instance.selectedTool,
-                page: this.props.Document.GetNumber(KeyStore.CurPage, 0)
+                page: this.props.Document.GetNumber(KeyStore.CurPage, -1)
             });
         this.inkData = data;
         this._isDrawing = true;
@@ -110,8 +114,8 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
 
     relativeCoordinatesForEvent = (e: React.MouseEvent): { x: number, y: number } => {
         let [x, y] = this.props.getScreenTransform().transformPoint(e.clientX, e.clientY);
-        x += 50000
-        y += 50000
+        x += InkingCanvas.InkOffset;
+        y += InkingCanvas.InkOffset;
         return { x, y };
     }
 
@@ -145,11 +149,11 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
 
         // parse data from server
         let paths: Array<JSX.Element> = []
-        let curPage = this.props.Document.GetNumber(KeyStore.CurPage, 0)
+        let curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1)
         Array.from(lines).map(item => {
             let id = item[0];
             let strokeData = item[1];
-            if (strokeData.page == 0 || strokeData.page == curPage)
+            if (strokeData.page == -1 || strokeData.page == curPage)
                 paths.push(<InkingStroke key={id} id={id}
                     line={strokeData.pathData}
                     color={strokeData.color}
diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx
index 955831fb6..fb75ef2a5 100644
--- a/src/client/views/InkingControl.tsx
+++ b/src/client/views/InkingControl.tsx
@@ -1,16 +1,25 @@
 import { observable, action, computed } from "mobx";
-import { CirclePicker, ColorResult } from 'react-color';
+
+import { CirclePicker, ColorResult } from 'react-color'
 import React = require("react");
 import "./InkingCanvas.scss"
 import { InkTool } from "../../fields/InkField";
 import { observer } from "mobx-react";
+import "./InkingCanvas.scss"
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faPen, faHighlighter, faEraser, faBan } from '@fortawesome/free-solid-svg-icons';
+
+library.add(faPen, faHighlighter, faEraser, faBan);
 
 @observer
 export class InkingControl extends React.Component {
     static Instance: InkingControl = new InkingControl({});
     @observable private _selectedTool: InkTool = InkTool.None;
-    @observable private _selectedColor: string = "#f44336";
+    @observable private _selectedColor: string = "rgb(244, 67, 54)";
     @observable private _selectedWidth: string = "25";
+    @observable private _open: boolean = false;
+    @observable private _colorPickerDisplay: boolean = false;
 
     constructor(props: Readonly<{}>) {
         super(props);
@@ -49,29 +58,50 @@ export class InkingControl extends React.Component {
 
     selected = (tool: InkTool) => {
         if (this._selectedTool === tool) {
-            return { backgroundColor: "black", color: "white" }
+            return { color: "#61aaa3" }
         }
         return {}
     }
 
+    @action
+    toggleDisplay = () => {
+        this._open = !this._open;
+    }
+
+    @action
+    toggleColorPicker = () => {
+        this._colorPickerDisplay = !this._colorPickerDisplay;
+    }
+
     render() {
         return (
-            <div className="inking-control">
-                <div className="ink-tools ink-panel">
-                    <button onClick={() => this.switchTool(InkTool.Pen)} style={this.selected(InkTool.Pen)}>Pen</button>
-                    <button onClick={() => this.switchTool(InkTool.Highlighter)} style={this.selected(InkTool.Highlighter)}>Highlighter</button>
-                    <button onClick={() => this.switchTool(InkTool.Eraser)} style={this.selected(InkTool.Eraser)}>Eraser</button>
-                    <button onClick={() => this.switchTool(InkTool.None)} style={this.selected(InkTool.None)}> None</button>
-                </div>
-                <div className="ink-size ink-panel">
-                    <label htmlFor="stroke-width">Size</label>
-                    <input type="range" min="1" max="100" defaultValue="25" name="stroke-width"
+            <ul className="inking-control" style={this._open ? { display: "flex" } : { display: "none" }}>
+                <li className="ink-tools ink-panel">
+                    <div className="ink-tool-buttons">
+                        <button onClick={() => this.switchTool(InkTool.Pen)} style={this.selected(InkTool.Pen)}><FontAwesomeIcon icon="pen" size="lg" title="Pen" /></button>
+                        <button onClick={() => this.switchTool(InkTool.Highlighter)} style={this.selected(InkTool.Highlighter)}><FontAwesomeIcon icon="highlighter" size="lg" title="Highlighter" /></button>
+                        <button onClick={() => this.switchTool(InkTool.Eraser)} style={this.selected(InkTool.Eraser)}><FontAwesomeIcon icon="eraser" size="lg" title="Eraser" /></button>
+                        <button onClick={() => this.switchTool(InkTool.None)} style={this.selected(InkTool.None)}><FontAwesomeIcon icon="ban" size="lg" title="Pointer" /></button>
+                    </div>
+                </li>
+                <li className="ink-color ink-panel">
+                    <label>COLOR: </label>
+                    <div className="ink-color-display" style={{ backgroundColor: this._selectedColor }}
+                        onClick={() => this.toggleColorPicker()}>
+                        {/* {this._colorPickerDisplay ? <span>&#9660;</span> : <span>&#9650;</span>} */}
+                    </div>
+                    <div className="ink-color-picker" style={this._colorPickerDisplay ? { display: "block" } : { display: "none" }}>
+                        <CirclePicker onChange={this.switchColor} circleSize={22} width={"220"} />
+                    </div>
+                </li>
+                <li className="ink-size ink-panel">
+                    <label htmlFor="stroke-width">SIZE: </label>
+                    <input type="text" min="1" max="100" value={this._selectedWidth} name="stroke-width"
+                        onChange={(e: React.ChangeEvent<HTMLInputElement>) => this.switchWidth(e.target.value)} />
+                    <input type="range" min="1" max="100" value={this._selectedWidth} name="stroke-width"
                         onChange={(e: React.ChangeEvent<HTMLInputElement>) => this.switchWidth(e.target.value)} />
-                </div>
-                <div className="ink-color ink-panel">
-                    <CirclePicker onChange={this.switchColor} />
-                </div>
-            </div>
+                </li>
+            </ul >
         )
     }
 }
\ No newline at end of file
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index d724421d3..87b5c43d8 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -21,8 +21,6 @@ export class InkingStroke extends React.Component<StrokeProps> {
     @observable private _strokeColor: string = this.props.color;
     @observable private _strokeWidth: string = this.props.width;
 
-    private _canvasColor: string = "#cdcdcd";
-
     deleteStroke = (e: React.MouseEvent): void => {
         if (InkingControl.Instance.selectedTool === InkTool.Eraser && e.buttons === 1) {
             this.props.deleteCallback(this.props.id);
diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss
index 2b1c77b74..bb42db202 100644
--- a/src/client/views/Main.scss
+++ b/src/client/views/Main.scss
@@ -1,22 +1,35 @@
+@import "global_variables";
+@import "nodeModuleOverrides";
 html,
 body {
     width: 100%;
     height: 100%;
     overflow: hidden;
-    font-family: 'Hind Siliguri', sans-serif;
+    font-family: $sans-serif;
     margin: 0;
 }
 
+#dash-title {
+    position: absolute;
+    right: 46.5%;
+    letter-spacing: 3px;
+    top: 9px;
+    font-size: 12px;
+    color: $alt-accent;
+    z-index: 9999;
+}
+
 h1 {
     font-size: 50px;
     position: fixed;
     top: 30px;
     left: 50%;
     transform: translateX(-50%);
-    color: black;
+    color: $dark-color;
     text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff;
     z-index: 9999;
-    font-family: 'Fjalla One', sans-serif;
+    font-family: $sans-serif;
+    font-weight: 700;
     -webkit-touch-callout: none;
     -webkit-user-select: none;
     -khtml-user-select: none;
@@ -33,23 +46,131 @@ p {
     margin: 0px;
     padding: 0px;
 }
+
 ::-webkit-scrollbar {
     -webkit-appearance: none;
-    height:5px;
-    width:5px;
+    height: 5px;
+    width: 5px;
 }
+
 ::-webkit-scrollbar-thumb {
     border-radius: 2px;
-    background-color: rgba(0,0,0,.5);
+    background-color: rgba(0, 0, 0, 0.5);
+}
+
+// button stuff
+button {
+    background: $dark-color;
+    outline: none;
+    border: 0px;
+    color: $light-color;
+    text-transform: uppercase;
+    letter-spacing: 2px;
+    font-size: 75%;
+    padding: 10px;
+    transition: transform 0.2s;
+}
+
+button:hover {
+    background: $main-accent;
+    transform: scale(1.05);
+    cursor: pointer;
 }
 
-.main-buttonDiv {
+.clear-db-button {
     position: absolute;
-    width: 150px;
-    left: 0px;
+    right: 45%;
+    bottom: 3%;
+    font-size: 50%;
+}
+
+.round-button {
+    width: 36px;
+    height: 36px;
+    border-radius: 18px;
+    font-size: 15px;
+}
+
+.round-button:hover {
+    transform: scale(1.15);
+}
+
+.add-button {
+    position: relative;
+    margin-right: 10px;
 }
+
 .main-undoButtons {
     position: absolute;
     width: 150px;
     right: 0px;
 }
+
+//toolbar stuff
+#toolbar {
+    position: absolute;
+    bottom: 62px;
+    left: 24px;
+    .toolbar-button {
+        display: block;
+        margin-bottom: 10px;
+    }
+}
+
+// add nodes menu. Note that the + button is actually an input label, not an actual button.
+#add-nodes-menu {
+    position: absolute;
+    bottom: 24px;
+    left: 24px;
+    label {
+        background: $dark-color;
+        color: $light-color;
+        display: inline-block;
+        border-radius: 18px;
+        font-size: 25px;
+        width: 36px;
+        height: 36px;
+        margin-right: 10px;
+        cursor: pointer;
+        transition: transform 0.2s;
+    }
+    label p {
+        padding-left: 10.5px;
+        padding-top: 3px;
+    }
+    label:hover {
+        background: $main-accent;
+        transform: scale(1.15);
+    }
+    input {
+        display: none;
+    }
+    input:not(:checked)~#add-options-content {
+        display: none;
+    }
+    input:checked~label {
+        transform: rotate(45deg);
+        transition: transform 0.5s;
+        cursor: pointer;
+    }
+}
+
+#add-options-content {
+    display: table;
+    opacity: 1;
+    margin: 0;
+    padding: 0;
+    position: relative;
+    float: right;
+    bottom: 0.3em;
+    margin-bottom: -1.68em;
+}
+
+ul#add-options-list {
+    list-style: none;
+    padding: 0;
+    li {
+        display: inline-block;
+        padding: 0;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 95bf9cad0..3a68b98ce 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -18,6 +18,19 @@ import { DocumentDecorations } from './DocumentDecorations';
 import { DocumentView } from './nodes/DocumentView';
 import "./Main.scss";
 import { InkingControl } from './InkingControl';
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faFont } from '@fortawesome/free-solid-svg-icons';
+import { faImage } from '@fortawesome/free-solid-svg-icons';
+import { faFilePdf } from '@fortawesome/free-solid-svg-icons';
+import { faObjectGroup } from '@fortawesome/free-solid-svg-icons';
+import { faTable } from '@fortawesome/free-solid-svg-icons';
+import { faGlobeAsia } from '@fortawesome/free-solid-svg-icons';
+import { faUndoAlt } from '@fortawesome/free-solid-svg-icons';
+import { faRedoAlt } from '@fortawesome/free-solid-svg-icons';
+import { faPenNib } from '@fortawesome/free-solid-svg-icons';
+import { faFilm } from '@fortawesome/free-solid-svg-icons';
+import { faMusic } from '@fortawesome/free-solid-svg-icons';
 
 
 configure({ enforceActions: "observed" });  // causes errors to be generated when modifying an observable outside of an action
@@ -29,10 +42,22 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) {
     }
 }), true)
 
-
 const mainDocId = "mainDoc";
 let mainContainer: Document;
 let mainfreeform: Document;
+
+library.add(faFont);
+library.add(faImage);
+library.add(faFilePdf);
+library.add(faObjectGroup);
+library.add(faTable);
+library.add(faGlobeAsia);
+library.add(faUndoAlt);
+library.add(faRedoAlt);
+library.add(faPenNib);
+library.add(faFilm);
+library.add(faMusic);
+
 Documents.initProtos(mainDocId, (res?: Document) => {
     if (res instanceof Document) {
         mainContainer = res;
@@ -80,6 +105,8 @@ Documents.initProtos(mainDocId, (res?: Document) => {
 
     ReactDOM.render((
         <div style={{ position: "absolute", width: "100%", height: "100%" }}>
+            {/* <div id="dash-title">— DASH —</div> */}
+
             <DocumentView Document={mainContainer}
                 AddDocument={undefined} RemoveDocument={undefined} ScreenToLocalTransform={() => Transform.Identity}
                 ContentScaling={() => 1}
@@ -91,27 +118,52 @@ Documents.initProtos(mainDocId, (res?: Document) => {
                 ContainingCollectionView={undefined} />
             <DocumentDecorations />
             <ContextMenu />
-            <div className="main-buttonDiv" style={{ bottom: '0px' }} ref={imgRef} >
-                <button onPointerDown={setupDrag(imgRef, addImageNode)} onClick={addClick(addImageNode)}>Add Image</button></div>
-            <div className="main-buttonDiv" style={{ bottom: '25px' }} ref={webRef} >
-                <button onPointerDown={setupDrag(webRef, addWebNode)} onClick={addClick(addWebNode)}>Add Web</button></div>
-            <div className="main-buttonDiv" style={{ bottom: '50px' }} ref={textRef}>
-                <button onPointerDown={setupDrag(textRef, addTextNode)} onClick={addClick(addTextNode)}>Add Text</button></div>
-            <div className="main-buttonDiv" style={{ bottom: '75px' }} ref={colRef}>
-                <button onPointerDown={setupDrag(colRef, addColNode)} onClick={addClick(addColNode)}>Add Collection</button></div>
-            <div className="main-buttonDiv" style={{ bottom: '100px' }} ref={schemaRef}>
-                <button onPointerDown={setupDrag(schemaRef, addSchemaNode)} onClick={addClick(addSchemaNode)}>Add Schema</button></div>
-            <div className="main-buttonDiv" style={{ bottom: '125px' }} >
-                <button onClick={clearDatabase}>Clear Database</button></div>
-            <div className="main-buttonDiv" style={{ bottom: '175px' }} ref={videoRef}>
-                <button onPointerDown={setupDrag(videoRef, addVideoNode)} onClick={addClick(addVideoNode)}>Add Videoooo</button></div>
-            <div className="main-buttonDiv" style={{ bottom: '200px' }} ref={audioRef}>
-                <button onPointerDown={setupDrag(audioRef, addAudioNode)} onClick={addClick(addAudioNode)}>Add Audio</button></div>
-            <div className="main-buttonDiv" style={{ bottom: '150px' }} ref={pdfRef}>
-                <button onPointerDown={setupDrag(pdfRef, addPDFNode)} onClick={addClick(addPDFNode)}>Add PDF</button></div>
-            <button className="main-undoButtons" style={{ bottom: '25px' }} onClick={() => UndoManager.Undo()}>Undo</button>
-            <button className="main-undoButtons" style={{ bottom: '0px' }} onClick={() => UndoManager.Redo()}>Redo</button>
+            <button className="clear-db-button" onClick={clearDatabase}>Clear Database</button>
+
+            {/* @TODO this should really be moved into a moveable toolbar component, but for now let's put it here to meet the deadline */}
+            < div id="toolbar" >
+                <button className="toolbar-button round-button" title="Undo" onClick={() => UndoManager.Undo()}><FontAwesomeIcon icon="undo-alt" size="sm" /></button>
+                <button className="toolbar-button round-button" title="Redo" onClick={() => UndoManager.Redo()}><FontAwesomeIcon icon="redo-alt" size="sm" /></button>
+                <button className="toolbar-button round-button" title="Ink" onClick={() => InkingControl.Instance.toggleDisplay()}><FontAwesomeIcon icon="pen-nib" size="sm" /></button>
+            </div >
+
+            {/* for the expandable add nodes menu. Not included with the above because once it expands it expands the whole div with it, making canvas interactions limited. */}
+            < div id="add-nodes-menu" >
+                <input type="checkbox" id="add-menu-toggle" />
+                <label htmlFor="add-menu-toggle" title="Add Node"><p>+</p></label>
+
+                <div id="add-options-content">
+                    <ul id="add-options-list">
+                        <li><div ref={textRef}><button className="round-button add-button" title="Add Textbox" onPointerDown={setupDrag(textRef, addTextNode)} onClick={addClick(addTextNode)}>
+                            <FontAwesomeIcon icon="font" size="sm" />
+                        </button></div></li>
+                        <li><div ref={imgRef}><button className="round-button add-button" title="Add Image" onPointerDown={setupDrag(imgRef, addImageNode)} onClick={addClick(addImageNode)}>
+                            <FontAwesomeIcon icon="image" size="sm" />
+                        </button></div></li>
+                        <li><div ref={pdfRef}><button className="round-button add-button" title="Add PDF" onPointerDown={setupDrag(pdfRef, addPDFNode)} onClick={addClick(addPDFNode)}>
+                            <FontAwesomeIcon icon="file-pdf" size="sm" />
+                        </button></div></li>
+                        <li><div ref={videoRef}><button className="round-button add-button" title="Add Video" onPointerDown={setupDrag(videoRef, addVideoNode)} onClick={addClick(addVideoNode)}>
+                            <FontAwesomeIcon icon="film" size="sm" />
+                        </button></div></li>
+                        <li><div ref={audioRef}><button className="round-button add-button" title="Add Audio" onPointerDown={setupDrag(audioRef, addAudioNode)} onClick={addClick(addAudioNode)}>
+                            <FontAwesomeIcon icon="music" size="sm" />
+                        </button></div></li>
+                        <li><div ref={webRef}><button className="round-button add-button" title="Add Web Clipping" onPointerDown={setupDrag(webRef, addWebNode)} onClick={addClick(addWebNode)}>
+                            <FontAwesomeIcon icon="globe-asia" size="sm" />
+                        </button></div></li>
+                        <li><div ref={colRef}><button className="round-button add-button" title="Add Collection" onPointerDown={setupDrag(colRef, addColNode)} onClick={addClick(addColNode)}>
+                            <FontAwesomeIcon icon="object-group" size="sm" />
+                        </button></div></li>
+                        <li><div ref={schemaRef}><button className="round-button add-button" title="Add Schema" onPointerDown={setupDrag(schemaRef, addSchemaNode)} onClick={addClick(addSchemaNode)}>
+                            <FontAwesomeIcon icon="table" size="sm" />
+                        </button></div></li>
+                    </ul>
+                </div>
+
+            </div >
+
             <InkingControl />
-        </div>),
+        </div >),
         document.getElementById('root'));
 })
diff --git a/src/client/views/_global_variables.scss b/src/client/views/_global_variables.scss
new file mode 100644
index 000000000..44a819b79
--- /dev/null
+++ b/src/client/views/_global_variables.scss
@@ -0,0 +1,17 @@
+@import url("https://fonts.googleapis.com/css?family=Noto+Sans:400,700|Crimson+Text:400,400i,700");
+// colors
+$light-color: #fcfbf7;
+$light-color-secondary: rgb(241, 239, 235);
+$main-accent: #61aaa3;
+// $alt-accent: #cdd5ec;
+// $alt-accent: #cdeceb;
+$alt-accent: #59dff7;
+$lighter-alt-accent: rgb(207, 220, 240);
+$intermediate-color: #9c9396;
+$dark-color: #121721;
+// fonts
+$sans-serif: "Noto Sans", sans-serif;
+// $sans-serif: "Roboto Slab", sans-serif;
+$serif: "Crimson Text", serif;
+// misc values
+$border-radius: 0.3em;
diff --git a/src/client/views/_nodeModuleOverrides.scss b/src/client/views/_nodeModuleOverrides.scss
new file mode 100644
index 000000000..6f97e60f8
--- /dev/null
+++ b/src/client/views/_nodeModuleOverrides.scss
@@ -0,0 +1,23 @@
+// this file is for overriding all the css from installed node modules
+
+// goldenlayout stuff
+div .lm_header {
+  background: $dark-color;
+  min-height: 2em;
+}
+
+.lm_tab {
+  margin-top: 0.6em !important;
+  padding-top: 0.5em !important;
+  min-height: 1.35em;
+  padding-bottom: 0px;
+  border-radius: 5px;
+  font-family: $sans-serif !important;
+}
+
+.lm_header .lm_controls {
+  right: 1em !important;
+}
+
+// @TODO the ril__navgiation buttons in the img gallery are a lil messed up but I can't figure out
+// why. Low priority for now but it's bugging me. --Julie
diff --git a/src/client/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss
index d472cc5c4..9c7a03b52 100644
--- a/src/client/views/collections/CollectionFreeFormView.scss
+++ b/src/client/views/collections/CollectionFreeFormView.scss
@@ -1,29 +1,56 @@
+@import "../global_variables";
+
 .collectionfreeformview-container {
+  .collectionfreeformview > .jsx-parser {
+    position: absolute;
+    height: 100%;
+    width: 100%;
+  }
 
-    .collectionfreeformview  > .jsx-parser{
-        position:absolute;
-        height: 100%;
-        width: 100%;
-    }
-        
-    border-style: solid;
-    box-sizing: border-box;
-    position: relative;
+  //nested freeform views
+  .collectionfreeformview-container {
+    // background-image: linear-gradient(to right, $light-color-secondary 1px, transparent 1px),
+    //   linear-gradient(to bottom, $light-color-secondary 1px, transparent 1px);
+    // background-size: 30px 30px;
+  }
+
+  border: 0px solid $light-color-secondary;
+  border-radius: $border-radius;
+  box-sizing: border-box;
+  position: relative;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+  box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw;
+  .collectionfreeformview {
+    position: absolute;
     top: 0;
     left: 0;
     width: 100%;
     height: 100%;
-    overflow: hidden;
-    .collectionfreeformview {
-        position: absolute;
-        top: 0;
-        left: 0;
-        width:100%;
-        height: 100%;
-    }
+  }
 }
 .collectionfreeformview-overlay {
+  .collectionfreeformview > .jsx-parser {
+    position: absolute;
+    height: 100%;
+  }
+  .formattedTextBox-cont {
+    background: $light-color-secondary;
+  }
 
+  position:absolute;
+  border: 0px solid transparent;
+  border-radius: $border-radius;
+  overflow: hidden;
+  box-sizing: border-box;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  .collectionfreeformview {
     .collectionfreeformview > .jsx-parser{
         position:absolute;
         height: 100%;
@@ -32,26 +59,39 @@
         background:yellow;
     }
         
-    border-style: solid;
-    box-sizing: border-box;
+    // overflow: hidden;
+    // border-style: solid;
+    // box-sizing: border-box;
     position: absolute;
     top: 0;
     left: 0;
     width: 100%;
     height: 100%;
-    overflow: hidden;
-    .collectionfreeformview {
-        position: absolute;
-        top: 0;
-        left: 0;
-        width:100%;
-        height: 100%;
-    }
+  }
 }
 
+// selection border...?
 .border {
-    border-style: solid;
-    box-sizing: border-box;
-    width: 100%;
-    height: 100%;
-}
\ No newline at end of file
+  border-style: solid;
+  box-sizing: border-box;
+  width: 98%;
+  height: 98%;
+  border-radius: $border-radius;
+}
+
+//this is an animation for the blinking cursor!
+@keyframes blink {
+  0% {
+    opacity: 0;
+  }
+  49% {
+    opacity: 0;
+  }
+  50% {
+    opacity: 1;
+  }
+}
+
+#prevCursor {
+  animation: blink 1s infinite;
+}
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 3d5326552..5c0eab392 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -52,13 +52,13 @@ export class CollectionFreeFormView extends CollectionViewBase {
     }
 
     public getActiveDocuments = () => {
-        var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1);
+        var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1);
         const lvalue = this.props.Document.GetT<ListField<Document>>(this.props.fieldKey, ListField);
         let active: Document[] = [];
         if (lvalue && lvalue != FieldWaiting) {
             lvalue.Data.map(doc => {
-                var page = doc.GetNumber(KeyStore.Page, 0);
-                if (page == curPage || page == 0) {
+                var page = doc.GetNumber(KeyStore.Page, -1);
+                if (page == curPage || page == -1) {
                     active.push(doc);
                 }
             })
@@ -126,7 +126,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
     onPointerUp = (e: PointerEvent): void => {
         e.stopPropagation();
 
-        if (!this.MarqueeVisible && Math.abs(this.DownX - e.clientX) < 3 && Math.abs(this.DownY - e.clientY) < 3) {
+        if (Math.abs(this.DownX - e.clientX) < 4 && Math.abs(this.DownY - e.clientY) < 4) {
             //show preview text cursor on tap
             this.PreviewCursorVisible = true;
             //select is not already selected
@@ -140,9 +140,8 @@ export class CollectionFreeFormView extends CollectionViewBase {
     @action
     onPointerMove = (e: PointerEvent): void => {
         if (!e.cancelBubble && this.props.active()) {
-            if (e.buttons != 2 && !e.altKey && !e.metaKey && !this.MarqueeVisible) {
+            if (e.buttons == 1 && !e.altKey && !e.metaKey) {
                 this.MarqueeVisible = true;
-                this.PreviewCursorVisible = false;
             }
             if (this.MarqueeVisible) {
                 e.stopPropagation();
@@ -152,7 +151,6 @@ export class CollectionFreeFormView extends CollectionViewBase {
                 let x = this.props.Document.GetNumber(KeyStore.PanX, 0);
                 let y = this.props.Document.GetNumber(KeyStore.PanY, 0);
                 let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
-                this.PreviewCursorVisible = false;
                 this.SetPan(x - dx, y - dy);
                 this._lastX = e.pageX;
                 this._lastY = e.pageY;
@@ -272,7 +270,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
 
     @computed
     get views() {
-        var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1);
+        var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1);
         const lvalue = this.props.Document.GetT<ListField<Document>>(this.props.fieldKey, ListField);
         if (lvalue && lvalue != FieldWaiting) {
             return lvalue.Data.map(doc => {
@@ -343,10 +341,12 @@ export class CollectionFreeFormView extends CollectionViewBase {
                     ref={this._canvasRef}>
                     {this.backgroundView}
                     <InkingCanvas getScreenTransform={this.getTransform} Document={this.props.Document} />
-                    <PreviewCursor container={this} addLiveTextDocuemnt={this.addLiveTextBox} getTransform={this.getTransform} />
+                    <PreviewCursor container={this} addLiveTextDocument={this.addLiveTextBox} getTransform={this.getTransform} />
                     {this.views}
                 </div>
-                <MarqueeView container={this} activeDocuemnts={this.getActiveDocuments} selectDocuments={this.selectDocuments} addDocument={this.props.addDocument} removeDocument={this.props.removeDocument} getMarqueeTransform={this.getMarqueeTransform} getTransform={this.getTransform} />
+                <MarqueeView container={this} activeDocuments={this.getActiveDocuments} selectDocuments={this.selectDocuments}
+                    addDocument={this.props.addDocument} removeDocument={this.props.removeDocument}
+                    getMarqueeTransform={this.getMarqueeTransform} getTransform={this.getTransform} />
                 {this.overlayView}
             </div>
         );
diff --git a/src/client/views/collections/CollectionPDFView.scss b/src/client/views/collections/CollectionPDFView.scss
new file mode 100644
index 000000000..0144625c1
--- /dev/null
+++ b/src/client/views/collections/CollectionPDFView.scss
@@ -0,0 +1,27 @@
+.collectionPdfView-buttonTray {
+    top : 25px;
+    left : 20px;
+    position: relative; 
+    transform-origin: left top;
+    position: absolute;
+}
+.collectionPdfView-cont{
+    width: 100%;
+    height: 100%;
+    position: absolute; 
+    
+}
+.collectionPdfView-backward {
+    color : white;
+    top :0px;
+    left : 0px;
+    position: absolute;
+    background-color: rgba(50, 50, 50, 0.2);
+}
+.collectionPdfView-forward {
+    color : white;
+    top :0px;
+    left : 35px;
+    position: absolute;
+    background-color: rgba(50, 50, 50, 0.2);
+}
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx
index f22c07060..124d82c8b 100644
--- a/src/client/views/collections/CollectionPDFView.tsx
+++ b/src/client/views/collections/CollectionPDFView.tsx
@@ -1,10 +1,11 @@
-import { action, computed } from "mobx";
+import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
 import { Document } from "../../../fields/Document";
 import { KeyStore } from "../../../fields/KeyStore";
 import { ContextMenu } from "../ContextMenu";
 import { CollectionView, CollectionViewType } from "./CollectionView";
 import { CollectionViewProps } from "./CollectionViewBase";
+import "./CollectionPDFView.scss"
 import React = require("react");
 import { FieldId } from "../../../fields/Field";
 
@@ -18,22 +19,23 @@ export class CollectionPDFView extends React.Component<CollectionViewProps> {
                     isTopMost={isTopMost} SelectOnLoad={selectOnLoad} BackgroundView={BackgroundView} focus={focus}/>`;
     }
 
-    public SelectedDocs: FieldId[] = []
-    @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : 0;
-    @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : 0;
+    private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, -1); }
+    private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); }
+    @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : -1;
+    @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : -1;
 
-    @computed private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, 0); }
-    @computed private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); }
-    @computed private get uIButtons() {
+    private get uIButtons() {
+        let scaling = Math.min(1.8, this.props.ScreenToLocalTransform().transformDirection(1, 1)[0]);
         return (
-            <div className="pdfBox-buttonTray" key="tray">
-                <button className="pdfButton" onClick={this.onPageBack}>{"<"}</button>
-                <button className="pdfButton" onClick={this.onPageForward}>{">"}</button>
+            <div className="collectionPdfView-buttonTray" key="tray" style={{ transform: `scale(${scaling}, ${scaling})` }}>
+                <button className="collectionPdfView-backward" onClick={this.onPageBack}>{"<"}</button>
+                <button className="collectionPdfView-forward" onClick={this.onPageForward}>{">"}</button>
             </div>);
     }
 
     // "inherited" CollectionView API starts here...
-
+    @observable
+    public SelectedDocs: FieldId[] = []
     public active: () => boolean = () => CollectionView.Active(this);
 
     addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); }
@@ -49,7 +51,7 @@ export class CollectionPDFView extends React.Component<CollectionViewProps> {
     get subView(): any { return CollectionView.SubView(this); }
 
     render() {
-        return (<div className="collectionView-cont" onContextMenu={this.specificContextMenu}>
+        return (<div className="collectionPdfView-cont" onContextMenu={this.specificContextMenu}>
             {this.subView}
             {this.props.isSelected() ? this.uIButtons : (null)}
         </div>)
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index d40e6d314..0d615dc01 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -1,185 +1,162 @@
-
+@import "../global_variables";
 
 .collectionSchemaView-container {
-    border-style: solid;
+  border: 1px solid $intermediate-color;
+  border-radius: $border-radius;
+  box-sizing: border-box;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+
+.collectionSchemaView-content {
+    position: absolute;  
+    height:100%;
+    width:100%;
+    overflow:auto;
+}
+  .collectionSchemaView-previewRegion {
+    position: relative;
+    background: $light-color;
+    float: left;
+    height: 100%;
+  }
+  .collectionSchemaView-previewHandle {
+    position: absolute;
+    height: 37px;
+    width: 20px;
+    z-index: 20;
+    right: 0;
+    top: 0;
+    background: $main-accent;
+  }
+  .collectionSchemaView-dividerDragger {
+    position: relative;
     box-sizing: border-box;
+    border-left: 1px solid $intermediate-color;
+    border-right: 1px solid $intermediate-color;
+    float: left;
+    height: 100%;
+  }
+  .collectionSchemaView-tableContainer {
+    position: relative;
+    float: left;
+    height: 100%;
+  }
+
+  .ReactTable {
     position: absolute;
+    // display: inline-block;
+    // overflow: auto;
     width: 100%;
     height: 100%;
-    .collectionSchemaView-previewRegion {
-        position: relative; 
-        background: black; 
-        float: left; 
-        height: 100%;
-    }
-    .collectionSchemaView-previewHandle {
-        position: absolute;
-        height: 37px;
-        width: 20px; 
-        z-index: 20; 
-        right: 0; 
-        top: 0; 
-        background: Black ;
-    }
-    .collectionSchemaView-dividerDragger{
-        position: relative; 
-        background: black; 
-        float: left; 
-        height: 100%;
-    }
-    .collectionSchemaView-tableContainer {
+    background: $light-color;
+    box-sizing: border-box;
+    border: none !important;
+    .rt-table {
+      overflow-y: auto;
+      overflow-x: auto;
+      height: 100%;
+      display: -webkit-inline-box;
+      direction: ltr;
+      // direction:rtl;
+      // display:block;
+    }
+    .rt-tbody {
+      //direction: ltr;
+      direction: rtl;
+    }
+    .rt-tr-group {
+      direction: ltr;
+      max-height: 44px;
+    }
+    .rt-td {
+      border-width: 1px;
+      border-right-color: $intermediate-color;
+      .imageBox-cont {
         position: relative;
-        float: left;
-        height: 100%; 
-    }
-
-    .ReactTable {
-        position: absolute;
-       // display: inline-block;
-       // overflow: auto;
-        width: 100%;
+        max-height: 100%;
+      }
+      .imageBox-cont img {
+        object-fit: contain;
+        max-width: 100%;
         height: 100%;
-        background: white;
-        box-sizing: border-box;
-        .rt-table {
-            overflow-y: auto;
-            overflow-x: auto;
-            height: 100%;
-
-            display: -webkit-inline-box;
-            direction: ltr;
-            // direction:rtl;
-            // display:block;
-        }
-        .rt-tbody {
-            //direction: ltr;
-            direction: rtl;
-        }
-        .rt-tr-group {
-            direction: ltr;
-            max-height: 44px;
-        }
-        .rt-td {
-            border-width: 1;
-            border-right-color: #aaa;
-            .imageBox-cont {
-                position:relative;
-                max-height:100%;
-            }
-            .imageBox-cont img {
-                object-fit: contain;
-                max-width: 100%;
-                height: 100%
-            }
-        }
-        .rt-tr-group {
-            border-width: 1;
-            border-bottom-color: #aaa
-        }
-    }
-    .ReactTable .rt-thead.-header {
-            background:grey;
-        }
-    .ReactTable .rt-th, .ReactTable .rt-td {
-        max-height: 44;
-        padding: 3px 7px;
-    }
-    .ReactTable .rt-tbody .rt-tr-group:last-child {
-        border-bottom: grey;
-        border-bottom-style: solid;
-        border-bottom-width: 1;
-    }
-    .documentView-node:first-child {
-        background: grey;
-        .imageBox-cont img {
-            object-fit: contain;
-        }
-    }
+      }
+      .videobox-cont  {
+        object-fit: contain;
+        width:auto;
+        height: 100%;
+      }
+    }
+  }
+  .ReactTable .rt-thead.-header {
+    background: $intermediate-color;
+    color: $light-color;
+    text-transform: uppercase;
+    letter-spacing: 2px;
+    font-size: 12px;
+    height: 30px;
+    padding-top: 4px;
+  }
+  .ReactTable .rt-th,
+  .ReactTable .rt-td {
+    max-height: 44;
+    padding: 3px 7px;
+    font-size: 13px;
+    text-align: center;
+  }
+  .ReactTable .rt-tbody .rt-tr-group:last-child {
+    border-bottom: $intermediate-color;
+    border-bottom-style: solid;
+    border-bottom-width: 1;
+  }
+  .documentView-node:first-child {
+    background: $light-color;
+    .imageBox-cont img {
+      object-fit: contain;
+    }
+  }
 }
 
 .Resizer {
-    box-sizing: border-box;
-    background: #000;
-    opacity: 0.5;
-    z-index: 1;
-    background-clip: padding-box;
-    &.horizontal {
-        height: 11px;
-        margin: -5px 0;
-        border-top: 5px solid rgba(255, 255, 255, 0);
-        border-bottom: 5px solid rgba(255, 255, 255, 0);
-        cursor: row-resize;
-        width: 100%;
-        &:hover {
-            border-top: 5px solid rgba(0, 0, 0, 0.5);
-            border-bottom: 5px solid rgba(0, 0, 0, 0.5);
-        }
-    }
-    &.vertical {
-        width: 11px;
-        margin: 0 -5px;
-        border-left: 5px solid rgba(255, 255, 255, 0);
-        border-right: 5px solid rgba(255, 255, 255, 0);
-        cursor: col-resize;
-        &:hover {
-            border-left: 5px solid rgba(0, 0, 0, 0.5);
-            border-right: 5px solid rgba(0, 0, 0, 0.5);
-        }
-    }
+  box-sizing: border-box;
+  background: #000;
+  opacity: 0.5;
+  z-index: 1;
+  background-clip: padding-box;
+  &.horizontal {
+    height: 11px;
+    margin: -5px 0;
+    border-top: 5px solid rgba(255, 255, 255, 0);
+    border-bottom: 5px solid rgba(255, 255, 255, 0);
+    cursor: row-resize;
+    width: 100%;
     &:hover {
-        -webkit-transition: all 2s ease;
-        transition: all 2s ease;
-    }
+      border-top: 5px solid rgba(0, 0, 0, 0.5);
+      border-bottom: 5px solid rgba(0, 0, 0, 0.5);
+    }
+  }
+  &.vertical {
+    width: 11px;
+    margin: 0 -5px;
+    border-left: 5px solid rgba(255, 255, 255, 0);
+    border-right: 5px solid rgba(255, 255, 255, 0);
+    cursor: col-resize;
+    &:hover {
+      border-left: 5px solid rgba(0, 0, 0, 0.5);
+      border-right: 5px solid rgba(0, 0, 0, 0.5);
+    }
+  }
+  &:hover {
+    -webkit-transition: all 2s ease;
+    transition: all 2s ease;
+  }
 }
 
 .vertical {
-    section {
-        width: 100vh;
-        height: 100vh;
-        display: -webkit-box;
-        display: -webkit-flex;
-        display: -ms-flexbox;
-        display: flex;
-        -webkit-box-orient: vertical;
-        -webkit-box-direction: normal;
-        -webkit-flex-direction: column;
-        -ms-flex-direction: column;
-        flex-direction: column;
-    }
-    header {
-        padding: 1rem;
-        background: #eee;
-    }
-    footer {
-        padding: 1rem;
-        background: #eee;
-    }
-}
-
-.horizontal {
-    section {
-        width: 100vh;
-        height: 100vh;
-        display: flex;
-        flex-direction: column;
-    }
-    header {
-        padding: 1rem;
-        background: #eee;
-    }
-    footer {
-        padding: 1rem;
-        background: #eee;
-    }
-}
-
-.parent {
-    width: 100%;
-    height: 100%;
-    -webkit-box-flex: 1;
-    -webkit-flex: 1;
-    -ms-flex: 1;
-    flex: 1;
+  section {
+    width: 100vh;
+    height: 100vh;
     display: -webkit-box;
     display: -webkit-flex;
     display: -ms-flexbox;
@@ -189,19 +166,71 @@
     -webkit-flex-direction: column;
     -ms-flex-direction: column;
     flex-direction: column;
+  }
+  header {
+    padding: 1rem;
+    background: #eee;
+  }
+  footer {
+    padding: 1rem;
+    background: #eee;
+  }
+}
+
+.horizontal {
+  section {
+    width: 100vh;
+    height: 100vh;
+    display: flex;
+    flex-direction: column;
+  }
+  header {
+    padding: 1rem;
+    background: #eee;
+  }
+  footer {
+    padding: 1rem;
+    background: #eee;
+  }
+}
+
+.parent {
+  width: 100%;
+  height: 100%;
+  -webkit-box-flex: 1;
+  -webkit-flex: 1;
+  -ms-flex: 1;
+  flex: 1;
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-box-orient: vertical;
+  -webkit-box-direction: normal;
+  -webkit-flex-direction: column;
+  -ms-flex-direction: column;
+  flex-direction: column;
 }
 
 .header {
-    background: #aaa;
-    height: 3rem;
-    line-height: 3rem;
+  background: #aaa;
+  height: 3rem;
+  line-height: 3rem;
 }
 
 .wrapper {
-    background: #ffa;
-    margin: 5rem;
-    -webkit-box-flex: 1;
-    -webkit-flex: 1;
-    -ms-flex: 1;
-    flex: 1;
-}
\ No newline at end of file
+  background: #ffa;
+  margin: 5rem;
+  -webkit-box-flex: 1;
+  -webkit-flex: 1;
+  -ms-flex: 1;
+  flex: 1;
+}
+
+.-even {
+  background: $light-color !important;
+}
+
+.-odd {
+  background: $light-color-secondary !important;
+}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 04f017378..8c1aeef2c 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, computed } from "mobx";
 import { observer } from "mobx-react";
 import Measure from "react-measure";
 import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
@@ -24,14 +24,14 @@ import { setupDrag } from "../../util/DragManager";
 @observer
 export class CollectionSchemaView extends CollectionViewBase {
     private _mainCont = React.createRef<HTMLDivElement>();
-    private DIVIDER_WIDTH = 5;
+    private DIVIDER_WIDTH = 4;
 
     @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;
+    @computed get splitPercentage() { return this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0); }
 
     renderCell = (rowProps: CellInfo) => {
         let props: FieldViewProps = {
@@ -49,7 +49,7 @@ export class CollectionSchemaView extends CollectionViewBase {
         let reference = React.createRef<HTMLDivElement>();
         let onItemDown = setupDrag(reference, () => props.doc);
         return (
-            <div onPointerDown={onItemDown} key={props.doc.Id} ref={reference}>
+            <div className="collectionSchemaView-cellContents" onPointerDown={onItemDown} style={{ height: "36px" }} key={props.doc.Id} ref={reference}>
                 <EditableView contents={contents}
                     height={36} GetValue={() => {
                         let field = props.doc.Get(props.fieldKey);
@@ -89,7 +89,8 @@ export class CollectionSchemaView extends CollectionViewBase {
         return {
             onClick: action((e: React.MouseEvent, handleOriginal: Function) => {
                 that._selectedIndex = rowInfo.index;
-                this._splitPercentage += 0.05; // bcz - ugh - needed to force Measure to do its thing and call onResize
+                // bcz - ugh - needed to force Measure to do its thing and call onResize
+                this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage - 0.05)
 
                 if (handleOriginal) {
                     handleOriginal()
@@ -106,18 +107,18 @@ export class CollectionSchemaView extends CollectionViewBase {
     @action
     onDividerMove = (e: PointerEvent): void => {
         let nativeWidth = this._mainCont.current!.getBoundingClientRect();
-        this._splitPercentage = Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100);
+        this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, 100 - Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100));
     }
     @action
     onDividerUp = (e: PointerEvent): void => {
         document.removeEventListener("pointermove", this.onDividerMove);
         document.removeEventListener('pointerup', this.onDividerUp);
-        if (this._startSplitPercent == this._splitPercentage) {
-            this._splitPercentage = this._splitPercentage == 1 ? 66 : 100;
+        if (this._startSplitPercent == this.splitPercentage) {
+            this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0);
         }
     }
     onDividerDown = (e: React.PointerEvent) => {
-        this._startSplitPercent = this._splitPercentage;
+        this._startSplitPercent = this.splitPercentage;
         e.stopPropagation();
         e.preventDefault();
         document.addEventListener("pointermove", this.onDividerMove);
@@ -134,12 +135,12 @@ export class CollectionSchemaView extends CollectionViewBase {
         e.preventDefault();
         document.removeEventListener("pointermove", this.onExpanderMove);
         document.removeEventListener('pointerup', this.onExpanderUp);
-        if (this._startSplitPercent == this._splitPercentage) {
-            this._splitPercentage = this._splitPercentage == 100 ? 66 : 100;
+        if (this._startSplitPercent == this.splitPercentage) {
+            this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0);
         }
     }
     onExpanderDown = (e: React.PointerEvent) => {
-        this._startSplitPercent = this._splitPercentage;
+        this._startSplitPercent = this.splitPercentage;
         e.stopPropagation();
         e.preventDefault();
         document.addEventListener("pointermove", this.onExpanderMove);
@@ -203,7 +204,7 @@ export class CollectionSchemaView extends CollectionViewBase {
         )
         let previewHandle = !this.props.active() ? (null) : (
             <div className="collectionSchemaView-previewHandle" onPointerDown={this.onExpanderDown} />);
-        let dividerDragger = this._splitPercentage == 100 ? (null) :
+        let dividerDragger = this.splitPercentage == 0 ? (null) :
             <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
@@ -213,7 +214,8 @@ export class CollectionSchemaView extends CollectionViewBase {
                         this._panelHeight = r.entry.height;
                     })}>
                         {({ measureRef }) =>
-                            <div ref={measureRef} className="collectionSchemaView-tableContainer" style={{ width: `${this._splitPercentage}%` }}>
+                            <div ref={measureRef} className="collectionSchemaView-tableContainer"
+                                style={{ width: `calc(100% - ${this.splitPercentage}%)` }}>
                                 <ReactTable
                                     data={children}
                                     pageSize={children.length}
@@ -235,7 +237,7 @@ export class CollectionSchemaView extends CollectionViewBase {
                         }
                     </Measure>
                     {dividerDragger}
-                    <div className="collectionSchemaView-previewRegion" style={{ width: `calc(${100 - this._splitPercentage}% - ${this.DIVIDER_WIDTH}px)` }}>
+                    <div className="collectionSchemaView-previewRegion" style={{ width: `calc(${this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0)}% - ${this.DIVIDER_WIDTH}px)` }}>
                         {content}
                     </div>
                     {previewHandle}
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index f8d580a7b..fa0f1c761 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -1,16 +1,25 @@
+@import "../global_variables";
 #body {
     padding: 20px;
-    background: #bbbbbb;
+    background: $light-color-secondary;
+    font-size: 13px;
+    overflow: scroll;
 }
 
 ul {
     list-style: none;
+    padding-left: 20px;
 }
 
 li {
     margin: 5px 0;
 }
 
+.collection-child {
+    margin-top: 10px;
+    margin-bottom: 10px;
+}
+
 .no-indent {
     padding-left: 0;
 }
@@ -18,10 +27,17 @@ li {
 .bullet {
     width: 1.5em;
     display: inline-block;
+    color: $intermediate-color;
+}
+
+.coll-title {
+    font-size: 24px;
+    margin-bottom: 20px;
 }
 
 .collectionTreeView-dropTarget {
-    border-style: solid;
+    border: 0px solid transparent;
+    border-radius: $border-radius;
     box-sizing: border-box;
     height: 100%;
 }
@@ -30,8 +46,16 @@ li {
     display: inline-table;
 }
 
+.docContainer:hover {
+    .delete-button {
+        display: inline;
+    }
+}
+
 .delete-button {
-    color: #999999;
+    color: $intermediate-color;
     float: right;
-    margin-left: 1em;
+    margin-left: 15px;
+    margin-top: 3px;
+    display: none;
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 8b06d9ac4..80fc89712 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -12,6 +12,10 @@ import { setupDrag } from "../../util/DragManager";
 import { FieldWaiting } from "../../../fields/Field";
 import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
 
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faTrashAlt, faCaretRight, faCaretDown } from '@fortawesome/free-solid-svg-icons';
+
 export interface TreeViewProps {
     document: Document;
     deleteDoc: (doc: Document) => void;
@@ -23,6 +27,10 @@ export enum BulletType {
     List
 }
 
+library.add(faTrashAlt);
+library.add(faCaretDown);
+library.add(faCaretRight);
+
 @observer
 /**
  * Component that takes in a document prop and a boolean whether it's collapsed or not.
@@ -50,11 +58,11 @@ class TreeView extends React.Component<TreeViewProps> {
 
         switch (type) {
             case BulletType.Collapsed:
-                return <div className="bullet" onClick={onClicked}>&#9654;</div>
+                return <div className="bullet" onClick={onClicked}><FontAwesomeIcon icon="caret-right" /></div>
             case BulletType.Collapsible:
-                return <div className="bullet" onClick={onClicked}>&#9660;</div>
+                return <div className="bullet" onClick={onClicked}><FontAwesomeIcon icon="caret-down" /></div>
             case BulletType.List:
-                return <div className="bullet">&mdash;</div>
+                return <div className="bullet"></div>
         }
     }
 
@@ -79,7 +87,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 this.props.document.SetData(KeyStore.Title, value, TextField);
                 return true;
             }} />
-            <div className="delete-button" onClick={this.delete}>x</div>
+            <div className="delete-button" onClick={this.delete}><FontAwesomeIcon icon="trash-alt" size="xs" /></div>
         </div >
     }
 
@@ -101,7 +109,7 @@ class TreeView extends React.Component<TreeViewProps> {
                     <TreeView document={value} deleteDoc={this.remove} />)
                 )
                 subView =
-                    <li key={this.props.document.Id} >
+                    <li className="collection-child" key={this.props.document.Id} >
                         {this.renderBullet(BulletType.Collapsible)}
                         {titleElement}
                         <ul key={this.props.document.Id}>
@@ -109,7 +117,7 @@ class TreeView extends React.Component<TreeViewProps> {
                         </ul>
                     </li>
             } else {
-                subView = <li key={this.props.document.Id}>
+                subView = <li className="collection-child" key={this.props.document.Id}>
                     {this.renderBullet(BulletType.Collapsed)}
                     {titleElement}
                 </li>
@@ -157,7 +165,7 @@ export class CollectionTreeView extends CollectionViewBase {
 
         return (
             <div id="body" className="collectionTreeView-dropTarget" onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }}>
-                <h3>
+                <div className="coll-title">
                     <EditableView contents={titleStr}
                         height={72} GetValue={() => {
                             return this.props.Document.Title;
@@ -165,7 +173,8 @@ export class CollectionTreeView extends CollectionViewBase {
                             this.props.Document.SetData(KeyStore.Title, value, TextField);
                             return true;
                         }} />
-                </h3>
+                </div>
+                <hr />
                 <ul className="no-indent">
                     {childrenElement}
                 </ul>
diff --git a/src/client/views/collections/CollectionVideoView.scss b/src/client/views/collections/CollectionVideoView.scss
new file mode 100644
index 000000000..cbb981b13
--- /dev/null
+++ b/src/client/views/collections/CollectionVideoView.scss
@@ -0,0 +1,40 @@
+
+.collectionVideoView-cont{
+    width: 100%;
+    height: 100%;
+    position: absolute;
+ 
+}
+.collectionVideoView-time{
+    color : white;
+    top :25px;
+    left : 25px;
+    position: absolute;
+    background-color: rgba(50, 50, 50, 0.2);
+    transform-origin: left top;
+}
+.collectionVideoView-play {
+    width: 25px;
+    height: 20px;
+    bottom: 25px;
+    left : 25px;
+    position: absolute;
+    color : white;
+    background-color: rgba(50, 50, 50, 0.2);
+    border-radius: 4px;
+    text-align: center;
+    transform-origin: left bottom;
+}
+.collectionVideoView-full {
+    width: 25px;
+    height: 20px;
+    bottom: 25px;
+    right : 25px;
+    position: absolute;
+    color : white;
+    background-color: rgba(50, 50, 50, 0.2);
+    border-radius: 4px;
+    text-align: center;
+    transform-origin: right bottom;
+
+}
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx
index a6471f53c..b64ef3c07 100644
--- a/src/client/views/collections/CollectionVideoView.tsx
+++ b/src/client/views/collections/CollectionVideoView.tsx
@@ -1,4 +1,4 @@
-import { action, computed } from "mobx";
+import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
 import { Document } from "../../../fields/Document";
 import { KeyStore } from "../../../fields/KeyStore";
@@ -7,6 +7,7 @@ import { CollectionView, CollectionViewType } from "./CollectionView";
 import { CollectionViewProps } from "./CollectionViewBase";
 import React = require("react");
 import { FieldId } from "../../../fields/Field";
+import "./CollectionVideoView.scss"
 
 
 @observer
@@ -18,14 +19,29 @@ export class CollectionVideoView extends React.Component<CollectionViewProps> {
                     isTopMost={isTopMost} SelectOnLoad={selectOnLoad} BackgroundView={BackgroundView} focus={focus}/>`;
     }
 
-    public SelectedDocs: FieldId[] = []
-    @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : 0;
-    @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : 0;
+    private _mainCont = React.createRef<HTMLDivElement>();
+
+    private get uIButtons() {
+        let scaling = Math.min(1.8, this.props.ScreenToLocalTransform().transformDirection(1, 1)[0]);
+        return ([
+            <div className="collectionVideoView-time" key="time" onPointerDown={this.onResetDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
+                <span>{"" + Math.round(this.ctime)}</span>
+                <span style={{ fontSize: 8 }}>{" " + Math.round((this.ctime - Math.trunc(this.ctime)) * 100)}</span>
+            </div>,
+            <div className="collectionVideoView-play" key="play" onPointerDown={this.onPlayDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
+                {this.playing ? "\"" : ">"}
+            </div>,
+            <div className="collectionVideoView-full" key="full" onPointerDown={this.onFullDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
+                F
+                </div>
+        ]);
+    }
+
 
-    @computed private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, 0); }
-    @computed private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); }
     // "inherited" CollectionView API starts here...
 
+    @observable
+    public SelectedDocs: FieldId[] = []
     public active: () => boolean = () => CollectionView.Active(this);
 
     addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); }
@@ -40,11 +56,63 @@ export class CollectionVideoView extends React.Component<CollectionViewProps> {
     get collectionViewType(): CollectionViewType { return CollectionViewType.Freeform; }
     get subView(): any { return CollectionView.SubView(this); }
 
+    componentDidMount() {
+        this.updateTimecode();
+    }
+
+    get player(): HTMLVideoElement | undefined {
+        return this._mainCont.current ? this._mainCont.current.getElementsByTagName("video")[0] : undefined;
+    }
+
+    @action
+    updateTimecode = () => {
+        if (this.player) {
+            this.ctime = this.player.currentTime;
+            this.props.Document.SetNumber(KeyStore.CurPage, Math.round(this.ctime));
+        }
+        setTimeout(() => this.updateTimecode(), 100)
+    }
+
+
+    @observable
+    ctime: number = 0
+    @observable
+    playing: boolean = false;
+
+    @action
+    onPlayDown = () => {
+        if (this.player) {
+            if (this.player.paused) {
+                this.player.play();
+                this.playing = true;
+            } else {
+                this.player.pause();
+                this.playing = false;
+            }
+        }
+    }
+    @action
+    onFullDown = (e: React.PointerEvent) => {
+        if (this.player) {
+            this.player.requestFullscreen();
+            e.stopPropagation();
+            e.preventDefault();
+        }
+    }
+
+    @action
+    onResetDown = () => {
+        if (this.player) {
+            this.player.pause();
+            this.player.currentTime = 0;
+        }
+
+    }
+
     render() {
-        return (<div className="collectionView-cont" onContextMenu={this.specificContextMenu}>
-            {/* <video controls className="videobox-cont"> */}
+        return (<div className="collectionVideoView-cont" ref={this._mainCont} onContextMenu={this.specificContextMenu}>
             {this.subView}
-            {/* </video> */}
+            {this.uIButtons}
         </div>)
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 17a0fbd23..d9b2722a6 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -22,20 +22,19 @@ export enum CollectionViewType {
     Tree
 }
 
-export const COLLECTION_BORDER_WIDTH = 2;
+export const COLLECTION_BORDER_WIDTH = 1;
 
 @observer
 export class CollectionView extends React.Component<CollectionViewProps> {
 
-    @observable
-    public SelectedDocs: FieldId[] = [];
-
     public static LayoutString(fieldKey: string = "DataKey") {
         return `<${CollectionView.name} Document={Document}
                     ScreenToLocalTransform={ScreenToLocalTransform} fieldKey={${fieldKey}} panelWidth={PanelWidth} panelHeight={PanelHeight} isSelected={isSelected} select={select} bindings={bindings}
                     isTopMost={isTopMost} SelectOnLoad={selectOnLoad} BackgroundView={BackgroundView} focus={focus}/>`;
     }
 
+    @observable
+    public SelectedDocs: FieldId[] = [];
     public active: () => boolean = () => CollectionView.Active(this);
     addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); }
     removeDocument = (doc: Document): boolean => { return CollectionView.RemoveDocument(this.props, doc); }
@@ -50,7 +49,7 @@ export class CollectionView extends React.Component<CollectionViewProps> {
 
     @action
     public static AddDocument(props: CollectionViewProps, doc: Document) {
-        doc.SetNumber(KeyStore.Page, props.Document.GetNumber(KeyStore.CurPage, 0));
+        doc.SetNumber(KeyStore.Page, props.Document.GetNumber(KeyStore.CurPage, -1));
         if (props.Document.Get(props.fieldKey) instanceof Field) {
             //TODO This won't create the field if it doesn't already exist
             const value = props.Document.GetData(props.fieldKey, ListField, new Array<Document>())
diff --git a/src/client/views/collections/MarqueeView.tsx b/src/client/views/collections/MarqueeView.tsx
index d9e4df1e9..65aaa837f 100644
--- a/src/client/views/collections/MarqueeView.tsx
+++ b/src/client/views/collections/MarqueeView.tsx
@@ -3,21 +3,22 @@ import { observer } from "mobx-react";
 import { Document } from "../../../fields/Document";
 import { FieldWaiting, Opt } from "../../../fields/Field";
 import { KeyStore } from "../../../fields/KeyStore";
-import { ListField } from "../../../fields/ListField";
 import { Documents } from "../../documents/Documents";
 import { SelectionManager } from "../../util/SelectionManager";
 import { Transform } from "../../util/Transform";
 import { CollectionFreeFormView } from "./CollectionFreeFormView";
 import "./MarqueeView.scss";
 import React = require("react");
-
+import { InkField, StrokeData } from "../../../fields/InkField";
+import { Utils } from "../../../Utils";
+import { InkingCanvas } from "../InkingCanvas";
 
 interface MarqueeViewProps {
     getMarqueeTransform: () => Transform;
     getTransform: () => Transform;
     container: CollectionFreeFormView;
     addDocument: (doc: Document) => void;
-    activeDocuemnts: () => Document[];
+    activeDocuments: () => Document[];
     selectDocuments: (docs: Document[]) => void;
     removeDocument: (doc: Document) => boolean;
 }
@@ -92,31 +93,59 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
 
     @action
     marqueeCommand = (e: KeyboardEvent) => {
-        if (e.key == "Backspace") {
+        if (e.key == "Backspace" || e.key == "Delete") {
             this.marqueeSelect().map(d => this.props.removeDocument(d));
+            this.props.container.props.Document.SetData(KeyStore.Ink, this.marqueeInkSelect(false), InkField);
             this.cleanupInteractions();
         }
         if (e.key == "c") {
             let bounds = this.Bounds;
-            let selected = this.marqueeSelect().map(m => m);
-            this.marqueeSelect().map(d => this.props.removeDocument(d));
-            //setTimeout(() => {
-            this.props.addDocument(Documents.FreeformDocument(selected.map(d => {
+            let selected = this.marqueeSelect().map(d => {
+                this.props.removeDocument(d);
                 d.SetNumber(KeyStore.X, d.GetNumber(KeyStore.X, 0) - bounds.left - bounds.width / 2);
                 d.SetNumber(KeyStore.Y, d.GetNumber(KeyStore.Y, 0) - bounds.top - bounds.height / 2);
                 d.SetNumber(KeyStore.Page, 0);
                 d.SetText(KeyStore.Title, "" + d.GetNumber(KeyStore.Width, 0) + " " + d.GetNumber(KeyStore.Height, 0));
                 return d;
-            }), { x: bounds.left, y: bounds.top, panx: 0, pany: 0, width: bounds.width, height: bounds.height, title: "a nested collection" }));
+            });
+            let liftedInk = this.marqueeInkSelect(true);
+            this.props.container.props.Document.SetData(KeyStore.Ink, this.marqueeInkSelect(false), InkField);
+            //setTimeout(() => {
+            this.props.addDocument(Documents.FreeformDocument(selected, { x: bounds.left, y: bounds.top, panx: 0, pany: 0, width: bounds.width, backgroundColor: "Transparent", height: bounds.height, ink: liftedInk, title: "a nested collection" }));
             // }, 100);
             this.cleanupInteractions();
         }
     }
+    marqueeInkSelect(select: boolean) {
+        let selRect = this.Bounds;
+        let centerShiftX = 0 - (selRect.left + selRect.width / 2); // moves each point by the offset that shifts the selection's center to the origin.
+        let centerShiftY = 0 - (selRect.top + selRect.height / 2);
+        let ink = this.props.container.props.Document.GetT(KeyStore.Ink, InkField);
+        if (ink && ink != FieldWaiting) {
+            let idata = new Map();
+            ink.Data.forEach((value: StrokeData, key: string, map: any) => {
+                let inside = InkingCanvas.IntersectStrokeRect(value, selRect);
+                if (inside && select) {
+                    idata.set(key,
+                        {
+                            pathData: value.pathData.map(val => { return { x: val.x + centerShiftX, y: val.y + centerShiftY } }),
+                            color: value.color,
+                            width: value.width,
+                            tool: value.tool,
+                            page: -1
+                        });
+                } else if (!inside && !select) {
+                    idata.set(key, value);
+                }
+            })
+            return idata;
+        }
+    }
 
     marqueeSelect() {
         let selRect = this.Bounds;
         let selection: Document[] = [];
-        this.props.activeDocuemnts().map(doc => {
+        this.props.activeDocuments().map(doc => {
             var x = doc.GetNumber(KeyStore.X, 0);
             var y = doc.GetNumber(KeyStore.Y, 0);
             var w = doc.GetNumber(KeyStore.Width, 0);
diff --git a/src/client/views/collections/PreviewCursor.tsx b/src/client/views/collections/PreviewCursor.tsx
index ab68fbc46..a1411250a 100644
--- a/src/client/views/collections/PreviewCursor.tsx
+++ b/src/client/views/collections/PreviewCursor.tsx
@@ -16,7 +16,7 @@ import { CollectionFreeFormView } from "./CollectionFreeFormView";
 export interface PreviewCursorProps {
     getTransform: () => Transform;
     container: CollectionFreeFormView;
-    addLiveTextDocuemnt: (doc: Document) => void;
+    addLiveTextDocument: (doc: Document) => void;
 }
 
 @observer
@@ -57,11 +57,13 @@ export class PreviewCursor extends React.Component<PreviewCursorProps>  {
     @action
     onKeyPress = (e: KeyboardEvent) => {
         //if not these keys, make a textbox if preview cursor is active!
-        if (!e.ctrlKey && !e.altKey) {
+        if (!e.ctrlKey && !e.altKey && !e.defaultPrevented) {
             //make textbox and add it to this collection
             let [x, y] = this.props.getTransform().transformPoint(this._lastX, this._lastY);
             let newBox = Documents.TextDocument({ width: 200, height: 100, x: x, y: y, title: "new" });
-            this.props.addLiveTextDocuemnt(newBox);
+            this.props.addLiveTextDocument(newBox);
+            e.stopPropagation();
+            e.preventDefault();
         }
     }
 
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index f7d89843d..6daf15f5f 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -18,7 +18,7 @@ export class AudioBox extends React.Component<FieldViewProps> {
         super(props);
     }
 
-   
+
 
     componentDidMount() {
     }
@@ -26,16 +26,16 @@ export class AudioBox extends React.Component<FieldViewProps> {
     componentWillUnmount() {
     }
 
-   
+
     render() {
         let field = this.props.doc.Get(this.props.fieldKey)
-        let path = field == FieldWaiting ? "http://techslides.com/demos/samples/sample.mp3":
+        let path = field == FieldWaiting ? "http://techslides.com/demos/samples/sample.mp3" :
             field instanceof AudioField ? field.Data.href : "http://techslides.com/demos/samples/sample.mp3";
-    
+
         return (
             <div>
-                <audio controls className = "audiobox-cont">
-                    <source src = {path} type="audio/mpeg"/>
+                <audio controls className="audiobox-cont">
+                    <source src={path} type="audio/mpeg" />
                     Not supported.
                 </audio>
             </div>
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
new file mode 100644
index 000000000..55b4938a0
--- /dev/null
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -0,0 +1,35 @@
+import { Document } from "../../../fields/Document";
+import { CollectionFreeFormView } from "../collections/CollectionFreeFormView";
+import { CollectionDockingView } from "../collections/CollectionDockingView";
+import { CollectionSchemaView } from "../collections/CollectionSchemaView";
+import { CollectionView, CollectionViewType } from "../collections/CollectionView";
+import { CollectionPDFView } from "../collections/CollectionPDFView";
+import { CollectionVideoView } from "../collections/CollectionVideoView";
+import { FormattedTextBox } from "../nodes/FormattedTextBox";
+import { ImageBox } from "../nodes/ImageBox";
+import { VideoBox } from "../nodes/VideoBox";
+import { AudioBox } from "../nodes/AudioBox";
+import { KeyValueBox } from "./KeyValueBox"
+import { WebBox } from "../nodes/WebBox";
+import { PDFBox } from "../nodes/PDFBox";
+import "./DocumentView.scss";
+import React = require("react");
+const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
+
+interface JsxBindings {
+    Document: Document;
+    layout: string;
+    [prop: string]: any;
+}
+
+export class DocumentContentsView extends React.PureComponent<JsxBindings> {
+    render() {
+        return <JsxParser
+            components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox }}
+            bindings={this.props}
+            jsx={this.props.layout}
+            showWarnings={true}
+            onError={(test: any) => { console.log(test) }}
+        />
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index ab913897b..85a115f1c 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -1,23 +1,23 @@
+@import "../global_variables";
 .documentView-node {
-    position: absolute;
-    background: #cdcdcd;
-    //overflow: hidden;
-    &.minimized {
-        width: 30px;
-        height: 30px;
-    }
-    .top {
-        background: #232323;
-        height: 20px;
-        cursor: pointer;
-    }
-    .content {
-        padding: 20px 20px;
-        height: auto;
-        box-sizing: border-box;
-    }
-    .scroll-box {
-        overflow-y: scroll;
-        height: calc(100% - 20px);
-    }
-}
\ No newline at end of file
+  position: absolute;
+  background: $light-color; //overflow: hidden;
+  &.minimized {
+    width: 30px;
+    height: 30px;
+  }
+  .top {
+    background: #232323;
+    height: 20px;
+    cursor: pointer;
+  }
+  .content {
+    padding: 20px 20px;
+    height: auto;
+    box-sizing: border-box;
+  }
+  .scroll-box {
+    overflow-y: scroll;
+    height: calc(100% - 20px);
+  }
+}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 8ff355a15..96a9ff2a8 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,32 +1,22 @@
-import { action, computed, IReactionDisposer, runInAction, reaction, trace } from "mobx";
+import { action, computed, IReactionDisposer, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { Document } from "../../../fields/Document";
 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 { Documents } from "../../documents/Documents";
+import { DocumentManager } from "../../util/DocumentManager";
 import { DragManager } from "../../util/DragManager";
 import { SelectionManager } from "../../util/SelectionManager";
 import { Transform } from "../../util/Transform";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
-import { CollectionFreeFormView } from "../collections/CollectionFreeFormView";
-import { CollectionSchemaView } from "../collections/CollectionSchemaView";
 import { CollectionView, CollectionViewType } from "../collections/CollectionView";
-import { CollectionPDFView } from "../collections/CollectionPDFView";
-import { CollectionVideoView } from "../collections/CollectionVideoView";
 import { ContextMenu } from "../ContextMenu";
-import { FormattedTextBox } from "../nodes/FormattedTextBox";
-import { ImageBox } from "../nodes/ImageBox";
-import { VideoBox } from "../nodes/VideoBox";
-import { AudioBox } from "../nodes/AudioBox";
-import { Documents } from "../../documents/Documents"
-import { KeyValueBox } from "./KeyValueBox"
-import { WebBox } from "../nodes/WebBox";
-import { PDFBox } from "../nodes/PDFBox";
 import "./DocumentView.scss";
 import React = require("react");
-import { TextField } from "../../../fields/TextField";
-import { DocumentManager } from "../../util/DocumentManager";
+import { DocumentContentsView } from "./DocumentContentsView";
 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
 
 
@@ -339,9 +329,11 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         var scaling = this.props.ContentScaling();
         var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
         var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
+        var backgroundcolor = this.props.Document.GetText(KeyStore.BackgroundColor, "");
         return (
             <div className="documentView-node" ref={this._mainCont}
                 style={{
+                    background: backgroundcolor,
                     width: nativeWidth > 0 ? nativeWidth.toString() + "px" : "100%",
                     height: nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%",
                     transformOrigin: "left top",
diff --git a/src/client/views/nodes/FieldTextBox.scss b/src/client/views/nodes/FieldTextBox.scss
index b6ce2fabc..d2cd61b0d 100644
--- a/src/client/views/nodes/FieldTextBox.scss
+++ b/src/client/views/nodes/FieldTextBox.scss
@@ -1,14 +1,14 @@
 .ProseMirror {
-    margin-top: -1em;
-    width: 100%;
-    height: 100%;
+  margin-top: -1em;
+  width: 100%;
+  height: 100%;
 }
 
 .ProseMirror:focus {
-    outline: none !important
+  outline: none !important;
 }
 
 .fieldTextBox-cont {
-    background: white;
-    padding: 1vw;
-}
\ No newline at end of file
+  background: white;
+  padding: 1vw;
+}
diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss
index ab5849f09..32da2632e 100644
--- a/src/client/views/nodes/FormattedTextBox.scss
+++ b/src/client/views/nodes/FormattedTextBox.scss
@@ -1,38 +1,46 @@
+@import "../global_variables";
 .ProseMirror {
-    width: 100%;
-    height: auto;
-    min-height: 100%
+  width: 100%;
+  height: auto;
+  min-height: 100%;
+  font-family: $serif;
 }
 
 .ProseMirror:focus {
-    outline: none !important
+  outline: none !important;
 }
 
 .formattedTextBox-cont {
-    background: white;
-    padding: 1;
-    border-width: 1px;
-    border-radius: 2px;
-    border-color:black;
-    box-sizing: border-box;
-    background: white;
-    border-style:solid;
-    overflow-y: scroll;
-    overflow-x: hidden;
-    color: initial;
-    height: 100%;
+  background: $light-color-secondary;
+  padding: 0.9em;
+  border-width: 0px;
+  border-radius: $border-radius;
+  border-color: $intermediate-color;
+  box-sizing: border-box;
+  border-style: solid;
+  overflow-y: scroll;
+  overflow-x: hidden;
+  color: initial;
+  height: 100%;
 }
 
 .menuicon {
-    display: inline-block;
-    border-right: 1px solid rgba(0, 0, 0, 0.2);
-    color: #888;
-    line-height: 1;
-    padding: 0 7px;
-    margin: 1px;
-    cursor: pointer;
-    text-align: center;
-    min-width: 1.4em;
-  }
-  .strong, .heading { font-weight: bold; }
-  .em { font-style: italic; }
\ No newline at end of file
+  display: inline-block;
+  border-right: 1px solid rgba(0, 0, 0, 0.2);
+  color: #888;
+  line-height: 1;
+  padding: 0 7px;
+  margin: 1px;
+  cursor: pointer;
+  text-align: center;
+  min-width: 1.4em;
+}
+
+.strong,
+.heading {
+  font-weight: bold;
+}
+
+.em {
+  font-style: italic;
+}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 5c7aaf9fe..f5d4c030b 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -31,7 +31,7 @@ import { ContextMenu } from "../../views/ContextMenu";
 //    and 'doc' property to the document that is being rendered
 //
 //  When rendered() by React, this extracts the TextController from the Document stored at the 
-//  specified Key and assigns it to an HTML input node.  When changes are made tot his node, 
+//  specified Key and assigns it to an HTML input node.  When changes are made to this node, 
 //  this will edit the document and assign the new value to that field.
 //]
 export class FormattedTextBox extends React.Component<FieldViewProps> {
diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss
index 31452bc85..487038841 100644
--- a/src/client/views/nodes/ImageBox.scss
+++ b/src/client/views/nodes/ImageBox.scss
@@ -1,12 +1,11 @@
-
 .imageBox-cont {
-    padding: 0vw;
-    position: relative;
-    text-align: center;
-    width: 100%;
-    height: auto;
-    max-width: 100%;
-    max-height: 100%
+  padding: 0vw;
+  position: relative;
+  text-align: center;
+  width: 100%;
+  height: auto;
+  max-width: 100%;
+  max-height: 100%;
 }
 
 .imageBox-cont img {
@@ -15,8 +14,8 @@
 }
 
 .imageBox-button {
-    padding : 0vw;
-    border: none;
-    width : 100%;
-    height: 100%;
-}
\ No newline at end of file
+  padding: 0vw;
+  border: none;
+  width: 100%;
+  height: 100%;
+}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index bceeedbc6..cad8904d0 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -70,7 +70,7 @@ export class ImageBox extends React.Component<FieldViewProps> {
     }
 
     lightbox = (path: string) => {
-        const images = [path, "http://www.cs.brown.edu/~bcz/face.gif"];
+        const images = [path];
         if (this._isOpen && this.props.isSelected()) {
             return (<Lightbox
                 mainSrc={images[this._photoIndex]}
diff --git a/src/client/views/nodes/KeyValueBox.scss b/src/client/views/nodes/KeyValueBox.scss
index 1295266e5..e946275fa 100644
--- a/src/client/views/nodes/KeyValueBox.scss
+++ b/src/client/views/nodes/KeyValueBox.scss
@@ -1,31 +1,31 @@
 .keyValueBox-cont {
-    overflow-y:scroll;
-    height: 100%;
-    border: black;
-    border-width: 1px;
-    border-style: solid;
-    box-sizing: border-box;
-    display: inline-block;
-    .imageBox-cont img {
-        max-height:45px;
-        height: auto;
-    }
+  overflow-y: scroll;
+  height: 100%;
+  border: black;
+  border-width: 1px;
+  border-style: solid;
+  box-sizing: border-box;
+  display: inline-block;
+  .imageBox-cont img {
+    max-height: 45px;
+    height: auto;
+  }
 }
 .keyValueBox-table {
-    position: relative;
+  position: relative;
 }
 .keyValueBox-header {
-    background:gray;
+  background: gray;
 }
 .keyValueBox-evenRow {
+  background: white;
+  .formattedTextBox-cont {
     background: white;
-    .formattedTextBox-cont {
-        background: white;
-    }
+  }
 }
 .keyValueBox-oddRow {
-    background: lightGray;
-    .formattedTextBox-cont {
-        background: lightgray;
-    }
-}
\ No newline at end of file
+  background: lightGray;
+  .formattedTextBox-cont {
+    background: lightgray;
+  }
+}
diff --git a/src/client/views/nodes/LinkBox.scss b/src/client/views/nodes/LinkBox.scss
index 00e5ebb3d..5d5f782d2 100644
--- a/src/client/views/nodes/LinkBox.scss
+++ b/src/client/views/nodes/LinkBox.scss
@@ -1,13 +1,14 @@
+@import "../global_variables";
 .link-container {
     width: 100%;
-    height: 30px;
+    height: 35px;
     display: flex;
     flex-direction: row;
     border-top: 0.5px solid #bababa;
 }
 
 .info-container {
-    width: 60%;
+    width: 55%;
     padding-top: 5px;
     padding-left: 5px;
     display: flex;
@@ -23,17 +24,42 @@
 }
 
 .button-container {
-    width: 40%;
+    width: 45%;
     display: flex;
     flex-direction: row;
 }
 
 .button {
-    height: 15px;
-    width: 15px;
-    margin: 8px 5px;
+    height: 20px;
+    width: 20px;
+    margin: 8px 4px;
     border-radius: 50%;
-    opacity: 0.6;
+    opacity: 0.9;
     pointer-events: auto;
-    background-color: #2B6091;
+    background-color: $dark-color;
+    color: $light-color;
+    text-transform: uppercase;
+    letter-spacing: 2px;
+    font-size: 60%;
+    transition: transform 0.2s;
+}
+
+.button:hover {
+    background: $main-accent;
+    cursor: pointer;
+}
+
+.fa-icon-view {
+    margin-left: 3px;
+    margin-top: 5px;
+}
+
+.fa-icon-edit {
+    margin-left: 5px;
+    margin-top: 5px;
+}
+
+.fa-icon-delete {
+    margin-left: 6px;
+    margin-top: 5px;
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 69df676ff..430c1b694 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -11,6 +11,16 @@ import { ListField } from "../../../fields/ListField";
 import { DocumentManager } from "../../util/DocumentManager";
 import { LinkEditor } from "./LinkEditor";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faEye } from '@fortawesome/free-solid-svg-icons';
+import { faEdit } from '@fortawesome/free-solid-svg-icons';
+import { faTimes } from '@fortawesome/free-solid-svg-icons';
+
+
+library.add(faEye);
+library.add(faEdit);
+library.add(faTimes);
 
 interface Props {
     linkDoc: Document;
@@ -79,9 +89,12 @@ export class LinkBox extends React.Component<Props> {
                 </div>
 
                 <div className="button-container">
-                    <div className="button" onPointerDown={this.onViewButtonPressed}></div>
-                    <div className="button" onPointerDown={this.onEditButtonPressed}></div>
-                    <div className="button" onPointerDown={this.onDeleteButtonPressed}></div>
+                    <div title="Follow Link" className="button" onPointerDown={this.onViewButtonPressed}>
+                        <FontAwesomeIcon className="fa-icon-view" icon="eye" size="sm" /></div>
+                    <div title="Edit Link" className="button" onPointerDown={this.onEditButtonPressed}>
+                        <FontAwesomeIcon className="fa-icon-edit" icon="edit" size="sm" /></div>
+                    <div title="Delete Link" className="button" onPointerDown={this.onDeleteButtonPressed}>
+                        <FontAwesomeIcon className="fa-icon-delete" icon="times" size="sm" /></div>
                 </div>
             </div>
         )
diff --git a/src/client/views/nodes/LinkEditor.scss b/src/client/views/nodes/LinkEditor.scss
index cb191dc8c..fb0c69cff 100644
--- a/src/client/views/nodes/LinkEditor.scss
+++ b/src/client/views/nodes/LinkEditor.scss
@@ -1,3 +1,4 @@
+@import "../global_variables";
 .edit-container {
     width: 100%;
     height: auto;
@@ -9,21 +10,34 @@
     margin-bottom: 10px;
     padding: 5px;
     font-size: 12px;
+    border: 1px solid #bababa;
 }
 
 .description-input {
-    font-size: 12px;
+    font-size: 11px;
     padding: 5px;
     margin-bottom: 10px;
+    border: 1px solid #bababa;
 }
 
 .save-button {
     width: 50px;
     height: 20px;
-    background-color: #2B6091;
+    pointer-events: auto;
+    background-color: $dark-color;
+    color: $light-color;
+    text-transform: uppercase;
+    letter-spacing: 2px;
+    padding: 2px;
+    font-size: 10px;
     margin: 0 auto;
-    color: white;
+    transition: transform 0.2s;
     text-align: center;
     line-height: 20px;
-    font-size: 12px;
+}
+
+.save-button:hover {
+    background: $main-accent;
+    transform: scale(1.05);
+    cursor: pointer;
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/LinkMenu.scss b/src/client/views/nodes/LinkMenu.scss
index a120ab2a7..dedcce6ef 100644
--- a/src/client/views/nodes/LinkMenu.scss
+++ b/src/client/views/nodes/LinkMenu.scss
@@ -10,6 +10,7 @@
     padding: 5px;
     margin-bottom: 10px;
     font-size: 12px;
+    border: 1px solid #bababa;
 }
 
 #linkMenu-list {
diff --git a/src/client/views/nodes/LinkMenu.tsx b/src/client/views/nodes/LinkMenu.tsx
index 5c6b06d00..5eeb40772 100644
--- a/src/client/views/nodes/LinkMenu.tsx
+++ b/src/client/views/nodes/LinkMenu.tsx
@@ -39,8 +39,8 @@ export class LinkMenu extends React.Component<Props> {
                 <div id="linkMenu-container">
                     <input id="linkMenu-searchBar" type="text" placeholder="Search..."></input>
                     <div id="linkMenu-list">
-                        {this.renderLinkItems(linkTo, KeyStore.LinkedToDocs, "Source: ")}
-                        {this.renderLinkItems(linkFrom, KeyStore.LinkedFromDocs, "Destination: ")}
+                        {this.renderLinkItems(linkTo, KeyStore.LinkedToDocs, "Destination: ")}
+                        {this.renderLinkItems(linkFrom, KeyStore.LinkedFromDocs, "Source: ")}
                     </div>
                 </div>
             )
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index 9f92410d4..ad947afd5 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -11,5 +11,5 @@
 }
 .pdfBox-contentContainer {
     position: absolute;
-    transform-origin: "left top";
+    transform-origin: left top;
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 544af41a2..b0b5a63a4 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -86,7 +86,7 @@ export class PDFBox extends React.Component<FieldViewProps> {
     @observable private _interactive: boolean = false;
     @observable private _loaded: boolean = false;
 
-    @computed private get curPage() { return this.props.doc.GetNumber(KeyStore.CurPage, 0); }
+    @computed private get curPage() { return this.props.doc.GetNumber(KeyStore.CurPage, -1); }
 
     componentDidMount() {
         this._reactionDisposer = reaction(
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 9c60d4348..8c1ee669f 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -30,7 +30,7 @@ export class VideoBox extends React.Component<FieldViewProps> {
             var nativeWidth = this.props.doc.GetNumber(KeyStore.NativeWidth, 0);
             var nativeHeight = this.props.doc.GetNumber(KeyStore.NativeHeight, 0);
             var newNativeHeight = nativeWidth * r.entry.height / r.entry.width;
-            if (newNativeHeight != nativeHeight && !isNaN(newNativeHeight)) {
+            if (!nativeHeight && newNativeHeight != nativeHeight && !isNaN(newNativeHeight)) {
                 this.props.doc.SetNumber(KeyStore.Height, newNativeHeight / nativeWidth * this.props.doc.GetNumber(KeyStore.Width, 0));
                 this.props.doc.SetNumber(KeyStore.NativeHeight, newNativeHeight);
             }
@@ -48,16 +48,14 @@ export class VideoBox extends React.Component<FieldViewProps> {
 
         //setTimeout(action(() => this._loaded = true), 500);
         return (
-            <div style={{ width: "100%", height: "Auto" }} >
-                <Measure onResize={this.setScaling}>
-                    {({ measureRef }) =>
-                        <video controls className="videobox-cont" ref={measureRef}>
-                            <source src={path} type="video/mp4" />
-                            Not supported.
+            <Measure onResize={this.setScaling}>
+                {({ measureRef }) =>
+                    <video className="videobox-cont" ref={measureRef}>
+                        <source src={path} type="video/mp4" />
+                        Not supported.
                         </video>
-                    }
-                </Measure>
-            </div>
+                }
+            </Measure>
         )
     }
 }
\ No newline at end of file
diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts
index 6481e14fe..06cdc8fc8 100644
--- a/src/fields/KeyStore.ts
+++ b/src/fields/KeyStore.ts
@@ -19,11 +19,13 @@ export namespace KeyStore {
     export const Annotations = new Key("Annotations");
     export const ViewType = new Key("ViewType");
     export const Layout = new Key("Layout");
+    export const BackgroundColor = new Key("BackgroundColor");
     export const BackgroundLayout = new Key("BackgroundLayout");
     export const OverlayLayout = new Key("OverlayLayout");
     export const LayoutKeys = new Key("LayoutKeys");
     export const LayoutFields = new Key("LayoutFields");
     export const ColumnsKey = new Key("SchemaColumns");
+    export const SchemaSplitPercentage = new Key("SchemaSplitPercentage");
     export const Caption = new Key("Caption");
     export const ActiveFrame = new Key("ActiveFrame");
     export const DocumentText = new Key("DocumentText");
@@ -33,7 +35,6 @@ export namespace KeyStore {
     export const LinkTags = new Key("LinkTag");
     export const Thumbnail = new Key("Thumbnail");
     export const CurPage = new Key("CurPage");
-    export const CurFrame = new Key("CurFrame");
     export const NumPages = new Key("NumPages");
     export const Ink = new Key("Ink");
 }
-- 
cgit v1.2.3-70-g09d2


From c1f88978266a007b1516295135d6959666a31894 Mon Sep 17 00:00:00 2001
From: Andrew Kim <andrewdkim@users.noreply.github.com>
Date: Sun, 17 Mar 2019 00:24:24 -0400
Subject: fixed some things

---
 src/client/views/nodes/DocumentView.tsx | 12 ++++++++++++
 1 file changed, 12 insertions(+)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 96a9ff2a8..54afda8f3 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -14,9 +14,21 @@ import { Transform } from "../../util/Transform";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
 import { CollectionView, CollectionViewType } from "../collections/CollectionView";
 import { ContextMenu } from "../ContextMenu";
+import {FormattedTextBox} from "../nodes/FormattedTextBox"
+import {ImageBox} from "../nodes/ImageBox"; 
+import {CollectionFreeFormView} from "../collections/CollectionFreeFormView"
+import {PDFBox} from "../nodes/PDFBox";
+import {WebBox} from "../nodes/WebBox"
+import {CollectionSchemaView} from "../collections/CollectionSchemaView"
+import {AudioBox} from "../nodes/AudioBox"; 
+import {VideoBox} from "../nodes/VideoBox"; 
+import {CollectionPDFView} from "../collections/CollectionPDFView"
+import {CollectionVideoView} from "../collections/CollectionVideoView"
+import {KeyValueBox} from "../nodes/KeyValueBox"
 import "./DocumentView.scss";
 import React = require("react");
 import { DocumentContentsView } from "./DocumentContentsView";
+import { faUserPlus } from "@fortawesome/free-solid-svg-icons";
 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
 
 
-- 
cgit v1.2.3-70-g09d2


From 301e7aef724a36926886659991c304da9c4d2b7c Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Sun, 17 Mar 2019 15:05:56 -0400
Subject: updates

---
 src/client/documents/Documents.ts                  | 27 +++++++++++-----------
 .../views/collections/CollectionViewBase.tsx       | 17 +++++++++-----
 src/client/views/nodes/DocumentView.tsx            |  4 ++--
 3 files changed, 26 insertions(+), 22 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 26167fab5..8fa2a7515 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -75,15 +75,15 @@ export namespace Documents {
     }
     function assignOptions(doc: Document, options: DocumentOptions): Document {
         if (options.title !== undefined) { doc.SetText(KeyStore.Title, options.title); }
-        if (options.panx !== undefined) { doc.SetNumber(KeyStore.PanX, options.panx); }
-        if (options.pany !== undefined) { doc.SetNumber(KeyStore.PanY, options.pany); }
         if (options.page !== undefined) { doc.SetNumber(KeyStore.Page, options.page); }
         if (options.scale !== undefined) { doc.SetNumber(KeyStore.Scale, options.scale); }
         if (options.viewType !== undefined) { doc.SetNumber(KeyStore.ViewType, options.viewType); }
         if (options.backgroundColor !== undefined) { doc.SetText(KeyStore.BackgroundColor, options.backgroundColor); }
+        if (options.ink !== undefined) { doc.Set(KeyStore.Ink, new InkField(options.ink)); }
         if (options.layout !== undefined) { doc.SetText(KeyStore.Layout, options.layout); }
         if (options.layoutKeys !== undefined) { doc.Set(KeyStore.LayoutKeys, new ListField(options.layoutKeys)); }
-        if (options.ink !== undefined) { doc.Set(KeyStore.Ink, new InkField(options.ink)); }
+        if (options.panx !== undefined) { doc.SetNumber(KeyStore.PanX, options.panx); }
+        if (options.pany !== undefined) { doc.SetNumber(KeyStore.PanY, options.pany); }
         return doc;
     }
 
@@ -162,8 +162,7 @@ export namespace Documents {
 
 
     export function ImageDocument(url: string, options: DocumentOptions = {}) {
-        return SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] },
-            [new URL(url), ImageField]).MakeDelegate();
+        return assignToDelegate(SetInstanceOptions(GetImagePrototype(), options, [new URL(url), ImageField]).MakeDelegate(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
         // let doc = SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] },
         //     [new URL(url), ImageField]);
         // doc.SetText(KeyStore.Caption, "my caption...");
@@ -172,38 +171,38 @@ export namespace Documents {
         // return doc;
     }
     export function VideoDocument(url: string, options: DocumentOptions = {}) {
-        return SetInstanceOptions(GetVideoPrototype(), options, [new URL(url), VideoField]);
+        return assignToDelegate(SetInstanceOptions(GetVideoPrototype(), options, [new URL(url), VideoField]), options);
     }
     export function AudioDocument(url: string, options: DocumentOptions = {}) {
-        return SetInstanceOptions(GetAudioPrototype(), options, [new URL(url), AudioField]);
+        return assignToDelegate(SetInstanceOptions(GetAudioPrototype(), options, [new URL(url), AudioField]), options);
     }
 
     export function TextDocument(options: DocumentOptions = {}) {
         return assignToDelegate(SetInstanceOptions(GetTextPrototype(), options, ["", TextField]).MakeDelegate(), options);
     }
     export function PdfDocument(url: string, options: DocumentOptions = {}) {
-        return SetInstanceOptions(GetPdfPrototype(), options, [new URL(url), PDFField]).MakeDelegate();
+        return assignToDelegate(SetInstanceOptions(GetPdfPrototype(), options, [new URL(url), PDFField]).MakeDelegate(), options);
     }
     export function WebDocument(url: string, options: DocumentOptions = {}) {
-        return SetInstanceOptions(GetWebPrototype(), options, [new URL(url), WebField]).MakeDelegate();
+        return assignToDelegate(SetInstanceOptions(GetWebPrototype(), options, [new URL(url), WebField]).MakeDelegate(), options);
     }
     export function HtmlDocument(html: string, options: DocumentOptions = {}) {
-        return SetInstanceOptions(GetWebPrototype(), options, [html, HtmlField]).MakeDelegate();
+        return assignToDelegate(SetInstanceOptions(GetWebPrototype(), options, [html, HtmlField]).MakeDelegate(), options);
     }
     export function KVPDocument(document: Document, options: DocumentOptions = {}, id?: string) {
-        return SetInstanceOptions(GetKVPPrototype(), options, document, id).MakeDelegate()
+        return assignToDelegate(SetInstanceOptions(GetKVPPrototype(), options, document, id), options)
     }
     export function FreeformDocument(documents: Array<Document>, options: DocumentOptions, id?: string, makePrototype: boolean = true) {
         if (!makePrototype) {
             return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id)
         }
-        return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id).MakeDelegate()
+        return assignToDelegate(SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id).MakeDelegate(), options)
     }
     export function SchemaDocument(documents: Array<Document>, options: DocumentOptions, id?: string) {
-        return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Schema }, [documents, ListField], id)
+        return assignToDelegate(SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Schema }, [documents, ListField], id), options)
     }
     export function DockDocument(config: string, options: DocumentOptions, id?: string) {
-        return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Docking }, [config, TextField], id)
+        return assignToDelegate(SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Docking }, [config, TextField], id), options)
     }
 
     // example of custom display string for an image that shows a caption.
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index 7cccfaf05..6725fc2d1 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -3,7 +3,7 @@ import { Document } from "../../../fields/Document";
 import { ListField } from "../../../fields/ListField";
 import React = require("react");
 import { KeyStore } from "../../../fields/KeyStore";
-import { FieldWaiting, Field } from "../../../fields/Field";
+import { FieldWaiting, Field, Opt } from "../../../fields/Field";
 import { undoBatch } from "../../util/UndoManager";
 import { DragManager } from "../../util/DragManager";
 import { DocumentView } from "../nodes/DocumentView";
@@ -11,6 +11,7 @@ import { Documents, DocumentOptions } from "../../documents/Documents";
 import { Key } from "../../../fields/Key";
 import { Transform } from "../../util/Transform";
 import { CollectionView } from "./CollectionView";
+import { NumberField } from "../../../fields/NumberField";
 
 export interface CollectionViewProps {
     fieldKey: Key;
@@ -51,11 +52,15 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
             let newDoc = docView ? docView.props.Document.CreateAlias() : doc.CreateAlias()
             de.data["newDoc"] = newDoc
             let oldDoc = docView ? docView.props.Document : doc
-            oldDoc.GetAsync(KeyStore.Width, (f: Field) => {
-                newDoc.Set(KeyStore.Width, f)
+            oldDoc.GetTAsync(KeyStore.Width, NumberField, (f: Opt<NumberField>) => {
+                if (f) {
+                    newDoc.SetNumber(KeyStore.Width, f.Data)
+                }
             })
-            oldDoc.GetAsync(KeyStore.Height, (f: Field) => {
-                newDoc.Set(KeyStore.Height, f)
+            oldDoc.GetTAsync(KeyStore.Height, NumberField, (f: Opt<NumberField>) => {
+                if (f) {
+                    newDoc.SetNumber(KeyStore.Height, f.Data)
+                }
             })
         }
 
@@ -68,7 +73,7 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
             if (!de.data["alias"]) {
                 this.props.removeDocument(doc)
             }
-            this.props.addDocument(doc)
+            this.props.addDocument(de.data["alias"] ? de.data["newDoc"] : doc)
         }
         e.stopPropagation();
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 84483ac55..a0ea9d3c2 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -156,7 +156,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
             const [left, top] = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
             let dragData: { [id: string]: any } = {};
             dragData["documentView"] = this;
-            dragData["document"] = ctrlPressed ? this.props.Document.CreateAlias() : this.props.Document
+            dragData["document"] = this.props.Document
             dragData["xOffset"] = x - left;
             dragData["yOffset"] = y - top;
             dragData["alias"] = ctrlPressed
@@ -203,7 +203,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
 
     fieldsClicked = (e: React.MouseEvent): void => {
         if (this.props.AddDocument) {
-            this.props.AddDocument(Documents.KVPDocument(this.props.Document));
+            this.props.AddDocument(Documents.KVPDocument(this.props.Document, { width: 300, height: 300 }));
         }
     }
     fullScreenClicked = (e: React.MouseEvent): void => {
-- 
cgit v1.2.3-70-g09d2


From 1bf3a5a0108704a0204cedcbad6e6d52d19cf982 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 17 Mar 2019 22:04:03 -0400
Subject: moved DocumentContents to DocumentContentsView

---
 src/client/views/InkingControl.tsx                 |  8 +++
 .../views/collections/CollectionFreeFormView.tsx   | 34 ++----------
 src/client/views/collections/MarqueeView.tsx       |  2 +-
 src/client/views/collections/PreviewCursor.tsx     | 10 ++--
 src/client/views/nodes/DocumentContentsView.tsx    | 60 +++++++++++++++-------
 src/client/views/nodes/DocumentView.tsx            | 55 ++------------------
 6 files changed, 62 insertions(+), 107 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx
index fb75ef2a5..6616f68d8 100644
--- a/src/client/views/InkingControl.tsx
+++ b/src/client/views/InkingControl.tsx
@@ -9,6 +9,8 @@ import "./InkingCanvas.scss"
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { faPen, faHighlighter, faEraser, faBan } from '@fortawesome/free-solid-svg-icons';
+import { SelectionManager } from "../util/SelectionManager";
+import { KeyStore } from "../../fields/KeyStore";
 
 library.add(faPen, faHighlighter, faEraser, faBan);
 
@@ -34,6 +36,12 @@ export class InkingControl extends React.Component {
     @action
     switchColor = (color: ColorResult): void => {
         this._selectedColor = color.hex;
+        if (SelectionManager.SelectedDocuments().length == 1) {
+            var sdoc = SelectionManager.SelectedDocuments()[0];
+            if (sdoc.props.ContainingCollectionView && sdoc.props.ContainingCollectionView) {
+                sdoc.props.Document.SetText(KeyStore.BackgroundColor, color.hex);
+            }
+        }
     }
 
     @action
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 988c9941f..cca57912c 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -8,28 +8,16 @@ import { TextField } from "../../../fields/TextField";
 import { DragManager } from "../../util/DragManager";
 import { Transform } from "../../util/Transform";
 import { undoBatch } from "../../util/UndoManager";
-import { CollectionDockingView } from "../collections/CollectionDockingView";
-import { CollectionPDFView } from "../collections/CollectionPDFView";
-import { CollectionSchemaView } from "../collections/CollectionSchemaView";
-import { CollectionVideoView } from "../collections/CollectionVideoView";
-import { CollectionView } from "../collections/CollectionView";
 import { InkingCanvas } from "../InkingCanvas";
-import { AudioBox } from "../nodes/AudioBox";
 import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
-import { DocumentView, DocumentViewProps, DocumentContents } from "../nodes/DocumentView";
-import { FormattedTextBox } from "../nodes/FormattedTextBox";
-import { ImageBox } from "../nodes/ImageBox";
-import { KeyValueBox } from "../nodes/KeyValueBox";
-import { PDFBox } from "../nodes/PDFBox";
-import { VideoBox } from "../nodes/VideoBox";
-import { WebBox } from "../nodes/WebBox";
+import { DocumentContentsView } from "../nodes/DocumentContentsView";
+import { DocumentView, DocumentViewProps } from "../nodes/DocumentView";
 import "./CollectionFreeFormView.scss";
 import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
 import { CollectionViewBase } from "./CollectionViewBase";
 import { MarqueeView } from "./MarqueeView";
 import { PreviewCursor } from "./PreviewCursor";
 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 {
@@ -283,28 +271,14 @@ export class CollectionFreeFormView extends CollectionViewBase {
     @computed
     get backgroundView() {
         return !this.backgroundLayout ? (null) :
-            (<DocumentContents {...this.getDocumentViewProps(this.props.Document)}
+            (<DocumentContentsView {...this.getDocumentViewProps(this.props.Document)}
                 layoutKey={KeyStore.BackgroundLayout} isSelected={() => false} select={() => { }} />);
-        // (<JsxParser
-        //     components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox }}
-        //     bindings={this.props.bindings}
-        //     jsx={this.backgroundLayout}
-        //     showWarnings={true}
-        //     onError={(test: any) => console.log(test)}
-        // />);
     }
     @computed
     get overlayView() {
         return !this.overlayLayout ? (null) :
-            (<DocumentContents {...this.getDocumentViewProps(this.props.Document)}
+            (<DocumentContentsView {...this.getDocumentViewProps(this.props.Document)}
                 layoutKey={KeyStore.OverlayLayout} isSelected={() => false} select={() => { }} />);
-        // (<JsxParser
-        //     components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox }}
-        //     bindings={this.props.bindings}
-        //     jsx={this.overlayLayout}
-        //     showWarnings={true}
-        //     onError={(test: any) => console.log(test)}
-        // />);
     }
 
     getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).translate(-this.centeringShiftX, -this.centeringShiftY).transform(this.getLocalTransform())
diff --git a/src/client/views/collections/MarqueeView.tsx b/src/client/views/collections/MarqueeView.tsx
index 65aaa837f..f5c83a934 100644
--- a/src/client/views/collections/MarqueeView.tsx
+++ b/src/client/views/collections/MarqueeView.tsx
@@ -121,7 +121,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
         let centerShiftX = 0 - (selRect.left + selRect.width / 2); // moves each point by the offset that shifts the selection's center to the origin.
         let centerShiftY = 0 - (selRect.top + selRect.height / 2);
         let ink = this.props.container.props.Document.GetT(KeyStore.Ink, InkField);
-        if (ink && ink != FieldWaiting) {
+        if (ink && ink != FieldWaiting && ink.Data) {
             let idata = new Map();
             ink.Data.forEach((value: StrokeData, key: string, map: any) => {
                 let inside = InkingCanvas.IntersectStrokeRect(value, selRect);
diff --git a/src/client/views/collections/PreviewCursor.tsx b/src/client/views/collections/PreviewCursor.tsx
index a1411250a..cbcfa568d 100644
--- a/src/client/views/collections/PreviewCursor.tsx
+++ b/src/client/views/collections/PreviewCursor.tsx
@@ -1,16 +1,12 @@
-import { trace } from "mobx";
-import "./PreviewCursor.scss";
-import React = require("react");
 import { action, IReactionDisposer, observable, reaction } from "mobx";
 import { observer } from "mobx-react";
 import { Document } from "../../../fields/Document";
-import { FieldWaiting, Opt } from "../../../fields/Field";
-import { KeyStore } from "../../../fields/KeyStore";
-import { ListField } from "../../../fields/ListField";
+import { Opt } from "../../../fields/Field";
 import { Documents } from "../../documents/Documents";
-import { SelectionManager } from "../../util/SelectionManager";
 import { Transform } from "../../util/Transform";
 import { CollectionFreeFormView } from "./CollectionFreeFormView";
+import "./PreviewCursor.scss";
+import React = require("react");
 
 
 export interface PreviewCursorProps {
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 55b4938a0..ce72ab64b 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -1,33 +1,55 @@
-import { Document } from "../../../fields/Document";
-import { CollectionFreeFormView } from "../collections/CollectionFreeFormView";
+import { computed } from "mobx";
+import { observer } from "mobx-react";
+import { FieldWaiting } from "../../../fields/Field";
+import { Key } from "../../../fields/Key";
+import { KeyStore } from "../../../fields/KeyStore";
+import { ListField } from "../../../fields/ListField";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
-import { CollectionSchemaView } from "../collections/CollectionSchemaView";
-import { CollectionView, CollectionViewType } from "../collections/CollectionView";
+import { CollectionFreeFormView } from "../collections/CollectionFreeFormView";
 import { CollectionPDFView } from "../collections/CollectionPDFView";
+import { CollectionSchemaView } from "../collections/CollectionSchemaView";
 import { CollectionVideoView } from "../collections/CollectionVideoView";
-import { FormattedTextBox } from "../nodes/FormattedTextBox";
-import { ImageBox } from "../nodes/ImageBox";
-import { VideoBox } from "../nodes/VideoBox";
-import { AudioBox } from "../nodes/AudioBox";
-import { KeyValueBox } from "./KeyValueBox"
-import { WebBox } from "../nodes/WebBox";
-import { PDFBox } from "../nodes/PDFBox";
+import { CollectionView } from "../collections/CollectionView";
+import { AudioBox } from "./AudioBox";
+import { DocumentViewProps, JsxBindings } from "./DocumentView";
 import "./DocumentView.scss";
+import { FormattedTextBox } from "./FormattedTextBox";
+import { ImageBox } from "./ImageBox";
+import { KeyValueBox } from "./KeyValueBox";
+import { PDFBox } from "./PDFBox";
+import { VideoBox } from "./VideoBox";
+import { WebBox } from "./WebBox";
 import React = require("react");
 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
 
-interface JsxBindings {
-    Document: Document;
-    layout: string;
-    [prop: string]: any;
-}
 
-export class DocumentContentsView extends React.PureComponent<JsxBindings> {
+@observer
+export class DocumentContentsView extends React.Component<DocumentViewProps & {
+    isSelected: () => boolean,
+    select: (ctrl: boolean) => void,
+    layoutKey: Key
+}> {
+    @computed get layout(): string { return this.props.Document.GetText(this.props.layoutKey, "<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>()); }
+
+    CreateBindings(): JsxBindings {
+        let bindings: JsxBindings = { ...this.props, };
+        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
+        }
+        for (const key of this.layoutFields) {
+            let field = this.props.Document.Get(key);
+            bindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field;
+        }
+        return bindings;
+    }
+
     render() {
         return <JsxParser
             components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox }}
-            bindings={this.props}
-            jsx={this.props.layout}
+            bindings={this.CreateBindings()}
+            jsx={this.layout}
             showWarnings={true}
             onError={(test: any) => { console.log(test) }}
         />
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 3e691ee6d..b36d47b8b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,11 +1,12 @@
 import { action, computed, IReactionDisposer, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { Document } from "../../../fields/Document";
-import { Field, FieldWaiting, Opt } from "../../../fields/Field";
+import { Field, 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 { Utils } from "../../../Utils";
 import { Documents } from "../../documents/Documents";
 import { DocumentManager } from "../../util/DocumentManager";
 import { DragManager } from "../../util/DragManager";
@@ -14,22 +15,9 @@ import { Transform } from "../../util/Transform";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
 import { CollectionView, CollectionViewType } from "../collections/CollectionView";
 import { ContextMenu } from "../ContextMenu";
+import { DocumentContentsView } from "./DocumentContentsView";
 import "./DocumentView.scss";
 import React = require("react");
-import { DocumentContentsView } from "./DocumentContentsView";
-import { Utils } from "../../../Utils";
-import { FormattedTextBox } from "./FormattedTextBox";
-import { ImageBox } from "./ImageBox";
-import { CollectionFreeFormView } from "../collections/CollectionFreeFormView";
-import { CollectionSchemaView } from "../collections/CollectionSchemaView";
-import { CollectionPDFView } from "../collections/CollectionPDFView";
-import { CollectionVideoView } from "../collections/CollectionVideoView";
-import { WebBox } from "./WebBox";
-import { KeyValueBox } from "./KeyValueBox";
-import { PDFBox } from "./PDFBox";
-import { VideoBox } from "./VideoBox";
-import { AudioBox } from "./AudioBox";
-const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
 
 
 export interface DocumentViewProps {
@@ -87,7 +75,7 @@ export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs {
     return args;
 }
 
-interface JsxBindings {
+export interface JsxBindings {
     Document: Document;
     isSelected: () => boolean;
     select: (isCtrlPressed: boolean) => void;
@@ -96,40 +84,7 @@ interface JsxBindings {
     [prop: string]: any;
 }
 
-@observer
-export class DocumentContents extends React.Component<DocumentViewProps & {
-    isSelected: () => boolean,
-    select: (ctrl: boolean) => void,
-    layoutKey: Key
-}> {
-    @computed get layout(): string { return this.props.Document.GetText(this.props.layoutKey, "<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>()); }
-
-    CreateBindings(): JsxBindings {
-        let bindings: JsxBindings = {
-            ...this.props,
-        };
-        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
-        }
-        for (const key of this.layoutFields) {
-            let field = this.props.Document.Get(key);
-            bindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field;
-        }
-        return bindings;
-    }
 
-    render() {
-        return <JsxParser
-            components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox }}
-            bindings={this.CreateBindings()}
-            jsx={this.layout}
-            showWarnings={true}
-            onError={(test: any) => { console.log(test) }}
-        />
-    }
-}
 
 @observer
 export class DocumentView extends React.Component<DocumentViewProps> {
@@ -377,7 +332,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                 onDrop={this.onDrop}
                 onContextMenu={this.onContextMenu}
                 onPointerDown={this.onPointerDown} >
-                <DocumentContents {...this.props} isSelected={this.isSelected} select={this.select} layoutKey={KeyStore.Layout} />
+                <DocumentContentsView {...this.props} isSelected={this.isSelected} select={this.select} layoutKey={KeyStore.Layout} />
             </div>
         )
     }
-- 
cgit v1.2.3-70-g09d2


From 196da9c88cc2489b4e6831be1e3ec72c7ce0f0c4 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 17 Mar 2019 22:29:15 -0400
Subject: added alt option to ctrl for macbook

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

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a0ea9d3c2..8ff86fbba 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -94,7 +94,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         this._downY = e.clientY;
         if (e.shiftKey && e.buttons === 2) {
             if (this.props.isTopMost) {
-                this.startDragging(e.pageX, e.pageY, e.ctrlKey);
+                this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey);
             }
             else CollectionDockingView.Instance.StartOtherDrag(this.props.Document, e);
             e.stopPropagation();
@@ -177,7 +177,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
             document.removeEventListener("pointermove", this.onPointerMove)
             document.removeEventListener("pointerup", this.onPointerUp);
             if (!this.topMost || e.buttons == 2 || e.altKey) {
-                this.startDragging(e.x, e.y, e.ctrlKey);
+                this.startDragging(e.x, e.y, e.ctrlKey || e.altKey);
             }
         }
         e.stopPropagation();
-- 
cgit v1.2.3-70-g09d2


From a6ca5db7f43ee31965169ff8d6d0aaffa86dc74e Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 17 Mar 2019 23:04:18 -0400
Subject: tweaked drop code

---
 src/client/documents/Documents.ts                  | 39 ++++++++++------------
 src/client/util/DragManager.ts                     |  2 +-
 .../views/collections/CollectionFreeFormView.tsx   | 19 +++--------
 .../views/collections/CollectionViewBase.tsx       | 34 +++++++++----------
 src/client/views/nodes/DocumentView.tsx            |  8 ++---
 5 files changed, 43 insertions(+), 59 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 20cbcdcb4..3aa575dbb 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,30 +1,27 @@
+import { AudioField } from "../../fields/AudioField";
 import { Document } from "../../fields/Document";
-import { Server } from "../Server";
+import { Field } from "../../fields/Field";
+import { HtmlField } from "../../fields/HtmlField";
+import { ImageField } from "../../fields/ImageField";
+import { InkField, StrokeData } from "../../fields/InkField";
+import { Key } from "../../fields/Key";
 import { KeyStore } from "../../fields/KeyStore";
-import { TextField } from "../../fields/TextField";
-import { NumberField } from "../../fields/NumberField";
 import { ListField } from "../../fields/ListField";
-import { FormattedTextBox } from "../views/nodes/FormattedTextBox";
-import { ImageField } from "../../fields/ImageField";
-import { ImageBox } from "../views/nodes/ImageBox";
+import { PDFField } from "../../fields/PDFField";
+import { TextField } from "../../fields/TextField";
+import { VideoField } from "../../fields/VideoField";
 import { WebField } from "../../fields/WebField";
-import { WebBox } from "../views/nodes/WebBox";
+import { Server } from "../Server";
+import { CollectionPDFView } from "../views/collections/CollectionPDFView";
+import { CollectionVideoView } from "../views/collections/CollectionVideoView";
 import { CollectionView, CollectionViewType } from "../views/collections/CollectionView";
-import { HtmlField } from "../../fields/HtmlField";
-import { Key } from "../../fields/Key"
-import { Field } from "../../fields/Field";
-import { KeyValueBox } from "../views/nodes/KeyValueBox"
-import { KVPField } from "../../fields/KVPField";
-import { VideoField } from "../../fields/VideoField"
-import { VideoBox } from "../views/nodes/VideoBox";
-import { AudioField } from "../../fields/AudioField";
 import { AudioBox } from "../views/nodes/AudioBox";
-import { PDFField } from "../../fields/PDFField";
+import { FormattedTextBox } from "../views/nodes/FormattedTextBox";
+import { ImageBox } from "../views/nodes/ImageBox";
+import { KeyValueBox } from "../views/nodes/KeyValueBox";
 import { PDFBox } from "../views/nodes/PDFBox";
-import { CollectionPDFView } from "../views/collections/CollectionPDFView";
-import { RichTextField } from "../../fields/RichTextField";
-import { CollectionVideoView } from "../views/collections/CollectionVideoView";
-import { StrokeData, InkField } from "../../fields/InkField";
+import { VideoBox } from "../views/nodes/VideoBox";
+import { WebBox } from "../views/nodes/WebBox";
 
 export interface DocumentOptions {
     x?: number;
@@ -137,7 +134,7 @@ export namespace Documents {
                 { x: 0, y: 0, width: 300, height: 300, layoutKeys: [KeyStore.Data] });
     }
     function GetCollectionPrototype(): Document {
-        return collProto ? collProto.MakeDelegate() :
+        return collProto ? collProto :
             collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("DataKey"),
                 { panx: 0, pany: 0, scale: 1, width: 500, height: 500, layoutKeys: [KeyStore.Data] });
     }
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 4a61220a5..c0abec407 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -123,7 +123,7 @@ export namespace DragManager {
         //      however, PDF's have a thumbnail field that contains an image of their canvas.
         //      So we replace the pdf's canvas with the image thumbnail
         const docView: DocumentView = dragData["documentView"];
-        const doc: Document = docView ? docView.props.Document : dragData["document"];
+        const doc: Document = dragData["document"];
 
         if (doc) {
             var pdfBox = dragElement.getElementsByClassName("pdfBox-cont")[0] as HTMLElement;
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index cf9bf9b92..808a22a5d 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -79,20 +79,11 @@ export class CollectionFreeFormView extends CollectionViewBase {
         let screenX = de.x - (de.data["xOffset"] as number || 0);
         let screenY = de.y - (de.data["yOffset"] as number || 0);
         const [x, y] = this.getTransform().transformPoint(screenX, screenY);
-        if (!de.data["alias"]) {
-            const docView: DocumentView = de.data["documentView"];
-            let doc: Document = docView ? docView.props.Document : de.data["document"];
-            if (doc) {
-                doc.SetNumber(KeyStore.X, x);
-                doc.SetNumber(KeyStore.Y, y);
-                this.bringToFront(doc);
-            }
-        }
-        else {
-            let newDoc: Document = de.data["newDoc"]
-            newDoc.SetNumber(KeyStore.X, x)
-            newDoc.SetNumber(KeyStore.Y, y)
-            this.bringToFront(newDoc)
+        let doc: Document = de.data["document"];
+        if (doc) {
+            doc.SetNumber(KeyStore.X, x);
+            doc.SetNumber(KeyStore.Y, y);
+            this.bringToFront(doc);
         }
     }
 
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index 6725fc2d1..304c44788 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -46,34 +46,30 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
     @undoBatch
     @action
     protected drop(e: Event, de: DragManager.DropEvent) {
-        const docView: DocumentView = de.data["documentView"]
-        const doc: Document = de.data["document"]
-        if (de.data["alias"]) {
-            let newDoc = docView ? docView.props.Document.CreateAlias() : doc.CreateAlias()
-            de.data["newDoc"] = newDoc
-            let oldDoc = docView ? docView.props.Document : doc
+        let dropDoc: Document = de.data["document"];
+        if (de.data["alias"] && dropDoc) {
+            let oldDoc = dropDoc;
+            de.data["document"] = dropDoc = oldDoc.CreateAlias();
             oldDoc.GetTAsync(KeyStore.Width, NumberField, (f: Opt<NumberField>) => {
                 if (f) {
-                    newDoc.SetNumber(KeyStore.Width, f.Data)
+                    dropDoc.SetNumber(KeyStore.Width, f.Data)
                 }
             })
             oldDoc.GetTAsync(KeyStore.Height, NumberField, (f: Opt<NumberField>) => {
                 if (f) {
-                    newDoc.SetNumber(KeyStore.Height, f.Data)
+                    dropDoc.SetNumber(KeyStore.Height, f.Data)
                 }
             })
-        }
-
-        if (docView && docView.props.ContainingCollectionView && docView.props.ContainingCollectionView !== this.props.CollectionView) {
-            if (docView.props.RemoveDocument && !de.data["alias"]) {
-                docView.props.RemoveDocument(docView.props.Document)
+        } else {
+            const docView: DocumentView = de.data["documentView"];
+            if (docView && docView.props.RemoveDocument && docView.props.ContainingCollectionView !== this.props.CollectionView) {
+                docView.props.RemoveDocument(dropDoc);
+            } else if (dropDoc) {
+                this.props.removeDocument(dropDoc);
             }
-            this.props.addDocument(de.data["alias"] ? de.data["newDoc"] : docView.props.Document)
-        } else if (doc) {
-            if (!de.data["alias"]) {
-                this.props.removeDocument(doc)
-            }
-            this.props.addDocument(de.data["alias"] ? de.data["newDoc"] : doc)
+        }
+        if (dropDoc) {
+            this.props.addDocument(dropDoc);
         }
         e.stopPropagation();
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index ec9db765a..981cabe71 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -160,20 +160,20 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         }
     }
 
-    startDragging(x: number, y: number, ctrlPressed: boolean) {
+    startDragging(x: number, y: number, dropAliasOfDraggedDoc: boolean) {
         if (this._mainCont.current) {
             const [left, top] = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
             let dragData: { [id: string]: any } = {};
             dragData["documentView"] = this;
-            dragData["document"] = this.props.Document
+            dragData["document"] = this.props.Document;
             dragData["xOffset"] = x - left;
             dragData["yOffset"] = y - top;
-            dragData["alias"] = ctrlPressed
+            dragData["alias"] = dropAliasOfDraggedDoc;
             DragManager.StartDrag(this._mainCont.current, dragData, {
                 handlers: {
                     dragComplete: action(() => { }),
                 },
-                hideSource: !ctrlPressed
+                hideSource: !dropAliasOfDraggedDoc
             })
         }
     }
-- 
cgit v1.2.3-70-g09d2


From 5d4b103402900abb43e78787a3c781f220d6ea97 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 18 Mar 2019 01:45:15 -0400
Subject: updated drag drop

---
 .../views/collections/CollectionViewBase.tsx       | 29 +++++++++++-----------
 src/client/views/nodes/DocumentView.tsx            |  3 +--
 2 files changed, 15 insertions(+), 17 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index 37ec203b5..3a6d1c141 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -46,27 +46,26 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
     @undoBatch
     @action
     protected drop(e: Event, de: DragManager.DropEvent) {
-        let dropDoc: Document = de.data["document"];
-        if (de.data["alias"] && dropDoc) {
-            let oldDoc = dropDoc;
-            de.data["document"] = dropDoc = oldDoc.CreateAlias();
+        let docToAlias = de.data["documentToAlias"];
+        let docView = de.data["documentView"];
+        let doc = docToAlias ? docToAlias.CreateAlias() : de.data["document"];
+        if (docToAlias) {
             [KeyStore.Width, KeyStore.Height].map(key =>
-                oldDoc.GetTAsync(key, NumberField, (f: Opt<NumberField>) => {
+                docToAlias.GetTAsync(key, NumberField, (f: Opt<NumberField>) => {
                     if (f) {
-                        dropDoc.SetNumber(key, f.Data)
+                        doc.SetNumber(key, f.Data)
                     }
                 })
             );
-        } else {
-            const docView: DocumentView = de.data["documentView"];
-            if (docView && docView.props.RemoveDocument && docView.props.ContainingCollectionView !== this.props.CollectionView) {
-                docView.props.RemoveDocument(dropDoc);
-            } else if (dropDoc) {
-                this.props.removeDocument(dropDoc);
+            this.props.addDocument(doc);
+        } else if (docView) {
+            if (doc && docView.props.RemoveDocument && docView.props.ContainingCollectionView !== this.props.CollectionView) {
+                docView.props.RemoveDocument(doc);
+                this.props.addDocument(doc);
             }
-        }
-        if (dropDoc) {
-            this.props.addDocument(dropDoc);
+        } else if (doc) {
+            // this.props.removeDocument(doc);  bcz: causes an exception
+            this.props.addDocument(doc);
         }
         e.stopPropagation();
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 981cabe71..5d2f6293d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -165,10 +165,9 @@ export class DocumentView extends React.Component<DocumentViewProps> {
             const [left, top] = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
             let dragData: { [id: string]: any } = {};
             dragData["documentView"] = this;
-            dragData["document"] = this.props.Document;
+            dragData[dropAliasOfDraggedDoc ? "documentToAlias" : "document"] = this.props.Document;
             dragData["xOffset"] = x - left;
             dragData["yOffset"] = y - top;
-            dragData["alias"] = dropAliasOfDraggedDoc;
             DragManager.StartDrag(this._mainCont.current, dragData, {
                 handlers: {
                     dragComplete: action(() => { }),
-- 
cgit v1.2.3-70-g09d2

