From 21b1e20106ff49c02657c88f503ef46bc7e4fb07 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Tue, 16 Apr 2019 23:09:03 -0400
Subject: various bug fixes

---
 .../collections/collectionFreeForm/CollectionFreeFormLinksView.tsx    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index 2f684a54e..cd74d3a84 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -16,9 +16,9 @@ export class CollectionFreeFormLinksView extends React.Component<CollectionViewP
 
     _brushReactionDisposer?: IReactionDisposer;
     componentDidMount() {
-        this._brushReactionDisposer = reaction(() => this.props.Document.GetList<Document>(this.props.fieldKey, []).map(doc => doc.GetNumber(KeyStore.X, 0)),
+        this._brushReactionDisposer = reaction(() => this.props.Document.GetList(this.props.fieldKey, [] as Document[]).map(doc => doc.GetNumber(KeyStore.X, 0)),
             () => {
-                let views = this.props.Document.GetList<Document>(this.props.fieldKey, []);
+                let views = this.props.Document.GetList(this.props.fieldKey, [] as Document[]);
                 for (let i = 0; i < views.length; i++) {
                     for (let j = 0; j < views.length; j++) {
                         let srcDoc = views[j];
-- 
cgit v1.2.3-70-g09d2


From e47656cdc18aa1fd801a3853fa0f819140a68646 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 20 Apr 2019 14:26:10 -0400
Subject: fixed issues with FormattedTextBox updates.  Changed brushes to
 operate only on Histograms for efficiency.

---
 src/client/views/MainOverlayTextBox.scss           |  1 +
 src/client/views/MainOverlayTextBox.tsx            |  9 +++++---
 .../CollectionFreeFormLinksView.tsx                |  2 +-
 src/client/views/nodes/FormattedTextBox.tsx        | 25 ++++++++--------------
 4 files changed, 17 insertions(+), 20 deletions(-)

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

diff --git a/src/client/views/MainOverlayTextBox.scss b/src/client/views/MainOverlayTextBox.scss
index 697d68c8c..f6a746e63 100644
--- a/src/client/views/MainOverlayTextBox.scss
+++ b/src/client/views/MainOverlayTextBox.scss
@@ -7,6 +7,7 @@
     overflow: visible;
     top: 0;
     left: 0;
+    pointer-events: none;   
     z-index: $mainTextInput-zindex;
     .formattedTextBox-cont {
         background-color: rgba(248, 6, 6, 0.001);
diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx
index 8cb01117c..a6c7eabf7 100644
--- a/src/client/views/MainOverlayTextBox.tsx
+++ b/src/client/views/MainOverlayTextBox.tsx
@@ -89,6 +89,8 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
         document.removeEventListener('pointerup', this.textBoxUp);
     }
 
+    textXf = () => this._textXf;
+
     render() {
         if (this.TextDoc) {
             let x: number = this._textRect.x;
@@ -98,10 +100,11 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
             let t = this._textXf.transformPoint(0, 0);
             let s = this._textXf.transformPoint(1, 0);
             s[0] = Math.sqrt((s[0] - t[0]) * (s[0] - t[0]) + (s[1] - t[1]) * (s[1] - t[1]));
-            return <div className="mainOverlayTextBox-textInput" style={{ pointerEvents: "none", transform: `translate(${x}px, ${y}px) scale(${1 / s[0]},${1 / s[0]})`, width: "auto", height: "auto" }} >
-                <div className="mainOverlayTextBox-textInput" onPointerDown={this.textBoxDown} ref={this._textProxyDiv} onScroll={this.textScroll} style={{ pointerEvents: "none", transform: `scale(${1}, ${1})`, width: `${w * s[0]}px`, height: `${h * s[0]}px` }}>
+            return <div className="mainOverlayTextBox-textInput" style={{ transform: `translate(${x}px, ${y}px) scale(${1 / s[0]},${1 / s[0]})`, width: "auto", height: "auto" }} >
+                <div className="mainOverlayTextBox-textInput" onPointerDown={this.textBoxDown} ref={this._textProxyDiv} onScroll={this.textScroll} style={{ transform: `scale(${1}, ${1})`, width: `${w * s[0]}px`, height: `${h * s[0]}px` }}>
                     <FormattedTextBox fieldKey={this._textFieldKey} isOverlay={true} Document={this.TextDoc} isSelected={returnTrue} select={emptyFunction} isTopMost={true}
-                        selectOnLoad={true} ContainingCollectionView={undefined} whenActiveChanged={emptyFunction} active={returnTrue} ScreenToLocalTransform={() => this._textXf} focus={emptyDocFunction} />
+                        selectOnLoad={true} ContainingCollectionView={undefined} whenActiveChanged={emptyFunction} active={returnTrue}
+                        ScreenToLocalTransform={this.textXf} focus={emptyDocFunction} />
                 </div>
             </ div>;
         }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index cd74d3a84..ebdb0c75c 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -18,7 +18,7 @@ export class CollectionFreeFormLinksView extends React.Component<CollectionViewP
     componentDidMount() {
         this._brushReactionDisposer = reaction(() => this.props.Document.GetList(this.props.fieldKey, [] as Document[]).map(doc => doc.GetNumber(KeyStore.X, 0)),
             () => {
-                let views = this.props.Document.GetList(this.props.fieldKey, [] as Document[]);
+                let views = this.props.Document.GetList(this.props.fieldKey, [] as Document[]).filter(doc => doc.GetText(KeyStore.BackgroundLayout, "").indexOf("istogram") !== -1);
                 for (let i = 0; i < views.length; i++) {
                     for (let j = 0; j < views.length; j++) {
                         let srcDoc = views[j];
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 639dae30a..ae05c2dad 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -1,4 +1,4 @@
-import { action, IReactionDisposer, reaction } from "mobx";
+import { action, IReactionDisposer, reaction, trace, computed } from "mobx";
 import { baseKeymap } from "prosemirror-commands";
 import { history } from "prosemirror-history";
 import { keymap } from "prosemirror-keymap";
@@ -20,6 +20,7 @@ import { FieldView, FieldViewProps } from "./FieldView";
 import "./FormattedTextBox.scss";
 import React = require("react");
 import { SelectionManager } from "../../util/SelectionManager";
+import { observer } from "mobx-react";
 const { buildMenuItems } = require("prosemirror-example-setup");
 const { menuBar } = require("prosemirror-menu");
 
@@ -44,6 +45,7 @@ export interface FormattedTextBoxOverlay {
     isOverlay?: boolean;
 }
 
+@observer
 export class FormattedTextBox extends React.Component<(FieldViewProps & FormattedTextBoxOverlay)> {
     public static LayoutString(fieldStr: string = "DataKey") {
         return FieldView.LayoutString(FormattedTextBox, fieldStr);
@@ -108,7 +110,7 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte
                     if (this._editorView) {
                         this._editorView.destroy();
                     }
-                    this.setupEditor(config, MainOverlayTextBox.Instance.TextDoc); // bcz: not sure why, but the order of events is such that this.props.Document hasn't updated yet, so without forcing the editor to the MainOverlayTextBox, it will display the previously focused textbox
+                    this.setupEditor(config, this.props.Document);// MainOverlayTextBox.Instance.TextDoc); // bcz: not sure why, but the order of events is such that this.props.Document hasn't updated yet, so without forcing the editor to the MainOverlayTextBox, it will display the previously focused textbox
                 }
             );
         } else {
@@ -116,26 +118,18 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte
                 () => this.props.isSelected() && MainOverlayTextBox.Instance.SetTextDoc(this.props.Document, this.props.fieldKey, this._ref.current!, this.props.ScreenToLocalTransform()));
         }
 
+
         this._reactionDisposer = reaction(
             () => {
                 const field = this.props.Document ? this.props.Document.GetT(this.props.fieldKey, RichTextField) : undefined;
                 return field && field !== FieldWaiting ? field.Data : undefined;
             },
-            field => {
-                if (field && this._editorView && !this._applyingChange) {
-                    this._editorView.updateState(
-                        EditorState.fromJSON(config, JSON.parse(field))
-                    );
-                }
-            }
+            field => field && this._editorView && !this._applyingChange &&
+                this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field)))
         );
         this.setupEditor(config, this.props.Document);
     }
 
-    shouldComponentUpdate() {
-        return false;
-    }
-
     private setupEditor(config: any, doc?: Document) {
         let field = doc ? doc.GetT(this.props.fieldKey, RichTextField) : undefined;
         if (this._ref.current) {
@@ -262,7 +256,7 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte
         // (e.nativeEvent as any).DASHFormattedTextBoxHandled = true;
     }
     render() {
-        let style = this.props.isSelected() || this.props.isOverlay ? "scroll" : "hidden";
+        let style = this.props.isOverlay ? "scroll" : "hidden";
         return (
             <div className={`formattedTextBox-cont-${style}`}
                 onKeyDown={this.onKeyPress}
@@ -273,8 +267,7 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte
                 onContextMenu={this.specificContextMenu}
                 // tfs: do we need this event handler
                 onWheel={this.onPointerWheel}
-                ref={this._ref}
-            />
+                ref={this._ref} />
         );
     }
 }
-- 
cgit v1.2.3-70-g09d2


From 73fb401abe04633112b45691e6e05657a0fbe2dc Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 27 Apr 2019 16:27:48 -0400
Subject: extended link lines to work for documents nested one-level in
 collections.

---
 .../collectionFreeForm/CollectionFreeFormLinksView.tsx         | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index ebdb0c75c..6d6b6e309 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -72,7 +72,15 @@ export class CollectionFreeFormLinksView extends React.Component<CollectionViewP
         let equalViews = [view];
         let containerDoc = view.props.Document.GetT(KeyStore.AnnotationOn, Document);
         if (containerDoc && containerDoc instanceof Document) {
-            equalViews = DocumentManager.Instance.getDocumentViews(containerDoc.GetPrototype()!);
+            equalViews.push(...DocumentManager.Instance.getDocumentViews(containerDoc.GetPrototype()!));
+        }
+        if (view.props.ContainingCollectionView) {
+            let collid = view.props.ContainingCollectionView.props.Document.Id;
+            this.props.Document.GetList(this.props.fieldKey, [] as Document[]).
+                filter(child =>
+                    child.Id === collid).map(view =>
+                        DocumentManager.Instance.getDocumentViews(view).map(view =>
+                            equalViews.push(view)));
         }
         return equalViews.filter(sv => sv.props.ContainingCollectionView && sv.props.ContainingCollectionView.props.Document === this.props.Document);
     }
-- 
cgit v1.2.3-70-g09d2


From 3ac2d1ed68fb4190c5ac6ca4f383ddaac6dbc1db Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 27 Apr 2019 23:18:05 -0400
Subject: added a UI to access the link document as a Text document

---
 .../CollectionFreeFormLinkView.scss                |  6 ++++
 .../CollectionFreeFormLinkView.tsx                 | 33 ++++++++++++++++++----
 .../CollectionFreeFormLinksView.tsx                |  3 +-
 src/fields/Document.ts                             |  4 +--
 4 files changed, 37 insertions(+), 9 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss
index 3b2f79be1..3e8a8a442 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss
@@ -3,4 +3,10 @@
     stroke-width: 3;
     transform: translate(10000px,10000px);
     pointer-events: all;
+}
+.collectionfreeformlinkview-linkCircle {
+    stroke: black;
+    stroke-width: 3;
+    transform: translate(10000px,10000px);
+    pointer-events: all;
 }
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index 20c5a84bf..8cd6c7624 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -5,19 +5,36 @@ import { Utils } from "../../../../Utils";
 import "./CollectionFreeFormLinkView.scss";
 import React = require("react");
 import v5 = require("uuid/v5");
+import { InkingControl } from "../../InkingControl";
 
 export interface CollectionFreeFormLinkViewProps {
     A: Document;
     B: Document;
     LinkDocs: Document[];
+    addDocument: (document: Document, allowDuplicates?: boolean) => boolean;
+    removeDocument: (document: Document) => boolean;
 }
 
 @observer
 export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFormLinkViewProps> {
 
     onPointerDown = (e: React.PointerEvent) => {
-        this.props.LinkDocs.map(l =>
-            console.log("Link:" + l.Title));
+        if (e.button === 0 && !InkingControl.Instance.selectedTool) {
+            let a = this.props.A;
+            let b = this.props.B;
+            let x1 = a.GetNumber(KeyStore.X, 0) + (a.GetBoolean(KeyStore.IsMinimized, false) ? 5 : a.Width() / 2);
+            let y1 = a.GetNumber(KeyStore.Y, 0) + (a.GetBoolean(KeyStore.IsMinimized, false) ? 5 : a.Height() / 2);
+            let x2 = b.GetNumber(KeyStore.X, 0) + (b.GetBoolean(KeyStore.IsMinimized, false) ? 5 : b.Width() / 2);
+            let y2 = b.GetNumber(KeyStore.Y, 0) + (b.GetBoolean(KeyStore.IsMinimized, false) ? 5 : b.Height() / 2);
+            this.props.LinkDocs.map(l => {
+                let width = l.GetNumber(KeyStore.Width, 0);
+                l.SetNumber(KeyStore.X, (x1 + x2) / 2 - width / 2);
+                l.SetNumber(KeyStore.Y, (y1 + y2) / 2 + 10);
+                if (!this.props.removeDocument(l)) this.props.addDocument(l, false);
+            });
+            e.stopPropagation();
+            e.preventDefault();
+        }
     }
     render() {
         let l = this.props.LinkDocs;
@@ -28,10 +45,14 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
         let x2 = b.GetNumber(KeyStore.X, 0) + (b.GetBoolean(KeyStore.IsMinimized, false) ? 5 : b.Width() / 2);
         let y2 = b.GetNumber(KeyStore.Y, 0) + (b.GetBoolean(KeyStore.IsMinimized, false) ? 5 : b.Height() / 2);
         return (
-            <line key={Utils.GenerateGuid()} className="collectionfreeformlinkview-linkLine" onPointerDown={this.onPointerDown}
-                style={{ strokeWidth: `${l.length * 5}` }}
-                x1={`${x1}`} y1={`${y1}`}
-                x2={`${x2}`} y2={`${y2}`} />
+            <>
+                <line key={Utils.GenerateGuid()} className="collectionfreeformlinkview-linkLine"
+                    style={{ strokeWidth: `${l.length * 5}` }}
+                    x1={`${x1}`} y1={`${y1}`}
+                    x2={`${x2}`} y2={`${y2}`} />
+                <circle key={Utils.GenerateGuid()} className="collectionfreeformlinkview-linkLine"
+                    cx={(x1 + x2) / 2} cy={(y1 + y2) / 2} r={10} onPointerDown={this.onPointerDown} />
+            </>
         );
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index 6d6b6e309..b97df7556 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -105,7 +105,8 @@ export class CollectionFreeFormLinksView extends React.Component<CollectionViewP
             );
             return drawnPairs;
         }, [] as { a: Document, b: Document, l: Document[] }[]);
-        return connections.map(c => <CollectionFreeFormLinkView key={Utils.GenerateGuid()} A={c.a} B={c.b} LinkDocs={c.l} />);
+        return connections.map(c => <CollectionFreeFormLinkView key={Utils.GenerateGuid()} A={c.a} B={c.b} LinkDocs={c.l}
+            removeDocument={this.props.removeDocument} addDocument={this.props.addDocument} />);
     }
 
     render() {
diff --git a/src/fields/Document.ts b/src/fields/Document.ts
index 7a7dbc3fe..2797efc09 100644
--- a/src/fields/Document.ts
+++ b/src/fields/Document.ts
@@ -13,6 +13,7 @@ import { BooleanField } from "./BooleanField";
 import { allLimit } from "async";
 import { prototype } from "nodemailer/lib/smtp-pool";
 import { HistogramField } from "../client/northstar/dash-fields/HistogramField";
+import { Documents } from "../client/documents/Documents";
 
 export class Document extends Field {
     //TODO tfs: We should probably store FieldWaiting in fields when we request it from the server so that we don't set up multiple server gets for the same document and field
@@ -374,8 +375,7 @@ export class Document extends Field {
     @action
     CreateLink(dstTarg: Document) {
         let batch = UndoManager.StartBatch("document view drop");
-        let linkDoc: Document = new Document();
-        linkDoc.SetText(KeyStore.Title, "New Link");
+        let linkDoc: Document = Documents.TextDocument({ width: 100, height: 25, title: "-link-" });
         linkDoc.SetText(KeyStore.LinkDescription, "");
         linkDoc.SetText(KeyStore.LinkTags, "Default");
 
-- 
cgit v1.2.3-70-g09d2

