diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/documents/Documents.ts | 4 | ||||
-rw-r--r-- | src/client/views/collections/CollectionMapView.tsx | 4 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 11 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 7 | ||||
-rw-r--r-- | src/client/views/nodes/WebBox.tsx | 35 | ||||
-rw-r--r-- | src/client/views/pdf/PDFViewer.tsx | 1 | ||||
-rw-r--r-- | src/fields/documentSchemas.ts | 6 |
7 files changed, 36 insertions, 32 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 18a0b43ff..b859086d5 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -112,7 +112,7 @@ export interface DocumentOptions { caption?: RichTextField; ignoreClick?: boolean; lockedPosition?: boolean; // lock the x,y coordinates of the document so that it can't be dragged - lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed + _lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed isAnnotating?: boolean; // whether we web document is annotation mode where links can't be clicked to allow annotations to be created opacity?: number; defaultBackgroundColor?: string; @@ -635,7 +635,7 @@ export namespace Docs { } export function WebDocument(url: string, options: DocumentOptions = {}) { - return InstanceFromProto(Prototypes.get(DocumentType.WEB), url ? new WebField(new URL(url)) : undefined, { _fitWidth: true, _chromeStatus: url ? "disabled" : "enabled", isAnnotating: true, lockedTransform: true, ...options }); + return InstanceFromProto(Prototypes.get(DocumentType.WEB), url ? new WebField(new URL(url)) : undefined, { _fitWidth: true, _chromeStatus: url ? "disabled" : "enabled", isAnnotating: true, _lockedTransform: true, ...options }); } export function HtmlDocument(html: string, options: DocumentOptions = {}) { diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx index d91337ce9..a0b7cd8a8 100644 --- a/src/client/views/collections/CollectionMapView.tsx +++ b/src/client/views/collections/CollectionMapView.tsx @@ -226,7 +226,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<IMapProps> initialCenter={center} center={center} onIdle={(_props?: IMapProps, map?: google.maps.Map) => { - if (this.layoutDoc.lockedTransform) { + if (this.layoutDoc._lockedTransform) { // reset zoom (ideally, we could probably can tell the map to disallow zooming somehow instead) map?.setZoom(center?.zoom || 10); map?.setCenter({ lat: center?.lat!, lng: center?.lng! }); @@ -238,7 +238,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<IMapProps> } }} onDragend={(_props?: IMapProps, map?: google.maps.Map) => { - if (this.layoutDoc.lockedTransform) { + if (this.layoutDoc._lockedTransform) { // reset the drag (ideally, we could probably can tell the map to disallow dragging somehow instead) map?.setCenter({ lat: center?.lat!, lng: center?.lng! }); } else { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index c9b3519aa..972c09484 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -769,7 +769,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P @action onPointerWheel = (e: React.WheelEvent): void => { - if (this.props.Document.lockedTransform || this.props.Document.inOverlay) return; + if (this.layoutDoc._lockedTransform || this.props.Document.inOverlay) return; if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming e.stopPropagation(); } @@ -805,7 +805,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P else if (ranges.yrange.max <= (panY - panelDim[1] / 2)) panY = ranges.yrange.min - panelDim[1] / 2; } } - if (!this.Document.lockedTransform || this.Document.inOverlay) { + if (!this.layoutDoc._lockedTransform || this.Document.inOverlay) { this.Document.panTransformType = panType; const scale = this.getLocalTransform().inverse().Scale; const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX)); @@ -1169,6 +1169,12 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P Doc.toggleNativeDimensions(this.layoutDoc, this.props.ContentScaling(), this.props.NativeWidth(), this.props.NativeHeight()); } + @undoBatch + @action + toggleLockTransform = (): void => { + this.layoutDoc._lockedTransform = this.layoutDoc._lockedTransform ? undefined : true; + } + private thumbIdentifier?: number; onContextMenu = (e: React.MouseEvent) => { @@ -1189,6 +1195,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P optionItems.push({ description: `${this.fitToContent ? "Unset" : "Set"} Fit To Container`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" }); optionItems.push({ description: `${this.Document.useClusters ? "Uncluster" : "Use Clusters"}`, event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" }); this.props.ContainingCollectionView && optionItems.push({ description: "Promote Collection", event: this.promoteCollection, icon: "table" }); + optionItems.push({ description: this.layoutDoc._lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: this.layoutDoc._lockedTransform ? "unlock" : "lock" }); optionItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" }); // layoutItems.push({ description: "Analyze Strokes", event: this.analyzeStrokes, icon: "paint-brush" }); optionItems.push({ diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 34aabfe5e..8dbd0232b 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -683,12 +683,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu this.Document.lockedPosition = this.Document.lockedPosition ? undefined : true; } - @undoBatch - @action - toggleLockTransform = (): void => { - this.Document.lockedTransform = this.Document.lockedTransform ? undefined : true; - } - @action onContextMenu = async (e: React.MouseEvent | Touch): Promise<void> => { // the touch onContextMenu is button 0, the pointer onContextMenu is button 2 @@ -751,7 +745,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu const moreItems: ContextMenuProps[] = more && "subitems" in more ? more.subitems : []; moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" }); - moreItems.push({ description: this.Document.lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" }); moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); if (!ClientUtils.RELEASE) { diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index c1a585bca..1d242d958 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -59,14 +59,19 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum iframe.contentDocument.addEventListener('scroll', this.iframeScrolled, false); this.layoutDoc.scrollHeight = iframe.contentDocument.children?.[0].scrollHeight || 1000; iframe.contentDocument.children[0].scrollTop = NumCast(this.layoutDoc.scrollTop); + iframe.contentDocument.children[0].scrollLeft = NumCast(this.layoutDoc.scrollLeft); } this._reactionDisposer?.(); - this._reactionDisposer = reaction(() => this.layoutDoc.scrollY, - (scrollY) => { - if (scrollY !== undefined) { - this._outerRef.current!.scrollTop = scrollY; + this._reactionDisposer = reaction(() => ({ y: this.layoutDoc.scrollY, x: this.layoutDoc.scrollX }), + ({ x, y }) => { + if (y !== undefined) { + this._outerRef.current!.scrollTop = y; this.layoutDoc.scrollY = undefined; } + if (x !== undefined) { + this._outerRef.current!.scrollLeft = x; + this.layoutDoc.scrollX = undefined; + } }, { fireImmediately: true } ); @@ -76,8 +81,10 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum this._setPreviewCursor?.(e.screenX, e.screenY, false); } iframeScrolled = (e: any) => { - const scroll = e.target?.children?.[0].scrollTop; - this.layoutDoc.scrollTop = this._outerRef.current!.scrollTop = scroll; + const scrollTop = e.target?.children?.[0].scrollTop; + const scrollLeft = e.target?.children?.[0].scrollLeft; + this.layoutDoc.scrollTop = this._outerRef.current!.scrollTop = scrollTop; + this.layoutDoc.scrollLeft = this._outerRef.current!.scrollLeft = scrollLeft; } async componentDidMount() { const urlField = Cast(this.dataDoc[this.props.fieldKey], WebField); @@ -182,14 +189,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum } toggleAnnotationMode = () => { - if (!this.layoutDoc.isAnnotating) { - this.layoutDoc.lockedTransform = false; - this.layoutDoc.isAnnotating = true; - } - else { - this.layoutDoc.lockedTransform = true; - this.layoutDoc.isAnnotating = false; - } + this.layoutDoc.isAnnotating = !this.layoutDoc.isAnnotating; } urlEditor() { @@ -427,7 +427,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum {this.urlEditor()} </>); } - scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.props.Document.scrollTop)); + scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc.scrollLeft), NumCast(this.layoutDoc.scrollTop)); render() { return (<div className={`webBox-container`} style={{ @@ -449,10 +449,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum if (iframe.children[0].scrollTop !== outerFrame.scrollTop) { iframe.children[0].scrollTop = outerFrame.scrollTop; } + if (iframe.children[0].scrollLeft !== outerFrame.scrollLeft) { + iframe.children[0].scrollLeft = outerFrame.scrollLeft; + } } //this._outerRef.current!.scrollTop !== this._scrollTop && (this._outerRef.current!.scrollTop = this._scrollTop) }}> - <div className={"webBox-innerContent"} style={{ height: NumCast(this.layoutDoc.scrollHeight) }}> + <div className={"webBox-innerContent"} style={{ height: NumCast(this.layoutDoc.scrollHeight), width: 4000 }}> <CollectionFreeFormView {...this.props} PanelHeight={this.props.PanelHeight} PanelWidth={this.props.PanelWidth} diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index c50969493..810ce5aea 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -125,7 +125,6 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu _lastSearch: string = ""; componentDidMount = async () => { - !this.props.Document.lockedTransform && (this.props.Document.lockedTransform = true); // change the address to be the file address of the PNG version of each page // file address of the pdf const { url: { href } } = Cast(this.dataDoc[this.props.fieldKey], PdfField)!; diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index cacba43b6..142f7e079 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -20,7 +20,9 @@ export const documentSchema = createSchema({ z: "number", // z "coordinate" - non-zero specifies the overlay layer of a freeformview zIndex: "number", // zIndex of a document in a freeform view scrollY: "number", // "command" to scroll a document to a position on load (the value will be reset to 0 after that ) + scrollX: "number", // "command" to scroll a document to a position on load (the value will be reset to 0 after that ) scrollTop: "number", // scroll position of a scrollable document (pdf, text, web) + scrollLeft: "number", // scroll position of a scrollable document (pdf, text, web) // appearance properties on the layout _autoHeight: "boolean", // whether the height of the document should be computed automatically based on its contents @@ -74,8 +76,8 @@ export const documentSchema = createSchema({ isLinkButton: "boolean", // whether document functions as a link follow button to follow the first link on the document when clicked isBackground: "boolean", // whether document is a background element and ignores input events (can only select with marquee) lockedPosition: "boolean", // whether the document can be moved (dragged) - lockedTransform: "boolean", // whether the document can be panned/zoomed - + _lockedTransform: "boolean",// whether a freeformview can pan/zoom + // drag drop properties dragFactory: Doc, // the document that serves as the "template" for the onDragStart script. ie, to drag out copies of the dragFactory document. dropAction: "string", // override specifying what should happen when this document is dropped (can be "alias", "copy", "move") |