From da5184d2113935df25633a6015e177a51e88df2f Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 17 May 2023 16:18:20 -0400
Subject: fixed scrolling/panning on fitWidth images.  fixed drag/zoom
 conflicts for overlayDocs that are pannable.

---
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 71 +++++++++++-----------
 1 file changed, 37 insertions(+), 34 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 9bf071cc0..3b5dd45d9 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -635,7 +635,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     case InkTool.None:
                         if (!(this.props.layoutEngine?.() || StrCast(this.layoutDoc._layoutEngine))) {
                             this._hitCluster = this.pickCluster(this.getTransform().transformPoint(e.clientX, e.clientY));
-                            setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, emptyFunction, this._hitCluster !== -1 ? true : false);
+                            setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, emptyFunction, this._hitCluster !== -1 ? true : false, false);
                         }
                         break;
                 }
@@ -868,9 +868,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             Doc.ActiveTool = InkTool.None;
         } else {
             if (this.tryDragCluster(e, this._hitCluster)) {
+                e.stopPropagation(); // we're moving a cluster, so stop propagation and return true to end panning and let the document drag take over
                 return true;
             }
-            this.pan(e);
+            // pan the view if this is a regular collection, or it's an overlay and the overlay is zoomed (otherwise, there's nothing to pan)
+            if (!this.props.isAnnotationOverlay || (1 - NumCast(this.rootDoc._freeform_scale_min, 1)/ this.getLocalTransform().inverse().Scale)) {
+                this.pan(e);                
+                e.stopPropagation();  // if we are actually panning, stop propagation -- this will preven things like the overlayView from dragging the document while we're panning
+            }
         }
         return false;
     };
@@ -1023,12 +1028,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         if (deltaScale * invTransform.Scale > 20) {
             deltaScale = 20 / invTransform.Scale;
         }
-        if (deltaScale < 1 && invTransform.Scale <= NumCast(this.rootDoc._freeform_scaleMin, 1) && this.isAnnotationOverlay) {
+        if (deltaScale < 1 && invTransform.Scale <= NumCast(this.rootDoc._freeform_scale_min, 1) && this.isAnnotationOverlay) {
             this.setPan(0, 0);
             return;
         }
-        if (deltaScale * invTransform.Scale < NumCast(this.rootDoc._freeform_scaleMin, 1) && this.isAnnotationOverlay) {
-            deltaScale = NumCast(this.rootDoc._freeform_scaleMin, 1) / invTransform.Scale;
+        if (deltaScale * invTransform.Scale < NumCast(this.rootDoc._freeform_scale_min, 1) && this.isAnnotationOverlay) {
+            deltaScale = NumCast(this.rootDoc._freeform_scale_min, 1) / invTransform.Scale;
         }
 
         const localTransform = invTransform.scaleAbout(deltaScale, x, y);
@@ -1040,36 +1045,25 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     };
 
     @action
-    onPointerWheel = (e: React.WheelEvent): void => {
+    onPointerWheel = (e:React.WheelEvent): void => {
         if (this.Document._isGroup || !this.isContentActive()) return; // group style collections neither pan nor zoom
         PresBox.Instance?.pauseAutoPres();
-        if (this.layoutDoc._Transform || DocListCast(Doc.MyOverlayDocs?.data).includes(this.props.Document) || this.props.Document.treeViewOutlineMode === TreeViewType.outline) return;
+        if (this.layoutDoc._Transform || this.props.Document.treeViewOutlineMode === TreeViewType.outline) return;
         e.stopPropagation();
+        const docHeight = NumCast(this.rootDoc[Doc.LayoutFieldKey(this.rootDoc)+"_nativeHeight"], this.nativeHeight);
+        const scrollable = NumCast(this.layoutDoc[this.scaleFieldKey],1) ===1 && docHeight > this.props.PanelHeight() / this.nativeDimScaling ;
         switch (!e.ctrlKey ? Doc.UserDoc().freeformScrollMode : freeformScrollMode.Pan) {
             case freeformScrollMode.Pan:
                 // if ctrl is selected then zoom
-                if (e.ctrlKey) {
-                    if (this.props.isContentActive(true)) {
-                        if (this.props.isAnnotationOverlayScrollable) {
-                            // bcz: zooming on a webbox doesn't get the correct coordinates here for unknown reasons.
-                            // so better to do nothing than having things jump around.
-                        } else this.zoom(e.screenX, e.screenY, e.deltaY);
-                    }
-                } // otherwise pan
-                else if (this.props.isContentActive(true)) {
-                    const dx = -e.deltaX;
-                    const dy = -e.deltaY;
-                    if (e.shiftKey) {
-                        !this.props.isAnnotationOverlayScrollable && this.scrollPan({ deltaX: dy, deltaY: 0 });
-                    } else {
-                        !this.props.isAnnotationOverlayScrollable && this.scrollPan({ deltaX: dx, deltaY: dy });
-                    }
+                if (!e.ctrlKey && this.props.isContentActive(true)) {
+                    this.scrollPan({ deltaX: -e.deltaX, deltaY: e.shiftKey ? 0 :-Math.max(-1, Math.min(1,e.deltaY)) });
+                    break;
                 }
-                break;
             default:
             case freeformScrollMode.Zoom:
-                if (this.props.isContentActive(true)) {
-                    !this.props.isAnnotationOverlayScrollable && this.zoom(e.clientX, e.clientY, e.deltaY); // if (!this.props.isAnnotationOverlay) // bcz: do we want to zoom in on images/videos/etc?
+                if ((e.ctrlKey || !scrollable) && this.props.isContentActive(true)) {
+                    this.zoom(e.clientX, e.clientY,Math.max(-1, Math.min(1,e.deltaY))); // if (!this.props.isAnnotationOverlay) // bcz: do we want to zoom in on images/videos/etc?
+                    e.preventDefault();
                 }
                 break;
         }
@@ -1112,19 +1106,20 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 else if (ranges.yrange.max <= panY - panelHgtMin / 2) panY = ranges.yrange.min - (this.props.originTopLeft ? panelHgtMax / 2 : panelHgtMin / 2);
             }
         }
-        if (!this.layoutDoc._lockedTransform || LightboxView.LightboxDoc || DocListCast(Doc.MyOverlayDocs?.data).includes(this.Document)) {
+        if (!this.layoutDoc._lockedTransform || LightboxView.LightboxDoc) {
             this.setPanZoomTransition(panTime);
-            const scale = this.getLocalTransform().inverse().Scale;
-            const minScale = NumCast(this.rootDoc._freeform_scaleMin, 1);
-            const minPanX = NumCast(this.rootDoc._freeform_panXMin, 0);
-            const minPanY = NumCast(this.rootDoc._freeform_panYMin, 0);
-            const newPanX = Math.min(minPanX + (1 - minScale / scale) * NumCast(this.rootDoc._freeform_panXMax, this.nativeWidth), Math.max(minPanX, panX));
+            const minScale = NumCast(this.rootDoc._freeform_scale_min, 1);
+            const scale = (1 - minScale/ this.getLocalTransform().inverse().Scale);
+            const minPanX = NumCast(this.rootDoc._freeform_panX_min, 0);
+            const minPanY = NumCast(this.rootDoc._freeform_panY_min, 0);
+            const maxPanX = NumCast(this.rootDoc._freeform_panX_max, this.nativeWidth);
+            const newPanX = Math.min(minPanX + scale *maxPanX, Math.max(minPanX, panX));
             const fitYscroll = (((this.nativeHeight / this.nativeWidth) * this.props.PanelWidth() - this.props.PanelHeight()) * this.props.ScreenToLocalTransform().Scale) / minScale;
             const nativeHeight = (this.props.PanelHeight() / this.props.PanelWidth() / (this.nativeHeight / this.nativeWidth)) * this.nativeHeight;
             const maxScrollTop = this.nativeHeight / this.props.ScreenToLocalTransform().Scale - this.props.PanelHeight();
             const maxPanY =
                 minPanY + // minPanY + scrolling introduced by view scaling + scrolling introduced by layout_fitWidth
-                (1 - minScale / scale) * NumCast(this.rootDoc._panYMax, nativeHeight) +
+                scale* NumCast(this.rootDoc._panY_max, nativeHeight) +
                 (!this.props.getScrollHeight?.() ? fitYscroll : 0); // when not zoomed, scrolling is handled via a scrollbar, not panning
             let newPanY = Math.max(minPanY, Math.min(maxPanY, panY));
             if (false && NumCast(this.rootDoc.layout_scrollTop) && NumCast(this.rootDoc._freeform_scale, minScale) !== minScale) {
@@ -1971,6 +1966,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     lightboxPanelWidth = () => Math.max(0, this.props.PanelWidth() - 30);
     lightboxPanelHeight = () => Math.max(0, this.props.PanelHeight() - 30);
     lightboxScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-15, -15);
+    onPassiveWheel = (e:WheelEvent) => {
+        const docHeight = NumCast(this.rootDoc[Doc.LayoutFieldKey(this.rootDoc)+"_nativeHeight"], this.nativeHeight);
+        const scrollable = NumCast(this.layoutDoc[this.scaleFieldKey],1) ===1 && docHeight > this.props.PanelHeight() / this.nativeDimScaling ;
+        this.props.isSelected() && !scrollable && e.preventDefault()
+    }
+    _oldWheel:any;
     render() {
         TraceMobx();
         return (
@@ -1978,8 +1979,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 className="collectionfreeformview-container"
                 ref={r => {
                     this.createDashEventsTarget(r);
+                    this._oldWheel?.removeEventListener('wheel', this.onPassiveWheel);
+                    this._oldWheel= r;
                     // prevent wheel events from passivly propagating up through containers
-                    !this.props.isAnnotationOverlay && r?.addEventListener('wheel', (e: WheelEvent) => this.props.isSelected() && e.preventDefault(), { passive: false });
+                     r?.addEventListener('wheel', this.onPassiveWheel, { passive: false });
                 }}
                 onWheel={this.onPointerWheel}
                 onClick={this.onClick}
-- 
cgit v1.2.3-70-g09d2

