From ea4588185f165f66a4d596d51a8a8ad955985762 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 22 Feb 2023 15:58:20 -0500
Subject: fixed pres hide before/after, select w/o nav, and updating contents..
 made collections fitWidth by default so that they resize like a normal
 window. Made freeform pan/zoom animate when changing keyframes.  allow
 nesting of keyframe collections..  made presEffects work even if there's no
 transition movement. made nested collection timelines follow parent by
 default, but with ability to change ordering.  fixed treeView incremental
 render.  treat doc anchors are preselements instead of delegating. don't
 highlight ink when dragging ctrl pts.

---
 src/client/views/collections/CollectionMenu.tsx | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index e2594b6ae..c83f4e689 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -15,6 +15,7 @@ import { RichTextField } from '../../../fields/RichTextField';
 import { listSpec } from '../../../fields/Schema';
 import { ScriptField } from '../../../fields/ScriptField';
 import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types';
+import { GestureUtils } from '../../../pen-gestures/GestureUtils';
 import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../../Utils';
 import { Docs } from '../../documents/Documents';
 import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
@@ -40,7 +41,7 @@ import { CollectionLinearView } from './collectionLinear';
 import './CollectionMenu.scss';
 import { COLLECTION_BORDER_WIDTH } from './CollectionView';
 import { TabDocView } from './TabDocView';
-import { GestureUtils } from '../../../pen-gestures/GestureUtils';
+import { CollectionFreeFormView } from './collectionFreeForm';
 
 interface CollectionMenuProps {
     panelHeight: () => number;
@@ -733,7 +734,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionView
                 doc._currentFrame = 0;
                 CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
             }
-            CollectionFreeFormDocumentView.updateKeyframe(undefined, childDocs, currentFrame || 0);
+            CollectionFreeFormView.updateKeyframe(undefined, [...childDocs, doc], currentFrame || 0);
             doc._currentFrame = newFrame === undefined ? 0 : Math.max(0, newFrame);
         }
     }
@@ -747,7 +748,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionView
             this.document._currentFrame = 0;
             CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0);
         }
-        this._keyTimer = CollectionFreeFormDocumentView.updateKeyframe(this._keyTimer, this.childDocs, currentFrame || 0);
+        this._keyTimer = CollectionFreeFormView.updateKeyframe(this._keyTimer, [...this.childDocs, this.document], currentFrame || 0);
         this.document._currentFrame = Math.max(0, (currentFrame || 0) + 1);
         this.document.lastFrame = Math.max(NumCast(this.document._currentFrame), NumCast(this.document.lastFrame));
     };
@@ -759,7 +760,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionView
             this.document._currentFrame = 0;
             CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0);
         }
-        this._keyTimer = CollectionFreeFormDocumentView.gotoKeyframe(this._keyTimer, this.childDocs.slice());
+        this._keyTimer = CollectionFreeFormView.gotoKeyframe(this._keyTimer, [...this.childDocs, this.document], 1000);
         this.document._currentFrame = Math.max(0, (currentFrame || 0) - 1);
     };
 
-- 
cgit v1.2.3-70-g09d2


From 3e93857b4dfdc09a4dce7ec12ca0dbc60b727fb1 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 22 Feb 2023 16:16:45 -0500
Subject: fixes for restoring layouts in presentations and link following.

---
 src/client/views/collections/CollectionMenu.tsx               |  2 +-
 .../collections/collectionFreeForm/CollectionFreeFormView.tsx |  2 +-
 src/client/views/nodes/ImageBox.tsx                           |  2 +-
 src/client/views/nodes/trails/PresElementBox.tsx              | 11 +++++------
 4 files changed, 8 insertions(+), 9 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index c83f4e689..17f02711d 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -746,7 +746,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionView
         const currentFrame = Cast(this.document._currentFrame, 'number', null);
         if (currentFrame === undefined) {
             this.document._currentFrame = 0;
-            CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0);
+            CollectionFreeFormDocumentView.setupKeyframes(this.c hildDocs, 0);
         }
         this._keyTimer = CollectionFreeFormView.updateKeyframe(this._keyTimer, [...this.childDocs, this.document], currentFrame || 0);
         this.document._currentFrame = Math.max(0, (currentFrame || 0) + 1);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index e5b4b76a8..132538ea4 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1612,7 +1612,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         const focusSpeed = options.instant ? 0 : options.zoomTime ?? 500;
         return PresBox.restoreTargetDocView(
             this.props.DocumentView?.(), //
-            { pinDocLayout: BoolCast(anchor.presPinDocLayout) },
+            { pinDocLayout: BoolCast(anchor.presPinLayout) },
             anchor,
             focusSpeed,
             {
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index c66f2a67b..6e616931d 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -76,7 +76,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
         const focusSpeed = options.instant ? 0 : options.zoomTime ?? 500;
         return PresBox.restoreTargetDocView(
             this.props.DocumentView?.(), //
-            { pinDocLayout: BoolCast(anchor.presPinDocLayout) },
+            { pinDocLayout: BoolCast(anchor.presPinLayout) },
             anchor,
             focusSpeed,
             !anchor.presPinData
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 40535c8cb..d19b78dbc 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -3,20 +3,17 @@ import { Tooltip } from '@material-ui/core';
 import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import { Doc, DocListCast, HeightSym, Opt, WidthSym } from '../../../../fields/Doc';
-import { Copy, Id } from '../../../../fields/FieldSymbols';
-import { InkField } from '../../../../fields/InkField';
+import { Id } from '../../../../fields/FieldSymbols';
 import { List } from '../../../../fields/List';
-import { RichTextField } from '../../../../fields/RichTextField';
 import { Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
 import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from '../../../../Utils';
 import { Docs, DocUtils } from '../../../documents/Documents';
-import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
+import { CollectionViewType } from '../../../documents/DocumentTypes';
 import { DocumentManager } from '../../../util/DocumentManager';
 import { DragManager } from '../../../util/DragManager';
 import { SettingsManager } from '../../../util/SettingsManager';
 import { Transform } from '../../../util/Transform';
 import { undoBatch } from '../../../util/UndoManager';
-import { MarqueeView } from '../../collections/collectionFreeForm';
 import { ViewBoxBaseComponent } from '../../DocComponent';
 import { EditableView } from '../../EditableView';
 import { Colors } from '../../global/globalEnums';
@@ -296,12 +293,14 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
      */
     @undoBatch
     @action
-    updateCapturedContainerLayout = (targetDoc: Doc, activeItem: Doc) => {
+    updateCapturedContainerLayout = (presTargetDoc: Doc, activeItem: Doc) => {
+        const targetDoc = DocCast(presTargetDoc.annotationOn) ?? presTargetDoc;
         activeItem.presX = NumCast(targetDoc.x);
         activeItem.presY = NumCast(targetDoc.y);
         activeItem.presRot = NumCast(targetDoc.rotation);
         activeItem.presWidth = NumCast(targetDoc.width);
         activeItem.presHeight = NumCast(targetDoc.height);
+        activeItem.presPinLayout = true;
     };
     /**
      * Method called for updating the view of the currently selected document
-- 
cgit v1.2.3-70-g09d2


From c7878fc9b8df619d77c1323725022997d93c9789 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 22 Feb 2023 19:31:43 -0500
Subject: capture viewType as part of pinning a document/making an anchor to
 simplify VIewSpec restoration

---
 src/client/views/collections/CollectionMenu.tsx           |  2 +-
 src/client/views/collections/CollectionTimeView.tsx       |  2 --
 .../collectionFreeForm/CollectionFreeFormView.tsx         | 13 ++++++++-----
 src/client/views/nodes/DocumentView.tsx                   | 13 ++++++-------
 src/client/views/nodes/trails/PresBox.tsx                 | 15 +++++++++++++--
 5 files changed, 28 insertions(+), 17 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 17f02711d..c83f4e689 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -746,7 +746,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionView
         const currentFrame = Cast(this.document._currentFrame, 'number', null);
         if (currentFrame === undefined) {
             this.document._currentFrame = 0;
-            CollectionFreeFormDocumentView.setupKeyframes(this.c hildDocs, 0);
+            CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0);
         }
         this._keyTimer = CollectionFreeFormView.updateKeyframe(this._keyTimer, [...this.childDocs, this.document], currentFrame || 0);
         this.document._currentFrame = Math.max(0, (currentFrame || 0) + 1);
diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx
index 0ec21cc51..8ec683e6d 100644
--- a/src/client/views/collections/CollectionTimeView.tsx
+++ b/src/client/views/collections/CollectionTimeView.tsx
@@ -16,7 +16,6 @@ import { ScriptingGlobals } from '../../util/ScriptingGlobals';
 import { ContextMenu } from '../ContextMenu';
 import { ContextMenuProps } from '../ContextMenuItem';
 import { EditableView } from '../EditableView';
-import { ViewSpecPrefix } from '../nodes/DocumentView';
 import { computePivotLayout, computeTimelineLayout, ViewDefBounds } from './collectionFreeForm/CollectionFreeFormLayoutEngines';
 import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
 import { CollectionSubView } from './CollectionSubView';
@@ -43,7 +42,6 @@ export class CollectionTimeView extends CollectionSubView() {
         proto.pivotField = this.pivotField;
         proto.docFilters = ObjectField.MakeCopy(this.layoutDoc._docFilters as ObjectField) || new List<string>([]);
         proto.docRangeFilters = ObjectField.MakeCopy(this.layoutDoc._docRangeFilters as ObjectField) || new List<string>([]);
-        proto[ViewSpecPrefix + '_viewType'] = this.layoutDoc._viewType;
 
         if (addAsAnnotation) {
             // when added as an annotation, links to anchors can be found as links to the document even if the anchors are not rendered
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 132538ea4..d69e6b810 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -38,7 +38,7 @@ import { GestureOverlay } from '../../GestureOverlay';
 import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, InkingStroke, SetActiveInkColor, SetActiveInkWidth } from '../../InkingStroke';
 import { LightboxView } from '../../LightboxView';
 import { CollectionFreeFormDocumentView } from '../../nodes/CollectionFreeFormDocumentView';
-import { DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere, ViewAdjustment, ViewSpecPrefix } from '../../nodes/DocumentView';
+import { DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere, ViewAdjustment } from '../../nodes/DocumentView';
 import { FieldViewProps } from '../../nodes/FieldView';
 import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
 import { PresBox } from '../../nodes/trails/PresBox';
@@ -1617,6 +1617,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             focusSpeed,
             {
                 pannable: anchor.presPinData ? true : false,
+                viewType: anchor.presPinViewType ? true : false,
             }
         )
             ? focusSpeed
@@ -1627,11 +1628,13 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         if (this.props.Document.annotationOn) {
             return this.rootDoc;
         }
+
+        // create an anchor that saves information about the current state of the freeform view (pan, zoom, view type)
         const anchor = Docs.Create.TextanchorDocument({ title: 'ViewSpec - ' + StrCast(this.layoutDoc._viewType), presTransition: 500, annotationOn: this.rootDoc });
-        PresBox.pinDocView(anchor, { pinData: { pannable: true } }, this.rootDoc);
-        const proto = Doc.GetProto(anchor);
-        proto[ViewSpecPrefix + '_viewType'] = this.layoutDoc._viewType;
-        proto.docFilters = ObjectField.MakeCopy(this.layoutDoc.docFilters as ObjectField) || new List<string>([]);
+        PresBox.pinDocView(anchor, { pinData: { pannable: true, viewType: true } }, this.rootDoc);
+        // bcz TODO: saving document filters should be part of pinDocView...
+        Doc.GetProto(anchor).docFilters = ObjectField.MakeCopy(this.layoutDoc.docFilters as ObjectField) || new List<string>([]);
+
         if (addAsAnnotation) {
             if (Cast(this.dataDoc[this.props.fieldKey + '-annotations'], listSpec(Doc), null) !== undefined) {
                 Cast(this.dataDoc[this.props.fieldKey + '-annotations'], listSpec(Doc), []).push(anchor);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index c3b0412de..5bdb994c5 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -98,8 +98,6 @@ export enum OpenWhereMod {
     bottom = 'bottom',
 }
 
-export const ViewSpecPrefix = 'viewSpec'; // field prefix for anchor fields that are immediately copied over to the target document when link is followed.  Other anchor properties will be copied over in the specific setViewSpec() method on their view (which allows for seting preview values instead of writing to the document)
-
 export interface DocFocusOptions {
     originalTarget?: Doc; // set in JumpToDocument, used by TabDocView to determine whether to fit contents to tab
     willPan?: boolean; // determines whether to pan to target document
@@ -585,13 +583,14 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
 
     focus = (anchor: Doc, options: DocFocusOptions) => {
         LightboxView.SetCookie(StrCast(anchor['cookies-set']));
-        // copying over VIEW fields immediately allows the view type to switch to create the right _componentView
-        Array.from(Object.keys(Doc.GetProto(anchor)))
-            .filter(key => key.startsWith(ViewSpecPrefix))
-            .forEach(spec => (this.layoutDoc[spec.replace(ViewSpecPrefix, '')] = (field => (field instanceof ObjectField ? ObjectField.MakeCopy(field) : field))(anchor[spec])));
-        // after a render the general viewSpec should have created the right _componentView, so after a timeout, call the componentview to update its specific view specs
+
+        // Restore viewing specification of target by reading them out of the anchor and applying to the target doc.
+        // after a render the correct _componentView should be created, so after a timeout, call the componentview to update its specific view specs
+        // bcz: TODO: all viewing specs should be restored via the anchor doc in PresBox.restoreTargetDocView called from scrollFocus() below.
         setTimeout(() => this._componentView?.setViewSpec?.(anchor, LinkDocPreview.LinkInfo ? true : false));
         const focusSpeed = this._componentView?.scrollFocus?.(anchor, { ...options, instant: options?.instant || LinkDocPreview.LinkInfo ? true : false });
+
+        // FOCUS: navigate through the display hierarchy making sure the target is in view
         const endFocus = focusSpeed === undefined ? options?.afterFocus : async (moved: boolean) => options?.afterFocus?.(true) ?? ViewAdjustment.doNothing;
         const startTime = Date.now();
         this.props.focus(options?.docTransform ? anchor : this.rootDoc, {
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 929bf1230..32fcc0fae 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -48,6 +48,7 @@ export interface PinProps {
     pinData?: {
         scrollable?: boolean | undefined;
         pannable?: boolean | undefined;
+        viewType?: boolean | undefined;
         temporal?: boolean | undefined;
         clippable?: boolean | undefined;
         dataview?: boolean | undefined;
@@ -316,7 +317,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             this.onHideDocument(); //Handles hide after/before
         }
     });
-    static pinDataTypes(target?: Doc): { scrollable?: boolean; pannable?: boolean; temporal?: boolean; clippable?: boolean; dataview?: boolean; textview?: boolean; poslayoutview?: boolean; dataannos?: boolean } {
+    static pinDataTypes(target?: Doc): { scrollable?: boolean; pannable?: boolean; viewType?: boolean; temporal?: boolean; clippable?: boolean; dataview?: boolean; textview?: boolean; poslayoutview?: boolean; dataannos?: boolean } {
         const targetType = target?.type as any;
         const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetType) || target?._viewType === CollectionViewType.Stacking;
         const pannable = [DocumentType.IMG, DocumentType.PDF].includes(targetType) || (targetType === DocumentType.COL && target?._viewType === CollectionViewType.Freeform);
@@ -325,8 +326,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         const dataview = [DocumentType.INK, DocumentType.COL, DocumentType.IMG].includes(targetType) && target?.activeFrame === undefined;
         const poslayoutview = [DocumentType.COL].includes(targetType) && target?.activeFrame === undefined;
         const textview = [DocumentType.RTF].includes(targetType) && target?.activeFrame === undefined;
+        const viewType = targetType === DocumentType.COL;
         const dataannos = false;
-        return { scrollable, pannable, temporal, clippable, dataview, textview, poslayoutview, dataannos };
+        return { scrollable, pannable, viewType, temporal, clippable, dataview, textview, poslayoutview, dataannos };
     }
 
     @action
@@ -366,6 +368,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 changed = true;
             }
         }
+        if (pinDataTypes.viewType && activeItem.presPinViewType !== undefined) {
+            if (bestTarget._viewType !== activeItem.presPinViewType) {
+                bestTarget._viewType = activeItem.presPinViewType;
+                changed = true;
+            }
+        }
+
         if (pinDataTypes.scrollable) {
             if (bestTarget._scrollTop !== activeItem.presPinViewScroll) {
                 bestTarget._scrollTop = activeItem.presPinViewScroll;
@@ -454,6 +463,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 pinProps.pinData.scrollable ||
                 pinProps.pinData.temporal ||
                 pinProps.pinData.pannable ||
+                pinProps.pinData.viewType ||
                 pinProps.pinData.clippable ||
                 pinProps.pinData.dataview ||
                 pinProps.pinData.textview ||
@@ -472,6 +482,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             if (pinProps.pinData.scrollable) pinDoc.presPinViewScroll = targetDoc._scrollTop;
             if (pinProps.pinData.clippable) pinDoc.presPinClipWidth = targetDoc._clipWidth;
             if (pinProps.pinData.poslayoutview) pinDoc.presPinLayoutData = new List<string>(DocListCast(targetDoc.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 (pinProps.pinData.viewType) pinDoc.presPinViewType = targetDoc._viewType;
             if (pinProps.pinData.pannable) {
                 pinDoc.presPinViewX = NumCast(targetDoc._panX);
                 pinDoc.presPinViewY = NumCast(targetDoc._panY);
-- 
cgit v1.2.3-70-g09d2

