aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx67
-rw-r--r--src/client/views/nodes/DocumentView.tsx6
2 files changed, 40 insertions, 33 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index eeb4e61aa..9609cb826 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -789,6 +789,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@action
zoom = (pointX: number, pointY: number, deltaY: number): void => {
+ if (this.Document._isGroup) return;
let deltaScale = deltaY > 0 ? (1 / 1.05) : 1.05;
if (deltaScale < 0) deltaScale = -deltaScale;
const [x, y] = this.getTransform().transformPoint(pointX, pointY);
@@ -815,10 +816,16 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
e.stopPropagation();
}
else if (this.props.active(true)) {
- e.stopPropagation();
- e.preventDefault();
- if (!e.ctrlKey && MarqueeView.DragMarquee) this.setPan(this.panX() + e.deltaX, this.panY() + e.deltaY, "None", true);
- else 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 && MarqueeView.DragMarquee) {
+ this.setPan(this.panX() + e.deltaX, this.panY() + e.deltaY, "None", true);
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ else if (!this.Document._isGroup) {
+ e.stopPropagation();
+ e.preventDefault();
+ this.zoom(e.clientX, e.clientY, e.deltaY); // if (!this.props.isAnnotationOverlay) // bcz: do we want to zoom in on images/videos/etc?
+ }
}
this.props.Document.targetScale = NumCast(this.props.Document[this.scaleFieldKey]);
@@ -876,6 +883,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
});
scaleAtPt(docpt: number[], scale: number) {
+ if (this.Document._isGroup) return;
const screenXY = this.getTransform().inverse().transformPoint(docpt[0], docpt[1]);
this.Document._viewTransition = "transform 500ms";
this.layoutDoc[this.scaleFieldKey] = scale;
@@ -886,7 +894,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
this.layoutDoc._panY = NumCast(this.layoutDoc._panY) - newpan[1];
}
- focusDocument = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc) => {
+ focusDocument = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, docTransform?: Transform) => {
const state = HistoryUtil.getState();
// TODO This technically isn't correct if type !== "doc", as
@@ -906,10 +914,11 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
if (this.props.Document.scrollHeight) {
this.props.focus(doc, undefined, undefined, afterFocus);
} else {
+ const xfToCollection = docTransform ?? Transform.Identity();
const layoutdoc = Doc.Layout(doc);
const savedState = { px: NumCast(this.Document._panX), py: NumCast(this.Document._panY), s: this.Document[this.scaleFieldKey], pt: this.Document._viewTransition };
const newState = HistoryUtil.getState();
- const { px, py } = layoutdoc.annotationOn || this.rootDoc._isGroup ? savedState : willZoom ? this.setZoomToDoc(layoutdoc, scale) : this.setPanIntoView(doc);
+ const { px, py } = layoutdoc.annotationOn || this.rootDoc._isGroup ? savedState : this.setPanIntoView(layoutdoc, xfToCollection, willZoom ? scale || .75 : undefined);
if (!layoutdoc.annotationOn && !this.rootDoc._isGroup) { // only pan and zoom to focus on a document if the document is not an annotation in an annotation overlay collection
newState.initializers![this.Document[Id]] = { panX: px, panY: py };
HistoryUtil.pushState(newState);
@@ -935,34 +944,32 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
return resetView;
};
this.props.focus(this.rootDoc._isGroup ? doc : this.rootDoc, willZoom, scale, (didFocus: boolean) =>
- new Promise<boolean>(res => setTimeout(async () => res(await endFocus(didMove || didFocus)), focusSpeed)));
+ new Promise<boolean>(res => setTimeout(async () => res(await endFocus(didMove || didFocus)), focusSpeed)),
+ !this.rootDoc._isGroup ? Transform.Identity() :
+ new Transform(NumCast(this.rootDoc.x) + this.rootDoc[WidthSym]() / 2 - NumCast(this.rootDoc._panX), NumCast(this.rootDoc.y) + this.rootDoc[HeightSym]() / 2 - NumCast(this.rootDoc._panY), 1)
+ .transform(docTransform ?? Transform.Identity()));
}
}
- setPanIntoView = (doc: Doc) => {
- const cx = NumCast(this.props.Document._panX);
- const cy = NumCast(this.props.Document._panY);
- const pwid = this.props.PanelWidth() / NumCast(this.props.Document._viewScale, 1);
- const phgt = this.props.PanelHeight() / NumCast(this.props.Document._viewScale, 1);
- const screen = { left: cx - pwid / 2, right: cx + pwid / 2, top: cy - phgt / 2, bot: cy + phgt / 2 };
- const bounds = { left: NumCast(doc.x) - pwid / 10, right: NumCast(doc.x) + doc[WidthSym]() + pwid / 10, top: NumCast(doc.y) - phgt / 10, bot: NumCast(doc.y) + doc[HeightSym]() + phgt / 10 };
- return {
- px: cx + Math.min(0, bounds.left - screen.left) + Math.max(0, bounds.right - screen.right),
- py: cy + Math.min(0, bounds.top - screen.top) + Math.max(0, bounds.bot - screen.bot)
- };
- }
+ setPanIntoView = (doc: Doc, xf: Transform, scale?: number) => {
+ const pw = this.props.PanelWidth() / NumCast(this.layoutDoc._viewScale, 1);
+ const ph = this.props.PanelHeight() / NumCast(this.layoutDoc._viewScale, 1);
+ const pt = xf.transformPoint(NumCast(doc.x), NumCast(doc.y));
+ const pt2 = xf.transformPoint(NumCast(doc.x) + doc[WidthSym](), NumCast(doc.y) + doc[HeightSym]());
+ const bounds = { left: pt[0], right: pt2[0], top: pt[1], bot: pt2[1] };
- setZoomToDoc = (doc: Doc, scale: number = 0.75) => {
- const pw = this.props.PanelWidth();
- const ph = this.props.PanelHeight();
- pw && ph && (this.Document[this.scaleFieldKey] = scale * Math.min(pw / NumCast(doc._width), ph / NumCast(doc._height)));
- const pwid = pw / NumCast(this.props.Document._viewScale, 1);
- const phgt = ph / NumCast(this.props.Document._viewScale, 1);
- const bounds = { left: NumCast(doc.x) - pwid / 10, right: NumCast(doc.x) + doc[WidthSym]() + pwid / 10, top: NumCast(doc.y) - phgt / 10, bot: NumCast(doc.y) + doc[HeightSym]() + phgt / 10 };
- return {
- px: (bounds.left + bounds.right) / 2,
- py: (bounds.top + bounds.bot) / 2
- };
+ if (scale) {
+ this.Document[this.scaleFieldKey] = scale * Math.min(this.props.PanelWidth() / doc[WidthSym](), this.props.PanelHeight() / doc[HeightSym]());
+ return { px: (bounds.left + bounds.right) / 2, py: (bounds.top + bounds.bot) / 2 };
+ } else {
+ const cx = NumCast(this.layoutDoc._panX);
+ const cy = NumCast(this.layoutDoc._panY);
+ const screen = { left: cx - pw / 2, right: cx + pw / 2, top: cy - ph / 2, bot: cy + ph / 2 };
+ return {
+ px: cx + Math.min(0, bounds.left - pw / 10 - screen.left) + Math.max(0, bounds.right + pw / 10 - screen.right),
+ py: cy + Math.min(0, bounds.top - ph / 10 - screen.top) + Math.max(0, bounds.bot + ph / 10 - screen.bot)
+ };
+ }
}
onChildClickHandler = () => this.props.childClickScript || ScriptCast(this.Document.onChildClick);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 3fc39d554..34e0a2bc8 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -43,7 +43,7 @@ import React = require("react");
import { LinkDocPreview } from "./LinkDocPreview";
export type DocAfterFocusFunc = (notFocused: boolean) => Promise<boolean>;
-export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc) => void;
+export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, docTransform?: Transform) => void;
export type StyleProviderFunc = (doc: Opt<Doc>, props: Opt<DocumentViewProps | FieldViewProps>, property: string) => any;
export interface DocComponentView {
getAnchor: () => Doc;
@@ -375,11 +375,11 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
}
- focus = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc) => {
+ focus = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, docTransform?: Transform) => {
if (this._componentView?.scrollFocus) {
return this._componentView?.scrollFocus?.(doc, !LinkDocPreview.LinkInfo, afterFocus); // bcz: smooth parameter should really be passed into focus() instead of inferred here
}
- return this.props.focus(doc, willZoom, scale, afterFocus);
+ return this.props.focus(doc, willZoom, scale, afterFocus, docTransform);
}
onClick = action((e: React.MouseEvent | React.PointerEvent) => {
if (!e.nativeEvent.cancelBubble && !this.Document.ignoreClick && this.props.renderDepth >= 0 &&