From 827cee4d7ac4f1e761b141097d20671e7873bea8 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 15 Sep 2019 01:14:21 -0400 Subject: changed moveDocument to move the draggedDoc -- its up to the caller to add the droppedDoc if it wants to. cleaned up some old code related to passing dataDoc along with doc's to drag and other functinos --- src/client/views/pdf/Page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx index 856e883e7..533247170 100644 --- a/src/client/views/pdf/Page.tsx +++ b/src/client/views/pdf/Page.tsx @@ -137,7 +137,7 @@ export default class Page extends React.Component { view.nativeWidth = this.props.Document.nativeWidth; view.startY = marquee.top + this.props.getScrollFromPage(this.props.page); view.width = this.props.Document[WidthSym](); - DragManager.StartDocumentDrag([], new DragManager.DocumentDragData([view], [undefined]), 0, 0); + DragManager.StartDocumentDrag([], new DragManager.DocumentDragData([view]), 0, 0); } @action -- cgit v1.2.3-70-g09d2 From 3e6f24e4ac4a4b64620d8c9f614f214f8f1c7b94 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 17 Sep 2019 19:47:05 -0400 Subject: cleanup for animating document icon collapse/expand - still need to fix for docs without native dimensions. lots of lint fixes. --- src/Utils.ts | 17 ++--- src/client/documents/Documents.ts | 4 +- src/client/util/ProsemirrorExampleTransfer.ts | 4 +- src/client/util/RichTextRules.ts | 6 +- src/client/util/RichTextSchema.tsx | 14 ++-- src/client/util/TooltipTextMenu.tsx | 4 +- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/GlobalKeyHandler.ts | 2 +- src/client/views/OverlayView.tsx | 1 + src/client/views/ScriptBox.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 14 ++-- src/client/views/nodes/ButtonBox.tsx | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 35 ++++------ src/client/views/nodes/DocumentView.tsx | 75 +++++++++------------- src/client/views/nodes/FormattedTextBox.tsx | 6 +- src/client/views/nodes/ImageBox.tsx | 8 +-- src/client/views/nodes/PDFBox.tsx | 6 +- src/client/views/nodes/VideoBox.tsx | 6 +- src/client/views/pdf/Annotation.tsx | 2 +- src/client/views/pdf/PDFViewer.tsx | 2 +- src/new_fields/Doc.ts | 12 ++-- .../authentication/models/current_user_utils.ts | 2 +- 23 files changed, 99 insertions(+), 129 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/Utils.ts b/src/Utils.ts index 415023ac4..65eb3cffd 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -115,28 +115,23 @@ export class Utils { // Calculate hue // No difference - if (delta == 0) - h = 0; + if (delta === 0) h = 0; // Red is max - else if (cmax == r) - h = ((g - b) / delta) % 6; + else if (cmax === r) h = ((g - b) / delta) % 6; // Green is max - else if (cmax == g) - h = (b - r) / delta + 2; + else if (cmax === g) h = (b - r) / delta + 2; // Blue is max - else - h = (r - g) / delta + 4; + else h = (r - g) / delta + 4; h = Math.round(h * 60); // Make negative hues positive behind 360° - if (h < 0) - h += 360; // Calculate lightness + if (h < 0) h += 360; // Calculate lightness l = (cmax + cmin) / 2; // Calculate saturation - s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1)); + s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1)); // Multiply l and s by 100 // s = +(s * 100).toFixed(1); diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 673acfbaf..206e2c4f1 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -631,8 +631,8 @@ export namespace DocUtils { LinkManager.Instance.deleteLink(link); LinkManager.Instance.addLink(link); } - }) - }) + }); + }); } } }); diff --git a/src/client/util/ProsemirrorExampleTransfer.ts b/src/client/util/ProsemirrorExampleTransfer.ts index 1d2d33800..3e3d3155c 100644 --- a/src/client/util/ProsemirrorExampleTransfer.ts +++ b/src/client/util/ProsemirrorExampleTransfer.ts @@ -97,7 +97,7 @@ export default function buildKeymap>(schema: S, mapKeys?: tx2.doc.descendants((node: any, offset: any, index: any) => { if (node.type === schema.nodes.ordered_list || node.type === schema.nodes.list_item) { let path = (tx2.doc.resolve(offset) as any).path; - let depth = Array.from(path).reduce((p: number, c: any) => p + (c.hasOwnProperty("type") && (c as any).type === schema.nodes.ordered_list ? 1 : 0), 0); + let depth = Array.from(path).reduce((p: number, c: any) => p + (c.hasOwnProperty("type") && c.type === schema.nodes.ordered_list ? 1 : 0), 0); if (node.type === schema.nodes.ordered_list) depth++; tx2.setNodeMarkup(offset, node.type, { ...node.attrs, mapStyle: node.attrs.mapStyle, bulletStyle: depth }, node.marks); } @@ -145,7 +145,7 @@ export default function buildKeymap>(schema: S, mapKeys?: marks && tx.ensureMarks(marks.filter((val: any) => val.type !== schema.marks.metadata && val.type !== schema.marks.metadataKey && val.type !== schema.marks.metadataVal)); marks && tx.setStoredMarks(marks.filter((val: any) => val.type !== schema.marks.metadata && val.type !== schema.marks.metadataKey && val.type !== schema.marks.metadataVal)); return tx; - } + }; bind("Enter", (state: EditorState, dispatch: (tx: Transaction) => void) => { var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); if (!splitListItem(schema.nodes.list_item)(state, (tx3: Transaction) => dispatch(tx3))) { diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts index c727eec73..cd37ea0bb 100644 --- a/src/client/util/RichTextRules.ts +++ b/src/client/util/RichTextRules.ts @@ -20,7 +20,7 @@ export const inpRules = { /^1\.\s$/, schema.nodes.ordered_list, () => { - return ({ mapStyle: "decimal", bulletStyle: 1 }) + return ({ mapStyle: "decimal", bulletStyle: 1 }); }, (match: any, node: any) => { return node.childCount + node.attrs.order === +match[1]; @@ -33,7 +33,7 @@ export const inpRules = { schema.nodes.ordered_list, // match => { () => { - return ({ mapStyle: "alpha", bulletStyle: 1 }) + return ({ mapStyle: "alpha", bulletStyle: 1 }); // return ({ order: +match[1] }) }, (match: any, node: any) => { @@ -67,7 +67,7 @@ export const inpRules = { (Cast(FormattedTextBox.InputBoxOverlay!.props.Document, Doc) as Doc).heading = Number(match[1]); return state.tr.deleteRange(start, end); } - return state.tr.deleteRange(start, end).addStoredMark(schema.marks.pFontSize.create({ fontSize: Number(match[1]) })) + return state.tr.deleteRange(start, end).addStoredMark(schema.marks.pFontSize.create({ fontSize: Number(match[1]) })); }), new InputRule( new RegExp(/^\^\^\s$/), diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index f027a4bf7..ba4b92a25 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -349,8 +349,9 @@ export const marks: { [index: string]: MarkSpec } = { let style = getComputedStyle(p); if (style.textDecoration === "underline") return null; if (p.parentElement.outerHTML.indexOf("text-decoration: underline") !== -1 && - p.parentElement.outerHTML.indexOf("text-decoration-style: dotted") !== -1) + p.parentElement.outerHTML.indexOf("text-decoration-style: dotted") !== -1) { return null; + } } return false; } @@ -371,10 +372,9 @@ export const marks: { [index: string]: MarkSpec } = { getAttrs: (p: any) => { if (typeof (p) !== "string") { let style = getComputedStyle(p); - if (style.textDecoration === "underline") - return null; - if (p.parentElement.outerHTML.indexOf("text-decoration-style:line") !== -1) + if (style.textDecoration === "underline" || p.parentElement.outerHTML.indexOf("text-decoration-style:line") !== -1) { return null; + } } return false; } @@ -633,11 +633,11 @@ export class ImageResizeView { DocumentManager.Instance.jumpToDocument(jumpToDoc, e.ctrlKey, false, document => addDocTab(document, undefined, location ? location : "inTab")); } else { DocumentManager.Instance.jumpToDocument(linkDoc, e.ctrlKey, false, document => addDocTab(document, undefined, location ? location : "inTab")); - } e.ctrlKey + } } }); } - } + }; this._handle.onpointerdown = function (e: any) { e.preventDefault(); e.stopPropagation(); @@ -776,7 +776,7 @@ export class FootnoteView { this.innerView.updateState(state); if (!tr.getMeta("fromOutside")) { - let outerTr = this.outerView.state.tr, offsetMap = StepMap.offset(this.getPos() + 1) + let outerTr = this.outerView.state.tr, offsetMap = StepMap.offset(this.getPos() + 1); for (let i = 0; i < transactions.length; i++) { let steps = transactions[i].steps; for (let j = 0; j < steps.length; j++) { diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 84d045e6f..5764af282 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -523,12 +523,12 @@ export class TooltipTextMenu { tx2.doc.descendants((node: any, offset: any, index: any) => { if (node.type === schema.nodes.ordered_list || node.type === schema.nodes.list_item) { let path = (tx2.doc.resolve(offset) as any).path; - let depth = Array.from(path).reduce((p: number, c: any) => p + (c.hasOwnProperty("type") && (c as any).type === schema.nodes.ordered_list ? 1 : 0), 0); + let depth = Array.from(path).reduce((p: number, c: any) => p + (c.hasOwnProperty("type") && c.type === schema.nodes.ordered_list ? 1 : 0), 0); if (node.type === schema.nodes.ordered_list) depth++; tx2.setNodeMarkup(offset, node.type, { mapStyle: style, bulletStyle: depth }, node.marks); } }); - }; + } //remove all node typeand apply the passed-in one to the selected text changeToNodeType = (nodeType: NodeType | undefined, view: EditorView) => { //remove oldif (nodeType) { //add new diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 7829bd7f1..9a2105467 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -439,7 +439,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let heading = NumCast(dv.props.Document.heading); ruleProvider && heading && (Doc.GetProto(ruleProvider)["ruleRounding_" + heading] = `${Math.min(100, dist)}%`); usingRule = usingRule || (ruleProvider && heading ? true : false); - }) + }); !usingRule && SelectionManager.SelectedDocuments().map(dv => dv.props.Document.layout instanceof Doc ? dv.props.Document.layout : dv.props.Document.isTemplate ? dv.props.Document : Doc.GetProto(dv.props.Document)). map(d => d.borderRounding = `${Math.min(100, dist)}%`); e.stopPropagation(); diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index ba125d6e5..59229418d 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -166,7 +166,7 @@ export default class KeyManager { break; case "o": let target = SelectionManager.SelectedDocuments()[0]; - target && CollectionDockingView.Instance && CollectionDockingView.Instance.OpenFullScreen(target) + target && CollectionDockingView.Instance && CollectionDockingView.Instance.OpenFullScreen(target); break; case "r": preventDefault = false; diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index da4b71e5c..15faea3cd 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -172,6 +172,7 @@ export class OverlayView extends React.Component { ChromeHeight={returnZero} isSelected={returnFalse} select={emptyFunction} + ruleProvider={undefined} layoutKey={"layout"} bringToFront={emptyFunction} addDocument={undefined} diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx index 8f06cf770..8ef9f3be6 100644 --- a/src/client/views/ScriptBox.tsx +++ b/src/client/views/ScriptBox.tsx @@ -98,7 +98,7 @@ export class ScriptBox extends React.Component { // tslint:disable-next-line: no-unnecessary-callback-wrapper let params: string[] = []; let setParams = (p: string[]) => params.splice(0, params.length, ...p); - let scriptingBox = overlayDisposer()} onSave={(text, onError) => { + let scriptingBox = { if (prewrapper) { text = prewrapper + text + (postwrapper ? postwrapper : ""); } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 548f663ec..5f4742834 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -99,7 +99,7 @@ export class CollectionView extends React.Component { subItems.push({ description: "Stacking (AutoHeight)", event: () => { this.props.Document.viewType = CollectionViewType.Stacking; - this.props.Document.autoHeight = true + this.props.Document.autoHeight = true; }, icon: "ellipsis-v" }); subItems.push({ description: "Masonry", event: () => this.props.Document.viewType = CollectionViewType.Masonry, icon: "columns" }); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 03ac012b4..8d392d764 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -24,9 +24,9 @@ import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss" import { ContextMenu } from "../../ContextMenu"; import { ContextMenuProps } from "../../ContextMenuItem"; import { InkingCanvas } from "../../InkingCanvas"; -import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView"; +import { CollectionFreeFormDocumentView, positionSchema } from "../../nodes/CollectionFreeFormDocumentView"; import { DocumentContentsView } from "../../nodes/DocumentContentsView"; -import { DocumentViewProps, positionSchema } from "../../nodes/DocumentView"; +import { DocumentViewProps, documentSchema } from "../../nodes/DocumentView"; import { pageSchema } from "../../nodes/ImageBox"; import { OverlayElementOptions, OverlayView } from "../../OverlayView"; import PDFMenu from "../../pdf/PDFMenu"; @@ -176,8 +176,8 @@ export namespace PivotView { } -type PanZoomDocument = makeInterface<[typeof panZoomSchema, typeof positionSchema, typeof pageSchema]>; -const PanZoomDocument = makeInterface(panZoomSchema, positionSchema, pageSchema); +type PanZoomDocument = makeInterface<[typeof panZoomSchema, typeof documentSchema, typeof positionSchema, typeof pageSchema]>; +const PanZoomDocument = makeInterface(panZoomSchema, documentSchema, positionSchema, pageSchema); @observer export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { @@ -341,7 +341,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { this.bringToFront(d); }); - de.data.droppedDocuments.length == 1 && this.updateCluster(de.data.droppedDocuments[0]); + de.data.droppedDocuments.length === 1 && this.updateCluster(de.data.droppedDocuments[0]); } } else if (de.data instanceof DragManager.AnnotationDragData) { @@ -473,7 +473,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { // choose a cluster color from a palette let colors = ["#da42429e", "#31ea318c", "#8c4000", "#4a7ae2c4", "#d809ff", "#ff7601", "#1dffff", "yellow", "#1b8231f2", "#000000ad"]; clusterColor = colors[cluster % colors.length]; - let set = this.sets.length > cluster ? this.sets[cluster].filter(s => s.backgroundColor && (s.backgroundColor != s.defaultBackgroundColor)) : undefined; + let set = this.sets.length > cluster ? this.sets[cluster].filter(s => s.backgroundColor && (s.backgroundColor !== s.defaultBackgroundColor)) : undefined; // override the cluster color with an explicitly set color on a non-background document. then override that with an explicitly set color on a background document set && set.filter(s => !s.isBackground).map(s => clusterColor = StrCast(s.backgroundColor)); set && set.filter(s => s.isBackground).map(s => clusterColor = StrCast(s.backgroundColor)); @@ -848,7 +848,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { Doc.GetProto(this.props.Document)["ruleColor_" + NumCast(headingLayout.heading)] = headingLayout.backgroundColor; } }) - ) + ); } analyzeStrokes = async () => { diff --git a/src/client/views/nodes/ButtonBox.tsx b/src/client/views/nodes/ButtonBox.tsx index 68d3b8ae1..eebf6c167 100644 --- a/src/client/views/nodes/ButtonBox.tsx +++ b/src/client/views/nodes/ButtonBox.tsx @@ -49,7 +49,7 @@ export class ButtonBox extends DocComponent(Butt funcs.push({ description: "Clear Script Params", event: () => { let params = Cast(this.props.Document.buttonParams, listSpec("string")); - params && params.map(p => this.props.Document[p] = undefined) + params && params.map(p => this.props.Document[p] = undefined); }, icon: "trash" }); diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 19d4a6784..bade3f8c1 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -1,10 +1,10 @@ -import { computed, action, observable, reaction, IReactionDisposer } from "mobx"; +import { computed, action, observable, reaction, IReactionDisposer, trace } from "mobx"; import { observer } from "mobx-react"; import { createSchema, makeInterface, listSpec } from "../../../new_fields/Schema"; import { FieldValue, NumCast, StrCast, Cast } from "../../../new_fields/Types"; import { Transform } from "../../util/Transform"; import { DocComponent } from "../DocComponent"; -import { percent2frac } from "../../../Utils" +import { percent2frac } from "../../../Utils"; import { DocumentView, DocumentViewProps, documentSchema } from "./DocumentView"; import "./CollectionFreeFormDocumentView.scss"; import React = require("react"); @@ -18,7 +18,7 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { height?: number; jitterRotation: number; } -const positionSchema = createSchema({ +export const positionSchema = createSchema({ zIndex: "number", x: "number", y: "number", @@ -32,8 +32,8 @@ export const PositionDocument = makeInterface(documentSchema, positionSchema); export class CollectionFreeFormDocumentView extends DocComponent(PositionDocument) { _disposer: IReactionDisposer | undefined = undefined; @computed get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) rotate(${random(-1, 1) * this.props.jitterRotation}deg)`; } - @computed get X() { return this._animx !== undefined ? this._animx : this.renderScriptDim ? this.renderScriptDim.x : this.props.x !== undefined ? this.props.x : this.Document.x || 0; } - @computed get Y() { return this._animy !== undefined ? this._animy : this.renderScriptDim ? this.renderScriptDim.y : this.props.y !== undefined ? this.props.y : this.Document.y || 0; } + @computed get X() { return this._animPos !== undefined ? this._animPos[0] : this.renderScriptDim ? this.renderScriptDim.x : this.props.x !== undefined ? this.props.x : this.Document.x || 0; } + @computed get Y() { return this._animPos !== undefined ? this._animPos[1] : this.renderScriptDim ? this.renderScriptDim.y : this.props.y !== undefined ? this.props.y : this.Document.y || 0; } @computed get width() { return this.renderScriptDim ? this.renderScriptDim.width : this.props.width !== undefined ? this.props.width : this.props.Document[WidthSym](); } @computed get height() { return this.renderScriptDim ? this.renderScriptDim.height : this.props.height !== undefined ? this.props.height : this.props.Document[HeightSym](); } @computed get nativeWidth() { return FieldValue(this.Document.nativeWidth, 0); } @@ -59,22 +59,10 @@ export class CollectionFreeFormDocumentView extends DocComponent this.props.Document.iconTarget, + this._disposer = reaction(() => [this.props.Document.animateToPos, this.props.Document.isAnimating], () => { - const icon = this.props.Document.iconTarget ? Array.from(Cast(this.props.Document.iconTarget, listSpec("number"))!) : undefined; - if (icon) { - let target = this.props.ScreenToLocalTransform().transformPoint(icon[0], icon[1]); - if (icon[2] === 1) { - this._animx = target[0]; - this._animy = target[1]; - } - setTimeout(action(() => { - this._animx = icon[2] === 1 ? this.Document.x : target[0]; - this._animy = icon[2] === 1 ? this.Document.y : target[1]; - }), 25); - } else { - this._animx = this._animy = undefined; - } + const target = this.props.Document.animateToPos ? Array.from(Cast(this.props.Document.animateToPos, listSpec("number"))!) : undefined; + this._animPos = !target ? undefined : target[2] ? [this.Document.x || 0, this.Document.y || 0] : this.props.ScreenToLocalTransform().transformPoint(target[0], target[1]); }, { fireImmediately: true }); } @@ -83,7 +71,7 @@ export class CollectionFreeFormDocumentView extends DocComponent this.props.PanelHeight(); getTransform = (): Transform => this.props.ScreenToLocalTransform() .translate(-this.X, -this.Y) - .scale(1 / this.contentScaling()).scale(1 / this.scaleToOverridingWidth); + .scale(1 / this.contentScaling()).scale(1 / this.scaleToOverridingWidth) borderRounding = () => { let ruleRounding = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleRounding_" + this.Document.heading]) : undefined; @@ -107,8 +95,7 @@ export class CollectionFreeFormDocumentView extends DocComponent(Docu @action public collapseTargetsToPoint = (scrpt: number[], expandedDocs: Doc[] | undefined): void => { SelectionManager.DeselectAll(); - if (expandedDocs) { - let isMinimized: boolean | undefined; - expandedDocs.map(maximizedDoc => { - if (isMinimized === undefined) { - isMinimized = BoolCast(maximizedDoc.isMinimized); + expandedDocs && expandedDocs.map(expDoc => { + if (expDoc.isMinimized || expDoc.isAnimating === "min") { // MAXIMIZE DOC + if (expDoc.isMinimized) { // docs are never actaully at the minimized location. so when we unminimize one, we have to set our overrides to make it look like it was at the minimize location + expDoc.isMinimized = false; + expDoc.animateToPos = new List([...scrpt, 0]); + expDoc.animateToDimensions = new List([0, 0]); } - let w = NumCast(maximizedDoc.width); - let h = NumCast(maximizedDoc.height); - let iconAnimating = maximizedDoc.isIconAnimating ? Array.from(Cast(maximizedDoc.isIconAnimating, listSpec("number"))!) : undefined; - if (isMinimized || (iconAnimating && iconAnimating.length && iconAnimating[0] === 0)) { - // MAXIMIZE DOC - if (maximizedDoc.isMinimized) { - maximizedDoc.isIconAnimating = new List([0, 0]); - maximizedDoc.isMinimized = false; + setTimeout(() => { + expDoc.isAnimating = "max"; + expDoc.animateToPos = new List([0, 0, 1]); + expDoc.animateToDimensions = new List([NumCast(expDoc.width), NumCast(expDoc.height)]); + setTimeout(() => expDoc.isAnimating === "max" && (expDoc.isAnimating = expDoc.animateToPos = expDoc.animateToDimensions = undefined), 600); + }, 0); + } else { // MINIMIZE DOC + expDoc.isAnimating = "min"; + expDoc.animateToPos = new List([...scrpt, 0]); + expDoc.animateToDimensions = new List([0, 0]); + setTimeout(() => { + if (expDoc.isAnimating === "min") { + expDoc.isMinimized = true; + expDoc.isAnimating = expDoc.animateToPos = expDoc.animateToDimensions = undefined; } - maximizedDoc.iconTarget = new List([...scrpt, 1]); - setTimeout(() => { - maximizedDoc.isIconAnimating = new List([w, h]); - setTimeout(() => { - if (maximizedDoc.isIconAnimating && Array.from(Cast(maximizedDoc.isIconAnimating, listSpec("number"))!)[0] !== 0) { - maximizedDoc.isIconAnimating = undefined; - } - }, 750); - }, 0); - } else { - maximizedDoc.iconTarget = new List([...scrpt, 0]); - // MINIMIZE DOC - maximizedDoc.isIconAnimating = new List([0, 0]); - setTimeout(() => { - if (maximizedDoc.isIconAnimating && Array.from(Cast(maximizedDoc.isIconAnimating, listSpec("number"))!)[0] === 0) { - maximizedDoc.isMinimized = true; - maximizedDoc.isIconAnimating = undefined; - } - }, 750); - } - }); - } + }, 600); + } + }); } onClick = async (e: React.MouseEvent) => { @@ -530,14 +518,14 @@ export class DocumentView extends DocComponent(Docu let portal = existingPortal instanceof Doc ? existingPortal : Docs.Create.FreeformDocument([], { width: (this.Document.width || 0) + 10, height: this.Document.height || 0, title: portalID }); DocUtils.MakeLink(this.props.Document, portal, undefined, portalID); Doc.GetProto(this.props.Document).isButton = true; - }) + }); } } @undoBatch @action toggleCustomView = (): void => { if (this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.DataDoc) { - Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.ContainingCollectionView.props.DataDoc) + Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.ContainingCollectionView.props.DataDoc); } else { if (this.Document.type !== DocumentType.COL && this.Document.type !== DocumentType.TEMPLATE) { this.makeCustomViewClicked(); @@ -623,7 +611,7 @@ export class DocumentView extends DocComponent(Docu let layoutItems: ContextMenuProps[] = existing && "subitems" in existing ? existing.subitems : []; layoutItems.push({ description: this.Document.isBackground ? "As Foreground" : "As Background", event: this.makeBackground, icon: this.Document.lockedPosition ? "unlock" : "lock" }); if (this.props.DataDoc) { - layoutItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc!), icon: "concierge-bell" }) + layoutItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc!), icon: "concierge-bell" }); } layoutItems.push({ description: `${this.layoutDoc.chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.layoutDoc.chromeStatus = (this.layoutDoc.chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" }); layoutItems.push({ description: `${this.layoutDoc.autoHeight ? "Variable Height" : "Auto Height"}`, event: () => this.layoutDoc.autoHeight = !this.layoutDoc.autoHeight, icon: "plus" }); @@ -786,7 +774,6 @@ export class DocumentView extends DocComponent(Docu const fullDegree = Doc.isBrushedHighlightedDegree(this.props.Document); const borderRounding = this.Document.borderRounding || ruleRounding; const localScale = this.props.ScreenToLocalTransform().Scale * fullDegree; - const iconAnimating = this.Document.isIconAnimating ? Array.from(Cast(this.Document.isIconAnimating, listSpec("number"))!) : undefined; const searchHighlight = (!this.Document.searchFields ? (null) :
{this.Document.searchFields} @@ -817,7 +804,7 @@ export class DocumentView extends DocComponent(Docu
{ doc.nonCustomNativeWidth = undefined; doc.nonCustomNativeHeight = undefined; doc.nonCustomIgnoreAspect = undefined; -} +}; let makeCustomView = (doc: any): void => { doc.nativeLayout = doc.layout; doc.nativeType = doc.type; @@ -911,7 +898,7 @@ let makeCustomView = (doc: any): void => { doc.customNativeHeight = undefined; doc.customIgnoreAspect = undefined; } -} +}; Scripting.addGlobal(function toggleDetail(doc: any) { if (doc.type !== DocumentType.COL && doc.type !== DocumentType.TEMPLATE) { makeCustomView(doc); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 77e29632e..1c946aa78 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -182,9 +182,9 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe DocUtils.Publish(this.dataDoc[key] as Doc, value, this.props.addDocument, this.props.removeDocument); if (linkDoc) { (linkDoc as Doc).anchor2 = this.dataDoc[key] as Doc; } else DocUtils.MakeLink(this.dataDoc, this.dataDoc[key] as Doc, undefined, "Ref:" + value, undefined, undefined, id, true); - }) + }); }); - }) + }); this.linkOnDeselect.clear(); } @@ -195,7 +195,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe let range = tx.selection.$from.blockRange(tx.selection.$to); let text = range ? tx.doc.textBetween(range.start, range.end) : ""; let textEndSelection = tx.selection.to; - for (; textEndSelection < range!.end && text[textEndSelection - range!.start] != " "; textEndSelection++) { } + for (; textEndSelection < range!.end && text[textEndSelection - range!.start] !== " "; textEndSelection++) { } text = text.substr(0, textEndSelection - range!.start); text = text.split(" ")[text.split(" ").length - 1]; let split = text.split("::"); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index beccce9dd..42307ee02 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -23,7 +23,7 @@ import { ContextMenu } from "../../views/ContextMenu"; import { ContextMenuProps } from '../ContextMenuItem'; import { DocComponent } from '../DocComponent'; import { InkingControl } from '../InkingControl'; -import { positionSchema } from './DocumentView'; +import { documentSchema } from './DocumentView'; import FaceRectangles from './FaceRectangles'; import { FieldView, FieldViewProps } from './FieldView'; import "./ImageBox.scss"; @@ -50,8 +50,8 @@ declare class MediaRecorder { constructor(e: any); } -type ImageDocument = makeInterface<[typeof pageSchema, typeof positionSchema]>; -const ImageDocument = makeInterface(pageSchema, positionSchema); +type ImageDocument = makeInterface<[typeof pageSchema, typeof documentSchema]>; +const ImageDocument = makeInterface(pageSchema, documentSchema); @observer export class ImageBox extends DocComponent(ImageDocument) { @@ -220,7 +220,7 @@ export class ImageBox extends DocComponent(ImageD let modes: ContextMenuProps[] = existingAnalyze && "subitems" in existingAnalyze ? existingAnalyze.subitems : []; modes.push({ description: "Generate Tags", event: this.generateMetadata, icon: "tag" }); modes.push({ description: "Find Faces", event: this.extractFaces, icon: "camera" }); - !existingAnalyze && ContextMenu.Instance.addItem({ description: "Analyzers...", subitems: modes, icon: "hand-point-right" }) + !existingAnalyze && ContextMenu.Instance.addItem({ description: "Analyzers...", subitems: modes, icon: "hand-point-right" }); ContextMenu.Instance.addItem({ description: "Image Funcs...", subitems: funcs, icon: "asterisk" }); } diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index df35b603c..31e8f122b 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -14,14 +14,14 @@ import { CompileScript } from '../../util/Scripting'; import { DocComponent } from "../DocComponent"; import { InkingControl } from "../InkingControl"; import { PDFViewer } from "../pdf/PDFViewer"; -import { positionSchema } from "./DocumentView"; +import { documentSchema } from "./DocumentView"; import { FieldView, FieldViewProps } from './FieldView'; import { pageSchema } from "./ImageBox"; import "./PDFBox.scss"; import React = require("react"); -type PdfDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>; -const PdfDocument = makeInterface(positionSchema, pageSchema); +type PdfDocument = makeInterface<[typeof documentSchema, typeof pageSchema]>; +const PdfDocument = makeInterface(documentSchema, pageSchema); export const handleBackspace = (e: React.KeyboardEvent) => { if (e.keyCode === KeyCodes.BACKSPACE) e.stopPropagation(); }; @observer diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 96f011eff..a696f255d 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -14,7 +14,7 @@ import { ContextMenuProps } from "../ContextMenuItem"; import { DocComponent } from "../DocComponent"; import { DocumentDecorations } from "../DocumentDecorations"; import { InkingControl } from "../InkingControl"; -import { positionSchema } from "./DocumentView"; +import { documentSchema } from "./DocumentView"; import { FieldView, FieldViewProps } from './FieldView'; import { pageSchema } from "./ImageBox"; import "./VideoBox.scss"; @@ -25,8 +25,8 @@ import { Doc } from "../../../new_fields/Doc"; import { ScriptField } from "../../../new_fields/ScriptField"; var path = require('path'); -type VideoDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>; -const VideoDocument = makeInterface(positionSchema, pageSchema); +type VideoDocument = makeInterface<[typeof documentSchema, typeof pageSchema]>; +const VideoDocument = makeInterface(documentSchema, pageSchema); library.add(faVideo); diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index eeb2531a2..34e3b0931 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -58,7 +58,7 @@ class RegionAnnotation extends React.Component { runInAction(() => this._brushed = brushed); } } - ) + ); } componentWillUnmount() { diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 7bc1d3507..c508935f2 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -81,7 +81,7 @@ export class PDFViewer extends React.Component { return annotations.filter(anno => { let run = this._script.run({ this: anno }); return run.success ? run.result : true; - }) + }); } @computed get nonDocAnnotations() { diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 614babd3c..0cf1208d7 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -144,12 +144,12 @@ export class Doc extends RefField { private [Self] = this; private [SelfProxy]: any; public [WidthSym] = () => { - let iconAnimating = this[SelfProxy].isIconAnimating ? Array.from(Cast(this[SelfProxy].isIconAnimating, listSpec("number"))!) : undefined; - return iconAnimating ? iconAnimating[0] : NumCast(this[SelfProxy].width); + let animDims = this[SelfProxy].animateToDimensions ? Array.from(Cast(this[SelfProxy].animateToDimensions, listSpec("number"))!) : undefined; + return animDims ? animDims[0] : NumCast(this[SelfProxy].width); } public [HeightSym] = () => { - let iconAnimating = this[SelfProxy].isIconAnimating ? Array.from(Cast(this[SelfProxy].isIconAnimating, listSpec("number"))!) : undefined; - return iconAnimating ? iconAnimating[1] : NumCast(this[SelfProxy].height); + let animDims = this[SelfProxy].animateToDimensions ? Array.from(Cast(this[SelfProxy].animateToDimensions, listSpec("number"))!) : undefined; + return animDims ? animDims[1] : NumCast(this[SelfProxy].height); } [ToScriptString]() { @@ -334,7 +334,7 @@ export namespace Doc { } export function IndexOf(toFind: Doc, list: Doc[]) { - return list.findIndex(doc => doc === toFind || Doc.AreProtosEqual(doc, toFind)) + return list.findIndex(doc => doc === toFind || Doc.AreProtosEqual(doc, toFind)); } export function AddDocToList(target: Doc, key: string, doc: Doc, relativeTo?: Doc, before?: boolean, first?: boolean, allowDuplicates?: boolean, reversed?: boolean) { if (target[key] === undefined) { @@ -419,7 +419,7 @@ export namespace Doc { export function MakeAlias(doc: Doc) { let alias = !GetT(doc, "isPrototype", "boolean", true) ? Doc.MakeCopy(doc) : Doc.MakeDelegate(doc); if (alias.layout instanceof Doc) { - alias.layout = Doc.MakeAlias(alias.layout as Doc); + alias.layout = Doc.MakeAlias(alias.layout); } let aliasNumber = Doc.GetProto(doc).aliasNumber = NumCast(Doc.GetProto(doc).aliasNumber) + 1; let script = `return renameAlias(self, ${aliasNumber})`; diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index af5774ebe..8cac8550c 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -59,7 +59,7 @@ export class CurrentUserUtils { noteTypes.excludeFromLibrary = true; doc.noteTypes = noteTypes; } - PromiseValue(Cast(doc.noteTypes, Doc)).then(noteTypes => noteTypes && PromiseValue(noteTypes.data).then(vals => DocListCast(vals))); + PromiseValue(Cast(doc.noteTypes, Doc)).then(noteTypes => noteTypes && PromiseValue(noteTypes.data).then(DocListCast)); if (doc.recentlyClosed === undefined) { const recentlyClosed = Docs.Create.TreeDocument([], { title: "Recently Closed", height: 75 }); recentlyClosed.excludeFromLibrary = true; -- cgit v1.2.3-70-g09d2 From 2cdca63ac039a7c66a9c93acb35fe51467269e64 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 19 Sep 2019 11:29:11 -0400 Subject: switche calls to COllectionDockingView... to addDocTabs. fixed following links to navigate/restore properly. --- src/client/util/DocumentManager.ts | 15 ++-- src/client/util/TooltipTextMenu.tsx | 8 +- src/client/views/GlobalKeyHandler.ts | 4 +- src/client/views/MainOverlayTextBox.tsx | 4 +- src/client/views/MainView.tsx | 10 ++- src/client/views/OverlayView.tsx | 2 +- .../views/collections/CollectionBaseView.tsx | 4 +- .../views/collections/CollectionDockingView.tsx | 85 ++++++++++++---------- .../views/collections/CollectionSchemaCells.tsx | 2 +- .../views/collections/CollectionSchemaView.tsx | 4 +- .../views/collections/CollectionTreeView.tsx | 8 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 17 +++-- src/client/views/linking/LinkFollowBox.tsx | 16 ++-- src/client/views/linking/LinkMenu.tsx | 2 +- src/client/views/linking/LinkMenuGroup.tsx | 24 +++--- src/client/views/linking/LinkMenuItem.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 24 ++---- src/client/views/nodes/FieldView.tsx | 2 +- src/client/views/nodes/KeyValueBox.tsx | 2 +- src/client/views/nodes/KeyValuePair.tsx | 7 +- src/client/views/pdf/Annotation.tsx | 8 +- src/client/views/pdf/PDFViewer.tsx | 2 +- src/client/views/search/SearchItem.tsx | 4 +- 23 files changed, 127 insertions(+), 129 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index ec731da84..65ab32539 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -10,6 +10,7 @@ import { DocumentView } from '../views/nodes/DocumentView'; import { LinkManager } from './LinkManager'; import { undoBatch, UndoManager } from './UndoManager'; import { Scripting } from './Scripting'; +import { emptyFunction } from '../../Utils'; export class DocumentManager { @@ -146,6 +147,7 @@ export class DocumentManager { if (!contextDoc) { let docs = docContext ? await DocListCastAsync(docContext.data) : undefined; let found = false; + // bcz: this just searches within the context for the target -- perhaps it should recursively search through all children? docs && docs.map(d => found = found || Doc.AreProtosEqual(d, docDelegate)); if (docContext && found) { let targetContextView: DocumentView | null; @@ -154,16 +156,19 @@ export class DocumentManager { docContext.panTransformType = "Ease"; targetContextView.props.focus(docDelegate, willZoom); } else { - (dockFunc || CollectionDockingView.Instance.AddRightSplit)(docContext, undefined); + (dockFunc || CollectionDockingView.AddRightSplit)(docContext, undefined); setTimeout(() => { - this.jumpToDocument(docDelegate, willZoom, forceDockFunc, dockFunc, linkPage); - }, 10); + let dv = DocumentManager.Instance.getDocumentView(docContext); + dv && this.jumpToDocument(docDelegate, willZoom, forceDockFunc, + doc => dv!.props.focus(dv!.props.Document, true, 1, () => dv!.props.addDocTab(doc, undefined, "inPlace")), + linkPage); + }, 1050); } } else { const actualDoc = Doc.MakeAlias(docDelegate); Doc.BrushDoc(actualDoc); if (linkPage !== undefined) actualDoc.curPage = linkPage; - (dockFunc || CollectionDockingView.Instance.AddRightSplit)(actualDoc, undefined); + (dockFunc || CollectionDockingView.AddRightSplit)(actualDoc, undefined); } } else { let contextView: DocumentView | null; @@ -172,7 +177,7 @@ export class DocumentManager { contextDoc.panTransformType = "Ease"; contextView.props.focus(docDelegate, willZoom); } else { - (dockFunc || CollectionDockingView.Instance.AddRightSplit)(contextDoc, undefined); + (dockFunc || CollectionDockingView.AddRightSplit)(contextDoc, undefined); setTimeout(() => { this.jumpToDocument(docDelegate, willZoom, forceDockFunc, dockFunc, linkPage); }, 10); diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index aa096dd64..b6de048e4 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -58,10 +58,6 @@ export class TooltipTextMenu { private _collapsed: boolean = false; - @observable - private _storedMarks: Mark[] | null | undefined; - - constructor(view: EditorView, editorProps: FieldViewProps & FormattedTextBoxProps) { this.view = view; this.editorProps = editorProps; @@ -84,8 +80,6 @@ export class TooltipTextMenu { this.dragElement(dragger); - this._storedMarks = this.view.state.storedMarks; - // this.createCollapse(); // if (this._collapseBtn) { // this.tooltip.appendChild(this._collapseBtn.render(this.view).dom); @@ -280,7 +274,7 @@ export class TooltipTextMenu { if (DocumentManager.Instance.getDocumentView(f)) { DocumentManager.Instance.getDocumentView(f)!.props.focus(f, false); } - else if (CollectionDockingView.Instance) CollectionDockingView.Instance.AddRightSplit(f, undefined); + else this.editorProps.addDocTab(f, undefined, "onRight"); } })); } diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index ef5d76ce8..2fa03e969 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -141,7 +141,7 @@ export default class KeyManager { return { stopPropagation: false, preventDefault: false }; } } - MainView.Instance.mainFreeform && CollectionDockingView.Instance.AddRightSplit(MainView.Instance.mainFreeform, undefined); + MainView.Instance.mainFreeform && CollectionDockingView.AddRightSplit(MainView.Instance.mainFreeform, undefined); break; case "arrowleft": if (document.activeElement) { @@ -149,7 +149,7 @@ export default class KeyManager { return { stopPropagation: false, preventDefault: false }; } } - MainView.Instance.mainFreeform && CollectionDockingView.Instance.CloseRightSplit(MainView.Instance.mainFreeform); + MainView.Instance.mainFreeform && CollectionDockingView.CloseRightSplit(MainView.Instance.mainFreeform); break; case "backspace": if (document.activeElement) { diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index ac1b437af..f32fb584a 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -119,9 +119,7 @@ export class MainOverlayTextBox extends React.Component } addDocTab = (doc: Doc, dataDoc: Doc | undefined, location: string) => { - if (true) { // location === "onRight") { need to figure out stack to add "inTab" - CollectionDockingView.Instance.AddRightSplit(doc, dataDoc); - } + this._textBox && this._textBox.props.addDocTab(doc, dataDoc, location); } render() { this.TextDoc; this.TextDataDoc; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 8b0caf9a6..097040b6c 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -288,6 +288,7 @@ export class MainView extends React.Component { } } }, 100); + return true; } onDrop = (e: React.DragEvent) => { @@ -319,7 +320,7 @@ export class MainView extends React.Component { this.flyoutWidth; - addDocTabFunc = (doc: Doc) => { + addDocTabFunc = (doc: Doc, data: Opt, where: string) => { + if (where === "close") + return CollectionDockingView.CloseRightSplit(doc); if (doc.dockingConfig) { this.openWorkspace(doc); + return true; } else { - CollectionDockingView.Instance.AddRightSplit(doc, undefined); + return CollectionDockingView.AddRightSplit(doc, undefined); } } @computed diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index 8124ce653..45e0a3562 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -186,7 +186,7 @@ export class OverlayView extends React.Component { whenActiveChanged={emptyFunction} focus={emptyFunction} backgroundColor={returnEmptyString} - addDocTab={emptyFunction} + addDocTab={returnFalse} pinToPres={emptyFunction} ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index fdb2f0dc9..0399371ff 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -103,7 +103,6 @@ export class CollectionBaseView extends React.Component { if (this.props.fieldExt) { // bcz: fieldExt !== undefined means this is an overlay layer Doc.GetProto(doc).annotationOn = this.props.Document; } - allowDuplicates = true; let targetDataDoc = this.props.fieldExt || this.props.Document.isTemplate ? this.extensionDoc : this.props.Document; let targetField = (this.props.fieldExt || this.props.Document.isTemplate) && this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey; const value = Cast(targetDataDoc[targetField], listSpec(Doc)); @@ -126,7 +125,8 @@ export class CollectionBaseView extends React.Component { let targetDataDoc = this.props.fieldExt || this.props.Document.isTemplate ? this.extensionDoc : this.props.Document; let targetField = (this.props.fieldExt || this.props.Document.isTemplate) && this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey; let value = Cast(targetDataDoc[targetField], listSpec(Doc), []); - let index = value.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, doc)) ? i : p, -1); + let index = value.reduce((p, v, i) => (v instanceof Doc && v === doc) ? i : p, -1); + index = index !== -1 ? index : value.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, doc)) ? i : p, -1); PromiseValue(Cast(doc.annotationOn, Doc)).then(annotationOn => annotationOn === this.dataDoc.Document && (doc.annotationOn = undefined)); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index cab085d9b..277fa0066 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -1,36 +1,35 @@ +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faFile } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import 'golden-layout/src/css/goldenlayout-base.css'; import 'golden-layout/src/css/goldenlayout-dark-theme.css'; -import { action, Lambda, observable, reaction, trace, computed } from "mobx"; +import { action, computed, Lambda, observable, reaction } from "mobx"; import { observer } from "mobx-react"; import * as ReactDOM from 'react-dom'; import Measure from "react-measure"; import * as GoldenLayout from "../../../client/goldenLayout"; +import { DateField } from '../../../new_fields/DateField'; import { Doc, DocListCast, Field, Opt } from "../../../new_fields/Doc"; import { Id } from '../../../new_fields/FieldSymbols'; +import { List } from '../../../new_fields/List'; import { FieldId } from "../../../new_fields/RefField"; import { listSpec } from "../../../new_fields/Schema"; -import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types"; -import { emptyFunction, returnTrue, Utils, returnOne, returnEmptyString } from "../../../Utils"; +import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types"; +import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils'; +import { emptyFunction, returnEmptyString, returnFalse, returnOne, returnTrue, Utils } from "../../../Utils"; import { DocServer } from "../../DocServer"; +import { Docs } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { DragLinksAsDocuments, DragManager } from "../../util/DragManager"; import { SelectionManager } from '../../util/SelectionManager'; import { Transform } from '../../util/Transform'; -import { undoBatch, UndoManager } from "../../util/UndoManager"; +import { undoBatch } from "../../util/UndoManager"; +import { MainView } from '../MainView'; import { DocumentView } from "../nodes/DocumentView"; import "./CollectionDockingView.scss"; import { SubCollectionViewProps } from "./CollectionSubView"; import { ParentDocSelector } from './ParentDocumentSelector'; import React = require("react"); -import { MainView } from '../MainView'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { library } from '@fortawesome/fontawesome-svg-core'; -import { faFile, faUnlockAlt } from '@fortawesome/free-solid-svg-icons'; -import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils'; -import { Docs } from '../../documents/Documents'; -import { DateField } from '../../../new_fields/DateField'; -import { List } from '../../../new_fields/List'; -import { DocumentType } from '../../documents/DocumentTypes'; library.add(faFile); @observer @@ -59,7 +58,7 @@ export class CollectionDockingView extends React.Component { + public static CloseRightSplit(document: Doc): boolean { + if (!CollectionDockingView.Instance) return false; + let instance = CollectionDockingView.Instance; let retVal = false; - if (this._goldenLayout.root.contentItems[0].isRow) { - retVal = Array.from(this._goldenLayout.root.contentItems[0].contentItems).some((child: any) => { + if (instance._goldenLayout.root.contentItems[0].isRow) { + retVal = Array.from(instance._goldenLayout.root.contentItems[0].contentItems).some((child: any) => { if (child.contentItems.length === 1 && child.contentItems[0].config.component === "DocumentFrameRenderer" && + DocumentManager.Instance.getDocumentViewById(child.contentItems[0].config.props.documentId) && Doc.AreProtosEqual(DocumentManager.Instance.getDocumentViewById(child.contentItems[0].config.props.documentId)!.Document, document)) { child.contentItems[0].remove(); - this.layoutChanged(document); + instance.layoutChanged(document); return true; } else { Array.from(child.contentItems).filter((tab: any) => tab.config.component === "DocumentFrameRenderer").some((tab: any, j: number) => { - if (Doc.AreProtosEqual(DocumentManager.Instance.getDocumentViewById(tab.config.props.documentId)!.Document, document)) { + if (DocumentManager.Instance.getDocumentViewById(tab.config.props.documentId) && + Doc.AreProtosEqual(DocumentManager.Instance.getDocumentViewById(tab.config.props.documentId)!.Document, document)) { child.contentItems[j].remove(); child.config.activeItemIndex = Math.max(child.contentItems.length - 1, 0); - let docs = Cast(this.props.Document.data, listSpec(Doc)); + let docs = Cast(instance.props.Document.data, listSpec(Doc)); docs && docs.indexOf(document) !== -1 && docs.splice(docs.indexOf(document), 1); return true; } @@ -146,7 +149,7 @@ export class CollectionDockingView extends React.Component { - let docs = Cast(this.props.Document.data, listSpec(Doc)); + public static AddRightSplit(document: Doc, dataDoc: Doc | undefined, minimize: boolean = false) { + if (!CollectionDockingView.Instance) return false; + let instance = CollectionDockingView.Instance; + let docs = Cast(instance.props.Document.data, listSpec(Doc)); if (docs) { docs.push(document); } @@ -183,15 +188,15 @@ export class CollectionDockingView extends React.Component, dragSpan); - ReactDOM.render( CollectionDockingView.Instance.AddTab(stack, doc, dataDoc)} />, upDiv); + ReactDOM.render( { + where === "onRight" ? CollectionDockingView.AddRightSplit(doc, dataDoc) : CollectionDockingView.Instance.AddTab(stack, doc, dataDoc); + return true; + }} />, upDiv); tab.reactComponents = [dragSpan, upDiv]; tab.element.append(dragSpan); tab.element.append(upDiv); @@ -604,15 +612,16 @@ export class DockedFrameRenderer extends React.Component { } get previewPanelCenteringOffset() { return this.nativeWidth() && !BoolCast(this._document!.ignoreAspect) ? (this._panelWidth - this.nativeWidth()) / 2 : 0; } - addDocTab = (doc: Doc, dataDoc: Doc | undefined, location: string) => { + addDocTab = (doc: Doc, dataDoc: Opt, location: string) => { if (doc.dockingConfig) { MainView.Instance.openWorkspace(doc); + return true; } else if (location === "onRight") { - CollectionDockingView.Instance.AddRightSplit(doc, dataDoc); + return CollectionDockingView.AddRightSplit(doc, dataDoc); } else if (location === "close") { - CollectionDockingView.Instance.CloseRightSplit(doc); + return CollectionDockingView.CloseRightSplit(doc); } else { - CollectionDockingView.Instance.AddTab(this._stack, doc, dataDoc); + return CollectionDockingView.Instance.AddTab(this._stack, doc, dataDoc); } } @computed get docView() { diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 059967a7d..0306d415c 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -39,7 +39,7 @@ export interface CellProps { Document: Doc; fieldKey: string; renderDepth: number; - addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; + addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; pinToPres: (document: Doc) => void; moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean; isFocused: boolean; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index a742054d0..7bd2a1971 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -256,7 +256,7 @@ export interface SchemaTableProps { ScreenToLocalTransform: () => Transform; active: () => boolean; onDrop: (e: React.DragEvent, options: DocumentOptions, completed?: (() => void) | undefined) => void; - addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; + addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; pinToPres: (document: Doc) => void; isSelected: () => boolean; isFocused: (document: Doc) => boolean; @@ -915,7 +915,7 @@ interface CollectionSchemaPreviewProps { removeDocument: (document: Doc) => boolean; active: () => boolean; whenActiveChanged: (isActive: boolean) => void; - addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; + addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; pinToPres: (document: Doc) => void; setPreviewScript: (script: string) => void; previewScript?: string; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index b4026a810..08d87c7b2 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -40,7 +40,7 @@ export interface TreeViewProps { ruleProvider: Doc | undefined; moveDocument: DragManager.MoveFunction; dropAction: "alias" | "copy" | undefined; - addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => void; + addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => boolean; pinToPres: (document: Doc) => void; panelWidth: () => number; panelHeight: () => number; @@ -414,7 +414,7 @@ class TreeView extends React.Component { remove: ((doc: Doc) => boolean), move: DragManager.MoveFunction, dropAction: dropActionType, - addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => void, + addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => boolean, pinToPres: (document: Doc) => void, screenToLocalXf: () => Transform, outerXf: () => { translateX: number, translateY: number }, @@ -562,8 +562,8 @@ export class CollectionTreeView extends CollectionSubView(Document) { outerXf = () => Utils.GetScreenTransform(this._mainEle!); onTreeDrop = (e: React.DragEvent) => this.onDrop(e, {}); openNotifsCol = () => { - if (CollectionTreeView.NotifsCol && CollectionDockingView.Instance) { - CollectionDockingView.Instance.AddRightSplit(CollectionTreeView.NotifsCol, undefined); + if (CollectionTreeView.NotifsCol) { + this.props.addDocTab(CollectionTreeView.NotifsCol, undefined, "onRight"); } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index ad77e0428..7383c5551 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -508,14 +508,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { }); } - let panelDim = this.props.ScreenToLocalTransform().transformDirection(this._pwidth / this.zoomScaling(), - this._pheight / this.zoomScaling()); - let panelwidth = panelDim[0]; - let panelheight = panelDim[1]; - if (ranges[0][0] - dx > (this.panX() + panelwidth / 2)) x = ranges[0][1] + panelwidth / 2; - if (ranges[0][1] - dx < (this.panX() - panelwidth / 2)) x = ranges[0][0] - panelwidth / 2; - if (ranges[1][0] - dy > (this.panY() + panelheight / 2)) y = ranges[1][1] + panelheight / 2; - if (ranges[1][1] - dy < (this.panY() - panelheight / 2)) y = ranges[1][0] - panelheight / 2; + let cscale = this.props.ContainingCollectionDoc ? NumCast(this.props.ContainingCollectionDoc.scale) : 1; + let panelDim = this.props.ScreenToLocalTransform().transformDirection(this._pwidth / this.zoomScaling() * cscale, + this._pheight / this.zoomScaling() * cscale); + if (ranges[0][0] - dx > (this.panX() + panelDim[0] / 2)) x = ranges[0][1] + panelDim[0] / 2; + if (ranges[0][1] - dx < (this.panX() - panelDim[0] / 2)) x = ranges[0][0] - panelDim[0] / 2; + if (ranges[1][0] - dy > (this.panY() + panelDim[1] / 2)) y = ranges[1][1] + panelDim[1] / 2; + if (ranges[1][1] - dy < (this.panY() - panelDim[1] / 2)) y = ranges[1][0] - panelDim[1] / 2; } this.setPan(x - dx, y - dy); this._lastX = e.pageX; @@ -613,8 +612,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { if (willZoom) { this.setScaleToZoom(doc, scale); } + console.log("Focused " + this.Document.title + " " + s); afterFocus && setTimeout(() => { if (afterFocus && afterFocus()) { + console.log("UnFocused " + this.Document.title + " " + s); this.Document.panX = px; this.Document.panY = py; this.Document.scale = s; diff --git a/src/client/views/linking/LinkFollowBox.tsx b/src/client/views/linking/LinkFollowBox.tsx index d7cb2585e..81b0249dd 100644 --- a/src/client/views/linking/LinkFollowBox.tsx +++ b/src/client/views/linking/LinkFollowBox.tsx @@ -2,7 +2,7 @@ import { observable, computed, action, runInAction, reaction, IReactionDisposer import React = require("react"); import { observer } from "mobx-react"; import { FieldViewProps, FieldView } from "../nodes/FieldView"; -import { Doc, DocListCastAsync } from "../../../new_fields/Doc"; +import { Doc, DocListCastAsync, Opt } from "../../../new_fields/Doc"; import { undoBatch } from "../../util/UndoManager"; import { NumCast, FieldValue, Cast, StrCast } from "../../../new_fields/Types"; import { CollectionViewType } from "../collections/CollectionBaseView"; @@ -195,9 +195,9 @@ export class LinkFollowBox extends React.Component { } - _addDocTab: (undefined | ((doc: Doc, dataDoc: Doc | undefined, where: string) => void)); + _addDocTab: (undefined | ((doc: Doc, dataDoc: Opt, where: string) => boolean)); - setAddDocTab = (addFunc: (doc: Doc, dataDoc: Doc | undefined, where: string) => void) => { + setAddDocTab = (addFunc: (doc: Doc, dataDoc: Opt, where: string) => boolean) => { this._addDocTab = addFunc; } @@ -211,7 +211,7 @@ export class LinkFollowBox extends React.Component { options.context.panX = newPanX; options.context.panY = newPanY; } - CollectionDockingView.Instance.AddRightSplit(options.context, undefined); + (this._addDocTab || this.props.addDocTab)(options.context, undefined, "onRight"); if (options.shouldZoom) this.jumpToLink({ shouldZoom: options.shouldZoom }); @@ -224,7 +224,7 @@ export class LinkFollowBox extends React.Component { openLinkRight = () => { if (LinkFollowBox.destinationDoc) { let alias = Doc.MakeAlias(LinkFollowBox.destinationDoc); - CollectionDockingView.Instance.AddRightSplit(alias, undefined); + (this._addDocTab || this.props.addDocTab)(alias, undefined, "onRight"); this.highlightDoc(); SelectionManager.DeselectAll(); } @@ -244,7 +244,7 @@ export class LinkFollowBox extends React.Component { let sourceContext = await Cast(proto.sourceContext, Doc); const shouldZoom = options ? options.shouldZoom : false; - let dockingFunc = (document: Doc) => { this._addDocTab && this._addDocTab(document, undefined, "inTab"); SelectionManager.DeselectAll(); }; + let dockingFunc = (document: Doc) => { (this._addDocTab || this.props.addDocTab)(document, undefined, "inTab"); SelectionManager.DeselectAll(); }; if (LinkFollowBox.destinationDoc === LinkFollowBox.linkDoc.anchor2 && targetContext) { DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, false, async document => dockingFunc(document), undefined, targetContext); @@ -271,7 +271,7 @@ export class LinkFollowBox extends React.Component { if (LinkFollowBox.destinationDoc) { let fullScreenAlias = Doc.MakeAlias(LinkFollowBox.destinationDoc); // this.prosp.addDocTab is empty -- use the link source's addDocTab - this._addDocTab && this._addDocTab(fullScreenAlias, undefined, "inTab"); + (this._addDocTab || this.props.addDocTab)(fullScreenAlias, undefined, "inTab"); this.highlightDoc(); SelectionManager.DeselectAll(); @@ -288,7 +288,7 @@ export class LinkFollowBox extends React.Component { options.context.panX = newPanX; options.context.panY = newPanY; } - this._addDocTab && this._addDocTab(options.context, undefined, "inTab"); + (this._addDocTab || this.props.addDocTab)(options.context, undefined, "inTab"); if (options.shouldZoom) this.jumpToLink({ shouldZoom: options.shouldZoom }); this.highlightDoc(); diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx index 842ce45b1..27af873b5 100644 --- a/src/client/views/linking/LinkMenu.tsx +++ b/src/client/views/linking/LinkMenu.tsx @@ -16,7 +16,7 @@ library.add(faTrash); interface Props { docView: DocumentView; changeFlyout: () => void; - addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; + addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; } @observer diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx index d711ac284..1891919ce 100644 --- a/src/client/views/linking/LinkMenuGroup.tsx +++ b/src/client/views/linking/LinkMenuGroup.tsx @@ -1,27 +1,25 @@ -import { action, observable } from "mobx"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { action } from "mobx"; import { observer } from "mobx-react"; -import { DocumentView } from "../nodes/DocumentView"; -import { LinkMenuItem } from "./LinkMenuItem"; -import { LinkEditor } from "./LinkEditor"; -import './LinkMenu.scss'; -import React = require("react"); -import { Doc, DocListCast } from "../../../new_fields/Doc"; +import { Doc } from "../../../new_fields/Doc"; import { Id } from "../../../new_fields/FieldSymbols"; -import { LinkManager } from "../../util/LinkManager"; -import { DragLinksAsDocuments, DragManager, SetupDrag } from "../../util/DragManager"; +import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField"; import { emptyFunction } from "../../../Utils"; import { Docs } from "../../documents/Documents"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { DragManager, SetupDrag } from "../../util/DragManager"; +import { LinkManager } from "../../util/LinkManager"; import { UndoManager } from "../../util/UndoManager"; -import { StrCast } from "../../../new_fields/Types"; -import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeaderField"; +import { DocumentView } from "../nodes/DocumentView"; +import './LinkMenu.scss'; +import { LinkMenuItem } from "./LinkMenuItem"; +import React = require("react"); interface LinkMenuGroupProps { sourceDoc: Doc; group: Doc[]; groupType: string; showEditor: (linkDoc: Doc) => void; - addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; + addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; docView: DocumentView; } diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 19a0023e9..82fe3df23 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -21,7 +21,7 @@ interface LinkMenuItemProps { sourceDoc: Doc; destinationDoc: Doc; showEditor: (linkDoc: Doc) => void; - addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; + addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; } @observer diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 4a37457c0..50691fd38 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -86,7 +86,7 @@ export interface DocumentViewProps { parentActive: () => boolean; whenActiveChanged: (isActive: boolean) => void; bringToFront: (doc: Doc, sendToBack?: boolean) => void; - addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => void; + addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => boolean; pinToPres: (document: Doc) => void; collapseToPoint?: (scrpt: number[], expandedDocs: Doc[] | undefined) => void; zoomToScale: (scale: number) => void; @@ -242,23 +242,13 @@ export class DocumentView extends DocComponent(Docu if (expandedDocs.length) { SelectionManager.DeselectAll(); let maxLocation = StrCast(this.Document.maximizeLocation, "inPlace"); - if (altKey || ctrlKey) { - maxLocation = this.Document.maximizeLocation = (ctrlKey ? maxLocation : (maxLocation === "inPlace" ? "inTab" : "inPlace")); - if (maxLocation === "inPlace") { - let hadView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedDocs[0], this.props.ContainingCollectionView); - let wasMinimized = !hadView && expandedDocs.reduce((min, d) => !min && !d.isMinimized, false); - expandedDocs.forEach(maxDoc => maxDoc.isMinimized = false); - let hasView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedDocs[0], this.props.ContainingCollectionView); - !hasView && expandedDocs.forEach(async maxDoc => this.props.addDocument && this.props.addDocument(maxDoc, false)); - expandedDocs.forEach(maxDoc => maxDoc.isMinimized = wasMinimized); - } - } - if (maxLocation !== "inPlace" && CollectionDockingView.Instance) { - expandedDocs.forEach(maxDoc => - (!CollectionDockingView.Instance.CloseRightSplit(maxDoc) && this.props.addDocTab(maxDoc, undefined, maxLocation))); - } else { + maxLocation = this.Document.maximizeLocation = (!ctrlKey ? !altKey ? maxLocation : (maxLocation !== "inPlace" ? "inPlace" : "onRight") : (maxLocation !== "inPlace" ? "inPlace" : "inTab")); + if (maxLocation === "inPlace") { + expandedDocs.forEach(maxDoc => this.props.addDocument && this.props.addDocument(maxDoc, false)); let scrpt = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint(NumCast(this.Document.width) / 2, NumCast(this.Document.height) / 2); this.collapseTargetsToPoint(scrpt, expandedDocs); + } else { + expandedDocs.forEach(maxDoc => (!this.props.addDocTab(maxDoc, undefined, "close") && this.props.addDocTab(maxDoc, undefined, maxLocation))); } } else if (linkedDocs.length) { @@ -277,7 +267,7 @@ export class DocumentView extends DocComponent(Docu let targetContext = !Doc.AreProtosEqual(linkedFwdContextDocs[altKey ? 1 : 0], this.props.ContainingCollectionDoc) ? linkedFwdContextDocs[altKey ? 1 : 0] : undefined; DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, false, // open up target if it's not already in view ... by zooming into the button document first and setting flag to reset zoom afterwards - doc => this.props.focus(this.props.Document, true, 1, () => { this.props.addDocTab(doc, undefined, maxLocation); return true; }), + doc => this.props.focus(this.props.Document, true, 1, () => this.props.addDocTab(doc, undefined, maxLocation)), linkedFwdPage[altKey ? 1 : 0], targetContext); } } diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index faf11e9be..49fc2263d 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -39,7 +39,7 @@ export interface FieldViewProps { select: (isCtrlPressed: boolean) => void; renderDepth: number; addDocument?: (document: Doc, allowDuplicates?: boolean) => boolean; - addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; + addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; pinToPres: (document: Doc) => void; removeDocument?: (document: Doc) => boolean; moveDocument?: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean; diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index ee70942de..8fcd44f46 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -124,7 +124,7 @@ export class KeyValueBox extends React.Component { let i = 0; const self = this; for (let key of Object.keys(ids).slice().sort()) { - rows.push( { if (oldEl) self.rows.splice(self.rows.indexOf(oldEl), 1); diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index c7e0f51d7..1fed4c8bb 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -1,7 +1,7 @@ import { action, observable } from 'mobx'; import { observer } from "mobx-react"; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app -import { Doc, Field } from '../../../new_fields/Doc'; +import { Doc, Field, Opt } from '../../../new_fields/Doc'; import { emptyFunction, returnFalse, returnOne, returnZero } from '../../../Utils'; import { Docs } from '../../documents/Documents'; import { Transform } from '../../util/Transform'; @@ -22,6 +22,7 @@ export interface KeyValuePairProps { keyName: string; doc: Doc; keyWidth: number; + addDocTab: (doc: Doc, data: Opt, where: string) => boolean; } @observer export class KeyValuePair extends React.Component { @@ -45,7 +46,7 @@ export class KeyValuePair extends React.Component { if (value instanceof Doc) { e.stopPropagation(); e.preventDefault(); - ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { let kvp = Docs.Create.KVPDocument(value, { width: 300, height: 300 }); CollectionDockingView.Instance.AddRightSplit(kvp, undefined); }, icon: "layer-group" }); + ContextMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(value, { width: 300, height: 300 }), undefined, "onRight"), icon: "layer-group" }); ContextMenu.Instance.displayMenu(e.clientX, e.clientY); } } @@ -68,7 +69,7 @@ export class KeyValuePair extends React.Component { focus: emptyFunction, PanelWidth: returnZero, PanelHeight: returnZero, - addDocTab: returnZero, + addDocTab: returnFalse, pinToPres: returnZero, ContentScaling: returnOne }; diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index 34e3b0931..a9fa883c8 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -1,20 +1,18 @@ import React = require("react"); import { action, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCast, HeightSym, WidthSym } from "../../../new_fields/Doc"; +import { Doc, DocListCast, HeightSym, WidthSym, Opt } from "../../../new_fields/Doc"; import { Id } from "../../../new_fields/FieldSymbols"; import { List } from "../../../new_fields/List"; import { Cast, FieldValue, NumCast, StrCast } from "../../../new_fields/Types"; import { DocumentManager } from "../../util/DocumentManager"; import PDFMenu from "./PDFMenu"; import "./Annotation.scss"; -import { scale } from "./PDFViewer"; -import { PresBox } from "../nodes/PresBox"; interface IAnnotationProps { anno: Doc; fieldExtensionDoc: Doc; - addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; + addDocTab: (document: Doc, dataDoc: Opt, where: string) => boolean; pinToPres: (document: Doc) => void; } @@ -31,7 +29,7 @@ interface IRegionAnnotationProps { width: number; height: number; fieldExtensionDoc: Doc; - addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; + addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; pinToPres: (document: Doc) => void; document: Doc; } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index c508935f2..19ef713c2 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -35,7 +35,7 @@ interface IViewerProps { scrollTo: (y: number) => void; active: () => boolean; setPanY?: (n: number) => void; - addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; + addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; pinToPres: (document: Doc) => void; addDocument?: (doc: Doc, allowDuplicates?: boolean) => boolean; } diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index b2e886d95..96eefacc2 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -76,7 +76,7 @@ export class SelectorContextMenu extends React.Component { col.panX = newPanX; col.panY = newPanY; } - CollectionDockingView.Instance.AddRightSplit(col, undefined); + CollectionDockingView.AddRightSplit(col, undefined); }; } render() { @@ -110,7 +110,7 @@ export class LinkContextMenu extends React.Component { unHighlightDoc = (doc: Doc) => () => Doc.UnBrushDoc(doc); - getOnClick = (col: Doc) => () => CollectionDockingView.Instance.AddRightSplit(col, undefined); + getOnClick = (col: Doc) => () => CollectionDockingView.AddRightSplit(col, undefined); render() { return ( -- cgit v1.2.3-70-g09d2 From 6f7936d5c71bf3c802d73f47b19abe96c6d61848 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 20 Sep 2019 15:11:30 -0400 Subject: simplified script execution api a little. fixed dataDoc() related stuff in various Box's. fixed some template stuff. --- src/client/util/Scripting.ts | 8 ++-- src/client/util/SelectionManager.ts | 4 ++ src/client/views/DocumentButtonBar.tsx | 2 +- src/client/views/ScriptingRepl.tsx | 20 ++++---- src/client/views/TemplateMenu.tsx | 11 ++++- .../views/collections/CollectionBaseView.tsx | 4 +- .../views/collections/CollectionSchemaCells.tsx | 10 ++-- src/client/views/collections/CollectionSubView.tsx | 40 ++++++---------- .../views/collections/CollectionTreeView.tsx | 13 +---- .../collectionFreeForm/CollectionFreeFormView.tsx | 56 +++++++++++----------- .../collections/collectionFreeForm/MarqueeView.tsx | 14 ++---- .../views/nodes/CollectionFreeFormDocumentView.tsx | 4 +- src/client/views/nodes/DocumentView.tsx | 29 +++++++---- src/client/views/nodes/DragBox.tsx | 8 ++-- src/client/views/nodes/FormattedTextBox.tsx | 7 ++- src/client/views/nodes/ImageBox.tsx | 6 +-- src/client/views/nodes/KeyValueBox.tsx | 2 +- src/client/views/nodes/PDFBox.tsx | 22 ++++----- src/client/views/nodes/VideoBox.tsx | 2 +- src/client/views/pdf/PDFAnnotationLayer.scss | 6 --- src/client/views/pdf/PDFAnnotationLayer.tsx | 21 -------- src/client/views/pdf/PDFViewer.tsx | 17 ++----- src/debug/Repl.tsx | 8 +--- src/new_fields/Doc.ts | 6 +-- src/new_fields/ScriptField.ts | 5 +- 25 files changed, 136 insertions(+), 189 deletions(-) delete mode 100644 src/client/views/pdf/PDFAnnotationLayer.scss delete mode 100644 src/client/views/pdf/PDFAnnotationLayer.tsx (limited to 'src/client/views/pdf') diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index 1d0916ac0..ff4451824 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -19,6 +19,7 @@ export interface ScriptSucccess { export interface ScriptError { success: false; error: any; + result: any; } export type ScriptResult = ScriptSucccess | ScriptError; @@ -27,7 +28,7 @@ export interface CompiledScript { readonly compiled: true; readonly originalScript: string; readonly options: Readonly; - run(args?: { [name: string]: any }): ScriptResult; + run(args?: { [name: string]: any }, onError?: (res: any) => void, errorVal?: any): ScriptResult; } export interface CompileError { @@ -100,7 +101,7 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an // let params: any[] = [Docs, ...fieldTypes]; let compiledFunction = new Function(...paramNames, `return ${script}`); let { capturedVariables = {} } = options; - let run = (args: { [name: string]: any } = {}): ScriptResult => { + let run = (args: { [name: string]: any } = {}, onError?: (e: any) => void, errorVal?: any): ScriptResult => { let argsArray: any[] = []; for (let name of customParams) { if (name === "this") { @@ -127,7 +128,8 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an if (batch) { batch.end(); } - return { success: false, error }; + onError && onError(error); + return { success: false, error, result: errorVal }; } }; return { compiled: true, run, originalScript, options }; diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 9efef888d..4c97a1056 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -24,6 +24,10 @@ export namespace SelectionManager { manager.SelectedDocuments.push(docView); // console.log(manager.SelectedDocuments); docView.props.whenActiveChanged(true); + } else if (!ctrlPressed && manager.SelectedDocuments.length > 1) { + manager.SelectedDocuments.map(dv => dv !== docView && dv.props.whenActiveChanged(false)); + manager.SelectedDocuments = [docView]; + FormattedTextBox.InputBoxOverlay = undefined; } } @action diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 6c29a2dc7..b482e3298 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -339,7 +339,7 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[], let templates: Map = new Map(); Array.from(Object.values(Templates.TemplateList)).map(template => - templates.set(template, this.props.views.reduce((checked, doc) => checked || (doc.props.Document["show" + template.Name] ? true : false), false as boolean))); + templates.set(template, this.props.views.reduce((checked, doc) => checked || doc.getLayoutPropStr("show" + template.Name) ? true : false, false as boolean))); return (
diff --git a/src/client/views/ScriptingRepl.tsx b/src/client/views/ScriptingRepl.tsx index e05195ca0..1eb380e0b 100644 --- a/src/client/views/ScriptingRepl.tsx +++ b/src/client/views/ScriptingRepl.tsx @@ -135,19 +135,17 @@ export class ScriptingRepl extends React.Component { this.commands.push({ command: this.commandString, result: script.errors }); return; } - const result = script.run({ args: this.args }); - if (!result.success) { - this.commands.push({ command: this.commandString, result: result.error.toString() }); - return; - } - this.commands.push({ command: this.commandString, result: result.result }); - this.commandsHistory.push(this.commandString); + const result = script.run({ args: this.args }, e => this.commands.push({ command: this.commandString, result: e.toString() })); + if (result.success) { + this.commands.push({ command: this.commandString, result: result.result }); + this.commandsHistory.push(this.commandString); - this.maybeScrollToBottom(); + this.maybeScrollToBottom(); - this.commandString = ""; - this.commandBuffer = ""; - this.historyIndex = -1; + this.commandString = ""; + this.commandBuffer = ""; + this.historyIndex = -1; + } break; } case "ArrowUp": { diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index bfb8168e4..e4ef8313d 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -98,7 +98,14 @@ export class TemplateMenu extends React.Component { @undoBatch @action clearTemplates = (event: React.MouseEvent) => { - Templates.TemplateList.map(template => this.props.docs.map(d => d.Document["show" + template.Name] = undefined)); + Templates.TemplateList.forEach(template => this.props.docs.forEach(d => d.Document["show" + template.Name] = undefined)); + ["backgroundColor", "borderRounding", "width", "height"].forEach(field => this.props.docs.forEach(d => { + if (d.Document.isTemplate && d.props.DataDoc) { + d.Document[field] = undefined; + } else if (d.Document["default" + field[0].toUpperCase() + field.slice(1)] !== undefined) { + d.Document[field] = Doc.GetProto(d.Document)[field] = undefined; + } + })); } @action @@ -128,7 +135,7 @@ export class TemplateMenu extends React.Component {
this.toggleTemplateActivity()}>+
    {templateMenu} - {/* */} + {}
); diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 0399371ff..56d12bd84 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -79,7 +79,7 @@ export class CollectionBaseView extends React.Component { } } - @computed get dataDoc() { return Doc.resolvedFieldDataDoc(BoolCast(this.props.Document.isTemplate) ? this.props.DataDoc ? this.props.DataDoc : this.props.Document : this.props.Document, this.props.fieldKey, this.props.fieldExt); } + @computed get dataDoc() { return Doc.fieldExtensionDoc(this.props.Document.isTemplate && this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, this.props.fieldExt); } @computed get dataField() { return this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey; } active = (): boolean => { @@ -94,7 +94,7 @@ export class CollectionBaseView extends React.Component { this.props.whenActiveChanged(isActive); } - @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, this.props.fieldExt); } + @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, this.props.fieldExt); } @action.bound addDocument(doc: Doc, allowDuplicates: boolean = false): boolean { diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 0306d415c..4dac27e60 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -238,13 +238,11 @@ export class CollectionSchemaCell extends React.Component { return this.applyToDoc(props.Document, this.props.row, this.props.col, script.run); }} OnFillDown={async (value: string) => { - let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } }); - if (!script.compiled) { - return; + const script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } }); + if (script.compiled) { + DocListCast(this.props.Document[this.props.fieldKey]). + forEach((doc, i) => this.applyToDoc(doc, i, this.props.col, script.run)); } - const run = script.run; - const val = await DocListCastAsync(this.props.Document[this.props.fieldKey]); - val && val.forEach((doc, i) => this.applyToDoc(doc, i, this.props.col, run)); }} />
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 804bfa2b2..774e6b1b9 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -40,6 +40,8 @@ export interface SubCollectionViewProps extends CollectionViewProps { export function CollectionSubView(schemaCtor: (doc: Doc) => T) { class CollectionSubView extends DocComponent(schemaCtor) { private dropDisposer?: DragManager.DragDropDisposer; + private _childLayoutDisposer?: IReactionDisposer; + protected createDropTarget = (ele: HTMLDivElement) => { this.dropDisposer && this.dropDisposer(); if (ele) { @@ -50,8 +52,6 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { this.createDropTarget(ele); } - _childLayoutDisposer?: IReactionDisposer; - componentDidMount() { this._childLayoutDisposer = reaction(() => [this.childDocs, Cast(this.props.Document.childLayout, Doc)], async (args) => args[1] instanceof Doc && @@ -62,35 +62,25 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { this._childLayoutDisposer && this._childLayoutDisposer(); } - @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(BoolCast(this.props.Document.isTemplate) && this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, this.props.fieldExt); } + // The data field for rendeing this collection will be on the this.props.Document unless we're rendering a template in which case we try to use props.DataDoc. + // When a document has a DataDoc but it's not a template, then it contains its own rendering data, but needs to pass the DataDoc through + // to its children which may be templates. + // The name of the data field comes from fieldExt if it's an extension, or fieldKey otherwise. + @computed get dataField() { + return Doc.fieldExtensionDoc(this.props.Document.isTemplate && this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, this.props.fieldExt)[this.props.fieldExt || this.props.fieldKey]; + } get childLayoutPairs() { return this.childDocs.map(cd => Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, cd)).filter(pair => pair.layout).map(pair => ({ layout: pair.layout!, data: pair.data! })); } - get childDocs() { - //TODO tfs: This might not be what we want? - //This linter error can't be fixed because of how js arguments work, so don't switch this to filter(FieldValue) - let docs = DocListCast(this.extensionDoc[this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey]); - let viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField); - if (viewSpecScript) { - let script = viewSpecScript.script; - docs = docs.filter(d => { - let res = script.run({ doc: d }); - if (res.success) { - return res.result; - } - else { - console.log(res.error); - } - }); - } - return docs; - } get childDocList() { - //TODO tfs: This might not be what we want? - //This linter error can't be fixed because of how js arguments work, so don't switch this to filter(FieldValue) - return Cast(this.extensionDoc[this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey], listSpec(Doc)); + return Cast(this.dataField, listSpec(Doc)); + } + get childDocs() { + let docs = DocListCast(this.dataField); + const viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField); + return viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs; } @action diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 08d87c7b2..e5313f68c 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -425,18 +425,9 @@ class TreeView extends React.Component { preventTreeViewOpen: boolean, renderedIds: string[] ) { - let viewSpecScript = Cast(containingCollection.viewSpecScript, ScriptField); + const viewSpecScript = Cast(containingCollection.viewSpecScript, ScriptField); if (viewSpecScript) { - let script = viewSpecScript.script; - docs = docs.filter(d => { - let res = script.run({ doc: d }); - if (res.success) { - return res.result; - } - else { - console.log(res.error); - } - }); + docs = docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result); } let ascending = Cast(containingCollection.sortAscending, "boolean", null); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 7383c5551..36e62842c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -156,6 +156,7 @@ export namespace PivotView { y={pos.y} width={pos.width} height={pos.height} + transition={"transform 1s"} jitterRotation={NumCast(target.props.Document.jitterRotation)} {...target.getChildDocumentViewProps(doc)} />, @@ -183,11 +184,9 @@ const PanZoomDocument = makeInterface(panZoomSchema, documentSchema, positionSch export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { private _lastX: number = 0; private _lastY: number = 0; - private _inkKey = "ink"; // the document key used to store ink annotation strokes private get _pwidth() { return this.props.PanelWidth(); } private get _pheight() { return this.props.PanelHeight(); } - - get parentScaling() { + private get parentScaling() { return (this.props as any).ContentScaling && this.fitToBox && !this.isAnnotationOverlay ? (this.props as any).ContentScaling() : 1; } @@ -264,7 +263,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } @computed get fieldExtensionDoc() { - return Doc.resolvedFieldDataDoc(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, "true"); + return Doc.fieldExtensionDoc(this.props.DataDoc || this.props.Document, this.props.fieldKey); } intersectRect(r1: { left: number, top: number, width: number, height: number }, @@ -700,10 +699,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { }; } - getCalculatedPositions(script: ScriptField, params: { doc: Doc, index: number, collection: Doc, docs: Doc[], state: any }): { x?: number, y?: number, z?: number, width?: number, height?: number, state?: any } { - const result = script.script.run(params); - return !result.success ? {} : result.result !== undefined ? result.result : - { x: Cast(params.doc.x, "number"), y: Cast(params.doc.y, "number"), z: Cast(params.doc.z, "number"), width: Cast(params.doc.width, "number"), height: Cast(params.doc.height, "number") }; + getCalculatedPositions(params: { doc: Doc, index: number, collection: Doc, docs: Doc[], state: any }): { x?: number, y?: number, z?: number, width?: number, height?: number, transition?: string, state?: any } { + const script = this.Document.arrangeScript; + const result = script && script.script.run(params, console.log); + if (result && result.success) { + return { ...result, transition: "transform 1s" }; + } + return { x: Cast(params.doc.x, "number"), y: Cast(params.doc.y, "number"), z: Cast(params.doc.z, "number"), width: Cast(params.doc.width, "number"), height: Cast(params.doc.height, "number") }; } viewDefsToJSX = (views: any[]) => { @@ -745,12 +747,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { if (this.Document.usePivotLayout) return PivotView.elements(this); let curPage = FieldValue(this.Document.curPage, -1); const initScript = this.Document.arrangeInit; - const script = this.Document.arrangeScript; let state: any = undefined; let pairs = this.childLayoutPairs; let elements: ViewDefResult[] = []; if (initScript) { - const initResult = initScript.script.run({ docs: pairs.map(pair => pair.layout), collection: this.Document }); + const initResult = initScript.script.run({ docs: pairs.map(pair => pair.layout), collection: this.Document }, console.log); if (initResult.success) { const result = initResult.result; const { state: scriptState, views } = result; @@ -760,23 +761,17 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } let docviews = pairs.reduce((prev, pair) => { var page = NumCast(pair.layout.page, -1); - if ((Math.abs(Math.round(page) - Math.round(curPage)) < 3) || page === -1) { - let minim = BoolCast(pair.layout.isMinimized); - if (minim === undefined || !minim) { - const pos = script ? this.getCalculatedPositions(script, { doc: pair.layout, index: prev.length, collection: this.Document, docs: pairs.map(pair => pair.layout), state }) : - { x: Cast(pair.layout.x, "number"), y: Cast(pair.layout.y, "number"), z: Cast(pair.layout.z, "number"), width: Cast(pair.layout.width, "number"), height: Cast(pair.layout.height, "number") }; - state = pos.state === undefined ? state : pos.state; - if (pair.layout && !(pair.data instanceof Promise)) { - prev.push({ - ele: , - bounds: { x: pos.x || 0, y: pos.y || 0, z: pos.z, width: NumCast(pos.width), height: NumCast(pos.height) } - }); - } - } + if (!pair.layout.isMinimized && ((Math.abs(Math.round(page) - Math.round(curPage)) < 3) || page === -1)) { + const pos = this.getCalculatedPositions({ doc: pair.layout, index: prev.length, collection: this.Document, docs: pairs.map(pair => pair.layout), state }); + state = pos.state === undefined ? state : pos.state; + prev.push({ + ele: , + bounds: { x: pos.x || 0, y: pos.y || 0, z: pos.z, width: pos.width || 0, height: pos.height || 0 } + }); } return prev; }, elements); @@ -838,7 +833,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } analyzeStrokes = async () => { - let data = Cast(this.fieldExtensionDoc[this._inkKey], InkField); + let data = Cast(this.fieldExtensionDoc.ink, InkField); if (data) { CognitiveServices.Inking.Appliers.ConcatenateHandwriting(this.fieldExtensionDoc, ["inkAnalysis", "handwriting"], data.inkData); } @@ -932,12 +927,15 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } render() { + // update the actual dimensions of the collection so that they can inquired (e.g., by a minimap) this.props.Document.fitX = this.actualContentBounds && this.actualContentBounds.x; this.props.Document.fitY = this.actualContentBounds && this.actualContentBounds.y; this.props.Document.fitW = this.actualContentBounds && (this.actualContentBounds.r - this.actualContentBounds.x); this.props.Document.fitH = this.actualContentBounds && (this.actualContentBounds.b - this.actualContentBounds.y); + // if fieldExt is set, then children will be stored in the extension document for the fieldKey. + // otherwise, they are stored in fieldKey. All annotations to this document are stored in the extension document + Doc.UpdateDocumentExtensionForField(this.props.DataDoc || this.props.Document, this.props.fieldKey); const easing = () => this.props.Document.panTransformType === "Ease"; - Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey); return (
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 18d0fea8c..bbea4a555 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -228,18 +228,14 @@ export class MarqueeView extends React.Component return { left: topLeft[0], top: topLeft[1], width: Math.abs(size[0]), height: Math.abs(size[1]) }; } - get ink() { - let container = this.props.container.props.Document; - let containerKey = this.props.container.props.fieldKey; - let extensionDoc = Doc.resolvedFieldDataDoc(container, containerKey, "true"); - return Cast(extensionDoc.ink, InkField); + get ink() { // ink will be stored on the extension doc for the field (fieldKey) where the container's data is stored. + let cprops = this.props.container.props; + return Cast(Doc.fieldExtensionDoc(cprops.Document, cprops.fieldKey).ink, InkField); } set ink(value: InkField | undefined) { - let container = Doc.GetProto(this.props.container.props.Document); - let containerKey = this.props.container.props.fieldKey; - let extensionDoc = Doc.resolvedFieldDataDoc(container, containerKey, "true"); - extensionDoc.ink = value; + let cprops = this.props.container.props; + Doc.fieldExtensionDoc(cprops.Document, cprops.fieldKey).ink = value; } @undoBatch diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index d05e39e2b..9685f9bca 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -17,6 +17,7 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { width?: number; height?: number; jitterRotation: number; + transition?: string; } export const positionSchema = createSchema({ zIndex: "number", @@ -98,7 +99,6 @@ export class CollectionFreeFormDocumentView extends DocComponent(Docu SelectionManager.DeselectAll(); Doc.UnBrushDoc(this.props.Document); } else if (this.onClickHandler && this.onClickHandler.script) { - this.onClickHandler.script.run({ this: this.Document.isTemplate && this.props.DataDoc ? this.props.DataDoc : this.props.Document }); + this.onClickHandler.script.run({ this: this.Document.isTemplate && this.props.DataDoc ? this.props.DataDoc : this.props.Document }, console.log); } else if (this.Document.isButton) { SelectionManager.SelectDoc(this, e.ctrlKey); // don't think this should happen if a button action is actually triggered. this.buttonClick(e.altKey, e.ctrlKey); @@ -569,32 +569,45 @@ export class DocumentView extends DocComponent(Docu }); } + + // the document containing the view layout information - will be the Document itself unless the Document has + // a layout field. In that case, all layout information comes from there unless overriden by Document + get layoutDoc(): Document { + return Document(this.props.Document.layout instanceof Doc ? this.props.Document.layout : this.props.Document); + } + + // does Document set a layout prop + setsLayoutProp = (prop: string) => this.props.Document[prop] !== this.props.Document["default" + prop[0].toUpperCase() + prop.slice(1)]; + // get the a layout prop by first choosing the prop from Document, then falling back to the layout doc otherwise. + getLayoutPropStr = (prop: string) => StrCast(this.setsLayoutProp(prop) ? this.props.Document[prop] : this.layoutDoc[prop]); + getLayoutPropNum = (prop: string) => NumCast(this.setsLayoutProp(prop) ? this.props.Document[prop] : this.layoutDoc[prop]); + isSelected = () => SelectionManager.IsSelected(this); select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); }; chromeHeight = () => { let showOverlays = this.props.showOverlays ? this.props.showOverlays(this.Document) : undefined; let showTitle = showOverlays && "title" in showOverlays ? showOverlays.title : StrCast(this.Document.showTitle); - return (showTitle ? 25 : 0) + 1;// bcz: why 8?? + return (showTitle ? 25 : 0) + 1; } render() { const ruleColor = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleColor_" + this.Document.heading]) : undefined; const ruleRounding = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleRounding_" + this.Document.heading]) : undefined; - const colorSet = this.Document.backgroundColor !== this.Document.defaultBackgroundColor; + const colorSet = this.setsLayoutProp("backgroundColor"); const clusterCol = this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.clusterOverridesDefaultBackground; const backgroundColor = this.Document.isBackground || (clusterCol && !colorSet) ? - this.props.backgroundColor(this.Document) || StrCast(this.Document.backgroundColor) : - ruleColor && !colorSet ? ruleColor : StrCast(this.Document.backgroundColor) || this.props.backgroundColor(this.Document); + this.props.backgroundColor(this.Document) || StrCast(this.layoutDoc.backgroundColor) : + ruleColor && !colorSet ? ruleColor : StrCast(this.layoutDoc.backgroundColor) || this.props.backgroundColor(this.Document); const nativeWidth = this.nativeWidth > 0 && !this.Document.ignoreAspect ? `${this.nativeWidth}px` : "100%"; const nativeHeight = this.Document.ignoreAspect ? this.props.PanelHeight() / this.props.ContentScaling() : this.nativeHeight > 0 ? `${this.nativeHeight}px` : "100%"; const showOverlays = this.props.showOverlays ? this.props.showOverlays(this.Document) : undefined; - const showTitle = showOverlays && "title" in showOverlays ? showOverlays.title : this.Document.showTitle; - const showCaption = showOverlays && "caption" in showOverlays ? showOverlays.caption : this.Document.showCaption; + const showTitle = showOverlays && "title" in showOverlays ? showOverlays.title : this.getLayoutPropStr("showTitle"); + const showCaption = showOverlays && "caption" in showOverlays ? showOverlays.caption : this.getLayoutPropStr("showCaption"); const showTextTitle = showTitle && StrCast(this.Document.layout).indexOf("FormattedTextBox") !== -1 ? showTitle : undefined; const fullDegree = Doc.isBrushedHighlightedDegree(this.props.Document); - const borderRounding = this.Document.borderRounding || ruleRounding; + const borderRounding = this.getLayoutPropStr("borderRounding") || ruleRounding; const localScale = this.props.ScreenToLocalTransform().Scale * fullDegree; const searchHighlight = (!this.Document.searchFields ? (null) :
diff --git a/src/client/views/nodes/DragBox.tsx b/src/client/views/nodes/DragBox.tsx index 2d1a98df2..6c3db18c4 100644 --- a/src/client/views/nodes/DragBox.tsx +++ b/src/client/views/nodes/DragBox.tsx @@ -51,11 +51,9 @@ export class DragBox extends DocComponent(DragDocu const onDragStart = this.Document.onDragStart; e.stopPropagation(); e.preventDefault(); - let res = onDragStart ? onDragStart.script.run({ this: this.props.Document }) : undefined; - let doc = res !== undefined && res.success ? - res.result as Doc : - Docs.Create.FreeformDocument([], { nativeWidth: undefined, nativeHeight: undefined, width: 150, height: 100, title: "freeform" }); - doc && DragManager.StartDocumentDrag([this._mainCont.current!], new DragManager.DocumentDragData([doc]), e.clientX, e.clientY); + let res = onDragStart && onDragStart.script.run({ this: this.props.Document }).result; + let doc = (res as Doc) || Docs.Create.FreeformDocument([], { nativeWidth: undefined, nativeHeight: undefined, width: 150, height: 100, title: "freeform" }); + DragManager.StartDocumentDrag([this._mainCont.current!], new DragManager.DocumentDragData([doc]), e.clientX, e.clientY); } e.stopPropagation(); e.preventDefault(); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 031929bbd..eb4718581 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -142,10 +142,9 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe public get CurrentDiv(): HTMLDivElement { return this._ref.current!; } - @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(this.dataDoc, this.props.fieldKey, "dummy"); } - - @computed get dataDoc() { return this.props.DataDoc && (BoolCast(this.props.Document.isTemplate) || BoolCast(this.props.DataDoc.isTemplate) || this.props.DataDoc.layout === this.props.Document) ? this.props.DataDoc : Doc.GetProto(this.props.Document); } + @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); } + @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplate ? this.props.DataDoc : Doc.GetProto(this.props.Document); } // this should be internal to prosemirror, but is needed // here to make sure that footnote view nodes in the overlay editor @@ -641,7 +640,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe let annotations = DocListCast(region.annotations); annotations.forEach(anno => anno.target = this.props.Document); - let fieldExtDoc = Doc.resolvedFieldDataDoc(doc, "data", "true"); + let fieldExtDoc = Doc.fieldExtensionDoc(doc, "data"); let targetAnnotations = DocListCast(fieldExtDoc.annotations); if (targetAnnotations) { targetAnnotations.push(region); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 3cb64aa40..624593245 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -63,9 +63,9 @@ export class ImageBox extends DocComponent(ImageD @observable private _isOpen: boolean = false; private dropDisposer?: DragManager.DragDropDisposer; + @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); } - @computed get dataDoc() { return this.props.DataDoc && (BoolCast(this.props.Document.isTemplate) || BoolCast(this.props.DataDoc.isTemplate) || this.props.DataDoc.layout === this.props.Document) ? this.props.DataDoc : Doc.GetProto(this.props.Document); } - + @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplate ? this.props.DataDoc : Doc.GetProto(this.props.Document); } protected createDropTarget = (ele: HTMLDivElement) => { if (this.dropDisposer) { @@ -81,8 +81,6 @@ export class ImageBox extends DocComponent(ImageD console.log("IMPLEMENT ME PLEASE"); } - @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(this.dataDoc, this.props.fieldKey, "Alternates"); } - @undoBatch @action drop = (e: Event, de: DragManager.DropEvent) => { diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 8fcd44f46..3a9318469 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -76,7 +76,7 @@ export class KeyValueBox extends React.Component { } else if (type === "script") { field = new ScriptField(script); } else { - let res = script.run({ this: target }); + let res = script.run({ this: target }, console.log); if (!res.success) return false; field = res.result; } diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index c8534ed0d..37bf6dbb7 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -31,11 +31,9 @@ export class PDFBox extends DocComponent(PdfDocumen @observable private _alt = false; @observable private _pdf: Opt; - @computed get containingCollectionDocument() { return this.props.ContainingCollectionDoc; } - @computed get dataDoc() { return this.props.DataDoc && (BoolCast(this.props.Document.isTemplate) || BoolCast(this.props.DataDoc.isTemplate) || this.props.DataDoc.layout === this.props.Document) ? this.props.DataDoc : Doc.GetProto(this.props.Document); } + @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); } - - @computed get fieldExtensionDoc() { return Doc.resolvedFieldDataDoc(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, "true"); } + @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplate ? this.props.DataDoc : Doc.GetProto(this.props.Document); } private _mainCont: React.RefObject = React.createRef(); private _reactionDisposer?: IReactionDisposer; @@ -96,7 +94,7 @@ export class PDFBox extends DocComponent(PdfDocumen @action setPanY = (y: number) => { - this.containingCollectionDocument && (this.containingCollectionDocument.panY = y); + this.props.ContainingCollectionDoc && (this.props.ContainingCollectionDoc.panY = y); } @action @@ -113,7 +111,7 @@ export class PDFBox extends DocComponent(PdfDocumen private resetFilters = () => { this._keyValue = this._valueValue = ""; - this._scriptValue = "return true"; + this._scriptValue = ""; this._keyRef.current && (this._keyRef.current.value = ""); this._valueRef.current && (this._valueRef.current.value = ""); this._scriptRef.current && (this._scriptRef.current.value = ""); @@ -127,7 +125,7 @@ export class PDFBox extends DocComponent(PdfDocumen return !this.props.active() ? (null) : (
e.stopPropagation()}> - - +
+
- ); + ) + } +} + +class SimpleLinkService { + _viewer: Test; + _pdfjsView: any; + + constructor(viewer: Test) { + this._viewer = viewer; } + setPDFJSview(v: any) { this._pdfjsView = v; } + + navigateTo() { } + + getDestinationHash() { return "#"; } + + getAnchorUrl() { return "#"; } + + setHash() { } + + isPageVisible(page: number) { return true; } + + executeNamedAction() { } + + cachePageRef() { } + + get pagesCount() { return this._viewer._pdfViewer.pagesCount; } + + get page() { return this._viewer._page; } + set page(p: number) { + this._pdfjsView._ensurePdfPageLoaded(this._pdfjsView._pages[p - 1]).then(() => { + this._pdfjsView.renderingQueue.renderView(this._pdfjsView._pages[p - 1]); + if (this._viewer.goToPage) { + this._viewer.goToPage(p); + } + }); + } + + + get rotation() { return 0; } + set rotation(value: any) { } } DocServer.init(window.location.protocol, window.location.hostname, 4321, "test"); -- cgit v1.2.3-70-g09d2 From c5ae3ee0f24b980ac6d9669aded7cd3d51047cb4 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 24 Sep 2019 16:32:31 -0400 Subject: fixed moving to not redraw objects. pdf changes started. --- .../collectionFreeForm/CollectionFreeFormView.tsx | 260 +++++++++++---------- .../views/nodes/CollectionFreeFormDocumentView.tsx | 16 +- src/client/views/nodes/PDFBox.scss | 12 +- src/client/views/nodes/PDFBox.tsx | 64 +++-- src/client/views/pdf/PDFViewer.scss | 7 +- src/client/views/pdf/PDFViewer.tsx | 184 +++------------ 6 files changed, 211 insertions(+), 332 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 36e62842c..438529596 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,7 +1,7 @@ import { library } from "@fortawesome/fontawesome-svg-core"; import { faEye } from "@fortawesome/free-regular-svg-icons"; import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrowsAlt, faPaintBrush, faTable, faUpload } from "@fortawesome/free-solid-svg-icons"; -import { action, computed, IReactionDisposer, observable, reaction, trace } from "mobx"; +import { action, computed, IReactionDisposer, observable, reaction, trace, ObservableMap, untracked } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCastAsync, Field, FieldResult, HeightSym, Opt, WidthSym, DocListCast } from "../../../../new_fields/Doc"; import { Id } from "../../../../new_fields/FieldSymbols"; @@ -60,6 +60,17 @@ export interface ViewDefBounds { z?: number; width: number; height: number; + transition?: string; +} + +interface PivotData { + type: string; + text: string; + x: number; + y: number; + width: number; + height: number; + fontSize: number; } export interface ViewDefResult { @@ -67,116 +78,6 @@ export interface ViewDefResult { bounds?: ViewDefBounds; } -export namespace PivotView { - - export interface PivotData { - type: string; - text: string; - x: number; - y: number; - width: number; - height: number; - fontSize: number; - } - - export const elements = (target: CollectionFreeFormView) => { - let collection = target.Document; - const field = StrCast(collection.pivotField) || "title"; - const width = NumCast(collection.pivotWidth) || 200; - const groups = new Map, Doc[]>(); - - for (const doc of target.childDocs) { - const val = doc[field]; - if (val === undefined) continue; - - const l = groups.get(val); - if (l) { - l.push(doc); - } else { - groups.set(val, [doc]); - } - } - - let minSize = Infinity; - - groups.forEach((val, key) => minSize = Math.min(minSize, val.length)); - - const numCols = NumCast(collection.pivotNumColumns) || Math.ceil(Math.sqrt(minSize)); - const fontSize = NumCast(collection.pivotFontSize); - - const docMap = new Map(); - const groupNames: PivotData[] = []; - - let x = 0; - groups.forEach((val, key) => { - let y = 0; - let xCount = 0; - groupNames.push({ - type: "text", - text: String(key), - x, - y: width + 50, - width: width * 1.25 * numCols, - height: 100, fontSize: fontSize - }); - for (const doc of val) { - docMap.set(doc, { - x: x + xCount * width * 1.25, - y: -y, - width, - height: width - }); - xCount++; - if (xCount >= numCols) { - xCount = 0; - y += width * 1.25; - } - } - x += width * 1.25 * (numCols + 1); - }); - - let elements = target.viewDefsToJSX(groupNames); - let docViews = target.childDocs.reduce((prev, doc) => { - let minim = BoolCast(doc.isMinimized); - if (minim === undefined || !minim) { - let defaultPosition = (): ViewDefBounds => { - return { - x: NumCast(doc.x), - y: NumCast(doc.y), - z: NumCast(doc.z), - width: NumCast(doc.width), - height: NumCast(doc.height) - }; - }; - const pos = docMap.get(doc) || defaultPosition(); - prev.push({ - ele: , - bounds: { - x: pos.x, - y: pos.y, - z: pos.z, - width: NumCast(pos.width), - height: NumCast(pos.height) - } - }); - } - return prev; - }, elements); - - return docViews; - }; - -} - type PanZoomDocument = makeInterface<[typeof panZoomSchema, typeof documentSchema, typeof positionSchema, typeof pageSchema]>; const PanZoomDocument = makeInterface(panZoomSchema, documentSchema, positionSchema, pageSchema); @@ -300,7 +201,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { let y = (z ? ypo : yp) - de.data.offset[1]; let dropX = NumCast(de.data.droppedDocuments[0].x); let dropY = NumCast(de.data.droppedDocuments[0].y); - de.data.droppedDocuments.forEach(d => { + de.data.droppedDocuments.forEach(action((d: Doc) => { d.x = x + NumCast(d.x) - dropX; d.y = y + NumCast(d.y) - dropY; if (!NumCast(d.width)) { @@ -312,7 +213,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { d.height = nw && nh ? nh / nw * NumCast(d.width) : 300; } this.bringToFront(d); - }); + })); de.data.droppedDocuments.length === 1 && this.updateCluster(de.data.droppedDocuments[0]); } @@ -645,6 +546,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { getScale = () => this.Document.scale ? this.Document.scale : 1; getChildDocumentViewProps(childLayout: Doc, childData?: Doc): DocumentViewProps { + trace(); return { DataDoc: childData, Document: childLayout, @@ -742,9 +644,99 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } } - @computed.struct - get elements() { - if (this.Document.usePivotLayout) return PivotView.elements(this); + lookupLayout = (doc: Doc, dataDoc?: Doc) => { + let data: any = undefined; + let compute = this.Document.usePivotLayout ? this.doPivotComputation.map : this._doComputation.map; + compute.forEach((value: any, key: { layout: Doc, data?: Doc }) => { + if (key.layout === doc && key.data === dataDoc) { + data = value; + } + }); + return data ? { x: data.x, y: data.y, z: data.z, width: data.width, height: data.height, transition: data.transition } : undefined; + } + + @computed get doPivotComputation() { + let layoutPoolData: Map<{ layout: Doc, data?: Doc }, any> = new Map(); + const field = StrCast(this.props.Document.pivotField) || "title"; + const width = NumCast(this.props.Document.pivotWidth) || 200; + const groups = new Map, Doc[]>(); + + for (const doc of this.childDocs) { + const val = doc[field]; + if (val === undefined) continue; + + const l = groups.get(val); + if (l) { + l.push(doc); + } else { + groups.set(val, [doc]); + } + } + + let minSize = Infinity; + + groups.forEach((val, key) => minSize = Math.min(minSize, val.length)); + + const numCols = NumCast(this.props.Document.pivotNumColumns) || Math.ceil(Math.sqrt(minSize)); + const fontSize = NumCast(this.props.Document.pivotFontSize); + + const docMap = new Map(); + const groupNames: PivotData[] = []; + + let x = 0; + groups.forEach((val, key) => { + let y = 0; + let xCount = 0; + groupNames.push({ + type: "text", + text: String(key), + x, + y: width + 50, + width: width * 1.25 * numCols, + height: 100, fontSize: fontSize + }); + for (const doc of val) { + docMap.set(doc, { + x: x + xCount * width * 1.25, + y: -y, + width, + height: width, + }); + xCount++; + if (xCount >= numCols) { + xCount = 0; + y += width * 1.25; + } + } + x += width * 1.25 * (numCols + 1); + }); + + let elements = this.viewDefsToJSX(groupNames); + let pairs = this.childLayoutPairs; + pairs.map((pair, i) => { + let minim = BoolCast(pair.layout.isMinimized); + if (minim === undefined || !minim) { + let defaultPosition = (): ViewDefBounds => { + return { + x: NumCast(pair.layout.x), + y: NumCast(pair.layout.y), + z: NumCast(pair.layout.z), + width: NumCast(pair.layout.width), + height: NumCast(pair.layout.height), + transition: "transform 1s" + }; + }; + const pos = docMap.get(pair.layout) || defaultPosition(); + layoutPoolData.set(pair, { transition: "transform 1s", ...pos }); + } + }); + return { map: layoutPoolData, elements: elements }; + }; + + + @computed + get _doComputation() { + let layoutPoolData: Map<{ layout: Doc, data?: Doc }, any> = new Map(); let curPage = FieldValue(this.Document.curPage, -1); const initScript = this.Document.arrangeInit; let state: any = undefined; @@ -759,24 +751,40 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { elements = this.viewDefsToJSX(views); } } - let docviews = pairs.reduce((prev, pair) => { + pairs.map((pair, i) => { var page = NumCast(pair.layout.page, -1); if (!pair.layout.isMinimized && ((Math.abs(Math.round(page) - Math.round(curPage)) < 3) || page === -1)) { - const pos = this.getCalculatedPositions({ doc: pair.layout, index: prev.length, collection: this.Document, docs: pairs.map(pair => pair.layout), state }); + const pos = this.getCalculatedPositions({ doc: pair.layout, index: i, collection: this.Document, docs: pairs.map(pair => pair.layout), state }); state = pos.state === undefined ? state : pos.state; + layoutPoolData.set(pair, pos); + } + }); + return { map: layoutPoolData, elements: elements }; + } + + @computed + get doComputation() { + let dc = this.Document.usePivotLayout ? this.doPivotComputation : this._doComputation; + let curPage = FieldValue(this.Document.curPage, -1); + let pairs = this.childLayoutPairs; + let docviews = pairs.reduce((prev, pair) => { + var page = NumCast(pair.layout.page, -1); + if (!pair.layout.isMinimized && ((Math.abs(Math.round(page) - Math.round(curPage)) < 3) || page === -1)) { prev.push({ - ele: , - bounds: { x: pos.x || 0, y: pos.y || 0, z: pos.z, width: pos.width || 0, height: pos.height || 0 } + jitterRotation={NumCast(this.props.Document.jitterRotation)} {...this.getChildDocumentViewProps(pair.layout, pair.data)} />, + bounds: this.lookupLayout(pair.layout, pair.data) }); } return prev; - }, elements); + }, dc.elements); - return docviews; + return { map: dc.map, elements: docviews }; + } + @computed.struct + get elements() { + return this.doComputation.elements; } @computed.struct @@ -945,7 +953,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { - + {this.childViews} diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 9685f9bca..0d9ace473 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -12,6 +12,7 @@ import { Doc, WidthSym, HeightSym } from "../../../new_fields/Doc"; import { random } from "animejs"; export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { + dataProvider?: (doc: Doc, dataDoc?: Doc) => { x: number, y: number, width: number, height: number, z: number, transition?: string } | undefined x?: number; y?: number; width?: number; @@ -32,11 +33,12 @@ export const PositionDocument = makeInterface(documentSchema, positionSchema); @observer export class CollectionFreeFormDocumentView extends DocComponent(PositionDocument) { _disposer: IReactionDisposer | undefined = undefined; - @computed get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) rotate(${random(-1, 1) * this.props.jitterRotation}deg)`; } - @computed get X() { return this._animPos !== undefined ? this._animPos[0] : this.renderScriptDim ? this.renderScriptDim.x : this.props.x !== undefined ? this.props.x : this.Document.x || 0; } - @computed get Y() { return this._animPos !== undefined ? this._animPos[1] : this.renderScriptDim ? this.renderScriptDim.y : this.props.y !== undefined ? this.props.y : this.Document.y || 0; } - @computed get width() { return this.renderScriptDim ? this.renderScriptDim.width : this.props.width !== undefined ? this.props.width : this.props.Document[WidthSym](); } - @computed get height() { return this.renderScriptDim ? this.renderScriptDim.height : this.props.height !== undefined ? this.props.height : this.props.Document[HeightSym](); } + get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) rotate(${random(-1, 1) * this.props.jitterRotation}deg)`; } + get X() { return this._animPos !== undefined ? this._animPos[0] : this.renderScriptDim ? this.renderScriptDim.x : this.props.x !== undefined ? this.props.x : this.dataProvider ? this.dataProvider.x : this.Document.x || 0; } + get Y() { return this._animPos !== undefined ? this._animPos[1] : this.renderScriptDim ? this.renderScriptDim.y : this.props.y !== undefined ? this.props.y : this.dataProvider ? this.dataProvider.y : this.Document.y || 0; } + get width() { return this.renderScriptDim ? this.renderScriptDim.width : this.props.width !== undefined ? this.props.width : this.props.dataProvider && this.dataProvider ? this.dataProvider.width : this.props.Document[WidthSym](); } + get height() { return this.renderScriptDim ? this.renderScriptDim.height : this.props.height !== undefined ? this.props.height : this.props.dataProvider && this.dataProvider ? this.dataProvider.height : this.props.Document[HeightSym](); } + @computed get dataProvider() { return this.props.dataProvider && this.props.dataProvider(this.props.Document, this.props.DataDoc) ? this.props.dataProvider(this.props.Document, this.props.DataDoc) : undefined; } @computed get nativeWidth() { return FieldValue(this.Document.nativeWidth, 0); } @computed get nativeHeight() { return FieldValue(this.Document.nativeHeight, 0); } @computed get scaleToOverridingWidth() { return this.width / FieldValue(this.Document.width, this.width); } @@ -99,6 +101,8 @@ export class CollectionFreeFormDocumentView extends DocComponent(PdfDocumen componentDidMount() { this.props.setPdfBox && this.props.setPdfBox(this); - this.props.Document.curPage = ComputedField.MakeFunction("Math.floor(Number(this.panY) / Number(this.nativeHeight) + 1)"); + this.props.Document.curPage = 1; // ComputedField.MakeFunction("Math.floor(Number(this.panY) / Number(this.nativeHeight) + 1)"); const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField); if (pdfUrl instanceof PdfField) { Pdfjs.getDocument(pdfUrl.url.pathname).promise.then(pdf => runInAction(() => this._pdf = pdf)); } - this._reactionDisposer = reaction( - () => this.Document.panY, - () => this._mainCont.current && this._mainCont.current.scrollTo({ top: this.Document.panY || 0, behavior: "auto" }) - ); } componentWillUnmount() { @@ -63,36 +59,36 @@ export class PDFBox extends DocComponent(PdfDocumen } public GetPage() { - return Math.floor((this.Document.panY || 0) / (this.Document.nativeHeight || 0)) + 1; + return 1;//Math.floor((this.Document.panY || 0) / (this.Document.nativeHeight || 0)) + 1; } @action public BackPage() { - let cp = Math.ceil((this.Document.panY || 0) / (this.Document.nativeHeight || 0)) + 1; - cp = cp - 1; - if (cp > 0) { - this.Document.panY = (cp - 1) * (this.Document.nativeHeight || 0); - } + // let cp = Math.ceil((this.Document.panY || 0) / (this.Document.nativeHeight || 0)) + 1; + // cp = cp - 1; + // if (cp > 0) { + // this.Document.panY = (cp - 1) * (this.Document.nativeHeight || 0); + // } } @action public GotoPage = (p: number) => { - if (p > 0 && p <= NumCast(this.dataDoc.numPages)) { - this.Document.panY = (p - 1) * (this.Document.nativeHeight || 0); - } + // if (p > 0 && p <= NumCast(this.dataDoc.numPages)) { + // this.Document.panY = (p - 1) * (this.Document.nativeHeight || 0); + // } } @action public ForwardPage() { - let cp = this.GetPage() + 1; - if (cp <= NumCast(this.dataDoc.numPages)) { - this.Document.panY = (cp - 1) * (this.Document.nativeHeight || 0); - } + // let cp = this.GetPage() + 1; + // if (cp <= NumCast(this.dataDoc.numPages)) { + // this.Document.panY = (cp - 1) * (this.Document.nativeHeight || 0); + // } } @action setPanY = (y: number) => { - this.Document.panY = y; + //this.Document.panY = y; } @action @@ -120,8 +116,7 @@ export class PDFBox extends DocComponent(PdfDocumen settingsPanel() { return !this.props.active() ? (null) : (
e.stopPropagation()}> -
- -
- ); - } - onContextMenu = (e: React.MouseEvent): void => { if (!e.isPropagationStopped() && this.props.Document[Id] !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 ContextMenu.Instance.addItem({ description: "PDFOptions", event: emptyFunction, icon: "file-pdf" }); } } - setPdfBox = (pdfBox: PDFBox) => { this._pdfBox = pdfBox; }; - subView = (_type: CollectionViewType, renderProps: CollectionRenderProps) => { - return (<> - - {renderProps.active() ? this.uIButtons : (null)} - ); + return (); } render() { diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index cbea47e20..4ceda1986 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -106,4 +106,86 @@ grid-template-columns: 47.5% 5% 47.5%; } } -} \ No newline at end of file +} + +.pdfViewer-overlayCont { + position: absolute; + width: 100%; + height: 100px; + background: #121721; + bottom: 0; + display: flex; + justify-content: center; + align-items: center; + padding: 20px; + overflow: hidden; + transition: left .5s; + + .pdfViewer-overlaySearchBar { + width: 70%; + height: 100%; + font-size: 30px; + padding: 5px; + } +} + +.pdfViewer-overlayButton { + border-bottom-left-radius: 50%; + display: flex; + justify-content: space-evenly; + align-items: center; + height: 70px; + background: none; + padding: 0; + position: absolute; + + .pdfViewer-overlayButton-arrow { + width: 0; + height: 0; + border-top: 25px solid transparent; + border-bottom: 25px solid transparent; + border-right: 25px solid #121721; + transition: all 0.5s; + } + + .pdfViewer-overlayButton-iconCont { + background: #121721; + height: 50px; + width: 70px; + display: flex; + justify-content: center; + align-items: center; + margin-left: -2px; + border-radius: 3px; + } +} + +.pdfViewer-overlayButton:hover { + background: none; +} +.collectionPdfView-buttonTray { + top: 15px; + left: 20px; + position: relative; + transform-origin: left top; + position: absolute; +} +.collectionPdfView-backward { + color: white; + font-size: 24px; + top: 0px; + left: 0px; + position: absolute; + background-color: rgba(50, 50, 50, 0.2); +} + +.collectionPdfView-forward { + color: white; + font-size: 24px; + top: 0px; + left: 45px; + position: absolute; + background-color: rgba(50, 50, 50, 0.2); +} + + diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 12a5bc492..f57ec406c 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -62,6 +62,12 @@ export class PDFBox extends DocComponent(PdfDocumen public search(string: string) { this._pdfViewer && this._pdfViewer.search(string); } + public prevAnnotation() { + this._pdfViewer && this._pdfViewer.prevAnnotation(); + } + public nextAnnotation() { + this._pdfViewer && this._pdfViewer.nextAnnotation(); + } setPdfViewer = (pdfViewer: PDFViewer) => { this._pdfViewer = pdfViewer; @@ -122,46 +128,88 @@ export class PDFBox extends DocComponent(PdfDocumen private newValueChange = (e: React.ChangeEvent) => this._valueValue = e.currentTarget.value; private newScriptChange = (e: React.ChangeEvent) => this._scriptValue = e.currentTarget.value; + searchStringChanged = (e: React.ChangeEvent) => this._searchString = e.currentTarget.value; + private _searchString: string = ""; settingsPanel() { return !this.props.active() ? (null) : - (
e.stopPropagation()}> - +
+ -
-
- Annotation View Settings -
-
- - -
-
- -
-
- - + + + + +
e.stopPropagation()}> + +
+
+ Annotation View Settings +
+
+ + +
+
+ +
+
+ + +
-
); + ); } loaded = (nw: number, nh: number, np: number) => { diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss index 4388bc64c..0ca3fa2d3 100644 --- a/src/client/views/pdf/PDFViewer.scss +++ b/src/client/views/pdf/PDFViewer.scss @@ -33,6 +33,8 @@ } } + + .pdfViewer-overlayButton { border-bottom-left-radius: 50%; display: flex; diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 899a0f5aa..01f19ebf6 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -238,8 +238,7 @@ export class PDFViewer extends React.Component { } @action - prevAnnotation = (e: React.MouseEvent) => { - e.stopPropagation(); + prevAnnotation = () => { this.Index = Math.max(this.Index - 1, 0); let scrollToAnnotation = this.allAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y))[this.Index]; this.allAnnotations.forEach(d => Doc.UnBrushDoc(d)); @@ -248,8 +247,7 @@ export class PDFViewer extends React.Component { } @action - nextAnnotation = (e: React.MouseEvent) => { - e.stopPropagation(); + nextAnnotation = () => { this.Index = Math.min(this.Index + 1, this.allAnnotations.length - 1); let scrollToAnnotation = this.allAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y))[this.Index]; this.allAnnotations.forEach(d => Doc.UnBrushDoc(d)); @@ -529,16 +527,6 @@ export class PDFViewer extends React.Component { {this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map((anno, index) => )}
- -
); } } -- cgit v1.2.3-70-g09d2 From 6d01b67aab6a6169b189002fc9c00477d55ca113 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 25 Sep 2019 14:26:26 -0400 Subject: pdf rendering is working, I think. Annotation documents aren't aligned at all. --- .../views/collections/CollectionDockingView.tsx | 12 +++- src/client/views/nodes/PDFBox.scss | 69 +++++++--------------- src/client/views/nodes/PDFBox.tsx | 61 ++++++++----------- src/client/views/pdf/PDFViewer.scss | 37 ------------ src/client/views/pdf/PDFViewer.tsx | 9 +-- 5 files changed, 56 insertions(+), 132 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 8fcba99e3..e5d652648 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -9,7 +9,7 @@ import * as ReactDOM from 'react-dom'; import Measure from "react-measure"; import * as GoldenLayout from "../../../client/goldenLayout"; import { DateField } from '../../../new_fields/DateField'; -import { Doc, DocListCast, Field, Opt } from "../../../new_fields/Doc"; +import { Doc, DocListCast, Field, Opt, WidthSym, HeightSym } from "../../../new_fields/Doc"; import { Id } from '../../../new_fields/FieldSymbols'; import { List } from '../../../new_fields/List'; import { FieldId } from "../../../new_fields/RefField"; @@ -30,6 +30,7 @@ import "./CollectionDockingView.scss"; import { SubCollectionViewProps } from "./CollectionSubView"; import React = require("react"); import { ButtonSelector } from './ParentDocumentSelector'; +import { DocumentType } from '../../documents/DocumentTypes'; library.add(faFile); @observer @@ -595,12 +596,17 @@ export class DockedFrameRenderer extends React.Component { } panelWidth = () => this._document!.ignoreAspect ? this._panelWidth : Math.min(this._panelWidth, Math.max(NumCast(this._document!.width), this.nativeWidth())); - panelHeight = () => this._document!.ignoreAspect ? this._panelHeight : Math.min(this._panelHeight, Math.max(NumCast(this._document!.height), NumCast(this._document!.nativeHeight, this._panelHeight))); + panelHeight = () => this._document!.ignoreAspect ? this._panelHeight : Math.min(this._panelHeight, Math.max(NumCast(this._document!.height), this.nativeHeight())); nativeWidth = () => !this._document!.ignoreAspect ? NumCast(this._document!.nativeWidth) || this._panelWidth : 0; nativeHeight = () => !this._document!.ignoreAspect ? NumCast(this._document!.nativeHeight) || this._panelHeight : 0; contentScaling = () => { + if (this._document!.type === DocumentType.PDF) { + if (this._panelHeight / NumCast(this._document!.nativeHeight) > this._panelWidth / NumCast(this._document!.nativeWidth)) + return this._panelWidth / NumCast(this._document!.nativeWidth); + else return this._panelHeight / NumCast(this._document!.nativeHeight); + } const nativeH = this.nativeHeight(); const nativeW = this.nativeWidth(); if (!nativeW || !nativeH) return 1; @@ -619,6 +625,7 @@ export class DockedFrameRenderer extends React.Component { get previewPanelCenteringOffset() { return this.nativeWidth() && !BoolCast(this._document!.ignoreAspect) ? (this._panelWidth - this.nativeWidth() / this.ScreenToLocalTransform().Scale) / 2 : 0; } addDocTab = (doc: Doc, dataDoc: Opt, location: string) => { + SelectionManager.DeselectAll(); if (doc.dockingConfig) { MainView.Instance.openWorkspace(doc); return true; @@ -635,6 +642,7 @@ export class DockedFrameRenderer extends React.Component { return (null); } let resolvedDataDoc = this._document.layout instanceof Doc ? this._document : this._dataDoc; + console.log("Wid = " + this.panelWidth() + " " + this.panelHeight()); return (PdfDocumen componentDidMount() { this.props.setPdfBox && this.props.setPdfBox(this); - this.props.Document.curPage = 1; // ComputedField.MakeFunction("Math.floor(Number(this.panY) / Number(this.nativeHeight) + 1)"); const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField); if (pdfUrl instanceof PdfField) { @@ -74,31 +73,25 @@ export class PDFBox extends DocComponent(PdfDocumen } public GetPage() { - return Math.floor((this.Document.panY || 0) / (this.Document.nativeHeight || 0)) + 1; + return this._pdfViewer!._pdfViewer.currentPageNumber; } @action public BackPage() { - let cp = Math.ceil((this.Document.panY || 0) / (this.Document.nativeHeight || 0)) + 1; - cp = cp - 1; - if (cp > 0) { - this.Document.panY = (cp - 1) * (this.Document.nativeHeight || 0); - } + this._pdfViewer!._pdfViewer.scrollPageIntoView({ pageNumber: Math.max(1, this.GetPage() - 1) }); + this.props.Document.curPage = this.GetPage(); } @action public GotoPage = (p: number) => { - if (p > 0 && p <= NumCast(this.dataDoc.numPages)) { - this.Document.panY = (p - 1) * (this.Document.nativeHeight || 0); - } + this._pdfViewer!._pdfViewer.scrollPageIntoView(p); + this.props.Document.curPage = this.GetPage(); } @action public ForwardPage() { - let cp = this.GetPage() + 1; - if (cp <= NumCast(this.dataDoc.numPages)) { - this.Document.panY = (cp - 1) * (this.Document.nativeHeight || 0); - } + this._pdfViewer!._pdfViewer.scrollPageIntoView({ pageNumber: Math.min(this._pdfViewer!._pdfViewer.pagesCount, this.GetPage() + 1) }); + this.props.Document.curPage = this.GetPage(); } @action @@ -133,39 +126,39 @@ export class PDFBox extends DocComponent(PdfDocumen settingsPanel() { return !this.props.active() ? (null) : (<> -
e.stopPropagation()} +
e.stopPropagation()} style={{ bottom: 0, left: `${this._searching ? 0 : 100}%` }}> - +
- - - - -
e.stopPropagation()}> -
+
Annotation View Settings
@@ -213,8 +200,6 @@ export class PDFBox extends DocComponent(PdfDocumen } loaded = (nw: number, nh: number, np: number) => { - // nh *= .33.33333; - // nw *= 1.33333; this.dataDoc.numPages = np; if (!this.Document.nativeWidth || !this.Document.nativeHeight || !this.Document.scrollHeight) { let oldaspect = (this.Document.nativeHeight || 0) / (this.Document.nativeWidth || 1); diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss index 0ca3fa2d3..456eea7a1 100644 --- a/src/client/views/pdf/PDFViewer.scss +++ b/src/client/views/pdf/PDFViewer.scss @@ -32,41 +32,4 @@ opacity: 0.1; } } - - - - .pdfViewer-overlayButton { - border-bottom-left-radius: 50%; - display: flex; - justify-content: space-evenly; - align-items: center; - height: 70px; - background: none; - padding: 0; - position: absolute; - - .pdfViewer-overlayButton-arrow { - width: 0; - height: 0; - border-top: 25px solid transparent; - border-bottom: 25px solid transparent; - border-right: 25px solid #121721; - transition: all 0.5s; - } - - .pdfViewer-overlayButton-iconCont { - background: #121721; - height: 50px; - width: 70px; - display: flex; - justify-content: center; - align-items: center; - margin-left: -2px; - border-radius: 3px; - } - } - - .pdfViewer-overlayButton:hover { - background: none; - } } \ No newline at end of file diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 01f19ebf6..bbd40d970 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -54,7 +54,6 @@ export class PDFViewer extends React.Component { @observable private _marqueeWidth: number = 0; @observable private _marqueeHeight: number = 0; - private _resizeReaction: IReactionDisposer | undefined; private _annotationLayer: React.RefObject = React.createRef(); private _reactionDisposer?: IReactionDisposer; private _annotationReactionDisposer?: IReactionDisposer; @@ -109,7 +108,6 @@ export class PDFViewer extends React.Component { } componentWillUnmount = () => { - this._resizeReaction && this._resizeReaction(); this._reactionDisposer && this._reactionDisposer(); this._annotationReactionDisposer && this._annotationReactionDisposer(); this._filterReactionDisposer && this._filterReactionDisposer(); @@ -153,9 +151,7 @@ export class PDFViewer extends React.Component { @action setupPdfJsViewer = () => { - this._reactionDisposer = reaction(() => this.props.Document[WidthSym](), - () => this._pdfViewer.currentScaleValue = (this.props.Document[WidthSym]() / this._pageSizes[0].width)); - document.addEventListener("pagesinit", () => this._pdfViewer.currentScaleValue = (this.props.Document[WidthSym]() / this._pageSizes[0].width)); + document.addEventListener("pagesinit", () => this._pdfViewer.currentScaleValue = 1); document.addEventListener("pagerendered", () => console.log("rendered")); var pdfLinkService = new PDFJSViewer.PDFLinkService(); let pdfFindController = new PDFJSViewer.PDFFindController({ @@ -511,9 +507,8 @@ export class PDFViewer extends React.Component { } render() { - let scaling = this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width / this.props.Document[WidthSym]() : 1; return (
-
+
Date: Wed, 25 Sep 2019 17:53:05 -0400 Subject: now working with annotations. --- src/client/documents/Documents.ts | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 6 +- src/client/views/nodes/PDFBox.scss | 5 +- src/client/views/nodes/PDFBox.tsx | 3 +- src/client/views/pdf/PDFViewer.scss | 9 +++ src/client/views/pdf/PDFViewer.tsx | 84 ++++++++++++++++------ 6 files changed, 82 insertions(+), 27 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 4ae770e25..ea7a3a8b6 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -144,7 +144,7 @@ export namespace Docs { options: { height: 32 } }], [DocumentType.PDF, { - layout: { view: PDFBox, collectionView: [CollectionPDFView, data, anno] as CollectionViewType }, + layout: { view: PDFBox }, options: { nativeWidth: 1200, curPage: 1 } }], [DocumentType.ICON, { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index af84a1d73..45c021c5f 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -286,7 +286,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { @action onPointerMove = (e: PointerEvent): void => { - if (!e.cancelBubble) { + if (!e.cancelBubble && this.props.layoutKey) { if (this._hitCluster && this.tryDragCluster(e)) { e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers e.preventDefault(); @@ -339,7 +339,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { @action onPointerWheel = (e: React.WheelEvent): void => { - if (this.props.Document.lockedPosition) return; + if (this.props.Document.lockedPosition || this.isAnnotationOverlay) return; if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming e.stopPropagation(); } @@ -699,7 +699,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { // otherwise, they are stored in fieldKey. All annotations to this document are stored in the extension document Doc.UpdateDocumentExtensionForField(this.props.DataDoc || this.props.Document, this.props.fieldKey); return ( -
(PdfDocumen e.button === 0 && e.stopPropagation(); } }}> - {this.settingsPanel()}
); diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss index 456eea7a1..a561be94d 100644 --- a/src/client/views/pdf/PDFViewer.scss +++ b/src/client/views/pdf/PDFViewer.scss @@ -6,6 +6,15 @@ overflow-y: scroll; overflow-x: hidden; + // .canvasWrapper { + // transform: scale(0.75); + // transform-origin: top left; + // } + // .textLayer { + // transform: scale(0.75); + // transform-origin: top left; + // } + .page { position: relative; } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index bbd40d970..ea5e00d73 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -20,6 +20,10 @@ import PDFMenu from "./PDFMenu"; import "./PDFViewer.scss"; import React = require("react"); import requestPromise = require("request-promise"); +import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; +import { CollectionView } from "../collections/CollectionView"; +import { listSpec } from "../../../new_fields/Schema"; +import { Transform } from "../../util/Transform"; const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer"); interface IViewerProps { @@ -37,6 +41,8 @@ interface IViewerProps { pinToPres: (document: Doc) => void; addDocument?: (doc: Doc, allowDuplicates?: boolean) => boolean; setPdfViewer: (view: PDFViewer) => void; + ScreenToLocalTransform: () => Transform; + } /** @@ -438,22 +444,22 @@ export class PDFViewer extends React.Component { this._marqueeHeight = this._marqueeWidth = 0; } - else { - let sel = window.getSelection(); - if (sel && sel.type === "Range") { - let selRange = sel.getRangeAt(0); - this.createTextAnnotation(sel, selRange); - PDFMenu.Instance.jumpTo(e.clientX, e.clientY); - } - } - - if (PDFMenu.Instance.Highlighting) { - this.highlight(undefined, "goldenrod"); - } - else { - PDFMenu.Instance.StartDrag = this.startDrag; - PDFMenu.Instance.Highlight = this.highlight; - } + // else { + // let sel = window.getSelection(); + // if (sel && sel.type === "Range") { + // let selRange = sel.getRangeAt(0); + // this.createTextAnnotation(sel, selRange); + // PDFMenu.Instance.jumpTo(e.clientX, e.clientY); + // } + // } + + // if (PDFMenu.Instance.Highlighting) { + // this.highlight(undefined, "goldenrod"); + // } + // else { + // PDFMenu.Instance.StartDrag = this.startDrag; + // PDFMenu.Instance.Highlight = this.highlight; + // } document.removeEventListener("pointermove", this.onSelectStart); document.removeEventListener("pointerup", this.onSelectEnd); } @@ -506,11 +512,36 @@ export class PDFViewer extends React.Component { DragManager.StartDocumentDrag([], new DragManager.DocumentDragData([view]), 0, 0); } + // this is called with the document that was dragged and the collection to move it into. + // if the target collection is the same as this collection, then the move will be allowed. + // otherwise, the document being moved must be able to be removed from its container before + // moving it into the target. + @action.bound + moveDocument(doc: Doc, targetCollection: Doc, addDocument: (doc: Doc) => boolean): boolean { + if (Doc.AreProtosEqual(this.props.Document, targetCollection)) { + return true; + } + return this.removeDocument(doc) ? addDocument(doc) : false; + } + + + @action.bound + removeDocument(doc: Doc): boolean { + //TODO This won't create the field if it doesn't already exist + let targetDataDoc = this.props.fieldExtensionDoc; + let targetField = "annotations"; + let value = Cast(targetDataDoc[targetField], listSpec(Doc), []); + let index = value.reduce((p, v, i) => (v instanceof Doc && v === doc) ? i : p, -1); + index = index !== -1 ? index : value.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, doc)) ? i : p, -1); + index !== -1 && value.splice(index, 1); + return true; + } + scrollXf = () => { + return this._mainCont.current ? this.props.ScreenToLocalTransform().translate(0, this._mainCont.current.scrollTop) : this.props.ScreenToLocalTransform(); + } render() { - return (
-
-
-
+ return (
e.stopPropagation()} ref={this._mainCont}> +
{ {this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map((anno, index) => )}
+ this._pageSizes.length && this._pageSizes[0] ? this.props.pdf.numPages * this._pageSizes[0].height : 300} + removeDocument={this.removeDocument} + moveDocument={this.moveDocument} + addDocument={(doc: Doc, allow: boolean | undefined) => { Doc.AddDocToList(this.props.fieldExtensionDoc, "annotations", doc); return true; }} + CollectionView={this.props.ContainingCollectionView} + ScreenToLocalTransform={this.scrollXf} + ruleProvider={this.props.ruleProvider} + chromeCollapsed={true} + layoutKey={undefined} + backgroundLayout={undefined} > +
); } } -- cgit v1.2.3-70-g09d2 From f4b628c2a6810c1af51508685f12287a300d6e6f Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 25 Sep 2019 22:26:54 -0400 Subject: all pdf annotations work? --- src/client/documents/Documents.ts | 7 +- src/client/views/DocumentButtonBar.tsx | 5 +- src/client/views/MainView.tsx | 7 +- src/client/views/TemplateMenu.tsx | 4 +- .../views/collections/CollectionDockingView.tsx | 6 +- .../views/collections/CollectionSchemaCells.tsx | 6 +- .../views/collections/CollectionSchemaView.tsx | 4 +- .../views/collections/CollectionStackingView.tsx | 8 +- .../CollectionStackingViewFieldColumn.tsx | 6 +- src/client/views/collections/CollectionSubView.tsx | 5 +- .../CollectionFreeFormLayoutEngines.tsx | 4 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 18 +-- .../collections/collectionFreeForm/MarqueeView.tsx | 13 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 6 +- src/client/views/nodes/DocumentView.tsx | 3 +- src/client/views/nodes/FormattedTextBox.tsx | 6 +- src/client/views/nodes/PDFBox.scss | 3 + src/client/views/nodes/PDFBox.tsx | 20 ++-- src/client/views/pdf/PDFViewer.scss | 5 +- src/client/views/pdf/PDFViewer.tsx | 132 +++++++++++++-------- 20 files changed, 159 insertions(+), 109 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index ea7a3a8b6..392dca373 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -95,12 +95,13 @@ export namespace Docs { export namespace Prototypes { - type LayoutSource = { LayoutString: () => string }; + type LayoutSource = { LayoutString: (ext?: string) => string }; type CollectionLayoutSource = { LayoutString: (fieldStr: string, fieldExt?: string) => string }; type CollectionViewType = [CollectionLayoutSource, string, string?]; type PrototypeTemplate = { layout: { view: LayoutSource, + ext?: string, // optional extension field for layout source collectionView?: CollectionViewType }, options?: Partial @@ -144,7 +145,7 @@ export namespace Docs { options: { height: 32 } }], [DocumentType.PDF, { - layout: { view: PDFBox }, + layout: { view: PDFBox, ext: anno }, options: { nativeWidth: 1200, curPage: 1 } }], [DocumentType.ICON, { @@ -254,7 +255,7 @@ export namespace Docs { // synthesize the default options, the type and title from computed values and // whatever options pertain to this specific prototype let options = { title: title, type: type, baseProto: true, ...defaultOptions, ...(template.options || {}) }; - let primary = layout.view.LayoutString(); + let primary = layout.view.LayoutString(layout.ext); let collectionView = layout.collectionView; if (collectionView) { options.layout = collectionView[0].LayoutString(collectionView[1], collectionView[2]); diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index b482e3298..9ca54f738 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -23,6 +23,7 @@ import React = require("react"); import { DocumentView } from './nodes/DocumentView'; import { ParentDocSelector } from './collections/ParentDocumentSelector'; import { CollectionDockingView } from './collections/CollectionDockingView'; +import { DocumentDecorations } from './DocumentDecorations'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -225,7 +226,7 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[], return (
{ - DocumentDecorations.hasPushedHack = false; + DocumentButtonBar.hasPushedHack = false; this.targetDoc[Pushes] = NumCast(this.targetDoc[Pushes]) + 1; }}> @@ -259,7 +260,7 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[], window.open(`https://docs.google.com/document/d/${dataDoc[GoogleRef]}/edit`); } else { this.clearPullColor(); - DocumentDecorations.hasPulledHack = false; + DocumentButtonBar.hasPulledHack = false; this.targetDoc[Pulls] = NumCast(this.targetDoc[Pulls]) + 1; dataDoc.unchanged && runInAction(() => this.isAnimatingFetch = true); } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 003919866..244b217ed 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -230,7 +230,7 @@ export class MainView extends React.Component { } else { DocServer.GetRefField(CurrentUserUtils.MainDocId).then(field => { field instanceof Doc ? this.openWorkspace(field) : - this.createNewWorkspace(CurrentUserUtils.MainDocId) + this.createNewWorkspace(CurrentUserUtils.MainDocId); }); } } @@ -371,8 +371,9 @@ export class MainView extends React.Component { } flyoutWidthFunc = () => this.flyoutWidth; addDocTabFunc = (doc: Doc, data: Opt, where: string) => { - if (where === "close") + if (where === "close") { return CollectionDockingView.CloseRightSplit(doc); + } if (doc.dockingConfig) { this.openWorkspace(doc); return true; @@ -564,7 +565,7 @@ export class MainView extends React.Component { let next = () => PresBox.CurrentPresentation.next(); let back = () => PresBox.CurrentPresentation.back(); let startOrResetPres = () => PresBox.CurrentPresentation.startOrResetPres(); - let closePresMode = action(() => { PresBox.CurrentPresentation.presMode = false; this.addDocTabFunc(PresBox.CurrentPresentation.props.Document); }); + let closePresMode = action(() => { PresBox.CurrentPresentation.presMode = false; this.addDocTabFunc(PresBox.CurrentPresentation.props.Document, undefined, "onRight"); }); return !PresBox.CurrentPresentation || !PresBox.CurrentPresentation.presMode ? (null) : ; } diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index e4ef8313d..9e5e62e03 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -117,13 +117,13 @@ export class TemplateMenu extends React.Component { @action toggleChrome = (): void => { this.props.docs.map(dv => { - let layout = dv.Document.layout instanceof Doc ? dv.Document.layout as Doc : dv.Document; + let layout = dv.Document.layout instanceof Doc ? dv.Document.layout : dv.Document; layout.chromeStatus = (layout.chromeStatus !== "disabled" ? "disabled" : "enabled"); }); } render() { - let layout = this.props.docs[0].Document.layout instanceof Doc ? this.props.docs[0].Document.layout as Doc : this.props.docs[0].Document; + let layout = this.props.docs[0].Document.layout instanceof Doc ? this.props.docs[0].Document.layout : this.props.docs[0].Document; let templateMenu: Array = []; this.props.templates.forEach((checked, template) => templateMenu.push()); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index e5d652648..2d9faee6b 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -603,9 +603,11 @@ export class DockedFrameRenderer extends React.Component { contentScaling = () => { if (this._document!.type === DocumentType.PDF) { - if (this._panelHeight / NumCast(this._document!.nativeHeight) > this._panelWidth / NumCast(this._document!.nativeWidth)) + if (this._panelHeight / NumCast(this._document!.nativeHeight) > this._panelWidth / NumCast(this._document!.nativeWidth)) { return this._panelWidth / NumCast(this._document!.nativeWidth); - else return this._panelHeight / NumCast(this._document!.nativeHeight); + } else { + return this._panelHeight / NumCast(this._document!.nativeHeight); + } } const nativeH = this.nativeHeight(); const nativeW = this.nativeWidth(); diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 4dac27e60..179e44266 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -34,7 +34,7 @@ export interface CellProps { row: number; col: number; rowProps: CellInfo; - CollectionView: CollectionView | CollectionPDFView | CollectionVideoView; + CollectionView: Opt; ContainingCollection: Opt; Document: Doc; fieldKey: string; @@ -151,7 +151,7 @@ export class CollectionSchemaCell extends React.Component { fieldExt: "", ruleProvider: undefined, ContainingCollectionView: this.props.CollectionView, - ContainingCollectionDoc: this.props.CollectionView.props.Document, + ContainingCollectionDoc: this.props.CollectionView && this.props.CollectionView.props.Document, isSelected: returnFalse, select: emptyFunction, renderDepth: this.props.renderDepth + 1, @@ -301,7 +301,7 @@ export class CollectionSchemaCheckboxCell extends CollectionSchemaCell { render() { let reference = React.createRef(); let onItemDown = (e: React.PointerEvent) => { - (!this.props.CollectionView.props.isSelected() ? undefined : + (!this.props.CollectionView || !this.props.CollectionView.props.isSelected() ? undefined : SetupDrag(reference, () => this._document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e)); }; return ( diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 7bd2a1971..8d931f812 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -246,7 +246,7 @@ export interface SchemaTableProps { PanelHeight: () => number; PanelWidth: () => number; childDocs?: Doc[]; - CollectionView: CollectionView | CollectionPDFView | CollectionVideoView; + CollectionView: Opt; ContainingCollectionView: Opt; ContainingCollectionDoc: Opt; fieldKey: string; @@ -804,7 +804,7 @@ export class SchemaTable extends React.Component { csv.substring(0, csv.length - 1); let dbName = StrCast(this.props.Document.title); let res = await Gateway.Instance.PostSchema(csv, dbName); - if (self.props.CollectionView.props.addDocument) { + if (self.props.CollectionView && self.props.CollectionView.props.addDocument) { let schemaDoc = await Docs.Create.DBDocument("https://www.cs.brown.edu/" + dbName, { title: dbName }, { dbDoc: self.props.Document }); if (schemaDoc) { //self.props.CollectionView.props.addDocument(schemaDoc, false); diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index ccf131797..597f3f745 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -42,7 +42,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); } @computed get isStackingView() { return BoolCast(this.props.Document.singleColumn, true); } @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; } - @computed get showAddAGroup() { return (this.sectionFilter && (this.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.CollectionView.props.Document.chromeStatus !== 'disabled')); } + @computed get showAddAGroup() { return (this.sectionFilter && this.props.ContainingCollectionDoc && (this.props.ContainingCollectionDoc.chromeStatus !== 'view-mode' && this.props.ContainingCollectionDoc.chromeStatus !== 'disabled')); } @computed get columnWidth() { return Math.min(this.props.PanelWidth() / (this.props as any).ContentScaling() - 2 * this.xMargin, this.isStackingView ? Number.MAX_VALUE : NumCast(this.props.Document.columnWidth, 250)); @@ -347,7 +347,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { } onToggle = (checked: Boolean) => { - this.props.CollectionView.props.Document.chromeStatus = checked ? "collapsed" : "view-mode"; + this.props.ContainingCollectionDoc && (this.props.ContainingCollectionDoc.chromeStatus = checked ? "collapsed" : "view-mode"); } onContextMenu = (e: React.MouseEvent): void => { @@ -391,10 +391,10 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { style={{ width: this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}>
} - {this.props.CollectionView.props.Document.chromeStatus !== 'disabled' ? : null} diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index b3b7b40dd..240adf428 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -266,7 +266,7 @@ export class CollectionStackingViewFieldColumn extends React.Component {/* the default bucket (no key value) has a tooltip that describes what it is. Further, it does not have a color and cannot be deleted. */} @@ -297,7 +297,7 @@ export class CollectionStackingViewFieldColumn extends React.Component : (null); for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth / style.numGroupColumns}px `; return ( -
{headingView}
- {(this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ? + {(this.props.parent.props.ContainingCollectionDoc && this.props.parent.props.ContainingCollectionDoc.chromeStatus !== 'view-mode' && this.props.parent.props.ContainingCollectionDoc.chromeStatus !== 'disabled') ?
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 774e6b1b9..ce80526b2 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -1,7 +1,7 @@ import { action, computed, IReactionDisposer, reaction } from "mobx"; import * as rp from 'request-promise'; import CursorField from "../../../new_fields/CursorField"; -import { Doc, DocListCast } from "../../../new_fields/Doc"; +import { Doc, DocListCast, Opt } from "../../../new_fields/Doc"; import { Id } from "../../../new_fields/FieldSymbols"; import { List } from "../../../new_fields/List"; import { listSpec } from "../../../new_fields/Schema"; @@ -30,10 +30,11 @@ export interface CollectionViewProps extends FieldViewProps { PanelWidth: () => number; PanelHeight: () => number; chromeCollapsed: boolean; + setPreviewCursor?: (func: (x: number, y: number) => void) => void; } export interface SubCollectionViewProps extends CollectionViewProps { - CollectionView: CollectionView | CollectionPDFView | CollectionVideoView; + CollectionView: Opt; ruleProvider: Doc | undefined; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index 21855b168..6135f3e45 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -90,9 +90,7 @@ export function computePivotLayout(pivotDoc: Doc, childDocs: Doc[], childPairs: layoutPoolData.set(pair, { transition: "transform 1s", ...pos }); }); return { map: layoutPoolData, elements: viewDefsToJSX(groupNames) }; -}; - - +} export function AddCustomFreeFormLayout(doc: Doc, dataKey: string): () => void { return () => { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 45c021c5f..075914e29 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -50,7 +50,7 @@ export const panZoomSchema = createSchema({ useClusters: "boolean", isRuleProvider: "boolean", fitToBox: "boolean", - panTransformType: "string" + panTransformType: "string", }); type PanZoomDocument = makeInterface<[typeof panZoomSchema, typeof documentSchema, typeof positionSchema, typeof pageSchema]>; @@ -61,6 +61,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { private _lastX: number = 0; private _lastY: number = 0; private _clusterDistance: number = 75; + private _hitCluster = false; @observable _clusterSets: (Doc[])[] = []; @computed get fitToContent() { return (this.props.fitToBox || this.Document.fitToBox) && !this.isAnnotationOverlay; } @@ -265,7 +266,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { return clusterColor; } - _hitCluster = false; @action onPointerDown = (e: React.PointerEvent): void => { this._hitCluster = this.props.Document.useClusters ? this.pickCluster(this.getTransform().transformPoint(e.clientX, e.clientY)) !== -1 : false; @@ -286,7 +286,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { @action onPointerMove = (e: PointerEvent): void => { - if (!e.cancelBubble && this.props.layoutKey) { + if (!e.cancelBubble && !this.isAnnotationOverlay) { if (this._hitCluster && this.tryDragCluster(e)) { e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers e.preventDefault(); @@ -451,7 +451,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { PanelHeight: childLayout[HeightSym], ContentScaling: returnOne, ContainingCollectionView: this.props.CollectionView, - ContainingCollectionDoc: this.props.CollectionView.props.Document, + ContainingCollectionDoc: this.props.ContainingCollectionDoc, focus: this.focusDocument, backgroundColor: this.getClusterColor, parentActive: this.props.active, @@ -478,7 +478,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { PanelHeight: layoutDoc[HeightSym], ContentScaling: returnOne, ContainingCollectionView: this.props.CollectionView, - ContainingCollectionDoc: this.props.CollectionView.props.Document, + ContainingCollectionDoc: this.props.ContainingCollectionDoc, focus: this.focusDocument, backgroundColor: returnEmptyString, parentActive: this.props.active, @@ -699,10 +699,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { // otherwise, they are stored in fieldKey. All annotations to this document are stored in the extension document Doc.UpdateDocumentExtensionForField(this.props.DataDoc || this.props.Document, this.props.fieldKey); return ( -
@@ -725,7 +725,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { class CollectionFreeFormOverlayView extends React.Component boolean }> { render() { return + renderDepth={this.props.renderDepth} isSelected={this.props.isSelected} select={emptyFunction} />; } } @@ -734,7 +734,7 @@ class CollectionFreeFormBackgroundView extends React.Component) + renderDepth={this.props.renderDepth} isSelected={this.props.isSelected} select={emptyFunction} />); } } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index c85c3e55b..689a55ec4 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -31,6 +31,7 @@ interface MarqueeViewProps { addLiveTextDocument: (doc: Doc) => void; isSelected: () => boolean; isAnnotationOverlay: boolean; + setPreviewCursor?: (func: (x: number, y: number) => void) => void; } @observer @@ -44,6 +45,10 @@ export class MarqueeView extends React.Component @observable _visible: boolean = false; _commandExecuted = false; + componentDidMount() { + this.props.setPreviewCursor && this.props.setPreviewCursor(this.setPreviewCursor); + } + @action cleanupInteractions = (all: boolean = false) => { if (all) { @@ -203,11 +208,17 @@ export class MarqueeView extends React.Component } } + setPreviewCursor = (x: number, y: number) => { + this._downX = x; + this._downY = y; + PreviewCursor.Show(x, y, this.onKeyPress, this.props.addLiveTextDocument, this.props.getTransform, this.props.addDocument); + } + @action onClick = (e: React.MouseEvent): void => { if (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD) { - PreviewCursor.Show(e.clientX, e.clientY, this.onKeyPress, this.props.addLiveTextDocument, this.props.getTransform, this.props.addDocument); + this.setPreviewCursor(e.clientX, e.clientY); // let the DocumentView stopPropagation of this event when it selects this document } else { // why do we get a click event when the cursor have moved a big distance? // let's cut it off here so no one else has to deal with it. diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index bcb26b4c4..cd183a984 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -12,7 +12,7 @@ import { Doc, WidthSym, HeightSym } from "../../../new_fields/Doc"; import { random } from "animejs"; export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { - dataProvider?: (doc: Doc, dataDoc?: Doc) => { x: number, y: number, width: number, height: number, z: number, transition?: string } | undefined + dataProvider?: (doc: Doc, dataDoc?: Doc) => { x: number, y: number, width: number, height: number, z: number, transition?: string } | undefined; x?: number; y?: number; width?: number; @@ -99,8 +99,8 @@ export class CollectionFreeFormDocumentView extends DocComponent { return this.dataProvider ? this.dataProvider.width : this.panelWidth(); } - finalPanelHeight = () => { return this.dataProvider ? this.dataProvider.height : this.panelHeight(); } + finalPanelWidh = () => this.dataProvider ? this.dataProvider.width : this.panelWidth(); + finalPanelHeight = () => this.dataProvider ? this.dataProvider.height : this.panelHeight(); render() { trace(); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e89fddd25..759c064b4 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -264,7 +264,8 @@ export class DocumentView extends DocComponent(Docu if (e.cancelBubble && this.active) { document.removeEventListener("pointermove", this.onPointerMove); } - else if (!e.cancelBubble && this.active) { + else if (!e.cancelBubble && (SelectionManager.IsSelected(this) || + this.props.parentActive())) { if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { if (!e.altKey && !this.topMost && e.buttons === 1 && !BoolCast(this.Document.lockedPosition)) { document.removeEventListener("pointermove", this.onPointerMove); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 47b64e260..923dd1544 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -153,7 +153,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } }); return { frag: Fragment.fromArray(nodes), start: start }; - } + }; let findLinkNode = (node: Node, editor: EditorView) => { if (!node.isText) { const content = findLinkFrag(node.content, editor); @@ -162,7 +162,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe const marks = [...node.marks]; const linkIndex = marks.findIndex(mark => mark.type === editor.state.schema.marks.link); return linkIndex !== -1 && scrollToLinkID === marks[linkIndex].attrs.href.replace(/.*\/doc\//, "") ? node : undefined; - } + }; let start = -1; @@ -748,7 +748,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe let ref = editorView.domAtPos(editorView.state.selection.from); let refNode = ref.node as any; while (refNode && !("getBoundingClientRect" in refNode)) refNode = refNode.parentElement; - let r1 = refNode && (refNode as any).getBoundingClientRect(); + let r1 = refNode && refNode.getBoundingClientRect(); let r3 = self._ref.current!.getBoundingClientRect(); r1 && (self._ref.current!.scrollTop += (r1.top - r3.top) * self.props.ScreenToLocalTransform().Scale); return true; diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index b7ff84d4a..2147292d6 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -16,6 +16,9 @@ user-select: none; } } + .collectionFreeFormView-none { + pointer-events: none; + } } .pdfBox-cont-interactive { diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index e00635408..69e438d4f 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, observable, reaction, runInAction, untracked } from 'mobx'; import { observer } from "mobx-react"; import * as Pdfjs from "pdfjs-dist"; import "pdfjs-dist/web/pdf_viewer.css"; @@ -25,7 +25,7 @@ const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema); @observer export class PDFBox extends DocComponent(PdfDocument) { - public static LayoutString() { return FieldView.LayoutString(PDFBox); } + public static LayoutString(fieldExt?: string) { return FieldView.LayoutString(PDFBox, "data", fieldExt); } private _reactionDisposer?: IReactionDisposer; private _keyValue: string = ""; private _valueValue: string = ""; @@ -73,24 +73,24 @@ export class PDFBox extends DocComponent(PdfDocumen } public GetPage() { - return this._pdfViewer!._pdfViewer.currentPageNumber; + return this._pdfViewer!.pdfViewer.currentPageNumber; } @action public BackPage() { - this._pdfViewer!._pdfViewer.scrollPageIntoView({ pageNumber: Math.max(1, this.GetPage() - 1) }); + this._pdfViewer!.pdfViewer.scrollPageIntoView({ pageNumber: Math.max(1, this.GetPage() - 1) }); this.props.Document.curPage = this.GetPage(); } @action public GotoPage = (p: number) => { - this._pdfViewer!._pdfViewer.scrollPageIntoView(p); + this._pdfViewer!.pdfViewer.scrollPageIntoView(p); this.props.Document.curPage = this.GetPage(); } @action public ForwardPage() { - this._pdfViewer!._pdfViewer.scrollPageIntoView({ pageNumber: Math.min(this._pdfViewer!._pdfViewer.pagesCount, this.GetPage() + 1) }); + this._pdfViewer!.pdfViewer.scrollPageIntoView({ pageNumber: Math.min(this._pdfViewer!.pdfViewer.pagesCount, this.GetPage() + 1) }); this.props.Document.curPage = this.GetPage(); } @@ -153,7 +153,7 @@ export class PDFBox extends DocComponent(PdfDocumen + + return !this.props.active() ? (null) : - (<> + (
e.keyCode === KeyCodes.BACKSPACE || e.keyCode === KeyCodes.DELETE ? e.stopPropagation() : true} style={{ display: this.active() ? "flex" : "none" }}>
e.stopPropagation()} style={{ bottom: 0, left: `${this._searching ? 0 : 100}%` }}> + +
- - - - + this.GotoPage(Number(e.currentTarget.textContent))} + style={{ left: 20, top: 5, height: "30px", width: "30px", position: "absolute", pointerEvents: "all" }} + onClick={action(() => this._pageControls = !this._pageControls)}> + {`${NumCast(this.props.Document.curPage)}`} + + {this._pageControls ? pageBtns : (null)}
e.stopPropagation()}>
- ); +
); } loaded = (nw: number, nh: number, np: number) => { @@ -211,7 +221,7 @@ export class PDFBox extends DocComponent(PdfDocumen render() { const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField); - let classname = "pdfBox-cont" + (InkingControl.Instance.selectedTool || !this.props.isSelected() ? "" : "-interactive"); + let classname = "pdfBox-cont" + (InkingControl.Instance.selectedTool || !this.active ? "" : "-interactive"); return (!(pdfUrl instanceof PdfField) || !this._pdf ?
{`pdf, ${this.dataDoc[this.props.fieldKey]}, not found`}
:
e.stopPropagation()} onPointerDown={(e: React.PointerEvent) => { @@ -222,12 +232,12 @@ export class PDFBox extends DocComponent(PdfDocumen }}> {this.settingsPanel()}
); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 783495e5a..848f1ddcd 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -34,6 +34,9 @@ interface IViewerProps { fieldExtensionDoc: Doc; fieldKey: string; fieldExt: string; + PanelWidth: () => number; + PanelHeight: () => number; + ContentScaling: () => number; renderDepth: number; isSelected: () => boolean; loaded: (nw: number, nh: number, np: number) => void; @@ -46,6 +49,7 @@ interface IViewerProps { setPdfViewer: (view: PDFViewer) => void; ScreenToLocalTransform: () => Transform; ContainingCollectionView: Opt; + whenActiveChanged: (isActive: boolean) => void; } /** @@ -62,6 +66,7 @@ export class PDFViewer extends React.Component { @observable private _marqueeY: number = 0; @observable private _marqueeWidth: number = 0; @observable private _marqueeHeight: number = 0; + @observable private _marqueeing: boolean = false; public pdfViewer: any; private _isChildActive = false; @@ -74,7 +79,6 @@ export class PDFViewer extends React.Component { private _mainCont: React.RefObject = React.createRef(); private _selectionText: string = ""; private _marquee: React.RefObject = React.createRef(); - private _marqueeing: boolean = false; private _startX: number = 0; private _startY: number = 0; private _downX: number = 0; @@ -165,7 +169,7 @@ export class PDFViewer extends React.Component { @action setupPdfJsViewer = () => { document.addEventListener("pagesinit", () => this.pdfViewer.currentScaleValue = 1); - document.addEventListener("pagerendered", () => console.log("rendered")); + // document.addEventListener("pagerendered", () => console.log("rendered")); // bcz: works, but not needed except to debug var pdfLinkService = new PDFJSViewer.PDFLinkService(); let pdfFindController = new PDFJSViewer.PDFFindController({ linkService: pdfLinkService, @@ -249,19 +253,23 @@ export class PDFViewer extends React.Component { @action prevAnnotation = () => { this.Index = Math.max(this.Index - 1, 0); - let scrollToAnnotation = this.allAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y))[this.Index]; - this.allAnnotations.forEach(d => Doc.UnBrushDoc(d)); - Doc.BrushDoc(scrollToAnnotation); - this.props.scrollTo(NumCast(scrollToAnnotation.y)); + this.scrollToAnnotation(this.allAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y))[this.Index]); } @action nextAnnotation = () => { this.Index = Math.min(this.Index + 1, this.allAnnotations.length - 1); - let scrollToAnnotation = this.allAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y))[this.Index]; + this.scrollToAnnotation(this.allAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y))[this.Index]); + } + + @action + scrollToAnnotation = (scrollToAnnotation: Doc) => { this.allAnnotations.forEach(d => Doc.UnBrushDoc(d)); + let windowHgt = this.props.PanelHeight() / this.props.ContentScaling(); + let scrollRange = this._mainCont.current!.scrollHeight - windowHgt; + let pgScroll = scrollRange / this._pageSizes.length; + this._mainCont.current!.scrollTo(0, NumCast(scrollToAnnotation.y) - pgScroll / 2); Doc.BrushDoc(scrollToAnnotation); - this.props.scrollTo(NumCast(scrollToAnnotation.y)); } sendAnnotations = (page: number) => { @@ -278,6 +286,11 @@ export class PDFViewer extends React.Component { } } + @action + onScroll = (e: React.UIEvent) => { + this.props.Document.curPage = this.pdfViewer.currentPageNumber; + } + // get the page index that the vertical offset passed in is on getPageFromScroll = (vOffset: number) => { let index = 0; @@ -288,10 +301,6 @@ export class PDFViewer extends React.Component { return index; } - getScrollFromPage = (index: number): number => { - return numberRange(Math.min(this.props.pdf.numPages, index)).reduce((counter, i) => counter + this._pageSizes[i].height, 0); - } - @action createAnnotation = (div: HTMLDivElement, page: number) => { if (this._annotationLayer.current) { @@ -311,11 +320,14 @@ export class PDFViewer extends React.Component { } @action - search = (searchString: string) => { - if (this.pdfViewer._pageViewsReady) { + search = (searchString: string, fwd: boolean) => { + if (!searchString) { + fwd ? this.nextAnnotation() : this.prevAnnotation(); + } + else if (this.pdfViewer._pageViewsReady) { this.pdfViewer.findController.executeCommand('findagain', { caseSensitive: false, - findPrevious: undefined, + findPrevious: !fwd, highlightAll: true, phraseSearch: true, query: searchString @@ -325,7 +337,7 @@ export class PDFViewer extends React.Component { let executeFind = () => { this.pdfViewer.findController.executeCommand('find', { caseSensitive: false, - findPrevious: undefined, + findPrevious: !fwd, highlightAll: true, phraseSearch: true, query: searchString @@ -383,6 +395,7 @@ export class PDFViewer extends React.Component { this._marqueeX = Math.min(this._startX, this._startX + this._marqueeWidth); this._marqueeY = Math.min(this._startY, this._startY + this._marqueeHeight); this._marqueeWidth = Math.abs(this._marqueeWidth); + this._marqueeHeight = Math.abs(this._marqueeHeight); e.stopPropagation(); e.preventDefault(); } @@ -399,7 +412,6 @@ export class PDFViewer extends React.Component { for (let i = 0; i < clientRects.length; i++) { let rect = clientRects.item(i); if (rect/* && rect.width !== this._mainCont.current.getBoundingClientRect().width && rect.height !== this._mainCont.current.getBoundingClientRect().height / this.props.pdf.numPages*/) { - let page = this.getPageFromScroll(rect.top); let scaleY = this._mainCont.current.offsetHeight / boundingRect.height; let scaleX = this._mainCont.current.offsetWidth / boundingRect.width; if (rect.width !== this._mainCont.current.clientWidth) { @@ -552,26 +564,29 @@ export class PDFViewer extends React.Component { this._setPreviewCursor = func; } onClick = (e: React.MouseEvent) => { - this._setPreviewCursor && this._marqueeing && Math.abs(e.clientX - this._downX) < 3 && Math.abs(e.clientY - this._downY) < 3 && + this._setPreviewCursor && + this._marqueeing && + Math.abs(e.clientX - this._downX) < 3 && + Math.abs(e.clientY - this._downY) < 3 && this._setPreviewCursor(e.clientX, e.clientY); } whenActiveChanged = (isActive: boolean) => { this._isChildActive = isActive; - //this.props.whenActiveChanged(isActive); // bcz: is this needed here? + this.props.whenActiveChanged(isActive); // bcz: is this needed here? } active = () => { return this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0; } render() { - return (
e.stopPropagation()} onClick={this.onClick} ref={this._mainCont}> + return (
e.stopPropagation()} onClick={this.onClick} ref={this._mainCont}>
-
-
+
}
{this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map((anno, index) => )} -- cgit v1.2.3-70-g09d2 From 0c0b5697957af3c1aa4560a707d37b1073b743a5 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 26 Sep 2019 12:02:35 -0400 Subject: more pdf cleanup/fixes --- src/client/views/nodes/DocumentView.tsx | 1 + src/client/views/nodes/FieldView.tsx | 1 - src/client/views/nodes/PDFBox.scss | 41 +++++------ src/client/views/nodes/PDFBox.tsx | 124 ++++++++++---------------------- src/client/views/pdf/PDFViewer.tsx | 6 +- 5 files changed, 59 insertions(+), 114 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 759c064b4..d1d150027 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -261,6 +261,7 @@ export class DocumentView extends DocComponent(Docu document.addEventListener("pointerup", this.onPointerUp); } onPointerMove = (e: PointerEvent): void => { + console.log("Move " + e.clientX + " " + this.props.Document.title); if (e.cancelBubble && this.active) { document.removeEventListener("pointermove", this.onPointerMove); } diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 49fc2263d..ec1b03a40 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -50,7 +50,6 @@ export interface FieldViewProps { PanelWidth: () => number; PanelHeight: () => number; setVideoBox?: (player: VideoBox) => void; - setPdfBox?: (player: PDFBox) => void; ContentScaling: () => number; ChromeHeight?: () => number; } diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index 2147292d6..d82bcf02f 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -10,15 +10,16 @@ .pdfBox-cont { pointer-events: none; - .pdfPage-textlayer { - span { - pointer-events: none !important; - user-select: none; - } - } .collectionFreeFormView-none { pointer-events: none; } + .pdfViewer-text { + .textLayer { + span { + user-select: none; + } + } + } } .pdfBox-cont-interactive { @@ -32,21 +33,6 @@ } } -.react-pdf__Page { - transform-origin: left top; - position: absolute; - top: 0; - left: 0; -} - -.react-pdf__Page__textContent span { - user-select: text; -} - -.react-pdf__Document { - position: absolute; -} - .pdfBox-settingsCont { position: absolute; @@ -124,7 +110,7 @@ overflow: hidden; transition: left .5s; - .pdfBox-overlaySearchBar { + .pdfBox-searchBar { width: 70%; font-size: 14px; } @@ -149,7 +135,9 @@ transition: all 0.5s; } - .pdfBox-overlayButton-iconCont { + .pdfBox-overlayButton-iconCont, + .pdfBox-nextIcon, + .pdfBox-prevIcon { background: #121721; height: 30px; width: 70px; @@ -165,4 +153,9 @@ background: none; } - +.pdfBox-nextIcon { + left: 20; top: 5; height: 30px; position: absolute; +} +.pdfBox-prevIcon { + left: 50; top: 5; height: 30px; position: absolute; +} diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 30f4ce392..6aa8aded9 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -6,7 +6,7 @@ import "pdfjs-dist/web/pdf_viewer.css"; import 'react-image-lightbox/style.css'; import { Doc, Opt, WidthSym } from "../../../new_fields/Doc"; import { makeInterface } from "../../../new_fields/Schema"; -import { ComputedField, ScriptField } from '../../../new_fields/ScriptField'; +import { ScriptField } from '../../../new_fields/ScriptField'; import { Cast, NumCast } from "../../../new_fields/Types"; import { PdfField } from "../../../new_fields/URLField"; import { KeyCodes } from '../../northstar/utils/KeyCodes'; @@ -19,7 +19,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import { pageSchema } from "./ImageBox"; import "./PDFBox.scss"; import React = require("react"); -import { CollectionSchemaBooleanCell } from '../collections/CollectionSchemaCells'; +import { undoBatch } from '../../util/UndoManager'; type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>; const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema); @@ -27,73 +27,48 @@ const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema); @observer export class PDFBox extends DocComponent(PdfDocument) { public static LayoutString(fieldExt?: string) { return FieldView.LayoutString(PDFBox, "data", fieldExt); } - private _reactionDisposer?: IReactionDisposer; private _keyValue: string = ""; private _valueValue: string = ""; private _scriptValue: string = ""; private _searchString: string = ""; - @observable private _searching: boolean = false; + private _isChildActive = false; private _pdfViewer: PDFViewer | undefined; private _keyRef: React.RefObject = React.createRef(); private _valueRef: React.RefObject = React.createRef(); private _scriptRef: React.RefObject = React.createRef(); + @observable private _searching: boolean = false; @observable private _flyout: boolean = false; - @observable private _alt = false; @observable private _pdf: Opt; + @observable private _pageControls = false; @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); } - @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplate ? this.props.DataDoc : Doc.GetProto(this.props.Document); } componentDidMount() { - this.props.setPdfBox && this.props.setPdfBox(this); - - const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField); if (pdfUrl instanceof PdfField) { Pdfjs.getDocument(pdfUrl.url.pathname).promise.then(pdf => runInAction(() => this._pdf = pdf)); } } - - componentWillUnmount() { - this._reactionDisposer && this._reactionDisposer(); - } - - public search(string: string, fwd: boolean) { - this._pdfViewer && this._pdfViewer.search(string, fwd); - } - public prevAnnotation() { - this._pdfViewer && this._pdfViewer.prevAnnotation(); - } - public nextAnnotation() { - this._pdfViewer && this._pdfViewer.nextAnnotation(); - } - - setPdfViewer = (pdfViewer: PDFViewer) => { - this._pdfViewer = pdfViewer; - } - - @action - public BackPage() { - this._pdfViewer!.pdfViewer.scrollPageIntoView({ pageNumber: Math.max(1, NumCast(this.props.Document.curPage) - 1) }); - } - - @action - public GotoPage = (p: number) => { - this._pdfViewer!.pdfViewer.scrollPageIntoView({ pageNumber: p }); - } - - @action - public ForwardPage() { - this._pdfViewer!.pdfViewer.scrollPageIntoView({ pageNumber: Math.min(this._pdfViewer!.pdfViewer.pagesCount, NumCast(this.props.Document.curPage) + 1) }); + loaded = (nw: number, nh: number, np: number) => { + this.dataDoc.numPages = np; + if (!this.Document.nativeWidth || !this.Document.nativeHeight || !this.Document.scrollHeight) { + let oldaspect = (this.Document.nativeHeight || 0) / (this.Document.nativeWidth || 1); + this.Document.nativeWidth = nw; + this.Document.nativeHeight = this.Document.nativeHeight ? nw * oldaspect : nh; + this.Document.height = this.Document[WidthSym]() * (nh / nw); + } } - @action - setPanY = (y: number) => { - this.Document.panY = y; - } + public search(string: string, fwd: boolean) { this._pdfViewer && this._pdfViewer.search(string, fwd); } + public prevAnnotation() { this._pdfViewer && this._pdfViewer.prevAnnotation(); } + public nextAnnotation() { this._pdfViewer && this._pdfViewer.nextAnnotation(); } + public backPage() { this._pdfViewer!.gotoPage(NumCast(this.props.Document.curPage) - 1); } + public gotoPage = (p: number) => { this._pdfViewer!.gotoPage(p); } + public forwardPage() { this._pdfViewer!.gotoPage(NumCast(this.props.Document.curPage) + 1); } + @undoBatch @action private applyFilter = () => { let scriptText = this._scriptValue ? this._scriptValue : @@ -101,10 +76,6 @@ export class PDFBox extends DocComponent(PdfDocumen this.props.Document.filterScript = ScriptField.MakeFunction(scriptText); } - scrollTo = (y: number) => { - - } - private resetFilters = () => { this._keyValue = this._valueValue = this._scriptValue = ""; this._keyRef.current && (this._keyRef.current.value = ""); @@ -116,51 +87,38 @@ export class PDFBox extends DocComponent(PdfDocumen private newValueChange = (e: React.ChangeEvent) => this._valueValue = e.currentTarget.value; private newScriptChange = (e: React.ChangeEvent) => this._scriptValue = e.currentTarget.value; - _isChildActive = false; - whenActiveChanged = (isActive: boolean) => { - this._isChildActive = isActive; - this.props.whenActiveChanged(isActive); - } - active = () => { - return this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0; - } + whenActiveChanged = (isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive); + active = () => this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0; + setPdfViewer = (pdfViewer: PDFViewer) => { this._pdfViewer = pdfViewer; } searchStringChanged = (e: React.ChangeEvent) => this._searchString = e.currentTarget.value; - @observable _pageControls = false; + settingsPanel() { - trace(); let pageBtns = <> return !this.props.active() ? (null) : - (
e.keyCode === KeyCodes.BACKSPACE || e.keyCode === KeyCodes.DELETE ? e.stopPropagation() : true} style={{ display: this.active() ? "flex" : "none" }}> -
e.stopPropagation()} - style={{ bottom: 0, left: `${this._searching ? 0 : 100}%` }}> + (
e.keyCode === KeyCodes.BACKSPACE || e.keyCode === KeyCodes.DELETE ? e.stopPropagation() : true} + onPointerDown={e => e.stopPropagation()} style={{ display: this.active() ? "flex" : "none" }}> +
e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}> - -
@@ -170,7 +128,7 @@ export class PDFBox extends DocComponent(PdfDocumen
e.stopPropagation()}>
- this.GotoPage(Number(e.currentTarget.textContent))} + this.gotoPage(Number(e.currentTarget.textContent))} style={{ left: 20, top: 5, height: "30px", width: "30px", position: "absolute", pointerEvents: "all" }} onClick={action(() => this._pageControls = !this._pageControls)}> {`${NumCast(this.props.Document.curPage)}`} @@ -209,16 +167,6 @@ export class PDFBox extends DocComponent(PdfDocumen
); } - loaded = (nw: number, nh: number, np: number) => { - this.dataDoc.numPages = np; - if (!this.Document.nativeWidth || !this.Document.nativeHeight || !this.Document.scrollHeight) { - let oldaspect = (this.Document.nativeHeight || 0) / (this.Document.nativeWidth || 1); - this.Document.nativeWidth = nw; - this.Document.nativeHeight = this.Document.nativeHeight ? nw * oldaspect : nh; - this.Document.height = this.Document[WidthSym]() * (nh / nw); - } - } - render() { const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField); let classname = "pdfBox-cont" + (InkingControl.Instance.selectedTool || !this.active ? "" : "-interactive"); @@ -226,15 +174,15 @@ export class PDFBox extends DocComponent(PdfDocumen
{`pdf, ${this.dataDoc[this.props.fieldKey]}, not found`}
:
e.stopPropagation()} onPointerDown={(e: React.PointerEvent) => { let hit = document.elementFromPoint(e.clientX, e.clientY); - if (hit && hit.localName === "span") { + if (hit && hit.localName === "span" && this.props.isSelected()) { e.button === 0 && e.stopPropagation(); } }}> - boolean; loaded: (nw: number, nh: number, np: number) => void; - scrollTo: (y: number) => void; active: () => boolean; GoToPage?: (n: number) => void; addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; @@ -262,6 +261,11 @@ export class PDFViewer extends React.Component { this.scrollToAnnotation(this.allAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y))[this.Index]); } + @action + gotoPage = (p: number) => { + this.pdfViewer.scrollPageIntoView({ pageNumber: Math.min(Math.max(1, p), this._pageSizes.length) }); + } + @action scrollToAnnotation = (scrollToAnnotation: Doc) => { this.allAnnotations.forEach(d => Doc.UnBrushDoc(d)); -- cgit v1.2.3-70-g09d2 From 288a3a1368ab7de11007080e54cd1879196342a4 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 26 Sep 2019 14:37:49 -0400 Subject: hopefully last fixes for pdf interactions -- this time for marquee dragging with right button. --- src/client/views/collections/CollectionSubView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 36 +++++++++++++--------- .../views/nodes/CollectionFreeFormDocumentView.tsx | 1 - src/client/views/nodes/DocumentView.tsx | 10 +++--- src/client/views/pdf/PDFViewer.tsx | 15 +++++---- 5 files changed, 36 insertions(+), 28 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index ce80526b2..9ffb7fa6d 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -30,7 +30,7 @@ export interface CollectionViewProps extends FieldViewProps { PanelWidth: () => number; PanelHeight: () => number; chromeCollapsed: boolean; - setPreviewCursor?: (func: (x: number, y: number) => void) => void; + setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void; } export interface SubCollectionViewProps extends CollectionViewProps { diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 689a55ec4..44611869e 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -31,7 +31,7 @@ interface MarqueeViewProps { addLiveTextDocument: (doc: Doc) => void; isSelected: () => boolean; isAnnotationOverlay: boolean; - setPreviewCursor?: (func: (x: number, y: number) => void) => void; + setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void; } @observer @@ -151,15 +151,10 @@ export class MarqueeView extends React.Component } @action onPointerDown = (e: React.PointerEvent): void => { - this._downX = this._lastX = e.pageX; - this._downY = this._lastY = e.pageY; - this._commandExecuted = false; - PreviewCursor.Visible = false; - this.cleanupInteractions(true); + this._downX = this._lastX = e.clientX; + this._downY = this._lastY = e.clientY; if (e.button === 2 || (e.button === 0 && e.altKey)) { - document.addEventListener("pointermove", this.onPointerMove, true); - document.addEventListener("pointerup", this.onPointerUp, true); - document.addEventListener("keydown", this.marqueeCommand, true); + this.setPreviewCursor(e.clientX, e.clientY, true); if (e.altKey) { //e.stopPropagation(); // bcz: removed so that you can alt-click on button in a collection to switch link following behaviors. e.preventDefault(); @@ -182,6 +177,8 @@ export class MarqueeView extends React.Component e.stopPropagation(); e.preventDefault(); } + } else { + this.cleanupInteractions(true); // stop listening for events if another lower-level handle (e.g. another Marquee) has stopPropagated this } if (e.altKey) { e.preventDefault(); @@ -208,17 +205,28 @@ export class MarqueeView extends React.Component } } - setPreviewCursor = (x: number, y: number) => { - this._downX = x; - this._downY = y; - PreviewCursor.Show(x, y, this.onKeyPress, this.props.addLiveTextDocument, this.props.getTransform, this.props.addDocument); + setPreviewCursor = (x: number, y: number, drag: boolean) => { + if (drag) { + this._downX = this._lastX = x; + this._downY = this._lastY = y; + this._commandExecuted = false; + PreviewCursor.Visible = false; + this.cleanupInteractions(true); + document.addEventListener("pointermove", this.onPointerMove, true); + document.addEventListener("pointerup", this.onPointerUp, true); + document.addEventListener("keydown", this.marqueeCommand, true); + } else { + this._downX = x; + this._downY = y; + PreviewCursor.Show(x, y, this.onKeyPress, this.props.addLiveTextDocument, this.props.getTransform, this.props.addDocument); + } } @action onClick = (e: React.MouseEvent): void => { if (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD) { - this.setPreviewCursor(e.clientX, e.clientY); + this.setPreviewCursor(e.clientX, e.clientY, false); // let the DocumentView stopPropagation of this event when it selects this document } else { // why do we get a click event when the cursor have moved a big distance? // let's cut it off here so no one else has to deal with it. diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index cd183a984..49b6f22db 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -103,7 +103,6 @@ export class CollectionFreeFormDocumentView extends DocComponent this.dataProvider ? this.dataProvider.height : this.panelHeight(); render() { - trace(); return (
(Docu this._hitTemplateDrag = true; } } - if (this.active) e.stopPropagation(); // events stop at the lowest document that is active. + if (this.active && e.button === 0) e.stopPropagation(); // events stop at the lowest document that is active. if right dragging, we let it go through though to allow for context menu clicks. PointerMove callbacks should remove themselves if the move event gets stopPropagated by a lower-level handler (e.g, marquee drag); document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); document.addEventListener("pointermove", this.onPointerMove); document.addEventListener("pointerup", this.onPointerUp); } onPointerMove = (e: PointerEvent): void => { - console.log("Move " + e.clientX + " " + this.props.Document.title); if (e.cancelBubble && this.active) { - document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointermove", this.onPointerMove); // stop listening to pointerMove if something else has stopPropagated it (e.g., the MarqueeView) } - else if (!e.cancelBubble && (SelectionManager.IsSelected(this) || - this.props.parentActive())) { + else if (!e.cancelBubble && (SelectionManager.IsSelected(this) || this.props.parentActive())) { if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { - if (!e.altKey && !this.topMost && e.buttons === 1 && !BoolCast(this.Document.lockedPosition)) { + if (!e.altKey && !this.topMost && e.buttons === 1 && !this.Document.lockedPosition) { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); this.startDragging(this._downX, this._downY, e.ctrlKey || e.altKey ? "alias" : undefined, this._hitTemplateDrag); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 427da1d9b..9ef311c86 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -69,7 +69,7 @@ export class PDFViewer extends React.Component { public pdfViewer: any; private _isChildActive = false; - private _setPreviewCursor: undefined | ((x: number, y: number) => void); + private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean) => void); private _annotationLayer: React.RefObject = React.createRef(); private _reactionDisposer?: IReactionDisposer; private _annotationReactionDisposer?: IReactionDisposer; @@ -355,7 +355,12 @@ export class PDFViewer extends React.Component { @action onPointerDown = (e: React.PointerEvent): void => { // if alt+left click, drag and annotate + this._downX = e.clientX; + this._downY = e.clientY; if (NumCast(this.props.Document.scale, 1) !== 1) return; + if (e.button !== 0 && this.active()) { + this._setPreviewCursor && this._setPreviewCursor(e.clientX, e.clientY, true); + } this._marqueeing = false; if (!e.altKey && e.button === 0 && this.active()) { PDFMenu.Instance.StartDrag = this.startDrag; @@ -370,8 +375,6 @@ export class PDFViewer extends React.Component { } } else { - this._downX = e.clientX; - this._downY = e.clientY; // set marquee x and y positions to the spatially transformed position if (this._mainCont.current) { let boundingRect = this._mainCont.current.getBoundingClientRect(); @@ -564,15 +567,15 @@ export class PDFViewer extends React.Component { scrollXf = () => { return this._mainCont.current ? this.props.ScreenToLocalTransform().translate(0, this._mainCont.current.scrollTop) : this.props.ScreenToLocalTransform(); } - setPreviewCursor = (func?: (x: number, y: number) => void) => { + setPreviewCursor = (func?: (x: number, y: number, drag: boolean) => void) => { this._setPreviewCursor = func; } onClick = (e: React.MouseEvent) => { this._setPreviewCursor && - this._marqueeing && + e.button === 0 && Math.abs(e.clientX - this._downX) < 3 && Math.abs(e.clientY - this._downY) < 3 && - this._setPreviewCursor(e.clientX, e.clientY); + this._setPreviewCursor(e.clientX, e.clientY, false); } whenActiveChanged = (isActive: boolean) => { this._isChildActive = isActive; -- cgit v1.2.3-70-g09d2 From 29dec8b7e547d75983d4533862726692fabbabd1 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 26 Sep 2019 14:49:50 -0400 Subject: fixed warnings with PDF page numbering. --- src/client/views/collections/CollectionSubView.tsx | 2 +- src/client/views/nodes/PDFBox.tsx | 10 ++++------ src/client/views/pdf/PDFViewer.tsx | 3 +-- 3 files changed, 6 insertions(+), 9 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 9ffb7fa6d..954a27cbd 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -6,7 +6,7 @@ import { Id } from "../../../new_fields/FieldSymbols"; import { List } from "../../../new_fields/List"; import { listSpec } from "../../../new_fields/Schema"; import { ScriptField } from "../../../new_fields/ScriptField"; -import { BoolCast, Cast } from "../../../new_fields/Types"; +import { Cast } from "../../../new_fields/Types"; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; import { RouteStore } from "../../../server/RouteStore"; import { Utils } from "../../../Utils"; diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 6aa8aded9..9e8478ffa 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -122,17 +122,15 @@ export class PDFBox extends DocComponent(PdfDocumen
- - this.gotoPage(Number(e.currentTarget.textContent))} + this.gotoPage(Number(e.currentTarget.value))} style={{ left: 20, top: 5, height: "30px", width: "30px", position: "absolute", pointerEvents: "all" }} - onClick={action(() => this._pageControls = !this._pageControls)}> - {`${NumCast(this.props.Document.curPage)}`} - + onClick={action(() => this._pageControls = !this._pageControls)} /> {this._pageControls ? pageBtns : (null)}
e.stopPropagation()}>