aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/util/DragManager.ts41
-rw-r--r--src/client/views/MainView.tsx8
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx70
-rw-r--r--src/client/views/nodes/formattedText/DashFieldView.tsx4
4 files changed, 53 insertions, 70 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index c03d9ea1b..c48611eff 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,5 +1,5 @@
import { Doc, Field, DocListCast } from "../../new_fields/Doc";
-import { Cast, ScriptCast, StrCast } from "../../new_fields/Types";
+import { Cast, ScriptCast, StrCast, NumCast } from "../../new_fields/Types";
import { emptyFunction } from "../../Utils";
import { CollectionDockingView } from "../views/collections/CollectionDockingView";
import * as globalCssVariables from "../views/globalCssVariables.scss";
@@ -305,33 +305,20 @@ export namespace DragManager {
}
export function snapDrag(e: PointerEvent, xFromLeft: number, yFromTop: number, xFromRight: number, yFromBottom: number) {
- let thisX = e.pageX;
- let thisY = e.pageY;
- const currLeft = e.pageX - xFromLeft;
- const currTop = e.pageY - yFromTop;
- const currRight = e.pageX + xFromRight;
- const currBottom = e.pageY + yFromBottom;
- const closestLeft = vertSnapLines.length ? vertSnapLines.reduce((prev, curr) => Math.abs(prev - currLeft) > Math.abs(curr - currLeft) ? curr : prev) : currLeft;
- const closestTop = horizSnapLines.length ? horizSnapLines.reduce((prev, curr) => Math.abs(prev - currTop) > Math.abs(curr - currTop) ? curr : prev) : currTop;
- const closestRight = vertSnapLines.length ? vertSnapLines.reduce((prev, curr) => Math.abs(prev - currRight) > Math.abs(curr - currRight) ? curr : prev) : currRight;
- const closestBottom = horizSnapLines.length ? horizSnapLines.reduce((prev, curr) => Math.abs(prev - currBottom) > Math.abs(curr - currBottom) ? curr : prev) : currBottom;
- const distFromClosestLeft = Math.abs(e.pageX - xFromLeft - closestLeft);
- const distFromClosestTop = Math.abs(e.pageY - yFromTop - closestTop);
- const distFromClosestRight = Math.abs(e.pageX + xFromRight - closestRight);
- const distFromClosestBottom = Math.abs(e.pageY + yFromBottom - closestBottom);
- if (distFromClosestLeft < 10 && distFromClosestLeft < distFromClosestRight) {
- thisX = closestLeft + xFromLeft;
- }
- else if (distFromClosestRight < 10) {
- thisX = closestRight - xFromRight;
- }
- if (distFromClosestTop < 10 && distFromClosestTop < distFromClosestBottom) {
- thisY = closestTop + yFromTop;
- }
- else if (distFromClosestBottom < 10) {
- thisY = closestBottom - yFromBottom;
+ const snapThreshold = NumCast(Doc.UserDoc()["constants-snapThreshold"], 10);
+ const snapVal = (pts: number[], drag: number, snapLines: number[]) => {
+ if (snapLines.length) {
+ const offs = [pts[0], (pts[0] - pts[1]) / 2, -pts[1]]; // offsets from drag pt
+ const rangePts = [drag - offs[0], drag - offs[1], drag - offs[2]]; // left, mid, right or top, mid, bottom pts to try to snap to snaplines
+ const closestPts = rangePts.map(pt => snapLines.reduce((nearest, curr) => Math.abs(nearest - pt) > Math.abs(curr - pt) ? curr : nearest));
+ const closestDists = rangePts.map((pt, i) => Math.abs(pt - closestPts[i]));
+ const minIndex = closestDists[0] < closestDists[1] && closestDists[0] < closestDists[2] ? 0 : closestDists[1] < closestDists[2] ? 1 : 2;
+ return closestDists[minIndex] < snapThreshold ? closestPts[minIndex] + offs[minIndex] : drag;
+ }
+ return drag;
}
- return { thisX, thisY };
+
+ return { thisX: snapVal([xFromLeft, xFromRight], e.pageX, vertSnapLines), thisY: snapVal([yFromTop, yFromBottom], e.pageY, horizSnapLines) };
}
export let docsBeingDragged: Doc[] = [];
function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void) {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index e5a8ebcb5..72dfdf75c 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -588,12 +588,12 @@ export class MainView extends React.Component {
<RichTextMenu />
<OverlayView />
{// TO VIEW SNAP LINES
- /* <div className="snapLines" style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%", pointerEvents: "none" }}>
+ <div className="snapLines" style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%", pointerEvents: "none" }}>
<svg style={{ width: "100%", height: "100%" }}>
- {this._hLines?.map(l => <line x1="0" y1={l} x2="2000" y2={l} stroke="black" />)}
- {this._vLines?.map(l => <line y1="0" x1={l} y2="2000" x2={l} stroke="black" />)}
+ {this._hLines?.map(l => <line x1="0" y1={l} x2="2000" y2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)}
+ {this._vLines?.map(l => <line y1="0" x1={l} y2="2000" x2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)}
</svg>
- </div>*/}
+ </div>}
<TimelineMenu />
</div >);
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 11d0f298d..763a6c605 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -869,6 +869,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
LibraryPath: this.libraryPath,
FreezeDimensions: this.props.freezeChildDimensions,
layoutKey: undefined,
+ setupDragLines: this.setupDragLines,
rootSelected: childData ? this.rootSelected : returnFalse,
dropAction: StrCast(this.props.Document.childDropAction) as dropActionType,
//onClick: undefined, // this.props.onClick, // bcz: check this out -- I don't think we want to inherit click handlers, or we at least need a way to ignore them
@@ -1146,37 +1147,36 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
@action
+ setupDragLines = () => {
+ const size = this.props.ScreenToLocalTransform().transformDirection(this.props.PanelWidth(), this.props.PanelHeight());
+ const selRect = { left: this.panX() - size[0] / 2, top: this.panY() - size[1] / 2, width: size[0], height: size[1] };
+ const docDims = (doc: Doc) => ({ left: NumCast(doc.x), top: NumCast(doc.y), width: NumCast(doc._width), height: NumCast(doc._height) });
+ const isDocInView = (doc: Doc, rect: { left: number, top: number, width: number, height: number }) => {
+ if (this.intersectRect(docDims(doc), rect)) {
+ snappableDocs.push(doc);
+ }
+ }
+ const snappableDocs: Doc[] = []; // the set of documents in the visible viewport that we will try to snap to;
+ const otherBounds = { left: this.panX(), top: this.panY(), width: Math.abs(size[0]), height: Math.abs(size[1]) };
+ this.getActiveDocuments().filter(doc => !doc.isBackground && doc.z === undefined).map(doc => isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to
+ !snappableDocs.length && this.getActiveDocuments().filter(doc => doc.z === undefined).map(doc => isDocInView(doc, selRect)); // if not, see if there are background docs to snap to
+ !snappableDocs.length && this.getActiveDocuments().filter(doc => doc.z !== undefined).map(doc => isDocInView(doc, otherBounds)); // if not, then why not snap to floating docs
+
+ const horizLines: number[] = [];
+ const vertLines: number[] = [];
+ snappableDocs.filter(doc => !DragManager.docsBeingDragged.includes(Cast(doc.rootDocument, Doc, null) || doc)).forEach(doc => {
+ const { left, top, width, height } = docDims(doc);
+ const topLeftInScreen = this.getTransform().inverse().transformPoint(left, top);
+ const docSize = this.getTransform().inverse().transformDirection(width, height);
+
+ horizLines.push(topLeftInScreen[1], topLeftInScreen[1] + docSize[1] / 2, topLeftInScreen[1] + docSize[1]); // horiz center line
+ vertLines.push(topLeftInScreen[0], topLeftInScreen[0] + docSize[0] / 2, topLeftInScreen[0] + docSize[0]);// right line
+ });
+ DragManager.SetSnapLines(horizLines, vertLines);
+ }
onPointerOver = (e: React.PointerEvent) => {
if (SelectionManager.GetIsDragging()) {
- const size = this.props.ScreenToLocalTransform().transformDirection(this.props.PanelWidth(), this.props.PanelHeight());
- const selRect = { left: this.panX() - size[0] / 2, top: this.panY() - size[1] / 2, width: size[0], height: size[1] };
- const selection: Doc[] = [];
- const docDims = (doc: Doc, layoutDoc: Doc) => ({ left: NumCast(doc.x), top: NumCast(doc.y), width: NumCast(layoutDoc._width), height: NumCast(layoutDoc._height) });
- const compareDoc = (doc: Doc, rect: { left: number, top: number, width: number, height: number }) => {
- if (this.intersectRect(docDims(doc, Doc.Layout(doc)), rect)) {
- selection.push(doc);
- }
- }
- const otherBounds = { left: this.panX(), top: this.panY(), width: Math.abs(size[0]), height: Math.abs(size[1]) };
- this.getActiveDocuments().filter(doc => !doc.isBackground && doc.z === undefined).map(doc => compareDoc(doc, selRect)); // first try foreground docs
- !selection.length && this.getActiveDocuments().filter(doc => doc.z === undefined).map(doc => compareDoc(doc, selRect)); // then background docs
- !selection.length && this.getActiveDocuments().filter(doc => doc.z !== undefined).map(doc => compareDoc(doc, otherBounds)); // then floating docs
-
- const horizLines: number[] = [];
- const vertLines: number[] = [];
- selection.filter(doc => !DragManager.docsBeingDragged.includes(doc)).forEach(doc => {
- const { left, top, width, height } = docDims(doc, Doc.Layout(doc));
- const topLeftInScreen = this.getTransform().inverse().transformPoint(left, top);
- const docSize = this.getTransform().inverse().transformDirection(width, height);
-
- horizLines.push(topLeftInScreen[1]); // top line
- horizLines.push(topLeftInScreen[1] + docSize[1]); // bottom line
- horizLines.push(topLeftInScreen[1] + docSize[1] / 2); // horiz center line
- vertLines.push(topLeftInScreen[0]);//left line
- vertLines.push(topLeftInScreen[0] + docSize[0]);// right line
- vertLines.push(topLeftInScreen[0] + docSize[0] / 2);// vert center line
- });
- DragManager.SetSnapLines(horizLines, vertLines);
+ this.setupDragLines(e);
}
e.stopPropagation();
}
@@ -1273,12 +1273,12 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}}>
</div>
{// uncomment to show snap lines
- /*<div className="snapLines" style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%", pointerEvents: "none" }}>
- <svg style={{ width: "100%", height: "100%" }}>
- {this._hLines?.map(l => <line x1="0" y1={l} x2="1000" y2={l} stroke="black" />)}
- {this._vLines?.map(l => <line y1="0" x1={l} y2="1000" x2={l} stroke="black" />)}
- </svg>
- </div>*/}
+ <div className="snapLines" style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%", pointerEvents: "none" }}>
+ <svg style={{ width: "100%", height: "100%" }}>
+ {this._hLines?.map(l => <line x1="0" y1={l} x2="1000" y2={l} stroke="black" />)}
+ {this._vLines?.map(l => <line y1="0" x1={l} y2="1000" x2={l} stroke="black" />)}
+ </svg>
+ </div>}
</div >;
}
}
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 422710c3e..1b22ed4cd 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -34,8 +34,6 @@ export class DashFieldView {
docid={node.attrs.docid}
width={node.attrs.width}
height={node.attrs.height}
- view={view}
- getPos={getPos}
tbox={tbox}
/>, this._fieldWrapper);
(this as any).dom = this._fieldWrapper;
@@ -49,8 +47,6 @@ export class DashFieldView {
interface IDashFieldViewInternal {
fieldKey: string;
docid: string;
- view: any;
- getPos: any;
tbox: FormattedTextBox;
width: number;
height: number;