aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2021-08-24 14:28:13 -0400
committerbobzel <zzzman@gmail.com>2021-08-24 14:28:13 -0400
commit5867ca16f8a8beaf7daf754ee5c42a5cc249346f (patch)
treed59c42afdbc9f0aa0abc8b8e79772df5c639f4ab /src
parenta38501569769c00dc1c25fb57d09ca88f3951c3d (diff)
fixed undo for dragging docs. made separate layers for transparent and other annotations on pdfs/webs so that transparency will work better.
Diffstat (limited to 'src')
-rw-r--r--src/Utils.ts10
-rw-r--r--src/client/util/DragManager.ts12
-rw-r--r--src/client/views/nodes/WebBox.tsx48
-rw-r--r--src/client/views/pdf/PDFViewer.tsx18
-rw-r--r--src/fields/Doc.ts5
5 files changed, 60 insertions, 33 deletions
diff --git a/src/Utils.ts b/src/Utils.ts
index f251f776c..f90296121 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -115,6 +115,16 @@ export namespace Utils {
return { r: r, g: g, b: b, a: a };
}
+ export function IsTransparentFilter() {
+ // bcz: isTransparent(__value__) is a hack. it would be nice to have acual functions be parsed, but now Doc.matchFieldValue is hardwired to recognize just this one
+ return ["backgroundColor:isTransparent(__value__):check"];
+ }
+ export function IsOpaqueFilter() {
+ // bcz: isTransparent(__value__) is a hack. it would be nice to have acual functions be parsed, but now Doc.matchFieldValue is hardwired to recognize just this one
+ return ["backgroundColor:isTransparent(__value__):x"];
+ }
+
+
export function toRGBAstr(col: { r: number, g: number, b: number, a?: number }) {
return "rgba(" + col.r + "," + col.g + "," + col.b + (col.a !== undefined ? "," + col.a : "") + ")";
}
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 5e16de617..f7ef9ae6f 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -425,10 +425,10 @@ export namespace DragManager {
AbortDrag = () => {
options?.dragComplete?.(new DragCompleteEvent(true, dragData));
- endDrag();
+ cleanupDrag();
};
- const endDrag = action(() => {
+ const cleanupDrag = action(() => {
hideDragShowOriginalElements(false);
document.removeEventListener("pointermove", moveHandler, true);
document.removeEventListener("pointerup", upHandler);
@@ -518,15 +518,14 @@ export namespace DragManager {
`translate(${(xs[i] += moveVec.x) + (options?.offsetX || 0)}px, ${(ys[i] += moveVec.y) + (options?.offsetY || 0)}px) scale(${scaleXs[i]}, ${scaleYs[i]})`)
);
};
- const upHandler = async (e: PointerEvent) => {
- dispatchDrag(document.elementFromPoint(e.x, e.y) || document.body, e, new DragCompleteEvent(false, dragData), snapDrag(e, xFromLeft, yFromTop, xFromRight, yFromBottom), finishDrag, options);
- endDrag();
+ const upHandler = (e: PointerEvent) => {
+ dispatchDrag(document.elementFromPoint(e.x, e.y) || document.body, e, new DragCompleteEvent(false, dragData), snapDrag(e, xFromLeft, yFromTop, xFromRight, yFromBottom), finishDrag, options, cleanupDrag);
};
document.addEventListener("pointermove", moveHandler, true);
document.addEventListener("pointerup", upHandler);
}
- async function dispatchDrag(target: Element, e: PointerEvent, complete: DragCompleteEvent, pos: { x: number, y: number }, finishDrag?: (e: DragCompleteEvent) => void, options?: DragOptions) {
+ async function dispatchDrag(target: Element, e: PointerEvent, complete: DragCompleteEvent, pos: { x: number, y: number }, finishDrag?: (e: DragCompleteEvent) => void, options?: DragOptions, endDrag?: () => void) {
const dropArgs = {
bubbles: true,
detail: {
@@ -543,5 +542,6 @@ export namespace DragManager {
await finishDrag?.(complete);
target.dispatchEvent(new CustomEvent<DropEvent>("dashOnDrop", dropArgs));
options?.dragComplete?.(complete);
+ endDrag?.();
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 0c32a30db..94697464a 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -512,6 +512,29 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const pointerEvents = this.props.layerProvider?.(this.layoutDoc) === false ? "none" : undefined;
const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1;
const scale = previewScale * (this.props.scaling?.() || 1);
+ const renderAnnotations = (docFilters: () => string[]) =>
+ <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
+ renderDepth={this.props.renderDepth + 1}
+ isAnnotationOverlay={true}
+ fieldKey={this.annotationKey}
+ CollectionView={undefined}
+ setPreviewCursor={this.setPreviewCursor}
+ PanelWidth={this.panelWidth}
+ PanelHeight={this.panelHeight}
+ ScreenToLocalTransform={this.scrollXf}
+ scaling={returnOne}
+ dropAction={"alias"}
+ docFilters={docFilters}
+ select={emptyFunction}
+ isContentActive={returnFalse}
+ ContentScaling={returnOne}
+ bringToFront={emptyFunction}
+ whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
+ removeDocument={this.removeDocument}
+ moveDocument={this.moveDocument}
+ addDocument={this.sidebarAddDocument}
+ childPointerEvents={true}
+ pointerEvents={this._isAnnotating || SnappingManager.GetIsDragging() ? "all" : "none"} />;
return (
<div className="webBox" ref={this._mainCont} style={{ pointerEvents: this.isContentActive() ? "all" : this.isContentActive() || SnappingManager.GetIsDragging() ? undefined : "none" }} >
<div className={`webBox-container`} style={{ pointerEvents }} onContextMenu={this.specificContextMenu}>
@@ -529,27 +552,10 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
>
<div className={"webBox-innerContent"} style={{ height: NumCast(this.scrollHeight, 50), pointerEvents }}>
{this.content}
- <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
- renderDepth={this.props.renderDepth + 1}
- isAnnotationOverlay={true}
- fieldKey={this.annotationKey}
- CollectionView={undefined}
- setPreviewCursor={this.setPreviewCursor}
- PanelWidth={this.panelWidth}
- PanelHeight={this.panelHeight}
- ScreenToLocalTransform={this.scrollXf}
- scaling={returnOne}
- dropAction={"alias"}
- select={emptyFunction}
- isContentActive={returnFalse}
- ContentScaling={returnOne}
- bringToFront={emptyFunction}
- whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
- removeDocument={this.removeDocument}
- moveDocument={this.moveDocument}
- addDocument={this.sidebarAddDocument}
- childPointerEvents={true}
- pointerEvents={this._isAnnotating || SnappingManager.GetIsDragging() ? "all" : "none"} />
+ <div style={{ mixBlendMode: "multiply" }}>
+ {renderAnnotations(Utils.IsTransparentFilter)}
+ </div>
+ {renderAnnotations(Utils.IsOpaqueFilter)}
{this.annotationLayer}
</div>
</div>
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 41a60bedf..2c00b005d 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -507,12 +507,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
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);
@computed get overlayLayer() {
- return <div className={`pdfViewerDash-overlay${CurrentUserUtils.SelectedTool !== InkTool.None || SnappingManager.GetIsDragging() ? "-inking" : ""}`}
- style={{
- pointerEvents: SnappingManager.GetIsDragging() ? "all" : undefined,
- mixBlendMode: this.allAnnotations.some(anno => anno.mixBlendMode) ? "hard-light" : undefined,
- transform: `scale(${this._zoomed})`
- }}>
+ const renderAnnotations = (docFilters: () => string[]) =>
<CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
isAnnotationOverlay={true}
isContentActive={returnFalse}
@@ -524,10 +519,21 @@ export class PDFViewer extends React.Component<IViewerProps> {
select={emptyFunction}
ContentScaling={this.contentZoom}
bringToFront={emptyFunction}
+ docFilters={doFilters}
CollectionView={undefined}
ScreenToLocalTransform={this.overlayTransform}
renderDepth={this.props.renderDepth + 1}
childPointerEvents={true} />
+ return <div className={`pdfViewerDash-overlay${CurrentUserUtils.SelectedTool !== InkTool.None || SnappingManager.GetIsDragging() ? "-inking" : ""}`}
+ style={{
+ pointerEvents: SnappingManager.GetIsDragging() ? "all" : undefined,
+ mixBlendMode: this.allAnnotations.some(anno => anno.mixBlendMode) ? "hard-light" : undefined,
+ transform: `scale(${this._zoomed})`
+ }}>
+ <div style={{ mixBlendMode: "multiply" }}>
+ {renderAnnotations(Utils.IsTransparentFilter)}
+ </div>
+ {renderAnnotations(Utils.IsOpaqueFilter)}
</div>;
}
@computed get pdfViewerDiv() {
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index e4087cf43..f6efefdf9 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -25,6 +25,7 @@ import { deleteProperty, GetEffectiveAcl, getField, getter, inheritParentAcls, m
import JSZip = require("jszip");
import { CurrentUserUtils } from "../client/util/CurrentUserUtils";
import { IconProp } from "@fortawesome/fontawesome-svg-core";
+import Color = require("color");
export namespace Field {
export function toKeyValueString(doc: Doc, key: string): string {
@@ -1087,6 +1088,10 @@ export namespace Doc {
}
export function matchFieldValue(doc: Doc, key: string, value: any): boolean {
+ if (value === "isTransparent(__value__)") {
+ const isTransparent = (color: string) => color !== "" && (Color(color).alpha() !== 1);
+ return isTransparent(StrCast(doc[key]));
+ }
const fieldVal = doc[key];
if (Cast(fieldVal, listSpec("string"), []).length) {
const vals = Cast(fieldVal, listSpec("string"), []);