From ef63a072a586f51e8fa51b4684987491287540b2 Mon Sep 17 00:00:00 2001 From: Naafiyan Ahmed Date: Thu, 7 Apr 2022 17:21:01 -0400 Subject: added grouping and write mode vs pen mode --- src/client/views/nodes/ImageBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/nodes/ImageBox.tsx') diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 0a4168698..a8da22b61 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -322,7 +322,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent; } marqueeDown = (e: React.PointerEvent) => { - if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) { + if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(CurrentUserUtils.SelectedTool)) { setupMoveUpEvents(this, e, action(e => { MarqueeAnnotator.clearAnnotations(this._savedAnnotations); this._marqueeing = [e.clientX, e.clientY]; -- cgit v1.2.3-70-g09d2 From 38e14d3eec79e40317bfd64388dd9bad97a24aff Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 29 Apr 2022 23:40:38 -0400 Subject: fixes to webpage proxying. fixes for images (and clippings) to use appropriate sampled image. --- src/client/views/nodes/ImageBox.tsx | 4 ++-- src/server/server_Initialization.ts | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src/client/views/nodes/ImageBox.tsx') diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 5982d4d66..d061cdd0b 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -72,10 +72,10 @@ export class ImageBox extends ViewBoxAnnotatableComponent ( { forceFull: this.props.renderDepth < 1 || this.layoutDoc._showFullRes, - scrSize: this.props.ScreenToLocalTransform().inverse().transformDirection(this.nativeSize.nativeWidth, this.nativeSize.nativeHeight)[0], + scrSize: this.props.ScreenToLocalTransform().inverse().transformDirection(this.nativeSize.nativeWidth, this.nativeSize.nativeHeight)[0] / this.nativeSize.nativeWidth, selected: this.props.isSelected() }), - ({ forceFull, scrSize, selected }) => this._curSuffix = this.fieldKey === "icon" ? "_m" : forceFull ? "_o" : scrSize < 100 ? "_s" : scrSize < 400 ? "_m" : scrSize < 800 || !selected ? "_l" : "_o", + ({ forceFull, scrSize, selected }) => this._curSuffix = this.fieldKey === "icon" ? "_m" : forceFull ? "_o" : scrSize < 0.25 ? "_s" : scrSize < 0.5 ? "_m" : scrSize < 0.8 || !selected ? "_l" : "_o", { fireImmediately: true, delay: 1000 }); this._disposers.path = reaction(() => ({ nativeSize: this.nativeSize, width: this.layoutDoc[WidthSym]() }), ({ nativeSize, width }) => { diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts index 81ed0d2a1..5bfd0213c 100644 --- a/src/server/server_Initialization.ts +++ b/src/server/server_Initialization.ts @@ -193,16 +193,11 @@ function proxyServe(req: any, requrl: string, response: any) { return `href="${resolvedServerUrl + "/corsProxy/http" + href}"`; }; const zipToStringDecoder = new (require('string_decoder').StringDecoder)('utf8'); - const htmlText = zipToStringDecoder.write(zlib.gunzipSync(htmlBodyMemoryStream.read()).toString('utf8') - .replace('', ' ') - .replace(/href="http([^"]*)"/g, replacer) - .replace(/target="_blank"/g, "")); - rewrittenHtmlBody = zlib.gzipSync(htmlText); const bodyStream = htmlBodyMemoryStream.read(); if (bodyStream) { const htmlText = zipToStringDecoder.write(zlib.gunzipSync(bodyStream).toString('utf8') .replace('', ' ') - // .replace(/href="http([^"]*)"/g, replacer) + .replace(/href="https?([^"]*)"/g, replacer) .replace(/target="_blank"/g, "")); rewrittenHtmlBody = zlib.gzipSync(htmlText); } else { @@ -216,7 +211,7 @@ function proxyServe(req: any, requrl: string, response: any) { }) .on('data', (e: any) => { try { - if (!response.connection.writable) { + if (response.connection?.writable) { rewrittenHtmlBody && response.send(rewrittenHtmlBody); } } catch (e) { @@ -237,12 +232,17 @@ function registerEmbeddedBrowseRelativePathHandler(server: express.Express) { const relativeUrl = req.originalUrl; if (!req.user) res.redirect("/home"); // When no user is logged in, we interpret a relative URL as being a reference to something they don't have access to and redirect to /home else if (!res.headersSent && req.headers.referer?.includes("corsProxy")) { // a request for something by a proxied referrer means it must be a relative reference. So construct a proxied absolute reference here. - const proxiedRefererUrl = decodeURIComponent(req.headers.referer); // (e.g., http://localhost:/corsProxy/https://en.wikipedia.org/wiki/Engelbart) - const dashServerUrl = proxiedRefererUrl.match(/.*corsProxy\//)![0]; // the dash server url (e.g.: http://localhost:/corsProxy/ ) - const actualReferUrl = proxiedRefererUrl.replace(dashServerUrl, ""); // the url of the referer without the proxy (e.g., : http:s//en.wikipedia.org/wiki/Engelbart) - const absoluteTargetBaseUrl = actualReferUrl.match(/http[s]?:\/\/[^\/]*/)![0]; // the base of the original url (e.g., https://en.wikipedia.org) - const redirectedProxiedUrl = dashServerUrl + encodeURIComponent(absoluteTargetBaseUrl + relativeUrl); // the new proxied full url (e..g, http://localhost:/corsProxy/https://en.wikipedia.org/) - res.redirect(redirectedProxiedUrl); + try { + const proxiedRefererUrl = decodeURIComponent(req.headers.referer); // (e.g., http://localhost:/corsProxy/https://en.wikipedia.org/wiki/Engelbart) + const dashServerUrl = proxiedRefererUrl.match(/.*corsProxy\//)![0]; // the dash server url (e.g.: http://localhost:/corsProxy/ ) + const actualReferUrl = proxiedRefererUrl.replace(dashServerUrl, ""); // the url of the referer without the proxy (e.g., : http:s//en.wikipedia.org/wiki/Engelbart) + const absoluteTargetBaseUrl = actualReferUrl.match(/https?:\/\/[^\/]*/)![0]; // the base of the original url (e.g., https://en.wikipedia.org) + const redirectedProxiedUrl = dashServerUrl + encodeURIComponent(absoluteTargetBaseUrl + relativeUrl); // the new proxied full url (e..g, http://localhost:/corsProxy/https://en.wikipedia.org/) + if (relativeUrl.startsWith("//")) res.redirect("http:" + relativeUrl); + else res.redirect(redirectedProxiedUrl); + } catch (e) { + console.log("Error embed: ", e); + } } else if (relativeUrl.startsWith("/search") && !req.headers.referer?.includes("corsProxy")) { // detect search query and use default search engine res.redirect(req.headers.referer + "corsProxy/" + encodeURIComponent("http://www.google.com" + relativeUrl)); } else { -- cgit v1.2.3-70-g09d2 From a2df645d2ffe83be24c20997c26eaf7257e847c0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 2 May 2022 18:09:22 -0400 Subject: fixed scaling ink label in lightbox,etc views. changed ink strokes so that clicking on label of closed stroke is lower preceden than clicking on line. fixed fontsize UI for setting ink label sizes. can no longer slide ink pts that are cusps along curve. --- src/client/views/InkStrokeProperties.ts | 61 +++++++++++----------- src/client/views/InkingStroke.tsx | 44 +++++++++++----- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 3 +- src/client/views/nodes/MapBox/MapBox.tsx | 4 +- src/client/views/nodes/VideoBox.tsx | 3 +- src/client/views/nodes/button/FontIconBox.tsx | 2 +- .../views/nodes/formattedText/RichTextMenu.tsx | 19 ++++--- src/client/views/pdf/PDFViewer.tsx | 3 +- 9 files changed, 84 insertions(+), 57 deletions(-) (limited to 'src/client/views/nodes/ImageBox.tsx') diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index e4486fc78..922f309d7 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -230,42 +230,41 @@ export class InkStrokeProperties { this.applyFunction(inkView, (view: DocumentView, ink: InkData) => { const order = controlIndex % 4; const closed = InkingStroke.IsClosed(ink); - if (origInk && this._currentPoint > 0 && this._currentPoint < ink.length - 1) { + const brokenIndices = Cast(inkView.props.Document.brokenInkIndices, listSpec("number"), []); + if (origInk && this._currentPoint > 0 && this._currentPoint < ink.length - 1 && brokenIndices.findIndex(value => value === controlIndex) === -1) { const cpt_before = ink[controlIndex]; const cpt = { X: cpt_before.X + deltaX, Y: cpt_before.Y + deltaY }; - if (true) { - const newink = origInk.slice(); - const start = this._currentPoint === 0 ? 0 : this._currentPoint - 4; - const splicedPoints = origInk.slice(start, start + (this._currentPoint === 0 || this._currentPoint === ink.length - 1 ? 4 : 8)); - const { nearestT, nearestSeg } = InkStrokeProperties.nearestPtToStroke(splicedPoints, cpt); - const samplesLeft: Point[] = []; - const samplesRight: Point[] = []; - var startDir = { x: 0, y: 0 }; - var endDir = { x: 0, y: 0 }; - for (var i = 0; i < nearestSeg / 4 + 1; i++) { - const bez = new Bezier(splicedPoints.slice(i * 4, i * 4 + 4).map(p => ({ x: p.X, y: p.Y }))); - if (i === 0) startDir = bez.derivative(0); - if (i === nearestSeg / 4) endDir = bez.derivative(nearestT); - for (var t = 0; t < (i === nearestSeg / 4 ? nearestT + .05 : 1); t += 0.05) { - const pt = bez.compute(i !== nearestSeg / 4 ? t : Math.min(nearestT, t)); - samplesLeft.push(new Point(pt.x, pt.y)); - } + const newink = origInk.slice(); + const start = this._currentPoint === 0 ? 0 : this._currentPoint - 4; + const splicedPoints = origInk.slice(start, start + (this._currentPoint === 0 || this._currentPoint === ink.length - 1 ? 4 : 8)); + const { nearestT, nearestSeg } = InkStrokeProperties.nearestPtToStroke(splicedPoints, cpt); + const samplesLeft: Point[] = []; + const samplesRight: Point[] = []; + var startDir = { x: 0, y: 0 }; + var endDir = { x: 0, y: 0 }; + for (var i = 0; i < nearestSeg / 4 + 1; i++) { + const bez = new Bezier(splicedPoints.slice(i * 4, i * 4 + 4).map(p => ({ x: p.X, y: p.Y }))); + if (i === 0) startDir = bez.derivative(0); + if (i === nearestSeg / 4) endDir = bez.derivative(nearestT); + for (var t = 0; t < (i === nearestSeg / 4 ? nearestT + .05 : 1); t += 0.05) { + const pt = bez.compute(i !== nearestSeg / 4 ? t : Math.min(nearestT, t)); + samplesLeft.push(new Point(pt.x, pt.y)); } - var { finalCtrls } = FitOneCurve(samplesLeft, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y }); - for (var i = nearestSeg / 4; i < splicedPoints.length / 4; i++) { - const bez = new Bezier(splicedPoints.slice(i * 4, i * 4 + 4).map(p => ({ x: p.X, y: p.Y }))); - if (i === nearestSeg / 4) startDir = bez.derivative(nearestT); - if (i === splicedPoints.length / 4 - 1) endDir = bez.derivative(1); - for (var t = i === nearestSeg / 4 ? nearestT : 0; t < (i === nearestSeg / 4 ? 1 + .05 + 1e-7 : 1 + 1e-7); t += 0.05) { - const pt = bez.compute(Math.min(1, t)); - samplesRight.push(new Point(pt.x, pt.y)); - } + } + var { finalCtrls } = FitOneCurve(samplesLeft, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y }); + for (var i = nearestSeg / 4; i < splicedPoints.length / 4; i++) { + const bez = new Bezier(splicedPoints.slice(i * 4, i * 4 + 4).map(p => ({ x: p.X, y: p.Y }))); + if (i === nearestSeg / 4) startDir = bez.derivative(nearestT); + if (i === splicedPoints.length / 4 - 1) endDir = bez.derivative(1); + for (var t = i === nearestSeg / 4 ? nearestT : 0; t < (i === nearestSeg / 4 ? 1 + .05 + 1e-7 : 1 + 1e-7); t += 0.05) { + const pt = bez.compute(Math.min(1, t)); + samplesRight.push(new Point(pt.x, pt.y)); } - const { finalCtrls: rightCtrls, error: errorRight } = FitOneCurve(samplesRight, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y }); - finalCtrls = finalCtrls.concat(rightCtrls); - newink.splice(this._currentPoint - 4, 8, ...finalCtrls); - return newink; } + const { finalCtrls: rightCtrls, error: errorRight } = FitOneCurve(samplesRight, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y }); + finalCtrls = finalCtrls.concat(rightCtrls); + newink.splice(this._currentPoint - 4, 8, ...finalCtrls); + return newink; } return ink.map((pt, i) => { diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 06671961d..1871ab5a4 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -328,12 +328,25 @@ export class InkingStroke extends ViewBoxBaseComponent() { StrCast(this.layoutDoc.strokeOutlineColor, !closed && fillColor && fillColor !== "transparent" ? StrCast(this.layoutDoc.color, "transparent") : "transparent") : ["transparent", "rgb(68, 118, 247)", "rgb(68, 118, 247)", "yellow", "magenta", "cyan", "orange"][highlightIndex]; // Invisible polygonal line that enables the ink to be selected by the user. - const clickableLine = (downHdlr?: (e: React.PointerEvent) => void) => InteractionUtils.CreatePolyline(inkData, inkLeft, inkTop, highlightColor, + const clickableLine = (downHdlr?: (e: React.PointerEvent) => void, suppressFill: boolean = false) => InteractionUtils.CreatePolyline(inkData, inkLeft, inkTop, highlightColor, inkStrokeWidth, inkStrokeWidth + (highlightIndex && closed && fillColor && (new Color(fillColor)).alpha() < 1 ? 6 : 15), StrCast(this.layoutDoc.strokeLineJoin), StrCast(this.layoutDoc.strokeLineCap), - StrCast(this.layoutDoc.strokeBezier), !closed ? "none" : fillColor === "transparent" ? "none" : fillColor, startMarker, endMarker, + StrCast(this.layoutDoc.strokeBezier), !closed ? "none" : fillColor === "transparent" || suppressFill ? "none" : fillColor, startMarker, endMarker, markerScale, undefined, inkScaleX, inkScaleY, "", this.props.pointerEvents ?? (this.props.layerProvider?.(this.props.Document) === false ? "none" : "visiblepainted"), 0.0, false, downHdlr); + const fsize = +(StrCast(this.props.Document.fontSize, "12px").replace("px", "")); + const lineHeightGuess = (+getComputedStyle(document.body).lineHeight.replace("px", "")) / (+getComputedStyle(document.body).fontSize.replace("px", "")); + const interactions = { + onPointerLeave: action(() => this._nearestScrPt = undefined), + onPointerMove: this.props.isSelected() ? this.onPointerMove : undefined, + onClick: (e: React.MouseEvent) => this._handledClick && e.stopPropagation(), + onContextMenu: () => { + const cm = ContextMenu.Instance; + !Doc.UserDoc().noviceMode && cm?.addItem({ description: "Recognize Writing", event: this.analyzeStrokes, icon: "paint-brush" }); + cm?.addItem({ description: "Toggle Mask", event: () => InkingStroke.toggleMask(this.rootDoc), icon: "paint-brush" }); + cm?.addItem({ description: "Edit Points", event: action(() => InkStrokeProperties.Instance._controlButton = !InkStrokeProperties.Instance._controlButton), icon: "paint-brush" }); + } + }; return
() { mixBlendMode: this.layoutDoc.tool === InkTool.Highlighter ? "multiply" : "unset", cursor: this.props.isSelected() ? "default" : undefined }} - onPointerLeave={action(e => this._nearestScrPt = undefined)} - onPointerMove={this.props.isSelected() ? this.onPointerMove : undefined} - onClick={e => this._handledClick && e.stopPropagation()} - onContextMenu={() => { - const cm = ContextMenu.Instance; - !Doc.UserDoc().noviceMode && cm?.addItem({ description: "Recognize Writing", event: this.analyzeStrokes, icon: "paint-brush" }); - cm?.addItem({ description: "Toggle Mask", event: () => InkingStroke.toggleMask(this.rootDoc), icon: "paint-brush" }); - cm?.addItem({ description: "Edit Points", event: action(() => InkStrokeProperties.Instance._controlButton = !InkStrokeProperties.Instance._controlButton), icon: "paint-brush" }); - }} + {...(!closed ? interactions : {})} > - {clickableLine(this.onPointerDown)} {inkLine} + {clickableLine(this.onPointerDown)} {!closed || (!RTFCast(this.rootDoc.text)?.Text && !this.props.isSelected()) ? (null) :
() { yPadding={10} xPadding={10} fieldKey={"text"} - fontSize={12} + fontSize={fsize} dontRegisterView={true} noSidebar={true} dontScale={true} @@ -374,6 +382,16 @@ export class InkingStroke extends ViewBoxBaseComponent() { />
} + {!closed ? null : + {clickableLine(this.onPointerDown, true)} + }
; } } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 3f16d3c49..edadd59c0 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -38,7 +38,7 @@ export class CollectionFreeFormDocumentView extends DocComponent this._savedAnnotations; render() { TraceMobx(); @@ -408,7 +409,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent this.props.PanelWidth() / 5; infoHeight = () => this.props.PanelHeight() / 5; anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; - + savedAnnotations = () => this._savedAnnotations; render() { const renderAnnotations = (docFilters?: () => string[]) => (null); // bcz: commmented this out. Otherwise, any documents that are rendered with an InfoWindow of a marker @@ -618,7 +618,7 @@ export class MapBox extends ViewBoxAnnotatableComponent} diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index e57cb1abe..c8b72990f 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -800,6 +800,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent; } + savedAnnotations = () => this._savedAnnotations; render() { const borderRad = this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BorderRounding); const borderRadius = borderRad?.includes("px") ? `${Number(borderRad.split("px")[0]) / this.scaling()}px` : borderRad; @@ -847,7 +848,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent} diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx index ca13590de..d3ff2586b 100644 --- a/src/client/views/nodes/button/FontIconBox.tsx +++ b/src/client/views/nodes/button/FontIconBox.tsx @@ -656,7 +656,7 @@ ScriptingGlobals.add(function setFontHighlight(color?: string, checkResult?: boo ScriptingGlobals.add(function setFontSize(size: string | number, checkResult?: boolean) { const editorView = RichTextMenu.Instance?.TextView?.EditorView; if (checkResult) { - return (editorView ? RichTextMenu.Instance.fontSize : StrCast(Doc.UserDoc().fontSize, "10px")).replace("px", ""); + return RichTextMenu.Instance.fontSize.replace("px", ""); } if (typeof size === "number") size = size.toString(); if (size && Number(size).toString() === size) size += "px"; diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 4814d6e9a..c5f76cc8d 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -9,7 +9,7 @@ import { wrapInList } from "prosemirror-schema-list"; import { EditorState, NodeSelection, TextSelection } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { Doc } from "../../../../fields/Doc"; -import { Cast, StrCast } from "../../../../fields/Types"; +import { Cast, NumCast, StrCast } from "../../../../fields/Types"; import { DocServer } from "../../../DocServer"; import { LinkManager } from "../../../util/LinkManager"; import { SelectionManager } from "../../../util/SelectionManager"; @@ -118,7 +118,7 @@ export class RichTextMenu extends AntimodeMenu { this.activeListType = this.getActiveListStyle(); this._activeAlignment = this.getActiveAlignment(); this._activeFontFamily = !activeFamilies.length ? "Arial" : activeFamilies.length === 1 ? String(activeFamilies[0]) : "various"; - this._activeFontSize = !activeSizes.length ? "13px" : activeSizes[0]; + this._activeFontSize = !activeSizes.length ? StrCast(this.TextView.Document.fontSize, StrCast(Doc.UserDoc().fontSize, "10px")) : activeSizes[0]; this._activeFontColor = !activeColors.length ? "black" : activeColors.length > 0 ? String(activeColors[0]) : "..."; this.activeHighlightColor = !activeHighlights.length ? "" : activeHighlights.length > 0 ? String(activeHighlights[0]) : "..."; @@ -310,10 +310,17 @@ export class RichTextMenu extends AntimodeMenu { setFontSize = (fontSize: string) => { if (this.view) { - const fmark = this.view.state.schema.marks.pFontSize.create({ fontSize }); - this.setMark(fmark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(fmark)), true); - this.view.focus(); - this.updateMenu(this.view, undefined, this.props); + if (this.view.state.selection.from === 1 && this.view.state.selection.empty && + (!this.view.state.doc.nodeAt(1) || !this.view.state.doc.nodeAt(1)?.marks.some(m => m.type.name === fontSize))) { + this.TextView.dataDoc.fontSize = fontSize; + this.view.focus(); + this.updateMenu(this.view, undefined, this.props); + } else { + const fmark = this.view.state.schema.marks.pFontSize.create({ fontSize }); + this.setMark(fmark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(fmark)), true); + this.view.focus(); + this.updateMenu(this.view, undefined, this.props); + } } } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index b55b2cf44..d3876906e 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -562,6 +562,7 @@ export class PDFViewer extends React.Component { ; } contentZoom = () => this._zoomed; + savedAnnotations = () => this._savedAnnotations; render() { TraceMobx(); return
@@ -586,7 +587,7 @@ export class PDFViewer extends React.Component { addDocument={(doc: Doc | Doc[]) => this.props.addDocument!(doc)} docView={this.props.docViewPath().lastElement()} finishMarquee={this.finishMarquee} - savedAnnotations={this._savedAnnotations} + savedAnnotations={this.savedAnnotations} annotationLayer={this._annotationLayer.current} mainCont={this._mainCont.current} />}
-- cgit v1.2.3-70-g09d2 From 57c1b8235b26a1b6a315922b4dc2926e1e597674 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 13 May 2022 18:17:10 -0400 Subject: removed layerProvider functionality. --- src/client/documents/Documents.ts | 3 +- src/client/views/DocComponent.tsx | 4 -- src/client/views/GestureOverlay.tsx | 1 - src/client/views/InkingStroke.tsx | 2 +- src/client/views/LightboxView.tsx | 1 - src/client/views/MainView.tsx | 6 --- src/client/views/OverlayView.tsx | 1 - src/client/views/Palette.tsx | 1 - src/client/views/PropertiesView.tsx | 2 - src/client/views/StyleProvider.tsx | 52 +++------------------- src/client/views/TemplateMenu.tsx | 1 - src/client/views/collections/CollectionMenu.tsx | 1 - .../collections/CollectionStackedTimeline.tsx | 2 +- .../views/collections/CollectionStackingView.tsx | 2 - .../views/collections/CollectionTreeView.tsx | 1 - src/client/views/collections/CollectionView.tsx | 2 +- src/client/views/collections/TabDocView.tsx | 19 +------- src/client/views/collections/TreeView.tsx | 2 - .../collectionFreeForm/CollectionFreeFormView.tsx | 24 +++++----- .../collections/collectionFreeForm/MarqueeView.tsx | 10 ++--- .../collectionLinear/CollectionLinearView.tsx | 1 - .../CollectionMulticolumnView.tsx | 1 - .../CollectionMultirowView.tsx | 1 - .../collectionSchema/CollectionSchemaView.tsx | 1 - .../collections/collectionSchema/SchemaTable.tsx | 1 - src/client/views/linking/LinkPopup.tsx | 3 +- src/client/views/nodes/AudioBox.tsx | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 - src/client/views/nodes/DocumentView.tsx | 5 +-- src/client/views/nodes/FilterBox.tsx | 1 - src/client/views/nodes/ImageBox.tsx | 2 +- src/client/views/nodes/KeyValuePair.tsx | 1 - src/client/views/nodes/LinkAnchorBox.tsx | 1 - src/client/views/nodes/LinkDocPreview.tsx | 1 - src/client/views/nodes/VideoBox.tsx | 2 +- src/client/views/nodes/WebBox.tsx | 6 +-- .../views/nodes/formattedText/DashDocView.tsx | 1 - .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- src/client/views/nodes/trails/PresBox.tsx | 2 +- src/client/views/nodes/trails/PresElementBox.tsx | 1 - src/client/views/pdf/Annotation.tsx | 2 +- src/client/views/search/SearchBox.tsx | 2 +- src/fields/Doc.ts | 2 +- src/mobile/AudioUpload.tsx | 1 - src/mobile/MobileInterface.tsx | 1 - src/server/server_Initialization.ts | 2 +- 46 files changed, 41 insertions(+), 143 deletions(-) (limited to 'src/client/views/nodes/ImageBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index d9c2e0d8b..797a129c4 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -122,7 +122,6 @@ export class DocumentOptions { _scrollTop?: number; // scroll location for pdfs _noAutoscroll?: boolean;// whether collections autoscroll when this item is dragged _chromeHidden?: boolean; // whether the editing chrome for a document is hidden - _layerTags?: List; // layer tags a document has (used for tab filtering "layers" in document tab) _searchDoc?: boolean; // is this a search document (used to change UI for search results in schema view) _forceActive?: boolean; // flag to handle pointer events when not selected (or otherwise active) _stayInCollection?: boolean;// whether the document should remain in its collection when someone tries to drag and drop it elsewhere @@ -426,7 +425,7 @@ export namespace Docs { childDontRegisterViews: true, _isLinkButton: true, _height: 150, description: "", showCaption: "description", backgroundColor: "lightblue", // lightblue is default color for linking dot and link documents text comment area links: "@links(self)", - _removeDropProperties: new List(["_layerTags", "isLinkButton"]), + _removeDropProperties: new List(["isLinkButton"]), } }], [DocumentType.LINKDB, { diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 79aaf2158..9c176a4fd 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -44,7 +44,6 @@ interface ViewBoxBaseProps { ContainingCollectionDoc: Opt; DocumentView?: () => DocumentView; fieldKey: string; - layerProvider?: (doc: Doc, assign?: boolean) => boolean; isSelected: (outsideReaction?: boolean) => boolean; isContentActive: () => boolean | undefined; renderDepth: number; @@ -85,7 +84,6 @@ export interface ViewBoxAnnotatableProps { DataDoc?: Doc; fieldKey: string; filterAddDocument?: (doc: Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example) - layerProvider?: (doc: Doc, assign?: boolean) => boolean; isContentActive: () => boolean | undefined; select: (isCtrlPressed: boolean) => void; whenChildContentsActiveChanged: (isActive: boolean) => void; @@ -209,13 +207,11 @@ export function ViewBoxAnnotatableComponent

() if ([AclAdmin, AclEdit].includes(GetEffectiveAcl(doc))) inheritParentAcls(CurrentUserUtils.ActiveDashboard, doc); doc.context = this.props.Document; if (annotationKey ?? this._annotationKeySuffix()) Doc.GetProto(doc).annotationOn = this.props.Document; - this.props.layerProvider?.(doc, true); Doc.AddDocToList(targetDataDoc, annotationKey ?? this.annotationKey, doc); }); } else { added.filter(doc => [AclAdmin, AclEdit].includes(GetEffectiveAcl(doc))).map(doc => { // only make a pushpin if we have acl's to edit the document - this.props.layerProvider?.(doc, true); //DocUtils.LeavePushpin(doc); doc._stayInCollection = undefined; doc.context = this.props.Document; diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 50dca0a99..482b62479 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -881,7 +881,6 @@ export class GestureOverlay extends Touchable { isContentActive={returnFalse} renderDepth={0} styleProvider={returnEmptyString} - layerProvider={undefined} docViewPath={returnEmptyDoclist} focus={DocUtils.DefaultFocus} whenChildContentsActiveChanged={emptyFunction} diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 3d9c048e5..d0f01c363 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -332,7 +332,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { inkStrokeWidth, inkStrokeWidth + (highlightIndex && closed && fillColor && (new Color(fillColor)).alpha() < 1 ? 6 : 15), StrCast(this.layoutDoc.strokeLineJoin), StrCast(this.layoutDoc.strokeLineCap), StrCast(this.layoutDoc.strokeBezier), !closed ? "none" : fillColor === "transparent" || suppressFill ? "none" : fillColor, startMarker, endMarker, - markerScale, undefined, inkScaleX, inkScaleY, "", this.props.pointerEvents?.() ?? (this.props.layerProvider?.(this.props.Document) === false ? "none" : "visiblepainted"), 0.0, + markerScale, undefined, inkScaleX, inkScaleY, "", this.props.pointerEvents?.() ?? (this.rootDoc._lockedPosition ? "none" : "visiblepainted"), 0.0, false, downHdlr); const fsize = +(StrCast(this.props.Document.fontSize, "12px").replace("px", "")); // bootsrap 3 style sheet sets line height to be 20px for default 14 point font size. diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 59ed0dc92..9882693ee 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -246,7 +246,6 @@ export class LightboxView extends React.Component { docFilters={this.docFilters} removeDocument={undefined} styleProvider={DefaultStyleProvider} - layerProvider={returnTrue} ScreenToLocalTransform={this.lightboxScreenToLocal} PanelWidth={this.lightboxWidth} PanelHeight={this.lightboxHeight} diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index db51c54f8..2e1d10955 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -281,7 +281,6 @@ export class MainView extends React.Component { addDocTab={this.addDocTabFunc} pinToPres={emptyFunction} docViewPath={returnEmptyDoclist} - layerProvider={undefined} styleProvider={undefined} rootSelected={returnTrue} isContentActive={returnTrue} @@ -361,7 +360,6 @@ export class MainView extends React.Component { addDocTab={this.addDocTabFunc} pinToPres={emptyFunction} docViewPath={returnEmptyDoclist} - layerProvider={undefined} styleProvider={this._sidebarContent.proto === Doc.UserDoc().myDashboards || this._sidebarContent.proto === Doc.UserDoc().myFilesystem ? DashboardStyleProvider : DefaultStyleProvider} rootSelected={returnTrue} removeDocument={returnFalse} @@ -402,7 +400,6 @@ export class MainView extends React.Component { docViewPath={returnEmptyDoclist} focus={DocUtils.DefaultFocus} styleProvider={DefaultStyleProvider} - layerProvider={undefined} isContentActive={returnTrue} whenChildContentsActiveChanged={emptyFunction} bringToFront={emptyFunction} @@ -516,7 +513,6 @@ export class MainView extends React.Component { dropAction={"alias"} setHeight={returnFalse} styleProvider={DefaultStyleProvider} - layerProvider={undefined} rootSelected={returnTrue} bringToFront={emptyFunction} select={emptyFunction} @@ -591,7 +587,6 @@ export class MainView extends React.Component { ContainingCollectionDoc={undefined} Document={DocumentLinksButton.invisibleWebDoc} dropAction={"move"} - layerProvider={undefined} styleProvider={undefined} isSelected={returnFalse} select={returnFalse} @@ -673,7 +668,6 @@ export class MainView extends React.Component { rootSelected={returnFalse} renderDepth={0} setHeight={returnFalse} - layerProvider={undefined} styleProvider={undefined} addDocTab={returnFalse} pinToPres={returnFalse} diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index 0f51cf9b2..ebad2981d 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -195,7 +195,6 @@ export class OverlayView extends React.Component { whenChildContentsActiveChanged={emptyFunction} focus={DocUtils.DefaultFocus} styleProvider={DefaultStyleProvider} - layerProvider={undefined} docViewPath={returnEmptyDoclist} addDocTab={returnFalse} pinToPres={emptyFunction} diff --git a/src/client/views/Palette.tsx b/src/client/views/Palette.tsx index 529697f71..954529bc9 100644 --- a/src/client/views/Palette.tsx +++ b/src/client/views/Palette.tsx @@ -54,7 +54,6 @@ export default class Palette extends React.Component { focus={emptyFunction} docViewPath={returnEmptyDoclist} styleProvider={returnEmptyString} - layerProvider={undefined} whenChildContentsActiveChanged={emptyFunction} bringToFront={emptyFunction} docFilters={returnEmptyFilter} diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 21c688421..bba2ac211 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -303,7 +303,6 @@ export class PropertiesView extends React.Component { fitContentsToDoc={returnTrue} rootSelected={returnFalse} styleProvider={DefaultStyleProvider} - layerProvider={undefined} docViewPath={returnEmptyDoclist} freezeDimensions={true} dontCenter={"y"} @@ -1010,7 +1009,6 @@ export class PropertiesView extends React.Component { createNewFilterDoc={this.createNewFilterDoc} updateFilterDoc={this.updateFilterDoc} docViewPath={returnEmptyDoclist} - layerProvider={undefined} dontCenter="y" /> diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 5056dedaf..334415b38 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -26,10 +26,6 @@ import React = require("react"); import { InkingStroke } from './InkingStroke'; import { TreeSort } from './collections/TreeView'; -export enum StyleLayers { - Background = "background" -} - export enum StyleProp { TreeViewIcon = "treeViewIcon", TreeViewSortings = "treeViewSortings",// options for how to sort tree view items @@ -56,14 +52,9 @@ export enum StyleProp { function darkScheme() { return CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark; } -function toggleBackground(doc: Doc) { +function toggleLockedPosition(doc: Doc) { UndoManager.RunInBatch(() => runInAction(() => { - const layers = StrListCast(doc._layerTags); - if (!layers.includes(StyleLayers.Background)) { - if (!layers.length) doc._layerTags = new List([StyleLayers.Background]); - else layers.push(StyleLayers.Background); - } - else layers.splice(layers.indexOf(StyleLayers.Background), 1); + doc._lockedPosition = !doc._lockedPosition; }), "toggleBackground"); } @@ -86,7 +77,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt doc && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === "comic"; - const isBackground = () => StrListCast(doc?._layerTags).includes(StyleLayers.Background); + const isBackground = () => doc && BoolCast(doc._lockedPosition); const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor); const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity); const showTitle = () => props?.styleProvider?.(doc, props, StyleProp.ShowTitle); @@ -177,7 +168,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt, props: Opt 0 && ((doc.type === DocumentType.COL && doc._viewType !== CollectionViewType.Pile) || [DocumentType.RTF, DocumentType.IMG, DocumentType.INK].includes(doc.type as DocumentType)) ? -

toggleBackground(doc)}> +
toggleLockedPosition(doc)}>
: (null); @@ -251,30 +240,3 @@ export function DashboardStyleProvider(doc: Opt, props: Opt { - if (doc.z) return true; - if (assign) { - const activeLayer = StrCast(thisDoc?.activeLayer); - if (activeLayer) { - const layers = Cast(doc._layerTags, listSpec("string"), []); - if (layers.length && !layers.includes(activeLayer)) layers.push(activeLayer); - else if (!layers.length) doc._layerTags = new List([activeLayer]); - if (activeLayer === "red" || activeLayer === "green" || activeLayer === "blue") doc._backgroundColor = activeLayer; - } - return true; - } else { - if (Doc.AreProtosEqual(doc, thisDoc)) return true; - const layers = StrListCast(doc._layerTags); - if (!layers.length && !thisDoc?.activeLayer) return true; - if (layers.includes(StrCast(thisDoc?.activeLayer))) return true; - return false; - } - }; -} \ No newline at end of file diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index b3a24e031..636f7042f 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -131,7 +131,6 @@ export class TemplateMenu extends React.Component { ContainingCollectionDoc={undefined} ContainingCollectionView={undefined} styleProvider={DefaultStyleProvider} - layerProvider={undefined} setHeight={returnFalse} docViewPath={returnEmptyDoclist} docFilters={returnEmptyFilter} diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 364a2440e..b3fbd4ca4 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -108,7 +108,6 @@ export class CollectionMenu extends AntimodeMenu{ dropAction={"alias"} setHeight={returnFalse} styleProvider={DefaultStyleProvider} - layerProvider={undefined} rootSelected={returnTrue} bringToFront={emptyFunction} select={emptyFunction} diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index de307416f..683b6d51d 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -392,7 +392,7 @@ export class CollectionStackedTimeline extends CollectionSubView + style={{ pointerEvents: this.rootDoc._lockedPosition ? "none" : undefined }}> {this.showIsTagged()} {this.renderSubView(this.collectionViewType, props)}
); diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 8dfc7edc7..73e5a9178 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -26,7 +26,7 @@ import { Colors, Shadows } from '../global/globalEnums'; import { LightboxView } from '../LightboxView'; import { DocFocusOptions, DocumentView, DocumentViewProps } from "../nodes/DocumentView"; import { PinProps, PresBox, PresMovement } from '../nodes/trails'; -import { DefaultLayerProvider, DefaultStyleProvider, StyleLayers, StyleProp } from '../StyleProvider'; +import { DefaultStyleProvider, StyleProp } from '../StyleProvider'; import { CollectionDockingView } from './CollectionDockingView'; import { CollectionDockingViewMenu } from './CollectionDockingViewMenu'; import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; @@ -94,20 +94,6 @@ export class TabDocView extends React.Component { if (tab.element[0].children[1].children.length === 1) { - const toggle = document.createElement("div"); - toggle.style.width = "10px"; - toggle.style.height = "calc(100% - 2px)"; - toggle.style.left = "-2px"; - toggle.style.bottom = "1px"; - toggle.style.borderTopRightRadius = "7px"; - toggle.style.position = "relative"; - toggle.style.display = "inline-block"; - toggle.style.background = "transparent"; - toggle.onclick = (e: MouseEvent) => { - if (tab.contentItem === tab.header.parent.getActiveContentItem()) { - tab.DashDoc.activeLayer = tab.DashDoc.activeLayer ? undefined : StyleLayers.Background; - } - }; iconWrap.className = "lm_iconWrap"; iconWrap.id = "lm_iconWrap"; closeWrap.className = "lm_iconWrap"; @@ -357,7 +343,6 @@ export class TabDocView extends React.Component { disableMinimap = () => !this._document || (this._document.layout !== CollectionView.LayoutString(Doc.LayoutFieldKey(this._document)) || this._document?._viewType !== CollectionViewType.Freeform); hideMinimap = () => this.disableMinimap() || BoolCast(this._document?.hideMinimap); - @computed get layerProvider() { return this._document && DefaultLayerProvider(this._document); } @computed get docView() { return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) : <> this._view = r)} @@ -369,7 +354,6 @@ export class TabDocView extends React.Component { isContentActive={returnTrue} PanelWidth={this.PanelWidth} PanelHeight={this.PanelHeight} - layerProvider={this.layerProvider} styleProvider={DefaultStyleProvider} docFilters={CollectionDockingView.Instance.childDocFilters} docRangeFilters={CollectionDockingView.Instance.childDocRangeFilters} @@ -520,7 +504,6 @@ export class TabMinimapView extends React.Component { whenChildContentsActiveChanged={emptyFunction} focus={DocUtils.DefaultFocus} styleProvider={TabMinimapView.miniStyleProvider} - layerProvider={undefined} addDocTab={this.props.addDocTab} pinToPres={TabDocView.PinDoc} docFilters={CollectionDockingView.Instance.childDocFilters} diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 164021358..d608f800c 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -663,7 +663,6 @@ export class TreeView extends React.Component { hideDecorationTitle={this.props.treeView.outlineMode} hideResizeHandles={this.props.treeView.outlineMode} styleProvider={this.titleStyleProvider} - layerProvider={returnTrue} docViewPath={returnEmptyDoclist} treeViewDoc={this.props.treeView.props.Document} addDocument={undefined} @@ -760,7 +759,6 @@ export class TreeView extends React.Component { renderDepth={this.props.renderDepth + 1} treeViewDoc={this.props.treeView?.props.Document} rootSelected={returnTrue} - layerProvider={returnTrue} docViewPath={this.props.treeView.props.docViewPath} docFilters={returnEmptyFilter} docRangeFilters={returnEmptyFilter} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 4f79d19ad..322944d92 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -44,7 +44,7 @@ import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox"; import { PresBox } from "../../nodes/trails/PresBox"; import { VideoBox } from "../../nodes/VideoBox"; import { CreateImage } from "../../nodes/WebBoxRenderer"; -import { StyleLayers, StyleProp } from "../../StyleProvider"; +import { StyleProp } from "../../StyleProvider"; import { CollectionDockingView } from "../CollectionDockingView"; import { CollectionSubView } from "../CollectionSubView"; import { CollectionViewType } from "../CollectionView"; @@ -122,8 +122,6 @@ export class CollectionFreeFormView extends CollectionSubView ele.bounds && !ele.bounds.z).map(ele => ele.ele); } - @computed get backgroundEvents() { return this.props.layerProvider?.(this.layoutDoc) === false && SnappingManager.GetIsDragging(); } - @computed get backgroundActive() { return this.props.layerProvider?.(this.layoutDoc) === false && this.props.isContentActive(); } @computed get fitToContentVals() { return { bounds: { ...this.contentBounds, cx: (this.contentBounds.x + this.contentBounds.r) / 2, cy: (this.contentBounds.y + this.contentBounds.b) / 2 }, @@ -222,8 +220,8 @@ export class CollectionFreeFormView extends CollectionSubView s.backgroundColor); // 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?.filter(s => !StrListCast(s._layerTags).includes(StyleLayers.Background)).map(s => styleProp = StrCast(s.backgroundColor)); - set?.filter(s => StrListCast(s._layerTags).includes(StyleLayers.Background)).map(s => styleProp = StrCast(s.backgroundColor)); + set?.map(s => styleProp = StrCast(s.backgroundColor)); } } //else if (doc && NumCast(doc.group, -1) !== -1) styleProp = "gray"; return styleProp; @@ -1017,7 +1014,7 @@ export class CollectionFreeFormView extends CollectionSubView { - if (sendToBack || StrListCast(doc._layerTags).includes(StyleLayers.Background)) { + if (sendToBack) { doc.zIndex = 0; } else if (doc.isInkMask) { doc.zIndex = 5000; @@ -1155,7 +1152,7 @@ export class CollectionFreeFormView extends CollectionSubView { const engine = this.props.layoutEngine?.() || StrCast(this.props.Document._layoutEngine); - const pointerEvents = this.props.isContentActive() === false ? "none" : this.backgroundActive || this.props.childPointerEvents ? "all" : + const pointerEvents = this.props.isContentActive() === false ? "none" : this.props.childPointerEvents ? "all" : (this.props.viewDefDivClick || (engine === "pass" && !this.props.isSelected(true))) ? "none" : this.props.pointerEvents?.(); return pointerEvents; } @@ -1195,7 +1192,6 @@ export class CollectionFreeFormView extends CollectionSubView intersectRect(docDims(doc), rect); const otherBounds = { left: this.panX(), top: this.panY(), width: Math.abs(size[0]), height: Math.abs(size[1]) }; - let snappableDocs = activeDocs.filter(doc => !StrListCast(doc._layerTags).includes(StyleLayers.Background) && doc.z === undefined && isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to + let snappableDocs = activeDocs.filter(doc => doc.z === undefined && isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to !snappableDocs.length && (snappableDocs = activeDocs.filter(doc => doc.z === undefined && isDocInView(doc, selRect))); // if not, see if there are background docs to snap to !snappableDocs.length && (snappableDocs = activeDocs.filter(doc => doc.z !== undefined && isDocInView(doc, otherBounds))); // if not, then why not snap to floating docs @@ -1739,7 +1735,7 @@ export class CollectionFreeFormView extends CollectionSubView } - {this.props.Document._isGroup && SnappingManager.GetIsDragging() && (this.ChildDrag || this.props.layerProvider?.(this.props.Document) === false) ? + {this.props.Document._isGroup && SnappingManager.GetIsDragging() && this.ChildDrag ?
, options: DocumentOptions, id?: string) => Doc>, layers: string[], makeGroup: Opt) => { + getCollection = action((selected: Doc[], creator: Opt<(documents: Array, options: DocumentOptions, id?: string) => Doc>, makeGroup: Opt) => { const newCollection = creator ? creator(selected, { title: "nested stack", }) : ((doc: Doc) => { Doc.GetProto(doc).data = new List(selected); Doc.GetProto(doc).title = makeGroup ? "grouping" : "nested freeform"; @@ -357,7 +356,6 @@ export class MarqueeView extends React.Component(layers); newCollection._width = this.Bounds.width; newCollection._height = this.Bounds.height; newCollection._isGroup = makeGroup; @@ -437,7 +435,7 @@ export class MarqueeView extends React.Component { - const newCollection = this.getCollection([], undefined, [StyleLayers.Background], undefined); + const newCollection = this.getCollection([], undefined, undefined); this.props.addDocument?.(newCollection); MarqueeOptionsMenu.Instance.fadeOut(true); this.hideMarquee(); @@ -617,7 +615,7 @@ export class MarqueeView extends React.Component this.props.layerProvider?.(doc) !== false && !doc.z).map(selectFunc); + this.props.activeDocuments().filter(doc => !doc.z && !doc._lockedPosition).map(selectFunc); if (!selection.length && selectBackgrounds) this.props.activeDocuments().filter(doc => doc.z === undefined).map(selectFunc); if (!selection.length) this.props.activeDocuments().filter(doc => doc.z !== undefined).map(selectFunc); return selection; diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index c615bfb8e..bec582dcd 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -155,7 +155,6 @@ export class CollectionLinearView extends CollectionSubView() { renderDepth={this.props.renderDepth + 1} focus={emptyFunction} styleProvider={this.props.styleProvider} - layerProvider={this.props.layerProvider} docViewPath={returnEmptyDoclist} whenChildContentsActiveChanged={emptyFunction} bringToFront={emptyFunction} diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 6929a1cd8..92f9b2f49 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -219,7 +219,6 @@ export class CollectionMulticolumnView extends CollectionSubView() { Document={layout} DataDoc={layout.resolvedDataDoc as Doc} styleProvider={this.props.styleProvider} - layerProvider={this.props.layerProvider} docViewPath={this.props.docViewPath} LayoutTemplate={this.props.childLayoutTemplate} LayoutTemplateString={this.props.childLayoutString} diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 7e2b83230..4c4054b09 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -218,7 +218,6 @@ export class CollectionMultirowView extends CollectionSubView() { Document={layout} DataDoc={layout.resolvedDataDoc as Doc} styleProvider={this.props.styleProvider} - layerProvider={this.props.layerProvider} docViewPath={this.props.docViewPath} LayoutTemplate={this.props.childLayoutTemplate} LayoutTemplateString={this.props.childLayoutString} diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index a93762ea4..b731479a5 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -417,7 +417,6 @@ export class CollectionSchemaView extends CollectionSubView() { docRangeFilters={this.childDocRangeFilters} searchFilterDocs={this.searchFilterDocs} styleProvider={DefaultStyleProvider} - layerProvider={undefined} docViewPath={returnEmptyDoclist} ContainingCollectionDoc={this.props.CollectionView?.props.Document} ContainingCollectionView={this.props.CollectionView} diff --git a/src/client/views/collections/collectionSchema/SchemaTable.tsx b/src/client/views/collections/collectionSchema/SchemaTable.tsx index 605481ddf..bea5b3be6 100644 --- a/src/client/views/collections/collectionSchema/SchemaTable.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTable.tsx @@ -573,7 +573,6 @@ export class SchemaTable extends React.Component { Document={this._showDoc} DataDoc={this._showDataDoc} styleProvider={DefaultStyleProvider} - layerProvider={undefined} docViewPath={returnEmptyDoclist} freezeDimensions={true} focus={DocUtils.DefaultFocus} diff --git a/src/client/views/linking/LinkPopup.tsx b/src/client/views/linking/LinkPopup.tsx index c8be9069c..4b33ef8ae 100644 --- a/src/client/views/linking/LinkPopup.tsx +++ b/src/client/views/linking/LinkPopup.tsx @@ -67,7 +67,7 @@ export class LinkPopup extends React.Component { */} - { pinToPres={emptyFunction} rootSelected={returnTrue} styleProvider={DefaultStyleProvider} - layerProvider={undefined} removeDocument={undefined} ScreenToLocalTransform={Transform.Identity} PanelWidth={this.getPWidth} diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index e28e5b453..d97cb6f84 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -654,7 +654,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent {!this.path ? this.recordingControls : this.playbackControls}
; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index edadd59c0..5a0ab9110 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -21,7 +21,6 @@ import React = require("react"); export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined; sizeProvider?: (doc: Doc, replica: string) => { width: number, height: number } | undefined; - layerProvider: ((doc: Doc, assign?: boolean) => boolean) | undefined; renderCutoffProvider: (doc: Doc) => boolean; zIndex?: number; highlight?: boolean; @@ -159,7 +158,6 @@ export class CollectionFreeFormDocumentView extends DocComponent number; docViewPath: () => DocumentView[]; dataTransition?: string; // specifies animation transition - used by collectionPile and potentially other layout engines when changing the size of documents so that the change won't be abrupt - layerProvider: undefined | ((doc: Doc, assign?: boolean) => boolean); styleProvider: Opt; focus: DocFocusFunc; fitWidth?: (doc: Doc) => boolean; @@ -474,7 +473,7 @@ export class DocumentViewInternal extends DocComponent() { treeViewHideHeaderFields={false} dontRegisterView={true} styleProvider={this.FilterStyleProvider} - layerProvider={this.props.layerProvider} docViewPath={this.props.docViewPath} scriptContext={this.props.scriptContext} moveDocument={returnFalse} diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index e7c43e5cd..3b04aa807 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -379,7 +379,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent { docRangeFilters: returnEmptyFilter, searchFilterDocs: returnEmptyDoclist, styleProvider: DefaultStyleProvider, - layerProvider: undefined, docViewPath: returnEmptyDoclist, ContainingCollectionView: undefined, ContainingCollectionDoc: undefined, diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index 437d29f39..7fd289a97 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -89,7 +89,6 @@ export class LinkAnchorBox extends ViewBoxBaseComponent() { openLinkTargetOnRight = (e: React.MouseEvent) => { const alias = Doc.MakeAlias(Cast(this.layoutDoc[this.fieldKey], Doc, null)); alias._isLinkButton = undefined; - alias._layerTags = undefined; alias.layoutKey = "layout"; this.props.addDocTab(alias, "add:right"); } diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 375434933..ba515fb89 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -179,7 +179,6 @@ export class LinkDocPreview extends React.Component { moveDocument={returnFalse} rootSelected={returnFalse} styleProvider={this.props.docProps?.styleProvider} - layerProvider={this.props.docProps?.layerProvider} docViewPath={returnEmptyDoclist} ScreenToLocalTransform={Transform.Identity} isDocumentActive={returnFalse} diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 3b4c94562..c350e3139 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -809,7 +809,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent { e.stopPropagation(); e.preventDefault(); }}> diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 20e01be05..445df8ddd 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -74,7 +74,7 @@ export class WebBox extends ViewBoxAnnotatableComponent a.textInlineAnnotations); } @computed get webField() { return Cast(this.dataDoc[this.props.fieldKey], WebField)?.url; } - @computed get webThumb() { return this.props.thumbShown?.() && ImageCast(this.layoutDoc["thumb-frozen"], ImageCast(this.layoutDoc.thumbScrollTop === this.layoutDoc._scrollTop ? this.layoutDoc.thumb : undefined))?.url } + @computed get webThumb() { return this.props.thumbShown?.() && ImageCast(this.layoutDoc["thumb-frozen"], ImageCast(this.layoutDoc.thumbScrollTop === this.layoutDoc._scrollTop ? this.layoutDoc.thumb : undefined))?.url; } constructor(props: any) { super(props); @@ -134,7 +134,7 @@ export class WebBox extends ViewBoxAnnotatableComponent setTimeout(action(() => { this.lockout = false; this.layoutDoc.thumb = new ImageField(returnedfilename); - this.layoutDoc.thumbScrollTop = scrollTop + this.layoutDoc.thumbScrollTop = scrollTop; }), 500)); }) .catch(function (error: any) { @@ -717,7 +717,7 @@ export class WebBox extends ViewBoxAnnotatableComponent !this._draggingSidebar && this.props.isContentActive() && this.props.pointerEvents?.() !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none"; annotationPointerEvents = () => this._isAnnotating || SnappingManager.GetIsDragging() ? "all" : "none"; render() { - const pointerEvents = this.props.layerProvider?.(this.layoutDoc) === false ? "none" : this.props.pointerEvents?.() as any; + const pointerEvents = this.layoutDoc._lockedPosition ? "none" : this.props.pointerEvents?.() as any; const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1; const scale = previewScale * (this.props.scaling?.() || 1); const renderAnnotations = (docFilters?: () => string[]) => diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index 364be461f..1d8e3a2cf 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -182,7 +182,6 @@ export class DashDocViewInternal extends React.Component { removeDocument={this.removeDoc} isDocumentActive={returnFalse} isContentActive={this._textBox.props.isContentActive} - layerProvider={this._textBox.props.layerProvider} styleProvider={this._textBox.props.styleProvider} docViewPath={this._textBox.props.docViewPath} ScreenToLocalTransform={this.getDocTransform} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 29117794e..f2a222cee 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1630,7 +1630,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const active = this.props.isContentActive(); const scale = (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1); const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : ""; - const interactive = (CurrentUserUtils.SelectedTool === InkTool.None || SnappingManager.GetIsDragging()) && (this.layoutDoc.z || this.props.layerProvider?.(this.layoutDoc) !== false); + const interactive = (CurrentUserUtils.SelectedTool === InkTool.None || SnappingManager.GetIsDragging()) && (this.layoutDoc.z || !this.layoutDoc._lockedPosition); if (!selected && FormattedTextBoxComment.textBox === this) setTimeout(FormattedTextBoxComment.Hide); const minimal = this.props.ignoreAutoHeight; const paddingX = NumCast(this.layoutDoc._xMargin, this.props.xPadding || 0); diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 820d7ef96..64f5a296f 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -700,7 +700,7 @@ export class PresBox extends ViewBoxBaseComponent() { removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.rootDoc, this.fieldKey, doc); getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight panelHeight = () => this.props.PanelHeight() - 40; - isContentActive = (outsideReaction?: boolean) => ((CurrentUserUtils.SelectedTool === InkTool.None && this.props.layerProvider?.(this.layoutDoc) !== false) && + isContentActive = (outsideReaction?: boolean) => ((CurrentUserUtils.SelectedTool === InkTool.None && !this.layoutDoc._lockedPosition) && (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false) /** diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index f4dc9b615..ef918d991 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -80,7 +80,6 @@ export class PresElementBox extends ViewBoxBaseComponent() { Document={this.targetDoc} DataDoc={this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]} styleProvider={this.styleProvider} - layerProvider={this.props.layerProvider} docViewPath={returnEmptyDoclist} rootSelected={returnTrue} addDocument={returnFalse} diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index fb2e33e2a..5bdce273d 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -26,7 +26,7 @@ export {DocListCast(this.props.anno.textInlineAnnotations).map(a => )} - + ; } } diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 2905e96d9..152b7bbcb 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -127,7 +127,7 @@ export class SearchBox extends ViewBoxBaseComponent() { static foreachRecursiveDoc(docs: Doc[], func: (depth: number, doc: Doc) => void) { let newarray: Doc[] = []; var depth = 0; - let visited: Doc[] = []; + const visited: Doc[] = []; while (docs.length > 0) { newarray = []; docs.filter(d => d && !visited.includes(d)).forEach(d => { diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 9de8d0831..194b3ba27 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1026,7 +1026,7 @@ export namespace Doc { if (status === DocBrushStatus.unbrushed) { const lastBrushed = Array.from(brushManager.BrushedDoc.keys()).lastElement(); if (lastBrushed) { - for (var link of LinkManager.Instance.getAllDirectLinks(lastBrushed)) { + for (const link of LinkManager.Instance.getAllDirectLinks(lastBrushed)) { const a1 = Cast(link.anchor1, Doc, null); const a2 = Cast(link.anchor2, Doc, null); if (Doc.AreProtosEqual(a1, doc) || Doc.AreProtosEqual(a2, doc) || diff --git a/src/mobile/AudioUpload.tsx b/src/mobile/AudioUpload.tsx index 88221732e..418464f0e 100644 --- a/src/mobile/AudioUpload.tsx +++ b/src/mobile/AudioUpload.tsx @@ -96,7 +96,6 @@ export class AudioUpload extends React.Component { isDocumentActive={returnTrue} isContentActive={emptyFunction} focus={emptyFunction} - layerProvider={undefined} styleProvider={() => "rgba(0,0,0,0)"} docViewPath={returnEmptyDoclist} whenChildContentsActiveChanged={emptyFunction} diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index cfcc48608..78ec706d7 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -214,7 +214,6 @@ export class MobileInterface extends React.Component { isContentActive={emptyFunction} focus={DocUtils.DefaultFocus} styleProvider={this.whitebackground} - layerProvider={undefined} docViewPath={returnEmptyDoclist} whenChildContentsActiveChanged={emptyFunction} bringToFront={emptyFunction} diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts index bdea57cb2..fd000a83c 100644 --- a/src/server/server_Initialization.ts +++ b/src/server/server_Initialization.ts @@ -195,7 +195,7 @@ function proxyServe(req: any, requrl: string, response: any) { console.log("EROR?: ", e); } } else req.pipe(request(requrl)).pipe(response); - } + }; retrieveHTTPBody = () => { req.headers.cookie = ""; req.pipe(request(requrl)) -- cgit v1.2.3-70-g09d2 From e6b882080471d915a80400e7e9a97ff78a232147 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 18 May 2022 14:05:39 -0400 Subject: fixed linking bug so that both start and end link can be regions. added zoom to target checkbox for link editing. extracted out a new field pointerEvents so that lockPosition is not automatically conflratd with no pointer events. updated freeformview focus to work with zooming on region selections. --- src/client/documents/Documents.ts | 3 +- src/client/views/DocumentButtonBar.tsx | 2 +- src/client/views/PropertiesView.tsx | 37 +++++++++++++++++++--- src/client/views/StyleProvider.tsx | 5 +-- .../collectionFreeForm/CollectionFreeFormView.tsx | 24 +++++++------- src/client/views/linking/LinkEditor.scss | 18 +++++++++++ src/client/views/linking/LinkEditor.tsx | 30 +++++++++++++++--- src/client/views/nodes/DocumentView.tsx | 4 +-- src/client/views/nodes/ImageBox.tsx | 6 ++-- src/client/views/nodes/PDFBox.tsx | 2 +- src/client/views/nodes/WebBox.tsx | 4 ++- src/client/views/pdf/PDFViewer.tsx | 29 +++++++++-------- 12 files changed, 120 insertions(+), 44 deletions(-) (limited to 'src/client/views/nodes/ImageBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 797a129c4..2dd8de089 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -173,6 +173,7 @@ export class DocumentOptions { label?: string; hidden?: boolean; _hidden?: boolean; + pointerEvents?: string; // pointer events that the documentview should have mediaState?: string; // status of media document: "pendingRecording", "recording", "paused", "playing" autoPlayAnchors?: boolean; // whether to play audio/video when an anchor is clicked in a stackedTimeline. dontPlayLinkOnSelect?: boolean; // whether an audio/video should start playing when a link is followed to it. @@ -482,7 +483,7 @@ export namespace Docs { }], [DocumentType.MARKER, { layout: { view: CollectionView, dataField: defaultDataKey }, - options: { links: "@links(self)", hideLinkButton: true } + options: { links: "@links(self)", hideLinkButton: true, pointerEvents: "none" } }], [DocumentType.INK, { // NOTE: this is unused!! ink fields are filled in directly within the InkDocument() method layout: { view: InkingStroke, dataField: defaultDataKey }, diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 9b95f1525..ffa168f6b 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -192,7 +192,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
{"Set onClick to follow primary link"}
}>
this.props.views().map(view => view?.docView?.toggleFollowLink(undefined, false, false)))}> + onClick={undoBatch(e => this.props.views().map(view => view?.docView?.toggleFollowLink(undefined, undefined, false)))}>
; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index bba2ac211..bcfd2dd56 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -1227,6 +1227,13 @@ export class PropertiesView extends React.Component { setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.selectedDoc.displayArrow = !this.selectedDoc.displayArrow))); } + toggleZoomToTarget1 = (e: React.PointerEvent) => { + setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => Cast(this.selectedDoc.anchor1, Doc, null).followLinkZoom = !Cast(this.selectedDoc.anchor1, Doc, null).followLinkZoom))); + } + toggleZoomToTarget2 = (e: React.PointerEvent) => { + setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => Cast(this.selectedDoc.anchor2, Doc, null).followLinkZoom = !Cast(this.selectedDoc.anchor2, Doc, null).followLinkZoom))); + } + @computed get editRelationship() { return {

Information

-
+

Link Relationship

{this.editRelationship}
-
+

Description

{this.editDescription}

Behavior

-
+

Follow

-
+

Auto-move anchor

-
+

Display arrow

+
+

Zoom to target

+ +
+
+

Zoom to source

+ +
; } diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 334415b38..93da2fa19 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -55,6 +55,7 @@ function darkScheme() { return CurrentUserUtils.ActiveDashboard?.colorScheme === function toggleLockedPosition(doc: Doc) { UndoManager.RunInBatch(() => runInAction(() => { doc._lockedPosition = !doc._lockedPosition; + doc._pointerEvents = doc._lockedPosition ? "none" : undefined; }), "toggleBackground"); } @@ -194,10 +195,10 @@ export function DefaultStyleProvider(doc: Opt, props: Opt { const layoutdoc = Doc.Layout(doc); - const pw = this.props.PanelWidth() / NumCast(this.layoutDoc._viewScale, 1); - const ph = this.props.PanelHeight() / NumCast(this.layoutDoc._viewScale, 1); const pt = xf.transformPoint(NumCast(doc.x), NumCast(doc.y)); const pt2 = xf.transformPoint(NumCast(doc.x) + layoutdoc[WidthSym](), NumCast(doc.y) + layoutdoc[HeightSym]()); - const bounds = { left: pt[0], right: pt2[0], top: pt[1], bot: pt2[1] }; - const cx = NumCast(this.layoutDoc._panX); - const cy = NumCast(this.layoutDoc._panY); - const screen = { left: cx - pw / 2, right: cx + pw / 2, top: cy - ph / 2, bot: cy + ph / 2 }; + const bounds = { left: pt[0], right: pt2[0], top: pt[1], bot: pt2[1], width: pt2[0] - pt[0], height: pt2[1] - pt[1] }; if (scale) { const maxZoom = 5; // sets the limit for how far we will zoom. this is useful for preventing small text boxes from filling the screen. So probably needs to be more sophisticated to consider more about the target and context + const newScale = Math.min(maxZoom, 1 / (this.contentScaling || 1) * scale * Math.min(this.props.PanelWidth() / Math.abs(bounds.width), this.props.PanelHeight() / Math.abs(bounds.height))); return { - panX: (bounds.left + bounds.right) / 2, - panY: (bounds.top + bounds.bot) / 2, - scale: Math.min(maxZoom, scale * Math.min(this.props.PanelWidth() / Math.abs(pt2[0] - pt[0]), this.props.PanelHeight() / Math.abs(pt2[1] - pt[1]))) + panX: this.props.isAnnotationOverlay ? bounds.left - (Doc.NativeWidth(this.layoutDoc) / newScale - bounds.width) / 2 : (bounds.left + bounds.right) / 2, + panY: this.props.isAnnotationOverlay ? bounds.top - (Doc.NativeHeight(this.layoutDoc) / newScale - bounds.height) / 2 : (bounds.top + bounds.bot) / 2, + scale: newScale }; } + const pw = this.props.PanelWidth() / NumCast(this.layoutDoc._viewScale, 1); + const ph = this.props.PanelHeight() / NumCast(this.layoutDoc._viewScale, 1); + const cx = NumCast(this.layoutDoc._panX); + const cy = NumCast(this.layoutDoc._panY); + const screen = { left: cx - pw / 2, right: cx + pw / 2, top: cy - ph / 2, bot: cy + ph / 2 }; if ((screen.right - screen.left) < (bounds.right - bounds.left) || (screen.bot - screen.top) < (bounds.bot - bounds.top)) { return { @@ -1990,6 +1991,7 @@ class CollectionFreeFormBackgroundGrid extends React.Component { if (!didMove) { diff --git a/src/client/views/linking/LinkEditor.scss b/src/client/views/linking/LinkEditor.scss index abd413f57..1d6496d3c 100644 --- a/src/client/views/linking/LinkEditor.scss +++ b/src/client/views/linking/LinkEditor.scss @@ -60,6 +60,24 @@ } } +.linkEditor-zoomFollow { + padding-left: 26px; + padding-right: 6.5px; + padding-bottom: 3.5px; + display: flex; + + .linkEditor-zoomFollow-label { + text-decoration-color: black; + color: black; + line-height: 1.7; + } + + .linkEditor-zoomFollow-input { + display: block; + width: 20px; + } +} + .linkEditor-description { padding-left: 26px; padding-right: 6.5px; diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index db331bb75..c3e0aff11 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -9,7 +9,6 @@ import { undoBatch } from "../../util/UndoManager"; import './LinkEditor.scss'; import { LinkRelationshipSearch } from "./LinkRelationshipSearch"; import React = require("react"); -import { ToString } from "../../../fields/FieldSymbols"; interface LinkEditorProps { @@ -23,6 +22,7 @@ export class LinkEditor extends React.Component { @observable description = Field.toString(LinkManager.currentLink?.description as any as Field); @observable relationship = StrCast(LinkManager.currentLink?.linkRelationship); + @observable zoomFollow1 = StrCast(this.props.sourceDoc.followLinkZoom); @observable openDropdown: boolean = false; @observable showInfo: boolean = false; @computed get infoIcon() { if (this.showInfo) { return "chevron-up"; } return "chevron-down"; } @@ -143,9 +143,9 @@ export class LinkEditor extends React.Component { @action handleDescriptionChange = (e: React.ChangeEvent) => { this.description = e.target.value; } @action - handleRelationshipChange = (e: React.ChangeEvent) => { - this.relationship = e.target.value; - } + handleRelationshipChange = (e: React.ChangeEvent) => { this.relationship = e.target.value; } + @action + handleZoomFollowChange = (e: React.ChangeEvent) => { this.props.sourceDoc.followLinkZoom = e.target.checked; } @action handleRelationshipSearchChange = (result: string) => { this.setRelationshipValue(result); @@ -183,6 +183,27 @@ export class LinkEditor extends React.Component {
; } + @computed + get editZoomFollow() { + //NOTE: confusingly, the classnames for the following relationship JSX elements are the same as the for the description elements for shared CSS + return
+
Zoom To Link Target:
+
+
+ +
+
+
; + } @computed get editDescription() { @@ -303,6 +324,7 @@ export class LinkEditor extends React.Component { {this.editDescription} {this.editRelationship} + {this.editZoomFollow} {this.followingDropdown}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index b6a2fae1a..49c2761b2 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -605,7 +605,7 @@ export class DocumentViewInternal extends DocComponent, zoom: boolean, setPushpin: boolean): void => { + toggleFollowLink = (location: Opt, zoom?: boolean, setPushpin?: boolean): void => { this.Document.ignoreClick = false; if (setPushpin) { this.Document.isPushpin = !this.Document.isPushpin; @@ -614,7 +614,7 @@ export class DocumentViewInternal extends DocComponent) => Opt = () => undefined; @observable _curSuffix = ""; @observable _uploadIcon = uploadIcons.idle; @@ -62,7 +63,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent { - const anchor = AnchorMenu.Instance?.GetAnchor(this._savedAnnotations); + const anchor = this._getAnchor?.(this._savedAnnotations); anchor && this.addDocument(anchor); return anchor ?? this.rootDoc; } @@ -366,6 +367,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent { + this._getAnchor = AnchorMenu.Instance?.GetAnchor; this._marqueeing = undefined; this.props.select(false); } diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 35b5e78a8..cbe7a5cc6 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -198,7 +198,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent { const anchor = - AnchorMenu.Instance?.GetAnchor() ?? + this._pdfViewer?._getAnchor(this._pdfViewer.savedAnnotations()) ?? Docs.Create.TextanchorDocument({ title: StrCast(this.rootDoc.title + "@" + NumCast(this.layoutDoc._scrollTop)?.toFixed(0)), y: NumCast(this.layoutDoc._scrollTop), diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 445df8ddd..2112c1d44 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -52,6 +52,7 @@ export class WebBox extends ViewBoxAnnotatableComponent = React.createRef(); private _keyInput = React.createRef(); private _initialScroll: Opt = NumCast(this.layoutDoc.thumbScrollTop, NumCast(this.layoutDoc.scrollTop)); + private _getAnchor: (savedAnnotations?: ObservableMap) => Opt = () => undefined; private _sidebarRef = React.createRef(); private _searchRef = React.createRef(); private _searchString = ""; @@ -256,7 +257,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { const anchor = - AnchorMenu.Instance?.GetAnchor(this._savedAnnotations) ?? + this._getAnchor(this._savedAnnotations) ?? Docs.Create.WebanchorDocument(this._url, { title: StrCast(this.rootDoc.title + " " + this.layoutDoc._scrollTop), y: NumCast(this.layoutDoc._scrollTop), @@ -555,6 +556,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { + this._getAnchor = AnchorMenu.Instance?.GetAnchor; this._marqueeing = undefined; this._isAnnotating = false; this._iframeClick = undefined; diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index b0a5fc93b..305b1fe68 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -6,7 +6,6 @@ import { Doc, DocListCast, Field, HeightSym, Opt } from "../../../fields/Doc"; import { Id } from "../../../fields/FieldSymbols"; import { InkTool } from "../../../fields/InkField"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; -import { PdfField } from "../../../fields/URLField"; import { TraceMobx } from "../../../fields/util"; import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, OmitKeys, returnFalse, smoothScroll, Utils } from "../../../Utils"; import { DocUtils } from "../../documents/Documents"; @@ -59,7 +58,6 @@ export class PDFViewer extends React.Component { @observable private _marqueeing: number[] | undefined; @observable private _textSelecting = true; @observable private _showWaiting = true; - @observable private _zoomed = 1; @observable private _overlayAnnoInfo: Opt; @observable private Index: number = -1; @@ -70,6 +68,7 @@ export class PDFViewer extends React.Component { private _annotationLayer: React.RefObject = React.createRef(); private _disposers: { [name: string]: IReactionDisposer } = {}; private _viewer: React.RefObject = React.createRef(); + public _getAnchor: (savedAnnotations?: ObservableMap) => Opt = () => undefined; _mainCont: React.RefObject = React.createRef(); private _selectionText: string = ""; private _downX: number = 0; @@ -184,7 +183,7 @@ export class PDFViewer extends React.Component { pagesinit = () => { if (this._pdfViewer._setDocumentViewerElement?.offsetParent) { - runInAction(() => this._pdfViewer.currentScaleValue = this._zoomed = 1); + runInAction(() => this._pdfViewer.currentScaleValue = this.props.layoutDoc._viewScale = 1); this.gotoPage(NumCast(this.props.Document._curPage, 1)); } document.removeEventListener("pagesinit", this.pagesinit); @@ -355,6 +354,7 @@ export class PDFViewer extends React.Component { @action finishMarquee = (x?: number, y?: number) => { + this._getAnchor = AnchorMenu.Instance?.GetAnchor; this.isAnnotating = false; this._marqueeing = undefined; this._textSelecting = true; @@ -387,13 +387,14 @@ export class PDFViewer extends React.Component { const rect = clientRects.item(i); if (rect && rect.width !== this._mainCont.current.clientWidth && rect.width) { const scaleX = this._mainCont.current.offsetWidth / boundingRect.width; + const pdfScale = NumCast(this.props.layoutDoc._viewScale, 1); const annoBox = document.createElement("div"); annoBox.className = "marqueeAnnotator-annotationBox"; // transforms the positions from screen onto the pdf div - annoBox.style.top = ((rect.top - boundingRect.top) * scaleX / this._zoomed + this._mainCont.current.scrollTop).toString(); - annoBox.style.left = ((rect.left - boundingRect.left) * scaleX / this._zoomed).toString(); - annoBox.style.width = (rect.width * this._mainCont.current.offsetWidth / boundingRect.width / this._zoomed).toString(); - annoBox.style.height = (rect.height * this._mainCont.current.offsetHeight / boundingRect.height / this._zoomed).toString(); + annoBox.style.top = ((rect.top - boundingRect.top) * scaleX / pdfScale + this._mainCont.current.scrollTop).toString(); + annoBox.style.left = ((rect.left - boundingRect.left) * scaleX / pdfScale).toString(); + annoBox.style.width = (rect.width * this._mainCont.current.offsetWidth / boundingRect.width / pdfScale).toString(); + annoBox.style.height = (rect.height * this._mainCont.current.offsetHeight / boundingRect.height / pdfScale).toString(); this._annotationLayer.current && MarqueeAnnotator.previewNewAnnotation(this._savedAnnotations, this._annotationLayer.current, annoBox, this.getPageFromScroll(rect.top)); } } @@ -430,14 +431,14 @@ export class PDFViewer extends React.Component { if (e.ctrlKey) { const curScale = Number(this._pdfViewer.currentScaleValue); this._pdfViewer.currentScaleValue = Math.max(1, Math.min(10, curScale - curScale * e.deltaY / 1000)); - this._zoomed = Number(this._pdfViewer.currentScaleValue); + this.props.layoutDoc._viewScale = Number(this._pdfViewer.currentScaleValue); } } } pointerEvents = () => this.props.isContentActive() && this.props.pointerEvents?.() !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none"; @computed get annotationLayer() { - return
+ return
{this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno => )}
; @@ -453,7 +454,7 @@ export class PDFViewer extends React.Component { } showInfo = action((anno: Opt) => this._overlayAnnoInfo = anno); - overlayTransform = () => this.scrollXf().scale(1 / this._zoomed); + overlayTransform = () => this.scrollXf().scale(1 / NumCast(this.props.layoutDoc._viewScale, 1)); panelWidth = () => this.props.PanelWidth() / (this.props.scaling?.() || 1); // (this.Document.scrollHeight || Doc.NativeHeight(this.Document) || 0); panelHeight = () => this.props.PanelHeight() / (this.props.scaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document); basicFilter = () => [...this.props.docFilters(), Utils.PropUnsetFilter("textInlineAnnotations")]; @@ -498,7 +499,7 @@ export class PDFViewer extends React.Component { style={{ pointerEvents: SnappingManager.GetIsDragging() ? "all" : "none", mixBlendMode: "multiply", - transform: `scale(${this._zoomed})` + transform: `scale(${NumCast(this.props.layoutDoc._viewScale, 1)})` }}> {this.overlayTransparentAnnotations}
@@ -506,7 +507,7 @@ export class PDFViewer extends React.Component { style={{ pointerEvents: SnappingManager.GetIsDragging() ? "all" : "none", mixBlendMode: this.allAnnotations.some(anno => anno.mixBlendMode) ? "hard-light" : undefined, - transform: `scale(${this._zoomed})` + transform: `scale(${NumCast(this.props.layoutDoc._viewScale, 1)})` }}> {this.overlayOpaqueAnnotations} {this.overlayClickableAnnotations} @@ -517,7 +518,7 @@ export class PDFViewer extends React.Component { return
; } @computed get contentScaling() { return this.props.ContentScaling?.() || 1; } - contentZoom = () => this._zoomed; + contentZoom = () => NumCast(this.props.layoutDoc._viewScale, 1); savedAnnotations = () => this._savedAnnotations; render() { TraceMobx(); @@ -525,7 +526,7 @@ export class PDFViewer extends React.Component {
600) ? Doc.NativeHeight(this.props.Document) : `${100 / this.contentScaling}%`, transform: `scale(${this.contentScaling})` }} > -- cgit v1.2.3-70-g09d2