From 93ab35c251b399f3e44ab2fa016e2af13df5a53b Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 3 May 2024 15:28:53 -0400
Subject: fixed not having docs being dragged show up in schema view unless it
 is active.

---
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 148 ++++++++++-----------
 1 file changed, 68 insertions(+), 80 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 64398a60a..a36c36261 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -88,13 +88,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         return parent instanceof CollectionFreeFormView ? parent : undefined;
     }
 
-    _oldWheel: any;
-    _clusters = new CollectionFreeFormClusters(this);
-    constructor(props: any) {
-        super(props);
-        makeObservable(this);
-    }
-
+    private _clusters = new CollectionFreeFormClusters(this);
+    private _oldWheel: any;
     private _panZoomTransitionTimer: any;
     private _lastX: number = 0;
     private _lastY: number = 0;
@@ -129,16 +124,20 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     @observable _paintedId = 'id' + Utils.GenerateGuid().replace(/-/g, '');
     @observable _keyframeEditing = false;
 
+    constructor(props: any) {
+        super(props);
+        makeObservable(this);
+    }
+
     @computed get layoutEngine() {
         return this._props.layoutEngine?.() || StrCast(this.layoutDoc._layoutEngine);
     }
     @computed get childPointerEvents() {
-        const engine = this._props.layoutEngine?.() || StrCast(this.Document._layoutEngine);
         return SnappingManager.IsResizing
             ? 'none'
             : this._props.childPointerEvents?.() ??
                   (this._props.viewDefDivClick || //
-                  (engine === computePassLayout.name && !this._props.isSelected()) ||
+                  (this.layoutEngine === computePassLayout.name && !this._props.isSelected()) ||
                   this.isContentActive() === false
                       ? 'none'
                       : this._props.pointerEvents?.());
@@ -149,27 +148,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         if (viewsMask.length) renderableEles.push(<div className={`collectionfreeformview-mask${this._layoutElements.some(ele => (ele.inkMask ?? 0) > 0) ? '' : '-empty'}`}>{viewsMask}</div>);
         return renderableEles;
     }
-    @computed get fitToContentVals() {
-        const hgt = this.contentBounds.b - this.contentBounds.y;
-        const wid = this.contentBounds.r - this.contentBounds.x;
-        return {
-            bounds: { ...this.contentBounds, cx: this.contentBounds.x + wid / 2, cy: this.contentBounds.y + hgt / 2 },
-            scale:
-                (!this.childDocs.length || !Number.isFinite(hgt) || !Number.isFinite(wid)
-                    ? 1 //
-                    : Math.min(this._props.PanelHeight() / hgt, this._props.PanelWidth() / wid)) / (this._props.NativeDimScaling?.() || 1),
-        };
-    }
     @computed get fitContentsToBox() {
         return (this._props.fitContentsToBox?.() || this.Document._freeform_fitContentsToBox) && !this.isAnnotationOverlay;
     }
-    @computed get contentBounds() {
-        return aggregateBounds(
-            this._layoutElements.filter(e => e.bounds?.width && !e.bounds.z).map(e => e.bounds!),
-            NumCast(this.layoutDoc._xPadding, this._props.xPadding ?? 10),
-            NumCast(this.layoutDoc._yPadding, this._props.yPadding ?? 10)
-        );
-    }
     @computed get nativeWidth() {
         return this._props.NativeWidth?.() || Doc.NativeWidth(this.Document, Cast(this.Document.resolvedDataDoc, Doc, null));
     }
@@ -177,14 +158,13 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         return this._props.NativeHeight?.() || Doc.NativeHeight(this.Document, Cast(this.Document.resolvedDataDoc, Doc, null));
     }
     @computed get centeringShiftX(): number {
-        const scaling = this.nativeDimScaling;
-        return this._props.isAnnotationOverlay || this._props.originTopLeft ? 0 : this._props.PanelWidth() / 2 / scaling; // shift so pan position is at center of window for non-overlay collections
+        return this._props.isAnnotationOverlay || this._props.originTopLeft ? 0 : this._props.PanelWidth() / 2 / this.nativeDimScaling; // shift so pan position is at center of window for non-overlay collections
     }
     @computed get centeringShiftY(): number {
         const panLocAtCenter = !(this._props.isAnnotationOverlay || this._props.originTopLeft);
         if (!panLocAtCenter) return 0;
         const dv = this.DocumentView?.();
-        const aspect = !(this._props.layout_fitWidth?.(this.Document) ?? dv?.layoutDoc.layout_fitWidth) && dv?.nativeWidth && dv?.nativeHeight;
+        const aspect = !this.fitWidth && dv?.nativeWidth && dv?.nativeHeight;
         const scaling = this.nativeDimScaling;
         // if freeform has a native aspect, then the panel height needs to be adjusted to match it
         const height = aspect ? (dv.nativeHeight / dv.nativeWidth) * this._props.PanelWidth() : this._props.PanelHeight();
@@ -202,14 +182,16 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     @computed get backgroundColor() {
         return this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor);
     }
+    @computed get fitWidth() {
+        return this._props.layout_fitWidth?.(this.Document) ?? this.layoutDoc.layout_fitWidth;
+    }
     @computed get nativeDimScaling() {
         if (this._firstRender || (this._props.isAnnotationOverlay && !this._props.annotationLayerHostsContent)) return 1;
-        const nw = this.nativeWidth;
-        const nh = this.nativeHeight;
-        const hscale = nh ? this._props.PanelHeight() / nh : 1;
-        const wscale = nw ? this._props.PanelWidth() / nw : 1;
-        return wscale < hscale || (this._props.layout_fitWidth?.(this.Document) ?? this.layoutDoc.layout_fitWidth) ? wscale : hscale;
+        const hscale = this._props.PanelHeight() / (this.nativeHeight || this._props.PanelHeight());
+        const wscale = this._props.PanelWidth() / (this.nativeWidth || this._props.PanelWidth());
+        return wscale < hscale || this.fitWidth ? wscale : hscale;
     }
+    @computed get fitContentBounds() { return !this._firstRender && this.fitContentsToBox ? this.contentBounds() : undefined; } // prettier-ignore
     @computed get paintFunc() {
         const field = this.dataDoc[this.fieldKey];
         const paintFunc = StrCast(Field.toJavascriptString(Cast(field, RichTextField, null)?.Text as FieldType)).trim();
@@ -244,23 +226,40 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     };
     getKeyFrameEditing = () => this._keyframeEditing;
 
+    override contentBounds = () => {
+        const { x, y, r, b } = aggregateBounds(
+            this._layoutElements.filter(e => e.bounds?.width && !e.bounds.z).map(e => e.bounds!),
+            NumCast(this.layoutDoc._xPadding, this._props.xPadding ?? 0),
+            NumCast(this.layoutDoc._yPadding, this._props.yPadding ?? 0)
+        );
+        const [width, height] = [r - x, b - y];
+        return {
+            width,
+            height,
+            cx: x + width / 2,
+            cy: y + height / 2,
+            bounds: { x, y, r, b },
+            scale: (!this.childDocs.length || !Number.isFinite(height) || !Number.isFinite(width)
+                ? 1 //
+                : Math.min(this._props.PanelHeight() / height,this._props.PanelWidth() / width )) / (this._props.NativeDimScaling?.() || 1),
+        }; // prettier-ignore
+    };
     onChildClickHandler = () => this._props.childClickScript || ScriptCast(this.Document.onChildClick);
     onChildDoubleClickHandler = () => this._props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick);
     elementFunc = () => this._layoutElements;
     viewTransition = () => (this._panZoomTransition ? '' + this._panZoomTransition : undefined);
     panZoomTransition = () => (this._panZoomTransition ? `transform ${this._panZoomTransition}ms` : Cast(this.layoutDoc._viewTransition, 'string', Cast(this.Document._viewTransition, 'string', null)));
     fitContentOnce = () => {
-        const vals = this.fitToContentVals;
-        this.layoutDoc._freeform_panX = vals.bounds.cx;
-        this.layoutDoc._freeform_panY = vals.bounds.cy;
-        this.layoutDoc._freeform_scale = vals.scale;
+        const { cx, cy, scale } = this.contentBounds(); // prettier-ignore
+        this.layoutDoc._freeform_panX = cx;
+        this.layoutDoc._freeform_panY = cy;
+        this.layoutDoc._freeform_scale = scale;
     };
-    freeformData = (force?: boolean) => (!this._firstRender && (this.fitContentsToBox || force) ? this.fitToContentVals : undefined);
     // freeform_panx, freeform_pany, freeform_scale all attempt to get values first from the layout controller, then from the layout/dataDoc (or template layout doc), and finally from the resolved template data document.
     // this search order, for example, allows icons of cropped images to find the panx/pany/zoom on the cropped image's data doc instead of the usual layout doc because the zoom/panX/panY define the cropped image
-    panX = () => this.freeformData()?.bounds.cx ?? NumCast(this.Document[this.panXFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panX, 1));
-    panY = () => this.freeformData()?.bounds.cy ?? NumCast(this.Document[this.panYFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panY, 1));
-    zoomScaling = () => this.freeformData()?.scale ?? NumCast(Doc.Layout(this.Document)[this.scaleFieldKey], 1); // , NumCast(DocCast(this.Document.resolvedDataDoc)?.[this.scaleFieldKey], 1));
+    panX = () => this.fitContentBounds?.cx ?? NumCast(this.Document[this.panXFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panX, 1));
+    panY = () => this.fitContentBounds?.cy ?? NumCast(this.Document[this.panYFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panY, 1));
+    zoomScaling = () => this.fitContentBounds?.scale ?? NumCast(Doc.Layout(this.Document)[this.scaleFieldKey], 1); // , NumCast(DocCast(this.Document.resolvedDataDoc)?.[this.scaleFieldKey], 1));
     PanZoomCenterXf = () => (this._props.isAnnotationOverlay && this.zoomScaling() === 1 ? `` : `translate(${this.centeringShiftX}px, ${this.centeringShiftY}px) scale(${this.zoomScaling()}) translate(${-this.panX()}px, ${-this.panY()}px)`);
     ScreenToContentsXf = () => this.screenToFreeformContentsXf.copy();
     getActiveDocuments = () => this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => pair.layout);
@@ -274,19 +273,16 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         docs.map(doc => DocumentView.getDocumentView(doc, this.DocumentView?.())).forEach(dv => dv && DocumentView.SelectView(dv, true));
     };
     addDocument = (newBox: Doc | Doc[]) => {
-        let retVal = false;
-        if (newBox instanceof Doc) {
-            retVal = this._props.addDocument?.(newBox) || false;
-            if (retVal) {
-                this.bringToFront(newBox);
-                this._clusters.addDocument(newBox);
+        const newBoxes = toList(newBox);
+        const retVal = newBoxes.every(doc => {
+            const added = this._props.addDocument?.(doc);
+            if (added) {
+                this.bringToFront(doc);
+                this._clusters.addDocument(doc);
             }
-        } else {
-            retVal = this._props.addDocument?.(newBox) || false;
-            // bcz: deal with clusters
-        }
+            return added;
+        });
         if (retVal) {
-            const newBoxes = toList(newBox);
             newBoxes.forEach(box => {
                 if (box.activeFrame !== undefined) {
                     const vals = CollectionFreeFormDocumentView.animFields.map(field => box[field.key]);
@@ -856,33 +852,25 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         if (!this.isAnnotationOverlay && clamp) {
             // this section wraps the pan position, horizontally and/or vertically whenever the content is panned out of the viewing bounds
             const docs = this.childLayoutPairs.map(pair => pair.layout).filter(doc => doc instanceof Doc && doc.type !== DocumentType.LINK);
-            const measuredDocs = docs
-                .map(doc => ({ pos: { x: NumCast(doc.x), y: NumCast(doc.y) }, size: { width: NumCast(doc._width), height: NumCast(doc._height) } }))
-                .filter(({ pos, size }) => pos && size)
-                .map(({ pos, size }) => ({ pos: pos!, size: size! }));
+            const measuredDocs = docs.map(doc => ({ x: NumCast(doc.x), y: NumCast(doc.y), width: NumCast(doc._width), height: NumCast(doc._height) }));
             if (measuredDocs.length) {
-                const ranges = measuredDocs.reduce(
-                    (
-                        { xrange, yrange },
-                        { pos, size } // computes range of content
-                    ) => ({
-                        xrange: { min: Math.min(xrange.min, pos.x), max: Math.max(xrange.max, pos.x + (size.width || 0)) },
-                        yrange: { min: Math.min(yrange.min, pos.y), max: Math.max(yrange.max, pos.y + (size.height || 0)) },
-                    }),
-                    {
-                        xrange: { min: this._props.originTopLeft ? 0 : Number.MAX_VALUE, max: -Number.MAX_VALUE },
-                        yrange: { min: this._props.originTopLeft ? 0 : Number.MAX_VALUE, max: -Number.MAX_VALUE },
-                    }
-                );
-                const scaling = this.zoomScaling() * (this._props.NativeDimScaling?.() || 1);
-                const panelWidMax = (this._props.PanelWidth() / scaling) * (this._props.originTopLeft ? 2 / this.nativeDimScaling : 1);
-                const panelWidMin = (this._props.PanelWidth() / scaling) * (this._props.originTopLeft ? 0 : 1);
-                const panelHgtMax = (this._props.PanelHeight() / scaling) * (this._props.originTopLeft ? 2 / this.nativeDimScaling : 1);
-                const panelHgtMin = (this._props.PanelHeight() / scaling) * (this._props.originTopLeft ? 0 : 1);
-                if (ranges.xrange.min >= panX + panelWidMax / 2) panX = ranges.xrange.max + (this._props.originTopLeft ? 0 : panelWidMax / 2);
-                else if (ranges.xrange.max <= panX - panelWidMin / 2) panX = ranges.xrange.min - (this._props.originTopLeft ? panelWidMax / 2 : panelWidMin / 2);
-                if (ranges.yrange.min >= panY + panelHgtMax / 2) panY = ranges.yrange.max + (this._props.originTopLeft ? 0 : panelHgtMax / 2);
-                else if (ranges.yrange.max <= panY - panelHgtMin / 2) panY = ranges.yrange.min - (this._props.originTopLeft ? panelHgtMax / 2 : panelHgtMin / 2);
+                const { originTopLeft } = this._props;
+                // const xrangeMin = Math.min(...measuredDocs.map(doc => doc.x), originTopLeft ? 0 : Number.MAX_VALUE);
+                // const yrangeMin = Math.min(...measuredDocs.map(doc => doc.y), originTopLeft ? 0 : Number.MAX_VALUE);
+                // const xrangeMax = Math.max(...measuredDocs.map(doc => doc.x + doc.width));
+                // const yrangeMax = Math.max(...measuredDocs.map(doc => doc.y + doc.height));
+                const { bounds: { x: xrangeMin, y: yrangeMin, r: xrangeMax, b: yrangeMax } } = this.contentBounds(); // prettier-ignore
+                const nativeScaling = this._props.NativeDimScaling?.() || 1;
+                const scaling = this.zoomScaling() * nativeScaling;
+                const [widScaling, hgtScaling] = [this._props.PanelWidth() / scaling, this._props.PanelHeight() / scaling];
+                const panelWidMax = widScaling * (originTopLeft ? 2 / nativeScaling : 1);
+                const panelHgtMax = hgtScaling * (originTopLeft ? 2 / nativeScaling : 1);
+                const panelWidMin = widScaling * (originTopLeft ? 0 : 1);
+                const panelHgtMin = hgtScaling * (originTopLeft ? 0 : 1);
+                if      (xrangeMin >= panX + panelWidMax / 2) panX = xrangeMax + (originTopLeft ? 0               : panelWidMax / 2);
+                else if (xrangeMax <= panX - panelWidMin / 2) panX = xrangeMin - (originTopLeft ? panelWidMax / 2 : panelWidMin / 2); // prettier-ignore
+                if      (yrangeMin >= panY + panelHgtMax / 2) panY = yrangeMax + (originTopLeft ? 0               : panelHgtMax / 2);
+                else if (yrangeMax <= panY - panelHgtMin / 2) panY = yrangeMin - (originTopLeft ? panelHgtMax / 2 : panelHgtMin / 2); // prettier-ignore
             }
         }
         if (!this.layoutDoc._lockedTransform || LightboxView.LightboxDoc) {
-- 
cgit v1.2.3-70-g09d2

