From e4a3b962f8de00f5bc0463bed886d9f8f526ff89 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 20 Nov 2023 09:09:50 -0500
Subject: fixes for selecting/moving docs that are rotated.

---
 src/client/views/DocumentDecorations.tsx | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 77554bd51..6663c5ee8 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -1,7 +1,7 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@material-ui/core';
 import { IconButton } from 'browndash-components';
-import { action, computed, observable, reaction, runInAction } from 'mobx';
+import { action, computed, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { FaUndo } from 'react-icons/fa';
 import { DateField } from '../../fields/DateField';
@@ -65,7 +65,17 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
         super(props);
         DocumentDecorations.Instance = this;
         document.addEventListener('pointermove', // show decorations whenever pointer moves outside of selection bounds.
-            action(e => (this._showNothing = !(this.Bounds.x !== Number.MAX_VALUE && (this.Bounds.x > e.clientX + this._resizeBorderWidth / 2 || this.Bounds.r < e.clientX - this._resizeBorderWidth / 2 || this.Bounds.y > e.clientY + this._resizeBorderWidth / 2 || this.Bounds.b < e.clientY - this._resizeBorderWidth / 2))))); // prettier-ignore
+            action(e => {
+                const center = {x: (this.Bounds.x+this.Bounds.r)/2, y: (this.Bounds.y+this.Bounds.b)/2};
+                const {x,y} = Utils.rotPt(e.clientX - center.x, 
+                                          e.clientY - center.y, 
+                                          -NumCast(SelectionManager.Docs().lastElement()?.rotation)/180*Math.PI);
+                (this._showNothing = !(this.Bounds.x !== Number.MAX_VALUE && //
+                    (this.Bounds.x > center.x+x + this._resizeBorderWidth / 2 || 
+                     this.Bounds.r < center.x+x - this._resizeBorderWidth / 2 || 
+                     this.Bounds.y > center.y+y + this._resizeBorderWidth / 2 || 
+                     this.Bounds.b < center.y+y - this._resizeBorderWidth / 2)));
+            })); // prettier-ignore
     }
 
     @computed get ClippedBounds() {
@@ -524,7 +534,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                 (doc.layout_reflowVertical && (opts.dragHdl === 'bottom' || opts.dragHdl === 'top' || opts.ctrlKey)); // eg rtf, web, pdf
             if (nwidth && nheight && !modifyNativeDim) {
                 // eg., dragging right resizer on PDF -- enforce native dimensions because not expliclty overridden with ctrl or bottom resize drag
-                scale.x === 1 ? (scale.x = scale.y) : (scale.x = scale.x);
+                scale.x === 1 ? (scale.x = scale.y) : (scale.y = scale.x);
             }
 
             if (['right', 'left'].includes(opts.dragHdl) && modifyNativeDim && Doc.NativeWidth(doc)) {
@@ -688,7 +698,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
         const bounds = this.ClippedBounds;
         const useLock = bounds.r - bounds.x > 135 && seldocview.CollectionFreeFormDocumentView;
         const useRotation = !hideResizers && seldocview.rootDoc.type !== DocumentType.EQUATION && seldocview.CollectionFreeFormDocumentView; // when do we want an object to not rotate?
-        const rotation = SelectionManager.Views().length == 1 ? NumCast(seldocview.rootDoc._rotation) : 0;
+        const rotation = SelectionManager.Views().length == 1 ? seldocview.docViewPath.reduce((rot, view) => rot + NumCast(view.rootDoc._rotation), 0) : 0;
 
         // Radius constants
         const useRounding = seldocview.ComponentView instanceof ImageBox || seldocview.ComponentView instanceof FormattedTextBox || seldocview.ComponentView instanceof CollectionFreeFormView;
@@ -748,6 +758,8 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                 )}
             </div>
         );
+        const centery = hideTitle ? 0 : this._titleHeight;
+        const transformOrigin = `${50}% calc(50% + ${centery / 2}px)`;
         const freeformDoc = SelectionManager.Views().some(v => v.CollectionFreeFormDocumentView);
         return (
             <div className="documentDecorations" style={{ display: this._showNothing && !freeformDoc ? 'none' : undefined }}>
@@ -758,9 +770,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                         height: bounds.b - bounds.y + this._resizeBorderWidth + 'px',
                         left: bounds.x - this._resizeBorderWidth / 2,
                         top: bounds.y - this._resizeBorderWidth / 2,
+                        transformOrigin,
                         background: SnappingManager.GetShiftKey() ? undefined : 'yellow',
                         pointerEvents: SnappingManager.GetShiftKey() || DocumentView.Interacting ? 'none' : 'all',
                         display: SelectionManager.Views().length <= 1 || hideDecorations ? 'none' : undefined,
+                        transform: `rotate(${rotation}deg)`,
                     }}
                     onPointerDown={this.onBackgroundDown}
                 />
@@ -770,6 +784,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                             className={`documentDecorations-container  ${this._showNothing ? 'showNothing' : ''}`}
                             style={{
                                 transform: `translate(${bounds.x - this._resizeBorderWidth / 2}px, ${bounds.y - this._resizeBorderWidth / 2 - this._titleHeight}px) rotate(${rotation}deg)`,
+                                transformOrigin,
                                 width: bounds.r - bounds.x + this._resizeBorderWidth + 'px',
                                 height: bounds.b - bounds.y + this._resizeBorderWidth + (this._showNothing ? 0 : this._titleHeight) + 'px',
                             }}>
-- 
cgit v1.2.3-70-g09d2

