From 2bb5667b10a8c402f8ec75c632ca3fdabe642419 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 15 Dec 2019 18:25:03 -0500
Subject: added LOD detail switching for collection free form views

---
 .../collectionFreeForm/CollectionFreeFormView.tsx   | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 89c1df598..9bb6fa97e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -882,6 +882,19 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         eles.push(<CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />);
         return eles;
     }
+    @computed get placeholder() {
+        return <div style={{ background: "gray", width: "100%", height: "100%", display: "flex", alignItems: "center" }}>
+            <span style={{ fontSize: 96, background: "gray", margin: "auto", display: "flex" }}>{this.props.Document.title}></span></div>;
+    }
+    @computed get marqueeView() {
+        return <MarqueeView {...this.props} extensionDoc={this.extensionDoc!} activeDocuments={this.getActiveDocuments} selectDocuments={this.selectDocuments} addDocument={this.addDocument}
+            addLiveTextDocument={this.addLiveTextBox} getContainerTransform={this.getContainerTransform} getTransform={this.getTransform} isAnnotationOverlay={this.isAnnotationOverlay}>
+            <CollectionFreeFormViewPannableContents centeringShiftX={this.centeringShiftX} centeringShiftY={this.centeringShiftY}
+                easing={this.easing} zoomScaling={this.zoomScaling} panX={this.panX} panY={this.panY}>
+                {this.children}
+            </CollectionFreeFormViewPannableContents>
+        </MarqueeView>;
+    }
     render() {
         TraceMobx();
         // update the actual dimensions of the collection so that they can inquired (e.g., by a minimap)
@@ -895,13 +908,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             <div className={"collectionfreeformview-container"} ref={this.createDropTarget} onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
                 style={{ pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined, height: this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}
                 onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onTouchStart={this.onTouchStart}>
-                <MarqueeView {...this.props} extensionDoc={this.extensionDoc} activeDocuments={this.getActiveDocuments} selectDocuments={this.selectDocuments} addDocument={this.addDocument}
-                    addLiveTextDocument={this.addLiveTextBox} getContainerTransform={this.getContainerTransform} getTransform={this.getTransform} isAnnotationOverlay={this.isAnnotationOverlay}>
-                    <CollectionFreeFormViewPannableContents centeringShiftX={this.centeringShiftX} centeringShiftY={this.centeringShiftY}
-                        easing={this.easing} zoomScaling={this.zoomScaling} panX={this.panX} panY={this.panY}>
-                        {this.children}
-                    </CollectionFreeFormViewPannableContents>
-                </MarqueeView>
+                {!BoolCast(this.Document.LODdisable) && this.props.renderDepth > 0 && this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale < NumCast(this.Document.LODarea, 100000) ? this.placeholder : this.marqueeView}
                 <CollectionFreeFormOverlayView elements={this.elementFunc} />
             </div>;
     }
-- 
cgit v1.2.3-70-g09d2


From 55823d0cc300f5cdd90ee34013bfdee93b5709e6 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 15 Dec 2019 20:11:58 -0500
Subject: added a DocumentBox as a contentfitting container for another
 document.  added a menu item for showing selected document.

---
 src/client/documents/DocumentTypes.ts              |  3 +-
 src/client/documents/Documents.ts                  |  9 ++++
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  2 +-
 .../views/nodes/ContentFittingDocumentView.tsx     |  6 +--
 src/client/views/nodes/DocumentBox.scss            |  6 +++
 src/client/views/nodes/DocumentBox.tsx             | 55 ++++++++++++++++++++++
 src/client/views/nodes/DocumentContentsView.tsx    |  3 +-
 src/client/views/nodes/ImageBox.tsx                |  1 -
 src/new_fields/ScriptField.ts                      |  2 +-
 .../authentication/models/current_user_utils.ts    |  1 +
 10 files changed, 80 insertions(+), 8 deletions(-)
 create mode 100644 src/client/views/nodes/DocumentBox.scss
 create mode 100644 src/client/views/nodes/DocumentBox.tsx

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

diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index f6dd0c346..8f96b2fa6 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -25,5 +25,6 @@ export enum DocumentType {
     COLOR = "color",
     DOCULINK = "doculink",
     PDFANNO = "pdfanno",
-    INK = "ink"
+    INK = "ink",
+    DOCUMENT = "document"
 }
\ No newline at end of file
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 4ba45ac30..50c51ace1 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -48,6 +48,7 @@ import { PresElementBox } from "../views/presentationview/PresElementBox";
 import { QueryBox } from "../views/nodes/QueryBox";
 import { ColorBox } from "../views/nodes/ColorBox";
 import { DocuLinkBox } from "../views/nodes/DocuLinkBox";
+import { DocumentBox } from "../views/nodes/DocumentBox";
 import { InkingStroke } from "../views/InkingStroke";
 import { InkField } from "../../new_fields/InkField";
 const requestImageSize = require('../util/request-image-size');
@@ -171,6 +172,10 @@ export namespace Docs {
                 layout: { view: KeyValueBox, dataField: data },
                 options: { height: 150 }
             }],
+            [DocumentType.DOCUMENT, {
+                layout: { view: DocumentBox, dataField: data },
+                options: { height: 250 }
+            }],
             [DocumentType.VID, {
                 layout: { view: VideoBox, dataField: data },
                 options: { currentTimecode: 0 },
@@ -482,6 +487,10 @@ export namespace Docs {
             return InstanceFromProto(Prototypes.get(DocumentType.KVP), document, { title: document.title + ".kvp", ...options });
         }
 
+        export function DocumentDocument(document?: Doc, options: DocumentOptions = {}) {
+            return InstanceFromProto(Prototypes.get(DocumentType.DOCUMENT), document, { title: document ? document.title + "" : "container", ...options });
+        }
+
         export function FreeformDocument(documents: Array<Doc>, options: DocumentOptions, id?: string) {
             return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Freeform }, id);
         }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 9bb6fa97e..0b18e9f25 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -908,7 +908,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             <div className={"collectionfreeformview-container"} ref={this.createDropTarget} onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
                 style={{ pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined, height: this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}
                 onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onTouchStart={this.onTouchStart}>
-                {!BoolCast(this.Document.LODdisable) && this.props.renderDepth > 0 && this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale < NumCast(this.Document.LODarea, 100000) ? this.placeholder : this.marqueeView}
+                {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 && this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale < NumCast(this.Document.LODarea, 100000) ? this.placeholder : this.marqueeView}
                 <CollectionFreeFormOverlayView elements={this.elementFunc} />
             </div>;
     }
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index 5e3306a11..2565fd932 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -31,9 +31,9 @@ interface ContentFittingDocumentViewProps {
     CollectionDoc?: Doc;
     onClick?: ScriptField;
     getTransform: () => Transform;
-    addDocument: (document: Doc) => boolean;
-    moveDocument: (document: Doc, target: Doc | undefined, addDoc: ((doc: Doc) => boolean)) => boolean;
-    removeDocument: (document: Doc) => boolean;
+    addDocument?: (document: Doc) => boolean;
+    moveDocument?: (document: Doc, target: Doc | undefined, addDoc: ((doc: Doc) => boolean)) => boolean;
+    removeDocument?: (document: Doc) => boolean;
     active: (outsideReaction: boolean) => boolean;
     whenActiveChanged: (isActive: boolean) => void;
     addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean;
diff --git a/src/client/views/nodes/DocumentBox.scss b/src/client/views/nodes/DocumentBox.scss
new file mode 100644
index 000000000..6a2f98166
--- /dev/null
+++ b/src/client/views/nodes/DocumentBox.scss
@@ -0,0 +1,6 @@
+.documentBox-container {
+    width: 100%;
+    height: 100%;
+    pointer-events: all;
+    background: gray;
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx
new file mode 100644
index 000000000..2f2cba485
--- /dev/null
+++ b/src/client/views/nodes/DocumentBox.tsx
@@ -0,0 +1,55 @@
+import { observer } from "mobx-react";
+import { Doc } from "../../../new_fields/Doc";
+import { documentSchema } from "../../../new_fields/documentSchemas";
+import { makeInterface } from "../../../new_fields/Schema";
+import { ComputedField } from "../../../new_fields/ScriptField";
+import { emptyFunction, emptyPath } from "../../../Utils";
+import { ContextMenu } from "../ContextMenu";
+import { ContextMenuProps } from "../ContextMenuItem";
+import { DocComponent } from "../DocComponent";
+import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
+import "./DocumentBox.scss";
+import { FieldView, FieldViewProps } from "./FieldView";
+import React = require("react");
+
+type DocBoxSchema = makeInterface<[typeof documentSchema]>;
+const DocBoxDocument = makeInterface(documentSchema);
+
+@observer
+export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocBoxDocument) {
+    public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DocumentBox, fieldKey); }
+
+
+    specificContextMenu = (e: React.MouseEvent): void => {
+        const funcs: ContextMenuProps[] = [];
+        funcs.push({ description: "Auto Show Selected", event: () => Doc.GetProto(this.props.Document).data = ComputedField.MakeFunction("selectedDocs(this,true,_last_)?.[0]"), icon: "expand-arrows-alt" });
+
+        ContextMenu.Instance.addItem({ description: "DocumentBox Funcs...", subitems: funcs, icon: "asterisk" });
+    }
+    render() {
+        const containedDoc = this.props.Document[this.props.fieldKey] as Doc;
+        return <div className="documentBox-container" onContextMenu={this.specificContextMenu}>
+            {!containedDoc ? (null) : <ContentFittingDocumentView
+                Document={containedDoc}
+                DataDocument={undefined}
+                LibraryPath={emptyPath}
+                fitToBox={this.props.fitToBox}
+                addDocument={this.props.addDocument}
+                moveDocument={this.props.moveDocument}
+                removeDocument={this.props.removeDocument}
+                ruleProvider={this.props.ruleProvider}
+                addDocTab={this.props.addDocTab}
+                pinToPres={this.props.pinToPres}
+                getTransform={this.props.ScreenToLocalTransform}
+                renderDepth={this.props.renderDepth - 1}
+                PanelWidth={this.props.PanelWidth}
+                PanelHeight={this.props.PanelHeight}
+                focus={this.props.focus}
+                active={this.props.active}
+                whenActiveChanged={this.props.whenActiveChanged}
+                setPreviewScript={emptyFunction}
+                previewScript={undefined}
+            />}
+        </div>;
+    }
+}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 1bbc82119..8f6bfc8e1 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -14,6 +14,7 @@ import { LinkFollowBox } from "../linking/LinkFollowBox";
 import { YoutubeBox } from "./../../apis/youtube/YoutubeBox";
 import { AudioBox } from "./AudioBox";
 import { ButtonBox } from "./ButtonBox";
+import { DocumentBox } from "./DocumentBox";
 import { DocumentViewProps } from "./DocumentView";
 import "./DocumentView.scss";
 import { FontIconBox } from "./FontIconBox";
@@ -102,7 +103,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
                     FormattedTextBox, ImageBox, IconBox, DirectoryImportBox, FontIconBox: FontIconBox, ButtonBox, FieldView,
                     CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox,
                     PDFBox, VideoBox, AudioBox, HistogramBox, PresBox, YoutubeBox, LinkFollowBox, PresElementBox, QueryBox,
-                    ColorBox, DocuLinkBox, InkingStroke
+                    ColorBox, DocuLinkBox, InkingStroke, DocumentBox
                 }}
                 bindings={this.CreateBindings()}
                 jsx={this.layout}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index f6aa47f15..09e627078 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -18,7 +18,6 @@ import { undoBatch } from '../../util/UndoManager';
 import { ContextMenu } from "../../views/ContextMenu";
 import { ContextMenuProps } from '../ContextMenuItem';
 import { DocAnnotatableComponent } from '../DocComponent';
-import { InkingControl } from '../InkingControl';
 import FaceRectangles from './FaceRectangles';
 import { FieldView, FieldViewProps } from './FieldView';
 import "./ImageBox.scss";
diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts
index 0cadb60ed..b5ad4a7f6 100644
--- a/src/new_fields/ScriptField.ts
+++ b/src/new_fields/ScriptField.ts
@@ -103,7 +103,7 @@ export class ScriptField extends ObjectField {
     }
     public static CompileScript(script: string, params: object = {}, addReturn = false) {
         const compiled = CompileScript(script, {
-            params: { this: Doc.name, ...params },
+            params: { this: Doc.name, _last_: "any", ...params },
             typecheck: false,
             editable: true,
             addReturn: addReturn
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 50bfb4832..fd01a291d 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -47,6 +47,7 @@ export class CurrentUserUtils {
         doc.activePen = doc;
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [
             { title: "collection", icon: "folder", ignoreClick: true, drag: 'Docs.Create.FreeformDocument([], { nativeWidth: undefined, nativeHeight: undefined, width: 150, height: 100, title: "freeform" })' },
+            { title: "preview", icon: "expand", ignoreClick: true, drag: 'Docs.Create.DocumentDocument(undefined, { width: 250, height: 250, title: "container" })' },
             { title: "todo item", icon: "check", ignoreClick: true, drag: 'getCopy(this.dragFactory, true)', dragFactory: notes[notes.length - 1] },
             { title: "web page", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.WebDocument("https://en.wikipedia.org/wiki/Hedgehog", { width: 300, height: 300, title: "New Webpage" })' },
             { title: "cat image", icon: "cat", ignoreClick: true, drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { width: 200, title: "an image of a cat" })' },
-- 
cgit v1.2.3-70-g09d2


From 7eb932ee4598ac12ba0b854325f51d4a1d052b7f Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 15 Dec 2019 20:31:34 -0500
Subject: from last

---
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 0b18e9f25..fc507bf5e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -908,7 +908,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             <div className={"collectionfreeformview-container"} ref={this.createDropTarget} onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
                 style={{ pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined, height: this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}
                 onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onTouchStart={this.onTouchStart}>
-                {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 && this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale < NumCast(this.Document.LODarea, 100000) ? this.placeholder : this.marqueeView}
+                {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 && this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale < NumCast(this.Document.LODarea, 100000) ? this.placeholder : this.marqueeView}
                 <CollectionFreeFormOverlayView elements={this.elementFunc} />
             </div>;
     }
-- 
cgit v1.2.3-70-g09d2


From e703ad6350a65403b0693542069199aa3a777dfd Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 16 Dec 2019 10:46:32 -0500
Subject: fixed styling of freeformview placeholder

---
 .../collections/collectionFreeForm/CollectionFreeFormView.scss    | 8 ++++++++
 .../collections/collectionFreeForm/CollectionFreeFormView.tsx     | 2 +-
 2 files changed, 9 insertions(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index f8a9e49d8..45eefe6d3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -28,6 +28,14 @@
     // touch action none means that the browser will handle none of the touch actions. this allows us to implement our own actions.
     touch-action: none;
 
+    .collectionfreeformview-placeholderSpan {
+        font-size: 32;
+        background: gray;
+        margin: auto;
+        display: flex;
+        text-align: center;
+    }
+
     .collectionfreeformview>.jsx-parser {
         position: inherit;
         height: 100%;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index fc507bf5e..67f7dd602 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -884,7 +884,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
     @computed get placeholder() {
         return <div style={{ background: "gray", width: "100%", height: "100%", display: "flex", alignItems: "center" }}>
-            <span style={{ fontSize: 96, background: "gray", margin: "auto", display: "flex" }}>{this.props.Document.title}></span></div>;
+            <span className="collectionfreeformview-placeholderSpan">{this.props.Document.title}</span></div>;
     }
     @computed get marqueeView() {
         return <MarqueeView {...this.props} extensionDoc={this.extensionDoc!} activeDocuments={this.getActiveDocuments} selectDocuments={this.selectDocuments} addDocument={this.addDocument}
-- 
cgit v1.2.3-70-g09d2


From 5241b4e7772b5caa10139c845eb6bc91f8827a12 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 16 Dec 2019 10:52:34 -0500
Subject: from last

---
 .../collectionFreeForm/CollectionFreeFormView.scss         | 14 ++++++++++----
 .../collectionFreeForm/CollectionFreeFormView.tsx          |  5 +++--
 2 files changed, 13 insertions(+), 6 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index 45eefe6d3..2e98dbc13 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -28,12 +28,18 @@
     // touch action none means that the browser will handle none of the touch actions. this allows us to implement our own actions.
     touch-action: none;
 
-    .collectionfreeformview-placeholderSpan {
-        font-size: 32;
+    .collectionfreeformview-placeholder {
         background: gray;
-        margin: auto;
+        width: 100%;
+        height: 100%;
         display: flex;
-        text-align: center;
+        align-items: center;
+        .collectionfreeformview-placeholderSpan {
+            font-size: 32;
+            display: flex;
+            text-align: center;
+            background: #80808069;
+        }
     }
 
     .collectionfreeformview>.jsx-parser {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 67f7dd602..e9c3f6b0f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -883,8 +883,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         return eles;
     }
     @computed get placeholder() {
-        return <div style={{ background: "gray", width: "100%", height: "100%", display: "flex", alignItems: "center" }}>
-            <span className="collectionfreeformview-placeholderSpan">{this.props.Document.title}</span></div>;
+        return <div className="collectionfreeformview-placeholder" style={{ background: this.Document.backgroundColor }}>
+            <span className="collectionfreeformview-placeholderSpan">{this.props.Document.title}</span>
+        </div>;
     }
     @computed get marqueeView() {
         return <MarqueeView {...this.props} extensionDoc={this.extensionDoc!} activeDocuments={this.getActiveDocuments} selectDocuments={this.selectDocuments} addDocument={this.addDocument}
-- 
cgit v1.2.3-70-g09d2


From e9d2663d616e4eddb3097145f1b3198c8ef6bcbf Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 16 Dec 2019 12:08:23 -0500
Subject: fixes for focusing on docs after treeview menu item

---
 src/client/views/collections/CollectionTreeView.tsx                | 7 ++++---
 .../collections/collectionFreeForm/CollectionFreeFormView.tsx      | 6 +++++-
 2 files changed, 9 insertions(+), 4 deletions(-)

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

diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 0a22a897c..c3fd85274 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,7 +1,7 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faAngleRight, faArrowsAltH, faBell, faCamera, faCaretDown, faCaretRight, faCaretSquareDown, faCaretSquareRight, faExpand, faMinus, faPlus, faTrash, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable } from "mobx";
+import { action, computed, observable, untracked, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, DocListCast, Field, HeightSym, WidthSym } from '../../../new_fields/Doc';
 import { Id } from '../../../new_fields/FieldSymbols';
@@ -90,8 +90,8 @@ class TreeView extends React.Component<TreeViewProps> {
 
     get defaultExpandedView() { return this.childDocs ? this.fieldKey : StrCast(this.props.document.defaultExpandedView, "fields"); }
     @observable _overrideTreeViewOpen = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state
-    set treeViewOpen(c: boolean) { if (this.props.preventTreeViewOpen) this._overrideTreeViewOpen = c; else this.props.document.treeViewOpen = c; }
-    @computed get treeViewOpen() { return (this.props.document.treeViewOpen && !this.props.preventTreeViewOpen) || this._overrideTreeViewOpen; }
+    set treeViewOpen(c: boolean) { if (this.props.preventTreeViewOpen) this._overrideTreeViewOpen = c; else this.props.document.treeViewOpen = this._overrideTreeViewOpen = c; }
+    @computed get treeViewOpen() { return (!this.props.preventTreeViewOpen && BoolCast(this.props.document.treeViewOpen)) || this._overrideTreeViewOpen; }
     @computed get treeViewExpandedView() { return StrCast(this.props.document.treeViewExpandedView, this.defaultExpandedView); }
     @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.document.maxEmbedHeight, 300); }
     @computed get dataDoc() { return this.templateDataDoc ? this.templateDataDoc : this.props.document; }
@@ -413,6 +413,7 @@ class TreeView extends React.Component<TreeViewProps> {
     }
 
     render() {
+        setTimeout(() => runInAction(() => untracked(() => this._overrideTreeViewOpen = this.treeViewOpen)), 0);
         return <div className="treeViewItem-container" ref={this.createTreeDropTarget} onContextMenu={this.onWorkspaceContextMenu}>
             <li className="collection-child">
                 <div className="treeViewItem-header" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index e9c3f6b0f..058022ab4 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -13,7 +13,7 @@ import { BoolCast, Cast, DateCast, NumCast, StrCast } from "../../../../new_fiel
 import { CurrentUserUtils } from "../../../../server/authentication/models/current_user_utils";
 import { aggregateBounds, emptyFunction, intersectRect, returnOne, Utils } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
-import { Docs } from "../../../documents/Documents";
+import { Docs, DocUtils } from "../../../documents/Documents";
 import { DocumentType } from "../../../documents/DocumentTypes";
 import { DocumentManager } from "../../../util/DocumentManager";
 import { DragManager } from "../../../util/DragManager";
@@ -559,6 +559,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     focusDocument = (doc: Doc, willZoom: boolean, scale?: number, afterFocus?: () => boolean) => {
         const state = HistoryUtil.getState();
+        Doc.linkFollowHighlight(doc);
+        if (doc.z) {
+            return;
+        }
         // TODO This technically isn't correct if type !== "doc", as 
         // currently nothing is done, but we should probably push a new state
         if (state.type === "doc" && this.Document.panX !== undefined && this.Document.panY !== undefined) {
-- 
cgit v1.2.3-70-g09d2


From 6c96238283acb38db79234f67966709b90f02527 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 16 Dec 2019 13:22:43 -0500
Subject: fixes to focus() from tree view. removed scrollbars from
 collectionview (when floating doc is out of view).

---
 src/client/util/DocumentManager.ts                                | 4 +++-
 src/client/views/PreviewCursor.tsx                                | 5 ++---
 src/client/views/TemplateMenu.tsx                                 | 2 +-
 src/client/views/Templates.tsx                                    | 2 +-
 src/client/views/collections/CollectionTreeView.tsx               | 2 +-
 src/client/views/collections/CollectionView.scss                  | 2 +-
 .../collections/collectionFreeForm/CollectionFreeFormView.tsx     | 8 +++-----
 7 files changed, 12 insertions(+), 13 deletions(-)

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

diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 1cb8b55d3..9824ea983 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -93,7 +93,9 @@ export class DocumentManager {
         const toReturn: DocumentView[] = [];
 
         DocumentManager.Instance.DocumentViews.map(view =>
-            Doc.AreProtosEqual(view.props.Document, toFind) && toReturn.push(view));
+            view.props.Document === toFind && toReturn.push(view));
+        DocumentManager.Instance.DocumentViews.map(view =>
+            view.props.Document !== toFind && Doc.AreProtosEqual(view.props.Document, toFind) && toReturn.push(view));
 
         return toReturn;
     }
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index 208bc2b70..9706d0f99 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -1,4 +1,4 @@
-import { action, observable } from 'mobx';
+import { action, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import "normalize.css";
 import * as React from 'react';
@@ -6,7 +6,6 @@ import "./PreviewCursor.scss";
 import { Docs } from '../documents/Documents';
 import { Doc } from '../../new_fields/Doc';
 import { Transform } from "../util/Transform";
-import { TraceMobx } from '../../new_fields/util';
 
 @observer
 export class PreviewCursor extends React.Component<{}> {
@@ -25,7 +24,7 @@ export class PreviewCursor extends React.Component<{}> {
     paste = (e: ClipboardEvent) => {
         if (PreviewCursor.Visible && e.clipboardData) {
             const newPoint = PreviewCursor._getTransform().transformPoint(PreviewCursor._clickPoint[0], PreviewCursor._clickPoint[1]);
-            PreviewCursor.Visible = false;
+            runInAction(() => PreviewCursor.Visible = false);
 
             if (e.clipboardData.getData("text/plain") !== "") {
                 // tests for youtube and makes video document
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index 4609d5211..10419ddb7 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -142,7 +142,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
         const templateMenu: Array<JSX.Element> = [];
         this.props.templates.forEach((checked, template) =>
             templateMenu.push(<TemplateToggle key={template.Name} template={template} checked={checked} toggle={this.toggleTemplate} />));
-        templateMenu.push(<OtherToggle key={"float"} name={"Float (alt-f)"} checked={this.props.docs[0].Document.z ? true : false} toggle={this.toggleFloat} />);
+        templateMenu.push(<OtherToggle key={"float"} name={"Float"} checked={this.props.docs[0].Document.z ? true : false} toggle={this.toggleFloat} />);
         templateMenu.push(<OtherToggle key={"custom"} name={"Custom"} checked={StrCast(this.props.docs[0].Document.layoutKey, "layout") !== "layout"} toggle={this.toggleCustom} />);
         templateMenu.push(<OtherToggle key={"chrome"} name={"Chrome"} checked={layout.chromeStatus !== "disabled"} toggle={this.toggleChrome} />);
         return (
diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index f686bc23d..ef78b60d4 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -47,7 +47,7 @@ export namespace Templates {
             </div>
         </div>` );
 
-    export const Title = new Template("Title (alt-t)", TemplatePosition.InnerTop,
+    export const Title = new Template("Title", TemplatePosition.InnerTop,
         `<div>
             <div style="height:25px; width:100%; background-color: rgba(0, 0, 0, .4); color: white; z-index: 100">
                 <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{props.Document.title}</span>
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index c3fd85274..9f5db5faf 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -198,7 +198,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 ContextMenu.Instance.addItem({ description: "Open Tab", event: () => this.props.addDocTab(this.props.document, this.templateDataDoc, "inTab", this.props.libraryPath), icon: "folder" });
                 ContextMenu.Instance.addItem({ description: "Open Right", event: () => this.props.addDocTab(this.props.document, this.templateDataDoc, "onRight", this.props.libraryPath), icon: "caret-square-right" });
                 if (DocumentManager.Instance.getDocumentViews(this.dataDoc).length) {
-                    ContextMenu.Instance.addItem({ description: "Focus", event: () => (view => view && view.props.focus(this.props.document, true))(DocumentManager.Instance.getFirstDocumentView(this.dataDoc)), icon: "camera" });
+                    ContextMenu.Instance.addItem({ description: "Focus", event: () => (view => view && view.props.focus(this.props.document, true))(DocumentManager.Instance.getFirstDocumentView(this.props.document)), icon: "camera" });
                 }
                 ContextMenu.Instance.addItem({ description: "Delete Item", event: () => this.props.deleteDoc(this.props.document), icon: "trash-alt" });
             } else {
diff --git a/src/client/views/collections/CollectionView.scss b/src/client/views/collections/CollectionView.scss
index e4187e4d6..0bf5c8767 100644
--- a/src/client/views/collections/CollectionView.scss
+++ b/src/client/views/collections/CollectionView.scss
@@ -9,7 +9,7 @@
     border-radius: inherit;
     width: 100%;
     height: 100%;
-    overflow: auto;
+    overflow: hidden; // bcz: why was this 'auto'?  is it needed?  causes scrollbars for some collection freeform views
 }
 
 #google-tags {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 058022ab4..6653639de 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -559,10 +559,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     focusDocument = (doc: Doc, willZoom: boolean, scale?: number, afterFocus?: () => boolean) => {
         const state = HistoryUtil.getState();
-        Doc.linkFollowHighlight(doc);
-        if (doc.z) {
-            return;
-        }
+
         // TODO This technically isn't correct if type !== "doc", as 
         // currently nothing is done, but we should probably push a new state
         if (state.type === "doc" && this.Document.panX !== undefined && this.Document.panY !== undefined) {
@@ -596,10 +593,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
             const savedState = { px: this.Document.panX, py: this.Document.panY, s: this.Document.scale, pt: this.Document.panTransformType };
 
-            this.setPan(newPanX, newPanY, "Ease");
+            if (!doc.z) this.setPan(newPanX, newPanY, "Ease"); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow
             Doc.BrushDoc(this.props.Document);
             this.props.focus(this.props.Document);
             willZoom && this.setScaleToZoom(layoutdoc, scale);
+            Doc.linkFollowHighlight(doc);
 
             afterFocus && setTimeout(() => {
                 if (afterFocus && afterFocus()) {
-- 
cgit v1.2.3-70-g09d2


From a68b3a82c7fd430119254cd8721bd4804e280ef3 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Tue, 17 Dec 2019 11:25:47 -0500
Subject: made documentbox more usable with borders, fwd/back/lock.  and
 annotation filtering.

---
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  5 +-
 src/client/views/nodes/DocumentBox.scss            |  3 +
 src/client/views/nodes/DocumentBox.tsx             | 69 +++++++++++++++++++---
 src/client/views/nodes/KeyValuePair.tsx            |  1 -
 src/new_fields/Doc.ts                              |  2 +-
 5 files changed, 68 insertions(+), 12 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 6653639de..ddd4fea56 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -911,7 +911,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             <div className={"collectionfreeformview-container"} ref={this.createDropTarget} onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
                 style={{ pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined, height: this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}
                 onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onTouchStart={this.onTouchStart}>
-                {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 && this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale < NumCast(this.Document.LODarea, 100000) ? this.placeholder : this.marqueeView}
+                {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 &&
+                    this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale <
+                    NumCast(this.Document.LODarea, 100000) ?
+                    this.placeholder : this.marqueeView}
                 <CollectionFreeFormOverlayView elements={this.elementFunc} />
             </div>;
     }
diff --git a/src/client/views/nodes/DocumentBox.scss b/src/client/views/nodes/DocumentBox.scss
index 6a2f98166..c70b324de 100644
--- a/src/client/views/nodes/DocumentBox.scss
+++ b/src/client/views/nodes/DocumentBox.scss
@@ -3,4 +3,7 @@
     height: 100%;
     pointer-events: all;
     background: gray;
+    border: gray solid 15px;
+    border-top: #aaaaa3 inset 15px;
+    border-bottom: #aaaaa3 outset 15px;
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx
index b9a97b42d..e23b7a38b 100644
--- a/src/client/views/nodes/DocumentBox.tsx
+++ b/src/client/views/nodes/DocumentBox.tsx
@@ -1,8 +1,11 @@
+import { IReactionDisposer, reaction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc } from "../../../new_fields/Doc";
+import { Doc, Field } from "../../../new_fields/Doc";
 import { documentSchema } from "../../../new_fields/documentSchemas";
+import { List } from "../../../new_fields/List";
 import { makeInterface } from "../../../new_fields/Schema";
 import { ComputedField } from "../../../new_fields/ScriptField";
+import { Cast, StrCast } from "../../../new_fields/Types";
 import { emptyFunction, emptyPath } from "../../../Utils";
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from "../ContextMenuItem";
@@ -18,17 +21,65 @@ const DocBoxDocument = makeInterface(documentSchema);
 @observer
 export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocBoxDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DocumentBox, fieldKey); }
-
-
+    _prevSelectionDisposer: IReactionDisposer | undefined;
+    _selections: Doc[] = [];
+    _curSelection = -1;
+    componentDidMount() {
+        this._prevSelectionDisposer = reaction(() => Cast(this.props.Document[this.props.fieldKey], Doc) as Doc, (data) => {
+            if (data && !this._selections.includes(data)) {
+                this._selections.length = ++this._curSelection;
+                this._selections.push(data);
+            }
+        });
+    }
     specificContextMenu = (e: React.MouseEvent): void => {
         const funcs: ContextMenuProps[] = [];
-        funcs.push({ description: "Auto Show Selected", event: () => Doc.GetProto(this.props.Document).data = ComputedField.MakeFunction("selectedDocs(this,true,[_last_])?.[0]"), icon: "expand-arrows-alt" });
+        funcs.push({ description: "Auto Show Selected", event: () => this.showSelection, icon: "expand-arrows-alt" });
+        funcs.push({ description: "Prev Selection", event: () => this.prevSelection, icon: "expand-arrows-alt" });
+        funcs.push({ description: "Lock Selection", event: () => this.lockSelection, icon: "expand-arrows-alt" });
 
         ContextMenu.Instance.addItem({ description: "DocumentBox Funcs...", subitems: funcs, icon: "asterisk" });
     }
+    lockSelection = () => {
+        Doc.GetProto(this.props.Document)[this.props.fieldKey] = this.props.Document[this.props.fieldKey];
+    }
+    showSelection = () => {
+        Doc.GetProto(this.props.Document)[this.props.fieldKey] = ComputedField.MakeFunction("selectedDocs(this,true,[_last_])?.[0]");
+    }
+    toggleLockSelection = () => {
+        const kvpstring = Field.toKeyValueString(this.props.Document, this.props.fieldKey);
+        (kvpstring.startsWith("=") || kvpstring.startsWith(":=")) ? this.lockSelection() : this.showSelection();
+    }
+    prevSelection = () => {
+        if (this._curSelection > 0) {
+            Doc.UserDoc().SelectedDocs = new List([this._selections[--this._curSelection]]);
+        }
+    }
+    nextSelection = () => {
+        if (this._curSelection < this._selections.length - 1 && this._selections.length) {
+            Doc.UserDoc().SelectedDocs = new List([this._selections[++this._curSelection]]);
+        }
+    }
+    onPointerDown = (e: React.PointerEvent) => {
+        if (e.button === 0 && !e.altKey) {
+            e.stopPropagation();
+        }
+    }
+    onClick = (e: React.MouseEvent) => {
+        if (this._contRef.current!.getBoundingClientRect().top + 15 > e.clientY) this.toggleLockSelection();
+        else {
+            if (this._contRef.current!.getBoundingClientRect().left + 15 > e.clientX) this.prevSelection();
+            if (this._contRef.current!.getBoundingClientRect().right - 15 < e.clientX) this.nextSelection();
+        }
+    }
+    _contRef = React.createRef<HTMLDivElement>();
+    pwidth = () => this.props.PanelWidth() - 30;
+    pheight = () => this.props.PanelHeight() - 30;
+    getTransform = () => this.props.ScreenToLocalTransform().translate(-15, -15);
     render() {
         const containedDoc = this.props.Document[this.props.fieldKey] as Doc;
-        return <div className="documentBox-container" onContextMenu={this.specificContextMenu}>
+        return <div className="documentBox-container" ref={this._contRef} onContextMenu={this.specificContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
+            style={{ background: StrCast(this.props.Document.backgroundColor) }}>
             {!containedDoc ? (null) : <ContentFittingDocumentView
                 Document={containedDoc}
                 DataDocument={undefined}
@@ -40,10 +91,10 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
                 ruleProvider={this.props.ruleProvider}
                 addDocTab={this.props.addDocTab}
                 pinToPres={this.props.pinToPres}
-                getTransform={this.props.ScreenToLocalTransform}
-                renderDepth={this.props.renderDepth - 1}
-                PanelWidth={this.props.PanelWidth}
-                PanelHeight={this.props.PanelHeight}
+                getTransform={this.getTransform}
+                renderDepth={this.props.renderDepth + 1}
+                PanelWidth={this.pwidth}
+                PanelHeight={this.pheight}
                 focus={this.props.focus}
                 active={this.props.active}
                 whenActiveChanged={this.props.whenActiveChanged}
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 3e253b83a..91f8bb3b0 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -5,7 +5,6 @@ import { emptyFunction, returnFalse, returnOne, returnZero } from '../../../Util
 import { Docs } from '../../documents/Documents';
 import { Transform } from '../../util/Transform';
 import { undoBatch } from '../../util/UndoManager';
-import { CollectionDockingView } from '../collections/CollectionDockingView';
 import { ContextMenu } from '../ContextMenu';
 import { EditableView } from "../EditableView";
 import { FieldView, FieldViewProps } from './FieldView';
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index b8f11c8c8..168e42b77 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -757,6 +757,6 @@ Scripting.addGlobal(function sameDocs(doc1: any, doc2: any) { return Doc.AreProt
 Scripting.addGlobal(function undo() { return UndoManager.Undo(); });
 Scripting.addGlobal(function redo() { return UndoManager.Redo(); });
 Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) {
-    const docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => !Doc.AreProtosEqual(d, container) && (!excludeCollections || !Cast(d.data, listSpec(Doc), null)) && d.type !== DocumentType.KVP);
+    const docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.DOCUMENT && d.type !== DocumentType.KVP && (!excludeCollections || !Cast(d.data, listSpec(Doc), null)));
     return docs.length ? new List(docs) : prevValue;
 });
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 96ada41d4c3c411be63bd656da65bba7894a4224 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Tue, 17 Dec 2019 18:21:22 -0500
Subject: fixed up interactions with documentBox contents.

---
 src/client/views/DocComponent.tsx                  |  1 +
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  2 +-
 .../views/nodes/ContentFittingDocumentView.tsx     |  2 +-
 src/client/views/nodes/DocumentBox.scss            | 12 ++++++---
 src/client/views/nodes/DocumentBox.tsx             | 29 +++++++++++++---------
 src/client/views/nodes/DocumentView.tsx            |  4 +--
 src/client/views/nodes/FormattedTextBox.tsx        |  2 +-
 7 files changed, 32 insertions(+), 20 deletions(-)

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

diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 7fbad4638..7c8e130b5 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -47,6 +47,7 @@ interface DocAnnotatableProps {
     Document: Doc;
     DataDoc?: Doc;
     fieldKey: string;
+    active: () => boolean;
     whenActiveChanged: (isActive: boolean) => void;
     isSelected: (outsideReaction?: boolean) => boolean;
     renderDepth: number;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ddd4fea56..22983e730 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -911,7 +911,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             <div className={"collectionfreeformview-container"} ref={this.createDropTarget} onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
                 style={{ pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined, height: this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}
                 onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onTouchStart={this.onTouchStart}>
-                {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 &&
+                {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 && this.props.CollectionView &&
                     this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale <
                     NumCast(this.Document.LODarea, 100000) ?
                     this.placeholder : this.marqueeView}
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index e15790c9d..2f8142a44 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -111,7 +111,7 @@ export class ContentFittingDocumentView extends React.Component<ContentFittingDo
                         pinToPres={this.props.pinToPres}
                         parentActive={this.props.active}
                         ScreenToLocalTransform={this.getTransform}
-                        renderDepth={this.props.renderDepth + 1}
+                        renderDepth={this.props.renderDepth}
                         ContentScaling={this.contentScaling}
                         PanelWidth={this.PanelWidth}
                         PanelHeight={this.PanelHeight}
diff --git a/src/client/views/nodes/DocumentBox.scss b/src/client/views/nodes/DocumentBox.scss
index c70b324de..b7d06b364 100644
--- a/src/client/views/nodes/DocumentBox.scss
+++ b/src/client/views/nodes/DocumentBox.scss
@@ -3,7 +3,13 @@
     height: 100%;
     pointer-events: all;
     background: gray;
-    border: gray solid 15px;
-    border-top: #aaaaa3 inset 15px;
-    border-bottom: #aaaaa3 outset 15px;
+    border: #00000021 solid 15px;
+    border-top: #0000005e inset 15px;
+    border-bottom: #0000005e outset 15px;
+    .documentBox-lock {
+        margin: auto;
+        color: white;
+        margin-top: -15px;
+        position: absolute;
+    }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx
index e23b7a38b..6be0289d7 100644
--- a/src/client/views/nodes/DocumentBox.tsx
+++ b/src/client/views/nodes/DocumentBox.tsx
@@ -5,12 +5,13 @@ import { documentSchema } from "../../../new_fields/documentSchemas";
 import { List } from "../../../new_fields/List";
 import { makeInterface } from "../../../new_fields/Schema";
 import { ComputedField } from "../../../new_fields/ScriptField";
-import { Cast, StrCast } from "../../../new_fields/Types";
+import { Cast, StrCast, BoolCast } from "../../../new_fields/Types";
 import { emptyFunction, emptyPath } from "../../../Utils";
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from "../ContextMenuItem";
 import { DocComponent } from "../DocComponent";
 import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import "./DocumentBox.scss";
 import { FieldView, FieldViewProps } from "./FieldView";
 import React = require("react");
@@ -34,9 +35,8 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
     }
     specificContextMenu = (e: React.MouseEvent): void => {
         const funcs: ContextMenuProps[] = [];
-        funcs.push({ description: "Auto Show Selected", event: () => this.showSelection, icon: "expand-arrows-alt" });
-        funcs.push({ description: "Prev Selection", event: () => this.prevSelection, icon: "expand-arrows-alt" });
-        funcs.push({ description: "Lock Selection", event: () => this.lockSelection, icon: "expand-arrows-alt" });
+        funcs.push({ description: (this.isSelectionLocked() ? "Show" : "Lock") + " Selection", event: () => this.toggleLockSelection, icon: "expand-arrows-alt" });
+        funcs.push({ description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" });
 
         ContextMenu.Instance.addItem({ description: "DocumentBox Funcs...", subitems: funcs, icon: "asterisk" });
     }
@@ -46,9 +46,12 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
     showSelection = () => {
         Doc.GetProto(this.props.Document)[this.props.fieldKey] = ComputedField.MakeFunction("selectedDocs(this,true,[_last_])?.[0]");
     }
-    toggleLockSelection = () => {
+    isSelectionLocked = () => {
         const kvpstring = Field.toKeyValueString(this.props.Document, this.props.fieldKey);
-        (kvpstring.startsWith("=") || kvpstring.startsWith(":=")) ? this.lockSelection() : this.showSelection();
+        return !(kvpstring.startsWith("=") || kvpstring.startsWith(":="));
+    }
+    toggleLockSelection = () => {
+        !this.isSelectionLocked() ? this.lockSelection() : this.showSelection();
     }
     prevSelection = () => {
         if (this._curSelection > 0) {
@@ -61,9 +64,6 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
         }
     }
     onPointerDown = (e: React.PointerEvent) => {
-        if (e.button === 0 && !e.altKey) {
-            e.stopPropagation();
-        }
     }
     onClick = (e: React.MouseEvent) => {
         if (this._contRef.current!.getBoundingClientRect().top + 15 > e.clientY) this.toggleLockSelection();
@@ -78,9 +78,14 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
     getTransform = () => this.props.ScreenToLocalTransform().translate(-15, -15);
     render() {
         const containedDoc = this.props.Document[this.props.fieldKey] as Doc;
-        return <div className="documentBox-container" ref={this._contRef} onContextMenu={this.specificContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
+        return <div className="documentBox-container" ref={this._contRef}
+            onContextMenu={this.specificContextMenu}
+            onPointerDown={this.onPointerDown} onClick={this.onClick}
             style={{ background: StrCast(this.props.Document.backgroundColor) }}>
-            {!containedDoc ? (null) : <ContentFittingDocumentView
+            <div className="documentBox-lock">
+                <FontAwesomeIcon icon={this.isSelectionLocked() ? "lock" : "unlock"} size="sm" />
+            </div>
+            {!(containedDoc instanceof Doc) ? (null) : <ContentFittingDocumentView
                 Document={containedDoc}
                 DataDocument={undefined}
                 LibraryPath={emptyPath}
@@ -92,7 +97,7 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
                 addDocTab={this.props.addDocTab}
                 pinToPres={this.props.pinToPres}
                 getTransform={this.getTransform}
-                renderDepth={this.props.renderDepth + 1}
+                renderDepth={this.props.Document.forceActive ? 0 : this.props.renderDepth + 1} // bcz: really need to have an 'alwaysSelected' prop that's not conflated with renderDepth
                 PanelWidth={this.pwidth}
                 PanelHeight={this.pheight}
                 focus={this.props.focus}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 9688c6ad4..8d3c3126d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -137,7 +137,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
     }
 
-     public static FloatDoc(topDocView:DocumentView, x:number, y:number) {
+    public static FloatDoc(topDocView: DocumentView, x: number, y: number) {
         const topDoc = topDocView.props.Document;
         const de = new DragManager.DocumentDragData([topDoc]);
         de.dragDivName = topDocView.props.dragDivName;
@@ -171,7 +171,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 }
             } else if (e.key === "f") {
                 const ex = (e.nativeEvent.target! as any).getBoundingClientRect().left;
-                const ey = (e.nativeEvent.target!as any).getBoundingClientRect().top;
+                const ey = (e.nativeEvent.target! as any).getBoundingClientRect().top;
                 DocumentView.FloatDoc(this, ex, ey);
             }
         }
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 3efbd434e..b19729811 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -873,7 +873,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         if (this.props.onClick && e.button === 0) {
             e.preventDefault();
         }
-        if (e.button === 0 && this.props.isSelected(true) && !e.altKey && !e.ctrlKey && !e.metaKey) {
+        if (e.button === 0 && this.active(true) && !e.altKey && !e.ctrlKey && !e.metaKey) {
             e.stopPropagation();
         }
         if (e.button === 2 || (e.button === 0 && e.ctrlKey)) {
-- 
cgit v1.2.3-70-g09d2

