From 6a2b210f32cb70646a5d9097e667c0d199057901 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 6 Mar 2020 13:06:34 -0500
Subject: fixes to documentBox to work with templates.  changed tree view to
 select documents.  fixed panning in freeform view to account for scale
 correctly.  increased max renderdepth to 12

---
 src/client/views/collections/CollectionTreeView.tsx | 5 +++++
 1 file changed, 5 insertions(+)

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

diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 28f620157..deff3d177 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -184,6 +184,11 @@ class TreeView extends React.Component<TreeViewProps> {
             EditableView.loadId = doc[Id];
             return this.props.addDocument(doc);
         })}
+        onClick={() => {
+            SelectionManager.DeselectAll();
+            Doc.UserDoc().SelectedDocs = new List([this.props.document]);
+            return false;
+        }}
         OnTab={undoBatch((shift?: boolean) => {
             EditableView.loadId = this.dataDoc[Id];
             shift ? this.props.outdentDocument?.() : this.props.indentDocument?.();
-- 
cgit v1.2.3-70-g09d2


From 4863b1ef9ec3160b0888a5ab8bb1a62274aed5ec Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 6 Mar 2020 17:29:27 -0500
Subject: made tree views display documentViews instead of just strings

---
 src/client/documents/Documents.ts                  |  1 +
 src/client/util/DocumentManager.ts                 | 11 ++++-
 src/client/views/DocumentDecorations.tsx           |  3 +-
 .../views/collections/CollectionSchemaCells.tsx    |  3 +-
 .../views/collections/CollectionTreeView.scss      |  3 ++
 .../views/collections/CollectionTreeView.tsx       | 52 +++++++++++++++++++---
 src/client/views/nodes/DocuLinkBox.scss            |  7 ++-
 src/client/views/nodes/DocuLinkBox.tsx             | 11 +++--
 src/client/views/nodes/DocumentView.scss           |  2 +
 src/client/views/nodes/DocumentView.tsx            | 14 ++++--
 .../authentication/models/current_user_utils.ts    | 14 +++---
 11 files changed, 95 insertions(+), 26 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 5f0e63b56..1f351e93f 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -123,6 +123,7 @@ export interface DocumentOptions {
     displayTimecode?: number; // the time that a document should be displayed (e.g., time an annotation should be displayed on a video)
     borderRounding?: string;
     boxShadow?: string;
+    dontRegisterChildren?: boolean;
     _pivotField?: string; // field key used to determine headings for sections in stacking, masonry, pivot views
     schemaColumns?: List<SchemaHeaderField>;
     dockingConfig?: string;
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 323d31af2..6711947ad 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -92,10 +92,17 @@ export class DocumentManager {
     public getDocumentViews(toFind: Doc): DocumentView[] {
         const toReturn: DocumentView[] = [];
 
+        // heurstic to return the "best" documents first:
+        //   choose an exact match over an alias match
+        //   choose documents that have a PanelWidth() over those that don't (the treeview documents have no panelWidth)
         DocumentManager.Instance.DocumentViews.map(view =>
-            view.props.Document.presBox === undefined && view.props.Document === toFind && toReturn.push(view));
+            view.props.Document.presBox === undefined && view.props.PanelWidth() > 1 && view.props.Document === toFind && toReturn.push(view));
         DocumentManager.Instance.DocumentViews.map(view =>
-            view.props.Document.presBox === undefined && view.props.Document !== toFind && Doc.AreProtosEqual(view.props.Document, toFind) && toReturn.push(view));
+            view.props.Document.presBox === undefined && view.props.PanelWidth() <= 1 && view.props.Document === toFind && toReturn.push(view));
+        DocumentManager.Instance.DocumentViews.map(view =>
+            view.props.Document.presBox === undefined && view.props.PanelWidth() > 1 && view.props.Document !== toFind && Doc.AreProtosEqual(view.props.Document, toFind) && toReturn.push(view));
+        DocumentManager.Instance.DocumentViews.map(view =>
+            view.props.Document.presBox === undefined && view.props.PanelWidth() <= 1 && view.props.Document !== toFind && Doc.AreProtosEqual(view.props.Document, toFind) && toReturn.push(view));
 
         return toReturn;
     }
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index c98be0d4a..39d078a36 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -43,7 +43,7 @@ export type CloseCall = (toBeDeleted: DocumentView[]) => void;
 export class DocumentDecorations extends React.Component<{}, { value: string }> {
     static Instance: DocumentDecorations;
     private _resizeHdlId = "";
-    private _keyinput: React.RefObject<HTMLInputElement>;
+    private _keyinput = React.createRef<HTMLInputElement>();
     private _resizeBorderWidth = 16;
     private _linkBoxHeight = 20 + 3; // link button height + margin
     private _titleHeight = 20;
@@ -62,7 +62,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
     constructor(props: Readonly<{}>) {
         super(props);
         DocumentDecorations.Instance = this;
-        this._keyinput = React.createRef();
         reaction(() => SelectionManager.SelectedDocuments().slice(), docs => this.titleBlur(false));
     }
 
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index df7abad61..79b5d7bb7 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -77,7 +77,8 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
 
     @action
     isEditingCallback = (isEditing: boolean): void => {
-        document.addEventListener("keydown", this.onKeyDown);
+        document.removeEventListener("keydown", this.onKeyDown);
+        isEditing && document.addEventListener("keydown", this.onKeyDown);
         this._isEditing = isEditing;
         this.props.setIsEditing(isEditing);
         this.props.changeFocusedCellByIndex(this.props.row, this.props.col);
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index 6ebe81545..fd4a963c3 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -123,6 +123,9 @@
     .editableView-container-editing-oneLine {
         min-width: 15px;
     }
+    .documentView-node-topmost {
+        width: unset;
+    }
 }
 
 .treeViewItem-header-above {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index deff3d177..54ad2ad48 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -10,7 +10,7 @@ import { Document, listSpec } from '../../../new_fields/Schema';
 import { ComputedField, ScriptField } from '../../../new_fields/ScriptField';
 import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../new_fields/Types';
 import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils';
-import { emptyFunction, emptyPath, returnFalse, Utils } from '../../../Utils';
+import { emptyFunction, emptyPath, returnFalse, Utils, returnOne, returnZero, returnTransparent, returnTrue } from '../../../Utils';
 import { Docs, DocUtils } from '../../documents/Documents';
 import { DocumentType } from "../../documents/DocumentTypes";
 import { DocumentManager } from '../../util/DocumentManager';
@@ -34,6 +34,7 @@ import "./CollectionTreeView.scss";
 import React = require("react");
 import { CollectionViewType } from './CollectionView';
 import { RichTextField } from '../../../new_fields/RichTextField';
+import { DocumentView } from '../nodes/DocumentView';
 
 
 export interface TreeViewProps {
@@ -92,6 +93,7 @@ class TreeView extends React.Component<TreeViewProps> {
     private _header?: React.RefObject<HTMLDivElement> = React.createRef();
     private _treedropDisposer?: DragManager.DragDropDisposer;
     private _dref = React.createRef<HTMLDivElement>();
+    private _tref = React.createRef<HTMLDivElement>();
 
     get displayName() { return "TreeView(" + this.props.document.title + ")"; }  // this makes mobx trace() statements more descriptive
 
@@ -171,13 +173,16 @@ class TreeView extends React.Component<TreeViewProps> {
     editableView = (key: string, style?: string) => (<EditableView
         oneLine={true}
         display={"inline-block"}
-        editing={this.dataDoc[Id] === EditableView.loadId}
+        editing={true /*this.dataDoc[Id] === EditableView.loadId*/}
         contents={StrCast(this.props.document[key])}
         height={12}
         fontStyle={style}
         fontSize={12}
         GetValue={() => StrCast(this.props.document[key])}
-        SetValue={undoBatch((value: string) => Doc.SetInPlace(this.props.document, key, value, false) || true)}
+        SetValue={undoBatch((value: string) => {
+            Doc.SetInPlace(this.props.document, key, value, false) || true;
+            this.props.document.editTitle = undefined;
+        })}
         OnFillDown={undoBatch((value: string) => {
             Doc.SetInPlace(this.props.document, key, value, false);
             const doc = Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, templates: new List<string>([Templates.Title.Layout]) });
@@ -263,6 +268,13 @@ class TreeView extends React.Component<TreeViewProps> {
         const finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1] + (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0));
         return finalXf;
     }
+    getTransform = () => {
+        const { scale, translateX, translateY } = Utils.GetScreenTransform(this._tref.current!);
+        const outerXf = this.props.outerXf();
+        const offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
+        const finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1]);
+        return finalXf;
+    }
     docWidth = () => {
         const layoutDoc = Doc.Layout(this.props.document);
         const aspect = NumCast(layoutDoc._nativeHeight) / NumCast(layoutDoc._nativeWidth);
@@ -404,8 +416,8 @@ class TreeView extends React.Component<TreeViewProps> {
      */
     @computed
     get renderTitle() {
-        const reference = React.createRef<HTMLDivElement>();
-        const onItemDown = SetupDrag(reference, () => this.dataDoc, this.move, this.props.dropAction, this.props.treeViewId[Id], true);
+        const onItemDown = SetupDrag(this._tref, () => this.dataDoc, this.move, this.props.dropAction, this.props.treeViewId[Id], true);
+        const editTitle = ScriptField.MakeFunction("this.editTitle=true", { this: Doc.name });
 
         const headerElements = (
             <span className="collectionTreeView-keyHeader" key={this.treeViewExpandedView}
@@ -424,14 +436,40 @@ class TreeView extends React.Component<TreeViewProps> {
             <FontAwesomeIcon title="open in pane on right" icon="angle-right" size="lg" />
         </div>);
         return <>
-            <div className="docContainer" title="click to edit title" id={`docContainer-${this.props.parentKey}`} ref={reference} onPointerDown={onItemDown}
+            <div className="docContainer" ref={this._tref} title="click to edit title" id={`docContainer-${this.props.parentKey}`} onPointerDown={onItemDown}
                 style={{
                     background: Doc.IsHighlighted(this.props.document) ? "orange" : Doc.IsBrushed(this.props.document) ? "#06121212" : "0",
                     fontWeight: this.props.document.searchMatch ? "bold" : undefined,
                     outline: BoolCast(this.props.document.workspaceBrush) ? "dashed 1px #06123232" : undefined,
                     pointerEvents: this.props.active() || SelectionManager.GetIsDragging() ? "all" : "none"
                 }} >
-                {this.editableView("title")}
+                {this.props.document.editTitle ?
+                    this.editableView("title") :
+                    <DocumentView
+                        Document={this.props.document}
+                        DataDoc={undefined}
+                        LibraryPath={this.props.libraryPath || []}
+                        addDocument={undefined}
+                        addDocTab={this.props.addDocTab}
+                        pinToPres={emptyFunction}
+                        onClick={editTitle}
+                        moveDocument={this.props.moveDocument}
+                        removeDocument={undefined}
+                        ScreenToLocalTransform={this.getTransform}
+                        ContentScaling={returnOne}
+                        PanelWidth={returnZero}
+                        PanelHeight={returnZero}
+                        renderDepth={1}
+                        focus={emptyFunction}
+                        parentActive={returnTrue}
+                        whenActiveChanged={emptyFunction}
+                        bringToFront={emptyFunction}
+                        dontRegisterView={BoolCast(this.props.treeViewId.dontRegisterChildren)}
+                        ContainingCollectionView={undefined}
+                        ContainingCollectionDoc={undefined}
+                        zoomToScale={emptyFunction}
+                        getScale={returnOne}
+                    />}
             </div >
             {this.props.treeViewHideHeaderFields() ? (null) : headerElements}
             {openRight}
diff --git a/src/client/views/nodes/DocuLinkBox.scss b/src/client/views/nodes/DocuLinkBox.scss
index 286033475..f2c203548 100644
--- a/src/client/views/nodes/DocuLinkBox.scss
+++ b/src/client/views/nodes/DocuLinkBox.scss
@@ -1,4 +1,4 @@
-.docuLinkBox-cont {
+.docuLinkBox-cont, .docuLinkBox-cont-small {
     cursor: default;
     position: absolute;
     width: 15;
@@ -21,4 +21,9 @@
         padding-left: 2px;
         padding-top: 1px;
     }
+}
+
+.docuLinkBox-cont-small {
+    width:5px;
+    height:5px;
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/DocuLinkBox.tsx b/src/client/views/nodes/DocuLinkBox.tsx
index 882e57006..776d2019d 100644
--- a/src/client/views/nodes/DocuLinkBox.tsx
+++ b/src/client/views/nodes/DocuLinkBox.tsx
@@ -124,8 +124,8 @@ export class DocuLinkBox extends DocComponent<FieldViewProps, DocLinkSchema>(Doc
     }
 
     render() {
-        const x = NumCast(this.props.Document[this.props.fieldKey + "_x"], 100);
-        const y = NumCast(this.props.Document[this.props.fieldKey + "_y"], 100);
+        const x = this.props.PanelWidth() > 1 ? NumCast(this.props.Document[this.props.fieldKey + "_x"], 100) : 0;
+        const y = this.props.PanelWidth() > 1 ? NumCast(this.props.Document[this.props.fieldKey + "_y"], 100) : 0;
         const c = StrCast(this.props.Document.backgroundColor, "lightblue");
         const anchor = this.props.fieldKey === "anchor1" ? "anchor2" : "anchor1";
         const anchorScale = (x === 0 || x === 100 || y === 0 || y === 100) ? 1 : .15;
@@ -140,9 +140,12 @@ export class DocuLinkBox extends DocComponent<FieldViewProps, DocLinkSchema>(Doc
                 </div>}
             </div>
         );
-        return <div className="docuLinkBox-cont" onPointerDown={this.onPointerDown} onClick={this.onClick} title={targetTitle} onContextMenu={this.specificContextMenu}
+        const small = this.props.PanelWidth() <= 1;
+        return <div className={`docuLinkBox-cont${small ? "-small" : ""}`} onPointerDown={this.onPointerDown} onClick={this.onClick} title={targetTitle} onContextMenu={this.specificContextMenu}
             ref={this._ref} style={{
-                background: c, left: `calc(${x}% - 7.5px)`, top: `calc(${y}% - 7.5px)`,
+                background: c,
+                left: !small ? `calc(${x}% - 7.5px)` : undefined,
+                top: !small ? `calc(${y}% - 7.5px)` : undefined,
                 transform: `scale(${anchorScale / this.props.ContentScaling()})`
             }} >
             {!this._editing && !this._forceOpen ? (null) :
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index 56e3eb220..d1d96f0a1 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -5,6 +5,8 @@
     position: inherit;
     top: 0;
     left: 0;
+    width: 100%;
+    height: 100%;
     border-radius: inherit;
     transition: outline .3s linear;
     cursor: grab;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 7d2940df5..463c6b5bd 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1018,6 +1018,16 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     @computed get innards() {
         TraceMobx();
+        if (!this.props.PanelWidth()) {
+            return <div style={{ display: "flex" }}>
+                {StrCast(this.props.Document.title)}
+                {this.Document.links && DocListCast(this.Document.links).filter(d => !d.hidden).filter(this.isNonTemporalLink).map((d, i) =>
+                    <div className="documentView-docuLinkWrapper" style={{ position: "absolute", top: 0, left: 0 }} key={`${d[Id]}`}>
+                        <DocumentView {...this.props} ContentScaling={returnOne} ContainingCollectionDoc={this.props.Document}
+                            PanelWidth={returnOne} PanelHeight={returnOne} Document={d} layoutKey={this.linkEndpoint(d)} backgroundColor={returnTransparent} removeDocument={undoBatch(doc => doc.hidden = true)} />
+                    </div>)}
+            </div>;
+        }
         const showTitle = StrCast(this.layoutDoc._showTitle);
         const showTitleHover = StrCast(this.layoutDoc._showTitleHover);
         const showCaption = StrCast(this.layoutDoc._showCaption);
@@ -1116,8 +1126,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 border: highlighting && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined,
                 boxShadow: this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : undefined,
                 background: finalColor,
-                width: "100%",
-                height: "100%",
                 opacity: this.Document.opacity
             }}>
             {this.Document.isBackground ? <div className="documentView-lock"> <FontAwesomeIcon icon="unlock" size="lg" /> </div> : (null)}
@@ -1131,7 +1139,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     }
 }
 
-Scripting.addGlobal(function toggleDetail(doc: any, layoutKey: string, otherKey: string="layout") {
+Scripting.addGlobal(function toggleDetail(doc: any, layoutKey: string, otherKey: string = "layout") {
     const dv = DocumentManager.Instance.getDocumentView(doc);
     if (dv?.props.Document.layoutKey === layoutKey) dv?.switchViews(otherKey !== "layout", otherKey.replace("layout_", ""));
     else dv?.switchViews(true, layoutKey.replace("layout_", ""));
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index f672da085..5d93f208a 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -37,17 +37,19 @@ export class CurrentUserUtils {
     @observable public static GuestMobile: Doc | undefined;
 
     static setupDefaultDocTemplates(doc: Doc, buttons?: string[]) {
-        const taskStatusValues = [  { title: "todo", _backgroundColor: "blue", color: "white" },
-                                    { title: "in progress", _backgroundColor: "yellow", color: "black" },
-                                    { title: "completed", _backgroundColor: "green", color: "white" }
+        const taskStatusValues = [{ title: "todo", _backgroundColor: "blue", color: "white" },
+        { title: "in progress", _backgroundColor: "yellow", color: "black" },
+        { title: "completed", _backgroundColor: "green", color: "white" }
         ];
         const noteTemplates = [
             Docs.Create.TextDocument("", { title: "text", style: "Note", isTemplateDoc: true, backgroundColor: "yellow" }),
             Docs.Create.TextDocument("", { title: "text", style: "Idea", isTemplateDoc: true, backgroundColor: "pink" }),
             Docs.Create.TextDocument("", { title: "text", style: "Topic", isTemplateDoc: true, backgroundColor: "lightBlue" }),
             Docs.Create.TextDocument("", { title: "text", style: "Person", isTemplateDoc: true, backgroundColor: "lightGreen" }),
-            Docs.Create.TextDocument("", { title: "text", style: "Todo", isTemplateDoc: true, backgroundColor: "orange",_autoHeight: false, 
-                layout:FormattedTextBox.LayoutString("Todo"), _height: 100, _showCaption: "caption",caption: RichTextField.DashField("taskStatus") })
+            Docs.Create.TextDocument("", {
+                title: "text", style: "Todo", isTemplateDoc: true, backgroundColor: "orange", _autoHeight: false,
+                layout: FormattedTextBox.LayoutString("Todo"), _height: 100, _showCaption: "caption", caption: RichTextField.DashField("taskStatus")
+            })
         ];
         doc.fieldTypes = Docs.Create.TreeDocument([], { title: "field enumerations" });
         Doc.addFieldEnumerations(Doc.GetProto(noteTemplates[4]), "taskStatus", taskStatusValues);
@@ -221,7 +223,7 @@ export class CurrentUserUtils {
             _width: 50, _height: 25, title: "Library", fontSize: 10,
             letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)",
             sourcePanel: Docs.Create.TreeDocument([doc.workspaces as Doc, doc.documents as Doc, Docs.Prototypes.MainLinkDocument(), doc, doc.recentlyClosed as Doc], {
-                title: "Library", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, dropAction: "alias", lockedPosition: true, boxShadow: "0 0",
+                title: "Library", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, dropAction: "alias", lockedPosition: true, boxShadow: "0 0", dontRegisterChildren: true
             }),
             targetContainer: sidebarContainer,
             onClick: ScriptField.MakeScript("this.targetContainer.proto = this.sourcePanel;")
-- 
cgit v1.2.3-70-g09d2

