aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/DocumentButtonBar.tsx2
-rw-r--r--src/client/views/DocumentDecorations.tsx14
-rw-r--r--src/client/views/MarqueeAnnotator.tsx29
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx2
-rw-r--r--src/client/views/nodes/DataVizBox/DataVizBox.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx8
-rw-r--r--src/client/views/nodes/ImageBox.tsx2
-rw-r--r--src/client/views/nodes/VideoBox.tsx2
-rw-r--r--src/client/views/nodes/WebBox.tsx17
-rw-r--r--src/client/views/pdf/PDFViewer.tsx5
10 files changed, 43 insertions, 40 deletions
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 63d2a5e08..e6d53e727 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -305,7 +305,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
if (this._dragRef.current) {
const dragDocView = this.view0!;
const dragData = new DragManager.DocumentDragData([dragDocView.Document]);
- const [left, top] = dragDocView.screenToLocalTransform().inverse().transformPoint(0, 0);
+ const [left, top] = dragDocView.screenToNativeLocalTransform().inverse().transformPoint(0, 0);
dragData.defaultDropAction = 'embed';
dragData.canEmbed = true;
DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, left, top, { hideSource: false });
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 51fd33222..583a7c447 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -77,7 +77,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
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.Views.lastElement()?.screenToLocalTransform().Rotate));
+ NumCast(SelectionManager.Views.lastElement()?.screenToNativeLocalTransform().Rotate));
(this._showNothing = !(this.Bounds.x !== Number.MAX_VALUE && //
(this.Bounds.x > center.x+x || this.Bounds.r < center.x+x ||
this.Bounds.y > center.y+y || this.Bounds.b < center.y+y )));
@@ -208,7 +208,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
SelectionManager.Views.map(dv => dv.Document),
dragDocView._props.dropAction
);
- dragData.offset = dragDocView.screenToLocalTransform().transformDirection(e.x - left, e.y - top);
+ dragData.offset = dragDocView.screenToNativeLocalTransform().transformDirection(e.x - left, e.y - top);
dragData.moveDocument = dragDocView._props.moveDocument;
dragData.removeDocument = dragDocView._props.removeDocument;
dragData.isDocDecorationMove = true;
@@ -353,7 +353,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
};
setRotateCenter = (seldocview: DocumentView, rotCenter: number[]) => {
- const newloccentern = seldocview.screenToLocalTransform().transformPoint(rotCenter[0], rotCenter[1]);
+ const newloccentern = seldocview.screenToNativeLocalTransform().transformPoint(rotCenter[0], rotCenter[1]);
const newlocenter = [newloccentern[0] - NumCast(seldocview.layoutDoc._width) / 2, newloccentern[1] - NumCast(seldocview.layoutDoc._height) / 2];
const final = Utils.rotPt(newlocenter[0], newlocenter[1], -(NumCast(seldocview.Document._rotation) / 180) * Math.PI);
seldocview.Document.rotation_centerX = final.x / NumCast(seldocview.layoutDoc._width);
@@ -462,7 +462,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
dot = (b[0] - a[0]) * (p[1] - a[1]) - (b[1] - a[1]) * (p[0] - a[0]);
return [a[0] + atob[0] * t, a[1] + atob[1] * t];
};
- const tl = docView.screenToLocalTransform().inverse().transformPoint(0, 0);
+ const tl = docView.screenToNativeLocalTransform().inverse().transformPoint(0, 0);
return project([e.clientX + this._offset.x, e.clientY + this._offset.y], tl, [tl[0] + fixedAspect, tl[1] + 1]);
};
onPointerMove = (e: PointerEvent, down: number[], move: number[]): boolean => {
@@ -530,7 +530,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
doc.xPadding = NumCast(doc.xPadding) * scale.x;
doc.yPadding = NumCast(doc.yPadding) * scale.y;
} else {
- const refCent = docView.screenToLocalTransform().transformPoint(refPt[0], refPt[1]); // fixed reference point for resize (ie, a point that doesn't move)
+ const refCent = docView.screenToNativeLocalTransform().transformPoint(refPt[0], refPt[1]); // fixed reference point for resize (ie, a point that doesn't move)
const [nwidth, nheight] = [docView.nativeWidth, docView.nativeHeight];
const [initWidth, initHeight] = [NumCast(doc._width, 1), NumCast(doc._height)];
@@ -632,7 +632,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
@computed get rotCenter() {
const lastView = SelectionManager.Views.lastElement();
if (lastView) {
- const invXf = lastView.screenToLocalTransform().inverse();
+ const invXf = lastView.screenToNativeLocalTransform().inverse();
const seldoc = lastView.layoutDoc;
const loccenter = Utils.rotPt(NumCast(seldoc.rotation_centerX) * NumCast(seldoc._width), NumCast(seldoc.rotation_centerY) * NumCast(seldoc._height), invXf.Rotate);
return invXf.transformPoint(loccenter.x + NumCast(seldoc._width) / 2, loccenter.y + NumCast(seldoc._height) / 2);
@@ -691,7 +691,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
const bounds = this.ClippedBounds;
const useLock = bounds.r - bounds.x > 135 && seldocview.CollectionFreeFormDocumentView;
const useRotation = !hideResizers && seldocview.Document.type !== DocumentType.EQUATION && seldocview.CollectionFreeFormDocumentView; // when do we want an object to not rotate?
- const rotation = SelectionManager.Views.length == 1 ? seldocview.screenToLocalTransform().inverse().RotateDeg : 0;
+ const rotation = SelectionManager.Views.length == 1 ? seldocview.screenToNativeLocalTransform().inverse().RotateDeg : 0;
// Radius constants
const useRounding = seldocview.ComponentView instanceof ImageBox || seldocview.ComponentView instanceof FormattedTextBox || seldocview.ComponentView instanceof CollectionFreeFormView;
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index 3eb43dacf..9f3786d8e 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -22,11 +22,12 @@ export interface MarqueeAnnotatorProps {
Document: Doc;
down?: number[];
scrollTop: number;
+ isNativeScaled?: boolean;
scaling?: () => number;
annotationLayerScaling?: () => number;
annotationLayerScrollTop: number;
containerOffset?: () => number[];
- mainCont: HTMLDivElement;
+ marqueeContainer: HTMLDivElement;
docView: () => DocumentView;
savedAnnotations: () => ObservableMap<number, HTMLDivElement[]>;
selectionText: () => string;
@@ -147,20 +148,28 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
savedAnnotations.set(page, savedPage ?? [div]);
});
+ // this transforms a screen point into a local coordinate subject. It's complicated by documents that are rotated
+ // since the DOM's bounding rectangle is not rotated and Dash's ScreenToLocalTransform carries along a rotation value, but doesn't
+ // use it when transforming points.
+ // So the idea here is to reconstruct a local point by unrotating the screen point about the center of the bounding box. The approach is:
+ // 1) Get vector from the screen point to the center of the rotated bounding box in screens space
+ // 2) unrotate that vector in screen space
+ // 3) localize the unrotated vector by scaling into the marquee container's coordinates
+ // 4) reattach the vector to the center of the bounding box
getTransformedScreenPt = (down: number[]) => {
- const boundingRect = this.props.mainCont.getBoundingClientRect();
+ const marqueeContainer = this.props.marqueeContainer;
+ const containerXf = this.props.isNativeScaled ? this.props.docView().screenToNativeLocalTransform() : this.props.docView().props.ScreenToLocalTransform();
+ const boundingRect = marqueeContainer.getBoundingClientRect();
const center = { x: boundingRect.x + boundingRect.width / 2, y: boundingRect.y + boundingRect.height / 2 };
- const downPt = Utils.rotPt(down[0] - center.x, down[1] - center.y, NumCast(this.props.docView().screenToLocalTransform().Rotate));
- const scale = this.props.docView().props.ScreenToLocalTransform().Scale;
- const scalex = this.props.mainCont.offsetWidth / NumCast(this.props.Document.width);
- const scaley = this.props.mainCont.offsetHeight / NumCast(this.props.Document.height);
- // set marquee x and y positions to the spatially transformed position
- return { x: scalex * (downPt.x + NumCast(this.props.Document.width) / scale / 2) * scale,
- y: scaley * (downPt.y + NumCast(this.props.Document.height) / scale / 2) * scale + this.props.annotationLayerScrollTop }; // prettier-ignore
+ const downVec = Utils.rotPt(down[0] - center.x,
+ down[1] - center.y, NumCast(containerXf.Rotate)); // prettier-ignore
+ return { x: downVec.x * containerXf.Scale + marqueeContainer.offsetWidth /2,
+ y: downVec.y * containerXf.Scale + marqueeContainer.offsetHeight/2 + this.props.annotationLayerScrollTop }; // prettier-ignore
};
@action
public onInitiateSelection(down: number[]) {
+ console.log('DOWN = ' + down[0] + ' ' + down[1]);
this._width = this._height = 0;
this._start = this.getTransformedScreenPt(down);
@@ -242,7 +251,7 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
@action
onSelectEnd = (e: PointerEvent) => {
e.stopPropagation();
- const marquees = this.props.mainCont.getElementsByClassName('marqueeAnnotator-dragBox');
+ const marquees = this.props.marqueeContainer.getElementsByClassName('marqueeAnnotator-dragBox');
const marqueeStyle = (Array.from(marquees).lastElement() as HTMLDivElement)?.style;
if (!this.isEmpty && marqueeStyle) {
// configure and show the annotation/link menu if a the drag region is big enough
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 548734dab..324a4b8d1 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -229,7 +229,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
@action public float = () => {
const topDoc = this.Document;
const containerDocView = this._props.docViewPath().lastElement();
- const screenXf = containerDocView?.screenToLocalTransform();
+ const screenXf = containerDocView?.screenToNativeLocalTransform();
if (screenXf) {
SelectionManager.DeselectAll();
if (topDoc.z) {
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index ff0e3271d..76cc010f6 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -425,7 +425,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
savedAnnotations={this.savedAnnotations}
selectionText={returnEmptyString}
annotationLayer={this._annotationLayer.current}
- mainCont={this._mainCont.current}
+ marqueeContainer={this._mainCont.current}
anchorMenuCrop={this.crop}
/>
)}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index d07824099..7ec0382e4 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1433,7 +1433,7 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
@computed get hideLinkButton() {
return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HideLinkBtn + (this.IsSelected ? ':selected' : ''));
}
- hideLinkCount = () => this._props.renderDepth === -1 || (this.IsSelected && this._props.renderDepth) || !this._isHovering || this.hideLinkButton;
+ hideLinkCount = () => false; // this._props.renderDepth === -1 || (this.IsSelected && this._props.renderDepth) || !this._isHovering || this.hideLinkButton;
@computed get linkCountView() {
return <DocumentLinksButton hideCount={this.hideLinkCount} View={this} scaling={this.scaleToScreenSpace} OnHover={true} Bottom={this.topMost} ShowCount={true} />;
}
@@ -1566,7 +1566,7 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
};
layout_fitWidthFunc = (doc: Doc) => BoolCast(this.layout_fitWidth);
- scaleToScreenSpace = () => (1 / (this._props.NativeDimScaling?.() || 1)) * this.screenToLocalTransform().Scale;
+ scaleToScreenSpace = () => this._props.ScreenToLocalTransform().Scale;
docViewPathFunc = () => this.docViewPath;
isSelected = () => this.IsSelected;
select = (extendSelection: boolean, focusSelection?: boolean) => {
@@ -1589,7 +1589,7 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
PanelHeight = () => this.panelHeight;
NativeDimScaling = () => this.nativeScaling;
selfView = () => this;
- screenToLocalTransform = () =>
+ screenToNativeLocalTransform = () =>
this._props
.ScreenToLocalTransform()
.translate(-this.centeringX, -this.centeringY)
@@ -1676,7 +1676,7 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
isSelected={this.isSelected}
select={this.select}
layout_fitWidth={this.layout_fitWidthFunc}
- ScreenToLocalTransform={this.screenToLocalTransform}
+ ScreenToLocalTransform={this.screenToNativeLocalTransform}
focus={this._props.focus || emptyFunction}
ref={action((r: DocumentViewInternal | null) => r && (this.docView = r))}
/>
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 876f13370..28c614786 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -458,7 +458,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
savedAnnotations={this.savedAnnotations}
selectionText={returnEmptyString}
annotationLayer={this._annotationLayer.current}
- mainCont={this._mainCont.current}
+ marqueeContainer={this._mainCont.current}
highlightDragSrcColor={''}
anchorMenuCrop={this.crop}
/>
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index f257d5769..7ab954b3f 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -1109,7 +1109,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
savedAnnotations={this.savedAnnotations}
selectionText={returnEmptyString}
annotationLayer={this._annotationLayer.current}
- mainCont={this._mainCont.current}
+ marqueeContainer={this._mainCont.current}
anchorMenuCrop={this.crop}
/>
)}
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 758c919d2..a61837dad 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -250,7 +250,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@action
createTextAnnotation = (sel: Selection, selRange: Range | undefined) => {
if (this._mainCont.current && selRange) {
- if (this.dataDoc[this._props.fieldKey] instanceof HtmlField) this._mainCont.current.style.transform = `rotate(${NumCast(this._props.DocumentView!().screenToLocalTransform().RotateDeg)}deg)`;
+ if (this.dataDoc[this._props.fieldKey] instanceof HtmlField) this._mainCont.current.style.transform = `rotate(${NumCast(this._props.DocumentView!().screenToNativeLocalTransform().RotateDeg)}deg)`;
const clientRects = selRange.getClientRects();
for (let i = 0; i < clientRects.length; i++) {
const rect = clientRects.item(i);
@@ -399,17 +399,10 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@action
iframeDown = (e: PointerEvent) => {
this._props.select(false);
- const locpt = {
- x: (e.clientX / NumCast(this.Document.nativeWidth)) * this._props.PanelWidth(),
- y: ((e.clientY - NumCast(this.layoutDoc.layout_scrollTop))/ NumCast(this.Document.nativeHeight)) * this._props.PanelHeight() }; // prettier-ignore
- const scrclick = this._props.DocumentView?.()._props.ScreenToLocalTransform().inverse().transformPoint(locpt.x, locpt.y)!;
- const scrcent = this._props
- .DocumentView?.()
- ._props.ScreenToLocalTransform()
+ const theclick = this.props
+ .ScreenToLocalTransform()
.inverse()
- .transformPoint(NumCast(this.Document.width) / 2, NumCast(this.Document.height) / 2)!;
- const theclickoff = Utils.rotPt(scrclick[0] - scrcent[0], scrclick[1] - scrcent[1], -this._props.ScreenToLocalTransform().Rotate);
- const theclick = [theclickoff.x + scrcent[0], theclickoff.y + scrcent[1]];
+ .transformPoint(e.clientX, e.clientY - NumCast(this.layoutDoc.layout_scrollTop));
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
const word = getWordAtPoint(e.target, e.clientX, e.clientY);
if (!word && !(e.target as any)?.className?.includes('rangeslider') && !(e.target as any)?.onclick && !(e.target as any)?.parentNode?.onclick) {
@@ -1121,7 +1114,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
savedAnnotations={this.savedAnnotationsCreator}
selectionText={this.selectionText}
annotationLayer={this._annotationLayer.current}
- mainCont={this._mainCont.current}
+ marqueeContainer={this._mainCont.current}
/>
</div>
)}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index b6d027d30..f41094010 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -419,7 +419,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
@action
createTextAnnotation = (sel: Selection, selRange: Range) => {
if (this._mainCont.current) {
- this._mainCont.current.style.transform = `rotate(${NumCast(this._props.DocumentView!().screenToLocalTransform().RotateDeg)}deg)`;
+ this._mainCont.current.style.transform = `rotate(${NumCast(this._props.DocumentView!().screenToNativeLocalTransform().RotateDeg)}deg)`;
const boundingRect = this._mainCont.current.getBoundingClientRect();
const clientRects = selRange.getClientRects();
for (let i = 0; i < clientRects.length; i++) {
@@ -585,6 +585,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
getPageFromScroll={this.getPageFromScroll}
anchorMenuClick={this._props.anchorMenuClick}
scrollTop={0}
+ isNativeScaled={true}
annotationLayerScrollTop={NumCast(this._props.Document._layout_scrollTop)}
addDocument={this.addDocumentWrapper}
docView={this._props.DocumentView!}
@@ -592,7 +593,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
savedAnnotations={this.savedAnnotations}
selectionText={this.selectionText}
annotationLayer={this._annotationLayer.current}
- mainCont={this._mainCont.current}
+ marqueeContainer={this._mainCont.current}
anchorMenuCrop={this._textSelecting ? undefined : this.crop}
/>
)}