From 2ea594a4c1ff221200e0795fb07d30b603177a67 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 3 Jan 2024 23:44:28 -0500 Subject: cleaned up screenToLocalTransform in several places by making it additional methods. cleaned up styleProider api a bit to take DocumentViewInternalProps, not DocumentViewProps.. --- src/client/util/HypothesisUtils.ts | 2 +- src/client/views/DocComponent.tsx | 10 ++ src/client/views/DocumentButtonBar.tsx | 2 +- src/client/views/DocumentDecorations.tsx | 16 +-- src/client/views/GestureOverlay.tsx | 2 +- src/client/views/GlobalKeyHandler.ts | 4 +- src/client/views/InkingStroke.tsx | 23 ++--- src/client/views/MarqueeAnnotator.tsx | 2 +- src/client/views/StyleProvider.tsx | 13 +-- .../views/collections/CollectionCarouselView.tsx | 5 +- .../views/collections/CollectionNoteTakingView.tsx | 18 ++-- .../collections/CollectionStackedTimeline.tsx | 11 ++- .../views/collections/CollectionStackingView.tsx | 12 +-- .../views/collections/CollectionTimeView.tsx | 1 - .../views/collections/CollectionTreeView.tsx | 4 +- src/client/views/collections/CollectionView.tsx | 2 +- src/client/views/collections/TabDocView.tsx | 7 +- src/client/views/collections/TreeView.tsx | 18 ++-- .../CollectionFreeFormLinkView.tsx | 10 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 94 +++++++++--------- .../collectionGrid/CollectionGridView.tsx | 6 +- .../CollectionMulticolumnView.tsx | 2 +- .../CollectionMultirowView.tsx | 2 +- .../collectionSchema/CollectionSchemaView.tsx | 21 ++-- src/client/views/nodes/AudioBox.tsx | 4 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 9 +- src/client/views/nodes/ComparisonBox.tsx | 6 +- .../views/nodes/DataVizBox/components/TableBox.tsx | 2 +- src/client/views/nodes/DocumentLinksButton.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 48 +++++---- src/client/views/nodes/ImageBox.tsx | 6 +- src/client/views/nodes/LinkBox.tsx | 10 +- src/client/views/nodes/MapBox/MapBox.tsx | 8 +- src/client/views/nodes/MapBox/MapBox2.tsx | 2 +- .../views/nodes/MapboxMapBox/MapboxContainer.tsx | 6 +- src/client/views/nodes/PDFBox.tsx | 2 +- src/client/views/nodes/ScreenshotBox.tsx | 1 - src/client/views/nodes/VideoBox.tsx | 6 +- src/client/views/nodes/WebBox.tsx | 12 +-- .../views/nodes/formattedText/FormattedTextBox.tsx | 109 +-------------------- .../views/nodes/importBox/ImportElementBox.tsx | 2 +- src/client/views/nodes/trails/PresBox.tsx | 4 +- src/client/views/nodes/trails/PresElementBox.tsx | 4 +- src/client/views/pdf/PDFViewer.tsx | 15 +-- 44 files changed, 230 insertions(+), 315 deletions(-) (limited to 'src') diff --git a/src/client/util/HypothesisUtils.ts b/src/client/util/HypothesisUtils.ts index 0ae23d793..f46c2d431 100644 --- a/src/client/util/HypothesisUtils.ts +++ b/src/client/util/HypothesisUtils.ts @@ -180,7 +180,7 @@ export namespace Hypothesis { }) ); const targetView: Opt = DocumentManager.Instance.getFirstDocumentView(target); - const position = targetView?.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); + const position = targetView?.screenToViewTransform().inverse().transformPoint(0, 0); targetView && position && simulateMouseClick(targetView.ContentDiv!, position[0], position[1], position[0], position[1], false); }, 300); diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index b5bd17572..dfc298840 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -12,12 +12,14 @@ import { DocumentManager } from '../util/DocumentManager'; import { ObservableReactComponent } from './ObservableReactComponent'; import { CollectionFreeFormView } from './collections/collectionFreeForm'; import { DocumentView } from './nodes/DocumentView'; +import { Transform } from '../util/Transform'; /// DocComponent returns a generic React base class used by views that don't have 'fieldKey' props (e.g.,CollectionFreeFormDocumentView, DocumentView) export interface DocComponentProps { Document: Doc; LayoutTemplate?: () => Opt; LayoutTemplateString?: string; + ScreenToLocalTransform: () => Transform; } export function DocComponent

() { class Component extends ObservableReactComponent> { @@ -26,6 +28,8 @@ export function DocComponent

() { makeObservable(this); } + ScreenToLocalBoxXf = () => this._props.ScreenToLocalTransform(); + //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then get Document() { return this._props.Document; @@ -50,10 +54,13 @@ interface ViewBoxBaseProps { fieldKey: string; isSelected: () => boolean; isContentActive: () => boolean | undefined; + ScreenToLocalTransform: () => Transform; renderDepth: number; } export function ViewBoxBaseComponent

() { class Component extends ObservableReactComponent> { + ScreenToLocalBoxXf = () => this._props.ScreenToLocalTransform(); + //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then get Document() { return this._props.Document; @@ -83,6 +90,7 @@ export interface ViewBoxAnnotatableProps { isContentActive: () => boolean | undefined; select: (isCtrlPressed: boolean) => void; whenChildContentsActiveChanged: (isActive: boolean) => void; + ScreenToLocalTransform: () => Transform; isSelected: () => boolean; renderDepth: number; isAnnotationOverlay?: boolean; @@ -94,6 +102,8 @@ export function ViewBoxAnnotatableComponent

() makeObservable(this); } + ScreenToLocalBoxXf = () => this._props.ScreenToLocalTransform(); + @observable _annotationKeySuffix = () => 'annotations'; @observable _isAnyChildContentActive = false; //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index e6d53e727..bb28d9ec9 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.screenToNativeLocalTransform().inverse().transformPoint(0, 0); + const [left, top] = dragDocView.screenToContentsTransform().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 583a7c447..ced8799bf 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -77,7 +77,7 @@ export class DocumentDecorations extends ObservableReactComponent 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 dv.Document), dragDocView._props.dropAction ); - dragData.offset = dragDocView.screenToNativeLocalTransform().transformDirection(e.x - left, e.y - top); + dragData.offset = dragDocView.screenToContentsTransform().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 { - const newloccentern = seldocview.screenToNativeLocalTransform().transformPoint(rotCenter[0], rotCenter[1]); + const newloccentern = seldocview.screenToContentsTransform().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); @@ -385,7 +385,7 @@ export class DocumentDecorations extends ObservableReactComponent { const accumRot = (NumCast(dv.Document._rotation) / 180) * Math.PI; - const localRotCtr = dv._props.ScreenToLocalTransform().transformPoint(rcScreen.X, rcScreen.Y); + const localRotCtr = dv.screenToViewTransform().transformPoint(rcScreen.X, rcScreen.Y); const localRotCtrOffset = [localRotCtr[0] - NumCast(dv.Document.width) / 2, localRotCtr[1] - NumCast(dv.Document.height) / 2]; const startRotCtr = Utils.rotPt(localRotCtrOffset[0], localRotCtrOffset[1], -accumRot); const unrotatedDocPos = { x: NumCast(dv.Document.x) + localRotCtrOffset[0] - startRotCtr.x, y: NumCast(dv.Document.y) + localRotCtrOffset[1] - startRotCtr.y }; @@ -462,7 +462,7 @@ export class DocumentDecorations extends ObservableReactComponent { @@ -530,7 +530,7 @@ export class DocumentDecorations extends ObservableReactComponent 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.screenToNativeLocalTransform().inverse().RotateDeg : 0; + const rotation = SelectionManager.Views.length == 1 ? seldocview.screenToContentsTransform().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/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 65aadc148..b1b04237c 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -385,7 +385,7 @@ export class GestureOverlay extends ObservableReactComponent dv.Document[Id]).join(':'); SelectionManager.Views.length && navigator.clipboard.writeText(text); DocumentDecorations.Instance.onCloseClick(true); @@ -312,7 +312,7 @@ export class KeyManager { case 'c': if ((document.activeElement as any)?.type !== 'text' && !AnchorMenu.Instance.Active && DocumentDecorations.Instance.Bounds.r - DocumentDecorations.Instance.Bounds.x > 2) { const bds = DocumentDecorations.Instance.Bounds; - const pt = SelectionManager.Views[0].props.ScreenToLocalTransform().transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2); + const pt = SelectionManager.Views[0].screenToViewTransform().transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2); const text = `__DashCloneId(${pt?.[0] || 0},${pt?.[1] || 0}):` + SelectionManager.Views.map(dv => dv.Document[Id]).join(':'); SelectionManager.Views.length && navigator.clipboard.writeText(text); stopPropagation = false; diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 95c677845..c652e8966 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -45,6 +45,7 @@ import { FieldView, FieldViewProps } from './nodes/FieldView'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { PinProps, PresBox } from './nodes/trails'; import { StyleProp } from './StyleProvider'; +import { Transform } from '../util/Transform'; const { default: { INK_MASK_SIZE } } = require('./global/globalCssVariables.module.scss'); // prettier-ignore @observer export class InkingStroke extends ViewBoxBaseComponent() { @@ -73,10 +74,6 @@ export class InkingStroke extends ViewBoxBaseComponent() { Object.keys(this._disposers).forEach(key => this._disposers[key]()); } - // transform is the inherited screentolocal xf plus any scaling that was done to make the stroke - // fit within its panel (e.g., for content fitting views like Lightbox or multicolumn, etc) - screenToLocal = () => this._props.ScreenToLocalTransform().scale(this._props.NativeDimScaling?.() || 1); - getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => { const subAnchor = this._subContentView?.getAnchor?.(addAsAnnotation); if (subAnchor !== this.Document && subAnchor) return subAnchor; @@ -129,7 +126,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { const { inkData, inkScaleX, inkScaleY, inkStrokeWidth, inkTop, inkLeft } = this.inkScaledData(); const screenPts = inkData .map(point => - this.screenToLocal() + this.ScreenToLocalBoxXf() .inverse() .transformPoint((point.X - inkLeft - inkStrokeWidth / 2) * inkScaleX + inkStrokeWidth / 2, (point.Y - inkTop - inkStrokeWidth / 2) * inkScaleY + inkStrokeWidth / 2) ) @@ -181,7 +178,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { */ ptFromScreen = (scrPt: { X: number; Y: number }) => { const { inkScaleX, inkScaleY, inkStrokeWidth, inkTop, inkLeft } = this.inkScaledData(); - const docPt = this.screenToLocal().transformPoint(scrPt.X, scrPt.Y); + const docPt = this.ScreenToLocalBoxXf().transformPoint(scrPt.X, scrPt.Y); const inkPt = { X: (docPt[0] - inkStrokeWidth / 2) / inkScaleX + inkStrokeWidth / 2 + inkLeft, Y: (docPt[1] - inkStrokeWidth / 2) / inkScaleY + inkStrokeWidth / 2 + inkTop, @@ -199,7 +196,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { X: (inkPt.X - inkLeft - inkStrokeWidth / 2) * inkScaleX + inkStrokeWidth / 2, Y: (inkPt.Y - inkTop - inkStrokeWidth / 2) * inkScaleY + inkStrokeWidth / 2, }; - const scrPt = this.screenToLocal().inverse().transformPoint(docPt.X, docPt.Y); + const scrPt = this.ScreenToLocalBoxXf().inverse().transformPoint(docPt.X, docPt.Y); return { X: scrPt[0], Y: scrPt[1] }; }; @@ -213,7 +210,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { snapPt = (scrPt: { X: number; Y: number }, excludeSegs?: number[]) => { const { inkData } = this.inkScaledData(); const { nearestPt, distance } = InkStrokeProperties.nearestPtToStroke(inkData, this.ptFromScreen(scrPt), excludeSegs ?? []); - return { nearestPt, distance: distance * this.screenToLocal().inverse().Scale }; + return { nearestPt, distance: distance * this.ScreenToLocalBoxXf().inverse().Scale }; }; /** @@ -250,7 +247,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { const { inkData, inkScaleX, inkScaleY, inkStrokeWidth, inkTop, inkLeft } = this.inkScaledData(); const screenPts = inkData .map(point => - this.screenToLocal() + this.ScreenToLocalBoxXf() .inverse() .transformPoint((point.X - inkLeft - inkStrokeWidth / 2) * inkScaleX + inkStrokeWidth / 2, (point.Y - inkTop - inkStrokeWidth / 2) * inkScaleY + inkStrokeWidth / 2) ) @@ -275,7 +272,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { const { inkData, inkScaleX, inkScaleY, inkStrokeWidth, inkTop, inkLeft } = this.inkScaledData(); return inkData .map(point => - this.screenToLocal() + this.ScreenToLocalBoxXf() .inverse() .transformPoint((point.X - inkLeft - inkStrokeWidth / 2) * inkScaleX + inkStrokeWidth / 2, (point.Y - inkTop - inkStrokeWidth / 2) * inkScaleY + inkStrokeWidth / 2) ) @@ -291,9 +288,9 @@ export class InkingStroke extends ViewBoxBaseComponent() { componentUI = (boundsLeft: number, boundsTop: number) => { const inkDoc = this.Document; const { inkData, inkStrokeWidth } = this.inkScaledData(); - const screenSpaceCenterlineStrokeWidth = Math.min(3, inkStrokeWidth * this.screenToLocal().inverse().Scale); // the width of the blue line widget that shows the centerline of the ink stroke + const screenSpaceCenterlineStrokeWidth = Math.min(3, inkStrokeWidth * this.ScreenToLocalBoxXf().inverse().Scale); // the width of the blue line widget that shows the centerline of the ink stroke - const screenInkWidth = this.screenToLocal().inverse().transformDirection(inkStrokeWidth, inkStrokeWidth); + const screenInkWidth = this.ScreenToLocalBoxXf().inverse().transformDirection(inkStrokeWidth, inkStrokeWidth); const startMarker = StrCast(this.layoutDoc.stroke_startMarker); const endMarker = StrCast(this.layoutDoc.stroke_endMarker); @@ -329,7 +326,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { false )} - + ); }; diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx index 9f3786d8e..ed09d3bf3 100644 --- a/src/client/views/MarqueeAnnotator.tsx +++ b/src/client/views/MarqueeAnnotator.tsx @@ -158,7 +158,7 @@ export class MarqueeAnnotator extends ObservableReactComponent { const marqueeContainer = this.props.marqueeContainer; - const containerXf = this.props.isNativeScaled ? this.props.docView().screenToNativeLocalTransform() : this.props.docView().props.ScreenToLocalTransform(); + const containerXf = this.props.isNativeScaled ? this.props.docView().screenToContentsTransform() : this.props.docView().screenToViewTransform(); const boundingRect = marqueeContainer.getBoundingClientRect(); const center = { x: boundingRect.x + boundingRect.width / 2, y: boundingRect.y + boundingRect.height / 2 }; const downVec = Utils.rotPt(down[0] - center.x, diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 835e61d55..ce69dcc41 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -20,7 +20,7 @@ import { SnappingManager } from '../util/SnappingManager'; import { undoBatch, UndoManager } from '../util/UndoManager'; import { TreeSort } from './collections/TreeSort'; import { Colors } from './global/globalEnums'; -import { DocumentViewProps } from './nodes/DocumentView'; +import { DocumentViewInternalProps, DocumentViewProps } from './nodes/DocumentView'; import { FieldViewProps } from './nodes/FieldView'; import { KeyValueBox } from './nodes/KeyValueBox'; import { PropertiesView } from './PropertiesView'; @@ -37,7 +37,6 @@ export enum StyleProp { BackgroundColor = 'backgroundColor', // background color of a document view FillColor = 'fillColor', // fill color of an ink stroke or shape WidgetColor = 'widgetColor', // color to display UI widgets on a document view -- used for the sidebar divider dragger on a text note - HideLinkBtn = 'hideLinkButton', // hides the blue-dot link button. used when a document acts like a button PointerEvents = 'pointerEvents', // pointer events for DocumentView -- inherits pointer events if not specified Decorations = 'decorations', // additional decoration to display above a DocumentView -- currently only used to display a Lock for making things background HeaderMargin = 'headerMargin', // margin at top of documentview, typically for displaying a title -- doc contents will start below that @@ -81,11 +80,10 @@ export function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) { // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab // -export function DefaultStyleProvider(doc: Opt, props: Opt, property: string): any { +export function DefaultStyleProvider(doc: Opt, props: Opt, property: string): any { const remoteDocHeader = 'author;author_date;noMargin'; const docProps = testDocProps(props) ? props : undefined; const fieldProps = testFieldProps(props) ? props : undefined; - const selected = property.includes(':selected'); const isCaption = property.includes(':caption'); const isAnchor = property.includes(':anchor'); const isContent = property.includes(':content'); @@ -138,14 +136,13 @@ export function DefaultStyleProvider(doc: Opt, props: Opt, props: Opt = StrCast(doc?.[fieldKey + 'color'], StrCast(doc?._color)); if (docColor) return docColor; const docView = props?.DocumentView?.(); - const backColor = backgroundCol() || docView?._props.styleProvider?.(docView._props.treeViewDoc, docView._props, StyleProp.BackgroundColor); + const backColor = backgroundCol() || docView?._props.styleProvider?.(docView._props.treeViewDoc, docView.docView?._props, StyleProp.BackgroundColor); return backColor ? lightOrDark(backColor) : undefined; case StyleProp.BorderRounding: return StrCast(doc?.[fieldKey + 'borderRounding'], StrCast(doc?.layout_borderRounding, doc?._type_collection === CollectionViewType.Pile ? '50%' : '')); @@ -373,7 +370,7 @@ export function DashboardToggleButton(doc: Doc, field: string, onIcon: IconProp, /** * add hide button decorations for the "Dashboards" flyout TreeView */ -export function DashboardStyleProvider(doc: Opt, props: Opt, property: string) { +export function DashboardStyleProvider(doc: Opt, props: Opt, property: string) { if (doc && property.split(':')[0] === StyleProp.Decorations) { return doc._type_collection === CollectionViewType.Docking || Doc.IsSystem(doc) ? null diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index b6acf3153..fb57a668e 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -7,10 +7,11 @@ import { Doc, Opt } from '../../../fields/Doc'; import { DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { DragManager } from '../../util/DragManager'; import { StyleProp } from '../StyleProvider'; -import { DocumentView, DocumentViewProps } from '../nodes/DocumentView'; +import { DocumentView, DocumentViewInternalProps, DocumentViewProps } from '../nodes/DocumentView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import './CollectionCarouselView.scss'; import { CollectionSubView } from './CollectionSubView'; +import { FieldViewProps } from '../nodes/FieldView'; @observer export class CollectionCarouselView extends CollectionSubView() { @@ -40,7 +41,7 @@ export class CollectionCarouselView extends CollectionSubView() { e.stopPropagation(); this.layoutDoc._carousel_index = (NumCast(this.layoutDoc._carousel_index) - 1 + this.childLayoutPairs.length) % this.childLayoutPairs.length; }; - captionStyleProvider = (doc: Doc | undefined, captionProps: Opt, property: string): any => { + captionStyleProvider = (doc: Doc | undefined, captionProps: Opt, property: string): any => { // first look for properties on the document in the carousel, then fallback to properties on the container const childValue = doc?.['caption-' + property] ? this.props.styleProvider?.(doc, captionProps, property) : undefined; return childValue ?? this.props.styleProvider?.(this.layoutDoc, captionProps, property); diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx index 0744814dd..527b72213 100644 --- a/src/client/views/collections/CollectionNoteTakingView.tsx +++ b/src/client/views/collections/CollectionNoteTakingView.tsx @@ -18,7 +18,7 @@ import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; import { LightboxView } from '../LightboxView'; -import { DocFocusOptions, DocumentView, DocumentViewProps } from '../nodes/DocumentView'; +import { DocFocusOptions, DocumentView, DocumentViewInternalProps, DocumentViewProps } from '../nodes/DocumentView'; import { FieldViewProps } from '../nodes/FieldView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { StyleProp } from '../StyleProvider'; @@ -195,7 +195,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName('documentView-node')).find((node: any) => node.id === doc[Id]); if (found) { const top = found.getBoundingClientRect().top; - const localTop = this.props.ScreenToLocalTransform().transformPoint(0, top); + const localTop = this.ScreenToLocalBoxXf().transformPoint(0, top); if (Math.floor(localTop[1]) !== 0 && Math.ceil(this.props.PanelHeight()) < (this._mainCont?.scrollHeight || 0)) { let focusSpeed = options.zoomTime ?? 500; smoothScroll(focusSpeed, this._mainCont!, localTop[1] + this._mainCont!.scrollTop, options.easeFunc); @@ -204,7 +204,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { } }; - styleProvider = (doc: Doc | undefined, props: Opt, property: string) => { + styleProvider = (doc: Doc | undefined, props: Opt, property: string) => { switch (property) { case StyleProp.BoxShadow: if (doc && DragManager.docsBeingDragged.includes(doc)) { @@ -282,7 +282,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { const y = this._scroll; // required for document decorations to update when the text box container is scrolled const { translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv || undefined); // the document view may center its contents and if so, will prepend that onto the screenToLocalTansform. so we have to subtract that off - return new Transform(-translateX + (dref?.centeringX || 0), -translateY + (dref?.centeringY || 0), 1).scale(this.props.ScreenToLocalTransform().Scale); + return new Transform(-translateX + (dref?.centeringX || 0), -translateY + (dref?.centeringY || 0), 1).scale(this.ScreenToLocalBoxXf().Scale); } // how to get the width of a document. Currently returns the width of the column (minus margins) @@ -341,10 +341,10 @@ export class CollectionNoteTakingView extends CollectionSubView() { onPointerMove = (force: boolean, ex: number, ey: number) => { if (this.childDocList?.includes(DragManager.DocDragData?.draggedDocuments?.lastElement() as any) || force || SnappingManager.CanEmbed) { // get the current docs for the column based on the mouse's x coordinate - const xCoord = this.props.ScreenToLocalTransform().transformPoint(ex, ey)[0] - 2 * this.gridGap; + const xCoord = this.ScreenToLocalBoxXf().transformPoint(ex, ey)[0] - 2 * this.gridGap; const colDocs = this.getDocsFromXCoord(xCoord); // get the index for where you need to insert the doc you are currently dragging - const clientY = this.props.ScreenToLocalTransform().transformPoint(ex, ey)[1]; + const clientY = this.ScreenToLocalBoxXf().transformPoint(ex, ey)[1]; let dropInd = -1; let pos0 = (this.refList.lastElement() as HTMLDivElement).children[0].getBoundingClientRect().height + this.yMargin * 2; colDocs.forEach((doc, i) => { @@ -437,7 +437,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { if (rowCol[0] <= 0) { docs.splice(0, 0, ...newDocs); } else { - const colDocs = this.getDocsFromXCoord(this.props.ScreenToLocalTransform().transformPoint(de.x, de.y)[0]); + const colDocs = this.getDocsFromXCoord(this.ScreenToLocalBoxXf().transformPoint(de.x, de.y)[0]); const previousDoc = colDocs[rowCol[0] - 1]; const previousDocIndex = docs.indexOf(previousDoc); docs.splice(previousDocIndex + 1, 0, ...newDocs); @@ -546,7 +546,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { yMargin={this.yMargin} type={type} createDropTarget={this.createDashEventsTarget} - screenToLocalTransform={this.props.ScreenToLocalTransform} + screenToLocalTransform={this.ScreenToLocalBoxXf} editableViewProps={this.editableViewProps} /> ); @@ -586,7 +586,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { // setColumnStartXCoords is used to update column widths when using the drag handlers between columns @action setColumnStartXCoords = (movementXScreen: number, colIndex: number) => { - const movementX = this.props.ScreenToLocalTransform().transformDirection(movementXScreen, 0)[0]; + const movementX = this.ScreenToLocalBoxXf().transformDirection(movementXScreen, 0)[0]; const leftHeader = this.colHeaderData[colIndex]; const rightHeader = this.colHeaderData[colIndex + 1]; leftHeader.setWidth(leftHeader.width + movementX / this.availableWidth); diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index a63688354..d99b4f9de 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -23,11 +23,12 @@ import { undoBatch, UndoManager } from '../../util/UndoManager'; import { CollectionSubView } from '../collections/CollectionSubView'; import { LightboxView } from '../LightboxView'; import { AudioWaveform } from '../nodes/audio/AudioWaveform'; -import { DocFocusFunc, DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere } from '../nodes/DocumentView'; +import { DocFocusFunc, DocFocusOptions, DocumentView, DocumentViewInternalProps, DocumentViewProps, OpenWhere, StyleProviderFunc } from '../nodes/DocumentView'; import { LabelBox } from '../nodes/LabelBox'; import { VideoBox } from '../nodes/VideoBox'; import { ObservableReactComponent } from '../ObservableReactComponent'; import './CollectionStackedTimeline.scss'; +import { FieldViewProps } from '../nodes/FieldView'; export type CollectionStackedTimelineProps = { Play: () => void; @@ -367,7 +368,7 @@ export class CollectionStackedTimeline extends CollectionSubView { @@ -502,7 +503,7 @@ export class CollectionStackedTimeline extends CollectionSubView this._props.ScreenToLocalTransform().translate(0, -this.timelineContentHeight); + dictationScreenToLocalTransform = () => this.ScreenToLocalBoxXf().translate(0, -this.timelineContentHeight); isContentActive = () => this._props.isSelected() || this._props.isContentActive(); @@ -672,7 +673,7 @@ interface StackedTimelineAnchorProps { width: number; height: number; toTimeline: (screen_delta: number, width: number) => number; - styleProvider?: (doc: Opt, props: Opt, property: string) => any; + styleProvider?: StyleProviderFunc; playLink: (linkDoc: Doc, options: DocFocusOptions) => void; setTime: (time: number) => void; startTag: string; @@ -695,7 +696,7 @@ class StackedTimelineAnchor extends ObservableReactComponent node.id === doc[Id]); if (found) { const top = found.getBoundingClientRect().top; - const localTop = this._props.ScreenToLocalTransform().transformPoint(0, top); + const localTop = this.ScreenToLocalBoxXf().transformPoint(0, top); if (Math.floor(localTop[1]) !== 0) { let focusSpeed = options.zoomTime ?? 500; smoothScroll(focusSpeed, this._mainCont!, localTop[1] + this._mainCont!.scrollTop, options.easeFunc); @@ -265,7 +265,7 @@ export class CollectionStackingView extends CollectionSubView, property: string) => { + styleProvider = (doc: Doc | undefined, props: Opt, property: string) => { if (property === StyleProp.Opacity && doc) { if (this._props.childOpacity) { return this._props.childOpacity(); @@ -370,7 +370,7 @@ export class CollectionStackingView extends CollectionSubView ); }; @@ -611,7 +611,7 @@ export class CollectionStackingView extends CollectionSubView ); diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index 7bbdb7073..7036ec41c 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -211,7 +211,6 @@ export class CollectionTimeView extends CollectionSubView() { Array.from(keySet).map(fieldKey => docItems.push({ description: ':' + fieldKey, event: () => (this.layoutDoc._pivotField = fieldKey), icon: 'compress-arrows-alt' })); docItems.push({ description: ':default', event: () => (this.layoutDoc._pivotField = undefined), icon: 'compress-arrows-alt' }); ContextMenu.Instance.addItem({ description: 'Pivot Fields ...', subitems: docItems, icon: 'eye' }); - const pt = this._props.ScreenToLocalTransform().inverse().transformPoint(x, y); ContextMenu.Instance.displayMenu(x, y, ':'); }; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 7f8d42088..18e0b98ef 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -154,7 +154,7 @@ export class CollectionTreeView extends CollectionSubView this._props.ScreenToLocalTransform().translate(0, -this._headerHeight); + screenToLocalTransform = () => this.ScreenToLocalBoxXf().translate(0, -this._headerHeight); @action remove = (doc: Doc | Doc[]): boolean => { @@ -312,7 +312,7 @@ export class CollectionTreeView extends CollectionSubView (this._titleRef = r) && (this._titleHeight = r.getBoundingClientRect().height * this._props.ScreenToLocalTransform().Scale))} + ref={action((r: any) => (this._titleRef = r) && (this._titleHeight = r.getBoundingClientRect().height * this.ScreenToLocalBoxXf().Scale))} key={this.Document[Id]} style={!this.outlineMode ? { marginLeft: this.marginX(), paddingTop: this.marginTop() } : {}}> {this.outlineMode ? this.documentTitle : this.editableTitle} diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index c2f5ab2c0..4a239e4b1 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -112,7 +112,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent (this._props.renderDepth ? this._props.ScreenToLocalTransform() : this._props.ScreenToLocalTransform().scale(this._props.PanelWidth() / this.bodyPanelWidth())); + screenToLocalTransform = () => (this._props.renderDepth ? this.ScreenToLocalBoxXf() : this.ScreenToLocalBoxXf().scale(this._props.PanelWidth() / this.bodyPanelWidth())); // prettier-ignore private renderSubView = (type: CollectionViewType | undefined, props: SubCollectionViewProps) => { TraceMobx(); diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index ac0ce7a2a..80808be92 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -29,7 +29,7 @@ import { LightboxView } from '../LightboxView'; import { ObservableReactComponent } from '../ObservableReactComponent'; import { DefaultStyleProvider, StyleProp } from '../StyleProvider'; import { Colors } from '../global/globalEnums'; -import { DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere, OpenWhereMod } from '../nodes/DocumentView'; +import { DocFocusOptions, DocumentView, DocumentViewInternalProps, DocumentViewProps, OpenWhere, OpenWhereMod } from '../nodes/DocumentView'; import { KeyValueBox } from '../nodes/KeyValueBox'; import { DashFieldView } from '../nodes/formattedText/DashFieldView'; import { PinProps, PresBox, PresMovement } from '../nodes/trails'; @@ -37,6 +37,7 @@ import { CollectionDockingView } from './CollectionDockingView'; import { CollectionView } from './CollectionView'; import './TabDocView.scss'; import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; +import { FieldViewProps } from '../nodes/FieldView'; const _global = (window /* browser */ || global) /* node */ as any; interface TabDocViewProps { @@ -426,7 +427,7 @@ export class TabDocView extends ObservableReactComponent { ScreenToLocalTransform = () => { this._forceInvalidateScreenToLocal; const { translateX, translateY } = Utils.GetScreenTransform(this._mainCont?.children?.[0] as HTMLElement); - return CollectionDockingView.Instance?._props.ScreenToLocalTransform().translate(-translateX, -translateY) ?? Transform.Identity(); + return CollectionDockingView.Instance?.ScreenToLocalBoxXf().translate(-translateX, -translateY) ?? Transform.Identity(); }; PanelWidth = () => this._panelWidth; PanelHeight = () => this._panelHeight; @@ -527,7 +528,7 @@ class TabMiniThumb extends React.Component { } @observer export class TabMinimapView extends ObservableReactComponent { - static miniStyleProvider = (doc: Opt, props: Opt, property: string): any => { + static miniStyleProvider = (doc: Opt, props: Opt, property: string): any => { if (doc) { switch (property.split(':')[0]) { default: diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index f2ceaa681..01b80e209 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -27,7 +27,7 @@ import { UndoManager, undoBatch, undoable } from '../../util/UndoManager'; import { EditableView } from '../EditableView'; import { ObservableReactComponent } from '../ObservableReactComponent'; import { StyleProp } from '../StyleProvider'; -import { DocumentView, DocumentViewInternal, DocumentViewProps, OpenWhere, StyleProviderFunc } from '../nodes/DocumentView'; +import { DocumentView, DocumentViewInternal, DocumentViewInternalProps, DocumentViewProps, OpenWhere, StyleProviderFunc } from '../nodes/DocumentView'; import { FieldViewProps } from '../nodes/FieldView'; import { KeyValueBox } from '../nodes/KeyValueBox'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; @@ -172,6 +172,8 @@ export class TreeView extends ObservableReactComponent { return this._docRef?.IsSelected; } + ScreenToLocalTransform = () => this._props.ScreenToLocalTransform(); + childDocList(field: string) { const layout = Cast(Doc.LayoutField(this.Document), Doc, null); return DocListCast(this._props.dataDoc?.[field], DocListCast(layout?.[field], DocListCast(this.Document[field]))); @@ -447,11 +449,11 @@ export class TreeView extends ObservableReactComponent { } refTransform = (ref: HTMLDivElement | undefined | null) => { - if (!ref) return this._props.ScreenToLocalTransform(); + if (!ref) return this.ScreenToLocalTransform(); const { scale, translateX, translateY } = Utils.GetScreenTransform(ref); const outerXf = Utils.GetScreenTransform(this.treeView.MainEle()); - const offset = this._props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY); - return this._props.ScreenToLocalTransform().translate(offset[0], offset[1]); + const offset = this.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY); + return this.ScreenToLocalTransform().translate(offset[0], offset[1]); }; docTransform = () => this.refTransform(this._dref?.ContentRef?.current); getTransform = () => this.refTransform(this._tref.current); @@ -511,7 +513,7 @@ export class TreeView extends ObservableReactComponent { this._props.dragAction, this._props.addDocTab, this.titleStyleProvider, - this._props.ScreenToLocalTransform, + this.ScreenToLocalTransform, this._props.isContentActive, expandedWidth, this._props.renderDepth, @@ -671,7 +673,7 @@ export class TreeView extends ObservableReactComponent { StrCast(this.Document.childDragAction, this._props.dragAction) as dropActionType, this._props.addDocTab, this.titleStyleProvider, - this._props.ScreenToLocalTransform, + this.ScreenToLocalTransform, this._props.isContentActive, this._props.panelWidth, this._props.renderDepth, @@ -865,7 +867,7 @@ export class TreeView extends ObservableReactComponent { e.preventDefault(); } }; - titleStyleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { + titleStyleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { if (!doc || doc !== this.Document) return this._props?.treeView?._props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView const treeView = this.treeView; @@ -897,7 +899,7 @@ export class TreeView extends ObservableReactComponent { } return treeView._props.styleProvider?.(doc, props, property); }; - embeddedStyleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { + embeddedStyleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { if (property.startsWith(StyleProp.Decorations)) return null; return this._props?.treeView?._props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView }; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 6131fe037..5204633ea 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -22,8 +22,6 @@ export interface CollectionFreeFormLinkViewProps { LinkDocs: Doc[]; } -// props.screentolocatransform - @observer export class CollectionFreeFormLinkView extends ObservableReactComponent { @observable _opacity: number = 0; @@ -42,10 +40,10 @@ export class CollectionFreeFormLinkView extends ObservableReactComponent [ - this._props.A._props.ScreenToLocalTransform(), + this._props.A.screenToViewTransform(), Cast(Cast(Cast(this._props.A.Document, Doc, null)?.link_anchor_1, Doc, null)?.annotationOn, Doc, null)?.layout_scrollTop, Cast(Cast(Cast(this._props.A.Document, Doc, null)?.link_anchor_1, Doc, null)?.annotationOn, Doc, null)?.[DocCss], - this._props.B._props.ScreenToLocalTransform(), + this._props.B.screenToViewTransform(), Cast(Cast(Cast(this._props.A.Document, Doc, null)?.link_anchor_2, Doc, null)?.annotationOn, Doc, null)?.layout_scrollTop, Cast(Cast(Cast(this._props.A.Document, Doc, null)?.link_anchor_2, Doc, null)?.annotationOn, Doc, null)?.[DocCss], ], @@ -91,7 +89,7 @@ export class CollectionFreeFormLinkView extends ObservableReactComponent= 0 && mpx <= 1) linkDoc.link_anchor_1_x = mpx * 100; @@ -106,7 +104,7 @@ export class CollectionFreeFormLinkView extends ObservableReactComponent= 0 && mpx <= 1) linkDoc.link_anchor_2_x = mpx * 100; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 44654c8fe..0128647a4 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -38,7 +38,7 @@ import { ActiveInkWidth, InkingStroke, SetActiveInkColor, SetActiveInkWidth } fr import { LightboxView } from '../../LightboxView'; import { CollectionFreeFormDocumentView, CollectionFreeFormDocumentViewWrapper } from '../../nodes/CollectionFreeFormDocumentView'; import { SchemaCSVPopUp } from '../../nodes/DataVizBox/SchemaCSVPopUp'; -import { DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere } from '../../nodes/DocumentView'; +import { DocFocusOptions, DocumentView, DocumentViewInternalProps, DocumentViewProps, OpenWhere } from '../../nodes/DocumentView'; import { FieldViewProps } from '../../nodes/FieldView'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { PinProps, PresBox } from '../../nodes/trails/PresBox'; @@ -172,10 +172,9 @@ export class CollectionFreeFormView extends CollectionSubView this.freeformData()?.scale ?? NumCast(Doc.Layout(this.Document)[this.scaleFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.[this.scaleFieldKey], 1)); PanZoomCenterXf = () => this._props.isAnnotationOverlay && this.zoomScaling() === 1 ? `` : `translate(${this.cachedCenteringShiftX}px, ${this.cachedCenteringShiftY}px) scale(${this.zoomScaling()}) translate(${-this.panX()}px, ${-this.panY()}px)`; - ScreenToLocalXf = () => this.screenToLocalXf.copy(); + ScreenToContentsXf = () => this.screenToFreeformContentsXf.copy(); getActiveDocuments = () => this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => pair.layout); isAnyChildContentActive = () => this._props.isAnyChildContentActive(); addLiveTextBox = (newDoc: Doc) => { @@ -329,13 +328,13 @@ export class CollectionFreeFormView extends CollectionSubView res(dv)); }); - internalDocDrop(e: Event, de: DragManager.DropEvent, docDragData: DragManager.DocumentDragData, xp: number, yp: number) { + internalDocDrop(e: Event, de: DragManager.DropEvent, docDragData: DragManager.DocumentDragData) { if (!super.onInternalDrop(e, de)) return false; const refDoc = docDragData.droppedDocuments[0]; - const [xpo, ypo] = this._props.ScreenToLocalTransform().transformPoint(de.x, de.y); - const z = NumCast(refDoc.z); - const x = (z ? xpo : xp) - docDragData.offset[0]; - const y = (z ? ypo : yp) - docDragData.offset[1]; + const fromScreenXf = NumCast(refDoc.z) ? this.ScreenToLocalBoxXf() : this.screenToFreeformContentsXf; + const [xpo, ypo] = fromScreenXf.transformPoint(de.x, de.y); + const x = xpo - docDragData.offset[0]; + const y = ypo - docDragData.offset[1]; const zsorted = this.childLayoutPairs .map(pair => pair.layout) .slice() @@ -347,7 +346,7 @@ export class CollectionFreeFormView extends CollectionSubView { const dropDoc = dropCreator(annotationOn); if (dropDoc) { @@ -408,20 +408,21 @@ export class CollectionFreeFormView extends CollectionSubView { - const [xp, yp] = this.screenToLocalXf.transformPoint(de.x, de.y); - if (de.complete.annoDragData?.dragDocument && super.onInternalDrop(e, de)) return this.internalAnchorAnnoDrop(e, de.complete.annoDragData, xp, yp); - else if (de.complete.linkDragData) return this.internalLinkDrop(e, de, de.complete.linkDragData, xp, yp); - else if (de.complete.docDragData?.droppedDocuments.length) return this.internalDocDrop(e, de, de.complete.docDragData, xp, yp); + if (de.complete.annoDragData?.dragDocument && super.onInternalDrop(e, de)) return this.internalAnchorAnnoDrop(e, de, de.complete.annoDragData); + else if (de.complete.linkDragData) return this.internalLinkDrop(e, de, de.complete.linkDragData); + else if (de.complete.docDragData?.droppedDocuments.length) return this.internalDocDrop(e, de, de.complete.docDragData); return false; }; - onExternalDrop = (e: React.DragEvent) => (([x, y]) => super.onExternalDrop(e, { x, y }))(this.screenToLocalXf.transformPoint(e.pageX, e.pageY)); + onExternalDrop = (e: React.DragEvent) => (([x, y]) => super.onExternalDrop(e, { x, y }))(this.screenToFreeformContentsXf.transformPoint(e.pageX, e.pageY)); static overlapping(doc1: Doc, doc2: Doc, clusterDistance: number) { const doc2Layout = Doc.Layout(doc2); @@ -489,7 +489,7 @@ export class CollectionFreeFormView extends CollectionSubView v.ContentDiv!), de, @@ -586,7 +586,7 @@ export class CollectionFreeFormView extends CollectionSubView, props: Opt, property: string) => { + clusterStyleProvider = (doc: Opt, props: Opt, property: string) => { let styleProp = this._props.styleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1 if (doc && this.childDocList?.includes(doc)) switch (property) { @@ -643,7 +643,7 @@ export class CollectionFreeFormView extends CollectionSubView 0 ? 1 / 1.05 : 1.05; if (deltaScale < 0) deltaScale = -deltaScale; - const [x, y] = this.screenToLocalXf.transformPoint(pointX, pointY); + const [x, y] = this.screenToFreeformContentsXf.transformPoint(pointX, pointY); const invTransform = this.panZoomXf.inverse(); if (deltaScale * invTransform.Scale > 20) { deltaScale = 20 / invTransform.Scale; @@ -982,7 +982,7 @@ export class CollectionFreeFormView extends CollectionSubView { - const pt = this.screenToLocalXf.transformPoint(NumCast(doc.x), NumCast(doc.y)); + const pt = this.screenToFreeformContentsXf.transformPoint(NumCast(doc.x), NumCast(doc.y)); doc.x = pt[0]; doc.y = pt[1]; return doc; @@ -1437,7 +1437,7 @@ export class CollectionFreeFormView extends CollectionSubView (this._hideInfo = true); - infoUI = () => (this._hideInfo || this.Document.annotationOn ? null : ); + infoUI = () => (this._hideInfo || this.Document.annotationOn || this._props.renderDepth ? null : ); componentDidMount() { this._props.setContentView?.(this); @@ -1601,7 +1601,7 @@ export class CollectionFreeFormView extends CollectionSubView { const childDocs = this.childDocs.slice(); childDocs.forEach(doc => { - const scr = this.screenToLocalXf.inverse().transformPoint(NumCast(doc.x), NumCast(doc.y)); + const scr = this.screenToFreeformContentsXf.inverse().transformPoint(NumCast(doc.x), NumCast(doc.y)); doc.x = scr?.[0]; doc.y = scr?.[1]; }); @@ -1713,7 +1713,7 @@ export class CollectionFreeFormView extends CollectionSubView ({ left: NumCast(doc.x), top: NumCast(doc.y), width: NumCast(doc._width), height: NumCast(doc._height) }); const isDocInView = (doc: Doc, rect: { left: number; top: number; width: number; height: number }) => intersectRect(docDims(doc), rect); @@ -1725,7 +1725,7 @@ export class CollectionFreeFormView extends CollectionSubView !doc.isGroup && (snapToDraggedDoc || (SnappingManager.IsResizing !== doc && !DragManager.docsBeingDragged.includes(doc)))) .forEach(doc => { @@ -1822,8 +1822,8 @@ export class CollectionFreeFormView extends CollectionSubView @@ -1859,7 +1859,7 @@ export class CollectionFreeFormView extends CollectionSubView Math.max(0, this._props.PanelWidth() - 30); lightboxPanelHeight = () => Math.max(0, this._props.PanelHeight() - 30); - lightboxScreenToLocal = () => this._props.ScreenToLocalTransform().translate(-15, -15); + lightboxScreenToLocal = () => this.ScreenToLocalBoxXf().translate(-15, -15); onPassiveWheel = (e: WheelEvent) => { const docHeight = NumCast(this.Document[Doc.LayoutFieldKey(this.Document) + '_nativeHeight'], this.nativeHeight); const scrollable = NumCast(this.layoutDoc[this.scaleFieldKey], 1) === 1 && docHeight > this._props.PanelHeight() / this.nativeDimScaling; @@ -1950,7 +1950,7 @@ export function CollectionBrowseClick(dv: DocumentView, clientX: number, clientY } while (parFfview?.Document.isGroup) parFfview = parFfview.props.DocumentView?.().CollectionFreeFormView; const ffview = selfFfview && selfFfview.layoutDoc[selfFfview.scaleFieldKey] !== 0.5 ? selfFfview : parFfview; // if focus doc is a freeform that is not at it's default 0.5 scale, then zoom out on it. Otherwise, zoom out on the parent ffview - ffview?.zoomSmoothlyAboutPt(ffview.screenToLocalXf.transformPoint(clientX, clientY), ffview?.isAnnotationOverlay ? 1 : 0.5, browseTransitionTime); + ffview?.zoomSmoothlyAboutPt(ffview.screenToFreeformContentsXf.transformPoint(clientX, clientY), ffview?.isAnnotationOverlay ? 1 : 0.5, browseTransitionTime); Doc.linkFollowHighlight(dv?.props.Document, false); } }); diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index 0f750c4f8..d078e1d4f 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -130,7 +130,7 @@ export class CollectionGridView extends CollectionSubView() { * Maps the x- and y- coordinates of the event to a grid cell. */ screenToCell(sx: number, sy: number) { - const pt = this._props.ScreenToLocalTransform().transformPoint(sx, sy); + const pt = this.ScreenToLocalBoxXf().transformPoint(sx, sy); const x = Math.floor(pt[0] / this.colWidthPlusGap); const y = Math.floor((pt[1] + this._scroll) / this.rowHeight); return { x, y }; @@ -159,7 +159,7 @@ export class CollectionGridView extends CollectionSubView() { const xypos = this.flexGrid ? layout : this.unflexedPosition(this.renderedLayoutList.findIndex(l => l.i === layout.i)); const pos = { x: xypos.x * this.colWidthPlusGap + this.margin, y: xypos.y * this.rowHeightPlusGap + this.margin - this._scroll }; - return this._props.ScreenToLocalTransform().translate(-pos.x, -pos.y); + return this.ScreenToLocalBoxXf().translate(-pos.x, -pos.y); }; /** @@ -390,7 +390,7 @@ export class CollectionGridView extends CollectionSubView() { numCols={this.numCols} rowHeight={this.rowHeight} setLayout={this.setLayout} - transformScale={this._props.ScreenToLocalTransform().Scale} + transformScale={this.ScreenToLocalBoxXf().Scale} compactType={this.compaction} // determines whether nodes should remain in position, be bound to the top, or to the left preventCollision={BoolCast(this.Document.gridPreventCollision)} // determines whether nodes should move out of the way (i.e. collide) when other nodes are dragged over them margin={this.margin} diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 5bea59e7b..563084af8 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -189,7 +189,7 @@ export class CollectionMulticolumnView extends CollectionSubView() { let offset = 0; for (const { layout: candidate } of this.childLayoutPairs) { if (candidate === layout) { - return this._props.ScreenToLocalTransform().translate(-offset / (this._props.NativeDimScaling?.() || 1), 0); + return this.ScreenToLocalBoxXf().translate(-offset / (this._props.NativeDimScaling?.() || 1), 0); } offset += this.lookupPixels(candidate) + resizerWidth; } diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 3043eb0f8..bf0d39197 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -184,7 +184,7 @@ export class CollectionMultirowView extends CollectionSubView() { let offset = 0; for (const { layout: candidate } of this.childLayoutPairs) { if (candidate === layout) { - return this._props.ScreenToLocalTransform().translate(0, -offset / (this._props.NativeDimScaling?.() || 1)); + return this.ScreenToLocalBoxXf().translate(0, -offset / (this._props.NativeDimScaling?.() || 1)); } offset += this.lookupPixels(candidate) + resizerHeight; } diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 2546f5b02..492aed0ea 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -16,7 +16,7 @@ import { undoable, undoBatch } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; import { EditableView } from '../../EditableView'; import { Colors } from '../../global/globalEnums'; -import { DocFocusOptions, DocumentView, DocumentViewProps } from '../../nodes/DocumentView'; +import { DocFocusOptions, DocumentView, DocumentViewInternalProps, DocumentViewProps } from '../../nodes/DocumentView'; import { KeyValueBox } from '../../nodes/KeyValueBox'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DefaultStyleProvider, StyleProp } from '../../StyleProvider'; @@ -24,6 +24,7 @@ import { CollectionSubView } from '../CollectionSubView'; import './CollectionSchemaView.scss'; import { SchemaColumnHeader } from './SchemaColumnHeader'; import { SchemaRowBox } from './SchemaRowBox'; +import { FieldViewProps } from '../../nodes/FieldView'; export enum ColumnType { Number, @@ -321,8 +322,8 @@ export class CollectionSchemaView extends CollectionSubView() { change = this._displayColumnWidths[shrinking] - CollectionSchemaView._minColWidth; } - this._displayColumnWidths[shrinking] -= change * this._props.ScreenToLocalTransform().Scale; - this._displayColumnWidths[growing] += change * this._props.ScreenToLocalTransform().Scale; + this._displayColumnWidths[shrinking] -= change * this.ScreenToLocalBoxXf().Scale; + this._displayColumnWidths[growing] += change * this.ScreenToLocalBoxXf().Scale; return false; } @@ -379,7 +380,7 @@ export class CollectionSchemaView extends CollectionSubView() { @action highlightDropColumn = (e: PointerEvent) => { e.stopPropagation(); - const mouseX = this._props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0]; + const mouseX = this.ScreenToLocalBoxXf().transformPoint(e.clientX, e.clientY)[0]; const index = this.findDropIndex(mouseX); this._colEles.forEach((colRef, i) => { let leftStyle = ''; @@ -439,7 +440,7 @@ export class CollectionSchemaView extends CollectionSubView() { onInternalDrop = (e: Event, de: DragManager.DropEvent) => { if (de.complete.columnDragData) { - const mouseX = this._props.ScreenToLocalTransform().transformPoint(de.x, de.y)[0]; + const mouseX = this.ScreenToLocalBoxXf().transformPoint(de.x, de.y)[0]; const index = this.findDropIndex(mouseX); this.moveColumn(de.complete.columnDragData.colIndex, index ?? de.complete.columnDragData.colIndex); @@ -483,7 +484,7 @@ export class CollectionSchemaView extends CollectionSubView() { const nativeWidth = this._previewRef!.getBoundingClientRect(); const minWidth = 40; const maxWidth = 1000; - const movedWidth = this._props.ScreenToLocalTransform().transformDirection(nativeWidth.right - e.clientX, 0)[0]; + const movedWidth = this.ScreenToLocalBoxXf().transformDirection(nativeWidth.right - e.clientX, 0)[0]; const width = movedWidth < minWidth ? minWidth : movedWidth > maxWidth ? maxWidth : movedWidth; this.layoutDoc.schema_previewWidth = width; return false; @@ -507,7 +508,7 @@ export class CollectionSchemaView extends CollectionSubView() { const found = this._tableContentRef && Array.from(this._tableContentRef.getElementsByClassName('documentView-node')).find((node: any) => node.id === doc[Id]); if (found) { const rect = found.getBoundingClientRect(); - const localRect = this._props.ScreenToLocalTransform().transformBounds(rect.left, rect.top, rect.width, rect.height); + const localRect = this.ScreenToLocalBoxXf().transformBounds(rect.left, rect.top, rect.width, rect.height); if (localRect.y < this.rowHeightFunc() || localRect.y + localRect.height > this._props.PanelHeight()) { let focusSpeed = options.zoomTime ?? 50; smoothScroll(focusSpeed, this._tableContentRef!, localRect.y + this._tableContentRef!.scrollTop - this.rowHeightFunc(), options.easeFunc); @@ -829,7 +830,7 @@ export class CollectionSchemaView extends CollectionSubView() { rowHeightFunc = () => (BoolCast(this.layoutDoc._schema_singleLine) ? CollectionSchemaView._rowSingleLineHeight : CollectionSchemaView._rowHeight); sortedDocsFunc = () => this.sortedDocs; isContentActive = () => this._props.isSelected() || this._props.isContentActive(); - screenToLocal = () => this._props.ScreenToLocalTransform().translate(-this.tableWidth, 0); + screenToLocal = () => this.ScreenToLocalBoxXf().translate(-this.tableWidth, 0); previewWidthFunc = () => this.previewWidth; render() { return ( @@ -960,8 +961,8 @@ class CollectionSchemaViewDoc extends ObservableReactComponent this._props.schema.tableWidth; - screenToLocalXf = () => this._props.schema._props.ScreenToLocalTransform().translate(0, -this._props.rowHeight() - this._props.index * this._props.rowHeight()); - noOpacityStyleProvider = (doc: Opt, props: Opt, property: string) => { + screenToLocalXf = () => this._props.schema.ScreenToLocalBoxXf().translate(0, -this._props.rowHeight() - this._props.index * this._props.rowHeight()); + noOpacityStyleProvider = (doc: Opt, props: Opt, property: string) => { if (property === StyleProp.Opacity) return 1; return DefaultStyleProvider(doc, props, property); }; diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 567cf193e..908cd5dc0 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -460,7 +460,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent() { @action timelineWhenChildContentsActiveChanged = (isActive: boolean) => this._props.whenChildContentsActiveChanged((this._isAnyChildContentActive = isActive)); - timelineScreenToLocal = () => this._props.ScreenToLocalTransform().translate(0, -AudioBox.topControlsHeight); + timelineScreenToLocal = () => this.ScreenToLocalBoxXf().translate(0, -AudioBox.topControlsHeight); setPlayheadTime = (time: number) => (this._ele!.currentTime /*= this.layoutDoc._layout_currentTimecode*/ = time); @@ -564,7 +564,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent() { this._dropDisposer = DragManager.MakeDropTarget( r, (e, de) => { - const [xp, yp] = this._props.ScreenToLocalTransform().transformPoint(de.x, de.y); + const [xp, yp] = this.ScreenToLocalBoxXf().transformPoint(de.x, de.y); de.complete.docDragData && this.timeline?.internalDocDrop(e, de, de.complete.docDragData, xp); }, this.layoutDoc, diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 324a4b8d1..ad5aabc21 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -15,7 +15,8 @@ import { DocComponent } from '../DocComponent'; import { StyleProp } from '../StyleProvider'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import './CollectionFreeFormDocumentView.scss'; -import { DocumentView, DocumentViewProps, OpenWhere } from './DocumentView'; +import { DocumentView, DocumentViewInternalProps, DocumentViewProps, OpenWhere } from './DocumentView'; +import { FieldViewProps } from './FieldView'; export interface CollectionFreeFormDocumentViewWrapperProps extends DocumentViewProps { x: number; @@ -148,7 +149,7 @@ export class CollectionFreeFormDocumentView extends DocComponent, property: string) => { + styleProvider = (doc: Doc | undefined, props: Opt, property: string) => { if (doc === this.layoutDoc) { switch (property) { case StyleProp.Opacity: return this._props.w_Opacity(); // only change the opacity for this specific document, not its children @@ -229,7 +230,7 @@ export class CollectionFreeFormDocumentView extends DocComponent { const topDoc = this.Document; const containerDocView = this._props.docViewPath().lastElement(); - const screenXf = containerDocView?.screenToNativeLocalTransform(); + const screenXf = containerDocView?.screenToContentsTransform(); if (screenXf) { SelectionManager.DeselectAll(); if (topDoc.z) { @@ -251,7 +252,7 @@ export class CollectionFreeFormDocumentView extends DocComponent { - const [locX, locY] = this._props.ScreenToLocalTransform().transformDirection(x, y); + const [locX, locY] = this.ScreenToLocalBoxXf().transformDirection(x, y); this._props.Document.x = this._props.w_X() + locX; this._props.Document.y = this._props.w_Y() + locY; }; diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index de382fca5..5e7e568b0 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -11,7 +11,7 @@ import { undoBatch } from '../../util/UndoManager'; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent'; import { StyleProp } from '../StyleProvider'; import './ComparisonBox.scss'; -import { DocumentView, DocumentViewProps } from './DocumentView'; +import { DocumentView, DocumentViewInternalProps, DocumentViewProps } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import { PinProps, PresBox } from './trails'; @@ -88,7 +88,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent { - const width = movementX * this._props.ScreenToLocalTransform().Scale + (this.clipWidth / 100) * this._props.PanelWidth(); + const width = movementX * this.ScreenToLocalBoxXf().Scale + (this.clipWidth / 100) * this._props.PanelWidth(); if (width && width > 5 && width < this._props.PanelWidth()) { this.layoutDoc[this.clipWidthKey] = (width * 100) / this._props.PanelWidth(); } @@ -148,7 +148,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent this.clearDoc(which) ); }; - docStyleProvider = (doc: Opt, props: Opt, property: string): any => { + docStyleProvider = (doc: Opt, props: Opt, property: string): any => { if (property === StyleProp.PointerEvents) return 'none'; return this._props.styleProvider?.(doc, props, property); }; diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx index 5365fe1b2..ed44d9269 100644 --- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx +++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx @@ -80,7 +80,7 @@ export class TableBox extends ObservableReactComponent { }; @computed get viewScale() { - return this._props.docView?.()?._props.ScreenToLocalTransform().Scale || 1; + return this._props.docView?.()?.screenToViewTransform().Scale || 1; } @computed get rowHeight() { console.log('scale = ' + this.viewScale + ' table = ' + this._tableHeight + ' ids = ' + this._tableDataIds.length); diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 165057d21..c549a146a 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -257,7 +257,7 @@ export class DocumentLinksButton extends ObservableReactComponent Opt; -export type StyleProviderFunc = (doc: Opt, props: Opt, property: string) => any; +export type StyleProviderFunc = (doc: Opt, props: Opt, property: string) => any; export interface DocComponentView { fieldKey?: string; annotationKey?: string; @@ -394,11 +394,9 @@ export class DocumentViewInternal extends DocComponent dv.docView?._mainCont.current); const selected = views.length > 1 && views.some(dv => dv.Document === this.Document) ? views : [this._props.DocumentView()]; const dragData = new DragManager.DocumentDragData(selected.map(dv => dv.Document)); - const [left, top] = this._props.ScreenToLocalTransform().scale(this.NativeDimScaling).inverse().transformPoint(0, 0); - dragData.offset = this._props - .ScreenToLocalTransform() - .scale(this.NativeDimScaling) - .transformDirection(x - left, y - top); + const screenXf = this.props.DocumentView().screenToViewTransform(); + const [left, top] = screenXf.inverse().transformPoint(0, 0); + dragData.offset = screenXf.transformDirection(x - left, y - top); dragData.dropAction = dropAction; dragData.treeViewDoc = this._props.treeViewDoc; dragData.removeDocument = this._props.removeDocument; @@ -881,7 +879,7 @@ export class DocumentViewInternal extends DocComponent this._rootSelected; panelHeight = () => this._props.PanelHeight() - this.headerMargin; - contentScreenToLocal = () => this._props.ScreenToLocalTransform().translate(0, -this.headerMargin); + screenToLocalContent = () => this.ScreenToLocalBoxXf().translate(0, -this.headerMargin); onClickFunc: any = () => (this.disableClickScriptFunc ? undefined : this.onClickHandler); setHeight = (height: number) => !this._props.suppressSetHeight && (this.layoutDoc._height = height); setContentView = action((view: { getAnchor?: (addAsAnnotation: boolean) => Doc; forward?: () => boolean; back?: () => boolean }) => (this._componentView = view)); @@ -925,7 +923,7 @@ export class DocumentViewInternal extends DocComponent this._props.PanelWidth() || 1; anchorPanelHeight = () => this._props.PanelHeight() || 1; - anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { + anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { // prettier-ignore switch (property.split(':')[0]) { case StyleProp.ShowTitle: return ''; @@ -1073,7 +1071,7 @@ export class DocumentViewInternal extends DocComponent, props: Opt, property: string) => this._props?.styleProvider?.(doc, props, property + ':caption'); + captionStyleProvider = (doc: Opt, props: Opt, property: string) => this._props?.styleProvider?.(doc, props, property + ':caption'); @observable _changingTitleField = false; @observable _dropDownInnerWidth = 0; fieldsDropdown = (inputOptions: string[], dropdownWidth: number, placeholder: string, onChange: (val: string | number) => void, onClose: () => void) => { @@ -1431,11 +1429,20 @@ export class DocumentView extends ObservableReactComponent { return this._props.LayoutTemplateString?.includes('link_anchor_2') ? DocCast(this.Document['link_anchor_2']) : this._props.LayoutTemplateString?.includes('link_anchor_1') ? DocCast(this.Document['link_anchor_1']) : undefined; } @computed get hideLinkButton() { - return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HideLinkBtn + (this.IsSelected ? ':selected' : '')); + return ( + this._props.hideLinkButton || + this._props.renderDepth === -1 || // + (this.IsSelected && this._props.renderDepth) || + !this._isHovering || + (!this.IsSelected && this.layoutDoc.layout_hideLinkButton) || + SnappingManager.IsDragging || + SnappingManager.IsResizing + ); } - hideLinkCount = () => false; // this._props.renderDepth === -1 || (this.IsSelected && this._props.renderDepth) || !this._isHovering || this.hideLinkButton; + hideLinkCount = () => (this.hideLinkButton ? true : false); + @computed get linkCountView() { - return ; + return ; } @computed get docViewPath(): DocumentView[] { return this._props.docViewPath ? [...this._props.docViewPath(), this] : [this]; @@ -1508,7 +1515,7 @@ export class DocumentView extends ObservableReactComponent { if (this.docView._componentView?.screenBounds?.()) { return this.docView._componentView.screenBounds(); } - const xf = this.docView._props.ScreenToLocalTransform().scale(this.nativeScaling).inverse(); + const xf = this.docView.ScreenToLocalBoxXf().scale(this.nativeScaling).inverse(); const [[left, top], [right, bottom]] = [xf.transformPoint(0, 0), xf.transformPoint(this.panelWidth, this.panelHeight)]; if (this.docView._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) { @@ -1566,7 +1573,7 @@ export class DocumentView extends ObservableReactComponent { }; layout_fitWidthFunc = (doc: Doc) => BoolCast(this.layout_fitWidth); - scaleToScreenSpace = () => this._props.ScreenToLocalTransform().Scale; + screenToLocalScale = () => this._props.ScreenToLocalTransform().Scale; docViewPathFunc = () => this.docViewPath; isSelected = () => this.IsSelected; select = (extendSelection: boolean, focusSelection?: boolean) => { @@ -1589,7 +1596,14 @@ export class DocumentView extends ObservableReactComponent { PanelHeight = () => this.panelHeight; NativeDimScaling = () => this.nativeScaling; selfView = () => this; - screenToNativeLocalTransform = () => + /** + * @returns Transform to the document view (in the coordinate system of whatever contains the DocumentView) + */ + screenToViewTransform = () => this._props.ScreenToLocalTransform(); + /** + * @returns Transform to the coordinate system of the contents of the document view (includes native dimension scaling and centering) + */ + screenToContentsTransform = () => this._props .ScreenToLocalTransform() .translate(-this.centeringX, -this.centeringY) @@ -1676,7 +1690,7 @@ export class DocumentView extends ObservableReactComponent { isSelected={this.isSelected} select={this.select} layout_fitWidth={this.layout_fitWidthFunc} - ScreenToLocalTransform={this.screenToNativeLocalTransform} + ScreenToLocalTransform={this.screenToContentsTransform} 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 28c614786..a5853499f 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -90,7 +90,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent ({ forceFull: this._props.renderDepth < 1 || this.layoutDoc._showFullRes, - scrSize: (this._props.ScreenToLocalTransform().inverse().transformDirection(this.nativeSize.nativeWidth, this.nativeSize.nativeHeight)[0] / this.nativeSize.nativeWidth) * NumCast(this.layoutDoc._freeform_scale, 1), + scrSize: (this.ScreenToLocalBoxXf().inverse().transformDirection(this.nativeSize.nativeWidth, this.nativeSize.nativeHeight)[0] / this.nativeSize.nativeWidth) * NumCast(this.layoutDoc._freeform_scale, 1), selected: this._props.isSelected(), }), ({ forceFull, scrSize, selected }) => (this._curSuffix = selected ? '_o' : this.fieldKey === 'icon' ? '_m' : forceFull ? '_o' : scrSize < 0.25 ? '_s' : scrSize < 0.5 ? '_m' : scrSize < 0.8 ? '_l' : '_o'), @@ -158,7 +158,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent { - const scaling = (this._props.DocumentView?.()._props.ScreenToLocalTransform().Scale || 1) / NumCast(this.layoutDoc._freeform_scale, 1); + const scaling = (this._props.DocumentView?.().screenToViewTransform().Scale || 1) / NumCast(this.layoutDoc._freeform_scale, 1); const nscale = NumCast(this._props.PanelWidth()) / scaling; const nw = nscale / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']); this.dataDoc[this.fieldKey + '_nativeHeight'] = NumCast(this.dataDoc[this.fieldKey + '_nativeHeight']) * nw; @@ -366,7 +366,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent; } - screenToLocalTransform = () => this._props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop) * this._props.ScreenToLocalTransform().Scale); + screenToLocalTransform = () => this.ScreenToLocalBoxXf().translate(0, NumCast(this.layoutDoc._layout_scrollTop) * this.ScreenToLocalBoxXf().Scale); marqueeDown = (e: React.PointerEvent) => { if (!e.altKey && e.button === 0 && NumCast(this.layoutDoc._freeform_scale, 1) <= NumCast(this.dataDoc.freeform_scaleMin, 1) && this._props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) { setupMoveUpEvents( diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index 134f2e14a..7f1d41547 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -38,8 +38,8 @@ export class LinkBox extends ViewBoxBaseComponent() { } screenBounds = () => { if (this.layoutDoc._layout_isSvg && this.anchor1 && this.anchor2 && this.anchor1.CollectionFreeFormView) { - const a_invXf = this.anchor1._props.ScreenToLocalTransform().inverse(); - const b_invXf = this.anchor2._props.ScreenToLocalTransform().inverse(); + const a_invXf = this.anchor1.screenToViewTransform().inverse(); + const b_invXf = this.anchor2.screenToViewTransform().inverse(); const a_scrBds = { tl: a_invXf.transformPoint(0, 0), br: a_invXf.transformPoint(NumCast(this.anchor1.Document._width), NumCast(this.anchor1.Document._height)) }; const b_scrBds = { tl: b_invXf.transformPoint(0, 0), br: b_invXf.transformPoint(NumCast(this.anchor2.Document._width), NumCast(this.anchor2.Document._height)) }; @@ -67,9 +67,9 @@ export class LinkBox extends ViewBoxBaseComponent() { const b = (this.anchor2 ?? this.anchor1)!; const parxf = this._props.docViewPath()[this._props.docViewPath().length - 2].ComponentView as CollectionFreeFormView; - const this_xf = parxf?.screenToLocalXf ?? Transform.Identity; //this._props.ScreenToLocalTransform(); - const a_invXf = a._props.ScreenToLocalTransform().inverse(); - const b_invXf = b._props.ScreenToLocalTransform().inverse(); + const this_xf = parxf?.screenToFreeformContentsXf ?? Transform.Identity; //this.ScreenToLocalTransform(); + const a_invXf = a.screenToViewTransform().inverse(); + const b_invXf = b.screenToViewTransform().inverse(); const a_scrBds = { tl: a_invXf.transformPoint(0, 0), br: a_invXf.transformPoint(NumCast(a.Document._width), NumCast(a.Document._height)) }; const b_scrBds = { tl: b_invXf.transformPoint(0, 0), br: b_invXf.transformPoint(NumCast(b.Document._width), NumCast(b.Document._height)) }; const a_bds = { tl: this_xf.transformPoint(a_scrBds.tl[0], a_scrBds.tl[1]), br: this_xf.transformPoint(a_scrBds.br[0], a_scrBds.br[1]) }; diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index ffd52fb0e..41befbbfe 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -431,7 +431,7 @@ export class MapBox extends ViewBoxAnnotatableComponent this._props.PanelWidth() / (this._props.NativeDimScaling?.() || 1) - this.sidebarWidth(); panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); - scrollXf = () => this._props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); + scrollXf = () => this.ScreenToLocalBoxXf().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter]; opaqueFilter = () => [...this._props.childFilters(), Utils.OpaqueBackgroundFilter]; infoWidth = () => this._props.PanelWidth() / 5; @@ -531,7 +531,7 @@ export class MapBox extends ViewBoxAnnotatableComponent string[]) => null; return ( diff --git a/src/client/views/nodes/MapBox/MapBox2.tsx b/src/client/views/nodes/MapBox/MapBox2.tsx index 722a347f1..9734d9db1 100644 --- a/src/client/views/nodes/MapBox/MapBox2.tsx +++ b/src/client/views/nodes/MapBox/MapBox2.tsx @@ -517,7 +517,7 @@ // panelWidth = () => this._props.PanelWidth() / (this._props.NativeDimScaling?.() || 1) - this.sidebarWidth(); // panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); -// scrollXf = () => this._props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); +// scrollXf = () => this.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); // transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter]; // opaqueFilter = () => [...this._props.childFilters(), Utils.OpaqueBackgroundFilter]; // infoWidth = () => this._props.PanelWidth() / 5; diff --git a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx index 2c31bbab7..8b22a1531 100644 --- a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx +++ b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx @@ -280,7 +280,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent this._props.PanelWidth() / (this._props.NativeDimScaling?.() || 1) - this.sidebarWidth(); panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); - scrollXf = () => this._props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); + scrollXf = () => this.ScreenToLocalBoxXf().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter]; opaqueFilter = () => [...this._props.childFilters(), Utils.OpaqueBackgroundFilter]; infoWidth = () => this._props.PanelWidth() / 5; @@ -401,7 +401,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent this.sidebarNativeHeight; sidebarMoveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.moveDocument(doc, targetCollection, addDocument, this.SidebarKey); sidebarRemDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, this.SidebarKey); - sidebarScreenToLocal = () => this._props.ScreenToLocalTransform().translate((this.sidebarWidth() - this._props.PanelWidth()) / this.pdfScale, 0); + sidebarScreenToLocal = () => this.ScreenToLocalBoxXf().translate((this.sidebarWidth() - this._props.PanelWidth()) / this.pdfScale, 0); @computed get sidebarCollection() { const renderComponent = (tag: string) => { const ComponentTag = tag === CollectionViewType.Freeform ? CollectionFreeFormView : CollectionStackingView; diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 36527c311..f74e6fb2b 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -313,7 +313,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent <> {this.threed} diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 7ab954b3f..ce73d9f37 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -682,7 +682,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { action(encodeURIComponent => { this._clicking = false; if (this._props.isContentActive()) { - // const local = this._props.ScreenToLocalTransform().scale(this._props.scaling?.() || 1).transformPoint(e.clientX, e.clientY); + // const local = this.ScreenToLocalTransform().scale(this._props.scaling?.() || 1).transformPoint(e.clientX, e.clientY); // this.layoutDoc._layout_timelineHeightPercent = Math.max(0, Math.min(100, local[1] / this._props.PanelHeight() * 100)); this.layoutDoc._layout_timelineHeightPercent = 80; @@ -922,7 +922,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { // renders video controls componentUI = (boundsLeft: number, boundsTop: number) => { - const xf = this._props.ScreenToLocalTransform().inverse(); + const xf = this.ScreenToLocalBoxXf().inverse(); const height = this._props.PanelHeight(); const vidHeight = (height * this.heightPercent) / 100 / this.scaling(); const vidWidth = this._props.PanelWidth() / this.scaling(); @@ -940,7 +940,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent() {

{ if (this._mainCont.current && selRange) { - if (this.dataDoc[this._props.fieldKey] instanceof HtmlField) this._mainCont.current.style.transform = `rotate(${NumCast(this._props.DocumentView!().screenToNativeLocalTransform().RotateDeg)}deg)`; + if (this.dataDoc[this._props.fieldKey] instanceof HtmlField) this._mainCont.current.style.transform = `rotate(${NumCast(this._props.DocumentView!().screenToContentsTransform().RotateDeg)}deg)`; const clientRects = selRange.getClientRects(); for (let i = 0; i < clientRects.length; i++) { const rect = clientRects.item(i); @@ -258,7 +258,7 @@ export class WebBox extends ViewBoxAnnotatableComponent 25) return
; + if (this.ScreenToLocalBoxXf().Scale > 25) return
; setTimeout( action(() => { if (this._initialScroll === undefined && !this._webPageHasBeenRendered) { @@ -1061,11 +1061,11 @@ export class WebBox extends ViewBoxAnnotatableComponent) => void) => (this._setPreviewCursor = func); panelWidth = () => this._props.PanelWidth() / (this._props.NativeDimScaling?.() || 1) - this.sidebarWidth() + WebBox.sidebarResizerWidth; panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); - scrollXf = () => this._props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); + scrollXf = () => this.ScreenToLocalBoxXf().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter]; opaqueFilter = () => [...this._props.childFilters(), Utils.noDragDocsFilter, ...(SnappingManager.CanEmbed ? [] : [Utils.OpaqueBackgroundFilter])]; - childStyleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { + childStyleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { if (doc instanceof Doc && property === StyleProp.PointerEvents) { if (this.inlineTextAnnotations.includes(doc)) return 'none'; } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 8bf8abafa..66802d198 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1,7 +1,6 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import { isEqual } from 'lodash'; import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { baseKeymap, selectAll } from 'prosemirror-commands'; @@ -21,12 +20,10 @@ import { InkTool } from '../../../../fields/InkField'; import { List } from '../../../../fields/List'; import { PrefetchProxy } from '../../../../fields/Proxy'; import { RichTextField } from '../../../../fields/RichTextField'; -import { RichTextUtils } from '../../../../fields/RichTextUtils'; import { ComputedField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { GetEffectiveAcl, TraceMobx } from '../../../../fields/util'; import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, numberRange, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, unimplementedFunction, Utils } from '../../../../Utils'; -import { GoogleApiClientUtils, Pulls, Pushes } from '../../../apis/google_docs/GoogleApiClientUtils'; import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT'; import { DocServer } from '../../../DocServer'; import { Docs, DocUtils } from '../../../documents/Documents'; @@ -46,7 +43,6 @@ import { CollectionTreeView } from '../../collections/CollectionTreeView'; import { ContextMenu } from '../../ContextMenu'; import { ContextMenuProps } from '../../ContextMenuItem'; import { ViewBoxAnnotatableComponent } from '../../DocComponent'; -import { DocumentButtonBar } from '../../DocumentButtonBar'; import { Colors } from '../../global/globalEnums'; import { LightboxView } from '../../LightboxView'; import { AnchorMenu } from '../../pdf/AnchorMenu'; @@ -71,9 +67,7 @@ import { RichTextMenu, RichTextMenuPlugin } from './RichTextMenu'; import { RichTextRules } from './RichTextRules'; import { schema } from './schema_rts'; import { SummaryView } from './SummaryView'; -export const GoogleRef = 'googleDocId'; // import * as applyDevTools from 'prosemirror-dev-tools'; -type PullHandler = (exportState: Opt, dataDoc: Doc) => void; export interface FormattedTextBoxProps {} @observer @@ -1189,15 +1183,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent DocumentButtonBar.Instance, - instance => { - if (instance) { - this.pullFromGoogleDoc(this.checkState); - this.dataDoc[GoogleRef] && this.dataDoc.googleDocUnchanged && runInAction(() => (instance.isAnimatingFetch = true)); - } - } - ); this._disposers.editorState = reaction( () => { const dataDoc = Doc.IsDelegateField(DocCast(this.layoutDoc?.proto), this.fieldKey) ? DocCast(this.layoutDoc?.proto) : this?.dataDoc; @@ -1218,24 +1203,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent this._props.Document[Pulls], - () => { - if (!DocumentButtonBar.hasPulledHack) { - DocumentButtonBar.hasPulledHack = true; - this.pullFromGoogleDoc(this.dataDoc.googleDocUnchanged ? this.checkState : this.updateState); - } - } - ); - this._disposers.pushDoc = reaction( - () => this._props.Document[Pushes], - () => { - if (!DocumentButtonBar.hasPushedHack) { - DocumentButtonBar.hasPushedHack = true; - this.pushToGoogleDoc(); - } - } - ); this._disposers.search = reaction( () => Doc.IsSearchMatch(this.Document), @@ -1295,80 +1262,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - this.pullFromGoogleDoc(async (exportState: Opt, dataDoc: Doc) => { - const modes = GoogleApiClientUtils.Docs.WriteMode; - let mode = modes.Replace; - let reference: Opt = Cast(this.dataDoc[GoogleRef], 'string'); - if (!reference) { - mode = modes.Insert; - reference = { title: StrCast(this.dataDoc.title) }; - } - const redo = async () => { - if (this._editorView && reference) { - const content = await RichTextUtils.GoogleDocs.Export(this._editorView.state); - const response = await GoogleApiClientUtils.Docs.write({ reference, content, mode }); - response?.documentId && (this.dataDoc[GoogleRef] = response.documentId); - const pushSuccess = response !== undefined && !('errors' in response); - dataDoc.googleDocUnchanged = pushSuccess; - DocumentButtonBar.Instance.startPushOutcome(pushSuccess); - } - }; - const undo = () => { - if (exportState && reference) { - const content: GoogleApiClientUtils.Docs.Content = { - text: exportState.text, - requests: [], - }; - GoogleApiClientUtils.Docs.write({ reference, content, mode }); - } - }; - UndoManager.AddEvent({ undo, redo, prop: '' }); - redo(); - }); - }; - - pullFromGoogleDoc = async (handler: PullHandler) => { - const dataDoc = this.dataDoc; - const documentId = StrCast(dataDoc[GoogleRef]); - let exportState: Opt; - if (documentId) { - exportState = await RichTextUtils.GoogleDocs.Import(documentId, dataDoc); - } - exportState && UndoManager.RunInBatch(() => handler(exportState, dataDoc), Pulls); - }; - - updateState = (exportState: Opt, dataDoc: Doc) => { - let pullSuccess = false; - if (exportState !== undefined) { - pullSuccess = true; - dataDoc[this.fieldKey] = new RichTextField(JSON.stringify(exportState.state.toJSON())); - setTimeout(() => { - if (this._editorView) { - const state = this._editorView.state; - const end = state.doc.content.size - 1; - this._editorView.dispatch(state.tr.setSelection(TextSelection.create(state.doc, end, end))); - } - }, 0); - dataDoc.title = exportState.title; - this.dataDoc.title_custom = true; - dataDoc.googleDocUnchanged = true; - } else { - delete dataDoc[GoogleRef]; - } - DocumentButtonBar.Instance.startPullOutcome(pullSuccess); - }; - - checkState = (exportState: Opt, dataDoc: Doc) => { - if (exportState && this._editorView) { - const equalContent = isEqual(this._editorView.state.doc, exportState.state.doc); - const equalTitles = dataDoc.title === exportState.title; - const unchanged = equalContent && equalTitles; - dataDoc.googleDocUnchanged = unchanged; - DocumentButtonBar.Instance.setPullState(unchanged); - } - }; - clipboardTextSerializer = (slice: Slice): string => { let text = '', separated = true; @@ -1462,7 +1355,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent viewRect.bottom ? docPos.bottom - viewRect.bottom : undefined; if (((topOff && Math.abs(Math.trunc(topOff)) > 0) || (botOff && Math.abs(Math.trunc(botOff)) > 0)) && scrollRef) { const shift = Math.min(topOff ?? Number.MAX_VALUE, botOff ?? Number.MAX_VALUE); - const scrollPos = scrollRef.scrollTop + shift * self._props.ScreenToLocalTransform().Scale; + const scrollPos = scrollRef.scrollTop + shift * self.ScreenToLocalBoxXf().Scale; if (this._focusSpeed !== undefined) { scrollPos && (this._scrollStopper = smoothScroll(this._focusSpeed, scrollRef, scrollPos, 'ease', this._scrollStopper)); } else { diff --git a/src/client/views/nodes/importBox/ImportElementBox.tsx b/src/client/views/nodes/importBox/ImportElementBox.tsx index 1a92acea1..7d0086c0c 100644 --- a/src/client/views/nodes/importBox/ImportElementBox.tsx +++ b/src/client/views/nodes/importBox/ImportElementBox.tsx @@ -13,7 +13,7 @@ export class ImportElementBox extends ViewBoxBaseComponent() { return FieldView.LayoutString(ImportElementBox, fieldKey); } - screenToLocalXf = () => this._props.ScreenToLocalTransform().scale(1 * (this._props.NativeDimScaling?.() || 1)); + screenToLocalXf = () => this.ScreenToLocalBoxXf().scale(1 * (this._props.NativeDimScaling?.() || 1)); @computed get mainItem() { return (
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 0305689e7..6fa64a765 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -979,7 +979,7 @@ export class PresBox extends ViewBoxBaseComponent() { enterMinimize = () => { this.updateCurrentPresentation(this.Document); clearTimeout(this._presTimer); - const pt = this._props.ScreenToLocalTransform().inverse().transformPoint(0, 0); + const pt = this.ScreenToLocalBoxXf().inverse().transformPoint(0, 0); this._props.removeDocument?.(this.layoutDoc); return PresBox.OpenPresMinimized(this.Document, [pt[0] + (this._props.PanelWidth() - 250), pt[1] + 10]); }; @@ -1076,7 +1076,7 @@ export class PresBox extends ViewBoxBaseComponent() { childLayoutTemplate = () => Docs.Create.PresElementBoxDocument(); removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.Document, this.fieldKey, doc); - getTransform = () => this._props.ScreenToLocalTransform().translate(-5, -65); // listBox padding-left and pres-box-cont minHeight + getTransform = () => this.ScreenToLocalBoxXf().translate(-5, -65); // listBox padding-left and pres-box-cont minHeight panelHeight = () => this._props.PanelHeight() - 40; /** * For sorting the array so that the order is maintained when it is dropped. diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index ec5d090dd..4945d66c8 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -19,7 +19,7 @@ import { TreeView } from '../../collections/TreeView'; import { ViewBoxBaseComponent } from '../../DocComponent'; import { EditableView } from '../../EditableView'; import { Colors } from '../../global/globalEnums'; -import { DocumentView, DocumentViewProps } from '../../nodes/DocumentView'; +import { DocumentView, DocumentViewInternalProps, DocumentViewProps } from '../../nodes/DocumentView'; import { FieldView, FieldViewProps } from '../../nodes/FieldView'; import { StyleProp } from '../../StyleProvider'; import { PresBox } from './PresBox'; @@ -97,7 +97,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { presExpandDocumentClick = () => (this.slideDoc.presentation_expandInlineButton = !this.slideDoc.presentation_expandInlineButton); embedHeight = () => this.collapsedHeight + this.expandViewHeight; embedWidth = () => this._props.PanelWidth() / 2; - styleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { + styleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { return property === StyleProp.Opacity ? 1 : this._props.styleProvider?.(doc, props, property); }; /** diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index f41094010..4a7e35c16 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -17,11 +17,11 @@ import { SnappingManager } from '../../util/SnappingManager'; import { MarqueeOptionsMenu } from '../collections/collectionFreeForm'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { MarqueeAnnotator } from '../MarqueeAnnotator'; -import { DocFocusOptions, DocumentViewProps } from '../nodes/DocumentView'; +import { DocFocusOptions, DocumentViewInternalProps, DocumentViewProps } from '../nodes/DocumentView'; import { FieldViewProps } from '../nodes/FieldView'; import { LinkInfo } from '../nodes/LinkDocPreview'; import { ObservableReactComponent } from '../ObservableReactComponent'; -import { StyleProp } from '../StyleProvider'; +import { StyleProp, testDocProps } from '../StyleProvider'; import { AnchorMenu } from './AnchorMenu'; import { Annotation } from './Annotation'; import { GPTPopup } from './GPTPopup/GPTPopup'; @@ -53,7 +53,7 @@ interface IViewerProps extends FieldViewProps { export class PDFViewer extends ObservableReactComponent { static _annotationStyle: any = addStyleSheet(); - constructor(props: any) { + constructor(props: IViewerProps) { super(props); makeObservable(this); } @@ -419,7 +419,7 @@ export class PDFViewer extends ObservableReactComponent { @action createTextAnnotation = (sel: Selection, selRange: Range) => { if (this._mainCont.current) { - this._mainCont.current.style.transform = `rotate(${NumCast(this._props.DocumentView!().screenToNativeLocalTransform().RotateDeg)}deg)`; + this._mainCont.current.style.transform = `rotate(${NumCast(this._props.DocumentView!().screenToContentsTransform().RotateDeg)}deg)`; const boundingRect = this._mainCont.current.getBoundingClientRect(); const clientRects = selRange.getClientRects(); for (let i = 0; i < clientRects.length; i++) { @@ -491,16 +491,17 @@ export class PDFViewer extends ObservableReactComponent { } getScrollHeight = () => this._scrollHeight; - scrollXf = () => (this._mainCont.current ? this._props.ScreenToLocalTransform().translate(0, NumCast(this._props.layoutDoc._layout_scrollTop)) : this._props.ScreenToLocalTransform()); + scrollXf = () => this._props.ScreenToLocalTransform().translate(0, this._mainCont.current ? NumCast(this._props.layoutDoc._layout_scrollTop) : 0); overlayTransform = () => this.scrollXf().scale(1 / NumCast(this._props.layoutDoc._freeform_scale, 1)); panelWidth = () => this._props.PanelWidth() / (this._props.NativeDimScaling?.() || 1); panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter]; opaqueFilter = () => [...this._props.childFilters(), Utils.noDragDocsFilter, ...(SnappingManager.CanEmbed && this._props.isContentActive() ? [] : [Utils.OpaqueBackgroundFilter])]; - childStyleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { + childStyleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { if (doc instanceof Doc && property === StyleProp.PointerEvents) { + const docProps = testDocProps(props) ? props : undefined; if (this.inlineTextAnnotations.includes(doc) || this._props.isContentActive() === false) return 'none'; - const isInk = doc.layout_isSvg && !props?.LayoutTemplateString; + const isInk = doc.layout_isSvg && !docProps?.LayoutTemplateString; return isInk ? 'visiblePainted' : 'all'; } return this._props.styleProvider?.(doc, props, property); -- cgit v1.2.3-70-g09d2