From 0a5e02a87fdabff5ff8399829ff857cae90fc1e2 Mon Sep 17 00:00:00 2001
From: mehekj <mehek.jethani@gmail.com>
Date: Sun, 20 Mar 2022 10:29:42 -0400
Subject: Revert "Merge remote-tracking branch 'origin/speedups2' into
 temporalmedia-mehek"

This reverts commit 1f7cf7babc76ecff5aef5fe663c48e067e85dd26, reversing
changes made to 1e3ad4de06f83eab54628de660529fefb9a0dc63.
---
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 249 ++++++++-------------
 1 file changed, 98 insertions(+), 151 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 e2ea81392..aeda71d01 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -4,12 +4,13 @@ import { observer } from "mobx-react";
 import { computedFn } from "mobx-utils";
 import { DateField } from "../../../../fields/DateField";
 import { Doc, HeightSym, Opt, StrListCast, WidthSym } from "../../../../fields/Doc";
+import { collectionSchema, documentSchema } from "../../../../fields/documentSchemas";
 import { Id } from "../../../../fields/FieldSymbols";
 import { InkData, InkField, InkTool, PointData, Segment } from "../../../../fields/InkField";
 import { List } from "../../../../fields/List";
 import { ObjectField } from "../../../../fields/ObjectField";
 import { RichTextField } from "../../../../fields/RichTextField";
-import { createSchema, listSpec } from "../../../../fields/Schema";
+import { createSchema, listSpec, makeInterface } from "../../../../fields/Schema";
 import { ScriptField } from "../../../../fields/ScriptField";
 import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types";
 import { TraceMobx } from "../../../../fields/util";
@@ -40,6 +41,7 @@ import { LightboxView } from "../../LightboxView";
 import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView";
 import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment, ViewSpecPrefix } from "../../nodes/DocumentView";
 import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox";
+import { pageSchema } from "../../nodes/ImageBox";
 import { PresBox } from "../../nodes/trails/PresBox";
 import { StyleLayers, StyleProp } from "../../StyleProvider";
 import { CollectionDockingView } from "../CollectionDockingView";
@@ -65,6 +67,8 @@ export const panZoomSchema = createSchema({
     scrollHeight: "number"    // this will be set when the collection is an annotation overlay for a PDF/Webpage
 });
 
+type PanZoomDocument = makeInterface<[typeof panZoomSchema, typeof collectionSchema, typeof documentSchema, typeof pageSchema]>;
+const PanZoomDocument = makeInterface(panZoomSchema, collectionSchema, documentSchema, pageSchema);
 export type collectionFreeformViewProps = {
     annotationLayerHostsContent?: boolean; // whether to force scaling of content (needed by ImageBox)
     viewDefDivClick?: ScriptField;
@@ -77,7 +81,7 @@ export type collectionFreeformViewProps = {
 };
 
 @observer
-export class CollectionFreeFormView extends CollectionSubView<Partial<collectionFreeformViewProps>>() {
+export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, Partial<collectionFreeformViewProps>>(PanZoomDocument) {
     public get displayName() { return "CollectionFreeFormView(" + this.props.Document.title?.toString() + ")"; } // this makes mobx trace() statements more descriptive
 
     private _lastNudge: any;
@@ -91,7 +95,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     private _clusterDistance: number = 75;
     private _hitCluster: number = -1;
     private _disposers: { [name: string]: IReactionDisposer } = {};
-    private _renderCutoffData = observable.map<string, boolean>();
     private _layoutPoolData = observable.map<string, PoolData>();
     private _layoutSizeData = observable.map<string, { width?: number, height?: number }>();
     private _cachedPool: Map<string, PoolData> = new Map();
@@ -106,7 +109,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     @observable _viewTransition: number = 0;  // sets the pan/zoom transform ease time- used by nudge(), focus() etc to smoothly zoom/pan.  set to 0 to use document's transition time or default of 0
     @observable _hLines: number[] | undefined;
     @observable _vLines: number[] | undefined;
-    @observable _firstRender = true; // this turns off rendering of the collection's content so that there's instant feedback when a tab is switched of what content will be shown.
     @observable _pullCoords: number[] = [0, 0];
     @observable _pullDirection: string = "";
     @observable _showAnimTimeline = false;
@@ -161,7 +163,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         this.layoutDoc._panY = vals.bounds.cy;
         this.layoutDoc._viewScale = vals.scale;
     }
-    freeformData = (force?: boolean) => !this._firstRender && (this.fitToContent || force) ? this.fitToContentVals : undefined;
+    freeformData = (force?: boolean) => this.fitToContent || force ? this.fitToContentVals : undefined;
     reverseNativeScaling = () => this.fitToContent ? true : false;
     panX = () => this.freeformData()?.bounds.cx ?? NumCast(this.Document._panX);
     panY = () => this.freeformData()?.bounds.cy ?? NumCast(this.Document._panY);
@@ -203,7 +205,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 }
             }
             if (this.Document._currentFrame !== undefined && !this.props.isAnnotationOverlay) {
-                CollectionFreeFormDocumentView.setupKeyframes(newBoxes, NumCast(this.Document._currentFrame), true);
+                CollectionFreeFormDocumentView.setupKeyframes(newBoxes, this.Document._currentFrame, true);
             }
         }
         return retVal;
@@ -233,12 +235,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             const d = docDragData.droppedDocuments[i];
             const layoutDoc = Doc.Layout(d);
             if (this.Document._currentFrame !== undefined) {
-                CollectionFreeFormDocumentView.setupKeyframes([d], NumCast(this.Document._currentFrame), false);
+                CollectionFreeFormDocumentView.setupKeyframes([d], this.Document._currentFrame, false);
                 const vals = CollectionFreeFormDocumentView.getValues(d, NumCast(d.activeFrame, 1000));
                 vals.x = x + (vals.x || 0) - dropPos[0];
                 vals.y = y + (vals.y || 0) - dropPos[1];
                 vals._scrollTop = this.Document.editScrollProgressivize ? vals._scrollTop : undefined;
-                CollectionFreeFormDocumentView.setValues(NumCast(this.Document._currentFrame), d, vals);
+                CollectionFreeFormDocumentView.setValues(this.Document._currentFrame, d, vals);
             } else {
                 d.x = x + NumCast(d.x) - dropPos[0];
                 d.y = y + NumCast(d.y) - dropPos[1];
@@ -633,7 +635,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     @action
     pan = (e: PointerEvent | React.Touch | { clientX: number, clientY: number }): void => {
         const [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
-        this.setPan(NumCast(this.Document._panX) - dx, NumCast(this.Document._panY) - dy, 0, true);
+        this.setPan((this.Document._panX || 0) - dx, (this.Document._panY || 0) - dy, 0, true);
         this._lastX = e.clientX;
         this._lastY = e.clientY;
     }
@@ -965,10 +967,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 .filter(({ pos, size }) => pos && size).map(({ pos, size }) => ({ pos: pos!, size: size! }));
             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: 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: Number.MAX_VALUE, max: -Number.MAX_VALUE },
                         yrange: { min: Number.MAX_VALUE, max: -Number.MAX_VALUE }
@@ -1043,11 +1045,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         if (state.type === "doc" && this.Document._panX !== undefined && this.Document._panY !== undefined) {
             const init = state.initializers![this.Document[Id]];
             if (!init) {
-                state.initializers![this.Document[Id]] = { panX: NumCast(this.Document._panX), panY: NumCast(this.Document._panY) };
+                state.initializers![this.Document[Id]] = { panX: this.Document._panX, panY: this.Document._panY };
                 HistoryUtil.pushState(state);
             } else if (init.panX !== this.Document._panX || init.panY !== this.Document._panY) {
-                init.panX = NumCast(this.Document._panX);
-                init.panY = NumCast(this.Document._panY);
+                init.panX = this.Document._panX;
+                init.panY = this.Document._panY;
                 HistoryUtil.pushState(state);
             }
         }
@@ -1142,7 +1144,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
 
     isContentActive = () => this.props.isSelected() || this.props.isContentActive();
 
-    getChildDocView(entry: PoolData, renderIndex: number) {
+    getChildDocView(entry: PoolData) {
         const childLayout = entry.pair.layout;
         const childData = entry.pair.data;
         const engine = this.props.layoutEngine?.() || StrCast(this.props.Document._layoutEngine);
@@ -1151,8 +1153,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             Document={childLayout}
             renderDepth={this.props.renderDepth + 1}
             replica={entry.replica}
-            renderIndex={renderIndex}
-            renderCutoffProvider={this.renderCutoffProvider}
             ContainingCollectionView={this.props.CollectionView}
             ContainingCollectionDoc={this.props.Document}
             CollectionFreeFormView={this}
@@ -1213,7 +1213,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         const { z, color, zIndex } = params.pair.layout;
         const { x, y, opacity } = this.Document._currentFrame === undefined ?
             { x: params.pair.layout.x, y: params.pair.layout.y, opacity: this.props.styleProvider?.(params.pair.layout, this.props, StyleProp.Opacity) } :
-            CollectionFreeFormDocumentView.getValues(params.pair.layout, NumCast(this.Document._currentFrame));
+            CollectionFreeFormDocumentView.getValues(params.pair.layout, this.Document._currentFrame);
         return {
             x: NumCast(x), y: NumCast(y), z: Cast(z, "number"), color: StrCast(color), zIndex: Cast(zIndex, "number"),
             transition: StrCast(layoutDoc.dataTransition), opacity: this._keyframeEditing ? 1 : Cast(opacity, "number", null),
@@ -1256,12 +1256,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         }
     }
 
-
-    renderCutoffProvider = computedFn(function renderCutoffProvider(this: any, doc: Doc) {
-        return !this._renderCutoffData.get(doc[Id] + "");
-    }.bind(this));
-
-
     childPositionProviderUnmemoized = (doc: Doc, replica: string) => {
         return this._layoutPoolData.get(doc[Id] + (replica || ""));
     }
@@ -1306,7 +1300,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         return { newPool, computedElementData: this.doFreeformLayout(newPool) };
     }
 
-    @observable _numLoaded = 1;
     get doLayoutComputation() {
         const { newPool, computedElementData } = this.doInternalLayoutComputation;
         const array = Array.from(newPool.entries());
@@ -1325,9 +1318,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         this._cachedPool.clear();
         Array.from(newPool.entries()).forEach(k => this._cachedPool.set(k[0], k[1]));
         const elements = computedElementData.slice();
-        Array.from(newPool.entries()).filter(entry => this.isCurrent(entry[1].pair.layout)).forEach((entry, i) =>
+        Array.from(newPool.entries()).filter(entry => this.isCurrent(entry[1].pair.layout)).forEach(entry =>
             elements.push({
-                ele: this.getChildDocView(entry[1], i),
+                ele: this.getChildDocView(entry[1]),
                 bounds: this.childDataProvider(entry[1].pair.layout, entry[1].replica)
             }));
 
@@ -1376,38 +1369,35 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     componentDidMount() {
         super.componentDidMount?.();
         this.props.setContentView?.(this);
-        setTimeout(action(() => {
-            this._firstRender = false;
-            this._disposers.layoutComputation = reaction(() => this.doLayoutComputation,
-                (elements) => this._layoutElements = elements || [],
-                { fireImmediately: true, name: "doLayout" });
-
-            this._marqueeRef.current?.addEventListener("dashDragAutoScroll", this.onDragAutoScroll as any);
-
-            this._disposers.groupBounds = reaction(() => {
-                if (this.props.Document._isGroup && this.childDocs.length === this.childDocList?.length) {
-                    const clist = this.childDocs.map(cd => ({ x: NumCast(cd.x), y: NumCast(cd.y), width: cd[WidthSym](), height: cd[HeightSym]() }));
-                    return aggregateBounds(clist, NumCast(this.layoutDoc._xPadding), NumCast(this.layoutDoc._yPadding));
+        this._disposers.layoutComputation = reaction(() => this.doLayoutComputation,
+            (elements) => this._layoutElements = elements || [],
+            { fireImmediately: true, name: "doLayout" });
+
+        this._marqueeRef.current?.addEventListener("dashDragAutoScroll", this.onDragAutoScroll as any);
+
+        this._disposers.groupBounds = reaction(() => {
+            if (this.props.Document._isGroup && this.childDocs.length === this.childDocList?.length) {
+                const clist = this.childDocs.map(cd => ({ x: NumCast(cd.x), y: NumCast(cd.y), width: cd[WidthSym](), height: cd[HeightSym]() }));
+                return aggregateBounds(clist, NumCast(this.layoutDoc._xPadding), NumCast(this.layoutDoc._yPadding));
+            }
+            return undefined;
+        },
+            (cbounds) => {
+                if (cbounds) {
+                    const c = [NumCast(this.layoutDoc.x) + this.layoutDoc[WidthSym]() / 2, NumCast(this.layoutDoc.y) + this.layoutDoc[HeightSym]() / 2];
+                    const p = [NumCast(this.layoutDoc._panX), NumCast(this.layoutDoc._panY)];
+                    const pbounds = {
+                        x: (cbounds.x - p[0]) * this.zoomScaling() + c[0], y: (cbounds.y - p[1]) * this.zoomScaling() + c[1],
+                        r: (cbounds.r - p[0]) * this.zoomScaling() + c[0], b: (cbounds.b - p[1]) * this.zoomScaling() + c[1]
+                    };
+                    this.layoutDoc._width = (pbounds.r - pbounds.x);
+                    this.layoutDoc._height = (pbounds.b - pbounds.y);
+                    this.layoutDoc._panX = (cbounds.r + cbounds.x) / 2;
+                    this.layoutDoc._panY = (cbounds.b + cbounds.y) / 2;
+                    this.layoutDoc.x = pbounds.x;
+                    this.layoutDoc.y = pbounds.y;
                 }
-                return undefined;
-            },
-                (cbounds) => {
-                    if (cbounds) {
-                        const c = [NumCast(this.layoutDoc.x) + this.layoutDoc[WidthSym]() / 2, NumCast(this.layoutDoc.y) + this.layoutDoc[HeightSym]() / 2];
-                        const p = [NumCast(this.layoutDoc._panX), NumCast(this.layoutDoc._panY)];
-                        const pbounds = {
-                            x: (cbounds.x - p[0]) * this.zoomScaling() + c[0], y: (cbounds.y - p[1]) * this.zoomScaling() + c[1],
-                            r: (cbounds.r - p[0]) * this.zoomScaling() + c[0], b: (cbounds.b - p[1]) * this.zoomScaling() + c[1]
-                        };
-                        this.layoutDoc._width = (pbounds.r - pbounds.x);
-                        this.layoutDoc._height = (pbounds.b - pbounds.y);
-                        this.layoutDoc._panX = (cbounds.r + cbounds.x) / 2;
-                        this.layoutDoc._panY = (cbounds.b + cbounds.y) / 2;
-                        this.layoutDoc.x = pbounds.x;
-                        this.layoutDoc.y = pbounds.y;
-                    }
-                }, { fireImmediately: true });
-        }));
+            }, { fireImmediately: true });
     }
 
     componentWillUnmount() {
@@ -1459,8 +1449,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         const height = Math.max(...docs.map(doc => NumCast(doc._height))) + 20;
         const dim = Math.ceil(Math.sqrt(docs.length));
         docs.forEach((doc, i) => {
-            doc.x = NumCast(this.Document._panX) + (i % dim) * width - width * dim / 2;
-            doc.y = NumCast(this.Document._panY) + Math.floor(i / dim) * height - height * dim / 2;
+            doc.x = (this.Document._panX || 0) + (i % dim) * width - width * dim / 2;
+            doc.y = (this.Document._panY || 0) + Math.floor(i / dim) * height - height * dim / 2;
         });
     }
 
@@ -1567,35 +1557,58 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         e.stopPropagation();
     }
 
-    incrementalRender = action(() => {
-        if (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath())) {
-            const unrendered = this.childDocs.filter(doc => !this._renderCutoffData.get(doc[Id]));
-            const loadIncrement = 5;
-            for (var i = 0; i < Math.min(unrendered.length, loadIncrement); i++) {
-                this._renderCutoffData.set(unrendered[i][Id] + "", true);
-            }
-        }
-        this.childDocs.some(doc => !this._renderCutoffData.get(doc[Id])) && setTimeout(this.incrementalRender, 1);
-    });
-
     children = () => {
-        this.incrementalRender();
         const children = typeof this.props.children === "function" ? (this.props.children as any)() as JSX.Element[] : [];
-        return [
-            ...children,
-            ...this.views,
-            <CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />
-        ];
+        return [...children, ...this.views, <CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />];
+    }
+
+    chooseGridSpace = (gridSpace: number): number => {
+        if (!this.zoomScaling()) return 50;
+        const divisions = this.props.PanelWidth() / this.zoomScaling() / gridSpace + 3;
+        return divisions < 60 ? gridSpace : this.chooseGridSpace(gridSpace * 10);
+    }
+
+    @computed get backgroundGrid() {
+        const gridSpace = this.chooseGridSpace(NumCast(this.layoutDoc["_backgroundGrid-spacing"], 50));
+        const shiftX = (this.props.isAnnotationOverlay ? 0 : -this.panX() % gridSpace - gridSpace) * this.zoomScaling();
+        const shiftY = (this.props.isAnnotationOverlay ? 0 : -this.panY() % gridSpace - gridSpace) * this.zoomScaling();
+        const renderGridSpace = gridSpace * this.zoomScaling();
+        const w = this.props.PanelWidth() + 2 * renderGridSpace;
+        const h = this.props.PanelHeight() + 2 * renderGridSpace;
+        const strokeStyle = CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "rgba(255,255,255,0.5)" : "rgba(0, 0,0,0.5)";
+        return <canvas className="collectionFreeFormView-grid" width={w} height={h} style={{ transform: `translate(${shiftX}px, ${shiftY}px)` }}
+            ref={(el) => {
+                const ctx = el?.getContext('2d');
+                if (ctx) {
+                    const Cx = this.cachedCenteringShiftX % renderGridSpace;
+                    const Cy = this.cachedCenteringShiftY % renderGridSpace;
+                    ctx.lineWidth = Math.min(1, Math.max(0.5, this.zoomScaling()));
+                    ctx.setLineDash(gridSpace > 50 ? [3, 3] : [1, 5]);
+                    ctx.clearRect(0, 0, w, h);
+                    if (ctx) {
+                        ctx.strokeStyle = strokeStyle;
+                        ctx.beginPath();
+                        for (let x = Cx - renderGridSpace; x <= w - Cx; x += renderGridSpace) {
+                            ctx.moveTo(x, Cy - h);
+                            ctx.lineTo(x, Cy + h);
+                        }
+                        for (let y = Cy - renderGridSpace; y <= h - Cy; y += renderGridSpace) {
+                            ctx.moveTo(Cx - w, y);
+                            ctx.lineTo(Cx + w, y);
+                        }
+                        ctx.stroke();
+                    }
+                }
+            }} />;
     }
 
     @computed get placeholder() {
-        return <div className="collectionfreeformview-placeholder" style={{ background: StrCast(this.Document.backgroundColor) }}>
+        return <div className="collectionfreeformview-placeholder" style={{ background: this.Document.backgroundColor }}>
             <span className="collectionfreeformview-placeholderSpan">{this.props.Document.title?.toString()}</span>
         </div>;
     }
 
     @computed get marqueeView() {
-        TraceMobx();
         return <MarqueeView
             {...this.props}
             ungroup={this.props.Document._isGroup ? this.promoteCollection : undefined}
@@ -1610,18 +1623,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             getTransform={this.getTransform}
             isAnnotationOverlay={this.isAnnotationOverlay}>
             <div className="marqueeView-div" ref={this._marqueeRef} style={{ opacity: this.props.dontRenderDocuments ? 0 : undefined }}>
-                {this.layoutDoc._backgroundGridShow ?
-                    <CollectionFreeFormBackgroundGrid
-                        PanelWidth={this.props.PanelWidth}
-                        PanelHeight={this.props.PanelHeight}
-                        panX={this.panX}
-                        panY={this.panY}
-                        zoomScaling={this.zoomScaling}
-                        layoutDoc={this.layoutDoc}
-                        isAnnotationOverlay={this.isAnnotationOverlay}
-                        cachedCenteringShiftX={this.cachedCenteringShiftX}
-                        cachedCenteringShiftY={this.cachedCenteringShiftY}
-                    /> : (null)}
+                {this.layoutDoc._backgroundGridShow ? this.backgroundGrid : (null)}
                 <CollectionFreeFormViewPannableContents
                     isAnnotationOverlay={this.isAnnotationOverlay}
                     isAnnotationOverlayScrollable={this.props.isAnnotationOverlayScrollable}
@@ -1640,7 +1642,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     }
 
     @computed get contentScaling() {
-        if (this._firstRender || (this.props.isAnnotationOverlay && !this.props.annotationLayerHostsContent)) return 0;
+        if (this.props.isAnnotationOverlay && !this.props.annotationLayerHostsContent) return 0;
         const nw = this.nativeWidth;
         const nh = this.nativeHeight;
         const hscale = nh ? this.props.PanelHeight() / nh : 1;
@@ -1673,9 +1675,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     this.backgroundEvents ? "all" : this.props.pointerEvents as any,
                 transform: `scale(${this.contentScaling || 1})`,
                 width: `${100 / (this.contentScaling || 1)}%`,
-                height: this.isAnnotationOverlay && this.Document.scrollHeight ? NumCast(this.Document.scrollHeight) : `${100 / (this.contentScaling || 1)}%`// : this.isAnnotationOverlay ? (this.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight()
+                height: this.isAnnotationOverlay && this.Document.scrollHeight ? this.Document.scrollHeight : `${100 / (this.contentScaling || 1)}%`// : this.isAnnotationOverlay ? (this.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight()
             }}>
-            {this._firstRender || (this.Document._freeformLOD && !this.props.isContentActive() && !this.props.isAnnotationOverlay && this.props.renderDepth > 0) ?
+            {this.Document._freeformLOD && !this.props.isContentActive() && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 ?
                 this.placeholder : this.marqueeView}
             {this.props.noOverlay ? (null) : <CollectionFreeFormOverlayView elements={this.elementFunc} />}
 
@@ -1852,59 +1854,4 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
             {this.zoomProgressivize}
         </div>;
     }
-}
-
-interface CollectionFreeFormViewBackgroundGridProps {
-    panX: () => number;
-    panY: () => number;
-    PanelWidth: () => number;
-    PanelHeight: () => number;
-    isAnnotationOverlay?: boolean;
-    zoomScaling: () => number;
-    layoutDoc: Doc;
-    cachedCenteringShiftX: number;
-    cachedCenteringShiftY: number;
-}
-@observer
-class CollectionFreeFormBackgroundGrid extends React.Component<CollectionFreeFormViewBackgroundGridProps> {
-
-
-    chooseGridSpace = (gridSpace: number): number => {
-        if (!this.props.zoomScaling()) return 50;
-        const divisions = this.props.PanelWidth() / this.props.zoomScaling() / gridSpace + 3;
-        return divisions < 60 ? gridSpace : this.chooseGridSpace(gridSpace * 10);
-    }
-    render() {
-        const gridSpace = this.chooseGridSpace(NumCast(this.props.layoutDoc["_backgroundGrid-spacing"], 50));
-        const shiftX = (this.props.isAnnotationOverlay ? 0 : -this.props.panX() % gridSpace - gridSpace) * this.props.zoomScaling();
-        const shiftY = (this.props.isAnnotationOverlay ? 0 : -this.props.panY() % gridSpace - gridSpace) * this.props.zoomScaling();
-        const renderGridSpace = gridSpace * this.props.zoomScaling();
-        const w = this.props.PanelWidth() + 2 * renderGridSpace;
-        const h = this.props.PanelHeight() + 2 * renderGridSpace;
-        const strokeStyle = CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "rgba(255,255,255,0.5)" : "rgba(0, 0,0,0.5)";
-        return <canvas className="collectionFreeFormView-grid" width={w} height={h} style={{ transform: `translate(${shiftX}px, ${shiftY}px)` }}
-            ref={(el) => {
-                const ctx = el?.getContext('2d');
-                if (ctx) {
-                    const Cx = this.props.cachedCenteringShiftX % renderGridSpace;
-                    const Cy = this.props.cachedCenteringShiftY % renderGridSpace;
-                    ctx.lineWidth = Math.min(1, Math.max(0.5, this.props.zoomScaling()));
-                    ctx.setLineDash(gridSpace > 50 ? [3, 3] : [1, 5]);
-                    ctx.clearRect(0, 0, w, h);
-                    if (ctx) {
-                        ctx.strokeStyle = strokeStyle;
-                        ctx.beginPath();
-                        for (let x = Cx - renderGridSpace; x <= w - Cx; x += renderGridSpace) {
-                            ctx.moveTo(x, Cy - h);
-                            ctx.lineTo(x, Cy + h);
-                        }
-                        for (let y = Cy - renderGridSpace; y <= h - Cy; y += renderGridSpace) {
-                            ctx.moveTo(Cx - w, y);
-                            ctx.lineTo(Cx + w, y);
-                        }
-                        ctx.stroke();
-                    }
-                }
-            }} />;
-    }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2

