From 2de2e154912d95a15e5f890c9d1a3a7a11610107 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 29 Sep 2022 20:44:33 -0400
Subject: a bunch of changes to trails: link to trail to initiate trail when
 following link.  cleanly separate pin layout data vs. content data.

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

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

diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx
index 1c9b0bc0e..37afcdd8b 100644
--- a/src/client/views/nodes/ScriptingBox.tsx
+++ b/src/client/views/nodes/ScriptingBox.tsx
@@ -115,6 +115,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
 
     @action
     componentDidMount() {
+        this.props.setContentView?.(this);
         this.rawText = this.rawScript;
         const observer = new _global.ResizeObserver(
             action((entries: any) => {
@@ -480,6 +481,10 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
         return value;
     }
 
+    scrollFocus = () => {
+        return undefined;
+    };
+
     getSuggestedParams(pos: number) {
         const firstScript = this.rawText.slice(0, pos);
         const indexP = firstScript.lastIndexOf('.');
-- 
cgit v1.2.3-70-g09d2


From 995ed33feef1eb663d65b1b1d3da8c91926013dc Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 29 Sep 2022 21:26:36 -0400
Subject: added content pinning for collections.

---
 src/client/views/nodes/DocumentView.tsx          |  3 +-
 src/client/views/nodes/ScriptingBox.tsx          |  1 -
 src/client/views/nodes/trails/PresBox.tsx        | 47 +++++++++++++++++++-----
 src/client/views/nodes/trails/PresElementBox.tsx |  5 ++-
 4 files changed, 42 insertions(+), 14 deletions(-)

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

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 913d5a7ef..a148ad142 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -566,7 +566,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                 }
                 if (this.onDoubleClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes(ScriptingBox.name)) {
                     // bcz: hack? don't execute script if you're clicking on a scripting box itself
-                    const { clientX, clientY, shiftKey } = e;
+                    const { clientX, clientY, shiftKey, altKey, ctrlKey } = e;
                     const func = () =>
                         this.onDoubleClickHandler.script.run(
                             {
@@ -579,6 +579,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                                 clientY,
                                 altKey,
                                 shiftKey,
+                                ctrlKey,
                             },
                             console.log
                         );
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx
index 37afcdd8b..f8ed70017 100644
--- a/src/client/views/nodes/ScriptingBox.tsx
+++ b/src/client/views/nodes/ScriptingBox.tsx
@@ -810,7 +810,6 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
 
     // renders script UI if _applied = false and params UI if _applied = true
     render() {
-        console.log(ReactTextareaAutocomplete);
         TraceMobx();
         return (
             <div className={`scriptingBox`} onContextMenu={this.specificContextMenu} onPointerUp={!this._function ? this.suggestionPos : undefined}>
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 18441aace..7cb976105 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -5,8 +5,8 @@ import { action, computed, IReactionDisposer, observable, ObservableSet, reactio
 import { observer } from 'mobx-react';
 import { ColorState, SketchPicker } from 'react-color';
 import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal';
-import { Doc, DocListCast, DocListCastAsync, FieldResult, Opt } from '../../../../fields/Doc';
-import { Copy } from '../../../../fields/FieldSymbols';
+import { Doc, DocListCast, DocListCastAsync, FieldResult, Opt, StrListCast } from '../../../../fields/Doc';
+import { Copy, Id } from '../../../../fields/FieldSymbols';
 import { InkTool } from '../../../../fields/InkField';
 import { List } from '../../../../fields/List';
 import { ObjectField } from '../../../../fields/ObjectField';
@@ -33,6 +33,7 @@ import './PresBox.scss';
 import { PresEffect, PresMovement, PresStatus } from './PresEnums';
 import { privateEncrypt } from 'crypto';
 import { ScriptingBox } from '../ScriptingBox';
+import { DocServer } from '../../../DocServer';
 
 export interface PinProps {
     audioRange?: boolean;
@@ -351,15 +352,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         const temporal = [DocumentType.AUDIO, DocumentType.VID].includes(target.type as any);
         const clippable = [DocumentType.COMPARISON].includes(target.type as any);
         const dataview = [DocumentType.INK, DocumentType.COL].includes(target.type as any) && target.activeFrame === undefined;
+        const poslayoutview = [DocumentType.COL].includes(target.type as any) && target.activeFrame === undefined;
         const textview = [DocumentType.RTF].includes(target.type as any) && target.activeFrame === undefined;
-        return { scrollable, pannable, temporal, clippable, dataview, textview };
+        return { scrollable, pannable, temporal, clippable, dataview, textview, poslayoutview };
     }
 
     @action
     static restoreTargetDocView(bestTarget: Doc, activeItem: Doc) {
         const transTime = NumCast(activeItem.presTransition, 500);
         const presTransitionTime = `all ${transTime}ms`;
-        const { scrollable, pannable, temporal, clippable, dataview, textview } = this.pinDataTypes(bestTarget);
+        const { scrollable, pannable, temporal, clippable, dataview, textview, poslayoutview } = this.pinDataTypes(bestTarget);
         bestTarget._viewTransition = presTransitionTime;
         if (clippable) bestTarget._clipWidth = activeItem.presPinClipWidth;
         if (temporal) bestTarget._currentTimecode = activeItem.presStartTime;
@@ -371,8 +373,32 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 dv?.brushView?.({ panX: (contentBounds[0] + contentBounds[2]) / 2, panY: (contentBounds[1] + contentBounds[3]) / 2, width: contentBounds[2] - contentBounds[0], height: contentBounds[3] - contentBounds[1] });
             }
         }
-        if (dataview) Doc.GetProto(bestTarget).data = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData;
-        if (textview) Doc.GetProto(bestTarget).text = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData;
+        if (dataview) Doc.GetProto(bestTarget)[Doc.LayoutFieldKey(bestTarget)] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData;
+        if (textview) Doc.GetProto(bestTarget)[Doc.LayoutFieldKey(bestTarget)] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData;
+        if (poslayoutview) {
+            StrListCast(activeItem.presPinLayoutData)
+                .map(str => JSON.parse(str) as { id: string; x: number; y: number; w: number; h: number })
+                .forEach(data => {
+                    const doc = DocServer.GetCachedRefField(data.id) as Doc;
+                    doc._dataTransition = presTransitionTime;
+                    doc.x = data.x;
+                    doc.y = data.y;
+                    doc._width = data.w;
+                    doc._height = data.h;
+                });
+            setTimeout(
+                () =>
+                    StrListCast(activeItem.presPinLayoutData)
+                        .map(str => JSON.parse(str) as { id: string; x: number; y: number; w: number; h: number })
+                        .forEach(
+                            action(data => {
+                                const doc = DocServer.GetCachedRefField(data.id) as Doc;
+                                doc._dataTransition = undefined;
+                            })
+                        ),
+                transTime + 10
+            );
+        }
         if (pannable) {
             const contentBounds = Cast(activeItem.presPinViewBounds, listSpec('number'));
             if (contentBounds) {
@@ -399,7 +425,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     /// target doc when navigating to it.
     @action
     static pinDocView(pinDoc: Doc, pinProps: PinProps | undefined, targetDoc: Doc) {
-        const { scrollable, pannable, temporal, clippable, dataview, textview } = this.pinDataTypes(pinDoc);
+        const { scrollable, pannable, temporal, clippable, dataview, textview, poslayoutview } = this.pinDataTypes(pinDoc);
         if (pinProps?.pinDocLayout) {
             pinDoc.presPinLayout = true;
             pinDoc.presX = NumCast(targetDoc.x);
@@ -409,11 +435,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             pinDoc.presHeight = NumCast(targetDoc.height);
         }
         if (pinProps?.pinDocContent) {
-            pinDoc.presPinData = scrollable || temporal || pannable || clippable || dataview || textview || pinProps.activeFrame !== undefined;
-            if (textview) pinDoc.presData = targetDoc.text instanceof ObjectField ? targetDoc.text[Copy]() : targetDoc.text;
+            pinDoc.presPinData = scrollable || temporal || pannable || clippable || dataview || textview || poslayoutview || pinProps.activeFrame !== undefined;
+            if (dataview) pinDoc.presData = targetDoc[Doc.LayoutFieldKey(targetDoc)] instanceof ObjectField ? (targetDoc[Doc.LayoutFieldKey(targetDoc)] as ObjectField)[Copy]() : targetDoc.data;
+            if (textview) pinDoc.presData = targetDoc[Doc.LayoutFieldKey(targetDoc)] instanceof ObjectField ? (targetDoc[Doc.LayoutFieldKey(targetDoc)] as ObjectField)[Copy]() : targetDoc.text;
             if (scrollable) pinDoc.presPinViewScroll = pinDoc._scrollTop;
             if (clippable) pinDoc.presPinClipWidth = pinDoc._clipWidth;
-            if (dataview) pinDoc.presData = targetDoc.data instanceof ObjectField ? targetDoc.data[Copy]() : targetDoc.data;
+            if (poslayoutview) pinDoc.presPinLayoutData = new List<string>(DocListCast(pinDoc.presData).map(d => JSON.stringify({ id: d[Id], x: NumCast(d.x), y: NumCast(d.y), w: NumCast(d._width), h: NumCast(d._height) })));
             if (pannable) {
                 pinDoc.presPinViewX = NumCast(pinDoc._panX);
                 pinDoc.presPinViewY = NumCast(pinDoc._panY);
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index fe2668492..f4ab845f3 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -327,11 +327,11 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 const scroll = targetDoc._scrollTop;
                 activeItem.presPinViewScroll = scroll;
                 if (targetDoc.type === DocumentType.RTF) {
-                    activeItem.presData = targetDoc.text instanceof RichTextField ? targetDoc.text[Copy]() : targetDoc.text;
+                    activeItem.presData = targetDoc[Doc.LayoutFieldKey(targetDoc)] instanceof RichTextField ? (targetDoc[Doc.LayoutFieldKey(targetDoc)] as RichTextField)[Copy]() : targetDoc.text;
                 }
                 break;
             case DocumentType.INK:
-                activeItem.presData = targetDoc.data instanceof InkField ? targetDoc.data[Copy]() : targetDoc.data;
+                activeItem.presData = targetDoc[Doc.LayoutFieldKey(targetDoc)] instanceof InkField ? (targetDoc[Doc.LayoutFieldKey(targetDoc)] as InkField)[Copy]() : targetDoc.data;
                 break;
             case DocumentType.VID:
             case DocumentType.AUDIO:
@@ -342,6 +342,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 activeItem.presPinClipWidth = clipWidth;
                 break;
             case DocumentType.COL:
+                activeItem.presPinLayoutData = new List<string>(DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]).map(d => JSON.stringify({ id: d[Id], x: NumCast(d.x), y: NumCast(d.y), w: NumCast(d._width), h: NumCast(d._height) })));
             default:
                 const bestView = DocumentManager.Instance.getFirstDocumentView(targetDoc);
                 if (activeItem.presPinViewBounds && bestView) {
-- 
cgit v1.2.3-70-g09d2

